diff --git a/js/freeboard+plugins.js b/js/freeboard+plugins.js
index cf3bf1e..40af892 100644
--- a/js/freeboard+plugins.js
+++ b/js/freeboard+plugins.js
@@ -1332,7 +1332,10 @@ PluginEditor = function(jsEditor, valueEditor)
ValueEditor = function(theFreeboardModel)
{
- var _veDatasourceRegex = new RegExp(".*datasources\\[\"([^\"]*)(\"\\].)?$");
+ var _veDatasourceRegex = new RegExp(".*datasources\\[\"([^\"]*)(\"\\]\\[\")?(.*)$");
+
+ var _autocompleteOptions = [];
+ var _autocompleteReplacementString;
function _resizeValueEditor(element)
{
@@ -1343,6 +1346,126 @@ ValueEditor = function(theFreeboardModel)
$(element).css({height: newHeight + "px"});
}
+ function _autocompleteFromDatasource(inputString, datasources)
+ {
+ var match = _veDatasourceRegex.exec(inputString);
+
+ var options = [];
+ var replacementString;
+
+ if(match)
+ {
+ if(match[1] == "") // List all datasources
+ {
+ _.each(datasources, function(datasource)
+ {
+ options.push({value: datasource.name(), follow_char: "\"][\""});
+ });
+ }
+ else if(match[1] != "" && _.isUndefined(match[2])) // List partial datasources
+ {
+ replacementString = match[1];
+
+ _.each(datasources, function(datasource)
+ {
+ var dsName = datasource.name();
+
+ if(dsName != replacementString && dsName.indexOf(replacementString) == 0)
+ {
+ options.push({value: dsName, follow_char: "\"][\""});
+ }
+ });
+ }
+ else
+ {
+ var datasource = _.find(datasources, function(datasource)
+ {
+ return (datasource.name() === match[1]);
+ });
+
+ if(!_.isUndefined(datasource))
+ {
+ var dataPath = "";
+
+ if(!_.isUndefined(match[2]))
+ {
+ dataPath = match[2] + match[3];
+ }
+
+ var dataPathItems = dataPath.split("\"][\"");
+ dataPath = "data";
+
+ for(var index = 1; index < dataPathItems.length - 1; index++)
+ {
+ if(dataPathItems[index] != "")
+ {
+ dataPathItem = "[\"" + dataPathItems[index] + "\"]";
+ dataPath = dataPath + dataPathItem;
+ }
+ }
+
+ var lastPathObject = _.last(dataPathItems);
+
+ // If the last character is a ", then ignore it
+ if(lastPathObject.charAt(lastPathObject.length - 1) == "\"")
+ {
+ lastPathObject = lastPathObject.replace(/\[\"?$/, "");
+ dataPath = dataPath + "[\"" + lastPathObject + "\"]";
+ }
+
+ var dataValue = datasource.getDataRepresentation(dataPath);
+
+ if(_.isArray(dataValue))
+ {
+ for(var index = 0; index < dataValue.length; index++)
+ {
+ var followChar = "\"]";
+
+ if(_.isObject(dataValue[index]))
+ {
+ followChar = followChar + "\"][\"";
+ }
+ else if(_.isArray(dataValue[index]))
+ {
+ followChar = followChar + "\"][";
+ }
+
+ options.push({value: index, follow_char: followChar});
+ }
+ }
+ else if(_.isObject(dataValue))
+ {
+ replacementString = lastPathObject;
+
+ if(_.keys(dataValue).indexOf(replacementString) == -1)
+ {
+ _.each(dataValue, function(value, name)
+ {
+ if(name != lastPathObject && name.indexOf(lastPathObject) == 0)
+ {
+ var followChar = "\"]";
+
+ if(_.isArray(value))
+ {
+ followChar = "\"][";
+ }
+ else if(_.isObject(value))
+ {
+ followChar = "\"][\"";
+ }
+
+ options.push({value: name, follow_char: followChar});
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+ _autocompleteOptions = options;
+ _autocompleteReplacementString = replacementString;
+ }
+
function createValueEditor(element)
{
var dropdown = null;
@@ -1360,121 +1483,9 @@ ValueEditor = function(theFreeboardModel)
var inputString = $(element).val().substring(0, $(element).getCaretPosition());
inputString = inputString.replace(String.fromCharCode(160), " "); // Weird issue where the textarea box was putting in ASCII (non breaking space) for spaces.
- var match = _veDatasourceRegex.exec(inputString);
+ _autocompleteFromDatasource(inputString, theFreeboardModel.datasources());
- var options = [];
- var replacementString;
-
- if(match)
- {
- if(match[1] == "") // List all datasources
- {
- _.each(theFreeboardModel.datasources(), function(datasource)
- {
- options.push({value: datasource.name(), follow_char: "\"]."});
- });
- }
- else if(match[1] != "" && _.isUndefined(match[2])) // List partial datasources
- {
- replacementString = match[1];
-
- _.each(theFreeboardModel.datasources(), function(datasource)
- {
- var dsName = datasource.name();
-
- if(dsName != replacementString && dsName.indexOf(replacementString) == 0)
- {
- options.push({value: dsName, follow_char: "\"]."});
- }
- });
- }
- else
- {
- var datasource = _.find(theFreeboardModel.datasources(), function(datasource)
- {
- return (datasource.name() === match[1]);
- });
-
- if(!_.isUndefined(datasource))
- {
- var dataPath = "";
-
- if(!_.isUndefined(match[2]))
- {
- dataPath = match[2];
- }
-
- var dataPathItems = dataPath.split(".");
- dataPath = "data";
-
- for(var index = 1; index < dataPathItems.length - 1; index++)
- {
- if(dataPathItems[index] != "")
- {
- dataPath = dataPath + "." + dataPathItems[index];
- }
- }
-
- var lastPathObject = _.last(dataPathItems);
-
- // If the last character is a [, then ignore it
- if(lastPathObject.charAt(lastPathObject.length - 1) == "[")
- {
- lastPathObject = lastPathObject.replace(/\[+$/, "");
- dataPath = dataPath + "." + lastPathObject;
- }
-
- var dataValue = datasource.getDataRepresentation(dataPath);
-
- if(_.isArray(dataValue))
- {
- for(var index = 0; index < dataValue.length; index++)
- {
- var followChar = "]";
-
- if(_.isObject(dataValue[index]))
- {
- followChar = followChar + ".";
- }
- else if(_.isArray(dataValue[index]))
- {
- followChar = followChar + "[";
- }
-
- options.push({value: index, follow_char: followChar});
- }
- }
- else if(_.isObject(dataValue))
- {
- replacementString = lastPathObject;
-
- if(_.keys(dataValue).indexOf(replacementString) == -1)
- {
- _.each(dataValue, function(value, name)
- {
- if(name != lastPathObject && name.indexOf(lastPathObject) == 0)
- {
- var followChar = undefined;
-
- if(_.isArray(value))
- {
- followChar = "[";
- }
- else if(_.isObject(value))
- {
- followChar = ".";
- }
-
- options.push({value: name, follow_char: followChar});
- }
- });
- }
- }
- }
- }
- }
-
- if(options.length > 0)
+ if(_autocompleteOptions.length > 0)
{
if(!dropdown)
{
@@ -1489,7 +1500,7 @@ ValueEditor = function(theFreeboardModel)
var currentIndex = 0;
- _.each(options, function(option)
+ _.each(_autocompleteOptions, function(option)
{
var li = $('
' + option.value + ' ').appendTo(dropdown).mouseenter(function()
{
@@ -1507,13 +1518,13 @@ ValueEditor = function(theFreeboardModel)
optionValue = optionValue + option.follow_char;
}
- if(!_.isUndefined(replacementString))
+ if(!_.isUndefined(_autocompleteReplacementString))
{
- var replacementIndex = inputString.lastIndexOf(replacementString);
+ var replacementIndex = inputString.lastIndexOf(_autocompleteReplacementString);
if(replacementIndex != -1)
{
- $(element).replaceTextAt(replacementIndex, replacementIndex + replacementString.length, optionValue);
+ $(element).replaceTextAt(replacementIndex, replacementIndex + _autocompleteReplacementString.length, optionValue);
}
}
else
diff --git a/js/freeboard+plugins.min.js b/js/freeboard+plugins.min.js
index 85b6971..45c8d19 100644
--- a/js/freeboard+plugins.min.js
+++ b/js/freeboard+plugins.min.js
@@ -1,2 +1,2 @@
-function DialogBox(e,t,n,i,a){function s(){o.fadeOut(200,function(){$(this).remove()})}var o=$('
'),r=$('
');r.append('"),$("").appendTo(r).append(e);var d=$("").appendTo(r);n&&$(''+n+" ").appendTo(d).click(function(){var e=!1;_.isFunction(a)&&(e=a()),e||s()}),i&&$(''+i+" ").appendTo(d).click(function(){s()}),o.append(r),$("body").append(o),o.fadeIn(200)}function FreeboardModel(e,t,n){var i=this,a=1;this.version=0,this.isEditing=ko.observable(!1),this.allow_edit=ko.observable(!1),this.allow_edit.subscribe(function(e){e?$("#main-header").show():$("#main-header").hide()}),this.header_image=ko.observable(),this.plugins=ko.observableArray(),this.datasources=ko.observableArray(),this.panes=ko.observableArray(),this.datasourceData={},this.processDatasourceUpdate=function(e,t){var n=e.name();i.datasourceData[n]=t,_.each(i.panes(),function(e){_.each(e.widgets(),function(e){e.processDatasourceUpdate(n)})})},this._datasourceTypes=ko.observable(),this.datasourceTypes=ko.computed({read:function(){i._datasourceTypes();var t=[];return _.each(e,function(e){var n=e.type_name,i=n;_.isUndefined(e.display_name)||(i=e.display_name),t.push({name:n,display_name:i})}),t}}),this._widgetTypes=ko.observable(),this.widgetTypes=ko.computed({read:function(){i._widgetTypes();var e=[];return _.each(t,function(t){var n=t.type_name,i=n;_.isUndefined(t.display_name)||(i=t.display_name),e.push({name:n,display_name:i})}),e}}),this.addPluginSource=function(e){e&&-1==i.plugins.indexOf(e)&&i.plugins.push(e)},this.serialize=function(){var e=[];_.each(i.panes(),function(t){e.push(t.serialize())});var t=[];return _.each(i.datasources(),function(e){t.push(e.serialize())}),{version:a,header_image:i.header_image(),allow_edit:i.allow_edit(),plugins:i.plugins(),panes:e,datasources:t}},this.deserialize=function(n,a){function s(){_.isUndefined(n.allow_edit)?i.allow_edit(!0):i.allow_edit(n.allow_edit),i.version=n.version||0,i.header_image(n.header_image),_.each(n.datasources,function(t){var n=new DatasourceModel(i,e);n.deserialize(t),i.addDatasource(n)});var s=_.sortBy(n.panes,function(e){return freeboard._getPositionForScreenSize(e).row});_.each(s,function(e){var n=new PaneModel(i,t);n.deserialize(e),i.panes.push(n)}),i.allow_edit()&&0==i.panes().length&&i.setEditing(!0),_.isFunction(a)&&a()}i.clearDashboard(),_.each(n.plugins,function(e){i.addPluginSource(e)}),_.isArray(n.plugins)&&n.plugins.length>0?head.js(n.plugins,function(){s()}):s()},this.clearDashboard=function(){freeboard._removeAllWidgets(),_.each(i.datasources(),function(e){e.dispose()}),_.each(i.panes(),function(e){e.dispose()}),i.plugins.removeAll(),i.datasources.removeAll(),i.panes.removeAll()},this.loadDashboard=function(e,t){n.showLoadingIndicator(!0),i.deserialize(e,function(){n.showLoadingIndicator(!1),_.isFunction(t)&&t(),freeboard.emit("dashboard_loaded")})},this.loadDashboardFromLocalFile=function(){if(window.File&&window.FileReader&&window.FileList&&window.Blob){var e=document.createElement("input");e.type="file",$(e).on("change",function(e){var t=e.target.files;if(t&&t.length>0){var n=t[0],a=new FileReader;a.addEventListener("load",function(e){var t=e.target,n=JSON.parse(t.result);i.loadDashboard(n),i.setEditing(!1)}),a.readAsText(n)}}),$(e).trigger("click")}else alert("Unable to load a file in this browser.")},this.saveDashboard=function(){var e="application/octet-stream",t=document.createElement("a"),n=new Blob([JSON.stringify(i.serialize())],{type:e});document.body.appendChild(t),t.href=window.URL.createObjectURL(n),t.download="dashboard.json",t.target="_self",t.click()},this.addDatasource=function(e){i.datasources.push(e)},this.deleteDatasource=function(e){delete i.datasourceData[e.name()],e.dispose(),i.datasources.remove(e)},this.createPane=function(){var e=new PaneModel(i,t);i.addPane(e)},this.addPane=function(e){i.panes.push(e)},this.deletePane=function(e){e.dispose(),i.panes.remove(e)},this.deleteWidget=function(e){ko.utils.arrayForEach(i.panes(),function(t){t.widgets.remove(e)}),e.dispose()},this.setEditing=function(e,t){if(i.allow_edit()||!e){i.isEditing(e),_.isUndefined(t)&&(t=!0);var a=t?250:0,s=$("#admin-bar").outerHeight();e?($("#toggle-header-icon").addClass("icon-chevron-up").removeClass("icon-wrench"),$(".gridster .gs_w").css({cursor:"pointer"}),$("#main-header").animate({top:"0px"},a),$("#board-content").animate({top:s+20+"px"},a),$("#main-header").data().shown=!0,n.attachWidgetEditIcons($(".sub-section")),freeboard._enableGrid()):($("#toggle-header-icon").addClass("icon-wrench").removeClass("icon-chevron-up"),$(".gridster .gs_w").css({cursor:"default"}),$("#main-header").animate({top:"-"+s+"px"},a),$("#board-content").animate({top:"20"},a),$("#main-header").data().shown=!1,$(".sub-section").unbind(),freeboard._disableGrid()),n.showPaneEditIcons(e,t)}},this.toggleEditing=function(){var e=!i.isEditing();i.setEditing(e)}}function FreeboardUI(){function e(e){e?a.fadeOut(0).appendTo("body").fadeIn(500):a.fadeOut(500).remove()}function t(e,t){_.isUndefined(t)&&(t=!0);var n=t?250:0;e?$(".pane-tools").fadeIn(n):$(".pane-tools").fadeOut(n)}function n(e){$(e).hover(function(){i(this,!0)},function(){i(this,!1)})}function i(e,t){t?$(e).find(".sub-section-tools").fadeIn(250):$(e).find(".sub-section-tools").fadeOut(250)}var a=$('');return{showLoadingIndicator:function(t){e(t)},showPaneEditIcons:function(e,n){t(e,n)},attachWidgetEditIcons:function(e){n(e)}}}function PaneModel(e,t){var n=this;this.title=ko.observable(),this.width=ko.observable(1),this.row={},this.col={},this.col_width=ko.observable(1),this.widgets=ko.observableArray(),this.addWidget=function(e){this.widgets.push(e)},this.widgetCanMoveUp=function(e){return n.widgets.indexOf(e)>=1},this.widgetCanMoveDown=function(e){var t=n.widgets.indexOf(e);return n.widgets().length-1>t},this.moveWidgetUp=function(e){if(n.widgetCanMoveUp(e)){var t=n.widgets.indexOf(e),i=n.widgets();n.widgets.splice(t-1,2,i[t],i[t-1])}},this.moveWidgetDown=function(e){if(n.widgetCanMoveDown(e)){var t=n.widgets.indexOf(e),i=n.widgets();n.widgets.splice(t,2,i[t+1],i[t])}},this.getCalculatedHeight=function(){var e=_.reduce(n.widgets(),function(e,t){return e+t.height()},0);e*=6,e+=3,e*=10;var t=Math.ceil((e+20)/30);return Math.max(4,t)},this.serialize=function(){var e=[];return _.each(n.widgets(),function(t){e.push(t.serialize())}),{title:n.title(),width:n.width(),row:n.row,col:n.col,col_width:n.col_width(),widgets:e}},this.deserialize=function(i){n.title(i.title),n.width(i.width),n.row=i.row,n.col=i.col,n.col_width(i.col_width||1),_.each(i.widgets,function(i){var a=new WidgetModel(e,t);a.deserialize(i),n.widgets.push(a)})},this.dispose=function(){_.each(n.widgets(),function(e){e.dispose()})}}function WidgetModel(e,t){function n(){_.isUndefined(i.widgetInstance)||(_.isFunction(i.widgetInstance.onDispose)&&i.widgetInstance.onDispose(),i.widgetInstance=void 0)}var i=this;this.datasourceRefreshNotifications={},this.calculatedSettingScripts={},this.title=ko.observable(),this.fillSize=ko.observable(!1),this.type=ko.observable(),this.type.subscribe(function(e){function a(){s.newInstance(i.settings(),function(e){i.fillSize(s.fill_size===!0),i.widgetInstance=e,i.shouldRender(!0),i._heightUpdate.valueHasMutated()})}if(n(),e in t&&_.isFunction(t[e].newInstance)){var s=t[e];s.external_scripts?head.js(s.external_scripts.slice(0),a):a()}}),this.settings=ko.observable({}),this.settings.subscribe(function(e){!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.onSettingsChanged)&&i.widgetInstance.onSettingsChanged(e),i.updateCalculatedSettings(),i._heightUpdate.valueHasMutated()}),this.processDatasourceUpdate=function(e){var t=i.datasourceRefreshNotifications[e];_.isArray(t)&&_.each(t,function(e){i.processCalculatedSetting(e)})},this.callValueFunction=function(t){return t.call(void 0,e.datasourceData)},this.processCalculatedSetting=function(e){if(_.isFunction(i.calculatedSettingScripts[e])){var t=void 0;try{t=i.callValueFunction(i.calculatedSettingScripts[e])}catch(n){var a=i.settings()[e];n instanceof ReferenceError&&/^\w+$/.test(a)&&(t=a)}if(!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.onCalculatedValueChanged)&&!_.isUndefined(t))try{i.widgetInstance.onCalculatedValueChanged(e,t)}catch(n){console.log(""+n)}}},this.updateCalculatedSettings=function(){if(i.datasourceRefreshNotifications={},i.calculatedSettingScripts={},!_.isUndefined(i.type())){var e=t[i.type()].settings,n=RegExp("datasources.([\\w_-]+)|datasources\\[['\"]([^'\"]+)","g"),a=i.settings();_.each(e,function(e){if("calculated"==e.type){var t=a[e.name];if(!_.isUndefined(t)){1>=(t.match(/;/g)||[]).length&&-1==t.indexOf("return")&&(t="return "+t);var s;try{s=Function("datasources",t)}catch(o){var r=a[e.name].replace(/"/g,'\\"').replace(/[\r\n]/g," \\\n");s=Function("datasources",'return "'+r+'";')}i.calculatedSettingScripts[e.name]=s,i.processCalculatedSetting(e.name);for(var d;d=n.exec(t);){var l=d[1]||d[2],c=i.datasourceRefreshNotifications[l];_.isUndefined(c)&&(c=[],i.datasourceRefreshNotifications[l]=c),c.push(e.name)}}}})}},this._heightUpdate=ko.observable(),this.height=ko.computed({read:function(){return i._heightUpdate(),!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.getHeight)?i.widgetInstance.getHeight():1}}),this.shouldRender=ko.observable(!1),this.render=function(e){i.shouldRender(!1),!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.render)&&(i.widgetInstance.render(e),i.updateCalculatedSettings())},this.dispose=function(){},this.serialize=function(){return{title:i.title(),type:i.type(),settings:i.settings()}},this.deserialize=function(e){i.title(e.title),i.settings(e.settings),i.type(e.type)}}DatasourceModel=function(e,t){function n(){_.isUndefined(i.datasourceInstance)||(_.isFunction(i.datasourceInstance.onDispose)&&i.datasourceInstance.onDispose(),i.datasourceInstance=void 0)}var i=this;this.name=ko.observable(),this.latestData=ko.observable(),this.settings=ko.observable({}),this.settings.subscribe(function(e){!_.isUndefined(i.datasourceInstance)&&_.isFunction(i.datasourceInstance.onSettingsChanged)&&i.datasourceInstance.onSettingsChanged(e)}),this.updateCallback=function(t){e.processDatasourceUpdate(i,t),i.latestData(t);var n=new Date;i.last_updated(n.toLocaleTimeString())},this.type=ko.observable(),this.type.subscribe(function(e){function a(){s.newInstance(i.settings(),function(e){i.datasourceInstance=e,e.updateNow()},i.updateCallback)}if(n(),e in t&&_.isFunction(t[e].newInstance)){var s=t[e];s.external_scripts?head.js(s.external_scripts.slice(0),a):a()}}),this.last_updated=ko.observable("never"),this.last_error=ko.observable(),this.serialize=function(){return{name:i.name(),type:i.type(),settings:i.settings()}},this.deserialize=function(e){i.settings(e.settings),i.name(e.name),i.type(e.type)},this.getDataRepresentation=function(e){var t=Function("data","return "+e+";");return t.call(void 0,i.latestData())},this.updateNow=function(){!_.isUndefined(i.datasourceInstance)&&_.isFunction(i.datasourceInstance.updateNow)&&i.datasourceInstance.updateNow()},this.dispose=function(){n()}},DeveloperConsole=function(e){function t(){function t(e){var t=$(" "),i=$(''),a=$(' '),s=$(' ').click(function(){n=_.without(n,a),t.remove()});n.push(a),e&&a.val(e),i.append(s),o.append(t.append($(" ").append(a)).append($('').append(i)))}var n=[],i=$("
"),a=$('ADD
'),s=$('');s.append($('Plugin Script URL '));var o=$(" ");s.append(o),i.append($("Here you can add references to other scripts to load datasource or widget plugins.
")).append(s).append(a).append('To learn how to build plugins for freeboard, please visit http://freeboard.github.io/freeboard/docs/plugin_example.html
'),_.each(e.plugins(),function(e){t(e)}),a.click(function(){t()}),new DialogBox(i,"Developer Console","OK",null,function(){_.each(e.plugins(),function(e){$('script[src^="'+e+'"]').remove()}),e.plugins.removeAll(),_.each(n,function(t){var n=t.val();n&&n.length>0&&(e.addPluginSource(n),head.js(n+"?"+Date.now()))})})}return{showDeveloperConsole:function(){t()}}},JSEditor=function(){function e(e){n=e}function t(e,t){head.js(n+"css/codemirror.css",n+"css/codemirror-ambiance.css",n+"js/codemirror.js",function(){var n='// Example: Convert temp from C to F and truncate to 2 decimal places.\n// return (datasources["MyDatasource"].sensor.tempInF * 1.8 + 32).toFixed(2);';e||(e=n);var i=$('
'),a=$('
'),s=$(''),o=$('');i.append([o,a,s]),$("body").append(i);var r=CodeMirror(a.get(0),{value:e,mode:"javascript",theme:"ambiance",indentUnit:4,lineNumbers:!0,matchBrackets:!0,autoCloseBrackets:!0}),d=$('Close ').click(function(){if(t){var e=r.getValue();e===n&&(e=""),t(e),i.remove()}});s.append(d)})}var n="";return{displayJSEditor:function(e,n){t(e,n)},setAssetRoot:function(){e(_assetRoot)}}},PluginEditor=function(e,t){function n(e,t){var n=$('
').html(t);$("#setting-value-container-"+e).append(n)}function i(){$("#setting-row-instance-name").length?$("#setting-row-instance-name").nextAll().remove():$("#setting-row-plugin-types").nextAll().remove()}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function s(s,o,r,d,l){function c(e,t){var n=$('
').appendTo(h);return n.append(''+t+"
"),$('
').appendTo(n)}function u(n){_.each(n,function(n){function i(){f.settings[n.name].length>0?u.show():u.hide()}function a(e){var t=$(" ").appendTo(h),a={};_.isArray(f.settings[n.name])||(f.settings[n.name]=[]),f.settings[n.name].push(a),_.each(n.settings,function(n){var i=$(" ").appendTo(t),s="";_.isUndefined(e[n.name])||(s=e[n.name]),a[n.name]=s,$(' ').appendTo(i).val(s).change(function(){a[n.name]=$(this).val()})}),t.append($(' ').append($('').append($(" ").append($(' ').click(function(){var e=f.settings[n.name].indexOf(a);-1!=e&&(f.settings[n.name].splice(e,1),t.remove(),i())}))))),r.scrollTop(r[0].scrollHeight),i()}!_.isUndefined(n.default_value)&&_.isUndefined(d[n.name])&&(d[n.name]=n.default_value);var s=n.name;_.isUndefined(n.display_name)||(s=n.display_name);var o=c(n.name,s);switch(n.type){case"array":var r=$('
').appendTo(o),l=$('').appendTo(r),u=$(" ").hide().appendTo(l),p=$(" ").appendTo(u),h=$(" ").appendTo(l),g=[];_.each(n.settings,function(e){var t=e.name;_.isUndefined(e.display_name)||(t=e.display_name),$(""+t+" ").appendTo(p)}),n.name in d&&(g=d[n.name]),$('ADD
').appendTo(o).click(function(){var e={};_.each(n.settings,function(t){e[t.name]=""}),a(e)}),_.each(g,function(e){a(e)});break;case"boolean":f.settings[n.name]=d[n.name];var m=$('').appendTo(o),v=$(' ').prependTo(m).change(function(){f.settings[n.name]=this.checked});n.name in d&&v.prop("checked",d[n.name]);break;case"option":var y=d[n.name],v=$(" ").appendTo($('
').appendTo(o)).change(function(){f.settings[n.name]=$(this).val()});_.each(n.options,function(e){var t,n;_.isObject(e)?(t=e.name,n=e.value):t=e,_.isUndefined(n)&&(n=t),_.isUndefined(y)&&(y=n),$(" ").text(t).attr("value",n).appendTo(v)}),f.settings[n.name]=y,n.name in d&&v.val(d[n.name]);break;default:if(f.settings[n.name]=d[n.name],"calculated"==n.type){var v=$("").appendTo(o).change(function(){f.settings[n.name]=$(this).val()});n.name in d&&v.val(d[n.name]),t.createValueEditor(v);var w=$(''),b=$('DATASOURCE ').mousedown(function(e){e.preventDefault(),$(v).focus(),$(v).insertAtCaret('datasources["'),$(v).trigger("freeboard-eval")}),x=$('.JS EDITOR ').mousedown(function(t){t.preventDefault(),e.displayJSEditor(v.val(),function(e){v.val(e),v.change()})});$(o).append(w.append([b,x]))}else{var v=$(' ').appendTo(o).change(function(){f.settings[n.name]="number"==n.type?Number($(this).val()):$(this).val()});n.name in d&&v.val(d[n.name])}}_.isUndefined(n.suffix)||o.append($(''+n.suffix+"
")),_.isUndefined(n.description)||o.append($(''+n.description+"
"))})}var p,f={type:r,settings:{}},h=$("
"),g=$('
').hide();h.append(g),new DialogBox(h,s,"Save","Cancel",function(){$(".validation-error").remove();for(var e=0;p.settings.length>e;e++){var t=p.settings[e];if(t.required&&(_.isUndefined(f.settings[t.name])||""==f.settings[t.name]))return n(t.name,"This is required."),!0;if("number"==t.type&&!a(f.settings[t.name]))return n(t.name,"Must be a number."),!0}_.isFunction(l)&&l(f)});var m,v=_.keys(o);if(v.length>1){var y=c("plugin-types","Type");m=$(" ").appendTo($('
').appendTo(y)),m.append($("Select a type... ").attr("value","undefined")),_.each(o,function(e){m.append($(" ").text(e.display_name).attr("value",e.type_name))}),m.change(function(){f.type=$(this).val(),f.settings={},i(),p=o[m.val()],_.isUndefined(p)?($("#setting-row-instance-name").hide(),$("#dialog-ok").hide()):($("#setting-row-instance-name").show(),p.description&&p.description.length>0?g.html(p.description).show():g.hide(),$("#dialog-ok").show(),u(p.settings))})}else 1==v.length&&(p=o[v[0]],u(p.settings));m&&(_.isUndefined(r)?($("#setting-row-instance-name").hide(),$("#dialog-ok").hide()):($("#dialog-ok").show(),m.val(r).trigger("change")))}return{createPluginEditor:function(e,t,n,i,a,o){s(e,t,n,i,a,o)}}},ValueEditor=function(e){function t(e){var t=($(e).val().match(/\n/g)||[]).length,n=Math.min(200,20*(t+1));$(e).css({height:n+"px"})}function n(n){var a=null,s=0;$(n).addClass("calculated-value-input").bind("keyup mouseup freeboard-eval",function(t){if(a&&"keyup"==t.type&&(38==t.keyCode||40==t.keyCode||13==t.keyCode))return t.preventDefault(),void 0;var o=$(n).val().substring(0,$(n).getCaretPosition());o=o.replace(String.fromCharCode(160)," ");var r,d=i.exec(o),l=[];if(d)if(""==d[1])_.each(e.datasources(),function(e){l.push({value:e.name(),follow_char:'"].'})});else if(""!=d[1]&&_.isUndefined(d[2]))r=d[1],_.each(e.datasources(),function(e){var t=e.name();t!=r&&0==t.indexOf(r)&&l.push({value:t,follow_char:'"].'})});else{var c=_.find(e.datasources(),function(e){return e.name()===d[1]});if(!_.isUndefined(c)){var u="";_.isUndefined(d[2])||(u=d[2]);var p=u.split(".");u="data";for(var f=1;p.length-1>f;f++)""!=p[f]&&(u=u+"."+p[f]);var h=_.last(p);"["==h.charAt(h.length-1)&&(h=h.replace(/\[+$/,""),u=u+"."+h);var g=c.getDataRepresentation(u);if(_.isArray(g))for(var f=0;g.length>f;f++){var m="]";_.isObject(g[f])?m+=".":_.isArray(g[f])&&(m+="["),l.push({value:f,follow_char:m})}else _.isObject(g)&&(r=h,-1==_.keys(g).indexOf(r)&&_.each(g,function(e,t){if(t!=h&&0==t.indexOf(h)){var n=void 0;_.isArray(e)?n="[":_.isObject(e)&&(n="."),l.push({value:t,follow_char:n})}}))}}if(l.length>0){a||(a=$('').insertAfter(n).width($(n).outerWidth()-2).css("left",$(n).position().left).css("top",$(n).position().top+$(n).outerHeight()-1)),a.empty(),a.scrollTop(0);var v=!0;s=0;var y=0;_.each(l,function(e){var t=$(""+e.value+" ").appendTo(a).mouseenter(function(){$(this).trigger("freeboard-select")}).mousedown(function(e){$(this).trigger("freeboard-insertValue"),e.preventDefault()}).data("freeboard-optionIndex",y).data("freeboard-optionValue",e.value).bind("freeboard-insertValue",function(){var t=e.value;if(_.isUndefined(e.follow_char)||(t+=e.follow_char),_.isUndefined(r))$(n).insertAtCaret(t);else{var i=o.lastIndexOf(r);-1!=i&&$(n).replaceTextAt(i,i+r.length,t)}$(n).triggerHandler("mouseup")}).bind("freeboard-select",function(){$(this).parent().find("li.selected").removeClass("selected"),$(this).addClass("selected"),s=$(this).data("freeboard-optionIndex")});v&&($(t).addClass("selected"),v=!1),y++})}else $(n).next("ul#value-selector").remove(),a=null,s=-1}).focus(function(){t(n)}).focusout(function(){$(n).css({height:""}),$(n).next("ul#value-selector").remove(),a=null,s=-1}).bind("keydown",function(e){if(a)if(38==e.keyCode||40==e.keyCode){e.preventDefault();var t=$(a).find("li");38==e.keyCode?s--:40==e.keyCode&&s++,0>s?s=t.size()-1:s>=t.size()&&(s=0);var n=$(t).eq(s);n.trigger("freeboard-select"),$(a).scrollTop($(n).position().top)}else 13==e.keyCode&&(e.preventDefault(),-1!=s&&$(a).find("li").eq(s).trigger("freeboard-insertValue"))})}var i=RegExp('.*datasources\\["([^"]*)("\\].)?$');return{createValueEditor:function(e){n(e)}}},function(e){function t(){var e=document.createElement("p"),t=!1;if(e.addEventListener)e.addEventListener("DOMAttrModified",function(){t=!0},!1);else{if(!e.attachEvent)return!1;e.attachEvent("onDOMAttrModified",function(){t=!0})}return e.setAttribute("id","target"),t}function n(t,n){if(t){var i=this.data("attr-old-value");if(n.attributeName.indexOf("style")>=0){i.style||(i.style={});var a=n.attributeName.split(".");n.attributeName=a[0],n.oldValue=i.style[a[1]],n.newValue=a[1]+":"+this.prop("style")[e.camelCase(a[1])],i.style[a[1]]=n.newValue}else n.oldValue=i[n.attributeName],n.newValue=this.attr(n.attributeName),i[n.attributeName]=n.newValue;this.data("attr-old-value",i)}}var i=window.MutationObserver||window.WebKitMutationObserver;e.fn.attrchange=function(a){var s={trackValues:!1,callback:e.noop};if("function"==typeof a?s.callback=a:e.extend(s,a),s.trackValues&&e(this).each(function(t,n){for(var i,a={},t=0,s=n.attributes,o=s.length;o>t;t++)i=s.item(t),a[i.nodeName]=i.value;e(this).data("attr-old-value",a)}),i){var o={subtree:!1,attributes:!0,attributeOldValue:s.trackValues},r=new i(function(t){t.forEach(function(t){var n=t.target;s.trackValues&&(t.newValue=e(n).attr(t.attributeName)),s.callback.call(n,t)})});return this.each(function(){r.observe(this,o)})}return t()?this.on("DOMAttrModified",function(e){e.originalEvent&&(e=e.originalEvent),e.attributeName=e.attrName,e.oldValue=e.prevValue,s.callback.call(this,e)}):"onpropertychange"in document.body?this.on("propertychange",function(t){t.attributeName=window.event.propertyName,n.call(e(this),s.trackValues,t),s.callback.call(this,t)}):this}}(jQuery),function(e){e.eventEmitter={_JQInit:function(){this._JQ=e(this)},emit:function(e,t){!this._JQ&&this._JQInit(),this._JQ.trigger(e,t)},once:function(e,t){!this._JQ&&this._JQInit(),this._JQ.one(e,t)},on:function(e,t){!this._JQ&&this._JQInit(),this._JQ.bind(e,t)},off:function(e,t){!this._JQ&&this._JQInit(),this._JQ.unbind(e,t)}}}(jQuery);var freeboard=function(){function e(e){var t=a.$el;t.find("> li").unbind().removeData(),$(".gridster").css("width",""),a.generate_grid_and_stylesheet(),e&&t.find("> li").each(function(){var e=this,t=ko.dataFor(e),i=n(t);$(e).attr("data-row",i.row).attr("data-col",i.col)}),a.init(),$(".gridster").css("width",300*a.cols+20*a.cols)}function t(e,t,n){var i=a.cols;_.isUndefined(t)||(e.row[i]=t),_.isUndefined(n)||(e.col[i]=n)}function n(e,t){var n=_.isUndefined(t)?a.cols:t;if(_.isNumber(e.row)&&_.isNumber(e.col)){var i={};i[n]=e.row,e.row=i,i={},i[n]=e.col,e.col=i}var s=1,o=1e3;for(var r in e.col){if(r==n)return{row:e.row[r],col:e.col[r]};if(e.col[r]>n)s=n;else{var d=n-r;o>d&&(s=r,o=d)}}return s in e.col&&s in e.row?{row:e.row[s],col:e.col[s]}:{row:1,col:s}}function i(e){e=e.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var t=RegExp("[\\?&]"+e+"=([^]*)"),n=t.exec(location.search);return null==n?"":decodeURIComponent(n[1].replace(/\+/g," "))}var a,s=10,o=300,r={},d={},l=new FreeboardUI,c=new FreeboardModel(r,d,l),u=new JSEditor,p=new ValueEditor(c),f=new PluginEditor(u,p),h=new DeveloperConsole(c),g={values:{"font-family":'"HelveticaNeue-UltraLight", "Helvetica Neue Ultra Light", "Helvetica Neue", sans-serif',color:"#d3d4d4","font-weight":100}};return ko.bindingHandlers.pluginEditor={init:function(e,t,n,i){var a=ko.unwrap(t()),s={},o=void 0,u="";"datasource"==a.type?(s=r,u="Datasource"):"widget"==a.type?(s=d,u="Widget"):"pane"==a.type&&(u="Pane"),$(e).click(function(){if("delete"==a.operation){var t=$("Are you sure you want to delete this "+u+"?
");new DialogBox(t,"Confirm Delete","Yes","No",function(){"datasource"==a.type?c.deleteDatasource(i):"widget"==a.type?c.deleteWidget(i):"pane"==a.type&&c.deletePane(i)})}else{var n=void 0;"datasource"==a.type?"add"==a.operation?o={}:(n=i.type(),o=i.settings(),o.name=i.name()):"widget"==a.type?"add"==a.operation?o={}:(n=i.type(),o=i.settings()):"pane"==a.type&&(o={},"edit"==a.operation&&(o.title=i.title(),o.col_width=i.col_width()),s={settings:{settings:[{name:"title",display_name:"Title",type:"text"},{name:"col_width",display_name:"Columns",type:"number",default_value:1,required:!0}]}}),f.createPluginEditor(u,s,n,o,function(t){if("add"==a.operation){if("datasource"==a.type){var n=new DatasourceModel(c,r);c.addDatasource(n),n.name(t.settings.name),delete t.settings.name,n.settings(t.settings),n.type(t.type)}else if("widget"==a.type){var n=new WidgetModel(c,d);n.settings(t.settings),n.type(t.type),i.widgets.push(n),l.attachWidgetEditIcons(e)}}else"edit"==a.operation&&("pane"==a.type?(i.title(t.settings.title),i.col_width(t.settings.col_width)):("datasource"==a.type&&(i.name(t.settings.name),delete t.settings.name),i.type(t.type),i.settings(t.settings)))})}})}},ko.virtualElements.allowedBindings.datasourceTypeSettings=!0,ko.bindingHandlers.datasourceTypeSettings={update:function(e,t,n,i,a){processPluginSettings(e,t,n,i,a)}},ko.bindingHandlers.grid={init:function(t){a=$(t).gridster({widget_margins:[s,s],widget_base_dimensions:[o,10],resize:{enabled:!0,axes:"x"}}).data("gridster"),e(!1),a.disable()}},ko.bindingHandlers.pane={init:function(e,i,s,o,r){c.isEditing()&&$(e).css({cursor:"pointer"});var d=n(o),u=d.col,p=d.row,f=Number(o.width()),h=Number(o.getCalculatedHeight());a.add_widget(e,f,h,u,p),r.$root.isEditing()&&l.showPaneEditIcons(!0),t(o,p,u),$(e).attrchange({trackValues:!0,callback:function(e){"data-row"==e.attributeName?t(o,Number(e.newValue),void 0):"data-col"==e.attributeName&&t(o,void 0,Number(e.newValue))}})},update:function(e,t,n,i){-1==c.panes.indexOf(i)&&a.remove_widget(e);var s=i.getCalculatedHeight();(s!=Number($(e).attr("data-sizey"))||i.col_width()!=Number($(e).attr("data-sizex")))&&a.resize_widget($(e),i.col_width(),s,function(){a.set_dom_grid_height()})}},ko.bindingHandlers.widget={init:function(e){c.isEditing()&&l.attachWidgetEditIcons($(e).parent())},update:function(e,t,n,i){i.shouldRender()&&($(e).empty(),i.render(e))}},$(function(){function t(){e(!0)}l.showLoadingIndicator(!0);var n;$(window).resize(function(){clearTimeout(n),n=setTimeout(t,500)})}),{initialize:function(e,t){ko.applyBindings(c);var n=i("load");""!=n?$.ajax({url:n,success:function(e){c.loadDashboard(e),_.isFunction(t)&&t()}}):(c.allow_edit(e),c.setEditing(e),l.showLoadingIndicator(!1),_.isFunction(t)&&t(),freeboard.emit("initialized"))},newDashboard:function(){c.loadDashboard({allow_edit:!0})},loadDashboard:function(e,t){c.loadDashboard(e,t)},serialize:function(){return c.serialize()},setEditing:function(e,t){c.setEditing(e,t)},isEditing:function(){return c.isEditing()},loadDatasourcePlugin:function(e){_.isUndefined(e.display_name)&&(e.display_name=e.type_name),e.settings.unshift({name:"name",display_name:"Name",type:"text",required:!0}),c.addPluginSource(e.source),r[e.type_name]=e,c._datasourceTypes.valueHasMutated()},resize:function(){e(!0)},loadWidgetPlugin:function(e){_.isUndefined(e.display_name)&&(e.display_name=e.type_name),c.addPluginSource(e.source),d[e.type_name]=e,c._widgetTypes.valueHasMutated()},setAssetRoot:function(e){u.setAssetRoot(e)},addStyle:function(e,t){var n,i=document;"object"==typeof i.styleSheets&&(i.styleSheets.length&&(n=i.styleSheets[i.styleSheets.length-1]),i.styleSheets.length&&(i.createStyleSheet?n=i.createStyleSheet():(i.getElementsByTagName("head")[0].appendChild(i.createElement("style")),n=i.styleSheets[i.styleSheets.length-1])),n.addRule?n.addRule(e,t):n.insertRule(e+"{"+t+"}",n.cssRules.length))},showLoadingIndicator:function(e){l.showLoadingIndicator(e)},showDialog:function(e,t,n,i,a){new DialogBox(e,t,n,i,a)},getDatasourceSettings:function(e){var t=c.datasources(),n=_.find(t,function(t){return t.name()===e});return n?n.settings():null},setDatasourceSettings:function(e,t){var n=c.datasources(),i=_.find(n,function(t){return t.name()===e});if(!i)return console.log("Datasource not found"),void 0;var a=_.defaults(t,i.settings());i.settings(a)},getStyleString:function(e){var t="";return _.each(g[e],function(e,n){t=t+n+":"+e+";"}),t},getStyleObject:function(e){return g[e]},showDeveloperConsole:function(){h.showDeveloperConsole()},_removeAllWidgets:function(){a.remove_all_widgets()},_disableGrid:function(){a.disable()},_enableGrid:function(){a.enable()},_getPositionForScreenSize:function(e){return n(e)}}}();$.extend(freeboard,jQuery.eventEmitter),function(){var e=function(e,t){function n(e){a&&clearInterval(a),a=setInterval(function(){i.updateNow()},e)}var i=this,a=null,s=e;n(1e3*s.refresh),this.updateNow=function(){$.ajax({url:s.url,dataType:s.is_jsonp?"JSONP":"JSON",beforeSend:function(e){try{_.each(s.headers,function(t){var n=t.name,i=t.value;_.isUndefined(n)||_.isUndefined(i)||e.setRequestHeader(n,i)})}catch(t){}},success:function(e){t(e)},error:function(){}})},this.onDispose=function(){clearInterval(a),a=null},this.onSettingsChanged=function(e){s=e,n(1e3*s.refresh)}};freeboard.loadDatasourcePlugin({type_name:"JSON",settings:[{name:"url",display_name:"URL",type:"text"},{name:"refresh",display_name:"Refresh Every",type:"number",suffix:"seconds",default_value:5},{name:"is_jsonp",display_name:"Is JSONP",type:"boolean"},{name:"headers",display_name:"Headers",type:"array",settings:[{name:"name",display_name:"Name",type:"text"},{name:"value",display_name:"Value",type:"text"}]}],newInstance:function(t,n,i){n(new e(t,i))
+function DialogBox(e,t,n,i,a){function s(){o.fadeOut(200,function(){$(this).remove()})}var o=$('
'),r=$('
');r.append('"),$("").appendTo(r).append(e);var d=$("").appendTo(r);n&&$(''+n+" ").appendTo(d).click(function(){var e=!1;_.isFunction(a)&&(e=a()),e||s()}),i&&$(''+i+" ").appendTo(d).click(function(){s()}),o.append(r),$("body").append(o),o.fadeIn(200)}function FreeboardModel(e,t,n){var i=this,a=1;this.version=0,this.isEditing=ko.observable(!1),this.allow_edit=ko.observable(!1),this.allow_edit.subscribe(function(e){e?$("#main-header").show():$("#main-header").hide()}),this.header_image=ko.observable(),this.plugins=ko.observableArray(),this.datasources=ko.observableArray(),this.panes=ko.observableArray(),this.datasourceData={},this.processDatasourceUpdate=function(e,t){var n=e.name();i.datasourceData[n]=t,_.each(i.panes(),function(e){_.each(e.widgets(),function(e){e.processDatasourceUpdate(n)})})},this._datasourceTypes=ko.observable(),this.datasourceTypes=ko.computed({read:function(){i._datasourceTypes();var t=[];return _.each(e,function(e){var n=e.type_name,i=n;_.isUndefined(e.display_name)||(i=e.display_name),t.push({name:n,display_name:i})}),t}}),this._widgetTypes=ko.observable(),this.widgetTypes=ko.computed({read:function(){i._widgetTypes();var e=[];return _.each(t,function(t){var n=t.type_name,i=n;_.isUndefined(t.display_name)||(i=t.display_name),e.push({name:n,display_name:i})}),e}}),this.addPluginSource=function(e){e&&-1==i.plugins.indexOf(e)&&i.plugins.push(e)},this.serialize=function(){var e=[];_.each(i.panes(),function(t){e.push(t.serialize())});var t=[];return _.each(i.datasources(),function(e){t.push(e.serialize())}),{version:a,header_image:i.header_image(),allow_edit:i.allow_edit(),plugins:i.plugins(),panes:e,datasources:t}},this.deserialize=function(n,a){function s(){_.isUndefined(n.allow_edit)?i.allow_edit(!0):i.allow_edit(n.allow_edit),i.version=n.version||0,i.header_image(n.header_image),_.each(n.datasources,function(t){var n=new DatasourceModel(i,e);n.deserialize(t),i.addDatasource(n)});var s=_.sortBy(n.panes,function(e){return freeboard._getPositionForScreenSize(e).row});_.each(s,function(e){var n=new PaneModel(i,t);n.deserialize(e),i.panes.push(n)}),i.allow_edit()&&0==i.panes().length&&i.setEditing(!0),_.isFunction(a)&&a()}i.clearDashboard(),_.each(n.plugins,function(e){i.addPluginSource(e)}),_.isArray(n.plugins)&&n.plugins.length>0?head.js(n.plugins,function(){s()}):s()},this.clearDashboard=function(){freeboard._removeAllWidgets(),_.each(i.datasources(),function(e){e.dispose()}),_.each(i.panes(),function(e){e.dispose()}),i.plugins.removeAll(),i.datasources.removeAll(),i.panes.removeAll()},this.loadDashboard=function(e,t){n.showLoadingIndicator(!0),i.deserialize(e,function(){n.showLoadingIndicator(!1),_.isFunction(t)&&t(),freeboard.emit("dashboard_loaded")})},this.loadDashboardFromLocalFile=function(){if(window.File&&window.FileReader&&window.FileList&&window.Blob){var e=document.createElement("input");e.type="file",$(e).on("change",function(e){var t=e.target.files;if(t&&t.length>0){var n=t[0],a=new FileReader;a.addEventListener("load",function(e){var t=e.target,n=JSON.parse(t.result);i.loadDashboard(n),i.setEditing(!1)}),a.readAsText(n)}}),$(e).trigger("click")}else alert("Unable to load a file in this browser.")},this.saveDashboard=function(){var e="application/octet-stream",t=document.createElement("a"),n=new Blob([JSON.stringify(i.serialize())],{type:e});document.body.appendChild(t),t.href=window.URL.createObjectURL(n),t.download="dashboard.json",t.target="_self",t.click()},this.addDatasource=function(e){i.datasources.push(e)},this.deleteDatasource=function(e){delete i.datasourceData[e.name()],e.dispose(),i.datasources.remove(e)},this.createPane=function(){var e=new PaneModel(i,t);i.addPane(e)},this.addPane=function(e){i.panes.push(e)},this.deletePane=function(e){e.dispose(),i.panes.remove(e)},this.deleteWidget=function(e){ko.utils.arrayForEach(i.panes(),function(t){t.widgets.remove(e)}),e.dispose()},this.setEditing=function(e,t){if(i.allow_edit()||!e){i.isEditing(e),_.isUndefined(t)&&(t=!0);var a=t?250:0,s=$("#admin-bar").outerHeight();e?($("#toggle-header-icon").addClass("icon-chevron-up").removeClass("icon-wrench"),$(".gridster .gs_w").css({cursor:"pointer"}),$("#main-header").animate({top:"0px"},a),$("#board-content").animate({top:s+20+"px"},a),$("#main-header").data().shown=!0,n.attachWidgetEditIcons($(".sub-section")),freeboard._enableGrid()):($("#toggle-header-icon").addClass("icon-wrench").removeClass("icon-chevron-up"),$(".gridster .gs_w").css({cursor:"default"}),$("#main-header").animate({top:"-"+s+"px"},a),$("#board-content").animate({top:"20"},a),$("#main-header").data().shown=!1,$(".sub-section").unbind(),freeboard._disableGrid()),n.showPaneEditIcons(e,t)}},this.toggleEditing=function(){var e=!i.isEditing();i.setEditing(e)}}function FreeboardUI(){function e(e){e?a.fadeOut(0).appendTo("body").fadeIn(500):a.fadeOut(500).remove()}function t(e,t){_.isUndefined(t)&&(t=!0);var n=t?250:0;e?$(".pane-tools").fadeIn(n):$(".pane-tools").fadeOut(n)}function n(e){$(e).hover(function(){i(this,!0)},function(){i(this,!1)})}function i(e,t){t?$(e).find(".sub-section-tools").fadeIn(250):$(e).find(".sub-section-tools").fadeOut(250)}var a=$('');return{showLoadingIndicator:function(t){e(t)},showPaneEditIcons:function(e,n){t(e,n)},attachWidgetEditIcons:function(e){n(e)}}}function PaneModel(e,t){var n=this;this.title=ko.observable(),this.width=ko.observable(1),this.row={},this.col={},this.col_width=ko.observable(1),this.widgets=ko.observableArray(),this.addWidget=function(e){this.widgets.push(e)},this.widgetCanMoveUp=function(e){return n.widgets.indexOf(e)>=1},this.widgetCanMoveDown=function(e){var t=n.widgets.indexOf(e);return n.widgets().length-1>t},this.moveWidgetUp=function(e){if(n.widgetCanMoveUp(e)){var t=n.widgets.indexOf(e),i=n.widgets();n.widgets.splice(t-1,2,i[t],i[t-1])}},this.moveWidgetDown=function(e){if(n.widgetCanMoveDown(e)){var t=n.widgets.indexOf(e),i=n.widgets();n.widgets.splice(t,2,i[t+1],i[t])}},this.getCalculatedHeight=function(){var e=_.reduce(n.widgets(),function(e,t){return e+t.height()},0);e*=6,e+=3,e*=10;var t=Math.ceil((e+20)/30);return Math.max(4,t)},this.serialize=function(){var e=[];return _.each(n.widgets(),function(t){e.push(t.serialize())}),{title:n.title(),width:n.width(),row:n.row,col:n.col,col_width:n.col_width(),widgets:e}},this.deserialize=function(i){n.title(i.title),n.width(i.width),n.row=i.row,n.col=i.col,n.col_width(i.col_width||1),_.each(i.widgets,function(i){var a=new WidgetModel(e,t);a.deserialize(i),n.widgets.push(a)})},this.dispose=function(){_.each(n.widgets(),function(e){e.dispose()})}}function WidgetModel(e,t){function n(){_.isUndefined(i.widgetInstance)||(_.isFunction(i.widgetInstance.onDispose)&&i.widgetInstance.onDispose(),i.widgetInstance=void 0)}var i=this;this.datasourceRefreshNotifications={},this.calculatedSettingScripts={},this.title=ko.observable(),this.fillSize=ko.observable(!1),this.type=ko.observable(),this.type.subscribe(function(e){function a(){s.newInstance(i.settings(),function(e){i.fillSize(s.fill_size===!0),i.widgetInstance=e,i.shouldRender(!0),i._heightUpdate.valueHasMutated()})}if(n(),e in t&&_.isFunction(t[e].newInstance)){var s=t[e];s.external_scripts?head.js(s.external_scripts.slice(0),a):a()}}),this.settings=ko.observable({}),this.settings.subscribe(function(e){!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.onSettingsChanged)&&i.widgetInstance.onSettingsChanged(e),i.updateCalculatedSettings(),i._heightUpdate.valueHasMutated()}),this.processDatasourceUpdate=function(e){var t=i.datasourceRefreshNotifications[e];_.isArray(t)&&_.each(t,function(e){i.processCalculatedSetting(e)})},this.callValueFunction=function(t){return t.call(void 0,e.datasourceData)},this.processCalculatedSetting=function(e){if(_.isFunction(i.calculatedSettingScripts[e])){var t=void 0;try{t=i.callValueFunction(i.calculatedSettingScripts[e])}catch(n){var a=i.settings()[e];n instanceof ReferenceError&&/^\w+$/.test(a)&&(t=a)}if(!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.onCalculatedValueChanged)&&!_.isUndefined(t))try{i.widgetInstance.onCalculatedValueChanged(e,t)}catch(n){console.log(""+n)}}},this.updateCalculatedSettings=function(){if(i.datasourceRefreshNotifications={},i.calculatedSettingScripts={},!_.isUndefined(i.type())){var e=t[i.type()].settings,n=RegExp("datasources.([\\w_-]+)|datasources\\[['\"]([^'\"]+)","g"),a=i.settings();_.each(e,function(e){if("calculated"==e.type){var t=a[e.name];if(!_.isUndefined(t)){1>=(t.match(/;/g)||[]).length&&-1==t.indexOf("return")&&(t="return "+t);var s;try{s=Function("datasources",t)}catch(o){var r=a[e.name].replace(/"/g,'\\"').replace(/[\r\n]/g," \\\n");s=Function("datasources",'return "'+r+'";')}i.calculatedSettingScripts[e.name]=s,i.processCalculatedSetting(e.name);for(var d;d=n.exec(t);){var l=d[1]||d[2],c=i.datasourceRefreshNotifications[l];_.isUndefined(c)&&(c=[],i.datasourceRefreshNotifications[l]=c),c.push(e.name)}}}})}},this._heightUpdate=ko.observable(),this.height=ko.computed({read:function(){return i._heightUpdate(),!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.getHeight)?i.widgetInstance.getHeight():1}}),this.shouldRender=ko.observable(!1),this.render=function(e){i.shouldRender(!1),!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.render)&&(i.widgetInstance.render(e),i.updateCalculatedSettings())},this.dispose=function(){},this.serialize=function(){return{title:i.title(),type:i.type(),settings:i.settings()}},this.deserialize=function(e){i.title(e.title),i.settings(e.settings),i.type(e.type)}}DatasourceModel=function(e,t){function n(){_.isUndefined(i.datasourceInstance)||(_.isFunction(i.datasourceInstance.onDispose)&&i.datasourceInstance.onDispose(),i.datasourceInstance=void 0)}var i=this;this.name=ko.observable(),this.latestData=ko.observable(),this.settings=ko.observable({}),this.settings.subscribe(function(e){!_.isUndefined(i.datasourceInstance)&&_.isFunction(i.datasourceInstance.onSettingsChanged)&&i.datasourceInstance.onSettingsChanged(e)}),this.updateCallback=function(t){e.processDatasourceUpdate(i,t),i.latestData(t);var n=new Date;i.last_updated(n.toLocaleTimeString())},this.type=ko.observable(),this.type.subscribe(function(e){function a(){s.newInstance(i.settings(),function(e){i.datasourceInstance=e,e.updateNow()},i.updateCallback)}if(n(),e in t&&_.isFunction(t[e].newInstance)){var s=t[e];s.external_scripts?head.js(s.external_scripts.slice(0),a):a()}}),this.last_updated=ko.observable("never"),this.last_error=ko.observable(),this.serialize=function(){return{name:i.name(),type:i.type(),settings:i.settings()}},this.deserialize=function(e){i.settings(e.settings),i.name(e.name),i.type(e.type)},this.getDataRepresentation=function(e){var t=Function("data","return "+e+";");return t.call(void 0,i.latestData())},this.updateNow=function(){!_.isUndefined(i.datasourceInstance)&&_.isFunction(i.datasourceInstance.updateNow)&&i.datasourceInstance.updateNow()},this.dispose=function(){n()}},DeveloperConsole=function(e){function t(){function t(e){var t=$(" "),i=$(''),a=$(' '),s=$(' ').click(function(){n=_.without(n,a),t.remove()});n.push(a),e&&a.val(e),i.append(s),o.append(t.append($(" ").append(a)).append($('').append(i)))}var n=[],i=$("
"),a=$('ADD
'),s=$('');s.append($('Plugin Script URL '));var o=$(" ");s.append(o),i.append($("Here you can add references to other scripts to load datasource or widget plugins.
")).append(s).append(a).append('To learn how to build plugins for freeboard, please visit http://freeboard.github.io/freeboard/docs/plugin_example.html
'),_.each(e.plugins(),function(e){t(e)}),a.click(function(){t()}),new DialogBox(i,"Developer Console","OK",null,function(){_.each(e.plugins(),function(e){$('script[src^="'+e+'"]').remove()}),e.plugins.removeAll(),_.each(n,function(t){var n=t.val();n&&n.length>0&&(e.addPluginSource(n),head.js(n+"?"+Date.now()))})})}return{showDeveloperConsole:function(){t()}}},JSEditor=function(){function e(e){n=e}function t(e,t){head.js(n+"css/codemirror.css",n+"css/codemirror-ambiance.css",n+"js/codemirror.js",function(){var n='// Example: Convert temp from C to F and truncate to 2 decimal places.\n// return (datasources["MyDatasource"].sensor.tempInF * 1.8 + 32).toFixed(2);';e||(e=n);var i=$('
'),a=$('
'),s=$(''),o=$('');i.append([o,a,s]),$("body").append(i);var r=CodeMirror(a.get(0),{value:e,mode:"javascript",theme:"ambiance",indentUnit:4,lineNumbers:!0,matchBrackets:!0,autoCloseBrackets:!0}),d=$('Close ').click(function(){if(t){var e=r.getValue();e===n&&(e=""),t(e),i.remove()}});s.append(d)})}var n="";return{displayJSEditor:function(e,n){t(e,n)},setAssetRoot:function(){e(_assetRoot)}}},PluginEditor=function(e,t){function n(e,t){var n=$('
').html(t);$("#setting-value-container-"+e).append(n)}function i(){$("#setting-row-instance-name").length?$("#setting-row-instance-name").nextAll().remove():$("#setting-row-plugin-types").nextAll().remove()}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function s(s,o,r,d,l){function c(e,t){var n=$('
').appendTo(h);return n.append(''+t+"
"),$('
').appendTo(n)}function u(n){_.each(n,function(n){function i(){f.settings[n.name].length>0?u.show():u.hide()}function a(e){var t=$(" ").appendTo(h),a={};_.isArray(f.settings[n.name])||(f.settings[n.name]=[]),f.settings[n.name].push(a),_.each(n.settings,function(n){var i=$(" ").appendTo(t),s="";_.isUndefined(e[n.name])||(s=e[n.name]),a[n.name]=s,$(' ').appendTo(i).val(s).change(function(){a[n.name]=$(this).val()})}),t.append($(' ').append($('').append($(" ").append($(' ').click(function(){var e=f.settings[n.name].indexOf(a);-1!=e&&(f.settings[n.name].splice(e,1),t.remove(),i())}))))),r.scrollTop(r[0].scrollHeight),i()}!_.isUndefined(n.default_value)&&_.isUndefined(d[n.name])&&(d[n.name]=n.default_value);var s=n.name;_.isUndefined(n.display_name)||(s=n.display_name);var o=c(n.name,s);switch(n.type){case"array":var r=$('
').appendTo(o),l=$('').appendTo(r),u=$(" ").hide().appendTo(l),p=$(" ").appendTo(u),h=$(" ").appendTo(l),g=[];_.each(n.settings,function(e){var t=e.name;_.isUndefined(e.display_name)||(t=e.display_name),$(""+t+" ").appendTo(p)}),n.name in d&&(g=d[n.name]),$('ADD
').appendTo(o).click(function(){var e={};_.each(n.settings,function(t){e[t.name]=""}),a(e)}),_.each(g,function(e){a(e)});break;case"boolean":f.settings[n.name]=d[n.name];var m=$('').appendTo(o),v=$(' ').prependTo(m).change(function(){f.settings[n.name]=this.checked});n.name in d&&v.prop("checked",d[n.name]);break;case"option":var y=d[n.name],v=$(" ").appendTo($('
').appendTo(o)).change(function(){f.settings[n.name]=$(this).val()});_.each(n.options,function(e){var t,n;_.isObject(e)?(t=e.name,n=e.value):t=e,_.isUndefined(n)&&(n=t),_.isUndefined(y)&&(y=n),$(" ").text(t).attr("value",n).appendTo(v)}),f.settings[n.name]=y,n.name in d&&v.val(d[n.name]);break;default:if(f.settings[n.name]=d[n.name],"calculated"==n.type){var v=$("").appendTo(o).change(function(){f.settings[n.name]=$(this).val()});n.name in d&&v.val(d[n.name]),t.createValueEditor(v);var w=$(''),b=$('DATASOURCE ').mousedown(function(e){e.preventDefault(),$(v).focus(),$(v).insertAtCaret('datasources["'),$(v).trigger("freeboard-eval")}),x=$('.JS EDITOR ').mousedown(function(t){t.preventDefault(),e.displayJSEditor(v.val(),function(e){v.val(e),v.change()})});$(o).append(w.append([b,x]))}else{var v=$(' ').appendTo(o).change(function(){f.settings[n.name]="number"==n.type?Number($(this).val()):$(this).val()});n.name in d&&v.val(d[n.name])}}_.isUndefined(n.suffix)||o.append($(''+n.suffix+"
")),_.isUndefined(n.description)||o.append($(''+n.description+"
"))})}var p,f={type:r,settings:{}},h=$("
"),g=$('
').hide();h.append(g),new DialogBox(h,s,"Save","Cancel",function(){$(".validation-error").remove();for(var e=0;p.settings.length>e;e++){var t=p.settings[e];if(t.required&&(_.isUndefined(f.settings[t.name])||""==f.settings[t.name]))return n(t.name,"This is required."),!0;if("number"==t.type&&!a(f.settings[t.name]))return n(t.name,"Must be a number."),!0}_.isFunction(l)&&l(f)});var m,v=_.keys(o);if(v.length>1){var y=c("plugin-types","Type");m=$(" ").appendTo($('
').appendTo(y)),m.append($("Select a type... ").attr("value","undefined")),_.each(o,function(e){m.append($(" ").text(e.display_name).attr("value",e.type_name))}),m.change(function(){f.type=$(this).val(),f.settings={},i(),p=o[m.val()],_.isUndefined(p)?($("#setting-row-instance-name").hide(),$("#dialog-ok").hide()):($("#setting-row-instance-name").show(),p.description&&p.description.length>0?g.html(p.description).show():g.hide(),$("#dialog-ok").show(),u(p.settings))})}else 1==v.length&&(p=o[v[0]],u(p.settings));m&&(_.isUndefined(r)?($("#setting-row-instance-name").hide(),$("#dialog-ok").hide()):($("#dialog-ok").show(),m.val(r).trigger("change")))}return{createPluginEditor:function(e,t,n,i,a,o){s(e,t,n,i,a,o)}}},ValueEditor=function(e){function t(e){var t=($(e).val().match(/\n/g)||[]).length,n=Math.min(200,20*(t+1));$(e).css({height:n+"px"})}function n(e,t){var n,i=s.exec(e),r=[];if(i)if(""==i[1])_.each(t,function(e){r.push({value:e.name(),follow_char:'"]["'})});else if(""!=i[1]&&_.isUndefined(i[2]))n=i[1],_.each(t,function(e){var t=e.name();t!=n&&0==t.indexOf(n)&&r.push({value:t,follow_char:'"]["'})});else{var d=_.find(t,function(e){return e.name()===i[1]});if(!_.isUndefined(d)){var l="";_.isUndefined(i[2])||(l=i[2]+i[3]);var c=l.split('"]["');l="data";for(var u=1;c.length-1>u;u++)""!=c[u]&&(dataPathItem='["'+c[u]+'"]',l+=dataPathItem);var p=_.last(c);'"'==p.charAt(p.length-1)&&(p=p.replace(/\[\"?$/,""),l=l+'["'+p+'"]');var f=d.getDataRepresentation(l);if(_.isArray(f))for(var u=0;f.length>u;u++){var h='"]';_.isObject(f[u])?h+='"]["':_.isArray(f[u])&&(h+='"]['),r.push({value:u,follow_char:h})}else _.isObject(f)&&(n=p,-1==_.keys(f).indexOf(n)&&_.each(f,function(e,t){if(t!=p&&0==t.indexOf(p)){var n='"]';_.isArray(e)?n='"][':_.isObject(e)&&(n='"]["'),r.push({value:t,follow_char:n})}}))}}o=r,a=n}function i(i){var s=null,r=0;$(i).addClass("calculated-value-input").bind("keyup mouseup freeboard-eval",function(t){if(s&&"keyup"==t.type&&(38==t.keyCode||40==t.keyCode||13==t.keyCode))return t.preventDefault(),void 0;var d=$(i).val().substring(0,$(i).getCaretPosition());if(d=d.replace(String.fromCharCode(160)," "),n(d,e.datasources()),o.length>0){s||(s=$('').insertAfter(i).width($(i).outerWidth()-2).css("left",$(i).position().left).css("top",$(i).position().top+$(i).outerHeight()-1)),s.empty(),s.scrollTop(0);var l=!0;r=0;var c=0;_.each(o,function(e){var t=$(""+e.value+" ").appendTo(s).mouseenter(function(){$(this).trigger("freeboard-select")}).mousedown(function(e){$(this).trigger("freeboard-insertValue"),e.preventDefault()}).data("freeboard-optionIndex",c).data("freeboard-optionValue",e.value).bind("freeboard-insertValue",function(){var t=e.value;if(_.isUndefined(e.follow_char)||(t+=e.follow_char),_.isUndefined(a))$(i).insertAtCaret(t);else{var n=d.lastIndexOf(a);-1!=n&&$(i).replaceTextAt(n,n+a.length,t)}$(i).triggerHandler("mouseup")}).bind("freeboard-select",function(){$(this).parent().find("li.selected").removeClass("selected"),$(this).addClass("selected"),r=$(this).data("freeboard-optionIndex")});l&&($(t).addClass("selected"),l=!1),c++})}else $(i).next("ul#value-selector").remove(),s=null,r=-1}).focus(function(){t(i)}).focusout(function(){$(i).css({height:""}),$(i).next("ul#value-selector").remove(),s=null,r=-1}).bind("keydown",function(e){if(s)if(38==e.keyCode||40==e.keyCode){e.preventDefault();var t=$(s).find("li");38==e.keyCode?r--:40==e.keyCode&&r++,0>r?r=t.size()-1:r>=t.size()&&(r=0);var n=$(t).eq(r);n.trigger("freeboard-select"),$(s).scrollTop($(n).position().top)}else 13==e.keyCode&&(e.preventDefault(),-1!=r&&$(s).find("li").eq(r).trigger("freeboard-insertValue"))})}var a,s=RegExp('.*datasources\\["([^"]*)("\\]\\[")?(.*)$'),o=[];return{createValueEditor:function(e){i(e)}}},function(e){function t(){var e=document.createElement("p"),t=!1;if(e.addEventListener)e.addEventListener("DOMAttrModified",function(){t=!0},!1);else{if(!e.attachEvent)return!1;e.attachEvent("onDOMAttrModified",function(){t=!0})}return e.setAttribute("id","target"),t}function n(t,n){if(t){var i=this.data("attr-old-value");if(n.attributeName.indexOf("style")>=0){i.style||(i.style={});var a=n.attributeName.split(".");n.attributeName=a[0],n.oldValue=i.style[a[1]],n.newValue=a[1]+":"+this.prop("style")[e.camelCase(a[1])],i.style[a[1]]=n.newValue}else n.oldValue=i[n.attributeName],n.newValue=this.attr(n.attributeName),i[n.attributeName]=n.newValue;this.data("attr-old-value",i)}}var i=window.MutationObserver||window.WebKitMutationObserver;e.fn.attrchange=function(a){var s={trackValues:!1,callback:e.noop};if("function"==typeof a?s.callback=a:e.extend(s,a),s.trackValues&&e(this).each(function(t,n){for(var i,a={},t=0,s=n.attributes,o=s.length;o>t;t++)i=s.item(t),a[i.nodeName]=i.value;e(this).data("attr-old-value",a)}),i){var o={subtree:!1,attributes:!0,attributeOldValue:s.trackValues},r=new i(function(t){t.forEach(function(t){var n=t.target;s.trackValues&&(t.newValue=e(n).attr(t.attributeName)),s.callback.call(n,t)})});return this.each(function(){r.observe(this,o)})}return t()?this.on("DOMAttrModified",function(e){e.originalEvent&&(e=e.originalEvent),e.attributeName=e.attrName,e.oldValue=e.prevValue,s.callback.call(this,e)}):"onpropertychange"in document.body?this.on("propertychange",function(t){t.attributeName=window.event.propertyName,n.call(e(this),s.trackValues,t),s.callback.call(this,t)}):this}}(jQuery),function(e){e.eventEmitter={_JQInit:function(){this._JQ=e(this)},emit:function(e,t){!this._JQ&&this._JQInit(),this._JQ.trigger(e,t)},once:function(e,t){!this._JQ&&this._JQInit(),this._JQ.one(e,t)},on:function(e,t){!this._JQ&&this._JQInit(),this._JQ.bind(e,t)},off:function(e,t){!this._JQ&&this._JQInit(),this._JQ.unbind(e,t)}}}(jQuery);var freeboard=function(){function e(e){var t=a.$el;t.find("> li").unbind().removeData(),$(".gridster").css("width",""),a.generate_grid_and_stylesheet(),e&&t.find("> li").each(function(){var e=this,t=ko.dataFor(e),i=n(t);$(e).attr("data-row",i.row).attr("data-col",i.col)}),a.init(),$(".gridster").css("width",300*a.cols+20*a.cols)}function t(e,t,n){var i=a.cols;_.isUndefined(t)||(e.row[i]=t),_.isUndefined(n)||(e.col[i]=n)}function n(e,t){var n=_.isUndefined(t)?a.cols:t;if(_.isNumber(e.row)&&_.isNumber(e.col)){var i={};i[n]=e.row,e.row=i,i={},i[n]=e.col,e.col=i}var s=1,o=1e3;for(var r in e.col){if(r==n)return{row:e.row[r],col:e.col[r]};if(e.col[r]>n)s=n;else{var d=n-r;o>d&&(s=r,o=d)}}return s in e.col&&s in e.row?{row:e.row[s],col:e.col[s]}:{row:1,col:s}}function i(e){e=e.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var t=RegExp("[\\?&]"+e+"=([^]*)"),n=t.exec(location.search);return null==n?"":decodeURIComponent(n[1].replace(/\+/g," "))}var a,s=10,o=300,r={},d={},l=new FreeboardUI,c=new FreeboardModel(r,d,l),u=new JSEditor,p=new ValueEditor(c),f=new PluginEditor(u,p),h=new DeveloperConsole(c),g={values:{"font-family":'"HelveticaNeue-UltraLight", "Helvetica Neue Ultra Light", "Helvetica Neue", sans-serif',color:"#d3d4d4","font-weight":100}};return ko.bindingHandlers.pluginEditor={init:function(e,t,n,i){var a=ko.unwrap(t()),s={},o=void 0,u="";"datasource"==a.type?(s=r,u="Datasource"):"widget"==a.type?(s=d,u="Widget"):"pane"==a.type&&(u="Pane"),$(e).click(function(){if("delete"==a.operation){var t=$("Are you sure you want to delete this "+u+"?
");new DialogBox(t,"Confirm Delete","Yes","No",function(){"datasource"==a.type?c.deleteDatasource(i):"widget"==a.type?c.deleteWidget(i):"pane"==a.type&&c.deletePane(i)})}else{var n=void 0;"datasource"==a.type?"add"==a.operation?o={}:(n=i.type(),o=i.settings(),o.name=i.name()):"widget"==a.type?"add"==a.operation?o={}:(n=i.type(),o=i.settings()):"pane"==a.type&&(o={},"edit"==a.operation&&(o.title=i.title(),o.col_width=i.col_width()),s={settings:{settings:[{name:"title",display_name:"Title",type:"text"},{name:"col_width",display_name:"Columns",type:"number",default_value:1,required:!0}]}}),f.createPluginEditor(u,s,n,o,function(t){if("add"==a.operation){if("datasource"==a.type){var n=new DatasourceModel(c,r);c.addDatasource(n),n.name(t.settings.name),delete t.settings.name,n.settings(t.settings),n.type(t.type)}else if("widget"==a.type){var n=new WidgetModel(c,d);n.settings(t.settings),n.type(t.type),i.widgets.push(n),l.attachWidgetEditIcons(e)}}else"edit"==a.operation&&("pane"==a.type?(i.title(t.settings.title),i.col_width(t.settings.col_width)):("datasource"==a.type&&(i.name(t.settings.name),delete t.settings.name),i.type(t.type),i.settings(t.settings)))})}})}},ko.virtualElements.allowedBindings.datasourceTypeSettings=!0,ko.bindingHandlers.datasourceTypeSettings={update:function(e,t,n,i,a){processPluginSettings(e,t,n,i,a)}},ko.bindingHandlers.grid={init:function(t){a=$(t).gridster({widget_margins:[s,s],widget_base_dimensions:[o,10],resize:{enabled:!0,axes:"x"}}).data("gridster"),e(!1),a.disable()}},ko.bindingHandlers.pane={init:function(e,i,s,o,r){c.isEditing()&&$(e).css({cursor:"pointer"});var d=n(o),u=d.col,p=d.row,f=Number(o.width()),h=Number(o.getCalculatedHeight());a.add_widget(e,f,h,u,p),r.$root.isEditing()&&l.showPaneEditIcons(!0),t(o,p,u),$(e).attrchange({trackValues:!0,callback:function(e){"data-row"==e.attributeName?t(o,Number(e.newValue),void 0):"data-col"==e.attributeName&&t(o,void 0,Number(e.newValue))}})},update:function(e,t,n,i){-1==c.panes.indexOf(i)&&a.remove_widget(e);var s=i.getCalculatedHeight();(s!=Number($(e).attr("data-sizey"))||i.col_width()!=Number($(e).attr("data-sizex")))&&a.resize_widget($(e),i.col_width(),s,function(){a.set_dom_grid_height()})}},ko.bindingHandlers.widget={init:function(e){c.isEditing()&&l.attachWidgetEditIcons($(e).parent())},update:function(e,t,n,i){i.shouldRender()&&($(e).empty(),i.render(e))}},$(function(){function t(){e(!0)}l.showLoadingIndicator(!0);var n;$(window).resize(function(){clearTimeout(n),n=setTimeout(t,500)})}),{initialize:function(e,t){ko.applyBindings(c);var n=i("load");""!=n?$.ajax({url:n,success:function(e){c.loadDashboard(e),_.isFunction(t)&&t()}}):(c.allow_edit(e),c.setEditing(e),l.showLoadingIndicator(!1),_.isFunction(t)&&t(),freeboard.emit("initialized"))},newDashboard:function(){c.loadDashboard({allow_edit:!0})},loadDashboard:function(e,t){c.loadDashboard(e,t)},serialize:function(){return c.serialize()},setEditing:function(e,t){c.setEditing(e,t)},isEditing:function(){return c.isEditing()},loadDatasourcePlugin:function(e){_.isUndefined(e.display_name)&&(e.display_name=e.type_name),e.settings.unshift({name:"name",display_name:"Name",type:"text",required:!0}),c.addPluginSource(e.source),r[e.type_name]=e,c._datasourceTypes.valueHasMutated()},resize:function(){e(!0)},loadWidgetPlugin:function(e){_.isUndefined(e.display_name)&&(e.display_name=e.type_name),c.addPluginSource(e.source),d[e.type_name]=e,c._widgetTypes.valueHasMutated()},setAssetRoot:function(e){u.setAssetRoot(e)},addStyle:function(e,t){var n,i=document;"object"==typeof i.styleSheets&&(i.styleSheets.length&&(n=i.styleSheets[i.styleSheets.length-1]),i.styleSheets.length&&(i.createStyleSheet?n=i.createStyleSheet():(i.getElementsByTagName("head")[0].appendChild(i.createElement("style")),n=i.styleSheets[i.styleSheets.length-1])),n.addRule?n.addRule(e,t):n.insertRule(e+"{"+t+"}",n.cssRules.length))},showLoadingIndicator:function(e){l.showLoadingIndicator(e)},showDialog:function(e,t,n,i,a){new DialogBox(e,t,n,i,a)},getDatasourceSettings:function(e){var t=c.datasources(),n=_.find(t,function(t){return t.name()===e});return n?n.settings():null},setDatasourceSettings:function(e,t){var n=c.datasources(),i=_.find(n,function(t){return t.name()===e});if(!i)return console.log("Datasource not found"),void 0;var a=_.defaults(t,i.settings());i.settings(a)},getStyleString:function(e){var t="";return _.each(g[e],function(e,n){t=t+n+":"+e+";"}),t},getStyleObject:function(e){return g[e]},showDeveloperConsole:function(){h.showDeveloperConsole()},_removeAllWidgets:function(){a.remove_all_widgets()},_disableGrid:function(){a.disable()},_enableGrid:function(){a.enable()},_getPositionForScreenSize:function(e){return n(e)}}}();$.extend(freeboard,jQuery.eventEmitter),function(){var e=function(e,t){function n(e){a&&clearInterval(a),a=setInterval(function(){i.updateNow()},e)}var i=this,a=null,s=e;n(1e3*s.refresh),this.updateNow=function(){$.ajax({url:s.url,dataType:s.is_jsonp?"JSONP":"JSON",beforeSend:function(e){try{_.each(s.headers,function(t){var n=t.name,i=t.value;_.isUndefined(n)||_.isUndefined(i)||e.setRequestHeader(n,i)})}catch(t){}},success:function(e){t(e)},error:function(){}})},this.onDispose=function(){clearInterval(a),a=null},this.onSettingsChanged=function(e){s=e,n(1e3*s.refresh)}};freeboard.loadDatasourcePlugin({type_name:"JSON",settings:[{name:"url",display_name:"URL",type:"text"},{name:"refresh",display_name:"Refresh Every",type:"number",suffix:"seconds",default_value:5},{name:"is_jsonp",display_name:"Is JSONP",type:"boolean"},{name:"headers",display_name:"Headers",type:"array",settings:[{name:"name",display_name:"Name",type:"text"},{name:"value",display_name:"Value",type:"text"}]}],newInstance:function(t,n,i){n(new e(t,i))
}});var t=function(e,t){function n(e){s&&clearInterval(s),s=setInterval(function(){a.updateNow()},e)}function i(e){return e.replace(/\w\S*/g,function(e){return e.charAt(0).toUpperCase()+e.substr(1).toLowerCase()})}var a=this,s=null,o=e;n(1e3*o.refresh),this.updateNow=function(){$.ajax({url:"http://api.openweathermap.org/data/2.5/weather?q="+encodeURIComponent(o.location)+"&units="+o.units,dataType:"JSONP",success:function(e){var n={place_name:e.name,sunrise:new Date(1e3*e.sys.sunrise).toLocaleTimeString(),sunset:new Date(1e3*e.sys.sunset).toLocaleTimeString(),conditions:i(e.weather[0].description),current_temp:e.main.temp,high_temp:e.main.temp_max,low_temp:e.main.temp_min,pressure:e.main.pressure,humidity:e.main.humidity,wind_speed:e.wind.speed,wind_direction:e.wind.deg};t(n)},error:function(){}})},this.onDispose=function(){clearInterval(s),s=null},this.onSettingsChanged=function(e){o=e,a.updateNow(),n(1e3*o.refresh)}};freeboard.loadDatasourcePlugin({type_name:"openweathermap",display_name:"Open Weather Map API",settings:[{name:"location",display_name:"Location",type:"text",description:"Example: London, UK"},{name:"units",display_name:"Units",type:"option","default":"imperial",options:[{name:"Imperial",value:"imperial"},{name:"Metric",value:"metric"}]},{name:"refresh",display_name:"Refresh Every",type:"number",suffix:"seconds",default_value:5}],newInstance:function(e,n,i){n(new t(e,i))}});var n=function(e,t){function n(e){t(e)}var i=this,a=e;this.updateNow=function(){dweetio.get_latest_dweet_for(a.thing_id,function(e,t){e||n(t[0].content)})},this.onDispose=function(){},this.onSettingsChanged=function(e){dweetio.stop_listening(),a=e,dweetio.listen_for(a.thing_id,function(e){n(e.content)})},i.onSettingsChanged(e)};freeboard.loadDatasourcePlugin({type_name:"dweet_io",display_name:"Dweet.io",external_scripts:["http://dweet.io/client/dweet.io.min.js"],settings:[{name:"thing_id",display_name:"Thing Name",description:"Example: salty-dog-1",type:"text"}],newInstance:function(e,t,i){t(new n(e,i))}});var i=function(e,t){function n(){r.length>0?(r.length>d&&(t(r[d]),d++),d>=r.length&&o.loop&&(d=0),r.length>d&&(a=setTimeout(n,1e3*o.refresh))):t({})}function i(){r=[],d=0,a&&(clearTimeout(a),a=null)}var a,s=this,o=e,r=[],d=0;this.updateNow=function(){i(),$.ajax({url:o.datafile,dataType:o.is_jsonp?"JSONP":"JSON",success:function(e){r=_.isArray(e)?e:[],d=0,n()},error:function(){}})},this.onDispose=function(){i()},this.onSettingsChanged=function(e){o=e,s.updateNow()}};freeboard.loadDatasourcePlugin({type_name:"playback",display_name:"Playback",settings:[{name:"datafile",display_name:"Data File URL",type:"text",description:"A link to a JSON array of data."},{name:"is_jsonp",display_name:"Is JSONP",type:"boolean"},{name:"loop",display_name:"Loop",type:"boolean",description:"Rewind and loop when finished"},{name:"refresh",display_name:"Refresh Every",type:"number",suffix:"seconds",default_value:5}],newInstance:function(e,t,n){t(new i(e,n))}});var a=function(e,t){function n(){a&&(clearTimeout(a),a=null)}function i(){n(),a=setInterval(s.updateNow,1e3*o.refresh)}var a,s=this,o=e;this.updateNow=function(){var e=new Date,n={numeric_value:e.getTime(),full_string_value:e.toLocaleString(),date_string_value:e.toLocaleDateString(),time_string_value:e.toLocaleTimeString(),date_object:e};t(n)},this.onDispose=function(){n()},this.onSettingsChanged=function(e){o=e,i()},i()};freeboard.loadDatasourcePlugin({type_name:"clock",display_name:"Clock",settings:[{name:"refresh",display_name:"Refresh Every",type:"number",suffix:"seconds",default_value:1}],newInstance:function(e,t,n){t(new a(e,n))}})}(),function(){function e(e,t,n,i){if(e!=t)if($.isNumeric(t)&&$.isNumeric(e)){var a=(""+t).split("."),s=0;a.length>1&&(s=a[1].length),a=(""+e).split(".");var o=0;a.length>1&&(o=a[1].length),jQuery({transitionValue:Number(e),precisionValue:o}).animate({transitionValue:Number(t),precisionValue:s},{duration:i,step:function(){$(n).text(this.transitionValue.toFixed(this.precisionValue))},done:function(){$(n).text(t)}})}else $(n).text(t)}function t(e,t){var i=$(e).data().values;i||(i=[]),i.length>=n&&i.shift(),i.push(Number(t)),$(e).data().values=i,$(e).sparkline(i,{type:"line",height:"100%",width:"100%",fillColor:!1,lineColor:"#FF9900",lineWidth:2,spotRadius:3,spotColor:!1,minSpotColor:"#78AB49",maxSpotColor:"#78AB49",highlightSpotColor:"#9D3926",highlightLineColor:"#9D3926"})}var n=100,i=freeboard.getStyleString("values");i+="overflow: hidden;text-overflow: ellipsis;display: inline;",freeboard.addStyle(".text-widget-unit","padding-left: 5px;display:inline;"),freeboard.addStyle(".text-widget-regular-value",i+"font-size:30px;"),freeboard.addStyle(".text-widget-big-value",i+"font-size:75px;"),freeboard.addStyle(".gauge-widget-wrapper","width: 100%;text-align: center;"),freeboard.addStyle(".gauge-widget","width:200px;height:160px;display:inline-block;"),freeboard.addStyle(".sparkline","width:100%;height: 75px;"),freeboard.addStyle(".sparkline-inline","width:50%;float:right;height:30px;"),freeboard.addStyle(".indicator-light","border-radius:50%;width:22px;height:22px;border:2px solid #3d3d3d;margin-top:5px;float:left;background-color:#222;margin-right:10px;"),freeboard.addStyle(".indicator-light.on","background-color:#FFC773;box-shadow: 0px 0px 15px #FF9900;border-color:#FDF1DF;"),freeboard.addStyle(".indicator-text","margin-top:10px;"),freeboard.addStyle("div.pointer-value","position:absolute;height:95px;margin: auto;top: 0px;bottom: 0px;width: 100%;text-align:center;");var a=function(n){var i,a=n,s=$(' '),o=$("
"),r=$('
'),d=$(' ');this.render=function(e){$(e).append(s).append(o).append(r).append(d)},this.onSettingsChanged=function(e){a=e,s.html(_.isUndefined(e.title)?"":e.title),o.toggleClass("text-widget-regular-value","regular"==e.size).toggleClass("text-widget-big-value","big"==e.size),r.html(_.isUndefined(e.units)?"":e.units),e.sparkline?d.show():(delete d.data().values,d.empty(),d.hide())},this.onCalculatedValueChanged=function(n,s){"value"==n&&(a.animate?e(i,s,o,500):o.text(s),a.sparkline&&t(d,s),i=s)},this.onDispose=function(){},this.getHeight=function(){return"big"==a.size?2:1},this.onSettingsChanged(n)};freeboard.loadWidgetPlugin({type_name:"text_widget",display_name:"Text",external_scripts:["plugins/thirdparty/jquery.sparkline.min.js"],settings:[{name:"title",display_name:"Title",type:"text"},{name:"size",display_name:"Size",type:"option",options:[{name:"Regular",value:"regular"},{name:"Big",value:"big"}]},{name:"value",display_name:"Value",type:"calculated"},{name:"sparkline",display_name:"Include Sparkline",type:"boolean"},{name:"animate",display_name:"Animate Value Changes",type:"boolean",default_value:!0},{name:"units",display_name:"Units",type:"text"}],newInstance:function(e,t){t(new a(e))}});var s=0,o=function(e){function t(){r&&(o.empty(),n=new JustGage({id:i,value:_.isUndefined(d.min_value)?0:d.min_value,min:_.isUndefined(d.min_value)?0:d.min_value,max:_.isUndefined(d.max_value)?0:d.max_value,label:d.units,showInnerShadow:!1,valueFontColor:"#d3d4d4"}))}var n,i="gauge-"+s++,a=$(' '),o=$('
'),r=!1,d=e;this.render=function(e){r=!0,$(e).append(a).append($('
').append(o)),t()},this.onSettingsChanged=function(e){e.min_value!=d.min_value||e.max_value!=d.max_value||e.units!=d.units?(d=e,t()):d=e,a.html(e.title)},this.onCalculatedValueChanged=function(e,t){_.isUndefined(n)||n.refresh(Number(t))},this.onDispose=function(){},this.getHeight=function(){return 3},this.onSettingsChanged(e)};freeboard.loadWidgetPlugin({type_name:"gauge",display_name:"Gauge",external_scripts:["plugins/thirdparty/raphael.2.1.0.min.js","plugins/thirdparty/justgage.1.0.1.js"],settings:[{name:"title",display_name:"Title",type:"text"},{name:"value",display_name:"Value",type:"calculated"},{name:"units",display_name:"Units",type:"text"},{name:"min_value",display_name:"Minimum",type:"text",default_value:0},{name:"max_value",display_name:"Maximum",type:"text",default_value:100}],newInstance:function(e,t){t(new o(e))}});var r=function(e){var n=$(' '),i=$('
');this.render=function(e){$(e).append(n).append(i)},this.onSettingsChanged=function(e){n.html(_.isUndefined(e.title)?"":e.title)},this.onCalculatedValueChanged=function(e,n){t(i,n)},this.onDispose=function(){},this.getHeight=function(){return 2},this.onSettingsChanged(e)};freeboard.loadWidgetPlugin({type_name:"sparkline",display_name:"Sparkline",external_scripts:["plugins/thirdparty/jquery.sparkline.min.js"],settings:[{name:"title",display_name:"Title",type:"text"},{name:"value",display_name:"Value",type:"calculated"}],newInstance:function(e,t){t(new r(e))}});var d=function(e){function t(e){if(!e||2>e.length)return[];var t=[];t.push(["m",e[0],e[1]]);for(var n=2;e.length>n;n+=2)t.push(["l",e[n],e[n+1]]);return t.push(["z"]),t}var n,i,a,s,o=3,r=0,d=$('
'),l=$("
");this.render=function(e){a=$(e).width(),s=$(e).height();var r=Math.min(a,s)/2-2*o;n=Raphael($(e).get()[0],a,s);var c=n.circle(a/2,s/2,r);c.attr("stroke","#FF9900"),c.attr("stroke-width",o),i=n.path(t([a/2,s/2-r+o,15,20,-30,0])),i.attr("stroke-width",0),i.attr("fill","#fff"),$(e).append($('
').append(d).append(l))},this.onSettingsChanged=function(e){l.html(e.units)},this.onCalculatedValueChanged=function(e,t){if("direction"==e){if(!_.isUndefined(i)){i.animate({transform:"r"+t+","+a/2+","+s/2},250,"bounce")}r=t}else"value_text"==e&&d.html(t)},this.onDispose=function(){},this.getHeight=function(){return 4},this.onSettingsChanged(e)};freeboard.loadWidgetPlugin({type_name:"pointer",display_name:"Pointer",external_scripts:["plugins/thirdparty/raphael.2.1.0.min.js"],settings:[{name:"direction",display_name:"Direction",type:"calculated",description:"In degrees"},{name:"value_text",display_name:"Value Text",type:"calculated"},{name:"units",display_name:"Units",type:"text"}],newInstance:function(e,t){t(new d(e))}});var l=function(e){function t(){a&&(clearInterval(a),a=null)}function n(){if(i&&s){var e=s+(-1==s.indexOf("?")?"?":"&")+Date.now();$(i).css({"background-image":"url("+e+")"})}}var i,a,s;this.render=function(e){$(e).css({width:"100%",height:"100%","background-size":"cover","background-position":"center"}),i=e},this.onSettingsChanged=function(e){t(),e.refresh&&e.refresh>0&&(a=setInterval(n,1e3*Number(e.refresh)))},this.onCalculatedValueChanged=function(e,t){"src"==e&&(s=t),n()},this.onDispose=function(){t()},this.getHeight=function(){return 4},this.onSettingsChanged(e)};freeboard.loadWidgetPlugin({type_name:"picture",display_name:"Picture",fill_size:!0,settings:[{name:"src",display_name:"Image URL",type:"calculated"},{type:"number",display_name:"Refresh every",name:"refresh",suffix:"seconds",description:"Leave blank if the image doesn't need to be refreshed"}],newInstance:function(e,t){t(new l(e))}});var c=function(e){function t(){a.toggleClass("on",o),o?i.text(_.isUndefined(s.on_text)?"":s.on_text):i.text(_.isUndefined(s.off_text)?"":s.off_text)}var n=$(' '),i=$('
'),a=$('
'),s=e,o=!1;this.render=function(e){$(e).append(n).append(a).append(i)},this.onSettingsChanged=function(e){s=e,n.html(_.isUndefined(e.title)?"":e.title),t()},this.onCalculatedValueChanged=function(e,n){"value"==e&&(o=Boolean(n)),t()},this.onDispose=function(){},this.getHeight=function(){return 1},this.onSettingsChanged(e)};freeboard.loadWidgetPlugin({type_name:"indicator",display_name:"Indicator Light",settings:[{name:"title",display_name:"Title",type:"text"},{name:"value",display_name:"Value",type:"calculated"},{name:"on_text",display_name:"On Text",type:"calculated"},{name:"off_text",display_name:"Off Text",type:"calculated"}],newInstance:function(e,t){t(new c(e))}}),freeboard.addStyle(".gm-style-cc a","text-shadow:none;");var u=function(e){function t(){if(n&&i&&s.lat&&s.lon){var e=new google.maps.LatLng(s.lat,s.lon);i.setPosition(e),n.panTo(e)}}var n,i,a=e,s={};this.render=function(e){function a(){var a={zoom:13,center:new google.maps.LatLng(37.235,-115.811111),disableDefaultUI:!0,draggable:!1,styles:[{featureType:"water",elementType:"geometry",stylers:[{color:"#2a2a2a"}]},{featureType:"landscape",elementType:"geometry",stylers:[{color:"#000000"},{lightness:20}]},{featureType:"road.highway",elementType:"geometry.fill",stylers:[{color:"#000000"},{lightness:17}]},{featureType:"road.highway",elementType:"geometry.stroke",stylers:[{color:"#000000"},{lightness:29},{weight:.2}]},{featureType:"road.arterial",elementType:"geometry",stylers:[{color:"#000000"},{lightness:18}]},{featureType:"road.local",elementType:"geometry",stylers:[{color:"#000000"},{lightness:16}]},{featureType:"poi",elementType:"geometry",stylers:[{color:"#000000"},{lightness:21}]},{elementType:"labels.text.stroke",stylers:[{visibility:"on"},{color:"#000000"},{lightness:16}]},{elementType:"labels.text.fill",stylers:[{saturation:36},{color:"#000000"},{lightness:40}]},{elementType:"labels.icon",stylers:[{visibility:"off"}]},{featureType:"transit",elementType:"geometry",stylers:[{color:"#000000"},{lightness:19}]},{featureType:"administrative",elementType:"geometry.fill",stylers:[{color:"#000000"},{lightness:20}]},{featureType:"administrative",elementType:"geometry.stroke",stylers:[{color:"#000000"},{lightness:17},{weight:1.2}]}]};n=new google.maps.Map(e,a),google.maps.event.addDomListener(e,"mouseenter",function(e){e.cancelBubble=!0,n.hover||(n.hover=!0,n.setOptions({zoomControl:!0}))}),google.maps.event.addDomListener(e,"mouseleave",function(){n.hover&&(n.setOptions({zoomControl:!1}),n.hover=!1)}),i=new google.maps.Marker({map:n}),t()}window.google&&window.google.maps?a():(window.gmap_initialize=a,head.js("https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=gmap_initialize"))},this.onSettingsChanged=function(e){a=e},this.onCalculatedValueChanged=function(e,n){"lat"==e?s.lat=n:"lon"==e&&(s.lon=n),t()},this.onDispose=function(){},this.getHeight=function(){return 4},this.onSettingsChanged(e)};freeboard.loadWidgetPlugin({type_name:"google_map",display_name:"Google Map",fill_size:!0,settings:[{name:"lat",display_name:"Latitude",type:"calculated"},{name:"lon",display_name:"Longitude",type:"calculated"}],newInstance:function(e,t){t(new u(e))}}),freeboard.addStyle(".html-widget","white-space:normal;width:100%;height:100%");var p=function(e){var t=$('
'),n=e;this.render=function(e){$(e).append(t)},this.onSettingsChanged=function(e){n=e},this.onCalculatedValueChanged=function(e,n){"html"==e&&t.html(n)},this.onDispose=function(){},this.getHeight=function(){return Number(n.height)},this.onSettingsChanged(e)};freeboard.loadWidgetPlugin({type_name:"html",display_name:"HTML",fill_size:!0,settings:[{name:"html",display_name:"HTML",type:"calculated",description:"Can be literal HTML, or javascript that outputs HTML."},{name:"height",display_name:"Height Blocks",type:"number",default_value:4,description:"A height block is around 60 pixels"}],newInstance:function(e,t){t(new p(e))}})}();
\ No newline at end of file
diff --git a/js/freeboard.js b/js/freeboard.js
index 20a548b..3792b6b 100644
--- a/js/freeboard.js
+++ b/js/freeboard.js
@@ -1332,7 +1332,10 @@ PluginEditor = function(jsEditor, valueEditor)
ValueEditor = function(theFreeboardModel)
{
- var _veDatasourceRegex = new RegExp(".*datasources\\[\"([^\"]*)(\"\\].)?$");
+ var _veDatasourceRegex = new RegExp(".*datasources\\[\"([^\"]*)(\"\\]\\[\")?(.*)$");
+
+ var _autocompleteOptions = [];
+ var _autocompleteReplacementString;
function _resizeValueEditor(element)
{
@@ -1343,6 +1346,126 @@ ValueEditor = function(theFreeboardModel)
$(element).css({height: newHeight + "px"});
}
+ function _autocompleteFromDatasource(inputString, datasources)
+ {
+ var match = _veDatasourceRegex.exec(inputString);
+
+ var options = [];
+ var replacementString;
+
+ if(match)
+ {
+ if(match[1] == "") // List all datasources
+ {
+ _.each(datasources, function(datasource)
+ {
+ options.push({value: datasource.name(), follow_char: "\"][\""});
+ });
+ }
+ else if(match[1] != "" && _.isUndefined(match[2])) // List partial datasources
+ {
+ replacementString = match[1];
+
+ _.each(datasources, function(datasource)
+ {
+ var dsName = datasource.name();
+
+ if(dsName != replacementString && dsName.indexOf(replacementString) == 0)
+ {
+ options.push({value: dsName, follow_char: "\"][\""});
+ }
+ });
+ }
+ else
+ {
+ var datasource = _.find(datasources, function(datasource)
+ {
+ return (datasource.name() === match[1]);
+ });
+
+ if(!_.isUndefined(datasource))
+ {
+ var dataPath = "";
+
+ if(!_.isUndefined(match[2]))
+ {
+ dataPath = match[2] + match[3];
+ }
+
+ var dataPathItems = dataPath.split("\"][\"");
+ dataPath = "data";
+
+ for(var index = 1; index < dataPathItems.length - 1; index++)
+ {
+ if(dataPathItems[index] != "")
+ {
+ dataPathItem = "[\"" + dataPathItems[index] + "\"]";
+ dataPath = dataPath + dataPathItem;
+ }
+ }
+
+ var lastPathObject = _.last(dataPathItems);
+
+ // If the last character is a ", then ignore it
+ if(lastPathObject.charAt(lastPathObject.length - 1) == "\"")
+ {
+ lastPathObject = lastPathObject.replace(/\[\"?$/, "");
+ dataPath = dataPath + "[\"" + lastPathObject + "\"]";
+ }
+
+ var dataValue = datasource.getDataRepresentation(dataPath);
+
+ if(_.isArray(dataValue))
+ {
+ for(var index = 0; index < dataValue.length; index++)
+ {
+ var followChar = "\"]";
+
+ if(_.isObject(dataValue[index]))
+ {
+ followChar = followChar + "\"][\"";
+ }
+ else if(_.isArray(dataValue[index]))
+ {
+ followChar = followChar + "\"][";
+ }
+
+ options.push({value: index, follow_char: followChar});
+ }
+ }
+ else if(_.isObject(dataValue))
+ {
+ replacementString = lastPathObject;
+
+ if(_.keys(dataValue).indexOf(replacementString) == -1)
+ {
+ _.each(dataValue, function(value, name)
+ {
+ if(name != lastPathObject && name.indexOf(lastPathObject) == 0)
+ {
+ var followChar = "\"]";
+
+ if(_.isArray(value))
+ {
+ followChar = "\"][";
+ }
+ else if(_.isObject(value))
+ {
+ followChar = "\"][\"";
+ }
+
+ options.push({value: name, follow_char: followChar});
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+ _autocompleteOptions = options;
+ _autocompleteReplacementString = replacementString;
+ }
+
function createValueEditor(element)
{
var dropdown = null;
@@ -1360,121 +1483,9 @@ ValueEditor = function(theFreeboardModel)
var inputString = $(element).val().substring(0, $(element).getCaretPosition());
inputString = inputString.replace(String.fromCharCode(160), " "); // Weird issue where the textarea box was putting in ASCII (non breaking space) for spaces.
- var match = _veDatasourceRegex.exec(inputString);
+ _autocompleteFromDatasource(inputString, theFreeboardModel.datasources());
- var options = [];
- var replacementString;
-
- if(match)
- {
- if(match[1] == "") // List all datasources
- {
- _.each(theFreeboardModel.datasources(), function(datasource)
- {
- options.push({value: datasource.name(), follow_char: "\"]."});
- });
- }
- else if(match[1] != "" && _.isUndefined(match[2])) // List partial datasources
- {
- replacementString = match[1];
-
- _.each(theFreeboardModel.datasources(), function(datasource)
- {
- var dsName = datasource.name();
-
- if(dsName != replacementString && dsName.indexOf(replacementString) == 0)
- {
- options.push({value: dsName, follow_char: "\"]."});
- }
- });
- }
- else
- {
- var datasource = _.find(theFreeboardModel.datasources(), function(datasource)
- {
- return (datasource.name() === match[1]);
- });
-
- if(!_.isUndefined(datasource))
- {
- var dataPath = "";
-
- if(!_.isUndefined(match[2]))
- {
- dataPath = match[2];
- }
-
- var dataPathItems = dataPath.split(".");
- dataPath = "data";
-
- for(var index = 1; index < dataPathItems.length - 1; index++)
- {
- if(dataPathItems[index] != "")
- {
- dataPath = dataPath + "." + dataPathItems[index];
- }
- }
-
- var lastPathObject = _.last(dataPathItems);
-
- // If the last character is a [, then ignore it
- if(lastPathObject.charAt(lastPathObject.length - 1) == "[")
- {
- lastPathObject = lastPathObject.replace(/\[+$/, "");
- dataPath = dataPath + "." + lastPathObject;
- }
-
- var dataValue = datasource.getDataRepresentation(dataPath);
-
- if(_.isArray(dataValue))
- {
- for(var index = 0; index < dataValue.length; index++)
- {
- var followChar = "]";
-
- if(_.isObject(dataValue[index]))
- {
- followChar = followChar + ".";
- }
- else if(_.isArray(dataValue[index]))
- {
- followChar = followChar + "[";
- }
-
- options.push({value: index, follow_char: followChar});
- }
- }
- else if(_.isObject(dataValue))
- {
- replacementString = lastPathObject;
-
- if(_.keys(dataValue).indexOf(replacementString) == -1)
- {
- _.each(dataValue, function(value, name)
- {
- if(name != lastPathObject && name.indexOf(lastPathObject) == 0)
- {
- var followChar = undefined;
-
- if(_.isArray(value))
- {
- followChar = "[";
- }
- else if(_.isObject(value))
- {
- followChar = ".";
- }
-
- options.push({value: name, follow_char: followChar});
- }
- });
- }
- }
- }
- }
- }
-
- if(options.length > 0)
+ if(_autocompleteOptions.length > 0)
{
if(!dropdown)
{
@@ -1489,7 +1500,7 @@ ValueEditor = function(theFreeboardModel)
var currentIndex = 0;
- _.each(options, function(option)
+ _.each(_autocompleteOptions, function(option)
{
var li = $('' + option.value + ' ').appendTo(dropdown).mouseenter(function()
{
@@ -1507,13 +1518,13 @@ ValueEditor = function(theFreeboardModel)
optionValue = optionValue + option.follow_char;
}
- if(!_.isUndefined(replacementString))
+ if(!_.isUndefined(_autocompleteReplacementString))
{
- var replacementIndex = inputString.lastIndexOf(replacementString);
+ var replacementIndex = inputString.lastIndexOf(_autocompleteReplacementString);
if(replacementIndex != -1)
{
- $(element).replaceTextAt(replacementIndex, replacementIndex + replacementString.length, optionValue);
+ $(element).replaceTextAt(replacementIndex, replacementIndex + _autocompleteReplacementString.length, optionValue);
}
}
else
diff --git a/js/freeboard.min.js b/js/freeboard.min.js
index 796f05b..6e77fb4 100644
--- a/js/freeboard.min.js
+++ b/js/freeboard.min.js
@@ -1 +1 @@
-function DialogBox(e,t,n,i,a){function s(){o.fadeOut(200,function(){$(this).remove()})}var o=$('
'),r=$('
');r.append('"),$("").appendTo(r).append(e);var d=$("").appendTo(r);n&&$(''+n+" ").appendTo(d).click(function(){var e=!1;_.isFunction(a)&&(e=a()),e||s()}),i&&$(''+i+" ").appendTo(d).click(function(){s()}),o.append(r),$("body").append(o),o.fadeIn(200)}function FreeboardModel(e,t,n){var i=this,a=1;this.version=0,this.isEditing=ko.observable(!1),this.allow_edit=ko.observable(!1),this.allow_edit.subscribe(function(e){e?$("#main-header").show():$("#main-header").hide()}),this.header_image=ko.observable(),this.plugins=ko.observableArray(),this.datasources=ko.observableArray(),this.panes=ko.observableArray(),this.datasourceData={},this.processDatasourceUpdate=function(e,t){var n=e.name();i.datasourceData[n]=t,_.each(i.panes(),function(e){_.each(e.widgets(),function(e){e.processDatasourceUpdate(n)})})},this._datasourceTypes=ko.observable(),this.datasourceTypes=ko.computed({read:function(){i._datasourceTypes();var t=[];return _.each(e,function(e){var n=e.type_name,i=n;_.isUndefined(e.display_name)||(i=e.display_name),t.push({name:n,display_name:i})}),t}}),this._widgetTypes=ko.observable(),this.widgetTypes=ko.computed({read:function(){i._widgetTypes();var e=[];return _.each(t,function(t){var n=t.type_name,i=n;_.isUndefined(t.display_name)||(i=t.display_name),e.push({name:n,display_name:i})}),e}}),this.addPluginSource=function(e){e&&-1==i.plugins.indexOf(e)&&i.plugins.push(e)},this.serialize=function(){var e=[];_.each(i.panes(),function(t){e.push(t.serialize())});var t=[];return _.each(i.datasources(),function(e){t.push(e.serialize())}),{version:a,header_image:i.header_image(),allow_edit:i.allow_edit(),plugins:i.plugins(),panes:e,datasources:t}},this.deserialize=function(n,a){function s(){_.isUndefined(n.allow_edit)?i.allow_edit(!0):i.allow_edit(n.allow_edit),i.version=n.version||0,i.header_image(n.header_image),_.each(n.datasources,function(t){var n=new DatasourceModel(i,e);n.deserialize(t),i.addDatasource(n)});var s=_.sortBy(n.panes,function(e){return freeboard._getPositionForScreenSize(e).row});_.each(s,function(e){var n=new PaneModel(i,t);n.deserialize(e),i.panes.push(n)}),i.allow_edit()&&0==i.panes().length&&i.setEditing(!0),_.isFunction(a)&&a()}i.clearDashboard(),_.each(n.plugins,function(e){i.addPluginSource(e)}),_.isArray(n.plugins)&&n.plugins.length>0?head.js(n.plugins,function(){s()}):s()},this.clearDashboard=function(){freeboard._removeAllWidgets(),_.each(i.datasources(),function(e){e.dispose()}),_.each(i.panes(),function(e){e.dispose()}),i.plugins.removeAll(),i.datasources.removeAll(),i.panes.removeAll()},this.loadDashboard=function(e,t){n.showLoadingIndicator(!0),i.deserialize(e,function(){n.showLoadingIndicator(!1),_.isFunction(t)&&t(),freeboard.emit("dashboard_loaded")})},this.loadDashboardFromLocalFile=function(){if(window.File&&window.FileReader&&window.FileList&&window.Blob){var e=document.createElement("input");e.type="file",$(e).on("change",function(e){var t=e.target.files;if(t&&t.length>0){var n=t[0],a=new FileReader;a.addEventListener("load",function(e){var t=e.target,n=JSON.parse(t.result);i.loadDashboard(n),i.setEditing(!1)}),a.readAsText(n)}}),$(e).trigger("click")}else alert("Unable to load a file in this browser.")},this.saveDashboard=function(){var e="application/octet-stream",t=document.createElement("a"),n=new Blob([JSON.stringify(i.serialize())],{type:e});document.body.appendChild(t),t.href=window.URL.createObjectURL(n),t.download="dashboard.json",t.target="_self",t.click()},this.addDatasource=function(e){i.datasources.push(e)},this.deleteDatasource=function(e){delete i.datasourceData[e.name()],e.dispose(),i.datasources.remove(e)},this.createPane=function(){var e=new PaneModel(i,t);i.addPane(e)},this.addPane=function(e){i.panes.push(e)},this.deletePane=function(e){e.dispose(),i.panes.remove(e)},this.deleteWidget=function(e){ko.utils.arrayForEach(i.panes(),function(t){t.widgets.remove(e)}),e.dispose()},this.setEditing=function(e,t){if(i.allow_edit()||!e){i.isEditing(e),_.isUndefined(t)&&(t=!0);var a=t?250:0,s=$("#admin-bar").outerHeight();e?($("#toggle-header-icon").addClass("icon-chevron-up").removeClass("icon-wrench"),$(".gridster .gs_w").css({cursor:"pointer"}),$("#main-header").animate({top:"0px"},a),$("#board-content").animate({top:s+20+"px"},a),$("#main-header").data().shown=!0,n.attachWidgetEditIcons($(".sub-section")),freeboard._enableGrid()):($("#toggle-header-icon").addClass("icon-wrench").removeClass("icon-chevron-up"),$(".gridster .gs_w").css({cursor:"default"}),$("#main-header").animate({top:"-"+s+"px"},a),$("#board-content").animate({top:"20"},a),$("#main-header").data().shown=!1,$(".sub-section").unbind(),freeboard._disableGrid()),n.showPaneEditIcons(e,t)}},this.toggleEditing=function(){var e=!i.isEditing();i.setEditing(e)}}function FreeboardUI(){function e(e){e?a.fadeOut(0).appendTo("body").fadeIn(500):a.fadeOut(500).remove()}function t(e,t){_.isUndefined(t)&&(t=!0);var n=t?250:0;e?$(".pane-tools").fadeIn(n):$(".pane-tools").fadeOut(n)}function n(e){$(e).hover(function(){i(this,!0)},function(){i(this,!1)})}function i(e,t){t?$(e).find(".sub-section-tools").fadeIn(250):$(e).find(".sub-section-tools").fadeOut(250)}var a=$('');return{showLoadingIndicator:function(t){e(t)},showPaneEditIcons:function(e,n){t(e,n)},attachWidgetEditIcons:function(e){n(e)}}}function PaneModel(e,t){var n=this;this.title=ko.observable(),this.width=ko.observable(1),this.row={},this.col={},this.col_width=ko.observable(1),this.widgets=ko.observableArray(),this.addWidget=function(e){this.widgets.push(e)},this.widgetCanMoveUp=function(e){return n.widgets.indexOf(e)>=1},this.widgetCanMoveDown=function(e){var t=n.widgets.indexOf(e);return n.widgets().length-1>t},this.moveWidgetUp=function(e){if(n.widgetCanMoveUp(e)){var t=n.widgets.indexOf(e),i=n.widgets();n.widgets.splice(t-1,2,i[t],i[t-1])}},this.moveWidgetDown=function(e){if(n.widgetCanMoveDown(e)){var t=n.widgets.indexOf(e),i=n.widgets();n.widgets.splice(t,2,i[t+1],i[t])}},this.getCalculatedHeight=function(){var e=_.reduce(n.widgets(),function(e,t){return e+t.height()},0);e*=6,e+=3,e*=10;var t=Math.ceil((e+20)/30);return Math.max(4,t)},this.serialize=function(){var e=[];return _.each(n.widgets(),function(t){e.push(t.serialize())}),{title:n.title(),width:n.width(),row:n.row,col:n.col,col_width:n.col_width(),widgets:e}},this.deserialize=function(i){n.title(i.title),n.width(i.width),n.row=i.row,n.col=i.col,n.col_width(i.col_width||1),_.each(i.widgets,function(i){var a=new WidgetModel(e,t);a.deserialize(i),n.widgets.push(a)})},this.dispose=function(){_.each(n.widgets(),function(e){e.dispose()})}}function WidgetModel(e,t){function n(){_.isUndefined(i.widgetInstance)||(_.isFunction(i.widgetInstance.onDispose)&&i.widgetInstance.onDispose(),i.widgetInstance=void 0)}var i=this;this.datasourceRefreshNotifications={},this.calculatedSettingScripts={},this.title=ko.observable(),this.fillSize=ko.observable(!1),this.type=ko.observable(),this.type.subscribe(function(e){function a(){s.newInstance(i.settings(),function(e){i.fillSize(s.fill_size===!0),i.widgetInstance=e,i.shouldRender(!0),i._heightUpdate.valueHasMutated()})}if(n(),e in t&&_.isFunction(t[e].newInstance)){var s=t[e];s.external_scripts?head.js(s.external_scripts.slice(0),a):a()}}),this.settings=ko.observable({}),this.settings.subscribe(function(e){!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.onSettingsChanged)&&i.widgetInstance.onSettingsChanged(e),i.updateCalculatedSettings(),i._heightUpdate.valueHasMutated()}),this.processDatasourceUpdate=function(e){var t=i.datasourceRefreshNotifications[e];_.isArray(t)&&_.each(t,function(e){i.processCalculatedSetting(e)})},this.callValueFunction=function(t){return t.call(void 0,e.datasourceData)},this.processCalculatedSetting=function(e){if(_.isFunction(i.calculatedSettingScripts[e])){var t=void 0;try{t=i.callValueFunction(i.calculatedSettingScripts[e])}catch(n){var a=i.settings()[e];n instanceof ReferenceError&&/^\w+$/.test(a)&&(t=a)}if(!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.onCalculatedValueChanged)&&!_.isUndefined(t))try{i.widgetInstance.onCalculatedValueChanged(e,t)}catch(n){console.log(""+n)}}},this.updateCalculatedSettings=function(){if(i.datasourceRefreshNotifications={},i.calculatedSettingScripts={},!_.isUndefined(i.type())){var e=t[i.type()].settings,n=RegExp("datasources.([\\w_-]+)|datasources\\[['\"]([^'\"]+)","g"),a=i.settings();_.each(e,function(e){if("calculated"==e.type){var t=a[e.name];if(!_.isUndefined(t)){1>=(t.match(/;/g)||[]).length&&-1==t.indexOf("return")&&(t="return "+t);var s;try{s=Function("datasources",t)}catch(o){var r=a[e.name].replace(/"/g,'\\"').replace(/[\r\n]/g," \\\n");s=Function("datasources",'return "'+r+'";')}i.calculatedSettingScripts[e.name]=s,i.processCalculatedSetting(e.name);for(var d;d=n.exec(t);){var c=d[1]||d[2],l=i.datasourceRefreshNotifications[c];_.isUndefined(l)&&(l=[],i.datasourceRefreshNotifications[c]=l),l.push(e.name)}}}})}},this._heightUpdate=ko.observable(),this.height=ko.computed({read:function(){return i._heightUpdate(),!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.getHeight)?i.widgetInstance.getHeight():1}}),this.shouldRender=ko.observable(!1),this.render=function(e){i.shouldRender(!1),!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.render)&&(i.widgetInstance.render(e),i.updateCalculatedSettings())},this.dispose=function(){},this.serialize=function(){return{title:i.title(),type:i.type(),settings:i.settings()}},this.deserialize=function(e){i.title(e.title),i.settings(e.settings),i.type(e.type)}}DatasourceModel=function(e,t){function n(){_.isUndefined(i.datasourceInstance)||(_.isFunction(i.datasourceInstance.onDispose)&&i.datasourceInstance.onDispose(),i.datasourceInstance=void 0)}var i=this;this.name=ko.observable(),this.latestData=ko.observable(),this.settings=ko.observable({}),this.settings.subscribe(function(e){!_.isUndefined(i.datasourceInstance)&&_.isFunction(i.datasourceInstance.onSettingsChanged)&&i.datasourceInstance.onSettingsChanged(e)}),this.updateCallback=function(t){e.processDatasourceUpdate(i,t),i.latestData(t);var n=new Date;i.last_updated(n.toLocaleTimeString())},this.type=ko.observable(),this.type.subscribe(function(e){function a(){s.newInstance(i.settings(),function(e){i.datasourceInstance=e,e.updateNow()},i.updateCallback)}if(n(),e in t&&_.isFunction(t[e].newInstance)){var s=t[e];s.external_scripts?head.js(s.external_scripts.slice(0),a):a()}}),this.last_updated=ko.observable("never"),this.last_error=ko.observable(),this.serialize=function(){return{name:i.name(),type:i.type(),settings:i.settings()}},this.deserialize=function(e){i.settings(e.settings),i.name(e.name),i.type(e.type)},this.getDataRepresentation=function(e){var t=Function("data","return "+e+";");return t.call(void 0,i.latestData())},this.updateNow=function(){!_.isUndefined(i.datasourceInstance)&&_.isFunction(i.datasourceInstance.updateNow)&&i.datasourceInstance.updateNow()},this.dispose=function(){n()}},DeveloperConsole=function(e){function t(){function t(e){var t=$(" "),i=$(''),a=$(' '),s=$(' ').click(function(){n=_.without(n,a),t.remove()});n.push(a),e&&a.val(e),i.append(s),o.append(t.append($(" ").append(a)).append($('').append(i)))}var n=[],i=$("
"),a=$('ADD
'),s=$('');s.append($('Plugin Script URL '));var o=$(" ");s.append(o),i.append($("Here you can add references to other scripts to load datasource or widget plugins.
")).append(s).append(a).append('To learn how to build plugins for freeboard, please visit http://freeboard.github.io/freeboard/docs/plugin_example.html
'),_.each(e.plugins(),function(e){t(e)}),a.click(function(){t()}),new DialogBox(i,"Developer Console","OK",null,function(){_.each(e.plugins(),function(e){$('script[src^="'+e+'"]').remove()}),e.plugins.removeAll(),_.each(n,function(t){var n=t.val();n&&n.length>0&&(e.addPluginSource(n),head.js(n+"?"+Date.now()))})})}return{showDeveloperConsole:function(){t()}}},JSEditor=function(){function e(e){n=e}function t(e,t){head.js(n+"css/codemirror.css",n+"css/codemirror-ambiance.css",n+"js/codemirror.js",function(){var n='// Example: Convert temp from C to F and truncate to 2 decimal places.\n// return (datasources["MyDatasource"].sensor.tempInF * 1.8 + 32).toFixed(2);';e||(e=n);var i=$('
'),a=$('
'),s=$(''),o=$('');i.append([o,a,s]),$("body").append(i);var r=CodeMirror(a.get(0),{value:e,mode:"javascript",theme:"ambiance",indentUnit:4,lineNumbers:!0,matchBrackets:!0,autoCloseBrackets:!0}),d=$('Close ').click(function(){if(t){var e=r.getValue();e===n&&(e=""),t(e),i.remove()}});s.append(d)})}var n="";return{displayJSEditor:function(e,n){t(e,n)},setAssetRoot:function(){e(_assetRoot)}}},PluginEditor=function(e,t){function n(e,t){var n=$('
').html(t);$("#setting-value-container-"+e).append(n)}function i(){$("#setting-row-instance-name").length?$("#setting-row-instance-name").nextAll().remove():$("#setting-row-plugin-types").nextAll().remove()}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function s(s,o,r,d,c){function l(e,t){var n=$('
').appendTo(h);return n.append(''+t+"
"),$('
').appendTo(n)}function u(n){_.each(n,function(n){function i(){f.settings[n.name].length>0?u.show():u.hide()}function a(e){var t=$(" ").appendTo(h),a={};_.isArray(f.settings[n.name])||(f.settings[n.name]=[]),f.settings[n.name].push(a),_.each(n.settings,function(n){var i=$(" ").appendTo(t),s="";_.isUndefined(e[n.name])||(s=e[n.name]),a[n.name]=s,$(' ').appendTo(i).val(s).change(function(){a[n.name]=$(this).val()})}),t.append($(' ').append($('').append($(" ").append($(' ').click(function(){var e=f.settings[n.name].indexOf(a);-1!=e&&(f.settings[n.name].splice(e,1),t.remove(),i())}))))),r.scrollTop(r[0].scrollHeight),i()}!_.isUndefined(n.default_value)&&_.isUndefined(d[n.name])&&(d[n.name]=n.default_value);var s=n.name;_.isUndefined(n.display_name)||(s=n.display_name);var o=l(n.name,s);switch(n.type){case"array":var r=$('
').appendTo(o),c=$('').appendTo(r),u=$(" ").hide().appendTo(c),p=$(" ").appendTo(u),h=$(" ").appendTo(c),g=[];_.each(n.settings,function(e){var t=e.name;_.isUndefined(e.display_name)||(t=e.display_name),$(""+t+" ").appendTo(p)}),n.name in d&&(g=d[n.name]),$('ADD
').appendTo(o).click(function(){var e={};_.each(n.settings,function(t){e[t.name]=""}),a(e)}),_.each(g,function(e){a(e)});break;case"boolean":f.settings[n.name]=d[n.name];var v=$('').appendTo(o),m=$(' ').prependTo(v).change(function(){f.settings[n.name]=this.checked});n.name in d&&m.prop("checked",d[n.name]);break;case"option":var w=d[n.name],m=$(" ").appendTo($('
').appendTo(o)).change(function(){f.settings[n.name]=$(this).val()});_.each(n.options,function(e){var t,n;_.isObject(e)?(t=e.name,n=e.value):t=e,_.isUndefined(n)&&(n=t),_.isUndefined(w)&&(w=n),$(" ").text(t).attr("value",n).appendTo(m)}),f.settings[n.name]=w,n.name in d&&m.val(d[n.name]);break;default:if(f.settings[n.name]=d[n.name],"calculated"==n.type){var m=$("").appendTo(o).change(function(){f.settings[n.name]=$(this).val()});n.name in d&&m.val(d[n.name]),t.createValueEditor(m);var b=$(''),y=$('DATASOURCE ').mousedown(function(e){e.preventDefault(),$(m).focus(),$(m).insertAtCaret('datasources["'),$(m).trigger("freeboard-eval")}),k=$('.JS EDITOR ').mousedown(function(t){t.preventDefault(),e.displayJSEditor(m.val(),function(e){m.val(e),m.change()})});$(o).append(b.append([y,k]))}else{var m=$(' ').appendTo(o).change(function(){f.settings[n.name]="number"==n.type?Number($(this).val()):$(this).val()});n.name in d&&m.val(d[n.name])}}_.isUndefined(n.suffix)||o.append($(''+n.suffix+"
")),_.isUndefined(n.description)||o.append($(''+n.description+"
"))})}var p,f={type:r,settings:{}},h=$("
"),g=$('
').hide();h.append(g),new DialogBox(h,s,"Save","Cancel",function(){$(".validation-error").remove();for(var e=0;p.settings.length>e;e++){var t=p.settings[e];if(t.required&&(_.isUndefined(f.settings[t.name])||""==f.settings[t.name]))return n(t.name,"This is required."),!0;if("number"==t.type&&!a(f.settings[t.name]))return n(t.name,"Must be a number."),!0}_.isFunction(c)&&c(f)});var v,m=_.keys(o);if(m.length>1){var w=l("plugin-types","Type");v=$(" ").appendTo($('
').appendTo(w)),v.append($("Select a type... ").attr("value","undefined")),_.each(o,function(e){v.append($(" ").text(e.display_name).attr("value",e.type_name))}),v.change(function(){f.type=$(this).val(),f.settings={},i(),p=o[v.val()],_.isUndefined(p)?($("#setting-row-instance-name").hide(),$("#dialog-ok").hide()):($("#setting-row-instance-name").show(),p.description&&p.description.length>0?g.html(p.description).show():g.hide(),$("#dialog-ok").show(),u(p.settings))})}else 1==m.length&&(p=o[m[0]],u(p.settings));v&&(_.isUndefined(r)?($("#setting-row-instance-name").hide(),$("#dialog-ok").hide()):($("#dialog-ok").show(),v.val(r).trigger("change")))}return{createPluginEditor:function(e,t,n,i,a,o){s(e,t,n,i,a,o)}}},ValueEditor=function(e){function t(e){var t=($(e).val().match(/\n/g)||[]).length,n=Math.min(200,20*(t+1));$(e).css({height:n+"px"})}function n(n){var a=null,s=0;$(n).addClass("calculated-value-input").bind("keyup mouseup freeboard-eval",function(t){if(a&&"keyup"==t.type&&(38==t.keyCode||40==t.keyCode||13==t.keyCode))return t.preventDefault(),void 0;var o=$(n).val().substring(0,$(n).getCaretPosition());o=o.replace(String.fromCharCode(160)," ");var r,d=i.exec(o),c=[];if(d)if(""==d[1])_.each(e.datasources(),function(e){c.push({value:e.name(),follow_char:'"].'})});else if(""!=d[1]&&_.isUndefined(d[2]))r=d[1],_.each(e.datasources(),function(e){var t=e.name();t!=r&&0==t.indexOf(r)&&c.push({value:t,follow_char:'"].'})});else{var l=_.find(e.datasources(),function(e){return e.name()===d[1]});if(!_.isUndefined(l)){var u="";_.isUndefined(d[2])||(u=d[2]);var p=u.split(".");u="data";for(var f=1;p.length-1>f;f++)""!=p[f]&&(u=u+"."+p[f]);var h=_.last(p);"["==h.charAt(h.length-1)&&(h=h.replace(/\[+$/,""),u=u+"."+h);var g=l.getDataRepresentation(u);if(_.isArray(g))for(var f=0;g.length>f;f++){var v="]";_.isObject(g[f])?v+=".":_.isArray(g[f])&&(v+="["),c.push({value:f,follow_char:v})}else _.isObject(g)&&(r=h,-1==_.keys(g).indexOf(r)&&_.each(g,function(e,t){if(t!=h&&0==t.indexOf(h)){var n=void 0;_.isArray(e)?n="[":_.isObject(e)&&(n="."),c.push({value:t,follow_char:n})}}))}}if(c.length>0){a||(a=$('').insertAfter(n).width($(n).outerWidth()-2).css("left",$(n).position().left).css("top",$(n).position().top+$(n).outerHeight()-1)),a.empty(),a.scrollTop(0);var m=!0;s=0;var w=0;_.each(c,function(e){var t=$(""+e.value+" ").appendTo(a).mouseenter(function(){$(this).trigger("freeboard-select")}).mousedown(function(e){$(this).trigger("freeboard-insertValue"),e.preventDefault()}).data("freeboard-optionIndex",w).data("freeboard-optionValue",e.value).bind("freeboard-insertValue",function(){var t=e.value;if(_.isUndefined(e.follow_char)||(t+=e.follow_char),_.isUndefined(r))$(n).insertAtCaret(t);else{var i=o.lastIndexOf(r);-1!=i&&$(n).replaceTextAt(i,i+r.length,t)}$(n).triggerHandler("mouseup")}).bind("freeboard-select",function(){$(this).parent().find("li.selected").removeClass("selected"),$(this).addClass("selected"),s=$(this).data("freeboard-optionIndex")});m&&($(t).addClass("selected"),m=!1),w++})}else $(n).next("ul#value-selector").remove(),a=null,s=-1}).focus(function(){t(n)}).focusout(function(){$(n).css({height:""}),$(n).next("ul#value-selector").remove(),a=null,s=-1}).bind("keydown",function(e){if(a)if(38==e.keyCode||40==e.keyCode){e.preventDefault();var t=$(a).find("li");38==e.keyCode?s--:40==e.keyCode&&s++,0>s?s=t.size()-1:s>=t.size()&&(s=0);var n=$(t).eq(s);n.trigger("freeboard-select"),$(a).scrollTop($(n).position().top)}else 13==e.keyCode&&(e.preventDefault(),-1!=s&&$(a).find("li").eq(s).trigger("freeboard-insertValue"))})}var i=RegExp('.*datasources\\["([^"]*)("\\].)?$');return{createValueEditor:function(e){n(e)}}},function(e){function t(){var e=document.createElement("p"),t=!1;if(e.addEventListener)e.addEventListener("DOMAttrModified",function(){t=!0},!1);else{if(!e.attachEvent)return!1;e.attachEvent("onDOMAttrModified",function(){t=!0})}return e.setAttribute("id","target"),t}function n(t,n){if(t){var i=this.data("attr-old-value");if(n.attributeName.indexOf("style")>=0){i.style||(i.style={});var a=n.attributeName.split(".");n.attributeName=a[0],n.oldValue=i.style[a[1]],n.newValue=a[1]+":"+this.prop("style")[e.camelCase(a[1])],i.style[a[1]]=n.newValue}else n.oldValue=i[n.attributeName],n.newValue=this.attr(n.attributeName),i[n.attributeName]=n.newValue;this.data("attr-old-value",i)}}var i=window.MutationObserver||window.WebKitMutationObserver;e.fn.attrchange=function(a){var s={trackValues:!1,callback:e.noop};if("function"==typeof a?s.callback=a:e.extend(s,a),s.trackValues&&e(this).each(function(t,n){for(var i,a={},t=0,s=n.attributes,o=s.length;o>t;t++)i=s.item(t),a[i.nodeName]=i.value;e(this).data("attr-old-value",a)}),i){var o={subtree:!1,attributes:!0,attributeOldValue:s.trackValues},r=new i(function(t){t.forEach(function(t){var n=t.target;s.trackValues&&(t.newValue=e(n).attr(t.attributeName)),s.callback.call(n,t)})});return this.each(function(){r.observe(this,o)})}return t()?this.on("DOMAttrModified",function(e){e.originalEvent&&(e=e.originalEvent),e.attributeName=e.attrName,e.oldValue=e.prevValue,s.callback.call(this,e)}):"onpropertychange"in document.body?this.on("propertychange",function(t){t.attributeName=window.event.propertyName,n.call(e(this),s.trackValues,t),s.callback.call(this,t)}):this}}(jQuery),function(e){e.eventEmitter={_JQInit:function(){this._JQ=e(this)},emit:function(e,t){!this._JQ&&this._JQInit(),this._JQ.trigger(e,t)},once:function(e,t){!this._JQ&&this._JQInit(),this._JQ.one(e,t)},on:function(e,t){!this._JQ&&this._JQInit(),this._JQ.bind(e,t)},off:function(e,t){!this._JQ&&this._JQInit(),this._JQ.unbind(e,t)}}}(jQuery);var freeboard=function(){function e(e){var t=a.$el;t.find("> li").unbind().removeData(),$(".gridster").css("width",""),a.generate_grid_and_stylesheet(),e&&t.find("> li").each(function(){var e=this,t=ko.dataFor(e),i=n(t);$(e).attr("data-row",i.row).attr("data-col",i.col)}),a.init(),$(".gridster").css("width",300*a.cols+20*a.cols)}function t(e,t,n){var i=a.cols;_.isUndefined(t)||(e.row[i]=t),_.isUndefined(n)||(e.col[i]=n)}function n(e,t){var n=_.isUndefined(t)?a.cols:t;if(_.isNumber(e.row)&&_.isNumber(e.col)){var i={};i[n]=e.row,e.row=i,i={},i[n]=e.col,e.col=i}var s=1,o=1e3;for(var r in e.col){if(r==n)return{row:e.row[r],col:e.col[r]};if(e.col[r]>n)s=n;else{var d=n-r;o>d&&(s=r,o=d)}}return s in e.col&&s in e.row?{row:e.row[s],col:e.col[s]}:{row:1,col:s}}function i(e){e=e.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var t=RegExp("[\\?&]"+e+"=([^]*)"),n=t.exec(location.search);return null==n?"":decodeURIComponent(n[1].replace(/\+/g," "))}var a,s=10,o=300,r={},d={},c=new FreeboardUI,l=new FreeboardModel(r,d,c),u=new JSEditor,p=new ValueEditor(l),f=new PluginEditor(u,p),h=new DeveloperConsole(l),g={values:{"font-family":'"HelveticaNeue-UltraLight", "Helvetica Neue Ultra Light", "Helvetica Neue", sans-serif',color:"#d3d4d4","font-weight":100}};return ko.bindingHandlers.pluginEditor={init:function(e,t,n,i){var a=ko.unwrap(t()),s={},o=void 0,u="";"datasource"==a.type?(s=r,u="Datasource"):"widget"==a.type?(s=d,u="Widget"):"pane"==a.type&&(u="Pane"),$(e).click(function(){if("delete"==a.operation){var t=$("Are you sure you want to delete this "+u+"?
");new DialogBox(t,"Confirm Delete","Yes","No",function(){"datasource"==a.type?l.deleteDatasource(i):"widget"==a.type?l.deleteWidget(i):"pane"==a.type&&l.deletePane(i)})}else{var n=void 0;"datasource"==a.type?"add"==a.operation?o={}:(n=i.type(),o=i.settings(),o.name=i.name()):"widget"==a.type?"add"==a.operation?o={}:(n=i.type(),o=i.settings()):"pane"==a.type&&(o={},"edit"==a.operation&&(o.title=i.title(),o.col_width=i.col_width()),s={settings:{settings:[{name:"title",display_name:"Title",type:"text"},{name:"col_width",display_name:"Columns",type:"number",default_value:1,required:!0}]}}),f.createPluginEditor(u,s,n,o,function(t){if("add"==a.operation){if("datasource"==a.type){var n=new DatasourceModel(l,r);l.addDatasource(n),n.name(t.settings.name),delete t.settings.name,n.settings(t.settings),n.type(t.type)}else if("widget"==a.type){var n=new WidgetModel(l,d);n.settings(t.settings),n.type(t.type),i.widgets.push(n),c.attachWidgetEditIcons(e)}}else"edit"==a.operation&&("pane"==a.type?(i.title(t.settings.title),i.col_width(t.settings.col_width)):("datasource"==a.type&&(i.name(t.settings.name),delete t.settings.name),i.type(t.type),i.settings(t.settings)))})}})}},ko.virtualElements.allowedBindings.datasourceTypeSettings=!0,ko.bindingHandlers.datasourceTypeSettings={update:function(e,t,n,i,a){processPluginSettings(e,t,n,i,a)}},ko.bindingHandlers.grid={init:function(t){a=$(t).gridster({widget_margins:[s,s],widget_base_dimensions:[o,10],resize:{enabled:!0,axes:"x"}}).data("gridster"),e(!1),a.disable()}},ko.bindingHandlers.pane={init:function(e,i,s,o,r){l.isEditing()&&$(e).css({cursor:"pointer"});var d=n(o),u=d.col,p=d.row,f=Number(o.width()),h=Number(o.getCalculatedHeight());a.add_widget(e,f,h,u,p),r.$root.isEditing()&&c.showPaneEditIcons(!0),t(o,p,u),$(e).attrchange({trackValues:!0,callback:function(e){"data-row"==e.attributeName?t(o,Number(e.newValue),void 0):"data-col"==e.attributeName&&t(o,void 0,Number(e.newValue))}})},update:function(e,t,n,i){-1==l.panes.indexOf(i)&&a.remove_widget(e);var s=i.getCalculatedHeight();(s!=Number($(e).attr("data-sizey"))||i.col_width()!=Number($(e).attr("data-sizex")))&&a.resize_widget($(e),i.col_width(),s,function(){a.set_dom_grid_height()})}},ko.bindingHandlers.widget={init:function(e){l.isEditing()&&c.attachWidgetEditIcons($(e).parent())},update:function(e,t,n,i){i.shouldRender()&&($(e).empty(),i.render(e))}},$(function(){function t(){e(!0)}c.showLoadingIndicator(!0);var n;$(window).resize(function(){clearTimeout(n),n=setTimeout(t,500)})}),{initialize:function(e,t){ko.applyBindings(l);var n=i("load");""!=n?$.ajax({url:n,success:function(e){l.loadDashboard(e),_.isFunction(t)&&t()}}):(l.allow_edit(e),l.setEditing(e),c.showLoadingIndicator(!1),_.isFunction(t)&&t(),freeboard.emit("initialized"))},newDashboard:function(){l.loadDashboard({allow_edit:!0})},loadDashboard:function(e,t){l.loadDashboard(e,t)},serialize:function(){return l.serialize()},setEditing:function(e,t){l.setEditing(e,t)},isEditing:function(){return l.isEditing()},loadDatasourcePlugin:function(e){_.isUndefined(e.display_name)&&(e.display_name=e.type_name),e.settings.unshift({name:"name",display_name:"Name",type:"text",required:!0}),l.addPluginSource(e.source),r[e.type_name]=e,l._datasourceTypes.valueHasMutated()},resize:function(){e(!0)},loadWidgetPlugin:function(e){_.isUndefined(e.display_name)&&(e.display_name=e.type_name),l.addPluginSource(e.source),d[e.type_name]=e,l._widgetTypes.valueHasMutated()},setAssetRoot:function(e){u.setAssetRoot(e)},addStyle:function(e,t){var n,i=document;"object"==typeof i.styleSheets&&(i.styleSheets.length&&(n=i.styleSheets[i.styleSheets.length-1]),i.styleSheets.length&&(i.createStyleSheet?n=i.createStyleSheet():(i.getElementsByTagName("head")[0].appendChild(i.createElement("style")),n=i.styleSheets[i.styleSheets.length-1])),n.addRule?n.addRule(e,t):n.insertRule(e+"{"+t+"}",n.cssRules.length))},showLoadingIndicator:function(e){c.showLoadingIndicator(e)},showDialog:function(e,t,n,i,a){new DialogBox(e,t,n,i,a)},getDatasourceSettings:function(e){var t=l.datasources(),n=_.find(t,function(t){return t.name()===e});return n?n.settings():null},setDatasourceSettings:function(e,t){var n=l.datasources(),i=_.find(n,function(t){return t.name()===e});if(!i)return console.log("Datasource not found"),void 0;var a=_.defaults(t,i.settings());i.settings(a)},getStyleString:function(e){var t="";return _.each(g[e],function(e,n){t=t+n+":"+e+";"}),t},getStyleObject:function(e){return g[e]},showDeveloperConsole:function(){h.showDeveloperConsole()},_removeAllWidgets:function(){a.remove_all_widgets()},_disableGrid:function(){a.disable()},_enableGrid:function(){a.enable()},_getPositionForScreenSize:function(e){return n(e)}}}();$.extend(freeboard,jQuery.eventEmitter);
\ No newline at end of file
+function DialogBox(e,t,n,i,a){function s(){o.fadeOut(200,function(){$(this).remove()})}var o=$('
'),r=$('
');r.append('"),$("").appendTo(r).append(e);var d=$("").appendTo(r);n&&$(''+n+" ").appendTo(d).click(function(){var e=!1;_.isFunction(a)&&(e=a()),e||s()}),i&&$(''+i+" ").appendTo(d).click(function(){s()}),o.append(r),$("body").append(o),o.fadeIn(200)}function FreeboardModel(e,t,n){var i=this,a=1;this.version=0,this.isEditing=ko.observable(!1),this.allow_edit=ko.observable(!1),this.allow_edit.subscribe(function(e){e?$("#main-header").show():$("#main-header").hide()}),this.header_image=ko.observable(),this.plugins=ko.observableArray(),this.datasources=ko.observableArray(),this.panes=ko.observableArray(),this.datasourceData={},this.processDatasourceUpdate=function(e,t){var n=e.name();i.datasourceData[n]=t,_.each(i.panes(),function(e){_.each(e.widgets(),function(e){e.processDatasourceUpdate(n)})})},this._datasourceTypes=ko.observable(),this.datasourceTypes=ko.computed({read:function(){i._datasourceTypes();var t=[];return _.each(e,function(e){var n=e.type_name,i=n;_.isUndefined(e.display_name)||(i=e.display_name),t.push({name:n,display_name:i})}),t}}),this._widgetTypes=ko.observable(),this.widgetTypes=ko.computed({read:function(){i._widgetTypes();var e=[];return _.each(t,function(t){var n=t.type_name,i=n;_.isUndefined(t.display_name)||(i=t.display_name),e.push({name:n,display_name:i})}),e}}),this.addPluginSource=function(e){e&&-1==i.plugins.indexOf(e)&&i.plugins.push(e)},this.serialize=function(){var e=[];_.each(i.panes(),function(t){e.push(t.serialize())});var t=[];return _.each(i.datasources(),function(e){t.push(e.serialize())}),{version:a,header_image:i.header_image(),allow_edit:i.allow_edit(),plugins:i.plugins(),panes:e,datasources:t}},this.deserialize=function(n,a){function s(){_.isUndefined(n.allow_edit)?i.allow_edit(!0):i.allow_edit(n.allow_edit),i.version=n.version||0,i.header_image(n.header_image),_.each(n.datasources,function(t){var n=new DatasourceModel(i,e);n.deserialize(t),i.addDatasource(n)});var s=_.sortBy(n.panes,function(e){return freeboard._getPositionForScreenSize(e).row});_.each(s,function(e){var n=new PaneModel(i,t);n.deserialize(e),i.panes.push(n)}),i.allow_edit()&&0==i.panes().length&&i.setEditing(!0),_.isFunction(a)&&a()}i.clearDashboard(),_.each(n.plugins,function(e){i.addPluginSource(e)}),_.isArray(n.plugins)&&n.plugins.length>0?head.js(n.plugins,function(){s()}):s()},this.clearDashboard=function(){freeboard._removeAllWidgets(),_.each(i.datasources(),function(e){e.dispose()}),_.each(i.panes(),function(e){e.dispose()}),i.plugins.removeAll(),i.datasources.removeAll(),i.panes.removeAll()},this.loadDashboard=function(e,t){n.showLoadingIndicator(!0),i.deserialize(e,function(){n.showLoadingIndicator(!1),_.isFunction(t)&&t(),freeboard.emit("dashboard_loaded")})},this.loadDashboardFromLocalFile=function(){if(window.File&&window.FileReader&&window.FileList&&window.Blob){var e=document.createElement("input");e.type="file",$(e).on("change",function(e){var t=e.target.files;if(t&&t.length>0){var n=t[0],a=new FileReader;a.addEventListener("load",function(e){var t=e.target,n=JSON.parse(t.result);i.loadDashboard(n),i.setEditing(!1)}),a.readAsText(n)}}),$(e).trigger("click")}else alert("Unable to load a file in this browser.")},this.saveDashboard=function(){var e="application/octet-stream",t=document.createElement("a"),n=new Blob([JSON.stringify(i.serialize())],{type:e});document.body.appendChild(t),t.href=window.URL.createObjectURL(n),t.download="dashboard.json",t.target="_self",t.click()},this.addDatasource=function(e){i.datasources.push(e)},this.deleteDatasource=function(e){delete i.datasourceData[e.name()],e.dispose(),i.datasources.remove(e)},this.createPane=function(){var e=new PaneModel(i,t);i.addPane(e)},this.addPane=function(e){i.panes.push(e)},this.deletePane=function(e){e.dispose(),i.panes.remove(e)},this.deleteWidget=function(e){ko.utils.arrayForEach(i.panes(),function(t){t.widgets.remove(e)}),e.dispose()},this.setEditing=function(e,t){if(i.allow_edit()||!e){i.isEditing(e),_.isUndefined(t)&&(t=!0);var a=t?250:0,s=$("#admin-bar").outerHeight();e?($("#toggle-header-icon").addClass("icon-chevron-up").removeClass("icon-wrench"),$(".gridster .gs_w").css({cursor:"pointer"}),$("#main-header").animate({top:"0px"},a),$("#board-content").animate({top:s+20+"px"},a),$("#main-header").data().shown=!0,n.attachWidgetEditIcons($(".sub-section")),freeboard._enableGrid()):($("#toggle-header-icon").addClass("icon-wrench").removeClass("icon-chevron-up"),$(".gridster .gs_w").css({cursor:"default"}),$("#main-header").animate({top:"-"+s+"px"},a),$("#board-content").animate({top:"20"},a),$("#main-header").data().shown=!1,$(".sub-section").unbind(),freeboard._disableGrid()),n.showPaneEditIcons(e,t)}},this.toggleEditing=function(){var e=!i.isEditing();i.setEditing(e)}}function FreeboardUI(){function e(e){e?a.fadeOut(0).appendTo("body").fadeIn(500):a.fadeOut(500).remove()}function t(e,t){_.isUndefined(t)&&(t=!0);var n=t?250:0;e?$(".pane-tools").fadeIn(n):$(".pane-tools").fadeOut(n)}function n(e){$(e).hover(function(){i(this,!0)},function(){i(this,!1)})}function i(e,t){t?$(e).find(".sub-section-tools").fadeIn(250):$(e).find(".sub-section-tools").fadeOut(250)}var a=$('');return{showLoadingIndicator:function(t){e(t)},showPaneEditIcons:function(e,n){t(e,n)},attachWidgetEditIcons:function(e){n(e)}}}function PaneModel(e,t){var n=this;this.title=ko.observable(),this.width=ko.observable(1),this.row={},this.col={},this.col_width=ko.observable(1),this.widgets=ko.observableArray(),this.addWidget=function(e){this.widgets.push(e)},this.widgetCanMoveUp=function(e){return n.widgets.indexOf(e)>=1},this.widgetCanMoveDown=function(e){var t=n.widgets.indexOf(e);return n.widgets().length-1>t},this.moveWidgetUp=function(e){if(n.widgetCanMoveUp(e)){var t=n.widgets.indexOf(e),i=n.widgets();n.widgets.splice(t-1,2,i[t],i[t-1])}},this.moveWidgetDown=function(e){if(n.widgetCanMoveDown(e)){var t=n.widgets.indexOf(e),i=n.widgets();n.widgets.splice(t,2,i[t+1],i[t])}},this.getCalculatedHeight=function(){var e=_.reduce(n.widgets(),function(e,t){return e+t.height()},0);e*=6,e+=3,e*=10;var t=Math.ceil((e+20)/30);return Math.max(4,t)},this.serialize=function(){var e=[];return _.each(n.widgets(),function(t){e.push(t.serialize())}),{title:n.title(),width:n.width(),row:n.row,col:n.col,col_width:n.col_width(),widgets:e}},this.deserialize=function(i){n.title(i.title),n.width(i.width),n.row=i.row,n.col=i.col,n.col_width(i.col_width||1),_.each(i.widgets,function(i){var a=new WidgetModel(e,t);a.deserialize(i),n.widgets.push(a)})},this.dispose=function(){_.each(n.widgets(),function(e){e.dispose()})}}function WidgetModel(e,t){function n(){_.isUndefined(i.widgetInstance)||(_.isFunction(i.widgetInstance.onDispose)&&i.widgetInstance.onDispose(),i.widgetInstance=void 0)}var i=this;this.datasourceRefreshNotifications={},this.calculatedSettingScripts={},this.title=ko.observable(),this.fillSize=ko.observable(!1),this.type=ko.observable(),this.type.subscribe(function(e){function a(){s.newInstance(i.settings(),function(e){i.fillSize(s.fill_size===!0),i.widgetInstance=e,i.shouldRender(!0),i._heightUpdate.valueHasMutated()})}if(n(),e in t&&_.isFunction(t[e].newInstance)){var s=t[e];s.external_scripts?head.js(s.external_scripts.slice(0),a):a()}}),this.settings=ko.observable({}),this.settings.subscribe(function(e){!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.onSettingsChanged)&&i.widgetInstance.onSettingsChanged(e),i.updateCalculatedSettings(),i._heightUpdate.valueHasMutated()}),this.processDatasourceUpdate=function(e){var t=i.datasourceRefreshNotifications[e];_.isArray(t)&&_.each(t,function(e){i.processCalculatedSetting(e)})},this.callValueFunction=function(t){return t.call(void 0,e.datasourceData)},this.processCalculatedSetting=function(e){if(_.isFunction(i.calculatedSettingScripts[e])){var t=void 0;try{t=i.callValueFunction(i.calculatedSettingScripts[e])}catch(n){var a=i.settings()[e];n instanceof ReferenceError&&/^\w+$/.test(a)&&(t=a)}if(!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.onCalculatedValueChanged)&&!_.isUndefined(t))try{i.widgetInstance.onCalculatedValueChanged(e,t)}catch(n){console.log(""+n)}}},this.updateCalculatedSettings=function(){if(i.datasourceRefreshNotifications={},i.calculatedSettingScripts={},!_.isUndefined(i.type())){var e=t[i.type()].settings,n=RegExp("datasources.([\\w_-]+)|datasources\\[['\"]([^'\"]+)","g"),a=i.settings();_.each(e,function(e){if("calculated"==e.type){var t=a[e.name];if(!_.isUndefined(t)){1>=(t.match(/;/g)||[]).length&&-1==t.indexOf("return")&&(t="return "+t);var s;try{s=Function("datasources",t)}catch(o){var r=a[e.name].replace(/"/g,'\\"').replace(/[\r\n]/g," \\\n");s=Function("datasources",'return "'+r+'";')}i.calculatedSettingScripts[e.name]=s,i.processCalculatedSetting(e.name);for(var d;d=n.exec(t);){var c=d[1]||d[2],l=i.datasourceRefreshNotifications[c];_.isUndefined(l)&&(l=[],i.datasourceRefreshNotifications[c]=l),l.push(e.name)}}}})}},this._heightUpdate=ko.observable(),this.height=ko.computed({read:function(){return i._heightUpdate(),!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.getHeight)?i.widgetInstance.getHeight():1}}),this.shouldRender=ko.observable(!1),this.render=function(e){i.shouldRender(!1),!_.isUndefined(i.widgetInstance)&&_.isFunction(i.widgetInstance.render)&&(i.widgetInstance.render(e),i.updateCalculatedSettings())},this.dispose=function(){},this.serialize=function(){return{title:i.title(),type:i.type(),settings:i.settings()}},this.deserialize=function(e){i.title(e.title),i.settings(e.settings),i.type(e.type)}}DatasourceModel=function(e,t){function n(){_.isUndefined(i.datasourceInstance)||(_.isFunction(i.datasourceInstance.onDispose)&&i.datasourceInstance.onDispose(),i.datasourceInstance=void 0)}var i=this;this.name=ko.observable(),this.latestData=ko.observable(),this.settings=ko.observable({}),this.settings.subscribe(function(e){!_.isUndefined(i.datasourceInstance)&&_.isFunction(i.datasourceInstance.onSettingsChanged)&&i.datasourceInstance.onSettingsChanged(e)}),this.updateCallback=function(t){e.processDatasourceUpdate(i,t),i.latestData(t);var n=new Date;i.last_updated(n.toLocaleTimeString())},this.type=ko.observable(),this.type.subscribe(function(e){function a(){s.newInstance(i.settings(),function(e){i.datasourceInstance=e,e.updateNow()},i.updateCallback)}if(n(),e in t&&_.isFunction(t[e].newInstance)){var s=t[e];s.external_scripts?head.js(s.external_scripts.slice(0),a):a()}}),this.last_updated=ko.observable("never"),this.last_error=ko.observable(),this.serialize=function(){return{name:i.name(),type:i.type(),settings:i.settings()}},this.deserialize=function(e){i.settings(e.settings),i.name(e.name),i.type(e.type)},this.getDataRepresentation=function(e){var t=Function("data","return "+e+";");return t.call(void 0,i.latestData())},this.updateNow=function(){!_.isUndefined(i.datasourceInstance)&&_.isFunction(i.datasourceInstance.updateNow)&&i.datasourceInstance.updateNow()},this.dispose=function(){n()}},DeveloperConsole=function(e){function t(){function t(e){var t=$(" "),i=$(''),a=$(' '),s=$(' ').click(function(){n=_.without(n,a),t.remove()});n.push(a),e&&a.val(e),i.append(s),o.append(t.append($(" ").append(a)).append($('').append(i)))}var n=[],i=$("
"),a=$('ADD
'),s=$('');s.append($('Plugin Script URL '));var o=$(" ");s.append(o),i.append($("Here you can add references to other scripts to load datasource or widget plugins.
")).append(s).append(a).append('To learn how to build plugins for freeboard, please visit http://freeboard.github.io/freeboard/docs/plugin_example.html
'),_.each(e.plugins(),function(e){t(e)}),a.click(function(){t()}),new DialogBox(i,"Developer Console","OK",null,function(){_.each(e.plugins(),function(e){$('script[src^="'+e+'"]').remove()}),e.plugins.removeAll(),_.each(n,function(t){var n=t.val();n&&n.length>0&&(e.addPluginSource(n),head.js(n+"?"+Date.now()))})})}return{showDeveloperConsole:function(){t()}}},JSEditor=function(){function e(e){n=e}function t(e,t){head.js(n+"css/codemirror.css",n+"css/codemirror-ambiance.css",n+"js/codemirror.js",function(){var n='// Example: Convert temp from C to F and truncate to 2 decimal places.\n// return (datasources["MyDatasource"].sensor.tempInF * 1.8 + 32).toFixed(2);';e||(e=n);var i=$('
'),a=$('
'),s=$(''),o=$('');i.append([o,a,s]),$("body").append(i);var r=CodeMirror(a.get(0),{value:e,mode:"javascript",theme:"ambiance",indentUnit:4,lineNumbers:!0,matchBrackets:!0,autoCloseBrackets:!0}),d=$('Close ').click(function(){if(t){var e=r.getValue();e===n&&(e=""),t(e),i.remove()}});s.append(d)})}var n="";return{displayJSEditor:function(e,n){t(e,n)},setAssetRoot:function(){e(_assetRoot)}}},PluginEditor=function(e,t){function n(e,t){var n=$('
').html(t);$("#setting-value-container-"+e).append(n)}function i(){$("#setting-row-instance-name").length?$("#setting-row-instance-name").nextAll().remove():$("#setting-row-plugin-types").nextAll().remove()}function a(e){return!isNaN(parseFloat(e))&&isFinite(e)}function s(s,o,r,d,c){function l(e,t){var n=$('
').appendTo(h);return n.append(''+t+"
"),$('
').appendTo(n)}function u(n){_.each(n,function(n){function i(){f.settings[n.name].length>0?u.show():u.hide()}function a(e){var t=$(" ").appendTo(h),a={};_.isArray(f.settings[n.name])||(f.settings[n.name]=[]),f.settings[n.name].push(a),_.each(n.settings,function(n){var i=$(" ").appendTo(t),s="";_.isUndefined(e[n.name])||(s=e[n.name]),a[n.name]=s,$(' ').appendTo(i).val(s).change(function(){a[n.name]=$(this).val()})}),t.append($(' ').append($('').append($(" ").append($(' ').click(function(){var e=f.settings[n.name].indexOf(a);-1!=e&&(f.settings[n.name].splice(e,1),t.remove(),i())}))))),r.scrollTop(r[0].scrollHeight),i()}!_.isUndefined(n.default_value)&&_.isUndefined(d[n.name])&&(d[n.name]=n.default_value);var s=n.name;_.isUndefined(n.display_name)||(s=n.display_name);var o=l(n.name,s);switch(n.type){case"array":var r=$('
').appendTo(o),c=$('').appendTo(r),u=$(" ").hide().appendTo(c),p=$(" ").appendTo(u),h=$(" ").appendTo(c),g=[];_.each(n.settings,function(e){var t=e.name;_.isUndefined(e.display_name)||(t=e.display_name),$(""+t+" ").appendTo(p)}),n.name in d&&(g=d[n.name]),$('ADD
').appendTo(o).click(function(){var e={};_.each(n.settings,function(t){e[t.name]=""}),a(e)}),_.each(g,function(e){a(e)});break;case"boolean":f.settings[n.name]=d[n.name];var v=$('').appendTo(o),m=$(' ').prependTo(v).change(function(){f.settings[n.name]=this.checked});n.name in d&&m.prop("checked",d[n.name]);break;case"option":var w=d[n.name],m=$(" ").appendTo($('
').appendTo(o)).change(function(){f.settings[n.name]=$(this).val()});_.each(n.options,function(e){var t,n;_.isObject(e)?(t=e.name,n=e.value):t=e,_.isUndefined(n)&&(n=t),_.isUndefined(w)&&(w=n),$(" ").text(t).attr("value",n).appendTo(m)}),f.settings[n.name]=w,n.name in d&&m.val(d[n.name]);break;default:if(f.settings[n.name]=d[n.name],"calculated"==n.type){var m=$("").appendTo(o).change(function(){f.settings[n.name]=$(this).val()});n.name in d&&m.val(d[n.name]),t.createValueEditor(m);var b=$(''),y=$('DATASOURCE ').mousedown(function(e){e.preventDefault(),$(m).focus(),$(m).insertAtCaret('datasources["'),$(m).trigger("freeboard-eval")}),k=$('.JS EDITOR ').mousedown(function(t){t.preventDefault(),e.displayJSEditor(m.val(),function(e){m.val(e),m.change()})});$(o).append(b.append([y,k]))}else{var m=$(' ').appendTo(o).change(function(){f.settings[n.name]="number"==n.type?Number($(this).val()):$(this).val()});n.name in d&&m.val(d[n.name])}}_.isUndefined(n.suffix)||o.append($(''+n.suffix+"
")),_.isUndefined(n.description)||o.append($(''+n.description+"
"))})}var p,f={type:r,settings:{}},h=$("
"),g=$('
').hide();h.append(g),new DialogBox(h,s,"Save","Cancel",function(){$(".validation-error").remove();for(var e=0;p.settings.length>e;e++){var t=p.settings[e];if(t.required&&(_.isUndefined(f.settings[t.name])||""==f.settings[t.name]))return n(t.name,"This is required."),!0;if("number"==t.type&&!a(f.settings[t.name]))return n(t.name,"Must be a number."),!0}_.isFunction(c)&&c(f)});var v,m=_.keys(o);if(m.length>1){var w=l("plugin-types","Type");v=$(" ").appendTo($('
').appendTo(w)),v.append($("Select a type... ").attr("value","undefined")),_.each(o,function(e){v.append($(" ").text(e.display_name).attr("value",e.type_name))}),v.change(function(){f.type=$(this).val(),f.settings={},i(),p=o[v.val()],_.isUndefined(p)?($("#setting-row-instance-name").hide(),$("#dialog-ok").hide()):($("#setting-row-instance-name").show(),p.description&&p.description.length>0?g.html(p.description).show():g.hide(),$("#dialog-ok").show(),u(p.settings))})}else 1==m.length&&(p=o[m[0]],u(p.settings));v&&(_.isUndefined(r)?($("#setting-row-instance-name").hide(),$("#dialog-ok").hide()):($("#dialog-ok").show(),v.val(r).trigger("change")))}return{createPluginEditor:function(e,t,n,i,a,o){s(e,t,n,i,a,o)}}},ValueEditor=function(e){function t(e){var t=($(e).val().match(/\n/g)||[]).length,n=Math.min(200,20*(t+1));$(e).css({height:n+"px"})}function n(e,t){var n,i=s.exec(e),r=[];if(i)if(""==i[1])_.each(t,function(e){r.push({value:e.name(),follow_char:'"]["'})});else if(""!=i[1]&&_.isUndefined(i[2]))n=i[1],_.each(t,function(e){var t=e.name();t!=n&&0==t.indexOf(n)&&r.push({value:t,follow_char:'"]["'})});else{var d=_.find(t,function(e){return e.name()===i[1]});if(!_.isUndefined(d)){var c="";_.isUndefined(i[2])||(c=i[2]+i[3]);var l=c.split('"]["');c="data";for(var u=1;l.length-1>u;u++)""!=l[u]&&(dataPathItem='["'+l[u]+'"]',c+=dataPathItem);var p=_.last(l);'"'==p.charAt(p.length-1)&&(p=p.replace(/\[\"?$/,""),c=c+'["'+p+'"]');var f=d.getDataRepresentation(c);if(_.isArray(f))for(var u=0;f.length>u;u++){var h='"]';_.isObject(f[u])?h+='"]["':_.isArray(f[u])&&(h+='"]['),r.push({value:u,follow_char:h})}else _.isObject(f)&&(n=p,-1==_.keys(f).indexOf(n)&&_.each(f,function(e,t){if(t!=p&&0==t.indexOf(p)){var n='"]';_.isArray(e)?n='"][':_.isObject(e)&&(n='"]["'),r.push({value:t,follow_char:n})}}))}}o=r,a=n}function i(i){var s=null,r=0;$(i).addClass("calculated-value-input").bind("keyup mouseup freeboard-eval",function(t){if(s&&"keyup"==t.type&&(38==t.keyCode||40==t.keyCode||13==t.keyCode))return t.preventDefault(),void 0;var d=$(i).val().substring(0,$(i).getCaretPosition());if(d=d.replace(String.fromCharCode(160)," "),n(d,e.datasources()),o.length>0){s||(s=$('').insertAfter(i).width($(i).outerWidth()-2).css("left",$(i).position().left).css("top",$(i).position().top+$(i).outerHeight()-1)),s.empty(),s.scrollTop(0);var c=!0;r=0;var l=0;_.each(o,function(e){var t=$(""+e.value+" ").appendTo(s).mouseenter(function(){$(this).trigger("freeboard-select")}).mousedown(function(e){$(this).trigger("freeboard-insertValue"),e.preventDefault()}).data("freeboard-optionIndex",l).data("freeboard-optionValue",e.value).bind("freeboard-insertValue",function(){var t=e.value;if(_.isUndefined(e.follow_char)||(t+=e.follow_char),_.isUndefined(a))$(i).insertAtCaret(t);else{var n=d.lastIndexOf(a);-1!=n&&$(i).replaceTextAt(n,n+a.length,t)}$(i).triggerHandler("mouseup")}).bind("freeboard-select",function(){$(this).parent().find("li.selected").removeClass("selected"),$(this).addClass("selected"),r=$(this).data("freeboard-optionIndex")});c&&($(t).addClass("selected"),c=!1),l++})}else $(i).next("ul#value-selector").remove(),s=null,r=-1}).focus(function(){t(i)}).focusout(function(){$(i).css({height:""}),$(i).next("ul#value-selector").remove(),s=null,r=-1}).bind("keydown",function(e){if(s)if(38==e.keyCode||40==e.keyCode){e.preventDefault();var t=$(s).find("li");38==e.keyCode?r--:40==e.keyCode&&r++,0>r?r=t.size()-1:r>=t.size()&&(r=0);var n=$(t).eq(r);n.trigger("freeboard-select"),$(s).scrollTop($(n).position().top)}else 13==e.keyCode&&(e.preventDefault(),-1!=r&&$(s).find("li").eq(r).trigger("freeboard-insertValue"))})}var a,s=RegExp('.*datasources\\["([^"]*)("\\]\\[")?(.*)$'),o=[];return{createValueEditor:function(e){i(e)}}},function(e){function t(){var e=document.createElement("p"),t=!1;if(e.addEventListener)e.addEventListener("DOMAttrModified",function(){t=!0},!1);else{if(!e.attachEvent)return!1;e.attachEvent("onDOMAttrModified",function(){t=!0})}return e.setAttribute("id","target"),t}function n(t,n){if(t){var i=this.data("attr-old-value");if(n.attributeName.indexOf("style")>=0){i.style||(i.style={});var a=n.attributeName.split(".");n.attributeName=a[0],n.oldValue=i.style[a[1]],n.newValue=a[1]+":"+this.prop("style")[e.camelCase(a[1])],i.style[a[1]]=n.newValue}else n.oldValue=i[n.attributeName],n.newValue=this.attr(n.attributeName),i[n.attributeName]=n.newValue;this.data("attr-old-value",i)}}var i=window.MutationObserver||window.WebKitMutationObserver;e.fn.attrchange=function(a){var s={trackValues:!1,callback:e.noop};if("function"==typeof a?s.callback=a:e.extend(s,a),s.trackValues&&e(this).each(function(t,n){for(var i,a={},t=0,s=n.attributes,o=s.length;o>t;t++)i=s.item(t),a[i.nodeName]=i.value;e(this).data("attr-old-value",a)}),i){var o={subtree:!1,attributes:!0,attributeOldValue:s.trackValues},r=new i(function(t){t.forEach(function(t){var n=t.target;s.trackValues&&(t.newValue=e(n).attr(t.attributeName)),s.callback.call(n,t)})});return this.each(function(){r.observe(this,o)})}return t()?this.on("DOMAttrModified",function(e){e.originalEvent&&(e=e.originalEvent),e.attributeName=e.attrName,e.oldValue=e.prevValue,s.callback.call(this,e)}):"onpropertychange"in document.body?this.on("propertychange",function(t){t.attributeName=window.event.propertyName,n.call(e(this),s.trackValues,t),s.callback.call(this,t)}):this}}(jQuery),function(e){e.eventEmitter={_JQInit:function(){this._JQ=e(this)},emit:function(e,t){!this._JQ&&this._JQInit(),this._JQ.trigger(e,t)},once:function(e,t){!this._JQ&&this._JQInit(),this._JQ.one(e,t)},on:function(e,t){!this._JQ&&this._JQInit(),this._JQ.bind(e,t)},off:function(e,t){!this._JQ&&this._JQInit(),this._JQ.unbind(e,t)}}}(jQuery);var freeboard=function(){function e(e){var t=a.$el;t.find("> li").unbind().removeData(),$(".gridster").css("width",""),a.generate_grid_and_stylesheet(),e&&t.find("> li").each(function(){var e=this,t=ko.dataFor(e),i=n(t);$(e).attr("data-row",i.row).attr("data-col",i.col)}),a.init(),$(".gridster").css("width",300*a.cols+20*a.cols)}function t(e,t,n){var i=a.cols;_.isUndefined(t)||(e.row[i]=t),_.isUndefined(n)||(e.col[i]=n)}function n(e,t){var n=_.isUndefined(t)?a.cols:t;if(_.isNumber(e.row)&&_.isNumber(e.col)){var i={};i[n]=e.row,e.row=i,i={},i[n]=e.col,e.col=i}var s=1,o=1e3;for(var r in e.col){if(r==n)return{row:e.row[r],col:e.col[r]};if(e.col[r]>n)s=n;else{var d=n-r;o>d&&(s=r,o=d)}}return s in e.col&&s in e.row?{row:e.row[s],col:e.col[s]}:{row:1,col:s}}function i(e){e=e.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var t=RegExp("[\\?&]"+e+"=([^]*)"),n=t.exec(location.search);return null==n?"":decodeURIComponent(n[1].replace(/\+/g," "))}var a,s=10,o=300,r={},d={},c=new FreeboardUI,l=new FreeboardModel(r,d,c),u=new JSEditor,p=new ValueEditor(l),f=new PluginEditor(u,p),h=new DeveloperConsole(l),g={values:{"font-family":'"HelveticaNeue-UltraLight", "Helvetica Neue Ultra Light", "Helvetica Neue", sans-serif',color:"#d3d4d4","font-weight":100}};return ko.bindingHandlers.pluginEditor={init:function(e,t,n,i){var a=ko.unwrap(t()),s={},o=void 0,u="";"datasource"==a.type?(s=r,u="Datasource"):"widget"==a.type?(s=d,u="Widget"):"pane"==a.type&&(u="Pane"),$(e).click(function(){if("delete"==a.operation){var t=$("Are you sure you want to delete this "+u+"?
");new DialogBox(t,"Confirm Delete","Yes","No",function(){"datasource"==a.type?l.deleteDatasource(i):"widget"==a.type?l.deleteWidget(i):"pane"==a.type&&l.deletePane(i)})}else{var n=void 0;"datasource"==a.type?"add"==a.operation?o={}:(n=i.type(),o=i.settings(),o.name=i.name()):"widget"==a.type?"add"==a.operation?o={}:(n=i.type(),o=i.settings()):"pane"==a.type&&(o={},"edit"==a.operation&&(o.title=i.title(),o.col_width=i.col_width()),s={settings:{settings:[{name:"title",display_name:"Title",type:"text"},{name:"col_width",display_name:"Columns",type:"number",default_value:1,required:!0}]}}),f.createPluginEditor(u,s,n,o,function(t){if("add"==a.operation){if("datasource"==a.type){var n=new DatasourceModel(l,r);l.addDatasource(n),n.name(t.settings.name),delete t.settings.name,n.settings(t.settings),n.type(t.type)}else if("widget"==a.type){var n=new WidgetModel(l,d);n.settings(t.settings),n.type(t.type),i.widgets.push(n),c.attachWidgetEditIcons(e)}}else"edit"==a.operation&&("pane"==a.type?(i.title(t.settings.title),i.col_width(t.settings.col_width)):("datasource"==a.type&&(i.name(t.settings.name),delete t.settings.name),i.type(t.type),i.settings(t.settings)))})}})}},ko.virtualElements.allowedBindings.datasourceTypeSettings=!0,ko.bindingHandlers.datasourceTypeSettings={update:function(e,t,n,i,a){processPluginSettings(e,t,n,i,a)}},ko.bindingHandlers.grid={init:function(t){a=$(t).gridster({widget_margins:[s,s],widget_base_dimensions:[o,10],resize:{enabled:!0,axes:"x"}}).data("gridster"),e(!1),a.disable()}},ko.bindingHandlers.pane={init:function(e,i,s,o,r){l.isEditing()&&$(e).css({cursor:"pointer"});var d=n(o),u=d.col,p=d.row,f=Number(o.width()),h=Number(o.getCalculatedHeight());a.add_widget(e,f,h,u,p),r.$root.isEditing()&&c.showPaneEditIcons(!0),t(o,p,u),$(e).attrchange({trackValues:!0,callback:function(e){"data-row"==e.attributeName?t(o,Number(e.newValue),void 0):"data-col"==e.attributeName&&t(o,void 0,Number(e.newValue))}})},update:function(e,t,n,i){-1==l.panes.indexOf(i)&&a.remove_widget(e);var s=i.getCalculatedHeight();(s!=Number($(e).attr("data-sizey"))||i.col_width()!=Number($(e).attr("data-sizex")))&&a.resize_widget($(e),i.col_width(),s,function(){a.set_dom_grid_height()})}},ko.bindingHandlers.widget={init:function(e){l.isEditing()&&c.attachWidgetEditIcons($(e).parent())},update:function(e,t,n,i){i.shouldRender()&&($(e).empty(),i.render(e))}},$(function(){function t(){e(!0)}c.showLoadingIndicator(!0);var n;$(window).resize(function(){clearTimeout(n),n=setTimeout(t,500)})}),{initialize:function(e,t){ko.applyBindings(l);var n=i("load");""!=n?$.ajax({url:n,success:function(e){l.loadDashboard(e),_.isFunction(t)&&t()}}):(l.allow_edit(e),l.setEditing(e),c.showLoadingIndicator(!1),_.isFunction(t)&&t(),freeboard.emit("initialized"))},newDashboard:function(){l.loadDashboard({allow_edit:!0})},loadDashboard:function(e,t){l.loadDashboard(e,t)},serialize:function(){return l.serialize()},setEditing:function(e,t){l.setEditing(e,t)},isEditing:function(){return l.isEditing()},loadDatasourcePlugin:function(e){_.isUndefined(e.display_name)&&(e.display_name=e.type_name),e.settings.unshift({name:"name",display_name:"Name",type:"text",required:!0}),l.addPluginSource(e.source),r[e.type_name]=e,l._datasourceTypes.valueHasMutated()},resize:function(){e(!0)},loadWidgetPlugin:function(e){_.isUndefined(e.display_name)&&(e.display_name=e.type_name),l.addPluginSource(e.source),d[e.type_name]=e,l._widgetTypes.valueHasMutated()},setAssetRoot:function(e){u.setAssetRoot(e)},addStyle:function(e,t){var n,i=document;"object"==typeof i.styleSheets&&(i.styleSheets.length&&(n=i.styleSheets[i.styleSheets.length-1]),i.styleSheets.length&&(i.createStyleSheet?n=i.createStyleSheet():(i.getElementsByTagName("head")[0].appendChild(i.createElement("style")),n=i.styleSheets[i.styleSheets.length-1])),n.addRule?n.addRule(e,t):n.insertRule(e+"{"+t+"}",n.cssRules.length))},showLoadingIndicator:function(e){c.showLoadingIndicator(e)},showDialog:function(e,t,n,i,a){new DialogBox(e,t,n,i,a)},getDatasourceSettings:function(e){var t=l.datasources(),n=_.find(t,function(t){return t.name()===e});return n?n.settings():null},setDatasourceSettings:function(e,t){var n=l.datasources(),i=_.find(n,function(t){return t.name()===e});if(!i)return console.log("Datasource not found"),void 0;var a=_.defaults(t,i.settings());i.settings(a)},getStyleString:function(e){var t="";return _.each(g[e],function(e,n){t=t+n+":"+e+";"}),t},getStyleObject:function(e){return g[e]},showDeveloperConsole:function(){h.showDeveloperConsole()},_removeAllWidgets:function(){a.remove_all_widgets()},_disableGrid:function(){a.disable()},_enableGrid:function(){a.enable()},_getPositionForScreenSize:function(e){return n(e)}}}();$.extend(freeboard,jQuery.eventEmitter);
\ No newline at end of file
diff --git a/lib/js/freeboard/ValueEditor.js b/lib/js/freeboard/ValueEditor.js
index b1b5164..19dc95c 100644
--- a/lib/js/freeboard/ValueEditor.js
+++ b/lib/js/freeboard/ValueEditor.js
@@ -1,6 +1,6 @@
ValueEditor = function(theFreeboardModel)
{
- var _veDatasourceRegex = new RegExp(".*datasources\\[\"([^\"]*)(\"\\].)?$");
+ var _veDatasourceRegex = new RegExp(".*datasources\\[\"([^\"]*)(\"\\]\\[\")?(.*)$");
var _autocompleteOptions = [];
var _autocompleteReplacementString;
@@ -27,7 +27,7 @@ ValueEditor = function(theFreeboardModel)
{
_.each(datasources, function(datasource)
{
- options.push({value: datasource.name(), follow_char: "\"]."});
+ options.push({value: datasource.name(), follow_char: "\"][\""});
});
}
else if(match[1] != "" && _.isUndefined(match[2])) // List partial datasources
@@ -40,7 +40,7 @@ ValueEditor = function(theFreeboardModel)
if(dsName != replacementString && dsName.indexOf(replacementString) == 0)
{
- options.push({value: dsName, follow_char: "\"]."});
+ options.push({value: dsName, follow_char: "\"][\""});
}
});
}
@@ -57,27 +57,28 @@ ValueEditor = function(theFreeboardModel)
if(!_.isUndefined(match[2]))
{
- dataPath = match[2];
+ dataPath = match[2] + match[3];
}
- var dataPathItems = dataPath.split(".");
+ var dataPathItems = dataPath.split("\"][\"");
dataPath = "data";
for(var index = 1; index < dataPathItems.length - 1; index++)
{
if(dataPathItems[index] != "")
{
- dataPath = dataPath + "." + dataPathItems[index];
+ dataPathItem = "[\"" + dataPathItems[index] + "\"]";
+ dataPath = dataPath + dataPathItem;
}
}
var lastPathObject = _.last(dataPathItems);
- // If the last character is a [, then ignore it
- if(lastPathObject.charAt(lastPathObject.length - 1) == "[")
+ // If the last character is a ", then ignore it
+ if(lastPathObject.charAt(lastPathObject.length - 1) == "\"")
{
- lastPathObject = lastPathObject.replace(/\[+$/, "");
- dataPath = dataPath + "." + lastPathObject;
+ lastPathObject = lastPathObject.replace(/\[\"?$/, "");
+ dataPath = dataPath + "[\"" + lastPathObject + "\"]";
}
var dataValue = datasource.getDataRepresentation(dataPath);
@@ -86,15 +87,15 @@ ValueEditor = function(theFreeboardModel)
{
for(var index = 0; index < dataValue.length; index++)
{
- var followChar = "]";
+ var followChar = "\"]";
if(_.isObject(dataValue[index]))
{
- followChar = followChar + ".";
+ followChar = followChar + "\"][\"";
}
else if(_.isArray(dataValue[index]))
{
- followChar = followChar + "[";
+ followChar = followChar + "\"][";
}
options.push({value: index, follow_char: followChar});
@@ -110,15 +111,15 @@ ValueEditor = function(theFreeboardModel)
{
if(name != lastPathObject && name.indexOf(lastPathObject) == 0)
{
- var followChar = undefined;
+ var followChar = "\"]";
if(_.isArray(value))
{
- followChar = "[";
+ followChar = "\"][";
}
else if(_.isObject(value))
{
- followChar = ".";
+ followChar = "\"][\"";
}
options.push({value: name, follow_char: followChar});