новые иконки в OpenBoard
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
OpenBoard/resources/library/applications/Calculator.wgt/dist/calculator.js

2 lines
44 KiB

!function(){"use strict";Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),window.klass={create:function(){var a=Object.create(this);return"function"==typeof a.constructor&&a.constructor.apply(a,arguments),a},extend:function(a){var b=Object.create(this);return a?(Object.keys(a).forEach(function(c){b[c]=a[c]}),b):b},define:function(a,b,c){var d=function(a,b){var c,e=a.split(".");return e.length>0?(c=e.shift(),"undefined"==typeof b[c]&&(b[c]={}),e.length>0?d(e.join("."),b[c]):b[c]):null},e=d(a,window);e[b]=c}}}(),function(){"use strict";klass.define("Sankore","Button",klass.extend({constructor:function(a,b,c,d){this.text=a,this.command=b,this.useLimit="undefined"==typeof c?-1:c,this.editable="undefined"==typeof d?!0:d},isEditable:function(){return this.editable},isUsable:function(){return-1===this.useLimit},isDisabled:function(){return 0===this.useLimit},clone:function(){return Sankore.Button.create(this.text,this.command,this.useLimit,this.editable)}}))}(),function(){"use strict";klass.define("Sankore","Calculator",klass.extend({constructor:function(a,b){Sankore.Util.i18n.load(b.locale||"en"),this.currentLayout=null,this.lastError=null,this.memory=null,this.op=null,this.output=null,this.history=[],this.buttonUseCount={},this.expressionString="",this.unpredictable=b.unpredictableMode||!1,this.eventDispatcher=Sankore.Util.EventDispatcher.create(),this.commands=Sankore.Util.Hash.create(),this.texts=Sankore.Util.Hash.create(),this.calculusEngine=Sankore.Calculus.Engine.create(),this.keystrokeLine=Sankore.KeystrokeLine.create(this.eventDispatcher),this.ui=Sankore.UI.MainInterface.create(a,this.eventDispatcher,this.texts,this.unpredictable),this.editor=Sankore.Editor.Editor.create(this),"undefined"!=typeof b.ready&&this.eventDispatcher.addEventListener("calculator.create",b.ready.bind(this));var c=Sankore.Text.create.bind(Sankore.Text);this.texts.add("id",[c("0","0","0"),c("1","1","1"),c("2","2","2"),c("3","3","3"),c("4","4","4"),c("5","5","5"),c("6","6","6"),c("7","7","7"),c("8","8","8"),c("9","9","9"),c("+","+","+","alt"),c("-","-","-","alt"),c("*","×","×","alt"),c("/","÷","÷","alt"),c(":","⊢","⊢","alt"),c("=","=","=","alt"),c(".",_("text.comma"),_("text.comma")),c("(","(","("),c(")",")",")"),c("op","OP","OP"),c("mr","MR","MR"),c("mc","MC","MC"),c("m+","M+","M+"),c("m-","M-","M-"),c("s","",_("text.del"),"alt",!1),c("l","","←","alt",!1),c("r","","→","alt",!1),c("c","","C","danger",!1)]),c=Sankore.Command.create.bind(Sankore.Command),this.commands.add("id",[c("0",_("command.zero"),function(){this.expressionString+="0"}),c("1",_("command.one"),function(){this.expressionString+="1"}),c("2",_("command.two"),function(){this.expressionString+="2"}),c("3",_("command.three"),function(){this.expressionString+="3"}),c("4",_("command.four"),function(){this.expressionString+="4"}),c("5",_("command.five"),function(){this.expressionString+="5"}),c("6",_("command.six"),function(){this.expressionString+="6"}),c("7",_("command.seven"),function(){this.expressionString+="7"}),c("8",_("command.eight"),function(){this.expressionString+="8"}),c("9",_("command.nine"),function(){this.expressionString+="9"}),c("+",_("command.plus"),function(){this.expressionString+="+"}),c("-",_("command.minus"),function(){this.expressionString+="-"}),c("*",_("command.times"),function(){this.expressionString+="*"}),c("/",_("command.divide"),function(){this.expressionString+="/"}),c(":",_("command.euclidean_divide"),function(){this.expressionString+=":"}),Sankore.InterruptingCommand.create("=",_("command.equal"),function(){this.evaluateStack()}),c(".",_("command.comma"),function(){this.expressionString+="."}),c("(",_("command.open_parenthesis"),function(){this.expressionString+="("}),c(")",_("command.close_parenthesis"),function(){this.expressionString+=")"}),Sankore.InterruptingCommand.create("op",_("command.op"),function(){if(null===this.op){if(this.expressionString.length>1&&-1!=="+-*/:".indexOf(this.expressionString[0]))try{this.calculusEngine.evaluate("(1)"+this.expressionString).getValue(),this.op=this.expressionString,this.eventDispatcher.notify("calculator.op_changed",this.op)}catch(a){}this.expressionString="",this.output=null}else 0===this.expressionString.length&&null!==this.output&&(this.expressionString="("+this.output.toString()+")"),this.expressionString+=this.op,this.execCommand("=")}),Sankore.InterruptingCommand.create("memoryAdd",_("command.memory_add"),function(){this.execCommand("=");try{null===this.memory&&(this.memory=0),this.memory+=this.output.getValue()}catch(a){this.memory=null}this.eventDispatcher.notify("calculator.memory_changed",this.memory)}),Sankore.InterruptingCommand.create("memorySub",_("command.memory_sub"),function(){this.execCommand("=");try{null===this.memory&&(this.memory=0),this.memory-=this.output.getValue()}catch(a){this.memory=null}this.eventDispatcher.notify("calculator.memory_changed",this.memory)}),c("memoryRecall",_("command.memory_recall"),function(){null!==this.memory&&(this.expressionString+="("+this.memory.toString()+")")}),c("memoryClear",_("command.memory_clear"),function(){this.memory=null,this.eventDispatcher.notify("calculator.memory_changed",this.memory)}),Sankore.InternalCommand.create("clear",_("command.clear"),function(){this.reset(),this.eventDispatcher.notify("calculator.memory_changed",this.memory),this.eventDispatcher.notify("calculator.op_changed",this.op),this.eventDispatcher.notify("calculator.output_changed",{output:this.output,error:this.lastError})}),Sankore.InternalCommand.create("left",_("command.left"),function(){this.keystrokeLine.moveCaretLeft()}),Sankore.InternalCommand.create("right",_("command.right"),function(){this.keystrokeLine.moveCaretRight()}),Sankore.InternalCommand.create("del",_("command.del"),function(){var a=this.keystrokeLine.del();a&&this.getButtonUseCount(a.slot)&&(this.buttonUseCount[a.slot]--,this.getButtonUseCount(a.slot)<this.currentLayout.getButton(a.slot).useLimit&&this.eventDispatcher.notify("calculator.button_enabled",a.slot))})]),this.attachEventHandlers(),this.eventDispatcher.notify("calculator.create")},attachEventHandlers:function(){var a=this,b=this.eventDispatcher;this.unpredictable&&(b.addEventListener("editor.show",this.reload.bind(this)),b.addEventListener("editor.hide",this.reload.bind(this))),b.addEventListener("editor.layout_selected",function(b){a.loadLayout(b.id)}),b.addEventListener("main_interface.button_created",function(c){!a.editor.enabled&&c.button.isDisabled()&&b.notify("calculator.button_disabled",c)}),b.addEventListener("main_interface.button_click",function(c){a.editor.enabled||(a.useButton(c.slot),a.keystroke(c.slot,c.button),!c.button.isUsable()&&a.getButtonUseCount(c.slot)>=c.button.useLimit&&b.notify("calculator.button_disabled",c))}),b.addEventListener("main_interface.reset_click",function(){a.reload()})},reset:function(){this.memory=null,this.op=null,this.output=null,this.lastError=null,this.expressionString=[],this.keystrokeLine.reset()},init:function(a){var b=this;this.ui.render(),this.editor.init(a.editor||{}),null!==this.layout&&this.loadLayout(a.layout||"default"),"buttonUseCount"in a&&(this.buttonUseCount=a.buttonUseCount),"keystrokes"in a&&this.keystrokeLine.loadState(a.keystrokes||{}),"output"in a&&a.output&&(this.expressionString=a.output||"",this.evaluateStack()),"error"in a&&a.error&&(this.lastError=Sankore.Util.Error.create(a.error.name,a.error.message),this.eventDispatcher.notify("calculator.output_changed",{output:this.output,error:this.lastError})),"memory"in a&&(this.memory=a.memory,this.eventDispatcher.notify("calculator.memory_changed",this.memory)),"op"in a&&(this.op=a.op,this.eventDispatcher.notify("calculator.op_changed",this.op)),"history"in a&&a.history.length>0&&(this.history=a.history.map(function(a){return{expression:a.expression,output:b.calculusEngine.evaluate(a.output)}}),this.eventDispatcher.notify("calculator.history_changed",this.history)),this.eventDispatcher.notify("calculator.init")},getState:function(){return{layout:this.currentLayout?this.currentLayout.id:null,error:this.lastError,memory:this.memory,op:this.op,output:this.output?this.output.toString():null,buttonUseCount:this.buttonUseCount,editor:this.editor.getState(),keystrokes:this.keystrokeLine.getState(),history:this.history.map(function(a){return{expression:a.expression,output:a.output.toString()}})}},loadLayout:function(a){this.currentLayout=this.editor.layouts.get(a),this.execCommand("clear"),this.buttonUseCount={},this.history=[],this.eventDispatcher.notify("calculator.layout_loaded",this.currentLayout)},reload:function(){this.loadLayout(this.currentLayout.id)},execCommand:function(a,b){var c=this.commands.get(a);c.exec(this,b),this.eventDispatcher.notify("calculator.command_executed",{command:c,args:b})},evaluateStack:function(){try{this.output=this.expressionString.length>0?this.calculusEngine.evaluate(this.expressionString):null,this.lastError=null}catch(a){this.lastError=a,this.output=null}this.expressionString="",this.eventDispatcher.notify("calculator.output_changed",{output:this.output,error:this.lastError})},keystroke:function(a,b){var c=this.commands.get(b.command),d=this.texts.get(b.text);c.isInternal()?this.execCommand(c.id):(c.isInterrupting()&&this.keystrokeLine.moveCaretToEnd(),this.keystrokeLine.hit({slot:a,text:d.screen,command:b.command})),c.isInterrupting()&&this.execute()},execute:function(){var a,b=this.keystrokeLine.count();for(a=0;b>a;a++)this.execCommand(this.keystrokeLine.at(a).command);if(this.eventDispatcher.notify("calculator.executed"),!this.lastError&&this.output)try{this.backup(this.keystrokeLine.getAsText().join(""),this.output)}catch(c){}this.keystrokeLine.reset()},useButton:function(a){"undefined"==typeof this.buttonUseCount[a]&&(this.buttonUseCount[a]=0),this.buttonUseCount[a]++},getButtonUseCount:function(a){return this.buttonUseCount[a]||0},backup:function(a,b){try{b.getValue(),this.history.push({expression:a,output:b}),this.eventDispatcher.notify("calculator.history_changed",this.history)}catch(c){}}}))}(),function(){"use strict";klass.define("Sankore.Calculus","Engine",klass.extend({constructor:function(){this.expressions=[],this.operators=[]},init:function(){this.expressions=[],this.operators=[]},evaluate:function(a){var b,c,d,e=[];a=a.replace(/\s+/g,"");for(var f in a)d=a[f],b=e.length>0?e[e.length-1]:void 0,c=e.length>1?e[e.length-2]:void 0,-1!=="0123456789.".indexOf(d)?isNaN(Number(b))&&"."!==b&&"-."!==b&&("-"!==b||"("!==c&&void 0!==c)?e.push(d):e[e.length-1]+=d:e.push(d);for(var g in e)if(e[g].length>1&&"."===e[g].charAt(e[g].length-1))throw Sankore.Util.Error.create("InvalidExpression","Trailing comma");return this.computeExpression(e)},computeExpression:function(a){var b=function(a,b){for(var c,d=Sankore.Calculus.BinaryOperation.getOperatorPrecedence;;){if(c=a.operators[a.operators.length-1],0===a.operators.length||"("===c||d(b)>d(c))return a.operators.push(b);a.reduce()}};this.init();for(var c in a)switch(a[c]){case"(":this.operators.push(a[c]);break;case")":if(0===this.operators.length)throw Sankore.Util.Error.create("InvalidExpression","Trailing closing brackets");for(;0!==this.operators.length&&"("!==this.operators[this.operators.length-1];)this.reduce();"("===this.operators[this.operators.length-1]&&this.operators.pop();break;case"+":case"-":case"*":case"/":case":":b(this,a[c]);break;default:this.expressions.push(Sankore.Calculus.Operand.create(a[c]))}for(;0!==this.operators.length;)this.reduce();if(1!==this.expressions.length)throw Sankore.Util.Error.create("InvalidExpression",'"'+a.join(" ")+'" is not a valid expression');return this.expressions.pop()},reduce:function(){var a,b=this.expressions.pop(),c=this.expressions.pop(),d=this.operators.pop();if("undefined"==typeof d||"undefined"==typeof c||"undefined"==typeof b)throw Sankore.Util.Error.create("InvalidExpression","Invalid expression");a=":"===d?Sankore.Calculus.EuclideanDivisionOperation.create(c,b):Sankore.Calculus.BinaryOperation.create(c,d,b),this.expressions.push(a)}}))}(),function(){"use strict";klass.define("Sankore.Calculus","Expression",klass.extend({constructor:function(){},getValue:function(){return null},isInteger:function(){try{var a=this.getValue();return a===Math.floor(a)}catch(b){return 0}},toString:function(){return""},isCompound:function(){return!1}})),klass.define("Sankore.Calculus","Operand",Sankore.Calculus.Expression.extend({constructor:function(a){if(this.value=Number(a),isNaN(this.value))throw Sankore.Util.Error.create("InvalidNumber",'"'+String(a)+'" is a not a number')},getValue:function(){return this.value},toString:function(){return String(this.value)}})),klass.define("Sankore.Calculus","Operation",Sankore.Calculus.Expression.extend({constructor:function(a,b){this.operator=a,Sankore.Calculus.Expression.isPrototypeOf(b)||(b=Sankore.Calculus.Operand.create(b)),this.right=b},getPrecedence:function(){return Sankore.Calculus.Operation.getOperatorPrecedence(this.operator)},isLeftAssociative:function(){return!1},isCompound:function(){return!0},getValue:function(){var a=Number(this.right.getValue());return"-"===this.operator&&(a*=-1),a},toString:function(){var a=this.right.toString();return"-"!==this.operator?a:(this.right.isCompound()&&(a="("+a+")"),"-"+a)}})),Sankore.Calculus.Operation.getOperatorPrecedence=function(a){switch(a){case"+":case"-":return 1;case"*":case"/":case":":return 2}},klass.define("Sankore.Calculus","BinaryOperation",Sankore.Calculus.Operation.extend({constructor:function(a,b,c){Sankore.Calculus.Operation.constructor.call(this,b,c),Sankore.Calculus.Expression.isPrototypeOf(a)||(a=Sankore.Calculus.Operand.create(a)),this.left=a},isLeftAssociative:function(){return!0},getValue:function(){var a=this.left.getValue(),b=this.right.getValue();switch(this.operator){case"+":return a+b;case"-":return a-b;case"*":return a*b;case"/":if(0===b)throw Sankore.Util.Error.create("ZeroDivision","Division by zero");return a/b;default:throw Sankore.Util.Error.create("InvalidOperator","This is not a valid operator : "+this.operator)}},toString:function(){if(this.isInteger())return String(this.getValue());var a=this.left.toString(),b=this.right.toString();return Sankore.Calculus.Operation.isPrototypeOf(this.left)&&this.left.getPrecedence()<this.getPrecedence()&&(a="("+a+")"),Sankore.Calculus.Operation.isPrototypeOf(this.right)&&this.right.getPrecedence()<this.getPrecedence()&&(b="("+b+")"),a+String(this.operator)+b}})),klass.define("Sankore.Calculus","EuclideanDivisionOperation",Sankore.Calculus.BinaryOperation.extend({constructor:function(a,b){Sankore.Calculus.BinaryOperation.constructor.call(this,a,":",b)},getValue:function(){var a=this.right.getValue();if(0===a)throw Sankore.Util.Error.create("ZeroDivision","Division by zero");return Math.floor(this.left.getValue()/a)},getRemainder:function(){var a=this.right.getValue();if(0===a)throw Sankore.Util.Error.create("ZeroDivision","Division by zero");return this.left.getValue()%a}}))}(),function(){"use strict";klass.define("Sankore","Command",klass.extend({constructor:function(a,b,c){this.id=a,this.name=b,this.closure=c},getId:function(){return this.id},getName:function(){return this.name},exec:function(a,b){this.closure.call(a,b)},isInterrupting:function(){return!1},isInternal:function(){return!1}})),klass.define("Sankore","InterruptingCommand",Sankore.Command.extend({constructor:function(a,b,c){Sankore.Command.constructor.call(this,a,b,c)},isInterrupting:function(){return!0}})),klass.define("Sankore","InternalCommand",Sankore.Command.extend({constructor:function(a,b,c){Sankore.Command.constructor.call(this,a,b,c)},isInternal:function(){return!0}}))}(),function(){"use strict";klass.define("Sankore.Editor","Editor",klass.extend({constructor:function(a){this.current=null,this.activeButton=null,this.enabled=!1,this.layouts=Sankore.Util.Hash.create({"default":Sankore.Editor.Layout.create({id:"default",name:_("layout.classic_name"),buttonMap:{a1:Sankore.Button.create("mr","memoryRecall"),b1:Sankore.Button.create("mc","memoryClear"),c1:Sankore.Button.create("m+","memoryAdd"),d1:Sankore.Button.create("m-","memorySub"),a2:Sankore.Button.create("op","op"),b2:Sankore.Button.create("(","("),c2:Sankore.Button.create(")",")"),d2:Sankore.Button.create(":",":"),a3:Sankore.Button.create("7","7"),b3:Sankore.Button.create("8","8"),c3:Sankore.Button.create("9","9"),d3:Sankore.Button.create("/","/"),a4:Sankore.Button.create("4","4"),b4:Sankore.Button.create("5","5"),c4:Sankore.Button.create("6","6"),d4:Sankore.Button.create("*","*"),a5:Sankore.Button.create("1","1"),b5:Sankore.Button.create("2","2"),c5:Sankore.Button.create("3","3"),d5:Sankore.Button.create("-","-"),a6:Sankore.Button.create("0","0"),b6:Sankore.Button.create(".","."),c6:Sankore.Button.create("=","="),d6:Sankore.Button.create("+","+")}})}),this.calculator=a,this.ui=Sankore.UI.EditorInterface.create(this,this.calculator.eventDispatcher),this.attachEventHandlers()},attachEventHandlers:function(){var a=this,b=this.calculator.eventDispatcher;b.addEventListener("editor_interface.add_click",function(){var b=a.createLayout();a.setCurrentLayout(b.id)}),b.addEventListener("editor_interface.remove_click",function(){a.removeLayout(a.current),a.setCurrentLayout("default")}),b.addEventListener("editor_interface.run_click",this.runCurrentLayout.bind(this)),b.addEventListener("editor_interface.layout_select",function(b){a.setCurrentLayout(b)}),b.addEventListener("editor_interface.layout_name_change",function(c){a.getCurrentLayout().name!==c&&c.trim().length>0&&(a.getCurrentLayout().name=c,b.notify("editor.layout_changed"))}),b.addEventListener("editor_interface.layout_description_change",function(c){a.getCurrentLayout().description!==c&&(a.getCurrentLayout().description=c,b.notify("editor.layout_changed"))}),b.addEventListener("editor_interface.button_command_change",function(c){a.activeButton&&(a.getCurrentLayout().getButton(a.activeButton).command=c,b.notify("editor.layout_changed"))}),b.addEventListener("editor_interface.button_text_change",function(c){if(a.activeButton){var d=a.getCurrentLayout().getButton(a.activeButton);d.text=c,b.notify("editor.button_renamed",{slot:a.activeButton,button:d}),b.notify("editor.layout_changed")}}),b.addEventListener("editor_interface.button_uselimit_change",function(c){a.activeButton&&(isNaN(Number(c))||(a.getCurrentLayout().getButton(a.activeButton).useLimit=0===c.length?-1:Number(c),b.notify("editor.layout_changed")))}),b.addEventListener("main_interface.button_click",function(b){a.enabled&&a.setActiveButton(b.slot)}),b.addEventListener("main_interface.editor_click",function(){a.enabled?a.runCurrentLayout():a.enable()}),b.addEventListener("main_interface.reset_click",function(){a.enabled&&a.resetActiveButton()})},init:function(a){"layouts"in a&&this.loadLayouts(a.layouts),"enabled"in a&&(this.enabled=a.enabled),this.ui.render(this.calculator.ui),this.setCurrentLayout("current"in a&&a.current?a.current:"default"),this.enabled&&this.enable(),"activeButton"in a&&this.enabled&&this.setActiveButton(a.activeButton)},getState:function(){return{current:this.current,activeButton:this.activeButton,enabled:this.enabled,layouts:this.layouts.map(function(a,b){return b.isEditable()?b:void 0})}},loadLayouts:function(a){var b,c={};for(var d in a){for(var e in a[d].buttonMap)a[d].buttonMap.hasOwnProperty(e)&&(c[e]=Sankore.Button.create(a[d].buttonMap[e].text,a[d].buttonMap[e].command,a[d].buttonMap[e].useLimit));b=Sankore.Editor.Layout.create({id:a[d].id,name:a[d].name,description:a[d].description,buttonMap:c}),b.setEditable(!0),this.layouts.add("id",[b])}},getCurrentLayout:function(){return null===this.current?null:this.layouts.get(this.current)},setCurrentLayout:function(a){this.current=a,this.calculator.eventDispatcher.notify("editor.layout_selected",this.getCurrentLayout()),this.resetActiveButton()},createLayout:function(){var a=this.layouts.get("default").clone();return a.id=this.generateId(),a.name=_("layout.new_name"),a.setEditable(!0),this.layouts.set(a.id,a),this.calculator.eventDispatcher.notify("editor.layout_created"),a},generateId:function(){var a,b="",c=new Date,d=0;for(a=0;a<document.URL.length;a++)b+=String(document.URL.charCodeAt(a)*(c.getMilliseconds()+c.getSeconds()+c.getMinutes()));b=b.match(/.{1,10}/g);for(a in b)d+=Number(b[a]);return d.toString(36)},removeLayout:function(a){confirm(_("editor.remove_alert"))&&(this.layouts.remove(a),this.calculator.eventDispatcher.notify("editor.layout_removed"))},setActiveButton:function(a){if(a&&this.getCurrentLayout().isEditable()){var b=this.getCurrentLayout().getButton(a);b.isEditable()&&(this.calculator.eventDispatcher.notify("editor.button_selected",{slot:a,button:b,previousSlot:this.activeButton}),this.activeButton=a)}else this.resetActiveButton()},resetActiveButton:function(){this.calculator.eventDispatcher.notify("editor.button_selected",{slot:null,button:null,previousSlot:this.activeButton}),this.activeButton=null},enable:function(){this.enabled=!0,this.setActiveButton(null),this.calculator.eventDispatcher.notify("editor.show")},disable:function(){this.enabled=!1,this.setActiveButton(null),this.calculator.eventDispatcher.notify("editor.hide")},getAssignableCommands:function(){return this.calculator.commands.map(function(a,b){return b.isInternal()?void 0:b})},getAssignableTexts:function(){return this.calculator.texts.map(function(a,b){return b.isEditable()?b:void 0})},runCurrentLayout:function(){this.disable()}}))}(),function(){"use strict";klass.define("Sankore.Editor","Layout",klass.extend({constructor:function(a){this.id=a.id||null,this.name=a.name||null,this.description=a.description||null,this.editable=!1,this.buttonMap=a.buttonMap||{}},setEditable:function(a){this.editable=!!a},isEditable:function(){return this.editable},getButton:function(a){return this.buttonMap[a]||null},clone:function(){var a={};for(var b in this.buttonMap)this.buttonMap.hasOwnProperty(b)&&(a[b]=this.buttonMap[b].clone());return Sankore.Editor.Layout.create({id:this.id,name:this.name,description:this.description,editable:this.editable,buttonMap:a})}}))}(),function(){"use strict";klass.define("Sankore","KeystrokeLine",klass.extend({constructor:function(a){this.dispatcher=a,this.keystrokes=[],this.caret=0},notify:function(){this.dispatcher.notify("keystroke_line.changed",this)},hit:function(a){this.keystrokes.splice(this.caret,0,a),this.caret++,this.notify()},del:function(){if(this.caret>0){var a=this.keystrokes.splice(this.caret-1,1)[0];return this.caret--,this.notify(),a}},moveCaretLeft:function(){this.caret>0&&(this.caret--,this.notify())},moveCaretRight:function(){this.caret<this.keystrokes.length&&(this.caret++,this.notify())},moveCaretToEnd:function(){this.caret=this.keystrokes.length,this.notify()},reset:function(){this.caret=0,this.keystrokes=[],this.notify()},count:function(){return this.keystrokes.length},at:function(a){if("undefined"!=typeof this.keystrokes[a])return this.keystrokes[a];throw Sankore.Util.Error.create("OutOfRangeError","No keystroke at index "+a)},getAsText:function(){return[this.getTextAtRange(0,this.caret),this.getTextAtRange(this.caret,this.keystrokes.length)]},getTextAtRange:function(a,b){var c,d="";if(0>a)throw Sankore.Util.Error.create("OutOfRangeError","Cannot get keystroke before index 0");if(a>this.keystrokes.length)throw Sankore.Util.Error.create("OutOfRangeError","Cannot get keystroke after index "+this.keystrokes.length);for(c=a;b>c;c++)d+=this.at(c).text;return d},getState:function(){return{keystrokes:this.keystrokes,caret:this.caret}},loadState:function(a){this.keystrokes=a.keystrokes||{},this.caret=a.caret||0,this.notify()}}))}(),function(){"use strict";klass.define("Sankore","Text",klass.extend({constructor:function(a,b,c,d,e){this.id=a,this.screen=b,this.button=c,this.type="undefined"!=typeof d?d:"normal",this.editable="undefined"!=typeof e?!!e:!0},isEditable:function(){return this.editable},setEditable:function(a){this.editable=!!a}}))}(),function(){"use strict";klass.define("Sankore.UI","EditorInterface",klass.extend({constructor:function(a,b){this.editor=a,this.dispatcher=b,this.hidden=!0,this.editArea=null,this.layoutSelect=null,this.layoutNameInput=null,this.layoutDescriptionInput=null,this.assignationDiv=null,this.runButton=null,this.addButton=null,this.removeButton=null,this.attachEventListeners(),this.rendered=!1},attachEventListeners:function(){var a=this;this.dispatcher.addEventListener("editor.show",this.show.bind(this)),this.dispatcher.addEventListener("editor.hide",this.hide.bind(this)),this.dispatcher.addEventSubscriber({events:["editor.layout_changed","editor.layout_created","editor.layout_removed"],listener:this.updateLayoutSelectElement.bind(this)}),this.dispatcher.addEventListener("editor.layout_selected",function(b){a.loadLayout(b),a.selectLayout(b.id)}),this.dispatcher.addEventListener("editor.button_selected",function(b){var c=b.button;null===c&&a.editor.getCurrentLayout()&&(c=a.editor.getCurrentLayout().isEditable()),a.renderAssignation(c)})},_clearElement:function(a){for(;a.firstChild;)a.removeChild(a.firstChild)},_map:function(a,b){var c,d=[];for(c in a)a.hasOwnProperty(c)&&d.push(b.call(a,a[c],c));return d},render:function(a){var b,c,d=this;this.editArea=document.createElement("div"),this.editArea.classList.add("edit-area"),this.layoutSelect=this.createLayoutSelectElement(),this.editArea.appendChild(this.layoutSelect),this.addButton=document.createElement("button"),this.addButton.className="small",this.addButton.setAttribute("type","button"),this.addButton.addEventListener("click",function(){d.dispatcher.notify("editor_interface.add_click")}),this.removeButton=this.addButton.cloneNode(),this.removeButton.classList.add("remove"),this.removeButton.addEventListener("click",function(){d.dispatcher.notify("editor_interface.remove_click")}),this.addButton.classList.add("add"),this.editArea.appendChild(this.addButton),this.editArea.appendChild(this.removeButton),this.editArea.appendChild(document.createElement("hr")),b=document.createElement("label"),b.appendChild(document.createTextNode(_("editor.layout_name.label"))),this.editArea.appendChild(b),this.layoutNameInput=document.createElement("input"),this.layoutNameInput.setAttribute("name","layout_name"),this.layoutNameInput.setAttribute("type","text"),this.layoutNameInput.setAttribute("maxlength",32),this.layoutNameInput.addEventListener("keyup",function(){d.dispatcher.notify("editor_interface.layout_name_change",this.value)}),this.layoutNameInput.addEventListener("change",function(){0===this.value.trim().length&&(this.value=d.editor.getCurrentLayout().name,d.dispatcher.notify("editor_interface.layout_name_change",this.value))}),this.editArea.appendChild(this.layoutNameInput),c=document.createElement("label"),c.appendChild(document.createTextNode(_("editor.layout_description.label"))),this.editArea.appendChild(c),this.layoutDescriptionInput=document.createElement("textarea"),this.layoutDescriptionInput.setAttribute("name","layout_description"),this.layoutDescriptionInput.setAttribute("maxlength",140),this.layoutDescriptionInput.addEventListener("keyup",function(){d.dispatcher.notify("editor_interface.layout_description_change",this.value)}),this.editArea.appendChild(this.layoutDescriptionInput),this.assignationDiv=document.createElement("div"),this.assignationDiv.classList.add("assignation"),this.editArea.appendChild(this.assignationDiv),this.runButton=document.createElement("button"),this.runButton.classList.add("run"),this.runButton.setAttribute("type","button"),this.runButton.appendChild(document.createTextNode(_("editor.run_button"))),this.runButton.addEventListener("click",function(){d.dispatcher.notify("editor_interface.run_click")}),this.editArea.appendChild(this.runButton),a.rearScreen.parentElement.appendChild(this.editArea),this.rendered=!0,this.hide()},createSelectElement:function(a,b,c,d){var e,f=document.createElement("select");f.setAttribute("name",b),c&&(f.className=c);for(var g in a)e=document.createElement("option"),e.setAttribute("value",a[g].value),"undefined"!=typeof d&&d===a[g].value&&(e.selected=!0),e.appendChild(document.createTextNode(a[g].text)),f.appendChild(e);return f},createLayoutSelectElement:function(){var a=this.createSelectElement(this.editor.layouts.map(function(a,b){return{text:b.name,value:b.id}}),"layouts","layout-select",this.editor.current),b=this;return a.addEventListener("change",function(){b.dispatcher.notify("editor_interface.layout_select",this.value)}),a},updateLayoutSelectElement:function(){var a=this.createLayoutSelectElement();this.editArea.replaceChild(a,this.layoutSelect),this.layoutSelect=a},selectLayout:function(a){this.layoutSelect.value=a},show:function(){this.rendered&&(this.editArea.style.display="block",this.hidden=!1)},hide:function(){this.rendered&&(this.editArea.style.display="none",this.hidden=!0)},loadLayout:function(a){this.layoutNameInput.value=a.name,this.layoutNameInput.disabled=!a.isEditable(),this.layoutDescriptionInput.value=a.description,this.layoutDescriptionInput.disabled=!a.isEditable(),this.removeButton.disabled=!a.isEditable(),this.renderAssignation(a.isEditable())},renderAssignation:function(a){var b,c,d,e,f,g,h,i,j,k=this;!1===a?(b=document.createElement("em"),b.appendChild(document.createTextNode(_("editor.assignation.disabled")))):Sankore.Button.isPrototypeOf(a)?(b=document.createDocumentFragment(),c=document.createElement("label"),c.appendChild(document.createTextNode(_("editor.assignation.text.label"))),b.appendChild(c),j=this.editor.calculator.texts.get(a.text),d=this.createSelectElement(this._map(this.editor.getAssignableTexts(),function(a){return{text:a.button,value:a.id}}),"button_text","",j.id),d.addEventListener("change",function(a){k.dispatcher.notify("editor_interface.button_text_change",a.target.value)}),b.appendChild(d),e=document.createElement("label"),e.appendChild(document.createTextNode(_("editor.assignation.command.label"))),b.appendChild(e),f=this.createSelectElement(this._map(this.editor.getAssignableCommands(),function(a){return{text:a.name,value:a.id}}),"button_command","",a.command),f.addEventListener("change",function(a){k.dispatcher.notify("editor_interface.button_command_change",a.target.value)}),b.appendChild(f),g=document.createElement("label"),g.appendChild(document.createTextNode(_("editor.assignation.use_limit.label"))),b.appendChild(g),h=document.createElement("input"),h.setAttribute("type","text"),h.setAttribute("name","button_count"),h.value=-1===a.useLimit?"":a.useLimit,h.addEventListener("change",function(a){k.dispatcher.notify("editor_interface.button_uselimit_change",a.target.value)}),b.appendChild(h),i=document.createElement("span"),i.className="help",i.appendChild(document.createTextNode(_("editor.assignation.use_limit.help"))),b.appendChild(i)):(b=document.createElement("em"),b.appendChild(document.createTextNode(_("editor.assignation.enabled")))),this._clearElement(this.assignationDiv),this.assignationDiv.appendChild(b)}}))}(),function(){"use strict";klass.define("Sankore.UI","MainInterface",klass.extend({constructor:function(a,b,c,d){this.id=a,this.dispatcher=b,this.texts=c,this.withEditor=d,this.title=null,this.caret=document.createElement("i"),this.caret.className="caret",this.frontScreen=null,this.expressionRow=null,this.resultRow=null,this.flagRow=null,this.flags=[],this.rearScreen=null,this.buttons=Sankore.Util.Hash.create(),this.rendered=!1,this.attachEventListeners()},attachEventListeners:function(){var a=this;this.dispatcher.addEventListener("keystroke_line.changed",function(b){a.updateExpressionRow(b.getAsText())}),this.dispatcher.addEventListener("calculator.memory_changed",function(b){null!==b?a.addFlag("M"):a.removeFlag("M"),a.updateFlagRow()
}),this.dispatcher.addEventListener("calculator.op_changed",function(b){null!==b?a.addFlag("OP"):a.removeFlag("OP"),a.updateFlagRow()}),this.dispatcher.addEventListener("calculator.output_changed",function(b){a.updateResultRow(null!==b.output?b.output:null!==b.error?b.error:"")}),this.dispatcher.addEventListener("calculator.history_changed",this.updateRearScreen.bind(this)),this.dispatcher.addEventListener("calculator.layout_loaded",function(b){a.renderButtons(b.buttonMap),a.changeTitle(b.name),a.clearRearScreen()}),this.dispatcher.addEventListener("calculator.button_disabled",function(b){var c=a.buttons.get(b.slot);c&&(c.disabled=!0)}),this.dispatcher.addEventListener("calculator.button_enabled",function(b){var c=a.buttons.get(b);c&&(c.disabled=!1)}),this.dispatcher.addEventListener("editor.show",this.hideRearScreen.bind(this)),this.dispatcher.addEventListener("editor.hide",this.showRearScreen.bind(this)),this.dispatcher.addEventListener("editor.button_selected",function(b){var c=a.buttons.get(b.slot),d=a.buttons.get(b.previousSlot);d&&d.parentElement.classList.remove("edit"),c&&c.parentElement.classList.add("edit")}),this.dispatcher.addEventListener("editor.button_renamed",function(b){var c,d=a.buttons.get(b.slot),e=a.texts.get(b.button.text);d&&(d.innerText=e.button,c=d.parentElement.classList.contains("edit"),d.parentElement.className=e.type,c&&d.parentElement.classList.add("edit"))})},_clearElement:function(a){for(;a.firstChild;)a.removeChild(a.firstChild)},getRootElement:function(){return document.getElementById(this.id)},render:function(){var a=this.getRootElement();this._clearElement(a),a.classList.contains("calculator")||a.classList.add("calculator"),this.createBaseMarkup(a),this.rearScreen=document.createElement("ul"),a.getElementsByClassName("rear-screen").item(0).appendChild(this.rearScreen),this.frontScreen=document.createElement("ul"),a.getElementsByClassName("front-screen").item(0).appendChild(this.frontScreen),this.expressionRow=document.createElement("li"),this.expressionRow.classList.add("expression-row"),this.frontScreen.appendChild(this.expressionRow),this.flagRow=document.createElement("li"),this.flagRow.classList.add("flag-row"),this.frontScreen.appendChild(this.flagRow),this.resultRow=document.createElement("li"),this.resultRow.classList.add("result-row"),this.frontScreen.appendChild(this.resultRow),this.rendered=!0},renderButtons:function(a){var b,c={},d=document.createDocumentFragment(),e=this.getRootElement().getElementsByClassName("screen").item(0).parentElement;for(var f in a)c[f]=a[f];for(c.a0=Sankore.Button.create("s","del",-1,!1),c.b0=Sankore.Button.create("l","left",-1,!1),c.c0=Sankore.Button.create("r","right",-1,!1),c.d0=Sankore.Button.create("c","clear",-1,!1),b=e.getElementsByClassName("buttons");b.length>0;)e.removeChild(b[0]);b=this.createButtons(c);for(var g in b)d.appendChild(b[g]);e.appendChild(d)},createBaseMarkup:function(a){var b=document.createElement("table"),c=document.createElement("tr"),d=document.createElement("td"),e=document.createElement("td");d.className="rear-screen",d.setAttribute("rowspan","8"),c.appendChild(d),e.className="front-screen",e.setAttribute("colspan","4"),c.appendChild(e),c.className="screen",b.appendChild(c),a.appendChild(this.createTitle()),a.appendChild(this.createControls()),a.appendChild(b)},createTitle:function(){return this.title=document.createElement("span"),this.title.appendChild(document.createTextNode("Chargement...")),this.title.className="title",this.title},createControls:function(){var a=document.createElement("div"),b=document.createElement("button"),c=document.createElement("button"),d=this;return this.withEditor&&(b.setAttribute("type","button"),b.appendChild(document.createTextNode(_("controls.editor"))),b.addEventListener("click",function(){d.dispatcher.notify("main_interface.editor_click")}),a.appendChild(b)),c.setAttribute("type","button"),c.appendChild(document.createTextNode(_("controls.reset"))),c.addEventListener("click",function(){d.dispatcher.notify("main_interface.reset_click")}),a.appendChild(c),a.className="controls",a},createButtons:function(a){var b,c=[];for(b=0;7>b;b++)c.push(this.createButtonRow(b,a));return c},createButtonRow:function(a,b){var c,d=document.createElement("tr");for(d.className="buttons",c="a";"d">=c;c=String.fromCharCode(c.charCodeAt(0)+1))d.appendChild(this.createButton(c+a,b));return d},createButton:function(a,b){var c,d,e=document.createElement("td"),f=this,g=b[a];return e.setAttribute("data-slot",a),e.setAttribute("data-editable",g.isEditable()),"undefined"!=typeof g&&(d=document.createElement("button"),c=this.texts.get(g.text),d.innerText=c.button,"normal"!==c.type&&e.classList.add(c.type),d.addEventListener("mousedown",function(b){f.handleButtonClick(this,b,g,a)}),this.buttons.set(a,d),this.dispatcher.notify("main_interface.button_created",{button:g,slot:a}),e.appendChild(d)),e},handleButtonClick:function(a,b,c,d){this.dispatcher.notify("main_interface.button_click",{button:c,slot:d})},updateFlagRow:function(){var a;this._clearElement(this.flagRow);for(var b in this.flags)a=document.createElement("span"),a.appendChild(document.createTextNode(this.flags[b])),this.flagRow.appendChild(a)},updateExpressionRow:function(a){this._clearElement(this.expressionRow),this.expressionRow.appendChild(document.createTextNode(a[0])),this.expressionRow.appendChild(this.caret),this.expressionRow.appendChild(document.createTextNode(a[1]))},updateResultRow:function(a){this._clearElement(this.resultRow),this.resultRow.appendChild(this.createResultRow(a))},createResultRow:function(a){try{return Sankore.Calculus.EuclideanDivisionOperation.isPrototypeOf(a)?this.createResultRowEuclidean(a.getValue(),a.getRemainder()):Sankore.Calculus.Expression.isPrototypeOf(a)?this.createResultRowExpression(a.getValue()):Sankore.Util.Error.isPrototypeOf(a)?this.createResultRowError(a):this.createResultRowText(String(a))}catch(b){return this.createResultRowError(b)}return null},createResultRowEuclidean:function(a,b){var c=document.createElement("p"),d=document.createElement("span"),e=document.createElement("span");return c.classList.add("euclidean"),e.classList.add("remainder"),e.textContent=this.formatResultValue(b),c.appendChild(e),d.classList.add("quotient"),d.textContent=this.formatResultValue(a),c.appendChild(d),c},createResultRowExpression:function(a){return document.createTextNode(this.formatResultValue(a))},createResultRowText:function(a){return document.createTextNode(a)},createResultRowError:function(a){var b=document.createElement("div"),c=_("error.common");return"ZeroDivision"===a.name&&(c=_("error.zero_division")),b.classList.add("error"),b.appendChild(document.createTextNode(c)),b},formatResultValue:function(a){var b,c=a.toFixed(Math.max(0,10-a.toFixed().length));if(-1!==c.indexOf("."))for(;;){b=c.charAt(c.length-1);{if("0"!==b){"."===b&&(c=c.slice(0,-1));break}c=c.slice(0,-1)}}return Number(c)>1e10-1&&(c=Number(c.substring(0,11)/10).toFixed()),-1!==c.indexOf(".")&&(c=c.replace(".",_("text.comma"))),c},updateRearScreen:function(a){var b,c,d=document.createDocumentFragment();for(var e in a)b=document.createElement("li"),b.className="expression-row",b.appendChild(document.createTextNode(a[e].expression)),d.appendChild(b),c=document.createElement("li"),c.className="result-row",c.appendChild(this.createResultRow(a[e].output)),d.appendChild(c);this.clearRearScreen(),this.rearScreen.appendChild(d),this.rearScreen.lastChild.scrollIntoView()},clearRearScreen:function(){this._clearElement(this.rearScreen)},showRearScreen:function(){this.rearScreen.style.display="block",this.showTitle()},hideRearScreen:function(){this.rearScreen.style.display="none",this.hideTitle()},addFlag:function(a){-1===this.flags.indexOf(a)&&(this.flags.push(a),this.flags.sort())},removeFlag:function(a){var b=this.flags.indexOf(a);-1!==b&&(this.flags.splice(b,1),this.flags.sort())},changeTitle:function(a){this._clearElement(this.title),this.title.appendChild(document.createTextNode(a))},showTitle:function(){this.title.style.visibility="visible"},hideTitle:function(){this.title.style.visibility="hidden"}}))}(),function(){"use strict";klass.define("Sankore.Util","Error",klass.extend({constructor:function(a,b){this.name=a,this.message=b},toString:function(){return this.name+": "+this.message}}))}(),function(){"use strict";klass.define("Sankore.Util","EventDispatcher",klass.extend({constructor:function(){this.eventListeners={}},addEventSubscriber:function(a){for(var b in a.events)this.addEventListener(a.events[b],a.listener);return this},addEventListener:function(a,b,c){return"undefined"==typeof this.eventListeners[a]&&(this.eventListeners[a]=[]),"undefined"==typeof c?this.eventListeners[a].push(b):this.eventListeners[a][c]=b,this},removeEventListener:function(a,b){delete this.eventListeners[a][b]},removeAllEventListeners:function(a){this.eventListeners[a]=[]},notify:function(a,b){var c;for(c in this.eventListeners[a])this.eventListeners[a][c](b)}}))}(),function(){"use strict";klass.define("Sankore.Util","Hash",klass.extend({constructor:function(a){this.elements=a||{}},length:function(){return this.keys().length},keys:function(){return Object.keys(this.elements)},set:function(a,b){this.elements[a]=b},add:function(a,b){for(var c in b)this.set(b[c][a],b[c])},has:function(a){return-1!==this.keys().indexOf(a)},get:function(a,b){return"undefined"!=typeof this.elements[a]?this.elements[a]:"undefined"!=typeof b?b:null},pos:function(a){var b=0;for(var c in this.elements){if(this.elements.hasOwnProperty(c)&&c===a)return b;b++}return null},remove:function(a){return delete this.elements[a]},map:function(a){var b,c=[];for(var d in this.elements)this.elements.hasOwnProperty(d)&&(b=a.call(this,d,this.elements[d]),b&&c.push(b));return c}}))}(),function(){"use strict";klass.define("Sankore.Util","I18N",klass.extend({catalogs:Sankore.Util.Hash.create(),constructor:function(){this.catalog={}},load:function(a){var b=a.split(/-|_/)[0].toLowerCase();Sankore.Util.I18N.catalogs.has(b)||(b="en"),this.catalog=Sankore.Util.I18N.catalogs.get(b,{})},translate:function(a){return a.split(".").reduce(function(a,b){return a&&b in a?a[b]:null},this.catalog)||a}})),Sankore.Util.i18n=Sankore.Util.I18N.create(),window._=function(a){return Sankore.Util.i18n.translate(a)}}(),function(){Sankore.Util.I18N.catalogs.set("en",{layout:{classic_name:"Basic calculator",new_name:"New calculator"},text:{del:"DEL",comma:"."},command:{zero:"0 digit",one:"1 digit",two:"2 digit",three:"3 digit",four:"4 digit",five:"5 digit",six:"6 digit",seven:"7 digit",eight:"8 digit",nine:"9 digit",plus:"Addition",minus:"Subtraction",times:"Multiplication",divide:"Division",euclidean_divide:"Euclidean division",equal:"Equal",comma:"Comma",open_parenthesis:"Open parenthesis",close_parenthesis:"Close parenthesis",op:"Constant operator",memory_add:"Memory addition",memory_sub:"Memory substraction",memory_recall:"Memory recall",memory_clear:"Memory clear",clear:"Clear",left:"Move left",right:"Move right",del:"Delete"},controls:{editor:"Editor",reset:"RST"},editor:{run_button:"Run",remove_alert:"Delete this calculator?",layout_name:{label:"Name"},layout_description:{label:"Description"},assignation:{enabled:"Click on a button to edit it",disabled:"This calculator is not editable",text:{label:"Display text"},command:{label:"Command"},use_limit:{label:"Use limit",help:"0 for disabled, empty for unlimited"}}},error:{common:"Error",zero_division:"Div/0 error"}})}(),function(){Sankore.Util.I18N.catalogs.set("fr",{layout:{classic_name:"Calculatrice standard",new_name:"Nouvelle calculatrice"},text:{del:"EFF",comma:","},command:{zero:"Chiffre 0",one:"Chiffre 1",two:"Chiffre 2",three:"Chiffre 3",four:"Chiffre 4",five:"Chiffre 5",six:"Chiffre 6",seven:"Chiffre 7",eight:"Chiffre 8",nine:"Chiffre 9",plus:"Addition",minus:"Soustraction",times:"Multiplication",divide:"Division",euclidean_divide:"Division euclidienne",equal:"Egalité",comma:"Virgule",open_parenthesis:"Parenthèse ouvrante",close_parenthesis:"Parenthèse fermante",op:"Opérateur constant",memory_add:"Addition mémoire",memory_sub:"Soustraction mémoire",memory_recall:"Rappel mémoire",memory_clear:"R.A.Z. mémoire",clear:"R.A.Z.",left:"Déplacement à gauche",right:"Déplacement à droite",del:"Suppression"},controls:{editor:"Editeur",reset:"RAZ"},editor:{run_button:"Utiliser",remove_alert:"Supprimer cette calculatrice ?",layout_name:{label:"Nom"},layout_description:{label:"Description"},assignation:{enabled:"Cliquez sur une touche pour la modifier",disabled:"Cette calculatrice n'est pas modifiable",text:{label:"Texte à afficher"},command:{label:"Commande"},use_limit:{label:"Nb d'utilisation",help:"0 pour désactiver, vide pour illimité"}}},error:{common:"Erreur",zero_division:"Erreur div/0"}})}();