UNPKG

nodegame-widgets

Version:

Collections of useful and reusable javascript / HTML snippets for nodeGame

15 lines 233 kB
/** * # Widget * Copyright(c) 2020 Stefano Balietti <ste@nodegame.org> * MIT Licensed * * Prototype of a widget class * * Prototype methods will be injected in every new widget, if missing. * * Additional properties can be automatically, depending on configuration. * * @see Widgets.get * @see Widgets.append */ (function(e){"use strict";function r(){}function i(e,t,n,r,i){var s;if(!e.constructor[n].hasOwnProperty(t))throw new Error(r+": name not found: "+t);s="undefined"!=typeof e[n][t]?e[n][t]:e.constructor[n][t];if("function"==typeof s){s=s(e,i);if("string"!=typeof s&&s!==!1)throw new TypeError(r+': cb "'+t+'" did not '+"return neither string or false. Found: "+s)}return s}function s(e,n,r,i,s,o){var u,a,f;s||(s=e.constructor[n]),"undefined"==typeof o&&(o={}),u={};if(t.isArray(s)){a=-1,f=s.length;for(;++a<f;)u[s[a]]=e[r](s[a],o)}else for(a in s)s.hasOwnProperty(a)&&(u[a]=e[r](a,o));return u}function o(e,t,n,r,i){var s;if("object"!=typeof t&&"undefined"!=typeof t)throw new TypeError(i+": "+n+" must be object or undefined. Found: "+t);for(s in t)t.hasOwnProperty(s)&&e[r](s,t[s])}function u(e,t,n,r,i){if("undefined"==typeof e.constructor[r][t])throw new TypeError(i+": name not found: "+t);if("string"!=typeof n&&"function"!=typeof n&&!1!==n)throw new TypeError(i+': value for item "'+t+'" must be string, function or false. '+"Found: "+n);e[r][t]=n}var t=e.JSUS,n=e.NDDB;e.Widget=r,r.prototype.init=function(e){},r.prototype.listeners=function(){},r.prototype.append=function(){},r.prototype.getValues=function(e){},r.prototype.setValues=function(e){},r.prototype.reset=function(e){},r.prototype.highlight=function(e){if(e&&"string"!=typeof e)throw new TypeError(t.funcName(this.constructor)+".highlight: "+"border must be string or undefined. Found: "+e);if(!this.isAppended()||this.isHighlighted())return;this.highlighted=!0,this.bodyDiv.style.border=e||"3px solid red",this.emit("highlighted",e)},r.prototype.unhighlight=function(){if(!this.isHighlighted())return;this.highlighted=!1,this.bodyDiv.style.border="",this.emit("unhighlighted")},r.prototype.isHighlighted=function(){return!!this.highlighted},r.prototype.isDocked=function(){return!!this.docked},r.prototype.isActionRequired=function(e){var t;return this.required?(e=e||{},e.markAttempt=e.markAttempt||!1,e.highlight=e.highlight||!1,t=this.getValues(e),t?t.choice===null||t.isCorrect===!1:!1):!1},r.prototype.collapse=function(){if(!this.panelDiv)return;this.bodyDiv.style.display="none",this.collapsed=!0,this.collapseButton&&(this.collapseButton.src="/images/maximize_small2.png",this.collapseButton.title="Restore"),this.footer&&(this.footer.style.display="none"),this.collapseTarget&&this.collapseTarget.appendChild(this.panelDiv),this.emit("collapsed")},r.prototype.uncollapse=function(){if(!this.panelDiv)return;this.collapseTarget&&this.originalRoot.appendChild(this.panelDiv),this.bodyDiv.style.display="",this.collapsed=!1,this.collapseButton&&(this.collapseButton.src="/images/maximize_small.png",this.collapseButton.title="Minimize"),this.footer&&(this.footer.style.display=""),this.emit("uncollapsed")},r.prototype.isCollapsed=function(){return!!this.collapsed},r.prototype.enable=function(e){if(!this.disabled)return;this.disabled=!1,this.emit("enabled",e)},r.prototype.disable=function(e){if(this.disabled)return;this.disabled=!0,this.emit("disabled",e)},r.prototype.isDisabled=function(){return!!this.disabled},r.prototype.hide=function(){if(!this.panelDiv)return;if(this.hidden)return;this.panelDiv.style.display="none",this.hidden=!0,this.emit("hidden")},r.prototype.show=function(e){this.panelDiv&&this.panelDiv.style.display==="none"&&(this.panelDiv.style.display=e||"",this.hidden=!1,this.emit("shown"))},r.prototype.toggle=function(e){if(!this.panelDiv)return;this.hidden?this.show():this.hide()},r.prototype.isHidden=function(){return!!this.hidden},r.prototype.destroy=null,r.prototype.setTitle=function(e,n){var r;if(!this.panelDiv)throw new Error("Widget.setTitle: panelDiv is missing.");if(!e)this.headingDiv&&(this.panelDiv.removeChild(this.headingDiv),this.headingDiv=null);else{if(!this.headingDiv){if(!n)n={className:"card-header"};else if("object"!=typeof n)throw new TypeError("Widget.setTitle: options must be object or undefined. Found: "+n);this.headingDiv=W.add("div",this.panelDiv,n),r=this.bodyDiv&&this.bodyDiv.childNodes[0]||null,this.panelDiv.insertBefore(this.headingDiv,r)}if(W.isElement(e))this.headingDiv.innerHTML="",this.headingDiv.appendChild(e);else{if("string"!=typeof e)throw new TypeError(t.funcName(this.constructor)+".setTitle: title must be string, "+"HTML element or falsy. Found: "+e);this.headingDiv.innerHTML=e}this.collapsible&&function(e){var t,n;t=document.createElement("span"),t.className="panel-collapse-link",n=document.createElement("img"),n.src="/images/minimize_small.png",t.appendChild(n),t.onclick=function(){e.isCollapsed()?e.uncollapse():e.collapse()},e.headingDiv.appendChild(t)}(this),this.closable&&function(e){var t,n;t=document.createElement("span"),t.className="panel-collapse-link",n=document.createElement("img"),n.src="/images/close_small.png",t.appendChild(n),t.onclick=function(){e.destroy()},e.headingDiv.appendChild(t)}(this),this.info&&function(e){var t,n,r;t=W.add("span",e.headingDiv),t.className="panel-collapse-link",r=W.add("a",t),r.href=e.info,r.target="_blank",n=W.add("img",r),n.src="/images/info.png"}(this)}},r.prototype.setFooter=function(e,n){if(!this.panelDiv)throw new Error("Widget.setFooter: panelDiv is missing.");if(!e)this.footerDiv&&(this.panelDiv.removeChild(this.footerDiv),delete this.footerDiv);else{if(!this.footerDiv){if(!n)n={className:"card-footer"};else if("object"!=typeof n)throw new TypeError("Widget.setFooter: options must be object or undefined. Found: "+n);this.footerDiv=W.add("div",this.panelDiv,n)}if(W.isElement(e))this.footerDiv.innerHTML="",this.footerDiv.appendChild(e);else{if("string"!=typeof e)throw new TypeError(t.funcName(this.constructor)+".setFooter: footer must be string, "+"HTML element or falsy. Found: "+e);this.footerDiv.innerHTML=e}}},r.prototype.setContext=function(){console.log("*** Deprecation warning: setContext no longer available in Bootstrap5.")},r.prototype.addFrame=function(e){if("undefined"==typeof e)e="default";else if("string"!=typeof e||e.trim()==="")throw new TypeError(t.funcName(this.constructor)+".addFrame: context must be a non-empty "+"string or undefined. Found: "+e);this.panelDiv&&this.panelDiv.className.indexOf("panel-")===-1&&W.addClass(this.panelDiv,"panel-"+e),this.bodyDiv&&this.bodyDiv.className.indexOf("panel-body")===-1&&W.addClass(this.bodyDiv,"panel-body")},r.prototype.removeFrame=function(){this.panelDiv&&W.removeClass(this.panelDiv,"panel-[a-z]*"),this.bodyDiv&&W.removeClass(this.bodyDiv,"panel-body")},r.prototype.isAppended=function(){return!!this.panelDiv},r.prototype.isDestroyed=function(){return!!this.destroyed},r.prototype.setSound=function(e,t){u(this,e,t,"sounds","Widget.setSound")},r.prototype.setSounds=function(e){o(this,e,"sounds","setSound",t.funcName(this.constructor)+".setSounds")},r.prototype.getSound=function(e,n){return i(this,e,"sounds",t.funcName(this.constructor)+".getSound",n)},r.prototype.getSounds=function(e,n){return s(this,"sounds","getSound",t.funcName(this.constructor)+".getSounds",e,n)},r.prototype.getAllSounds=function(e){return s(this,"sounds","getSound",t.funcName(this.constructor)+".getAllSounds",undefined,e)},r.prototype.setText=function(e,n){u(this,e,n,"texts",t.funcName(this.constructor)+".setText")},r.prototype.setTexts=function(e){o(this,e,"texts","setText",t.funcName(this.constructor)+".setTexts")},r.prototype.getText=function(e,n){return i(this,e,"texts",t.funcName(this.constructor)+".getText",n)},r.prototype.getTexts=function(e,n){return s(this,"texts","getText",t.funcName(this.constructor)+".getTexts",e,n)},r.prototype.getAllTexts=function(e){return s(this,"texts","getText",t.funcName(this.constructor)+".getAllTexts",undefined,e)},r.prototype.on=function(){n.prototype.on.apply(this,arguments)},r.prototype.off=function(){n.prototype.off.apply(this,arguments)},r.prototype.emit=function(){n.prototype.emit.apply(this,arguments)},r.prototype.throwErr=function(e,n,r){var i;throw i=t.funcName(this.constructor)+"."+n+": ","object"==typeof r?i+=r.stack||r:"string"==typeof r&&(i+=r),e==="TypeError"?new TypeError(i):new Error(i)}})("undefined"!=typeof node?node:module.parent.exports.node),function(e,t){"use strict";function n(){var e;this.widgets={},this.instances=[],this.lastAppended=null,this.docked=[],this.dockedHidden=[],this.boxSelector=null,this.collapseTarget=null,e=this,t.registerSetup("widgets",function(n){var r,i,s;if(!n)return;if(n.widgets)for(r in n.widgets)n.widgets.hasOwnProperty(r)&&e.register(r,n.widgets[r]);n.destroyAll&&e.destroyAll();if(n.append)for(r in n.append)n.append.hasOwnProperty(r)&&(i=n.append[r].root,"function"==typeof i?i=i():"string"==typeof i&&(i=W.getElementById(i)),i||(i=W.getScreen()),i?e.append(r,i,n.append[r]):t.warn("setup widgets: could not find a root for widget "+r+". Requested: "+n.append[r].root));return n.collapseTarget&&("function"==typeof n.collapseTarget?s=n.collapseTarget():"string"==typeof n.collapseTarget?s=W.getElementById(n.collapseTarget):J.isElement(n.collapseTarget)&&(s=n.collapseTarget),s?e.collapseTarget=s:t.warn("setup widgets: could not find collapse target.")),n}),t.on("FRAME_LOADED",function(){t.widgets.garbageCollection()}),t.info("node-widgets: loading")}function r(e,n){var r=e.name||e.id;t.err(n+" not found. "+r+" cannot be loaded")}function i(e,n){var r,i,u,a,f;r=t.widgets.docked,u=r.length;for(i=0;i<u;i++)a?r[i].panelDiv.style.right=o(r[i].panelDiv.style.right)-a+"px":r[i].wid===e&&(a=r[i].dockedOffsetWidth,f=t.widgets.docked.splice(i,1)[0],n&&(t.widgets.dockedHidden.push(f),f.hide(),t.widgets.boxSelector||(t.widgets.boxSelector=t.widgets.append("BoxSelector",document.body,{className:"docked-left",getId:function(e){return e.wid},getDescr:function(e){return e.title},onclick:function(e,n){e.show(),t.widgets.docked.push(e),s(e),this.removeItem(n),this.items.length===0&&(this.destroy(),t.widgets.boxSelector=null)}})),t.widgets.boxSelector.addItem(f)),u--,i--);return!!a}function s(n){var r,s,u,a,f,l;s=200,r=20,f=t.widgets,a=0,f.docked.length>1&&(u=f.docked[f.docked.length-2],a=o(u.panelDiv.style.right),a+=u.panelDiv.offsetWidth),a+=r,n.panelDiv.style.right=a+"px",l=0,a+=n.panelDiv.offsetWidth+s;while(f.docked.length>1&&a>e.innerWidth&&l<f.docked.length-1)i(f.docked[l].wid,!0),l++;n.dockedOffsetWidth=n.panelDiv.offsetWidth+r}function o(e){return parseInt(e.substring(0,e.length-2),10)}n.prototype.register=function(e,n){if("string"!=typeof e)throw new TypeError("Widgets.register: name must be string. Found: "+e);if("function"!=typeof n)throw new TypeError("Widgets.register: w must be function.Found: "+n);return"undefined"==typeof n.sounds&&(n.sounds={}),"undefined"==typeof n.texts&&(n.texts={}),J.mixout(n.prototype,new t.Widget),this.widgets[e]=n,this.widgets[e]},n.prototype.get=function(e,n){var r,s,o,u;if("string"!=typeof e)throw new TypeError("Widgets.get: widgetName must be string.Found: "+e);if(!n)n={};else if("object"!=typeof n)throw new TypeError("Widgets.get: "+e+" options "+"must be object or undefined. Found: "+n);if(n.storeRef===!1&&n.docked===!0)throw new TypeError("Widgets.get: "+e+"options.storeRef cannot be false "+"if options.docked is true.");r=J.getNestedValue(e,this.widgets);if(!r)throw new Error("Widgets.get: "+e+" not found");t.info("creating widget "+e+" v."+r.version);if(!this.checkDependencies(r))throw new Error("Widgets.get: "+e+" has unmet "+"dependencies");s=new r(n),u=n.id;if("undefined"!=typeof u){"number"==typeof u&&(u+="");if("string"!=typeof u)throw new TypeError("Widgets.get: options.id must be string, number or undefined. Found: "+u);if("undefined"!=typeof n.idPrefix){if("string"!=typeof n.idPrefix||"number"==typeof n.idPrefix)throw new TypeError("Widgets.get: options.idPrefix must be string, number or undefined. Found: "+n.idPrefix);u=n.idPrefix+u}s.id=u}else n.widgetStep&&(s.id=t.game.getStepId());"undefined"!=typeof n.title?s.title=n.title:"undefined"!=typeof r.title?s.title=r.title:s.title="&nbsp;",s.panel="undefined"==typeof n.panel?r.panel:n.panel,s.footer="undefined"==typeof n.footer?r.footer:n.footer,s.className=r.className;if(J.isArray(n.className))s.className+=" "+n.className.join(" ");else if("string"==typeof n.className)s.className+=" "+n.className;else if("undefined"!=typeof n.className)throw new TypeError("Widgets.get: className must be array, string, or undefined. Found: "+n.className);s.context="undefined"==typeof n.context?r.context:n.context,s.sounds="undefined"==typeof n.sounds?r.sounds:n.sounds,s.texts="undefined"==typeof n.texts?r.texts:n.texts,s.collapsible=n.collapsible||!1,s.closable=n.closable||!1,s.collapseTarget=n.collapseTarget||this.collapseTarget||null,s.info=n.info||!1,s.hooks={hidden:[],shown:[],collapsed:[],uncollapsed:[],disabled:[],enabled:[],destroyed:[],highlighted:[],unhighlighted:[]},s.destroyOnExit=n.destroyOnExit!==!1;if(n.required||n.requiredChoice||"undefined"!=typeof n.correctChoice)s.required=!0;return s.widgetName=e,s.wid=""+J.randomInt(0,1e19),s.disabled=null,s.highlighted=null,s.collapsed=null,s.hidden=null,s.docked=null,n.disabled&&(s._disabled=!0),n.highlighted&&(s._highlighted=!0),n.collapsed&&(s._collapsed=!0),n.hidden&&(s._hidden=!0),n.docked&&(s._docked=!0),s.init(n),n.listeners!==!1&&(t.events.setRecordChanges(!0),s.listeners.call(s),o=t.events.getChanges(!0),t.events.setRecordChanges(!1)),s.destroy=function(){var n,r,u,a;(function(){try{s.panelDiv&&s.panelDiv.parentNode&&s.panelDiv.parentNode.removeChild(s.panelDiv)}catch(n){t.warn(e+".destroy: error caught: "+n)}})();if(o)for(a in o)if(o.hasOwnProperty(a)){u=o[a],n=-1,r=u.added.length;for(;++n<r;)t.events.ee[a].off(u.added[n].type,u.added[n].listener);n=-1,r=o[a].removed.length;for(;++n<r;)t.events.ee[a].on(u.removed[n].type,u.removed[n].listener)}if(s.storeRef!==!1){n=-1,r=t.widgets.instances.length;for(;++n<r;)if(t.widgets.instances[n].wid===s.wid){t.widgets.instances.splice(n,1);break}t.widgets.lastAppended&&t.widgets.lastAppended.wid===this.wid&&(t.warn("node.widgets.lastAppended destroyed."),t.widgets.lastAppended=null)}this.docked?i(s.wid,!1):t.window&&t.window.adjustFrameHeight(undefined,120),this.destroyed=!0,this.emit("destroyed")},n.storeRef!==!1?this.instances.push(s):s.storeRef=!1,s},n.prototype.append=function(e,t,n){var r;if("string"!=typeof e&&"object"!=typeof e)throw new TypeError("Widgets.append: w must be string or object. Found: "+e);if(!t)t=W.getFrameDocument(),t&&(t=t.body),t||(t=document.body);else if("string"==typeof t){r=W.gid(t);if(!r)throw new Error('Widgets.append: element with id "'+t+'" not found');t=r}if(!J.isElement(t))throw new TypeError("Widgets.append: root must be HTMLElement, string or undefined. Found: "+t);if(n&&"object"!=typeof n)throw new TypeError("Widgets.append: options must be object or undefined. Found: "+n);n=n||{},"undefined"==typeof n.panel&&t===W.getHeader()&&(n.panel=!1),"string"==typeof e&&(e=this.get(e,n)),r=n.panel===!1?!0:e.panel===!1,n.bootstrap5?r={className:r?["ng_widget","no-panel",e.className]:["ng_widget","card",e.className]}:r={className:r?["ng_widget","no-panel",e.className]:["ng_widget","panel","panel-default",e.className]};if(n.docked||e._docked)r.className.push("docked"),this.docked.push(e),e.docked=!0;return e.panelDiv=W.get("div",r),n.title!==!1&&e.title&&(n.bootstrap5?r=n.panel===!1?"no-panel-heading":"card-header":r=n.panel===!1?"no-panel-heading":"panel-heading",e.setTitle(e.title,{className:r})),n.bootstrap5?r=n.panel!==!1?"card-body":"no-panel-body":r=n.panel!==!1?"panel-body":"no-panel-body",e.bodyDiv=W.append("div",e.panelDiv,{className:r}),e.footer&&(n.bootstrap5?r=n.panel===!1?"no-panel-heading":"card-footer":r=n.panel===!1?"no-panel-heading":"panel-heading",e.setFooter(e.footer)),e.context&&e.setContext(e.context),(n.hidden||e._hidden)&&e.hide(),(n.collapsed||e._collapsed)&&e.collapse(),t.appendChild(e.panelDiv),e.originalRoot=t,e.append(),(n.highlighted||e._highlighted)&&e.highlight(),(n.disabled||e._disabled)&&e.disable(),e.docked?s(e):!e.isHidden()&&!e.isCollapsed()&&W.adjustFrameHeight(undefined,150),e.storeRef!==!1&&(this.lastAppended=e),e},n.prototype.add=function(e,t,n){return console.log("***Widgets.add is deprecated. Use Widgets.append instead.***"),this.append(e,t,n)},n.prototype.isWidget=function(e,n){return n?e instanceof t.Widget:"object"==typeof e&&"function"==typeof e.append&&"function"==typeof e.getValues&&"function"==typeof e.isHidden&&"function"==typeof e.isCollapsed},n.prototype.destroyAll=function(){var e,n;e=-1,n=this.instances.length;for(;++e<n;)this.instances[0].destroy();this.lastAppended=null,this.instances.length&&t.warn("node.widgets.destroyAll: some widgets could not be destroyed.")},n.prototype.checkDependencies=function(n,i){var s,o,u,a,f;if(!n.dependencies)return!0;s=[e,t,this.widgets,t.window],o=n.dependencies;for(u in o)if(o.hasOwnProperty(u)){a=!1;for(f=0;f<s.length;f++)if(J.getNestedValue(u,s[f])){a=!0;break}if(!a)return i||r(n,u),!1}return!0},n.prototype.garbageCollection=function(){function e(e,t){var n;if(e.contains)return e.contains(t.panelDiv);n=t.panelDiv.parentNode;while(n!=null){if(n==e)return!0;n=n.parentNode}return!1}return function(){var n,r,i,s;s=[],i=W.getFrameDocument(),n=t.widgets.instances;for(r=0;r<n.length;r++)n[r].isAppended()&&i&&!e(i,n[r])&&!e(document.body,n[r])&&(s.push(n[r]),n[r].destroy(),r--);return s}}(),n.prototype.isActionRequired=function(e){var n,r,i,s;n=t.widgets.instances,s=!1;for(r=0;r<n.length;r++)n[r].required&&n[r].isActionRequired(e)&&(s=!0,i=n[r]);return i&&e.highlight&&"function"==typeof i.bodyDiv.scrollIntoView&&i.bodyDiv.scrollIntoView({behavior:"smooth"}),s},t.widgets=new n}("undefined"!=typeof window?window:module.parent.exports.window,"undefined"!=typeof window?window.node:module.parent.exports.node),function(e){"use strict";function t(t){var n;n=this;if("object"==typeof t.button)this.button=t.button;else{if("undefined"!=typeof t.button)throw new TypeError("BackButton constructor: options.button must be object or undefined. Found: "+t.button);this.button=document.createElement("input"),this.button.type="button"}this.button.onclick=function(){var t;n.disable(),t=e.game.stepBack(n.stepOptions),t===!1&&n.enable()},this.stepOptions={acrossStages:null,acrossRounds:null,noZeroStep:!0}}e.widgets.register("BackButton",t),t.version="0.4.0",t.description="Creates a button that if pressed goes to the previous step.",t.title=!1,t.className="backbutton",t.texts.back="Back",t.dependencies={JSUS:{}},t.prototype.init=function(e){var n;e=e||{};if("undefined"==typeof e.id)n=t.className;else if("string"==typeof e.id)n=e.id;else{if(!1!==e.id)throw new TypeError("BackButton.init: opts.id must be string, false, or undefined. Found: "+e.id);n=""}this.button.id=n;if("undefined"==typeof e.className)n="btn btn-lg btn-secondary";else if(e.className===!1)n="";else if("string"==typeof e.className)n=e.className;else{if(!J.isArray(e.className))throw new TypeError("BackButton.init: opts.className must be string, array, or undefined. Found: "+e.className);n=e.className.join(" ")}this.button.className=n,this.button.value="string"==typeof e.text?e.text:this.getText("back"),this.stepOptions.acrossStages="undefined"==typeof e.acrossStages?!1:!!e.acrossStages,this.stepOptions.acrossRounds="undefined"==typeof e.acrossRounds?!0:!!e.acrossRounds},t.prototype.append=function(){e.game.getPreviousStep(1,this.stepOptions)||this.disable(),this.bodyDiv.appendChild(this.button)},t.prototype.listeners=function(){var t=this;e.events.game.on("DONE",function(){t.disable()}),e.events.game.on("PLAYING",function(){var n,r;r=e.game.getPreviousStep(1,t.stepOptions),n=e.game.getProperty("backbutton"),!r||n===!1||n&&n.enableOnPlaying===!1?t.disable():r&&t.enable(),"string"==typeof n?t.button.value=n:n&&n.text&&(t.button.value=n.text)})},t.prototype.disable=function(){this.button.disabled="disabled"},t.prototype.enable=function(){this.button.disabled=!1}}(node),function(e){"use strict";function n(){this.button=null,this.buttonText="",this.items=[],this.onclick=null,this.getDescr=null,this.getId=function(e){return e.id},this.ul=null}var t=e.NDDB;e.widgets.register("BoxSelector",n),n.version="1.0.0",n.description="Creates a simple box that opens a menu of items to choose from.",n.panel=!1,n.title=!1,n.className="boxselector",n.dependencies={JSUS:{}},n.prototype.init=function(e){if(e.onclick){if("function"!=typeof e.onclick)throw new Error("BoxSelector.init: options.getId must be function or undefined. Found: "+e.getId);this.onclick=e.onclick}if("function"!=typeof e.getDescr)throw new Error("BoxSelector.init: options.getDescr must be function. Found: "+e.getDescr);this.getDescr=e.getDescr;if(e.getId&&"function"!=typeof e.getId)throw new Error("BoxSelector.init: options.getId must be function or undefined. Found: "+e.getId);this.getId=e.getId},n.prototype.append=function(){var e,t,n,r,i;r=W.add("div",this.bodyDiv),r.role="group",r["aria-label"]="Select Items",r.className="btn-group dropup",n=this.button=W.add("button",r),n.className="btn btn-default btn dropdown-toggle",n["data-toggle"]="dropdown",n["aria-haspopup"]="true",n["aria-expanded"]="false",n.innerHTML=this.buttonText+"&nbsp;",W.add("span",n,{className:"caret"}),t=this.ul=W.add("ul",r),t.className="dropdown-menu",t.style.display="none",i=!1,n.onclick=function(){i?(t.style.display="none",i=!1):(t.style.display="block",i=!0)},this.onclick&&(e=this,t.onclick=function(n){var r,s,o;r=n.target,t.style.display="",i=!1,r=r.parentNode.id,r||(r=n.target.parentNode.parentNode.id);if(!r)return;o=e.items.length;for(s=0;s<o;s++)if(e.getId(e.items[s])===r){e.onclick.call(e,e.items[s],r);break}})},n.prototype.addItem=function(e){var t,n,r,i;t=this.ul,n=document.createElement("li"),i=this.getDescr(e);if(!i||"string"!=typeof i)throw new Error("BoxSelector.addItem: getDescr did not return a string. Found: "+i+". Item: "+e);this.onclick?(r=document.createElement("a"),r.href="#",r.innerHTML=i,n.appendChild(r)):n.innerHTML=i,i=this.getId(e);if(!i||"string"!=typeof i)throw new Error("BoxSelector.addItem: getId did not return a string. Found: "+i+". Item: "+e);n.id=i,n.className="dropdown-header",t.appendChild(n),this.items.push(e)},n.prototype.removeItem=function(e){var t,n,r;n=this.items.length;for(t=0;t<n;t++)if(this.getId(this.items[t])===e)return r=W.gid(e),this.ul.removeChild(r),this.items.splice(t,1);return!1},n.prototype.getValues=function(){return this.items}}(node),function(e){"use strict";function n(){this.chatEvent=null,this.stats={received:0,sent:0,unread:0},this.submitButton=null,this.useSubmitButton=null,this.useSubmitEnter=null,this.receiverOnly=!1,this.storeMsgs=!1,this.db=null,this.chatDiv=null,this.textarea=null,this.initialMsg=null,this.recipientsIds=null,this.recipientsIdsQuitted=null,this.senderToNameMap=null,this.recipientToNameMap=null,this.senderToRecipientMap=null,this.recipientToSenderMap=null,this.showIsTyping=null,this.amTypingTimeout=null,this.isTypingTimeouts={},this.isTypingDivs={},this.preprocessMsg=null}function r(t){var n;if(t.isDisabled())return;if(t.amTypingTimeout)return;n=t.recipientsIds;if(!n.length)return;n.length===1&&(n=n[0]),t.amTypingTimeout=setTimeout(function(){t.amTypingTimeout=null},4e3),e.say(t.chatEvent+"_TYPING",n)}var t=e.NDDB;e.widgets.register("Chat",n),n.texts={outgoing:function(e,t){return t.msg},incoming:function(e,t){var n;return n="<span>",e.recipientsIds.length>1&&(n+='<span class="chat_id_other">'+(e.senderToNameMap[t.id]||t.id)+"</span>: "),n+=t.msg+"</span>",n},quit:function(e,t){return(e.senderToNameMap[t.id]||t.id)+" left the chat"},noMoreParticipants:function(){return"No active participant left. Chat disabled."},collapse:function(e,t){return(e.senderToNameMap[t.id]||t.id)+" "+(t.collapsed?"mini":"maxi")+"mized the chat"},textareaPlaceholder:function(e){return e.useSubmitEnter?"Type something and press enter to send":"Type something"},submitButton:"Send",isTyping:"is typing..."},n.version="1.5.0",n.description="Offers a uni-/bi-directional communication interface between players, or between players and the server.",n.title="Chat",n.className="chat",n.panel=!1,n.dependencies={JSUS:{}},n.prototype.init=function(n){var r,i,s,o,u;n=n||{},u=this,this.receiverOnly=!!n.receiverOnly,r=n.preprocessMsg;if("function"==typeof r)this.preprocessMsg=r;else if(r)throw new TypeError("Chat.init: preprocessMsg must be function or undefined. Found: "+r);r=n.chatEvent;if(r){if("string"!=typeof r)throw new TypeError("Chat.init: chatEvent must be a non-empty string or undefined. Found: "+r);this.chatEvent=n.chatEvent}else this.chatEvent="CHAT";this.storeMsgs=!!n.storeMsgs,this.storeMsgs&&(this.db||(this.db=new t)),this.useSubmitButton="undefined"==typeof n.useSubmitButton?J.isMobileAgent():!!n.useSubmitButton,this.useSubmitEnter="undefined"==typeof n.useSubmitEnter?!0:!!n.useSubmitEnter,r=n.participants;if(!J.isArray(r)||!r.length)throw new TypeError("Chat.init: participants must be a non-empty array. Found: "+r);this.recipientsIds=new Array(r.length),this.recipientsIdsQuitted=[],this.recipientToSenderMap={},this.recipientToNameMap={},this.senderToNameMap={},this.senderToRecipientMap={};for(i=0;i<r.length;i++)if("string"==typeof r[i])this.recipientsIds[i]=r[i],this.recipientToNameMap[r[i]]=r[i],this.recipientToSenderMap[r[i]]=r[i],this.senderToRecipientMap[r[i]]=r[i],this.senderToNameMap[r[i]]=r[i];else{if("object"!=typeof r[i])throw new TypeError("Chat.init: participants array must contain string or object. Found: "+r[i]);s=r[i].recipient,o=r[i].sender,this.recipientsIds[i]=s,this.recipientToSenderMap[s]=o||s,this.recipientToNameMap[s]=r[i].name||s,this.senderToRecipientMap[o]=s,this.senderToNameMap[o]=this.recipientToNameMap[s]}this.uncollapseOnMsg=n.uncollapseOnMsg||!1,this.printStartTime=n.printStartTime||!1,this.printNames=n.printNames||!1;if(n.initialMsg){if("object"!=typeof n.initialMsg)throw new TypeError("Chat.init: initialMsg must be object or undefined. Found: "+n.initialMsg);this.initialMsg=n.initialMsg}this.on("uncollapsed",function(){u.setTitle(u.title),u.recipientsIds.length&&e.say(u.chatEvent+"_COLLAPSE",u.recipientsIds,!1)}),this.on("collapsed",function(){u.recipientsIds.length&&e.say(u.chatEvent+"_COLLAPSE",u.recipientsIds,!0)}),this.on("destroyed",function(){u.recipientsIds.length&&e.say(u.chatEvent+"_QUIT",u.recipientsIds)}),this.showIsTyping="undefined"==typeof n.showIsTyping?!0:!!n.showIsTyping},n.prototype.append=function(){var e,t,n;e=this,this.chatDiv=W.get("div",{className:"chat_chat"}),this.bodyDiv.appendChild(this.chatDiv);if(!this.receiverOnly){t=document.createElement("div"),t.className="chat_inputgroup",this.textarea=W.get("textarea",{className:"chat_textarea form-control",placeholder:this.getText("textareaPlaceholder")}),t.appendChild(this.textarea),this.useSubmitButton&&(this.submitButton=W.get("button",{className:"btn-sm btn-info form-control chat_submit",innerHTML:this.getText("submitButton")}),this.submitButton.onclick=function(){e.sendMsg(),"function"==typeof e.textarea.focus&&e.textarea.focus()},t.appendChild(this.submitButton));if(this.useSubmitEnter||this.showIsTyping)this.textarea.onkeydown=function(t){e.useSubmitEnter?(t=t||window.event,(t.keyCode||t.which)===13?e.sendMsg():r(e)):e.showIsTyping&&r(e)};this.bodyDiv.appendChild(t)}this.printStartTime&&(W.add("div",this.chatDiv,{innerHTML:Date(J.getDate()),className:"chat_event"}),n=!0),this.printNames&&(W.add("div",this.chatDiv,{className:"chat_event",innerHTML:"Participants: "+J.keys(this.senderToNameMap).join(", ")}),n=!0),n&&W.add("div",this.chatDiv,{className:"chat_event",innerHTML:"&nbsp;"}),this.initialMsg&&this.writeMsg(this.initialMsg.id?"incoming":"outgoing",this.initialMsg)},n.prototype.readTextarea=function(){var e;return e=this.textarea.value,this.textarea.value="",e.trim()},n.prototype.writeMsg=function(e,t){var n;return n=e==="incoming"||e==="outgoing"?e:"event",n=W.add("div",this.chatDiv,{innerHTML:this.getText(e,t),className:"chat_msg chat_msg_"+n}),this.scrollToBottom(),n},n.prototype.renderMsg=function(e,t){var n;return"function"==typeof this.preprocessMsg&&this.preprocessMsg(e,t),"function"==typeof e.msg?n=e.msg(e,t):n=e.msg,n},n.prototype.scrollToBottom=function(){this.chatDiv.scrollTop=this.chatDiv.scrollHeight},n.prototype.listeners=function(){var t=this;e.on.data(this.chatEvent,function(n){if(!t.handleMsg(n))return;t.stats.received++,t.storeMsgs&&t.db.insert({from:n.from,text:n.data,time:e.timer.getTimeSince("step"),timestamp:J.now()}),t.clearIsTyping(n.from),n={msg:t.renderMsg(n.data,"incoming"),id:n.from},t.writeMsg("incoming",n)}),e.on.data(this.chatEvent+"_QUIT",function(n){var r,i,s;if(!t.handleMsg(n))return;t.writeMsg("quit",{id:n.from}),i=t.recipientsIds.length;for(r=0;r<i;r++)if(t.recipientsIds[r]===t.senderToRecipientMap[n.from]){s=t.recipientsIds.splice(r,1),t.recipientsIdsQuitted.push(s),t.recipientsIds.length===0&&(t.writeMsg("noMoreParticipants"),t.disable());break}e.warn("Chat: participant quitted not found: "+n.from)}),e.on.data(this.chatEvent+"_COLLAPSE",function(e){if(!t.handleMsg(e))return;t.writeMsg("collapse",{id:e.from,collapsed:e.data})}),e.on.data(this.chatEvent+"_TYPING",function(e){if(!t.handleMsg(e))return;t.addIsTyping(e.from)})},n.prototype.addIsTyping=function(e){var t,n,r;t=this.isTypingTimeouts[e],t&&clearTimeout(t),n=this.isTypingDivs[e],n?(this.chatDiv.appendChild(n),n.style.display=""):this.isTypingDivs[e]=this.writeMsg("incoming",{msg:this.getText("isTyping"),id:e}),this.scrollToBottom(),r=this,this.isTypingTimeouts[e]=setTimeout(function(){r.clearIsTyping(e),r.isTypingTimeouts[e]=null},3e3)},n.prototype.clearIsTyping=function(e){this.isTypingTimeouts[e]&&(clearTimeout(this.isTypingTimeouts[e]),this.isTypingTimeouts[e]=null),this.isTypingDivs[e]&&(this.isTypingDivs[e].style.display="none")},n.prototype.handleMsg=function(t){var n;return n=t.from,n===e.player.id||n===e.player.sid?(e.warn("Chat: your own message came back: "+t.id),!1):(this.isCollapsed()&&(this.uncollapseOnMsg?(this.uncollapse(),this.stats.unread=0):(this.setTitle("<strong>"+this.title+"</strong>"),this.stats.unread++)),!0)},n.prototype.disable=function(){this.submitButton&&(this.submitButton.disabled=!0),this.textarea.disabled=!0,this.disabled=!0},n.prototype.enable=function(){this.submitButton&&(this.submitButton.disabled=!1),this.textarea.disabled=!1,this.disabled=!1},n.prototype.getValues=function(){var e;return e={participants:this.participants,totSent:this.stats.sent,totReceived:this.stats.received,totUnread:this.stats.unread,initialMsg:this.initialMsg},this.db&&(e.msgs=this.db.fetch()),e},n.prototype.sendMsg=function(t){var n,r,i;if(this.isDisabled()){e.warn("Chat is disable, msg not sent.");return}if("object"==typeof t){if("undefined"!=typeof t.msg&&"object"==typeof t.msg)throw new TypeError("Chat.sendMsg: opts.msg cannot be object. Found: "+t.msg)}else if("undefined"==typeof t)t={msg:this.readTextarea()};else{if("string"!=typeof t&&"number"!=typeof t)throw new TypeError("Chat.sendMsg: opts must be string, number, object, or undefined. Found: "+t);t={msg:t}}t.msg=this.renderMsg(t,"outgoing");if(t.msg===""){e.warn("Chat: message has no text, not sent.");return}r=t.recipients||this.recipientsIds;if(r.length===0){e.warn("Chat: empty recipient list, message not sent.");return}n=r.length===1?r[0]:r,e.say(this.chatEvent,n,t),t.silent||(i=this,this.writeMsg("outgoing",t),i.textarea&&setTimeout(function(){i.textarea.value=""})),this.amTypingTimeout&&(clearTimeout(this.amTypingTimeout),this.amTypingTimeout=null)}}(node),function(e){"use strict";function n(e){var t=this;this.options=null,this.table=null,this.sc=null,this.fp=null,this.canvas=null,this.changes=[],this.onChange=null,this.onChangeCb=function(e,n){"undefined"==typeof n&&(n=!1),e||(t.sc?e=t.sc.getValues():e=i.random()),t.draw(e,n)},this.timeFrom="step",this.features=null}function r(e,t){this.canvas=new W.Canvas(e),this.scaleX=e.width/n.width,this.scaleY=e.height/n.heigth,this.face=null}function i(e,t){var n;if("undefined"==typeof e)for(n in i.defaults)i.defaults.hasOwnProperty(n)&&(n==="color"?this.color="red":n==="lineWidth"?this.lineWidth=1:n==="scaleX"?this.scaleX=1:n==="scaleY"?this.scaleY=1:this[n]=i.defaults[n].min+Math.random()*i.defaults[n].range);else{if("object"!=typeof e)throw new TypeError("FaceVector constructor: faceVector must be object or undefined.");this.scaleX=e.scaleX||1,this.scaleY=e.scaleY||1,this.color=e.color||"green",this.lineWidth=e.lineWidth||1,t=t||i.defaults;for(n in t)t.hasOwnProperty(n)&&(e.hasOwnProperty(n)?this[n]=e[n]:this[n]=t?t[n]:i.defaults[n].value)}}var t=W.Table;e.widgets.register("ChernoffFaces",n),n.version="0.6.2",n.description="Display parametric data in the form of a Chernoff Face.",n.title="ChernoffFaces",n.className="chernofffaces",n.dependencies={JSUS:{},Table:{},Canvas:{},SliderControls:{}},n.FaceVector=i,n.FacePainter=r,n.width=100,n.height=100,n.onChange="CF_CHANGE",n.prototype.init=function(t){this.options=t,t.features?this.features=new i(t.features):this.features||(this.features=i.random()),this.fp&&this.fp.draw(this.features),t.onChange===!1||t.onChange===null?this.onChange&&(e.off(this.onChange,this.onChangeCb),this.onChange=null):(this.onChange="undefined"==typeof t.onChange?n.onChange:t.onChange,e.on(this.onChange,this.onChangeCb))},n.prototype.getCanvas=function(){return this.canvas},n.prototype.buildHTML=function(){var n,r,s,o;if(this.table)return;o=this.options,s={},this.id&&(s.id=this.id),"string"==typeof o.className?s.className=o.className:o.className!==!1&&(s.className="cf_table"),this.table=new t(s),this.canvas||this.buildCanvas();if("undefined"==typeof o.controls||o.controls)r=J.mergeOnKey(i.defaults,this.features,"value"),n={id:"cf_controls",features:r,onChange:this.onChange,submit:"Send"},"object"==typeof o.controls?this.sc=o.controls:this.sc=e.widgets.get("SliderControls",n);this.sc?this.table.addRow([{content:this.sc,id:this.id+"_td_controls"},{content:this.canvas,id:this.id+"_td_cf"}]):this.table.add({content:this.canvas,id:this.id+"_td_cf"}),this.table.parse()},n.prototype.buildCanvas=function(){var e;this.canvas||(e=this.options,e.canvas||(e.canvas={},"undefined"!=typeof e.height&&(e.canvas.height=e.height),"undefined"!=typeof e.width&&(e.canvas.width=e.width)),this.canvas=W.get("canvas",e.canvas),this.canvas.id="ChernoffFaces_canvas",this.fp=new r(this.canvas),this.fp.draw(this.features))},n.prototype.append=function(){this.table||this.buildHTML(),this.bodyDiv.appendChild(this.table.table)},n.prototype.draw=function(t,n){var r;if("object"!=typeof t)throw new TypeError("ChernoffFaces.draw: features must be object.");this.options.trackChanges&&("string"==typeof this.timeFrom?r=e.timer.getTimeSince(this.timeFrom):r=Date.now?Date.now():(new Date).getTime(),this.changes.push({time:r,change:t})),this.features=t instanceof i?t:new i(t,this.features),this.fp.redraw(this.features),this.sc&&n!==!1&&(this.sc.init({features:J.mergeOnKey(i.defaults,t,"value")}),this.sc.refresh())},n.prototype.getValues=function(e){return e&&e.changes?{changes:this.changes,cf:this.features}:this.fp.face},n.prototype.randomize=function(){var e;return e=i.random(),this.fp.redraw(e),this.sc&&(this.sc.init({features:J.mergeOnValue(i.defaults,e),onChange:this.onChange}),this.sc.refresh()),!0},r.prototype.draw=function(e,t,n){if(!e)return;this.face=e,this.fit2Canvas(e),this.canvas.scale(e.scaleX,e.scaleY),t=t||this.canvas.centerX,n=n||this.canvas.centerY,this.drawHead(e,t,n),this.drawEyes(e,t,n),this.drawPupils(e,t,n),this.drawEyebrow(e,t,n),this.drawNose(e,t,n),this.drawMouth(e,t,n)},r.prototype.redraw=function(e,t,n){this.canvas.clear(),this.draw(e,t,n)},r.prototype.scale=function(e,t){this.canvas.scale(this.scaleX,this.scaleY)},r.prototype.fit2Canvas=function(e){var t;if(!this.canvas){console.log("No canvas found");return}this.canvas.width>this.canvas.height?t=this.canvas.width/e.head_radius*e.head_scale_x:t=this.canvas.height/e.head_radius*e.head_scale_y,e.scaleX=t/2,e.scaleY=t/2},r.prototype.drawHead=function(e,t,n){var r=e.head_radius;this.canvas.drawOval({x:t,y:n,radius:r,scale_x:e.head_scale_x,scale_y:e.head_scale_y,color:e.color,lineWidth:e.lineWidth})},r.prototype.drawEyes=function(e,t,n){var i=r.computeFaceOffset(e,e.eye_height,n),s=e.eye_spacing,o=e.eye_radius;this.canvas.drawOval({x:t-s,y:i,radius:o,scale_x:e.eye_scale_x,scale_y:e.eye_scale_y,color:e.color,lineWidth:e.lineWidth}),this.canvas.drawOval({x:t+s,y:i,radius:o,scale_x:e.eye_scale_x,scale_y:e.eye_scale_y,color:e.color,lineWidth:e.lineWidth})},r.prototype.drawPupils=function(e,t,n){var i=e.pupil_radius,s=e.eye_spacing,o=r.computeFaceOffset(e,e.eye_height,n);this.canvas.drawOval({x:t-s,y:o,radius:i,scale_x:e.pupil_scale_x,scale_y:e.pupil_scale_y,color:e.color,lineWidth:e.lineWidth}),this.canvas.drawOval({x:t+s,y:o,radius:i,scale_x:e.pupil_scale_x,scale_y:e.pupil_scale_y,color:e.color,lineWidth:e.lineWidth})},r.prototype.drawEyebrow=function(e,t,n){var i=r.computeEyebrowOffset(e,n),s=e.eyebrow_spacing,o=e.eyebrow_length,u=e.eyebrow_angle;this.canvas.drawLine({x:t-s,y:i,length:o,angle:u,color:e.color,lineWidth:e.lineWidth}),this.canvas.drawLine({x:t+s,y:i,length:0-o,angle:-u,color:e.color,lineWidth:e.lineWidth})},r.prototype.drawNose=function(e,t,n){var i=r.computeFaceOffset(e,e.nose_height,n),s=t+e.nose_width/2,o=i+e.nose_length,u=s-e.nose_width,a=o;this.canvas.ctx.lineWidth=e.lineWidth,this.canvas.ctx.strokeStyle=e.color,this.canvas.ctx.save(),this.canvas.ctx.beginPath(),this.canvas.ctx.moveTo(t,i),this.canvas.ctx.lineTo(s,o),this.canvas.ctx.lineTo(u,a),this.canvas.ctx.stroke(),this.canvas.ctx.restore()},r.prototype.drawMouth=function(e,t,n){var i=r.computeFaceOffset(e,e.mouth_height,n),s=t-e.mouth_width/2,o=t+e.mouth_width/2,u=i-e.mouth_top_y,a=i+e.mouth_bottom_y;this.canvas.ctx.moveTo(s,i),this.canvas.ctx.quadraticCurveTo(t,u,o,i),this.canvas.ctx.stroke(),this.canvas.ctx.moveTo(s,i),this.canvas.ctx.quadraticCurveTo(t,a,o,i),this.canvas.ctx.stroke()},r.computeFaceOffset=function(e,t,n){n=n||0;var r=n-e.head_radius+e.head_radius*2*t;return r},r.computeEyebrowOffset=function(e,t){t=t||0;var n=2;return r.computeFaceOffset(e,e.eye_height,t)-n-e.eyebrow_eyedistance},i.defaults={head_radius:{min:10,max:100,step:.01,value:30,label:"Face radius"},head_scale_x:{min:.2,max:2,step:.01,value:.5,label:"Scale head horizontally"},head_scale_y:{min:.2,max:2,step:.01,value:1,label:"Scale head vertically"},eye_height:{min:.1,max:.9,step:.01,value:.4,label:"Eye height"},eye_radius:{min:2,max:30,step:.01,value:5,label:"Eye radius"},eye_spacing:{min:0,max:50,step:.01,value:10,label:"Eye spacing"},eye_scale_x:{min:.2,max:2,step:.01,value:1,label:"Scale eyes horizontally"},eye_scale_y:{min:.2,max:2,step:.01,value:1,label:"Scale eyes vertically"},pupil_radius:{min:1,max:9,step:.01,value:1,label:"Pupil radius"},pupil_scale_x:{min:.2,max:2,step:.01,value:1,label:"Scale pupils horizontally"},pupil_scale_y:{min:.2,max:2,step:.01,value:1,label:"Scale pupils vertically"},eyebrow_length:{min:1,max:30,step:.01,value:10,label:"Eyebrow length"},eyebrow_eyedistance:{min:.3,max:10,step:.01,value:3,label:"Eyebrow from eye"},eyebrow_angle:{min:-2,max:2,step:.01,value:-0.5,label:"Eyebrow angle"},eyebrow_spacing:{min:0,max:20,step:.01,value:5,label:"Eyebrow spacing"},nose_height:{min:.4,max:1,step:.01,value:.4,label:"Nose height"},nose_length:{min:.2,max:30,step:.01,value:15,label:"Nose length"},nose_width:{min:0,max:30,step:.01,value:10,label:"Nose width"},mouth_height:{min:.2,max:2,step:.01,value:.75,label:"Mouth height"},mouth_width:{min:2,max:100,step:.01,value:20,label:"Mouth width"},mouth_top_y:{min:-10,max:30,step:.01,value:-2,label:"Upper lip"},mouth_bottom_y:{min:-10,max:30,step:.01,value:20,label:"Lower lip"},scaleX:{min:0,max:20,step:.01,value:.2,label:"Scale X"},scaleY:{min:0,max:20,step:.01,value:.2,label:"Scale Y"},color:{min:0,max:20,step:.01,value:.2,label:"color"},lineWidth:{min:0,max:20,step:.01,value:.2,label:"lineWidth"}},function(e){var t;for(t in e)e.hasOwnProperty(t)&&(e[t].range=e[t].max-e[t].min)}(i.defaults),i.random=function(){return console.log("*** FaceVector.random is deprecated. Use new FaceVector() instead."),new i}}(node),function(e){"use strict";function n(n){this.options=n,this.id=n.id,this.table=new t({id:"cf_table"}),this.root=n.root||document.createElement("div"),this.root.id=this.id,this.sc=e.widgets.get("Controls.Slider"),this.fp=null,this.canvas=null,this.dims=null,this.change="CF_CHANGE";var r=this;this.changeFunc=function(){r.draw(r.sc.getAllValues())},this.features=null,this.controls=null}function r(e,t){this.canvas=new W.Canvas(e),this.scaleX=e.width/n.defaults.canvas.width,this.scaleY=e.height/n.defaults.canvas.heigth}function i(e){e=e||{},this.scaleX=e.scaleX||1,this.scaleY=e.scaleY||1,this.color=e.color||"green",this.lineWidth=e.lineWidth||1;for(var t in i.defaults)i.defaults.hasOwnProperty(t)&&(e.hasOwnProperty(t)?this[t]=e[t]:this[t]=i.defaults[t].value)}var t=W.Table;e.widgets.register("ChernoffFacesSimple",n),n.defaults={},n.defaults.id="ChernoffFaces",n.defaults.canvas={},n.defaults.canvas.width=100,n.defaults.canvas.heigth=100,n.version="0.4",n.description="Display parametric data in the form of a Chernoff Face.",n.dependencies={JSUS:{},Table:{},Canvas:{},"Controls.Slider":{}},n.FaceVector=i,n.FacePainter=r,n.prototype.init=function(t){this.id=t.id||this.id;var s=this.id+"_";this.features=t.features||this.features||i.random(),this.controls="undefined"!=typeof t.controls?t.controls:!0;var o=t.idCanvas?t.idCanvas:s+"canvas";this.dims={width:t.width?t.width:n.defaults.canvas.width,height:t.height?t.height:n.defaults.canvas.heigth},this.canvas=W.getCanvas(o,this.dims),this.fp=new r(this.canvas),this.fp.draw(new i(this.features));var u={id:"cf_controls",features:J.mergeOnKey(i.defaults,this.features,"value"),change:this.change,fieldset:{id:this.id+"_controls_fieldest",legend:this.controls.legend||"Controls"},submit:"Send"};this.sc=e.widgets.get("Controls.Slider",u),this.controls&&this.table.add(this.sc),"undefined"==typeof t.change?e.on(this.change,this.changeFunc):(t.change?e.on(t.change,this.changeFunc):e.removeListener(this.change,this.changeFunc),this.change=t.change),this.table.add(this.canvas),this.table.parse(),this.root.appendChild(this.table.table)},n.prototype.getRoot=function(){return this.root},n.prototype.getCanvas=function(){return this.canvas},n.prototype.append=function(e){return e.appendChild(this.root),this.table.parse(),this.root},n.prototype.listeners=function(){},n.prototype.draw=function(e){if(!e)return;var t=new i(e);this.fp.redraw(t),this.sc.init({features:J.mergeOnKey(i.defaults,e,"value")}),this.sc.refresh()},n.prototype.getAllValues=function(){return this.fp.face},n.prototype.randomize=function(){var e=i.random();this.fp.redraw(e);var t={features:J.mergeOnKey(i.defaults,e,"value"),change:this.change};return this.sc.init(t),this.sc.refresh(),!0},r.prototype.draw=function(e,t,n){if(!e)return;this.face=e,this.fit2Canvas(e),this.canvas.scale(e.scaleX,e.scaleY),t=t||this.canvas.centerX,n=n||this.canvas.centerY,this.drawHead(e,t,n),this.drawEyes(e,t,n),this.drawPupils(e,t,n),this.drawEyebrow(e,t,n),this.drawNose(e,t,n),this.drawMouth(e,t,n)},r.prototype.redraw=function(e,t,n){this.canvas.clear(),this.draw(e,t,n)},r.prototype.scale=function(e,t){this.canvas.scale(this.scaleX,this.scaleY)},r.prototype.fit2Canvas=function(e){var t;if(!this.canvas){console.log("No canvas found");return}this.canvas.width>this.canvas.height?t=this.canvas.width/e.head_radius*e.head_scale_x:t=this.canvas.height/e.head_radius*e.head_scale_y,e.scaleX=t/2,e.scaleY=t/2},r.prototype.drawHead=function(e,t,n){var r=e.head_radius;this.canvas.drawOval({x:t,y:n,radius:r,scale_x:e.head_scale_x,scale_y:e.head_scale_y,color:e.color,lineWidth:e.lineWidth})},r.prototype.drawEyes=function(e,t,n){var i=r.computeFaceOffset(e,e.eye_height,n),s=e.eye_spacing,o=e.eye_radius;this.canvas.drawOval({x:t-s,y:i,radius:o,scale_x:e.eye_scale_x,scale_y:e.eye_scale_y,color:e.color,lineWidth:e.lineWidth}),this.canvas.drawOval({x:t+s,y:i,radius:o,scale_x:e.eye_scale_x,scale_y:e.eye_scale_y,color:e.color,lineWidth:e.lineWidth})},r.prototype.drawPupils=function(e,t,n){var i=e.pupil_radius,s=e.eye_spacing,o=r.computeFaceOffset(e,e.eye_height,n);this.canvas.drawOval({x:t-s,y:o,radius:i,scale_x:e.pupil_scale_x,scale_y:e.pupil_scale_y,color:e.color,lineWidth:e.lineWidth}),this.canvas.drawOval({x:t+s,y:o,radius:i,scale_x:e.pupil_scale_x,scale_y:e.pupil_scale_y,color:e.color,lineWidth:e.lineWidth})},r.prototype.drawEyebrow=function(e,t,n){var i=r.computeEyebrowOffset(e,n),s=e.eyebrow_spacing,o=e.eyebrow_length,u=e.eyebrow_angle;this.canvas.drawLine({x:t-s,y:i,length:o,angle:u,color:e.color,lineWidth:e.lineWidth}),this.canvas.drawLine({x:t+s,y:i,length:0-o,angle:-u,color:e.color,lineWidth:e.lineWidth})},r.prototype.drawNose=function(e,t,n){var i=r.computeFaceOffset(e,e.nose_height,n),s=t+e.nose_width/2,o=i+e.nose_length,u=s-e.nose_width,a=o;this.canvas.ctx.lineWidth=e.lineWidth,this.canvas.ctx.strokeStyle=e.color,this.canvas.ctx.save(),this.canvas.ctx.beginPath(),this.canvas.ctx.moveTo(t,i),this.canvas.ctx.lineTo(s,o),this.canvas.ctx.lineTo(u,a),this.canvas.ctx.stroke(),this.canvas.ctx.restore()},r.prototype.drawMouth=function(e,t,n){var i=r.computeFaceOffset(e,e.mouth_height,n),s=t-e.mouth_width/2,o=t+e.mouth_width/2,u=i-e.mouth_top_y,a=i+e.mouth_bottom_y;this.canvas.ctx.moveTo(s,i),this.canvas.ctx.quadraticCurveTo(t,u,o,i),this.canvas.ctx.stroke(),this.canvas.ctx.moveTo(s,i),this.canvas.ctx.quadraticCurveTo(t,a,o,i),this.canvas.ctx.stroke()},r.computeFaceOffset=function(e,t,n){n=n||0;var r=n-e.head_radius+e.head_radius*2*t;return r},r.computeEyebrowOffset=function(e,t){t=t||0;var n=2;return r.computeFaceOffset(e,e.eye_height,t)-n-e.eyebrow_eyedistance},i.defaults={head_radius:{min:10,max:100,step:.01,value:30,label:"Face radius"},head_scale_x:{min:.2,max:2,step:.01,value:.5,label:"Scale head horizontally"},head_scale_y:{min:.2,max:2,step:.01,value:1,label:"Scale head vertically"},eye_height:{min:.1,max:.9,step:.01,value:.4,label:"Eye height"},eye_radius:{min:2,max:30,step:.01,value:5,label:"Eye radius"},eye_spacing:{min:0,max:50,step:.01,value:10,label:"Eye spacing"},eye_scale_x:{min:.2,max:2,step:.01,value:1,label:"Scale eyes horizontally"},eye_scale_y:{min:.2,max:2,step:.01,value:1,label:"Scale eyes vertically"},pupil_radius:{min:1,max:9,step:.01,value:1,label:"Pupil radius"},pupil_scale_x:{min:.2,max:2,step:.01,value:1,label:"Scale pupils horizontally"},pupil_scale_y:{min:.2,max:2,step:.01,value:1,label:"Scale pupils vertically"},eyebrow_length:{min:1,max:30,step:.01,value:10,label:"Eyebrow length"},eyebrow_eyedistance:{min:.3,max:10,step:.01,value:3,label:"Eyebrow from eye"},eyebrow_angle:{min:-2,max:2,step:.01,value:-0.5,label:"Eyebrow angle"},eyebrow_spacing:{min:0,max:20,step:.01,value:5,label:"Eyebrow spacing"},nose_height:{min:.4,max:1,step:.01,value:.4,label:"Nose height"},nose_length:{min:.2,max:30,step:.01,value:15,label:"Nose length"},nose_width:{min:0,max:30,step:.01,value:10,label:"Nose width"},mouth_height:{min:.2,max:2,step:.01,value:.75,label:"Mouth height"},mouth_width:{min:2,max:100,step:.01,value:20,label:"Mouth width"},mouth_top_y:{min:-10,max:30,step:.01,value:-2,label:"Upper lip"},mouth_bottom_y:{min:-10,max:30,step:.01,value:20,label:"Lower lip"}},i.random=function(){var e={};for(var t in i.defaults)i.defaults.hasOwnProperty(t)&&(J.inArray(t,["color","lineWidth","scaleX","scaleY"])||(e[t]=i.defaults[t].min+Math.random()*i.defaults[t].max));return e.scaleX=1,e.scaleY=1,e.color="green",e.lineWidth=1,new i(e)},i.prototype.shuffle=function(){for(var e in this)this.hasOwnProperty(e)&&i.defaults.hasOwnProperty(e)&&e!=="color"&&(this[e]=i.defaults[e].min+Math.random()*i.defaults[e].max)},i.prototype.distance=function(e){return i.distance(this,e)},i.distance=function(e,t){var n=0,r;for(var i in e)e.hasOwnProperty(i)&&(r=e[i]-t[i],n+=r*r);return Math.sqrt(n)},i.prototype.toString=function(){var e="Face: ";for(var t in this)this.hasOwnProperty(t)&&(e+=t+" "+this[t]);return e}}(node),function(e){"use strict";function t(){this.dl=null,this.mainText=null,this.spanMainText=null,this.forms=null,this.formsById=null,this.order=null,this.shuffleForms=null,this.group=null,this.groupOrder=null,this.formsOptions={title:!1,frame:!1,storeRef:!1},this.simplify=null,this.freeText=null,this.textarea=null,this.required=null}e.widgets.register("ChoiceManager",t),t.version="1.4.1",t.description="Groups together and manages a set of survey forms (e.g., ChoiceTable).",t.title=!1,t.className="choicemanager",t.dependencies={},t.prototype.init=function(e){var t;"undefined"==typeof e.shuffleForms?t=!1:t=!!e.shuffleForms,this.shuffleForms=t;if("string"==typeof e.group||"number"==typeof e.group)this.group=e.group;else if("undefined"!=typeof e.group)throw new TypeError("ChoiceManager.init: options.group must be string, number or undefined. Found: "+e.group);if("number"==typeof e.groupOrder)this.groupOrder=e.groupOrder;else if("undefined"!=typeof e.group)throw new TypeError("ChoiceManager.init: options.groupOrder must be number or undefined. Found: "+e.groupOrder);if("string"==typeof e.mainText)this.mainText=e.mainText;else if("undefined"!=typeof e.mainText)throw new TypeError("ChoiceManager.init: options.mainText must be string or undefined. Found: "+e.mainText);if("undefined"!=typeof e.formsOptions){if("object"!=typeof e.formsOptions)throw new TypeError("ChoiceManager.init: options.formsOptions must be object or undefined. Found: "+e.formsOptions);if(e.formsOptions.hasOwnProperty("name"))throw new Error("ChoiceManager.init: options.formsOptions cannot contain property name. Found: "+e.formsOptions);this.formsOptions=J.mixin(this.formsOptions,e.formsOptions)}this.freeText="string"==typeof e.freeText?e.freeText:!!e.freeText,"undefined"!=typeof e.requ