diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/003671ee2a876e7614cd94390e2255b3.js b/003671ee2a876e7614cd94390e2255b3.js new file mode 100644 index 00000000..7d6dcb3e --- /dev/null +++ b/003671ee2a876e7614cd94390e2255b3.js @@ -0,0 +1 @@ +ace.define("ace/snippets/csound_document.snippets",["require","exports","module"],(function(e,n,t){t.exports="# \nsnippet synth\n\t\n\t\n\t${1}\n\t\n\t\n\te\n\t\n\t\n"})),ace.define("ace/snippets/csound_document",["require","exports","module","ace/snippets/csound_document.snippets"],(function(e,n,t){"use strict";n.snippetText=e("./csound_document.snippets"),n.scope="csound_document"})),ace.require(["ace/snippets/csound_document"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/0078b630bed2938ce03f618c2bcd1363.js b/0078b630bed2938ce03f618c2bcd1363.js new file mode 100644 index 00000000..6d299ebd --- /dev/null +++ b/0078b630bed2938ce03f618c2bcd1363.js @@ -0,0 +1 @@ +ace.define("ace/mode/ion_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var i=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,r=function(){var e={token:this.createKeywordMapper({"constant.language.bool.ion":"TRUE|FALSE","constant.language.null.ion":"NULL.NULL|NULL.BOOL|NULL.INT|NULL.FLOAT|NULL.DECIMAL|NULL.TIMESTAMP|NULL.STRING|NULL.SYMBOL|NULL.BLOB|NULL.CLOB|NULL.STRUCT|NULL.LIST|NULL.SEXP|NULL"},"constant.other.symbol.identifier.ion",!0),regex:"\\b\\w+(?:\\.\\w+)?\\b"};this.$rules={start:[{include:"value"}],value:[{include:"whitespace"},{include:"comment"},{include:"annotation"},{include:"string"},{include:"number"},{include:"keywords"},{include:"symbol"},{include:"clob"},{include:"blob"},{include:"struct"},{include:"list"},{include:"sexp"}],sexp:[{token:"punctuation.definition.sexp.begin.ion",regex:"\\(",push:[{token:"punctuation.definition.sexp.end.ion",regex:"\\)",next:"pop"},{include:"comment"},{include:"value"},{token:"storage.type.symbol.operator.ion",regex:"[\\!\\#\\%\\&\\*\\+\\-\\./\\;\\<\\=\\>\\?\\@\\^\\`\\|\\~]+"}]}],comment:[{token:"comment.line.ion",regex:"//[^\\n]*"},{token:"comment.block.ion",regex:"/\\*",push:[{token:"comment.block.ion",regex:"[*]/",next:"pop"},{token:"comment.block.ion",regex:"[^*/]+"},{token:"comment.block.ion",regex:"[*/]+"}]}],list:[{token:"punctuation.definition.list.begin.ion",regex:"\\[",push:[{token:"punctuation.definition.list.end.ion",regex:"\\]",next:"pop"},{include:"comment"},{include:"value"},{token:"punctuation.definition.list.separator.ion",regex:","}]}],struct:[{token:"punctuation.definition.struct.begin.ion",regex:"\\{",push:[{token:"punctuation.definition.struct.end.ion",regex:"\\}",next:"pop"},{include:"comment"},{include:"value"},{token:"punctuation.definition.struct.separator.ion",regex:",|:"}]}],blob:[{token:["punctuation.definition.blob.begin.ion","string.other.blob.ion","punctuation.definition.blob.end.ion"],regex:'(\\{\\{)([^"]*)(\\}\\})'}],clob:[{token:["punctuation.definition.clob.begin.ion","string.other.clob.ion","punctuation.definition.clob.end.ion"],regex:'(\\{\\{)("[^"]*")(\\}\\})'}],symbol:[{token:"storage.type.symbol.quoted.ion",regex:"(['])((?:(?:\\\\')|(?:[^']))*?)(['])"},{token:"storage.type.symbol.identifier.ion",regex:"[\\$_a-zA-Z][\\$_a-zA-Z0-9]*"}],number:[{token:"constant.numeric.timestamp.ion",regex:"\\d{4}(?:-\\d{2})?(?:-\\d{2})?T(?:\\d{2}:\\d{2})(?::\\d{2})?(?:\\.\\d+)?(?:Z|[-+]\\d{2}:\\d{2})?"},{token:"constant.numeric.timestamp.ion",regex:"\\d{4}-\\d{2}-\\d{2}T?"},{token:"constant.numeric.integer.binary.ion",regex:"-?0[bB][01](?:_?[01])*"},{token:"constant.numeric.integer.hex.ion",regex:"-?0[xX][0-9a-fA-F](?:_?[0-9a-fA-F])*"},{token:"constant.numeric.float.ion",regex:"-?(?:0|[1-9](?:_?\\d)*)(?:\\.(?:\\d(?:_?\\d)*)?)?(?:[eE][+-]?\\d+)"},{token:"constant.numeric.float.ion",regex:"(?:[-+]inf)|(?:nan)"},{token:"constant.numeric.decimal.ion",regex:"-?(?:0|[1-9](?:_?\\d)*)(?:(?:(?:\\.(?:\\d(?:_?\\d)*)?)(?:[dD][+-]?\\d+)|\\.(?:\\d(?:_?\\d)*)?)|(?:[dD][+-]?\\d+))"},{token:"constant.numeric.integer.ion",regex:"-?(?:0|[1-9](?:_?\\d)*)"}],string:[{token:["punctuation.definition.string.begin.ion","string.quoted.double.ion","punctuation.definition.string.end.ion"],regex:'(["])((?:(?:\\\\")|(?:[^"]))*?)(["])'},{token:"punctuation.definition.string.begin.ion",regex:"'{3}",push:[{token:"punctuation.definition.string.end.ion",regex:"'{3}",next:"pop"},{token:"string.quoted.triple.ion",regex:"(?:\\\\'|[^'])+"},{token:"string.quoted.triple.ion",regex:"'"}]}],annotation:[{token:["variable.language.annotation.ion","punctuation.definition.annotation.ion"],regex:/('(?:[^'\\]|\\.)*')\s*(::)/},{token:["variable.language.annotation.ion","punctuation.definition.annotation.ion"],regex:"([\\$_a-zA-Z][\\$_a-zA-Z0-9]*)\\s*(::)"}],whitespace:[{token:"text.ion",regex:"\\s+"}]},this.$rules.keywords=[e],this.normalizeRules()};i.inherits(r,o),t.IonHighlightRules=r})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var i=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,r=e.findMatchingBracket({row:t,column:o});if(!r||r.row==t)return 0;var a=this.$getIndent(e.getLine(r.row));e.replace(new i(t,0,t,o-1),a)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var i=e("../../lib/oop"),o=e("../../range").Range,r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};i.inherits(a,r),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var i=e.getLine(n);if(this.singleLineBlockCommentRe.test(i)&&!this.startRegionRe.test(i)&&!this.tripleStarBlockCommentRe.test(i))return"";var o=this._getFoldWidgetBase(e,t,n);return!o&&this.startRegionRe.test(i)?"start":o},this.getFoldWidgetRange=function(e,t,n,i){var o,r=e.getLine(n);if(this.startRegionRe.test(r))return this.getCommentRegionBlock(e,r,n);if(o=r.match(this.foldingStartMarker)){var a=o.index;if(o[1])return this.openingBracketBlock(e,o[1],n,a);var s=e.getCommentFoldRange(n,a+o[0].length,1);return s&&!s.isMultiLine()&&(i?s=this.getSectionRange(e,n):"all"!=t&&(s=null)),s}return"markbegin"!==t&&(o=r.match(this.foldingStopMarker))?(a=o.index+o[0].length,o[1]?this.closingBracketBlock(e,o[1],n,a):e.getCommentFoldRange(n,a,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),i=n.search(/\S/),r=t,a=n.length,s=t+=1,c=e.getLength();++tu)break;var d=this.getFoldWidgetRange(e,"all",t);if(d){if(d.start.row<=r)break;if(d.isMultiLine())t=d.end.row;else if(i==u)break}s=t}}return new o(r,a,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var i=t.search(/\s*$/),r=e.getLength(),a=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,c=1;++na)return new o(a,i,n,t.length)}}.call(a.prototype)})),ace.define("ace/mode/ion",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ion_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var i=e("../lib/oop"),o=e("./text").Mode,r=e("./ion_highlight_rules").IonHighlightRules,a=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=r,this.$outdent=new a,this.$behaviour=this.$defaultBehaviour,this.foldingRules=new s};i.inherits(c,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var i=this.$getIndent(t);return"start"==e&&t.match(/^.*[\{\(\[]\s*$/)&&(i+=n),i},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/ion"}.call(c.prototype),t.Mode=c})),ace.require(["ace/mode/ion"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/0144de97a3c256f81447e7e7135780e5.js b/0144de97a3c256f81447e7e7135780e5.js new file mode 100644 index 00000000..cd7b7987 --- /dev/null +++ b/0144de97a3c256f81447e7e7135780e5.js @@ -0,0 +1 @@ +ace.define("ace/mode/properties_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,o){"use strict";var i=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,s=function(){var e=/\\u[0-9a-fA-F]{4}|\\/;this.$rules={start:[{token:"comment",regex:/[!#].*$/},{token:"keyword",regex:/[=:]$/},{token:"keyword",regex:/[=:]/,next:"value"},{token:"constant.language.escape",regex:e},{defaultToken:"variable"}],value:[{regex:/\\$/,token:"string",next:"value"},{regex:/$/,token:"string",next:"start"},{token:"constant.language.escape",regex:e},{defaultToken:"string"}]}};i.inherits(s,r),t.PropertiesHighlightRules=s})),ace.define("ace/mode/properties",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/properties_highlight_rules"],(function(e,t,o){"use strict";var i=e("../lib/oop"),r=e("./text").Mode,s=e("./properties_highlight_rules").PropertiesHighlightRules,l=function(){this.HighlightRules=s,this.$behaviour=this.$defaultBehaviour};i.inherits(l,r),function(){this.$id="ace/mode/properties"}.call(l.prototype),t.Mode=l})),ace.require(["ace/mode/properties"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/019e34e85139cfc611bf23efa096c980.js b/019e34e85139cfc611bf23efa096c980.js new file mode 100644 index 00000000..9d874b10 --- /dev/null +++ b/019e34e85139cfc611bf23efa096c980.js @@ -0,0 +1 @@ +ace.define("ace/theme/chrome-css",["require","exports","module"],(function(e,c,n){n.exports='.ace-chrome .ace_gutter {\n background: #ebebeb;\n color: #333;\n overflow : hidden;\n}\n\n.ace-chrome .ace_print-margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-chrome {\n background-color: #FFFFFF;\n color: black;\n}\n\n.ace-chrome .ace_cursor {\n color: black;\n}\n\n.ace-chrome .ace_invisible {\n color: rgb(191, 191, 191);\n}\n\n.ace-chrome .ace_constant.ace_buildin {\n color: rgb(88, 72, 246);\n}\n\n.ace-chrome .ace_constant.ace_language {\n color: rgb(88, 92, 246);\n}\n\n.ace-chrome .ace_constant.ace_library {\n color: rgb(6, 150, 14);\n}\n\n.ace-chrome .ace_invalid {\n background-color: rgb(153, 0, 0);\n color: white;\n}\n\n.ace-chrome .ace_fold {\n}\n\n.ace-chrome .ace_support.ace_function {\n color: rgb(60, 76, 114);\n}\n\n.ace-chrome .ace_support.ace_constant {\n color: rgb(6, 150, 14);\n}\n\n.ace-chrome .ace_support.ace_type,\n.ace-chrome .ace_support.ace_class\n.ace-chrome .ace_support.ace_other {\n color: rgb(109, 121, 222);\n}\n\n.ace-chrome .ace_variable.ace_parameter {\n font-style:italic;\n color:#FD971F;\n}\n.ace-chrome .ace_keyword.ace_operator {\n color: rgb(104, 118, 135);\n}\n\n.ace-chrome .ace_comment {\n color: #236e24;\n}\n\n.ace-chrome .ace_comment.ace_doc {\n color: #236e24;\n}\n\n.ace-chrome .ace_comment.ace_doc.ace_tag {\n color: #236e24;\n}\n\n.ace-chrome .ace_constant.ace_numeric {\n color: rgb(0, 0, 205);\n}\n\n.ace-chrome .ace_variable {\n color: rgb(49, 132, 149);\n}\n\n.ace-chrome .ace_xml-pe {\n color: rgb(104, 104, 91);\n}\n\n.ace-chrome .ace_entity.ace_name.ace_function {\n color: #0000A2;\n}\n\n\n.ace-chrome .ace_heading {\n color: rgb(12, 7, 255);\n}\n\n.ace-chrome .ace_list {\n color:rgb(185, 6, 144);\n}\n\n.ace-chrome .ace_marker-layer .ace_selection {\n background: rgb(181, 213, 255);\n}\n\n.ace-chrome .ace_marker-layer .ace_step {\n background: rgb(252, 255, 0);\n}\n\n.ace-chrome .ace_marker-layer .ace_stack {\n background: rgb(164, 229, 101);\n}\n\n.ace-chrome .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-chrome .ace_marker-layer .ace_active-line {\n background: rgba(0, 0, 0, 0.07);\n}\n\n.ace-chrome .ace_gutter-active-line {\n background-color : #dcdcdc;\n}\n\n.ace-chrome .ace_marker-layer .ace_selected-word {\n background: rgb(250, 250, 255);\n border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-chrome .ace_storage,\n.ace-chrome .ace_keyword,\n.ace-chrome .ace_meta.ace_tag {\n color: rgb(147, 15, 128);\n}\n\n.ace-chrome .ace_string.ace_regex {\n color: rgb(255, 0, 0)\n}\n\n.ace-chrome .ace_string {\n color: #1A1AA6;\n}\n\n.ace-chrome .ace_entity.ace_other.ace_attribute-name {\n color: #994409;\n}\n\n.ace-chrome .ace_indent-guide {\n background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;\n}\n \n.ace-chrome .ace_indent-guide-active {\n background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC") right repeat-y;\n}\n'})),ace.define("ace/theme/chrome",["require","exports","module","ace/theme/chrome-css","ace/lib/dom"],(function(e,c,n){c.isDark=!1,c.cssClass="ace-chrome",c.cssText=e("./chrome-css"),e("../lib/dom").importCssString(c.cssText,c.cssClass,!1)})),ace.require(["ace/theme/chrome"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/02174460fe8ff6a6bc19db86543b9600.js b/02174460fe8ff6a6bc19db86543b9600.js new file mode 100644 index 00000000..babd16b0 --- /dev/null +++ b/02174460fe8ff6a6bc19db86543b9600.js @@ -0,0 +1 @@ +ace.define("ace/snippets/robot.snippets",["require","exports","module"],(function(n,e,t){t.exports="# scope: robot\n### Sections\nsnippet settingssection\ndescription *** Settings *** section\n\t*** Settings ***\n\tLibrary ${1}\n\nsnippet keywordssection\ndescription *** Keywords *** section\n\t*** Keywords ***\n\t${1:Keyword Name}\n\t [Arguments] \\${${2:Example Arg 1}}\n\t\nsnippet testcasessection\ndescription *** Test Cases *** section\n\t*** Test Cases ***\n\t${1:First Test Case}\n\t ${2:Log Example Arg}\n\nsnippet variablessection\ndescription *** Variables *** section\n\t*** Variables ***\n\t\\${${1:Variable Name}}= ${2:Variable Value}\n\n### Helpful keywords\nsnippet testcase\ndescription A test case\n\t${1:Test Case Name}\n\t ${2:Log Example log message}\n\t\nsnippet keyword\ndescription A keyword\n\t${1:Example Keyword}\n\t [Arguments] \\${${2:Example Arg 1}}\n\n### Built Ins\nsnippet forinr\ndescription For In Range Loop\n\tFOR \\${${1:Index}} IN RANGE \\${${2:10}}\n\t Log \\${${1:Index}}\n\tEND\n\nsnippet forin\ndescription For In Loop\n\tFOR \\${${1:Item}} IN @{${2:List Variable}}\n\t Log \\${${1:Item}}\n\tEND\n\nsnippet if\ndescription If Statement\n\tIF ${1:condition}\n\t ${2:Do something}\n\tEND\n\nsnippet else\ndescription If Statement\n\tIF ${1:Condition}\n\t ${2:Do something}\n\tELSE\n\t ${3:Otherwise do this}\n\tEND\n\nsnippet elif\ndescription Else-If Statement\n\tIF ${1:Condition 1}\n\t ${2:Do something}\n\tELSE IF ${3:Condition 2}\n\t ${4:Do something else}\n\tEND\n"})),ace.define("ace/snippets/robot",["require","exports","module","ace/snippets/robot.snippets"],(function(n,e,t){"use strict";e.snippetText=n("./robot.snippets"),e.scope="robot"})),ace.require(["ace/snippets/robot"],(function(n){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=n)})); \ No newline at end of file diff --git a/029ed9161a8d24a9c2ba97124020989d.js b/029ed9161a8d24a9c2ba97124020989d.js new file mode 100644 index 00000000..2d29e063 --- /dev/null +++ b/029ed9161a8d24a9c2ba97124020989d.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/gcode"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/029f5ee0420883bc3c38a7f143fd174a.js b/029f5ee0420883bc3c38a7f143fd174a.js new file mode 100644 index 00000000..5e953895 --- /dev/null +++ b/029f5ee0420883bc3c38a7f143fd174a.js @@ -0,0 +1 @@ +ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var o=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var i=n[1].length,r=e.findMatchingBracket({row:t,column:i});if(!r||r.row==t)return 0;var a=this.$getIndent(e.getLine(r.row));e.replace(new o(t,0,t,i-1),a)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i})),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,r=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},r.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}]}};o.inherits(r,i),r.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},r.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},r.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=r})),ace.define("ace/mode/dot_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/doc_comment_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),i=e("../lib/lang"),r=e("./text_highlight_rules").TextHighlightRules,a=(e("./doc_comment_highlight_rules").DocCommentHighlightRules,function(){var e=i.arrayToMap("strict|node|edge|graph|digraph|subgraph".split("|")),t=i.arrayToMap("damping|k|url|area|arrowhead|arrowsize|arrowtail|aspect|bb|bgcolor|center|charset|clusterrank|color|colorscheme|comment|compound|concentrate|constraint|decorate|defaultdist|dim|dimen|dir|diredgeconstraints|distortion|dpi|edgeurl|edgehref|edgetarget|edgetooltip|epsilon|esep|fillcolor|fixedsize|fontcolor|fontname|fontnames|fontpath|fontsize|forcelabels|gradientangle|group|headurl|head_lp|headclip|headhref|headlabel|headport|headtarget|headtooltip|height|href|id|image|imagepath|imagescale|label|labelurl|label_scheme|labelangle|labeldistance|labelfloat|labelfontcolor|labelfontname|labelfontsize|labelhref|labeljust|labelloc|labeltarget|labeltooltip|landscape|layer|layerlistsep|layers|layerselect|layersep|layout|len|levels|levelsgap|lhead|lheight|lp|ltail|lwidth|margin|maxiter|mclimit|mindist|minlen|mode|model|mosek|nodesep|nojustify|normalize|nslimit|nslimit1|ordering|orientation|outputorder|overlap|overlap_scaling|pack|packmode|pad|page|pagedir|pencolor|penwidth|peripheries|pin|pos|quadtree|quantum|rank|rankdir|ranksep|ratio|rects|regular|remincross|repulsiveforce|resolution|root|rotate|rotation|samehead|sametail|samplepoints|scale|searchsize|sep|shape|shapefile|showboxes|sides|size|skew|smoothing|sortv|splines|start|style|stylesheet|tailurl|tail_lp|tailclip|tailhref|taillabel|tailport|tailtarget|tailtooltip|target|tooltip|truecolor|vertices|viewport|voro_margin|weight|width|xlabel|xlp|z".split("|"));this.$rules={start:[{token:"comment",regex:/\/\/.*$/},{token:"comment",regex:/#.*$/},{token:"comment",merge:!0,regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/[+\-]?\d+(?:(?:\.\d*)?(?:[eE][+\-]?\d+)?)?\b/},{token:"keyword.operator",regex:/\+|=|\->/},{token:"punctuation.operator",regex:/,|;/},{token:"paren.lparen",regex:/[\[{]/},{token:"paren.rparen",regex:/[\]}]/},{token:"comment",regex:/^#!.*$/},{token:function(n){return e.hasOwnProperty(n.toLowerCase())?"keyword":t.hasOwnProperty(n.toLowerCase())?"variable":"text"},regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"}],comment:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],qqstring:[{token:"string",regex:'[^"\\\\]+',merge:!0},{token:"string",regex:"\\\\$",next:"qqstring",merge:!0},{token:"string",regex:'"|$',next:"start",merge:!0}],qstring:[{token:"string",regex:"[^'\\\\]+",merge:!0},{token:"string",regex:"\\\\$",next:"qstring",merge:!0},{token:"string",regex:"'|$",next:"start",merge:!0}]}});o.inherits(a,r),t.DotHighlightRules=a})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),i=e("../../range").Range,r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};o.inherits(a,r),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var o=e.getLine(n);if(this.singleLineBlockCommentRe.test(o)&&!this.startRegionRe.test(o)&&!this.tripleStarBlockCommentRe.test(o))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(o)?"start":i},this.getFoldWidgetRange=function(e,t,n,o){var i,r=e.getLine(n);if(this.startRegionRe.test(r))return this.getCommentRegionBlock(e,r,n);if(i=r.match(this.foldingStartMarker)){var a=i.index;if(i[1])return this.openingBracketBlock(e,i[1],n,a);var l=e.getCommentFoldRange(n,a+i[0].length,1);return l&&!l.isMultiLine()&&(o?l=this.getSectionRange(e,n):"all"!=t&&(l=null)),l}return"markbegin"!==t&&(i=r.match(this.foldingStopMarker))?(a=i.index+i[0].length,i[1]?this.closingBracketBlock(e,i[1],n,a):e.getCommentFoldRange(n,a,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),o=n.search(/\S/),r=t,a=n.length,l=t+=1,s=e.getLength();++tg)break;var c=this.getFoldWidgetRange(e,"all",t);if(c){if(c.start.row<=r)break;if(c.isMultiLine())t=c.end.row;else if(o==g)break}l=t}}return new i(r,a,l,e.getLine(l).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),r=e.getLength(),a=n,l=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,s=1;++na)return new i(a,o,n,t.length)}}.call(a.prototype)})),ace.define("ace/mode/dot",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/matching_brace_outdent","ace/mode/dot_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),i=e("./text").Mode,r=e("./matching_brace_outdent").MatchingBraceOutdent,a=e("./dot_highlight_rules").DotHighlightRules,l=e("./folding/cstyle").FoldMode,s=function(){this.HighlightRules=a,this.$outdent=new r,this.foldingRules=new l,this.$behaviour=this.$defaultBehaviour};o.inherits(s,i),function(){this.lineCommentStart=["//","#"],this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),r=i.tokens;return i.state,r.length&&"comment"==r[r.length-1].type||"start"==e&&t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(o+=n),o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/dot"}.call(s.prototype),t.Mode=s})),ace.require(["ace/mode/dot"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/03980cb12dacd26148c22bb61fce440f.js b/03980cb12dacd26148c22bb61fce440f.js new file mode 100644 index 00000000..9429612b --- /dev/null +++ b/03980cb12dacd26148c22bb61fce440f.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/scheme"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/03a5f5b2b97a8fc289399d92fba810d0.js b/03a5f5b2b97a8fc289399d92fba810d0.js new file mode 100644 index 00000000..9c8b6f15 --- /dev/null +++ b/03a5f5b2b97a8fc289399d92fba810d0.js @@ -0,0 +1 @@ +ace.define("ace/mode/python_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e=this.createKeywordMapper({"invalid.deprecated":"debugger","support.function":"abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|bin|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|apply|delattr|help|next|setattr|set|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern|ascii|breakpoint|bytes","variable.language":"self|cls","constant.language":"True|False|None|NotImplemented|Ellipsis|__debug__",keyword:"and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield|async|await|nonlocal"},"identifier"),t="[uU]?",n="[rR]",r="[fF]",i="(?:[rR][fF]|[fF][rR])",s="(?:(?:(?:[1-9]\\d*)|(?:0))|(?:0[oO]?[0-7]+)|(?:0[xX][\\dA-Fa-f]+)|(?:0[bB][01]+))",o="(?:\\d+)",g="(?:(?:"+o+"?(?:\\.\\d+))|(?:"+o+"\\.))",a="(?:(?:(?:"+g+"|"+o+")(?:[eE][+-]?\\d+))|"+g+")",l="\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:t+'"{3}',next:"qqstring3"},{token:"string",regex:t+'"(?=.)',next:"qqstring"},{token:"string",regex:t+"'{3}",next:"qstring3"},{token:"string",regex:t+"'(?=.)",next:"qstring"},{token:"string",regex:n+'"{3}',next:"rawqqstring3"},{token:"string",regex:n+'"(?=.)',next:"rawqqstring"},{token:"string",regex:n+"'{3}",next:"rawqstring3"},{token:"string",regex:n+"'(?=.)",next:"rawqstring"},{token:"string",regex:r+'"{3}',next:"fqqstring3"},{token:"string",regex:r+'"(?=.)',next:"fqqstring"},{token:"string",regex:r+"'{3}",next:"fqstring3"},{token:"string",regex:r+"'(?=.)",next:"fqstring"},{token:"string",regex:i+'"{3}',next:"rfqqstring3"},{token:"string",regex:i+'"(?=.)',next:"rfqqstring"},{token:"string",regex:i+"'{3}",next:"rfqstring3"},{token:"string",regex:i+"'(?=.)",next:"rfqstring"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|@|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"punctuation",regex:",|:|;|\\->|\\+=|\\-=|\\*=|\\/=|\\/\\/=|%=|@=|&=|\\|=|^=|>>=|<<=|\\*\\*="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:["keyword","text","entity.name.function"],regex:"(def|class)(\\s+)([\\u00BF-\\u1FFF\\u2C00-\\uD7FF\\w]+)"},{token:"text",regex:"\\s+"},{include:"constants"}],qqstring3:[{token:"constant.language.escape",regex:l},{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],qstring3:[{token:"constant.language.escape",regex:l},{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:l},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:l},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}],rawqqstring3:[{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],rawqstring3:[{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],rawqqstring:[{token:"string",regex:"\\\\$",next:"rawqqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],rawqstring:[{token:"string",regex:"\\\\$",next:"rawqstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}],fqqstring3:[{token:"constant.language.escape",regex:l},{token:"string",regex:'"{3}',next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],fqstring3:[{token:"constant.language.escape",regex:l},{token:"string",regex:"'{3}",next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],fqqstring:[{token:"constant.language.escape",regex:l},{token:"string",regex:"\\\\$",next:"fqqstring"},{token:"string",regex:'"|$',next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],fqstring:[{token:"constant.language.escape",regex:l},{token:"string",regex:"'|$",next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],rfqqstring3:[{token:"string",regex:'"{3}',next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],rfqstring3:[{token:"string",regex:"'{3}",next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],rfqqstring:[{token:"string",regex:"\\\\$",next:"rfqqstring"},{token:"string",regex:'"|$',next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],rfqstring:[{token:"string",regex:"'|$",next:"start"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"},{defaultToken:"string"}],fqstringParRules:[{token:"paren.lparen",regex:"[\\[\\(]"},{token:"paren.rparen",regex:"[\\]\\)]"},{token:"string",regex:"\\s+"},{token:"string",regex:"'[^']*'"},{token:"string",regex:'"[^"]*"'},{token:"function.support",regex:"(!s|!r|!a)"},{include:"constants"},{token:"paren.rparen",regex:"}",next:"pop"},{token:"paren.lparen",regex:"{",push:"fqstringParRules"}],constants:[{token:"constant.numeric",regex:"(?:"+a+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:a},{token:"constant.numeric",regex:s+"[lL]\\b"},{token:"constant.numeric",regex:s+"\\b"},{token:["punctuation","function.support"],regex:"(\\.)([a-zA-Z_]+)\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"}]},this.normalizeRules()};r.inherits(s,i),t.PythonHighlightRules=s})),ace.define("ace/mode/folding/pythonic",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e){this.foldingStartMarker=new RegExp("([\\[{])(?:\\s*)$|("+e+")(?:\\s*)(?:#.*)?$")};r.inherits(s,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n).match(this.foldingStartMarker);if(r)return r[1]?this.openingBracketBlock(e,r[1],n,r.index):r[2]?this.indentationBlock(e,n,r.index+r[2].length):this.indentationBlock(e,n)}}.call(s.prototype)})),ace.define("ace/mode/python",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/python_highlight_rules","ace/mode/folding/pythonic","ace/range"],(function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./python_highlight_rules").PythonHighlightRules,o=e("./folding/pythonic").FoldMode,g=e("../range").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o("\\:"),this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart="#",this.$pairQuotesAfter={"'":/[ruf]/i,'"':/[ruf]/i},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;return i.length&&"comment"==i[i.length-1].type||"start"==e&&t.match(/^.*[\{\(\[:]\s*$/)&&(r+=n),r};var e={pass:1,return:1,raise:1,break:1,continue:1};this.checkOutdent=function(t,n,r){if("\r\n"!==r&&"\r"!==r&&"\n"!==r)return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do{var s=i.pop()}while(s&&("comment"==s.type||"text"==s.type&&s.value.match(/^\s+$/)));return!!s&&"keyword"==s.type&&e[s.value]},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new g(n,r.length-i.length,n,r.length))},this.$id="ace/mode/python",this.snippetFileId="ace/snippets/python"}.call(a.prototype),t.Mode=a})),ace.require(["ace/mode/python"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/03aae8272914723a7bf85b984385032c.js b/03aae8272914723a7bf85b984385032c.js new file mode 100644 index 00000000..7a1deb4e --- /dev/null +++ b/03aae8272914723a7bf85b984385032c.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/ftl"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/03cecfc674939048da99384e68631f13.js b/03cecfc674939048da99384e68631f13.js new file mode 100644 index 00000000..81937071 --- /dev/null +++ b/03cecfc674939048da99384e68631f13.js @@ -0,0 +1 @@ +ace.define("ace/autocomplete/popup",["require","exports","module","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom","ace/config","ace/lib/useragent"],(function(e,t,n){"use strict";var i=e("../virtual_renderer").VirtualRenderer,o=e("../editor").Editor,r=e("../range").Range,s=e("../lib/event"),a=e("../lib/lang"),c=e("../lib/dom"),p=e("../config").nls,l=e("./../lib/useragent"),h=function(e){return"suggest-aria-id:".concat(e)},u=l.isSafari?"menu":"listbox",d=l.isSafari?"menuitem":"option",f=l.isSafari?"aria-current":"aria-selected",m=function(e){var t=new i(e);t.$maxLines=4;var n=new o(t);return n.setHighlightActiveLine(!1),n.setShowPrintMargin(!1),n.renderer.setShowGutter(!1),n.renderer.setHighlightGutterLine(!1),n.$mouseHandler.$focusTimeout=0,n.$highlightTagPending=!0,n};c.importCssString('\n.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #CAD6FA;\n z-index: 1;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #3a674e;\n}\n.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid #abbffe;\n margin-top: -1px;\n background: rgba(233,233,253,0.4);\n position: absolute;\n z-index: 2;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid rgba(109, 150, 13, 0.8);\n background: rgba(58, 103, 78, 0.62);\n}\n.ace_completion-meta {\n opacity: 0.5;\n margin-left: 0.9em;\n}\n.ace_completion-message {\n margin-left: 0.9em;\n color: blue;\n}\n.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #2d69c7;\n}\n.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #93ca12;\n}\n.ace_editor.ace_autocomplete {\n width: 300px;\n z-index: 200000;\n border: 1px lightgray solid;\n position: fixed;\n box-shadow: 2px 3px 5px rgba(0,0,0,.2);\n line-height: 1.4;\n background: #fefefe;\n color: #111;\n}\n.ace_dark.ace_editor.ace_autocomplete {\n border: 1px #484747 solid;\n box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\n line-height: 1.4;\n background: #25282c;\n color: #c1c1c1;\n}\n.ace_autocomplete .ace_text-layer {\n width: calc(100% - 8px);\n}\n.ace_autocomplete .ace_line {\n display: flex;\n align-items: center;\n}\n.ace_autocomplete .ace_line > * {\n min-width: 0;\n flex: 0 0 auto;\n}\n.ace_autocomplete .ace_line .ace_ {\n flex: 0 1 auto;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ace_autocomplete .ace_completion-spacer {\n flex: 1;\n}\n.ace_autocomplete.ace_loading:after {\n content: "";\n position: absolute;\n top: 0px;\n height: 2px;\n width: 8%;\n background: blue;\n z-index: 100;\n animation: ace_progress 3s infinite linear;\n animation-delay: 300ms;\n transform: translateX(-100%) scaleX(1);\n}\n@keyframes ace_progress {\n 0% { transform: translateX(-100%) scaleX(1) }\n 50% { transform: translateX(625%) scaleX(2) } \n 100% { transform: translateX(1500%) scaleX(3) } \n}\n@media (prefers-reduced-motion) {\n .ace_autocomplete.ace_loading:after {\n transform: translateX(625%) scaleX(2);\n animation: none;\n }\n}\n',"autocompletion.css",!1),t.AcePopup=function(e){var t=c.createElement("div"),n=m(t);e&&e.appendChild(t),t.style.display="none",n.renderer.content.style.cursor="default",n.renderer.setStyle("ace_autocomplete"),n.renderer.$textLayer.element.setAttribute("role",u),n.renderer.$textLayer.element.setAttribute("aria-roledescription",p("autocomplete.popup.aria-roledescription","Autocomplete suggestions")),n.renderer.$textLayer.element.setAttribute("aria-label",p("autocomplete.popup.aria-label","Autocomplete suggestions")),n.renderer.textarea.setAttribute("aria-hidden","true"),n.setOption("displayIndentGuides",!1),n.setOption("dragDelay",150);var i,o=function(){};n.focus=o,n.$isFocused=!0,n.renderer.$cursorLayer.restartTimer=o,n.renderer.$cursorLayer.element.style.opacity="0",n.renderer.$maxLines=8,n.renderer.$keepTextAreaAtCursor=!1,n.setHighlightActiveLine(!1),n.session.highlight(""),n.session.$searchHighlight.clazz="ace_highlight-marker",n.on("mousedown",(function(e){var t=e.getDocumentPosition();n.selection.moveToPosition(t),g.start.row=g.end.row=t.row,e.stop()}));var l=new r(-1,0,-1,1/0),g=new r(-1,0,-1,1/0);g.id=n.session.addMarker(g,"ace_active-line","fullLine"),n.setSelectOnHover=function(e){e?l.id&&(n.session.removeMarker(l.id),l.id=null):l.id=n.session.addMarker(l,"ace_line-hover","fullLine")},n.setSelectOnHover(!1),n.on("mousemove",(function(e){if(i){if(i.x!=e.x||i.y!=e.y){(i=e).scrollTop=n.renderer.scrollTop,n.isMouseOver=!0;var t=i.getDocumentPosition().row;l.start.row!=t&&(l.id||n.setRow(t),b(t))}}else i=e})),n.renderer.on("beforeRender",(function(){if(i&&-1!=l.start.row){i.$pos=null;var e=i.getDocumentPosition().row;l.id||n.setRow(e),b(e,!0)}})),n.renderer.on("afterRender",(function(){var e=n.getRow(),t=n.renderer.$textLayer,i=t.element.childNodes[e-t.config.firstRow],o=document.activeElement;if(i!==n.selectedNode&&n.selectedNode&&(c.removeCssClass(n.selectedNode,"ace_selected"),o.removeAttribute("aria-activedescendant"),n.selectedNode.removeAttribute(f),n.selectedNode.removeAttribute("id")),n.selectedNode=i,i){c.addCssClass(i,"ace_selected");var r=h(e);i.id=r,t.element.setAttribute("aria-activedescendant",r),o.setAttribute("aria-activedescendant",r),i.setAttribute("role",d),i.setAttribute("aria-roledescription",p("autocomplete.popup.item.aria-roledescription","item")),i.setAttribute("aria-label",n.getData(e).caption||n.getData(e).value),i.setAttribute("aria-setsize",n.data.length),i.setAttribute("aria-posinset",e+1),i.setAttribute("aria-describedby","doc-tooltip"),i.setAttribute(f,"true")}}));var v=function(){b(-1)},b=function(e,t){e!==l.start.row&&(l.start.row=l.end.row=e,t||n.session._emit("changeBackMarker"),n._emit("changeHoverMarker"))};n.getHoveredRow=function(){return l.start.row},s.addListener(n.container,"mouseout",(function(){n.isMouseOver=!1,v()})),n.on("hide",v),n.on("changeSelection",v),n.session.doc.getLength=function(){return n.data.length},n.session.doc.getLine=function(e){var t=n.data[e];return"string"==typeof t?t:t&&t.value||""};var y=n.session.bgTokenizer;return y.$tokenizeRow=function(e){var t=n.data[e],i=[];if(!t)return i;"string"==typeof t&&(t={value:t});var o=t.caption||t.value||t.name;function r(e,n){e&&i.push({type:(t.className||"")+(n||""),value:e})}for(var s=o.toLowerCase(),a=(n.filterText||"").toLowerCase(),c=0,p=0,l=0;l<=a.length;l++)if(l!=p&&(t.matchMask&1<=l?"bottom":"top"),"top"===o?(h.bottom=e.top-this.$borderSize,h.top=h.bottom-l):"bottom"===o&&(h.top=e.top+t+this.$borderSize,h.bottom=h.top+l);var f=h.top>=0&&h.bottom<=a;if(!r&&!f)return!1;p.$maxPixelHeight=f?null:"top"===o?d:u,"top"===o?(s.style.top="",s.style.bottom=a-h.bottom+"px",n.isTopdown=!1):(s.style.top=h.top+"px",s.style.bottom="",n.isTopdown=!0),s.style.display="";var m=e.left;return m+s.offsetWidth>c&&(m=c-s.offsetWidth),s.style.left=m+"px",s.style.right="",n.isOpen||(n.isOpen=!0,this._signal("show"),i=null),n.anchorPos=e,n.anchor=o,!0},n.show=function(e,t,n){this.tryShow(e,t,n?"bottom":void 0,!0)},n.goTo=function(e){var t=this.getRow(),n=this.session.getLength()-1;switch(e){case"up":t=t<=0?n:t-1;break;case"down":t=t>=n?-1:t+1;break;case"start":t=0;break;case"end":t=n}this.setRow(t)},n.getTextLeftOffset=function(){return this.$borderSize+this.renderer.$padding+this.$imageSize},n.$imageSize=0,n.$borderSize=1,n},t.$singleLineEditor=m,t.getAriaId=h})),ace.define("ace/snippets",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/editor"],(function(e,t,n){"use strict";var i=e("./lib/dom"),o=e("./lib/oop"),r=e("./lib/event_emitter").EventEmitter,s=e("./lib/lang"),a=e("./range").Range,c=e("./range_list").RangeList,p=e("./keyboard/hash_handler").HashHandler,l=e("./tokenizer").Tokenizer,h=e("./clipboard"),u={CURRENT_WORD:function(e){return e.session.getTextRange(e.session.getWordRange())},SELECTION:function(e,t,n){var i=e.session.getTextRange();return n?i.replace(/\n\r?([ \t]*\S)/g,"\n"+n+"$1"):i},CURRENT_LINE:function(e){return e.session.getLine(e.getCursorPosition().row)},PREV_LINE:function(e){return e.session.getLine(e.getCursorPosition().row-1)},LINE_INDEX:function(e){return e.getCursorPosition().row},LINE_NUMBER:function(e){return e.getCursorPosition().row+1},SOFT_TABS:function(e){return e.session.getUseSoftTabs()?"YES":"NO"},TAB_SIZE:function(e){return e.session.getTabSize()},CLIPBOARD:function(e){return h.getText&&h.getText()},FILENAME:function(e){return/[^/\\]*$/.exec(this.FILEPATH(e))[0]},FILENAME_BASE:function(e){return/[^/\\]*$/.exec(this.FILEPATH(e))[0].replace(/\.[^.]*$/,"")},DIRECTORY:function(e){return this.FILEPATH(e).replace(/[^/\\]*$/,"")},FILEPATH:function(e){return"/not implemented.txt"},WORKSPACE_NAME:function(){return"Unknown"},FULLNAME:function(){return"Unknown"},BLOCK_COMMENT_START:function(e){var t=e.session.$mode||{};return t.blockComment&&t.blockComment.start||""},BLOCK_COMMENT_END:function(e){var t=e.session.$mode||{};return t.blockComment&&t.blockComment.end||""},LINE_COMMENT:function(e){return(e.session.$mode||{}).lineCommentStart||""},CURRENT_YEAR:d.bind(null,{year:"numeric"}),CURRENT_YEAR_SHORT:d.bind(null,{year:"2-digit"}),CURRENT_MONTH:d.bind(null,{month:"numeric"}),CURRENT_MONTH_NAME:d.bind(null,{month:"long"}),CURRENT_MONTH_NAME_SHORT:d.bind(null,{month:"short"}),CURRENT_DATE:d.bind(null,{day:"2-digit"}),CURRENT_DAY_NAME:d.bind(null,{weekday:"long"}),CURRENT_DAY_NAME_SHORT:d.bind(null,{weekday:"short"}),CURRENT_HOUR:d.bind(null,{hour:"2-digit",hour12:!1}),CURRENT_MINUTE:d.bind(null,{minute:"2-digit"}),CURRENT_SECOND:d.bind(null,{second:"2-digit"})};function d(e){var t=(new Date).toLocaleString("en-us",e);return 1==t.length?"0"+t:t}u.SELECTED_TEXT=u.SELECTION;var f=function(){function e(){this.snippetMap={},this.snippetNameMap={},this.variables=u}return e.prototype.getTokenizer=function(){return e.$tokenizer||this.createTokenizer()},e.prototype.createTokenizer=function(){function t(e){return e=e.substr(1),/^\d+$/.test(e)?[{tabstopId:parseInt(e,10)}]:[{text:e}]}function n(e){return"(?:[^\\\\"+e+"]|\\\\.)"}var i={regex:"/("+n("/")+"+)/",onMatch:function(e,t,n){var i=n[0];return i.fmtString=!0,i.guard=e.slice(1,-1),i.flag="",""},next:"formatString"};return e.$tokenizer=new l({start:[{regex:/\\./,onMatch:function(e,t,n){var i=e[1];return("}"==i&&n.length||-1!="`$\\".indexOf(i))&&(e=i),[e]}},{regex:/}/,onMatch:function(e,t,n){return[n.length?n.shift():e]}},{regex:/\$(?:\d+|\w+)/,onMatch:t},{regex:/\$\{[\dA-Z_a-z]+/,onMatch:function(e,n,i){var o=t(e.substr(1));return i.unshift(o[0]),o},next:"snippetVar"},{regex:/\n/,token:"newline",merge:!1}],snippetVar:[{regex:"\\|"+n("\\|")+"*\\|",onMatch:function(e,t,n){var i=e.slice(1,-1).replace(/\\[,|\\]|,/g,(function(e){return 2==e.length?e[1]:"\0"})).split("\0").map((function(e){return{value:e}}));return n[0].choices=i,[i[0]]},next:"start"},i,{regex:"([^:}\\\\]|\\\\.)*:?",token:"",next:"start"}],formatString:[{regex:/:/,onMatch:function(e,t,n){return n.length&&n[0].expectElse?(n[0].expectElse=!1,n[0].ifEnd={elseEnd:n[0]},[n[0].ifEnd]):":"}},{regex:/\\./,onMatch:function(e,t,n){var i=e[1];return"}"==i&&n.length||-1!="`$\\".indexOf(i)?e=i:"n"==i?e="\n":"t"==i?e="\t":-1!="ulULE".indexOf(i)&&(e={changeCase:i,local:i>"a"}),[e]}},{regex:"/\\w*}",onMatch:function(e,t,n){var i=n.shift();return i&&(i.flag=e.slice(1,-1)),this.next=i&&i.tabstopId?"start":"",[i||e]},next:"start"},{regex:/\$(?:\d+|\w+)/,onMatch:function(e,t,n){return[{text:e.slice(1)}]}},{regex:/\${\w+/,onMatch:function(e,t,n){var i={text:e.slice(2)};return n.unshift(i),[i]},next:"formatStringVar"},{regex:/\n/,token:"newline",merge:!1},{regex:/}/,onMatch:function(e,t,n){var i=n.shift();return this.next=i&&i.tabstopId?"start":"",[i||e]},next:"start"}],formatStringVar:[{regex:/:\/\w+}/,onMatch:function(e,t,n){return n[0].formatFunction=e.slice(2,-1),[n.shift()]},next:"formatString"},i,{regex:/:[\?\-+]?/,onMatch:function(e,t,n){"+"==e[1]&&(n[0].ifEnd=n[0]),"?"==e[1]&&(n[0].expectElse=!0)},next:"formatString"},{regex:"([^:}\\\\]|\\\\.)*:?",token:"",next:"formatString"}]}),e.$tokenizer},e.prototype.tokenizeTmSnippet=function(e,t){return this.getTokenizer().getLineTokens(e,t).tokens.map((function(e){return e.value||e}))},e.prototype.getVariableValue=function(e,t,n){if(/^\d+$/.test(t))return(this.variables.__||{})[t]||"";if(/^[A-Z]\d+$/.test(t))return(this.variables[t[0]+"__"]||{})[t.substr(1)]||"";if(t=t.replace(/^TM_/,""),!this.variables.hasOwnProperty(t))return"";var i=this.variables[t];return"function"==typeof i&&(i=this.variables[t](e,t,n)),null==i?"":i},e.prototype.tmStrFormat=function(e,t,n){if(!t.fmt)return e;var i=t.flag||"",o=t.guard;o=new RegExp(o,i.replace(/[^gim]/g,""));var r="string"==typeof t.fmt?this.tokenizeTmSnippet(t.fmt,"formatString"):t.fmt,s=this,a=e.replace(o,(function(){var e=s.variables.__;s.variables.__=[].slice.call(arguments);for(var t=s.resolveVariables(r,n),i="E",o=0;o=0&&r.splice(s,1)}}e.content?o(e):Array.isArray(e)&&e.forEach(o)},e.prototype.parseSnippetFile=function(e){e=e.replace(/\r/g,"");for(var t,n=[],i={},o=/^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm;t=o.exec(e);){if(t[1])try{i=JSON.parse(t[1]),n.push(i)}catch(e){}if(t[4])i.content=t[4].replace(/^\t/gm,""),n.push(i),i={};else{var r=t[2],s=t[3];if("regex"==r){var a=/\/((?:[^\/\\]|\\.)*)|$/g;i.guard=a.exec(s)[1],i.trigger=a.exec(s)[1],i.endTrigger=a.exec(s)[1],i.endGuard=a.exec(s)[1]}else"snippet"==r?(i.tabTrigger=s.match(/^\S*/)[0],i.name||(i.name=s)):r&&(i[r]=s)}}return n},e.prototype.getSnippetByName=function(e,t){var n,i=this.snippetNameMap;return this.getActiveScopes(t).some((function(t){var o=i[t];return o&&(n=o[e]),!!n}),this),n},e}();o.implement(f.prototype,r);var m=function(e,t,n){void 0===n&&(n={});var i=e.getCursorPosition(),o=e.session.getLine(i.row),r=e.session.getTabString(),s=o.match(/^\s*/)[0];i.column1?(b=t[t.length-1].length,v+=t.length-1):b+=e.length,y+=e}else e&&(e.start?e.end={row:v,column:b}:e.start={row:v,column:b})})),{text:y,tabstops:c,tokens:a}},g=function(){function e(e){if(this.index=0,this.ranges=[],this.tabstops=[],e.tabstopManager)return e.tabstopManager;e.tabstopManager=this,this.$onChange=this.onChange.bind(this),this.$onChangeSelection=s.delayedCall(this.onChangeSelection.bind(this)).schedule,this.$onChangeSession=this.onChangeSession.bind(this),this.$onAfterExec=this.onAfterExec.bind(this),this.attach(e)}return e.prototype.attach=function(e){this.$openTabstops=null,this.selectedTabstop=null,this.editor=e,this.session=e.session,this.editor.on("change",this.$onChange),this.editor.on("changeSelection",this.$onChangeSelection),this.editor.on("changeSession",this.$onChangeSession),this.editor.commands.on("afterExec",this.$onAfterExec),this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},e.prototype.detach=function(){this.tabstops.forEach(this.removeTabstopMarkers,this),this.ranges.length=0,this.tabstops.length=0,this.selectedTabstop=null,this.editor.off("change",this.$onChange),this.editor.off("changeSelection",this.$onChangeSelection),this.editor.off("changeSession",this.$onChangeSession),this.editor.commands.off("afterExec",this.$onAfterExec),this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.tabstopManager=null,this.session=null,this.editor=null},e.prototype.onChange=function(e){for(var t="r"==e.action[0],n=this.selectedTabstop||{},i=n.parents||{},o=this.tabstops.slice(),r=0;r2&&(this.tabstops.length&&r.push(r.splice(2,1)[0]),this.tabstops.splice.apply(this.tabstops,r))},e.prototype.addTabstopMarkers=function(e){var t=this.session;e.forEach((function(e){e.markerId||(e.markerId=t.addMarker(e,"ace_snippet-marker","text"))}))},e.prototype.removeTabstopMarkers=function(e){var t=this.session;e.forEach((function(e){t.removeMarker(e.markerId),e.markerId=null}))},e.prototype.updateTabstopMarkers=function(){if(this.selectedTabstop){var e=this.selectedTabstop.snippetId;0===this.selectedTabstop.index&&e--,this.tabstops.forEach((function(t){t.snippetId===e?this.addTabstopMarkers(t):this.removeTabstopMarkers(t)}),this)}},e.prototype.removeRange=function(e){var t=e.tabstop.indexOf(e);-1!=t&&e.tabstop.splice(t,1),-1!=(t=this.ranges.indexOf(e))&&this.ranges.splice(t,1),-1!=(t=e.tabstop.rangeList.ranges.indexOf(e))&&e.tabstop.splice(t,1),this.session.removeMarker(e.markerId),e.tabstop.length||(-1!=(t=this.tabstops.indexOf(e.tabstop))&&this.tabstops.splice(t,1),this.tabstops.length||this.detach())},e}();g.prototype.keyboardHandler=new p,g.prototype.keyboardHandler.bindKeys({Tab:function(e){t.snippetManager&&t.snippetManager.expandWithTab(e)||(e.tabstopManager.tabNext(1),e.renderer.scrollCursorIntoView())},"Shift-Tab":function(e){e.tabstopManager.tabNext(-1),e.renderer.scrollCursorIntoView()},Esc:function(e){e.tabstopManager.detach()}});var v=function(e,t){0==e.row&&(e.column+=t.column),e.row+=t.row},b=function(e,t){e.row==t.row&&(e.column-=t.column),e.row-=t.row};i.importCssString("\n.ace_snippet-marker {\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n background: rgba(194, 193, 208, 0.09);\n border: 1px dotted rgba(211, 208, 235, 0.62);\n position: absolute;\n}","snippets.css",!1),t.snippetManager=new f;var y=e("./editor").Editor;(function(){this.insertSnippet=function(e,n){return t.snippetManager.insertSnippet(this,e,n)},this.expandSnippet=function(e){return t.snippetManager.expandWithTab(this,e)}}).call(y.prototype)})),ace.define("ace/autocomplete/inline_screenreader",["require","exports","module"],(function(e,t,n){"use strict";var i=function(){function e(e){this.editor=e,this.screenReaderDiv=document.createElement("div"),this.screenReaderDiv.classList.add("ace_screenreader-only"),this.editor.container.appendChild(this.screenReaderDiv)}return e.prototype.setScreenReaderContent=function(e){for(!this.popup&&this.editor.completer&&this.editor.completer.popup&&(this.popup=this.editor.completer.popup,this.popup.renderer.on("afterRender",function(){var e=this.popup.getRow(),t=this.popup.renderer.$textLayer,n=t.element.childNodes[e-t.config.firstRow];if(n){for(var i="doc-tooltip ",o=0;o=0&&n.test(e[r]);r--)o.push(e[r]);return o.reverse().join("")},t.retrieveFollowingIdentifier=function(e,t,n){n=n||i;for(var o=[],r=t;r0)for(var t=this.popup.getFirstVisibleRow();t<=this.popup.getLastVisibleRow();t++){var n=this.popup.getData(t);!n||e&&!n.hideInlinePreview||this.$seen(n)}},e.prototype.$onPopupShow=function(e){this.$onPopupChange(e),this.stickySelection=!1,this.stickySelectionDelay>=0&&this.stickySelectionTimer.schedule(this.stickySelectionDelay)},e.prototype.observeLayoutChanges=function(){if(!this.$elements&&this.editor){window.addEventListener("resize",this.onLayoutChange,{passive:!0}),window.addEventListener("wheel",this.mousewheelListener);for(var e=this.editor.container.parentNode,t=[];e;)t.push(e),e.addEventListener("scroll",this.onLayoutChange,{passive:!0}),e=e.parentNode;this.$elements=t}},e.prototype.unObserveLayoutChanges=function(){var e=this;window.removeEventListener("resize",this.onLayoutChange,{passive:!0}),window.removeEventListener("wheel",this.mousewheelListener),this.$elements&&this.$elements.forEach((function(t){t.removeEventListener("scroll",e.onLayoutChange,{passive:!0})})),this.$elements=null},e.prototype.onLayoutChange=function(){if(!this.popup.isOpen)return this.unObserveLayoutChanges();this.$updatePopupPosition(),this.updateDocTooltip()},e.prototype.$updatePopupPosition=function(){var e=this.editor,t=e.renderer,n=t.layerConfig.lineHeight,i=t.$cursorLayer.getPixelPosition(this.base,!0);i.left-=this.popup.getTextLeftOffset();var o=e.container.getBoundingClientRect();i.top+=o.top-t.layerConfig.offset,i.left+=o.left-e.renderer.scrollLeft,i.left+=t.gutterWidth;var r={top:i.top,left:i.left};t.$ghostText&&t.$ghostTextWidget&&this.base.row===t.$ghostText.position.row&&(r.top+=t.$ghostTextWidget.el.offsetHeight);var s=e.container.getBoundingClientRect().bottom-n,a=sthis.filterText&&0===e.lastIndexOf(this.filterText,0))var t=this.filtered;else t=this.all;this.filterText=e,t=(t=this.filterCompletions(t,this.filterText)).sort((function(e,t){return t.exactMatch-e.exactMatch||t.$score-e.$score||(e.caption||e.value).localeCompare(t.caption||t.value)}));var n=null;t=t.filter((function(e){var t=e.snippet||e.caption||e.value;return t!==n&&(n=t,!0)})),this.filtered=t},e.prototype.filterCompletions=function(e,t){var n=[],i=t.toUpperCase(),o=t.toLowerCase();e:for(var r,s=0;r=e[s];s++){var a=!this.ignoreCaption&&r.caption||r.value||r.snippet;if(a){var c,p,l=-1,h=0,u=0;if(this.exactMatch){if(t!==a.substr(0,t.length))continue e}else{var d=a.toLowerCase().indexOf(o);if(d>-1)u=d;else for(var f=0;f=0&&(g<0||m0&&(-1===l&&(u+=10),u+=p,h|=1<0?C():a.getValue();var t=g?g.getData(g.getRow()):e;t&&!t.error&&(S(),n.onAccept&&n.onAccept({value:e,item:t},a))}m.setIgnoreFocusOut(n.ignoreFocusOut);var x={Enter:y,"Esc|Shift-Esc":function(){n.onCancel&&n.onCancel(a.getValue(),a),S()}};function S(){m.close(),o&&o(),i=null}function w(){if(n.getCompletions){var e;n.getPrefix&&(e=n.getPrefix(a));var t=n.getCompletions(a);g.setData(t,e),g.resize(!0)}}function C(){var e=g.getData(g.getRow());if(e&&!e.error)return e.value||e.caption||e}g&&Object.assign(x,{Up:function(e){g.goTo("up"),C()},Down:function(e){g.goTo("down"),C()},"Ctrl-Up|Ctrl-Home":function(e){g.goTo("start"),C()},"Ctrl-Down|Ctrl-End":function(e){g.goTo("end"),C()},Tab:function(e){g.goTo("down"),C()},PageUp:function(e){g.gotoPageUp(),C()},PageDown:function(e){g.gotoPageDown(),C()}}),a.commands.bindKeys(x),a.on("input",(function(){n.onInput&&n.onInput(),w()})),a.resize(!0),g&&g.resize(!0),a.focus(),i={close:S,name:n.name,editor:e}}f.gotoLine=function(e,t){var n;f(e,":"+(n=e.selection.toJSON(),Array.isArray(n)||(n=[n]),n.map((function(e){var t=e.isBackwards?e.start:e.end,n=e.isBackwards?e.end:e.start,i=n.row+1+":"+n.column;return n.row==t.row?n.column!=t.column&&(i+=">:"+t.column):i+=">"+(t.row+1)+":"+t.column,i})).reverse().join(", ")),{name:"gotoLine",selection:[1,Number.MAX_VALUE],onAccept:function(t){var n=t.value,i=f.gotoLine._history;i||(f.gotoLine._history=i=[]),-1!=i.indexOf(n)&&i.splice(i.indexOf(n),1),i.unshift(n),i.length>20&&(i.length=20);var o=e.getCursorPosition(),s=[];n.replace(/^:/,"").split(/,/).map((function(t){var n=t.split(/([<>:+-]|c?\d+)|[^c\d<>:+-]+/).filter(Boolean),i=0;function a(){var t=n[i++];if(t){if("c"==t[0]){var r=parseInt(t.slice(1))||0;return e.session.doc.indexToPosition(r)}var s=o.row,a=0;return/\d/.test(t)&&(s=parseInt(t)-1,t=n[i++]),":"==t&&(t=n[i++],/\d/.test(t)&&(a=parseInt(t)||0)),{row:s,column:a}}}o=a();var c=r.fromPoints(o,o);">"==n[i]?(i++,c.end=a()):"<"==n[i]&&(i++,c.start=a()),s.unshift(c)})),e.selection.fromJSON(s);var a=e.renderer.scrollTop;e.renderer.scrollSelectionIntoView(e.selection.anchor,e.selection.cursor,.5),e.renderer.animateScrolling(a)},history:function(){return f.gotoLine._history?f.gotoLine._history:[]},getCompletions:function(t){var n=t.getValue(),i=n.replace(/^:/,"").split(":"),o=Math.min(parseInt(i[0])||1,e.session.getLength())-1;return[n+" "+e.session.getLine(o)].concat(this.history())},$rules:{start:[{regex:/\d+/,token:"string"},{regex:/[:,><+\-c]/,token:"keyword"}]}})},f.commands=function(e,t){var n,i,r,s=(n=["insertstring","inserttext","setIndentation","paste"],i=[],r={},e.keyBinding.$handlers.forEach((function(e){var t=e.platform,o=e.byName;for(var s in o){var a=o[s].bindKey;"string"!=typeof a&&(a=a&&a[t]||"");var c=o[s],p=c.description||(c.name||"").replace(/^./,(function(e){return e.toUpperCase(e)})).replace(/[a-z][A-Z]/g,(function(e){return e[0]+" "+e[1].toLowerCase(e)}));Array.isArray(c)||(c=[c]),c.forEach((function(e){"string"!=typeof e&&(e=e.name),n.find((function(t){return t===e}))||(r[e]?r[e].key+="|"+a:(r[e]={key:a,command:e,description:p},i.push(r[e])))}))}})),i);s=s.map((function(e){return{value:e.description,meta:e.key,command:e.command}})),f(e,"",{name:"commands",selection:[0,Number.MAX_VALUE],maxHistoryCount:5,onAccept:function(t){if(t.item){var n=t.item.command;this.addToHistory(t.item),e.execCommand(n)}},addToHistory:function(e){var t=this.history();t.unshift(e),delete e.message;for(var n=1;n0&&t.length>this.maxHistoryCount&&t.splice(t.length-1,1),f.commands.history=t},history:function(){return f.commands.history||[]},getPrefix:function(e){var t=e.getCursorPosition();return e.getValue().substring(0,t.column)},getCompletions:function(e){function t(e,t){var n=JSON.parse(JSON.stringify(e));return new a(n).filterCompletions(n,t)}var n=this.getPrefix(e),i=t(this.history(),n),r=function(e,t){if(!t||!t.length)return e;var n=[];t.forEach((function(e){n.push(e.command)}));var i=[];return e.forEach((function(e){-1===n.indexOf(e.command)&&i.push(e)})),i}(s,i);r=t(r,n),i.length&&r.length&&(i[0].message=o("prompt.recently-used","Recently used"),r[0].message=o("prompt.other-commands","Other commands"));var c=i.concat(r);return c.length>0?c:[{value:o("prompt.no-matching-commands","No matching commands"),error:1}]}})},f.modes=function(e,t){var n=d.modes;n=n.map((function(e){return{value:e.caption,mode:e.name}})),f(e,"",{name:"modes",selection:[0,Number.MAX_VALUE],onAccept:function(t){if(t.item){var n="ace/mode/"+t.item.mode;e.session.setMode(n)}},getPrefix:function(e){var t=e.getCursorPosition();return e.getValue().substring(0,t.column)},getCompletions:function(e){var t=this.getPrefix(e),i=function(e,t){var n=JSON.parse(JSON.stringify(e));return new a(n).filterCompletions(n,t)}(n,t);return i.length>0?i:[{caption:"No mode matching",value:"No mode matching",error:1}]}})},s.importCssString(".ace_prompt_container {\n max-width: 603px;\n width: 100%;\n margin: 20px auto;\n padding: 3px;\n background: white;\n border-radius: 2px;\n box-shadow: 0px 2px 3px 0px #555;\n}","promtp.css",!1),t.prompt=f})),ace.require(["ace/ext/prompt"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/0416c21cfe088739209926632a360e3b.js b/0416c21cfe088739209926632a360e3b.js new file mode 100644 index 00000000..c24263c0 --- /dev/null +++ b/0416c21cfe088739209926632a360e3b.js @@ -0,0 +1 @@ +ace.define("ace/mode/flix_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,r){"use strict";var o=e("../lib/oop"),n=e("./text_highlight_rules").TextHighlightRules,a=function(){var e=this.createKeywordMapper({keyword:"use|checked_cast|checked_ecast|unchecked_cast|masked_cast|as|discard|from|into|inject|project|solve|query|where|select|force|import|region|red|deref","keyword.control":"choose|debug|do|for|forA|forM|foreach|yield|if|else|case|match|typematch|try|catch|resume|spawn|par|branch|jumpto","keyword.operator":"not|and|or|fix","storage.type":"eff|def|law|enum|case|type|alias|class|instance|mod|let","storage.modifier":"with|without|opaque|lazy|lawful|pub|override|sealed|static","support.type":"Unit|Bool|Char|Float32|Float64|Int8|Int16|Int32|Int64|BigInt|String"},"identifier");this.$rules={start:[{token:"comment.line",regex:"\\/\\/.*$"},{token:"comment.block",regex:"\\/\\*",next:"comment"},{token:"string",regex:'"',next:"string"},{token:"string.regexp",regex:'regex"',next:"regex"},{token:"constant.character",regex:"'",next:"char"},{token:"constant.numeric",regex:"0x[a-fA-F0-9](_*[a-fA-F0-9])*(i8|i16|i32|i64|ii)?\\b"},{token:"constant.numeric",regex:"[0-9](_*[0-9])*\\.[0-9](_*[0-9])*(f32|f64)?\\b"},{token:"constant.numeric",regex:"[0-9](_*[0-9])*(i8|i16|i32|i64|ii)?\\b"},{token:"constant.language.boolean",regex:"(true|false)\\b"},{token:"constant.language",regex:"null\\b"},{token:"keyword.operator",regex:"\\->|~>|<\\-|=>"},{token:"storage.modifier",regex:"@(Deprecated|Experimental|Internal|ParallelWhenPure|Parallel|LazyWhenPure|Lazy|Skip|Test)\\b"},{token:"keyword",regex:"(\\?\\?\\?|\\?[a-zA-Z0-9]+)"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment.block",regex:"\\*\\/",next:"start"},{defaultToken:"comment.block"}],string:[{token:"constant.character.escape",regex:"\\\\(u[0-9a-fA-F]{4})"},{token:"constant.character.escape",regex:"\\\\."},{token:"string",regex:'"',next:"start"},{token:"string",regex:'[^"\\\\]+'}],regex:[{token:"constant.character.escape",regex:"\\\\(u[0-9a-fA-F]{4})"},{token:"constant.character.escape",regex:"\\\\."},{token:"string.regexp",regex:'"',next:"start"},{token:"string.regexp",regex:'[^"\\\\]+'}],char:[{token:"constant.character.escape",regex:"\\\\(u[0-9a-fA-F]{4})"},{token:"constant.character.escape",regex:"\\\\."},{token:"constant.character",regex:"'",next:"start"},{token:"constant.character",regex:"[^'\\\\]+"}]}};o.inherits(a,n),t.FlixHighlightRules=a})),ace.define("ace/mode/flix",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/flix_highlight_rules"],(function(e,t,r){"use strict";var o=e("../lib/oop"),n=e("./text").Mode,a=e("./flix_highlight_rules").FlixHighlightRules,c=function(){this.HighlightRules=a};o.inherits(c,n),function(){this.$id="ace/mode/flix"}.call(c.prototype),t.Mode=c})),ace.require(["ace/mode/flix"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/05922e9c75ebd5e5ccf6f4dc59320e0d.js b/05922e9c75ebd5e5ccf6f4dc59320e0d.js new file mode 100644 index 00000000..a627bffa --- /dev/null +++ b/05922e9c75ebd5e5ccf6f4dc59320e0d.js @@ -0,0 +1 @@ +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=(e("../lib/lang"),e("./text_highlight_rules").TextHighlightRules),a=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",i=t.supportFunction="rgb|rgba|url|attr|counter|counters",s=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|flex-end|flex-start|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",l=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",c=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",u=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",d=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",g=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",p=function(){var e=this.createKeywordMapper({"support.function":i,"support.constant":s,"support.type":a,"support.constant.color":l,"support.constant.fonts":c},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:u},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+u+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:u},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:d},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:g},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{token:"paren.lparen",regex:"\\{"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};o.inherits(p,r),t.CssHighlightRules=p})),ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};o.inherits(a,r),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),o="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[r.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[r.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:o},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(r,"doc-",[r.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var o="/"==e.charAt(1)?2:1;return 1==o?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==o&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==o?"":"end-")+"tag-open.xml",value:e.slice(0,o)},{type:"meta.tag.tag-name.xml",value:e.substr(o)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[r.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[r.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}o.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(e){var t="[_:a-zA-ZÀ-￿][-_:.a-zA-Z0-9À-￿]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"--\x3e",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===a&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(r.prototype),o.inherits(a,r),t.XmlHighlightRules=a})),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./css_highlight_rules").CssHighlightRules,i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./xml_highlight_rules").XmlHighlightRules,l=r.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),c=function(){s.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=l[t];return["meta.tag.punctuation."+("<"==e?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(a,"css-","style"),this.embedTagRules(new i({jsx:!1}).getRules(),"js-","script"),this.constructor===c&&this.normalizeRules()};o.inherits(c,s),t.HtmlHighlightRules=c})),ace.define("ace/mode/markdown_highlight_rules",["require","exports","module","ace/config","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/html_highlight_rules"],(function(e,t,n){"use strict";var o=e("../config").$modes,r=e("../lib/oop"),a=e("../lib/lang"),i=e("./text_highlight_rules").TextHighlightRules,s=e("./html_highlight_rules").HtmlHighlightRules,l=function(e){return"(?:[^"+a.escapeRegExp(e)+"\\\\]|\\\\.)*"},c=function(){s.call(this);var e={token:"support.function",regex:/^\s*(```+[^`]*|~~~+[^~]*)$/,onMatch:function(e,t,n,r){var a=e.match(/^(\s*)([`~]+)(.*)/),i=/[\w-]+|$/.exec(a[3])[0];return o[i]||(i=""),n.unshift("githubblock",[],[a[1],a[2],i],t),this.token},next:"githubblock"},t=[{token:"support.function",regex:".*",onMatch:function(e,t,n,r){var a=n[1],i=n[2][0],s=n[2][1],l=n[2][2],c=/^(\s*)(`+|~+)\s*$/.exec(e);if(c&&c[1].length=s.length&&c[2][0]==s[0])return n.splice(0,3),this.next=n.shift(),this.token;if(this.next="",l&&o[l]){var u=o[l].getTokenizer().getLineTokens(e,a.slice(0));return n[1]=u.state,u.tokens}return this.token}}];this.$rules.start.unshift({token:"empty_line",regex:"^$",next:"allowBlock"},{token:"markup.heading.1",regex:"^=+(?=\\s*$)"},{token:"markup.heading.2",regex:"^\\-+(?=\\s*$)"},{token:function(e){return"markup.heading."+e.length},regex:/^#{1,6}(?=\s|$)/,next:"header"},e,{token:"string.blockquote",regex:"^\\s*>\\s*(?:[*+-]|\\d+\\.)?\\s+",next:"blockquote"},{token:"constant",regex:"^ {0,3}(?:(?:\\* ?){3,}|(?:\\- ?){3,}|(?:\\_ ?){3,})\\s*$",next:"allowBlock"},{token:"markup.list",regex:"^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",next:"listblock-start"},{include:"basic"}),this.addRules({basic:[{token:"constant.language.escape",regex:/\\[\\`*_{}\[\]()#+\-.!]/},{token:"support.function",regex:"(`+)(.*?[^`])(\\1)"},{token:["text","constant","text","url","string","text"],regex:'^([ ]{0,3}\\[)([^\\]]+)(\\]:\\s*)([^ ]+)(\\s*(?:["][^"]+["])?(\\s*))$'},{token:["text","string","text","constant","text"],regex:"(\\[)("+l("]")+")(\\]\\s*\\[)("+l("]")+")(\\])"},{token:["text","string","text","markup.underline","string","text"],regex:"(\\!?\\[)("+l("]")+')(\\]\\()((?:[^\\)\\s\\\\]|\\\\.|\\s(?=[^"]))*)(\\s*"'+l('"')+'"\\s*)?(\\))'},{token:"string.strong",regex:"([*]{2}|[_]{2}(?=\\S))(.*?\\S[*_]*)(\\1)"},{token:"string.emphasis",regex:"([*]|[_](?=\\S))(.*?\\S[*_]*)(\\1)"},{token:["text","url","text"],regex:"(<)((?:https?|ftp|dict):[^'\">\\s]+|(?:mailto:)?[-.\\w]+\\@[-a-z0-9]+(?:\\.[-a-z0-9]+)*\\.[a-z]+)(>)"}],allowBlock:[{token:"support.function",regex:"^ {4}.+",next:"allowBlock"},{token:"empty_line",regex:"^$",next:"allowBlock"},{token:"empty",regex:"",next:"start"}],header:[{regex:"$",next:"start"},{include:"basic"},{defaultToken:"heading"}],"listblock-start":[{token:"support.variable",regex:/(?:\[[ x]\])?/,next:"listblock"}],listblock:[{token:"empty_line",regex:"^$",next:"start"},{token:"markup.list",regex:"^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",next:"listblock-start"},{include:"basic",noEscape:!0},e,{defaultToken:"list"}],blockquote:[{token:"empty_line",regex:"^\\s*$",next:"start"},{token:"string.blockquote",regex:"^\\s*>\\s*(?:[*+-]|\\d+\\.)?\\s+",next:"blockquote"},{include:"basic",noEscape:!0},{defaultToken:"string.blockquote"}],githubblock:t}),this.normalizeRules()};r.inherits(c,i),t.MarkdownHighlightRules=c})),ace.define("ace/mode/folding/markdown",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./fold_mode").FoldMode,a=e("../../range").Range,i=t.FoldMode=function(){};o.inherits(i,r),function(){this.foldingStartMarker=/^(?:[=-]+\s*$|#{1,6} |`{3})/,this.getFoldWidget=function(e,t,n){var o=e.getLine(n);return this.foldingStartMarker.test(o)?"`"==o[0]&&"start"==e.bgTokenizer.getState(n)?"end":"start":""},this.getFoldWidgetRange=function(e,t,n){var o=e.getLine(n),r=o.length,i=e.getLength(),s=n,l=n;if(o.match(this.foldingStartMarker)){if("`"==o[0]){if("start"!==e.bgTokenizer.getState(n)){for(;++n0&&!("`"==(o=e.getLine(n))[0]&"```"==o.substring(0,3)););return new a(n,o.length,s,0)}var c,u="markup.heading";if(p(n)){for(var d=m();++n=d););if((l=n-(c&&-1!=["=","-"].indexOf(c.value[0])?2:1))>s)for(;l>s&&/^\s*$/.test(e.getLine(l));)l--;if(l>s){var g=e.getLine(l).length;return new a(s,r,l,g)}}}function p(t){return(c=e.getTokens(t)[0])&&0===c.type.lastIndexOf(u,0)}function m(){var e=c.value[0];return"="==e?6:"-"==e?5:7-c.value.search(/[^#]|$/)}}}.call(i.prototype)})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var o=e("../range").Range,r=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var r=n[1].length,a=e.findMatchingBracket({row:t,column:r});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new o(t,0,t,r-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(r.prototype),t.MatchingBraceOutdent=r})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,o,r){if('"'==r||"'"==r){var s=r,l=o.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),u=o.doc.getLine(c.row).substring(c.column,c.column+1),d=new a(o,c.row,c.column),g=d.getCurrentToken();if(u==s&&(i(g,"attribute-value")||i(g,"string")))return{text:"",selection:[1,1]};if(g||(g=d.stepBackward()),!g)return;for(;i(g,"tag-whitespace")||i(g,"whitespace");)g=d.stepBackward();var p=!u||u.match(/\s/);if(i(g,"attribute-equals")&&(p||">"==u)||i(g,"decl-attribute-equals")&&(p||"?"==u))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,o,r){var a=o.doc.getTextRange(r);if(!r.isMultiLine()&&('"'==a||"'"==a)&&o.doc.getLine(r.start.row).substring(r.start.column+1,r.start.column+2)==a)return r.end.column++,r})),this.add("autoclosing","insertion",(function(e,t,n,o,r){if(">"==r){var s=n.getSelectionRange().start,l=new a(o,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var u=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(o.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var g=l.getCurrentTokenRow(),p=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var m=c.value;if(g==s.row&&(m=m.substring(0,s.column-p)),this.voidElements&&this.voidElements.hasOwnProperty(m.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,o,r){if("\n"==r){var s=n.getCursorPosition(),l=o.getLine(s.row),c=new a(o,s.row,s.column),u=c.getCurrentToken();if(i(u,"")&&-1!==u.type.indexOf("tag-close")){if("/>"==u.value)return;for(;u&&-1===u.type.indexOf("tag-name");)u=c.stepBackward();if(!u)return;var d=u.value,g=c.getCurrentTokenRow();if(!(u=c.stepBackward())||-1!==u.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[d]||!this.voidElements){var p=o.getTokenAt(s.row,s.column+1),m=(l=o.getLine(g),this.$getIndent(l)),h=m+o.getTabString();return p&&""==a){var i=n.getSelectionRange().start,s=new r(o,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};o.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=o.mixin({},this.voidElements),t&&o.mixin(this.optionalEndTags,t)};o.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var o=this._getFirstTagInLine(e,n);return o?o.closing||!o.tagName&&o.selfClosing?"markbeginend"===t?"end":"":!o.tagName||o.selfClosing||this.voidElements.hasOwnProperty(o.tagName.toLowerCase())||this._findEndTagInLine(e,n,o.tagName,o.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return o}if(l(a,"tag-close"))return o.selfClosing="/>"==a.value,o;o.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,o){for(var r=e.getTokens(t),a=0,i=0;ic)break;var u=this.getFoldWidgetRange(e,"all",t);if(u){if(u.start.row<=a)break;if(u.isMultiLine())t=u.end.row;else if(o==c)break}s=t}}return new r(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new r(i,o,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new r};o.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,o){return this.getFoldWidgetRangeBase(e,t,n,o)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,u=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};o.inherits(u,r),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e),a=r.tokens,i=r.state;if(a.length&&"comment"==a[a.length-1].type)return o;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(o+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(u.prototype),t.Mode=u})),ace.define("ace/mode/css_completions",["require","exports","module"],(function(e,t,n){"use strict";var o={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,double:2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{default:1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},float:{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,static:1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},r=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e)if("string"==typeof e[t]){var n=t.replace(/[A-Z]/g,(function(e){return"-"+e.toLowerCase()}));o.hasOwnProperty(n)||(o[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,o){if(this.completionsDefined||this.defineCompletions(),"ruleset"===e||"ace/mode/scss"==t.$mode.$id){var r=t.getLine(n.row).substr(0,n.column),a=/\([^)]*$/.test(r);return a&&(r=r.substr(r.lastIndexOf("(")+1)),/:[^;]+$/.test(r)?(/([\w\-]+):[^:]*$/.test(r),this.getPropertyValueCompletions(e,t,n,o)):this.getPropertyCompletions(e,t,n,o,a)}return[]},this.getPropertyCompletions=function(e,t,n,r,a){return a=a||!1,Object.keys(o).map((function(e){return{caption:e,snippet:e+": $0"+(a?"":";"),meta:"property",score:1e6}}))},this.getPropertyValueCompletions=function(e,t,n,r){var a=t.getLine(n.row).substr(0,n.column),i=(/([\w\-]+):[^:]*$/.exec(a)||{})[1];if(!i)return[];var s=[];return i in o&&"object"==typeof o[i]&&(s=Object.keys(o[i])),s.map((function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}}))}}).call(r.prototype),t.CssCompletions=r})),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=(e("../behaviour").Behaviour,e("./cstyle").CstyleBehaviour),a=e("../../token_iterator").TokenIterator,i=function(){this.inherit(r),this.add("colon","insertion",(function(e,t,n,o,r){if(":"===r&&n.selection.isEmpty()){var i=n.getCursorPosition(),s=new a(o,i.row,i.column),l=s.getCurrentToken();if(l&&l.value.match(/\s+/)&&(l=s.stepBackward()),l&&"support.type"===l.type){var c=o.doc.getLine(i.row);if(":"===c.substring(i.column,i.column+1))return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(c.substring(i.column)))return{text:":;",selection:[1,1]}}}})),this.add("colon","deletion",(function(e,t,n,o,r){var i=o.doc.getTextRange(r);if(!r.isMultiLine()&&":"===i){var s=n.getCursorPosition(),l=new a(o,s.row,s.column),c=l.getCurrentToken();if(c&&c.value.match(/\s+/)&&(c=l.stepBackward()),c&&"support.type"===c.type&&";"===o.doc.getLine(r.start.row).substring(r.end.column,r.end.column+1))return r.end.column++,r}})),this.add("semicolon","insertion",(function(e,t,n,o,r){if(";"===r&&n.selection.isEmpty()){var a=n.getCursorPosition();if(";"===o.doc.getLine(a.row).substring(a.column,a.column+1))return{text:"",selection:[1,1]}}})),this.add("!important","insertion",(function(e,t,n,o,r){if("!"===r&&n.selection.isEmpty()){var a=n.getCursorPosition(),i=o.doc.getLine(a.row);if(/^\s*(;|}|$)/.test(i.substring(a.column)))return{text:"!important",selection:[10,10]}}}))};o.inherits(i,r),t.CssBehaviour=i})),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./css_highlight_rules").CssHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./css_completions").CssCompletions,c=e("./behaviour/css").CssBehaviour,u=e("./folding/cstyle").FoldMode,d=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new c,this.$completer=new l,this.foldingRules=new u};o.inherits(d,r),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e).tokens;return r.length&&"comment"==r[r.length-1].type||t.match(/^.*\{\s*$/)&&(o+=n),o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/css",this.snippetFileId="ace/snippets/css"}.call(d.prototype),t.Mode=d})),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};o.inherits(a,r),function(){this.$getMode=function(e){for(var t in"string"!=typeof e&&(e=e[0]),this.subModes)if(0===e.indexOf(t))return this.subModes[t];return null},this.$tryMode=function(e,t,n,o){var r=this.$getMode(e);return r?r.getFoldWidget(t,n,o):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var o=this.$getMode(e.getState(n-1));return o&&o.getFoldWidget(e,t,n)||(o=this.$getMode(e.getState(n))),o&&o.getFoldWidget(e,t,n)||(o=this.defaultMode),o.getFoldWidgetRange(e,t,n)}}.call(a.prototype)})),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./mixed").FoldMode,a=e("./xml").FoldMode,i=e("./cstyle").FoldMode,s=t.FoldMode=function(e,t){r.call(this,new a(e,t),{"js-":new i,"css-":new i})};o.inherits(s,r)})),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../token_iterator").TokenIterator,r=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"].concat(["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"]),a={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,for:1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{for:1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,default:1},section:{},summary:{},u:{},ul:{},var:{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},i=Object.keys(a);function s(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"tag-name");)r=n.stepBackward();if(r)return r.value}var c=function(){};(function(){this.getCompletions=function(e,t,n,o){var r=t.getTokenAt(n.row,n.column);if(!r)return[];if(s(r,"tag-name")||s(r,"tag-open")||s(r,"end-tag-open"))return this.getTagCompletions(e,t,n,o);if(s(r,"tag-whitespace")||s(r,"attribute-name"))return this.getAttributeCompletions(e,t,n,o);if(s(r,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,o);var a=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(a)?this.getHTMLEntityCompletions(e,t,n,o):[]},this.getTagCompletions=function(e,t,n,o){return i.map((function(e){return{value:e,meta:"tag",score:1e6}}))},this.getAttributeCompletions=function(e,t,n,o){var i=l(t,n);if(!i)return[];var s=r;return i in a&&(s=s.concat(Object.keys(a[i]))),s.map((function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}}))},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),c=function(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"attribute-name");)r=n.stepBackward();if(r)return r.value}(t,n);if(!i)return[];var u=[];return i in a&&c in a[i]&&"object"==typeof a[i][c]&&(u=Object.keys(a[i][c])),u.map((function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}}))},this.getHTMLEntityCompletions=function(e,t,n,o){return["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"].map((function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}}))}}).call(c.prototype),t.HtmlCompletions=c})),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./text").Mode,i=e("./javascript").Mode,s=e("./css").Mode,l=e("./html_highlight_rules").HtmlHighlightRules,c=e("./behaviour/xml").XmlBehaviour,u=e("./folding/html").FoldMode,d=e("./html_completions").HtmlCompletions,g=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],m=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],h=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=l,this.$behaviour=new c,this.$completer=new d,this.createModeDelegates({"js-":i,"css-":s}),this.foldingRules=new u(this.voidElements,r.arrayToMap(m))};o.inherits(h,a),function(){this.blockComment={start:"\x3c!--",end:"--\x3e"},this.voidElements=r.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){if(this.constructor==h){var t=new g(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t}},this.$id="ace/mode/html",this.snippetFileId="ace/snippets/html"}.call(h.prototype),t.Mode=h})),ace.define("ace/mode/sh_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=t.reservedKeywords="!|{|}|case|do|done|elif|else|esac|fi|for|if|in|then|until|while|&|;|export|local|read|typeset|unset|elif|select|set|function|declare|readonly",i=t.languageConstructs="[|]|alias|bg|bind|break|builtin|cd|command|compgen|complete|continue|dirs|disown|echo|enable|eval|exec|exit|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|return|set|shift|shopt|source|suspend|test|times|trap|type|ulimit|umask|unalias|wait",s=function(){var e=this.createKeywordMapper({keyword:a,"support.function.builtin":i,"invalid.deprecated":"debugger"},"identifier"),t="(?:\\d+)",n="(?:(?:"+t+"?(?:\\.\\d+))|(?:"+t+"\\.))",o="(?:(?:(?:"+n+"|"+t+"))|"+n+")",r="(?:&"+t+")",s="[a-zA-Z_][a-zA-Z0-9_]*",l="(?:"+s+"(?==))",c="(?:"+s+"\\s*\\(\\))";this.$rules={start:[{token:"constant",regex:/\\./},{token:["text","comment"],regex:/(^|\s)(#.*)$/},{token:"string.start",regex:'"',push:[{token:"constant.language.escape",regex:/\\(?:[$`"\\]|$)/},{include:"variables"},{token:"keyword.operator",regex:/`/},{token:"string.end",regex:'"',next:"pop"},{defaultToken:"string"}]},{token:"string",regex:"\\$'",push:[{token:"constant.language.escape",regex:/\\(?:[abeEfnrtv\\'"]|x[a-fA-F\d]{1,2}|u[a-fA-F\d]{4}([a-fA-F\d]{4})?|c.|\d{1,3})/},{token:"string",regex:"'",next:"pop"},{defaultToken:"string"}]},{regex:"<<<",token:"keyword.operator"},{stateName:"heredoc",regex:"(<<-?)(\\s*)(['\"`]?)([\\w\\-]+)(['\"`]?)",onMatch:function(e,t,n){var o="-"==e[2]?"indentedHeredoc":"heredoc",r=e.split(this.splitRegex);return n.push(o,r[4]),[{type:"constant",value:r[1]},{type:"text",value:r[2]},{type:"string",value:r[3]},{type:"support.class",value:r[4]},{type:"string",value:r[5]}]},rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^\t+"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return"heredoc"===t[0]||"indentedHeredoc"===t[0]?t[0]:e}},{token:["keyword","text","text","text","variable"],regex:/(declare|local|readonly)(\s+)(?:(-[fixar]+)(\s+))?([a-zA-Z_][a-zA-Z0-9_]*\b)/},{token:"variable.language",regex:"(?:\\$(?:SHLVL|\\$|\\!|\\?))"},{token:"variable",regex:l},{include:"variables"},{token:"support.function",regex:c},{token:"support.function",regex:r},{token:"string",start:"'",end:"'"},{token:"constant.numeric",regex:o},{token:"constant.numeric",regex:"(?:(?:[1-9]\\d*)|(?:0))\\b"},{token:e,regex:"[a-zA-Z_][a-zA-Z0-9_]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|~|<|>|<=|=>|=|!=|[%&|`]"},{token:"punctuation.operator",regex:";"},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]]"},{token:"paren.rparen",regex:"[\\)\\}]",next:"pop"}],variables:[{token:"variable",regex:/(\$)(\w+)/},{token:["variable","paren.lparen"],regex:/(\$)(\()/,push:"start"},{token:["variable","paren.lparen","keyword.operator","variable","keyword.operator"],regex:/(\$)(\{)([#!]?)(\w+|[*@#?\-$!0_])(:[?+\-=]?|##?|%%?|,,?\/|\^\^?)?/,push:"start"},{token:"variable",regex:/\$[*@#?\-$!0_]/},{token:["variable","paren.lparen"],regex:/(\$)(\{)/,push:"start"}]},this.normalizeRules()};o.inherits(s,r),t.ShHighlightRules=s})),ace.define("ace/mode/sh",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sh_highlight_rules","ace/range","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./sh_highlight_rules").ShHighlightRules,i=e("../range").Range,s=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=a,this.foldingRules=new s,this.$behaviour=this.$defaultBehaviour};o.inherits(l,r),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e).tokens;return r.length&&"comment"==r[r.length-1].type||"start"==e&&t.match(/^.*[\{\(\[:]\s*$/)&&(o+=n),o};var e={pass:1,return:1,raise:1,break:1,continue:1};this.checkOutdent=function(t,n,o){if("\r\n"!==o&&"\r"!==o&&"\n"!==o)return!1;var r=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!r)return!1;do{var a=r.pop()}while(a&&("comment"==a.type||"text"==a.type&&a.value.match(/^\s+$/)));return!!a&&"keyword"==a.type&&e[a.value]},this.autoOutdent=function(e,t,n){n+=1;var o=this.$getIndent(t.getLine(n)),r=t.getTabString();o.slice(-r.length)==r&&t.remove(new i(n,o.length-r.length,n,o.length))},this.$id="ace/mode/sh",this.snippetFileId="ace/snippets/sh"}.call(l.prototype),t.Mode=l})),ace.define("ace/mode/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/xml_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/xml","ace/worker/worker_client"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./text").Mode,i=e("./xml_highlight_rules").XmlHighlightRules,s=e("./behaviour/xml").XmlBehaviour,l=e("./folding/xml").FoldMode,c=e("../worker/worker_client").WorkerClient,u=function(){this.HighlightRules=i,this.$behaviour=new s,this.foldingRules=new l};o.inherits(u,a),function(){this.voidElements=r.arrayToMap([]),this.blockComment={start:"\x3c!--",end:"--\x3e"},this.createWorker=function(e){var t=new c(["ace"],"ace/mode/xml_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("error",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/xml"}.call(u.prototype),t.Mode=u})),ace.define("ace/mode/markdown",["require","exports","module","ace/lib/oop","ace/mode/behaviour/cstyle","ace/mode/text","ace/mode/markdown_highlight_rules","ace/mode/folding/markdown","ace/mode/javascript","ace/mode/html","ace/mode/sh","ace/mode/sh","ace/mode/xml","ace/mode/css"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./behaviour/cstyle").CstyleBehaviour,a=e("./text").Mode,i=e("./markdown_highlight_rules").MarkdownHighlightRules,s=e("./folding/markdown").FoldMode,l=function(){this.HighlightRules=i,this.createModeDelegates({javascript:e("./javascript").Mode,html:e("./html").Mode,bash:e("./sh").Mode,sh:e("./sh").Mode,xml:e("./xml").Mode,css:e("./css").Mode}),this.foldingRules=new s,this.$behaviour=new r({braces:!0})};o.inherits(l,a),function(){this.type="text",this.blockComment={start:"\x3c!--",end:"--\x3e"},this.$quotes={'"':'"',"`":"`"},this.getNextLineIndent=function(e,t,n){if("listblock"==e){var o=/^(\s*)(?:([-+*])|(\d+)\.)(\s+)/.exec(t);if(!o)return"";var r=o[2];return r||(r=parseInt(o[3],10)+1+"."),o[1]+r+o[4]}return this.$getIndent(t)},this.$id="ace/mode/markdown",this.snippetFileId="ace/snippets/markdown"}.call(l.prototype),t.Mode=l})),ace.require(["ace/mode/markdown"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/069a0d6b093e73e820f6a60a91fa614b.js b/069a0d6b093e73e820f6a60a91fa614b.js new file mode 100644 index 00000000..49145215 --- /dev/null +++ b/069a0d6b093e73e820f6a60a91fa614b.js @@ -0,0 +1 @@ +ace.define("ace/mode/sparql_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,r){"use strict";var i=e("../lib/oop"),s=e("./text_highlight_rules").TextHighlightRules,o=function(){this.$rules={start:[{include:"#comments"},{include:"#strings"},{include:"#string-language-suffixes"},{include:"#string-datatype-suffixes"},{include:"#logic-operators"},{include:"#relative-urls"},{include:"#xml-schema-types"},{include:"#rdf-schema-types"},{include:"#owl-types"},{include:"#qnames"},{include:"#keywords"},{include:"#built-in-functions"},{include:"#variables"},{include:"#boolean-literal"},{include:"#punctuation-operators"}],"#boolean-literal":[{token:"constant.language.boolean.sparql",regex:/true|false/}],"#built-in-functions":[{token:"support.function.sparql",regex:/[Aa][Bb][Ss]|[Aa][Vv][Gg]|[Bb][Nn][Oo][Dd][Ee]|[Bb][Oo][Uu][Nn][Dd]|[Cc][Ee][Ii][Ll]|[Cc][Oo][Aa][Ll][Ee][Ss][Cc][Ee]|[Cc][Oo][Nn][Cc][Aa][Tt]|[Cc][Oo][Nn][Tt][Aa][Ii][Nn][Ss]|[Cc][Oo][Uu][Nn][Tt]|[Dd][Aa][Tt][Aa][Tt][Yy][Pp][Ee]|[Dd][Aa][Yy]|[Ee][Nn][Cc][Oo][Dd][Ee]_[Ff][Oo][Rr]_[Uu][Rr][Ii]|[Ee][Xx][Ii][Ss][Tt][Ss]|[Ff][Ll][Oo][Oo][Rr]|[Gg][Rr][Oo][Uu][Pp]_[Cc][Oo][Nn][Cc][Aa][Tt]|[Hh][Oo][Uu][Rr][Ss]|[Ii][Ff]|[Ii][Rr][Ii]|[Ii][Ss][Bb][Ll][Aa][Nn][Kk]|[Ii][Ss][Ii][Rr][Ii]|[Ii][Ss][Ll][Ii][Tt][Ee][Rr][Aa][Ll]|[Ii][Ss][Nn][Uu][Mm][Ee][Rr][Ii][Cc]|[Ii][Ss][Uu][Rr][Ii]|[Ll][Aa][Nn][Gg]|[Ll][Aa][Nn][Gg][Mm][Aa][Tt][Cc][Hh][Ee][Ss]|[Ll][Cc][Aa][Ss][Ee]|[Mm][Aa][Xx]|[Mm][Dd]5|[Mm][Ii][Nn]|[Mm][Ii][Nn][Uu][Tt][Ee][Ss]|[Mm][Oo][Nn][Tt][Hh]|[Nn][Oo][Ww]|[Rr][Aa][Nn][Dd]|[Rr][Ee][Gg][Ee][Xx]|[Rr][Ee][Pp][Ll][Aa][Cc][Ee]|[Rr][Oo][Uu][Nn][Dd]|[Ss][Aa][Mm][Ee][Tt][Ee][Rr][Mm]|[Ss][Aa][Mm][Pp][Ll][Ee]|[Ss][Ee][Cc][Oo][Nn][Dd][Ss]|[Ss][Ee][Pp][Aa][Rr][Aa][Tt][Oo][Rr]|[Ss][Hh][Aa](?:1|256|384|512)|[Ss][Tt][Rr]|[Ss][Tt][Rr][Aa][Ff][Tt][Ee][Rr]|[Ss][Tt][Rr][Bb][Ee][Ff][Oo][Rr][Ee]|[Ss][Tt][Rr][Dd][Tt]|[Ss][Tt][Rr][Ee][Nn][Dd][Ss]|[Ss][Tt][Rr][Ll][Aa][Nn][Gg]|[Ss][Tt][Rr][Ll][Ee][Nn]|[Ss][Tt][Rr][Ss][Tt][Aa][Rr][Tt][Ss]|[Ss][Tt][Rr][Uu][Uu][Ii][Dd]|[Ss][Uu][Bb][Ss][Tt][Rr]|[Ss][Uu][Mm]|[Tt][Ii][Mm][Ee][Zz][Oo][Nn][Ee]|[Tt][Zz]|[Uu][Cc][Aa][Ss][Ee]|[Uu][Rr][Ii]|[Uu][Uu][Ii][Dd]|[Yy][Ee][Aa][Rr]/}],"#comments":[{token:["punctuation.definition.comment.sparql","comment.line.hash.sparql"],regex:/(#)(.*$)/}],"#keywords":[{token:"keyword.other.sparql",regex:/[Aa][Dd][Dd]|[Aa][Ll][Ll]|[Aa][Ss]|[As][Ss][Cc]|[Aa][Ss][Kk]|[Bb][Aa][Ss][Ee]|[Bb][Ii][Nn][Dd]|[Bb][Yy]|[Cc][Ll][Ee][Aa][Rr]|[Cc][Oo][Nn][Ss][Tt][Rr][Uu][Cc][Tt]|[Cc][Oo][Pp][Yy]|[Cc][Rr][Ee][Aa][Tt][Ee]|[Dd][Aa][Tt][Aa]|[Dd][Ee][Ff][Aa][Uu][Ll][Tt]|[Dd][Ee][Ll][Ee][Tt][Ee]|[Dd][Ee][Sc][Cc]|[Dd][Ee][Ss][Cc][Rr][Ii][Bb][Ee]|[Dd][Ii][Ss][Tt][Ii][Nn][Cc][Tt]|[Dd][Rr][Oo][Pp]|[Ff][Ii][Ll][Tt][Ee][Rr]|[Ff][Rr][Oo][Mm]|[Gg][Rr][Aa][Pp][Hh]|[Gg][Rr][Oo][Uu][Pp]|[Hh][Aa][Vv][Ii][Nn][Gg]|[Ii][Nn][Ss][Ee][Rr][Tt]|[Ll][Ii][Mm][Ii][Tt]|[Ll][Oo][Aa][Dd]|[Mm][Ii][Nn][Uu][Ss]|[Mm][Oo][Vv][Ee]|[Nn][Aa][Mm][Ee][Dd]|[Oo][Ff][Ff][Ss][Ee][Tt]|[Oo][Pp][Tt][Ii][Oo][Nn][Aa][Ll]|[Oo][Rr][Dd][Ee][Rr]|[Pp][Rr][Ee][Ff][Ii][Xx]|[Rr][Ee][Dd][Uu][Cc][Ee][Dd]|[Ss][Ee][Ll][Ee][Cc][Tt]|[Ss][Ee][Pp][Aa][Rr][Aa][Tt][Oo][Rr]|[Ss][Ee][Rr][Vv][Ii][Cc][Ee]|[Ss][Ii][Ll][Ee][Nn][Tt]|[Tt][Oo]|[Uu][Nn][Dd][Ee][Ff]|[Uu][Nn][Ii][Oo][Nn]|[Uu][Ss][Ii][Nn][Gg]|[Vv][Aa][Ll][Uu][Ee][Ss]|[Ww][He][Ee][Rr][Ee]|[Ww][Ii][Tt][Hh]/}],"#logic-operators":[{token:"keyword.operator.logical.sparql",regex:/\|\||&&|=|!=|<|>|<=|>=|(?:^|!?\s)IN(?:!?\s|$)|(?:^|!?\s)NOT(?:!?\s|$)|-|\+|\*|\/|\!/}],"#owl-types":[{token:"support.type.datatype.owl.sparql",regex:/owl:[a-zA-Z]+/}],"#punctuation-operators":[{token:"keyword.operator.punctuation.sparql",regex:/;|,|\.|\(|\)|\{|\}|\|/}],"#qnames":[{token:"entity.name.other.qname.sparql",regex:/(?:[a-zA-Z][-_a-zA-Z0-9]*)?:(?:[_a-zA-Z][-_a-zA-Z0-9]*)?/}],"#rdf-schema-types":[{token:"support.type.datatype.rdf.schema.sparql",regex:/rdfs?:[a-zA-Z]+|(?:^|\s)a(?:\s|$)/}],"#relative-urls":[{token:"string.quoted.other.relative.url.sparql",regex://,next:"pop"},{defaultToken:"string.quoted.other.relative.url.sparql"}]}],"#string-datatype-suffixes":[{token:"keyword.operator.datatype.suffix.sparql",regex:/\^\^/}],"#string-language-suffixes":[{token:["keyword.operator.language.suffix.sparql","constant.language.suffix.sparql"],regex:/(?!")(@)([a-z]+(?:\-[a-z0-9]+)*)/}],"#strings":[{token:"string.quoted.triple.sparql",regex:/"""/,push:[{token:"string.quoted.triple.sparql",regex:/"""/,next:"pop"},{defaultToken:"string.quoted.triple.sparql"}]},{token:"string.quoted.double.sparql",regex:/"/,push:[{token:"string.quoted.double.sparql",regex:/"/,next:"pop"},{token:"invalid.string.newline",regex:/$/},{token:"constant.character.escape.sparql",regex:/\\./},{defaultToken:"string.quoted.double.sparql"}]}],"#variables":[{token:"variable.other.sparql",regex:/(?:\?|\$)[-_a-zA-Z0-9]+/}],"#xml-schema-types":[{token:"support.type.datatype.schema.sparql",regex:/xsd?:[a-z][a-zA-Z]+/}]},this.normalizeRules()};o.metaData={fileTypes:["rq","sparql"],name:"SPARQL",scopeName:"source.sparql"},i.inherits(o,s),t.SPARQLHighlightRules=o})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,r){"use strict";var i=e("../../lib/oop"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,n=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};i.inherits(n,o),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,r){var i=e.getLine(r);if(this.singleLineBlockCommentRe.test(i)&&!this.startRegionRe.test(i)&&!this.tripleStarBlockCommentRe.test(i))return"";var s=this._getFoldWidgetBase(e,t,r);return!s&&this.startRegionRe.test(i)?"start":s},this.getFoldWidgetRange=function(e,t,r,i){var s,o=e.getLine(r);if(this.startRegionRe.test(o))return this.getCommentRegionBlock(e,o,r);if(s=o.match(this.foldingStartMarker)){var n=s.index;if(s[1])return this.openingBracketBlock(e,s[1],r,n);var a=e.getCommentFoldRange(r,n+s[0].length,1);return a&&!a.isMultiLine()&&(i?a=this.getSectionRange(e,r):"all"!=t&&(a=null)),a}return"markbegin"!==t&&(s=o.match(this.foldingStopMarker))?(n=s.index+s[0].length,s[1]?this.closingBracketBlock(e,s[1],r,n):e.getCommentFoldRange(r,n,-1)):void 0},this.getSectionRange=function(e,t){for(var r=e.getLine(t),i=r.search(/\S/),o=t,n=r.length,a=t+=1,l=e.getLength();++tg)break;var u=this.getFoldWidgetRange(e,"all",t);if(u){if(u.start.row<=o)break;if(u.isMultiLine())t=u.end.row;else if(i==g)break}a=t}}return new s(o,n,a,e.getLine(a).length)},this.getCommentRegionBlock=function(e,t,r){for(var i=t.search(/\s*$/),o=e.getLength(),n=r,a=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++rn)return new s(n,i,r,t.length)}}.call(n.prototype)})),ace.define("ace/mode/sparql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sparql_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,r){"use strict";var i=e("../lib/oop"),s=e("./text").Mode,o=e("./sparql_highlight_rules").SPARQLHighlightRules,n=e("./folding/cstyle").FoldMode,a=function(){this.HighlightRules=o,this.foldingRules=new n};i.inherits(a,s),function(){this.$id="ace/mode/sparql"}.call(a.prototype),t.Mode=a})),ace.require(["ace/mode/sparql"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/06d958315fc6cdbb28576b03e43203aa.js b/06d958315fc6cdbb28576b03e43203aa.js new file mode 100644 index 00000000..e487bca1 --- /dev/null +++ b/06d958315fc6cdbb28576b03e43203aa.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/dockerfile"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/07397bd479cbc34bc04576b4f15bdf18.js b/07397bd479cbc34bc04576b4f15bdf18.js new file mode 100644 index 00000000..2a8341da --- /dev/null +++ b/07397bd479cbc34bc04576b4f15bdf18.js @@ -0,0 +1 @@ +ace.define("ace/snippets/perl.snippets",["require","exports","module"],(function(n,t,e){e.exports="# #!/usr/bin/perl\nsnippet #!\n\t#!/usr/bin/env perl\n\n# Hash Pointer\nsnippet .\n\t =>\n# Function\nsnippet sub\n\tsub ${1:function_name} {\n\t\t${2:#body ...}\n\t}\n# Conditional\nsnippet if\n\tif (${1}) {\n\t\t${2:# body...}\n\t}\n# Conditional if..else\nsnippet ife\n\tif (${1}) {\n\t\t${2:# body...}\n\t}\n\telse {\n\t\t${3:# else...}\n\t}\n# Conditional if..elsif..else\nsnippet ifee\n\tif (${1}) {\n\t\t${2:# body...}\n\t}\n\telsif (${3}) {\n\t\t${4:# elsif...}\n\t}\n\telse {\n\t\t${5:# else...}\n\t}\n# Conditional One-line\nsnippet xif\n\t${1:expression} if ${2:condition};${3}\n# Unless conditional\nsnippet unless\n\tunless (${1}) {\n\t\t${2:# body...}\n\t}\n# Unless conditional One-line\nsnippet xunless\n\t${1:expression} unless ${2:condition};${3}\n# Try/Except\nsnippet eval\n\tlocal $@;\n\teval {\n\t\t${1:# do something risky...}\n\t};\n\tif (my $e = $@) {\n\t\t${2:# handle failure...}\n\t}\n# While Loop\nsnippet wh\n\twhile (${1}) {\n\t\t${2:# body...}\n\t}\n# While Loop One-line\nsnippet xwh\n\t${1:expression} while ${2:condition};${3}\n# C-style For Loop\nsnippet cfor\n\tfor (my $${2:var} = 0; $$2 < ${1:count}; $$2${3:++}) {\n\t\t${4:# body...}\n\t}\n# For loop one-line\nsnippet xfor\n\t${1:expression} for @${2:array};${3}\n# Foreach Loop\nsnippet for\n\tforeach my $${1:x} (@${2:array}) {\n\t\t${3:# body...}\n\t}\n# Foreach Loop One-line\nsnippet fore\n\t${1:expression} foreach @${2:array};${3}\n# Package\nsnippet package\n\tpackage ${1:`substitute(Filename('', 'Page Title'), '^.', '\\u&', '')`};\n\n\t${2}\n\n\t1;\n\n\t__END__\n# Package syntax perl >= 5.14\nsnippet packagev514\n\tpackage ${1:`substitute(Filename('', 'Page Title'), '^.', '\\u&', '')`} ${2:0.99};\n\n\t${3}\n\n\t1;\n\n\t__END__\n#moose\nsnippet moose\n\tuse Moose;\n\tuse namespace::autoclean;\n\t${1:#}BEGIN {extends '${2:ParentClass}'};\n\n\t${3}\n# parent\nsnippet parent\n\tuse parent qw(${1:Parent Class});\n# Read File\nsnippet slurp\n\tmy $${1:var} = do { local $/; open my $file, '<', \"${2:file}\"; <$file> };\n\t${3}\n# strict warnings\nsnippet strwar\n\tuse strict;\n\tuse warnings;\n# older versioning with perlcritic bypass\nsnippet vers\n\t## no critic\n\tour $VERSION = '${1:version}';\n\teval $VERSION;\n\t## use critic\n# new 'switch' like feature\nsnippet switch\n\tuse feature 'switch';\n\n# Anonymous subroutine\nsnippet asub\n\tsub {\n\t \t${1:# body }\n\t}\n\n\n\n# Begin block\nsnippet begin\n\tBEGIN {\n\t\t${1:# begin body}\n\t}\n\n# call package function with some parameter\nsnippet pkgmv\n\t__PACKAGE__->${1:package_method}(${2:var})\n\n# call package function without a parameter\nsnippet pkgm\n\t__PACKAGE__->${1:package_method}()\n\n# call package \"get_\" function without a parameter\nsnippet pkget\n\t__PACKAGE__->get_${1:package_method}()\n\n# call package function with a parameter\nsnippet pkgetv\n\t__PACKAGE__->get_${1:package_method}(${2:var})\n\n# complex regex\nsnippet qrx\n\tqr/\n\t ${1:regex}\n\t/xms\n\n#simpler regex\nsnippet qr/\n\tqr/${1:regex}/x\n\n#given\nsnippet given\n\tgiven ($${1:var}) {\n\t\t${2:# cases}\n\t\t${3:# default}\n\t}\n\n# switch-like case\nsnippet when\n\twhen (${1:case}) {\n\t\t${2:# body}\n\t}\n\n# hash slice\nsnippet hslice\n\t@{ ${1:hash} }{ ${2:array} }\n\n\n# map\nsnippet map\n\tmap { ${2: body } } ${1: @array } ;\n\n\n\n# Pod stub\nsnippet ppod\n\t=head1 NAME\n\n\t${1:ClassName} - ${2:ShortDesc}\n\n\t=head1 SYNOPSIS\n\n\t use $1;\n\n\t ${3:# synopsis...}\n\n\t=head1 DESCRIPTION\n\n\t${4:# longer description...}\n\n\n\t=head1 INTERFACE\n\n\n\t=head1 DEPENDENCIES\n\n\n\t=head1 SEE ALSO\n\n\n# Heading for a subroutine stub\nsnippet psub\n\t=head2 ${1:MethodName}\n\n\t${2:Summary....}\n\n# Heading for inline subroutine pod\nsnippet psubi\n\t=head2 ${1:MethodName}\n\n\t${2:Summary...}\n\n\n\t=cut\n# inline documented subroutine\nsnippet subpod\n\t=head2 $1\n\n\tSummary of $1\n\n\t=cut\n\n\tsub ${1:subroutine_name} {\n\t\t${2:# body...}\n\t}\n# Subroutine signature\nsnippet parg\n\t=over 2\n\n\t=item\n\tArguments\n\n\n\t=over 3\n\n\t=item\n\tC<${1:DataStructure}>\n\n\t ${2:Sample}\n\n\n\t=back\n\n\n\t=item\n\tReturn\n\n\t=over 3\n\n\n\t=item\n\tC<${3:...return data}>\n\n\n\t=back\n\n\n\t=back\n\n\n\n# Moose has\nsnippet has\n\thas ${1:attribute} => (\n\t\tis\t => '${2:ro|rw}',\n\t\tisa \t=> '${3:Str|Int|HashRef|ArrayRef|etc}',\n\t\tdefault => sub {\n\t\t\t${4:defaultvalue}\n\t\t},\n\t\t${5:# other attributes}\n\t);\n\n\n# override\nsnippet override\n\toverride ${1:attribute} => sub {\n\t\t${2:# my $self = shift;};\n\t\t${3:# my ($self, $args) = @_;};\n\t};\n\n\n# use test classes\nsnippet tuse\n\tuse Test::More;\n\tuse Test::Deep; # (); # uncomment to stop prototype errors\n\tuse Test::Exception;\n\n# local test lib\nsnippet tlib\n\tuse lib qw{ ./t/lib };\n\n#test methods\nsnippet tmeths\n\t$ENV{TEST_METHOD} = '${1:regex}';\n\n# runtestclass\nsnippet trunner\n\tuse ${1:test_class};\n\t$1->runtests();\n\n# Test::Class-style test\nsnippet tsub\n\tsub t${1:number}_${2:test_case} :Test(${3:num_of_tests}) {\n\t\tmy $self = shift;\n\t\t${4:# body}\n\n\t}\n\n# Test::Routine-style test\nsnippet trsub\n\ttest ${1:test_name} => { description => '${2:Description of test.}'} => sub {\n\t\tmy ($self) = @_;\n\t\t${3:# test code}\n\t};\n\n#prep test method\nsnippet tprep\n\tsub prep${1:number}_${2:test_case} :Test(startup) {\n\t\tmy $self = shift;\n\t\t${4:# body}\n\t}\n\n# cause failures to print stack trace\nsnippet debug_trace\n\tuse Carp; # 'verbose';\n\t# cloak \"die\"\n\t# warn \"warning\"\n\t$SIG{'__DIE__'} = sub {\n\t\trequire Carp; Carp::confess\n\t};\n\n"})),ace.define("ace/snippets/perl",["require","exports","module","ace/snippets/perl.snippets"],(function(n,t,e){"use strict";t.snippetText=n("./perl.snippets"),t.scope="perl"})),ace.require(["ace/snippets/perl"],(function(n){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=n)})); \ No newline at end of file diff --git a/07567125b93045706d81f17f7d04e262.js b/07567125b93045706d81f17f7d04e262.js new file mode 100644 index 00000000..880a4116 --- /dev/null +++ b/07567125b93045706d81f17f7d04e262.js @@ -0,0 +1 @@ +ace.define("ace/ext/rtl",["require","exports","module","ace/editor","ace/config"],(function(e,t,i){"use strict";var n=[{name:"leftToRight",bindKey:{win:"Ctrl-Alt-Shift-L",mac:"Command-Alt-Shift-L"},exec:function(e){e.session.$bidiHandler.setRtlDirection(e,!1)},readOnly:!0},{name:"rightToLeft",bindKey:{win:"Ctrl-Alt-Shift-R",mac:"Command-Alt-Shift-R"},exec:function(e){e.session.$bidiHandler.setRtlDirection(e,!0)},readOnly:!0}],r=e("../editor").Editor;function o(e,t){var i=t.getSelection().lead;t.session.$bidiHandler.isRtlLine(i.row)&&0===i.column&&(t.session.$bidiHandler.isMoveLeftOperation&&i.row>0?t.getSelection().moveCursorTo(i.row-1,t.session.getLine(i.row-1).length):t.getSelection().isEmpty()?i.column+=1:i.setPosition(i.row,i.column+1))}function s(e){e.editor.session.$bidiHandler.isMoveLeftOperation=/gotoleft|selectleft|backspace|removewordleft/.test(e.command.name)}function d(e,t){var i=t.session;if(i.$bidiHandler.currentRow=null,i.$bidiHandler.isRtlLine(e.start.row)&&"insert"===e.action&&e.lines.length>1)for(var n=e.start.row;n\n\t\t${2}\n\t\nsnippet header\n\t
\n\t\t${1}\n\t
\nsnippet header.\n\t
\n\t\t${2}\n\t
\nsnippet header#\n\t
\n\t\t${2}\n\t
\nsnippet hgroup\n\t
\n\t\t${1}\n\t
\nsnippet hgroup.\n\t
\n\t${1}\n\t\nsnippet html5\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t${1:`substitute(Filename(\'\', \'Page Title\'), \'^.\', \'\\u&\', \'\')`}\n\t\t\t${2:meta}\n\t\t\n\t\t\n\t\t\t${3:body}\n\t\t\n\t\nsnippet xhtml5\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t${1:`substitute(Filename(\'\', \'Page Title\'), \'^.\', \'\\u&\', \'\')`}\n\t\t\t${2:meta}\n\t\t\n\t\t\n\t\t\t${3:body}\n\t\t\n\t\nsnippet i\n\t${1}\nsnippet iframe\n\t${2}\nsnippet iframe.\n\t${3}\nsnippet iframe#\n\t${3}\nsnippet img\n\t${2}${3}\nsnippet img.\n\t${3}${4}\nsnippet img#\n\t${3}${4}\nsnippet input\n\t${5}\nsnippet input.\n\t${6}\nsnippet input:text\n\t${4}\nsnippet input:submit\n\t${4}\nsnippet input:hidden\n\t${4}\nsnippet input:button\n\t${4}\nsnippet input:image\n\t${5}\nsnippet input:checkbox\n\t${3}\nsnippet input:radio\n\t${3}\nsnippet input:color\n\t${4}\nsnippet input:date\n\t${4}\nsnippet input:datetime\n\t${4}\nsnippet input:datetime-local\n\t${4}\nsnippet input:email\n\t${4}\nsnippet input:file\n\t${4}\nsnippet input:month\n\t${4}\nsnippet input:number\n\t${4}\nsnippet input:password\n\t${4}\nsnippet input:range\n\t${4}\nsnippet input:reset\n\t${4}\nsnippet input:search\n\t${4}\nsnippet input:time\n\t${4}\nsnippet input:url\n\t${4}\nsnippet input:week\n\t${4}\nsnippet ins\n\t${1}\nsnippet kbd\n\t${1}\nsnippet keygen\n\t${1}\nsnippet label\n\t\nsnippet label:i\n\t\n\t${7}\nsnippet label:s\n\t\n\t\nsnippet legend\n\t${1}\nsnippet legend+\n\t${1}\nsnippet li\n\t
  • ${1}
  • \nsnippet li.\n\t
  • ${2}
  • \nsnippet li+\n\t
  • ${1}
  • \n\tli+${2}\nsnippet lia\n\t
  • ${1}
  • \nsnippet lia+\n\t
  • ${1}
  • \n\tlia+${3}\nsnippet link\n\t${5}\nsnippet link:atom\n\t${2}\nsnippet link:css\n\t${4}\nsnippet link:favicon\n\t${2}\nsnippet link:rss\n\t${2}\nsnippet link:touch\n\t${2}\nsnippet map\n\t\n\t\t${2}\n\t\nsnippet map.\n\t\n\t\t${3}\n\t\nsnippet map#\n\t\n\t\t${5}${6}\n\t${7}\nsnippet mark\n\t${1}\nsnippet menu\n\t\n\t\t${1}\n\t\nsnippet menu:c\n\t\n\t\t${1}\n\t\nsnippet menu:t\n\t\n\t\t${1}\n\t\nsnippet meta\n\t${3}\nsnippet meta:compat\n\t${3}\nsnippet meta:refresh\n\t${3}\nsnippet meta:utf\n\t${3}\nsnippet meter\n\t${1}\nsnippet nav\n\t\nsnippet nav.\n\t\nsnippet nav#\n\t\nsnippet noscript\n\t\nsnippet object\n\t\n\t\t${3}\n\t${4}\n# Embed QT Movie\nsnippet movie\n\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t${6}\nsnippet ol\n\t
      \n\t\t${1}\n\t
    \nsnippet ol.\n\t
      \n\t\t${2}\n\t
    \nsnippet ol+\n\t
      \n\t\t
    1. ${1}
    2. \n\t\tli+${2}\n\t
    \nsnippet opt\n\t\nsnippet opt+\n\t\n\topt+${3}\nsnippet optt\n\t\nsnippet optgroup\n\t\n\t\t\n\t\topt+${3}\n\t\nsnippet output\n\t${1}\nsnippet p\n\t

    ${1}

    \nsnippet param\n\t${3}\nsnippet pre\n\t
    \n\t\t${1}\n\t
    \nsnippet progress\n\t${1}\nsnippet q\n\t${1}\nsnippet rp\n\t${1}\nsnippet rt\n\t${1}\nsnippet ruby\n\t\n\t\t${1}\n\t\nsnippet s\n\t${1}\nsnippet samp\n\t\n\t\t${1}\n\t\nsnippet script\n\t + + + + +
    +
    +

    Icon
    + Ray Optics Simulation

    + A free, open-source web app for creating and simulating 2D geometric optical scenes.
    +
    +
    +

    This project, including the gallery contents, is licensed under the Apache License 2.0, and is officially hosted on the PhyDemo (phydemo.app) website (formerly on ricktu288.github.io). The source code is available on GitHub, and you are welcome to contribute. If you have questions or suggestions, you can open issues or discussions on GitHub, or email us at ray-optics@phydemo.app if you do not use GitHub.

    + +

    + Cite this project +

    +

    Main Author

    +
      +
    • Yi-Ting Tu (code, UI design, gallery, module, zh-TW & zh-CN translations)
    • +
    +

    Contributors

    +
      +
    • Stas Fainer (code, gallery, module)
    • +
    • Wei-Fang Sun (code, UI design)
    • +
    • Paul Falstad (code, gallery)
    • +
    • James Garrard (code, gallery)
    • +
    • digitalgreenery (code)
    • +
    • Scott Cheng (code)
    • +
    • Lo-Chen Cheng (de translation)
    • +
    • Michael Heise (de translation)
    • +
    • sadajun916 (ja translation)
    • +
    • GLmontanari (code)
    • +
    • Adrian Dorrington (code)
    • +
    • Tharusha Theekshana (si translation)
    • +
    • Pedroobraga (pt-BR translation)
    • +
    • cyamahat (code)
    • +
    • kqakqakqa (code, zh-CN translation)
    • +
    • Miguel Sánchez Palomino (es translation)
    • +
    • SukkaW (code)
    • +
    • Martin Poitras (code)
    • +
    • BoopSnoot (ru translation)
    • +
    • mahjsa (nl translation)
    • +
    • Wen Zhou (gallery)
    • +
    • Cutivel Dimitri (fr translation)
    • +
    • Vincent Fan (code, UI design, gallery)
    • +
    • Victory Science (gallery)
    • +
    • Matteo Ricci Cipolloni (gallery)
    • +
    • Mikhail Kochiev (gallery)
    • +
    • Fundacja Nauka i Wiedza (pl translation)
    • +
    • Steve Stonebraker (gallery)
    • +
    • krzysztofkrzeslak (UI design)
    • +
    • Young-Gi Kim (ko translation)
    • +
    • chuangyu J (gallery)
    • +
    • Georg Nadorff (gallery)
    • +
    • Rene (gallery)
    • +
    • josephernest (module)
    • +
    • Alex (gallery)
    • +
    • Liu Quanhong (gallery)
    • +
    • Peter Becher (gallery)
    • +
    • Mario Petitclerc (gallery)
    • +
    + (GitHub contributors first; others sorted chronologically.) + +
    +
    + + +
    +
    + + + \ No newline at end of file diff --git a/af1635b600efd13f6059eb6ac9deae12.js b/af1635b600efd13f6059eb6ac9deae12.js new file mode 100644 index 00000000..2e747f90 --- /dev/null +++ b/af1635b600efd13f6059eb6ac9deae12.js @@ -0,0 +1 @@ +!function(e){if(!(void 0!==e.window&&e.document||e.require&&e.define)){e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,o){postMessage({type:"error",data:{message:e,data:o&&o.data,file:t,line:n,col:r,stack:o&&o.stack}})},e.normalizeModule=function(t,n){if(-1!==n.indexOf("!")){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if("."==n.charAt(0)){var o=t.split("/").slice(0,-1).join("/");for(n=(o?o+"/":"")+n;-1!==n.indexOf(".")&&i!=n;){var i=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(t,n){if(n||(n=t,t=null),!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;if(!e.require.tlns)return console.log("unable to load "+n);var o=function(e,t){for(var n=e,r="";n;){var o=t[n];if("string"==typeof o)return o+r;if(o)return o.location.replace(/\/*$/,"/")+(r||o.main||o.name);if(!1===o)return"";var i=n.lastIndexOf("/");if(-1===i)break;r=n.substr(i)+r,n=n.slice(0,i)}return e}(n,e.require.tlns);return".js"!=o.slice(-3)&&(o+=".js"),e.require.id=n,e.require.modules[n]={},importScripts(o),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){if(2==arguments.length?(r=n,"string"!=typeof t&&(n=t,t=e.require.id)):1==arguments.length&&(r=t,n=[],t=e.require.id),"function"==typeof r){n.length||(n=["require","exports","module"]);var o=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.slice(0,r.length).map((function(t){switch(t){case"require":return o;case"exports":return e.exports;case"module":return e;default:return o(t)}})));return t&&(e.exports=t),e}}}else e.require.modules[t]={exports:r,initialized:!0}},e.define.amd={},e.require.tlns={},e.initBaseUrls=function(e){for(var t in e)this.require.tlns[t]=e[t]},e.initSender=function(){var t=e.require("ace/lib/event_emitter").EventEmitter,n=e.require("ace/lib/oop"),r=function(){};return function(){n.implement(this,t),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(r.prototype),new r};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var o=r.data;if(o.event&&n)n._signal(o.event,o.data);else if(o.command)if(t[o.command])t[o.command].apply(t,o.args);else{if(!e[o.command])throw new Error("Unknown command:"+o.command);e[o.command].apply(e,o.args)}else if(o.init){e.initBaseUrls(o.tlns),n=e.sender=e.initSender();var i=this.require(o.module)[o.classname];t=e.main=new i(n)}}}}(this),ace.define("ace/lib/oop",[],(function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}})),ace.define("ace/apply_delta",[],(function(e,t,n){"use strict";t.applyDelta=function(e,t,n){var r=t.start.row,o=t.start.column,i=e[r]||"";switch(t.action){case"insert":if(1===t.lines.length)e[r]=i.substring(0,o)+t.lines[0]+i.substring(o);else{var a=[r,1].concat(t.lines);e.splice.apply(e,a),e[r]=i.substring(0,o)+e[r],e[r+t.lines.length-1]+=i.substring(o)}break;case"remove":var s=t.end.column,c=t.end.row;r===c?e[r]=i.substring(0,o)+i.substring(s):e.splice(r,c-r+1,i.substring(0,o)+e[c].substring(s))}}})),ace.define("ace/lib/event_emitter",[],(function(e,t,n){"use strict";var r={},o=function(){this.propagationStopped=!0},i=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(n.length||r){"object"==typeof t&&t||(t={}),t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=o),t.preventDefault||(t.preventDefault=i),n=n.slice();for(var a=0;a ["+this.end.row+"/"+this.end.column+"]"},e.prototype.contains=function(e,t){return 0==this.compare(e,t)},e.prototype.compareRange=function(e){var t,n=e.end,r=e.start;return 1==(t=this.compare(n.row,n.column))?1==(t=this.compare(r.row,r.column))?2:0==t?1:0:-1==t?-2:-1==(t=this.compare(r.row,r.column))?-1:1==t?42:0},e.prototype.comparePoint=function(e){return this.compare(e.row,e.column)},e.prototype.containsRange=function(e){return 0==this.comparePoint(e.start)&&0==this.comparePoint(e.end)},e.prototype.intersects=function(e){var t=this.compareRange(e);return-1==t||0==t||1==t},e.prototype.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},e.prototype.isStart=function(e,t){return this.start.row==e&&this.start.column==t},e.prototype.setStart=function(e,t){"object"==typeof e?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},e.prototype.setEnd=function(e,t){"object"==typeof e?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},e.prototype.inside=function(e,t){return 0==this.compare(e,t)&&!this.isEnd(e,t)&&!this.isStart(e,t)},e.prototype.insideStart=function(e,t){return 0==this.compare(e,t)&&!this.isEnd(e,t)},e.prototype.insideEnd=function(e,t){return 0==this.compare(e,t)&&!this.isStart(e,t)},e.prototype.compare=function(e,t){return this.isMultiLine()||e!==this.start.row?ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0:tthis.end.column?1:0},e.prototype.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},e.prototype.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},e.prototype.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},e.prototype.clipRows=function(t,n){if(this.end.row>n)var r={row:n+1,column:0};else this.end.rown)var o={row:n+1,column:0};else this.start.rowthis.row)){var t=function(e,t,n){var r="insert"==e.action,o=(r?1:-1)*(e.end.row-e.start.row),i=(r?1:-1)*(e.end.column-e.start.column),s=e.start,c=r?s:e.end;return a(t,s,n)?{row:t.row,column:t.column}:a(c,t,!n)?{row:t.row+o,column:t.column+(t.row==c.row?i:0)}:{row:s.row,column:s.column}}(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(t.row,t.column,!0)}},e.prototype.setPosition=function(e,t,n){var r;if(r=n?{row:e,column:t}:this.$clipPositionToDocument(e,t),this.row!=r.row||this.column!=r.column){var o={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:o,value:r})}},e.prototype.detach=function(){this.document.off("change",this.$onChange)},e.prototype.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},e.prototype.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n},e}();function a(e,t,n){var r=n?e.column<=t.column:e.column=n&&(e=n-1,t=void 0);var r=this.getLine(e);return null==t&&(t=r.length),{row:e,column:t=Math.min(Math.max(t,0),r.length)}},e.prototype.clonePos=function(e){return{row:e.row,column:e.column}},e.prototype.pos=function(e,t){return{row:e,column:t}},e.prototype.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},e.prototype.insertFullLines=function(e,t){var n=0;(e=Math.min(Math.max(e,0),this.getLength()))0,r=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},e.prototype.replace=function(e,t){return e instanceof a||(e=a.fromPoints(e.start,e.end)),0===t.length&&e.isEmpty()?e.start:t==this.getTextRange(e)?e.end:(this.remove(e),t?this.insert(e.start,t):e.start)},e.prototype.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},e.prototype.applyDelta=function(e,t){var n="insert"==e.action;(n?e.lines.length<=1&&!e.lines[0]:!a.comparePoints(e.start,e.end))||(n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(o(this.$lines,e,t),this._signal("change",e)))},e.prototype.$safeApplyDelta=function(e){var t=this.$lines.length;("remove"==e.action&&e.start.row0;)1&t&&(n+=e),(t>>=1)&&(e+=e);return n};var r=/^\s\s*/,o=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(o,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){for(var t=[],n=0,r=e.length;n65535?2:1}})),ace.define("ace/worker/mirror",[],(function(e,t,n){"use strict";var r=e("../document").Document,o=e("../lib/lang"),i=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=o.delayedCall(this.onUpdate.bind(this)),i=this;e.on("change",(function(e){var r=e.data;if(r[0].start)t.applyDeltas(r);else for(var o=0;o=t.$lines.length)throw(s=new Error("Invalid delta")).data={path:i.$path,linesLength:t.$lines.length,start:a.start,end:a.end},s;t.applyDelta(a,!0)}if(i.$timeout)return n.schedule(i.$timeout);i.onUpdate()}))};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(i.prototype)})),ace.define("ace/mode/lua/luaparse",[],(function(e,t,n){!function(e){"use strict";var t,n,r,o,i;e.version="0.3.1";var a=e.defaultOptions={wait:!1,comments:!0,scope:!1,locations:!1,ranges:!1,onCreateNode:null,onCreateScope:null,onDestroyScope:null,onLocalDeclaration:null,luaVersion:"5.3",encodingMode:"none"};function s(e,t){return t=t||0,e<128?String.fromCharCode(e):e<2048?String.fromCharCode(192|t|e>>6,128|t|63&e):e<65536?String.fromCharCode(224|t|e>>12,128|t|e>>6&63,128|t|63&e):e<1114112?String.fromCharCode(240|t|e>>18,128|t|e>>12&63,128|t|e>>6&63,128|t|63&e):null}function c(e){return function(t){var n=e.exec(t);if(!n)return t;U(null,w.invalidCodeUnit,function(e,t){for(var n=e.toString(16);n.length=128?String.fromCharCode(63232|e):String.fromCharCode(e)},encodeUTF8:function(e){return s(e,63232)}},none:{discardStrings:!0,fixup:function(e){return e},encodeByte:function(e){return""},encodeUTF8:function(e){return""}}},l=1,p=2,h=4,f=8,d=16,m=32,g=64,v=128,y=256;e.tokenTypes={EOF:l,StringLiteral:p,Keyword:h,Identifier:f,NumericLiteral:d,Punctuator:m,BooleanLiteral:g,NilLiteral:v,VarargLiteral:y};var w=e.errors={unexpected:"unexpected %1 '%2' near '%3'",unexpectedEOF:"unexpected symbol near ''",expected:"'%1' expected near '%2'",expectedToken:"%1 expected near '%2'",unfinishedString:"unfinished string near '%1'",malformedNumber:"malformed number near '%1'",decimalEscapeTooLarge:"decimal escape too large near '%1'",invalidEscape:"invalid escape sequence near '%1'",hexadecimalDigitExpected:"hexadecimal digit expected near '%1'",braceExpected:"missing '%1' near '%2'",tooLargeCodepoint:"UTF-8 value too large near '%1'",unfinishedLongString:"unfinished long string (starting at line %1) near '%2'",unfinishedLongComment:"unfinished long comment (starting at line %1) near '%2'",ambiguousSyntax:"ambiguous syntax (function call x new statement) near '%1'",noLoopToBreak:"no loop to break near '%1'",labelAlreadyDefined:"label '%1' already defined on line %2",labelNotVisible:"no visible label '%1' for ",gotoJumpInLocalScope:" jumps into the scope of local '%2'",cannotUseVararg:"cannot use '...' outside a vararg function near '%1'",invalidCodeUnit:"code unit U+%1 is not allowed in the current encoding mode"},b=e.ast={labelStatement:function(e){return{type:"LabelStatement",label:e}},breakStatement:function(){return{type:"BreakStatement"}},gotoStatement:function(e){return{type:"GotoStatement",label:e}},returnStatement:function(e){return{type:"ReturnStatement",arguments:e}},ifStatement:function(e){return{type:"IfStatement",clauses:e}},ifClause:function(e,t){return{type:"IfClause",condition:e,body:t}},elseifClause:function(e,t){return{type:"ElseifClause",condition:e,body:t}},elseClause:function(e){return{type:"ElseClause",body:e}},whileStatement:function(e,t){return{type:"WhileStatement",condition:e,body:t}},doStatement:function(e){return{type:"DoStatement",body:e}},repeatStatement:function(e,t){return{type:"RepeatStatement",condition:e,body:t}},localStatement:function(e,t){return{type:"LocalStatement",variables:e,init:t}},assignmentStatement:function(e,t){return{type:"AssignmentStatement",variables:e,init:t}},callStatement:function(e){return{type:"CallStatement",expression:e}},functionStatement:function(e,t,n,r){return{type:"FunctionDeclaration",identifier:e,isLocal:n,parameters:t,body:r}},forNumericStatement:function(e,t,n,r,o){return{type:"ForNumericStatement",variable:e,start:t,end:n,step:r,body:o}},forGenericStatement:function(e,t,n){return{type:"ForGenericStatement",variables:e,iterators:t,body:n}},chunk:function(e){return{type:"Chunk",body:e}},identifier:function(e){return{type:"Identifier",name:e}},literal:function(e,t,n){return{type:e=e===p?"StringLiteral":e===d?"NumericLiteral":e===g?"BooleanLiteral":e===v?"NilLiteral":"VarargLiteral",value:t,raw:n}},tableKey:function(e,t){return{type:"TableKey",key:e,value:t}},tableKeyString:function(e,t){return{type:"TableKeyString",key:e,value:t}},tableValue:function(e){return{type:"TableValue",value:e}},tableConstructorExpression:function(e){return{type:"TableConstructorExpression",fields:e}},binaryExpression:function(e,t,n){return{type:"and"===e||"or"===e?"LogicalExpression":"BinaryExpression",operator:e,left:t,right:n}},unaryExpression:function(e,t){return{type:"UnaryExpression",operator:e,argument:t}},memberExpression:function(e,t,n){return{type:"MemberExpression",indexer:t,identifier:n,base:e}},indexExpression:function(e,t){return{type:"IndexExpression",base:e,index:t}},callExpression:function(e,t){return{type:"CallExpression",base:e,arguments:t}},tableCallExpression:function(e,t){return{type:"TableCallExpression",base:e,arguments:t}},stringCallExpression:function(e,t){return{type:"StringCallExpression",base:e,argument:t}},comment:function(e,t){return{type:"Comment",value:e,raw:t}}};function x(e){if(le){var t=pe.pop();t.complete(),t.bless(e)}return n.onCreateNode&&n.onCreateNode(e),e}var L=Array.prototype.slice,S=(Object.prototype.toString,function(e,t){for(var n=0,r=e.length;n=r)return{type:l,value:"",line:O,lineStart:_,range:[E,E]};var e,n,a,s=t.charCodeAt(E),c=t.charCodeAt(E+1);if(P=E,function(e){return e>=65&&e<=90||e>=97&&e<=122||95===e||!!(o.extendedIdentifiers&&e>=128)}(s))return function(){for(var e,n;ne(t.charCodeAt(++E)););return function(e){switch(e.length){case 2:return"do"===e||"if"===e||"in"===e||"or"===e;case 3:return"and"===e||"end"===e||"for"===e||"not"===e;case 4:return"else"===e||"then"===e||!(!o.labels||o.contextualGoto)&&"goto"===e;case 5:return"break"===e||"local"===e||"until"===e||"while"===e;case 6:return"elseif"===e||"repeat"===e||"return"===e;case 8:return"function"===e}return!1}(e=i.fixup(t.slice(P,E)))?n=h:"true"===e||"false"===e?(n=g,e="true"===e):"nil"===e?(n=v,e=null):n=f,{type:n,value:e,line:O,lineStart:_,range:[P,E]}}();switch(s){case 39:case 34:return function(){for(var e,n=t.charCodeAt(E++),o=O,a=_,s=E,c=i.discardStrings?null:"";n!==(e=t.charCodeAt(E++));)if((E>r||Z(e))&&(c+=t.slice(s,E-1),U(null,w.unfinishedString,t.slice(P,E-1))),92===e){if(!i.discardStrings){var u=t.slice(s,E-1);c+=i.fixup(u)}var l=K();i.discardStrings||(c+=l),s=E}return i.discardStrings||(c+=i.encodeByte(null),c+=i.fixup(t.slice(s,E-1))),{type:p,value:c,line:o,lineStart:a,lastLine:O,lastLineStart:_,range:[P,E]}}();case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return z();case 46:return ee(c)?z():46===c?46===t.charCodeAt(E+2)?{type:y,value:"...",line:O,lineStart:_,range:[P,E+=3]}:H(".."):H(".");case 61:return H(61===c?"==":"=");case 62:return o.bitwiseOperators&&62===c?H(">>"):H(61===c?">=":">");case 60:return o.bitwiseOperators&&60===c?H("<<"):H(61===c?"<=":"<");case 126:if(61===c)return H("~=");if(!o.bitwiseOperators)break;return H("~");case 58:return o.labels&&58===c?H("::"):H(":");case 91:return 91===c||61===c?(e=O,n=_,!1===(a=J(!1))&&U(A,w.expected,"[",I(A)),{type:p,value:i.discardStrings?null:i.fixup(a),line:e,lineStart:n,lastLine:O,lastLineStart:_,range:[P,E]}):H("[");case 47:return o.integerDivision&&47===c?H("//"):H("/");case 38:case 124:if(!o.bitwiseOperators)break;case 42:case 94:case 37:case 44:case 123:case 125:case 93:case 40:case 41:case 59:case 35:case 45:case 43:return H(t.charAt(E))}return q(t.charAt(E))}function G(){var e=t.charCodeAt(E),n=t.charCodeAt(E+1);return!!Z(e)&&(10===e&&13===n&&++E,13===e&&10===n&&++E,++O,_=++E,!0)}function B(){for(;E=0?function(){var e,n,r,o,i=0,a=1,s=1;for(o=E+=2,te(t.charCodeAt(E))||U(null,w.malformedNumber,t.slice(P,E));te(t.charCodeAt(E));)++E;e=parseInt(t.slice(o,E),16);var c=!1;if("."===t.charAt(E)){for(c=!0,n=++E;te(t.charCodeAt(E));)++E;i=t.slice(n,E),i=n===E?0:parseInt(i,16)/Math.pow(16,E-n)}var u=!1;if("pP".indexOf(t.charAt(E)||null)>=0){for(u=!0,++E,"+-".indexOf(t.charAt(E)||null)>=0&&(s="+"===t.charAt(E++)?1:-1),r=E,ee(t.charCodeAt(E))||U(null,w.malformedNumber,t.slice(P,E));ee(t.charCodeAt(E));)++E;a=t.slice(r,E),a=Math.pow(2,a*s)}return{value:(e+i)*a,hasFractionPart:c||u}}():function(){for(;ee(t.charCodeAt(E));)++E;var e=!1;if("."===t.charAt(E))for(e=!0,++E;ee(t.charCodeAt(E));)++E;var n=!1;if("eE".indexOf(t.charAt(E)||null)>=0)for(n=!0,++E,"+-".indexOf(t.charAt(E)||null)>=0&&++E,ee(t.charCodeAt(E))||U(null,w.malformedNumber,t.slice(P,E));ee(t.charCodeAt(E));)++E;return{value:parseFloat(t.slice(P,E)),hasFractionPart:e||n}}(),i=function(){if(o.imaginaryNumbers)return"iI".indexOf(t.charAt(E)||null)>=0&&(++E,!0)}();return function(){if(o.integerSuffixes)if("uU".indexOf(t.charAt(E)||null)>=0)if(++E,"lL".indexOf(t.charAt(E)||null)>=0){if(++E,"lL".indexOf(t.charAt(E)||null)>=0)return++E,"ULL";U(null,w.malformedNumber,t.slice(P,E))}else U(null,w.malformedNumber,t.slice(P,E));else if("lL".indexOf(t.charAt(E)||null)>=0){if(++E,"lL".indexOf(t.charAt(E)||null)>=0)return++E,"LL";U(null,w.malformedNumber,t.slice(P,E))}}()&&(i||r.hasFractionPart)&&U(null,w.malformedNumber,t.slice(P,E)),{type:d,value:r.value,line:O,lineStart:_,range:[P,E]}}function K(){var e=E;switch(t.charAt(E)){case"a":return++E,"";case"n":return++E,"\n";case"r":return++E,"\r";case"t":return++E,"\t";case"v":return++E,"\v";case"b":return++E,"\b";case"f":return++E,"\f";case"\r":case"\n":return G(),"\n";case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":for(;ee(t.charCodeAt(E))&&E-e<3;)++E;var n=t.slice(e,E),r=parseInt(n,10);return r>255&&U(null,w.decimalEscapeTooLarge,"\\"+r),i.encodeByte(r,"\\"+n);case"z":if(o.skipWhitespaceEscape)return++E,B(),"";break;case"x":if(o.hexEscapes){if(te(t.charCodeAt(E+1))&&te(t.charCodeAt(E+2)))return E+=3,i.encodeByte(parseInt(t.slice(e+1,E),16),"\\"+t.slice(e,E));U(null,w.hexadecimalDigitExpected,"\\"+t.slice(e,E+2))}break;case"u":if(o.unicodeEscapes)return function(){var e=E++;for("{"!==t.charAt(E++)&&U(null,w.braceExpected,"{","\\"+t.slice(e,E)),te(t.charCodeAt(E))||U(null,w.hexadecimalDigitExpected,"\\"+t.slice(e,E));48===t.charCodeAt(E);)++E;for(var n=E;te(t.charCodeAt(E));)++E-n>6&&U(null,w.tooLargeCodepoint,"\\"+t.slice(e,E));var r=t.charAt(E++);"}"!==r&&('"'===r||"'"===r?U(null,w.braceExpected,"}","\\"+t.slice(e,E--)):U(null,w.hexadecimalDigitExpected,"\\"+t.slice(e,E)));var o=parseInt(t.slice(n,E-1)||"0",16),a="\\"+t.slice(e,E);return o>1114111&&U(null,w.tooLargeCodepoint,a),i.encodeUTF8(o,a)}();break;case"\\":case'"':case"'":return t.charAt(E++)}return o.strictEscapes&&U(null,w.invalidEscape,"\\"+t.slice(e,E+1)),t.charAt(E++)}function W(){P=E,E+=2;var e=t.charAt(E),o="",i=!1,a=E,s=_,c=O;if("["===e&&(!1===(o=J(!0))?o=e:i=!0),!i){for(;E")}function X(){k=A,A=D,D=V()}function Q(e){return e===A.value&&(X(),!0)}function Y(e){e===A.value?X():U(A,w.expected,e,I(A))}function Z(e){return 10===e||13===e}function ee(e){return e>=48&&e<=57}function te(e){return e>=48&&e<=57||e>=97&&e<=102||e>=65&&e<=70}function ne(e){return e>=65&&e<=90||e>=97&&e<=122||95===e||e>=48&&e<=57||!!(o.extendedIdentifiers&&e>=128)}function re(e){if(l===e.type)return!0;if(h!==e.type)return!1;switch(e.value){case"else":case"elseif":case"end":case"until":return!0;default:return!1}}function oe(){var e=$[N++].slice();$.push(e),n.onCreateScope&&n.onCreateScope()}function ie(){$.pop(),--N,n.onDestroyScope&&n.onDestroyScope()}function ae(e){n.onLocalDeclaration&&n.onLocalDeclaration(e),-1===S($[N],e)&&$[N].push(e)}function se(e){ae(e.name),ce(e,!0)}function ce(e,t){t||-1!==function(e,t,n){for(var r=0,o=e.length;r",A)}(e);case"if":return X(),function(e){var t,r,o,i=[];for(le&&(o=pe[pe.length-1],pe.push(o)),t=Ae(e),Y("then"),n.scope&&oe(),e.pushScope(),r=we(e),e.popScope(),n.scope&&ie(),i.push(x(b.ifClause(t,r))),le&&(o=he());Q("elseif");)me(o),t=Ae(e),Y("then"),n.scope&&oe(),e.pushScope(),r=we(e),e.popScope(),n.scope&&ie(),i.push(x(b.elseifClause(t,r))),le&&(o=he());return Q("else")&&(le&&(o=new fe(k),pe.push(o)),n.scope&&oe(),e.pushScope(),r=we(e),e.popScope(),n.scope&&ie(),i.push(x(b.elseClause(r)))),Y("end"),x(b.ifStatement(i))}(e);case"return":return X(),function(e){var t=[];if("end"!==A.value){var n=Ee(e);for(null!=n&&t.push(n);Q(",");)n=Ae(e),t.push(n);Q(";")}return x(b.returnStatement(t))}(e);case"function":return X(),Se(function(){var e,t,r;for(le&&(r=he()),e=Le(),n.scope&&(ce(e,ue(e.name)),oe());Q(".");)me(r),t=Le(),e=x(b.memberExpression(e,".",t));return Q(":")&&(me(r),t=Le(),e=x(b.memberExpression(e,":",t)),n.scope&&ae("self")),e}());case"while":return X(),function(e){var t=Ae(e);Y("do"),n.scope&&oe(),e.pushScope(!0);var r=we(e);return e.popScope(),n.scope&&ie(),Y("end"),x(b.whileStatement(t,r))}(e);case"for":return X(),function(e){var t,r=Le();if(n.scope&&(oe(),se(r)),Q("=")){var o=Ae(e);Y(",");var i=Ae(e),a=Q(",")?Ae(e):null;return Y("do"),e.pushScope(!0),t=we(e),e.popScope(),Y("end"),n.scope&&ie(),x(b.forNumericStatement(r,o,i,a,t))}for(var s=[r];Q(",");)r=Le(),n.scope&&se(r),s.push(r);Y("in");var c=[];do{var u=Ae(e);c.push(u)}while(Q(","));return Y("do"),e.pushScope(!0),t=we(e),e.popScope(),Y("end"),n.scope&&ie(),x(b.forGenericStatement(s,c,t))}(e);case"repeat":return X(),function(e){n.scope&&oe(),e.pushScope(!0);var t=we(e);Y("until"),e.raiseDeferredErrors();var r=Ae(e);return e.popScope(),n.scope&&ie(),x(b.repeatStatement(r,t))}(e);case"break":return X(),e.isInLoop()||U(A,w.noLoopToBreak,A.value),x(b.breakStatement());case"do":return X(),function(e){n.scope&&oe(),e.pushScope();var t=we(e);return e.popScope(),n.scope&&ie(),Y("end"),x(b.doStatement(t))}(e);case"goto":return X(),xe(e)}return o.contextualGoto&&A.type===f&&"goto"===A.value&&D.type===f&&"goto"!==D.value?(X(),xe(e)):(le&&pe.pop(),function(e){var t,r,o,i,a,s=[];for(le&&(r=he());;){if(le&&(t=he()),f===A.type)a=A.value,i=Le(),n.scope&&ce(i,ue(a)),o=!0;else{if("("!==A.value)return q(A);X(),i=Ae(e),Y(")"),o=!1}e:for(;;){switch(p===A.type?'"':A.value){case".":case"[":o=!0;break;case":":case"(":case"{":case'"':o=null;break;default:break e}i=Me(i,t,e)}if(s.push(i),","!==A.value)break;if(!o)return q(A);X()}if(1===s.length&&null===o)return me(t),x(b.callStatement(s[0]));if(!o)return q(A);Y("=");var c=[];do{c.push(Ae(e))}while(Q(","));return me(r),x(b.assignmentStatement(s,c))}(e))}le&&pe.pop()}function xe(e){var t=A.value,n=k,r=Le();return e.addGoto(t,n),x(b.gotoStatement(r))}function Le(){de();var e=A.value;return f!==A.type&&F("",A),X(),x(b.identifier(e))}function Se(e,t){var r=ye();r.pushScope();var o=[];if(Y("("),!Q(")"))for(;;){if(f===A.type){var i=Le();if(n.scope&&se(i),o.push(i),Q(","))continue}else y===A.type?(r.allowVararg=!0,o.push(Oe(r))):F(" or '...'",A);Y(")");break}var a=we(r);return r.popScope(),Y("end"),n.scope&&ie(),t=t||!1,x(b.functionStatement(e,o,t,a))}function Ce(e){for(var t,n,r=[];;){if(de(),m===A.type&&Q("["))t=Ae(e),Y("]"),Y("="),n=Ae(e),r.push(x(b.tableKey(t,n)));else if(f===A.type)"="===D.value?(t=Le(),X(),n=Ae(e),r.push(x(b.tableKeyString(t,n)))):(n=Ae(e),r.push(x(b.tableValue(n))));else{if(null==(n=Ee(e))){pe.pop();break}r.push(x(b.tableValue(n)))}if(!(",;".indexOf(A.value)>=0))break;X()}return Y("}"),x(b.tableConstructorExpression(r))}function Ee(e){return De(0,e)}function Ae(e){var t=Ee(e);if(null!=t)return t;F("",A)}function ke(e){var t=e.charCodeAt(0),n=e.length;if(1===n)switch(t){case 94:return 12;case 42:case 47:case 37:return 10;case 43:case 45:return 9;case 38:return 6;case 126:return 5;case 124:return 4;case 60:case 62:return 3}else if(2===n)switch(t){case 47:return 10;case 46:return 8;case 60:case 62:return"<<"===e||">>"===e?7:3;case 61:case 126:return 3;case 111:return 1}else if(97===t&&"and"===e)return 2;return 0}function De(e,t){var r,o,i,a=A.value;if(le&&(o=he()),function(e){return m===e.type?"#-~".indexOf(e.value)>=0:h===e.type&&"not"===e.value}(A)){de(),X();var s=De(10,t);null==s&&F("",A),r=x(b.unaryExpression(a,s))}if(null==r&&null==(r=Oe(t))&&(r=function(e){var t,r,o;if(le&&(o=he()),f===A.type)r=A.value,t=Le(),n.scope&&ce(t,ue(r));else{if(!Q("("))return null;t=Ae(e),Y(")")}for(;;){var i=Me(t,o,e);if(null===i)break;t=i}return t}(t)),null==r)return null;for(;a=A.value,!(0===(i=m===A.type||h===A.type?ke(a):0)||i<=e);){"^"!==a&&".."!==a||--i,X();var c=De(i,t);null==c&&F("",A),le&&pe.push(o),r=x(b.binaryExpression(a,r,c))}return r}function Me(e,t,n){var r,o;if(m===A.type)switch(A.value){case"[":return me(t),X(),r=Ae(n),Y("]"),x(b.indexExpression(e,r));case".":return me(t),X(),o=Le(),x(b.memberExpression(e,".",o));case":":return me(t),X(),o=Le(),e=x(b.memberExpression(e,":",o)),me(t),Pe(e,n);case"(":case"{":return me(t),Pe(e,n)}else if(p===A.type)return me(t),Pe(e,n);return null}function Pe(e,t){if(m===A.type)switch(A.value){case"(":o.emptyStatement||A.line!==k.line&&U(null,w.ambiguousSyntax,A.value),X();var n=[],r=Ee(t);for(null!=r&&n.push(r);Q(",");)r=Ae(t),n.push(r);return Y(")"),x(b.callExpression(e,n));case"{":de(),X();var i=Ce(t);return x(b.tableCallExpression(e,i))}else if(p===A.type)return x(b.stringCallExpression(e,Oe(t)));F("function arguments",A)}function Oe(e){var r,o=p|d|g|v|y,i=A.value,a=A.type;if(le&&(r=he()),a!==y||e.allowVararg||U(A,w.cannotUseVararg,A.value),a&o){me(r);var s=t.slice(A.range[0],A.range[1]);return X(),x(b.literal(a,i,s))}return h===a&&"function"===i?(me(r),X(),n.scope&&oe(),Se(null)):Q("{")?(me(r),Ce(e)):void 0}fe.prototype.complete=function(){n.locations&&(this.loc.end.line=k.lastLine||k.line,this.loc.end.column=k.range[1]-(k.lastLineStart||k.lineStart)),n.ranges&&(this.range[1]=k.range[1])},fe.prototype.bless=function(e){if(this.loc){var t=this.loc;e.loc={start:{line:t.start.line,column:t.start.column},end:{line:t.end.line,column:t.end.column}}}this.range&&(e.range=[this.range[0],this.range[1]])},ge.prototype.isInLoop=function(){for(var e=this.scopes.length;e-- >0;)if(this.scopes[e].isLoop)return!0;return!1},ge.prototype.pushScope=function(e){var t={labels:{},locals:[],deferredGotos:[],isLoop:!!e};this.scopes.push(t)},ge.prototype.popScope=function(){for(var e=0;e=this.scopes.length&&--t.maxDepth<=0&&U(t.token,w.labelNotVisible,t.target)}this.scopes.pop()},ge.prototype.addGoto=function(e,t){for(var n=[],r=0;r=this.scopes.length&&i.target===e?i.localCounts[this.scopes.length-1]0)throw new Error("Location tracking failed. This is most likely a bug in luaparse");return o}e.write=$e,e.end=Ne}(t)})),ace.define("ace/mode/lua_worker",[],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("../worker/mirror").Mirror,i=e("../mode/lua/luaparse"),a=t.Worker=function(e){o.call(this,e),this.setTimeout(500)};r.inherits(a,o),function(){this.onUpdate=function(){var e=this.doc.getValue(),t=[];try{i.parse(e)}catch(e){e instanceof i.SyntaxError&&t.push({row:e.line-1,column:e.column,text:e.message,type:"error"})}this.sender.emit("annotate",t)}}.call(a.prototype)})); \ No newline at end of file diff --git a/af6fdb556ee3f9065578bb01f81f6216.js b/af6fdb556ee3f9065578bb01f81f6216.js new file mode 100644 index 00000000..3dedface --- /dev/null +++ b/af6fdb556ee3f9065578bb01f81f6216.js @@ -0,0 +1 @@ +!function(e){if(!(void 0!==e.window&&e.document||e.require&&e.define)){e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,r,n,a){postMessage({type:"error",data:{message:e,data:a&&a.data,file:t,line:r,col:n,stack:a&&a.stack}})},e.normalizeModule=function(t,r){if(-1!==r.indexOf("!")){var n=r.split("!");return e.normalizeModule(t,n[0])+"!"+e.normalizeModule(t,n[1])}if("."==r.charAt(0)){var a=t.split("/").slice(0,-1).join("/");for(r=(a?a+"/":"")+r;-1!==r.indexOf(".")&&o!=r;){var o=r;r=r.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return r},e.require=function(t,r){if(r||(r=t,t=null),!r.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");r=e.normalizeModule(t,r);var n=e.require.modules[r];if(n)return n.initialized||(n.initialized=!0,n.exports=n.factory().exports),n.exports;if(!e.require.tlns)return console.log("unable to load "+r);var a=function(e,t){for(var r=e,n="";r;){var a=t[r];if("string"==typeof a)return a+n;if(a)return a.location.replace(/\/*$/,"/")+(n||a.main||a.name);if(!1===a)return"";var o=r.lastIndexOf("/");if(-1===o)break;n=r.substr(o)+n,r=r.slice(0,o)}return e}(r,e.require.tlns);return".js"!=a.slice(-3)&&(a+=".js"),e.require.id=r,e.require.modules[r]={},importScripts(a),e.require(t,r)},e.require.modules={},e.require.tlns={},e.define=function(t,r,n){if(2==arguments.length?(n=r,"string"!=typeof t&&(r=t,t=e.require.id)):1==arguments.length&&(n=t,r=[],t=e.require.id),"function"==typeof n){r.length||(r=["require","exports","module"]);var a=function(r){return e.require(t,r)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=n.apply(this,r.slice(0,n.length).map((function(t){switch(t){case"require":return a;case"exports":return e.exports;case"module":return e;default:return a(t)}})));return t&&(e.exports=t),e}}}else e.require.modules[t]={exports:n,initialized:!0}},e.define.amd={},e.require.tlns={},e.initBaseUrls=function(e){for(var t in e)this.require.tlns[t]=e[t]},e.initSender=function(){var t=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),n=function(){};return function(){r.implement(this,t),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(n.prototype),new n};var t=e.main=null,r=e.sender=null;e.onmessage=function(n){var a=n.data;if(a.event&&r)r._signal(a.event,a.data);else if(a.command)if(t[a.command])t[a.command].apply(t,a.args);else{if(!e[a.command])throw new Error("Unknown command:"+a.command);e[a.command].apply(e,a.args)}else if(a.init){e.initBaseUrls(a.tlns),r=e.sender=e.initSender();var o=this.require(a.module)[a.classname];t=e.main=new o(r)}}}}(this),ace.define("ace/lib/oop",[],(function(e,t,r){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var r in t)e[r]=t[r];return e},t.implement=function(e,r){t.mixin(e,r)}})),ace.define("ace/lib/deep_copy",[],(function(e,t,r){t.deepCopy=function e(t){if("object"!=typeof t||!t)return t;var r;if(Array.isArray(t)){r=[];for(var n=0;n0;)1&t&&(r+=e),(t>>=1)&&(e+=e);return r};var n=/^\s\s*/,a=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(n,"")},t.stringTrimRight=function(e){return e.replace(a,"")},t.copyObject=function(e){var t={};for(var r in e)t[r]=e[r];return t},t.copyArray=function(e){for(var t=[],r=0,n=e.length;r65535?2:1}})),ace.define("ace/apply_delta",[],(function(e,t,r){"use strict";t.applyDelta=function(e,t,r){var n=t.start.row,a=t.start.column,o=e[n]||"";switch(t.action){case"insert":if(1===t.lines.length)e[n]=o.substring(0,a)+t.lines[0]+o.substring(a);else{var i=[n,1].concat(t.lines);e.splice.apply(e,i),e[n]=o.substring(0,a)+e[n],e[n+t.lines.length-1]+=o.substring(a)}break;case"remove":var s=t.end.column,c=t.end.row;n===c?e[n]=o.substring(0,a)+o.substring(s):e.splice(n,c-n+1,o.substring(0,a)+e[c].substring(s))}}})),ace.define("ace/lib/event_emitter",[],(function(e,t,r){"use strict";var n={},a=function(){this.propagationStopped=!0},o=function(){this.defaultPrevented=!0};n._emit=n._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var r=this._eventRegistry[e]||[],n=this._defaultHandlers[e];if(r.length||n){"object"==typeof t&&t||(t={}),t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=a),t.preventDefault||(t.preventDefault=o),r=r.slice();for(var i=0;i ["+this.end.row+"/"+this.end.column+"]"},e.prototype.contains=function(e,t){return 0==this.compare(e,t)},e.prototype.compareRange=function(e){var t,r=e.end,n=e.start;return 1==(t=this.compare(r.row,r.column))?1==(t=this.compare(n.row,n.column))?2:0==t?1:0:-1==t?-2:-1==(t=this.compare(n.row,n.column))?-1:1==t?42:0},e.prototype.comparePoint=function(e){return this.compare(e.row,e.column)},e.prototype.containsRange=function(e){return 0==this.comparePoint(e.start)&&0==this.comparePoint(e.end)},e.prototype.intersects=function(e){var t=this.compareRange(e);return-1==t||0==t||1==t},e.prototype.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},e.prototype.isStart=function(e,t){return this.start.row==e&&this.start.column==t},e.prototype.setStart=function(e,t){"object"==typeof e?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},e.prototype.setEnd=function(e,t){"object"==typeof e?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},e.prototype.inside=function(e,t){return 0==this.compare(e,t)&&!this.isEnd(e,t)&&!this.isStart(e,t)},e.prototype.insideStart=function(e,t){return 0==this.compare(e,t)&&!this.isEnd(e,t)},e.prototype.insideEnd=function(e,t){return 0==this.compare(e,t)&&!this.isStart(e,t)},e.prototype.compare=function(e,t){return this.isMultiLine()||e!==this.start.row?ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0:tthis.end.column?1:0},e.prototype.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},e.prototype.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},e.prototype.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},e.prototype.clipRows=function(t,r){if(this.end.row>r)var n={row:r+1,column:0};else this.end.rowr)var a={row:r+1,column:0};else this.start.rowthis.row)){var t=function(e,t,r){var n="insert"==e.action,a=(n?1:-1)*(e.end.row-e.start.row),o=(n?1:-1)*(e.end.column-e.start.column),s=e.start,c=n?s:e.end;return i(t,s,r)?{row:t.row,column:t.column}:i(c,t,!r)?{row:t.row+a,column:t.column+(t.row==c.row?o:0)}:{row:s.row,column:s.column}}(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(t.row,t.column,!0)}},e.prototype.setPosition=function(e,t,r){var n;if(n=r?{row:e,column:t}:this.$clipPositionToDocument(e,t),this.row!=n.row||this.column!=n.column){var a={row:this.row,column:this.column};this.row=n.row,this.column=n.column,this._signal("change",{old:a,value:n})}},e.prototype.detach=function(){this.document.off("change",this.$onChange)},e.prototype.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},e.prototype.$clipPositionToDocument=function(e,t){var r={};return e>=this.document.getLength()?(r.row=Math.max(0,this.document.getLength()-1),r.column=this.document.getLine(r.row).length):e<0?(r.row=0,r.column=0):(r.row=e,r.column=Math.min(this.document.getLine(r.row).length,Math.max(0,t))),t<0&&(r.column=0),r},e}();function i(e,t,r){var n=r?e.column<=t.column:e.column=r&&(e=r-1,t=void 0);var n=this.getLine(e);return null==t&&(t=n.length),{row:e,column:t=Math.min(Math.max(t,0),n.length)}},e.prototype.clonePos=function(e){return{row:e.row,column:e.column}},e.prototype.pos=function(e,t){return{row:e,column:t}},e.prototype.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},e.prototype.insertFullLines=function(e,t){var r=0;(e=Math.min(Math.max(e,0),this.getLength()))0,n=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},e.prototype.replace=function(e,t){return e instanceof i||(e=i.fromPoints(e.start,e.end)),0===t.length&&e.isEmpty()?e.start:t==this.getTextRange(e)?e.end:(this.remove(e),t?this.insert(e.start,t):e.start)},e.prototype.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},e.prototype.applyDelta=function(e,t){var r="insert"==e.action;(r?e.lines.length<=1&&!e.lines[0]:!i.comparePoints(e.start,e.end))||(r&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(a(this.$lines,e,t),this._signal("change",e)))},e.prototype.$safeApplyDelta=function(e){var t=this.$lines.length;("remove"==e.action&&e.start.row=t.$lines.length)throw(s=new Error("Invalid delta")).data={path:o.$path,linesLength:t.$lines.length,start:i.start,end:i.end},s;t.applyDelta(i,!0)}if(o.$timeout)return r.schedule(o.$timeout);o.onUpdate()}))};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(o.prototype)})),ace.define("ace/mode/html/saxparser",[],(function(e,t,r){r.exports=function t(r,n,a){function o(s,c){if(!n[s]){if(!r[s]){var l="function"==typeof e&&e;if(!c&&l)return l(s,!0);if(i)return i(s,!0);throw new Error("Cannot find module '"+s+"'")}var p=n[s]={exports:{}};r[s][0].call(p.exports,(function(e){return o(r[s][1][e]||e)}),p,p.exports,t,r,n,a)}return n[s].exports}for(var i="function"==typeof e&&e,s=0;s=0;r--){var n=this.elements[r];if(n.localName===e)return!0;if(t(n))return!1}},c.prototype.push=function(e){this.elements.push(e)},c.prototype.pushHtmlElement=function(e){this.rootNode=e.node,this.push(e)},c.prototype.pushHeadElement=function(e){this.headElement=e.node,this.push(e)},c.prototype.pushBodyElement=function(e){this.bodyElement=e.node,this.push(e)},c.prototype.pop=function(){return this.elements.pop()},c.prototype.remove=function(e){this.elements.splice(this.elements.indexOf(e),1)},c.prototype.popUntilPopped=function(e){var t;do{t=this.pop()}while(t.localName!=e)},c.prototype.popUntilTableScopeMarker=function(){for(;!o(this.top);)this.pop()},c.prototype.popUntilTableBodyScopeMarker=function(){for(;!("http://www.w3.org/1999/xhtml"===(e=this.top).namespaceURI&&"tbody"===e.localName||"http://www.w3.org/1999/xhtml"===e.namespaceURI&&"tfoot"===e.localName||"http://www.w3.org/1999/xhtml"===e.namespaceURI&&"thead"===e.localName||"http://www.w3.org/1999/xhtml"===e.namespaceURI&&"html"===e.localName);)this.pop();var e},c.prototype.popUntilTableRowScopeMarker=function(){for(;!("http://www.w3.org/1999/xhtml"===(e=this.top).namespaceURI&&"tr"===e.localName||"http://www.w3.org/1999/xhtml"===e.namespaceURI&&"html"===e.localName);)this.pop();var e},c.prototype.item=function(e){return this.elements[e]},c.prototype.contains=function(e){return-1!==this.elements.indexOf(e)},c.prototype.inScope=function(e){return this._inScope(e,n)},c.prototype.inListItemScope=function(e){return this._inScope(e,a)},c.prototype.inTableScope=function(e){return this._inScope(e,o)},c.prototype.inButtonScope=function(e){return this._inScope(e,i)},c.prototype.inSelectScope=function(e){return this._inScope(e,s)},c.prototype.hasNumberedHeaderElementInScope=function(){for(var e=this.elements.length-1;e>=0;e--){var t=this.elements[e];if(t.isNumberedHeader())return!0;if(n(t))return!1}},c.prototype.furthestBlockForFormattingElement=function(e){for(var t=null,r=this.elements.length-1;r>=0;r--){var n=this.elements[r];if(n.node===e)break;n.isSpecial()&&(t=n)}return t},c.prototype.findIndex=function(e){for(var t=this.elements.length-1;t>=0;t--)if(this.elements[t].localName==e)return t;return-1},c.prototype.remove_openElements_until=function(e){for(var t,r=!1;!r;)r=e(t=this.elements.pop());return t},Object.defineProperty(c.prototype,"top",{get:function(){return this.elements[this.elements.length-1]}}),Object.defineProperty(c.prototype,"length",{get:function(){return this.elements.length}}),r.ElementStack=c},{}],2:[function(e,t,r){var n=e("html5-entities"),a=e("./InputStream").InputStream,o={};function i(e){return e>="0"&&e<="9"||e>="a"&&e<="f"||e>="A"&&e<="F"}function s(e){return e>="0"&&e<="9"}Object.keys(n).forEach((function(e){for(var t=0;t65535&&h<=1114111){var f=55296+((1047552&(h-=65536))>>10),T=56320+(1023&h);l=String.fromCharCode(f,T)}else l=String.fromCharCode(h);return";"!==d&&(t._parseError("numeric-entity-without-semicolon"),e.unget(d)),l}return e.unget(p),t._parseError("expected-numeric-entity"),!1}if(d>="a"&&d<="z"||d>="A"&&d<="Z"){for(var y="";o[p]&&(n[p]&&(y=p),";"!=d)&&(d=e.char())!==a.EOF;)p+=d;return y?(l=n[y],";"!==d&&r&&((c=d)>="0"&&c<="9"||c>="a"&&c<="z"||c>="A"&&c<="Z"||"="===d)?(e.unget(p),!1):(p.length>y.length&&e.unget(p.substring(y.length)),";"!==d&&t._parseError("named-entity-without-semicolon"),l)):(t._parseError("expected-named-entity"),e.unget(p),!1)}},replaceEntityNumbers:function(e){switch(e){case 0:return 65533;case 19:return 16;case 128:return 8364;case 129:return 129;case 130:return 8218;case 131:return 402;case 132:return 8222;case 133:return 8230;case 134:return 8224;case 135:return 8225;case 136:return 710;case 137:return 8240;case 138:return 352;case 139:return 8249;case 140:return 338;case 141:return 141;case 142:return 381;case 143:return 143;case 144:return 144;case 145:return 8216;case 146:return 8217;case 147:return 8220;case 148:return 8221;case 149:return 8226;case 150:return 8211;case 151:return 8212;case 152:return 732;case 153:return 8482;case 154:return 353;case 155:return 8250;case 156:return 339;case 157:return 157;case 158:return 382;case 159:return 376;default:if(e>=55296&&e<=57343||e>1114111)return 65533;if(e>=1&&e<=8||e>=14&&e<=31||e>=127&&e<=159||e>=64976&&e<=65007||11==e||65534==e||131070==e||3145726==e||196607==e||262142==e||262143==e||327678==e||327679==e||393214==e||393215==e||458750==e||458751==e||524286==e||524287==e||589822==e||589823==e||655358==e||655359==e||720894==e||720895==e||786430==e||786431==e||851966==e||851967==e||917502==e||917503==e||983038==e||983039==e||1048574==e||1048575==e||1114110==e||1114111==e)return e}}};r.EntityParser=c},{"./InputStream":3,"html5-entities":12}],3:[function(e,t,r){function n(){this.data="",this.start=0,this.committed=0,this.eof=!1,this.lastLocation={line:0,column:0}}n.EOF=-1,n.DRAIN=-2,n.prototype={slice:function(){if(this.start>=this.data.length){if(!this.eof)throw n.DRAIN;return n.EOF}return this.data.slice(this.start,this.data.length)},char:function(){if(!this.eof&&this.start>=this.data.length-1)throw n.DRAIN;if(this.start>=this.data.length)return n.EOF;var e=this.data[this.start++];return"\r"===e&&(e="\n"),e},advance:function(e){if(this.start+=e,this.start>=this.data.length){if(!this.eof)throw n.DRAIN;return n.EOF}this.committed>this.data.length/2&&(this.lastLocation=this.location(),this.data=this.data.slice(this.committed),this.start=this.start-this.committed,this.committed=0)},matchWhile:function(e){if(this.eof&&this.start>=this.data.length)return"";var t=new RegExp("^"+e+"+").exec(this.slice());if(t){if(!this.eof&&t[0].length==this.data.length-this.start)throw n.DRAIN;return this.advance(t[0].length),t[0]}return""},matchUntil:function(e){var t,r;if((r=this.slice())===n.EOF)return"";if(t=new RegExp(e+(this.eof?"|$":"")).exec(r)){var a=this.data.slice(this.start,this.start+t.index);return this.advance(t.index),a.replace(/\r/g,"\n").replace(/\n{2,}/g,"\n")}throw n.DRAIN},append:function(e){this.data+=e},shift:function(e){if(!this.eof&&this.start+e>=this.data.length)throw n.DRAIN;if(this.eof&&this.start>=this.data.length)return n.EOF;var t=this.data.slice(this.start,this.start+e).toString();return this.advance(Math.min(e,this.data.length-this.start)),t},peek:function(e){if(!this.eof&&this.start+e>=this.data.length)throw n.DRAIN;return this.eof&&this.start>=this.data.length?n.EOF:this.data.slice(this.start,Math.min(this.start+e,this.data.length)).toString()},length:function(){return this.data.length-this.start-1},unget:function(e){e!==n.EOF&&(this.start-=e.length)},undo:function(){this.start=this.committed},commit:function(){this.committed=this.start},location:function(){var e=this.lastLocation.line,t=this.lastLocation.column,r=this.data.slice(0,this.committed),n=r.match(/\n/g);return{line:n?e+n.length:e,column:n?r.length-r.lastIndexOf("\n")-1:t+r.length}}},r.InputStream=n},{}],4:[function(e,t,r){var n={"http://www.w3.org/1999/xhtml":["address","applet","area","article","aside","base","basefont","bgsound","blockquote","body","br","button","caption","center","col","colgroup","dd","details","dir","div","dl","dt","embed","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","iframe","img","input","isindex","li","link","listing","main","marquee","menu","menuitem","meta","nav","noembed","noframes","noscript","object","ol","p","param","plaintext","pre","script","section","select","source","style","summary","table","tbody","td","textarea","tfoot","th","thead","title","tr","track","ul","wbr","xmp"],"http://www.w3.org/1998/Math/MathML":["mi","mo","mn","ms","mtext","annotation-xml"],"http://www.w3.org/2000/svg":["foreignObject","desc","title"]};function a(e,t,r,n){this.localName=t,this.namespaceURI=e,this.attributes=r,this.node=n}a.prototype.isSpecial=function(){return this.namespaceURI in n&&n[this.namespaceURI].indexOf(this.localName)>-1},a.prototype.isFosterParenting=function(){return"http://www.w3.org/1999/xhtml"===this.namespaceURI&&("table"===this.localName||"tbody"===this.localName||"tfoot"===this.localName||"thead"===this.localName||"tr"===this.localName)},a.prototype.isNumberedHeader=function(){return"http://www.w3.org/1999/xhtml"===this.namespaceURI&&("h1"===this.localName||"h2"===this.localName||"h3"===this.localName||"h4"===this.localName||"h5"===this.localName||"h6"===this.localName)},a.prototype.isForeign=function(){return"http://www.w3.org/1999/xhtml"!=this.namespaceURI},a.prototype.isHtmlIntegrationPoint=function(){if("http://www.w3.org/1998/Math/MathML"===this.namespaceURI){if("annotation-xml"!==this.localName)return!1;var e=function(e){for(var t=0;t="A"&&e<="Z"||e>="a"&&e<="z"}function s(e){this._tokenHandler=e,this._state=s.DATA,this._inputStream=new n,this._currentToken=null,this._temporaryBuffer="",this._additionalAllowedCharacter=""}s.prototype._parseError=function(e,t){this._tokenHandler.parseError(e,t)},s.prototype._emitToken=function(e){if("StartTag"===e.type)for(var t=1;t"===a&&n?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(r)):i(a)?(this._temporaryBuffer+=a,e.commit()):(t._emitToken({type:"Characters",data:""===a&&n?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(r)):i(a)?(this._temporaryBuffer+=a,e.commit()):(t._emitToken({type:"Characters",data:""===n&&r?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t._emitCurrentToken()):i(n)?(this._temporaryBuffer+=n,e.commit()):(t._emitToken({type:"Characters",data:""===a?(t._emitToken({type:"Characters",data:">"}),t.setState(u)):"\0"===a?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"�"}),t.setState(S)):(t._emitToken({type:"Characters",data:a}),t.setState(S)),!0}function C(e){var r=e.char();return"/"===r?(this._temporaryBuffer="",t.setState(N)):i(r)?(t._emitToken({type:"Characters",data:"<"+r}),this._temporaryBuffer=r,t.setState(O)):(t._emitToken({type:"Characters",data:"<"}),e.unget(r),t.setState(S)),!0}function N(e){var r=e.char();return i(r)?(this._temporaryBuffer=r,t.setState(I)):(t._emitToken({type:"Characters",data:""===a&&n?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(r),t._emitCurrentToken()):i(a)?(this._temporaryBuffer+=a,e.commit()):(t._emitToken({type:"Characters",data:""===r?(t._emitToken({type:"Characters",data:r}),"script"===this._temporaryBuffer.toLowerCase()?t.setState(M):t.setState(S)):i(r)?(t._emitToken({type:"Characters",data:r}),this._temporaryBuffer+=r,e.commit()):(e.unget(r),t.setState(S)),!0}function M(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-script"),e.unget(a),t.setState(r)):"-"===a?(t._emitToken({type:"Characters",data:"-"}),t.setState(A)):"<"===a?(t._emitToken({type:"Characters",data:"<"}),t.setState(L)):"\0"===a?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"�"}),e.commit()):(t._emitToken({type:"Characters",data:a}),e.commit()),!0}function A(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-script"),e.unget(a),t.setState(r)):"-"===a?(t._emitToken({type:"Characters",data:"-"}),t.setState(F)):"<"===a?(t._emitToken({type:"Characters",data:"<"}),t.setState(L)):"\0"===a?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"�"}),t.setState(M)):(t._emitToken({type:"Characters",data:a}),t.setState(M)),!0}function F(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-script"),e.unget(a),t.setState(r)):"-"===a?(t._emitToken({type:"Characters",data:"-"}),e.commit()):"<"===a?(t._emitToken({type:"Characters",data:"<"}),t.setState(L)):">"===a?(t._emitToken({type:"Characters",data:">"}),t.setState(u)):"\0"===a?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"�"}),t.setState(M)):(t._emitToken({type:"Characters",data:a}),t.setState(M)),!0}function L(e){var r=e.char();return"/"===r?(t._emitToken({type:"Characters",data:"/"}),this._temporaryBuffer="",t.setState(B)):(e.unget(r),t.setState(M)),!0}function B(e){var r=e.char();return o(r)||"/"===r||">"===r?(t._emitToken({type:"Characters",data:r}),"script"===this._temporaryBuffer.toLowerCase()?t.setState(S):t.setState(M)):i(r)?(t._emitToken({type:"Characters",data:r}),this._temporaryBuffer+=r,e.commit()):(e.unget(r),t.setState(M)),!0}function q(e){var a=e.char();return a===n.EOF?(t._parseError("bare-less-than-sign-at-eof"),t._emitToken({type:"Characters",data:"<"}),e.unget(a),t.setState(r)):i(a)?(t._currentToken={type:"StartTag",name:a.toLowerCase(),data:[]},t.setState(D)):"!"===a?t.setState(X):"/"===a?t.setState(H):">"===a?(t._parseError("expected-tag-name-but-got-right-bracket"),t._emitToken({type:"Characters",data:"<>"}),t.setState(r)):"?"===a?(t._parseError("expected-tag-name-but-got-question-mark"),e.unget(a),t.setState(W)):(t._parseError("expected-tag-name"),t._emitToken({type:"Characters",data:"<"}),e.unget(a),t.setState(r)),!0}function H(e){var a=e.char();return a===n.EOF?(t._parseError("expected-closing-tag-but-got-eof"),t._emitToken({type:"Characters",data:""===a?(t._parseError("expected-closing-tag-but-got-right-bracket"),t.setState(r)):(t._parseError("expected-closing-tag-but-got-char",{data:a}),e.unget(a),t.setState(W)),!0}function D(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-tag-name"),e.unget(a),t.setState(r)):o(a)?t.setState(R):i(a)?t._currentToken.name+=a.toLowerCase():">"===a?t._emitCurrentToken():"/"===a?t.setState(Y):"\0"===a?(t._parseError("invalid-codepoint"),t._currentToken.name+="�"):t._currentToken.name+=a,e.commit(),!0}function R(e){var a=e.char();if(a===n.EOF)t._parseError("expected-attribute-name-but-got-eof"),e.unget(a),t.setState(r);else{if(o(a))return!0;i(a)?(t._currentToken.data.push({nodeName:a.toLowerCase(),nodeValue:""}),t.setState(U)):">"===a?t._emitCurrentToken():"/"===a?t.setState(Y):"'"===a||'"'===a||"="===a||"<"===a?(t._parseError("invalid-character-in-attribute-name"),t._currentToken.data.push({nodeName:a,nodeValue:""}),t.setState(U)):"\0"===a?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"�",nodeValue:""})):(t._currentToken.data.push({nodeName:a,nodeValue:""}),t.setState(U))}return!0}function U(e){var a=e.char(),s=!0,c=!1;if(a===n.EOF?(t._parseError("eof-in-attribute-name"),e.unget(a),t.setState(r),c=!0):"="===a?t.setState(j):i(a)?(t._currentAttribute().nodeName+=a.toLowerCase(),s=!1):">"===a?c=!0:o(a)?t.setState(P):"/"===a?t.setState(Y):"'"===a||'"'===a?(t._parseError("invalid-character-in-attribute-name"),t._currentAttribute().nodeName+=a,s=!1):"\0"===a?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeName+="�"):(t._currentAttribute().nodeName+=a,s=!1),s){for(var l=t._currentToken.data,p=l[l.length-1],d=l.length-2;d>=0;d--)if(p.nodeName===l[d].nodeName){t._parseError("duplicate-attribute",{name:p.nodeName}),p.nodeName=null;break}c&&t._emitCurrentToken()}else e.commit();return!0}function P(e){var a=e.char();if(a===n.EOF)t._parseError("expected-end-of-tag-but-got-eof"),e.unget(a),t.setState(r);else{if(o(a))return!0;"="===a?t.setState(j):">"===a?t._emitCurrentToken():i(a)?(t._currentToken.data.push({nodeName:a,nodeValue:""}),t.setState(U)):"/"===a?t.setState(Y):"'"===a||'"'===a||"<"===a?(t._parseError("invalid-character-after-attribute-name"),t._currentToken.data.push({nodeName:a,nodeValue:""}),t.setState(U)):"\0"===a?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"�",nodeValue:""})):(t._currentToken.data.push({nodeName:a,nodeValue:""}),t.setState(U))}return!0}function j(e){var a=e.char();if(a===n.EOF)t._parseError("expected-attribute-value-but-got-eof"),e.unget(a),t.setState(r);else{if(o(a))return!0;'"'===a?t.setState(G):"&"===a?(t.setState(z),e.unget(a)):"'"===a?t.setState(V):">"===a?(t._parseError("expected-attribute-value-but-got-right-bracket"),t._emitCurrentToken()):"="===a||"<"===a||"`"===a?(t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=a,t.setState(z)):"\0"===a?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="�"):(t._currentAttribute().nodeValue+=a,t.setState(z))}return!0}function G(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-attribute-value-double-quote"),e.unget(a),t.setState(r)):'"'===a?t.setState(Q):"&"===a?(this._additionalAllowedCharacter='"',t.setState($)):"\0"===a?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="�"):(a+=e.matchUntil('[\0"&]'),t._currentAttribute().nodeValue+=a),!0}function V(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-attribute-value-single-quote"),e.unget(a),t.setState(r)):"'"===a?t.setState(Q):"&"===a?(this._additionalAllowedCharacter="'",t.setState($)):"\0"===a?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="�"):t._currentAttribute().nodeValue+=a+e.matchUntil("\0|['&]"),!0}function z(e){var a=e.char();if(a===n.EOF)t._parseError("eof-after-attribute-value"),e.unget(a),t.setState(r);else if(o(a))t.setState(R);else if("&"===a)this._additionalAllowedCharacter=">",t.setState($);else if(">"===a)t._emitCurrentToken();else if('"'===a||"'"===a||"="===a||"`"===a||"<"===a)t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=a,e.commit();else if("\0"===a)t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="�";else{var i=e.matchUntil("\0|[\t\n\v\f \r&<>\"'=`]");i===n.EOF&&(t._parseError("eof-in-attribute-value-no-quotes"),t._emitCurrentToken()),e.commit(),t._currentAttribute().nodeValue+=a+i}return!0}function $(e){var r=a.consumeEntity(e,t,this._additionalAllowedCharacter);return this._currentAttribute().nodeValue+=r||"&",'"'===this._additionalAllowedCharacter?t.setState(G):"'"===this._additionalAllowedCharacter?t.setState(V):">"===this._additionalAllowedCharacter&&t.setState(z),!0}function Q(e){var a=e.char();return a===n.EOF?(t._parseError("eof-after-attribute-value"),e.unget(a),t.setState(r)):o(a)?t.setState(R):">"===a?(t.setState(r),t._emitCurrentToken()):"/"===a?t.setState(Y):(t._parseError("unexpected-character-after-attribute-value"),e.unget(a),t.setState(R)),!0}function Y(e){var a=e.char();return a===n.EOF?(t._parseError("unexpected-eof-after-solidus-in-tag"),e.unget(a),t.setState(r)):">"===a?(t._currentToken.selfClosing=!0,t.setState(r),t._emitCurrentToken()):(t._parseError("unexpected-character-after-solidus-in-tag"),e.unget(a),t.setState(R)),!0}function W(e){var n=e.matchUntil(">");return n=n.replace(/\u0000/g,"�"),e.char(),t._emitToken({type:"Comment",data:n}),t.setState(r),!0}function X(e){var r=e.shift(2);if("--"===r)t._currentToken={type:"Comment",data:""},t.setState(Z);else{var a=e.shift(5);if(a===n.EOF||r===n.EOF)return t._parseError("expected-dashes-or-doctype"),t.setState(W),e.unget(r),!0;"DOCTYPE"===(r+=a).toUpperCase()?(t._currentToken={type:"Doctype",name:"",publicId:null,systemId:null,forceQuirks:!1},t.setState(ae)):t._tokenHandler.isCdataSectionAllowed()&&"[CDATA["===r?t.setState(J):(t._parseError("expected-dashes-or-doctype"),e.unget(r),t.setState(W))}return!0}function J(e){var n=e.matchUntil("]]>");return e.shift(3),n&&t._emitToken({type:"Characters",data:n}),t.setState(r),!0}function Z(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(a),t.setState(r)):"-"===a?t.setState(K):">"===a?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(r)):"\0"===a?(t._parseError("invalid-codepoint"),t._currentToken.data+="�"):(t._currentToken.data+=a,t.setState(ee)),!0}function K(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(a),t.setState(r)):"-"===a?t.setState(re):">"===a?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(r)):"\0"===a?(t._parseError("invalid-codepoint"),t._currentToken.data+="�"):(t._currentToken.data+="-"+a,t.setState(ee)),!0}function ee(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(a),t.setState(r)):"-"===a?t.setState(te):"\0"===a?(t._parseError("invalid-codepoint"),t._currentToken.data+="�"):(t._currentToken.data+=a,e.commit()),!0}function te(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-comment-end-dash"),t._emitToken(t._currentToken),e.unget(a),t.setState(r)):"-"===a?t.setState(re):"\0"===a?(t._parseError("invalid-codepoint"),t._currentToken.data+="-�",t.setState(ee)):(t._currentToken.data+="-"+a+e.matchUntil("\0|-"),e.char()),!0}function re(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-comment-double-dash"),t._emitToken(t._currentToken),e.unget(a),t.setState(r)):">"===a?(t._emitToken(t._currentToken),t.setState(r)):"!"===a?(t._parseError("unexpected-bang-after-double-dash-in-comment"),t.setState(ne)):"-"===a?(t._parseError("unexpected-dash-after-double-dash-in-comment"),t._currentToken.data+=a):"\0"===a?(t._parseError("invalid-codepoint"),t._currentToken.data+="--�",t.setState(ee)):(t._parseError("unexpected-char-in-comment"),t._currentToken.data+="--"+a,t.setState(ee)),!0}function ne(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-comment-end-bang-state"),t._emitToken(t._currentToken),e.unget(a),t.setState(r)):">"===a?(t._emitToken(t._currentToken),t.setState(r)):"-"===a?(t._currentToken.data+="--!",t.setState(te)):(t._currentToken.data+="--!"+a,t.setState(ee)),!0}function ae(e){var a=e.char();return a===n.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(a),t.setState(r),t._emitCurrentToken()):(o(a)||(t._parseError("need-space-after-doctype"),e.unget(a)),t.setState(oe)),!0}function oe(e){var a=e.char();return a===n.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(a),t.setState(r),t._emitCurrentToken()):o(a)||(">"===a?(t._parseError("expected-doctype-name-but-got-right-bracket"),t._currentToken.forceQuirks=!0,t.setState(r),t._emitCurrentToken()):(i(a)&&(a=a.toLowerCase()),t._currentToken.name=a,t.setState(ie))),!0}function ie(e){var a=e.char();return a===n.EOF?(t._currentToken.forceQuirks=!0,e.unget(a),t._parseError("eof-in-doctype-name"),t.setState(r),t._emitCurrentToken()):o(a)?t.setState(se):">"===a?(t.setState(r),t._emitCurrentToken()):(i(a)&&(a=a.toLowerCase()),t._currentToken.name+=a,e.commit()),!0}function se(e){var a=e.char();if(a===n.EOF)t._currentToken.forceQuirks=!0,e.unget(a),t._parseError("eof-in-doctype"),t.setState(r),t._emitCurrentToken();else if(o(a));else if(">"===a)t.setState(r),t._emitCurrentToken();else{if(["p","P"].indexOf(a)>-1){var i=[["u","U"],["b","B"],["l","L"],["i","I"],["c","C"]].every((function(t){return a=e.char(),t.indexOf(a)>-1}));if(i)return t.setState(ce),!0}else if(["s","S"].indexOf(a)>-1&&(i=[["y","Y"],["s","S"],["t","T"],["e","E"],["m","M"]].every((function(t){return a=e.char(),t.indexOf(a)>-1}))))return t.setState(he),!0;e.unget(a),t._currentToken.forceQuirks=!0,a===n.EOF?(t._parseError("eof-in-doctype"),e.unget(a),t.setState(r),t._emitCurrentToken()):(t._parseError("expected-space-or-right-bracket-in-doctype",{data:a}),t.setState(be))}return!0}function ce(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(a),t.setState(r),t._emitCurrentToken()):o(a)?t.setState(le):"'"===a||'"'===a?(t._parseError("unexpected-char-in-doctype"),e.unget(a),t.setState(le)):(e.unget(a),t.setState(le)),!0}function le(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(a),t.setState(r),t._emitCurrentToken()):o(a)||('"'===a?(t._currentToken.publicId="",t.setState(pe)):"'"===a?(t._currentToken.publicId="",t.setState(de)):">"===a?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(r),t._emitCurrentToken()):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(be))),!0}function pe(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(a),t.setState(r),t._emitCurrentToken()):'"'===a?t.setState(ue):">"===a?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(r),t._emitCurrentToken()):t._currentToken.publicId+=a,!0}function de(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(a),t.setState(r),t._emitCurrentToken()):"'"===a?t.setState(ue):">"===a?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(r),t._emitCurrentToken()):t._currentToken.publicId+=a,!0}function ue(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(a),t.setState(r)):o(a)?t.setState(me):">"===a?(t.setState(r),t._emitCurrentToken()):'"'===a?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(fe)):"'"===a?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(Te)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(be)),!0}function me(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(a),t.setState(r)):o(a)||(">"===a?(t._emitCurrentToken(),t.setState(r)):'"'===a?(t._currentToken.systemId="",t.setState(fe)):"'"===a?(t._currentToken.systemId="",t.setState(Te)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(be))),!0}function he(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(a),t.setState(r)):o(a)?t.setState(ge):"'"===a||'"'===a?(t._parseError("unexpected-char-in-doctype"),e.unget(a),t.setState(ge)):(e.unget(a),t.setState(ge)),!0}function ge(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(a),t.setState(r)):o(a)||('"'===a?(t._currentToken.systemId="",t.setState(fe)):"'"===a?(t._currentToken.systemId="",t.setState(Te)):">"===a?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(r)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(be))),!0}function fe(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(a),t.setState(r)):'"'===a?t.setState(ye):">"===a?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(r)):t._currentToken.systemId+=a,!0}function Te(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(a),t.setState(r)):"'"===a?t.setState(ye):">"===a?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(r)):t._currentToken.systemId+=a,!0}function ye(e){var a=e.char();return a===n.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(a),t.setState(r)):o(a)||(">"===a?(t._emitCurrentToken(),t.setState(r)):(t._parseError("unexpected-char-in-doctype"),t.setState(be))),!0}function be(e){var a=e.char();return a===n.EOF?(e.unget(a),t._emitCurrentToken(),t.setState(r)):">"===a&&(t._emitCurrentToken(),t.setState(r)),!0}},Object.defineProperty(s.prototype,"lineNumber",{get:function(){return this._inputStream.location().line}}),Object.defineProperty(s.prototype,"columnNumber",{get:function(){return this._inputStream.location().column}}),r.Tokenizer=s},{"./EntityParser":2,"./InputStream":3}],6:[function(e,t,r){var n=e("assert"),a=e("./messages.json"),o=e("./constants"),i=(e("events").EventEmitter,e("./Tokenizer").Tokenizer),s=e("./ElementStack").ElementStack,c=e("./StackItem").StackItem,l={};function p(e){return" "===e||"\n"===e||"\t"===e||"\r"===e||"\f"===e}function d(e){for(var t=0;t2||2==e.openElements.length&&"body"!=e.openElements.item(1).localName?e.parseError("expected-closing-tag-but-got-eof"):e.context&&e.openElements.length},processComment:function(t){e.insertComment(t,e.currentStackItem().node)},processDoctype:function(t,r,n,a){e.parseError("unexpected-doctype")},processStartTag:function(e,t,r){if(this[this.start_tag_handlers[e]])this[this.start_tag_handlers[e]](e,t,r);else{if(!this[this.start_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.start_tag_handlers["-default"]](e,t,r)}},processEndTag:function(e){if(this[this.end_tag_handlers[e]])this[this.end_tag_handlers[e]](e);else{if(!this[this.end_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.end_tag_handlers["-default"]](e)}},startTagHtml:function(e,r){t.inBody.startTagHtml(e,r)}},t.initial=Object.create(t.base),t.initial.processEOF=function(){e.parseError("expected-doctype-but-got-eof"),this.anythingElse(),e.insertionMode.processEOF()},t.initial.processComment=function(t){e.insertComment(t,e.document)},t.initial.processDoctype=function(t,r,n,a){function o(e){return 0===r.toLowerCase().indexOf(e)}e.insertDoctype(t||"",r||"",n||""),a||"html"!=t||null!=r&&(["+//silmaril//dtd html pro v0r11 19970101//","-//advasoft ltd//dtd html 3.0 aswedit + extensions//","-//as//dtd html 3.0 aswedit + extensions//","-//ietf//dtd html 2.0 level 1//","-//ietf//dtd html 2.0 level 2//","-//ietf//dtd html 2.0 strict level 1//","-//ietf//dtd html 2.0 strict level 2//","-//ietf//dtd html 2.0 strict//","-//ietf//dtd html 2.0//","-//ietf//dtd html 2.1e//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.2 final//","-//ietf//dtd html 3.2//","-//ietf//dtd html 3//","-//ietf//dtd html level 0//","-//ietf//dtd html level 0//","-//ietf//dtd html level 1//","-//ietf//dtd html level 1//","-//ietf//dtd html level 2//","-//ietf//dtd html level 2//","-//ietf//dtd html level 3//","-//ietf//dtd html level 3//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html//","-//ietf//dtd html//","-//ietf//dtd html//","-//metrius//dtd metrius presentational//","-//microsoft//dtd internet explorer 2.0 html strict//","-//microsoft//dtd internet explorer 2.0 html//","-//microsoft//dtd internet explorer 2.0 tables//","-//microsoft//dtd internet explorer 3.0 html strict//","-//microsoft//dtd internet explorer 3.0 html//","-//microsoft//dtd internet explorer 3.0 tables//","-//netscape comm. corp.//dtd html//","-//netscape comm. corp.//dtd strict html//","-//o'reilly and associates//dtd html 2.0//","-//o'reilly and associates//dtd html extended 1.0//","-//spyglass//dtd html 2.0 extended//","-//sq//dtd html 2.0 hotmetal + extensions//","-//sun microsystems corp.//dtd hotjava html//","-//sun microsystems corp.//dtd hotjava strict html//","-//w3c//dtd html 3 1995-03-24//","-//w3c//dtd html 3.2 draft//","-//w3c//dtd html 3.2 final//","-//w3c//dtd html 3.2//","-//w3c//dtd html 3.2s draft//","-//w3c//dtd html 4.0 frameset//","-//w3c//dtd html 4.0 transitional//","-//w3c//dtd html experimental 19960712//","-//w3c//dtd html experimental 970421//","-//w3c//dtd w3 html//","-//w3o//dtd w3 html 3.0//","-//webtechs//dtd mozilla html 2.0//","-//webtechs//dtd mozilla html//","html"].some(o)||["-//w3o//dtd w3 html strict 3.0//en//","-/w3c/dtd html 4.0 transitional/en","html"].indexOf(r.toLowerCase())>-1||null==n&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].some(o))||null!=n&&"http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"==n.toLowerCase()?(e.compatMode="quirks",e.parseError("quirky-doctype")):null!=r&&(["-//w3c//dtd xhtml 1.0 transitional//","-//w3c//dtd xhtml 1.0 frameset//"].some(o)||null!=n&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].indexOf(r.toLowerCase())>-1)?(e.compatMode="limited quirks",e.parseError("almost-standards-doctype")):"-//W3C//DTD HTML 4.0//EN"==r&&(null==n||"http://www.w3.org/TR/REC-html40/strict.dtd"==n)||"-//W3C//DTD HTML 4.01//EN"==r&&(null==n||"http://www.w3.org/TR/html4/strict.dtd"==n)||"-//W3C//DTD XHTML 1.0 Strict//EN"==r&&"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"==n||"-//W3C//DTD XHTML 1.1//EN"==r&&"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"==n||(null!=n&&"about:legacy-compat"!=n||null!=r)&&e.parseError("unknown-doctype"),e.setInsertionMode("beforeHTML")},t.initial.processCharacters=function(t){t.skipLeadingWhitespace(),t.length&&(e.parseError("expected-doctype-but-got-chars"),this.anythingElse(),e.insertionMode.processCharacters(t))},t.initial.processStartTag=function(t,r,n){e.parseError("expected-doctype-but-got-start-tag",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,r,n)},t.initial.processEndTag=function(t){e.parseError("expected-doctype-but-got-end-tag",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t)},t.initial.anythingElse=function(){e.compatMode="quirks",e.setInsertionMode("beforeHTML")},t.beforeHTML=Object.create(t.base),t.beforeHTML.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.beforeHTML.processEOF=function(){this.anythingElse(),e.insertionMode.processEOF()},t.beforeHTML.processComment=function(t){e.insertComment(t,e.document)},t.beforeHTML.processCharacters=function(t){t.skipLeadingWhitespace(),t.length&&(this.anythingElse(),e.insertionMode.processCharacters(t))},t.beforeHTML.startTagHtml=function(t,r,n){e.insertHtmlElement(r),e.setInsertionMode("beforeHead")},t.beforeHTML.startTagOther=function(t,r,n){this.anythingElse(),e.insertionMode.processStartTag(t,r,n)},t.beforeHTML.processEndTag=function(t){this.anythingElse(),e.insertionMode.processEndTag(t)},t.beforeHTML.anythingElse=function(){e.insertHtmlElement(),e.setInsertionMode("beforeHead")},t.afterAfterBody=Object.create(t.base),t.afterAfterBody.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.afterAfterBody.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterBody.processDoctype=function(e){t.inBody.processDoctype(e)},t.afterAfterBody.startTagHtml=function(e,r){t.inBody.startTagHtml(e,r)},t.afterAfterBody.startTagOther=function(t,r,n){e.parseError("unexpected-start-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,r,n)},t.afterAfterBody.endTagOther=function(t){e.parseError("unexpected-end-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterAfterBody.processCharacters=function(r){if(!d(r.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(r);t.inBody.processCharacters(r)},t.afterBody=Object.create(t.base),t.afterBody.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterBody.processComment=function(t){e.insertComment(t,e.openElements.rootNode)},t.afterBody.processCharacters=function(r){if(!d(r.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(r);t.inBody.processCharacters(r)},t.afterBody.processStartTag=function(t,r,n){e.parseError("unexpected-start-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,r,n)},t.afterBody.endTagHtml=function(t){e.context?e.parseError("end-html-in-innerhtml"):e.setInsertionMode("afterAfterBody")},t.afterBody.endTagOther=function(t){e.parseError("unexpected-end-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterFrameset=Object.create(t.base),t.afterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoframes","-default":"startTagOther"},t.afterFrameset.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterFrameset.processCharacters=function(t){for(var r=t.takeRemaining(),n="",a=0;a1;)e.openElements.pop();e.insertElement(t,r),e.setInsertionMode("inFrameset")}},t.inBody.startTagCloseP=function(t,r){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,r)},t.inBody.startTagPreListing=function(t,r){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,r),e.framesetOk=!1,e.shouldSkipLeadingNewline=!0},t.inBody.startTagForm=function(t,r){e.form?e.parseError("unexpected-start-tag",{name:t}):(e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,r),e.form=e.currentStackItem())},t.inBody.startTagRpRt=function(t,r){e.openElements.inScope("ruby")&&(e.generateImpliedEndTags(),"ruby"!=e.currentStackItem().localName&&e.parseError("unexpected-start-tag",{name:t})),e.insertElement(t,r)},t.inBody.startTagListItem=function(t,r){for(var n={li:["li"],dd:["dd","dt"],dt:["dd","dt"]}[t],a=e.openElements,o=a.length-1;o>=0;o--){var i=a.item(o);if(-1!=n.indexOf(i.localName)){e.insertionMode.processEndTag(i.localName);break}if(i.isSpecial()&&"p"!==i.localName&&"address"!==i.localName&&"div"!==i.localName)break}e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,r),e.framesetOk=!1},t.inBody.startTagPlaintext=function(t,r){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,r),e.tokenizer.setState(i.PLAINTEXT)},t.inBody.startTagHeading=function(t,r){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.currentStackItem().isNumberedHeader()&&(e.parseError("unexpected-start-tag",{name:t}),e.popElement()),e.insertElement(t,r)},t.inBody.startTagA=function(t,r){var n=e.elementInActiveFormattingElements("a");n&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"a",endName:"a"}),e.adoptionAgencyEndTag("a"),e.openElements.contains(n)&&e.openElements.remove(n),e.removeElementFromActiveFormattingElements(n)),e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,r)},t.inBody.startTagFormatting=function(t,r){e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,r)},t.inBody.startTagNobr=function(t,r){e.reconstructActiveFormattingElements(),e.openElements.inScope("nobr")&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"nobr",endName:"nobr"}),this.processEndTag("nobr"),e.reconstructActiveFormattingElements()),e.insertFormattingElement(t,r)},t.inBody.startTagButton=function(t,r){e.openElements.inScope("button")?(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"button",endName:"button"}),this.processEndTag("button"),e.insertionMode.processStartTag(t,r)):(e.framesetOk=!1,e.reconstructActiveFormattingElements(),e.insertElement(t,r))},t.inBody.startTagAppletMarqueeObject=function(t,r){e.reconstructActiveFormattingElements(),e.insertElement(t,r),e.activeFormattingElements.push(l),e.framesetOk=!1},t.inBody.endTagAppletMarqueeObject=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t),e.clearActiveFormattingElements()):e.parseError("unexpected-end-tag",{name:t})},t.inBody.startTagXmp=function(t,r){e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.reconstructActiveFormattingElements(),e.processGenericRawTextStartTag(t,r),e.framesetOk=!1},t.inBody.startTagTable=function(t,r){"quirks"!==e.compatMode&&e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.insertElement(t,r),e.setInsertionMode("inTable"),e.framesetOk=!1},t.inBody.startTagVoidFormatting=function(t,r){e.reconstructActiveFormattingElements(),e.insertSelfClosingElement(t,r),e.framesetOk=!1},t.inBody.startTagParamSourceTrack=function(t,r){e.insertSelfClosingElement(t,r)},t.inBody.startTagHr=function(t,r){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertSelfClosingElement(t,r),e.framesetOk=!1},t.inBody.startTagImage=function(t,r){e.parseError("unexpected-start-tag-treated-as",{originalName:"image",newName:"img"}),this.processStartTag("img",r)},t.inBody.startTagInput=function(t,r){var n=e.framesetOk;for(var a in this.startTagVoidFormatting(t,r),r)if("type"==r[a].nodeName){"hidden"==r[a].nodeValue.toLowerCase()&&(e.framesetOk=n);break}},t.inBody.startTagIsindex=function(t,r){if(e.parseError("deprecated-tag",{name:"isindex"}),e.selfClosingFlagAcknowledged=!0,!e.form){var n=[],a=[],o="This is a searchable index. Enter search keywords: ";for(var i in r)switch(r[i].nodeName){case"action":n.push({nodeName:"action",nodeValue:r[i].nodeValue});break;case"prompt":o=r[i].nodeValue;break;case"name":break;default:a.push({nodeName:r[i].nodeName,nodeValue:r[i].nodeValue})}a.push({nodeName:"name",nodeValue:"isindex"}),this.processStartTag("form",n),this.processStartTag("hr"),this.processStartTag("label"),this.processCharacters(new h(o)),this.processStartTag("input",a),this.processEndTag("label"),this.processStartTag("hr"),this.processEndTag("form")}},t.inBody.startTagTextarea=function(t,r){e.insertElement(t,r),e.tokenizer.setState(i.RCDATA),e.originalInsertionMode=e.insertionModeName,e.shouldSkipLeadingNewline=!0,e.framesetOk=!1,e.setInsertionMode("text")},t.inBody.startTagIFrame=function(t,r){e.framesetOk=!1,this.startTagRawText(t,r)},t.inBody.startTagRawText=function(t,r){e.processGenericRawTextStartTag(t,r)},t.inBody.startTagSelect=function(t,r){e.reconstructActiveFormattingElements(),e.insertElement(t,r),e.framesetOk=!1;var n=e.insertionModeName;"inTable"==n||"inCaption"==n||"inColumnGroup"==n||"inTableBody"==n||"inRow"==n||"inCell"==n?e.setInsertionMode("inSelectInTable"):e.setInsertionMode("inSelect")},t.inBody.startTagMisplaced=function(t,r){e.parseError("unexpected-start-tag-ignored",{name:t})},t.inBody.endTagMisplaced=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagBr=function(t){e.parseError("unexpected-end-tag-treated-as",{originalName:"br",newName:"br element"}),e.reconstructActiveFormattingElements(),e.insertElement(t,[]),e.popElement()},t.inBody.startTagOptionOptgroup=function(t,r){"option"==e.currentStackItem().localName&&e.popElement(),e.reconstructActiveFormattingElements(),e.insertElement(t,r)},t.inBody.startTagOther=function(t,r){e.reconstructActiveFormattingElements(),e.insertElement(t,r)},t.inBody.endTagOther=function(t){for(var r,n=e.openElements.length-1;n>0;n--){if((r=e.openElements.item(n)).localName==t){e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("unexpected-end-tag",{name:t}),e.openElements.remove_openElements_until((function(e){return e===r}));break}if(r.isSpecial()){e.parseError("unexpected-end-tag",{name:t});break}}},t.inBody.startTagMath=function(t,r,n){e.reconstructActiveFormattingElements(),r=e.adjustMathMLAttributes(r),r=e.adjustForeignAttributes(r),e.insertForeignElement(t,r,"http://www.w3.org/1998/Math/MathML",n)},t.inBody.startTagSVG=function(t,r,n){e.reconstructActiveFormattingElements(),r=e.adjustSVGAttributes(r),r=e.adjustForeignAttributes(r),e.insertForeignElement(t,r,"http://www.w3.org/2000/svg",n)},t.inBody.endTagP=function(t){e.openElements.inButtonScope("p")?(e.generateImpliedEndTags("p"),"p"!=e.currentStackItem().localName&&e.parseError("unexpected-implied-end-tag",{name:"p"}),e.openElements.popUntilPopped(t)):(e.parseError("unexpected-end-tag",{name:"p"}),this.startTagCloseP("p",[]),this.endTagP("p"))},t.inBody.endTagBody=function(t){e.openElements.inScope("body")?("body"!=e.currentStackItem().localName&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody")):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagHtml=function(t){e.openElements.inScope("body")?("body"!=e.currentStackItem().localName&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody"),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagBlock=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagForm=function(t){var r=e.form;e.form=null,r&&e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem()!=r&&e.parseError("end-tag-too-early-ignored",{name:"form"}),e.openElements.remove(r)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagListItem=function(t){e.openElements.inListItemScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagHeading=function(t){e.openElements.hasNumberedHeaderElementInScope()?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.remove_openElements_until((function(e){return e.isNumberedHeader()}))):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagFormatting=function(t,r){e.adoptionAgencyEndTag(t)||this.endTagOther(t,r)},t.inCaption=Object.create(t.base),t.inCaption.start_tag_handlers={html:"startTagHtml",caption:"startTagTableElement",col:"startTagTableElement",colgroup:"startTagTableElement",tbody:"startTagTableElement",td:"startTagTableElement",tfoot:"startTagTableElement",thead:"startTagTableElement",tr:"startTagTableElement","-default":"startTagOther"},t.inCaption.end_tag_handlers={caption:"endTagCaption",table:"endTagTable",body:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfood:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inCaption.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCaption.startTagTableElement=function(t,r){e.parseError("unexpected-end-tag",{name:t});var n=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),n||e.insertionMode.processStartTag(t,r)},t.inCaption.startTagOther=function(e,r,n){t.inBody.processStartTag(e,r,n)},t.inCaption.endTagCaption=function(t){e.openElements.inTableScope("caption")?(e.generateImpliedEndTags(),"caption"!=e.currentStackItem().localName&&e.parseError("expected-one-end-tag-but-got-another",{gotName:"caption",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("caption"),e.clearActiveFormattingElements(),e.setInsertionMode("inTable")):(n.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inCaption.endTagTable=function(t){e.parseError("unexpected-end-table-in-caption");var r=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),r||e.insertionMode.processEndTag(t)},t.inCaption.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCaption.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell=Object.create(t.base),t.inCell.start_tag_handlers={html:"startTagHtml",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",td:"startTagTableOther",tfoot:"startTagTableOther",th:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inCell.end_tag_handlers={td:"endTagTableCell",th:"endTagTableCell",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",table:"endTagImply",tbody:"endTagImply",tfoot:"endTagImply",thead:"endTagImply",tr:"endTagImply","-default":"endTagOther"},t.inCell.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCell.startTagTableOther=function(t,r,n){e.openElements.inTableScope("td")||e.openElements.inTableScope("th")?(this.closeCell(),e.insertionMode.processStartTag(t,r,n)):e.parseError("unexpected-start-tag",{name:t})},t.inCell.startTagOther=function(e,r,n){t.inBody.processStartTag(e,r,n)},t.inCell.endTagTableCell=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t.toLowerCase()?(e.parseError("unexpected-cell-end-tag",{name:t}),e.openElements.popUntilPopped(t)):e.popElement(),e.clearActiveFormattingElements(),e.setInsertionMode("inRow")):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagImply=function(t){e.openElements.inTableScope(t)?(this.closeCell(),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell.closeCell=function(){e.openElements.inTableScope("td")?this.endTagTableCell("td"):e.openElements.inTableScope("th")&&this.endTagTableCell("th")},t.inColumnGroup=Object.create(t.base),t.inColumnGroup.start_tag_handlers={html:"startTagHtml",col:"startTagCol","-default":"startTagOther"},t.inColumnGroup.end_tag_handlers={colgroup:"endTagColgroup",col:"endTagCol","-default":"endTagOther"},t.inColumnGroup.ignoreEndTagColgroup=function(){return"html"==e.currentStackItem().localName},t.inColumnGroup.processCharacters=function(t){var r=t.takeLeadingWhitespace();if(r&&e.insertText(r),t.length){var n=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),n||e.insertionMode.processCharacters(t)}},t.inColumnGroup.startTagCol=function(t,r){e.insertSelfClosingElement(t,r)},t.inColumnGroup.startTagOther=function(t,r,n){var a=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),a||e.insertionMode.processStartTag(t,r,n)},t.inColumnGroup.endTagColgroup=function(t){this.ignoreEndTagColgroup()?(n.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.popElement(),e.setInsertionMode("inTable"))},t.inColumnGroup.endTagCol=function(t){e.parseError("no-end-tag",{name:"col"})},t.inColumnGroup.endTagOther=function(t){var r=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),r||e.insertionMode.processEndTag(t)},t.inForeignContent=Object.create(t.base),t.inForeignContent.processStartTag=function(t,r,n){if(-1!=["b","big","blockquote","body","br","center","code","dd","div","dl","dt","em","embed","h1","h2","h3","h4","h5","h6","head","hr","i","img","li","listing","menu","meta","nobr","ol","p","pre","ruby","s","small","span","strong","strike","sub","sup","table","tt","u","ul","var"].indexOf(t)||"font"==t&&r.some((function(e){return["color","face","size"].indexOf(e.nodeName)>=0}))){for(e.parseError("unexpected-html-element-in-foreign-content",{name:t});e.currentStackItem().isForeign()&&!e.currentStackItem().isHtmlIntegrationPoint()&&!e.currentStackItem().isMathMLTextIntegrationPoint();)e.openElements.pop();e.insertionMode.processStartTag(t,r,n)}else"http://www.w3.org/1998/Math/MathML"==e.currentStackItem().namespaceURI&&(r=e.adjustMathMLAttributes(r)),"http://www.w3.org/2000/svg"==e.currentStackItem().namespaceURI&&(t=e.adjustSVGTagNameCase(t),r=e.adjustSVGAttributes(r)),r=e.adjustForeignAttributes(r),e.insertForeignElement(t,r,e.currentStackItem().namespaceURI,n)},t.inForeignContent.processEndTag=function(t){var r=e.currentStackItem(),n=e.openElements.length-1;for(r.localName.toLowerCase()!=t&&e.parseError("unexpected-end-tag",{name:t});0!==n;){if(r.localName.toLowerCase()==t){for(;e.openElements.pop()!=r;);break}if(n-=1,!(r=e.openElements.item(n)).isForeign()){e.insertionMode.processEndTag(t);break}}},t.inForeignContent.processCharacters=function(t){var r=t.takeRemaining();r=r.replace(/\u0000/g,(function(t,r){return e.parseError("invalid-codepoint"),"�"})),e.framesetOk&&!u(r)&&(e.framesetOk=!1),e.insertText(r)},t.inHeadNoscript=Object.create(t.base),t.inHeadNoscript.start_tag_handlers={html:"startTagHtml",basefont:"startTagBasefontBgsoundLinkMetaNoframesStyle",bgsound:"startTagBasefontBgsoundLinkMetaNoframesStyle",link:"startTagBasefontBgsoundLinkMetaNoframesStyle",meta:"startTagBasefontBgsoundLinkMetaNoframesStyle",noframes:"startTagBasefontBgsoundLinkMetaNoframesStyle",style:"startTagBasefontBgsoundLinkMetaNoframesStyle",head:"startTagHeadNoscript",noscript:"startTagHeadNoscript","-default":"startTagOther"},t.inHeadNoscript.end_tag_handlers={noscript:"endTagNoscript",br:"endTagBr","-default":"endTagOther"},t.inHeadNoscript.processCharacters=function(t){var r=t.takeLeadingWhitespace();r&&e.insertText(r),t.length&&(e.parseError("unexpected-char-in-frameset"),this.anythingElse(),e.insertionMode.processCharacters(t))},t.inHeadNoscript.processComment=function(e){t.inHead.processComment(e)},t.inHeadNoscript.startTagBasefontBgsoundLinkMetaNoframesStyle=function(e,r){t.inHead.processStartTag(e,r)},t.inHeadNoscript.startTagHeadNoscript=function(t,r){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inHeadNoscript.startTagOther=function(t,r){e.parseError("unexpected-start-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,r)},t.inHeadNoscript.endTagBr=function(t,r){e.parseError("unexpected-end-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t,r)},t.inHeadNoscript.endTagNoscript=function(t,r){e.popElement(),e.setInsertionMode("inHead")},t.inHeadNoscript.endTagOther=function(t,r){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inHeadNoscript.anythingElse=function(){e.popElement(),e.setInsertionMode("inHead")},t.inFrameset=Object.create(t.base),t.inFrameset.start_tag_handlers={html:"startTagHtml",frameset:"startTagFrameset",frame:"startTagFrame",noframes:"startTagNoframes","-default":"startTagOther"},t.inFrameset.end_tag_handlers={frameset:"endTagFrameset",noframes:"endTagNoframes","-default":"endTagOther"},t.inFrameset.processCharacters=function(t){e.parseError("unexpected-char-in-frameset")},t.inFrameset.startTagFrameset=function(t,r){e.insertElement(t,r)},t.inFrameset.startTagFrame=function(t,r){e.insertSelfClosingElement(t,r)},t.inFrameset.startTagNoframes=function(e,r){t.inBody.processStartTag(e,r)},t.inFrameset.startTagOther=function(t,r){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inFrameset.endTagFrameset=function(t,r){"html"==e.currentStackItem().localName?e.parseError("unexpected-frameset-in-frameset-innerhtml"):e.popElement(),e.context||"frameset"==e.currentStackItem().localName||e.setInsertionMode("afterFrameset")},t.inFrameset.endTagNoframes=function(e){t.inBody.processEndTag(e)},t.inFrameset.endTagOther=function(t){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inTable=Object.create(t.base),t.inTable.start_tag_handlers={html:"startTagHtml",caption:"startTagCaption",colgroup:"startTagColgroup",col:"startTagCol",table:"startTagTable",tbody:"startTagRowGroup",tfoot:"startTagRowGroup",thead:"startTagRowGroup",td:"startTagImplyTbody",th:"startTagImplyTbody",tr:"startTagImplyTbody",style:"startTagStyleScript",script:"startTagStyleScript",input:"startTagInput",form:"startTagForm","-default":"startTagOther"},t.inTable.end_tag_handlers={table:"endTagTable",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfoot:"endTagIgnore",th:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTable.processCharacters=function(r){if(e.currentStackItem().isFosterParenting()){var n=e.insertionModeName;e.setInsertionMode("inTableText"),e.originalInsertionMode=n,e.insertionMode.processCharacters(r)}else e.redirectAttachToFosterParent=!0,t.inBody.processCharacters(r),e.redirectAttachToFosterParent=!1},t.inTable.startTagCaption=function(t,r){e.openElements.popUntilTableScopeMarker(),e.activeFormattingElements.push(l),e.insertElement(t,r),e.setInsertionMode("inCaption")},t.inTable.startTagColgroup=function(t,r){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,r),e.setInsertionMode("inColumnGroup")},t.inTable.startTagCol=function(t,r){this.startTagColgroup("colgroup",[]),e.insertionMode.processStartTag(t,r)},t.inTable.startTagRowGroup=function(t,r){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,r),e.setInsertionMode("inTableBody")},t.inTable.startTagImplyTbody=function(t,r){this.startTagRowGroup("tbody",[]),e.insertionMode.processStartTag(t,r)},t.inTable.startTagTable=function(t,r){e.parseError("unexpected-start-tag-implies-end-tag",{startName:"table",endName:"table"}),e.insertionMode.processEndTag("table"),e.context||e.insertionMode.processStartTag(t,r)},t.inTable.startTagStyleScript=function(e,r){t.inHead.processStartTag(e,r)},t.inTable.startTagInput=function(t,r){for(var n in r)if("type"==r[n].nodeName.toLowerCase()){if("hidden"==r[n].nodeValue.toLowerCase())return e.parseError("unexpected-hidden-input-in-table"),e.insertElement(t,r),void e.openElements.pop();break}this.startTagOther(t,r)},t.inTable.startTagForm=function(t,r){e.parseError("unexpected-form-in-table"),e.form||(e.insertElement(t,r),e.form=e.currentStackItem(),e.openElements.pop())},t.inTable.startTagOther=function(r,n,a){e.parseError("unexpected-start-tag-implies-table-voodoo",{name:r}),e.redirectAttachToFosterParent=!0,t.inBody.processStartTag(r,n,a),e.redirectAttachToFosterParent=!1},t.inTable.endTagTable=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early-named",{gotName:"table",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("table"),e.resetInsertionMode()):(n.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inTable.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inTable.endTagOther=function(r){e.parseError("unexpected-end-tag-implies-table-voodoo",{name:r}),e.redirectAttachToFosterParent=!0,t.inBody.processEndTag(r),e.redirectAttachToFosterParent=!1},t.inTableText=Object.create(t.base),t.inTableText.flushCharacters=function(){var t=e.pendingTableCharacters.join("");d(t)?e.insertText(t):(e.redirectAttachToFosterParent=!0,e.reconstructActiveFormattingElements(),e.insertText(t),e.framesetOk=!1,e.redirectAttachToFosterParent=!1),e.pendingTableCharacters=[]},t.inTableText.processComment=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processComment(t)},t.inTableText.processEOF=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEOF()},t.inTableText.processCharacters=function(t){var r=t.takeRemaining();(r=r.replace(/\u0000/g,(function(t,r){return e.parseError("invalid-codepoint"),""})))&&e.pendingTableCharacters.push(r)},t.inTableText.processStartTag=function(t,r,n){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processStartTag(t,r,n)},t.inTableText.processEndTag=function(t,r){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEndTag(t,r)},t.inTableBody=Object.create(t.base),t.inTableBody.start_tag_handlers={html:"startTagHtml",tr:"startTagTr",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther","-default":"startTagOther"},t.inTableBody.end_tag_handlers={table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTableBody.processCharacters=function(e){t.inTable.processCharacters(e)},t.inTableBody.startTagTr=function(t,r){e.openElements.popUntilTableBodyScopeMarker(),e.insertElement(t,r),e.setInsertionMode("inRow")},t.inTableBody.startTagTableCell=function(t,r){e.parseError("unexpected-cell-in-table-body",{name:t}),this.startTagTr("tr",[]),e.insertionMode.processStartTag(t,r)},t.inTableBody.startTagTableOther=function(t,r){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processStartTag(t,r)):e.parseError("unexpected-start-tag",{name:t})},t.inTableBody.startTagOther=function(e,r){t.inTable.processStartTag(e,r)},t.inTableBody.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(e.openElements.popUntilTableBodyScopeMarker(),e.popElement(),e.setInsertionMode("inTable")):e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagTable=function(t){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inTableBody.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagOther=function(e){t.inTable.processEndTag(e)},t.inSelect=Object.create(t.base),t.inSelect.start_tag_handlers={html:"startTagHtml",option:"startTagOption",optgroup:"startTagOptgroup",select:"startTagSelect",input:"startTagInput",keygen:"startTagInput",textarea:"startTagInput",script:"startTagScript","-default":"startTagOther"},t.inSelect.end_tag_handlers={option:"endTagOption",optgroup:"endTagOptgroup",select:"endTagSelect",caption:"endTagTableElements",table:"endTagTableElements",tbody:"endTagTableElements",tfoot:"endTagTableElements",thead:"endTagTableElements",tr:"endTagTableElements",td:"endTagTableElements",th:"endTagTableElements","-default":"endTagOther"},t.inSelect.processCharacters=function(t){var r=t.takeRemaining();(r=r.replace(/\u0000/g,(function(t,r){return e.parseError("invalid-codepoint"),""})))&&e.insertText(r)},t.inSelect.startTagOption=function(t,r){"option"==e.currentStackItem().localName&&e.popElement(),e.insertElement(t,r)},t.inSelect.startTagOptgroup=function(t,r){"option"==e.currentStackItem().localName&&e.popElement(),"optgroup"==e.currentStackItem().localName&&e.popElement(),e.insertElement(t,r)},t.inSelect.endTagOption=function(t){"option"===e.currentStackItem().localName?e.popElement():e.parseError("unexpected-end-tag-in-select",{name:t})},t.inSelect.endTagOptgroup=function(t){"option"==e.currentStackItem().localName&&"optgroup"==e.openElements.item(e.openElements.length-2).localName&&e.popElement(),"optgroup"==e.currentStackItem().localName?e.popElement():e.parseError("unexpected-end-tag-in-select",{name:"optgroup"})},t.inSelect.startTagSelect=function(t){e.parseError("unexpected-select-in-select"),this.endTagSelect("select")},t.inSelect.endTagSelect=function(t){e.openElements.inTableScope("select")?(e.openElements.popUntilPopped("select"),e.resetInsertionMode()):e.parseError("unexpected-end-tag",{name:t})},t.inSelect.startTagInput=function(t,r){e.parseError("unexpected-input-in-select"),e.openElements.inSelectScope("select")&&(this.endTagSelect("select"),e.insertionMode.processStartTag(t,r))},t.inSelect.startTagScript=function(e,r){t.inHead.processStartTag(e,r)},t.inSelect.endTagTableElements=function(t){e.parseError("unexpected-end-tag-in-select",{name:t}),e.openElements.inTableScope(t)&&(this.endTagSelect("select"),e.insertionMode.processEndTag(t))},t.inSelect.startTagOther=function(t,r){e.parseError("unexpected-start-tag-in-select",{name:t})},t.inSelect.endTagOther=function(t){e.parseError("unexpected-end-tag-in-select",{name:t})},t.inSelectInTable=Object.create(t.base),t.inSelectInTable.start_tag_handlers={caption:"startTagTable",table:"startTagTable",tbody:"startTagTable",tfoot:"startTagTable",thead:"startTagTable",tr:"startTagTable",td:"startTagTable",th:"startTagTable","-default":"startTagOther"},t.inSelectInTable.end_tag_handlers={caption:"endTagTable",table:"endTagTable",tbody:"endTagTable",tfoot:"endTagTable",thead:"endTagTable",tr:"endTagTable",td:"endTagTable",th:"endTagTable","-default":"endTagOther"},t.inSelectInTable.processCharacters=function(e){t.inSelect.processCharacters(e)},t.inSelectInTable.startTagTable=function(t,r){e.parseError("unexpected-table-element-start-tag-in-select-in-table",{name:t}),this.endTagOther("select"),e.insertionMode.processStartTag(t,r)},t.inSelectInTable.startTagOther=function(e,r,n){t.inSelect.processStartTag(e,r,n)},t.inSelectInTable.endTagTable=function(t){e.parseError("unexpected-table-element-end-tag-in-select-in-table",{name:t}),e.openElements.inTableScope(t)&&(this.endTagOther("select"),e.insertionMode.processEndTag(t))},t.inSelectInTable.endTagOther=function(e){t.inSelect.processEndTag(e)},t.inRow=Object.create(t.base),t.inRow.start_tag_handlers={html:"startTagHtml",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inRow.end_tag_handlers={tr:"endTagTr",table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore","-default":"endTagOther"},t.inRow.processCharacters=function(e){t.inTable.processCharacters(e)},t.inRow.startTagTableCell=function(t,r){e.openElements.popUntilTableRowScopeMarker(),e.insertElement(t,r),e.setInsertionMode("inCell"),e.activeFormattingElements.push(l)},t.inRow.startTagTableOther=function(t,r){var n=this.ignoreEndTagTr();this.endTagTr("tr"),n||e.insertionMode.processStartTag(t,r)},t.inRow.startTagOther=function(e,r,n){t.inTable.processStartTag(e,r,n)},t.inRow.endTagTr=function(t){this.ignoreEndTagTr()?(n.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.openElements.popUntilTableRowScopeMarker(),e.popElement(),e.setInsertionMode("inTableBody"))},t.inRow.endTagTable=function(t){var r=this.ignoreEndTagTr();this.endTagTr("tr"),r||e.insertionMode.processEndTag(t)},t.inRow.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(this.endTagTr("tr"),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inRow.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-row",{name:t})},t.inRow.endTagOther=function(e){t.inTable.processEndTag(e)},t.inRow.ignoreEndTagTr=function(){return!e.openElements.inTableScope("tr")},t.afterAfterFrameset=Object.create(t.base),t.afterAfterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoFrames","-default":"startTagOther"},t.afterAfterFrameset.processEOF=function(){},t.afterAfterFrameset.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterFrameset.processCharacters=function(t){for(var r=t.takeRemaining(),n="",a=0;a0&&this.currentStackItem().isForeign()},g.prototype.isSelfClosingFlagAcknowledged=function(){return this.selfClosingFlagAcknowledged},g.prototype.createElement=function(e,t,r){throw new Error("Not implemented")},g.prototype.attachNode=function(e,t){throw new Error("Not implemented")},g.prototype.attachNodeToFosterParent=function(e,t,r){throw new Error("Not implemented")},g.prototype.detachFromParent=function(e){throw new Error("Not implemented")},g.prototype.addAttributesToElement=function(e,t){throw new Error("Not implemented")},g.prototype.insertHtmlElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","html",e);return this.attachNode(t,this.document),this.openElements.pushHtmlElement(new c("http://www.w3.org/1999/xhtml","html",e,t)),t},g.prototype.insertHeadElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","head",e);return this.head=new c("http://www.w3.org/1999/xhtml","head",e,t),this.attachNode(t,this.openElements.top.node),this.openElements.pushHeadElement(this.head),t},g.prototype.insertBodyElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","body",e);return this.attachNode(t,this.openElements.top.node),this.openElements.pushBodyElement(new c("http://www.w3.org/1999/xhtml","body",e,t)),t},g.prototype.insertIntoFosterParent=function(e){var t=this.openElements.findIndex("table"),r=this.openElements.item(t).node;if(0===t)return this.attachNode(e,r);this.attachNodeToFosterParent(e,r,this.openElements.item(t-1).node)},g.prototype.insertElement=function(e,t,r,n){r||(r="http://www.w3.org/1999/xhtml");var a=this.createElement(r,e,t);this.shouldFosterParent()?this.insertIntoFosterParent(a):this.attachNode(a,this.openElements.top.node),n||this.openElements.push(new c(r,e,t,a))},g.prototype.insertFormattingElement=function(e,t){this.insertElement(e,t,"http://www.w3.org/1999/xhtml"),this.appendElementToActiveFormattingElements(this.currentStackItem())},g.prototype.insertSelfClosingElement=function(e,t){this.selfClosingFlagAcknowledged=!0,this.insertElement(e,t,"http://www.w3.org/1999/xhtml",!0)},g.prototype.insertForeignElement=function(e,t,r,n){n&&(this.selfClosingFlagAcknowledged=!0),this.insertElement(e,t,r,n)},g.prototype.insertComment=function(e,t){throw new Error("Not implemented")},g.prototype.insertDoctype=function(e,t,r){throw new Error("Not implemented")},g.prototype.insertText=function(e){throw new Error("Not implemented")},g.prototype.currentStackItem=function(){return this.openElements.top},g.prototype.popElement=function(){return this.openElements.pop()},g.prototype.shouldFosterParent=function(){return this.redirectAttachToFosterParent&&this.currentStackItem().isFosterParenting()},g.prototype.generateImpliedEndTags=function(e){var t=this.openElements.top.localName;-1!=["dd","dt","li","option","optgroup","p","rp","rt"].indexOf(t)&&t!=e&&(this.popElement(),this.generateImpliedEndTags(e))},g.prototype.reconstructActiveFormattingElements=function(){if(0!==this.activeFormattingElements.length){var e=this.activeFormattingElements.length-1,t=this.activeFormattingElements[e];if(t!=l&&!this.openElements.contains(t)){for(;t!=l&&!this.openElements.contains(t)&&(e-=1,t=this.activeFormattingElements[e]););for(;;){e+=1,t=this.activeFormattingElements[e],this.insertElement(t.localName,t.attributes);var r=this.currentStackItem();if(this.activeFormattingElements[e]=r,r==this.activeFormattingElements[this.activeFormattingElements.length-1])break}}}},g.prototype.ensureNoahsArkCondition=function(e){if(!(this.activeFormattingElements.length<3)){for(var t=[],r=e.attributes.length,n=this.activeFormattingElements.length-1;n>=0&&(c=this.activeFormattingElements[n])!==l;n--)e.localName===c.localName&&e.namespaceURI===c.namespaceURI&&c.attributes.length==r&&t.push(c);if(!(t.length<3)){var a=[],o=e.attributes;for(n=0;n=0&&this.activeFormattingElements.splice(t,1)},g.prototype.elementInActiveFormattingElements=function(e){for(var t=this.activeFormattingElements,r=t.length-1;r>=0&&t[r]!=l;r--)if(t[r].localName==e)return t[r];return!1},g.prototype.clearActiveFormattingElements=function(){for(;0!==this.activeFormattingElements.length&&this.activeFormattingElements.pop()!=l;);},g.prototype.reparentChildren=function(e,t){throw new Error("Not implemented")},g.prototype.setFragmentContext=function(e){this.context=e},g.prototype.parseError=function(e,t){if(this.errorHandler){var r=function(e,t){return e.replace(new RegExp("{[0-9a-z-]+}","gi"),(function(e){return t[e.slice(1,-1)]||e}))}(a[e],t);this.errorHandler.error(r,this.tokenizer._inputStream.location(),e)}},g.prototype.resetInsertionMode=function(){for(var e=!1,t=null,r=this.openElements.length-1;r>=0;r--){if(t=this.openElements.item(r),0===r&&(n.ok(this.context),e=!0,t=new c("http://www.w3.org/1999/xhtml",this.context,[],null)),"http://www.w3.org/1999/xhtml"===t.namespaceURI){if("select"===t.localName)return this.setInsertionMode("inSelect");if("td"===t.localName||"th"===t.localName)return this.setInsertionMode("inCell");if("tr"===t.localName)return this.setInsertionMode("inRow");if("tbody"===t.localName||"thead"===t.localName||"tfoot"===t.localName)return this.setInsertionMode("inTableBody");if("caption"===t.localName)return this.setInsertionMode("inCaption");if("colgroup"===t.localName)return this.setInsertionMode("inColumnGroup");if("table"===t.localName)return this.setInsertionMode("inTable");if("head"===t.localName)return this.setInsertionMode("inHead");if("body"===t.localName)return this.setInsertionMode("inBody");if("frameset"===t.localName)return this.setInsertionMode("inFrameset");if("html"===t.localName)return this.openElements.headElement?this.setInsertionMode("afterHead"):this.setInsertionMode("beforeHead")}if(e)return this.setInsertionMode("inBody")}},g.prototype.processGenericRCDATAStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(i.RCDATA),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.processGenericRawTextStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(i.RAWTEXT),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.adjustMathMLAttributes=function(e){return e.forEach((function(e){e.namespaceURI="http://www.w3.org/1998/Math/MathML",o.MATHMLAttributeMap[e.nodeName]&&(e.nodeName=o.MATHMLAttributeMap[e.nodeName])})),e},g.prototype.adjustSVGTagNameCase=function(e){return o.SVGTagMap[e]||e},g.prototype.adjustSVGAttributes=function(e){return e.forEach((function(e){e.namespaceURI="http://www.w3.org/2000/svg",o.SVGAttributeMap[e.nodeName]&&(e.nodeName=o.SVGAttributeMap[e.nodeName])})),e},g.prototype.adjustForeignAttributes=function(e){for(var t=0;t' instead.","expected-tag-name-but-got-question-mark":"Expected tag name. Got '?' instead. (HTML doesn't support processing instructions.)","expected-tag-name":"Expected tag name. Got something else instead.","expected-closing-tag-but-got-right-bracket":"Expected closing tag. Got '>' instead. Ignoring ''.","expected-closing-tag-but-got-eof":"Expected closing tag. Unexpected end of file.","expected-closing-tag-but-got-char":"Expected closing tag. Unexpected character '{data}' found.","eof-in-tag-name":"Unexpected end of file in the tag name.","expected-attribute-name-but-got-eof":"Unexpected end of file. Expected attribute name instead.","eof-in-attribute-name":"Unexpected end of file in attribute name.","invalid-character-in-attribute-name":"Invalid character in attribute name.","duplicate-attribute":"Dropped duplicate attribute '{name}' on tag.","expected-end-of-tag-but-got-eof":"Unexpected end of file. Expected = or end of tag.","expected-attribute-value-but-got-eof":"Unexpected end of file. Expected attribute value.","expected-attribute-value-but-got-right-bracket":"Expected attribute value. Got '>' instead.","unexpected-character-in-unquoted-attribute-value":"Unexpected character in unquoted attribute","invalid-character-after-attribute-name":"Unexpected character after attribute name.","unexpected-character-after-attribute-value":"Unexpected character after attribute value.","eof-in-attribute-value-double-quote":'Unexpected end of file in attribute value (").',"eof-in-attribute-value-single-quote":"Unexpected end of file in attribute value (').","eof-in-attribute-value-no-quotes":"Unexpected end of file in attribute value.","eof-after-attribute-value":"Unexpected end of file after attribute value.","unexpected-eof-after-solidus-in-tag":"Unexpected end of file in tag. Expected >.","unexpected-character-after-solidus-in-tag":"Unexpected character after / in tag. Expected >.","expected-dashes-or-doctype":"Expected '--' or 'DOCTYPE'. Not found.","unexpected-bang-after-double-dash-in-comment":"Unexpected ! after -- in comment.","incorrect-comment":"Incorrect comment.","eof-in-comment":"Unexpected end of file in comment.","eof-in-comment-end-dash":"Unexpected end of file in comment (-).","unexpected-dash-after-double-dash-in-comment":"Unexpected '-' after '--' found in comment.","eof-in-comment-double-dash":"Unexpected end of file in comment (--).","eof-in-comment-end-bang-state":"Unexpected end of file in comment.","unexpected-char-in-comment":"Unexpected character in comment found.","need-space-after-doctype":"No space after literal string 'DOCTYPE'.","expected-doctype-name-but-got-right-bracket":"Unexpected > character. Expected DOCTYPE name.","expected-doctype-name-but-got-eof":"Unexpected end of file. Expected DOCTYPE name.","eof-in-doctype-name":"Unexpected end of file in DOCTYPE name.","eof-in-doctype":"Unexpected end of file in DOCTYPE.","expected-space-or-right-bracket-in-doctype":"Expected space or '>'. Got '{data}'.","unexpected-end-of-doctype":"Unexpected end of DOCTYPE.","unexpected-char-in-doctype":"Unexpected character in DOCTYPE.","eof-in-bogus-doctype":"Unexpected end of file in bogus doctype.","eof-in-innerhtml":"Unexpected EOF in inner html mode.","unexpected-doctype":"Unexpected DOCTYPE. Ignored.","non-html-root":"html needs to be the first start tag.","expected-doctype-but-got-eof":"Unexpected End of file. Expected DOCTYPE.","unknown-doctype":"Erroneous DOCTYPE. Expected .","quirky-doctype":"Quirky doctype. Expected .","almost-standards-doctype":"Almost standards mode doctype. Expected .","obsolete-doctype":"Obsolete doctype. Expected .","expected-doctype-but-got-chars":"Non-space characters found without seeing a doctype first. Expected e.g. .","expected-doctype-but-got-start-tag":"Start tag seen without seeing a doctype first. Expected e.g. .","expected-doctype-but-got-end-tag":"End tag seen without seeing a doctype first. Expected e.g. .","end-tag-after-implied-root":"Unexpected end tag ({name}) after the (implied) root element.","expected-named-closing-tag-but-got-eof":"Unexpected end of file. Expected end tag ({name}).","two-heads-are-not-better-than-one":"Unexpected start tag head in existing head. Ignored.","unexpected-end-tag":"Unexpected end tag ({name}). Ignored.","unexpected-implied-end-tag":"End tag {name} implied, but there were open elements.","unexpected-start-tag-out-of-my-head":"Unexpected start tag ({name}) that can be in head. Moved.","unexpected-start-tag":"Unexpected start tag ({name}).","missing-end-tag":"Missing end tag ({name}).","missing-end-tags":"Missing end tags ({name}).","unexpected-start-tag-implies-end-tag":"Unexpected start tag ({startName}) implies end tag ({endName}).","unexpected-start-tag-treated-as":"Unexpected start tag ({originalName}). Treated as {newName}.","deprecated-tag":"Unexpected start tag {name}. Don't use it!","unexpected-start-tag-ignored":"Unexpected start tag {name}. Ignored.","expected-one-end-tag-but-got-another":"Unexpected end tag ({gotName}). Missing end tag ({expectedName}).","end-tag-too-early":"End tag ({name}) seen too early. Expected other end tag.","end-tag-too-early-named":"Unexpected end tag ({gotName}). Expected end tag ({expectedName}.","end-tag-too-early-ignored":"End tag ({name}) seen too early. Ignored.","adoption-agency-1.1":"End tag ({name}) violates step 1, paragraph 1 of the adoption agency algorithm.","adoption-agency-1.2":"End tag ({name}) violates step 1, paragraph 2 of the adoption agency algorithm.","adoption-agency-1.3":"End tag ({name}) violates step 1, paragraph 3 of the adoption agency algorithm.","adoption-agency-4.4":"End tag ({name}) violates step 4, paragraph 4 of the adoption agency algorithm.","unexpected-end-tag-treated-as":"Unexpected end tag ({originalName}). Treated as {newName}.","no-end-tag":"This element ({name}) has no end tag.","unexpected-implied-end-tag-in-table":"Unexpected implied end tag ({name}) in the table phase.","unexpected-implied-end-tag-in-table-body":"Unexpected implied end tag ({name}) in the table body phase.","unexpected-char-implies-table-voodoo":"Unexpected non-space characters in table context caused voodoo mode.","unexpected-hidden-input-in-table":"Unexpected input with type hidden in table context.","unexpected-form-in-table":"Unexpected form in table context.","unexpected-start-tag-implies-table-voodoo":"Unexpected start tag ({name}) in table context caused voodoo mode.","unexpected-end-tag-implies-table-voodoo":"Unexpected end tag ({name}) in table context caused voodoo mode.","unexpected-cell-in-table-body":"Unexpected table cell start tag ({name}) in the table body phase.","unexpected-cell-end-tag":"Got table cell end tag ({name}) while required end tags are missing.","unexpected-end-tag-in-table-body":"Unexpected end tag ({name}) in the table body phase. Ignored.","unexpected-implied-end-tag-in-table-row":"Unexpected implied end tag ({name}) in the table row phase.","unexpected-end-tag-in-table-row":"Unexpected end tag ({name}) in the table row phase. Ignored.","unexpected-select-in-select":"Unexpected select start tag in the select phase treated as select end tag.","unexpected-input-in-select":"Unexpected input start tag in the select phase.","unexpected-start-tag-in-select":"Unexpected start tag token ({name}) in the select phase. Ignored.","unexpected-end-tag-in-select":"Unexpected end tag ({name}) in the select phase. Ignored.","unexpected-table-element-start-tag-in-select-in-table":"Unexpected table element start tag ({name}) in the select in table phase.","unexpected-table-element-end-tag-in-select-in-table":"Unexpected table element end tag ({name}) in the select in table phase.","unexpected-char-after-body":"Unexpected non-space characters in the after body phase.","unexpected-start-tag-after-body":"Unexpected start tag token ({name}) in the after body phase.","unexpected-end-tag-after-body":"Unexpected end tag token ({name}) in the after body phase.","unexpected-char-in-frameset":"Unepxected characters in the frameset phase. Characters ignored.","unexpected-start-tag-in-frameset":"Unexpected start tag token ({name}) in the frameset phase. Ignored.","unexpected-frameset-in-frameset-innerhtml":"Unexpected end tag token (frameset in the frameset phase (innerHTML).","unexpected-end-tag-in-frameset":"Unexpected end tag token ({name}) in the frameset phase. Ignored.","unexpected-char-after-frameset":"Unexpected non-space characters in the after frameset phase. Ignored.","unexpected-start-tag-after-frameset":"Unexpected start tag ({name}) in the after frameset phase. Ignored.","unexpected-end-tag-after-frameset":"Unexpected end tag ({name}) in the after frameset phase. Ignored.","expected-eof-but-got-char":"Unexpected non-space characters. Expected end of file.","expected-eof-but-got-start-tag":"Unexpected start tag ({name}). Expected end of file.","expected-eof-but-got-end-tag":"Unexpected end tag ({name}). Expected end of file.","unexpected-end-table-in-caption":"Unexpected end table tag in caption. Generates implied end caption.","end-html-in-innerhtml":"Unexpected html end tag in inner html mode.","eof-in-table":"Unexpected end of file. Expected table content.","eof-in-script":"Unexpected end of file. Expected script content.","non-void-element-with-trailing-solidus":"Trailing solidus not allowed on element {name}.","unexpected-html-element-in-foreign-content":'HTML start tag "{name}" in a foreign namespace context.',"unexpected-start-tag-in-table":"Unexpected {name}. Expected table content."}},{}],9:[function(e,t,r){var n=e("./SAXTreeBuilder").SAXTreeBuilder,a=e("../Tokenizer").Tokenizer,o=e("./TreeParser").TreeParser;function i(){this.contentHandler=null,this._errorHandler=null,this._treeBuilder=new n,this._tokenizer=new a(this._treeBuilder),this._scriptingEnabled=!1}i.prototype.parse=function(e,t){t&&this._treeBuilder.setFragmentContext(t),this._tokenizer.tokenize(e);var r=this._treeBuilder.document;r&&new o(this.contentHandler).parse(r)},i.prototype.parseFragment=function(e,t){this._treeBuilder.setFragmentContext(t),this._tokenizer.tokenize(e);var r=this._treeBuilder.getFragment();r&&new o(this.contentHandler).parse(r)},Object.defineProperty(i.prototype,"scriptingEnabled",{get:function(){return this._scriptingEnabled},set:function(e){this._scriptingEnabled=e,this._treeBuilder.scriptingEnabled=e}}),Object.defineProperty(i.prototype,"errorHandler",{get:function(){return this._errorHandler},set:function(e){this._errorHandler=e,this._treeBuilder.errorHandler=e}}),r.SAXParser=i},{"../Tokenizer":5,"./SAXTreeBuilder":10,"./TreeParser":11}],10:[function(e,t,r){var n=e("util"),a=e("../TreeBuilder").TreeBuilder;function o(){a.call(this)}function i(e,t){for(var r=0;r",gt:">","GT;":">",GT:">","Gt;":"≫","gtdot;":"⋗","gtlPar;":"⦕","gtquest;":"⩼","gtrapprox;":"⪆","gtrarr;":"⥸","gtrdot;":"⋗","gtreqless;":"⋛","gtreqqless;":"⪌","gtrless;":"≷","gtrsim;":"≳","gvertneqq;":"≩︀","gvnE;":"≩︀","Hacek;":"ˇ","hairsp;":" ","half;":"½","hamilt;":"ℋ","HARDcy;":"Ъ","hardcy;":"ъ","harrcir;":"⥈","harr;":"↔","hArr;":"⇔","harrw;":"↭","Hat;":"^","hbar;":"ℏ","Hcirc;":"Ĥ","hcirc;":"ĥ","hearts;":"♥","heartsuit;":"♥","hellip;":"…","hercon;":"⊹","hfr;":"𝔥","Hfr;":"ℌ","HilbertSpace;":"ℋ","hksearow;":"⤥","hkswarow;":"⤦","hoarr;":"⇿","homtht;":"∻","hookleftarrow;":"↩","hookrightarrow;":"↪","hopf;":"𝕙","Hopf;":"ℍ","horbar;":"―","HorizontalLine;":"─","hscr;":"𝒽","Hscr;":"ℋ","hslash;":"ℏ","Hstrok;":"Ħ","hstrok;":"ħ","HumpDownHump;":"≎","HumpEqual;":"≏","hybull;":"⁃","hyphen;":"‐","Iacute;":"Í",Iacute:"Í","iacute;":"í",iacute:"í","ic;":"⁣","Icirc;":"Î",Icirc:"Î","icirc;":"î",icirc:"î","Icy;":"И","icy;":"и","Idot;":"İ","IEcy;":"Е","iecy;":"е","iexcl;":"¡",iexcl:"¡","iff;":"⇔","ifr;":"𝔦","Ifr;":"ℑ","Igrave;":"Ì",Igrave:"Ì","igrave;":"ì",igrave:"ì","ii;":"ⅈ","iiiint;":"⨌","iiint;":"∭","iinfin;":"⧜","iiota;":"℩","IJlig;":"IJ","ijlig;":"ij","Imacr;":"Ī","imacr;":"ī","image;":"ℑ","ImaginaryI;":"ⅈ","imagline;":"ℐ","imagpart;":"ℑ","imath;":"ı","Im;":"ℑ","imof;":"⊷","imped;":"Ƶ","Implies;":"⇒","incare;":"℅","in;":"∈","infin;":"∞","infintie;":"⧝","inodot;":"ı","intcal;":"⊺","int;":"∫","Int;":"∬","integers;":"ℤ","Integral;":"∫","intercal;":"⊺","Intersection;":"⋂","intlarhk;":"⨗","intprod;":"⨼","InvisibleComma;":"⁣","InvisibleTimes;":"⁢","IOcy;":"Ё","iocy;":"ё","Iogon;":"Į","iogon;":"į","Iopf;":"𝕀","iopf;":"𝕚","Iota;":"Ι","iota;":"ι","iprod;":"⨼","iquest;":"¿",iquest:"¿","iscr;":"𝒾","Iscr;":"ℐ","isin;":"∈","isindot;":"⋵","isinE;":"⋹","isins;":"⋴","isinsv;":"⋳","isinv;":"∈","it;":"⁢","Itilde;":"Ĩ","itilde;":"ĩ","Iukcy;":"І","iukcy;":"і","Iuml;":"Ï",Iuml:"Ï","iuml;":"ï",iuml:"ï","Jcirc;":"Ĵ","jcirc;":"ĵ","Jcy;":"Й","jcy;":"й","Jfr;":"𝔍","jfr;":"𝔧","jmath;":"ȷ","Jopf;":"𝕁","jopf;":"𝕛","Jscr;":"𝒥","jscr;":"𝒿","Jsercy;":"Ј","jsercy;":"ј","Jukcy;":"Є","jukcy;":"є","Kappa;":"Κ","kappa;":"κ","kappav;":"ϰ","Kcedil;":"Ķ","kcedil;":"ķ","Kcy;":"К","kcy;":"к","Kfr;":"𝔎","kfr;":"𝔨","kgreen;":"ĸ","KHcy;":"Х","khcy;":"х","KJcy;":"Ќ","kjcy;":"ќ","Kopf;":"𝕂","kopf;":"𝕜","Kscr;":"𝒦","kscr;":"𝓀","lAarr;":"⇚","Lacute;":"Ĺ","lacute;":"ĺ","laemptyv;":"⦴","lagran;":"ℒ","Lambda;":"Λ","lambda;":"λ","lang;":"⟨","Lang;":"⟪","langd;":"⦑","langle;":"⟨","lap;":"⪅","Laplacetrf;":"ℒ","laquo;":"«",laquo:"«","larrb;":"⇤","larrbfs;":"⤟","larr;":"←","Larr;":"↞","lArr;":"⇐","larrfs;":"⤝","larrhk;":"↩","larrlp;":"↫","larrpl;":"⤹","larrsim;":"⥳","larrtl;":"↢","latail;":"⤙","lAtail;":"⤛","lat;":"⪫","late;":"⪭","lates;":"⪭︀","lbarr;":"⤌","lBarr;":"⤎","lbbrk;":"❲","lbrace;":"{","lbrack;":"[","lbrke;":"⦋","lbrksld;":"⦏","lbrkslu;":"⦍","Lcaron;":"Ľ","lcaron;":"ľ","Lcedil;":"Ļ","lcedil;":"ļ","lceil;":"⌈","lcub;":"{","Lcy;":"Л","lcy;":"л","ldca;":"⤶","ldquo;":"“","ldquor;":"„","ldrdhar;":"⥧","ldrushar;":"⥋","ldsh;":"↲","le;":"≤","lE;":"≦","LeftAngleBracket;":"⟨","LeftArrowBar;":"⇤","leftarrow;":"←","LeftArrow;":"←","Leftarrow;":"⇐","LeftArrowRightArrow;":"⇆","leftarrowtail;":"↢","LeftCeiling;":"⌈","LeftDoubleBracket;":"⟦","LeftDownTeeVector;":"⥡","LeftDownVectorBar;":"⥙","LeftDownVector;":"⇃","LeftFloor;":"⌊","leftharpoondown;":"↽","leftharpoonup;":"↼","leftleftarrows;":"⇇","leftrightarrow;":"↔","LeftRightArrow;":"↔","Leftrightarrow;":"⇔","leftrightarrows;":"⇆","leftrightharpoons;":"⇋","leftrightsquigarrow;":"↭","LeftRightVector;":"⥎","LeftTeeArrow;":"↤","LeftTee;":"⊣","LeftTeeVector;":"⥚","leftthreetimes;":"⋋","LeftTriangleBar;":"⧏","LeftTriangle;":"⊲","LeftTriangleEqual;":"⊴","LeftUpDownVector;":"⥑","LeftUpTeeVector;":"⥠","LeftUpVectorBar;":"⥘","LeftUpVector;":"↿","LeftVectorBar;":"⥒","LeftVector;":"↼","lEg;":"⪋","leg;":"⋚","leq;":"≤","leqq;":"≦","leqslant;":"⩽","lescc;":"⪨","les;":"⩽","lesdot;":"⩿","lesdoto;":"⪁","lesdotor;":"⪃","lesg;":"⋚︀","lesges;":"⪓","lessapprox;":"⪅","lessdot;":"⋖","lesseqgtr;":"⋚","lesseqqgtr;":"⪋","LessEqualGreater;":"⋚","LessFullEqual;":"≦","LessGreater;":"≶","lessgtr;":"≶","LessLess;":"⪡","lesssim;":"≲","LessSlantEqual;":"⩽","LessTilde;":"≲","lfisht;":"⥼","lfloor;":"⌊","Lfr;":"𝔏","lfr;":"𝔩","lg;":"≶","lgE;":"⪑","lHar;":"⥢","lhard;":"↽","lharu;":"↼","lharul;":"⥪","lhblk;":"▄","LJcy;":"Љ","ljcy;":"љ","llarr;":"⇇","ll;":"≪","Ll;":"⋘","llcorner;":"⌞","Lleftarrow;":"⇚","llhard;":"⥫","lltri;":"◺","Lmidot;":"Ŀ","lmidot;":"ŀ","lmoustache;":"⎰","lmoust;":"⎰","lnap;":"⪉","lnapprox;":"⪉","lne;":"⪇","lnE;":"≨","lneq;":"⪇","lneqq;":"≨","lnsim;":"⋦","loang;":"⟬","loarr;":"⇽","lobrk;":"⟦","longleftarrow;":"⟵","LongLeftArrow;":"⟵","Longleftarrow;":"⟸","longleftrightarrow;":"⟷","LongLeftRightArrow;":"⟷","Longleftrightarrow;":"⟺","longmapsto;":"⟼","longrightarrow;":"⟶","LongRightArrow;":"⟶","Longrightarrow;":"⟹","looparrowleft;":"↫","looparrowright;":"↬","lopar;":"⦅","Lopf;":"𝕃","lopf;":"𝕝","loplus;":"⨭","lotimes;":"⨴","lowast;":"∗","lowbar;":"_","LowerLeftArrow;":"↙","LowerRightArrow;":"↘","loz;":"◊","lozenge;":"◊","lozf;":"⧫","lpar;":"(","lparlt;":"⦓","lrarr;":"⇆","lrcorner;":"⌟","lrhar;":"⇋","lrhard;":"⥭","lrm;":"‎","lrtri;":"⊿","lsaquo;":"‹","lscr;":"𝓁","Lscr;":"ℒ","lsh;":"↰","Lsh;":"↰","lsim;":"≲","lsime;":"⪍","lsimg;":"⪏","lsqb;":"[","lsquo;":"‘","lsquor;":"‚","Lstrok;":"Ł","lstrok;":"ł","ltcc;":"⪦","ltcir;":"⩹","lt;":"<",lt:"<","LT;":"<",LT:"<","Lt;":"≪","ltdot;":"⋖","lthree;":"⋋","ltimes;":"⋉","ltlarr;":"⥶","ltquest;":"⩻","ltri;":"◃","ltrie;":"⊴","ltrif;":"◂","ltrPar;":"⦖","lurdshar;":"⥊","luruhar;":"⥦","lvertneqq;":"≨︀","lvnE;":"≨︀","macr;":"¯",macr:"¯","male;":"♂","malt;":"✠","maltese;":"✠","Map;":"⤅","map;":"↦","mapsto;":"↦","mapstodown;":"↧","mapstoleft;":"↤","mapstoup;":"↥","marker;":"▮","mcomma;":"⨩","Mcy;":"М","mcy;":"м","mdash;":"—","mDDot;":"∺","measuredangle;":"∡","MediumSpace;":" ","Mellintrf;":"ℳ","Mfr;":"𝔐","mfr;":"𝔪","mho;":"℧","micro;":"µ",micro:"µ","midast;":"*","midcir;":"⫰","mid;":"∣","middot;":"·",middot:"·","minusb;":"⊟","minus;":"−","minusd;":"∸","minusdu;":"⨪","MinusPlus;":"∓","mlcp;":"⫛","mldr;":"…","mnplus;":"∓","models;":"⊧","Mopf;":"𝕄","mopf;":"𝕞","mp;":"∓","mscr;":"𝓂","Mscr;":"ℳ","mstpos;":"∾","Mu;":"Μ","mu;":"μ","multimap;":"⊸","mumap;":"⊸","nabla;":"∇","Nacute;":"Ń","nacute;":"ń","nang;":"∠⃒","nap;":"≉","napE;":"⩰̸","napid;":"≋̸","napos;":"ʼn","napprox;":"≉","natural;":"♮","naturals;":"ℕ","natur;":"♮","nbsp;":" ",nbsp:" ","nbump;":"≎̸","nbumpe;":"≏̸","ncap;":"⩃","Ncaron;":"Ň","ncaron;":"ň","Ncedil;":"Ņ","ncedil;":"ņ","ncong;":"≇","ncongdot;":"⩭̸","ncup;":"⩂","Ncy;":"Н","ncy;":"н","ndash;":"–","nearhk;":"⤤","nearr;":"↗","neArr;":"⇗","nearrow;":"↗","ne;":"≠","nedot;":"≐̸","NegativeMediumSpace;":"​","NegativeThickSpace;":"​","NegativeThinSpace;":"​","NegativeVeryThinSpace;":"​","nequiv;":"≢","nesear;":"⤨","nesim;":"≂̸","NestedGreaterGreater;":"≫","NestedLessLess;":"≪","NewLine;":"\n","nexist;":"∄","nexists;":"∄","Nfr;":"𝔑","nfr;":"𝔫","ngE;":"≧̸","nge;":"≱","ngeq;":"≱","ngeqq;":"≧̸","ngeqslant;":"⩾̸","nges;":"⩾̸","nGg;":"⋙̸","ngsim;":"≵","nGt;":"≫⃒","ngt;":"≯","ngtr;":"≯","nGtv;":"≫̸","nharr;":"↮","nhArr;":"⇎","nhpar;":"⫲","ni;":"∋","nis;":"⋼","nisd;":"⋺","niv;":"∋","NJcy;":"Њ","njcy;":"њ","nlarr;":"↚","nlArr;":"⇍","nldr;":"‥","nlE;":"≦̸","nle;":"≰","nleftarrow;":"↚","nLeftarrow;":"⇍","nleftrightarrow;":"↮","nLeftrightarrow;":"⇎","nleq;":"≰","nleqq;":"≦̸","nleqslant;":"⩽̸","nles;":"⩽̸","nless;":"≮","nLl;":"⋘̸","nlsim;":"≴","nLt;":"≪⃒","nlt;":"≮","nltri;":"⋪","nltrie;":"⋬","nLtv;":"≪̸","nmid;":"∤","NoBreak;":"⁠","NonBreakingSpace;":" ","nopf;":"𝕟","Nopf;":"ℕ","Not;":"⫬","not;":"¬",not:"¬","NotCongruent;":"≢","NotCupCap;":"≭","NotDoubleVerticalBar;":"∦","NotElement;":"∉","NotEqual;":"≠","NotEqualTilde;":"≂̸","NotExists;":"∄","NotGreater;":"≯","NotGreaterEqual;":"≱","NotGreaterFullEqual;":"≧̸","NotGreaterGreater;":"≫̸","NotGreaterLess;":"≹","NotGreaterSlantEqual;":"⩾̸","NotGreaterTilde;":"≵","NotHumpDownHump;":"≎̸","NotHumpEqual;":"≏̸","notin;":"∉","notindot;":"⋵̸","notinE;":"⋹̸","notinva;":"∉","notinvb;":"⋷","notinvc;":"⋶","NotLeftTriangleBar;":"⧏̸","NotLeftTriangle;":"⋪","NotLeftTriangleEqual;":"⋬","NotLess;":"≮","NotLessEqual;":"≰","NotLessGreater;":"≸","NotLessLess;":"≪̸","NotLessSlantEqual;":"⩽̸","NotLessTilde;":"≴","NotNestedGreaterGreater;":"⪢̸","NotNestedLessLess;":"⪡̸","notni;":"∌","notniva;":"∌","notnivb;":"⋾","notnivc;":"⋽","NotPrecedes;":"⊀","NotPrecedesEqual;":"⪯̸","NotPrecedesSlantEqual;":"⋠","NotReverseElement;":"∌","NotRightTriangleBar;":"⧐̸","NotRightTriangle;":"⋫","NotRightTriangleEqual;":"⋭","NotSquareSubset;":"⊏̸","NotSquareSubsetEqual;":"⋢","NotSquareSuperset;":"⊐̸","NotSquareSupersetEqual;":"⋣","NotSubset;":"⊂⃒","NotSubsetEqual;":"⊈","NotSucceeds;":"⊁","NotSucceedsEqual;":"⪰̸","NotSucceedsSlantEqual;":"⋡","NotSucceedsTilde;":"≿̸","NotSuperset;":"⊃⃒","NotSupersetEqual;":"⊉","NotTilde;":"≁","NotTildeEqual;":"≄","NotTildeFullEqual;":"≇","NotTildeTilde;":"≉","NotVerticalBar;":"∤","nparallel;":"∦","npar;":"∦","nparsl;":"⫽⃥","npart;":"∂̸","npolint;":"⨔","npr;":"⊀","nprcue;":"⋠","nprec;":"⊀","npreceq;":"⪯̸","npre;":"⪯̸","nrarrc;":"⤳̸","nrarr;":"↛","nrArr;":"⇏","nrarrw;":"↝̸","nrightarrow;":"↛","nRightarrow;":"⇏","nrtri;":"⋫","nrtrie;":"⋭","nsc;":"⊁","nsccue;":"⋡","nsce;":"⪰̸","Nscr;":"𝒩","nscr;":"𝓃","nshortmid;":"∤","nshortparallel;":"∦","nsim;":"≁","nsime;":"≄","nsimeq;":"≄","nsmid;":"∤","nspar;":"∦","nsqsube;":"⋢","nsqsupe;":"⋣","nsub;":"⊄","nsubE;":"⫅̸","nsube;":"⊈","nsubset;":"⊂⃒","nsubseteq;":"⊈","nsubseteqq;":"⫅̸","nsucc;":"⊁","nsucceq;":"⪰̸","nsup;":"⊅","nsupE;":"⫆̸","nsupe;":"⊉","nsupset;":"⊃⃒","nsupseteq;":"⊉","nsupseteqq;":"⫆̸","ntgl;":"≹","Ntilde;":"Ñ",Ntilde:"Ñ","ntilde;":"ñ",ntilde:"ñ","ntlg;":"≸","ntriangleleft;":"⋪","ntrianglelefteq;":"⋬","ntriangleright;":"⋫","ntrianglerighteq;":"⋭","Nu;":"Ν","nu;":"ν","num;":"#","numero;":"№","numsp;":" ","nvap;":"≍⃒","nvdash;":"⊬","nvDash;":"⊭","nVdash;":"⊮","nVDash;":"⊯","nvge;":"≥⃒","nvgt;":">⃒","nvHarr;":"⤄","nvinfin;":"⧞","nvlArr;":"⤂","nvle;":"≤⃒","nvlt;":"<⃒","nvltrie;":"⊴⃒","nvrArr;":"⤃","nvrtrie;":"⊵⃒","nvsim;":"∼⃒","nwarhk;":"⤣","nwarr;":"↖","nwArr;":"⇖","nwarrow;":"↖","nwnear;":"⤧","Oacute;":"Ó",Oacute:"Ó","oacute;":"ó",oacute:"ó","oast;":"⊛","Ocirc;":"Ô",Ocirc:"Ô","ocirc;":"ô",ocirc:"ô","ocir;":"⊚","Ocy;":"О","ocy;":"о","odash;":"⊝","Odblac;":"Ő","odblac;":"ő","odiv;":"⨸","odot;":"⊙","odsold;":"⦼","OElig;":"Œ","oelig;":"œ","ofcir;":"⦿","Ofr;":"𝔒","ofr;":"𝔬","ogon;":"˛","Ograve;":"Ò",Ograve:"Ò","ograve;":"ò",ograve:"ò","ogt;":"⧁","ohbar;":"⦵","ohm;":"Ω","oint;":"∮","olarr;":"↺","olcir;":"⦾","olcross;":"⦻","oline;":"‾","olt;":"⧀","Omacr;":"Ō","omacr;":"ō","Omega;":"Ω","omega;":"ω","Omicron;":"Ο","omicron;":"ο","omid;":"⦶","ominus;":"⊖","Oopf;":"𝕆","oopf;":"𝕠","opar;":"⦷","OpenCurlyDoubleQuote;":"“","OpenCurlyQuote;":"‘","operp;":"⦹","oplus;":"⊕","orarr;":"↻","Or;":"⩔","or;":"∨","ord;":"⩝","order;":"ℴ","orderof;":"ℴ","ordf;":"ª",ordf:"ª","ordm;":"º",ordm:"º","origof;":"⊶","oror;":"⩖","orslope;":"⩗","orv;":"⩛","oS;":"Ⓢ","Oscr;":"𝒪","oscr;":"ℴ","Oslash;":"Ø",Oslash:"Ø","oslash;":"ø",oslash:"ø","osol;":"⊘","Otilde;":"Õ",Otilde:"Õ","otilde;":"õ",otilde:"õ","otimesas;":"⨶","Otimes;":"⨷","otimes;":"⊗","Ouml;":"Ö",Ouml:"Ö","ouml;":"ö",ouml:"ö","ovbar;":"⌽","OverBar;":"‾","OverBrace;":"⏞","OverBracket;":"⎴","OverParenthesis;":"⏜","para;":"¶",para:"¶","parallel;":"∥","par;":"∥","parsim;":"⫳","parsl;":"⫽","part;":"∂","PartialD;":"∂","Pcy;":"П","pcy;":"п","percnt;":"%","period;":".","permil;":"‰","perp;":"⊥","pertenk;":"‱","Pfr;":"𝔓","pfr;":"𝔭","Phi;":"Φ","phi;":"φ","phiv;":"ϕ","phmmat;":"ℳ","phone;":"☎","Pi;":"Π","pi;":"π","pitchfork;":"⋔","piv;":"ϖ","planck;":"ℏ","planckh;":"ℎ","plankv;":"ℏ","plusacir;":"⨣","plusb;":"⊞","pluscir;":"⨢","plus;":"+","plusdo;":"∔","plusdu;":"⨥","pluse;":"⩲","PlusMinus;":"±","plusmn;":"±",plusmn:"±","plussim;":"⨦","plustwo;":"⨧","pm;":"±","Poincareplane;":"ℌ","pointint;":"⨕","popf;":"𝕡","Popf;":"ℙ","pound;":"£",pound:"£","prap;":"⪷","Pr;":"⪻","pr;":"≺","prcue;":"≼","precapprox;":"⪷","prec;":"≺","preccurlyeq;":"≼","Precedes;":"≺","PrecedesEqual;":"⪯","PrecedesSlantEqual;":"≼","PrecedesTilde;":"≾","preceq;":"⪯","precnapprox;":"⪹","precneqq;":"⪵","precnsim;":"⋨","pre;":"⪯","prE;":"⪳","precsim;":"≾","prime;":"′","Prime;":"″","primes;":"ℙ","prnap;":"⪹","prnE;":"⪵","prnsim;":"⋨","prod;":"∏","Product;":"∏","profalar;":"⌮","profline;":"⌒","profsurf;":"⌓","prop;":"∝","Proportional;":"∝","Proportion;":"∷","propto;":"∝","prsim;":"≾","prurel;":"⊰","Pscr;":"𝒫","pscr;":"𝓅","Psi;":"Ψ","psi;":"ψ","puncsp;":" ","Qfr;":"𝔔","qfr;":"𝔮","qint;":"⨌","qopf;":"𝕢","Qopf;":"ℚ","qprime;":"⁗","Qscr;":"𝒬","qscr;":"𝓆","quaternions;":"ℍ","quatint;":"⨖","quest;":"?","questeq;":"≟","quot;":'"',quot:'"',"QUOT;":'"',QUOT:'"',"rAarr;":"⇛","race;":"∽̱","Racute;":"Ŕ","racute;":"ŕ","radic;":"√","raemptyv;":"⦳","rang;":"⟩","Rang;":"⟫","rangd;":"⦒","range;":"⦥","rangle;":"⟩","raquo;":"»",raquo:"»","rarrap;":"⥵","rarrb;":"⇥","rarrbfs;":"⤠","rarrc;":"⤳","rarr;":"→","Rarr;":"↠","rArr;":"⇒","rarrfs;":"⤞","rarrhk;":"↪","rarrlp;":"↬","rarrpl;":"⥅","rarrsim;":"⥴","Rarrtl;":"⤖","rarrtl;":"↣","rarrw;":"↝","ratail;":"⤚","rAtail;":"⤜","ratio;":"∶","rationals;":"ℚ","rbarr;":"⤍","rBarr;":"⤏","RBarr;":"⤐","rbbrk;":"❳","rbrace;":"}","rbrack;":"]","rbrke;":"⦌","rbrksld;":"⦎","rbrkslu;":"⦐","Rcaron;":"Ř","rcaron;":"ř","Rcedil;":"Ŗ","rcedil;":"ŗ","rceil;":"⌉","rcub;":"}","Rcy;":"Р","rcy;":"р","rdca;":"⤷","rdldhar;":"⥩","rdquo;":"”","rdquor;":"”","rdsh;":"↳","real;":"ℜ","realine;":"ℛ","realpart;":"ℜ","reals;":"ℝ","Re;":"ℜ","rect;":"▭","reg;":"®",reg:"®","REG;":"®",REG:"®","ReverseElement;":"∋","ReverseEquilibrium;":"⇋","ReverseUpEquilibrium;":"⥯","rfisht;":"⥽","rfloor;":"⌋","rfr;":"𝔯","Rfr;":"ℜ","rHar;":"⥤","rhard;":"⇁","rharu;":"⇀","rharul;":"⥬","Rho;":"Ρ","rho;":"ρ","rhov;":"ϱ","RightAngleBracket;":"⟩","RightArrowBar;":"⇥","rightarrow;":"→","RightArrow;":"→","Rightarrow;":"⇒","RightArrowLeftArrow;":"⇄","rightarrowtail;":"↣","RightCeiling;":"⌉","RightDoubleBracket;":"⟧","RightDownTeeVector;":"⥝","RightDownVectorBar;":"⥕","RightDownVector;":"⇂","RightFloor;":"⌋","rightharpoondown;":"⇁","rightharpoonup;":"⇀","rightleftarrows;":"⇄","rightleftharpoons;":"⇌","rightrightarrows;":"⇉","rightsquigarrow;":"↝","RightTeeArrow;":"↦","RightTee;":"⊢","RightTeeVector;":"⥛","rightthreetimes;":"⋌","RightTriangleBar;":"⧐","RightTriangle;":"⊳","RightTriangleEqual;":"⊵","RightUpDownVector;":"⥏","RightUpTeeVector;":"⥜","RightUpVectorBar;":"⥔","RightUpVector;":"↾","RightVectorBar;":"⥓","RightVector;":"⇀","ring;":"˚","risingdotseq;":"≓","rlarr;":"⇄","rlhar;":"⇌","rlm;":"‏","rmoustache;":"⎱","rmoust;":"⎱","rnmid;":"⫮","roang;":"⟭","roarr;":"⇾","robrk;":"⟧","ropar;":"⦆","ropf;":"𝕣","Ropf;":"ℝ","roplus;":"⨮","rotimes;":"⨵","RoundImplies;":"⥰","rpar;":")","rpargt;":"⦔","rppolint;":"⨒","rrarr;":"⇉","Rrightarrow;":"⇛","rsaquo;":"›","rscr;":"𝓇","Rscr;":"ℛ","rsh;":"↱","Rsh;":"↱","rsqb;":"]","rsquo;":"’","rsquor;":"’","rthree;":"⋌","rtimes;":"⋊","rtri;":"▹","rtrie;":"⊵","rtrif;":"▸","rtriltri;":"⧎","RuleDelayed;":"⧴","ruluhar;":"⥨","rx;":"℞","Sacute;":"Ś","sacute;":"ś","sbquo;":"‚","scap;":"⪸","Scaron;":"Š","scaron;":"š","Sc;":"⪼","sc;":"≻","sccue;":"≽","sce;":"⪰","scE;":"⪴","Scedil;":"Ş","scedil;":"ş","Scirc;":"Ŝ","scirc;":"ŝ","scnap;":"⪺","scnE;":"⪶","scnsim;":"⋩","scpolint;":"⨓","scsim;":"≿","Scy;":"С","scy;":"с","sdotb;":"⊡","sdot;":"⋅","sdote;":"⩦","searhk;":"⤥","searr;":"↘","seArr;":"⇘","searrow;":"↘","sect;":"§",sect:"§","semi;":";","seswar;":"⤩","setminus;":"∖","setmn;":"∖","sext;":"✶","Sfr;":"𝔖","sfr;":"𝔰","sfrown;":"⌢","sharp;":"♯","SHCHcy;":"Щ","shchcy;":"щ","SHcy;":"Ш","shcy;":"ш","ShortDownArrow;":"↓","ShortLeftArrow;":"←","shortmid;":"∣","shortparallel;":"∥","ShortRightArrow;":"→","ShortUpArrow;":"↑","shy;":"­",shy:"­","Sigma;":"Σ","sigma;":"σ","sigmaf;":"ς","sigmav;":"ς","sim;":"∼","simdot;":"⩪","sime;":"≃","simeq;":"≃","simg;":"⪞","simgE;":"⪠","siml;":"⪝","simlE;":"⪟","simne;":"≆","simplus;":"⨤","simrarr;":"⥲","slarr;":"←","SmallCircle;":"∘","smallsetminus;":"∖","smashp;":"⨳","smeparsl;":"⧤","smid;":"∣","smile;":"⌣","smt;":"⪪","smte;":"⪬","smtes;":"⪬︀","SOFTcy;":"Ь","softcy;":"ь","solbar;":"⌿","solb;":"⧄","sol;":"/","Sopf;":"𝕊","sopf;":"𝕤","spades;":"♠","spadesuit;":"♠","spar;":"∥","sqcap;":"⊓","sqcaps;":"⊓︀","sqcup;":"⊔","sqcups;":"⊔︀","Sqrt;":"√","sqsub;":"⊏","sqsube;":"⊑","sqsubset;":"⊏","sqsubseteq;":"⊑","sqsup;":"⊐","sqsupe;":"⊒","sqsupset;":"⊐","sqsupseteq;":"⊒","square;":"□","Square;":"□","SquareIntersection;":"⊓","SquareSubset;":"⊏","SquareSubsetEqual;":"⊑","SquareSuperset;":"⊐","SquareSupersetEqual;":"⊒","SquareUnion;":"⊔","squarf;":"▪","squ;":"□","squf;":"▪","srarr;":"→","Sscr;":"𝒮","sscr;":"𝓈","ssetmn;":"∖","ssmile;":"⌣","sstarf;":"⋆","Star;":"⋆","star;":"☆","starf;":"★","straightepsilon;":"ϵ","straightphi;":"ϕ","strns;":"¯","sub;":"⊂","Sub;":"⋐","subdot;":"⪽","subE;":"⫅","sube;":"⊆","subedot;":"⫃","submult;":"⫁","subnE;":"⫋","subne;":"⊊","subplus;":"⪿","subrarr;":"⥹","subset;":"⊂","Subset;":"⋐","subseteq;":"⊆","subseteqq;":"⫅","SubsetEqual;":"⊆","subsetneq;":"⊊","subsetneqq;":"⫋","subsim;":"⫇","subsub;":"⫕","subsup;":"⫓","succapprox;":"⪸","succ;":"≻","succcurlyeq;":"≽","Succeeds;":"≻","SucceedsEqual;":"⪰","SucceedsSlantEqual;":"≽","SucceedsTilde;":"≿","succeq;":"⪰","succnapprox;":"⪺","succneqq;":"⪶","succnsim;":"⋩","succsim;":"≿","SuchThat;":"∋","sum;":"∑","Sum;":"∑","sung;":"♪","sup1;":"¹",sup1:"¹","sup2;":"²",sup2:"²","sup3;":"³",sup3:"³","sup;":"⊃","Sup;":"⋑","supdot;":"⪾","supdsub;":"⫘","supE;":"⫆","supe;":"⊇","supedot;":"⫄","Superset;":"⊃","SupersetEqual;":"⊇","suphsol;":"⟉","suphsub;":"⫗","suplarr;":"⥻","supmult;":"⫂","supnE;":"⫌","supne;":"⊋","supplus;":"⫀","supset;":"⊃","Supset;":"⋑","supseteq;":"⊇","supseteqq;":"⫆","supsetneq;":"⊋","supsetneqq;":"⫌","supsim;":"⫈","supsub;":"⫔","supsup;":"⫖","swarhk;":"⤦","swarr;":"↙","swArr;":"⇙","swarrow;":"↙","swnwar;":"⤪","szlig;":"ß",szlig:"ß","Tab;":"\t","target;":"⌖","Tau;":"Τ","tau;":"τ","tbrk;":"⎴","Tcaron;":"Ť","tcaron;":"ť","Tcedil;":"Ţ","tcedil;":"ţ","Tcy;":"Т","tcy;":"т","tdot;":"⃛","telrec;":"⌕","Tfr;":"𝔗","tfr;":"𝔱","there4;":"∴","therefore;":"∴","Therefore;":"∴","Theta;":"Θ","theta;":"θ","thetasym;":"ϑ","thetav;":"ϑ","thickapprox;":"≈","thicksim;":"∼","ThickSpace;":"  ","ThinSpace;":" ","thinsp;":" ","thkap;":"≈","thksim;":"∼","THORN;":"Þ",THORN:"Þ","thorn;":"þ",thorn:"þ","tilde;":"˜","Tilde;":"∼","TildeEqual;":"≃","TildeFullEqual;":"≅","TildeTilde;":"≈","timesbar;":"⨱","timesb;":"⊠","times;":"×",times:"×","timesd;":"⨰","tint;":"∭","toea;":"⤨","topbot;":"⌶","topcir;":"⫱","top;":"⊤","Topf;":"𝕋","topf;":"𝕥","topfork;":"⫚","tosa;":"⤩","tprime;":"‴","trade;":"™","TRADE;":"™","triangle;":"▵","triangledown;":"▿","triangleleft;":"◃","trianglelefteq;":"⊴","triangleq;":"≜","triangleright;":"▹","trianglerighteq;":"⊵","tridot;":"◬","trie;":"≜","triminus;":"⨺","TripleDot;":"⃛","triplus;":"⨹","trisb;":"⧍","tritime;":"⨻","trpezium;":"⏢","Tscr;":"𝒯","tscr;":"𝓉","TScy;":"Ц","tscy;":"ц","TSHcy;":"Ћ","tshcy;":"ћ","Tstrok;":"Ŧ","tstrok;":"ŧ","twixt;":"≬","twoheadleftarrow;":"↞","twoheadrightarrow;":"↠","Uacute;":"Ú",Uacute:"Ú","uacute;":"ú",uacute:"ú","uarr;":"↑","Uarr;":"↟","uArr;":"⇑","Uarrocir;":"⥉","Ubrcy;":"Ў","ubrcy;":"ў","Ubreve;":"Ŭ","ubreve;":"ŭ","Ucirc;":"Û",Ucirc:"Û","ucirc;":"û",ucirc:"û","Ucy;":"У","ucy;":"у","udarr;":"⇅","Udblac;":"Ű","udblac;":"ű","udhar;":"⥮","ufisht;":"⥾","Ufr;":"𝔘","ufr;":"𝔲","Ugrave;":"Ù",Ugrave:"Ù","ugrave;":"ù",ugrave:"ù","uHar;":"⥣","uharl;":"↿","uharr;":"↾","uhblk;":"▀","ulcorn;":"⌜","ulcorner;":"⌜","ulcrop;":"⌏","ultri;":"◸","Umacr;":"Ū","umacr;":"ū","uml;":"¨",uml:"¨","UnderBar;":"_","UnderBrace;":"⏟","UnderBracket;":"⎵","UnderParenthesis;":"⏝","Union;":"⋃","UnionPlus;":"⊎","Uogon;":"Ų","uogon;":"ų","Uopf;":"𝕌","uopf;":"𝕦","UpArrowBar;":"⤒","uparrow;":"↑","UpArrow;":"↑","Uparrow;":"⇑","UpArrowDownArrow;":"⇅","updownarrow;":"↕","UpDownArrow;":"↕","Updownarrow;":"⇕","UpEquilibrium;":"⥮","upharpoonleft;":"↿","upharpoonright;":"↾","uplus;":"⊎","UpperLeftArrow;":"↖","UpperRightArrow;":"↗","upsi;":"υ","Upsi;":"ϒ","upsih;":"ϒ","Upsilon;":"Υ","upsilon;":"υ","UpTeeArrow;":"↥","UpTee;":"⊥","upuparrows;":"⇈","urcorn;":"⌝","urcorner;":"⌝","urcrop;":"⌎","Uring;":"Ů","uring;":"ů","urtri;":"◹","Uscr;":"𝒰","uscr;":"𝓊","utdot;":"⋰","Utilde;":"Ũ","utilde;":"ũ","utri;":"▵","utrif;":"▴","uuarr;":"⇈","Uuml;":"Ü",Uuml:"Ü","uuml;":"ü",uuml:"ü","uwangle;":"⦧","vangrt;":"⦜","varepsilon;":"ϵ","varkappa;":"ϰ","varnothing;":"∅","varphi;":"ϕ","varpi;":"ϖ","varpropto;":"∝","varr;":"↕","vArr;":"⇕","varrho;":"ϱ","varsigma;":"ς","varsubsetneq;":"⊊︀","varsubsetneqq;":"⫋︀","varsupsetneq;":"⊋︀","varsupsetneqq;":"⫌︀","vartheta;":"ϑ","vartriangleleft;":"⊲","vartriangleright;":"⊳","vBar;":"⫨","Vbar;":"⫫","vBarv;":"⫩","Vcy;":"В","vcy;":"в","vdash;":"⊢","vDash;":"⊨","Vdash;":"⊩","VDash;":"⊫","Vdashl;":"⫦","veebar;":"⊻","vee;":"∨","Vee;":"⋁","veeeq;":"≚","vellip;":"⋮","verbar;":"|","Verbar;":"‖","vert;":"|","Vert;":"‖","VerticalBar;":"∣","VerticalLine;":"|","VerticalSeparator;":"❘","VerticalTilde;":"≀","VeryThinSpace;":" ","Vfr;":"𝔙","vfr;":"𝔳","vltri;":"⊲","vnsub;":"⊂⃒","vnsup;":"⊃⃒","Vopf;":"𝕍","vopf;":"𝕧","vprop;":"∝","vrtri;":"⊳","Vscr;":"𝒱","vscr;":"𝓋","vsubnE;":"⫋︀","vsubne;":"⊊︀","vsupnE;":"⫌︀","vsupne;":"⊋︀","Vvdash;":"⊪","vzigzag;":"⦚","Wcirc;":"Ŵ","wcirc;":"ŵ","wedbar;":"⩟","wedge;":"∧","Wedge;":"⋀","wedgeq;":"≙","weierp;":"℘","Wfr;":"𝔚","wfr;":"𝔴","Wopf;":"𝕎","wopf;":"𝕨","wp;":"℘","wr;":"≀","wreath;":"≀","Wscr;":"𝒲","wscr;":"𝓌","xcap;":"⋂","xcirc;":"◯","xcup;":"⋃","xdtri;":"▽","Xfr;":"𝔛","xfr;":"𝔵","xharr;":"⟷","xhArr;":"⟺","Xi;":"Ξ","xi;":"ξ","xlarr;":"⟵","xlArr;":"⟸","xmap;":"⟼","xnis;":"⋻","xodot;":"⨀","Xopf;":"𝕏","xopf;":"𝕩","xoplus;":"⨁","xotime;":"⨂","xrarr;":"⟶","xrArr;":"⟹","Xscr;":"𝒳","xscr;":"𝓍","xsqcup;":"⨆","xuplus;":"⨄","xutri;":"△","xvee;":"⋁","xwedge;":"⋀","Yacute;":"Ý",Yacute:"Ý","yacute;":"ý",yacute:"ý","YAcy;":"Я","yacy;":"я","Ycirc;":"Ŷ","ycirc;":"ŷ","Ycy;":"Ы","ycy;":"ы","yen;":"¥",yen:"¥","Yfr;":"𝔜","yfr;":"𝔶","YIcy;":"Ї","yicy;":"ї","Yopf;":"𝕐","yopf;":"𝕪","Yscr;":"𝒴","yscr;":"𝓎","YUcy;":"Ю","yucy;":"ю","yuml;":"ÿ",yuml:"ÿ","Yuml;":"Ÿ","Zacute;":"Ź","zacute;":"ź","Zcaron;":"Ž","zcaron;":"ž","Zcy;":"З","zcy;":"з","Zdot;":"Ż","zdot;":"ż","zeetrf;":"ℨ","ZeroWidthSpace;":"​","Zeta;":"Ζ","zeta;":"ζ","zfr;":"𝔷","Zfr;":"ℨ","ZHcy;":"Ж","zhcy;":"ж","zigrarr;":"⇝","zopf;":"𝕫","Zopf;":"ℤ","Zscr;":"𝒵","zscr;":"𝓏","zwj;":"‍","zwnj;":"‌"}},{}],13:[function(e,t,r){var n=e("util/"),a=Array.prototype.slice,o=Object.prototype.hasOwnProperty,i=t.exports=p;function s(e,t){return n.isUndefined(t)?""+t:!n.isNumber(t)||!isNaN(t)&&isFinite(t)?n.isFunction(t)||n.isRegExp(t)?t.toString():t:t.toString()}function c(e,t){return n.isString(e)?e.length=0;o--)if(i[o]!=s[o])return!1;for(o=i.length-1;o>=0;o--)if(!d(e[r=i[o]],t[r]))return!1;return!0}(e,t):e==t}function u(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function m(e,t){return!(!e||!t)&&("[object RegExp]"==Object.prototype.toString.call(t)?t.test(e):e instanceof t||!0===t.call({},e))}function h(e,t,r,a){var o;n.isString(r)&&(a=r,r=null);try{t()}catch(e){o=e}if(a=(r&&r.name?" ("+r.name+").":".")+(a?" "+a:"."),e&&!o&&l(o,r,"Missing expected exception"+a),!e&&m(o,r)&&l(o,r,"Got unwanted exception"+a),e&&o&&r&&!m(o,r)||!e&&o)throw o}i.AssertionError=function(e){this.name="AssertionError",this.actual=e.actual,this.expected=e.expected,this.operator=e.operator,e.message?(this.message=e.message,this.generatedMessage=!1):(this.message=function(e){return c(JSON.stringify(e.actual,s),128)+" "+e.operator+" "+c(JSON.stringify(e.expected,s),128)}(this),this.generatedMessage=!0);var t=e.stackStartFunction||l;if(Error.captureStackTrace)Error.captureStackTrace(this,t);else{var r=new Error;if(r.stack){var n=r.stack,a=t.name,o=n.indexOf("\n"+a);if(o>=0){var i=n.indexOf("\n",o+1);n=n.substring(i+1)}this.stack=n}}},n.inherits(i.AssertionError,Error),i.fail=l,i.ok=p,i.equal=function(e,t,r){e!=t&&l(e,t,r,"==",i.equal)},i.notEqual=function(e,t,r){e==t&&l(e,t,r,"!=",i.notEqual)},i.deepEqual=function(e,t,r){d(e,t)||l(e,t,r,"deepEqual",i.deepEqual)},i.notDeepEqual=function(e,t,r){d(e,t)&&l(e,t,r,"notDeepEqual",i.notDeepEqual)},i.strictEqual=function(e,t,r){e!==t&&l(e,t,r,"===",i.strictEqual)},i.notStrictEqual=function(e,t,r){e===t&&l(e,t,r,"!==",i.notStrictEqual)},i.throws=function(e,t,r){h.apply(this,[!0].concat(a.call(arguments)))},i.doesNotThrow=function(e,t){h.apply(this,[!1].concat(a.call(arguments)))},i.ifError=function(e){if(e)throw e};var g=Object.keys||function(e){var t=[];for(var r in e)o.call(e,r)&&t.push(r);return t}},{"util/":15}],14:[function(e,t,r){t.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},{}],15:[function(e,t,r){(function(t,n){var a=/%[sdj%]/g;r.format=function(e){if(!T(e)){for(var t=[],r=0;r=o)return e;switch(e){case"%s":return String(n[r++]);case"%d":return Number(n[r++]);case"%j":try{return JSON.stringify(n[r++])}catch(e){return"[Circular]"}default:return e}})),c=n[r];r=3&&(n.depth=arguments[2]),arguments.length>=4&&(n.colors=arguments[3]),h(t)?n.showHidden=t:t&&r._extend(n,t),y(n.showHidden)&&(n.showHidden=!1),y(n.depth)&&(n.depth=2),y(n.colors)&&(n.colors=!1),y(n.customInspect)&&(n.customInspect=!0),n.colors&&(n.stylize=c),p(n,e,n.depth)}function c(e,t){var r=s.styles[t];return r?"["+s.colors[r][0]+"m"+e+"["+s.colors[r][1]+"m":e}function l(e,t){return e}function p(e,t,n){if(e.customInspect&&t&&x(t.inspect)&&t.inspect!==r.inspect&&(!t.constructor||t.constructor.prototype!==t)){var a=t.inspect(n,e);return T(a)||(a=p(e,a,n)),a}var o=function(e,t){if(y(t))return e.stylize("undefined","undefined");if(T(t)){var r="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(r,"string")}return f(t)?e.stylize(""+t,"number"):h(t)?e.stylize(""+t,"boolean"):g(t)?e.stylize("null","null"):void 0}(e,t);if(o)return o;var i=Object.keys(t),s=function(e){var t={};return e.forEach((function(e,r){t[e]=!0})),t}(i);if(e.showHidden&&(i=Object.getOwnPropertyNames(t)),v(t)&&(i.indexOf("message")>=0||i.indexOf("description")>=0))return d(t);if(0===i.length){if(x(t)){var c=t.name?": "+t.name:"";return e.stylize("[Function"+c+"]","special")}if(b(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(w(t))return e.stylize(Date.prototype.toString.call(t),"date");if(v(t))return d(t)}var l,E="",S=!1,k=["{","}"];return m(t)&&(S=!0,k=["[","]"]),x(t)&&(E=" [Function"+(t.name?": "+t.name:"")+"]"),b(t)&&(E=" "+RegExp.prototype.toString.call(t)),w(t)&&(E=" "+Date.prototype.toUTCString.call(t)),v(t)&&(E=" "+d(t)),0!==i.length||S&&0!=t.length?n<0?b(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special"):(e.seen.push(t),l=S?function(e,t,r,n,a){for(var o=[],i=0,s=t.length;i60?r[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+r[1]:r[0]+t+" "+e.join(", ")+" "+r[1]}(l,E,k)):k[0]+E+k[1]}function d(e){return"["+Error.prototype.toString.call(e)+"]"}function u(e,t,r,n,a,o){var i,s,c;if((c=Object.getOwnPropertyDescriptor(t,a)||{value:t[a]}).get?s=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(s=e.stylize("[Setter]","special")),C(n,a)||(i="["+a+"]"),s||(e.seen.indexOf(c.value)<0?(s=g(r)?p(e,c.value,null):p(e,c.value,r-1)).indexOf("\n")>-1&&(s=o?s.split("\n").map((function(e){return" "+e})).join("\n").substr(2):"\n"+s.split("\n").map((function(e){return" "+e})).join("\n")):s=e.stylize("[Circular]","special")),y(i)){if(o&&a.match(/^\d+$/))return s;(i=JSON.stringify(""+a)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(i=i.substr(1,i.length-2),i=e.stylize(i,"name")):(i=i.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),i=e.stylize(i,"string"))}return i+": "+s}function m(e){return Array.isArray(e)}function h(e){return"boolean"==typeof e}function g(e){return null===e}function f(e){return"number"==typeof e}function T(e){return"string"==typeof e}function y(e){return void 0===e}function b(e){return E(e)&&"[object RegExp]"===S(e)}function E(e){return"object"==typeof e&&null!==e}function w(e){return E(e)&&"[object Date]"===S(e)}function v(e){return E(e)&&("[object Error]"===S(e)||e instanceof Error)}function x(e){return"function"==typeof e}function S(e){return Object.prototype.toString.call(e)}function k(e){return e<10?"0"+e.toString(10):e.toString(10)}r.debuglog=function(e){if(y(o)&&(o=t.env.NODE_DEBUG||""),e=e.toUpperCase(),!i[e])if(new RegExp("\\b"+e+"\\b","i").test(o)){var n=t.pid;i[e]=function(){var t=r.format.apply(r,arguments);console.error("%s %d: %s",e,n,t)}}else i[e]=function(){};return i[e]},r.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},r.isArray=m,r.isBoolean=h,r.isNull=g,r.isNullOrUndefined=function(e){return null==e},r.isNumber=f,r.isString=T,r.isSymbol=function(e){return"symbol"==typeof e},r.isUndefined=y,r.isRegExp=b,r.isObject=E,r.isDate=w,r.isError=v,r.isFunction=x,r.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},r.isBuffer=e("./support/isBuffer");var _=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function C(e,t){return Object.prototype.hasOwnProperty.call(e,t)}r.log=function(){var e,t;console.log("%s - %s",(t=[k((e=new Date).getHours()),k(e.getMinutes()),k(e.getSeconds())].join(":"),[e.getDate(),_[e.getMonth()],t].join(" ")),r.format.apply(r,arguments))},r.inherits=e("inherits"),r._extend=function(e,t){if(!t||!E(t))return e;for(var r=Object.keys(t),n=r.length;n--;)e[r[n]]=t[r[n]];return e}}).call(this,e("/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./support/isBuffer":14,"/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":18,inherits:17}],16:[function(e,t,r){function n(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function a(e){return"function"==typeof e}function o(e){return"object"==typeof e&&null!==e}function i(e){return void 0===e}t.exports=n,n.EventEmitter=n,n.prototype._events=void 0,n.prototype._maxListeners=void 0,n.defaultMaxListeners=10,n.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},n.prototype.emit=function(e){var t,r,n,s,c,l;if(this._events||(this._events={}),"error"===e&&(!this._events.error||o(this._events.error)&&!this._events.error.length))throw(t=arguments[1])instanceof Error?t:TypeError('Uncaught, unspecified "error" event.');if(i(r=this._events[e]))return!1;if(a(r))switch(arguments.length){case 1:r.call(this);break;case 2:r.call(this,arguments[1]);break;case 3:r.call(this,arguments[1],arguments[2]);break;default:for(n=arguments.length,s=new Array(n-1),c=1;c0&&this._events[e].length>r&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),console.trace()),this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(e,t){if(!a(t))throw TypeError("listener must be a function");var r=!1;function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}return n.listener=t,this.on(e,n),this},n.prototype.removeListener=function(e,t){var r,n,i,s;if(!a(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(i=(r=this._events[e]).length,n=-1,r===t||a(r.listener)&&r.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(r)){for(s=i;s-- >0;)if(r[s]===t||r[s].listener&&r[s].listener===t){n=s;break}if(n<0)return this;1===r.length?(r.length=0,delete this._events[e]):r.splice(n,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},n.prototype.removeAllListeners=function(e){var t,r;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(a(r=this._events[e]))this.removeListener(e,r);else for(;r.length;)this.removeListener(e,r[r.length-1]);return delete this._events[e],this},n.prototype.listeners=function(e){return this._events&&this._events[e]?a(this._events[e])?[this._events[e]]:this._events[e].slice():[]},n.listenerCount=function(e,t){return e._events&&e._events[t]?a(e._events[t])?1:e._events[t].length:0}},{}],17:[function(e,t,r){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e}},{}],18:[function(e,t,r){var n=t.exports={};function a(){}n.nextTick=function(){var e="undefined"!=typeof window&&window.setImmediate,t="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(e)return function(e){return window.setImmediate(e)};if(t){var r=[];return window.addEventListener("message",(function(e){var t=e.source;t!==window&&null!==t||"process-tick"!==e.data||(e.stopPropagation(),r.length>0&&r.shift()())}),!0),function(e){r.push(e),window.postMessage("process-tick","*")}}return function(e){setTimeout(e,0)}}(),n.title="browser",n.browser=!0,n.env={},n.argv=[],n.on=a,n.once=a,n.off=a,n.emit=a,n.binding=function(e){throw new Error("process.binding is not supported")},n.cwd=function(){return"/"},n.chdir=function(e){throw new Error("process.chdir is not supported")}},{}],19:[function(e,t,r){t.exports=e(14)},{}],20:[function(e,t,r){t.exports=e(15)},{"./support/isBuffer":19,"/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":18,inherits:17}]},{},[9])(9)})),ace.define("ace/mode/html_worker",[],(function(e,t,r){"use strict";var n=e("../lib/oop"),a=(e("../lib/lang"),e("../worker/mirror").Mirror),o=e("./html/saxparser").SAXParser,i={"expected-doctype-but-got-start-tag":"info","expected-doctype-but-got-chars":"info","non-html-root":"info"},s=t.Worker=function(e){a.call(this,e),this.setTimeout(400),this.context=null};n.inherits(s,a),function(){this.setOptions=function(e){this.context=e.context},this.onUpdate=function(){var e=this.doc.getValue();if(e){var t=new o,r=[],n=function(){};t.contentHandler={startDocument:n,endDocument:n,startElement:n,endElement:n,characters:n},t.errorHandler={error:function(e,t,n){r.push({row:t.line,column:t.column,text:e,type:i[n]||"error"})}},t.parse(e,this.context),this.sender.emit("error",r)}}}.call(s.prototype)})); \ No newline at end of file diff --git a/afba1f28f2baa29eae717d6cb03f5464.js b/afba1f28f2baa29eae717d6cb03f5464.js new file mode 100644 index 00000000..838e369a --- /dev/null +++ b/afba1f28f2baa29eae717d6cb03f5464.js @@ -0,0 +1 @@ +ace.define("ace/mode/gcode_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,o){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,n=function(){var e=this.createKeywordMapper({"support.function":"ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN",keyword:"IF|DO|WHILE|ENDWHILE|CALL|ENDIF|SUB|ENDSUB|GOTO|REPEAT|ENDREPEAT|CALL","constant.language":"PI"},"identifier",!0);this.$rules={start:[{token:"comment",regex:"\\(.*\\)"},{token:"comment",regex:"([N])([0-9]+)"},{token:"string",regex:"([G])([0-9]+\\.?[0-9]?)"},{token:"string",regex:"([M])([0-9]+\\.?[0-9]?)"},{token:"constant.numeric",regex:"([-+]?([0-9]*\\.?[0-9]+\\.?))|(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)"},{token:e,regex:"[A-Z]"},{token:"keyword.operator",regex:"EQ|LT|GT|NE|GE|LE|OR|XOR"},{token:"paren.lparen",regex:"[\\[]"},{token:"paren.rparen",regex:"[\\]]"},{token:"text",regex:"\\s+"}]}};r.inherits(n,i),t.GcodeHighlightRules=n})),ace.define("ace/mode/gcode",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/gcode_highlight_rules","ace/range"],(function(e,t,o){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,n=e("./gcode_highlight_rules").GcodeHighlightRules,g=(e("../range").Range,function(){this.HighlightRules=n,this.$behaviour=this.$defaultBehaviour});r.inherits(g,i),function(){this.$id="ace/mode/gcode"}.call(g.prototype),t.Mode=g})),ace.require(["ace/mode/gcode"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b02d982ccb1011197a5a24800b178a0a.js b/b02d982ccb1011197a5a24800b178a0a.js new file mode 100644 index 00000000..163090e8 --- /dev/null +++ b/b02d982ccb1011197a5a24800b178a0a.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/abap"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b10accbff47791a59b8494225af07025.js b/b10accbff47791a59b8494225af07025.js new file mode 100644 index 00000000..52a16689 --- /dev/null +++ b/b10accbff47791a59b8494225af07025.js @@ -0,0 +1 @@ +ace.define("ace/mode/jack_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var i=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,o=function(){this.$rules={start:[{token:"string",regex:'"',next:"string2"},{token:"string",regex:"'",next:"string1"},{token:"constant.numeric",regex:"-?0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"(?:0|[-+]?[1-9][0-9]*)\\b"},{token:"constant.binary",regex:"<[0-9A-Fa-f][0-9A-Fa-f](\\s+[0-9A-Fa-f][0-9A-Fa-f])*>"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:"constant.language.null",regex:"null\\b"},{token:"storage.type",regex:"(?:Integer|Boolean|Null|String|Buffer|Tuple|List|Object|Function|Coroutine|Form)\\b"},{token:"keyword",regex:"(?:return|abort|vars|for|delete|in|is|escape|exec|split|and|if|elif|else|while)\\b"},{token:"language.builtin",regex:"(?:lines|source|parse|read-stream|interval|substr|parseint|write|print|range|rand|inspect|bind|i-values|i-pairs|i-map|i-filter|i-chunk|i-all\\?|i-any\\?|i-collect|i-zip|i-merge|i-each)\\b"},{token:"comment",regex:"--.*$"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"storage.form",regex:"@[a-z]+"},{token:"constant.other.symbol",regex:":+[a-zA-Z_]([-]?[a-zA-Z0-9_])*[?!]?"},{token:"variable",regex:"[a-zA-Z_]([-]?[a-zA-Z0-9_])*[?!]?"},{token:"keyword.operator",regex:"\\|\\||\\^\\^|&&|!=|==|<=|<|>=|>|\\+|-|\\*|\\/|\\^|\\%|\\#|\\!"},{token:"text",regex:"\\s+"}],string1:[{token:"constant.language.escape",regex:/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|['"\\\/bfnrt])/},{token:"string",regex:"[^'\\\\]+"},{token:"string",regex:"'",next:"start"},{token:"string",regex:"",next:"start"}],string2:[{token:"constant.language.escape",regex:/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|['"\\\/bfnrt])/},{token:"string",regex:'[^"\\\\]+'},{token:"string",regex:'"',next:"start"},{token:"string",regex:"",next:"start"}]}};i.inherits(o,r),t.JackHighlightRules=o})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var i=e("../range").Range,r=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var r=n[1].length,o=e.findMatchingBracket({row:t,column:r});if(!o||o.row==t)return 0;var a=this.$getIndent(e.getLine(o.row));e.replace(new i(t,0,t,r-1),a)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(r.prototype),t.MatchingBraceOutdent=r})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var i=e("../../lib/oop"),r=e("../../range").Range,o=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};i.inherits(a,o),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var i=e.getLine(n);if(this.singleLineBlockCommentRe.test(i)&&!this.startRegionRe.test(i)&&!this.tripleStarBlockCommentRe.test(i))return"";var r=this._getFoldWidgetBase(e,t,n);return!r&&this.startRegionRe.test(i)?"start":r},this.getFoldWidgetRange=function(e,t,n,i){var r,o=e.getLine(n);if(this.startRegionRe.test(o))return this.getCommentRegionBlock(e,o,n);if(r=o.match(this.foldingStartMarker)){var a=r.index;if(r[1])return this.openingBracketBlock(e,r[1],n,a);var s=e.getCommentFoldRange(n,a+r[0].length,1);return s&&!s.isMultiLine()&&(i?s=this.getSectionRange(e,n):"all"!=t&&(s=null)),s}return"markbegin"!==t&&(r=o.match(this.foldingStopMarker))?(a=r.index+r[0].length,r[1]?this.closingBracketBlock(e,r[1],n,a):e.getCommentFoldRange(n,a,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),i=n.search(/\S/),o=t,a=n.length,s=t+=1,g=e.getLength();++tl)break;var c=this.getFoldWidgetRange(e,"all",t);if(c){if(c.start.row<=o)break;if(c.isMultiLine())t=c.end.row;else if(i==l)break}s=t}}return new r(o,a,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var i=t.search(/\s*$/),o=e.getLength(),a=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,g=1;++na)return new r(a,i,n,t.length)}}.call(a.prototype)})),ace.define("ace/mode/jack",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/jack_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var i=e("../lib/oop"),r=e("./text").Mode,o=e("./jack_highlight_rules").JackHighlightRules,a=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("./folding/cstyle").FoldMode,g=function(){this.HighlightRules=o,this.$outdent=new a,this.$behaviour=this.$defaultBehaviour,this.foldingRules=new s};i.inherits(g,r),function(){this.lineCommentStart="--",this.getNextLineIndent=function(e,t,n){var i=this.$getIndent(t);return"start"==e&&t.match(/^.*[\{\(\[]\s*$/)&&(i+=n),i},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/jack"}.call(g.prototype),t.Mode=g})),ace.require(["ace/mode/jack"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b1170472ae4b50e3b0070eb991e502fe.js b/b1170472ae4b50e3b0070eb991e502fe.js new file mode 100644 index 00000000..65f849ef --- /dev/null +++ b/b1170472ae4b50e3b0070eb991e502fe.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/toml"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b13d991d1e4a016abea3fe5837261690.js b/b13d991d1e4a016abea3fe5837261690.js new file mode 100644 index 00000000..59f4e27b --- /dev/null +++ b/b13d991d1e4a016abea3fe5837261690.js @@ -0,0 +1 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var i=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,r=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},r.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}]}};i.inherits(r,o),r.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},r.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},r.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=r})),ace.define("ace/mode/csharp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var i=e("../lib/oop"),o=e("./doc_comment_highlight_rules").DocCommentHighlightRules,r=e("./text_highlight_rules").TextHighlightRules,a=function(){var e=this.createKeywordMapper({"variable.language":"this",keyword:"abstract|async|await|event|new|struct|as|explicit|null|switch|base|extern|object|this|bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|delegate|internal|partial|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|string|var|dynamic","constant.language":"null|true|false"},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},o.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:/'(?:.|\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n]))?'/},{token:"string",start:'"',end:'"|$',next:[{token:"constant.language.escape",regex:/\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/},{token:"invalid",regex:/\\./}]},{token:"string",start:'@"',end:'"',next:[{token:"constant.language.escape",regex:'""'}]},{token:"string",start:/\$"/,end:'"|$',next:[{token:"constant.language.escape",regex:/\\(:?$)|{{/},{token:"constant.language.escape",regex:/\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/},{token:"invalid",regex:/\\./}]},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"keyword",regex:"^\\s*#(if|else|elif|endif|define|undef|warning|error|line|region|endregion|pragma)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}]},this.embedRules(o,"doc-",[o.getEndRule("start")]),this.normalizeRules()};i.inherits(a,r),t.CSharpHighlightRules=a})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var i=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,r=e.findMatchingBracket({row:t,column:o});if(!r||r.row==t)return 0;var a=this.$getIndent(e.getLine(r.row));e.replace(new i(t,0,t,o-1),a)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var i=e("../../lib/oop"),o=e("../../range").Range,r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};i.inherits(a,r),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var i=e.getLine(n);if(this.singleLineBlockCommentRe.test(i)&&!this.startRegionRe.test(i)&&!this.tripleStarBlockCommentRe.test(i))return"";var o=this._getFoldWidgetBase(e,t,n);return!o&&this.startRegionRe.test(i)?"start":o},this.getFoldWidgetRange=function(e,t,n,i){var o,r=e.getLine(n);if(this.startRegionRe.test(r))return this.getCommentRegionBlock(e,r,n);if(o=r.match(this.foldingStartMarker)){var a=o.index;if(o[1])return this.openingBracketBlock(e,o[1],n,a);var s=e.getCommentFoldRange(n,a+o[0].length,1);return s&&!s.isMultiLine()&&(i?s=this.getSectionRange(e,n):"all"!=t&&(s=null)),s}return"markbegin"!==t&&(o=r.match(this.foldingStopMarker))?(a=o.index+o[0].length,o[1]?this.closingBracketBlock(e,o[1],n,a):e.getCommentFoldRange(n,a,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),i=n.search(/\S/),r=t,a=n.length,s=t+=1,g=e.getLength();++tc)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=r)break;if(l.isMultiLine())t=l.end.row;else if(i==c)break}s=t}}return new o(r,a,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var i=t.search(/\s*$/),r=e.getLength(),a=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,g=1;++na)return new o(a,i,n,t.length)}}.call(a.prototype)})),ace.define("ace/mode/folding/csharp",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var i=e("../../lib/oop"),o=e("../../range").Range,r=e("./cstyle").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};i.inherits(a,r),function(){this.usingRe=/^\s*using \S/,this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var i=this.getFoldWidgetBase(e,t,n);if(!i){var o=e.getLine(n);if(/^\s*#region\b/.test(o))return"start";var r=this.usingRe;if(r.test(o)){var a=e.getLine(n-1),s=e.getLine(n+1);if(!r.test(a)&&r.test(s))return"start"}}return i},this.getFoldWidgetRange=function(e,t,n){var i=this.getFoldWidgetRangeBase(e,t,n);if(i)return i;var o=e.getLine(n);return this.usingRe.test(o)?this.getUsingStatementBlock(e,o,n):/^\s*#region\b/.test(o)?this.getRegionBlock(e,o,n):void 0},this.getUsingStatementBlock=function(e,t,n){for(var i=t.match(this.usingRe)[0].length-1,r=e.getLength(),a=n,s=n;++na){var g=e.getLine(s).length;return new o(a,i,s,g)}},this.getRegionBlock=function(e,t,n){for(var i=t.search(/\s*$/),r=e.getLength(),a=n,s=/^\s*#(end)?region\b/,g=1;++na)return new o(a,i,n,t.length)}}.call(a.prototype)})),ace.define("ace/mode/csharp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/csharp_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/csharp"],(function(e,t,n){"use strict";var i=e("../lib/oop"),o=e("./text").Mode,r=e("./csharp_highlight_rules").CSharpHighlightRules,a=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("./folding/csharp").FoldMode,g=function(){this.HighlightRules=r,this.$outdent=new a,this.$behaviour=this.$defaultBehaviour,this.foldingRules=new s};i.inherits(g,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var i=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e).tokens;return o.length&&"comment"==o[o.length-1].type||"start"==e&&t.match(/^.*[\{\(\[]\s*$/)&&(i+=n),i},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){return null},this.$id="ace/mode/csharp"}.call(g.prototype),t.Mode=g})),ace.require(["ace/mode/csharp"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b1e349371cb9c226905c846706ad8b93.js b/b1e349371cb9c226905c846706ad8b93.js new file mode 100644 index 00000000..249dd881 --- /dev/null +++ b/b1e349371cb9c226905c846706ad8b93.js @@ -0,0 +1 @@ +ace.define("ace/snippets/clojure.snippets",["require","exports","module"],(function(e,n,t){t.exports='snippet comm\n\t(comment\n\t ${1}\n\t )\nsnippet condp\n\t(condp ${1:pred} ${2:expr}\n\t ${3})\nsnippet def\n\t(def ${1})\nsnippet defm\n\t(defmethod ${1:multifn} "${2:doc-string}" ${3:dispatch-val} [${4:args}]\n\t ${5})\nsnippet defmm\n\t(defmulti ${1:name} "${2:doc-string}" ${3:dispatch-fn})\nsnippet defma\n\t(defmacro ${1:name} "${2:doc-string}" ${3:dispatch-fn})\nsnippet defn\n\t(defn ${1:name} "${2:doc-string}" [${3:arg-list}]\n\t ${4})\nsnippet defp\n\t(defprotocol ${1:name}\n\t ${2})\nsnippet defr\n\t(defrecord ${1:name} [${2:fields}]\n\t ${3:protocol}\n\t ${4})\nsnippet deft\n\t(deftest ${1:name}\n\t (is (= ${2:assertion})))\n\t ${3})\nsnippet is\n\t(is (= ${1} ${2}))\nsnippet defty\n\t(deftype ${1:Name} [${2:fields}]\n\t ${3:Protocol}\n\t ${4})\nsnippet doseq\n\t(doseq [${1:elem} ${2:coll}]\n\t ${3})\nsnippet fn\n\t(fn [${1:arg-list}] ${2})\nsnippet if\n\t(if ${1:test-expr}\n\t ${2:then-expr}\n\t ${3:else-expr})\nsnippet if-let \n\t(if-let [${1:result} ${2:test-expr}]\n\t\t(${3:then-expr} $1)\n\t\t(${4:else-expr}))\nsnippet imp\n\t(:import [${1:package}])\n\t& {:keys [${1:keys}] :or {${2:defaults}}}\nsnippet let\n\t(let [${1:name} ${2:expr}]\n\t\t${3})\nsnippet letfn\n\t(letfn [(${1:name) [${2:args}]\n\t ${3})])\nsnippet map\n\t(map ${1:func} ${2:coll})\nsnippet mapl\n\t(map #(${1:lambda}) ${2:coll})\nsnippet met\n\t(${1:name} [${2:this} ${3:args}]\n\t ${4})\nsnippet ns\n\t(ns ${1:name}\n\t ${2})\nsnippet dotimes\n\t(dotimes [_ 10]\n\t (time\n\t (dotimes [_ ${1:times}]\n\t ${2})))\nsnippet pmethod\n\t(${1:name} [${2:this} ${3:args}])\nsnippet refer\n\t(:refer-clojure :exclude [${1}])\nsnippet require\n\t(:require [${1:namespace} :as [${2}]])\nsnippet use\n\t(:use [${1:namespace} :only [${2}]])\nsnippet print\n\t(println ${1})\nsnippet reduce\n\t(reduce ${1:(fn [p n] ${3})} ${2})\nsnippet when\n\t(when ${1:test} ${2:body})\nsnippet when-let\n\t(when-let [${1:result} ${2:test}]\n\t\t${3:body})\n'})),ace.define("ace/snippets/clojure",["require","exports","module","ace/snippets/clojure.snippets"],(function(e,n,t){"use strict";n.snippetText=e("./clojure.snippets"),n.scope="clojure"})),ace.require(["ace/snippets/clojure"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b1f3f77a9279cdb38846ebe13c3438bc.js b/b1f3f77a9279cdb38846ebe13c3438bc.js new file mode 100644 index 00000000..2a9b2b8d --- /dev/null +++ b/b1f3f77a9279cdb38846ebe13c3438bc.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/csp"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b20cd9acf45420fcacfd923754185663.js b/b20cd9acf45420fcacfd923754185663.js new file mode 100644 index 00000000..b650f33e --- /dev/null +++ b/b20cd9acf45420fcacfd923754185663.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/zeek"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b306285dfd802d091e788de0f96b8cb2.js b/b306285dfd802d091e788de0f96b8cb2.js new file mode 100644 index 00000000..1ab13b41 --- /dev/null +++ b/b306285dfd802d091e788de0f96b8cb2.js @@ -0,0 +1 @@ +ace.define("ace/snippets/snippets.snippets",["require","exports","module"],(function(e,p,s){s.exports="# snippets for making snippets :)\nsnippet snip\n\tsnippet ${1:trigger}\n\t\t${2}\nsnippet msnip\n\tsnippet ${1:trigger} ${2:description}\n\t\t${3}\nsnippet v\n\t{VISUAL}\n"})),ace.define("ace/snippets/snippets",["require","exports","module","ace/snippets/snippets.snippets"],(function(e,p,s){"use strict";p.snippetText=e("./snippets.snippets"),p.scope="snippets"})),ace.require(["ace/snippets/snippets"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b33ef9b4202539d3690251cb8213a034.js b/b33ef9b4202539d3690251cb8213a034.js new file mode 100644 index 00000000..75327b14 --- /dev/null +++ b/b33ef9b4202539d3690251cb8213a034.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/visualforce"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b3f1431b9e6d9e6632a93c2cd89f945b.js b/b3f1431b9e6d9e6632a93c2cd89f945b.js new file mode 100644 index 00000000..4a0c2377 --- /dev/null +++ b/b3f1431b9e6d9e6632a93c2cd89f945b.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/astro"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b60ba1535a60c18ce97b4e7f53ddbe67.js b/b60ba1535a60c18ce97b4e7f53ddbe67.js new file mode 100644 index 00000000..fc1d1671 --- /dev/null +++ b/b60ba1535a60c18ce97b4e7f53ddbe67.js @@ -0,0 +1 @@ +ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};r.inherits(a,o),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[o.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[o.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(o,"doc-",[o.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r="/"==e.charAt(1)?2:1;return 1==r?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==r&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==r?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[o.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[o.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}r.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var r=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,a=e.findMatchingBracket({row:t,column:o});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new r(t,0,t,o-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,r,o){if('"'==o||"'"==o){var s=o,l=r.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),g=r.doc.getLine(c.row).substring(c.column,c.column+1),u=new a(r,c.row,c.column),d=u.getCurrentToken();if(g==s&&(i(d,"attribute-value")||i(d,"string")))return{text:"",selection:[1,1]};if(d||(d=u.stepBackward()),!d)return;for(;i(d,"tag-whitespace")||i(d,"whitespace");)d=u.stepBackward();var p=!g||g.match(/\s/);if(i(d,"attribute-equals")&&(p||">"==g)||i(d,"decl-attribute-equals")&&(p||"?"==g))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,r,o){var a=r.doc.getTextRange(o);if(!o.isMultiLine()&&('"'==a||"'"==a)&&r.doc.getLine(o.start.row).substring(o.start.column+1,o.start.column+2)==a)return o.end.column++,o})),this.add("autoclosing","insertion",(function(e,t,n,r,o){if(">"==o){var s=n.getSelectionRange().start,l=new a(r,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var g=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(r.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var d=l.getCurrentTokenRow(),p=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var m=c.value;if(d==s.row&&(m=m.substring(0,s.column-p)),this.voidElements&&this.voidElements.hasOwnProperty(m.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,r,o){if("\n"==o){var s=n.getCursorPosition(),l=r.getLine(s.row),c=new a(r,s.row,s.column),g=c.getCurrentToken();if(i(g,"")&&-1!==g.type.indexOf("tag-close")){if("/>"==g.value)return;for(;g&&-1===g.type.indexOf("tag-name");)g=c.stepBackward();if(!g)return;var u=g.value,d=c.getCurrentTokenRow();if(!(g=c.stepBackward())||-1!==g.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[u]||!this.voidElements){var p=r.getTokenAt(s.row,s.column+1),m=(l=r.getLine(d),this.$getIndent(l)),x=m+r.getTabString();return p&&""==a){var i=n.getSelectionRange().start,s=new o(r,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};r.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?"markbeginend"===t?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())||this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return r}if(l(a,"tag-close"))return r.selfClosing="/>"==a.value,r;r.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,r){for(var o=e.getTokens(t),a=0,i=0;ic)break;var g=this.getFoldWidgetRange(e,"all",t);if(g){if(g.start.row<=a)break;if(g.isMultiLine())t=g.end.row;else if(r==c)break}s=t}}return new o(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var r=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new o(i,r,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new o};r.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,r){return this.getFoldWidgetRangeBase(e,t,n,r)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,g=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};r.inherits(g,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e),a=o.tokens,i=o.state;if(a.length&&"comment"==a[a.length-1].type)return r;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(r+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(g.prototype),t.Mode=g})),ace.define("ace/mode/jsx",["require","exports","module","ace/lib/oop","ace/mode/javascript"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./javascript").Mode;function a(){o.call(this),this.$highlightRuleConfig={jsx:!0}}r.inherits(a,o),function(){this.createWorker=function(){return null},this.$id="ace/mode/jsx"}.call(a.prototype),t.Mode=a})),ace.require(["ace/mode/jsx"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b808fb222140a85b23ebbe0fffa906d9.js b/b808fb222140a85b23ebbe0fffa906d9.js new file mode 100644 index 00000000..fe18184a --- /dev/null +++ b/b808fb222140a85b23ebbe0fffa906d9.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/asl"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b881dca9d9a80f61d87374b4bd5a2dd5.js b/b881dca9d9a80f61d87374b4bd5a2dd5.js new file mode 100644 index 00000000..0b0140a5 --- /dev/null +++ b/b881dca9d9a80f61d87374b4bd5a2dd5.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/jssm"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b8b6bd460e7da0ba8f3b2218327966ee.js b/b8b6bd460e7da0ba8f3b2218327966ee.js new file mode 100644 index 00000000..4bee467a --- /dev/null +++ b/b8b6bd460e7da0ba8f3b2218327966ee.js @@ -0,0 +1 @@ +ace.define("ace/snippets/actionscript.snippets",["require","exports","module"],(function(t,n,e){e.exports='snippet main\n\tpackage {\n\t\timport flash.display.*;\n\t\timport flash.Events.*;\n\t\n\t\tpublic class Main extends Sprite {\n\t\t\tpublic function Main (\t) {\n\t\t\t\ttrace("start");\n\t\t\t\tstage.scaleMode = StageScaleMode.NO_SCALE;\n\t\t\t\tstage.addEventListener(Event.RESIZE, resizeListener);\n\t\t\t}\n\t\n\t\t\tprivate function resizeListener (e:Event):void {\n\t\t\t\ttrace("The application window changed size!");\n\t\t\t\ttrace("New width: " + stage.stageWidth);\n\t\t\t\ttrace("New height: " + stage.stageHeight);\n\t\t\t}\n\t\n\t\t}\n\t\n\t}\nsnippet class\n\t${1:public|internal} class ${2:name} ${3:extends } {\n\t\tpublic function $2 (\t) {\n\t\t\t("start");\n\t\t}\n\t}\nsnippet all\n\tpackage name {\n\n\t\t${1:public|internal|final} class ${2:name} ${3:extends } {\n\t\t\tprivate|public| static const FOO = "abc";\n\t\t\tprivate|public| static var BAR = "abc";\n\n\t\t\t// class initializer - no JIT !! one time setup\n\t\t\tif Cababilities.os == "Linux|MacOS" {\n\t\t\t\tFOO = "other";\n\t\t\t}\n\n\t\t\t// constructor:\n\t\t\tpublic function $2 (\t){\n\t\t\t\tsuper2();\n\t\t\t\ttrace("start");\n\t\t\t}\n\t\t\tpublic function name (a, b...){\n\t\t\t\tsuper.name(..);\n\t\t\t\tlable:break\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction A(){\n\t\t// A can only be accessed within this file\n\t}\nsnippet switch\n\tswitch(${1}){\n\t\tcase ${2}:\n\t\t\t${3}\n\t\tbreak;\n\t\tdefault:\n\t}\nsnippet case\n\t\tcase ${1}:\n\t\t\t${2}\n\t\tbreak;\nsnippet package\n\tpackage ${1:package}{\n\t\t${2}\n\t}\nsnippet wh\n\twhile ${1:cond}{\n\t\t${2}\n\t}\nsnippet do\n\tdo {\n\t\t${2}\n\t} while (${1:cond})\nsnippet while\n\twhile ${1:cond}{\n\t\t${2}\n\t}\nsnippet for enumerate names\n\tfor (${1:var} in ${2:object}){\n\t\t${3}\n\t}\nsnippet for enumerate values\n\tfor each (${1:var} in ${2:object}){\n\t\t${3}\n\t}\nsnippet get_set\n\tfunction get ${1:name} {\n\t\treturn ${2}\n\t}\n\tfunction set $1 (newValue) {\n\t\t${3}\n\t}\nsnippet interface\n\tinterface name {\n\t\tfunction method(${1}):${2:returntype};\n\t}\nsnippet try\n\ttry {\n\t\t${1}\n\t} catch (error:ErrorType) {\n\t\t${2}\n\t} finally {\n\t\t${3}\n\t}\n# For Loop (same as c.snippet)\nsnippet for for (..) {..}\n\tfor (${2:i} = 0; $2 < ${1:count}; $2${3:++}) {\n\t\t${4:/* code */}\n\t}\n# Custom For Loop\nsnippet forr\n\tfor (${1:i} = ${2:0}; ${3:$1 < 10}; $1${4:++}) {\n\t\t${5:/* code */}\n\t}\n# If Condition\nsnippet if\n\tif (${1:/* condition */}) {\n\t\t${2:/* code */}\n\t}\nsnippet el\n\telse {\n\t\t${1}\n\t}\n# Ternary conditional\nsnippet t\n\t${1:/* condition */} ? ${2:a} : ${3:b}\nsnippet fun\n\tfunction ${1:function_name}(${2})${3}\n\t{\n\t\t${4:/* code */}\n\t}\n# FlxSprite (usefull when using the flixel library)\nsnippet FlxSprite\n\tpackage\n\t{\n\t\timport org.flixel.*\n\n\t\tpublic class ${1:ClassName} extends ${2:FlxSprite}\n\t\t{\n\t\t\tpublic function $1(${3: X:Number, Y:Number}):void\n\t\t\t{\n\t\t\t\tsuper(X,Y);\n\t\t\t\t${4: //code...}\n\t\t\t}\n\n\t\t\toverride public function update():void\n\t\t\t{\n\t\t\t\tsuper.update();\n\t\t\t\t${5: //code...}\n\t\t\t}\n\t\t}\n\t}\n\n'})),ace.define("ace/snippets/actionscript",["require","exports","module","ace/snippets/actionscript.snippets"],(function(t,n,e){"use strict";n.snippetText=t("./actionscript.snippets"),n.scope="actionscript"})),ace.require(["ace/snippets/actionscript"],(function(t){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=t)})); \ No newline at end of file diff --git a/b934b22e8f8a8b1ba81dbc2cf058b0cd.js b/b934b22e8f8a8b1ba81dbc2cf058b0cd.js new file mode 100644 index 00000000..0673c0d1 --- /dev/null +++ b/b934b22e8f8a8b1ba81dbc2cf058b0cd.js @@ -0,0 +1 @@ +ace.define("ace/mode/textile_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,i){"use strict";var n=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,r=function(){this.$rules={start:[{token:function(e){return"h"==e.charAt(0)?"markup.heading."+e.charAt(1):"markup.heading"},regex:"h1|h2|h3|h4|h5|h6|bq|p|bc|pre",next:"blocktag"},{token:"keyword",regex:"[\\*]+|[#]+"},{token:"text",regex:".+"}],blocktag:[{token:"keyword",regex:"\\. ",next:"start"},{token:"keyword",regex:"\\(",next:"blocktagproperties"}],blocktagproperties:[{token:"keyword",regex:"\\)",next:"blocktag"},{token:"string",regex:"[a-zA-Z0-9\\-_]+"},{token:"keyword",regex:"#"}]}};n.inherits(r,o),t.TextileHighlightRules=r})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,i){"use strict";var n=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var i=e.getLine(t).match(/^(\s*\})/);if(!i)return 0;var o=i[1].length,r=e.findMatchingBracket({row:t,column:o});if(!r||r.row==t)return 0;var c=this.$getIndent(e.getLine(r.row));e.replace(new n(t,0,t,o-1),c)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/textile",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/textile_highlight_rules","ace/mode/matching_brace_outdent"],(function(e,t,i){"use strict";var n=e("../lib/oop"),o=e("./text").Mode,r=e("./textile_highlight_rules").TextileHighlightRules,c=e("./matching_brace_outdent").MatchingBraceOutdent,u=function(){this.HighlightRules=r,this.$outdent=new c,this.$behaviour=this.$defaultBehaviour};n.inherits(u,o),function(){this.type="text",this.getNextLineIndent=function(e,t,i){return"intag"==e?i:""},this.checkOutdent=function(e,t,i){return this.$outdent.checkOutdent(t,i)},this.autoOutdent=function(e,t,i){this.$outdent.autoOutdent(t,i)},this.$id="ace/mode/textile",this.snippetFileId="ace/snippets/textile"}.call(u.prototype),t.Mode=u})),ace.require(["ace/mode/textile"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b953ce2f19e7291598cd9c05128133c1.js b/b953ce2f19e7291598cd9c05128133c1.js new file mode 100644 index 00000000..612a1884 --- /dev/null +++ b/b953ce2f19e7291598cd9c05128133c1.js @@ -0,0 +1 @@ +ace.define("ace/mode/coffee_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules;function a(){var e="[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*",t="case|const|function|var|void|with|enum|implements|interface|let|package|private|protected|public|static",n=this.createKeywordMapper({keyword:"this|throw|then|try|typeof|super|switch|return|break|by|continue|catch|class|in|instanceof|is|isnt|if|else|extends|for|own|finally|function|while|when|new|no|not|delete|debugger|do|loop|of|off|or|on|unless|until|and|yes|yield|export|import|default","constant.language":"true|false|null|undefined|NaN|Infinity","invalid.illegal":t,"language.support.class":"Array|Boolean|Date|Function|Number|Object|RegExp|ReferenceError|String|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray","language.support.function":"Math|JSON|isNaN|isFinite|parseInt|parseFloat|encodeURI|encodeURIComponent|decodeURI|decodeURIComponent|String|","variable.language":"window|arguments|prototype|document"},"identifier"),r={token:["paren.lparen","variable.parameter","paren.rparen","text","storage.type"],regex:/(?:(\()((?:"[^")]*?"|'[^')]*?'|\/[^\/)]*?\/|[^()"'\/])*?)(\))(\s*))?([\-=]>)/.source},o=/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)/;this.$rules={start:[{token:"constant.numeric",regex:"(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)"},{stateName:"qdoc",token:"string",regex:"'''",next:[{token:"string",regex:"'''",next:"start"},{token:"constant.language.escape",regex:o},{defaultToken:"string"}]},{stateName:"qqdoc",token:"string",regex:'"""',next:[{token:"string",regex:'"""',next:"start"},{token:"paren.string",regex:"#{",push:"start"},{token:"constant.language.escape",regex:o},{defaultToken:"string"}]},{stateName:"qstring",token:"string",regex:"'",next:[{token:"string",regex:"'",next:"start"},{token:"constant.language.escape",regex:o},{defaultToken:"string"}]},{stateName:"qqstring",token:"string.start",regex:'"',next:[{token:"string.end",regex:'"',next:"start"},{token:"paren.string",regex:"#{",push:"start"},{token:"constant.language.escape",regex:o},{defaultToken:"string"}]},{stateName:"js",token:"string",regex:"`",next:[{token:"string",regex:"`",next:"start"},{token:"constant.language.escape",regex:o},{defaultToken:"string"}]},{regex:"[{}]",onMatch:function(e,t,n){return this.next="","{"==e&&n.length?(n.unshift("start",t),"paren"):"}"==e&&n.length&&(n.shift(),this.next=n.shift()||"",-1!=this.next.indexOf("string"))?"paren.string":"paren"}},{token:"string.regex",regex:"///",next:"heregex"},{token:"string.regex",regex:/(?:\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)(?:[imgy]{0,4})(?!\w)/},{token:"comment",regex:"###(?!#)",next:"comment"},{token:"comment",regex:"#.*"},{token:["punctuation.operator","text","identifier"],regex:"(\\.)(\\s*)("+t+")"},{token:"punctuation.operator",regex:"\\.{1,3}"},{token:["keyword","text","language.support.class","text","keyword","text","language.support.class"],regex:"(class)(\\s+)("+e+")(?:(\\s+)(extends)(\\s+)("+e+"))?"},{token:["entity.name.function","text","keyword.operator","text"].concat(r.token),regex:"("+e+")(\\s*)([=:])(\\s*)"+r.regex},r,{token:"variable",regex:"@(?:"+e+")?"},{token:n,regex:e},{token:"punctuation.operator",regex:"\\,|\\."},{token:"storage.type",regex:"[\\-=]>"},{token:"keyword.operator",regex:"(?:[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|[!*+-=><])"},{token:"paren.lparen",regex:"[({[]"},{token:"paren.rparen",regex:"[\\]})]"},{token:"text",regex:"\\s+"}],heregex:[{token:"string.regex",regex:".*?///[imgy]{0,4}",next:"start"},{token:"comment.regex",regex:"\\s+(?:#.*)?"},{token:"string.regex",regex:"\\S+"}],comment:[{token:"comment",regex:"###",next:"start"},{defaultToken:"comment"}]},this.normalizeRules()}r.inherits(a,o),t.CoffeeHighlightRules=a})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var r=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,a=e.findMatchingBracket({row:t,column:o});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new r(t,0,t,o-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./fold_mode").FoldMode,a=e("../../range").Range,i=t.FoldMode=function(){};r.inherits(i,o),function(){this.commentBlock=function(e,t){var n=/\S/,r=e.getLine(t),o=r.search(n);if(-1!=o&&"#"==r[o]){for(var i=r.length,s=e.getLength(),g=t,c=t;++tg){var f=e.getLine(c).length;return new a(g,i,c,f)}}},this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);return r||(r=this.commentBlock(e,n))||void 0},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),o=r.search(/\S/),a=e.getLine(n+1),i=e.getLine(n-1),s=i.search(/\S/),g=a.search(/\S/);if(-1==o)return e.foldWidgets[n-1]=-1!=s&&s|\b(?:else|try|(?:swi|ca)tch(?:\s+[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$|^\s*(else\b\s*)?(?:if|for|while|loop)\b(?!.*\bthen\b)/;this.lineCommentStart="#",this.blockComment={start:"###",end:"###"},this.getNextLineIndent=function(t,n,r){var o=this.$getIndent(n),a=this.getTokenizer().getLineTokens(n,t).tokens;return a.length&&"comment"===a[a.length-1].type||"start"!==t||!e.test(n)||(o+=r),o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/coffee_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/coffee",this.snippetFileId="ace/snippets/coffee"}.call(g.prototype),t.Mode=g})),ace.require(["ace/mode/coffee"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/b992b348ffb6453e4a02a60e71c5304e.js b/b992b348ffb6453e4a02a60e71c5304e.js new file mode 100644 index 00000000..2a3d7536 --- /dev/null +++ b/b992b348ffb6453e4a02a60e71c5304e.js @@ -0,0 +1 @@ +ace.define("ace/mode/csound_preprocessor_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.embeddedRulePrefix=void 0===e?"":e,this.semicolonComments={token:"comment.line.semicolon.csound",regex:";.*$"},this.comments=[{token:"punctuation.definition.comment.begin.csound",regex:"/\\*",push:[{token:"punctuation.definition.comment.end.csound",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.csound"}]},{token:"comment.line.double-slash.csound",regex:"//.*$"},this.semicolonComments],this.macroUses=[{token:["entity.name.function.preprocessor.csound","punctuation.definition.macro-parameter-value-list.begin.csound"],regex:/(\$[A-Z_a-z]\w*\.?)(\()/,next:"macro parameter value list"},{token:"entity.name.function.preprocessor.csound",regex:/\$[A-Z_a-z]\w*(?:\.|\b)/}],this.numbers=[{token:"constant.numeric.float.csound",regex:/(?:\d+[Ee][+-]?\d+)|(?:\d+\.\d*|\d*\.\d+)(?:[Ee][+-]?\d+)?/},{token:["storage.type.number.csound","constant.numeric.integer.hexadecimal.csound"],regex:/(0[Xx])([0-9A-Fa-f]+)/},{token:"constant.numeric.integer.decimal.csound",regex:/\d+/}],this.bracedStringContents=[{token:"constant.character.escape.csound",regex:/\\(?:[\\abnrt"]|[0-7]{1,3})/},{token:"constant.character.placeholder.csound",regex:/%[#0\- +]*\d*(?:\.\d+)?[diuoxXfFeEgGaAcs]/},{token:"constant.character.escape.csound",regex:/%%/}],this.quotedStringContents=[this.macroUses,this.bracedStringContents];var t=[this.comments,{token:"keyword.preprocessor.csound",regex:/#(?:e(?:nd(?:if)?|lse)\b|##)|@@?[ \t]*\d+/},{token:"keyword.preprocessor.csound",regex:/#include/,push:[this.comments,{token:"string.csound",regex:/([^ \t])(?:.*?\1)/,next:"pop"}]},{token:"keyword.preprocessor.csound",regex:/#includestr/,push:[this.comments,{token:"string.csound",regex:/([^ \t])(?:.*?\1)/,next:"pop"}]},{token:"keyword.preprocessor.csound",regex:/#[ \t]*define/,next:"define directive"},{token:"keyword.preprocessor.csound",regex:/#(?:ifn?def|undef)\b/,next:"macro directive"},this.macroUses];this.$rules={start:t,"define directive":[this.comments,{token:"entity.name.function.preprocessor.csound",regex:/[A-Z_a-z]\w*/},{token:"punctuation.definition.macro-parameter-name-list.begin.csound",regex:/\(/,next:"macro parameter name list"},{token:"punctuation.definition.macro.begin.csound",regex:/#/,next:"macro body"}],"macro parameter name list":[{token:"variable.parameter.preprocessor.csound",regex:/[A-Z_a-z]\w*/},{token:"punctuation.definition.macro-parameter-name-list.end.csound",regex:/\)/,next:"define directive"}],"macro body":[{token:"constant.character.escape.csound",regex:/\\#/},{token:"punctuation.definition.macro.end.csound",regex:/#/,next:"start"},t],"macro directive":[this.comments,{token:"entity.name.function.preprocessor.csound",regex:/[A-Z_a-z]\w*/,next:"start"}],"macro parameter value list":[{token:"punctuation.definition.macro-parameter-value-list.end.csound",regex:/\)/,next:"start"},{token:"punctuation.definition.string.begin.csound",regex:/"/,next:"macro parameter value quoted string"},this.pushRule({token:"punctuation.macro-parameter-value-parenthetical.begin.csound",regex:/\(/,next:"macro parameter value parenthetical"}),{token:"punctuation.macro-parameter-value-separator.csound",regex:"[#']"}],"macro parameter value quoted string":[{token:"constant.character.escape.csound",regex:/\\[#'()]/},{token:"invalid.illegal.csound",regex:/[#'()]/},{token:"punctuation.definition.string.end.csound",regex:/"/,next:"macro parameter value list"},this.quotedStringContents,{defaultToken:"string.quoted.csound"}],"macro parameter value parenthetical":[{token:"constant.character.escape.csound",regex:/\\\)/},this.popRule({token:"punctuation.macro-parameter-value-parenthetical.end.csound",regex:/\)/}),this.pushRule({token:"punctuation.macro-parameter-value-parenthetical.begin.csound",regex:/\(/,next:"macro parameter value parenthetical"}),t]}};o.inherits(s,r),function(){this.pushRule=function(e){if(Array.isArray(e.next))for(var t=0;t1?o[o.length-1]:o.pop(),e.token}}}}.call(s.prototype),t.CsoundPreprocessorHighlightRules=s})),ace.define("ace/mode/csound_score_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/csound_preprocessor_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./csound_preprocessor_highlight_rules").CsoundPreprocessorHighlightRules,s=function(e){r.call(this,e),this.quotedStringContents.push({token:"invalid.illegal.csound-score",regex:/[^"]*$/});var t=this.$rules.start;t.push({token:"keyword.control.csound-score",regex:/[aBbCdefiqstvxy]/},{token:"invalid.illegal.csound-score",regex:/w/},{token:"constant.numeric.language.csound-score",regex:/z/},{token:["keyword.control.csound-score","constant.numeric.integer.decimal.csound-score"],regex:/([nNpP][pP])(\d+)/},{token:"keyword.other.csound-score",regex:/[mn]/,push:[{token:"empty",regex:/$/,next:"pop"},this.comments,{token:"entity.name.label.csound-score",regex:/[A-Z_a-z]\w*/}]},{token:"keyword.preprocessor.csound-score",regex:/r\b/,next:"repeat section"},this.numbers,{token:"keyword.operator.csound-score",regex:"[!+\\-*/^%&|<>#~.]"},this.pushRule({token:"punctuation.definition.string.begin.csound-score",regex:/"/,next:"quoted string"}),this.pushRule({token:"punctuation.braced-loop.begin.csound-score",regex:/{/,next:"loop after left brace"})),this.addRules({"repeat section":[{token:"empty",regex:/$/,next:"start"},this.comments,{token:"constant.numeric.integer.decimal.csound-score",regex:/\d+/,next:"repeat section before label"}],"repeat section before label":[{token:"empty",regex:/$/,next:"start"},this.comments,{token:"entity.name.label.csound-score",regex:/[A-Z_a-z]\w*/,next:"start"}],"quoted string":[this.popRule({token:"punctuation.definition.string.end.csound-score",regex:/"/}),this.quotedStringContents,{defaultToken:"string.quoted.csound-score"}],"loop after left brace":[this.popRule({token:"constant.numeric.integer.decimal.csound-score",regex:/\d+/,next:"loop after repeat count"}),this.comments,{token:"invalid.illegal.csound",regex:/\S.*/}],"loop after repeat count":[this.popRule({token:"entity.name.function.preprocessor.csound-score",regex:/[A-Z_a-z]\w*\b/,next:"loop after macro name"}),this.comments,{token:"invalid.illegal.csound",regex:/\S.*/}],"loop after macro name":[t,this.popRule({token:"punctuation.braced-loop.end.csound-score",regex:/}/})]}),this.normalizeRules()};o.inherits(s,r),t.CsoundScoreHighlightRules=s})),ace.define("ace/mode/csound_score",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/csound_score_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,s=e("./csound_score_highlight_rules").CsoundScoreHighlightRules,c=function(){this.HighlightRules=s};o.inherits(c,r),function(){this.lineCommentStart=";",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/csound_score"}.call(c.prototype),t.Mode=c})),ace.require(["ace/mode/csound_score"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/ba6b8b3e06cd9d0aee9c69278ee84647.js b/ba6b8b3e06cd9d0aee9c69278ee84647.js new file mode 100644 index 00000000..902701f1 --- /dev/null +++ b/ba6b8b3e06cd9d0aee9c69278ee84647.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/nix"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/bb1365c0983ce5ad50060b24788b9630.js b/bb1365c0983ce5ad50060b24788b9630.js new file mode 100644 index 00000000..e0317761 --- /dev/null +++ b/bb1365c0983ce5ad50060b24788b9630.js @@ -0,0 +1 @@ +ace.define("ace/ext/command_bar",["require","exports","module","ace/tooltip","ace/lib/event_emitter","ace/lib/lang","ace/lib/dom","ace/lib/oop","ace/lib/useragent"],(function(t,e,o){var i=this&&this.__values||function(t){var e="function"==typeof Symbol&&Symbol.iterator,o=e&&t[e],i=0;if(o)return o.call(t);if(t&&"number"==typeof t.length)return{next:function(){return t&&i>=t.length&&(t=void 0),{value:t&&t[i++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},n=t("../tooltip").Tooltip,s=t("../lib/event_emitter").EventEmitter,r=t("../lib/lang"),a=t("../lib/dom"),h=t("../lib/oop"),l=t("../lib/useragent"),d="command_bar_tooltip_button",c="command_bar_button_value",p="command_bar_button_caption",m="command_bar_keybinding",u="command_bar_tooltip",f="MoreOptionsButton",g=function(t,e){return e.row>t.row||e.row===t.row&&e.column>t.column?t:e},v={Ctrl:{mac:"^"},Option:{mac:"⌥"},Command:{mac:"⌘"},Cmd:{mac:"⌘"},Shift:"⇧",Left:"←",Right:"→",Up:"↑",Down:"↓"},b=function(){function t(t,e){var o,s;e=e||{},this.parentNode=t,this.tooltip=new n(this.parentNode),this.moreOptions=new n(this.parentNode),this.maxElementsOnTooltip=e.maxElementsOnTooltip||4,this.$alwaysShow=e.alwaysShow||!1,this.eventListeners={},this.elements={},this.commands={},this.tooltipEl=a.buildDom(["div",{class:u}],this.tooltip.getElement()),this.moreOptionsEl=a.buildDom(["div",{class:u+" tooltip_more_options"}],this.moreOptions.getElement()),this.$showTooltipTimer=r.delayedCall(this.$showTooltip.bind(this),e.showDelay||100),this.$hideTooltipTimer=r.delayedCall(this.$hideTooltip.bind(this),e.hideDelay||100),this.$tooltipEnter=this.$tooltipEnter.bind(this),this.$onMouseMove=this.$onMouseMove.bind(this),this.$onChangeScroll=this.$onChangeScroll.bind(this),this.$onEditorChangeSession=this.$onEditorChangeSession.bind(this),this.$scheduleTooltipForHide=this.$scheduleTooltipForHide.bind(this),this.$preventMouseEvent=this.$preventMouseEvent.bind(this);try{for(var h=i(["mousedown","mouseup","click"]),l=h.next();!l.done;l=h.next()){var d=l.value;this.tooltip.getElement().addEventListener(d,this.$preventMouseEvent),this.moreOptions.getElement().addEventListener(d,this.$preventMouseEvent)}}catch(t){o={error:t}}finally{try{l&&!l.done&&(s=h.return)&&s.call(h)}finally{if(o)throw o.error}}}return t.prototype.registerCommand=function(t,e){var o=Object.keys(this.commands).length=l.top&&s.top<=l.bottom&&s.left>=l.left+e.gutterWidth&&s.left<=l.right;if(d||!this.isShown())if(d&&!this.isShown()&&this.getAlwaysShow())this.$showTooltip();else{var c=s.top-r.offsetHeight,p=Math.min(a-r.offsetWidth,s.left);if(c>=0&&c+r.offsetHeight<=h&&p>=0&&p+r.offsetWidth<=a){if(this.tooltip.setPosition(p,c),this.isMoreOptionsShown()){c+=r.offsetHeight,p=this.elements[f].getBoundingClientRect().left;var m=this.moreOptions.getElement();h=window.innerHeight,c+m.offsetHeight>h&&(c-=r.offsetHeight+m.offsetHeight),p+m.offsetWidth>a&&(p=a-m.offsetWidth),this.moreOptions.setPosition(p,c)}}else this.$hideTooltip()}else this.$hideTooltip()}}},t.prototype.update=function(){Object.keys(this.elements).forEach(this.$updateElement.bind(this))},t.prototype.detach=function(){this.tooltip.hide(),this.moreOptions.hide(),this.$updateOnHoverHandlers(!1),this.editor&&(this.editor.off("changeSession",this.$onEditorChangeSession),this.editor.session&&(this.editor.session.off("changeScrollLeft",this.$onChangeScroll),this.editor.session.off("changeScrollTop",this.$onChangeScroll))),this.$mouseInTooltip=!1,this.editor=null},t.prototype.destroy=function(){this.tooltip&&this.moreOptions&&(this.detach(),this.tooltip.destroy(),this.moreOptions.destroy()),this.eventListeners={},this.commands={},this.elements={},this.tooltip=this.moreOptions=this.parentNode=null},t.prototype.$createCommand=function(t,e,o){var i,n=o?this.tooltipEl:this.moreOptionsEl,s=[],r=e.bindKey;r&&("object"==typeof r&&(r=l.isMac?r.mac:r.win),s=(s=(r=r.split("|")[0]).split("-")).map((function(t){if(v[t]){if("string"==typeof v[t])return v[t];if(l.isMac&&v[t].mac)return v[t].mac}return t}))),o&&e.iconCssClass?i=["div",{class:["ace_icon_svg",e.iconCssClass].join(" "),"aria-label":e.name+" ("+e.bindKey+")"}]:(i=[["div",{class:c}],["div",{class:p},e.name]],s.length&&i.push(["div",{class:m},s.map((function(t){return["div",t]}))])),a.buildDom(["div",{class:[d,e.cssClass||""].join(" "),ref:t},i],n,this.elements),this.commands[t]=e;var h=function(o){this.editor&&this.editor.focus(),this.$shouldHideMoreOptions=this.isMoreOptionsShown(),!this.elements[t].disabled&&e.exec&&e.exec(this.editor),this.$shouldHideMoreOptions&&this.$setMoreOptionsVisibility(!1),this.update(),o.preventDefault()}.bind(this);this.eventListeners[t]=h,this.elements[t].addEventListener("click",h.bind(this)),this.$updateElement(t)},t.prototype.$setMoreOptionsVisibility=function(t){t?(this.moreOptions.setTheme(this.editor.renderer.theme),this.moreOptions.setClassName(u+"_wrapper"),this.moreOptions.show(),this.update(),this.updatePosition()):this.moreOptions.hide()},t.prototype.$onEditorChangeSession=function(t){t.oldSession&&(t.oldSession.off("changeScrollTop",this.$onChangeScroll),t.oldSession.off("changeScrollLeft",this.$onChangeScroll)),this.detach()},t.prototype.$onChangeScroll=function(){this.editor.renderer&&(this.isShown()||this.getAlwaysShow())&&this.editor.renderer.once("afterRender",this.updatePosition.bind(this))},t.prototype.$onMouseMove=function(t){if(!this.$mouseInTooltip){var e=this.editor.getCursorPosition(),o=this.editor.renderer.textToScreenCoordinates(e.row,e.column),i=this.editor.renderer.lineHeight;t.clientY>=o.pageY&&t.clientY<0-9]*)",comment:"Notes"},{token:"zupfnoter.jumptarget.string.quoted",regex:'[\\"!]\\^\\:.*?[\\"!]',comment:"Zupfnoter jumptarget"},{token:"zupfnoter.goto.string.quoted",regex:'[\\"!]\\^\\@.*?[\\"!]',comment:"Zupfnoter goto"},{token:"zupfnoter.annotation.string.quoted",regex:'[\\"!]\\^\\!.*?[\\"!]',comment:"Zupfnoter annoation"},{token:"zupfnoter.annotationref.string.quoted",regex:'[\\"!]\\^\\#.*?[\\"!]',comment:"Zupfnoter annotation reference"},{token:"chordname.string.quoted",regex:'[\\"!]\\^.*?[\\"!]',comment:"abc chord"},{token:"string.quoted",regex:'[\\"!].*?[\\"!]',comment:"abc annotation"}]},this.normalizeRules()};r.metaData={fileTypes:["abc"],name:"ABC",scopeName:"text.abcnotation"},o.inherits(r,i),t.ABCHighlightRules=r})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),i=e("../../range").Range,r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};o.inherits(a,r),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var o=e.getLine(n);if(this.singleLineBlockCommentRe.test(o)&&!this.startRegionRe.test(o)&&!this.tripleStarBlockCommentRe.test(o))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(o)?"start":i},this.getFoldWidgetRange=function(e,t,n,o){var i,r=e.getLine(n);if(this.startRegionRe.test(r))return this.getCommentRegionBlock(e,r,n);if(i=r.match(this.foldingStartMarker)){var a=i.index;if(i[1])return this.openingBracketBlock(e,i[1],n,a);var s=e.getCommentFoldRange(n,a+i[0].length,1);return s&&!s.isMultiLine()&&(o?s=this.getSectionRange(e,n):"all"!=t&&(s=null)),s}return"markbegin"!==t&&(i=r.match(this.foldingStopMarker))?(a=i.index+i[0].length,i[1]?this.closingBracketBlock(e,i[1],n,a):e.getCommentFoldRange(n,a,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),o=n.search(/\S/),r=t,a=n.length,s=t+=1,g=e.getLength();++tc)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=r)break;if(l.isMultiLine())t=l.end.row;else if(o==c)break}s=t}}return new i(r,a,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),r=e.getLength(),a=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,g=1;++na)return new i(a,o,n,t.length)}}.call(a.prototype)})),ace.define("ace/mode/abc",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/abc_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),i=e("./text").Mode,r=e("./abc_highlight_rules").ABCHighlightRules,a=e("./folding/cstyle").FoldMode,s=function(){this.HighlightRules=r,this.foldingRules=new a,this.$behaviour=this.$defaultBehaviour};o.inherits(s,i),function(){this.lineCommentStart="%",this.$id="ace/mode/abc",this.snippetFileId="ace/snippets/abc"}.call(s.prototype),t.Mode=s})),ace.require(["ace/mode/abc"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/bfae1ca81a1ee3b319b4562b0e40c591.js b/bfae1ca81a1ee3b319b4562b0e40c591.js new file mode 100644 index 00000000..95cd51c7 --- /dev/null +++ b/bfae1ca81a1ee3b319b4562b0e40c591.js @@ -0,0 +1 @@ +ace.define("ace/theme/cloud_editor_dark-css",["require","exports","module"],(function(e,c,o){o.exports="\n.ace-cloud_editor_dark .ace_gutter {\n background: #282c34;\n color: #8e96a9;\n}\n\n.ace-cloud_editor_dark.ace_dark .ace_tooltip-marker-error.ace_tooltip-marker {\n background-color: #ff5d64;\n}\n.ace-cloud_editor_dark.ace_dark .ace_tooltip-marker-security.ace_tooltip-marker {\n background-color: #ff5d64;\n}\n.ace-cloud_editor_dark.ace_dark .ace_tooltip-marker-warning.ace_tooltip-marker {\n background-color: #e0ca57;\n}\n\n.ace-cloud_editor_dark .ace_print-margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-cloud_editor_dark {\n background-color: #282c34;\n color: #dcdfe4;\n}\n\n.ace-cloud_editor_dark .ace_cursor {\n color: #66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_marker-layer .ace_selection {\n background: #4376bd;\n}\n\n.ace-cloud_editor_dark.ace_multiselect .ace_selection.ace_start {\n box-shadow: 0 0 3px 0px #8e96a9;\n border-radius: 2px;\n}\n\n.ace-cloud_editor_dark .ace_marker-layer .ace_step {\n background: #6fb342;\n}\n\n.ace-cloud_editor_dark .ace_marker-layer .ace_bracket {\n margin: 0 0 0 -1px;\n border: 1px solid #e8e8e8;\n}\n\n.ace-cloud_editor_dark .ace_marker-layer .ace_active-line {\n box-sizing: border-box;\n border-top: 1px solid #75777a;\n border-bottom: 1px solid #75777a;\n}\n\n.ace-cloud_editor_dark .ace_gutter-cell_svg-icons {\n box-sizing: border-box;\n border-top: 1px solid #282c34;\n border-bottom: 1px solid #282c34;\n}\n\n.ace-cloud_editor_dark .ace_gutter-active-line {\n background-repeat: no-repeat;\n box-sizing: border-box;\n border-top: 1px solid #75777a;\n border-bottom: 1px solid #75777a;\n}\n\n.ace-cloud_editor_dark .ace_marker-layer .ace_selected-word {\n border: 1px solid #9bd0f7;\n}\n\n.ace-cloud_editor_dark .ace_fold {\n background-color: #66b2f0;\n border-color: #dcdfe4;\n}\n\n.ace-cloud_editor_dark .ace_keyword {\n color: #c674dc;\n}\n\n.ace-cloud_editor_dark .ace_constant {\n color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_constant.ace_numeric {\n color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_constant.ace_character.ace_escape {\n color: #71ccc7;\n}\n\n.ace-cloud_editor_dark .ace_support.ace_function {\n color: #e96a71;\n}\n\n.ace-cloud_editor_dark .ace_support.ace_class {\n color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_storage {\n color: #c674dc;\n}\n\n.ace-cloud_editor_dark .ace_invalid.ace_illegal {\n color: #dcdfe4;\n background-color:#66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_invalid.ace_deprecated {\n color: #dcdfe4;\n background-color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_string {\n color: #6fb342;\n}\n\n.ace-cloud_editor_dark .ace_string.ace_regexp {\n color: #6fb342;\n}\n\n.ace-cloud_editor_dark .ace_comment,\n.ace-cloud_editor_dark .ace_ghost_text {\n color: #b5bac0;\n opacity: 1;\n}\n\n.ace-cloud_editor_dark .ace_variable {\n color:#66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_meta.ace_selector {\n color: #c674dc;\n}\n\n.ace-cloud_editor_dark .ace_entity.ace_other.ace_attribute-name {\n color: #e5c383;\n}\n\n.ace-cloud_editor_dark .ace_entity.ace_name.ace_function {\n color: #e96a71;\n}\n\n.ace-cloud_editor_dark .ace_entity.ace_name.ace_tag {\n color:#66b2f0;\n}\n.ace-cloud_editor_dark .ace_heading {\n color: #e96a71;\n}\n\n.ace-cloud_editor_dark .ace_xml-pe {\n color: #e5c383;\n}\n.ace-cloud_editor_dark .ace_doctype {\n color:#66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_entity.ace_name.ace_tag,\n.ace-cloud_editor_dark .ace_entity.ace_other.ace_attribute-name,\n.ace-cloud_editor_dark .ace_meta.ace_tag,\n.ace-cloud_editor_dark .ace_string.ace_regexp,\n.ace-cloud_editor_dark .ace_variable {\n color:#66b2f0;\n}\n\n.ace-cloud_editor_dark .ace_tooltip {\n background-color: #282c34;\n color: #dcdfe4;\n}\n\n.ace-cloud_editor_dark .ace_icon_svg.ace_error,\n.ace-cloud_editor_dark .ace_icon_svg.ace_error_fold {\n background-color: #ff5d64;\n}\n.ace-cloud_editor_dark .ace_icon_svg.ace_security,\n.ace-cloud_editor_dark .ace_icon_svg.ace_security_fold {\n background-color: #ff5d64;\n}\n.ace-cloud_editor_dark .ace_icon_svg.ace_warning,\n.ace-cloud_editor_dark .ace_icon_svg.ace_warning_fold {\n background-color: #e0ca57;\n}\n.ace-cloud_editor_dark .ace_icon_svg.ace_info {\n background-color: #44b9d6;\n}\n.ace-cloud_editor_dark .ace_icon_svg.ace_hint {\n background-color: #44b9d6;\n}\n.ace-cloud_editor_dark .ace_highlight-marker {\n background: none;\n border: #66b2f0 1px solid;\n}\n.ace-cloud_editor_dark .ace_tooltip.ace_hover-tooltip:focus > div {\n outline: 1px solid #44b9d6;\n}\n.ace-cloud_editor_dark .ace_snippet-marker {\n background-color: #434650;\n border: 0;\n}\n\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\n background-color: #272A30;\n border: #299FBC 1.5px solid;\n}\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\n border: 1px solid #d5dbdb;\n background: #272A30;\n}\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete .ace_completion-meta {\n color: #95a5a6;\n opacity: 1;\n}\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\n color: #2AA0BC;\n}\n.ace-cloud_editor_dark.ace_dark.ace_editor.ace_autocomplete {\n box-shadow: 0 1px 1px 0 #001c244d, 1px 1px 1px 0 #001c2426, -1px 1px 1px 0 #001c2426;\n line-height: 1.5;\n border: 1px solid #2a2e33;\n background: #050506;\n color: #ffffff;\n}\n\n"})),ace.define("ace/theme/cloud_editor_dark",["require","exports","module","ace/theme/cloud_editor_dark-css","ace/lib/dom"],(function(e,c,o){c.isDark=!0,c.cssClass="ace-cloud_editor_dark",c.cssText=e("./cloud_editor_dark-css"),e("../lib/dom").importCssString(c.cssText,c.cssClass,!1)})),ace.require(["ace/theme/cloud_editor_dark"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/bfbf008c2d6aebaec1764670826893bb.js b/bfbf008c2d6aebaec1764670826893bb.js new file mode 100644 index 00000000..97a1d887 --- /dev/null +++ b/bfbf008c2d6aebaec1764670826893bb.js @@ -0,0 +1 @@ +ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};o.inherits(a,r),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),o="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[r.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[r.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:o},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(r,"doc-",[r.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var o="/"==e.charAt(1)?2:1;return 1==o?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==o&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==o?"":"end-")+"tag-open.xml",value:e.slice(0,o)},{type:"meta.tag.tag-name.xml",value:e.substr(o)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[r.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[r.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}o.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var o=e("../range").Range,r=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var r=n[1].length,a=e.findMatchingBracket({row:t,column:r});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new o(t,0,t,r-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(r.prototype),t.MatchingBraceOutdent=r})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,o,r){if('"'==r||"'"==r){var s=r,l=o.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),u=o.doc.getLine(c.row).substring(c.column,c.column+1),d=new a(o,c.row,c.column),g=d.getCurrentToken();if(u==s&&(i(g,"attribute-value")||i(g,"string")))return{text:"",selection:[1,1]};if(g||(g=d.stepBackward()),!g)return;for(;i(g,"tag-whitespace")||i(g,"whitespace");)g=d.stepBackward();var m=!u||u.match(/\s/);if(i(g,"attribute-equals")&&(m||">"==u)||i(g,"decl-attribute-equals")&&(m||"?"==u))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,o,r){var a=o.doc.getTextRange(r);if(!r.isMultiLine()&&('"'==a||"'"==a)&&o.doc.getLine(r.start.row).substring(r.start.column+1,r.start.column+2)==a)return r.end.column++,r})),this.add("autoclosing","insertion",(function(e,t,n,o,r){if(">"==r){var s=n.getSelectionRange().start,l=new a(o,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var u=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(o.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var g=l.getCurrentTokenRow(),m=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var p=c.value;if(g==s.row&&(p=p.substring(0,s.column-m)),this.voidElements&&this.voidElements.hasOwnProperty(p.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,o,r){if("\n"==r){var s=n.getCursorPosition(),l=o.getLine(s.row),c=new a(o,s.row,s.column),u=c.getCurrentToken();if(i(u,"")&&-1!==u.type.indexOf("tag-close")){if("/>"==u.value)return;for(;u&&-1===u.type.indexOf("tag-name");)u=c.stepBackward();if(!u)return;var d=u.value,g=c.getCurrentTokenRow();if(!(u=c.stepBackward())||-1!==u.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[d]||!this.voidElements){var m=o.getTokenAt(s.row,s.column+1),p=(l=o.getLine(g),this.$getIndent(l)),h=p+o.getTabString();return m&&""==a){var i=n.getSelectionRange().start,s=new r(o,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};o.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=o.mixin({},this.voidElements),t&&o.mixin(this.optionalEndTags,t)};o.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var o=this._getFirstTagInLine(e,n);return o?o.closing||!o.tagName&&o.selfClosing?"markbeginend"===t?"end":"":!o.tagName||o.selfClosing||this.voidElements.hasOwnProperty(o.tagName.toLowerCase())||this._findEndTagInLine(e,n,o.tagName,o.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return o}if(l(a,"tag-close"))return o.selfClosing="/>"==a.value,o;o.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,o){for(var r=e.getTokens(t),a=0,i=0;ic)break;var u=this.getFoldWidgetRange(e,"all",t);if(u){if(u.start.row<=a)break;if(u.isMultiLine())t=u.end.row;else if(o==c)break}s=t}}return new r(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new r(i,o,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new r};o.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,o){return this.getFoldWidgetRangeBase(e,t,n,o)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,u=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};o.inherits(u,r),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e),a=r.tokens,i=r.state;if(a.length&&"comment"==a[a.length-1].type)return o;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(o+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(u.prototype),t.Mode=u})),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=(e("../lib/lang"),e("./text_highlight_rules").TextHighlightRules),a=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",i=t.supportFunction="rgb|rgba|url|attr|counter|counters",s=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|flex-end|flex-start|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",l=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",c=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",u=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",d=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",g=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",m=function(){var e=this.createKeywordMapper({"support.function":i,"support.constant":s,"support.type":a,"support.constant.color":l,"support.constant.fonts":c},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:u},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+u+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:u},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:d},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:g},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{token:"paren.lparen",regex:"\\{"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};o.inherits(m,r),t.CssHighlightRules=m})),ace.define("ace/mode/css_completions",["require","exports","module"],(function(e,t,n){"use strict";var o={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,double:2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{default:1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},float:{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,static:1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},r=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e)if("string"==typeof e[t]){var n=t.replace(/[A-Z]/g,(function(e){return"-"+e.toLowerCase()}));o.hasOwnProperty(n)||(o[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,o){if(this.completionsDefined||this.defineCompletions(),"ruleset"===e||"ace/mode/scss"==t.$mode.$id){var r=t.getLine(n.row).substr(0,n.column),a=/\([^)]*$/.test(r);return a&&(r=r.substr(r.lastIndexOf("(")+1)),/:[^;]+$/.test(r)?(/([\w\-]+):[^:]*$/.test(r),this.getPropertyValueCompletions(e,t,n,o)):this.getPropertyCompletions(e,t,n,o,a)}return[]},this.getPropertyCompletions=function(e,t,n,r,a){return a=a||!1,Object.keys(o).map((function(e){return{caption:e,snippet:e+": $0"+(a?"":";"),meta:"property",score:1e6}}))},this.getPropertyValueCompletions=function(e,t,n,r){var a=t.getLine(n.row).substr(0,n.column),i=(/([\w\-]+):[^:]*$/.exec(a)||{})[1];if(!i)return[];var s=[];return i in o&&"object"==typeof o[i]&&(s=Object.keys(o[i])),s.map((function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}}))}}).call(r.prototype),t.CssCompletions=r})),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=(e("../behaviour").Behaviour,e("./cstyle").CstyleBehaviour),a=e("../../token_iterator").TokenIterator,i=function(){this.inherit(r),this.add("colon","insertion",(function(e,t,n,o,r){if(":"===r&&n.selection.isEmpty()){var i=n.getCursorPosition(),s=new a(o,i.row,i.column),l=s.getCurrentToken();if(l&&l.value.match(/\s+/)&&(l=s.stepBackward()),l&&"support.type"===l.type){var c=o.doc.getLine(i.row);if(":"===c.substring(i.column,i.column+1))return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(c.substring(i.column)))return{text:":;",selection:[1,1]}}}})),this.add("colon","deletion",(function(e,t,n,o,r){var i=o.doc.getTextRange(r);if(!r.isMultiLine()&&":"===i){var s=n.getCursorPosition(),l=new a(o,s.row,s.column),c=l.getCurrentToken();if(c&&c.value.match(/\s+/)&&(c=l.stepBackward()),c&&"support.type"===c.type&&";"===o.doc.getLine(r.start.row).substring(r.end.column,r.end.column+1))return r.end.column++,r}})),this.add("semicolon","insertion",(function(e,t,n,o,r){if(";"===r&&n.selection.isEmpty()){var a=n.getCursorPosition();if(";"===o.doc.getLine(a.row).substring(a.column,a.column+1))return{text:"",selection:[1,1]}}})),this.add("!important","insertion",(function(e,t,n,o,r){if("!"===r&&n.selection.isEmpty()){var a=n.getCursorPosition(),i=o.doc.getLine(a.row);if(/^\s*(;|}|$)/.test(i.substring(a.column)))return{text:"!important",selection:[10,10]}}}))};o.inherits(i,r),t.CssBehaviour=i})),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./css_highlight_rules").CssHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./css_completions").CssCompletions,c=e("./behaviour/css").CssBehaviour,u=e("./folding/cstyle").FoldMode,d=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new c,this.$completer=new l,this.foldingRules=new u};o.inherits(d,r),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e).tokens;return r.length&&"comment"==r[r.length-1].type||t.match(/^.*\{\s*$/)&&(o+=n),o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/css",this.snippetFileId="ace/snippets/css"}.call(d.prototype),t.Mode=d})),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(e){var t="[_:a-zA-ZÀ-￿][-_:.a-zA-Z0-9À-￿]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"--\x3e",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===a&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(r.prototype),o.inherits(a,r),t.XmlHighlightRules=a})),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./css_highlight_rules").CssHighlightRules,i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./xml_highlight_rules").XmlHighlightRules,l=r.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),c=function(){s.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=l[t];return["meta.tag.punctuation."+("<"==e?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(a,"css-","style"),this.embedTagRules(new i({jsx:!1}).getRules(),"js-","script"),this.constructor===c&&this.normalizeRules()};o.inherits(c,s),t.HtmlHighlightRules=c})),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};o.inherits(a,r),function(){this.$getMode=function(e){for(var t in"string"!=typeof e&&(e=e[0]),this.subModes)if(0===e.indexOf(t))return this.subModes[t];return null},this.$tryMode=function(e,t,n,o){var r=this.$getMode(e);return r?r.getFoldWidget(t,n,o):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var o=this.$getMode(e.getState(n-1));return o&&o.getFoldWidget(e,t,n)||(o=this.$getMode(e.getState(n))),o&&o.getFoldWidget(e,t,n)||(o=this.defaultMode),o.getFoldWidgetRange(e,t,n)}}.call(a.prototype)})),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./mixed").FoldMode,a=e("./xml").FoldMode,i=e("./cstyle").FoldMode,s=t.FoldMode=function(e,t){r.call(this,new a(e,t),{"js-":new i,"css-":new i})};o.inherits(s,r)})),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../token_iterator").TokenIterator,r=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"].concat(["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"]),a={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,for:1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{for:1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,default:1},section:{},summary:{},u:{},ul:{},var:{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},i=Object.keys(a);function s(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"tag-name");)r=n.stepBackward();if(r)return r.value}var c=function(){};(function(){this.getCompletions=function(e,t,n,o){var r=t.getTokenAt(n.row,n.column);if(!r)return[];if(s(r,"tag-name")||s(r,"tag-open")||s(r,"end-tag-open"))return this.getTagCompletions(e,t,n,o);if(s(r,"tag-whitespace")||s(r,"attribute-name"))return this.getAttributeCompletions(e,t,n,o);if(s(r,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,o);var a=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(a)?this.getHTMLEntityCompletions(e,t,n,o):[]},this.getTagCompletions=function(e,t,n,o){return i.map((function(e){return{value:e,meta:"tag",score:1e6}}))},this.getAttributeCompletions=function(e,t,n,o){var i=l(t,n);if(!i)return[];var s=r;return i in a&&(s=s.concat(Object.keys(a[i]))),s.map((function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}}))},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),c=function(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"attribute-name");)r=n.stepBackward();if(r)return r.value}(t,n);if(!i)return[];var u=[];return i in a&&c in a[i]&&"object"==typeof a[i][c]&&(u=Object.keys(a[i][c])),u.map((function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}}))},this.getHTMLEntityCompletions=function(e,t,n,o){return["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"].map((function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}}))}}).call(c.prototype),t.HtmlCompletions=c})),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./text").Mode,i=e("./javascript").Mode,s=e("./css").Mode,l=e("./html_highlight_rules").HtmlHighlightRules,c=e("./behaviour/xml").XmlBehaviour,u=e("./folding/html").FoldMode,d=e("./html_completions").HtmlCompletions,g=e("../worker/worker_client").WorkerClient,m=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],p=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],h=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=l,this.$behaviour=new c,this.$completer=new d,this.createModeDelegates({"js-":i,"css-":s}),this.foldingRules=new u(this.voidElements,r.arrayToMap(p))};o.inherits(h,a),function(){this.blockComment={start:"\x3c!--",end:"--\x3e"},this.voidElements=r.arrayToMap(m),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){if(this.constructor==h){var t=new g(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t}},this.$id="ace/mode/html",this.snippetFileId="ace/snippets/html"}.call(h.prototype),t.Mode=h})),ace.define("ace/mode/astro_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/javascript_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./html_highlight_rules").HtmlHighlightRules,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=function(){r.call(this);var e={token:"paren.quasi.start",regex:/{/,next:function(e,t){return"start"!==e&&(-1!==e.indexOf("attribute-equals")?(t.splice(0),t.unshift("tag_stuff")):t.unshift(e)),"inline-js-start"}};for(var t in this.$rules)t.startsWith("js")||t.startsWith("css")||t.startsWith("comment")||this.$rules[t].unshift(e);this.$rules.start.unshift({token:"comment",regex:/^---$/,onMatch:function(e,t,n){return n.splice(0),this.token},next:"javascript-start"}),this.embedRules(a,"javascript-",[{regex:/^---$/,token:"comment",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}]),this.embedRules(a,"inline-js-");var n=[{regex:/}/,token:"paren.quasi.end",onMatch:function(e,t,n){return"inline-js-start"===n[0]?(n.shift(),this.next=n.shift(),-1!==this.next.indexOf("string")?"paren.quasi.end":"paren.rparen"):(this.next=n.shift()||"start",this.token)}},{regex:/{/,token:"paren.lparen",push:"inline-js-start"}];function o(e){for(var t in this.$rules[e+"jsxAttributes"])if("meta.tag.punctuation.tag-close.xml"===this.$rules[e+"jsxAttributes"][t].token){this.$rules[e+"jsxAttributes"][t].onMatch=function(t,n,o){return n==o[0]&&o.shift(),2==t.length&&(o[0]==this.nextState&&o[1]--,(!o[1]||o[1]<0)&&o.splice(0,2)),this.next=o[0]||e+"start",[{type:this.token,value:t}]};break}}this.$rules["inline-js-start"].unshift(n),this.$rules["inline-js-no_regex"].unshift(n),o.call(this,"javascript-"),o.call(this,"inline-js-"),this.normalizeRules()};o.inherits(i,r),t.AstroHighlightRules=i})),ace.define("ace/mode/behaviour/html",["require","exports","module","ace/lib/oop","ace/mode/behaviour/xml"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../behaviour/xml").XmlBehaviour,a=function(){r.call(this)};o.inherits(a,r),t.HtmlBehaviour=a})),ace.define("ace/mode/astro",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/astro_highlight_rules","ace/mode/behaviour/html"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./html").Mode,a=e("./astro_highlight_rules").AstroHighlightRules,i=e("./behaviour/html").HtmlBehaviour,s=function(){r.call(this),this.HighlightRules=a,this.$behaviour=new i};o.inherits(s,r),function(){this.$id="ace/mode/astro"}.call(s.prototype),t.Mode=s})),ace.require(["ace/mode/astro"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/c1a1f4ba29aa2d9a0b1a1abe5cfee0c6.js b/c1a1f4ba29aa2d9a0b1a1abe5cfee0c6.js new file mode 100644 index 00000000..f23a8d7c --- /dev/null +++ b/c1a1f4ba29aa2d9a0b1a1abe5cfee0c6.js @@ -0,0 +1 @@ +ace.define("ace/mode/lsl_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(_,e,l){"use strict";var E=_("../lib/oop"),A=_("./text_highlight_rules").TextHighlightRules;function T(){var _=this.createKeywordMapper({"constant.language.float.lsl":"DEG_TO_RAD|PI|PI_BY_TWO|RAD_TO_DEG|SQRT2|TWO_PI","constant.language.integer.lsl":"ACTIVE|AGENT|AGENT_ALWAYS_RUN|AGENT_ATTACHMENTS|AGENT_AUTOPILOT|AGENT_AWAY|AGENT_BUSY|AGENT_BY_LEGACY_NAME|AGENT_BY_USERNAME|AGENT_CROUCHING|AGENT_FLYING|AGENT_IN_AIR|AGENT_LIST_PARCEL|AGENT_LIST_PARCEL_OWNER|AGENT_LIST_REGION|AGENT_MOUSELOOK|AGENT_ON_OBJECT|AGENT_SCRIPTED|AGENT_SITTING|AGENT_TYPING|AGENT_WALKING|ALL_SIDES|ANIM_ON|ATTACH_AVATAR_CENTER|ATTACH_BACK|ATTACH_BELLY|ATTACH_CHEST|ATTACH_CHIN|ATTACH_HEAD|ATTACH_HUD_BOTTOM|ATTACH_HUD_BOTTOM_LEFT|ATTACH_HUD_BOTTOM_RIGHT|ATTACH_HUD_CENTER_1|ATTACH_HUD_CENTER_2|ATTACH_HUD_TOP_CENTER|ATTACH_HUD_TOP_LEFT|ATTACH_HUD_TOP_RIGHT|ATTACH_LEAR|ATTACH_LEFT_PEC|ATTACH_LEYE|ATTACH_LFOOT|ATTACH_LHAND|ATTACH_LHIP|ATTACH_LLARM|ATTACH_LLLEG|ATTACH_LSHOULDER|ATTACH_LUARM|ATTACH_LULEG|ATTACH_MOUTH|ATTACH_NECK|ATTACH_NOSE|ATTACH_PELVIS|ATTACH_REAR|ATTACH_REYE|ATTACH_RFOOT|ATTACH_RHAND|ATTACH_RHIP|ATTACH_RIGHT_PEC|ATTACH_RLARM|ATTACH_RLLEG|ATTACH_RSHOULDER|ATTACH_RUARM|ATTACH_RULEG|AVOID_CHARACTERS|AVOID_DYNAMIC_OBSTACLES|AVOID_NONE|CAMERA_ACTIVE|CAMERA_BEHINDNESS_ANGLE|CAMERA_BEHINDNESS_LAG|CAMERA_DISTANCE|CAMERA_FOCUS|CAMERA_FOCUS_LAG|CAMERA_FOCUS_LOCKED|CAMERA_FOCUS_OFFSET|CAMERA_FOCUS_THRESHOLD|CAMERA_PITCH|CAMERA_POSITION|CAMERA_POSITION_LAG|CAMERA_POSITION_LOCKED|CAMERA_POSITION_THRESHOLD|CHANGED_ALLOWED_DROP|CHANGED_COLOR|CHANGED_INVENTORY|CHANGED_LINK|CHANGED_MEDIA|CHANGED_OWNER|CHANGED_REGION|CHANGED_REGION_START|CHANGED_SCALE|CHANGED_SHAPE|CHANGED_TELEPORT|CHANGED_TEXTURE|CHARACTER_ACCOUNT_FOR_SKIPPED_FRAMES|CHARACTER_AVOIDANCE_MODE|CHARACTER_CMD_JUMP|CHARACTER_CMD_SMOOTH_STOP|CHARACTER_CMD_STOP|CHARACTER_DESIRED_SPEED|CHARACTER_DESIRED_TURN_SPEED|CHARACTER_LENGTH|CHARACTER_MAX_ACCEL|CHARACTER_MAX_DECEL|CHARACTER_MAX_SPEED|CHARACTER_MAX_TURN_RADIUS|CHARACTER_ORIENTATION|CHARACTER_RADIUS|CHARACTER_STAY_WITHIN_PARCEL|CHARACTER_TYPE|CHARACTER_TYPE_A|CHARACTER_TYPE_B|CHARACTER_TYPE_C|CHARACTER_TYPE_D|CHARACTER_TYPE_NONE|CLICK_ACTION_BUY|CLICK_ACTION_NONE|CLICK_ACTION_OPEN|CLICK_ACTION_OPEN_MEDIA|CLICK_ACTION_PAY|CLICK_ACTION_PLAY|CLICK_ACTION_SIT|CLICK_ACTION_TOUCH|CONTENT_TYPE_ATOM|CONTENT_TYPE_FORM|CONTENT_TYPE_HTML|CONTENT_TYPE_JSON|CONTENT_TYPE_LLSD|CONTENT_TYPE_RSS|CONTENT_TYPE_TEXT|CONTENT_TYPE_XHTML|CONTENT_TYPE_XML|CONTROL_BACK|CONTROL_DOWN|CONTROL_FWD|CONTROL_LBUTTON|CONTROL_LEFT|CONTROL_ML_LBUTTON|CONTROL_RIGHT|CONTROL_ROT_LEFT|CONTROL_ROT_RIGHT|CONTROL_UP|DATA_BORN|DATA_NAME|DATA_ONLINE|DATA_PAYINFO|DATA_SIM_POS|DATA_SIM_RATING|DATA_SIM_STATUS|DEBUG_CHANNEL|DENSITY|ERR_GENERIC|ERR_MALFORMED_PARAMS|ERR_PARCEL_PERMISSIONS|ERR_RUNTIME_PERMISSIONS|ERR_THROTTLED|ESTATE_ACCESS_ALLOWED_AGENT_ADD|ESTATE_ACCESS_ALLOWED_AGENT_REMOVE|ESTATE_ACCESS_ALLOWED_GROUP_ADD|ESTATE_ACCESS_ALLOWED_GROUP_REMOVE|ESTATE_ACCESS_BANNED_AGENT_ADD|ESTATE_ACCESS_BANNED_AGENT_REMOVE|FALSE|FORCE_DIRECT_PATH|FRICTION|GCNP_RADIUS|GCNP_STATIC|GRAVITY_MULTIPLIER|HORIZONTAL|HTTP_BODY_MAXLENGTH|HTTP_BODY_TRUNCATED|HTTP_CUSTOM_HEADER|HTTP_METHOD|HTTP_MIMETYPE|HTTP_PRAGMA_NO_CACHE|HTTP_VERBOSE_THROTTLE|HTTP_VERIFY_CERT|INVENTORY_ALL|INVENTORY_ANIMATION|INVENTORY_BODYPART|INVENTORY_CLOTHING|INVENTORY_GESTURE|INVENTORY_LANDMARK|INVENTORY_NONE|INVENTORY_NOTECARD|INVENTORY_OBJECT|INVENTORY_SCRIPT|INVENTORY_SOUND|INVENTORY_TEXTURE|JSON_APPEND|KFM_CMD_PAUSE|KFM_CMD_PLAY|KFM_CMD_SET_MODE|KFM_CMD_STOP|KFM_COMMAND|KFM_DATA|KFM_FORWARD|KFM_LOOP|KFM_MODE|KFM_PING_PONG|KFM_REVERSE|KFM_ROTATION|KFM_TRANSLATION|LAND_LEVEL|LAND_LOWER|LAND_NOISE|LAND_RAISE|LAND_REVERT|LAND_SMOOTH|LINK_ALL_CHILDREN|LINK_ALL_OTHERS|LINK_ROOT|LINK_SET|LINK_THIS|LIST_STAT_GEOMETRIC_MEAN|LIST_STAT_MAX|LIST_STAT_MEAN|LIST_STAT_MEDIAN|LIST_STAT_MIN|LIST_STAT_NUM_COUNT|LIST_STAT_RANGE|LIST_STAT_STD_DEV|LIST_STAT_SUM|LIST_STAT_SUM_SQUARES|LOOP|MASK_BASE|MASK_EVERYONE|MASK_GROUP|MASK_NEXT|MASK_OWNER|OBJECT_ATTACHED_POINT|OBJECT_BODY_SHAPE_TYPE|OBJECT_CHARACTER_TIME|OBJECT_CLICK_ACTION|OBJECT_CREATOR|OBJECT_DESC|OBJECT_GROUP|OBJECT_HOVER_HEIGHT|OBJECT_LAST_OWNER_ID|OBJECT_NAME|OBJECT_OWNER|OBJECT_PATHFINDING_TYPE|OBJECT_PHANTOM|OBJECT_PHYSICS|OBJECT_PHYSICS_COST|OBJECT_POS|OBJECT_PRIM_EQUIVALENCE|OBJECT_RENDER_WEIGHT|OBJECT_RETURN_PARCEL|OBJECT_RETURN_PARCEL_OWNER|OBJECT_RETURN_REGION|OBJECT_ROOT|OBJECT_ROT|OBJECT_RUNNING_SCRIPT_COUNT|OBJECT_SCRIPT_MEMORY|OBJECT_SCRIPT_TIME|OBJECT_SERVER_COST|OBJECT_STREAMING_COST|OBJECT_TEMP_ON_REZ|OBJECT_TOTAL_SCRIPT_COUNT|OBJECT_UNKNOWN_DETAIL|OBJECT_VELOCITY|OPT_AVATAR|OPT_CHARACTER|OPT_EXCLUSION_VOLUME|OPT_LEGACY_LINKSET|OPT_MATERIAL_VOLUME|OPT_OTHER|OPT_STATIC_OBSTACLE|OPT_WALKABLE|PARCEL_COUNT_GROUP|PARCEL_COUNT_OTHER|PARCEL_COUNT_OWNER|PARCEL_COUNT_SELECTED|PARCEL_COUNT_TEMP|PARCEL_COUNT_TOTAL|PARCEL_DETAILS_AREA|PARCEL_DETAILS_DESC|PARCEL_DETAILS_GROUP|PARCEL_DETAILS_ID|PARCEL_DETAILS_NAME|PARCEL_DETAILS_OWNER|PARCEL_DETAILS_SEE_AVATARS|PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY|PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS|PARCEL_FLAG_ALLOW_CREATE_OBJECTS|PARCEL_FLAG_ALLOW_DAMAGE|PARCEL_FLAG_ALLOW_FLY|PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY|PARCEL_FLAG_ALLOW_GROUP_SCRIPTS|PARCEL_FLAG_ALLOW_LANDMARK|PARCEL_FLAG_ALLOW_SCRIPTS|PARCEL_FLAG_ALLOW_TERRAFORM|PARCEL_FLAG_LOCAL_SOUND_ONLY|PARCEL_FLAG_RESTRICT_PUSHOBJECT|PARCEL_FLAG_USE_ACCESS_GROUP|PARCEL_FLAG_USE_ACCESS_LIST|PARCEL_FLAG_USE_BAN_LIST|PARCEL_FLAG_USE_LAND_PASS_LIST|PARCEL_MEDIA_COMMAND_AGENT|PARCEL_MEDIA_COMMAND_AUTO_ALIGN|PARCEL_MEDIA_COMMAND_DESC|PARCEL_MEDIA_COMMAND_LOOP|PARCEL_MEDIA_COMMAND_LOOP_SET|PARCEL_MEDIA_COMMAND_PAUSE|PARCEL_MEDIA_COMMAND_PLAY|PARCEL_MEDIA_COMMAND_SIZE|PARCEL_MEDIA_COMMAND_STOP|PARCEL_MEDIA_COMMAND_TEXTURE|PARCEL_MEDIA_COMMAND_TIME|PARCEL_MEDIA_COMMAND_TYPE|PARCEL_MEDIA_COMMAND_UNLOAD|PARCEL_MEDIA_COMMAND_URL|PASS_ALWAYS|PASS_IF_NOT_HANDLED|PASS_NEVER|PASSIVE|PATROL_PAUSE_AT_WAYPOINTS|PAYMENT_INFO_ON_FILE|PAYMENT_INFO_USED|PAY_DEFAULT|PAY_HIDE|PERMISSION_ATTACH|PERMISSION_CHANGE_LINKS|PERMISSION_CONTROL_CAMERA|PERMISSION_DEBIT|PERMISSION_OVERRIDE_ANIMATIONS|PERMISSION_RETURN_OBJECTS|PERMISSION_SILENT_ESTATE_MANAGEMENT|PERMISSION_TAKE_CONTROLS|PERMISSION_TELEPORT|PERMISSION_TRACK_CAMERA|PERMISSION_TRIGGER_ANIMATION|PERM_ALL|PERM_COPY|PERM_MODIFY|PERM_MOVE|PERM_TRANSFER|PING_PONG|PRIM_ALPHA_MODE|PRIM_ALPHA_MODE_BLEND|PRIM_ALPHA_MODE_EMISSIVE|PRIM_ALPHA_MODE_MASK|PRIM_ALPHA_MODE_NONE|PRIM_BUMP_BARK|PRIM_BUMP_BLOBS|PRIM_BUMP_BRICKS|PRIM_BUMP_BRIGHT|PRIM_BUMP_CHECKER|PRIM_BUMP_CONCRETE|PRIM_BUMP_DARK|PRIM_BUMP_DISKS|PRIM_BUMP_GRAVEL|PRIM_BUMP_LARGETILE|PRIM_BUMP_NONE|PRIM_BUMP_SHINY|PRIM_BUMP_SIDING|PRIM_BUMP_STONE|PRIM_BUMP_STUCCO|PRIM_BUMP_SUCTION|PRIM_BUMP_TILE|PRIM_BUMP_WEAVE|PRIM_BUMP_WOOD|PRIM_COLOR|PRIM_DESC|PRIM_FLEXIBLE|PRIM_FULLBRIGHT|PRIM_GLOW|PRIM_HOLE_CIRCLE|PRIM_HOLE_DEFAULT|PRIM_HOLE_SQUARE|PRIM_HOLE_TRIANGLE|PRIM_LINK_TARGET|PRIM_MATERIAL|PRIM_MATERIAL_FLESH|PRIM_MATERIAL_GLASS|PRIM_MATERIAL_METAL|PRIM_MATERIAL_PLASTIC|PRIM_MATERIAL_RUBBER|PRIM_MATERIAL_STONE|PRIM_MATERIAL_WOOD|PRIM_MEDIA_ALT_IMAGE_ENABLE|PRIM_MEDIA_AUTO_LOOP|PRIM_MEDIA_AUTO_PLAY|PRIM_MEDIA_AUTO_SCALE|PRIM_MEDIA_AUTO_ZOOM|PRIM_MEDIA_CONTROLS|PRIM_MEDIA_CONTROLS_MINI|PRIM_MEDIA_CONTROLS_STANDARD|PRIM_MEDIA_CURRENT_URL|PRIM_MEDIA_FIRST_CLICK_INTERACT|PRIM_MEDIA_HEIGHT_PIXELS|PRIM_MEDIA_HOME_URL|PRIM_MEDIA_MAX_HEIGHT_PIXELS|PRIM_MEDIA_MAX_URL_LENGTH|PRIM_MEDIA_MAX_WHITELIST_COUNT|PRIM_MEDIA_MAX_WHITELIST_SIZE|PRIM_MEDIA_MAX_WIDTH_PIXELS|PRIM_MEDIA_PARAM_MAX|PRIM_MEDIA_PERMS_CONTROL|PRIM_MEDIA_PERMS_INTERACT|PRIM_MEDIA_PERM_ANYONE|PRIM_MEDIA_PERM_GROUP|PRIM_MEDIA_PERM_NONE|PRIM_MEDIA_PERM_OWNER|PRIM_MEDIA_WHITELIST|PRIM_MEDIA_WHITELIST_ENABLE|PRIM_MEDIA_WIDTH_PIXELS|PRIM_NAME|PRIM_NORMAL|PRIM_OMEGA|PRIM_PHANTOM|PRIM_PHYSICS|PRIM_PHYSICS_SHAPE_CONVEX|PRIM_PHYSICS_SHAPE_NONE|PRIM_PHYSICS_SHAPE_PRIM|PRIM_PHYSICS_SHAPE_TYPE|PRIM_POINT_LIGHT|PRIM_POSITION|PRIM_POS_LOCAL|PRIM_ROTATION|PRIM_ROT_LOCAL|PRIM_SCULPT_FLAG_INVERT|PRIM_SCULPT_FLAG_MIRROR|PRIM_SCULPT_TYPE_CYLINDER|PRIM_SCULPT_TYPE_MASK|PRIM_SCULPT_TYPE_PLANE|PRIM_SCULPT_TYPE_SPHERE|PRIM_SCULPT_TYPE_TORUS|PRIM_SHINY_HIGH|PRIM_SHINY_LOW|PRIM_SHINY_MEDIUM|PRIM_SHINY_NONE|PRIM_SIZE|PRIM_SLICE|PRIM_SPECULAR|PRIM_TEMP_ON_REZ|PRIM_TEXGEN|PRIM_TEXGEN_DEFAULT|PRIM_TEXGEN_PLANAR|PRIM_TEXT|PRIM_TEXTURE|PRIM_TYPE|PRIM_TYPE_BOX|PRIM_TYPE_CYLINDER|PRIM_TYPE_PRISM|PRIM_TYPE_RING|PRIM_TYPE_SCULPT|PRIM_TYPE_SPHERE|PRIM_TYPE_TORUS|PRIM_TYPE_TUBE|PROFILE_NONE|PROFILE_SCRIPT_MEMORY|PSYS_PART_BF_DEST_COLOR|PSYS_PART_BF_ONE|PSYS_PART_BF_ONE_MINUS_DEST_COLOR|PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA|PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR|PSYS_PART_BF_SOURCE_ALPHA|PSYS_PART_BF_SOURCE_COLOR|PSYS_PART_BF_ZERO|PSYS_PART_BLEND_FUNC_DEST|PSYS_PART_BLEND_FUNC_SOURCE|PSYS_PART_BOUNCE_MASK|PSYS_PART_EMISSIVE_MASK|PSYS_PART_END_ALPHA|PSYS_PART_END_COLOR|PSYS_PART_END_GLOW|PSYS_PART_END_SCALE|PSYS_PART_FLAGS|PSYS_PART_FOLLOW_SRC_MASK|PSYS_PART_FOLLOW_VELOCITY_MASK|PSYS_PART_INTERP_COLOR_MASK|PSYS_PART_INTERP_SCALE_MASK|PSYS_PART_MAX_AGE|PSYS_PART_RIBBON_MASK|PSYS_PART_START_ALPHA|PSYS_PART_START_COLOR|PSYS_PART_START_GLOW|PSYS_PART_START_SCALE|PSYS_PART_TARGET_LINEAR_MASK|PSYS_PART_TARGET_POS_MASK|PSYS_PART_WIND_MASK|PSYS_SRC_ACCEL|PSYS_SRC_ANGLE_BEGIN|PSYS_SRC_ANGLE_END|PSYS_SRC_BURST_PART_COUNT|PSYS_SRC_BURST_RADIUS|PSYS_SRC_BURST_RATE|PSYS_SRC_BURST_SPEED_MAX|PSYS_SRC_BURST_SPEED_MIN|PSYS_SRC_MAX_AGE|PSYS_SRC_OMEGA|PSYS_SRC_PATTERN|PSYS_SRC_PATTERN_ANGLE|PSYS_SRC_PATTERN_ANGLE_CONE|PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY|PSYS_SRC_PATTERN_DROP|PSYS_SRC_PATTERN_EXPLODE|PSYS_SRC_TARGET_KEY|PSYS_SRC_TEXTURE|PUBLIC_CHANNEL|PURSUIT_FUZZ_FACTOR|PURSUIT_GOAL_TOLERANCE|PURSUIT_INTERCEPT|PURSUIT_OFFSET|PU_EVADE_HIDDEN|PU_EVADE_SPOTTED|PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED|PU_FAILURE_INVALID_GOAL|PU_FAILURE_INVALID_START|PU_FAILURE_NO_NAVMESH|PU_FAILURE_NO_VALID_DESTINATION|PU_FAILURE_OTHER|PU_FAILURE_PARCEL_UNREACHABLE|PU_FAILURE_TARGET_GONE|PU_FAILURE_UNREACHABLE|PU_GOAL_REACHED|PU_SLOWDOWN_DISTANCE_REACHED|RCERR_CAST_TIME_EXCEEDED|RCERR_SIM_PERF_LOW|RCERR_UNKNOWN|RC_DATA_FLAGS|RC_DETECT_PHANTOM|RC_GET_LINK_NUM|RC_GET_NORMAL|RC_GET_ROOT_KEY|RC_MAX_HITS|RC_REJECT_AGENTS|RC_REJECT_LAND|RC_REJECT_NONPHYSICAL|RC_REJECT_PHYSICAL|RC_REJECT_TYPES|REGION_FLAG_ALLOW_DAMAGE|REGION_FLAG_ALLOW_DIRECT_TELEPORT|REGION_FLAG_BLOCK_FLY|REGION_FLAG_BLOCK_TERRAFORM|REGION_FLAG_DISABLE_COLLISIONS|REGION_FLAG_DISABLE_PHYSICS|REGION_FLAG_FIXED_SUN|REGION_FLAG_RESTRICT_PUSHOBJECT|REGION_FLAG_SANDBOX|REMOTE_DATA_CHANNEL|REMOTE_DATA_REPLY|REMOTE_DATA_REQUEST|REQUIRE_LINE_OF_SIGHT|RESTITUTION|REVERSE|ROTATE|SCALE|SCRIPTED|SIM_STAT_PCT_CHARS_STEPPED|SMOOTH|STATUS_BLOCK_GRAB|STATUS_BLOCK_GRAB_OBJECT|STATUS_BOUNDS_ERROR|STATUS_CAST_SHADOWS|STATUS_DIE_AT_EDGE|STATUS_INTERNAL_ERROR|STATUS_MALFORMED_PARAMS|STATUS_NOT_FOUND|STATUS_NOT_SUPPORTED|STATUS_OK|STATUS_PHANTOM|STATUS_PHYSICS|STATUS_RETURN_AT_EDGE|STATUS_ROTATE_X|STATUS_ROTATE_Y|STATUS_ROTATE_Z|STATUS_SANDBOX|STATUS_TYPE_MISMATCH|STATUS_WHITELIST_FAILED|STRING_TRIM|STRING_TRIM_HEAD|STRING_TRIM_TAIL|TOUCH_INVALID_FACE|TRAVERSAL_TYPE|TRAVERSAL_TYPE_FAST|TRAVERSAL_TYPE_NONE|TRAVERSAL_TYPE_SLOW|TRUE|TYPE_FLOAT|TYPE_INTEGER|TYPE_INVALID|TYPE_KEY|TYPE_ROTATION|TYPE_STRING|TYPE_VECTOR|VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY|VEHICLE_ANGULAR_DEFLECTION_TIMESCALE|VEHICLE_ANGULAR_FRICTION_TIMESCALE|VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE|VEHICLE_ANGULAR_MOTOR_DIRECTION|VEHICLE_ANGULAR_MOTOR_TIMESCALE|VEHICLE_BANKING_EFFICIENCY|VEHICLE_BANKING_MIX|VEHICLE_BANKING_TIMESCALE|VEHICLE_BUOYANCY|VEHICLE_FLAG_CAMERA_DECOUPLED|VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT|VEHICLE_FLAG_HOVER_TERRAIN_ONLY|VEHICLE_FLAG_HOVER_UP_ONLY|VEHICLE_FLAG_HOVER_WATER_ONLY|VEHICLE_FLAG_LIMIT_MOTOR_UP|VEHICLE_FLAG_LIMIT_ROLL_ONLY|VEHICLE_FLAG_MOUSELOOK_BANK|VEHICLE_FLAG_MOUSELOOK_STEER|VEHICLE_FLAG_NO_DEFLECTION_UP|VEHICLE_HOVER_EFFICIENCY|VEHICLE_HOVER_HEIGHT|VEHICLE_HOVER_TIMESCALE|VEHICLE_LINEAR_DEFLECTION_EFFICIENCY|VEHICLE_LINEAR_DEFLECTION_TIMESCALE|VEHICLE_LINEAR_FRICTION_TIMESCALE|VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE|VEHICLE_LINEAR_MOTOR_DIRECTION|VEHICLE_LINEAR_MOTOR_OFFSET|VEHICLE_LINEAR_MOTOR_TIMESCALE|VEHICLE_REFERENCE_FRAME|VEHICLE_TYPE_AIRPLANE|VEHICLE_TYPE_BALLOON|VEHICLE_TYPE_BOAT|VEHICLE_TYPE_CAR|VEHICLE_TYPE_NONE|VEHICLE_TYPE_SLED|VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY|VEHICLE_VERTICAL_ATTRACTION_TIMESCALE|VERTICAL|WANDER_PAUSE_AT_WAYPOINTS|XP_ERROR_EXPERIENCES_DISABLED|XP_ERROR_EXPERIENCE_DISABLED|XP_ERROR_EXPERIENCE_SUSPENDED|XP_ERROR_INVALID_EXPERIENCE|XP_ERROR_INVALID_PARAMETERS|XP_ERROR_KEY_NOT_FOUND|XP_ERROR_MATURITY_EXCEEDED|XP_ERROR_NONE|XP_ERROR_NOT_FOUND|XP_ERROR_NOT_PERMITTED|XP_ERROR_NO_EXPERIENCE|XP_ERROR_QUOTA_EXCEEDED|XP_ERROR_RETRY_UPDATE|XP_ERROR_STORAGE_EXCEPTION|XP_ERROR_STORE_DISABLED|XP_ERROR_THROTTLED|XP_ERROR_UNKNOWN_ERROR","constant.language.integer.boolean.lsl":"FALSE|TRUE","constant.language.quaternion.lsl":"ZERO_ROTATION","constant.language.string.lsl":"EOF|JSON_ARRAY|JSON_DELETE|JSON_FALSE|JSON_INVALID|JSON_NULL|JSON_NUMBER|JSON_OBJECT|JSON_STRING|JSON_TRUE|NULL_KEY|TEXTURE_BLANK|TEXTURE_DEFAULT|TEXTURE_MEDIA|TEXTURE_PLYWOOD|TEXTURE_TRANSPARENT|URL_REQUEST_DENIED|URL_REQUEST_GRANTED","constant.language.vector.lsl":"TOUCH_INVALID_TEXCOORD|TOUCH_INVALID_VECTOR|ZERO_VECTOR","invalid.broken.lsl":"LAND_LARGE_BRUSH|LAND_MEDIUM_BRUSH|LAND_SMALL_BRUSH","invalid.deprecated.lsl":"ATTACH_LPEC|ATTACH_RPEC|DATA_RATING|OBJECT_ATTACHMENT_GEOMETRY_BYTES|OBJECT_ATTACHMENT_SURFACE_AREA|PRIM_CAST_SHADOWS|PRIM_MATERIAL_LIGHT|PRIM_TYPE_LEGACY|PSYS_SRC_INNERANGLE|PSYS_SRC_OUTERANGLE|VEHICLE_FLAG_NO_FLY_UP|llClearExperiencePermissions|llCloud|llGetExperienceList|llMakeExplosion|llMakeFire|llMakeFountain|llMakeSmoke|llRemoteDataSetRegion|llSound|llSoundPreload|llXorBase64Strings|llXorBase64StringsCorrect","invalid.illegal.lsl":"event","invalid.unimplemented.lsl":"CHARACTER_MAX_ANGULAR_ACCEL|CHARACTER_MAX_ANGULAR_SPEED|CHARACTER_TURN_SPEED_MULTIPLIER|PERMISSION_CHANGE_JOINTS|PERMISSION_CHANGE_PERMISSIONS|PERMISSION_EXPERIENCE|PERMISSION_RELEASE_OWNERSHIP|PERMISSION_REMAP_CONTROLS|PRIM_PHYSICS_MATERIAL|PSYS_SRC_OBJ_REL_MASK|llCollisionSprite|llPointAt|llRefreshPrimURL|llReleaseCamera|llRemoteLoadScript|llSetPrimURL|llStopPointAt|llTakeCamera","reserved.godmode.lsl":"llGodLikeRezObject|llSetInventoryPermMask|llSetObjectPermMask","reserved.log.lsl":"print","keyword.control.lsl":"do|else|for|if|jump|return|while","storage.type.lsl":"float|integer|key|list|quaternion|rotation|string|vector","support.function.lsl":"llAbs|llAcos|llAddToLandBanList|llAddToLandPassList|llAdjustSoundVolume|llAgentInExperience|llAllowInventoryDrop|llAngleBetween|llApplyImpulse|llApplyRotationalImpulse|llAsin|llAtan2|llAttachToAvatar|llAttachToAvatarTemp|llAvatarOnLinkSitTarget|llAvatarOnSitTarget|llAxes2Rot|llAxisAngle2Rot|llBase64ToInteger|llBase64ToString|llBreakAllLinks|llBreakLink|llCSV2List|llCastRay|llCeil|llClearCameraParams|llClearLinkMedia|llClearPrimMedia|llCloseRemoteDataChannel|llCollisionFilter|llCollisionSound|llCos|llCreateCharacter|llCreateKeyValue|llCreateLink|llDataSizeKeyValue|llDeleteCharacter|llDeleteKeyValue|llDeleteSubList|llDeleteSubString|llDetachFromAvatar|llDetectedGrab|llDetectedGroup|llDetectedKey|llDetectedLinkNumber|llDetectedName|llDetectedOwner|llDetectedPos|llDetectedRot|llDetectedTouchBinormal|llDetectedTouchFace|llDetectedTouchNormal|llDetectedTouchPos|llDetectedTouchST|llDetectedTouchUV|llDetectedType|llDetectedVel|llDialog|llDie|llDumpList2String|llEdgeOfWorld|llEjectFromLand|llEmail|llEscapeURL|llEuler2Rot|llEvade|llExecCharacterCmd|llFabs|llFleeFrom|llFloor|llForceMouselook|llFrand|llGenerateKey|llGetAccel|llGetAgentInfo|llGetAgentLanguage|llGetAgentList|llGetAgentSize|llGetAlpha|llGetAndResetTime|llGetAnimation|llGetAnimationList|llGetAnimationOverride|llGetAttached|llGetAttachedList|llGetBoundingBox|llGetCameraPos|llGetCameraRot|llGetCenterOfMass|llGetClosestNavPoint|llGetColor|llGetCreator|llGetDate|llGetDisplayName|llGetEnergy|llGetEnv|llGetExperienceDetails|llGetExperienceErrorMessage|llGetForce|llGetFreeMemory|llGetFreeURLs|llGetGMTclock|llGetGeometricCenter|llGetHTTPHeader|llGetInventoryCreator|llGetInventoryKey|llGetInventoryName|llGetInventoryNumber|llGetInventoryPermMask|llGetInventoryType|llGetKey|llGetLandOwnerAt|llGetLinkKey|llGetLinkMedia|llGetLinkName|llGetLinkNumber|llGetLinkNumberOfSides|llGetLinkPrimitiveParams|llGetListEntryType|llGetListLength|llGetLocalPos|llGetLocalRot|llGetMass|llGetMassMKS|llGetMaxScaleFactor|llGetMemoryLimit|llGetMinScaleFactor|llGetNextEmail|llGetNotecardLine|llGetNumberOfNotecardLines|llGetNumberOfPrims|llGetNumberOfSides|llGetObjectDesc|llGetObjectDetails|llGetObjectMass|llGetObjectName|llGetObjectPermMask|llGetObjectPrimCount|llGetOmega|llGetOwner|llGetOwnerKey|llGetParcelDetails|llGetParcelFlags|llGetParcelMaxPrims|llGetParcelMusicURL|llGetParcelPrimCount|llGetParcelPrimOwners|llGetPermissions|llGetPermissionsKey|llGetPhysicsMaterial|llGetPos|llGetPrimMediaParams|llGetPrimitiveParams|llGetRegionAgentCount|llGetRegionCorner|llGetRegionFPS|llGetRegionFlags|llGetRegionName|llGetRegionTimeDilation|llGetRootPosition|llGetRootRotation|llGetRot|llGetSPMaxMemory|llGetScale|llGetScriptName|llGetScriptState|llGetSimStats|llGetSimulatorHostname|llGetStartParameter|llGetStaticPath|llGetStatus|llGetSubString|llGetSunDirection|llGetTexture|llGetTextureOffset|llGetTextureRot|llGetTextureScale|llGetTime|llGetTimeOfDay|llGetTimestamp|llGetTorque|llGetUnixTime|llGetUsedMemory|llGetUsername|llGetVel|llGetWallclock|llGiveInventory|llGiveInventoryList|llGiveMoney|llGround|llGroundContour|llGroundNormal|llGroundRepel|llGroundSlope|llHTTPRequest|llHTTPResponse|llInsertString|llInstantMessage|llIntegerToBase64|llJson2List|llJsonGetValue|llJsonSetValue|llJsonValueType|llKey2Name|llKeyCountKeyValue|llKeysKeyValue|llLinkParticleSystem|llLinkSitTarget|llList2CSV|llList2Float|llList2Integer|llList2Json|llList2Key|llList2List|llList2ListStrided|llList2Rot|llList2String|llList2Vector|llListFindList|llListInsertList|llListRandomize|llListReplaceList|llListSort|llListStatistics|llListen|llListenControl|llListenRemove|llLoadURL|llLog|llLog10|llLookAt|llLoopSound|llLoopSoundMaster|llLoopSoundSlave|llMD5String|llManageEstateAccess|llMapDestination|llMessageLinked|llMinEventDelay|llModPow|llModifyLand|llMoveToTarget|llNavigateTo|llOffsetTexture|llOpenRemoteDataChannel|llOverMyLand|llOwnerSay|llParcelMediaCommandList|llParcelMediaQuery|llParseString2List|llParseStringKeepNulls|llParticleSystem|llPassCollisions|llPassTouches|llPatrolPoints|llPlaySound|llPlaySoundSlave|llPow|llPreloadSound|llPursue|llPushObject|llReadKeyValue|llRegionSay|llRegionSayTo|llReleaseControls|llReleaseURL|llRemoteDataReply|llRemoteLoadScriptPin|llRemoveFromLandBanList|llRemoveFromLandPassList|llRemoveInventory|llRemoveVehicleFlags|llRequestAgentData|llRequestDisplayName|llRequestExperiencePermissions|llRequestInventoryData|llRequestPermissions|llRequestSecureURL|llRequestSimulatorData|llRequestURL|llRequestUsername|llResetAnimationOverride|llResetLandBanList|llResetLandPassList|llResetOtherScript|llResetScript|llResetTime|llReturnObjectsByID|llReturnObjectsByOwner|llRezAtRoot|llRezObject|llRot2Angle|llRot2Axis|llRot2Euler|llRot2Fwd|llRot2Left|llRot2Up|llRotBetween|llRotLookAt|llRotTarget|llRotTargetRemove|llRotateTexture|llRound|llSHA1String|llSameGroup|llSay|llScaleByFactor|llScaleTexture|llScriptDanger|llScriptProfiler|llSendRemoteData|llSensor|llSensorRemove|llSensorRepeat|llSetAlpha|llSetAngularVelocity|llSetAnimationOverride|llSetBuoyancy|llSetCameraAtOffset|llSetCameraEyeOffset|llSetCameraParams|llSetClickAction|llSetColor|llSetContentType|llSetDamage|llSetForce|llSetForceAndTorque|llSetHoverHeight|llSetKeyframedMotion|llSetLinkAlpha|llSetLinkCamera|llSetLinkColor|llSetLinkMedia|llSetLinkPrimitiveParams|llSetLinkPrimitiveParamsFast|llSetLinkTexture|llSetLinkTextureAnim|llSetLocalRot|llSetMemoryLimit|llSetObjectDesc|llSetObjectName|llSetParcelMusicURL|llSetPayPrice|llSetPhysicsMaterial|llSetPos|llSetPrimMediaParams|llSetPrimitiveParams|llSetRegionPos|llSetRemoteScriptAccessPin|llSetRot|llSetScale|llSetScriptState|llSetSitText|llSetSoundQueueing|llSetSoundRadius|llSetStatus|llSetText|llSetTexture|llSetTextureAnim|llSetTimerEvent|llSetTorque|llSetTouchText|llSetVehicleFlags|llSetVehicleFloatParam|llSetVehicleRotationParam|llSetVehicleType|llSetVehicleVectorParam|llSetVelocity|llShout|llSin|llSitTarget|llSleep|llSqrt|llStartAnimation|llStopAnimation|llStopHover|llStopLookAt|llStopMoveToTarget|llStopSound|llStringLength|llStringToBase64|llStringTrim|llSubStringIndex|llTakeControls|llTan|llTarget|llTargetOmega|llTargetRemove|llTeleportAgent|llTeleportAgentGlobalCoords|llTeleportAgentHome|llTextBox|llToLower|llToUpper|llTransferLindenDollars|llTriggerSound|llTriggerSoundLimited|llUnSit|llUnescapeURL|llUpdateCharacter|llUpdateKeyValue|llVecDist|llVecMag|llVecNorm|llVolumeDetect|llWanderWithin|llWater|llWhisper|llWind|llXorBase64","support.function.event.lsl":"at_rot_target|at_target|attach|changed|collision|collision_end|collision_start|control|dataserver|email|experience_permissions|experience_permissions_denied|http_request|http_response|land_collision|land_collision_end|land_collision_start|link_message|listen|money|moving_end|moving_start|no_sensor|not_at_rot_target|not_at_target|object_rez|on_rez|path_update|remote_data|run_time_permissions|sensor|state_entry|state_exit|timer|touch|touch_end|touch_start|transaction_result"},"identifier");this.$rules={start:[{token:"comment.line.double-slash.lsl",regex:"\\/\\/.*$"},{token:"comment.block.begin.lsl",regex:"\\/\\*",next:"comment"},{token:"string.quoted.double.lsl",start:'"',end:'"',next:[{token:"constant.character.escape.lsl",regex:/\\[tn"\\]/}]},{token:"constant.numeric.lsl",regex:"(0[xX][0-9a-fA-F]+|[+-]?[0-9]+(?:(?:\\.[0-9]*)?(?:[eE][+-]?[0-9]+)?)?)\\b"},{token:"entity.name.state.lsl",regex:"\\b((state)\\s+[A-Za-z_]\\w*|default)\\b"},{token:_,regex:"\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"},{token:"support.function.user-defined.lsl",regex:/\b([a-zA-Z_]\w*)(?=\(.*?\))/},{token:"keyword.operator.lsl",regex:"\\+\\+|\\-\\-|<<|>>|&&?|\\|\\|?|\\^|~|[!%<>=*+\\-\\/]=?"},{token:"invalid.illegal.keyword.operator.lsl",regex:":=?"},{token:"punctuation.operator.lsl",regex:"\\,|\\;"},{token:"paren.lparen.lsl",regex:"[\\[\\(\\{]"},{token:"paren.rparen.lsl",regex:"[\\]\\)\\}]"},{token:"text.lsl",regex:"\\s+"}],comment:[{token:"comment.block.end.lsl",regex:"\\*\\/",next:"start"},{defaultToken:"comment.block.lsl"}]},this.normalizeRules()}E.inherits(T,A),e.LSLHighlightRules=T})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(_,e,l){"use strict";var E=_("../range").Range,A=function(){};(function(){this.checkOutdent=function(_,e){return!!/^\s+$/.test(_)&&/^\s*\}/.test(e)},this.autoOutdent=function(_,e){var l=_.getLine(e).match(/^(\s*\})/);if(!l)return 0;var A=l[1].length,T=_.findMatchingBracket({row:e,column:A});if(!T||T.row==e)return 0;var R=this.$getIndent(_.getLine(T.row));_.replace(new E(e,0,e,A-1),R)},this.$getIndent=function(_){return _.match(/^\s*/)[0]}}).call(A.prototype),e.MatchingBraceOutdent=A})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(_,e,l){"use strict";var E=_("../../lib/oop"),A=_("../../range").Range,T=_("./fold_mode").FoldMode,R=e.FoldMode=function(_){_&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+_.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+_.end)))};E.inherits(R,T),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(_,e,l){var E=_.getLine(l);if(this.singleLineBlockCommentRe.test(E)&&!this.startRegionRe.test(E)&&!this.tripleStarBlockCommentRe.test(E))return"";var A=this._getFoldWidgetBase(_,e,l);return!A&&this.startRegionRe.test(E)?"start":A},this.getFoldWidgetRange=function(_,e,l,E){var A,T=_.getLine(l);if(this.startRegionRe.test(T))return this.getCommentRegionBlock(_,T,l);if(A=T.match(this.foldingStartMarker)){var R=A.index;if(A[1])return this.openingBracketBlock(_,A[1],l,R);var t=_.getCommentFoldRange(l,R+A[0].length,1);return t&&!t.isMultiLine()&&(E?t=this.getSectionRange(_,l):"all"!=e&&(t=null)),t}return"markbegin"!==e&&(A=T.match(this.foldingStopMarker))?(R=A.index+A[0].length,A[1]?this.closingBracketBlock(_,A[1],l,R):_.getCommentFoldRange(l,R,-1)):void 0},this.getSectionRange=function(_,e){for(var l=_.getLine(e),E=l.search(/\S/),T=e,R=l.length,t=e+=1,S=_.getLength();++eL)break;var I=this.getFoldWidgetRange(_,"all",e);if(I){if(I.start.row<=T)break;if(I.isMultiLine())e=I.end.row;else if(E==L)break}t=e}}return new A(T,R,t,_.getLine(t).length)},this.getCommentRegionBlock=function(_,e,l){for(var E=e.search(/\s*$/),T=_.getLength(),R=l,t=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,S=1;++lR)return new A(R,E,l,e.length)}}.call(R.prototype)})),ace.define("ace/mode/lsl",["require","exports","module","ace/mode/lsl_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/text","ace/mode/folding/cstyle","ace/lib/oop"],(function(_,e,l){"use strict";var E=_("./lsl_highlight_rules").LSLHighlightRules,A=_("./matching_brace_outdent").MatchingBraceOutdent,T=_("./text").Mode,R=_("./folding/cstyle").FoldMode,t=function(){this.HighlightRules=E,this.$outdent=new A,this.$behaviour=this.$defaultBehaviour,this.foldingRules=new R};_("../lib/oop").inherits(t,T),function(){this.lineCommentStart=["//"],this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(_,e,l){var E=this.$getIndent(e),A=this.getTokenizer().getLineTokens(e,_),T=A.tokens;return A.state,T.length&&"comment.block.lsl"===T[T.length-1].type||"start"===_&&e.match(/^.*[\{\(\[]\s*$/)&&(E+=l),E},this.checkOutdent=function(_,e,l){return this.$outdent.checkOutdent(e,l)},this.autoOutdent=function(_,e,l){this.$outdent.autoOutdent(e,l)},this.$id="ace/mode/lsl",this.snippetFileId="ace/snippets/lsl"}.call(t.prototype),e.Mode=t})),ace.require(["ace/mode/lsl"],(function(_){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=_)})); \ No newline at end of file diff --git a/c3832579be376308fa819b04e7b0c66f.js b/c3832579be376308fa819b04e7b0c66f.js new file mode 100644 index 00000000..75dc169d --- /dev/null +++ b/c3832579be376308fa819b04e7b0c66f.js @@ -0,0 +1 @@ +!function(t){if(!(void 0!==t.window&&t.document||t.require&&t.define)){t.console||(t.console=function(){var t=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:t})},t.console.error=t.console.warn=t.console.log=t.console.trace=t.console),t.window=t,t.ace=t,t.onerror=function(t,e,n,r,s){postMessage({type:"error",data:{message:t,data:s&&s.data,file:e,line:n,col:r,stack:s&&s.stack}})},t.normalizeModule=function(e,n){if(-1!==n.indexOf("!")){var r=n.split("!");return t.normalizeModule(e,r[0])+"!"+t.normalizeModule(e,r[1])}if("."==n.charAt(0)){var s=e.split("/").slice(0,-1).join("/");for(n=(s?s+"/":"")+n;-1!==n.indexOf(".")&&o!=n;){var o=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},t.require=function(e,n){if(n||(n=e,e=null),!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=t.normalizeModule(e,n);var r=t.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;if(!t.require.tlns)return console.log("unable to load "+n);var s=function(t,e){for(var n=t,r="";n;){var s=e[n];if("string"==typeof s)return s+r;if(s)return s.location.replace(/\/*$/,"/")+(r||s.main||s.name);if(!1===s)return"";var o=n.lastIndexOf("/");if(-1===o)break;r=n.substr(o)+r,n=n.slice(0,o)}return t}(n,t.require.tlns);return".js"!=s.slice(-3)&&(s+=".js"),t.require.id=n,t.require.modules[n]={},importScripts(s),t.require(e,n)},t.require.modules={},t.require.tlns={},t.define=function(e,n,r){if(2==arguments.length?(r=n,"string"!=typeof e&&(n=e,e=t.require.id)):1==arguments.length&&(r=e,n=[],e=t.require.id),"function"==typeof r){n.length||(n=["require","exports","module"]);var s=function(n){return t.require(e,n)};t.require.modules[e]={exports:{},factory:function(){var t=this,e=r.apply(this,n.slice(0,r.length).map((function(e){switch(e){case"require":return s;case"exports":return t.exports;case"module":return t;default:return s(e)}})));return e&&(t.exports=e),t}}}else t.require.modules[e]={exports:r,initialized:!0}},t.define.amd={},t.require.tlns={},t.initBaseUrls=function(t){for(var e in t)this.require.tlns[e]=t[e]},t.initSender=function(){var e=t.require("ace/lib/event_emitter").EventEmitter,n=t.require("ace/lib/oop"),r=function(){};return function(){n.implement(this,e),this.callback=function(t,e){postMessage({type:"call",id:e,data:t})},this.emit=function(t,e){postMessage({type:"event",name:t,data:e})}}.call(r.prototype),new r};var e=t.main=null,n=t.sender=null;t.onmessage=function(r){var s=r.data;if(s.event&&n)n._signal(s.event,s.data);else if(s.command)if(e[s.command])e[s.command].apply(e,s.args);else{if(!t[s.command])throw new Error("Unknown command:"+s.command);t[s.command].apply(t,s.args)}else if(s.init){t.initBaseUrls(s.tlns),n=t.sender=t.initSender();var o=this.require(s.module)[s.classname];e=t.main=new o(n)}}}}(this),ace.define("ace/lib/oop",[],(function(t,e,n){"use strict";e.inherits=function(t,e){t.super_=e,t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})},e.mixin=function(t,e){for(var n in e)t[n]=e[n];return t},e.implement=function(t,n){e.mixin(t,n)}})),ace.define("ace/apply_delta",[],(function(t,e,n){"use strict";e.applyDelta=function(t,e,n){var r=e.start.row,s=e.start.column,o=t[r]||"";switch(e.action){case"insert":if(1===e.lines.length)t[r]=o.substring(0,s)+e.lines[0]+o.substring(s);else{var a=[r,1].concat(e.lines);t.splice.apply(t,a),t[r]=o.substring(0,s)+t[r],t[r+e.lines.length-1]+=o.substring(s)}break;case"remove":var i=e.end.column,_=e.end.row;r===_?t[r]=o.substring(0,s)+o.substring(i):t.splice(r,_-r+1,o.substring(0,s)+t[_].substring(i))}}})),ace.define("ace/lib/event_emitter",[],(function(t,e,n){"use strict";var r={},s=function(){this.propagationStopped=!0},o=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(t,e){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[t]||[],r=this._defaultHandlers[t];if(n.length||r){"object"==typeof e&&e||(e={}),e.type||(e.type=t),e.stopPropagation||(e.stopPropagation=s),e.preventDefault||(e.preventDefault=o),n=n.slice();for(var a=0;a ["+this.end.row+"/"+this.end.column+"]"},t.prototype.contains=function(t,e){return 0==this.compare(t,e)},t.prototype.compareRange=function(t){var e,n=t.end,r=t.start;return 1==(e=this.compare(n.row,n.column))?1==(e=this.compare(r.row,r.column))?2:0==e?1:0:-1==e?-2:-1==(e=this.compare(r.row,r.column))?-1:1==e?42:0},t.prototype.comparePoint=function(t){return this.compare(t.row,t.column)},t.prototype.containsRange=function(t){return 0==this.comparePoint(t.start)&&0==this.comparePoint(t.end)},t.prototype.intersects=function(t){var e=this.compareRange(t);return-1==e||0==e||1==e},t.prototype.isEnd=function(t,e){return this.end.row==t&&this.end.column==e},t.prototype.isStart=function(t,e){return this.start.row==t&&this.start.column==e},t.prototype.setStart=function(t,e){"object"==typeof t?(this.start.column=t.column,this.start.row=t.row):(this.start.row=t,this.start.column=e)},t.prototype.setEnd=function(t,e){"object"==typeof t?(this.end.column=t.column,this.end.row=t.row):(this.end.row=t,this.end.column=e)},t.prototype.inside=function(t,e){return 0==this.compare(t,e)&&!this.isEnd(t,e)&&!this.isStart(t,e)},t.prototype.insideStart=function(t,e){return 0==this.compare(t,e)&&!this.isEnd(t,e)},t.prototype.insideEnd=function(t,e){return 0==this.compare(t,e)&&!this.isStart(t,e)},t.prototype.compare=function(t,e){return this.isMultiLine()||t!==this.start.row?tthis.end.row?1:this.start.row===t?e>=this.start.column?0:-1:this.end.row===t?e<=this.end.column?0:1:0:ethis.end.column?1:0},t.prototype.compareStart=function(t,e){return this.start.row==t&&this.start.column==e?-1:this.compare(t,e)},t.prototype.compareEnd=function(t,e){return this.end.row==t&&this.end.column==e?1:this.compare(t,e)},t.prototype.compareInside=function(t,e){return this.end.row==t&&this.end.column==e?1:this.start.row==t&&this.start.column==e?-1:this.compare(t,e)},t.prototype.clipRows=function(e,n){if(this.end.row>n)var r={row:n+1,column:0};else this.end.rown)var s={row:n+1,column:0};else this.start.rowthis.row)){var e=function(t,e,n){var r="insert"==t.action,s=(r?1:-1)*(t.end.row-t.start.row),o=(r?1:-1)*(t.end.column-t.start.column),i=t.start,_=r?i:t.end;return a(e,i,n)?{row:e.row,column:e.column}:a(_,e,!n)?{row:e.row+s,column:e.column+(e.row==_.row?o:0)}:{row:i.row,column:i.column}}(t,{row:this.row,column:this.column},this.$insertRight);this.setPosition(e.row,e.column,!0)}},t.prototype.setPosition=function(t,e,n){var r;if(r=n?{row:t,column:e}:this.$clipPositionToDocument(t,e),this.row!=r.row||this.column!=r.column){var s={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:s,value:r})}},t.prototype.detach=function(){this.document.off("change",this.$onChange)},t.prototype.attach=function(t){this.document=t||this.document,this.document.on("change",this.$onChange)},t.prototype.$clipPositionToDocument=function(t,e){var n={};return t>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):t<0?(n.row=0,n.column=0):(n.row=t,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,e))),e<0&&(n.column=0),n},t}();function a(t,e,n){var r=n?t.column<=e.column:t.column=n&&(t=n-1,e=void 0);var r=this.getLine(t);return null==e&&(e=r.length),{row:t,column:e=Math.min(Math.max(e,0),r.length)}},t.prototype.clonePos=function(t){return{row:t.row,column:t.column}},t.prototype.pos=function(t,e){return{row:t,column:e}},t.prototype.$clipPosition=function(t){var e=this.getLength();return t.row>=e?(t.row=Math.max(0,e-1),t.column=this.getLine(e-1).length):(t.row=Math.max(0,t.row),t.column=Math.min(Math.max(t.column,0),this.getLine(t.row).length)),t},t.prototype.insertFullLines=function(t,e){var n=0;(t=Math.min(Math.max(t,0),this.getLength()))0,r=e=0&&this.applyDelta({start:this.pos(t,this.getLine(t).length),end:this.pos(t+1,0),action:"remove",lines:["",""]})},t.prototype.replace=function(t,e){return t instanceof a||(t=a.fromPoints(t.start,t.end)),0===e.length&&t.isEmpty()?t.start:e==this.getTextRange(t)?t.end:(this.remove(t),e?this.insert(t.start,e):t.start)},t.prototype.applyDeltas=function(t){for(var e=0;e=0;e--)this.revertDelta(t[e])},t.prototype.applyDelta=function(t,e){var n="insert"==t.action;(n?t.lines.length<=1&&!t.lines[0]:!a.comparePoints(t.start,t.end))||(n&&t.lines.length>2e4?this.$splitAndapplyLargeDelta(t,2e4):(s(this.$lines,t,e),this._signal("change",t)))},t.prototype.$safeApplyDelta=function(t){var e=this.$lines.length;("remove"==t.action&&t.start.row0;)1&e&&(n+=t),(e>>=1)&&(t+=t);return n};var r=/^\s\s*/,s=/\s\s*$/;e.stringTrimLeft=function(t){return t.replace(r,"")},e.stringTrimRight=function(t){return t.replace(s,"")},e.copyObject=function(t){var e={};for(var n in t)e[n]=t[n];return e},e.copyArray=function(t){for(var e=[],n=0,r=t.length;n65535?2:1}})),ace.define("ace/worker/mirror",[],(function(t,e,n){"use strict";var r=t("../document").Document,s=t("../lib/lang"),o=e.Mirror=function(t){this.sender=t;var e=this.doc=new r(""),n=this.deferredUpdate=s.delayedCall(this.onUpdate.bind(this)),o=this;t.on("change",(function(t){var r=t.data;if(r[0].start)e.applyDeltas(r);else for(var s=0;s=e.$lines.length)throw(i=new Error("Invalid delta")).data={path:o.$path,linesLength:e.$lines.length,start:a.start,end:a.end},i;e.applyDelta(a,!0)}if(o.$timeout)return n.schedule(o.$timeout);o.onUpdate()}))};(function(){this.$timeout=500,this.setTimeout=function(t){this.$timeout=t},this.setValue=function(t){this.doc.setValue(t),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(t){this.sender.callback(this.doc.getValue(),t)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(o.prototype)})),ace.define("ace/mode/php/php",[],(function(t,e,n){var r={Constants:{}};r.Constants.T_THROW=317,r.Constants.T_INCLUDE=272,r.Constants.T_INCLUDE_ONCE=273,r.Constants.T_EVAL=274,r.Constants.T_REQUIRE=275,r.Constants.T_REQUIRE_ONCE=276,r.Constants.T_LOGICAL_OR=277,r.Constants.T_LOGICAL_XOR=278,r.Constants.T_LOGICAL_AND=279,r.Constants.T_PRINT=280,r.Constants.T_YIELD=281,r.Constants.T_DOUBLE_ARROW=386,r.Constants.T_YIELD_FROM=282,r.Constants.T_PLUS_EQUAL=352,r.Constants.T_MINUS_EQUAL=353,r.Constants.T_MUL_EQUAL=354,r.Constants.T_DIV_EQUAL=355,r.Constants.T_CONCAT_EQUAL=356,r.Constants.T_MOD_EQUAL=357,r.Constants.T_AND_EQUAL=358,r.Constants.T_OR_EQUAL=359,r.Constants.T_XOR_EQUAL=360,r.Constants.T_SL_EQUAL=361,r.Constants.T_SR_EQUAL=362,r.Constants.T_POW_EQUAL=402,r.Constants.T_COALESCE_EQUAL=363,r.Constants.T_COALESCE=400,r.Constants.T_BOOLEAN_OR=364,r.Constants.T_BOOLEAN_AND=365,r.Constants.T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG=404,r.Constants.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG=403,r.Constants.T_IS_EQUAL=366,r.Constants.T_IS_NOT_EQUAL=367,r.Constants.T_IS_IDENTICAL=368,r.Constants.T_IS_NOT_IDENTICAL=369,r.Constants.T_SPACESHIP=372,r.Constants.T_IS_SMALLER_OR_EQUAL=370,r.Constants.T_IS_GREATER_OR_EQUAL=371,r.Constants.T_SL=373,r.Constants.T_SR=374,r.Constants.T_INSTANCEOF=283,r.Constants.T_INC=375,r.Constants.T_DEC=376,r.Constants.T_INT_CAST=377,r.Constants.T_DOUBLE_CAST=378,r.Constants.T_STRING_CAST=379,r.Constants.T_ARRAY_CAST=380,r.Constants.T_OBJECT_CAST=381,r.Constants.T_BOOL_CAST=382,r.Constants.T_UNSET_CAST=383,r.Constants.T_POW=401,r.Constants.T_NEW=284,r.Constants.T_CLONE=285,r.Constants.T_EXIT=286,r.Constants.T_IF=287,r.Constants.T_ELSEIF=288,r.Constants.T_ELSE=289,r.Constants.T_ENDIF=290,r.Constants.T_LNUMBER=260,r.Constants.T_DNUMBER=261,r.Constants.T_STRING=262,r.Constants.T_STRING_VARNAME=270,r.Constants.T_VARIABLE=266,r.Constants.T_NUM_STRING=271,r.Constants.T_INLINE_HTML=267,r.Constants.T_ENCAPSED_AND_WHITESPACE=268,r.Constants.T_CONSTANT_ENCAPSED_STRING=269,r.Constants.T_ECHO=291,r.Constants.T_DO=292,r.Constants.T_WHILE=293,r.Constants.T_ENDWHILE=294,r.Constants.T_FOR=295,r.Constants.T_ENDFOR=296,r.Constants.T_FOREACH=297,r.Constants.T_ENDFOREACH=298,r.Constants.T_DECLARE=299,r.Constants.T_ENDDECLARE=300,r.Constants.T_AS=301,r.Constants.T_SWITCH=302,r.Constants.T_MATCH=306,r.Constants.T_ENDSWITCH=303,r.Constants.T_CASE=304,r.Constants.T_DEFAULT=305,r.Constants.T_BREAK=307,r.Constants.T_CONTINUE=308,r.Constants.T_GOTO=309,r.Constants.T_FUNCTION=310,r.Constants.T_FN=311,r.Constants.T_CONST=312,r.Constants.T_RETURN=313,r.Constants.T_TRY=314,r.Constants.T_CATCH=315,r.Constants.T_FINALLY=316,r.Constants.T_THROW=317,r.Constants.T_USE=318,r.Constants.T_INSTEADOF=319,r.Constants.T_GLOBAL=320,r.Constants.T_STATIC=321,r.Constants.T_ABSTRACT=322,r.Constants.T_FINAL=323,r.Constants.T_PRIVATE=324,r.Constants.T_PROTECTED=325,r.Constants.T_PUBLIC=326,r.Constants.T_READONLY=327,r.Constants.T_VAR=328,r.Constants.T_UNSET=329,r.Constants.T_ISSET=330,r.Constants.T_EMPTY=331,r.Constants.T_HALT_COMPILER=332,r.Constants.T_CLASS=333,r.Constants.T_TRAIT=334,r.Constants.T_INTERFACE=335,r.Constants.T_ENUM=336,r.Constants.T_EXTENDS=337,r.Constants.T_IMPLEMENTS=338,r.Constants.T_OBJECT_OPERATOR=384,r.Constants.T_NULLSAFE_OBJECT_OPERATOR=385,r.Constants.T_DOUBLE_ARROW=386,r.Constants.T_LIST=340,r.Constants.T_ARRAY=341,r.Constants.T_CALLABLE=342,r.Constants.T_CLASS_C=346,r.Constants.T_TRAIT_C=347,r.Constants.T_METHOD_C=348,r.Constants.T_FUNC_C=349,r.Constants.T_LINE=343,r.Constants.T_FILE=344,r.Constants.T_START_HEREDOC=393,r.Constants.T_END_HEREDOC=394,r.Constants.T_DOLLAR_OPEN_CURLY_BRACES=395,r.Constants.T_CURLY_OPEN=396,r.Constants.T_PAAMAYIM_NEKUDOTAYIM=397,r.Constants.T_NAMESPACE=339,r.Constants.T_NS_C=350,r.Constants.T_DIR=345,r.Constants.T_NS_SEPARATOR=398,r.Constants.T_ELLIPSIS=399,r.Constants.T_NAME_FULLY_QUALIFIED=263,r.Constants.T_NAME_QUALIFIED=265,r.Constants.T_NAME_RELATIVE=264,r.Constants.T_ATTRIBUTE=351,r.Constants.T_ENUM=336,r.Constants.T_BAD_CHARACTER=405,r.Constants.T_COMMENT=387,r.Constants.T_DOC_COMMENT=388,r.Constants.T_OPEN_TAG=389,r.Constants.T_OPEN_TAG_WITH_ECHO=390,r.Constants.T_CLOSE_TAG=391,r.Constants.T_WHITESPACE=392,r.Lexer=function(t,e){var n,s,o=["INITIAL"],a=0,i=function(t){o[a]=t},_=function(t){o[++a]=t},T=function(){--a},u=void 0===e||/^(on|true|1)$/i.test(e.short_open_tag),E=u?/^(\<\?php(?:\r\n|[ \t\r\n])|<\?|\ + + + + +
    +
    +

    Icon
    + 射线光学模拟

    + 自由、开源的网页程序,用于建立及模拟二维几何光学场景。
    +
    +
    +

    本项目,包括作品集内容,皆采用 Apache License 2.0 授权条款,且官方版本位于 PhyDemo(phydemo.app)网站(原先于 ricktu288.github.io)。本项目源代码公开于此 GitHub Repo,欢迎您贡献本项目。若有问题或建议,您可以在 GitHub 上建立 IssueDiscussion(请使用英文),也可以传送电子邮件至 ray-optics@phydemo.app(可使用中文)。

    + +

    + 引用本项目 +

    +

    主要作者

    + +

    贡献者

    +
      +
    • Stas Fainer(代码、作品集、模块)
    • +
    • Wei-Fang Sun(代码、介面设计)
    • +
    • Paul Falstad(代码、作品集)
    • +
    • James Garrard(代码、作品集)
    • +
    • digitalgreenery(代码)
    • +
    • Scott Cheng(代码)
    • +
    • Lo-Chen Cheng(de 翻译)
    • +
    • Michael Heise(de 翻译)
    • +
    • sadajun916(ja 翻译)
    • +
    • GLmontanari(代码)
    • +
    • Adrian Dorrington(代码)
    • +
    • Tharusha Theekshana(si 翻译)
    • +
    • Pedroobraga(pt-BR 翻译)
    • +
    • cyamahat(代码)
    • +
    • kqakqakqa(代码、zh-CN 翻译)
    • +
    • Miguel Sánchez Palomino(es 翻译)
    • +
    • SukkaW(代码)
    • +
    • Martin Poitras(代码)
    • +
    • BoopSnoot(ru 翻译)
    • +
    • mahjsa(nl 翻译)
    • +
    • Wen Zhou(作品集)
    • +
    • Cutivel Dimitri(fr 翻译)
    • +
    • Vincent Fan(代码、介面设计、作品集)
    • +
    • Victory Science(作品集)
    • +
    • Matteo Ricci Cipolloni(作品集)
    • +
    • Mikhail Kochiev(作品集)
    • +
    • Fundacja Nauka i Wiedza(pl 翻译)
    • +
    • Steve Stonebraker(作品集)
    • +
    • krzysztofkrzeslak(介面设计)
    • +
    • Young-Gi Kim(ko 翻译)
    • +
    • chuangyu J(作品集)
    • +
    • Georg Nadorff(作品集)
    • +
    • Rene(作品集)
    • +
    • josephernest(模块)
    • +
    • Alex(作品集)
    • +
    • Liu Quanhong(作品集)
    • +
    • Peter Becher(作品集)
    • +
    • Mario Petitclerc(作品集)
    • +
    + (GitHub 贡献者优先;其余依时间排序。) + +
    +
    + + +
    +
    + + + \ No newline at end of file diff --git a/cn/gallery/GRIN-slab-thumbnail.avif b/cn/gallery/GRIN-slab-thumbnail.avif new file mode 100644 index 00000000..1db50461 Binary files /dev/null and b/cn/gallery/GRIN-slab-thumbnail.avif differ diff --git a/cn/gallery/GRIN-slab-thumbnail.jpg b/cn/gallery/GRIN-slab-thumbnail.jpg new file mode 100644 index 00000000..379a8119 Binary files /dev/null and b/cn/gallery/GRIN-slab-thumbnail.jpg differ diff --git a/cn/gallery/GRIN-slab.avif b/cn/gallery/GRIN-slab.avif new file mode 100644 index 00000000..c57d3290 Binary files /dev/null and b/cn/gallery/GRIN-slab.avif differ diff --git a/cn/gallery/GRIN-slab.html b/cn/gallery/GRIN-slab.html new file mode 100644 index 00000000..81caf04f --- /dev/null +++ b/cn/gallery/GRIN-slab.html @@ -0,0 +1,172 @@ + + + + + + + 渐变折射率平板 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    渐变折射率平板

    +

    + 贡献者:Stas Fainer, Yi-Ting Tu +

    +
    +

    模拟折射率 \(n(\rho) = n_0 \sqrt{1-(\alpha \rho)^2}\)的介电材料,其中 \(n_0\) 是其中央轴的折射率,\(\rho \) 是从其中央轴的径向距离,使得 \(\alpha=\frac{\sqrt{3}}{2R} \),其中 \(R=100 \) 是其半径。上方的介电材料为一系列的薄矩形,每个矩形具有恒定的折射率(根据前述 \(n(\rho)\) 的式子)。下方的介电材料是折射率为\(n(\rho)\)的渐变折射率材料。

    +
    +

    + 在模拟器中打开 +

    + + + 渐变折射率平板 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/GRIN-slab.jpg b/cn/gallery/GRIN-slab.jpg new file mode 100644 index 00000000..8fdee17c Binary files /dev/null and b/cn/gallery/GRIN-slab.jpg differ diff --git a/cn/gallery/GRIN-slab.json b/cn/gallery/GRIN-slab.json new file mode 100644 index 00000000..118ced40 --- /dev/null +++ b/cn/gallery/GRIN-slab.json @@ -0,0 +1,198 @@ +{ + "name": "渐变折射率平板", + "version": 5, + "modules": { + "ApproxGrinSlab": { + "numPoints": 2, + "params": [ + "N=1:1:200:100" + ], + "objs": [ + { + "for": "i=0:1:N-1", + "type": "Glass", + "path": [ + { + "x": "`x_1`", + "y": "`y_1+(y_2-y_1)i/N`", + "arc": false + }, + { + "x": "`x_1`", + "y": "`y_1+(y_2-y_1)(i+1)/N`", + "arc": false + }, + { + "x": "`x_2`", + "y": "`y_1+(y_2-y_1)(i+1)/N`", + "arc": false + }, + { + "x": "`x_2`", + "y": "`y_1+(y_2-y_1)i/N`", + "arc": false + } + ], + "refIndex": "`2*sqrt(1-(sqrt(3)/(y_2-y_1)*abs((y_2-y_1)((i+0.5)/N-0.5)))^2)`" + } + ] + } + }, + "objs": [ + { + "type": "AngleSource", + "p1": { + "x": -100, + "y": 0 + }, + "p2": { + "x": -40, + "y": 0 + }, + "brightness": "0.8", + "emisAngle": "46" + }, + { + "type": "Ruler", + "p1": { + "x": -120, + "y": 0 + }, + "p2": { + "x": -120, + "y": -100 + } + }, + { + "type": "GrinGlass", + "path": [ + { + "x": 0, + "y": 200, + "arc": false + }, + { + "x": 0, + "y": 400, + "arc": false + }, + { + "x": 1000, + "y": 400, + "arc": false + }, + { + "x": 1000, + "y": 200, + "arc": false + } + ], + "refIndexFn": "2\\cdot\\sqrt{1-\\frac{3}{40000}y^2}", + "origin": { + "x": 0, + "y": 300 + }, + "stepSize": 0.5 + }, + { + "type": "Blocker", + "p1": { + "x": -240, + "y": 160 + }, + "p2": { + "x": 1576, + "y": 160 + } + }, + { + "type": "AngleSource", + "p1": { + "x": -100, + "y": 300 + }, + "p2": { + "x": -40, + "y": 300 + }, + "brightness": "0.8", + "emisAngle": "46" + }, + { + "type": "Ruler", + "p1": { + "x": -120, + "y": 300 + }, + "p2": { + "x": -120, + "y": 200 + } + }, + { + "type": "ModuleObj", + "module": "ApproxGrinSlab", + "points": [ + { + "x": 0, + "y": -100 + }, + { + "x": 1000, + "y": 100 + } + ], + "params": { + "N": 100 + } + }, + { + "type": "TextLabel", + "x": -270.0000000000001, + "y": -172, + "text": "警告:光线出现的顺序并不代表实际的光速。只有最终的图像有意义。", + "fontSize": "37" + }, + { + "type": "TextLabel", + "x": -223.99999999999997, + "y": 140.1290322580645, + "text": "用多层近似的渐变折射率平板(您可以选择并更改层数 N)" + }, + { + "type": "TextLabel", + "x": -214.70967741935488, + "y": 451.0645161290323, + "text": "正统的渐变折射率平板(您可以选择并更改数值求解器的步长)" + }, + { + "type": "CropBox", + "p1": { + "x": -262.65538600919143, + "y": -158.53830518758198 + }, + "p4": { + "x": 1039.1510656037117, + "y": 470.64879158661137 + } + }, + { + "type": "CropBox", + "p1": { + "x": 10.247839797260134, + "y": 175.42193475817962 + }, + "p4": { + "x": 256.44138779726006, + "y": 421.61548314527636 + } + } + ], + "width": 1952.7096774193546, + "height": 1280.090322580645, + "origin": { + "x": 588.1069989124172, + "y": 483.9899180908078 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/NL-simulation-thumbnail.avif b/cn/gallery/NL-simulation-thumbnail.avif new file mode 100644 index 00000000..22850411 Binary files /dev/null and b/cn/gallery/NL-simulation-thumbnail.avif differ diff --git a/cn/gallery/NL-simulation-thumbnail.jpg b/cn/gallery/NL-simulation-thumbnail.jpg new file mode 100644 index 00000000..32167a9e Binary files /dev/null and b/cn/gallery/NL-simulation-thumbnail.jpg differ diff --git a/cn/gallery/NL-simulation.avif b/cn/gallery/NL-simulation.avif new file mode 100644 index 00000000..bcb0d496 Binary files /dev/null and b/cn/gallery/NL-simulation.avif differ diff --git a/cn/gallery/NL-simulation.html b/cn/gallery/NL-simulation.html new file mode 100644 index 00000000..a4cb4b56 --- /dev/null +++ b/cn/gallery/NL-simulation.html @@ -0,0 +1,172 @@ + + + + + + + NL 双筒望远镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    NL 双筒望远镜

    +

    + 贡献者:Wen Zhou +

    +
    +

    这个模拟展示了 Swarovski NL 双筒望远镜的粗略草图。

    +
    +

    + 在模拟器中打开 +

    + + + NL 双筒望远镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/NL-simulation.jpg b/cn/gallery/NL-simulation.jpg new file mode 100644 index 00000000..c6212ea0 Binary files /dev/null and b/cn/gallery/NL-simulation.jpg differ diff --git a/cn/gallery/NL-simulation.json b/cn/gallery/NL-simulation.json new file mode 100644 index 00000000..b73dd76d --- /dev/null +++ b/cn/gallery/NL-simulation.json @@ -0,0 +1,434 @@ +{ + "name": "NL 双筒望远镜", + "version": 5, + "objs": [ + { + "type": "SphericalLens", + "path": [ + { + "x": 850, + "y": 558, + "arc": false + }, + { + "x": 870, + "y": 558, + "arc": false + }, + { + "x": 872, + "y": 709, + "arc": true + }, + { + "x": 870, + "y": 860, + "arc": false + }, + { + "x": 850, + "y": 860, + "arc": false + }, + { + "x": 839.9895878505357, + "y": 709.5, + "arc": true + } + ] + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 888, + "y": 560, + "arc": false + }, + { + "x": 940, + "y": 560, + "arc": false + }, + { + "x": 940, + "y": 710, + "arc": true + }, + { + "x": 940, + "y": 860, + "arc": false + }, + { + "x": 888, + "y": 860, + "arc": false + }, + { + "x": 878, + "y": 710, + "arc": true + } + ] + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 1150, + "y": 600, + "arc": false + }, + { + "x": 1170, + "y": 600, + "arc": false + }, + { + "x": 1160, + "y": 710, + "arc": true + }, + { + "x": 1170, + "y": 820, + "arc": false + }, + { + "x": 1150, + "y": 820, + "arc": false + }, + { + "x": 1140, + "y": 710, + "arc": true + } + ] + }, + { + "type": "Mirror", + "p1": { + "x": 1480, + "y": 640 + }, + "p2": { + "x": 1699.0259690163161, + "y": 542.3986105701293 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 1538.1183235768412, + "y": 792.4732943073643, + "arc": false + }, + { + "x": 1738.1183235768412, + "y": 592.4732943073643, + "arc": false + }, + { + "x": 1735.4559245523026, + "y": 880.0700021262944, + "arc": false + } + ], + "refIndex": 1.75 + }, + { + "type": "SingleRay", + "p1": { + "x": -514.141325189438, + "y": 1248.7510749076566 + }, + "p2": { + "x": -94.1413251894378, + "y": 1248.7510749076566 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 1480, + "y": 820, + "arc": false + }, + { + "x": 1480, + "y": 640, + "arc": false + }, + { + "x": 1700, + "y": 540, + "arc": false + }, + { + "x": 1700, + "y": 600, + "arc": false + }, + { + "x": 1480, + "y": 820, + "arc": false + } + ], + "refIndex": 1.78 + }, + { + "type": "Mirror", + "p1": { + "x": 1738.0526380162619, + "y": 883.4758364522121 + }, + "p2": { + "x": 1543.763352846318, + "y": 794.3549707305232 + } + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 1760, + "y": 620, + "arc": false + }, + { + "x": 1800, + "y": 620, + "arc": false + }, + { + "x": 1800, + "y": 720, + "arc": true + }, + { + "x": 1800, + "y": 820, + "arc": false + }, + { + "x": 1760, + "y": 820, + "arc": false + }, + { + "x": 1780, + "y": 720, + "arc": true + } + ] + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 1810, + "y": 600, + "arc": false + }, + { + "x": 1830, + "y": 600, + "arc": false + }, + { + "x": 1860, + "y": 720, + "arc": true + }, + { + "x": 1830, + "y": 840, + "arc": false + }, + { + "x": 1810, + "y": 840, + "arc": false + }, + { + "x": 1820, + "y": 720, + "arc": true + } + ], + "refIndex": 1.64 + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 2008.118323576841, + "y": 580, + "arc": false + }, + { + "x": 2028.118323576841, + "y": 580, + "arc": false + }, + { + "x": 2058.118323576841, + "y": 720, + "arc": true + }, + { + "x": 2028.118323576841, + "y": 860, + "arc": false + }, + { + "x": 2008.118323576841, + "y": 860, + "arc": false + }, + { + "x": 1998.118323576841, + "y": 720, + "arc": true + } + ], + "refIndex": 1.82 + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 2080, + "y": 580, + "arc": false + }, + { + "x": 2120, + "y": 580, + "arc": false + }, + { + "x": 2130, + "y": 720, + "arc": true + }, + { + "x": 2120, + "y": 860, + "arc": false + }, + { + "x": 2080, + "y": 860, + "arc": false + }, + { + "x": 2070, + "y": 720, + "arc": true + } + ], + "refIndex": 1.66 + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 2170, + "y": 580, + "arc": false + }, + { + "x": 2190, + "y": 580, + "arc": false + }, + { + "x": 2180, + "y": 720, + "arc": true + }, + { + "x": 2190, + "y": 860, + "arc": false + }, + { + "x": 2170, + "y": 860, + "arc": false + }, + { + "x": 2140, + "y": 720, + "arc": true + } + ], + "refIndex": 1.87 + }, + { + "type": "Beam", + "p1": { + "x": -556.7214422673449, + "y": 594.8397658441859 + }, + "p2": { + "x": -556.7214422673449, + "y": 774.8397658441854 + } + }, + { + "type": "Beam", + "p1": { + "x": -555.2223859280703, + "y": 83.2695633193527 + }, + "p2": { + "x": -569.4787191804917, + "y": 294.0173227131519 + } + }, + { + "type": "CropBox", + "p1": { + "x": -654.387294490692, + "y": -41.45499909007458 + }, + "p4": { + "x": 2691.212705509308, + "y": 1369.7450009099257 + } + }, + { + "type": "CropBox", + "p1": { + "x": 795.2127055093079, + "y": 10.54500090992542 + }, + "p4": { + "x": 2239.212705509308, + "y": 1454.5450009099254 + } + } + ], + "width": 5018.4, + "height": 3084, + "rayModeDensity": 0.06070677333952344, + "observer": { + "c": { + "x": 2359.494393545097, + "y": 727.7437382512829 + }, + "r": 20 + }, + "origin": { + "x": 1490.7872944906921, + "y": 877.8549990900746 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/aplanatic-points-thumbnail.avif b/cn/gallery/aplanatic-points-thumbnail.avif new file mode 100644 index 00000000..e9858b6a Binary files /dev/null and b/cn/gallery/aplanatic-points-thumbnail.avif differ diff --git a/cn/gallery/aplanatic-points-thumbnail.jpg b/cn/gallery/aplanatic-points-thumbnail.jpg new file mode 100644 index 00000000..8e3cb51b Binary files /dev/null and b/cn/gallery/aplanatic-points-thumbnail.jpg differ diff --git a/cn/gallery/aplanatic-points.avif b/cn/gallery/aplanatic-points.avif new file mode 100644 index 00000000..d2d5a07e Binary files /dev/null and b/cn/gallery/aplanatic-points.avif differ diff --git a/cn/gallery/aplanatic-points.html b/cn/gallery/aplanatic-points.html new file mode 100644 index 00000000..e3bc5231 --- /dev/null +++ b/cn/gallery/aplanatic-points.html @@ -0,0 +1,178 @@ + + + + + + + 等光程点 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    等光程点

    +

    + 贡献者:Stas Fainer +

    +
    +

    光学系统的等光程点是其光学轴上的特殊点,即“从其中一点发出的光线会汇聚到另一点,或看似从从该点发散”。

    +
      +
    • 椭圆:椭圆镜片/镜子的两个焦点是等光程点,因为从一个焦点发出的光将汇聚向另一点。
    • +
    • 球体:球形透镜有两个等光程点,分别在球内和球外 - 更多细节请见模拟。
    • +
    • 双曲线:在双曲面镜模拟中的两个焦点也是等光程点。
    • +
    +

    给定两个拥有水平座标 \(x_1\) 和 \(x_2\) 、具有相同垂直座标的点,并且设光学元件外部和内部的折射率分别为 \(n_1\) 和 \(n_2\),则若这两点要成为等光程点,我们的光学元件的边界必须满足\begin{equation}k_1 n_1 \sqrt{ (x - x_1)^2 + y^2} + k_2 n_2 \sqrt{ (x - x_2)^2 + y^2} = E\end{equation}使得 \(k_i=1\) 或 \(-1\)(取决于连接 \(x_i\) 和我们的光学元件边界的光线是实的或虚的),而 \(E\) 是一个使这个方程有非平凡解的常数。这个方程(可以用费马原理推导出来)是笛卡尔卵形线的方程(圆锥曲线是其特例)。

    +
    +

    + 在模拟器中打开 +

    + + + 等光程点 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/aplanatic-points.jpg b/cn/gallery/aplanatic-points.jpg new file mode 100644 index 00000000..34647bde Binary files /dev/null and b/cn/gallery/aplanatic-points.jpg differ diff --git a/cn/gallery/aplanatic-points.json b/cn/gallery/aplanatic-points.json new file mode 100644 index 00000000..780be6bd --- /dev/null +++ b/cn/gallery/aplanatic-points.json @@ -0,0 +1,303 @@ +{ + "name": "等光程点", + "version": 5, + "objs": [ + { + "type": "CustomGlass", + "p1": { + "x": 640, + "y": -500 + }, + "p2": { + "x": 1000, + "y": -500 + }, + "eqn1": "-0.5\\cdot\\sqrt{1-x^2}" + }, + { + "type": "Blocker", + "p1": { + "x": 640, + "y": 240 + }, + "p2": { + "x": 1000, + "y": 240 + } + }, + { + "type": "CircleGlass", + "p1": { + "x": 820, + "y": 60 + }, + "p2": { + "x": 1000, + "y": 60 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 700, + "y": 60 + }, + "p2": { + "x": 960, + "y": 60 + }, + "emisAngle": 162 + }, + { + "type": "Blocker", + "p1": { + "x": 1000, + "y": -600 + }, + "p2": { + "x": 640, + "y": -600 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1000, + "y": -400 + }, + "p2": { + "x": 1000, + "y": -600 + } + }, + { + "type": "Blocker", + "p1": { + "x": 640, + "y": -400 + }, + "p2": { + "x": 1000, + "y": -400 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1000, + "y": -120 + }, + "p2": { + "x": 1000, + "y": 240 + } + }, + { + "type": "Blocker", + "p1": { + "x": 640, + "y": -120 + }, + "p2": { + "x": 1000, + "y": -120 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 664.115427318801, + "y": -500 + }, + "p2": { + "x": 720, + "y": -500 + }, + "emisAngle": 162 + }, + { + "type": "Blocker", + "p1": { + "x": 640, + "y": -400 + }, + "p2": { + "x": 640, + "y": -600 + } + }, + { + "type": "Blocker", + "p1": { + "x": 640, + "y": 240 + }, + "p2": { + "x": 640, + "y": -120 + } + }, + { + "type": "Blocker", + "p1": { + "x": 640, + "y": -840 + }, + "p2": { + "x": 640, + "y": 440 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 550, + "y": 90 + }, + "p2": { + "x": 550, + "y": 70 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 700.048951048951, + "y": 90 + }, + "p2": { + "x": 700.048951048951, + "y": 70 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 664.0364698291962, + "y": -472.4595062650682 + }, + "p2": { + "x": 664.0364698291962, + "y": -492.4595062650683 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 976.7252915814619, + "y": -472.4595062650682 + }, + "p2": { + "x": 976.7252915814619, + "y": -492.4595062650683 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 664.0364698291962, + "y": -472.4595062650682 + }, + "p2": { + "x": 664.0364698291962, + "y": -492.4595062650683 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 640, + "y": -870 + }, + "p2": { + "x": 640, + "y": -850 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": -960, + "y": -480, + "text": "点选“延长光线”按钮以验证从球面镜片中的光源(点 A)发出的光,\n是从球面镜片外的光学轴上的另一点(点 B)发散,无球面像差。\n点 A 和 B 是球体的等光程点的例子。对于此点,在标记的 Y 轴的相对座标中(k1, k2, n1, n2, x1, x2, E)=(1, -1, 1.5, 1, 3 * 20, -4.5 * 20, 0),\n其中 x1,x2 是点 A,B 的水平座标(每个网格单元的尺寸为 20x20)。\n同样地,椭圆的焦点(点 C 和 D)是椭圆的等光程点的例子,对于此点(k1, k2, n1, n2, E)=(1, 1, 1.5, 1.5, > 0)" + }, + { + "type": "TextLabel", + "x": 1020, + "y": -60, + "text": "球面透镜" + }, + { + "type": "TextLabel", + "x": 1009.3333333333333, + "y": -544, + "text": "椭圆透镜" + }, + { + "type": "TextLabel", + "x": 693.3333333333333, + "y": 119.33333333333334, + "text": "A" + }, + { + "type": "TextLabel", + "x": 544, + "y": 119.33333333333331, + "text": "B" + }, + { + "type": "TextLabel", + "x": 967, + "y": -446, + "text": "C" + }, + { + "type": "TextLabel", + "x": 656.2666666666667, + "y": -445.6000000000001, + "text": "D" + }, + { + "type": "TextLabel", + "x": 638.1814223512337, + "y": -877.7406869859694, + "text": "Y 轴", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": -1011.6168389230002, + "y": -951.9758897459494 + }, + "p4": { + "x": 1275.0498277436664, + "y": 300.82411025405054 + } + }, + { + "type": "CropBox", + "p1": { + "x": 643.0498277436664, + "y": -681.1758897459495 + }, + "p4": { + "x": 1006.0498277436664, + "y": -318.17588974594946 + } + } + ], + "width": 3430, + "height": 2396.133333333333, + "rayModeDensity": 0.1210577348092538, + "origin": { + "x": 1583.2835055896667, + "y": 1523.6425564126162 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/apparent-depth-thumbnail.avif b/cn/gallery/apparent-depth-thumbnail.avif new file mode 100644 index 00000000..a86fcbc3 Binary files /dev/null and b/cn/gallery/apparent-depth-thumbnail.avif differ diff --git a/cn/gallery/apparent-depth-thumbnail.jpg b/cn/gallery/apparent-depth-thumbnail.jpg new file mode 100644 index 00000000..7a2a8250 Binary files /dev/null and b/cn/gallery/apparent-depth-thumbnail.jpg differ diff --git a/cn/gallery/apparent-depth.avif b/cn/gallery/apparent-depth.avif new file mode 100644 index 00000000..13184e57 Binary files /dev/null and b/cn/gallery/apparent-depth.avif differ diff --git a/cn/gallery/apparent-depth.html b/cn/gallery/apparent-depth.html new file mode 100644 index 00000000..85c9149c --- /dev/null +++ b/cn/gallery/apparent-depth.html @@ -0,0 +1,172 @@ + + + + + + + 视深度 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    视深度

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    当您从空气中观察水下的物体时,物体的深度会看似小于其实际深度。本模拟演示了这种由光的折射造成的现象。视深度与观察者的位置有关,这点我们可以通过拖动蓝色圆圈来演示。

    +
    +

    + 在模拟器中打开 +

    + + + 视深度 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/apparent-depth.jpg b/cn/gallery/apparent-depth.jpg new file mode 100644 index 00000000..34cd3e2e Binary files /dev/null and b/cn/gallery/apparent-depth.jpg differ diff --git a/cn/gallery/apparent-depth.json b/cn/gallery/apparent-depth.json new file mode 100644 index 00000000..d66e9e13 --- /dev/null +++ b/cn/gallery/apparent-depth.json @@ -0,0 +1,91 @@ +{ + "name": "视深度", + "version": 5, + "objs": [ + { + "type": "PlaneGlass", + "p1": { + "x": 760, + "y": 400 + }, + "p2": { + "x": 820, + "y": 400 + }, + "refIndex": 1.33 + }, + { + "type": "PointSource", + "x": 680, + "y": 600, + "brightness": 1 + }, + { + "type": "Ruler", + "p1": { + "x": 680, + "y": 600 + }, + "p2": { + "x": 680, + "y": 400 + } + }, + { + "type": "TextLabel", + "x": 714.7, + "y": 537.4, + "text": "观察到的像(橘点)" + }, + { + "type": "TextLabel", + "x": 910.7, + "y": 256.4, + "text": "观察者" + }, + { + "type": "TextLabel", + "x": 697.7, + "y": 616.4, + "text": "水中物体(绿点)" + }, + { + "type": "CropBox", + "p1": { + "x": 293.90844999999985, + "y": 179.63222500000003 + }, + "p4": { + "x": 1344.90845, + "y": 671.5450000000001 + } + }, + { + "type": "CropBox", + "p1": { + "x": 596.1999999999996, + "y": 167.70000000000002 + }, + "p4": { + "x": 1112.7999999999997, + "y": 684.3 + } + } + ], + "width": 1576.5, + "height": 1017.412775, + "mode": "observer", + "imageModeDensity": 3.2520969380833185, + "observer": { + "c": { + "x": 881.5, + "y": 241 + }, + "r": 20 + }, + "origin": { + "x": -31.158449999999846, + "y": 83.11777499999997 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/beam-directors-thumbnail.avif b/cn/gallery/beam-directors-thumbnail.avif new file mode 100644 index 00000000..a96791a9 Binary files /dev/null and b/cn/gallery/beam-directors-thumbnail.avif differ diff --git a/cn/gallery/beam-directors-thumbnail.jpg b/cn/gallery/beam-directors-thumbnail.jpg new file mode 100644 index 00000000..f3242a23 Binary files /dev/null and b/cn/gallery/beam-directors-thumbnail.jpg differ diff --git a/cn/gallery/beam-directors.avif b/cn/gallery/beam-directors.avif new file mode 100644 index 00000000..5d51678d Binary files /dev/null and b/cn/gallery/beam-directors.avif differ diff --git a/cn/gallery/beam-directors.html b/cn/gallery/beam-directors.html new file mode 100644 index 00000000..119dfbbe --- /dev/null +++ b/cn/gallery/beam-directors.html @@ -0,0 +1,172 @@ + + + + + + + 光束导向器 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    光束导向器

    +

    + 贡献者:Stas Fainer +

    +
    +

    这是一个普通双棱镜 (biprism) 和菲涅耳双稜鏡(Fresnel biprism)的模拟。双棱镜可以将入射的平行光束导向两个方向,其取决于顶角的大小。

    +
    +

    + 在模拟器中打开 +

    + + + 光束导向器 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/beam-directors.jpg b/cn/gallery/beam-directors.jpg new file mode 100644 index 00000000..0be797d7 Binary files /dev/null and b/cn/gallery/beam-directors.jpg differ diff --git a/cn/gallery/beam-directors.json b/cn/gallery/beam-directors.json new file mode 100644 index 00000000..81d9a616 --- /dev/null +++ b/cn/gallery/beam-directors.json @@ -0,0 +1,164 @@ +{ + "name": "光束导向器", + "version": 5, + "modules": { + "FresnelBiprism": { + "numPoints": 2, + "params": [ + "N_slice=1:1:100:20", + "refIndex=0.5:0.01:2.5:1.5" + ], + "objs": [ + { + "type": "CustomGlass", + "p1": { + "x": "`x_1`", + "y": "`y_1`" + }, + "p2": { + "x": "`x_2`", + "y": "`y_2`" + }, + "eqn1": "-0.05", + "eqn2": "\\max(1-\\operatorname{abs}(x/3),0)-\\operatorname{floor}(`N_slice`*\\max(1-\\operatorname{abs}(x/3),0))/`N_slice`", + "refIndex": "`refIndex`" + } + ] + } + }, + "objs": [ + { + "type": "Glass", + "path": [ + { + "x": 780, + "y": 240, + "arc": false + }, + { + "x": 780, + "y": 360, + "arc": false + }, + { + "x": 800, + "y": 300, + "arc": false + } + ] + }, + { + "type": "Blocker", + "p1": { + "x": 500, + "y": 460 + }, + "p2": { + "x": 2000, + "y": 460 + } + }, + { + "type": "Beam", + "p1": { + "x": 740, + "y": 260 + }, + "p2": { + "x": 740, + "y": 340 + } + }, + { + "type": "Beam", + "p1": { + "x": 740, + "y": 580 + }, + "p2": { + "x": 740, + "y": 660 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 778.8678627532039, + "y": 535.2465977676727 + }, + "p2": { + "x": 778.8678627532039, + "y": 556.3197684993801 + }, + "arrow": true + }, + { + "type": "ModuleObj", + "module": "FresnelBiprism", + "points": [ + { + "x": 780, + "y": 560 + }, + { + "x": 780, + "y": 680 + } + ], + "params": { + "N_slice": 50, + "refIndex": 1.5 + } + }, + { + "type": "TextLabel", + "x": 550, + "y": 496, + "text": "这个菲涅耳双稜鏡是由上面的双稜鏡制成\n您可以选择双稜鏡并调整 N_silce(切片数量)参数。" + }, + { + "type": "TextLabel", + "x": 714.5365853658536, + "y": 630.5365853658537, + "text": "菲涅耳双稜鏡", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 711.9024390243901, + "y": 314.04878048780495, + "text": "双稜鏡", + "alignment": "right" + }, + { + "type": "CropBox", + "p1": { + "x": 397.4396298326651, + "y": 173.9628550245341 + }, + "p4": { + "x": 1955.098166418031, + "y": 753.4750501464854 + } + }, + { + "type": "CropBox", + "p1": { + "x": 437.82987373510423, + "y": 127.2311477074609 + }, + "p4": { + "x": 1123.5859712960787, + "y": 812.9872457074608 + } + } + ], + "width": 2336.487804878049, + "height": 1358.3414634146343, + "rayModeDensity": 2.497024941914371, + "origin": { + "x": -8.02499568632362, + "y": 215.4517791218074 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/beam-expanders-thumbnail.avif b/cn/gallery/beam-expanders-thumbnail.avif new file mode 100644 index 00000000..e5d5d55b Binary files /dev/null and b/cn/gallery/beam-expanders-thumbnail.avif differ diff --git a/cn/gallery/beam-expanders-thumbnail.jpg b/cn/gallery/beam-expanders-thumbnail.jpg new file mode 100644 index 00000000..7927ea19 Binary files /dev/null and b/cn/gallery/beam-expanders-thumbnail.jpg differ diff --git a/cn/gallery/beam-expanders.avif b/cn/gallery/beam-expanders.avif new file mode 100644 index 00000000..ae073b8d Binary files /dev/null and b/cn/gallery/beam-expanders.avif differ diff --git a/cn/gallery/beam-expanders.html b/cn/gallery/beam-expanders.html new file mode 100644 index 00000000..78efd3f6 --- /dev/null +++ b/cn/gallery/beam-expanders.html @@ -0,0 +1,172 @@ + + + + + + + 扩束镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    扩束镜

    +

    + 贡献者:Stas Fainer +

    +
    +

    模拟两种类型的扩束镜(Beam expanders)- 开普勒扩束镜和伽利略扩束镜。扩束镜可以扩大或缩小平行光束的直径。伽利略扩束镜由一个凸镜和一个凹镜组成,而开普勒扩束镜由两个凸镜组成。在这两种类型中,镜头的焦距之和都等于它们之间的距离。

    +
    +

    + 在模拟器中打开 +

    + + + 扩束镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/beam-expanders.jpg b/cn/gallery/beam-expanders.jpg new file mode 100644 index 00000000..f877b938 Binary files /dev/null and b/cn/gallery/beam-expanders.jpg differ diff --git a/cn/gallery/beam-expanders.json b/cn/gallery/beam-expanders.json new file mode 100644 index 00000000..69938dda --- /dev/null +++ b/cn/gallery/beam-expanders.json @@ -0,0 +1,148 @@ +{ + "name": "扩束镜", + "version": 5, + "objs": [ + { + "type": "IdealLens", + "p1": { + "x": 1080, + "y": 620 + }, + "p2": { + "x": 1080, + "y": 780 + }, + "focalLength": "-100" + }, + { + "type": "Beam", + "p1": { + "x": 780, + "y": 660 + }, + "p2": { + "x": 780, + "y": 740 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 880, + "y": 620 + }, + "p2": { + "x": 880, + "y": 780 + }, + "focalLength": "300" + }, + { + "type": "Ruler", + "p1": { + "x": 880, + "y": 700 + }, + "p2": { + "x": 1380, + "y": 700 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 880, + "y": 420 + }, + "p2": { + "x": 880, + "y": 580 + }, + "focalLength": "300" + }, + { + "type": "Ruler", + "p1": { + "x": 880, + "y": 500 + }, + "p2": { + "x": 1380, + "y": 500 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 1280, + "y": 420 + }, + "p2": { + "x": 1280, + "y": 580 + }, + "focalLength": "100" + }, + { + "type": "Beam", + "p1": { + "x": 780, + "y": 460 + }, + "p2": { + "x": 780, + "y": 540 + } + }, + { + "type": "TextLabel", + "x": 766.5714285714287, + "y": 511.9999999999999, + "text": "开普勒扩束镜", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 764, + "y": 711.9999999999998, + "text": "伽利略扩束镜", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 621.7368421052631, + "y": 364, + "text": "在两种类型中,镜头之间的距离都等于它们的焦距之和" + }, + { + "type": "CropBox", + "p1": { + "x": 384.48120300751873, + "y": 389.5503759398497 + }, + "p4": { + "x": 1544.0601503759399, + "y": 812.8345864661654 + } + }, + { + "type": "CropBox", + "p1": { + "x": 843.0075187969925, + "y": 372.49774436090223 + }, + "p4": { + "x": 1299.639097744361, + "y": 829.1293233609022 + } + } + ], + "width": 1739.368421052632, + "height": 1003.0736842105264, + "rayModeDensity": 3.4339115327994474, + "origin": { + "x": -94.58646616541341, + "y": -99.65563909774437 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/bended-pencil-thumbnail.avif b/cn/gallery/bended-pencil-thumbnail.avif new file mode 100644 index 00000000..d870f9a5 Binary files /dev/null and b/cn/gallery/bended-pencil-thumbnail.avif differ diff --git a/cn/gallery/bended-pencil-thumbnail.jpg b/cn/gallery/bended-pencil-thumbnail.jpg new file mode 100644 index 00000000..0c7735e5 Binary files /dev/null and b/cn/gallery/bended-pencil-thumbnail.jpg differ diff --git a/cn/gallery/bended-pencil.avif b/cn/gallery/bended-pencil.avif new file mode 100644 index 00000000..bc4bf561 Binary files /dev/null and b/cn/gallery/bended-pencil.avif differ diff --git a/cn/gallery/bended-pencil.html b/cn/gallery/bended-pencil.html new file mode 100644 index 00000000..358ef246 --- /dev/null +++ b/cn/gallery/bended-pencil.html @@ -0,0 +1,172 @@ + + + + + + + 弯曲的铅笔 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    弯曲的铅笔

    +

    + 贡献者:Stas Fainer +

    +
    +

    从上方观察部分浸入水中的铅笔,因为空气和水之间的折射率的不连续性,我们的眼睛会感觉到铅笔看起来既断裂又弯曲。然而,在这个模拟中,弯曲的现象更为明显。您可以查看<a href=""https://phydemo.app/ray-optics/cn/gallery/broken-pencil"" target=""_blank"">断裂的铅笔模拟,那里的断裂现象更为明显。

    +
    +

    + 在模拟器中打开 +

    + + + 弯曲的铅笔 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/bended-pencil.jpg b/cn/gallery/bended-pencil.jpg new file mode 100644 index 00000000..dacdc776 Binary files /dev/null and b/cn/gallery/bended-pencil.jpg differ diff --git a/cn/gallery/bended-pencil.json b/cn/gallery/bended-pencil.json new file mode 100644 index 00000000..7f93f53b --- /dev/null +++ b/cn/gallery/bended-pencil.json @@ -0,0 +1,154 @@ +{ + "name": "弯曲的铅笔", + "version": 5, + "objs": [ + { + "type": "IdealLens", + "p1": { + "x": 822.1683000000002, + "y": 500 + }, + "p2": { + "x": 822.1683000000002, + "y": 660 + }, + "focalLength": "100" + }, + { + "type": "Glass", + "path": [ + { + "x": 620, + "y": 480, + "arc": false + }, + { + "x": 620, + "y": 680, + "arc": false + }, + { + "x": 200, + "y": 680, + "arc": false + }, + { + "x": 200, + "y": 480, + "arc": false + } + ] + }, + { + "type": "PointSource", + "x": 650, + "y": 520 + }, + { + "type": "PointSource", + "x": 660, + "y": 500 + }, + { + "type": "PointSource", + "x": 590, + "y": 640 + }, + { + "type": "PointSource", + "x": 580, + "y": 660 + }, + { + "type": "PointSource", + "x": 630, + "y": 560 + }, + { + "type": "PointSource", + "x": 610, + "y": 600 + }, + { + "type": "PointSource", + "x": 600, + "y": 620 + }, + { + "type": "PointSource", + "x": 640, + "y": 540 + }, + { + "type": "TextLabel", + "x": 1022.5261689664474, + "y": 501.105882042485, + "text": "弯曲的铅笔(黄色)\n视网膜上的影像" + }, + { + "type": "TextLabel", + "x": 233.13442005815097, + "y": 595.5632519114808, + "text": "电介质材料" + }, + { + "type": "TextLabel", + "x": 613.6954349053124, + "y": 466.332582042485, + "text": "原始铅笔(绿色)" + }, + { + "type": "TextLabel", + "x": 813.4997485299867, + "y": 701.2435132076063, + "text": "观察者的眼睛", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 617.8264181705608, + "y": 758.3098816551066, + "text": "忽略橙色的正方形!", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": -50.064989069895475, + "y": -18.656479804253806 + }, + "p4": { + "x": 1499.192652851502, + "y": 775.6387167022964 + } + }, + { + "type": "CropBox", + "p1": { + "x": 590.8607751222443, + "y": 195.55138045775485 + }, + "p4": { + "x": 1339.3149235938602, + "y": 944.005528457755 + } + } + ], + "width": 2323.8864628820966, + "height": 1568.924017467249, + "mode": "images", + "imageModeDensity": 0.08803683258237255, + "observer": { + "c": { + "x": 1236.5956333333334, + "y": 497.18188888888886 + }, + "r": 20 + }, + "origin": { + "x": 437.3793995502449, + "y": 405.97089028460323 + }, + "scale": 1, + "backgroundImage": "bended-pencil-background.png" +} \ No newline at end of file diff --git a/cn/gallery/black-cat-becomes-white-thumbnail.avif b/cn/gallery/black-cat-becomes-white-thumbnail.avif new file mode 100644 index 00000000..90a60a49 Binary files /dev/null and b/cn/gallery/black-cat-becomes-white-thumbnail.avif differ diff --git a/cn/gallery/black-cat-becomes-white-thumbnail.jpg b/cn/gallery/black-cat-becomes-white-thumbnail.jpg new file mode 100644 index 00000000..ca638613 Binary files /dev/null and b/cn/gallery/black-cat-becomes-white-thumbnail.jpg differ diff --git a/cn/gallery/black-cat-becomes-white.avif b/cn/gallery/black-cat-becomes-white.avif new file mode 100644 index 00000000..84847edd Binary files /dev/null and b/cn/gallery/black-cat-becomes-white.avif differ diff --git a/cn/gallery/black-cat-becomes-white.html b/cn/gallery/black-cat-becomes-white.html new file mode 100644 index 00000000..6226d491 --- /dev/null +++ b/cn/gallery/black-cat-becomes-white.html @@ -0,0 +1,178 @@ + + + + + + + 「黑猫变白猫」演示 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    「黑猫变白猫」演示

    +

    + 贡献者:Victory Science, Yi-Ting Tu +

    +
    +

    「黑猫变白猫」是一个科普演示。当图画浸入水中时有部分会消失。制作步骤如下:

    +
      +
    1. 在纸上绘制图案(如黑猫)。
    2. +
    3. 将纸放入塑胶套中。
    4. +
    5. 在塑胶套上描出该图案的一部分(如猫的边框)或其他图案。当放入水中时,绘制在纸上的图案将消失,但绘制在塑胶套上的图案不会消失。
    6. +
    +

    本模拟解释它的原理。

    +
    +

    + 在模拟器中打开 +

    + + + 「黑猫变白猫」演示 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/black-cat-becomes-white.jpg b/cn/gallery/black-cat-becomes-white.jpg new file mode 100644 index 00000000..3fec43ce Binary files /dev/null and b/cn/gallery/black-cat-becomes-white.jpg differ diff --git a/cn/gallery/black-cat-becomes-white.json b/cn/gallery/black-cat-becomes-white.json new file mode 100644 index 00000000..c69841b2 --- /dev/null +++ b/cn/gallery/black-cat-becomes-white.json @@ -0,0 +1,710 @@ +{ + "name": "「黑猫变白猫」演示", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 699, + "y": -244 + }, + "p2": { + "x": 235.97777777777787, + "y": -241.0666666666667 + }, + "controlPoints": [ + { + "newPoint": { + "x": 200.33333333333337, + "y": -500.2666666666664 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 1, + "index": 0 + } + }, + { + "newPoint": { + "x": 220.33333333333337, + "y": -500.2666666666664 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 1, + "index": 7 + } + }, + { + "newPoint": { + "x": 240.33333333333337, + "y": -500.2666666666664 + }, + "targetObjIndex": 13, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 260.33333333333337, + "y": -500.2666666666664 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 1, + "index": 4 + } + }, + { + "newPoint": { + "x": 280.33333333333337, + "y": -500.2666666666664 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 1, + "index": 3 + } + }, + { + "newPoint": { + "x": 545.6666666666667, + "y": -500.2666666666664 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1, + "index": 0 + } + }, + { + "newPoint": { + "x": 565.6666666666667, + "y": -500.2666666666664 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1, + "index": 7 + } + }, + { + "newPoint": { + "x": 585.6666666666667, + "y": -500.2666666666664 + }, + "targetObjIndex": 5, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 605.6666666666667, + "y": -500.2666666666664 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1, + "index": 4 + } + }, + { + "newPoint": { + "x": 625.6666666666667, + "y": -500.2666666666664 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1, + "index": 3 + } + }, + { + "newPoint": { + "x": 240.33333333333337, + "y": -200.26666666666677 + }, + "targetObjIndex": 13, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 585.6666666666667, + "y": -200.26666666666677 + }, + "targetObjIndex": 5, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 220.33333333333337, + "y": -180.26666666666654 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 1, + "index": 6 + } + }, + { + "newPoint": { + "x": 260.33333333333337, + "y": -180.26666666666654 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 1, + "index": 5 + } + }, + { + "newPoint": { + "x": 565.6666666666667, + "y": -180.26666666666654 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1, + "index": 6 + } + }, + { + "newPoint": { + "x": 605.6666666666667, + "y": -180.26666666666654 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1, + "index": 5 + } + }, + { + "newPoint": { + "x": 200.33333333333337, + "y": -160.26666666666654 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 1, + "index": 1 + } + }, + { + "newPoint": { + "x": 200.33333333333337, + "y": -160.26666666666654 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 2 + } + }, + { + "newPoint": { + "x": 280.33333333333337, + "y": -160.26666666666654 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 1, + "index": 2 + } + }, + { + "newPoint": { + "x": 280.33333333333337, + "y": -160.26666666666654 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 3 + } + }, + { + "newPoint": { + "x": 545.6666666666667, + "y": -160.26666666666654 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1, + "index": 1 + } + }, + { + "newPoint": { + "x": 545.6666666666667, + "y": -160.26666666666654 + }, + "targetObjIndex": 1, + "dragContext": { + "part": 1, + "index": 2 + } + }, + { + "newPoint": { + "x": 625.6666666666667, + "y": -160.26666666666654 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1, + "index": 2 + } + }, + { + "newPoint": { + "x": 625.6666666666667, + "y": -160.26666666666654 + }, + "targetObjIndex": 1, + "dragContext": { + "part": 1, + "index": 3 + } + }, + { + "newPoint": { + "x": 236.33333333333337, + "y": -242.266666666667 + }, + "targetObjIndex": 14, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 234.0036630036633, + "y": -245.76117216117197 + }, + "targetObjIndex": 14, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 543.6666666666667, + "y": -242.266666666667 + }, + "targetObjIndex": 4, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 541.3369963369967, + "y": -245.76117216117197 + }, + "targetObjIndex": 4, + "dragContext": { + "part": 2 + } + } + ], + "transformation": "yTranslation" + }, + { + "type": "Glass", + "path": [ + { + "x": 345.66666666666674, + "y": -369.33333333333326, + "arc": false + }, + { + "x": 545.6666666666667, + "y": -369.33333333333326, + "arc": false + }, + { + "x": 545.6666666666667, + "y": -160.26666666666654, + "arc": false + }, + { + "x": 625.6666666666667, + "y": -160.26666666666654, + "arc": false + }, + { + "x": 625.6666666666667, + "y": -369.33333333333326, + "arc": false + }, + { + "x": 645.6666666666667, + "y": -369.33333333333326, + "arc": false + }, + { + "x": 645.6666666666667, + "y": -129.33333333333326, + "arc": false + }, + { + "x": 345.66666666666674, + "y": -129.33333333333326, + "arc": false + } + ], + "refIndex": 1.33 + }, + { + "type": "Blocker", + "p1": { + "x": 345.66666666666674, + "y": -489.33333333333326 + }, + "p2": { + "x": 345.66666666666674, + "y": -129.33333333333326 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 545.6666666666667, + "y": -500.2666666666664, + "arc": false + }, + { + "x": 545.6666666666667, + "y": -160.26666666666654, + "arc": false + }, + { + "x": 625.6666666666667, + "y": -160.26666666666654, + "arc": false + }, + { + "x": 625.6666666666667, + "y": -500.2666666666664, + "arc": false + }, + { + "x": 605.6666666666667, + "y": -500.2666666666664, + "arc": false + }, + { + "x": 605.6666666666667, + "y": -180.26666666666654, + "arc": false + }, + { + "x": 565.6666666666667, + "y": -180.26666666666654, + "arc": false + }, + { + "x": 565.6666666666667, + "y": -500.2666666666664, + "arc": false + } + ] + }, + { + "type": "AngleSource", + "p1": { + "x": 543.6666666666667, + "y": -242.266666666667 + }, + "p2": { + "x": 541.3369963369967, + "y": -245.76117216117197 + }, + "emisAngle": 52 + }, + { + "type": "Blocker", + "p1": { + "x": 585.6666666666667, + "y": -500.2666666666664 + }, + "p2": { + "x": 585.6666666666667, + "y": -200.26666666666677 + } + }, + { + "type": "Blocker", + "p1": { + "x": 645.6666666666667, + "y": -129.33333333333326 + }, + "p2": { + "x": 345.66666666666674, + "y": -129.33333333333326 + } + }, + { + "type": "Blocker", + "p1": { + "x": 645.6666666666667, + "y": -129.33333333333326 + }, + "p2": { + "x": 645.6666666666667, + "y": -489.33333333333326 + } + }, + { + "type": "Blocker", + "p1": { + "x": 0.33333333333337123, + "y": -489.33333333333326 + }, + "p2": { + "x": 0.33333333333337123, + "y": -129.33333333333326 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 0.33333333333337123, + "y": -369.33333333333326, + "arc": false + }, + { + "x": 200.33333333333337, + "y": -369.33333333333326, + "arc": false + }, + { + "x": 200.33333333333337, + "y": -160.26666666666654, + "arc": false + }, + { + "x": 280.33333333333337, + "y": -160.26666666666654, + "arc": false + }, + { + "x": 280.33333333333337, + "y": -369.33333333333326, + "arc": false + }, + { + "x": 300.33333333333337, + "y": -369.33333333333326, + "arc": false + }, + { + "x": 300.33333333333337, + "y": -129.33333333333326, + "arc": false + }, + { + "x": 0.33333333333337123, + "y": -129.33333333333326, + "arc": false + } + ], + "refIndex": 1.33 + }, + { + "type": "Blocker", + "p1": { + "x": 300.33333333333337, + "y": -129.33333333333326 + }, + "p2": { + "x": 0.33333333333337123, + "y": -129.33333333333326 + } + }, + { + "type": "Blocker", + "p1": { + "x": 300.33333333333337, + "y": -129.33333333333326 + }, + "p2": { + "x": 300.33333333333337, + "y": -489.33333333333326 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 200.33333333333337, + "y": -500.2666666666664, + "arc": false + }, + { + "x": 200.33333333333337, + "y": -160.26666666666654, + "arc": false + }, + { + "x": 280.33333333333337, + "y": -160.26666666666654, + "arc": false + }, + { + "x": 280.33333333333337, + "y": -500.2666666666664, + "arc": false + }, + { + "x": 260.33333333333337, + "y": -500.2666666666664, + "arc": false + }, + { + "x": 260.33333333333337, + "y": -180.26666666666654, + "arc": false + }, + { + "x": 220.33333333333337, + "y": -180.26666666666654, + "arc": false + }, + { + "x": 220.33333333333337, + "y": -500.2666666666664, + "arc": false + } + ] + }, + { + "type": "Blocker", + "p1": { + "x": 240.33333333333337, + "y": -500.2666666666664 + }, + "p2": { + "x": 240.33333333333337, + "y": -200.26666666666677 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 236.33333333333337, + "y": -242.266666666667 + }, + "p2": { + "x": 234.0036630036633, + "y": -245.76117216117197 + }, + "emisAngle": 52 + }, + { + "type": "LineArrow", + "p1": { + "x": 15, + "y": -610 + }, + "p2": { + "x": 35, + "y": -590 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 355, + "y": -610 + }, + "p2": { + "x": 375, + "y": -590 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 716.7777777777783, + "y": -327.86666666666656, + "text": "当塑胶套在水中时,来自纸上的光无法到达眼睛,\n故我们只看到画在塑胶套上的图案。" + }, + { + "type": "TextLabel", + "x": 496.3813664596275, + "y": -81.1682539682537, + "text": "来自塑胶套上的光", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 150.29440993788845, + "y": -81.16825396825368, + "text": "来自纸上的光", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 6.661835748792635, + "y": -602.8666666666667, + "text": "眼睛", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 716.5803140096623, + "y": -235.9971014492753, + "text": "拖曳此处可将塑胶套移出水面", + "fontSize": 18 + }, + { + "type": "TextLabel", + "x": 350.8357487922708, + "y": -602.8666666666664, + "text": "眼睛", + "alignment": "right" + }, + { + "type": "CropBox", + "p1": { + "x": -360.9236542443061, + "y": -684.9641304347823 + }, + "p4": { + "x": 1739.933488612837, + "y": 532.3501552795033 + } + }, + { + "type": "CropBox", + "p1": { + "x": -107.20936853002024, + "y": -796.9641304347822 + }, + "p4": { + "x": 682.7906314699798, + "y": -6.9641304347821915 + } + } + ], + "width": 3151.2857142857147, + "height": 2267.7428571428572, + "rayModeDensity": 0.17000966340305945, + "origin": { + "x": 886.1379399585919, + "y": 1210.1784161490682 + }, + "scale": 1, + "backgroundImage": "black-cat-becomes-white-background.png" +} \ No newline at end of file diff --git a/cn/gallery/branched-flow-thumbnail.avif b/cn/gallery/branched-flow-thumbnail.avif new file mode 100644 index 00000000..5e0d072e Binary files /dev/null and b/cn/gallery/branched-flow-thumbnail.avif differ diff --git a/cn/gallery/branched-flow-thumbnail.jpg b/cn/gallery/branched-flow-thumbnail.jpg new file mode 100644 index 00000000..5f0274ae Binary files /dev/null and b/cn/gallery/branched-flow-thumbnail.jpg differ diff --git a/cn/gallery/branched-flow.avif b/cn/gallery/branched-flow.avif new file mode 100644 index 00000000..d711d2c8 Binary files /dev/null and b/cn/gallery/branched-flow.avif differ diff --git a/cn/gallery/branched-flow.html b/cn/gallery/branched-flow.html new file mode 100644 index 00000000..4c5342b1 --- /dev/null +++ b/cn/gallery/branched-flow.html @@ -0,0 +1,170 @@ + + + + + + + 分支流 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    分支流

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    当光线经过折射率在空间上有随机扰动(相关长度远大于光的波长)的介质时,会形成一种类似树状的图案,称为分支流。本模拟使用一些余弦函数的和作为折射率函数来演示这个现象,其中余弦函数的振幅、波数与相位都是类似随机的数。

    +
    +

    + 在模拟器中打开 +

    + + + 分支流 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/branched-flow.jpg b/cn/gallery/branched-flow.jpg new file mode 100644 index 00000000..f2ca013e Binary files /dev/null and b/cn/gallery/branched-flow.jpg differ diff --git a/cn/gallery/branched-flow.json b/cn/gallery/branched-flow.json new file mode 100644 index 00000000..b7255e46 --- /dev/null +++ b/cn/gallery/branched-flow.json @@ -0,0 +1,75 @@ +{ + "name": "分支流", + "version": 5, + "objs": [ + { + "type": "GrinGlass", + "path": [ + { + "x": 340, + "y": 180, + "arc": false + }, + { + "x": 340, + "y": 520, + "arc": false + }, + { + "x": 780, + "y": 520, + "arc": false + }, + { + "x": 780, + "y": 180, + "arc": false + } + ], + "refIndexFn": "1+\\frac{\\cos\\left(\\frac{x}{6.3}+\\frac{y}{6.7}+4.3\\right)}{86}+\\frac{\\cos\\left(\\frac{x}{6.4}-\\frac{y}{3.2}+4.5\\right)}{95}+\\frac{\\cos\\left(-\\frac{x}{3.4}-\\frac{y}{5.4}+3.4\\right)}{82}+\\frac{\\cos\\left(-\\frac{x}{9.7}+\\frac{y}{5.4}+3.5\\right)}{71}+\\frac{\\cos\\left(\\frac{x}{1.2}+\\frac{y}{3.5}+2.2\\right)}{75}+\\frac{\\cos\\left(\\frac{x}{5.6}-\\frac{y}{1.8}+5.2\\right)}{95}+\\frac{\\cos\\left(-\\frac{x}{5.4}-\\frac{y}{3.2}+5.4\\right)}{82}+\\frac{\\cos\\left(-\\frac{x}{8.7}+\\frac{y}{6.5}+7.4\\right)}{71}+\\frac{\\cos\\left(\\frac{x}{9.4}+\\frac{y}{4.2}+2.3\\right)}{94}+\\frac{\\cos\\left(\\frac{x}{2.3}-\\frac{y}{6.4}+0.9\\right)}{63}+\\frac{\\cos\\left(-\\frac{x}{7.5}-\\frac{y}{8.6}+5.7\\right)}{81}+\\frac{\\cos\\left(-\\frac{x}{9.7}+\\frac{y}{10}+3.2\\right)}{105}" + }, + { + "type": "AngleSource", + "p1": { + "x": 370.2510318821846, + "y": 219.920967054945 + }, + "p2": { + "x": 794.9478534860789, + "y": 482.07949890920065 + }, + "brightness": 0.25, + "emisAngle": 55 + }, + { + "type": "CropBox", + "p1": { + "x": 347.78639218940026, + "y": 210.43838158421786 + }, + "p4": { + "x": 775.1309348476076, + "y": 512.949073038962 + } + }, + { + "type": "CropBox", + "p1": { + "x": 362.4755187529593, + "y": 210.44068265320084 + }, + "p4": { + "x": 661.1302697529593, + "y": 509.0954336532008 + } + } + ], + "width": 641.016813987311, + "height": 516.1829627838478, + "rayModeDensity": 3.7859619403392255, + "origin": { + "x": -240.95025652484844, + "y": -103.60224591966603 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/broken-pencil-thumbnail.avif b/cn/gallery/broken-pencil-thumbnail.avif new file mode 100644 index 00000000..9273733d Binary files /dev/null and b/cn/gallery/broken-pencil-thumbnail.avif differ diff --git a/cn/gallery/broken-pencil-thumbnail.jpg b/cn/gallery/broken-pencil-thumbnail.jpg new file mode 100644 index 00000000..acd32aaf Binary files /dev/null and b/cn/gallery/broken-pencil-thumbnail.jpg differ diff --git a/cn/gallery/broken-pencil.avif b/cn/gallery/broken-pencil.avif new file mode 100644 index 00000000..09c0f31c Binary files /dev/null and b/cn/gallery/broken-pencil.avif differ diff --git a/cn/gallery/broken-pencil.html b/cn/gallery/broken-pencil.html new file mode 100644 index 00000000..4e540424 --- /dev/null +++ b/cn/gallery/broken-pencil.html @@ -0,0 +1,172 @@ + + + + + + + 断裂的铅笔 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    断裂的铅笔

    +

    + 贡献者:Stas Fainer +

    +
    +

    从侧面观察部分浸入水中的铅笔,因为空气和水之间的折射率的不连续性,我们的眼睛会感觉到铅笔看起来既断裂又弯曲。然而,在这个模拟中,断裂的现象更为明显。您可以查看<a href=""https://phydemo.app/ray-optics/cn/gallery/bended-pencil"" target=""_blank"">弯曲的铅笔模拟,那里的弯曲现象更为明显。

    +
    +

    + 在模拟器中打开 +

    + + + 断裂的铅笔 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/broken-pencil.jpg b/cn/gallery/broken-pencil.jpg new file mode 100644 index 00000000..c78f9f82 Binary files /dev/null and b/cn/gallery/broken-pencil.jpg differ diff --git a/cn/gallery/broken-pencil.json b/cn/gallery/broken-pencil.json new file mode 100644 index 00000000..ff190e26 --- /dev/null +++ b/cn/gallery/broken-pencil.json @@ -0,0 +1,170 @@ +{ + "name": "断裂的铅笔", + "version": 5, + "objs": [ + { + "type": "IdealLens", + "p1": { + "x": 760, + "y": 500 + }, + "p2": { + "x": 760, + "y": 660 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 640, + "y": 580, + "arc": false + }, + { + "x": 640, + "y": 860, + "arc": false + }, + { + "x": 160, + "y": 860, + "arc": false + }, + { + "x": 160, + "y": 580, + "arc": false + } + ], + "refIndex": 1.44 + }, + { + "type": "PointSource", + "x": 480, + "y": 540, + "brightness": "0.5" + }, + { + "type": "PointSource", + "x": 360, + "y": 600, + "brightness": "0.5" + }, + { + "type": "PointSource", + "x": 320, + "y": 620, + "brightness": "0.5" + }, + { + "type": "PointSource", + "x": 200, + "y": 680, + "brightness": "0.5" + }, + { + "type": "PointSource", + "x": 440, + "y": 560, + "brightness": "0.5" + }, + { + "type": "PointSource", + "x": 520, + "y": 520, + "brightness": "0.5" + }, + { + "type": "PointSource", + "x": 280, + "y": 640, + "brightness": "0.5" + }, + { + "type": "PointSource", + "x": 560, + "y": 500, + "brightness": "0.5" + }, + { + "type": "PointSource", + "x": 240, + "y": 660, + "brightness": "0.5" + }, + { + "type": "TextLabel", + "x": 830.0100000000001, + "y": 469.2399999999999, + "text": "断裂的铅笔(黄色)\n视网膜上的影像" + }, + { + "type": "TextLabel", + "x": 397.6456768558952, + "y": 830.9351528384279, + "text": "电介质材料", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 544.1222707423581, + "y": 460, + "text": "原始铅笔(绿色)", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 764.2126637554585, + "y": 695.9000000000001, + "text": "观察者的眼睛", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 172.77710945203543, + "y": 560.6412734187915, + "text": "忽略橙色的正方形!", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": -205.4527398225102, + "y": -26.81518523735727 + }, + "p4": { + "x": 1237.6913649809833, + "y": 886.3271728412453 + } + }, + { + "type": "CropBox", + "p1": { + "x": 514.5897480802392, + "y": 262.32221591925776 + }, + "p4": { + "x": 1178.2677841949574, + "y": 926.0002519192578 + } + } + ], + "width": 2164.71615720524, + "height": 1634.7144104803492, + "mode": "images", + "imageModeDensity": 0.21709939257630184, + "observer": { + "c": { + "x": 1427.1100000000001, + "y": 659.45 + }, + "r": 20 + }, + "origin": { + "x": 566.2387660233836, + "y": 387.6012114382306 + }, + "scale": 1, + "backgroundImage": "broken-pencil-background.png" +} \ No newline at end of file diff --git a/cn/gallery/camera-obscura-thumbnail.avif b/cn/gallery/camera-obscura-thumbnail.avif new file mode 100644 index 00000000..85f97fe7 Binary files /dev/null and b/cn/gallery/camera-obscura-thumbnail.avif differ diff --git a/cn/gallery/camera-obscura-thumbnail.jpg b/cn/gallery/camera-obscura-thumbnail.jpg new file mode 100644 index 00000000..f37ea485 Binary files /dev/null and b/cn/gallery/camera-obscura-thumbnail.jpg differ diff --git a/cn/gallery/camera-obscura.avif b/cn/gallery/camera-obscura.avif new file mode 100644 index 00000000..a2173b87 Binary files /dev/null and b/cn/gallery/camera-obscura.avif differ diff --git a/cn/gallery/camera-obscura.html b/cn/gallery/camera-obscura.html new file mode 100644 index 00000000..ae11c1a8 --- /dev/null +++ b/cn/gallery/camera-obscura.html @@ -0,0 +1,172 @@ + + + + + + + 暗箱 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    暗箱

    +

    + 贡献者:Stas Fainer +

    +
    +

    这是一个暗箱的模拟。在黑暗的房间里的观察者看到的是外面物体的倒置影像,并且这个影像是直接投影在他/她前面的墙壁上的(无需使用额外的透镜)。

    +
    +

    + 在模拟器中打开 +

    + + + 暗箱 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/camera-obscura.jpg b/cn/gallery/camera-obscura.jpg new file mode 100644 index 00000000..fcdb3c73 Binary files /dev/null and b/cn/gallery/camera-obscura.jpg differ diff --git a/cn/gallery/camera-obscura.json b/cn/gallery/camera-obscura.json new file mode 100644 index 00000000..9b4be2ee --- /dev/null +++ b/cn/gallery/camera-obscura.json @@ -0,0 +1,171 @@ +{ + "name": "暗箱", + "version": 5, + "objs": [ + { + "type": "Blocker", + "p1": { + "x": 1060, + "y": 680 + }, + "p2": { + "x": 760, + "y": 680 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1060, + "y": 400 + }, + "p2": { + "x": 760, + "y": 400 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1060, + "y": 680 + }, + "p2": { + "x": 1060, + "y": 400 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 60, + "y": 620 + }, + "p2": { + "x": 720, + "y": 540 + }, + "brightness": "5", + "emisAngle": "4" + }, + { + "type": "AngleSource", + "p1": { + "x": 60, + "y": 480 + }, + "p2": { + "x": 720, + "y": 540 + }, + "brightness": "5", + "emisAngle": "4" + }, + { + "type": "AngleSource", + "p1": { + "x": 60, + "y": 640 + }, + "p2": { + "x": 720, + "y": 540 + }, + "brightness": "5", + "emisAngle": 4 + }, + { + "type": "AngleSource", + "p1": { + "x": 60, + "y": 400 + }, + "p2": { + "x": 720, + "y": 540 + }, + "brightness": "5", + "emisAngle": "4" + }, + { + "type": "Ruler", + "p1": { + "x": 60, + "y": 700 + }, + "p2": { + "x": 1060, + "y": 700 + } + }, + { + "type": "Aperture", + "p1": { + "x": 760, + "y": 400 + }, + "p2": { + "x": 760, + "y": 680 + }, + "p3": { + "x": 760, + "y": 539.5 + }, + "p4": { + "x": 760, + "y": 540.5 + } + }, + { + "type": "TextLabel", + "x": 763, + "y": 676.3333333333335, + "text": "观察者" + }, + { + "type": "TextLabel", + "x": 93.31962598804716, + "y": 535.5267977636405, + "text": "外面的物体", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 913.5043956043952, + "y": 392.9062845651083, + "text": "黑暗的房间", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": -139.83866396761127, + "y": 326.32154443423786 + }, + "p4": { + "x": 1133.424493927126, + "y": 779.921544434238 + } + }, + { + "type": "CropBox", + "p1": { + "x": 704.0034412955467, + "y": 362.3215444342379 + }, + "p4": { + "x": 1086.74028340081, + "y": 745.058386434238 + } + } + ], + "width": 1909.8947368421057, + "height": 1090.2315789473687, + "rayModeDensity": 20.08352846991968, + "origin": { + "x": 458.1544534412956, + "y": -8.005754960553588 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/caustics-from-a-reflective-sphere-thumbnail.avif b/cn/gallery/caustics-from-a-reflective-sphere-thumbnail.avif new file mode 100644 index 00000000..400db6b8 Binary files /dev/null and b/cn/gallery/caustics-from-a-reflective-sphere-thumbnail.avif differ diff --git a/cn/gallery/caustics-from-a-reflective-sphere-thumbnail.jpg b/cn/gallery/caustics-from-a-reflective-sphere-thumbnail.jpg new file mode 100644 index 00000000..c1674375 Binary files /dev/null and b/cn/gallery/caustics-from-a-reflective-sphere-thumbnail.jpg differ diff --git a/cn/gallery/caustics-from-a-reflective-sphere.avif b/cn/gallery/caustics-from-a-reflective-sphere.avif new file mode 100644 index 00000000..fd3766be Binary files /dev/null and b/cn/gallery/caustics-from-a-reflective-sphere.avif differ diff --git a/cn/gallery/caustics-from-a-reflective-sphere.html b/cn/gallery/caustics-from-a-reflective-sphere.html new file mode 100644 index 00000000..b5f263cd --- /dev/null +++ b/cn/gallery/caustics-from-a-reflective-sphere.html @@ -0,0 +1,170 @@ + + + + + + + 反射性球体的焦散 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    反射性球体的焦散

    +

    + 贡献者:Georg Nadorff +

    +
    +

    一个反射性的积分球。也可以是液滴(如雨滴)中的反射。移动点光源的位置可以看到许多漂亮的图样。

    +
    +

    + 在模拟器中打开 +

    + + + 反射性球体的焦散 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/caustics-from-a-reflective-sphere.jpg b/cn/gallery/caustics-from-a-reflective-sphere.jpg new file mode 100644 index 00000000..f9f50c66 Binary files /dev/null and b/cn/gallery/caustics-from-a-reflective-sphere.jpg differ diff --git a/cn/gallery/caustics-from-a-reflective-sphere.json b/cn/gallery/caustics-from-a-reflective-sphere.json new file mode 100644 index 00000000..64b0e622 --- /dev/null +++ b/cn/gallery/caustics-from-a-reflective-sphere.json @@ -0,0 +1,98 @@ +{ + "name": "反射性球体的焦散", + "version": 5, + "objs": [ + { + "type": "ArcMirror", + "p1": { + "x": 699.9773664931605, + "y": 602.3560439560447 + }, + "p2": { + "x": 697.8619047619047, + "y": 678.3238095238096 + }, + "p3": { + "x": 695, + "y": 512 + } + }, + { + "type": "PointSource", + "x": 757.9773664931608, + "y": 652.3560439560447 + }, + { + "type": "Blocker", + "p1": { + "x": 605.0000000000001, + "y": 744.3333333333334 + }, + "p2": { + "x": 471.06190476190505, + "y": 743.9904761904763 + } + }, + { + "type": "CircleBlocker", + "p1": { + "x": 201.97736649316084, + "y": 382.3560439560447 + }, + "p2": { + "x": 241.97736649316084, + "y": 412.3560439560447 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 940.6440331598274, + "y": 610.3560439560447 + }, + "p2": { + "x": 778.6440331598274, + "y": 658.3560439560447 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 962.6440331598274, + "y": 620.3560439560447, + "text": "移动点光源以观看焦散及节点\n在积分球中是如何变换的。\n改变遮光物的大小与位置,\n以及球的开口大小来观察更多效果。", + "fontSize": 40 + }, + { + "type": "CropBox", + "p1": { + "x": -1613.3464430306476, + "y": -429.1106227106218 + }, + "p4": { + "x": 2014.6535569693524, + "y": 1668.4893772893781 + } + }, + { + "type": "CropBox", + "p1": { + "x": -1380.3464430306476, + "y": -475.5106227106219 + }, + "p4": { + "x": 803.6535569693524, + "y": 1708.4893772893781 + } + } + ], + "width": 5442, + "height": 3911.6, + "rayModeDensity": 20.085536923187668, + "origin": { + "x": 2520.3464430306476, + "y": 1336.1106227106218 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/chaff-countermeasure-thumbnail.avif b/cn/gallery/chaff-countermeasure-thumbnail.avif new file mode 100644 index 00000000..44670669 Binary files /dev/null and b/cn/gallery/chaff-countermeasure-thumbnail.avif differ diff --git a/cn/gallery/chaff-countermeasure-thumbnail.jpg b/cn/gallery/chaff-countermeasure-thumbnail.jpg new file mode 100644 index 00000000..b3f15ae8 Binary files /dev/null and b/cn/gallery/chaff-countermeasure-thumbnail.jpg differ diff --git a/cn/gallery/chaff-countermeasure.avif b/cn/gallery/chaff-countermeasure.avif new file mode 100644 index 00000000..ade65165 Binary files /dev/null and b/cn/gallery/chaff-countermeasure.avif differ diff --git a/cn/gallery/chaff-countermeasure.html b/cn/gallery/chaff-countermeasure.html new file mode 100644 index 00000000..2952144a --- /dev/null +++ b/cn/gallery/chaff-countermeasure.html @@ -0,0 +1,172 @@ + + + + + + + 干扰箔 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    干扰箔

    +

    + 贡献者:Stas Fainer, Yi-Ting Tu +

    +
    +

    这是一个箔片反射对雷达效应的定性模拟(忽略衍射效应)。

    +
    +

    + 在模拟器中打开 +

    + + + 干扰箔 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/chaff-countermeasure.jpg b/cn/gallery/chaff-countermeasure.jpg new file mode 100644 index 00000000..a7e3f998 Binary files /dev/null and b/cn/gallery/chaff-countermeasure.jpg differ diff --git a/cn/gallery/chaff-countermeasure.json b/cn/gallery/chaff-countermeasure.json new file mode 100644 index 00000000..630e5e08 --- /dev/null +++ b/cn/gallery/chaff-countermeasure.json @@ -0,0 +1,307 @@ +{ + "name": "干扰箔", + "version": 5, + "modules": { + "ChaffPiece": { + "numPoints": 0, + "params": [ + "x=0:1:1000:0", + "y=0:1:1000:0", + "theta=0:0.001:2pi:0", + "L=0.01:0.01:10:5" + ], + "objs": [ + { + "type": "Mirror", + "p1": { + "x": "`x`", + "y": "`y`" + }, + "p2": { + "x": "`x+L*cos(theta)`", + "y": "`y+L*sin(theta)`" + } + } + ] + }, + "Chaff": { + "numPoints": 2, + "params": [ + "N=1:1:10000:10", + "L=0.01:0.01:10:5" + ], + "objs": [ + { + "for": "i=1:1:N", + "type": "ModuleObj", + "module": "ChaffPiece", + "points": [], + "params": { + "x": "`x_1+random()*(x_2-x_1)`", + "y": "`y_1+random()*(y_2-y_1)`", + "L": "`L`", + "theta": "`random()*pi`" + } + } + ], + "maxLoopLength": 10000 + } + }, + "objs": [ + { + "type": "ModuleObj", + "module": "Chaff", + "points": [ + { + "x": 0, + "y": -4 + }, + { + "x": 1300, + "y": 1296 + } + ], + "params": { + "L": 5, + "N": 3000 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1580, + "y": 840 + }, + "p2": { + "x": 1740, + "y": 840 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1660, + "y": 560 + }, + "p2": { + "x": 1580, + "y": 840 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1660, + "y": 560 + }, + "p2": { + "x": 1740, + "y": 840 + } + }, + { + "type": "Blocker", + "p1": { + "x": -540, + "y": -80 + }, + "p2": { + "x": -2920, + "y": -80 + } + }, + { + "type": "Blocker", + "p1": { + "x": -2920, + "y": 1400 + }, + "p2": { + "x": -2920, + "y": -80 + } + }, + { + "type": "Blocker", + "p1": { + "x": -540, + "y": 1400 + }, + "p2": { + "x": -2920, + "y": 1400 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1840, + "y": -80 + }, + "p2": { + "x": 1840, + "y": 1400 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1840, + "y": -80 + }, + "p2": { + "x": -540, + "y": -80 + } + }, + { + "type": "Blocker", + "p1": { + "x": -540, + "y": 1400 + }, + "p2": { + "x": -540, + "y": -80 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1840, + "y": 1400 + }, + "p2": { + "x": -540, + "y": 1400 + } + }, + { + "type": "Mirror", + "p1": { + "x": -800, + "y": 840 + }, + "p2": { + "x": -640, + "y": 840 + } + }, + { + "type": "Mirror", + "p1": { + "x": -720, + "y": 560 + }, + "p2": { + "x": -640, + "y": 840 + } + }, + { + "type": "Mirror", + "p1": { + "x": -720, + "y": 560 + }, + "p2": { + "x": -800, + "y": 840 + } + }, + { + "type": "AngleSource", + "p1": { + "x": -2820, + "y": 100 + }, + "p2": { + "x": -1000, + "y": 700 + }, + "brightness": 1, + "emisAngle": 30 + }, + { + "type": "AngleSource", + "p1": { + "x": -440, + "y": 100 + }, + "p2": { + "x": 1380, + "y": 700 + }, + "brightness": 1, + "emisAngle": 30 + }, + { + "type": "TextLabel", + "x": -678.3571428571429, + "y": 629.0714285714286, + "text": "飞机" + }, + { + "type": "TextLabel", + "x": -506, + "y": 138, + "text": "雷达" + }, + { + "type": "TextLabel", + "x": 1701.642857142857, + "y": 629.0714285714286, + "text": "飞机" + }, + { + "type": "TextLabel", + "x": -2896, + "y": 138, + "text": "雷达" + }, + { + "type": "TextLabel", + "x": 645, + "y": 857.4999999999999, + "text": "箔片" + }, + { + "type": "TextLabel", + "x": -431, + "y": 1319, + "text": "选择箔片可改变箔片数量(N)和长度(L)。", + "fontSize": 48 + }, + { + "type": "CropBox", + "p1": { + "x": -532.7046342546346, + "y": -20.852086802087 + }, + "p4": { + "x": 1781.2953657453654, + "y": 1339.147913197913 + } + }, + { + "type": "CropBox", + "p1": { + "x": -532.7046342546346, + "y": -18.852086802087 + }, + "p4": { + "x": 191.29536574536542, + "y": 705.147913197913 + } + } + ], + "width": 3471, + "height": 2517, + "rayModeDensity": 3.087927024744393, + "origin": { + "x": 1111.2046342546346, + "y": 599.352086802087 + }, + "scale": 1, + "randomSeed": "0" +} \ No newline at end of file diff --git a/cn/gallery/chromatic-aberration-thumbnail.avif b/cn/gallery/chromatic-aberration-thumbnail.avif new file mode 100644 index 00000000..b5eb7282 Binary files /dev/null and b/cn/gallery/chromatic-aberration-thumbnail.avif differ diff --git a/cn/gallery/chromatic-aberration-thumbnail.jpg b/cn/gallery/chromatic-aberration-thumbnail.jpg new file mode 100644 index 00000000..03df9368 Binary files /dev/null and b/cn/gallery/chromatic-aberration-thumbnail.jpg differ diff --git a/cn/gallery/chromatic-aberration.avif b/cn/gallery/chromatic-aberration.avif new file mode 100644 index 00000000..8040677e Binary files /dev/null and b/cn/gallery/chromatic-aberration.avif differ diff --git a/cn/gallery/chromatic-aberration.html b/cn/gallery/chromatic-aberration.html new file mode 100644 index 00000000..e821ff54 --- /dev/null +++ b/cn/gallery/chromatic-aberration.html @@ -0,0 +1,172 @@ + + + + + + + 色像差 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    色像差

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    此模拟显示了球面透镜的色像差(Chromatic aberration)。这里的白色是由红、橙、黄、绿、青、蓝、紫混色形成的。红光的焦距最大,而紫光的焦距最小。

    +
    +

    + 在模拟器中打开 +

    + + + 色像差 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/chromatic-aberration.jpg b/cn/gallery/chromatic-aberration.jpg new file mode 100644 index 00000000..f3863185 Binary files /dev/null and b/cn/gallery/chromatic-aberration.jpg differ diff --git a/cn/gallery/chromatic-aberration.json b/cn/gallery/chromatic-aberration.json new file mode 100644 index 00000000..51f58fbe --- /dev/null +++ b/cn/gallery/chromatic-aberration.json @@ -0,0 +1,558 @@ +{ + "name": "色像差", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 102.17244673513872, + "y": 500 + }, + "p2": { + "x": 281.4341375969836, + "y": 500 + }, + "controlPoints": [ + { + "newPoint": { + "x": 191.80329216606003, + "y": 410.3691545690761 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 221.6802406430355, + "y": 410.3691545690761 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 251.5571891200092, + "y": 410.3691545690761 + }, + "targetObjIndex": 10, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 281.4341375969836, + "y": 410.3691545690761 + }, + "targetObjIndex": 11, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 311.31108607395794, + "y": 410.3691545690761 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 341.1880345509317, + "y": 410.3691545690761 + }, + "targetObjIndex": 13, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 371.0649830279073, + "y": 410.3691545690761 + }, + "targetObjIndex": 14, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 191.80329216606003, + "y": 589.6308454309253 + }, + "targetObjIndex": 1, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 221.6802406430355, + "y": 589.6308454309253 + }, + "targetObjIndex": 2, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 251.5571891200092, + "y": 589.6308454309253 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 281.4341375969836, + "y": 589.6308454309253 + }, + "targetObjIndex": 4, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 311.31108607395794, + "y": 589.6308454309253 + }, + "targetObjIndex": 5, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 341.1880345509317, + "y": 589.6308454309253 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 371.0649830279073, + "y": 589.6308454309253 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "targetObjIndex": 5, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "targetObjIndex": 4, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "targetObjIndex": 2, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "targetObjIndex": 1, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "targetObjIndex": 14, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "targetObjIndex": 13, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "targetObjIndex": 12, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "targetObjIndex": 11, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "targetObjIndex": 10, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 2 + } + } + ], + "transformation": "scaling" + }, + { + "type": "SingleRay", + "p1": { + "x": 191.80329216606003, + "y": 589.6308454309253 + }, + "p2": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "brightness": "0.9", + "wavelength": "620" + }, + { + "type": "SingleRay", + "p1": { + "x": 221.6802406430355, + "y": 589.6308454309253 + }, + "p2": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "brightness": "0.4", + "wavelength": "600" + }, + { + "type": "SingleRay", + "p1": { + "x": 251.5571891200092, + "y": 589.6308454309253 + }, + "p2": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "brightness": "0.6", + "wavelength": "580" + }, + { + "type": "SingleRay", + "p1": { + "x": 281.4341375969836, + "y": 589.6308454309253 + }, + "p2": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "brightness": "0.9", + "wavelength": "540" + }, + { + "type": "SingleRay", + "p1": { + "x": 311.31108607395794, + "y": 589.6308454309253 + }, + "p2": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "brightness": "0.6", + "wavelength": "500" + }, + { + "type": "SingleRay", + "p1": { + "x": 341.1880345509317, + "y": 589.6308454309253 + }, + "p2": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "brightness": "0.9", + "wavelength": "460" + }, + { + "type": "SingleRay", + "p1": { + "x": 371.0649830279073, + "y": 589.6308454309253 + }, + "p2": { + "x": 400.9419315048804, + "y": 589.6308454309253 + }, + "brightness": "0.8", + "wavelength": "420" + }, + { + "type": "SingleRay", + "p1": { + "x": 191.80329216606003, + "y": 410.3691545690761 + }, + "p2": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "brightness": "0.9", + "wavelength": "620" + }, + { + "type": "SingleRay", + "p1": { + "x": 221.6802406430355, + "y": 410.3691545690761 + }, + "p2": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "brightness": "0.4", + "wavelength": "600" + }, + { + "type": "SingleRay", + "p1": { + "x": 251.5571891200092, + "y": 410.3691545690761 + }, + "p2": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "brightness": "0.6", + "wavelength": "580" + }, + { + "type": "SingleRay", + "p1": { + "x": 281.4341375969836, + "y": 410.3691545690761 + }, + "p2": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "brightness": "0.9", + "wavelength": "540" + }, + { + "type": "SingleRay", + "p1": { + "x": 311.31108607395794, + "y": 410.3691545690761 + }, + "p2": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "brightness": "0.6", + "wavelength": "500" + }, + { + "type": "SingleRay", + "p1": { + "x": 341.1880345509317, + "y": 410.3691545690761 + }, + "p2": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "brightness": "0.9", + "wavelength": "460" + }, + { + "type": "SingleRay", + "p1": { + "x": 371.0649830279073, + "y": 410.3691545690761 + }, + "p2": { + "x": 400.9419315048804, + "y": 410.3691545690761 + }, + "brightness": "0.8", + "wavelength": "420" + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 510, + "y": 340, + "arc": false + }, + { + "x": 530, + "y": 340, + "arc": false + }, + { + "x": 560, + "y": 500, + "arc": true + }, + { + "x": 530, + "y": 660, + "arc": false + }, + { + "x": 510, + "y": 660, + "arc": false + }, + { + "x": 480, + "y": 500, + "arc": true + } + ], + "refIndex": 1.728, + "cauchyB": "0.01342" + }, + { + "type": "TextLabel", + "x": 97.70452880452885, + "y": 544.514119214119, + "text": "拖拽此处可调整光束宽度", + "fontSize": 16, + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": -94.67004313196283, + "y": 299.1044033366009 + }, + "p4": { + "x": 1008.8684184064988, + "y": 696.4890187212163 + } + }, + { + "type": "CropBox", + "p1": { + "x": 448.7145722526526, + "y": 300.2265752823023 + }, + "p4": { + "x": 844.7145722526526, + "y": 696.2265752823023 + } + } + ], + "width": 1655.3076923076924, + "height": 949.1538461538462, + "rayModeDensity": 0.049787068367863944, + "origin": { + "x": 370.55465851657823, + "y": -23.219787951985495 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/chromatic-dispersion-thumbnail.avif b/cn/gallery/chromatic-dispersion-thumbnail.avif new file mode 100644 index 00000000..01b1084b Binary files /dev/null and b/cn/gallery/chromatic-dispersion-thumbnail.avif differ diff --git a/cn/gallery/chromatic-dispersion-thumbnail.jpg b/cn/gallery/chromatic-dispersion-thumbnail.jpg new file mode 100644 index 00000000..419c0d31 Binary files /dev/null and b/cn/gallery/chromatic-dispersion-thumbnail.jpg differ diff --git a/cn/gallery/chromatic-dispersion.avif b/cn/gallery/chromatic-dispersion.avif new file mode 100644 index 00000000..acf17b02 Binary files /dev/null and b/cn/gallery/chromatic-dispersion.avif differ diff --git a/cn/gallery/chromatic-dispersion.html b/cn/gallery/chromatic-dispersion.html new file mode 100644 index 00000000..ce293a65 --- /dev/null +++ b/cn/gallery/chromatic-dispersion.html @@ -0,0 +1,172 @@ + + + + + + + 色散 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    色散

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    这个模拟使用一个白色光束和一个三角稜鏡展示色散现象。此处白色是由红、橙、黄、绿、青、蓝、紫的混色形成的。

    +
    +

    + 在模拟器中打开 +

    + + + 色散 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/chromatic-dispersion.jpg b/cn/gallery/chromatic-dispersion.jpg new file mode 100644 index 00000000..867c1310 Binary files /dev/null and b/cn/gallery/chromatic-dispersion.jpg differ diff --git a/cn/gallery/chromatic-dispersion.json b/cn/gallery/chromatic-dispersion.json new file mode 100644 index 00000000..89cf2892 --- /dev/null +++ b/cn/gallery/chromatic-dispersion.json @@ -0,0 +1,364 @@ +{ + "name": "色散", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 398.882349951634, + "y": 350 + }, + "p2": { + "x": 398.32123046391723, + "y": 420.7118902106877 + }, + "controlPoints": [ + { + "newPoint": { + "x": 369.2729584346481, + "y": 415.87051153914274 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 369.2729584346481, + "y": 425.5532688822327 + }, + "targetObjIndex": 3, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 378.9557157777377, + "y": 415.87051153914274 + }, + "targetObjIndex": 4, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 378.9557157777377, + "y": 425.5532688822327 + }, + "targetObjIndex": 4, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 388.6384731208275, + "y": 415.87051153914274 + }, + "targetObjIndex": 5, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 388.6384731208275, + "y": 425.5532688822327 + }, + "targetObjIndex": 5, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 398.3212304639173, + "y": 415.87051153914274 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 398.3212304639173, + "y": 425.5532688822327 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 408.00398780700704, + "y": 415.87051153914274 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 408.00398780700704, + "y": 425.5532688822327 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 417.6867451500969, + "y": 415.87051153914274 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 417.6867451500969, + "y": 425.5532688822327 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 427.36950249318636, + "y": 415.87051153914274 + }, + "targetObjIndex": 2, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 427.36950249318636, + "y": 425.5532688822327 + }, + "targetObjIndex": 2, + "dragContext": { + "part": 2 + } + } + ], + "transformation": "scaling" + }, + { + "type": "Handle", + "p1": { + "x": 530, + "y": 505 + }, + "p2": { + "x": 619.9096459780985, + "y": 456.622767643451 + }, + "controlPoints": [ + { + "newPoint": { + "x": 550.2995322873085, + "y": 493.93205013002427 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 2 + } + }, + { + "newPoint": { + "x": 622.4892395392826, + "y": 377.81460660753737 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 0 + } + }, + { + "newPoint": { + "x": 686.9401661077047, + "y": 498.12164619279156 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 1 + } + } + ], + "transformation": "rotation" + }, + { + "type": "Beam", + "p1": { + "x": 427.36950249318636, + "y": 415.87051153914274 + }, + "p2": { + "x": 427.36950249318636, + "y": 425.5532688822327 + }, + "brightness": "0.4", + "wavelength": "420" + }, + { + "type": "Beam", + "p1": { + "x": 369.2729584346481, + "y": 415.87051153914274 + }, + "p2": { + "x": 369.2729584346481, + "y": 425.5532688822327 + }, + "brightness": "0.45", + "wavelength": "620" + }, + { + "type": "Beam", + "p1": { + "x": 378.9557157777377, + "y": 415.87051153914274 + }, + "p2": { + "x": 378.9557157777377, + "y": 425.5532688822327 + }, + "brightness": "0.2", + "wavelength": "600" + }, + { + "type": "Beam", + "p1": { + "x": 388.6384731208275, + "y": 415.87051153914274 + }, + "p2": { + "x": 388.6384731208275, + "y": 425.5532688822327 + }, + "brightness": "0.3", + "wavelength": "580" + }, + { + "type": "Beam", + "p1": { + "x": 398.3212304639173, + "y": 415.87051153914274 + }, + "p2": { + "x": 398.3212304639173, + "y": 425.5532688822327 + }, + "brightness": "0.45", + "wavelength": "540" + }, + { + "type": "Beam", + "p1": { + "x": 408.00398780700704, + "y": 415.87051153914274 + }, + "p2": { + "x": 408.00398780700704, + "y": 425.5532688822327 + }, + "brightness": "0.3", + "wavelength": "500" + }, + { + "type": "Beam", + "p1": { + "x": 417.6867451500969, + "y": 415.87051153914274 + }, + "p2": { + "x": 417.6867451500969, + "y": 425.5532688822327 + }, + "brightness": "0.45", + "wavelength": "460" + }, + { + "type": "Glass", + "path": [ + { + "x": 622.4892395392826, + "y": 377.81460660753737, + "arc": false + }, + { + "x": 686.9401661077047, + "y": 498.12164619279156, + "arc": false + }, + { + "x": 550.2995322873085, + "y": 493.93205013002427, + "arc": false + } + ] + }, + { + "type": "TextLabel", + "x": 419.47561821366054, + "y": 343.8461116752542, + "text": "拖曳此处\n可调整光束宽度", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 504.9456926915665, + "y": 502.1990798526488, + "text": "拖曳此处\n可旋转棱镜", + "fontSize": 12, + "alignment": "right" + }, + { + "type": "CropBox", + "p1": { + "x": 224.10839465489053, + "y": 285.8027072321243 + }, + "p4": { + "x": 911.1083946548902, + "y": 607.3531292667758 + } + }, + { + "type": "CropBox", + "p1": { + "x": 546.354037102933, + "y": 368.43405273892125 + }, + "p4": { + "x": 746.354037102933, + "y": 568.4340527389213 + } + } + ], + "width": 1030.4999999999995, + "height": 665.0504220346513, + "rayModeDensity": 1, + "origin": { + "x": -52.35839465489062, + "y": -114.05270723212439 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/compound-microscope-thumbnail.avif b/cn/gallery/compound-microscope-thumbnail.avif new file mode 100644 index 00000000..5b7527b9 Binary files /dev/null and b/cn/gallery/compound-microscope-thumbnail.avif differ diff --git a/cn/gallery/compound-microscope-thumbnail.jpg b/cn/gallery/compound-microscope-thumbnail.jpg new file mode 100644 index 00000000..0431e90a Binary files /dev/null and b/cn/gallery/compound-microscope-thumbnail.jpg differ diff --git a/cn/gallery/compound-microscope.avif b/cn/gallery/compound-microscope.avif new file mode 100644 index 00000000..02e732ff Binary files /dev/null and b/cn/gallery/compound-microscope.avif differ diff --git a/cn/gallery/compound-microscope.html b/cn/gallery/compound-microscope.html new file mode 100644 index 00000000..2111a49f --- /dev/null +++ b/cn/gallery/compound-microscope.html @@ -0,0 +1,172 @@ + + + + + + + 复式显微镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    复式显微镜

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    复式显微镜(Compound Microscope)由两个镜头组成,即物镜和目镜。物(绿色)非常接近轴,代表一个小物体。然后,两个镜头将物体放大,使产生一个大的倒置虚像(最终的橙色延长线的交点)。

    +
    +

    + 在模拟器中打开 +

    + + + 复式显微镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/compound-microscope.jpg b/cn/gallery/compound-microscope.jpg new file mode 100644 index 00000000..0476e9fb Binary files /dev/null and b/cn/gallery/compound-microscope.jpg differ diff --git a/cn/gallery/compound-microscope.json b/cn/gallery/compound-microscope.json new file mode 100644 index 00000000..1d64bf97 --- /dev/null +++ b/cn/gallery/compound-microscope.json @@ -0,0 +1,97 @@ +{ + "name": "复式显微镜", + "version": 5, + "objs": [ + { + "type": "Ruler", + "p1": { + "x": 404, + "y": 334 + }, + "p2": { + "x": 1084, + "y": 334 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 849, + "y": 190 + }, + "p2": { + "x": 849, + "y": 478 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 464, + "y": 274 + }, + "p2": { + "x": 464, + "y": 394 + }, + "focalLength": 50 + }, + { + "type": "AngleSource", + "p1": { + "x": 404.6412698412697, + "y": 321.8297258297258 + }, + "p2": { + "x": 463.94039644565953, + "y": 333.94335080124546 + }, + "emisAngle": 82 + }, + { + "type": "TextLabel", + "x": 464.3216604345087, + "y": 433.32548572858167, + "text": "物镜", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 847.2168985297469, + "y": 516.2588190619147, + "text": "目镜", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": 222.57729596564377, + "y": 129.03670550880133 + }, + "p4": { + "x": 1184.5772959656438, + "y": 579.1744747395705 + } + }, + { + "type": "CropBox", + "p1": { + "x": 371.4220267348749, + "y": 62.87493627803207 + }, + "p4": { + "x": 934.9604882733365, + "y": 626.413398278033 + } + } + ], + "width": 1443, + "height": 931.1377692307692, + "mode": "extended", + "rayModeDensity": 0.049787068367863944, + "origin": { + "x": 17.92270403435623, + "y": 111.46329449119867 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/concave-lens-thumbnail.avif b/cn/gallery/concave-lens-thumbnail.avif new file mode 100644 index 00000000..1c9a91cd Binary files /dev/null and b/cn/gallery/concave-lens-thumbnail.avif differ diff --git a/cn/gallery/concave-lens-thumbnail.jpg b/cn/gallery/concave-lens-thumbnail.jpg new file mode 100644 index 00000000..adae0253 Binary files /dev/null and b/cn/gallery/concave-lens-thumbnail.jpg differ diff --git a/cn/gallery/concave-lens.avif b/cn/gallery/concave-lens.avif new file mode 100644 index 00000000..e3af80ff Binary files /dev/null and b/cn/gallery/concave-lens.avif differ diff --git a/cn/gallery/concave-lens.html b/cn/gallery/concave-lens.html new file mode 100644 index 00000000..0ccbedeb --- /dev/null +++ b/cn/gallery/concave-lens.html @@ -0,0 +1,172 @@ + + + + + + + 凹透镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    凹透镜

    +

    + 贡献者:Paul Falstad +

    +
    +

    模拟凹透镜使光束分散的现象。

    +
    +

    + 在模拟器中打开 +

    + + + 凹透镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/concave-lens.jpg b/cn/gallery/concave-lens.jpg new file mode 100644 index 00000000..ef325463 Binary files /dev/null and b/cn/gallery/concave-lens.jpg differ diff --git a/cn/gallery/concave-lens.json b/cn/gallery/concave-lens.json new file mode 100644 index 00000000..08b07f2f --- /dev/null +++ b/cn/gallery/concave-lens.json @@ -0,0 +1,84 @@ +{ + "name": "凹透镜", + "version": 5, + "objs": [ + { + "type": "SphericalLens", + "path": [ + { + "x": 232.67204034309847, + "y": -25.495482215672098, + "arc": false + }, + { + "x": 329.3279596569015, + "y": -25.495482215672098, + "arc": false + }, + { + "x": 295.8072311430985, + "y": 317.92169198432794, + "arc": true + }, + { + "x": 329.3279596569015, + "y": 661.3388661843279, + "arc": false + }, + { + "x": 232.67204034309847, + "y": 661.3388661843279, + "arc": false + }, + { + "x": 267.1094171430985, + "y": 317.92169198432794, + "arc": true + } + ], + "refIndex": 2.39 + }, + { + "type": "Beam", + "p1": { + "x": -844.5341336, + "y": 145.38568359999996 + }, + "p2": { + "x": -844.5341336, + "y": 505.38568359999994 + } + }, + { + "type": "CropBox", + "p1": { + "x": -907.1643243369017, + "y": -135.51926833567222 + }, + "p4": { + "x": 1184.8356756630983, + "y": 784.4807316643278 + } + }, + { + "type": "CropBox", + "p1": { + "x": -391.1643243369017, + "y": -83.51926833567222 + }, + "p4": { + "x": 414.8356756630983, + "y": 722.4807316643278 + } + } + ], + "width": 3138, + "height": 1966, + "mode": "extended", + "rayModeDensity": 0.16524930599282625, + "origin": { + "x": 1430.1643243369017, + "y": 658.5192683356722 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/concave-mirror-wearable-display-thumbnail.avif b/cn/gallery/concave-mirror-wearable-display-thumbnail.avif new file mode 100644 index 00000000..2b184d6f Binary files /dev/null and b/cn/gallery/concave-mirror-wearable-display-thumbnail.avif differ diff --git a/cn/gallery/concave-mirror-wearable-display-thumbnail.jpg b/cn/gallery/concave-mirror-wearable-display-thumbnail.jpg new file mode 100644 index 00000000..eeb7110c Binary files /dev/null and b/cn/gallery/concave-mirror-wearable-display-thumbnail.jpg differ diff --git a/cn/gallery/concave-mirror-wearable-display.avif b/cn/gallery/concave-mirror-wearable-display.avif new file mode 100644 index 00000000..78636782 Binary files /dev/null and b/cn/gallery/concave-mirror-wearable-display.avif differ diff --git a/cn/gallery/concave-mirror-wearable-display.html b/cn/gallery/concave-mirror-wearable-display.html new file mode 100644 index 00000000..b7996ffa --- /dev/null +++ b/cn/gallery/concave-mirror-wearable-display.html @@ -0,0 +1,171 @@ + + + + + + + 凹面镜可穿戴显示器 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    凹面镜可穿戴显示器

    +

    + 贡献者:Rene +

    +
    +

    简易的可穿戴显示器。许多设计都使用两个镜子及一个正透镜,但本模拟为只用一个光学元件的版本。比例约为5:1mm。

    +

    < p>CC0:此作品已被标记为释出至公有领域

    +
    +

    + 在模拟器中打开 +

    + + + 凹面镜可穿戴显示器 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/concave-mirror-wearable-display.jpg b/cn/gallery/concave-mirror-wearable-display.jpg new file mode 100644 index 00000000..9ba42540 Binary files /dev/null and b/cn/gallery/concave-mirror-wearable-display.jpg differ diff --git a/cn/gallery/concave-mirror-wearable-display.json b/cn/gallery/concave-mirror-wearable-display.json new file mode 100644 index 00000000..2a8f1950 --- /dev/null +++ b/cn/gallery/concave-mirror-wearable-display.json @@ -0,0 +1,274 @@ +{ + "name": "凹面镜可穿戴显示器", + "version": 5, + "objs": [ + { + "type": "ArcMirror", + "p1": { + "x": 667.1808510890548, + "y": 74.56195880143267 + }, + "p2": { + "x": 730.922853531057, + "y": 236.68122842070227 + }, + "p3": { + "x": 697.1808510890548, + "y": 137.56195880143267 + } + }, + { + "type": "Ruler", + "p1": { + "x": 503.5597069597069, + "y": 485.6413919413919 + }, + "p2": { + "x": 707.3852281705217, + "y": 484.57955247367005 + } + }, + { + "type": "Beam", + "p1": { + "x": 489.0419011501046, + "y": 348.0542442937182 + }, + "p2": { + "x": 498.1808510890548, + "y": 356.56195880143264 + }, + "brightness": 1, + "wavelength": 484, + "emisAngle": 13 + }, + { + "type": "Ruler", + "p1": { + "x": 445.18085108905484, + "y": 119.56195880143267 + }, + "p2": { + "x": 445.8475177557215, + "y": 181.2286254680993 + }, + "scaleInterval": 5 + }, + { + "type": "Ruler", + "p1": { + "x": 704.1808510890548, + "y": 102.56195880143267 + }, + "p2": { + "x": 733.1808510890548, + "y": 167.56195880143267 + }, + "scaleInterval": 5 + }, + { + "type": "LineArrow", + "p1": { + "x": 273.1969758999164, + "y": 187.08921633921622 + }, + "p2": { + "x": 600.0541187570593, + "y": 188.23207348207336 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 602.0969758999163, + "y": 483.89874014874005 + }, + "p2": { + "x": 601.4779282808689, + "y": 187.265406815407 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 499.1731663761068, + "y": 461.61302586302565 + }, + "p2": { + "x": 629.7636425665833, + "y": 485.765406815407 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 503.83983304277353, + "y": 515.2796925296924 + }, + "p2": { + "x": 628.7636425665833, + "y": 487.765406815407 + } + }, + { + "type": "Ruler", + "p1": { + "x": 502.9636425665829, + "y": 485.63207348207334 + }, + "p2": { + "x": 500.4969758999162, + "y": 75.09874014874003 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 7.180851089054765, + "y": 427.2286254680993 + }, + "p2": { + "x": 446.2475177557216, + "y": 218.82862546809932 + }, + "brightness": 0.07, + "wavelength": 593, + "emisAngle": 5 + }, + { + "type": "Ruler", + "p1": { + "x": 5.847517755721409, + "y": 429.89529213476595 + }, + "p2": { + "x": 722.2475177557216, + "y": 217.49529213476595 + } + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 606.181829665601, + "y": 189.54911608858987, + "arc": false + }, + { + "x": 610.2353059679416, + "y": 189.54911608858987, + "arc": false + }, + { + "x": 613.2085678167713, + "y": 308.660227199701, + "arc": true + }, + { + "x": 610.2353059679416, + "y": 427.7713383108121, + "arc": false + }, + { + "x": 606.181829665601, + "y": 427.7713383108121, + "arc": false + }, + { + "x": 603.2085678167713, + "y": 308.660227199701, + "arc": true + } + ] + }, + { + "type": "TextLabel", + "x": 420.09540902027635, + "y": 118.16309801309795, + "text": "TFT 0.9吋显示屏", + "fontSize": 12, + "font": "Arial", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 727.6318965348369, + "y": 134.83842268842255, + "text": "凹面镜", + "fontSize": 12, + "font": "Arial" + }, + { + "type": "TextLabel", + "x": 489.06840447134493, + "y": 363.0447718947717, + "text": "眼睛", + "fontSize": 12, + "font": "Arial", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 510.6240155269562, + "y": 482.33720168720185, + "text": "鼻子", + "fontSize": 12, + "font": "Arial" + }, + { + "type": "TextLabel", + "x": -1.2229345031940397, + "y": 414.68122842070215, + "text": "用来测量半径的点光源", + "fontSize": 12, + "font": "Arial", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 612.2657106739144, + "y": 296.0621808016546, + "text": "+1.5度阅读眼镜", + "fontSize": 12, + "font": "Arial" + }, + { + "type": "CropBox", + "p1": { + "x": -289.0340998747197, + "y": 9.633780442366021 + }, + "p4": { + "x": 976.2443094380272, + "y": 607.8264945397603 + } + }, + { + "type": "CropBox", + "p1": { + "x": 448.6248930712244, + "y": 31.314097054999152 + }, + "p4": { + "x": 828.6248930712244, + "y": 411.31409705499914 + } + } + ], + "width": 1897.9176139691206, + "height": 1230.8319187537677, + "rayModeDensity": 0.37719235356315695, + "observer": { + "c": { + "x": 530.997802197802, + "y": 368.16153846153844 + }, + "r": 2.5 + }, + "origin": { + "x": 605.3537022029064, + "y": 306.68582188582076 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/convex-lens-thumbnail.avif b/cn/gallery/convex-lens-thumbnail.avif new file mode 100644 index 00000000..74b55ab5 Binary files /dev/null and b/cn/gallery/convex-lens-thumbnail.avif differ diff --git a/cn/gallery/convex-lens-thumbnail.jpg b/cn/gallery/convex-lens-thumbnail.jpg new file mode 100644 index 00000000..8b449c42 Binary files /dev/null and b/cn/gallery/convex-lens-thumbnail.jpg differ diff --git a/cn/gallery/convex-lens.avif b/cn/gallery/convex-lens.avif new file mode 100644 index 00000000..d5c5c109 Binary files /dev/null and b/cn/gallery/convex-lens.avif differ diff --git a/cn/gallery/convex-lens.html b/cn/gallery/convex-lens.html new file mode 100644 index 00000000..b2fb374b --- /dev/null +++ b/cn/gallery/convex-lens.html @@ -0,0 +1,172 @@ + + + + + + + 凸透镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    凸透镜

    +

    + 贡献者:Paul Falstad +

    +
    +

    模拟凸透镜使光束聚焦的现象。

    +
    +

    + 在模拟器中打开 +

    + + + 凸透镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/convex-lens.jpg b/cn/gallery/convex-lens.jpg new file mode 100644 index 00000000..c5d17ec4 Binary files /dev/null and b/cn/gallery/convex-lens.jpg differ diff --git a/cn/gallery/convex-lens.json b/cn/gallery/convex-lens.json new file mode 100644 index 00000000..4eb1b163 --- /dev/null +++ b/cn/gallery/convex-lens.json @@ -0,0 +1,83 @@ +{ + "name": "凸透镜", + "version": 5, + "objs": [ + { + "type": "SphericalLens", + "path": [ + { + "x": 275.75870685690154, + "y": -26.695522137358694, + "arc": false + }, + { + "x": 286.24129314309846, + "y": -26.695522137358694, + "arc": false + }, + { + "x": 311.1127319430985, + "y": 317.3216720234846, + "arc": true + }, + { + "x": 286.24129314309846, + "y": 661.3388661843279, + "arc": false + }, + { + "x": 275.75870685690154, + "y": 661.3388661843279, + "arc": false + }, + { + "x": 246.0643535430985, + "y": 317.3216720234846, + "arc": true + } + ], + "refIndex": 2.39 + }, + { + "type": "Beam", + "p1": { + "x": -678.0868124, + "y": 143.47249599999998 + }, + "p2": { + "x": -678.0868124, + "y": 503.4724960000001 + } + }, + { + "type": "CropBox", + "p1": { + "x": -738.461985416902, + "y": -91.30913565567205 + }, + "p4": { + "x": 1245.1309182630985, + "y": 752.406595944328 + } + }, + { + "type": "CropBox", + "p1": { + "x": 184.45971282309836, + "y": -152.23697113567204 + }, + "p4": { + "x": 1152.1500009030983, + "y": 815.4533168643279 + } + } + ], + "width": 2975.3893555200007, + "height": 1835.5121834400004, + "rayModeDensity": 0.16524930599282625, + "origin": { + "x": 1234.3602113369022, + "y": 587.2073615756722 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/dichroic-rbg-splitter-and-combiner-thumbnail.avif b/cn/gallery/dichroic-rbg-splitter-and-combiner-thumbnail.avif new file mode 100644 index 00000000..25188f94 Binary files /dev/null and b/cn/gallery/dichroic-rbg-splitter-and-combiner-thumbnail.avif differ diff --git a/cn/gallery/dichroic-rbg-splitter-and-combiner-thumbnail.jpg b/cn/gallery/dichroic-rbg-splitter-and-combiner-thumbnail.jpg new file mode 100644 index 00000000..896fb430 Binary files /dev/null and b/cn/gallery/dichroic-rbg-splitter-and-combiner-thumbnail.jpg differ diff --git a/cn/gallery/dichroic-rbg-splitter-and-combiner.avif b/cn/gallery/dichroic-rbg-splitter-and-combiner.avif new file mode 100644 index 00000000..3c64a8e0 Binary files /dev/null and b/cn/gallery/dichroic-rbg-splitter-and-combiner.avif differ diff --git a/cn/gallery/dichroic-rbg-splitter-and-combiner.html b/cn/gallery/dichroic-rbg-splitter-and-combiner.html new file mode 100644 index 00000000..f88fe0fb --- /dev/null +++ b/cn/gallery/dichroic-rbg-splitter-and-combiner.html @@ -0,0 +1,172 @@ + + + + + + + 二色性RGB分光器与合光器 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    二色性RGB分光器与合光器

    +

    + 贡献者:James Garrard +

    +
    +

    这个模拟使用二色镜来分割和组合RGB光束。

    +
    +

    + 在模拟器中打开 +

    + + + 二色性RGB分光器与合光器 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/dichroic-rbg-splitter-and-combiner.jpg b/cn/gallery/dichroic-rbg-splitter-and-combiner.jpg new file mode 100644 index 00000000..5d04cdbb Binary files /dev/null and b/cn/gallery/dichroic-rbg-splitter-and-combiner.jpg differ diff --git a/cn/gallery/dichroic-rbg-splitter-and-combiner.json b/cn/gallery/dichroic-rbg-splitter-and-combiner.json new file mode 100644 index 00000000..1bcab07c --- /dev/null +++ b/cn/gallery/dichroic-rbg-splitter-and-combiner.json @@ -0,0 +1,206 @@ +{ + "name": "二色性RGB分光器与合光器", + "version": 5, + "objs": [ + { + "type": "Beam", + "p1": { + "x": 600, + "y": 440 + }, + "p2": { + "x": 600, + "y": 480 + }, + "wavelength": 620 + }, + { + "type": "Mirror", + "p1": { + "x": 920, + "y": 400 + }, + "p2": { + "x": 960, + "y": 360 + }, + "filter": true, + "wavelength": "620" + }, + { + "type": "Mirror", + "p1": { + "x": 920, + "y": 560 + }, + "p2": { + "x": 960, + "y": 520 + }, + "wavelength": "540" + }, + { + "type": "Mirror", + "p1": { + "x": 920, + "y": 480 + }, + "p2": { + "x": 960, + "y": 440 + }, + "filter": true, + "wavelength": "460" + }, + { + "type": "Mirror", + "p1": { + "x": 660, + "y": 480 + }, + "p2": { + "x": 700, + "y": 440 + }, + "filter": true, + "wavelength": 620 + }, + { + "type": "Mirror", + "p1": { + "x": 660, + "y": 440 + }, + "p2": { + "x": 700, + "y": 480 + }, + "filter": true, + "wavelength": "540" + }, + { + "type": "Beam", + "p1": { + "x": 600, + "y": 440 + }, + "p2": { + "x": 600, + "y": 480 + } + }, + { + "type": "Beam", + "p1": { + "x": 600, + "y": 440 + }, + "p2": { + "x": 600, + "y": 480 + }, + "wavelength": 460 + }, + { + "type": "Mirror", + "p1": { + "x": 660, + "y": 400 + }, + "p2": { + "x": 700, + "y": 360 + } + }, + { + "type": "Mirror", + "p1": { + "x": 660, + "y": 520 + }, + "p2": { + "x": 700, + "y": 560 + } + }, + { + "type": "Mirror", + "p1": { + "x": 920, + "y": 280 + }, + "p2": { + "x": 960, + "y": 320 + } + }, + { + "type": "Blocker", + "p1": { + "x": 440, + "y": 280 + }, + "p2": { + "x": 440, + "y": 320 + } + }, + { + "type": "TextLabel", + "x": 436.57142857142844, + "y": 352.00000000000006, + "text": "RGB分量分光器与合光器" + }, + { + "type": "TextLabel", + "x": 588.0000000000002, + "y": 469.7142857142858, + "text": "光源", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 679.4285714285716, + "y": 436, + "text": "二色性立方体", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 969.142857142857, + "y": 433.14285714285717, + "text": "合光器" + }, + { + "type": "CropBox", + "p1": { + "x": 303.4742857142859, + "y": 219.93142857142854 + }, + "p4": { + "x": 1274.8571428571431, + "y": 628.6857142857143 + } + }, + { + "type": "CropBox", + "p1": { + "x": 591.8857142857144, + "y": 238.85714285714275 + }, + "p4": { + "x": 967.3142857142858, + "y": 614.2857138571428 + } + } + ], + "width": 1457.074285714286, + "height": 894.4457142857143, + "rayModeDensity": 0.4134990756293879, + "origin": { + "x": -60.628571428571576, + "y": 22.914285714285768 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece-thumbnail.avif b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece-thumbnail.avif new file mode 100644 index 00000000..a54f40c2 Binary files /dev/null and b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece-thumbnail.avif differ diff --git a/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece-thumbnail.jpg b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece-thumbnail.jpg new file mode 100644 index 00000000..57b7b22c Binary files /dev/null and b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece-thumbnail.jpg differ diff --git a/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.avif b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.avif new file mode 100644 index 00000000..b4f6559c Binary files /dev/null and b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.avif differ diff --git a/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.html b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.html new file mode 100644 index 00000000..2e6c2a0b --- /dev/null +++ b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.html @@ -0,0 +1,172 @@ + + + + + + + 经由目镜将爱因斯坦环重新聚焦为单一影像 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    经由目镜将爱因斯坦环重新聚焦为单一影像

    +

    + 贡献者:Jordan Anderson +

    +
    +

    这是一个目镜/透镜的模型,可以用在任何科学望远镜上,透过逆转“光晕”,将爱因斯坦环聚焦回原始形态,同时散射用来创建环的星体或大质量物体的光。

    +
    +

    + 在模拟器中打开 +

    + + + 经由目镜将爱因斯坦环重新聚焦为单一影像 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.jpg b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.jpg new file mode 100644 index 00000000..2f79fb29 Binary files /dev/null and b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.jpg differ diff --git a/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.json b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.json new file mode 100644 index 00000000..a73152c5 --- /dev/null +++ b/cn/gallery/einstein-ring-refocused-to-single-image-via-eyepiece.json @@ -0,0 +1,286 @@ +{ + "name": "经由目镜将爱因斯坦环重新聚焦为单一影像", + "version": 5, + "objs": [ + { + "type": "AngleSource", + "p1": { + "x": 690.6, + "y": 475 + }, + "p2": { + "x": 714.6, + "y": 475 + }, + "brightness": 1, + "wavelength": 673, + "emisAngle": "5" + }, + { + "type": "AngleSource", + "p1": { + "x": 690.8, + "y": 480.2 + }, + "p2": { + "x": 714.8, + "y": 480.2 + }, + "brightness": 1, + "wavelength": 593, + "emisAngle": "5" + }, + { + "type": "AngleSource", + "p1": { + "x": 690.8281099189365, + "y": 485.4 + }, + "p2": { + "x": 714.6, + "y": 485.4 + }, + "brightness": 1, + "emisAngle": "5" + }, + { + "type": "AngleSource", + "p1": { + "x": 31385.42857142857, + "y": 346.2285714285711 + }, + "p2": { + "x": 31402.828571428567, + "y": 346.2285714285711 + }, + "brightness": 1, + "wavelength": 427, + "emisAngle": "5" + }, + { + "type": "IdealLens", + "p1": { + "x": 31351.42857142857, + "y": 71.82857142857125 + }, + "p2": { + "x": 31351.42857142857, + "y": 347.82857142857125 + }, + "focalLength": "-3000" + }, + { + "type": "IdealLens", + "p1": { + "x": 31351.42857142857, + "y": 344.8285714285712 + }, + "p2": { + "x": 31351.42857142857, + "y": 620.8285714285712 + }, + "focalLength": "-3000" + }, + { + "type": "AngleSource", + "p1": { + "x": 4443.9841269841245, + "y": 481.49523809523765 + }, + "p2": { + "x": 4505.761904761903, + "y": 481.49523809523765 + }, + "brightness": 1, + "wavelength": 459, + "emisAngle": "5" + }, + { + "type": "IdealLens", + "p1": { + "x": 4443.984126984124, + "y": 242.73577071363434 + }, + "p2": { + "x": 4443.984126984124, + "y": 474.3841269841268 + }, + "focalLength": "-3000" + }, + { + "type": "AngleSource", + "p1": { + "x": 690.4070572873576, + "y": 477.2019361271682 + }, + "p2": { + "x": 727.2491625505155, + "y": 477.2019361271682 + }, + "brightness": 1, + "wavelength": 614, + "emisAngle": "5" + }, + { + "type": "AngleSource", + "p1": { + "x": 690.4070572873576, + "y": 483.09667296927347 + }, + "p2": { + "x": 727.459688866305, + "y": 483.09667296927347 + }, + "brightness": 1, + "wavelength": 545, + "emisAngle": "5" + }, + { + "type": "IdealMirror", + "p1": { + "x": 25460.16703525231, + "y": -704.1631815896526 + }, + "p2": { + "x": 25460.16703525231, + "y": 1699.8368184103474 + }, + "focalLength": 3000 + }, + { + "type": "IdealLens", + "p1": { + "x": 22027.023600908877, + "y": 469.45298002650895 + }, + "p2": { + "x": 22027.023600908877, + "y": 531.2307578042869 + }, + "focalLength": "-26" + }, + { + "type": "Mirror", + "p1": { + "x": 22028.07439455968, + "y": 464.3132974868265 + }, + "p2": { + "x": 21468.86770891644, + "y": 464.3132974868265 + } + }, + { + "type": "Mirror", + "p1": { + "x": 22027.059315194605, + "y": 536.8942498677787 + }, + "p2": { + "x": 21457.017708916443, + "y": 536.8942498677787 + } + }, + { + "type": "Blocker", + "p1": { + "x": 21450.985505670793, + "y": 459.468853042382 + }, + "p2": { + "x": 21450.985505670793, + "y": 539.4688530423819 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 690.8281099189365, + "y": 463.09667296927347 + }, + "p2": { + "x": 722.8281099189365, + "y": 463.09667296927347 + }, + "brightness": 1, + "wavelength": 750, + "emisAngle": "5" + }, + { + "type": "AngleSource", + "p1": { + "x": 690.1965309715681, + "y": 500.78088349558925 + }, + "p2": { + "x": 724.3017941294629, + "y": 500.78088349558925 + }, + "brightness": 1, + "wavelength": 400, + "emisAngle": "5" + }, + { + "type": "IdealLens", + "p1": { + "x": 4443.984126984124, + "y": 489.02148499934856 + }, + "p2": { + "x": 4443.984126984124, + "y": 720.669841269841 + }, + "focalLength": "-3000" + }, + { + "type": "Blocker", + "p1": { + "x": 21960.026799825533, + "y": 486.0820910599549 + }, + "p2": { + "x": 21960.026799825533, + "y": 516.2154243932882 + } + }, + { + "type": "CropBox", + "p1": { + "x": 21387.202917486728, + "y": 381.19402012216193 + }, + "p4": { + "x": 22159.831488915293, + "y": 629.5316824598244 + } + }, + { + "type": "CropBox", + "p1": { + "x": 21427.566553850364, + "y": 173.26674739488885 + }, + "p4": { + "x": 22107.54577462958, + "y": 853.2459683948891 + } + } + ], + "width": 1158.9428571428489, + "height": 634.6519480519455, + "rayModeDensity": 20.085536923187668, + "imageModeDensity": 20.085536923187668, + "observer": { + "c": { + "x": 21617.518004217996, + "y": 498.72849372849225 + }, + "r": 20 + }, + "origin": { + "x": -21194.045774629587, + "y": -188.03687726502045 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/fresnel-lens-thumbnail.avif b/cn/gallery/fresnel-lens-thumbnail.avif new file mode 100644 index 00000000..9bbd1d90 Binary files /dev/null and b/cn/gallery/fresnel-lens-thumbnail.avif differ diff --git a/cn/gallery/fresnel-lens-thumbnail.jpg b/cn/gallery/fresnel-lens-thumbnail.jpg new file mode 100644 index 00000000..c0ab773a Binary files /dev/null and b/cn/gallery/fresnel-lens-thumbnail.jpg differ diff --git a/cn/gallery/fresnel-lens.avif b/cn/gallery/fresnel-lens.avif new file mode 100644 index 00000000..a5bc5f85 Binary files /dev/null and b/cn/gallery/fresnel-lens.avif differ diff --git a/cn/gallery/fresnel-lens.html b/cn/gallery/fresnel-lens.html new file mode 100644 index 00000000..72a27c21 --- /dev/null +++ b/cn/gallery/fresnel-lens.html @@ -0,0 +1,172 @@ + + + + + + + 菲涅耳透镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    菲涅耳透镜

    +

    + 贡献者:Stas Fainer, Yi-Ting Tu +

    +
    +

    这是球面镜与菲涅耳透镜(Fresnel lens)的对比。菲涅耳透镜的优点:它的功能与常规的球面镜相似,但占用的空间少很多 - 因此重量更轻。

    +
    +

    + 在模拟器中打开 +

    + + + 菲涅耳透镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/fresnel-lens.jpg b/cn/gallery/fresnel-lens.jpg new file mode 100644 index 00000000..d1186724 Binary files /dev/null and b/cn/gallery/fresnel-lens.jpg differ diff --git a/cn/gallery/fresnel-lens.json b/cn/gallery/fresnel-lens.json new file mode 100644 index 00000000..892202e2 --- /dev/null +++ b/cn/gallery/fresnel-lens.json @@ -0,0 +1,140 @@ +{ + "name": "菲涅耳透镜", + "version": 5, + "modules": { + "FresnelLens": { + "numPoints": 2, + "params": [ + "N_slice=1:1:100:20", + "refIndex=0.5:0.01:2.5:1.5" + ], + "objs": [ + { + "type": "CustomGlass", + "p1": { + "x": "`x_1`", + "y": "`y_1`" + }, + "p2": { + "x": "`x_2`", + "y": "`y_2`" + }, + "eqn1": "-0.05", + "eqn2": "\\sqrt{1-x^2}-\\frac{\\operatorname{floor}\\left(`N_slice`\\cdot\\sqrt{1-x^2}\\right)}{`N_slice`}", + "refIndex": "`refIndex`" + } + ] + } + }, + "objs": [ + { + "type": "Beam", + "p1": { + "x": 1040, + "y": 820 + }, + "p2": { + "x": 1040, + "y": 900 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 1260, + "y": 780, + "arc": false + }, + { + "x": 1340, + "y": 860, + "arc": true + }, + { + "x": 1260, + "y": 940, + "arc": false + } + ] + }, + { + "type": "ModuleObj", + "module": "FresnelLens", + "points": [ + { + "x": 1340, + "y": 600 + }, + { + "x": 1340, + "y": 760 + } + ], + "params": { + "N_slice": 50, + "refIndex": 1.5 + } + }, + { + "type": "Beam", + "p1": { + "x": 1040, + "y": 640 + }, + "p2": { + "x": 1040, + "y": 720 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 1338.8549982860036, + "y": 551.6119816791208 + }, + "p2": { + "x": 1338.8549982860036, + "y": 579.3663107824154 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 1354.6447437999493, + "y": 497.8676902426197, + "text": "此菲涅耳透镜是由下面的半圆形透镜制成的\n您可以选择透镜并调整 N_silce(切片数量)参数。", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": 846.8317284877828, + "y": 455.34759324587964 + }, + "p4": { + "x": 1863.596929418593, + "y": 981.0288917442568 + } + }, + { + "type": "CropBox", + "p1": { + "x": 1322.2347967320538, + "y": 581.7767008307075 + }, + "p4": { + "x": 1520.500941732054, + "y": 780.0428458299864 + } + } + ], + "width": 1525.147801396215, + "height": 1034.0638989637823, + "rayModeDensity": 1, + "origin": { + "x": -592.6404282550802, + "y": -201.1562930131771 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/gan-based-lcd-pixel-thumbnail.avif b/cn/gallery/gan-based-lcd-pixel-thumbnail.avif new file mode 100644 index 00000000..32ae9488 Binary files /dev/null and b/cn/gallery/gan-based-lcd-pixel-thumbnail.avif differ diff --git a/cn/gallery/gan-based-lcd-pixel-thumbnail.jpg b/cn/gallery/gan-based-lcd-pixel-thumbnail.jpg new file mode 100644 index 00000000..b34c7a38 Binary files /dev/null and b/cn/gallery/gan-based-lcd-pixel-thumbnail.jpg differ diff --git a/cn/gallery/gan-based-lcd-pixel.avif b/cn/gallery/gan-based-lcd-pixel.avif new file mode 100644 index 00000000..e1fa93ce Binary files /dev/null and b/cn/gallery/gan-based-lcd-pixel.avif differ diff --git a/cn/gallery/gan-based-lcd-pixel.html b/cn/gallery/gan-based-lcd-pixel.html new file mode 100644 index 00000000..dad886aa --- /dev/null +++ b/cn/gallery/gan-based-lcd-pixel.html @@ -0,0 +1,172 @@ + + + + + + + 液晶显示器像素 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    液晶显示器像素

    +

    + 贡献者:James Garrard +

    +
    +

    这是一个液晶显示器像素的模型。它模拟了新型的微型发光二极体显示层的功能,以及我们的眼睛是如何感知它的。

    +
    +

    + 在模拟器中打开 +

    + + + 液晶显示器像素 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/gan-based-lcd-pixel.jpg b/cn/gallery/gan-based-lcd-pixel.jpg new file mode 100644 index 00000000..a1641c1e Binary files /dev/null and b/cn/gallery/gan-based-lcd-pixel.jpg differ diff --git a/cn/gallery/gan-based-lcd-pixel.json b/cn/gallery/gan-based-lcd-pixel.json new file mode 100644 index 00000000..7f1df0fe --- /dev/null +++ b/cn/gallery/gan-based-lcd-pixel.json @@ -0,0 +1,288 @@ +{ + "name": "液晶显示器像素", + "version": 5, + "objs": [ + { + "type": "Beam", + "p1": { + "x": 20, + "y": 400 + }, + "p2": { + "x": 20, + "y": 700 + }, + "brightness": 1, + "wavelength": "460" + }, + { + "type": "Beam", + "p1": { + "x": 140, + "y": 400 + }, + "p2": { + "x": 140, + "y": 700 + }, + "wavelength": "620" + }, + { + "type": "Beam", + "p1": { + "x": 140, + "y": 400 + }, + "p2": { + "x": 140, + "y": 700 + }, + "wavelength": "540" + }, + { + "type": "Beam", + "p1": { + "x": 140, + "y": 400 + }, + "p2": { + "x": 140, + "y": 700 + }, + "brightness": 0, + "wavelength": 580 + }, + { + "type": "Blocker", + "p1": { + "x": 20, + "y": 400 + }, + "p2": { + "x": 20, + "y": 700 + } + }, + { + "type": "Mirror", + "p1": { + "x": 820, + "y": 400 + }, + "p2": { + "x": 720, + "y": 500 + }, + "filter": true, + "wavelength": 620 + }, + { + "type": "Mirror", + "p1": { + "x": 820, + "y": 500 + }, + "p2": { + "x": 720, + "y": 600 + }, + "filter": true, + "wavelength": "540" + }, + { + "type": "Mirror", + "p1": { + "x": 820, + "y": 600 + }, + "p2": { + "x": 720, + "y": 700 + }, + "filter": true, + "wavelength": 460 + }, + { + "type": "Mirror", + "p1": { + "x": 820, + "y": 340 + }, + "p2": { + "x": 720, + "y": 240 + } + }, + { + "type": "Blocker", + "p1": { + "x": 20, + "y": 340 + }, + "p2": { + "x": 20, + "y": 240 + } + }, + { + "type": "Blocker", + "p1": { + "x": 260, + "y": 400 + }, + "p2": { + "x": 260, + "y": 500 + }, + "filter": true, + "invert": true, + "wavelength": 620 + }, + { + "type": "Blocker", + "p1": { + "x": 260, + "y": 500 + }, + "p2": { + "x": 260, + "y": 600 + }, + "filter": true, + "invert": true, + "wavelength": "540" + }, + { + "type": "Blocker", + "p1": { + "x": 260, + "y": 600 + }, + "p2": { + "x": 260, + "y": 700 + }, + "filter": true, + "invert": true, + "wavelength": 460 + }, + { + "type": "BeamSplitter", + "p1": { + "x": 460, + "y": 400 + }, + "p2": { + "x": 460, + "y": 500 + }, + "transRatio": 1 + }, + { + "type": "BeamSplitter", + "p1": { + "x": 460, + "y": 600 + }, + "p2": { + "x": 460, + "y": 500 + }, + "transRatio": 0.33 + }, + { + "type": "BeamSplitter", + "p1": { + "x": 460, + "y": 700 + }, + "p2": { + "x": 460, + "y": 600 + } + }, + { + "type": "TextLabel", + "x": 844, + "y": 486.00000000000006, + "text": "由于像素非常小,光\n在我们的眼中看起来是混合的" + }, + { + "type": "TextLabel", + "x": 384, + "y": 748, + "text": "改变透光率\n来产生任何RGB值" + }, + { + "type": "TextLabel", + "x": 7.684234851661699, + "y": 562.0760260946291, + "text": "蓝色LED背光", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 136.09942466453506, + "y": 391.6666666666665, + "text": "黄色磷光体", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 455.46592181428963, + "y": 387.5968253968253, + "text": "液晶", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 256.18714234109103, + "y": 746.5333333333335, + "text": "滤光器", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 20, + "y": 230.00000000000006, + "text": "观察者看到的像素" + }, + { + "type": "TextLabel", + "x": 846, + "y": 432.00000000000006, + "text": "不是液晶显示器的一部分" + }, + { + "type": "CropBox", + "p1": { + "x": -319.5999999999999, + "y": 157.59999999999997 + }, + "p4": { + "x": 1263.300343994497, + "y": 821.1764534775474 + } + }, + { + "type": "CropBox", + "p1": { + "x": 13.200000000000045, + "y": 96.39999999999998 + }, + "p4": { + "x": 831.2, + "y": 914.4 + } + } + ], + "width": 2374.3505159917454, + "height": 1455.0266254747958, + "rayModeDensity": 2.718281828459045, + "origin": { + "x": 715.3250859986242, + "y": 238.1250859986243 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/hyperbolic-lens-thumbnail.avif b/cn/gallery/hyperbolic-lens-thumbnail.avif new file mode 100644 index 00000000..66589035 Binary files /dev/null and b/cn/gallery/hyperbolic-lens-thumbnail.avif differ diff --git a/cn/gallery/hyperbolic-lens-thumbnail.jpg b/cn/gallery/hyperbolic-lens-thumbnail.jpg new file mode 100644 index 00000000..3265a272 Binary files /dev/null and b/cn/gallery/hyperbolic-lens-thumbnail.jpg differ diff --git a/cn/gallery/hyperbolic-lens.avif b/cn/gallery/hyperbolic-lens.avif new file mode 100644 index 00000000..b12a8311 Binary files /dev/null and b/cn/gallery/hyperbolic-lens.avif differ diff --git a/cn/gallery/hyperbolic-lens.html b/cn/gallery/hyperbolic-lens.html new file mode 100644 index 00000000..a49a26bf --- /dev/null +++ b/cn/gallery/hyperbolic-lens.html @@ -0,0 +1,172 @@ + + + + + + + 双曲透镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    双曲透镜

    +

    + 贡献者:Stas Fainer +

    +
    +

    这是双曲透镜与球面透镜的对比。这两个透镜有相同的焦距,但双曲透镜可以将单色光的平行光束集中到一点(忽略光的波动性 - 也就是在几何光学的近似下)而不像球面透镜会有有球面像差(Spherical aberrations)。

    +
    +

    + 在模拟器中打开 +

    + + + 双曲透镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/hyperbolic-lens.jpg b/cn/gallery/hyperbolic-lens.jpg new file mode 100644 index 00000000..7ceee695 Binary files /dev/null and b/cn/gallery/hyperbolic-lens.jpg differ diff --git a/cn/gallery/hyperbolic-lens.json b/cn/gallery/hyperbolic-lens.json new file mode 100644 index 00000000..952dcdf3 --- /dev/null +++ b/cn/gallery/hyperbolic-lens.json @@ -0,0 +1,186 @@ +{ + "name": "双曲透镜", + "version": 5, + "objs": [ + { + "type": "CustomGlass", + "p1": { + "x": 679, + "y": 20 + }, + "p2": { + "x": 1079, + "y": 20 + }, + "eqn1": "0.1", + "eqn2": "1.5-\\sqrt{\\frac{0.8+x^2}{1.25}}" + }, + { + "type": "Ruler", + "p1": { + "x": 59, + "y": 120 + }, + "p2": { + "x": 459, + "y": 120 + } + }, + { + "type": "Ruler", + "p1": { + "x": 679, + "y": 120 + }, + "p2": { + "x": 1079, + "y": 120 + } + }, + { + "type": "CustomGlass", + "p1": { + "x": 59, + "y": 80 + }, + "p2": { + "x": 459, + "y": 80 + }, + "eqn2": "\\sqrt{1-x^2}" + }, + { + "type": "Blocker", + "p1": { + "x": 619, + "y": 1120 + }, + "p2": { + "x": 619, + "y": -120 + } + }, + { + "type": "Ruler", + "p1": { + "x": 499, + "y": 80 + }, + "p2": { + "x": 499, + "y": -120 + } + }, + { + "type": "Ruler", + "p1": { + "x": 619, + "y": -120 + }, + "p2": { + "x": 619, + "y": -520 + } + }, + { + "type": "Blocker", + "p1": { + "x": 619, + "y": -520 + }, + "p2": { + "x": 619, + "y": -1520 + } + }, + { + "type": "Beam", + "p1": { + "x": 79, + "y": 180 + }, + "p2": { + "x": 439, + "y": 180 + } + }, + { + "type": "Beam", + "p1": { + "x": 699, + "y": 180 + }, + "p2": { + "x": 1059, + "y": 180 + } + }, + { + "type": "TextLabel", + "x": -540.422222222222, + "y": -143.4476190476192, + "text": "此球面透镜的焦距(在近轴近似中)为:\nf=R/(n-1)=200/(1.5-1)=400" + }, + { + "type": "TextLabel", + "x": 1117.5997557997562, + "y": -184.98608058608073, + "text": "此双曲透镜的焦距是:\nf = |C| ∙ sqrt(n^2 - 1) / (n - 1) = K ∙ sqrt(0.8) ∙ sqrt(1.5^2 - 1) / (1.5 - 1) = 400\n此双曲透镜的方程式是:\ny(x) = (a/K) - sqrt( ((x/K)^2 + (C/K)^2) / (n^2 - 1) )\n= 1.5 - sqrt( (0.8 + (x / 200)^2) / (1.5^2 - 1) )\n使得K是方程式维度与网格维度之间的转换常数 - 对于这个双曲面镜,K=20\n(例如0 + + + + + + 双曲面镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    双曲面镜

    +

    + 贡献者:Stas Fainer +

    +
    +

    本模拟演示了双曲面镜的反射特性:从一个焦点向双曲面镜传播的光线将如同从另一个焦点射出。

    +

    双曲面的两个焦点是等光程点(请参阅 等光程点)。

    +
    +

    + 在模拟器中打开 +

    + + + 双曲面镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/hyperbolic-mirror.jpg b/cn/gallery/hyperbolic-mirror.jpg new file mode 100644 index 00000000..950694d5 Binary files /dev/null and b/cn/gallery/hyperbolic-mirror.jpg differ diff --git a/cn/gallery/hyperbolic-mirror.json b/cn/gallery/hyperbolic-mirror.json new file mode 100644 index 00000000..9c97594e --- /dev/null +++ b/cn/gallery/hyperbolic-mirror.json @@ -0,0 +1,103 @@ +{ + "name": "双曲面镜", + "version": 5, + "objs": [ + { + "type": "CustomMirror", + "p1": { + "x": 880.0000000000002, + "y": 640 + }, + "p2": { + "x": 879.9999999999998, + "y": 840 + }, + "eqn": "\\sqrt{1+x^2}" + }, + { + "type": "PointSource", + "x": 738.5786437626906, + "y": 739.9999999999999, + "brightness": 0.43 + }, + { + "type": "CircleBlocker", + "p1": { + "x": 880, + "y": 740 + }, + "p2": { + "x": 1140, + "y": 740 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 1051.762340634194, + "y": 739.3010787839165 + }, + "p2": { + "x": 1029.066688460281, + "y": 739.3010787839165 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 737.6008499509643, + "y": 790.4501471068977 + }, + "p2": { + "x": 737.6008499509643, + "y": 759.928407976463 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 1058.7142857142853, + "y": 722.4099378881986, + "text": "橙色线是黄色反射光线的延长线。\n这些虚射线在另一个焦点上汇合。" + }, + { + "type": "TextLabel", + "x": 737.3478260869565, + "y": 815.9565217391303, + "text": "位于一个焦点的点光源", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": 379.6338018960446, + "y": 407.4213141549526 + }, + "p4": { + "x": 2282.4338018960443, + "y": 1113.0213141549527 + } + }, + { + "type": "CropBox", + "p1": { + "x": 578.4338018960445, + "y": 442.22131415495255 + }, + "p4": { + "x": 1194.4338018960445, + "y": 1058.2213141549526 + } + } + ], + "width": 2854.2, + "height": 1657, + "mode": "extended", + "rayModeDensity": 0.5077327766614864, + "origin": { + "x": 96.06619810395534, + "y": 68.27868584504733 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/images-formed-by-two-mirrors-thumbnail.avif b/cn/gallery/images-formed-by-two-mirrors-thumbnail.avif new file mode 100644 index 00000000..89150af6 Binary files /dev/null and b/cn/gallery/images-formed-by-two-mirrors-thumbnail.avif differ diff --git a/cn/gallery/images-formed-by-two-mirrors-thumbnail.jpg b/cn/gallery/images-formed-by-two-mirrors-thumbnail.jpg new file mode 100644 index 00000000..e216ff31 Binary files /dev/null and b/cn/gallery/images-formed-by-two-mirrors-thumbnail.jpg differ diff --git a/cn/gallery/images-formed-by-two-mirrors.avif b/cn/gallery/images-formed-by-two-mirrors.avif new file mode 100644 index 00000000..410d6590 Binary files /dev/null and b/cn/gallery/images-formed-by-two-mirrors.avif differ diff --git a/cn/gallery/images-formed-by-two-mirrors.html b/cn/gallery/images-formed-by-two-mirrors.html new file mode 100644 index 00000000..bc4c2d05 --- /dev/null +++ b/cn/gallery/images-formed-by-two-mirrors.html @@ -0,0 +1,172 @@ + + + + + + + 两面镜子成像 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    两面镜子成像

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    本模拟项目显示了两面镜子所成的像,其中绿色的 L 为物。若两面镜子的夹脚为 \(\frac{360^\circ}{n}\) 那么将成\(n-1\) 个虚像(橘色的 L)。可拖曳镜子端点来改变夹角。

    +
    +

    + 在模拟器中打开 +

    + + + 两面镜子成像 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/images-formed-by-two-mirrors.jpg b/cn/gallery/images-formed-by-two-mirrors.jpg new file mode 100644 index 00000000..75946e4a Binary files /dev/null and b/cn/gallery/images-formed-by-two-mirrors.jpg differ diff --git a/cn/gallery/images-formed-by-two-mirrors.json b/cn/gallery/images-formed-by-two-mirrors.json new file mode 100644 index 00000000..29fceb6f --- /dev/null +++ b/cn/gallery/images-formed-by-two-mirrors.json @@ -0,0 +1,89 @@ +{ + "name": "两面镜子成像", + "version": 5, + "objs": [ + { + "type": "PointSource", + "x": 494, + "y": 300 + }, + { + "type": "PointSource", + "x": 494, + "y": 320 + }, + { + "type": "PointSource", + "x": 494, + "y": 280 + }, + { + "type": "PointSource", + "x": 514, + "y": 320 + }, + { + "type": "Mirror", + "p1": { + "x": 395, + "y": 380 + }, + "p2": { + "x": 674, + "y": 380 + } + }, + { + "type": "Mirror", + "p1": { + "x": 533.1954312487626, + "y": 136.62256659554347 + }, + "p2": { + "x": 674, + "y": 380 + } + }, + { + "type": "Protractor", + "p1": { + "x": 674, + "y": 380 + }, + "p2": { + "x": 594, + "y": 380 + } + }, + { + "type": "CropBox", + "p1": { + "x": 243.42857142857156, + "y": 113.91428571428574 + }, + "p4": { + "x": 1101.0000000000005, + "y": 626.1428571428573 + } + }, + { + "type": "CropBox", + "p1": { + "x": 424.71428571428584, + "y": 126.00000000000006 + }, + "p4": { + "x": 920.9999997142858, + "y": 622.2857142857142 + } + } + ], + "width": 1286.3571428571433, + "height": 941.0142857142861, + "mode": "images", + "origin": { + "x": -29.035714285714334, + "y": 100.47857142857148 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/index.html b/cn/gallery/index.html new file mode 100644 index 00000000..9ce13066 --- /dev/null +++ b/cn/gallery/index.html @@ -0,0 +1,857 @@ + + + + + + + 作品集 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +

    “射线光学模拟”作品集

    + 以下列表为使用“射线光学模拟”网页程序制作的互动式光学演示。欢迎您贡献新项目(请参阅贡献指南)。如发现内容有误,请在GitHub上建立Issue或发送电子邮件至ray-optics@phydemo.app。 + +

    类别

    + 光的反射
    + 光的折射
    + 透镜
    + 透镜组合
    + 渐变折射率光学
    + 其他
    + + +   +

    光的反射

    + + + + + +
    +

    两面镜子成像

    +

    Yi-Ting Tu

    +
    +
    + + + + + +
    +

    抛物面镜

    +

    Paul Falstad

    +
    +
    + + + + + +
    +

    双曲面镜

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    回复反射器

    +

    Stas Fainer, Yi-Ting Tu

    +
    +
    + + + + + +
    +

    潜望镜

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    牛顿望远镜

    +

    Matteo Ricci Cipolloni

    +
    +
    + + + + + +
    +

    无法照亮的彭罗斯房间

    +

    Vincent Fan, Yi-Ting Tu

    +
    +
    + + + + + +
    +

    双镜共振腔

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    平凹共振腔

    +

    Mikhail Kochiev

    +
    +
    + + + + + +
    +

    用一条光线解迷宫

    +

    Stas Fainer, Yi-Ting Tu

    +
    +
    + + + + + +
    +

    镜面反射与漫反射

    +

    Steve Stonebraker

    +
    +
    + + + + + +
    +

    干扰箔

    +

    Stas Fainer, Yi-Ting Tu

    +
    +
    + + + + + +
    +

    反射性球体的焦散

    +

    Georg Nadorff

    +
    +
    + + + + + +
    +

    幻象镜

    +

    Mario Petitclerc

    +
    +
    +
    + +   +

    光的折射

    + + + + + +
    +

    反射与折射

    +

    Paul Falstad

    +
    +
    + + + + + +
    +

    全反射

    +

    Paul Falstad

    +
    +
    + + + + + +
    +

    稜鏡

    +

    Paul Falstad

    +
    +
    + + + + + +
    +

    光束导向器

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    视深度

    +

    Yi-Ting Tu

    +
    +
    + + + + + +
    +

    弯曲的铅笔

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    断裂的铅笔

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    色散

    +

    Yi-Ting Tu

    +
    +
    + + + + + +
    +

    彩虹

    +

    Yi-Ting Tu

    +
    +
    + + + + + +
    +

    最小偏向角

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    等光程点

    +

    Stas Fainer

    +
    +
    +
    + +   +

    透镜

    + + + + + +
    +

    凹透镜

    +

    Paul Falstad

    +
    +
    + + + + + +
    +

    凸透镜

    +

    Paul Falstad

    +
    +
    + + + + + +
    +

    透镜成像

    +

    Paul Falstad

    +
    +
    + + + + + +
    +

    横向和纵向放大率

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    消失点

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    单色像差

    +

    Paul Falstad, Stas Fainer

    +
    +
    + + + + + +
    +

    色像差

    +

    Yi-Ting Tu

    +
    +
    + + + + + +
    +

    双曲透镜

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    菲涅耳透镜

    +

    Stas Fainer, Yi-Ting Tu

    +
    +
    +
    + +   +

    透镜组合

    + + + + + +
    +

    变焦镜头

    +

    Paul Falstad

    +
    +
    + + + + + +
    +

    复式显微镜

    +

    Yi-Ting Tu

    +
    +
    + + + + + +
    +

    望远镜

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    开普勒望远镜

    +

    chuangyu J

    +
    +
    + + + + + +
    +

    扩束镜

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    光线中继

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    罗切斯特斗篷

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    简易双高斯透镜

    +

    Alex

    +
    +
    + + + + + +
    +

    一对锥透镜产生彩虹环

    +

    Peter Becher

    +
    +
    +
    + +   +

    渐变折射率光学

    + + + + + +
    +

    渐变折射率平板

    +

    Stas Fainer, Yi-Ting Tu

    +
    +
    + + + + + +
    +

    下蜃景

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    海市蜃楼

    +

    chuangyu J

    +
    +
    + + + + + +
    +

    等角螺线形的光线路径

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    龙勃透镜

    +

    Stas Fainer, Yi-Ting Tu

    +
    +
    + + + + + +
    +

    麦克斯韦鱼眼透镜

    +

    Stas Fainer, Yi-Ting Tu

    +
    +
    + + + + + +
    +

    分支流

    +

    Yi-Ting Tu

    +
    +
    +
    + +   +

    其他

    + + + + + +
    +

    单一光线演示

    +

    Yi-Ting Tu

    +
    +
    + + + + + +
    +

    球面透镜与面镜

    +

    Yi-Ting Tu

    +
    +
    + + + + + +
    +

    审讯室

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    暗箱

    +

    Stas Fainer

    +
    +
    + + + + + +
    +

    相机成像原理

    +

    Liu Quanhong

    +
    +
    + + + + + +
    +

    NL 双筒望远镜

    +

    Wen Zhou

    +
    +
    + + + + + +
    +

    经由目镜将爱因斯坦环重新聚焦为单一影像

    +

    Jordan Anderson

    +
    +
    + + + + + +
    +

    「黑猫变白猫」演示

    +

    Victory Science, Yi-Ting Tu

    +
    +
    + + + + + +
    +

    二色性RGB分光器与合光器

    +

    James Garrard

    +
    +
    + + + + + +
    +

    液晶显示器像素

    +

    James Garrard

    +
    +
    + + + + + +
    +

    凹面镜可穿戴显示器

    +

    Rene

    +
    +
    + + + + + +
    +

    反射式单色仪

    +

    James Garrard

    +
    +
    + + + + + +
    +

    日食

    +

    Yi-Ting Tu

    +
    +
    +
    + +
    + + + + \ No newline at end of file diff --git a/cn/gallery/inferior-mirage-thumbnail.avif b/cn/gallery/inferior-mirage-thumbnail.avif new file mode 100644 index 00000000..deeb8ac4 Binary files /dev/null and b/cn/gallery/inferior-mirage-thumbnail.avif differ diff --git a/cn/gallery/inferior-mirage-thumbnail.jpg b/cn/gallery/inferior-mirage-thumbnail.jpg new file mode 100644 index 00000000..bbaa127f Binary files /dev/null and b/cn/gallery/inferior-mirage-thumbnail.jpg differ diff --git a/cn/gallery/inferior-mirage.avif b/cn/gallery/inferior-mirage.avif new file mode 100644 index 00000000..5deedc7e Binary files /dev/null and b/cn/gallery/inferior-mirage.avif differ diff --git a/cn/gallery/inferior-mirage.html b/cn/gallery/inferior-mirage.html new file mode 100644 index 00000000..b95f8d35 --- /dev/null +++ b/cn/gallery/inferior-mirage.html @@ -0,0 +1,172 @@ + + + + + + + 下蜃景 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    下蜃景

    +

    + 贡献者:Stas Fainer +

    +
    +

    此为下蜃景效果的定性模拟。将天空的折射率模拟为 \(n(y)=\sqrt{1 + (\frac{y}{h})^2 }\),其中 \(h=600\) 代表太阳在地面以上的高度。

    +
    +

    + 在模拟器中打开 +

    + + + 下蜃景 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/inferior-mirage.jpg b/cn/gallery/inferior-mirage.jpg new file mode 100644 index 00000000..6df1ffa3 Binary files /dev/null and b/cn/gallery/inferior-mirage.jpg differ diff --git a/cn/gallery/inferior-mirage.json b/cn/gallery/inferior-mirage.json new file mode 100644 index 00000000..ad636088 --- /dev/null +++ b/cn/gallery/inferior-mirage.json @@ -0,0 +1,299 @@ +{ + "name": "下蜃景", + "version": 5, + "objs": [ + { + "type": "Ruler", + "p1": { + "x": 240, + "y": 1660 + }, + "p2": { + "x": 240, + "y": 1060 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 1760, + "y": 1360 + }, + "p2": { + "x": 1760, + "y": 1640 + }, + "focalLength": 180 + }, + { + "type": "Ruler", + "p1": { + "x": 240, + "y": 1000 + }, + "p2": { + "x": 240, + "y": 400 + } + }, + { + "type": "Blocker", + "p1": { + "x": 260, + "y": 1000 + }, + "p2": { + "x": 2180, + "y": 1000 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 1760, + "y": 700 + }, + "p2": { + "x": 1760, + "y": 980 + }, + "focalLength": "180" + }, + { + "type": "AngleSource", + "p1": { + "x": 320, + "y": 1060 + }, + "p2": { + "x": 791.9008264462811, + "y": 1206.1157024793388 + }, + "brightness": 1, + "emisAngle": "15" + }, + { + "type": "GrinGlass", + "path": [ + { + "x": 260, + "y": 380, + "arc": false + }, + { + "x": 260, + "y": 1000, + "arc": false + }, + { + "x": 2180, + "y": 1000, + "arc": false + }, + { + "x": 2180, + "y": 380, + "arc": false + } + ], + "refIndexFn": "\\sqrt{1+\\left(\\frac{y}{600}\\right)^2}", + "origin": { + "x": 260, + "y": 1000 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 320, + "y": 400 + }, + "p2": { + "x": 440, + "y": 520 + }, + "brightness": 1, + "emisAngle": 15 + }, + { + "type": "Blocker", + "p1": { + "x": 260, + "y": 380 + }, + "p2": { + "x": 260, + "y": 1000 + } + }, + { + "type": "Blocker", + "p1": { + "x": 260, + "y": 380 + }, + "p2": { + "x": 2180, + "y": 380 + } + }, + { + "type": "Blocker", + "p1": { + "x": 2180, + "y": 380 + }, + "p2": { + "x": 2180, + "y": 1000 + } + }, + { + "type": "Blocker", + "p1": { + "x": 260, + "y": 1660 + }, + "p2": { + "x": 2180, + "y": 1660 + } + }, + { + "type": "Blocker", + "p1": { + "x": 260, + "y": 1040 + }, + "p2": { + "x": 260, + "y": 1660 + } + }, + { + "type": "Blocker", + "p1": { + "x": 260, + "y": 1040 + }, + "p2": { + "x": 2180, + "y": 1040 + } + }, + { + "type": "Blocker", + "p1": { + "x": 2180, + "y": 1040 + }, + "p2": { + "x": 2180, + "y": 1660 + } + }, + { + "type": "Ruler", + "p1": { + "x": 2017, + "y": 840 + }, + "p2": { + "x": 2017, + "y": 740 + } + }, + { + "type": "Ruler", + "p1": { + "x": 1965, + "y": 1500 + }, + "p2": { + "x": 1965, + "y": 1600 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 1760, + "y": 666 + }, + "p2": { + "x": 1760, + "y": 686 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 1095.22469087333, + "y": 1152.997527429502, + "text": "空气(没有下蜃景效果)" + }, + { + "type": "TextLabel", + "x": 1096.6461784766357, + "y": 552.997527429502, + "text": "空气(有下蜃景效果)" + }, + { + "type": "TextLabel", + "x": 1274.4282514460556, + "y": 989.0955793479338, + "text": "地面", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 372.29176768061257, + "y": 415.70184882729745, + "text": "从物体发射或反射的光" + }, + { + "type": "TextLabel", + "x": 1766.390890452898, + "y": 659.3309605530451, + "text": "观察者的眼睛(非真实比例)", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 260, + "y": 360, + "text": "警告:光线出现的顺序并不代表实际的光速。只有最终的图像有意义。", + "fontSize": "37" + }, + { + "type": "CropBox", + "p1": { + "x": 173.95505169874787, + "y": 371.6825209493911 + }, + "p4": { + "x": 2213.955051698748, + "y": 1682.482520949391 + } + }, + { + "type": "CropBox", + "p1": { + "x": 285.95505169874787, + "y": 383.6825209493911 + }, + "p4": { + "x": 827.9550516987479, + "y": 925.6825209493911 + } + } + ], + "width": 3060, + "height": 2330.8, + "rayModeDensity": 1.4861665211342676, + "origin": { + "x": 336.04494830125213, + "y": 138.31747905060888 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/internal-reflection-thumbnail.avif b/cn/gallery/internal-reflection-thumbnail.avif new file mode 100644 index 00000000..554c8470 Binary files /dev/null and b/cn/gallery/internal-reflection-thumbnail.avif differ diff --git a/cn/gallery/internal-reflection-thumbnail.jpg b/cn/gallery/internal-reflection-thumbnail.jpg new file mode 100644 index 00000000..fb6d584a Binary files /dev/null and b/cn/gallery/internal-reflection-thumbnail.jpg differ diff --git a/cn/gallery/internal-reflection.avif b/cn/gallery/internal-reflection.avif new file mode 100644 index 00000000..26a61989 Binary files /dev/null and b/cn/gallery/internal-reflection.avif differ diff --git a/cn/gallery/internal-reflection.html b/cn/gallery/internal-reflection.html new file mode 100644 index 00000000..94b0c1c6 --- /dev/null +++ b/cn/gallery/internal-reflection.html @@ -0,0 +1,172 @@ + + + + + + + 全反射 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    全反射

    +

    + 贡献者:Paul Falstad +

    +
    +

    此模拟显示了光经过界面的折射和内部反射,包括全反射。

    +
    +

    + 在模拟器中打开 +

    + + + 全反射 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/internal-reflection.jpg b/cn/gallery/internal-reflection.jpg new file mode 100644 index 00000000..ba111feb Binary files /dev/null and b/cn/gallery/internal-reflection.jpg differ diff --git a/cn/gallery/internal-reflection.json b/cn/gallery/internal-reflection.json new file mode 100644 index 00000000..01315af9 --- /dev/null +++ b/cn/gallery/internal-reflection.json @@ -0,0 +1,64 @@ +{ + "name": "全反射", + "version": 5, + "objs": [ + { + "type": "PlaneGlass", + "p1": { + "x": 242.74, + "y": 559.1899999999999 + }, + "p2": { + "x": 702.7400000000002, + "y": 559.1899999999999 + }, + "refIndex": 2.5 + }, + { + "type": "PointSource", + "x": 406.348888658, + "y": 812.7033319319999 + }, + { + "type": "Protractor", + "p1": { + "x": 308.3388886580001, + "y": 559.1733319319999 + }, + "p2": { + "x": 308.3388886580001, + "y": 635.3133319319999 + } + }, + { + "type": "CropBox", + "p1": { + "x": -37.77411134199991, + "y": 447.182731932 + }, + "p4": { + "x": 845.0448886579998, + "y": 878.3133319319998 + } + }, + { + "type": "CropBox", + "p1": { + "x": 167.0748886580001, + "y": 468.6153319319999 + }, + "p4": { + "x": 543.9678886580002, + "y": 845.5083319319998 + } + } + ], + "width": 1324.2284999999997, + "height": 872.5400999999996, + "rayModeDensity": 0.13710612746686596, + "origin": { + "x": 258.47886134199985, + "y": -226.4779819320001 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/interrogation-room-thumbnail.avif b/cn/gallery/interrogation-room-thumbnail.avif new file mode 100644 index 00000000..524959cd Binary files /dev/null and b/cn/gallery/interrogation-room-thumbnail.avif differ diff --git a/cn/gallery/interrogation-room-thumbnail.jpg b/cn/gallery/interrogation-room-thumbnail.jpg new file mode 100644 index 00000000..256ccc14 Binary files /dev/null and b/cn/gallery/interrogation-room-thumbnail.jpg differ diff --git a/cn/gallery/interrogation-room.avif b/cn/gallery/interrogation-room.avif new file mode 100644 index 00000000..da816052 Binary files /dev/null and b/cn/gallery/interrogation-room.avif differ diff --git a/cn/gallery/interrogation-room.html b/cn/gallery/interrogation-room.html new file mode 100644 index 00000000..13cb56d9 --- /dev/null +++ b/cn/gallery/interrogation-room.html @@ -0,0 +1,172 @@ + + + + + + + 审讯室 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    审讯室

    +

    + 贡献者:Stas Fainer +

    +
    +

    这是一个审讯室双向镜的模拟。在黑暗的房间里的观察者(理想情况下,黑暗的房间内部不会发出/反射光,同时会吸收来自审讯室的所有入射光)能够通过双向镜看到审讯室内部,因为审讯室里的灯产生的光被散射并由观察者接收,而嫌疑人只能看到审讯室内部以及他/她和灯的反射(因为嫌疑人未从黑暗的房间接收到光)。

    +
    +

    + 在模拟器中打开 +

    + + + 审讯室 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/interrogation-room.jpg b/cn/gallery/interrogation-room.jpg new file mode 100644 index 00000000..670f4daf Binary files /dev/null and b/cn/gallery/interrogation-room.jpg differ diff --git a/cn/gallery/interrogation-room.json b/cn/gallery/interrogation-room.json new file mode 100644 index 00000000..d2ddf5fe --- /dev/null +++ b/cn/gallery/interrogation-room.json @@ -0,0 +1,275 @@ +{ + "name": "审讯室", + "version": 5, + "objs": [ + { + "type": "PointSource", + "x": 1240, + "y": 700, + "brightness": 1 + }, + { + "type": "Blocker", + "p1": { + "x": 1400, + "y": 640 + }, + "p2": { + "x": 1100, + "y": 640 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1400, + "y": 920 + }, + "p2": { + "x": 1100, + "y": 920 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1100, + "y": 640 + }, + "p2": { + "x": 1100, + "y": 920 + } + }, + { + "type": "BeamSplitter", + "p1": { + "x": 1401, + "y": 918 + }, + "p2": { + "x": 1401, + "y": 638 + }, + "transRatio": 0.56 + }, + { + "type": "Blocker", + "p1": { + "x": 1700, + "y": 920 + }, + "p2": { + "x": 1400, + "y": 920 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1700, + "y": 640 + }, + "p2": { + "x": 1700, + "y": 920 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1700, + "y": 640 + }, + "p2": { + "x": 1400, + "y": 640 + } + }, + { + "type": "Ruler", + "p1": { + "x": 1100, + "y": 980 + }, + "p2": { + "x": 1700, + "y": 980 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 1160, + "y": 800 + }, + "p2": { + "x": 1160, + "y": 820 + }, + "focalLength": "50" + }, + { + "type": "IdealLens", + "p1": { + "x": 1440, + "y": 800 + }, + "p2": { + "x": 1440, + "y": 820 + }, + "focalLength": "50" + }, + { + "type": "LineArrow", + "p1": { + "x": 1595, + "y": 700 + }, + "p2": { + "x": 1575, + "y": 700 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 1540, + "y": 847 + }, + "p2": { + "x": 1520, + "y": 847 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 1103, + "y": 857 + }, + "p2": { + "x": 1103, + "y": 837 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 1027.418181818182, + "y": 1023.9090909090909 + }, + "p2": { + "x": 1027.418181818182, + "y": 1003.9090909090909 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 691, + "y": 513.7142857142857, + "text": "按下“所有像”以查看\n灯的反射以及嫌疑人和观察者\n构成的的影像平面中物体的位置", + "fontSize": 20 + }, + { + "type": "TextLabel", + "x": 1555.3333333333328, + "y": 626.3333333333333, + "text": "黑暗的房间", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1400.0476190476193, + "y": 912.666666666667, + "text": "双向镜", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1206.0000000000002, + "y": 675.3333333333334, + "text": "灯" + }, + { + "type": "TextLabel", + "x": 1252.5714285714287, + "y": 627, + "text": "审讯室", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1443.0000000000002, + "y": 797.6666666666669, + "text": "观察者的眼睛" + }, + { + "type": "TextLabel", + "x": 1134.6000000000001, + "y": 790.6666666666667, + "text": "嫌疑人的眼睛" + }, + { + "type": "TextLabel", + "x": 1100.7368421052633, + "y": 882.9999999999999, + "text": "嫌疑人的影像平面中的灯物体", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1039.4210526315792, + "y": 1052, + "text": "嫌疑人的影像平面中的灯的反射", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1606, + "y": 711, + "text": "灯的反射" + }, + { + "type": "TextLabel", + "x": 1555, + "y": 859, + "text": "观察者的影像平面中的灯物体" + }, + { + "type": "CropBox", + "p1": { + "x": 569.6757339883194, + "y": 434.5817068576793 + }, + "p4": { + "x": 2238.9388918830564, + "y": 1103.0448647524163 + } + }, + { + "type": "CropBox", + "p1": { + "x": 1136.202049777793, + "y": 489.2659173839952 + }, + "p4": { + "x": 1672.4125764093724, + "y": 1025.476444383995 + } + } + ], + "width": 2503.894736842106, + "height": 1503.0947368421055, + "rayModeDensity": 20.085536923187668, + "origin": { + "x": -152.35994451463512, + "y": -17.26591738399503 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/keplerian-telescope-thumbnail.avif b/cn/gallery/keplerian-telescope-thumbnail.avif new file mode 100644 index 00000000..3bcd79bc Binary files /dev/null and b/cn/gallery/keplerian-telescope-thumbnail.avif differ diff --git a/cn/gallery/keplerian-telescope-thumbnail.jpg b/cn/gallery/keplerian-telescope-thumbnail.jpg new file mode 100644 index 00000000..44fcf7d3 Binary files /dev/null and b/cn/gallery/keplerian-telescope-thumbnail.jpg differ diff --git a/cn/gallery/keplerian-telescope.avif b/cn/gallery/keplerian-telescope.avif new file mode 100644 index 00000000..c67dd072 Binary files /dev/null and b/cn/gallery/keplerian-telescope.avif differ diff --git a/cn/gallery/keplerian-telescope.html b/cn/gallery/keplerian-telescope.html new file mode 100644 index 00000000..dd6eac9b --- /dev/null +++ b/cn/gallery/keplerian-telescope.html @@ -0,0 +1,170 @@ + + + + + + + 开普勒望远镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    开普勒望远镜

    +

    + 贡献者:chuangyu J +

    +
    +

    本模拟案例中描述了开普勒望远镜的光路图。

    +
    +

    + 在模拟器中打开 +

    + + + 开普勒望远镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/keplerian-telescope.jpg b/cn/gallery/keplerian-telescope.jpg new file mode 100644 index 00000000..ac6262d5 Binary files /dev/null and b/cn/gallery/keplerian-telescope.jpg differ diff --git a/cn/gallery/keplerian-telescope.json b/cn/gallery/keplerian-telescope.json new file mode 100644 index 00000000..533899ae --- /dev/null +++ b/cn/gallery/keplerian-telescope.json @@ -0,0 +1,275 @@ +{ + "name": "开普勒望远镜", + "version": 5, + "objs": [ + { + "type": "Ruler", + "p1": { + "x": 700, + "y": 580 + }, + "p2": { + "x": 1200, + "y": 580 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 706.6999999999999, + "y": 300 + }, + "p2": { + "x": 706.6999999999999, + "y": 860 + }, + "focalLength": "100" + }, + { + "type": "Blocker", + "p1": { + "x": 540, + "y": 540 + }, + "p2": { + "x": 540, + "y": 280 + } + }, + { + "type": "Blocker", + "p1": { + "x": 540, + "y": 280 + }, + "p2": { + "x": 1480, + "y": 280 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 899.9829059829063, + "y": 300.7700854700855 + }, + "p2": { + "x": 899.9829059829063, + "y": 860.7700854700854 + } + }, + { + "type": "Blocker", + "p1": { + "x": 540, + "y": 880 + }, + "p2": { + "x": 540, + "y": 620 + } + }, + { + "type": "Blocker", + "p1": { + "x": 540, + "y": 880 + }, + "p2": { + "x": 1480, + "y": 880 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1480, + "y": 880 + }, + "p2": { + "x": 1480, + "y": 280 + } + }, + { + "type": "Blocker", + "p1": { + "x": -760, + "y": 840 + }, + "p2": { + "x": -760, + "y": 840 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1240, + "y": 1180 + }, + "p2": { + "x": 1240, + "y": 1180 + } + }, + { + "type": "PointSource", + "x": -574.5214074255941, + "y": 306.6631034851275 + }, + { + "type": "PointSource", + "x": -593.8102963144827, + "y": 321.8472304692545 + }, + { + "type": "Ruler", + "p1": { + "x": -675.936641898722, + "y": 734.9270450990687 + }, + "p2": { + "x": -675.436641898722, + "y": 756.4270450990687 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 830.858649808155, + "y": 725.3830674405777 + }, + "p2": { + "x": 816.1842816222015, + "y": 613.1278553998783 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 362.1842816222015, + "y": 871.1278553998783 + }, + "p2": { + "x": 336.1842816222015, + "y": 731.1278553998783 + }, + "arrow": true + }, + { + "type": "Blocker", + "p1": { + "x": 1106.517614955535, + "y": 504.7945220665449 + }, + "p2": { + "x": 1196.517614955535, + "y": 526.7945220665449 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1198.517614955535, + "y": 527.7945220665449 + }, + "p2": { + "x": 1101.517614955535, + "y": 586.7945220665449 + } + }, + { + "type": "CircleBlocker", + "p1": { + "x": 1123.517614955535, + "y": 538.7945220665449 + }, + "p2": { + "x": 1129.517614955535, + "y": 551.7945220665449 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1103.517614955535, + "y": 486.7945220665449 + }, + "p2": { + "x": 1152.517614955535, + "y": 492.7945220665449 + } + }, + { + "type": "TextLabel", + "x": -518, + "y": 266, + "text": "来自星体的光", + "fontSize": 45 + }, + { + "type": "TextLabel", + "x": 351.3920551858034, + "y": 923.9538269761367, + "text": "虚像", + "fontSize": 45, + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 843.5459652653466, + "y": 782.0461730238629, + "text": "实像", + "fontSize": 45, + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1466.6634089702875, + "y": 858.6666666666663, + "text": "开普勒望远镜", + "fontSize": 45, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 1204, + "y": 499.9999999999998, + "text": "眼睛", + "fontSize": 45 + }, + { + "type": "CropBox", + "p1": { + "x": -830.9285620553803, + "y": 50.570057402717936 + }, + "p4": { + "x": 1646.2899141291648, + "y": 1139.7558480282262 + } + }, + { + "type": "CropBox", + "p1": { + "x": 173.66626864059478, + "y": -73.53784731141332 + }, + "p4": { + "x": 1519.7122003659963, + "y": 1272.508084413989 + } + } + ], + "width": 3715.8277142768175, + "height": 2327.795028717781, + "mode": "extended", + "rayModeDensity": 2.694196459062872, + "origin": { + "x": 1450.2331811015165, + "y": 568.7345616434184 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/lens-images-thumbnail.avif b/cn/gallery/lens-images-thumbnail.avif new file mode 100644 index 00000000..d7ef764f Binary files /dev/null and b/cn/gallery/lens-images-thumbnail.avif differ diff --git a/cn/gallery/lens-images-thumbnail.jpg b/cn/gallery/lens-images-thumbnail.jpg new file mode 100644 index 00000000..82407ad6 Binary files /dev/null and b/cn/gallery/lens-images-thumbnail.jpg differ diff --git a/cn/gallery/lens-images.avif b/cn/gallery/lens-images.avif new file mode 100644 index 00000000..76f47ba1 Binary files /dev/null and b/cn/gallery/lens-images.avif differ diff --git a/cn/gallery/lens-images.html b/cn/gallery/lens-images.html new file mode 100644 index 00000000..b18bd16f --- /dev/null +++ b/cn/gallery/lens-images.html @@ -0,0 +1,172 @@ + + + + + + + 透镜成像 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    透镜成像

    +

    + 贡献者:Paul Falstad +

    +
    +

    模拟理想透镜成像,包括平行光与点光源成的像。

    +
    +

    + 在模拟器中打开 +

    + + + 透镜成像 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/lens-images.jpg b/cn/gallery/lens-images.jpg new file mode 100644 index 00000000..c7509798 Binary files /dev/null and b/cn/gallery/lens-images.jpg differ diff --git a/cn/gallery/lens-images.json b/cn/gallery/lens-images.json new file mode 100644 index 00000000..37126e36 --- /dev/null +++ b/cn/gallery/lens-images.json @@ -0,0 +1,96 @@ +{ + "name": "透镜成像", + "version": 5, + "objs": [ + { + "type": "Beam", + "p1": { + "x": 169, + "y": 259 + }, + "p2": { + "x": 170, + "y": 433 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 660, + "y": 240 + }, + "p2": { + "x": 660, + "y": 460 + }, + "focalLength": 199 + }, + { + "type": "IdealLens", + "p1": { + "x": 660, + "y": 520 + }, + "p2": { + "x": 660, + "y": 760 + }, + "focalLength": 199 + }, + { + "type": "PointSource", + "x": 260, + "y": 560 + }, + { + "type": "PointSource", + "x": 260, + "y": 600 + }, + { + "type": "PointSource", + "x": 260, + "y": 640 + }, + { + "type": "Blocker", + "p1": { + "x": 40, + "y": 480 + }, + "p2": { + "x": 1700, + "y": 480 + } + }, + { + "type": "CropBox", + "p1": { + "x": -4.4419354838710206, + "y": 204.6193548387098 + }, + "p4": { + "x": 1267.1709677419353, + "y": 798.5032258064516 + } + }, + { + "type": "CropBox", + "p1": { + "x": 144.67829912023456, + "y": 50.84809384164248 + }, + "p4": { + "x": 1086.4847507331378, + "y": 992.6545458416425 + } + } + ], + "width": 1907.4193548387095, + "height": 1229.690322580645, + "origin": { + "x": 322.3451612903226, + "y": 113.28387096774179 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/logarithmic-spiral-lens-thumbnail.avif b/cn/gallery/logarithmic-spiral-lens-thumbnail.avif new file mode 100644 index 00000000..0bb6b7c7 Binary files /dev/null and b/cn/gallery/logarithmic-spiral-lens-thumbnail.avif differ diff --git a/cn/gallery/logarithmic-spiral-lens-thumbnail.jpg b/cn/gallery/logarithmic-spiral-lens-thumbnail.jpg new file mode 100644 index 00000000..ba8d1b5c Binary files /dev/null and b/cn/gallery/logarithmic-spiral-lens-thumbnail.jpg differ diff --git a/cn/gallery/logarithmic-spiral-lens.avif b/cn/gallery/logarithmic-spiral-lens.avif new file mode 100644 index 00000000..f861d77b Binary files /dev/null and b/cn/gallery/logarithmic-spiral-lens.avif differ diff --git a/cn/gallery/logarithmic-spiral-lens.html b/cn/gallery/logarithmic-spiral-lens.html new file mode 100644 index 00000000..95f82fbd --- /dev/null +++ b/cn/gallery/logarithmic-spiral-lens.html @@ -0,0 +1,172 @@ + + + + + + + 等角螺线形的光线路径 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    等角螺线形的光线路径

    +

    + 贡献者:Stas Fainer +

    +
    +

    能使光线路径呈现等角螺线形( \(r(θ) = r_0\,e^{-k\theta}\),其中\(r_0,k > 0\) 且\(\alpha = \arctan k\) 为等角螺线与同心圆形的交点上两切线的固定夹角,见这个动画)的折射率函数为\(n(r) &prop; \frac{1}{r} \) (这可用将光线路径以极座标表示并使用费马原理来证明)。

    +
    +

    + 在模拟器中打开 +

    + + + 等角螺线形的光线路径 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/logarithmic-spiral-lens.jpg b/cn/gallery/logarithmic-spiral-lens.jpg new file mode 100644 index 00000000..3a59ba20 Binary files /dev/null and b/cn/gallery/logarithmic-spiral-lens.jpg differ diff --git a/cn/gallery/logarithmic-spiral-lens.json b/cn/gallery/logarithmic-spiral-lens.json new file mode 100644 index 00000000..835a595c --- /dev/null +++ b/cn/gallery/logarithmic-spiral-lens.json @@ -0,0 +1,125 @@ +{ + "name": "等角螺线形的光线路径", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 261.40404469518285, + "y": 161.14412992729143 + }, + "p2": { + "x": -20, + "y": 140 + }, + "controlPoints": [ + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 3, + "newPoint": { + "x": -20, + "y": 140 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 3, + "newPoint": { + "x": -6.382663283384224, + "y": 140.8699339902433 + } + } + ], + "transformation": "rotation" + }, + { + "type": "CircleGrinGlass", + "p1": { + "x": 0, + "y": 0 + }, + "p2": { + "x": 200, + "y": 0 + }, + "refIndexFn": "\\frac{1}{\\sqrt{x^2+y^2}}", + "stepSize": 0.5 + }, + { + "type": "CircleBlocker", + "p1": { + "x": 0, + "y": 0 + }, + "p2": { + "x": 10, + "y": 0 + } + }, + { + "type": "SingleRay", + "p1": { + "x": -20, + "y": 140 + }, + "p2": { + "x": -6.382663283384224, + "y": 140.8699339902433 + } + }, + { + "type": "TextLabel", + "x": -168, + "y": -237.375, + "text": "中央的圆形遮光物是为了\n避开折射率的奇异点", + "fontSize": 18 + }, + { + "type": "TextLabel", + "x": 283.71121951219516, + "y": 161.58048780487803, + "text": "拖动此处可改变\n光线的初始方向", + "fontSize": 18 + }, + { + "type": "TextLabel", + "x": 211.54878048780483, + "y": -111.3109756097561, + "text": "您可以选择渐变折射率透光物\n并更改数值求解器的步长", + "fontSize": 18 + }, + { + "type": "CropBox", + "p1": { + "x": -430.20754067067077, + "y": -284.4151383653915 + }, + "p4": { + "x": 703.7924593293293, + "y": 262.33486163460856 + } + }, + { + "type": "CropBox", + "p1": { + "x": -206.33254067067077, + "y": -204.99013836539143 + }, + "p4": { + "x": 205.41745932932923, + "y": 206.75986163460857 + } + } + ], + "width": 1701, + "height": 1113.75, + "origin": { + "x": 713.7075406706708, + "y": 567.9151383653915 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/luneburg-lens-thumbnail.avif b/cn/gallery/luneburg-lens-thumbnail.avif new file mode 100644 index 00000000..c842484b Binary files /dev/null and b/cn/gallery/luneburg-lens-thumbnail.avif differ diff --git a/cn/gallery/luneburg-lens-thumbnail.jpg b/cn/gallery/luneburg-lens-thumbnail.jpg new file mode 100644 index 00000000..077940ad Binary files /dev/null and b/cn/gallery/luneburg-lens-thumbnail.jpg differ diff --git a/cn/gallery/luneburg-lens.avif b/cn/gallery/luneburg-lens.avif new file mode 100644 index 00000000..3f15589f Binary files /dev/null and b/cn/gallery/luneburg-lens.avif differ diff --git a/cn/gallery/luneburg-lens.html b/cn/gallery/luneburg-lens.html new file mode 100644 index 00000000..f1cfd7bb --- /dev/null +++ b/cn/gallery/luneburg-lens.html @@ -0,0 +1,174 @@ + + + + + + + 龙勃透镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    龙勃透镜

    +

    + 贡献者:Stas Fainer, Yi-Ting Tu +

    +
    +

    龙勃透镜(Luneburg lens)是一个球形介电材料,折射率为 \(n(\rho) = \sqrt{n_0-(\frac{\rho}{R})^2} \),其中 \(n_0=2\) 是其球心的折射率,\(R=100\) 是球的半径,\(\rho\) 是与球心的距离。

    +

    上方的介电材料为由 \(N=20\) 个同心球组成的龙勃透镜,半径 \(R_i=5(N+1-i)\),折射率 \(n_i = \sqrt{n_0-(\frac{R_i}{R})^2} \),其中 \(i=1,...,N\)。然而,由于此模拟器会将互相重叠的光学元件的折射率相乘,所以第 \(i\) 个同心球形镜的数值折射率为 \(n_{i}^\text{numerical}=\frac{n_i}{n_{i-1}}\)。

    +

    下方的介电材料是折射率为\(n(r)\)的渐变折射率材料。

    +
    +

    + 在模拟器中打开 +

    + + + 龙勃透镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/luneburg-lens.jpg b/cn/gallery/luneburg-lens.jpg new file mode 100644 index 00000000..27d816d8 Binary files /dev/null and b/cn/gallery/luneburg-lens.jpg differ diff --git a/cn/gallery/luneburg-lens.json b/cn/gallery/luneburg-lens.json new file mode 100644 index 00000000..3b827bd3 --- /dev/null +++ b/cn/gallery/luneburg-lens.json @@ -0,0 +1,157 @@ +{ + "name": "龙勃透镜", + "version": 5, + "modules": { + "ApproxLuneburg": { + "numPoints": 1, + "params": [ + "N=1:1:50:20", + "R=1:1:200:100", + "n_0=1:0.01:3:2" + ], + "objs": [ + { + "for": "i=2:1:N", + "type": "CircleGlass", + "p1": { + "x": "`x_1`", + "y": "`y_1`" + }, + "p2": { + "x": "`x_1+R/N*(N+1-i)`", + "y": "`y_1`" + }, + "refIndex": "`(n_0-((1/N*(1+N-i)))^2)^0.5/(n_0-((1/N*(1+N-(i-1))))^2)^0.5`" + } + ] + } + }, + "objs": [ + { + "type": "Ruler", + "p1": { + "x": 500, + "y": 480 + }, + "p2": { + "x": 700, + "y": 480 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 500, + "y": 840 + }, + "p2": { + "x": 780, + "y": 840 + }, + "emisAngle": 30 + }, + { + "type": "Ruler", + "p1": { + "x": 500, + "y": 840 + }, + "p2": { + "x": 700, + "y": 840 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 500, + "y": 480 + }, + "p2": { + "x": 780, + "y": 480 + }, + "emisAngle": 30 + }, + { + "type": "CircleGrinGlass", + "p1": { + "x": 600, + "y": 840 + }, + "p2": { + "x": 700, + "y": 840 + }, + "refIndexFn": "\\sqrt{2-\\frac{\\left(x^2+y^2\\right)}{100^2}}", + "origin": { + "x": 600, + "y": 840 + }, + "stepSize": 0.1 + }, + { + "type": "ModuleObj", + "module": "ApproxLuneburg", + "points": [ + { + "x": 600, + "y": 480 + } + ], + "params": { + "N": 20, + "R": 100, + "n_0": 2 + } + }, + { + "type": "TextLabel", + "x": 493.7745058576679, + "y": 595.2707590443969, + "text": "用多层近似的龙勃透镜(您可以选择并更改层数 N)" + }, + { + "type": "TextLabel", + "x": 487.95264788835954, + "y": 977.1783458250111, + "text": "正统的龙勃透镜(您可以选择并更改数值求解器的步长)" + }, + { + "type": "TextLabel", + "x": 414.3263157894738, + "y": 300.95087719298243, + "text": "警告:光线出现的顺序并不代表实际的光速。只有最终的图像有意义。", + "fontSize": 37 + }, + { + "type": "CropBox", + "p1": { + "x": 461.07665108717765, + "y": 346.3583959899747 + }, + "p4": { + "x": 1975.1729323308275, + "y": 1014.8215538847111 + } + }, + { + "type": "CropBox", + "p1": { + "x": 492.16240601503773, + "y": 732.6952380952379 + }, + "p4": { + "x": 708.1624060150378, + "y": 948.6952380952379 + } + } + ], + "width": 2271.1444218654747, + "height": 1425.5112985165613, + "origin": { + "x": -82.55258077626519, + "y": 32.16567432093774 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/maxwell-fisheye-lens-thumbnail.avif b/cn/gallery/maxwell-fisheye-lens-thumbnail.avif new file mode 100644 index 00000000..f81850ff Binary files /dev/null and b/cn/gallery/maxwell-fisheye-lens-thumbnail.avif differ diff --git a/cn/gallery/maxwell-fisheye-lens-thumbnail.jpg b/cn/gallery/maxwell-fisheye-lens-thumbnail.jpg new file mode 100644 index 00000000..e7a3360b Binary files /dev/null and b/cn/gallery/maxwell-fisheye-lens-thumbnail.jpg differ diff --git a/cn/gallery/maxwell-fisheye-lens.avif b/cn/gallery/maxwell-fisheye-lens.avif new file mode 100644 index 00000000..26ac3843 Binary files /dev/null and b/cn/gallery/maxwell-fisheye-lens.avif differ diff --git a/cn/gallery/maxwell-fisheye-lens.html b/cn/gallery/maxwell-fisheye-lens.html new file mode 100644 index 00000000..3067e695 --- /dev/null +++ b/cn/gallery/maxwell-fisheye-lens.html @@ -0,0 +1,174 @@ + + + + + + + 麦克斯韦鱼眼透镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    麦克斯韦鱼眼透镜

    +

    + 贡献者:Stas Fainer, Yi-Ting Tu +

    +
    +

    麦克斯韦鱼眼透镜(Maxwell fisheye lens)是一个球形介电材料,折射率为 \(n(\rho) = \frac{n_0}{1+(\frac{\rho}{R})^2} \),其中 \(n_0=2\) 是其球心的折射率,\(R=100\) 是球的半径,\(\rho\) 是与球心的距离。

    +

    上方的介电材料为由 \(N=20\) 个同心球组成的麦克斯韦鱼眼透镜,半径 \(R_i=5(N+1-i)\),折射率 \(n_i = \frac{n_0}{1+(\frac{R_i}{R})^2} \),其中 \(i=1,...,N\)。然而,由于此模拟器会将互相重叠的光学元件的折射率相乘,所以第 \(i\) 个同心球形镜的数值折射率为 \(n_{i}^\text{numerical}=\frac{n_i}{n_{i-1}}\)。

    +

    下方的介电材料是折射率为\(n(r)\)的渐变折射率材料。

    +
    +

    + 在模拟器中打开 +

    + + + 麦克斯韦鱼眼透镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/maxwell-fisheye-lens.jpg b/cn/gallery/maxwell-fisheye-lens.jpg new file mode 100644 index 00000000..ad0e66f1 Binary files /dev/null and b/cn/gallery/maxwell-fisheye-lens.jpg differ diff --git a/cn/gallery/maxwell-fisheye-lens.json b/cn/gallery/maxwell-fisheye-lens.json new file mode 100644 index 00000000..7d392b0b --- /dev/null +++ b/cn/gallery/maxwell-fisheye-lens.json @@ -0,0 +1,168 @@ +{ + "name": "麦克斯韦鱼眼透镜", + "version": 5, + "modules": { + "ApproxFisheye": { + "numPoints": 1, + "params": [ + "N=1:1:50:20", + "R=1:1:200:100", + "n_0=1:0.01:3:2" + ], + "objs": [ + { + "for": "i=2:1:N", + "type": "CircleGlass", + "p1": { + "x": "`x_1`", + "y": "`y_1`" + }, + "p2": { + "x": "`x_1+R/N*(N+1-i)`", + "y": "`y_1`" + }, + "refIndex": "`(n_0/(1+((1/N*(1+N-i)))^2))/(n_0/(1+((1/N*(1+N-(i-1))))^2))`" + } + ] + } + }, + "objs": [ + { + "type": "Ruler", + "p1": { + "x": 500, + "y": 480 + }, + "p2": { + "x": 700, + "y": 480 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 500, + "y": 840 + }, + "p2": { + "x": 780, + "y": 840 + }, + "emisAngle": 30 + }, + { + "type": "Ruler", + "p1": { + "x": 500, + "y": 840 + }, + "p2": { + "x": 700, + "y": 840 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 500, + "y": 480 + }, + "p2": { + "x": 780, + "y": 480 + }, + "emisAngle": 30 + }, + { + "type": "CircleGrinGlass", + "p1": { + "x": 600, + "y": 840 + }, + "p2": { + "x": 700, + "y": 840 + }, + "refIndexFn": "\\frac{2}{1+\\frac{x^2+y^2}{100^2}}", + "origin": { + "x": 600, + "y": 840 + }, + "stepSize": 0.1 + }, + { + "type": "Blocker", + "p1": { + "x": 483.813493192441, + "y": 671.6842105263157 + }, + "p2": { + "x": 1959.0436846097498, + "y": 671.6842105263157 + } + }, + { + "type": "ModuleObj", + "module": "ApproxFisheye", + "points": [ + { + "x": 600, + "y": 480 + } + ], + "params": { + "N": 20, + "R": 100, + "n_0": 2 + } + }, + { + "type": "TextLabel", + "x": 493.7745058576679, + "y": 595.2707590443969, + "text": "用多层近似的麦克斯韦鱼眼透镜(您可以选择并更改层数 N)" + }, + { + "type": "TextLabel", + "x": 487.95264788835954, + "y": 977.1783458250111, + "text": "正统的麦克斯韦鱼眼透镜(您可以选择并更改数值求解器的步长)" + }, + { + "type": "TextLabel", + "x": 414.3263157894738, + "y": 300.95087719298243, + "text": "警告:光线出现的顺序并不代表实际的光速。只有最终的图像有意义。", + "fontSize": 37 + }, + { + "type": "CropBox", + "p1": { + "x": 461.07665108717765, + "y": 346.3583959899747 + }, + "p4": { + "x": 1975.1729323308275, + "y": 1014.8215538847111 + } + }, + { + "type": "CropBox", + "p1": { + "x": 492.16240601503773, + "y": 732.6952380952379 + }, + "p4": { + "x": 708.1624060150378, + "y": 948.6952380952379 + } + } + ], + "width": 2271.1444218654747, + "height": 1425.5112985165613, + "origin": { + "x": -82.55258077626519, + "y": 32.16567432093774 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/maze-solution-thumbnail.avif b/cn/gallery/maze-solution-thumbnail.avif new file mode 100644 index 00000000..6f62aadd Binary files /dev/null and b/cn/gallery/maze-solution-thumbnail.avif differ diff --git a/cn/gallery/maze-solution-thumbnail.jpg b/cn/gallery/maze-solution-thumbnail.jpg new file mode 100644 index 00000000..1927f92f Binary files /dev/null and b/cn/gallery/maze-solution-thumbnail.jpg differ diff --git a/cn/gallery/maze-solution.avif b/cn/gallery/maze-solution.avif new file mode 100644 index 00000000..658e37de Binary files /dev/null and b/cn/gallery/maze-solution.avif differ diff --git a/cn/gallery/maze-solution.html b/cn/gallery/maze-solution.html new file mode 100644 index 00000000..3fcaf663 --- /dev/null +++ b/cn/gallery/maze-solution.html @@ -0,0 +1,172 @@ + + + + + + + 用一条光线解迷宫 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    用一条光线解迷宫

    +

    + 贡献者:Stas Fainer, Yi-Ting Tu +

    +
    +

    此模拟中,一条光线在迷宫内部产生,并被墙壁多次反射。迷宫内的大红色和小红色正方形(如下面的截图所示)分别代表光线的起源和初始方向。取决于光线初始方向,光线可能最终会离开迷宫,因此原则上可以通过追踪光线的路径计算出迷宫的解法。

    +
    +

    + 在模拟器中打开 +

    + + + 用一条光线解迷宫 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/maze-solution.jpg b/cn/gallery/maze-solution.jpg new file mode 100644 index 00000000..9b38b84f Binary files /dev/null and b/cn/gallery/maze-solution.jpg differ diff --git a/cn/gallery/maze-solution.json b/cn/gallery/maze-solution.json new file mode 100644 index 00000000..0d0a4dc7 --- /dev/null +++ b/cn/gallery/maze-solution.json @@ -0,0 +1,1347 @@ +{ + "name": "用一条光线解迷宫", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 300, + "y": 597 + }, + "p2": { + "x": 847.7103992768032, + "y": 644.2931549915269 + }, + "controlPoints": [ + { + "newPoint": { + "x": 847.7103992768032, + "y": 644.2931549915269 + }, + "targetObjIndex": 114, + "dragContext": { + "part": 2 + } + } + ], + "transformation": "translation" + }, + { + "type": "Handle", + "p1": { + "x": 300, + "y": 527.6360528360532 + }, + "p2": { + "x": 840.4000000000004, + "y": 625.4095238095238 + }, + "controlPoints": [ + { + "newPoint": { + "x": 840.4000000000004, + "y": 625.4095238095238 + }, + "targetObjIndex": 114, + "dragContext": { + "part": 1 + } + } + ], + "transformation": "translation" + }, + { + "type": "Mirror", + "p1": { + "x": 520, + "y": 320 + }, + "p2": { + "x": 1420, + "y": 320 + } + }, + { + "type": "Mirror", + "p1": { + "x": 520, + "y": 1220 + }, + "p2": { + "x": 520, + "y": 320 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1420, + "y": 1220 + }, + "p2": { + "x": 520, + "y": 1220 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1420, + "y": 920 + }, + "p2": { + "x": 1420, + "y": 1220 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1420, + "y": 860 + }, + "p2": { + "x": 1420, + "y": 320 + } + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 1180 + }, + "p2": { + "x": 560, + "y": 1220 + } + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 1060 + }, + "p2": { + "x": 520, + "y": 1060 + } + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 1120 + }, + "p2": { + "x": 560, + "y": 1060 + } + }, + { + "type": "Mirror", + "p1": { + "x": 640, + "y": 1120 + }, + "p2": { + "x": 560, + "y": 1120 + } + }, + { + "type": "Mirror", + "p1": { + "x": 640, + "y": 1180 + }, + "p2": { + "x": 640, + "y": 1120 + } + }, + { + "type": "Mirror", + "p1": { + "x": 600, + "y": 1180 + }, + "p2": { + "x": 640, + "y": 1180 + } + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 1020 + }, + "p2": { + "x": 520, + "y": 1020 + } + }, + { + "type": "Mirror", + "p1": { + "x": 640, + "y": 980 + }, + "p2": { + "x": 520, + "y": 980 + } + }, + { + "type": "Mirror", + "p1": { + "x": 600, + "y": 1060 + }, + "p2": { + "x": 600, + "y": 980 + } + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 460 + }, + "p2": { + "x": 520, + "y": 460 + } + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 360 + }, + "p2": { + "x": 560, + "y": 460 + } + }, + { + "type": "Mirror", + "p1": { + "x": 760, + "y": 360 + }, + "p2": { + "x": 560, + "y": 360 + } + }, + { + "type": "Mirror", + "p1": { + "x": 800, + "y": 360 + }, + "p2": { + "x": 880, + "y": 360 + } + }, + { + "type": "Mirror", + "p1": { + "x": 840, + "y": 400 + }, + "p2": { + "x": 840, + "y": 360 + } + }, + { + "type": "Mirror", + "p1": { + "x": 840, + "y": 400 + }, + "p2": { + "x": 600, + "y": 400 + } + }, + { + "type": "Mirror", + "p1": { + "x": 600, + "y": 500 + }, + "p2": { + "x": 600, + "y": 400 + } + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 500 + }, + "p2": { + "x": 600, + "y": 500 + } + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 540 + }, + "p2": { + "x": 560, + "y": 500 + } + }, + { + "type": "Mirror", + "p1": { + "x": 840, + "y": 440 + }, + "p2": { + "x": 600, + "y": 440 + } + }, + { + "type": "Mirror", + "p1": { + "x": 760, + "y": 500 + }, + "p2": { + "x": 760, + "y": 440 + } + }, + { + "type": "Mirror", + "p1": { + "x": 840, + "y": 580 + }, + "p2": { + "x": 840, + "y": 440 + } + }, + { + "type": "Mirror", + "p1": { + "x": 800, + "y": 580 + }, + "p2": { + "x": 840, + "y": 580 + } + }, + { + "type": "Mirror", + "p1": { + "x": 800, + "y": 500 + }, + "p2": { + "x": 800, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 680, + "y": 540 + }, + "p2": { + "x": 800, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 720, + "y": 500 + }, + "p2": { + "x": 720, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 680, + "y": 500 + }, + "p2": { + "x": 680, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 600, + "y": 540 + }, + "p2": { + "x": 680, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 600, + "y": 580 + }, + "p2": { + "x": 600, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 520, + "y": 580 + }, + "p2": { + "x": 600, + "y": 580 + } + }, + { + "type": "Mirror", + "p1": { + "x": 720, + "y": 580 + }, + "p2": { + "x": 720, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 760, + "y": 660 + }, + "p2": { + "x": 760, + "y": 740 + } + }, + { + "type": "Mirror", + "p1": { + "x": 680, + "y": 660 + }, + "p2": { + "x": 1000, + "y": 660 + } + }, + { + "type": "Mirror", + "p1": { + "x": 760, + "y": 580 + }, + "p2": { + "x": 760, + "y": 660 + } + }, + { + "type": "Mirror", + "p1": { + "x": 680, + "y": 580 + }, + "p2": { + "x": 680, + "y": 840 + } + }, + { + "type": "Mirror", + "p1": { + "x": 720, + "y": 1060 + }, + "p2": { + "x": 720, + "y": 1220 + } + }, + { + "type": "Mirror", + "p1": { + "x": 680, + "y": 1060 + }, + "p2": { + "x": 760, + "y": 1060 + } + }, + { + "type": "Mirror", + "p1": { + "x": 720, + "y": 840 + }, + "p2": { + "x": 680, + "y": 840 + } + }, + { + "type": "Mirror", + "p1": { + "x": 720, + "y": 740 + }, + "p2": { + "x": 720, + "y": 1020 + } + }, + { + "type": "Mirror", + "p1": { + "x": 680, + "y": 1020 + }, + "p2": { + "x": 680, + "y": 1060 + } + }, + { + "type": "Mirror", + "p1": { + "x": 720, + "y": 1020 + }, + "p2": { + "x": 680, + "y": 1020 + } + }, + { + "type": "Mirror", + "p1": { + "x": 760, + "y": 840 + }, + "p2": { + "x": 760, + "y": 1060 + } + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 760 + }, + "p2": { + "x": 560, + "y": 940 + } + }, + { + "type": "Mirror", + "p1": { + "x": 600, + "y": 940 + }, + "p2": { + "x": 560, + "y": 940 + } + }, + { + "type": "Mirror", + "p1": { + "x": 600, + "y": 580 + }, + "p2": { + "x": 600, + "y": 940 + } + }, + { + "type": "Mirror", + "p1": { + "x": 800, + "y": 840 + }, + "p2": { + "x": 760, + "y": 840 + } + }, + { + "type": "Mirror", + "p1": { + "x": 800, + "y": 740 + }, + "p2": { + "x": 800, + "y": 840 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1000, + "y": 1020 + }, + "p2": { + "x": 760, + "y": 1020 + } + }, + { + "type": "Mirror", + "p1": { + "x": 800, + "y": 980 + }, + "p2": { + "x": 800, + "y": 1020 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1000, + "y": 980 + }, + "p2": { + "x": 1000, + "y": 1020 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1060, + "y": 400 + }, + "p2": { + "x": 1060, + "y": 320 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1020, + "y": 400 + }, + "p2": { + "x": 1060, + "y": 400 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1020, + "y": 440 + }, + "p2": { + "x": 1020, + "y": 400 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1100, + "y": 440 + }, + "p2": { + "x": 1020, + "y": 440 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1100, + "y": 360 + }, + "p2": { + "x": 1100, + "y": 440 + } + }, + { + "type": "Mirror", + "p1": { + "x": 760, + "y": 1180 + }, + "p2": { + "x": 1080, + "y": 1180 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1000, + "y": 1140 + }, + "p2": { + "x": 1000, + "y": 1180 + } + }, + { + "type": "Mirror", + "p1": { + "x": 760, + "y": 1140 + }, + "p2": { + "x": 760, + "y": 1180 + } + }, + { + "type": "Mirror", + "p1": { + "x": 960, + "y": 1140 + }, + "p2": { + "x": 760, + "y": 1140 + } + }, + { + "type": "Mirror", + "p1": { + "x": 960, + "y": 1100 + }, + "p2": { + "x": 960, + "y": 1140 + } + }, + { + "type": "Mirror", + "p1": { + "x": 800, + "y": 1100 + }, + "p2": { + "x": 1040, + "y": 1100 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1040, + "y": 1140 + }, + "p2": { + "x": 1040, + "y": 940 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1000, + "y": 940 + }, + "p2": { + "x": 1040, + "y": 940 + } + }, + { + "type": "Mirror", + "p1": { + "x": 960, + "y": 980 + }, + "p2": { + "x": 960, + "y": 660 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1000, + "y": 620 + }, + "p2": { + "x": 1000, + "y": 700 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1120, + "y": 1140 + }, + "p2": { + "x": 1040, + "y": 1140 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1080, + "y": 1100 + }, + "p2": { + "x": 1080, + "y": 1140 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1120, + "y": 1180 + }, + "p2": { + "x": 1120, + "y": 1140 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 1180 + }, + "p2": { + "x": 1120, + "y": 1180 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1340, + "y": 1140 + }, + "p2": { + "x": 1340, + "y": 1180 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1040, + "y": 1060 + }, + "p2": { + "x": 1160, + "y": 1060 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1120, + "y": 1100 + }, + "p2": { + "x": 1120, + "y": 1060 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1160, + "y": 1140 + }, + "p2": { + "x": 1160, + "y": 1060 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 1100 + }, + "p2": { + "x": 1380, + "y": 1180 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1340, + "y": 1100 + }, + "p2": { + "x": 1380, + "y": 1100 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1340, + "y": 1060 + }, + "p2": { + "x": 1420, + "y": 1060 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1040, + "y": 620 + }, + "p2": { + "x": 1000, + "y": 620 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1040, + "y": 540 + }, + "p2": { + "x": 1040, + "y": 620 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1080, + "y": 700 + }, + "p2": { + "x": 1000, + "y": 700 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1080, + "y": 660 + }, + "p2": { + "x": 1080, + "y": 740 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1040, + "y": 660 + }, + "p2": { + "x": 1080, + "y": 660 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1080, + "y": 620 + }, + "p2": { + "x": 1220, + "y": 620 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1000, + "y": 540 + }, + "p2": { + "x": 840, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1000, + "y": 500 + }, + "p2": { + "x": 1000, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 500 + }, + "p2": { + "x": 1000, + "y": 500 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 460 + }, + "p2": { + "x": 1340, + "y": 460 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1340, + "y": 460 + }, + "p2": { + "x": 1340, + "y": 500 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1240, + "y": 500 + }, + "p2": { + "x": 1240, + "y": 320 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1340, + "y": 360 + }, + "p2": { + "x": 1340, + "y": 320 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 360 + }, + "p2": { + "x": 1340, + "y": 360 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1280, + "y": 400 + }, + "p2": { + "x": 1420, + "y": 400 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1280, + "y": 360 + }, + "p2": { + "x": 1280, + "y": 440 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1180, + "y": 540 + }, + "p2": { + "x": 1180, + "y": 500 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1220, + "y": 540 + }, + "p2": { + "x": 1220, + "y": 960 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1260, + "y": 680 + }, + "p2": { + "x": 1220, + "y": 680 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 960 + }, + "p2": { + "x": 1040, + "y": 960 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 900 + }, + "p2": { + "x": 1380, + "y": 860 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 860 + }, + "p2": { + "x": 1420, + "y": 860 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1340, + "y": 580 + }, + "p2": { + "x": 1340, + "y": 960 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1300, + "y": 580 + }, + "p2": { + "x": 1340, + "y": 580 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 540 + }, + "p2": { + "x": 1220, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 580 + }, + "p2": { + "x": 1380, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1420, + "y": 580 + }, + "p2": { + "x": 1380, + "y": 580 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1180, + "y": 580 + }, + "p2": { + "x": 1220, + "y": 580 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1380, + "y": 680 + }, + "p2": { + "x": 1340, + "y": 680 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1300, + "y": 860 + }, + "p2": { + "x": 1340, + "y": 860 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1300, + "y": 900 + }, + "p2": { + "x": 1300, + "y": 860 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1340, + "y": 1000 + }, + "p2": { + "x": 1340, + "y": 1060 + } + }, + { + "type": "SingleRay", + "p1": { + "x": 840.4000000000004, + "y": 625.4095238095238 + }, + "p2": { + "x": 847.7103992768032, + "y": 644.2931549915269 + }, + "brightness": "1" + }, + { + "type": "TextLabel", + "x": 258.1664668664671, + "y": 548.4446553446539, + "text": "通过分别拖曳此两标记\n以调整光线的初始点与方向。", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": -357.16660006660015, + "y": 1125.5819402819402, + "text": "请注意,只有当左下角的“处理中…”\n消失时,才代表模拟完成。" + }, + { + "type": "TextLabel", + "x": 1443.2311388776352, + "y": 953.0278131289024, + "text": "迷宫出口" + }, + { + "type": "CropBox", + "p1": { + "x": -424.72703962703986, + "y": 273.4808413808418 + }, + "p4": { + "x": 1700.9872460872461, + "y": 1255.766555666556 + } + }, + { + "type": "CropBox", + "p1": { + "x": 486.9872460872461, + "y": 297.76655566655603 + }, + "p4": { + "x": 1436.9872460872461, + "y": 1247.766555666556 + } + } + ], + "width": 3188.5714285714294, + "height": 2045.1428571428573, + "rayModeDensity": 0.10000000000000002, + "origin": { + "x": 956.1556110556114, + "y": 257.94773004772975 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/minimum-deviation-angle-thumbnail.avif b/cn/gallery/minimum-deviation-angle-thumbnail.avif new file mode 100644 index 00000000..d3da42e9 Binary files /dev/null and b/cn/gallery/minimum-deviation-angle-thumbnail.avif differ diff --git a/cn/gallery/minimum-deviation-angle-thumbnail.jpg b/cn/gallery/minimum-deviation-angle-thumbnail.jpg new file mode 100644 index 00000000..c1939b9a Binary files /dev/null and b/cn/gallery/minimum-deviation-angle-thumbnail.jpg differ diff --git a/cn/gallery/minimum-deviation-angle.avif b/cn/gallery/minimum-deviation-angle.avif new file mode 100644 index 00000000..159a80cd Binary files /dev/null and b/cn/gallery/minimum-deviation-angle.avif differ diff --git a/cn/gallery/minimum-deviation-angle.html b/cn/gallery/minimum-deviation-angle.html new file mode 100644 index 00000000..f636ab83 --- /dev/null +++ b/cn/gallery/minimum-deviation-angle.html @@ -0,0 +1,172 @@ + + + + + + + 最小偏向角 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    最小偏向角

    +

    + 贡献者:Stas Fainer +

    +
    +

    光线射到光学元件上的偏向角有多种定义。下方的截图中可以看到对于三棱镜和球形透镜的定义。在本模拟中,光线进入光学元件的入射角与偏向角之间的关系在某个角度有局部极小值,这个偏向角被称为“最小偏向角”。这个局部极小值可以解释如彩虹和光晕这样的光学现象。由于这个局部极小值,偏转的光线在特定的方向上堆积,产生“光学焦散”(如在模拟中的例子C中看到的)我们会将其视为彩虹/光晕。

    +
    +

    + 在模拟器中打开 +

    + + + 最小偏向角 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/minimum-deviation-angle.jpg b/cn/gallery/minimum-deviation-angle.jpg new file mode 100644 index 00000000..df60cd6f Binary files /dev/null and b/cn/gallery/minimum-deviation-angle.jpg differ diff --git a/cn/gallery/minimum-deviation-angle.json b/cn/gallery/minimum-deviation-angle.json new file mode 100644 index 00000000..eeceab9d --- /dev/null +++ b/cn/gallery/minimum-deviation-angle.json @@ -0,0 +1,948 @@ +{ + "name": "最小偏向角", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 1814.398444996955, + "y": 553.3782429379147 + }, + "p2": { + "x": 1721.0344186772975, + "y": 399.9520292916584 + }, + "controlPoints": [ + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 21, + "newPoint": { + "x": 1751.7473931629236, + "y": 450.81557088403065 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 21, + "newPoint": { + "x": 1783.3588603725555, + "y": 501.51041648670116 + } + }, + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 30, + "newPoint": { + "x": 1720.7904404729272, + "y": 400.66217779106074 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 30, + "newPoint": { + "x": 1557.1819092415824, + "y": 137.28785288262856 + } + } + ], + "transformation": "rotation" + }, + { + "type": "Handle", + "p1": { + "x": 839.3704194886167, + "y": 415.9625522948089 + }, + "p2": { + "x": 779.734304738948, + "y": 399.9256990859164 + }, + "controlPoints": [ + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 26, + "newPoint": { + "x": 780.1829303320025, + "y": 399.8138490018858 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 26, + "newPoint": { + "x": 609.68684045716, + "y": 79.1068061353044 + } + }, + { + "dragContext": { + "part": 1, + "index": 0 + }, + "targetObjIndex": 4, + "newPoint": { + "x": 738.9476835979258, + "y": 421.64699964155176 + } + }, + { + "dragContext": { + "part": 1, + "index": 1 + }, + "targetObjIndex": 4, + "newPoint": { + "x": 806.7667118772957, + "y": 464.0802342960355 + } + }, + { + "dragContext": { + "part": 1, + "index": 2 + }, + "targetObjIndex": 4, + "newPoint": { + "x": 809.6054397792627, + "y": 384.13064300315534 + } + } + ], + "transformation": "rotation" + }, + { + "type": "Handle", + "p1": { + "x": 2560, + "y": 422.6093794147466 + }, + "p2": { + "x": 2560, + "y": 401.6093794147466 + }, + "controlPoints": [ + { + "newPoint": { + "x": 2540, + "y": 401.6093794147466 + }, + "targetObjIndex": 24, + "dragContext": { + "part": 2 + } + }, + { + "newPoint": { + "x": 2580, + "y": 401.6093794147466 + }, + "targetObjIndex": 23, + "dragContext": { + "part": 2 + } + } + ], + "transformation": "yTranslation" + }, + { + "type": "Protractor", + "p1": { + "x": 2686, + "y": 488.66666666666663 + }, + "p2": { + "x": 3086, + "y": 488.66666666666663 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 738.9476835979258, + "y": 421.64699964155176, + "arc": false + }, + { + "x": 806.7667118772957, + "y": 464.0802342960355, + "arc": false + }, + { + "x": 809.6054397792627, + "y": 384.13064300315534, + "arc": false + } + ] + }, + { + "type": "CircleGlass", + "p1": { + "x": 2695.014553318879, + "y": 429.06052298722733 + }, + "p2": { + "x": 2747.5072766594403, + "y": 458.12104597445074 + } + }, + { + "type": "SingleRay", + "p1": { + "x": 1560, + "y": 400 + }, + "p2": { + "x": 1720.367752010631, + "y": 400 + }, + "brightness": 10, + "wavelength": "575" + }, + { + "type": "Blocker", + "p1": { + "x": 340, + "y": -40 + }, + "p2": { + "x": 340, + "y": 900 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1220, + "y": -40 + }, + "p2": { + "x": 340, + "y": -40 + } + }, + { + "type": "Blocker", + "p1": { + "x": 3100, + "y": -40 + }, + "p2": { + "x": 2260, + "y": -40 + } + }, + { + "type": "Blocker", + "p1": { + "x": 2180, + "y": 900 + }, + "p2": { + "x": 2180, + "y": -40 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1220, + "y": 900 + }, + "p2": { + "x": 1220, + "y": -40 + } + }, + { + "type": "Protractor", + "p1": { + "x": 779.984304738948, + "y": 400 + }, + "p2": { + "x": 1180, + "y": 400 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1220, + "y": 900 + }, + "p2": { + "x": 340, + "y": 900 + } + }, + { + "type": "Blocker", + "p1": { + "x": 3100, + "y": 900 + }, + "p2": { + "x": 2260, + "y": 900 + } + }, + { + "type": "Blocker", + "p1": { + "x": 3100, + "y": 900 + }, + "p2": { + "x": 3100, + "y": -40 + } + }, + { + "type": "SingleRay", + "p1": { + "x": 620, + "y": 400 + }, + "p2": { + "x": 780.0057333103766, + "y": 400 + }, + "wavelength": "575" + }, + { + "type": "Blocker", + "p1": { + "x": 1300, + "y": 900 + }, + "p2": { + "x": 1300, + "y": -40 + } + }, + { + "type": "Blocker", + "p1": { + "x": 2180, + "y": 900 + }, + "p2": { + "x": 1300, + "y": 900 + } + }, + { + "type": "Blocker", + "p1": { + "x": 2180, + "y": -40 + }, + "p2": { + "x": 1300, + "y": -40 + } + }, + { + "type": "Blocker", + "p1": { + "x": 2260, + "y": 900 + }, + "p2": { + "x": 2260, + "y": -40 + } + }, + { + "type": "CircleGlass", + "p1": { + "x": 1751.7473931629236, + "y": 450.81557088403065 + }, + "p2": { + "x": 1783.3588603725555, + "y": 501.51041648670116 + } + }, + { + "type": "Protractor", + "p1": { + "x": 1740, + "y": 440 + }, + "p2": { + "x": 2140, + "y": 440 + } + }, + { + "type": "Beam", + "p1": { + "x": 2580, + "y": 280 + }, + "p2": { + "x": 2580, + "y": 401.6093794147466 + }, + "brightness": "10", + "wavelength": "650" + }, + { + "type": "Beam", + "p1": { + "x": 2540, + "y": 300 + }, + "p2": { + "x": 2540, + "y": 401.6093794147466 + }, + "brightness": "10", + "wavelength": "408" + }, + { + "type": "LineArrow", + "p1": { + "x": 780.5771618818052, + "y": 400.16825396825465 + }, + "p2": { + "x": 1136.4661062707496, + "y": 400.16825396825465 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 780.1829303320025, + "y": 399.8138490018858 + }, + "p2": { + "x": 609.68684045716, + "y": 79.1068061353044 + } + }, + { + "type": "Drawing", + "strokes": [ + [ + 712, + 311, + 710, + 311, + 708, + 312, + 706, + 314, + 704, + 316, + 701, + 318, + 699, + 320, + 697, + 322, + 694, + 326, + 692, + 328, + 691, + 330, + 689, + 332, + 686, + 336, + 684, + 339, + 682, + 342, + 681, + 346, + 680, + 348, + 678, + 351, + 676, + 354, + 674, + 358, + 673, + 361, + 672, + 366, + 671, + 369, + 670, + 372, + 670, + 374, + 669, + 378, + 668, + 381 + ], + [ + 662, + 369, + 664, + 374, + 665, + 376, + 667, + 380, + 669, + 382, + 672, + 380, + 676, + 378, + 680, + 378 + ] + ] + }, + { + "type": "Drawing", + "strokes": [ + [ + 1120, + 278 + ] + ], + "isDrawing": true + }, + { + "type": "Drawing", + "strokes": [ + [ + 944, + 425, + 944, + 427, + 943, + 430, + 943, + 435, + 942, + 439, + 941, + 441, + 940, + 444, + 940, + 448, + 938, + 452, + 937, + 455, + 936, + 457, + 934, + 460, + 933, + 462, + 932, + 465, + 931, + 467, + 930, + 469, + 930, + 471, + 929, + 473, + 927, + 477, + 924, + 479, + 923, + 481, + 922, + 483 + ], + [ + 920, + 471, + 920, + 475, + 921, + 479, + 921, + 481, + 922, + 483, + 923, + 485, + 926, + 485, + 929, + 484, + 931, + 483, + 934, + 481 + ] + ] + }, + { + "type": "LineArrow", + "p1": { + "x": 1720.7904404729272, + "y": 400.66217779106074 + }, + "p2": { + "x": 1557.1819092415824, + "y": 137.28785288262856 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 1740.888386931266, + "y": 509.7107594503886 + }, + "p2": { + "x": 1740.888386931266, + "y": 793.7107594503885 + } + }, + { + "type": "Drawing", + "strokes": [ + [ + 1622, + 357 + ] + ], + "isDrawing": true + }, + { + "type": "Drawing", + "strokes": [ + [ + 1647, + 315, + 1645, + 315, + 1643, + 316, + 1641, + 318, + 1639, + 320, + 1636, + 322, + 1634, + 324, + 1632, + 326, + 1629, + 330, + 1627, + 332, + 1626, + 334, + 1624, + 336, + 1621, + 340, + 1619, + 343, + 1617, + 346, + 1616, + 350, + 1615, + 352, + 1613, + 355, + 1611, + 358, + 1609, + 362, + 1608, + 365, + 1607, + 370, + 1606, + 373, + 1605, + 376, + 1605, + 378, + 1604, + 382, + 1603, + 385 + ], + [ + 1597, + 373, + 1599, + 378, + 1600, + 380, + 1602, + 384, + 1604, + 386, + 1607, + 384, + 1611, + 382, + 1615, + 382 + ] + ] + }, + { + "type": "Drawing", + "strokes": [ + [ + 1716, + 620, + 1714, + 620, + 1711, + 619, + 1708, + 618, + 1704, + 617, + 1702, + 615, + 1699, + 614, + 1695, + 612, + 1690, + 609, + 1687, + 607, + 1683, + 604, + 1679, + 601, + 1673, + 596, + 1670, + 593, + 1668, + 590, + 1664, + 584, + 1659, + 580, + 1657, + 576, + 1654, + 572, + 1653, + 569, + 1652, + 565, + 1650, + 564 + ], + [ + 1646, + 578, + 1647, + 573, + 1648, + 569, + 1650, + 565, + 1652, + 563, + 1655, + 563, + 1658, + 564, + 1664, + 565, + 1667, + 565 + ] + ] + }, + { + "type": "TextLabel", + "x": 3124.4, + "y": 1.6000000000001364, + "text": "在例A和B中,通过在点A1到A2和B1到B2之间旋转稜鏡,改变光线进入光学元件的\n入射角,你可以清楚地看到一个最小的\n偏向角出现在两点之间的某处。\n(在例A中,偏向角为相对于水平轴测量,而在例B中,\n偏向角为相对于垂直轴测量)。\n现在请看例C(可用缩放功能拉近),并将两束光扩展(红色和紫色,\n重叠部分呈现粉红色。这与例B中旋转棱镜\n的效果相同,故是在改变入射角),并观察从点\nC1到C2之间的反向出射光线向下堆积于两个明显的红色和紫色\n线(“光学焦散”)- 最小偏向角出现在点C2附近,并与\n光的波长(颜色)有关。然后,把光束从C2扩展到C3时,它们的\n反向出射光线的方向反转为向上。" + }, + { + "type": "TextLabel", + "x": 722, + "y": -56, + "text": "例A" + }, + { + "type": "TextLabel", + "x": 2642, + "y": -56, + "text": "例C" + }, + { + "type": "TextLabel", + "x": 1682, + "y": -56, + "text": "例B" + }, + { + "type": "TextLabel", + "x": 814.6666666666666, + "y": 447, + "text": "A2", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 823.9047619047618, + "y": 387.57142857142867, + "text": "A1", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 1880.7619047619041, + "y": 458.7619047619048, + "text": "B1", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 1732.5714285714284, + "y": 590.5714285714287, + "text": "B2", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 2544.266666666666, + "y": 400.9333333333336, + "text": "C1", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 2543.933333333333, + "y": 447.93333333333356, + "text": "C3", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 2544.933333333333, + "y": 414.6000000000002, + "text": "C2", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 1817.7333333333336, + "y": 587.6000000000003, + "text": "拖曳以旋转", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 851.7333333333335, + "y": 423.26666666666694, + "text": "拖曳以旋转", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 2539.7333333333327, + "y": 428.60000000000014, + "text": "拖曳以调整光束宽度", + "fontSize": 12, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 1439.819047619047, + "y": -203.57460317460277, + "text": "建议使用模拟器内建的缩放功能以利观察" + }, + { + "type": "TextLabel", + "x": 1689.0277271761097, + "y": 636.560817192037, + "text": "偏向角", + "fontSize": 18, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 1606.0632034632033, + "y": 339.3976911976918, + "text": "入射角", + "fontSize": 18, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 660.7298701298695, + "y": 326.0643578643584, + "text": "入射角", + "fontSize": 18, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 961.3965367965367, + "y": 473.39769119769176, + "text": "偏向角", + "fontSize": 18 + }, + { + "type": "CropBox", + "p1": { + "x": 314.6403129057385, + "y": -118.39062058525337 + }, + "p4": { + "x": 3119.973646239072, + "y": 930.94271274808 + } + }, + { + "type": "CropBox", + "p1": { + "x": 2594.640312905738, + "y": 341.60937941474685 + }, + "p4": { + "x": 2814.6403129057385, + "y": 561.6093794147469 + } + } + ], + "width": 4208, + "height": 2452, + "rayModeDensity": 3.8186616201103805, + "origin": { + "x": 386.6930204275949, + "y": 819.7239539185867 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/module-example-arrays-and-conditionals.json b/cn/gallery/module-example-arrays-and-conditionals.json new file mode 100644 index 00000000..96bc089d --- /dev/null +++ b/cn/gallery/module-example-arrays-and-conditionals.json @@ -0,0 +1,59 @@ +{ + "name": "模块示例 - 数组与条件", + "version": 5, + "modules": { + "ExampleModule": { + "numPoints": 0, + "params": [ + "n=1:1:10:1" + ], + "objs": [ + { + "for": "i=1:1:n", + "type": "TextLabel", + "x": 600, + "y": "`300+50i`", + "text": "一维数组:i=`i`" + }, + { + "if": "n>5", + "type": "TextLabel", + "x": 600, + "y": 250, + "text": "这段文字只在n>5时显示" + }, + { + "for": [ + "i=-10:1:10", + "j=-10:1:10" + ], + "if": "i^2+j^2<11^2", + "type": "TextLabel", + "x": "`1100+25i`", + "y": "`550+25j`", + "text": "`i`,`j`", + "fontSize": 9, + "alignment": "center" + } + ] + } + }, + "objs": [ + { + "type": "ModuleObj", + "module": "ExampleModule", + "points": [], + "params": { + "n": 10, + "theta": 1.23 + } + } + ], + "width": 1200, + "height": 400, + "origin": { + "x": 298.0105908080373, + "y": 19.812605130125487 + }, + "scale": 0.45976518247654025 +} \ No newline at end of file diff --git a/cn/gallery/module-example-basics.json b/cn/gallery/module-example-basics.json new file mode 100644 index 00000000..2334752d --- /dev/null +++ b/cn/gallery/module-example-basics.json @@ -0,0 +1,51 @@ +{ + "name": "模块示例 - 基本概念", + "version": 5, + "modules": { + "ExampleModule": { + "numPoints": 0, + "params": [], + "objs": [ + { + "type": "TextLabel", + "x": 600, + "y": 450, + "text": "这段文字在 ExampleModule 中" + }, + { + "type": "TextLabel", + "x": 600, + "y": 500, + "text": "这段文字也在 ExampleModule 中" + } + ] + } + }, + "objs": [ + { + "type": "TextLabel", + "x": 600, + "y": 300, + "text": "这段文字不在模块中。" + }, + { + "type": "TextLabel", + "x": 600, + "y": 350, + "text": "这段文字也不在模块中。" + }, + { + "type": "ModuleObj", + "module": "ExampleModule", + "points": [], + "params": {} + } + ], + "width": 1000, + "height": 400, + "origin": { + "x": 50.64898989898987, + "y": -86.41666666666666 + }, + "scale": 0.7175925925925926 +} \ No newline at end of file diff --git a/cn/gallery/module-example-control-points.json b/cn/gallery/module-example-control-points.json new file mode 100644 index 00000000..5135121c --- /dev/null +++ b/cn/gallery/module-example-control-points.json @@ -0,0 +1,54 @@ +{ + "name": "模块示例 - 控制点", + "version": 5, + "modules": { + "ExampleModule": { + "numPoints": 2, + "params": [], + "objs": [ + { + "type": "TextLabel", + "x": "`x_1`", + "y": "`y_1`", + "text": "↙这是本模块的第一个(可被拖曳的)控制点" + }, + { + "type": "TextLabel", + "x": "`x_2`", + "y": "`y_2`", + "text": "↙这是本模块的第二个(可被拖曳的)控制点" + }, + { + "type": "TextLabel", + "x": "`(x_1+x_2)/2`", + "y": "`(y_1+y_2)/2`", + "text": "↙这是中间点" + } + ] + } + }, + "objs": [ + { + "type": "ModuleObj", + "module": "ExampleModule", + "points": [ + { + "x": 500, + "y": 300 + }, + { + "x": 600, + "y": 600 + } + ], + "params": {} + } + ], + "width": 1200, + "height": 400, + "origin": { + "x": 140.37500000000014, + "y": -57.249999999999986 + }, + "scale": 0.6944444444444444 +} \ No newline at end of file diff --git a/cn/gallery/module-example-custom-equation.json b/cn/gallery/module-example-custom-equation.json new file mode 100644 index 00000000..224ed6ea --- /dev/null +++ b/cn/gallery/module-example-custom-equation.json @@ -0,0 +1,52 @@ +{ + "name": "模块示例 - 自定义数学式", + "version": 5, + "modules": { + "ExampleModule": { + "numPoints": 0, + "params": [ + "phi=0:0.01:2pi:1" + ], + "objs": [ + { + "type": "CustomMirror", + "p1": { + "x": 600, + "y": 400 + }, + "p2": { + "x": 800, + "y": 400 + }, + "eqn": "\\cos(2 \\pi x+`phi`)" + }, + { + "type": "TextLabel", + "x": 520, + "y": 270, + "text": "形状为 y=cos(2 pi x + `phi`) 的镜子" + } + ] + } + }, + "objs": [ + { + "type": "ModuleObj", + "module": "ExampleModule", + "points": [], + "params": { + "n": 2, + "theta": 1.23, + "a": 5, + "phi": 1.23 + } + } + ], + "width": 1200, + "height": 400, + "origin": { + "x": 236.49999999999994, + "y": -9.81249999999998 + }, + "scale": 0.6944444444444444 +} \ No newline at end of file diff --git a/cn/gallery/module-example-parameters.json b/cn/gallery/module-example-parameters.json new file mode 100644 index 00000000..6525724f --- /dev/null +++ b/cn/gallery/module-example-parameters.json @@ -0,0 +1,46 @@ +{ + "name": "模块示例 - 参数", + "version": 5, + "modules": { + "ExampleModule": { + "numPoints": 0, + "params": [ + "n=1:1:10:1", + "theta=0:0.01:5*pi:0" + ], + "objs": [ + { + "type": "TextLabel", + "x": 600, + "y": 400, + "text": "本模块有两个参数:n=`n`与theta=`theta`。\n您可以选取并拖曳数值滑杆来调整它们。" + }, + { + "type": "TextLabel", + "x": 600, + "y": 550, + "text": "这段文字的大小会随theta震荡。", + "fontSize": "`24+3*cos(theta)`" + } + ] + } + }, + "objs": [ + { + "type": "ModuleObj", + "module": "ExampleModule", + "points": [], + "params": { + "n": 1, + "theta": 1.23 + } + } + ], + "width": 1000, + "height": 400, + "origin": { + "x": 92.44791666666666, + "y": -68.02083333333334 + }, + "scale": 0.5787037037037037 +} \ No newline at end of file diff --git a/cn/gallery/module-example-shape-parametrization.json b/cn/gallery/module-example-shape-parametrization.json new file mode 100644 index 00000000..5bca138c --- /dev/null +++ b/cn/gallery/module-example-shape-parametrization.json @@ -0,0 +1,75 @@ +{ + "name": "模块示例 - 形状参数化", + "version": 5, + "modules": { + "ExampleModule": { + "numPoints": 0, + "params": [], + "objs": [ + { + "type": "SphericalLens", + "defBy": "DFfdBfd", + "p1": { + "x": 600, + "y": 200 + }, + "p2": { + "x": 600, + "y": 350 + }, + "params": { + "d": 40, + "ffd": 300, + "bfd": 350 + }, + "refIndex": 1.5 + }, + { + "type": "SphericalLens", + "defBy": "DR1R2", + "p1": { + "x": 600, + "y": 400 + }, + "p2": { + "x": 600, + "y": 550 + }, + "params": { + "d": 40, + "r1": 300, + "r2": -350 + }, + "refIndex": 1.5 + } + ] + } + }, + "objs": [ + { + "type": "ModuleObj", + "module": "ExampleModule", + "points": [], + "params": {} + }, + { + "type": "TextLabel", + "x": 640, + "y": 480, + "text": "以 d, R_1, R_2 定义的透镜" + }, + { + "type": "TextLabel", + "x": 640, + "y": 280, + "text": "以 d, FFD, BFD 定义的透镜" + } + ], + "width": 1200, + "height": 400, + "origin": { + "x": 207.06249999999997, + "y": -9.937500000000002 + }, + "scale": 0.6944444444444444 +} \ No newline at end of file diff --git a/cn/gallery/monochromatic-aberrations-thumbnail.avif b/cn/gallery/monochromatic-aberrations-thumbnail.avif new file mode 100644 index 00000000..87de11e7 Binary files /dev/null and b/cn/gallery/monochromatic-aberrations-thumbnail.avif differ diff --git a/cn/gallery/monochromatic-aberrations-thumbnail.jpg b/cn/gallery/monochromatic-aberrations-thumbnail.jpg new file mode 100644 index 00000000..bf26a9dc Binary files /dev/null and b/cn/gallery/monochromatic-aberrations-thumbnail.jpg differ diff --git a/cn/gallery/monochromatic-aberrations.avif b/cn/gallery/monochromatic-aberrations.avif new file mode 100644 index 00000000..77fe6a40 Binary files /dev/null and b/cn/gallery/monochromatic-aberrations.avif differ diff --git a/cn/gallery/monochromatic-aberrations.html b/cn/gallery/monochromatic-aberrations.html new file mode 100644 index 00000000..c54b9b60 --- /dev/null +++ b/cn/gallery/monochromatic-aberrations.html @@ -0,0 +1,178 @@ + + + + + + + 单色像差 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    单色像差

    +

    + 贡献者:Paul Falstad, Stas Fainer +

    +
    +

    这是不同单色像差的模拟:

    +
      +
    1. 球面像差(Spherical aberration)。
    2. +
    3. 彗形像差(Coma aberration)。
    4. +
    5. 散焦像差(Defocus aberration)。
    6. +
    7. 场曲像差(Field curvature aberration)。
    8. +

    +
    +

    + 在模拟器中打开 +

    + + + 单色像差 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/monochromatic-aberrations.jpg b/cn/gallery/monochromatic-aberrations.jpg new file mode 100644 index 00000000..984d39dd Binary files /dev/null and b/cn/gallery/monochromatic-aberrations.jpg differ diff --git a/cn/gallery/monochromatic-aberrations.json b/cn/gallery/monochromatic-aberrations.json new file mode 100644 index 00000000..0119d3ea --- /dev/null +++ b/cn/gallery/monochromatic-aberrations.json @@ -0,0 +1,396 @@ +{ + "name": "单色像差", + "version": 5, + "objs": [ + { + "type": "SphericalLens", + "path": [ + { + "x": -290, + "y": 240, + "arc": false + }, + { + "x": -270, + "y": 240, + "arc": false + }, + { + "x": -260, + "y": 320, + "arc": true + }, + { + "x": -270, + "y": 400, + "arc": false + }, + { + "x": -290, + "y": 400, + "arc": false + }, + { + "x": -300, + "y": 320, + "arc": true + } + ], + "refIndex": 2 + }, + { + "type": "Ruler", + "p1": { + "x": -280, + "y": 320 + }, + "p2": { + "x": -80, + "y": 320 + } + }, + { + "type": "Beam", + "p1": { + "x": 240, + "y": 940 + }, + "p2": { + "x": 240, + "y": 980 + } + }, + { + "type": "Beam", + "p1": { + "x": 320, + "y": 980 + }, + "p2": { + "x": 360, + "y": 1040 + } + }, + { + "type": "CircleBlocker", + "p1": { + "x": 1120, + "y": 320 + }, + "p2": { + "x": 1420, + "y": 400 + } + }, + { + "type": "CircleBlocker", + "p1": { + "x": -280, + "y": 320 + }, + "p2": { + "x": 20, + "y": 400 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 1120, + "y": 400 + }, + "p2": { + "x": 1120, + "y": 240 + }, + "focalLength": "155.15" + }, + { + "type": "Ruler", + "p1": { + "x": 1120, + "y": 320 + }, + "p2": { + "x": 1320, + "y": 320 + } + }, + { + "type": "Beam", + "p1": { + "x": 940, + "y": 280 + }, + "p2": { + "x": 940, + "y": 360 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1360, + "y": 520 + }, + "p2": { + "x": 1360, + "y": 120 + } + }, + { + "type": "CircleBlocker", + "p1": { + "x": 420, + "y": 960 + }, + "p2": { + "x": 720, + "y": 1040 + } + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 410, + "y": 880, + "arc": false + }, + { + "x": 430, + "y": 880, + "arc": false + }, + { + "x": 440, + "y": 960, + "arc": true + }, + { + "x": 430, + "y": 1040, + "arc": false + }, + { + "x": 410, + "y": 1040, + "arc": false + }, + { + "x": 400, + "y": 960, + "arc": true + } + ], + "refIndex": 2 + }, + { + "type": "Beam", + "p1": { + "x": -520, + "y": 240 + }, + "p2": { + "x": -520, + "y": 400 + } + }, + { + "type": "Ruler", + "p1": { + "x": 420, + "y": 960 + }, + "p2": { + "x": 620, + "y": 960 + } + }, + { + "type": "CircleBlocker", + "p1": { + "x": 420, + "y": 320 + }, + "p2": { + "x": 720, + "y": 400 + } + }, + { + "type": "Ruler", + "p1": { + "x": 420, + "y": 320 + }, + "p2": { + "x": 620, + "y": 320 + } + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 410, + "y": 240, + "arc": false + }, + { + "x": 430, + "y": 240, + "arc": false + }, + { + "x": 440, + "y": 320, + "arc": true + }, + { + "x": 430, + "y": 400, + "arc": false + }, + { + "x": 410, + "y": 400, + "arc": false + }, + { + "x": 400, + "y": 320, + "arc": true + } + ], + "refIndex": 2 + }, + { + "type": "Beam", + "p1": { + "x": 240, + "y": 300 + }, + "p2": { + "x": 240, + "y": 340 + } + }, + { + "type": "Beam", + "p1": { + "x": 320, + "y": 340 + }, + "p2": { + "x": 360, + "y": 400 + } + }, + { + "type": "Blocker", + "p1": { + "x": 380, + "y": 880 + }, + "p2": { + "x": 380, + "y": 950 + } + }, + { + "type": "Blocker", + "p1": { + "x": 380, + "y": 970 + }, + "p2": { + "x": 380, + "y": 1040 + } + }, + { + "type": "Blocker", + "p1": { + "x": 504.8392784176408, + "y": 816.7845014620493 + }, + "p2": { + "x": 695.1607215823592, + "y": 1103.2154985379507 + } + }, + { + "type": "TextLabel", + "x": 1120.381818181818, + "y": 113.25454545454568, + "text": "散焦像差", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": -281.61818181818194, + "y": 113.25454545454568, + "text": "球面像差", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 660.2194751485076, + "y": 1072.237634408602, + "text": "屏幕", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 1347.2, + "y": 479.20000000000005, + "text": "屏幕", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 420.38181818181806, + "y": 753.2545454545457, + "text": "场曲像差", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 426.38181818181806, + "y": 113.25454545454568, + "text": "彗形像差", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": -918.6443349753695, + "y": -10.368472906403895 + }, + "p4": { + "x": 1788.5556650246308, + "y": 1303.231527093596 + } + }, + { + "type": "CropBox", + "p1": { + "x": 94.95566502463043, + "y": -6.768472906403986 + }, + "p4": { + "x": 746.9556650246304, + "y": 645.231527093596 + } + } + ], + "width": 4060.8, + "height": 2667.2, + "rayModeDensity": 2.9284128885307004, + "origin": { + "x": 1595.4443349753697, + "y": 687.168472906404 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/newtonian-telescope-thumbnail.avif b/cn/gallery/newtonian-telescope-thumbnail.avif new file mode 100644 index 00000000..98c5f7b0 Binary files /dev/null and b/cn/gallery/newtonian-telescope-thumbnail.avif differ diff --git a/cn/gallery/newtonian-telescope-thumbnail.jpg b/cn/gallery/newtonian-telescope-thumbnail.jpg new file mode 100644 index 00000000..da7009be Binary files /dev/null and b/cn/gallery/newtonian-telescope-thumbnail.jpg differ diff --git a/cn/gallery/newtonian-telescope.avif b/cn/gallery/newtonian-telescope.avif new file mode 100644 index 00000000..e657dea2 Binary files /dev/null and b/cn/gallery/newtonian-telescope.avif differ diff --git a/cn/gallery/newtonian-telescope.html b/cn/gallery/newtonian-telescope.html new file mode 100644 index 00000000..1e74a1bc --- /dev/null +++ b/cn/gallery/newtonian-telescope.html @@ -0,0 +1,172 @@ + + + + + + + 牛顿望远镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    牛顿望远镜

    +

    + 贡献者:Matteo Ricci Cipolloni +

    +
    +

    这是一个配有Plössl目镜的牛顿望远镜模型。

    +
    +

    + 在模拟器中打开 +

    + + + 牛顿望远镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/newtonian-telescope.jpg b/cn/gallery/newtonian-telescope.jpg new file mode 100644 index 00000000..1f73927e Binary files /dev/null and b/cn/gallery/newtonian-telescope.jpg differ diff --git a/cn/gallery/newtonian-telescope.json b/cn/gallery/newtonian-telescope.json new file mode 100644 index 00000000..f490982a --- /dev/null +++ b/cn/gallery/newtonian-telescope.json @@ -0,0 +1,559 @@ +{ + "name": "牛顿望远镜", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 1267.4777777777776, + "y": 574.1251415251414 + }, + "p2": { + "x": 1389.058214419746, + "y": 574.5821211958582 + }, + "controlPoints": [ + { + "newPoint": { + "x": 1459.0798333245705, + "y": 559.5212985844565 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 1, + "index": 3 + } + }, + { + "newPoint": { + "x": 1459.0798333245705, + "y": 563.8148897885734 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 1, + "index": 4 + } + }, + { + "newPoint": { + "x": 1459.0798333245705, + "y": 564.3347608531817 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 3 + } + }, + { + "newPoint": { + "x": 1459.0798333245705, + "y": 604.3347608531817 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 4 + } + }, + { + "newPoint": { + "x": 1319.0219715956562, + "y": 559.5212985844565 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 1, + "index": 1 + } + }, + { + "newPoint": { + "x": 1319.0219715956562, + "y": 563.8148897885734 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 1, + "index": 0 + } + }, + { + "newPoint": { + "x": 1319.0798333245705, + "y": 564.3347608531817 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 1 + } + }, + { + "newPoint": { + "x": 1389.0509024601133, + "y": 539.3967574405771 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 1, + "index": 2 + } + }, + { + "newPoint": { + "x": 1389.0509024601133, + "y": 583.9212985844565 + }, + "targetObjIndex": 8, + "dragContext": { + "part": 1, + "index": 5 + } + }, + { + "newPoint": { + "x": 1389.0798333245705, + "y": 584.3347608531817 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 2 + } + }, + { + "newPoint": { + "x": 1389.0798333245705, + "y": 604.3347608531817 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 5 + } + }, + { + "newPoint": { + "x": 1318.9939916534188, + "y": 603.3212173132964 + }, + "targetObjIndex": 9, + "dragContext": { + "part": 1, + "index": 0 + } + } + ] + }, + { + "type": "Handle", + "p1": { + "x": 1212.2777777777778, + "y": 460 + }, + "p2": { + "x": 1389.8000000000004, + "y": 461.84126984126965 + }, + "controlPoints": [ + { + "newPoint": { + "x": 1299.8000000000004, + "y": 422.5079365079364 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 1, + "index": 4 + } + }, + { + "newPoint": { + "x": 1299.8000000000004, + "y": 462.5079365079364 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 1, + "index": 3 + } + }, + { + "newPoint": { + "x": 1299.8000000000004, + "y": 464.5079365079364 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 1, + "index": 4 + } + }, + { + "newPoint": { + "x": 1389.8000000000004, + "y": 442.5079365079364 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 1, + "index": 2 + } + }, + { + "newPoint": { + "x": 1389.8000000000004, + "y": 444.5079365079364 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 1, + "index": 5 + } + }, + { + "newPoint": { + "x": 1389.8000000000004, + "y": 422.5079365079364 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 1, + "index": 5 + } + }, + { + "newPoint": { + "x": 1479.8000000000004, + "y": 422.5079365079364 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 1, + "index": 0 + } + }, + { + "newPoint": { + "x": 1479.8000000000004, + "y": 462.5079365079364 + }, + "targetObjIndex": 7, + "dragContext": { + "part": 1, + "index": 1 + } + }, + { + "newPoint": { + "x": 1479.8000000000004, + "y": 464.5079365079364 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 1, + "index": 0 + } + }, + { + "newPoint": { + "x": 1479.8000000000004, + "y": 504.5079365079365 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 1, + "index": 1 + } + }, + { + "newPoint": { + "x": 1389.8000000000004, + "y": 524.5079365079364 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 1, + "index": 2 + } + }, + { + "newPoint": { + "x": 1299.8000000000004, + "y": 504.5079365079365 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 1, + "index": 3 + } + } + ] + }, + { + "type": "ParabolicMirror", + "p1": { + "x": 320, + "y": 20 + }, + "p2": { + "x": 320, + "y": 400 + }, + "p3": { + "x": 314.0870286576168, + "y": 210 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1320, + "y": 140 + }, + "p2": { + "x": 1440, + "y": 260 + } + }, + { + "type": "Beam", + "p1": { + "x": 2220, + "y": 400 + }, + "p2": { + "x": 2220, + "y": 20 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1340, + "y": 140 + }, + "p2": { + "x": 1460, + "y": 260 + } + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 1479.8000000000004, + "y": 464.5079365079364, + "arc": false + }, + { + "x": 1479.8000000000004, + "y": 504.5079365079365, + "arc": false + }, + { + "x": 1389.8000000000004, + "y": 524.5079365079364, + "arc": true + }, + { + "x": 1299.8000000000004, + "y": 504.5079365079365, + "arc": false + }, + { + "x": 1299.8000000000004, + "y": 464.5079365079364, + "arc": false + }, + { + "x": 1389.8000000000004, + "y": 444.5079365079364, + "arc": true + } + ] + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 1479.8000000000004, + "y": 422.5079365079364, + "arc": false + }, + { + "x": 1479.8000000000004, + "y": 462.5079365079364, + "arc": false + }, + { + "x": 1389.8000000000004, + "y": 442.5079365079364, + "arc": true + }, + { + "x": 1299.8000000000004, + "y": 462.5079365079364, + "arc": false + }, + { + "x": 1299.8000000000004, + "y": 422.5079365079364, + "arc": false + }, + { + "x": 1389.8000000000004, + "y": 422.5079365079364, + "arc": true + } + ] + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 1319.0219715956562, + "y": 563.8148897885734, + "arc": false + }, + { + "x": 1319.0219715956562, + "y": 559.5212985844565, + "arc": false + }, + { + "x": 1389.0509024601133, + "y": 539.3967574405771, + "arc": true + }, + { + "x": 1459.0798333245705, + "y": 559.5212985844565, + "arc": false + }, + { + "x": 1459.0798333245705, + "y": 563.8148897885734, + "arc": false + }, + { + "x": 1389.0509024601133, + "y": 583.9212985844565, + "arc": true + } + ] + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 1318.9939916534188, + "y": 603.3212173132964, + "arc": false + }, + { + "x": 1319.0798333245705, + "y": 564.3347608531817, + "arc": false + }, + { + "x": 1389.0798333245705, + "y": 584.3347608531817, + "arc": true + }, + { + "x": 1459.0798333245705, + "y": 564.3347608531817, + "arc": false + }, + { + "x": 1459.0798333245705, + "y": 604.3347608531817, + "arc": false + }, + { + "x": 1389.0798333245705, + "y": 604.3347608531817, + "arc": true + } + ] + }, + { + "type": "Ruler", + "p1": { + "x": 260, + "y": 20 + }, + "p2": { + "x": 260, + "y": 400 + } + }, + { + "type": "Ruler", + "p1": { + "x": 320, + "y": -20 + }, + "p2": { + "x": 1860, + "y": -20 + } + }, + { + "type": "Ruler", + "p1": { + "x": 1403.458241758242, + "y": 632.7918081918082 + }, + "p2": { + "x": 1403.9026862026865, + "y": 604.7918081918082 + } + }, + { + "type": "TextLabel", + "x": 1559.0000000000005, + "y": 567.5333333333332, + "text": "Plossl" + }, + { + "type": "CropBox", + "p1": { + "x": 178.35665445665475, + "y": -91.93454101454115 + }, + "p4": { + "x": 2287.9566544566546, + "y": 697.1854589854588 + } + }, + { + "type": "CropBox", + "p1": { + "x": 295.75665445665476, + "y": -361.0145410145412 + }, + "p4": { + "x": 1486.7930180930184, + "y": 830.0218229854588 + } + } + ], + "width": 3164.3999999999996, + "height": 1843.92, + "observer": { + "c": { + "x": 1058.9825396825402, + "y": 881.2904761904762 + }, + "r": 20 + }, + "origin": { + "x": 349.04334554334525, + "y": 619.3345410145412 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/optical-cavity-thumbnail.avif b/cn/gallery/optical-cavity-thumbnail.avif new file mode 100644 index 00000000..4c631d08 Binary files /dev/null and b/cn/gallery/optical-cavity-thumbnail.avif differ diff --git a/cn/gallery/optical-cavity-thumbnail.jpg b/cn/gallery/optical-cavity-thumbnail.jpg new file mode 100644 index 00000000..bac17eb2 Binary files /dev/null and b/cn/gallery/optical-cavity-thumbnail.jpg differ diff --git a/cn/gallery/optical-cavity.avif b/cn/gallery/optical-cavity.avif new file mode 100644 index 00000000..2686ee7f Binary files /dev/null and b/cn/gallery/optical-cavity.avif differ diff --git a/cn/gallery/optical-cavity.html b/cn/gallery/optical-cavity.html new file mode 100644 index 00000000..b7993479 --- /dev/null +++ b/cn/gallery/optical-cavity.html @@ -0,0 +1,172 @@ + + + + + + + 双镜共振腔 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    双镜共振腔

    +

    + 贡献者:Stas Fainer +

    +
    +

    模拟由两面镜子组成的共振腔。假设腔体的长度为\(d\),其镜子的曲率半径分别为\(R_1\)和\(R_2\)(根据惯例,\(R>0\)为凹面镜),那么只有当\(0\leq (1-\frac {d}{R_1})(1-\frac {d}{R_2})\leq 1\)时,共振腔才会稳定(这意味着从一面镜子向另一面镜子发出的每一道光线都保证有非发散的轨迹,前提是镜子的反射率足够高)。在此模拟中,我们假设镜子是理想曲面镜,这意味着\(f=\frac{R}{2}\),将先前的稳定条件变为\(0\leq (1-\frac {d}{2f_1})(1-\frac {d}{2f_2})\leq 1\)。 这里有一个使用球面镜的类似模拟,在抛物面近似下,第一种稳定条件成立。

    +
    +

    + 在模拟器中打开 +

    + + + 双镜共振腔 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/optical-cavity.jpg b/cn/gallery/optical-cavity.jpg new file mode 100644 index 00000000..b0b4e7c8 Binary files /dev/null and b/cn/gallery/optical-cavity.jpg differ diff --git a/cn/gallery/optical-cavity.json b/cn/gallery/optical-cavity.json new file mode 100644 index 00000000..ea5f159b --- /dev/null +++ b/cn/gallery/optical-cavity.json @@ -0,0 +1,402 @@ +{ + "name": "双镜共振腔", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 978.3725092112181, + "y": 1010 + }, + "p2": { + "x": 979, + "y": 560 + }, + "controlPoints": [ + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 16, + "newPoint": { + "x": 979, + "y": 160 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 16, + "newPoint": { + "x": 979, + "y": 960 + } + } + ], + "transformation": "xTranslation" + }, + { + "type": "IdealMirror", + "p1": { + "x": 180, + "y": 160 + }, + "p2": { + "x": 180, + "y": 960 + }, + "focalLength": 200 + }, + { + "type": "Blocker", + "p1": { + "x": 1980, + "y": 100 + }, + "p2": { + "x": 1980, + "y": 1020 + } + }, + { + "type": "Ruler", + "p1": { + "x": 2180, + "y": 560 + }, + "p2": { + "x": 2580, + "y": 560 + } + }, + { + "type": "IdealMirror", + "p1": { + "x": 2180, + "y": 160 + }, + "p2": { + "x": 2180, + "y": 960 + }, + "focalLength": 400 + }, + { + "type": "IdealMirror", + "p1": { + "x": 2580, + "y": 160 + }, + "p2": { + "x": 2580, + "y": 960 + }, + "focalLength": -300 + }, + { + "type": "SingleRay", + "p1": { + "x": -220, + "y": 540 + }, + "p2": { + "x": 218.63481228668945, + "y": 488.39590443686006 + } + }, + { + "type": "SingleRay", + "p1": { + "x": 580, + "y": 540 + }, + "p2": { + "x": 1020, + "y": 540 + } + }, + { + "type": "IdealMirror", + "p1": { + "x": -220, + "y": 160 + }, + "p2": { + "x": -220, + "y": 960 + }, + "focalLength": 200 + }, + { + "type": "Ruler", + "p1": { + "x": -220, + "y": 560 + }, + "p2": { + "x": 180, + "y": 560 + } + }, + { + "type": "Blocker", + "p1": { + "x": 380, + "y": 100 + }, + "p2": { + "x": 380, + "y": 1020 + } + }, + { + "type": "Ruler", + "p1": { + "x": 580, + "y": 560 + }, + "p2": { + "x": 980, + "y": 560 + } + }, + { + "type": "SingleRay", + "p1": { + "x": 2180, + "y": 540 + }, + "p2": { + "x": 2640, + "y": 500 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1180, + "y": 100 + }, + "p2": { + "x": 1180, + "y": 1020 + } + }, + { + "type": "IdealMirror", + "p1": { + "x": 1380, + "y": 160 + }, + "p2": { + "x": 1380, + "y": 960 + }, + "focalLength": 200 + }, + { + "type": "Ruler", + "p1": { + "x": 1380, + "y": 560 + }, + "p2": { + "x": 1780, + "y": 560 + } + }, + { + "type": "IdealMirror", + "p1": { + "x": 979, + "y": 160 + }, + "p2": { + "x": 979, + "y": 960 + } + }, + { + "type": "IdealMirror", + "p1": { + "x": 580, + "y": 160 + }, + "p2": { + "x": 580, + "y": 960 + } + }, + { + "type": "SingleRay", + "p1": { + "x": 1380, + "y": 540 + }, + "p2": { + "x": 1840, + "y": 540 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1779, + "y": 160 + }, + "p2": { + "x": 1779, + "y": 960 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 218.88766072637014, + "y": 449.2476126024506 + }, + "p2": { + "x": 218.88766072637014, + "y": 474.580945935784 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 200, + "y": 420, + "text": "点击 + 按住左键\n以移动光线" + }, + { + "type": "TextLabel", + "x": 977.5854137442425, + "y": 1049.2819534933333, + "text": "拖曳此处\n可水平移动镜子", + "fontSize": 18, + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1181.8181818181815, + "y": 18.181818181818016, + "text": "下方的共振腔中d = 400", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 175.63636363636337, + "y": 136.36363636363626, + "text": "f2 = d/2", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 979.0909090909088, + "y": 136.36363636363626, + "text": "f2 = d/4", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": -216.1818181818184, + "y": 136.36363636363626, + "text": "f1 = d/2", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 2575.818181818183, + "y": 136.36363636363626, + "text": "f2 < 0", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": -17.50146627566002, + "y": 270.909090909091, + "text": "焦聚共振腔", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 776.739002932551, + "y": 230.90909090909096, + "text": "共心共振腔", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 2379.1608391608393, + "y": 230.90909090909088, + "text": "凹凸共振腔", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 585.9999999999995, + "y": 136.36363636363626, + "text": "f1 = d/4", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1380.9090909090905, + "y": 136.36363636363626, + "text": "f1 = d/2", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1776.7272727272725, + "y": 136.36363636363626, + "text": "f2 = ∞", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 2175.0909090909095, + "y": 136.36363636363626, + "text": "f1 > 0", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1618.9930069930074, + "y": 230.90909090909093, + "text": "平凹共振腔", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": -342.6853146853146, + "y": -64.54545454545499 + }, + "p4": { + "x": 2769.9300699300693, + "y": 1137.3006993006989 + }, + "rayCountLimit": 20000 + }, + { + "type": "CropBox", + "p1": { + "x": 327.46853146853147, + "y": 90.5314685314682 + }, + "p4": { + "x": 1227.4685314685312, + "y": 990.5314685314681 + }, + "rayCountLimit": 20000 + } + ], + "width": 4668.923076923076, + "height": 2758.1538461538457, + "origin": { + "x": 1120.8391608391605, + "y": 842.6993006993009 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/pair-of-axicons-making-a-rainbow-ring-thumbnail.avif b/cn/gallery/pair-of-axicons-making-a-rainbow-ring-thumbnail.avif new file mode 100644 index 00000000..0bc5db8d Binary files /dev/null and b/cn/gallery/pair-of-axicons-making-a-rainbow-ring-thumbnail.avif differ diff --git a/cn/gallery/pair-of-axicons-making-a-rainbow-ring-thumbnail.jpg b/cn/gallery/pair-of-axicons-making-a-rainbow-ring-thumbnail.jpg new file mode 100644 index 00000000..4d6c4516 Binary files /dev/null and b/cn/gallery/pair-of-axicons-making-a-rainbow-ring-thumbnail.jpg differ diff --git a/cn/gallery/pair-of-axicons-making-a-rainbow-ring.avif b/cn/gallery/pair-of-axicons-making-a-rainbow-ring.avif new file mode 100644 index 00000000..742b818d Binary files /dev/null and b/cn/gallery/pair-of-axicons-making-a-rainbow-ring.avif differ diff --git a/cn/gallery/pair-of-axicons-making-a-rainbow-ring.html b/cn/gallery/pair-of-axicons-making-a-rainbow-ring.html new file mode 100644 index 00000000..f8b55514 --- /dev/null +++ b/cn/gallery/pair-of-axicons-making-a-rainbow-ring.html @@ -0,0 +1,171 @@ + + + + + + + 一对锥透镜产生彩虹环 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    一对锥透镜产生彩虹环

    +

    + 贡献者:Peter Becher +

    +
    +

    此模拟使用两个平凸锥透镜、一个白色光源和一个光圈来产生圆形彩虹。入射的白光必须为环状,此处透过窄的环状光圈来实现。

    +

    将右侧的锥透镜左右移动可改变彩虹环的大小。

    +
    +

    + 在模拟器中打开 +

    + + + 一对锥透镜产生彩虹环 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/pair-of-axicons-making-a-rainbow-ring.jpg b/cn/gallery/pair-of-axicons-making-a-rainbow-ring.jpg new file mode 100644 index 00000000..9c730aa7 Binary files /dev/null and b/cn/gallery/pair-of-axicons-making-a-rainbow-ring.jpg differ diff --git a/cn/gallery/pair-of-axicons-making-a-rainbow-ring.json b/cn/gallery/pair-of-axicons-making-a-rainbow-ring.json new file mode 100644 index 00000000..9d1fede6 --- /dev/null +++ b/cn/gallery/pair-of-axicons-making-a-rainbow-ring.json @@ -0,0 +1,465 @@ +{ + "name": "一对锥透镜产生彩虹环", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": -5, + "y": 31.48348230081941 + }, + "p2": { + "x": -5, + "y": 48 + }, + "controlPoints": [ + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 3, + "newPoint": { + "x": 5.270033283803388, + "y": 73.76311786652741 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 4, + "newPoint": { + "x": 11.884000208593882, + "y": 73.76311786652741 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 5, + "newPoint": { + "x": 18.497967133384364, + "y": 73.76311786652741 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 6, + "newPoint": { + "x": 25.1119340581755, + "y": 73.76311786652741 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 7, + "newPoint": { + "x": 31.72590098296631, + "y": 73.76311786652741 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 8, + "newPoint": { + "x": 38.33986790775698, + "y": 73.76311786652741 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 2, + "newPoint": { + "x": 44.95383483254731, + "y": 73.76311786652741 + } + }, + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 2, + "newPoint": { + "x": 44.95383483254731, + "y": -12.560564896995494 + } + }, + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 8, + "newPoint": { + "x": 38.33986790775698, + "y": -12.560564896995494 + } + }, + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 7, + "newPoint": { + "x": 31.72590098296631, + "y": -12.560564896995494 + } + }, + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 6, + "newPoint": { + "x": 25.1119340581755, + "y": -12.560564896995494 + } + }, + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 5, + "newPoint": { + "x": 18.497967133384364, + "y": -12.560564896995494 + } + }, + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 4, + "newPoint": { + "x": 11.884000208593882, + "y": -12.560564896995494 + } + }, + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 3, + "newPoint": { + "x": 5.270033283803388, + "y": -12.560564896995494 + } + } + ] + }, + { + "type": "Handle", + "p1": { + "x": 75, + "y": 30 + }, + "p2": { + "x": 70, + "y": 32.5 + }, + "controlPoints": [ + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 13, + "newPoint": { + "x": 70, + "y": 5 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 13, + "newPoint": { + "x": 70, + "y": 60 + } + }, + { + "dragContext": { + "part": 2 + }, + "targetObjIndex": 14, + "newPoint": { + "x": 70, + "y": 45 + } + }, + { + "dragContext": { + "part": 1 + }, + "targetObjIndex": 14, + "newPoint": { + "x": 70, + "y": 20 + } + } + ] + }, + { + "type": "Beam", + "p1": { + "x": 44.95383483254731, + "y": -12.560564896995494 + }, + "p2": { + "x": 44.95383483254731, + "y": 73.76311786652741 + }, + "brightness": "0.4", + "wavelength": "420" + }, + { + "type": "Beam", + "p1": { + "x": 5.270033283803388, + "y": -12.560564896995494 + }, + "p2": { + "x": 5.270033283803388, + "y": 73.76311786652741 + }, + "brightness": "0.45", + "wavelength": "620" + }, + { + "type": "Beam", + "p1": { + "x": 11.884000208593882, + "y": -12.560564896995494 + }, + "p2": { + "x": 11.884000208593882, + "y": 73.76311786652741 + }, + "brightness": "0.2", + "wavelength": "600" + }, + { + "type": "Beam", + "p1": { + "x": 18.497967133384364, + "y": -12.560564896995494 + }, + "p2": { + "x": 18.497967133384364, + "y": 73.76311786652741 + }, + "brightness": "0.3", + "wavelength": "580" + }, + { + "type": "Beam", + "p1": { + "x": 25.1119340581755, + "y": -12.560564896995494 + }, + "p2": { + "x": 25.1119340581755, + "y": 73.76311786652741 + }, + "brightness": "0.45", + "wavelength": "540" + }, + { + "type": "Beam", + "p1": { + "x": 31.72590098296631, + "y": -12.560564896995494 + }, + "p2": { + "x": 31.72590098296631, + "y": 73.76311786652741 + }, + "brightness": "0.3", + "wavelength": "500" + }, + { + "type": "Beam", + "p1": { + "x": 38.33986790775698, + "y": -12.560564896995494 + }, + "p2": { + "x": 38.33986790775698, + "y": 73.76311786652741 + }, + "brightness": "0.45", + "wavelength": "460" + }, + { + "type": "CropBox", + "p1": { + "x": -110.02458689263113, + "y": -53.54835745413453 + }, + "p4": { + "x": 346.3037830468433, + "y": 117.49787457418806 + } + }, + { + "type": "CropBox", + "p1": { + "x": 1.7528111665845536, + "y": -85.11773782127092 + }, + "p4": { + "x": 237.00225789302374, + "y": 150.13170917872904 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 90, + "y": -5, + "arc": false + }, + { + "x": 115, + "y": 30, + "arc": false + }, + { + "x": 90, + "y": 65, + "arc": false + }, + { + "x": 85, + "y": 65, + "arc": false + }, + { + "x": 85, + "y": 30, + "arc": false + }, + { + "x": 85, + "y": -5, + "arc": false + } + ] + }, + { + "type": "Glass", + "path": [ + { + "x": 213.2969167226662, + "y": 64.97394268191726, + "arc": false + }, + { + "x": 187.95555555555555, + "y": 30, + "arc": false + }, + { + "x": 212.6139564058454, + "y": -5.0227255616902085, + "arc": false + }, + { + "x": 217.61371842324598, + "y": -5.071508441463095, + "arc": false + }, + { + "x": 217.95519858165628, + "y": 29.92682568034062, + "arc": false + }, + { + "x": 218.2966787400667, + "y": 64.92515980214444, + "arc": false + } + ] + }, + { + "type": "Aperture", + "p1": { + "x": 70, + "y": -15 + }, + "p2": { + "x": 70, + "y": 75 + }, + "p3": { + "x": 70, + "y": 3.552713678800501e-15 + }, + "p4": { + "x": 70, + "y": 60 + } + }, + { + "type": "Blocker", + "p1": { + "x": 70, + "y": 2 + }, + "p2": { + "x": 70, + "y": 58 + } + }, + { + "type": "TextLabel", + "x": 82.61986504689585, + "y": -5.809756086281965, + "text": "左侧锥透镜", + "fontSize": 8 + }, + { + "type": "TextLabel", + "x": -1.2729920959612961, + "y": -2.809756086281965, + "text": "白光\n光源", + "fontSize": 8, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 218.9412936183244, + "y": -6.059756086281967, + "text": "右侧锥透镜", + "fontSize": 8, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 61.86986504689585, + "y": 88.19024391371806, + "text": "环状光圈", + "fontSize": 8 + } + ], + "width": 684.4925549092117, + "height": 399.2104169980598, + "rayModeDensity": 1, + "gridSize": 10, + "origin": { + "x": 224.10667937749974, + "y": 167.63044993900314 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/parabolic-mirror-thumbnail.avif b/cn/gallery/parabolic-mirror-thumbnail.avif new file mode 100644 index 00000000..f3e6cb9f Binary files /dev/null and b/cn/gallery/parabolic-mirror-thumbnail.avif differ diff --git a/cn/gallery/parabolic-mirror-thumbnail.jpg b/cn/gallery/parabolic-mirror-thumbnail.jpg new file mode 100644 index 00000000..e1f7d4ff Binary files /dev/null and b/cn/gallery/parabolic-mirror-thumbnail.jpg differ diff --git a/cn/gallery/parabolic-mirror.avif b/cn/gallery/parabolic-mirror.avif new file mode 100644 index 00000000..b2882af6 Binary files /dev/null and b/cn/gallery/parabolic-mirror.avif differ diff --git a/cn/gallery/parabolic-mirror.html b/cn/gallery/parabolic-mirror.html new file mode 100644 index 00000000..aa17bb37 --- /dev/null +++ b/cn/gallery/parabolic-mirror.html @@ -0,0 +1,172 @@ + + + + + + + 抛物面镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    抛物面镜

    +

    + 贡献者:Paul Falstad +

    +
    +

    此模拟演示了抛物面镜的聚焦特性。

    +
    +

    + 在模拟器中打开 +

    + + + 抛物面镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/parabolic-mirror.jpg b/cn/gallery/parabolic-mirror.jpg new file mode 100644 index 00000000..cda9bc8f Binary files /dev/null and b/cn/gallery/parabolic-mirror.jpg differ diff --git a/cn/gallery/parabolic-mirror.json b/cn/gallery/parabolic-mirror.json new file mode 100644 index 00000000..c39e1972 --- /dev/null +++ b/cn/gallery/parabolic-mirror.json @@ -0,0 +1,92 @@ +{ + "name": "抛物面镜", + "version": 5, + "objs": [ + { + "type": "ParabolicMirror", + "p1": { + "x": 200, + "y": 240 + }, + "p2": { + "x": 200, + "y": 440 + }, + "p3": { + "x": 140, + "y": 340 + } + }, + { + "type": "ParabolicMirror", + "p1": { + "x": 200, + "y": 480 + }, + "p2": { + "x": 200, + "y": 680 + }, + "p3": { + "x": 260, + "y": 580 + } + }, + { + "type": "PointSource", + "x": 180, + "y": 340 + }, + { + "type": "Blocker", + "p1": { + "x": -200, + "y": 460 + }, + "p2": { + "x": 780, + "y": 460 + } + }, + { + "type": "Beam", + "p1": { + "x": -284.9382716049383, + "y": 495.0617283950618 + }, + "p2": { + "x": -284.9382716049383, + "y": 655.0617283950618 + } + }, + { + "type": "CropBox", + "p1": { + "x": -367.6476242064725, + "y": 189.72310750453272 + }, + "p4": { + "x": 809.177772618924, + "y": 749.7231075045327 + } + }, + { + "type": "CropBox", + "p1": { + "x": -47.965084523933015, + "y": 217.3421551235803 + }, + "p4": { + "x": 445.6857094760669, + "y": 710.9929487743739 + } + } + ], + "width": 1765.238095238095, + "height": 1148.4126984126983, + "origin": { + "x": 661.8539734128217, + "y": 104.48324170181644 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/penrose-unilluminable-room-thumbnail.avif b/cn/gallery/penrose-unilluminable-room-thumbnail.avif new file mode 100644 index 00000000..5a97f88a Binary files /dev/null and b/cn/gallery/penrose-unilluminable-room-thumbnail.avif differ diff --git a/cn/gallery/penrose-unilluminable-room-thumbnail.jpg b/cn/gallery/penrose-unilluminable-room-thumbnail.jpg new file mode 100644 index 00000000..f3d8479f Binary files /dev/null and b/cn/gallery/penrose-unilluminable-room-thumbnail.jpg differ diff --git a/cn/gallery/penrose-unilluminable-room.avif b/cn/gallery/penrose-unilluminable-room.avif new file mode 100644 index 00000000..748d6646 Binary files /dev/null and b/cn/gallery/penrose-unilluminable-room.avif differ diff --git a/cn/gallery/penrose-unilluminable-room.html b/cn/gallery/penrose-unilluminable-room.html new file mode 100644 index 00000000..e99c3be1 --- /dev/null +++ b/cn/gallery/penrose-unilluminable-room.html @@ -0,0 +1,172 @@ + + + + + + + 无法照亮的彭罗斯房间 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    无法照亮的彭罗斯房间

    +

    + 贡献者:Vincent Fan, Yi-Ting Tu +

    +
    +

    无法照亮的彭罗斯房间由椭圆形、圆形和线性镜子构成。它有一个有趣的特性,即房间内的一个点源(绿色)无论放在哪里,都不会照亮整个房间。您可以拖动绿色点以移动源。

    +
    +

    + 在模拟器中打开 +

    + + + 无法照亮的彭罗斯房间 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/penrose-unilluminable-room.jpg b/cn/gallery/penrose-unilluminable-room.jpg new file mode 100644 index 00000000..d7c2e72f Binary files /dev/null and b/cn/gallery/penrose-unilluminable-room.jpg differ diff --git a/cn/gallery/penrose-unilluminable-room.json b/cn/gallery/penrose-unilluminable-room.json new file mode 100644 index 00000000..bbc209d5 --- /dev/null +++ b/cn/gallery/penrose-unilluminable-room.json @@ -0,0 +1,236 @@ +{ + "name": "无法照亮的彭罗斯房间", + "version": 5, + "objs": [ + { + "type": "CustomMirror", + "p1": { + "x": 655, + "y": 580 + }, + "p2": { + "x": 1655, + "y": 580 + }, + "eqn": "\\frac{4}{5}\\cdot\\sqrt{1-x^2}" + }, + { + "type": "CustomMirror", + "p1": { + "x": 1655, + "y": 780 + }, + "p2": { + "x": 655, + "y": 780 + }, + "eqn": "\\frac{4}{5}\\cdot\\sqrt{1-x^2}" + }, + { + "type": "Mirror", + "p1": { + "x": 1655, + "y": 580 + }, + "p2": { + "x": 1655, + "y": 660 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1455, + "y": 660 + }, + "p2": { + "x": 1655, + "y": 660 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1455, + "y": 580 + }, + "p2": { + "x": 1455, + "y": 660 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1655, + "y": 780 + }, + "p2": { + "x": 1655, + "y": 700 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1455, + "y": 700 + }, + "p2": { + "x": 1655, + "y": 700 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1455, + "y": 780 + }, + "p2": { + "x": 1455, + "y": 700 + } + }, + { + "type": "Mirror", + "p1": { + "x": 855, + "y": 660 + }, + "p2": { + "x": 855, + "y": 580 + } + }, + { + "type": "Mirror", + "p1": { + "x": 655, + "y": 660 + }, + "p2": { + "x": 855, + "y": 660 + } + }, + { + "type": "Mirror", + "p1": { + "x": 655, + "y": 660 + }, + "p2": { + "x": 655, + "y": 580 + } + }, + { + "type": "Mirror", + "p1": { + "x": 655, + "y": 700 + }, + "p2": { + "x": 655, + "y": 780 + } + }, + { + "type": "Mirror", + "p1": { + "x": 855, + "y": 700 + }, + "p2": { + "x": 655, + "y": 700 + } + }, + { + "type": "Mirror", + "p1": { + "x": 855, + "y": 780 + }, + "p2": { + "x": 855, + "y": 700 + } + }, + { + "type": "ArcMirror", + "p1": { + "x": 855, + "y": 780 + }, + "p2": { + "x": 855, + "y": 580 + }, + "p3": { + "x": 955, + "y": 680 + } + }, + { + "type": "ArcMirror", + "p1": { + "x": 1455, + "y": 780 + }, + "p2": { + "x": 1455, + "y": 580 + }, + "p3": { + "x": 1355, + "y": 680 + } + }, + { + "type": "PointSource", + "x": 733, + "y": 620, + "brightness": "0.02" + }, + { + "type": "TextLabel", + "x": 1127.022222222223, + "y": 105.84444444444438, + "text": "无论您将点光源放在哪里,它都不会照亮整个房间。\n警告:由于数值误差,可能会在一段时间后仍然照亮。", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": 109.16464646464664, + "y": 35.972929292929166 + }, + "p4": { + "x": 2182.764646464645, + "y": 1212.092929292929 + }, + "rayCountLimit": 2500 + }, + { + "type": "CropBox", + "p1": { + "x": 582.5646464646468, + "y": 40.292929292929244 + }, + "p4": { + "x": 1727.3646464646467, + "y": 1185.0929292929293 + }, + "rayCountLimit": 2500 + } + ], + "width": 3110.399999999998, + "height": 2212.919999999999, + "origin": { + "x": 409.235353535353, + "y": 482.42707070707047 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/periscope-thumbnail.avif b/cn/gallery/periscope-thumbnail.avif new file mode 100644 index 00000000..b9d37338 Binary files /dev/null and b/cn/gallery/periscope-thumbnail.avif differ diff --git a/cn/gallery/periscope-thumbnail.jpg b/cn/gallery/periscope-thumbnail.jpg new file mode 100644 index 00000000..637dcae1 Binary files /dev/null and b/cn/gallery/periscope-thumbnail.jpg differ diff --git a/cn/gallery/periscope.avif b/cn/gallery/periscope.avif new file mode 100644 index 00000000..30ad9c31 Binary files /dev/null and b/cn/gallery/periscope.avif differ diff --git a/cn/gallery/periscope.html b/cn/gallery/periscope.html new file mode 100644 index 00000000..2c96ca97 --- /dev/null +++ b/cn/gallery/periscope.html @@ -0,0 +1,172 @@ + + + + + + + 潜望镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    潜望镜

    +

    + 贡献者:Stas Fainer +

    +
    +

    这是一个由两面平镜和一些光线阻挡器制成的潜望镜模拟。

    +
    +

    + 在模拟器中打开 +

    + + + 潜望镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/periscope.jpg b/cn/gallery/periscope.jpg new file mode 100644 index 00000000..5681b079 Binary files /dev/null and b/cn/gallery/periscope.jpg differ diff --git a/cn/gallery/periscope.json b/cn/gallery/periscope.json new file mode 100644 index 00000000..7b82c92e --- /dev/null +++ b/cn/gallery/periscope.json @@ -0,0 +1,187 @@ +{ + "name": "潜望镜", + "version": 5, + "objs": [ + { + "type": "Blocker", + "p1": { + "x": 860, + "y": 440 + }, + "p2": { + "x": 860, + "y": 880 + } + }, + { + "type": "Blocker", + "p1": { + "x": 920, + "y": 380 + }, + "p2": { + "x": 920, + "y": 820 + } + }, + { + "type": "Blocker", + "p1": { + "x": 860, + "y": 380 + }, + "p2": { + "x": 920, + "y": 380 + } + }, + { + "type": "Blocker", + "p1": { + "x": 960, + "y": 880 + }, + "p2": { + "x": 860, + "y": 880 + } + }, + { + "type": "Mirror", + "p1": { + "x": 860, + "y": 380 + }, + "p2": { + "x": 920, + "y": 440 + } + }, + { + "type": "Mirror", + "p1": { + "x": 860, + "y": 820 + }, + "p2": { + "x": 920, + "y": 880 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 960, + "y": 820 + }, + "p2": { + "x": 960, + "y": 880 + }, + "focalLength": 162 + }, + { + "type": "AngleSource", + "p1": { + "x": 820, + "y": 400 + }, + "p2": { + "x": 880, + "y": 400 + }, + "brightness": 1, + "wavelength": "460", + "emisAngle": 7 + }, + { + "type": "AngleSource", + "p1": { + "x": 460, + "y": 440 + }, + "p2": { + "x": 760, + "y": 420 + }, + "brightness": 1, + "wavelength": "540", + "emisAngle": 7 + }, + { + "type": "AngleSource", + "p1": { + "x": 20, + "y": 420 + }, + "p2": { + "x": 1160, + "y": 400 + }, + "brightness": 1, + "wavelength": "620", + "emisAngle": "4" + }, + { + "type": "Blocker", + "p1": { + "x": 960, + "y": 820 + }, + "p2": { + "x": 920, + "y": 820 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 960.7142857142857, + "y": 931.2857142857144 + }, + "p2": { + "x": 960.7142857142857, + "y": 900.4285714285716 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 979.2571428571429, + "y": 962.2571428571428, + "text": "观察者的眼睛(非按比例)", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": -22.5428571428574, + "y": 360.7428571428573 + }, + "p4": { + "x": 1437, + "y": 999.1428571428573 + } + }, + { + "type": "CropBox", + "p1": { + "x": 605.5714285714284, + "y": 379.0285714285715 + }, + "p4": { + "x": 1206.8285715714292, + "y": 980.2857142857144 + } + } + ], + "width": 2189.314285714286, + "height": 1368.1714285714288, + "rayModeDensity": 20.031379119430994, + "origin": { + "x": 387.4285714285718, + "y": 4.1428571428570535 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/prisms-thumbnail.avif b/cn/gallery/prisms-thumbnail.avif new file mode 100644 index 00000000..a2f3d8af Binary files /dev/null and b/cn/gallery/prisms-thumbnail.avif differ diff --git a/cn/gallery/prisms-thumbnail.jpg b/cn/gallery/prisms-thumbnail.jpg new file mode 100644 index 00000000..8bbf1cb5 Binary files /dev/null and b/cn/gallery/prisms-thumbnail.jpg differ diff --git a/cn/gallery/prisms.avif b/cn/gallery/prisms.avif new file mode 100644 index 00000000..2e47db86 Binary files /dev/null and b/cn/gallery/prisms.avif differ diff --git a/cn/gallery/prisms.html b/cn/gallery/prisms.html new file mode 100644 index 00000000..87b4062b --- /dev/null +++ b/cn/gallery/prisms.html @@ -0,0 +1,172 @@ + + + + + + + 稜鏡 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    稜鏡

    +

    + 贡献者:Paul Falstad +

    +
    +

    此模拟演示了直角稜鏡(right-angle prism)、波罗稜鏡(Porro prism)、菱形稜鏡(rhomboid prism)、杜福稜鏡(Dove prism),和五面稜鏡(pentaprism)。

    +
    +

    + 在模拟器中打开 +

    + + + 稜鏡 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/prisms.jpg b/cn/gallery/prisms.jpg new file mode 100644 index 00000000..a74ad481 Binary files /dev/null and b/cn/gallery/prisms.jpg differ diff --git a/cn/gallery/prisms.json b/cn/gallery/prisms.json new file mode 100644 index 00000000..2f816280 --- /dev/null +++ b/cn/gallery/prisms.json @@ -0,0 +1,258 @@ +{ + "name": "稜鏡", + "version": 5, + "objs": [ + { + "type": "Beam", + "p1": { + "x": 505, + "y": 313 + }, + "p2": { + "x": 405, + "y": 313 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 360, + "y": 500, + "arc": false + }, + { + "x": 540, + "y": 680, + "arc": false + }, + { + "x": 720, + "y": 500, + "arc": false + } + ], + "refIndex": 2.03 + }, + { + "type": "Glass", + "path": [ + { + "x": 100, + "y": 500, + "arc": false + }, + { + "x": 100, + "y": 660, + "arc": false + }, + { + "x": 260, + "y": 500, + "arc": false + } + ], + "refIndex": 1.99 + }, + { + "type": "Beam", + "p1": { + "x": 220, + "y": 300 + }, + "p2": { + "x": 140, + "y": 300 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 140, + "y": 800, + "arc": false + }, + { + "x": 40, + "y": 880, + "arc": false + }, + { + "x": 320, + "y": 880, + "arc": false + }, + { + "x": 220, + "y": 800, + "arc": false + } + ], + "refIndex": 1.99 + }, + { + "type": "Beam", + "p1": { + "x": -20, + "y": 800 + }, + "p2": { + "x": -20, + "y": 860 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 820, + "y": 700, + "arc": false + }, + { + "x": 940, + "y": 580, + "arc": false + }, + { + "x": 940, + "y": 400, + "arc": false + }, + { + "x": 820, + "y": 520, + "arc": false + } + ], + "refIndex": 1.9 + }, + { + "type": "Beam", + "p1": { + "x": 760, + "y": 600 + }, + "p2": { + "x": 760, + "y": 680 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 440.0493827160492, + "y": 880.9382716049383, + "arc": false + }, + { + "x": 559.4719232606673, + "y": 880.382448432791, + "arc": false + }, + { + "x": 602.2719232606672, + "y": 784.582448432791, + "arc": false + }, + { + "x": 534.4219478165446, + "y": 724.9890531170365, + "arc": false + }, + { + "x": 439.4432521495561, + "y": 761.5664484327909, + "arc": false + } + ] + }, + { + "type": "Mirror", + "p1": { + "x": 560, + "y": 880 + }, + "p2": { + "x": 602.839702562603, + "y": 782.5683516656995 + } + }, + { + "type": "Mirror", + "p1": { + "x": 439.01234567901224, + "y": 760.9876543209878 + }, + "p2": { + "x": 535.776754841219, + "y": 723.6342460923621 + } + }, + { + "type": "TextLabel", + "x": 881.2010657279563, + "y": 455.37777777777796, + "text": "菱形", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 125.93333333333354, + "y": 683.7111111111112, + "text": "直角" + }, + { + "type": "TextLabel", + "x": 540.4155199286618, + "y": 465.99589160387313, + "text": "波罗", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 182.3182219815275, + "y": 914.7111111111111, + "text": "杜福", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 534.9816224388505, + "y": 911.7172702972307, + "text": "五面" + }, + { + "type": "CropBox", + "p1": { + "x": -106.94741301627386, + "y": 294.72011024224327 + }, + "p4": { + "x": 1041.0222368398374, + "y": 928.4542087549601 + } + }, + { + "type": "CropBox", + "p1": { + "x": 25.284585900599023, + "y": 320.18701373734467 + }, + "p4": { + "x": 728.5629208807081, + "y": 1023.4653487373444 + } + } + ], + "width": 1721.954474784167, + "height": 1207.7189234407724, + "origin": { + "x": 393.9398254803017, + "y": -7.727697778215429 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/rainbows-thumbnail.avif b/cn/gallery/rainbows-thumbnail.avif new file mode 100644 index 00000000..3ad88427 Binary files /dev/null and b/cn/gallery/rainbows-thumbnail.avif differ diff --git a/cn/gallery/rainbows-thumbnail.jpg b/cn/gallery/rainbows-thumbnail.jpg new file mode 100644 index 00000000..22c4ddb8 Binary files /dev/null and b/cn/gallery/rainbows-thumbnail.jpg differ diff --git a/cn/gallery/rainbows.avif b/cn/gallery/rainbows.avif new file mode 100644 index 00000000..118375d1 Binary files /dev/null and b/cn/gallery/rainbows.avif differ diff --git a/cn/gallery/rainbows.html b/cn/gallery/rainbows.html new file mode 100644 index 00000000..426c13e5 --- /dev/null +++ b/cn/gallery/rainbows.html @@ -0,0 +1,172 @@ + + + + + + + 彩虹 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    彩虹

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    本模拟演示了虹、霓以及亚历山大暗带是如何形成的。这里,我们以红、橙、黄、绿、青、蓝、紫的混色来近似阳光的光谱。对于虹/霓,离开雨滴的光线是由雨滴内部的一次/两次内部反射产生的(你可以通过将光线密调低并拖动雨滴来观察这一点)。请注意,这些并不是全内反射,因此出射光线的强度远低于入射光线。由于最小偏向角与波长有关,不同颜色的光线会在不同的角度堆积,于是彩虹中的颜色就产生了。远离最小偏向角时,光线不会堆积,所以所有颜色都很弱并混合在一起,使得在两彩虹之外的角度产生昏暗的白色(或“灰色”)。相较之下,虹与霓之间则没有这样的光线,于是形成亚历山大暗带。

    +
    +

    + 在模拟器中打开 +

    + + + 彩虹 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/rainbows.jpg b/cn/gallery/rainbows.jpg new file mode 100644 index 00000000..47a6b429 Binary files /dev/null and b/cn/gallery/rainbows.jpg differ diff --git a/cn/gallery/rainbows.json b/cn/gallery/rainbows.json new file mode 100644 index 00000000..daa7c91d --- /dev/null +++ b/cn/gallery/rainbows.json @@ -0,0 +1,234 @@ +{ + "name": "彩虹", + "version": 5, + "objs": [ + { + "type": "Beam", + "p1": { + "x": 72, + "y": 260 + }, + "p2": { + "x": 72, + "y": 300 + }, + "brightness": "40", + "wavelength": "420" + }, + { + "type": "Beam", + "p1": { + "x": 42, + "y": 260 + }, + "p2": { + "x": 42, + "y": 300 + }, + "brightness": "40", + "wavelength": "620" + }, + { + "type": "Beam", + "p1": { + "x": 47, + "y": 260 + }, + "p2": { + "x": 47, + "y": 300 + }, + "brightness": "20", + "wavelength": "600" + }, + { + "type": "Beam", + "p1": { + "x": 52, + "y": 260 + }, + "p2": { + "x": 52, + "y": 300 + }, + "brightness": "30", + "wavelength": "580" + }, + { + "type": "Beam", + "p1": { + "x": 57, + "y": 260 + }, + "p2": { + "x": 57, + "y": 300 + }, + "brightness": "45", + "wavelength": "540" + }, + { + "type": "Beam", + "p1": { + "x": 62, + "y": 260 + }, + "p2": { + "x": 62, + "y": 300 + }, + "brightness": "30", + "wavelength": "500" + }, + { + "type": "Beam", + "p1": { + "x": 67, + "y": 260 + }, + "p2": { + "x": 67, + "y": 300 + }, + "brightness": "45", + "wavelength": "460" + }, + { + "type": "CircleGlass", + "p1": { + "x": 642, + "y": 280 + }, + "p2": { + "x": 662, + "y": 280 + }, + "refIndex": 1.324, + "cauchyB": "0.00312" + }, + { + "type": "LineArrow", + "p1": { + "x": 640, + "y": 340 + }, + "p2": { + "x": 640, + "y": 320 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 280, + "y": 760 + }, + "p2": { + "x": 260, + "y": 740 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 180, + "y": 660 + }, + "p2": { + "x": 200, + "y": 680 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 162.2857142857143, + "y": 782.2857142857142 + }, + "p2": { + "x": 182.2857142857143, + "y": 762.2857142857142 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 220.53333333333342, + "y": 870.1523809523809, + "text": "以上是由单个雨滴产生的颜色。\n我们最终看到的彩虹是由天空中大量的雨滴产生的,\n每个都对观察者呈现单一一种颜色(在相应的角度)。" + }, + { + "type": "TextLabel", + "x": 290.8188289789092, + "y": 776.7034138036452, + "text": "霓" + }, + { + "type": "TextLabel", + "x": 115.7714285714286, + "y": 817.1428571428569, + "text": "亚历山大暗带" + }, + { + "type": "TextLabel", + "x": 639.8285714285715, + "y": 379.2571428571425, + "text": "雨滴", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 164.97100000000012, + "y": 644.3428571428567, + "text": "虹", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 87.82857142857156, + "y": 342.0571428571426, + "text": "阳光" + }, + { + "type": "CropBox", + "p1": { + "x": -103.4097424496623, + "y": 221.10341380364525 + }, + "p4": { + "x": 1279.390257550338, + "y": 1005.1034138036453 + } + }, + { + "type": "CropBox", + "p1": { + "x": 20.590257550337697, + "y": 153.10341380364525 + }, + "p4": { + "x": 704.5902575503377, + "y": 837.1034138036453 + } + } + ], + "width": 2074.2000000000003, + "height": 1475.4, + "rayModeDensity": 148.4131591025766, + "observer": { + "c": { + "x": 270.4, + "y": 519.5999999999999 + }, + "r": 20 + }, + "origin": { + "x": 449.10974244966235, + "y": 124.59658619635479 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/ray-relaying-thumbnail.avif b/cn/gallery/ray-relaying-thumbnail.avif new file mode 100644 index 00000000..3cd57305 Binary files /dev/null and b/cn/gallery/ray-relaying-thumbnail.avif differ diff --git a/cn/gallery/ray-relaying-thumbnail.jpg b/cn/gallery/ray-relaying-thumbnail.jpg new file mode 100644 index 00000000..d5111edd Binary files /dev/null and b/cn/gallery/ray-relaying-thumbnail.jpg differ diff --git a/cn/gallery/ray-relaying.avif b/cn/gallery/ray-relaying.avif new file mode 100644 index 00000000..eacedaf7 Binary files /dev/null and b/cn/gallery/ray-relaying.avif differ diff --git a/cn/gallery/ray-relaying.html b/cn/gallery/ray-relaying.html new file mode 100644 index 00000000..437b4ba7 --- /dev/null +++ b/cn/gallery/ray-relaying.html @@ -0,0 +1,172 @@ + + + + + + + 光线中继 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    光线中继

    +

    + 贡献者:Stas Fainer +

    +
    +

    由一系列理想相同透镜组成的光线中继模拟,其中每个透镜的焦距皆为 \(f\),且之间的距离为 \(d\)。若且唯若 \(d\leq 4f\) 时,可以保证光线轨迹不会发散。

    +
    +

    + 在模拟器中打开 +

    + + + 光线中继 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/ray-relaying.jpg b/cn/gallery/ray-relaying.jpg new file mode 100644 index 00000000..a0da8b92 Binary files /dev/null and b/cn/gallery/ray-relaying.jpg differ diff --git a/cn/gallery/ray-relaying.json b/cn/gallery/ray-relaying.json new file mode 100644 index 00000000..bb9cb6b5 --- /dev/null +++ b/cn/gallery/ray-relaying.json @@ -0,0 +1,139 @@ +{ + "name": "光线中继", + "version": 5, + "modules": { + "RayRelay": { + "numPoints": 2, + "params": [ + "f=-200:1:200:40", + "d=1:1:200:80", + "N=1:1:100:30" + ], + "objs": [ + { + "for": "i=0:1:N-1", + "type": "IdealLens", + "p1": { + "x": "`x_1+i*d`", + "y": "`y_1`" + }, + "p2": { + "x": "`x_2+i*d`", + "y": "`y_2`" + }, + "focalLength": "`f`" + } + ] + } + }, + "objs": [ + { + "type": "ModuleObj", + "module": "RayRelay", + "points": [ + { + "x": 300, + "y": 960 + }, + { + "x": 300, + "y": 1500 + } + ], + "params": { + "f": 40, + "d": 80, + "N": 37 + } + }, + { + "type": "Beam", + "p1": { + "x": 260, + "y": 1170 + }, + "p2": { + "x": 260, + "y": 1290 + } + }, + { + "type": "ModuleObj", + "module": "RayRelay", + "points": [ + { + "x": 300, + "y": 1770 + }, + { + "x": 300, + "y": 2310 + } + ], + "params": { + "f": 40, + "d": 152, + "N": 20 + } + }, + { + "type": "Beam", + "p1": { + "x": 260, + "y": 1980 + }, + "p2": { + "x": 260, + "y": 2100 + } + }, + { + "type": "Blocker", + "p1": { + "x": 3320, + "y": 960 + }, + "p2": { + "x": 3320, + "y": 2320 + } + }, + { + "type": "TextLabel", + "x": 250.47756948933397, + "y": 1644.0472096530923, + "text": "您可以选择任何透镜以查看和调整阵列的参数。", + "fontSize": 50 + }, + { + "type": "CropBox", + "p1": { + "x": 148.99185520361993, + "y": 904.1614953673782 + }, + "p4": { + "x": 3372.9918552036197, + "y": 2384.161495367378 + } + }, + { + "type": "CropBox", + "p1": { + "x": 224.99185520361993, + "y": 1666.161495367378 + }, + "p4": { + "x": 976.9918552036199, + "y": 2418.161495367378 + } + } + ], + "width": 4836, + "height": 3092, + "rayModeDensity": 0.25, + "origin": { + "x": 657.0081447963801, + "y": -98.16149536737817 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/reflect-thumbnail.avif b/cn/gallery/reflect-thumbnail.avif new file mode 100644 index 00000000..97a9d545 Binary files /dev/null and b/cn/gallery/reflect-thumbnail.avif differ diff --git a/cn/gallery/reflect-thumbnail.jpg b/cn/gallery/reflect-thumbnail.jpg new file mode 100644 index 00000000..4a0e9e4e Binary files /dev/null and b/cn/gallery/reflect-thumbnail.jpg differ diff --git a/cn/gallery/reflect.avif b/cn/gallery/reflect.avif new file mode 100644 index 00000000..50e34277 Binary files /dev/null and b/cn/gallery/reflect.avif differ diff --git a/cn/gallery/reflect.html b/cn/gallery/reflect.html new file mode 100644 index 00000000..66d22c21 --- /dev/null +++ b/cn/gallery/reflect.html @@ -0,0 +1,172 @@ + + + + + + + 反射与折射 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    反射与折射

    +

    + 贡献者:Paul Falstad +

    +
    +

    此模拟显示了光经过界面的反射和折射。

    +
    +

    + 在模拟器中打开 +

    + + + 反射与折射 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/reflect.jpg b/cn/gallery/reflect.jpg new file mode 100644 index 00000000..cb41df89 Binary files /dev/null and b/cn/gallery/reflect.jpg differ diff --git a/cn/gallery/reflect.json b/cn/gallery/reflect.json new file mode 100644 index 00000000..4c0db668 --- /dev/null +++ b/cn/gallery/reflect.json @@ -0,0 +1,63 @@ +{ + "name": "反射与折射", + "version": 5, + "objs": [ + { + "type": "PlaneGlass", + "p1": { + "x": 280, + "y": 560 + }, + "p2": { + "x": 740, + "y": 560 + }, + "refIndex": 2.5 + }, + { + "type": "PointSource", + "x": 563.3244586579999, + "y": 397.53135193200006 + }, + { + "type": "Protractor", + "p1": { + "x": 308.23277865800003, + "y": 560.506591932 + }, + "p2": { + "x": 307.95091897299994, + "y": 499.16042447499996 + } + }, + { + "type": "CropBox", + "p1": { + "x": 37.04909266900377, + "y": 257.235230311215 + }, + "p4": { + "x": 938.1283751493123, + "y": 682.0814462276336 + } + }, + { + "type": "CropBox", + "p1": { + "x": 237.5301860401246, + "y": 305.72704711939224 + }, + "p4": { + "x": 583.4867298357774, + "y": 651.6835911193923 + } + } + ], + "width": 1351.6189237204628, + "height": 875.3858571565729, + "origin": { + "x": 188.22072795107334, + "y": -31.965409691137864 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/reflecting-monochromator-thumbnail.avif b/cn/gallery/reflecting-monochromator-thumbnail.avif new file mode 100644 index 00000000..3a0d6a63 Binary files /dev/null and b/cn/gallery/reflecting-monochromator-thumbnail.avif differ diff --git a/cn/gallery/reflecting-monochromator-thumbnail.jpg b/cn/gallery/reflecting-monochromator-thumbnail.jpg new file mode 100644 index 00000000..9bd97bd1 Binary files /dev/null and b/cn/gallery/reflecting-monochromator-thumbnail.jpg differ diff --git a/cn/gallery/reflecting-monochromator.avif b/cn/gallery/reflecting-monochromator.avif new file mode 100644 index 00000000..7d34dac9 Binary files /dev/null and b/cn/gallery/reflecting-monochromator.avif differ diff --git a/cn/gallery/reflecting-monochromator.html b/cn/gallery/reflecting-monochromator.html new file mode 100644 index 00000000..4750b44c --- /dev/null +++ b/cn/gallery/reflecting-monochromator.html @@ -0,0 +1,170 @@ + + + + + + + 反射式单色仪 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    反射式单色仪

    +

    + 贡献者:James Garrard +

    +
    +

    这是一个反射式单色仪的模拟,其透过反射式衍射光栅与聚焦处的出射口,从多波长混合的光之中取得窄频宽的光。

    +
    +

    + 在模拟器中打开 +

    + + + 反射式单色仪 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/reflecting-monochromator.jpg b/cn/gallery/reflecting-monochromator.jpg new file mode 100644 index 00000000..906c1d90 Binary files /dev/null and b/cn/gallery/reflecting-monochromator.jpg differ diff --git a/cn/gallery/reflecting-monochromator.json b/cn/gallery/reflecting-monochromator.json new file mode 100644 index 00000000..1fc4e72c --- /dev/null +++ b/cn/gallery/reflecting-monochromator.json @@ -0,0 +1,316 @@ +{ + "name": "反射式单色仪", + "version": 5, + "objs": [ + { + "type": "DiffractionGrating", + "p1": { + "x": 360.6948362703425, + "y": 526.024136412217 + }, + "p2": { + "x": 475.8604455797841, + "y": 545.7923268593499 + }, + "lineDensity": 600, + "mirrored": true + }, + { + "type": "Mirror", + "p1": { + "x": 331.5434956601015, + "y": 519.9068253717573 + }, + "p2": { + "x": 364.49927901234054, + "y": 483.77458097351933 + } + }, + { + "type": "ParabolicMirror", + "p1": { + "x": 309.132325507247, + "y": 432.05884738500265 + }, + "p2": { + "x": 549.1323255072473, + "y": 432.05884738500265 + }, + "p3": { + "x": 429.1323255072472, + "y": 400.11587950232513 + } + }, + { + "type": "Mirror", + "p1": { + "x": 523.8219293327015, + "y": 520.7928819104918 + }, + "p2": { + "x": 483.8219293327016, + "y": 480.79288191049204 + } + }, + { + "type": "Blocker", + "p1": { + "x": 380.06894178927695, + "y": 420.59855495395067 + }, + "p2": { + "x": 457.4987893368847, + "y": 420.8458963824957 + } + }, + { + "type": "Aperture", + "p1": { + "x": 550.8896092023899, + "y": 456.90209450601355 + }, + "p2": { + "x": 550.8896092023899, + "y": 536.9020945060134 + }, + "p3": { + "x": 550.8896092023898, + "y": 495.90209450601344 + }, + "p4": { + "x": 550.8896092023898, + "y": 497.90209450601344 + } + }, + { + "type": "Beam", + "p1": { + "x": 162.9091131091131, + "y": 494.65147075147087 + }, + "p2": { + "x": 162.9091131091131, + "y": 507.2228993228999 + }, + "brightness": 1 + }, + { + "type": "Beam", + "p1": { + "x": 153.2146076146076, + "y": 494.6075147075149 + }, + "p2": { + "x": 153.2146076146076, + "y": 507.17894327894396 + }, + "brightness": 1, + "wavelength": 450 + }, + { + "type": "Beam", + "p1": { + "x": 171.8036186036186, + "y": 494.7171606171608 + }, + "p2": { + "x": 171.8036186036186, + "y": 507.28858918859 + }, + "brightness": 1, + "wavelength": 630 + }, + { + "type": "LineArrow", + "p1": { + "x": 369.15030252189524, + "y": 571.7877945473758 + }, + "p2": { + "x": 385.69850342374957, + "y": 535.7431706401763 + }, + "arrow": true + }, + { + "type": "Beam", + "p1": { + "x": 167.4124098124098, + "y": 494.6954267954269 + }, + "p2": { + "x": 167.4124098124098, + "y": 507.2668553668559 + }, + "brightness": 1, + "wavelength": 585 + }, + { + "type": "Beam", + "p1": { + "x": 157.8299922299922, + "y": 494.65147075147087 + }, + "p2": { + "x": 157.8299922299922, + "y": 507.2228993228998 + }, + "brightness": 1, + "wavelength": 495 + }, + { + "type": "Beam", + "p1": { + "x": 148.3257187257187, + "y": 494.60751470751484 + }, + "p2": { + "x": 148.3257187257187, + "y": 507.17894327894396 + }, + "brightness": 1, + "wavelength": 405 + }, + { + "type": "Aperture", + "p1": { + "x": 309.29709299285435, + "y": 478.5777466417769 + }, + "p2": { + "x": 309.60876356293545, + "y": 522.3284925598894 + }, + "p3": { + "x": 309.44936647962743, + "y": 499.9531322874008 + }, + "p4": { + "x": 309.45649007616237, + "y": 500.95310691426533 + } + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 264.2706890549245, + "y": 480.27027433966737, + "arc": false + }, + { + "x": 284.2706890549246, + "y": 480.27027433966737, + "arc": false + }, + { + "x": 294.2706890549245, + "y": 500.5154130266584, + "arc": true + }, + { + "x": 284.2706890549246, + "y": 520.7605517136493, + "arc": false + }, + { + "x": 264.2706890549245, + "y": 520.7605517136493, + "arc": false + }, + { + "x": 254.2706890549246, + "y": 500.5154130266584, + "arc": true + } + ] + }, + { + "type": "Blocker", + "p1": { + "x": 521.2723172919648, + "y": 522.372784334506 + }, + "p2": { + "x": 476.8689176458664, + "y": 477.58682994037025 + } + }, + { + "type": "Blocker", + "p1": { + "x": 365.39923830113577, + "y": 486.5580518502825 + }, + "p2": { + "x": 334.0772410363024, + "y": 521.3094648740392 + } + }, + { + "type": "Blocker", + "p1": { + "x": 525.1008331970219, + "y": 521.6311505053407 + }, + "p2": { + "x": 502.5864342917547, + "y": 559.1040401390266 + } + }, + { + "type": "TextLabel", + "x": 422.63028885046424, + "y": 368.8867243867245, + "text": "反射式单色仪", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 353.2183713067841, + "y": 589.0268650509676, + "text": "旋转衍射光栅\n以从多波长混合的光\n之中取得窄频宽的光", + "fontSize": 12 + }, + { + "type": "TextLabel", + "x": 559.8474148820138, + "y": 488.01320832883624, + "text": "出射口\n\n单色光", + "fontSize": 12 + }, + { + "type": "CropBox", + "p1": { + "x": 72.04158981092095, + "y": 323.442183580709 + }, + "p4": { + "x": 785.0470368733759, + "y": 671.4592958717983 + }, + "rayCountLimit": 3000 + }, + { + "type": "CropBox", + "p1": { + "x": 398.9481570655684, + "y": 404.5443586294322 + }, + "p4": { + "x": 559.5253250655683, + "y": 565.1215267565242 + }, + "rayCountLimit": 3000 + } + ], + "width": 1069.5081705936823, + "height": 704.5198358223167, + "rayModeDensity": 0.8607079764250578, + "origin": { + "x": 106.20977195469277, + "y": -145.1908218150953 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/resonator-thumbnail.avif b/cn/gallery/resonator-thumbnail.avif new file mode 100644 index 00000000..00350b14 Binary files /dev/null and b/cn/gallery/resonator-thumbnail.avif differ diff --git a/cn/gallery/resonator-thumbnail.jpg b/cn/gallery/resonator-thumbnail.jpg new file mode 100644 index 00000000..588f742e Binary files /dev/null and b/cn/gallery/resonator-thumbnail.jpg differ diff --git a/cn/gallery/resonator.avif b/cn/gallery/resonator.avif new file mode 100644 index 00000000..c7657d65 Binary files /dev/null and b/cn/gallery/resonator.avif differ diff --git a/cn/gallery/resonator.html b/cn/gallery/resonator.html new file mode 100644 index 00000000..7707bc74 --- /dev/null +++ b/cn/gallery/resonator.html @@ -0,0 +1,172 @@ + + + + + + + 平凹共振腔 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    平凹共振腔

    +

    + 贡献者:Mikhail Kochiev +

    +
    +

    这是一个平凹共振腔的演示。如果镜子间的距离大于曲率半径,共振腔将会不稳定。如果镜子间的距离小于或等于曲率半径,就会形成稳定的共振腔模式。

    +
    +

    + 在模拟器中打开 +

    + + + 平凹共振腔 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/resonator.jpg b/cn/gallery/resonator.jpg new file mode 100644 index 00000000..05ba604b Binary files /dev/null and b/cn/gallery/resonator.jpg differ diff --git a/cn/gallery/resonator.json b/cn/gallery/resonator.json new file mode 100644 index 00000000..65cbca88 --- /dev/null +++ b/cn/gallery/resonator.json @@ -0,0 +1,169 @@ +{ + "name": "平凹共振腔", + "version": 5, + "objs": [ + { + "type": "Mirror", + "p1": { + "x": 760, + "y": 400 + }, + "p2": { + "x": 760, + "y": 560 + } + }, + { + "type": "ArcMirror", + "p1": { + "x": 620, + "y": 400 + }, + "p2": { + "x": 620, + "y": 560 + }, + "p3": { + "x": 600, + "y": 480 + } + }, + { + "type": "PointSource", + "x": 660, + "y": 500 + }, + { + "type": "Ruler", + "p1": { + "x": 760, + "y": 600 + }, + "p2": { + "x": 620, + "y": 600 + } + }, + { + "type": "Ruler", + "p1": { + "x": 1140, + "y": 600 + }, + "p2": { + "x": 980, + "y": 600 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1140, + "y": 560 + }, + "p2": { + "x": 1140, + "y": 400 + } + }, + { + "type": "ArcMirror", + "p1": { + "x": 980, + "y": 560 + }, + "p2": { + "x": 980, + "y": 400 + }, + "p3": { + "x": 960, + "y": 480 + } + }, + { + "type": "PointSource", + "x": 1020, + "y": 500 + }, + { + "type": "Blocker", + "p1": { + "x": 760, + "y": 580 + }, + "p2": { + "x": 600, + "y": 580 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1140, + "y": 580 + }, + "p2": { + "x": 960, + "y": 580 + } + }, + { + "type": "TextLabel", + "x": 766.4047619047619, + "y": 431.2095238095238, + "text": "平面镜" + }, + { + "type": "TextLabel", + "x": 591.0547619047619, + "y": 427.0011904761904, + "text": "球形凹面镜", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 1210.205952380952, + "y": 484.77023809523774, + "text": "不稳定的共振腔" + }, + { + "type": "TextLabel", + "x": 520.9845238095238, + "y": 493.66071428571416, + "text": "稳定的共振腔", + "alignment": "right" + }, + { + "type": "CropBox", + "p1": { + "x": 68.51873706004118, + "y": 204.33312629399572 + }, + "p4": { + "x": 1721.3883022774326, + "y": 794.4200828157351 + }, + "rayCountLimit": 20000 + }, + { + "type": "CropBox", + "p1": { + "x": 592.8665631469977, + "y": 224.33312629399572 + }, + "p4": { + "x": 1153.214389233954, + "y": 784.6809522939959 + }, + "rayCountLimit": 2500 + } + ], + "width": 2479.304347826087, + "height": 1416.521739130435, + "origin": { + "x": 344.6986542443067, + "y": 208.88426501035215 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/retroreflectors-thumbnail.avif b/cn/gallery/retroreflectors-thumbnail.avif new file mode 100644 index 00000000..3e68f0c6 Binary files /dev/null and b/cn/gallery/retroreflectors-thumbnail.avif differ diff --git a/cn/gallery/retroreflectors-thumbnail.jpg b/cn/gallery/retroreflectors-thumbnail.jpg new file mode 100644 index 00000000..5710af4c Binary files /dev/null and b/cn/gallery/retroreflectors-thumbnail.jpg differ diff --git a/cn/gallery/retroreflectors.avif b/cn/gallery/retroreflectors.avif new file mode 100644 index 00000000..bfde996f Binary files /dev/null and b/cn/gallery/retroreflectors.avif differ diff --git a/cn/gallery/retroreflectors.html b/cn/gallery/retroreflectors.html new file mode 100644 index 00000000..cb9544af --- /dev/null +++ b/cn/gallery/retroreflectors.html @@ -0,0 +1,176 @@ + + + + + + + 回复反射器 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    回复反射器

    +

    + 贡献者:Stas Fainer, Yi-Ting Tu +

    +
    +

    这是两种回复反射器的模拟:

    +
      +
    1. 角隅反射器。
    2. +
    3. 猫眼回复反射器。
    4. +

    +
    +

    + 在模拟器中打开 +

    + + + 回复反射器 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/retroreflectors.jpg b/cn/gallery/retroreflectors.jpg new file mode 100644 index 00000000..aa72ef31 Binary files /dev/null and b/cn/gallery/retroreflectors.jpg differ diff --git a/cn/gallery/retroreflectors.json b/cn/gallery/retroreflectors.json new file mode 100644 index 00000000..b8b07005 --- /dev/null +++ b/cn/gallery/retroreflectors.json @@ -0,0 +1,279 @@ +{ + "name": "回复反射器", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 1561.8419961934637, + "y": 430 + }, + "p2": { + "x": 1700, + "y": 400 + }, + "controlPoints": [ + { + "newPoint": { + "x": 1589.8370290514372, + "y": 340.9312279475333 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 1579.690302034749, + "y": 359.2556410260939 + }, + "targetObjIndex": 6, + "dragContext": { + "part": 2 + } + } + ], + "transformation": "rotation" + }, + { + "type": "Handle", + "p1": { + "x": 1564.2100462571639, + "y": 720 + }, + "p2": { + "x": 1738.0410074234537, + "y": 674.1230222703612 + }, + "controlPoints": [ + { + "newPoint": { + "x": 1578.6178318367304, + "y": 625.2021567235963 + }, + "targetObjIndex": 13, + "dragContext": { + "part": 1 + } + }, + { + "newPoint": { + "x": 1572.2412181624272, + "y": 645.1540734704547 + }, + "targetObjIndex": 13, + "dragContext": { + "part": 2 + } + } + ], + "transformation": "rotation" + }, + { + "type": "CircleGlass", + "p1": { + "x": 1700, + "y": 399 + }, + "p2": { + "x": 1740, + "y": 399 + }, + "refIndex": 2 + }, + { + "type": "ArcMirror", + "p1": { + "x": 1700, + "y": 359 + }, + "p2": { + "x": 1700, + "y": 439 + }, + "p3": { + "x": 1740, + "y": 399 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1740, + "y": 679 + }, + "p2": { + "x": 1680, + "y": 619 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1680, + "y": 739 + }, + "p2": { + "x": 1740, + "y": 679 + } + }, + { + "type": "Beam", + "p1": { + "x": 1589.8370290514372, + "y": 340.9312279475333 + }, + "p2": { + "x": 1579.690302034749, + "y": 359.2556410260939 + } + }, + { + "type": "Blocker", + "p1": { + "x": 120, + "y": 539 + }, + "p2": { + "x": 1860, + "y": 539 + } + }, + { + "type": "CircleGlass", + "p1": { + "x": 980, + "y": 399 + }, + "p2": { + "x": 1020, + "y": 399 + }, + "refIndex": 2 + }, + { + "type": "ArcMirror", + "p1": { + "x": 980, + "y": 359 + }, + "p2": { + "x": 980, + "y": 439 + }, + "p3": { + "x": 1020, + "y": 399 + } + }, + { + "type": "Beam", + "p1": { + "x": 600, + "y": 655 + }, + "p2": { + "x": 600, + "y": 705 + } + }, + { + "type": "Mirror", + "p1": { + "x": 960, + "y": 739 + }, + "p2": { + "x": 1020, + "y": 679 + } + }, + { + "type": "Mirror", + "p1": { + "x": 1020, + "y": 679 + }, + "p2": { + "x": 960, + "y": 619 + } + }, + { + "type": "Beam", + "p1": { + "x": 1578.6178318367304, + "y": 625.2021567235963 + }, + "p2": { + "x": 1572.2412181624272, + "y": 645.1540734704547 + } + }, + { + "type": "Beam", + "p1": { + "x": 600, + "y": 375 + }, + "p2": { + "x": 600, + "y": 425 + } + }, + { + "type": "TextLabel", + "x": 1529.732420828533, + "y": 718.1146426079544, + "text": "拖曳此处\n可旋转光束", + "fontSize": 18, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 984.2775143314573, + "y": 273.79378187562054, + "text": "猫眼回覆反射器", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 976.2775143314573, + "y": 827.7937818756205, + "text": "角隅反射器", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": 499.5762324102069, + "y": 183.10971113826525 + }, + "p4": { + "x": 1914.3762324102067, + "y": 888.7097111382654 + } + }, + { + "type": "CropBox", + "p1": { + "x": 1253.576232410207, + "y": 279.10971113826525 + }, + "p4": { + "x": 1818.3762324102067, + "y": 843.9097111382653 + } + } + ], + "width": 2122.2, + "height": 1413, + "rayModeDensity": 1, + "origin": { + "x": -145.87623241020697, + "y": 170.59028886173468 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/rochester-cloak-thumbnail.avif b/cn/gallery/rochester-cloak-thumbnail.avif new file mode 100644 index 00000000..236190aa Binary files /dev/null and b/cn/gallery/rochester-cloak-thumbnail.avif differ diff --git a/cn/gallery/rochester-cloak-thumbnail.jpg b/cn/gallery/rochester-cloak-thumbnail.jpg new file mode 100644 index 00000000..ad60a269 Binary files /dev/null and b/cn/gallery/rochester-cloak-thumbnail.jpg differ diff --git a/cn/gallery/rochester-cloak.avif b/cn/gallery/rochester-cloak.avif new file mode 100644 index 00000000..57ceb900 Binary files /dev/null and b/cn/gallery/rochester-cloak.avif differ diff --git a/cn/gallery/rochester-cloak.html b/cn/gallery/rochester-cloak.html new file mode 100644 index 00000000..00e224dc --- /dev/null +++ b/cn/gallery/rochester-cloak.html @@ -0,0 +1,172 @@ + + + + + + + 罗切斯特斗篷 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    罗切斯特斗篷

    +

    + 贡献者:Stas Fainer +

    +
    +

    罗切斯特斗篷(Rochester cloak)是一种使用4个透镜构成的隐形装置。在这个模拟中,两个外部透镜的焦距为 \(f_1\),两个中间的透镜的焦距为 \(f_2\),使得焦距为 \(f_1\) 和 \(f_2\) 的相邻透镜之间的距离 \(t_1=f_1+f_2\),中间两个透镜之间的距离为 \(t_2=2f_2\frac{f1+f2}{f1-f2}\)。

    +
    +

    + 在模拟器中打开 +

    + + + 罗切斯特斗篷 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/rochester-cloak.jpg b/cn/gallery/rochester-cloak.jpg new file mode 100644 index 00000000..12a4d92e Binary files /dev/null and b/cn/gallery/rochester-cloak.jpg differ diff --git a/cn/gallery/rochester-cloak.json b/cn/gallery/rochester-cloak.json new file mode 100644 index 00000000..6e118d8a --- /dev/null +++ b/cn/gallery/rochester-cloak.json @@ -0,0 +1,222 @@ +{ + "name": "罗切斯特斗篷", + "version": 5, + "objs": [ + { + "type": "PointSource", + "x": 740, + "y": 680, + "brightness": 0.06, + "wavelength": 478 + }, + { + "type": "PointSource", + "x": 760, + "y": 660, + "brightness": 0.06, + "wavelength": 478 + }, + { + "type": "PointSource", + "x": 740, + "y": 720, + "brightness": 0.06, + "wavelength": 478 + }, + { + "type": "PointSource", + "x": 780, + "y": 660, + "brightness": 0.06, + "wavelength": 478 + }, + { + "type": "Blocker", + "p1": { + "x": -180, + "y": 560 + }, + "p2": { + "x": 1480, + "y": 560 + } + }, + { + "type": "Ruler", + "p1": { + "x": 620, + "y": 700 + }, + "p2": { + "x": 1220, + "y": 700 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 620, + "y": 640 + }, + "p2": { + "x": 620, + "y": 760 + }, + "focalLength": "150" + }, + { + "type": "IdealLens", + "p1": { + "x": 820, + "y": 640 + }, + "p2": { + "x": 820, + "y": 760 + }, + "focalLength": "50" + }, + { + "type": "IdealLens", + "p1": { + "x": 1020, + "y": 640 + }, + "p2": { + "x": 1020, + "y": 760 + }, + "focalLength": "50" + }, + { + "type": "IdealLens", + "p1": { + "x": 1220, + "y": 640 + }, + "p2": { + "x": 1220, + "y": 760 + }, + "focalLength": "150" + }, + { + "type": "AngleSource", + "p1": { + "x": 526.4045982887067, + "y": 659.4411080855376 + }, + "p2": { + "x": 580.524691358025, + "y": 661.8358024691357 + }, + "brightness": 0.35, + "wavelength": 610, + "emisAngle": 7 + }, + { + "type": "PointSource", + "x": 720, + "y": 660, + "brightness": 0.06, + "wavelength": 478 + }, + { + "type": "PointSource", + "x": 720, + "y": 740, + "brightness": 0.06, + "wavelength": 478 + }, + { + "type": "PointSource", + "x": 760, + "y": 740, + "brightness": 0.06, + "wavelength": 478 + }, + { + "type": "PointSource", + "x": 780, + "y": 740, + "brightness": 0.06, + "wavelength": 478 + }, + { + "type": "Blocker", + "p1": { + "x": -180, + "y": 800 + }, + "p2": { + "x": 1480, + "y": 800 + } + }, + { + "type": "TextLabel", + "x": 1304.41728, + "y": 677.86802, + "text": "观察者(看不到部分隐形区域中的物体,\n但是可以看到可视区域中的物体)" + }, + { + "type": "TextLabel", + "x": 731.627983238983, + "y": 791.2114110116363, + "text": "部分隐形区域", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 523.7611963945017, + "y": 689.1647798121937, + "text": "物体", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 744.0550188738907, + "y": 640, + "text": "8个物体", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 458.08969363158343, + "y": 719.2695194863097, + "text": "可视区域", + "alignment": "right" + }, + { + "type": "CropBox", + "p1": { + "x": 244.4551279550168, + "y": 508.5603792369109 + }, + "p4": { + "x": 1910.580075633622, + "y": 861.9808226838877 + } + }, + { + "type": "CropBox", + "p1": { + "x": 471.6539844566448, + "y": 442.5367799116515 + }, + "p4": { + "x": 974.5984616696502, + "y": 945.4812569116516 + } + } + ], + "width": 2499.1874215179078, + "height": 1186.4829172862794, + "rayModeDensity": 0.3501127617352208, + "origin": { + "x": 172.0761089646345, + "y": -92.02914231725958 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/sea-mirage-thumbnail.avif b/cn/gallery/sea-mirage-thumbnail.avif new file mode 100644 index 00000000..8ba98f92 Binary files /dev/null and b/cn/gallery/sea-mirage-thumbnail.avif differ diff --git a/cn/gallery/sea-mirage-thumbnail.jpg b/cn/gallery/sea-mirage-thumbnail.jpg new file mode 100644 index 00000000..82317dc1 Binary files /dev/null and b/cn/gallery/sea-mirage-thumbnail.jpg differ diff --git a/cn/gallery/sea-mirage.avif b/cn/gallery/sea-mirage.avif new file mode 100644 index 00000000..9b0e0009 Binary files /dev/null and b/cn/gallery/sea-mirage.avif differ diff --git a/cn/gallery/sea-mirage.html b/cn/gallery/sea-mirage.html new file mode 100644 index 00000000..8979ec2b --- /dev/null +++ b/cn/gallery/sea-mirage.html @@ -0,0 +1,170 @@ + + + + + + + 海市蜃楼 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    海市蜃楼

    +

    + 贡献者:chuangyu J +

    +
    +

    当一个物体在地平线以下时,有时我们仍然能看见其形成的上蜃景。此为这个效果的定性模拟。

    +
    +

    + 在模拟器中打开 +

    + + + 海市蜃楼 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/sea-mirage.jpg b/cn/gallery/sea-mirage.jpg new file mode 100644 index 00000000..10cf93d6 Binary files /dev/null and b/cn/gallery/sea-mirage.jpg differ diff --git a/cn/gallery/sea-mirage.json b/cn/gallery/sea-mirage.json new file mode 100644 index 00000000..82f664e3 --- /dev/null +++ b/cn/gallery/sea-mirage.json @@ -0,0 +1,399 @@ +{ + "name": "海市蜃楼", + "version": 5, + "objs": [ + { + "type": "CircleGrinGlass", + "p1": { + "x": 720.607843137255, + "y": 813.5434173669469 + }, + "p2": { + "x": 1263.0000000000002, + "y": 486.6666666666667 + }, + "refIndexFn": "1+e^{-\\frac{x^2+y^2}{200^2}}", + "origin": { + "x": 727.0000000000001, + "y": 806.6666666666666 + } + }, + { + "type": "AngleSource", + "p1": { + "x": 1113.226890756302, + "y": 798.067226890756 + }, + "p2": { + "x": 1104.984149953943, + "y": 783.5590178012463 + }, + "brightness": 3, + "emisAngle": 20 + }, + { + "type": "CircleBlocker", + "p1": { + "x": 723.464985994398, + "y": 813.5434173669469 + }, + "p2": { + "x": 935.0616246498602, + "y": 963.7955182072831 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 743.9666412019354, + "y": 837.4649859943974 + }, + "p2": { + "x": 953.9411764705883, + "y": 709.7338935574228 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 680.6078431372549, + "y": 836.4005602240894 + }, + "p2": { + "x": 510.6078431372549, + "y": 668.0672268907562 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 1363.7030812324929, + "y": 982.1148459383752 + }, + "p2": { + "x": 1136.5602240896355, + "y": 816.4005602240893 + }, + "arrow": true + }, + { + "type": "Drawing", + "strokes": [ + [ + 1006.5602240896355, + 768.067226890756, + 1008.2268907563022, + 768.067226890756, + 1011.5602240896355, + 769.7338935574227, + 1016.5602240896355, + 769.7338935574227, + 1019.8935574229688, + 771.4005602240893, + 1021.5602240896355, + 773.067226890756, + 1023.2268907563022, + 773.067226890756, + 1028.2268907563023, + 773.067226890756, + 1034.8935574229688, + 776.4005602240893, + 1039.8935574229688, + 776.4005602240893, + 1043.2268907563023, + 776.4005602240893, + 1044.8935574229688, + 776.4005602240893, + 1046.5602240896355, + 776.4005602240893, + 1048.2268907563023, + 778.067226890756, + 1051.5602240896355, + 778.067226890756, + 1053.2268907563023, + 779.7338935574227, + 1054.8935574229688, + 779.7338935574227, + 1056.5602240896355, + 779.7338935574227, + 1059.8935574229688, + 781.4005602240893, + 1063.2268907563023, + 783.067226890756, + 1071.5602240896355, + 784.7338935574227, + 1074.8935574229688, + 784.7338935574227, + 1078.2268907563023, + 786.4005602240893, + 1081.5602240896355, + 786.4005602240893, + 1084.8935574229688, + 788.067226890756, + 1086.5602240896355, + 788.067226890756, + 1088.2268907563023, + 788.067226890756, + 1088.2268907563023, + 789.7338935574227, + 1093.2268907563023, + 789.7338935574227, + 1094.8935574229688, + 789.7338935574227, + 1096.5602240896355, + 791.4005602240893, + 1098.2268907563023, + 791.4005602240893, + 1099.8935574229688, + 793.067226890756, + 1101.5602240896355, + 793.067226890756, + 1101.5602240896355, + 794.7338935574227, + 1103.2268907563023, + 796.4005602240893, + 1103.2268907563023, + 798.067226890756, + 1101.5602240896355, + 798.067226890756, + 1101.5602240896355, + 799.7338935574227, + 1098.2268907563023, + 799.7338935574227, + 1093.2268907563023, + 803.067226890756, + 1088.2268907563023, + 803.067226890756, + 1083.2268907563023, + 804.7338935574227, + 1076.5602240896355, + 806.4005602240893, + 1073.2268907563023, + 808.067226890756, + 1068.2268907563023, + 809.7338935574227, + 1063.2268907563023, + 809.7338935574227, + 1061.5602240896355, + 811.4005602240893, + 1056.5602240896355, + 813.067226890756, + 1051.5602240896355, + 813.067226890756, + 1048.2268907563023, + 814.7338935574227, + 1043.2268907563023, + 816.4005602240893, + 1036.5602240896355, + 816.4005602240893, + 1033.2268907563023, + 818.067226890756, + 1029.8935574229688, + 819.7338935574227, + 1026.5602240896355, + 821.4005602240893, + 1023.2268907563022, + 823.067226890756, + 1021.5602240896355, + 824.7338935574227, + 1019.8935574229688, + 824.7338935574227, + 1018.2268907563022, + 826.4005602240893, + 1016.5602240896355, + 828.067226890756, + 1014.8935574229688, + 828.067226890756, + 1011.5602240896355, + 829.7338935574227, + 1009.8935574229688, + 829.7338935574227, + 1008.2268907563022, + 831.4005602240893, + 1008.2268907563022, + 833.067226890756, + 1006.5602240896355, + 833.067226890756, + 1004.8935574229688, + 834.7338935574227, + 1003.2268907563022, + 834.7338935574227, + 1001.5602240896355, + 834.7338935574227, + 1001.5602240896355, + 836.4005602240893, + 999.8935574229688, + 836.4005602240893, + 999.8935574229688, + 838.067226890756, + 998.2268907563022, + 838.067226890756, + 994.8935574229688, + 839.7338935574227, + 993.2268907563022, + 841.4005602240893, + 991.5602240896355, + 843.067226890756, + 989.8935574229688, + 843.067226890756, + 988.2268907563022, + 843.067226890756, + 986.5602240896355, + 843.067226890756, + 984.8935574229688, + 843.067226890756 + ], + [ + 1008.2268907563022, + 771.4005602240893, + 1006.5602240896355, + 771.4005602240893, + 1004.8935574229688, + 771.4005602240893, + 1003.2268907563022, + 771.4005602240893, + 1001.5602240896355, + 771.4005602240893, + 999.8935574229688, + 771.4005602240893, + 998.2268907563022, + 771.4005602240893, + 996.5602240896355, + 771.4005602240893, + 994.8935574229688, + 769.7338935574227, + 993.2268907563022, + 769.7338935574227, + 991.5602240896355, + 769.7338935574227, + 989.8935574229688, + 769.7338935574227, + 988.2268907563022, + 769.7338935574227, + 988.2268907563022, + 768.067226890756, + 986.5602240896355, + 768.067226890756, + 984.8935574229688, + 768.067226890756, + 983.2268907563022, + 768.067226890756, + 981.5602240896355, + 768.067226890756 + ] + ] + }, + { + "type": "LineArrow", + "p1": { + "x": 1211.571683218742, + "y": 427.74509803921524 + }, + "p2": { + "x": 906.5716832187421, + "y": 509.41176470588186 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 719.1758859926426, + "y": 886.4005602240895, + "text": "地球表面", + "fontSize": 45, + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 106.57885182948164, + "y": 926.4005602240891, + "text": "大气层", + "fontSize": 45 + }, + { + "type": "TextLabel", + "x": 1323.9672553063717, + "y": 1041.4005602240893, + "text": "建筑/高山", + "fontSize": 45 + }, + { + "type": "TextLabel", + "x": 498.444692613495, + "y": 433.0375236878842, + "text": "观察者", + "fontSize": 45 + }, + { + "type": "TextLabel", + "x": 421.49756943801776, + "y": 187.11484593837534, + "text": "真空", + "fontSize": 45, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 1225.8608405672267, + "y": 423.8001403448874, + "text": "虚像", + "fontSize": 45 + }, + { + "type": "TextLabel", + "x": 361.3932540948824, + "y": 1421.4005602240893, + "text": "真空", + "fontSize": 45, + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 1150.2728836519623, + "y": 1404.2577030812322, + "text": "真空", + "fontSize": 45 + }, + { + "type": "CropBox", + "p1": { + "x": -590.1349129092536, + "y": 135.31585691431232 + }, + "p4": { + "x": 2145.98974053277, + "y": 1491.0809941816522 + } + }, + { + "type": "CropBox", + "p1": { + "x": 478.9190402567574, + "y": 369.04100901711183 + }, + "p4": { + "x": 1134.9190402567574, + "y": 1025.0410090171117 + } + } + ], + "width": 4104.1869801630355, + "height": 2723.827463988352, + "mode": "observer", + "rayModeDensity": 0.33147595696352583, + "imageModeDensity": 5.405948925141168, + "observer": { + "c": { + "x": 554.512605042017, + "y": 475.77871148459394 + }, + "r": 20 + }, + "origin": { + "x": 1274.1660762697595, + "y": 548.7153064461936 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/simple-double-gauss-lens-thumbnail.avif b/cn/gallery/simple-double-gauss-lens-thumbnail.avif new file mode 100644 index 00000000..aef87517 Binary files /dev/null and b/cn/gallery/simple-double-gauss-lens-thumbnail.avif differ diff --git a/cn/gallery/simple-double-gauss-lens-thumbnail.jpg b/cn/gallery/simple-double-gauss-lens-thumbnail.jpg new file mode 100644 index 00000000..a4523ce6 Binary files /dev/null and b/cn/gallery/simple-double-gauss-lens-thumbnail.jpg differ diff --git a/cn/gallery/simple-double-gauss-lens.avif b/cn/gallery/simple-double-gauss-lens.avif new file mode 100644 index 00000000..5533f979 Binary files /dev/null and b/cn/gallery/simple-double-gauss-lens.avif differ diff --git a/cn/gallery/simple-double-gauss-lens.html b/cn/gallery/simple-double-gauss-lens.html new file mode 100644 index 00000000..89c60749 --- /dev/null +++ b/cn/gallery/simple-double-gauss-lens.html @@ -0,0 +1,170 @@ + + + + + + + 简易双高斯透镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    简易双高斯透镜

    +

    + 贡献者:Alex +

    +
    +

    本模拟为一个简易双高斯透镜的演示。

    +
    +

    + 在模拟器中打开 +

    + + + 简易双高斯透镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/simple-double-gauss-lens.jpg b/cn/gallery/simple-double-gauss-lens.jpg new file mode 100644 index 00000000..0c2bf6e9 Binary files /dev/null and b/cn/gallery/simple-double-gauss-lens.jpg differ diff --git a/cn/gallery/simple-double-gauss-lens.json b/cn/gallery/simple-double-gauss-lens.json new file mode 100644 index 00000000..cbcc7a5f --- /dev/null +++ b/cn/gallery/simple-double-gauss-lens.json @@ -0,0 +1,526 @@ +{ + "name": "简易双高斯透镜", + "version": 5, + "objs": [ + { + "type": "SphericalLens", + "path": [ + { + "x": 120.9183745876242, + "y": 4.9135113709122376, + "arc": false + }, + { + "x": 150.2616161757574, + "y": 4.9135113709122376, + "arc": false + }, + { + "x": 127.06161617575735, + "y": 477.2135113709122, + "arc": true + }, + { + "x": 150.2616161757574, + "y": 949.513511370912, + "arc": false + }, + { + "x": 120.9183745876242, + "y": 949.513511370912, + "arc": false + }, + { + "x": 1.8616161757573764, + "y": 477.21351137091216, + "arc": true + } + ] + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 306.5301712017425, + "y": 63.6272893370123, + "arc": false + }, + { + "x": 335.5286731126283, + "y": 63.6272893370123, + "arc": false + }, + { + "x": 246.17493979743995, + "y": 477.38265839176216, + "arc": true + }, + { + "x": 335.5286731126283, + "y": 891.1380274465121, + "arc": false + }, + { + "x": 306.5301712017425, + "y": 891.1380274465121, + "arc": false + }, + { + "x": 132.53017120174252, + "y": 477.38265839176216, + "arc": true + } + ] + }, + { + "type": "Glass", + "path": [ + { + "x": 491.6099253738125, + "y": 859.5275748572643, + "arc": false + }, + { + "x": 491.32815578428017, + "y": 787.0217401352518, + "arc": false + }, + { + "x": 329.3424862810199, + "y": 477.0400398528249, + "arc": true + }, + { + "x": 491.6099253738125, + "y": 167.4072734206596, + "arc": false + }, + { + "x": 491.6099253738125, + "y": 92.896714653561, + "arc": false + }, + { + "x": 354.730140761807, + "y": 93.51079545557643, + "arc": false + }, + { + "x": 287.1198363129974, + "y": 477.0400398528249, + "arc": true + }, + { + "x": 355.0072343007983, + "y": 859.5275748572643, + "arc": false + } + ] + }, + { + "type": "Glass", + "path": [ + { + "x": 555.0665195876597, + "y": 856.1559796315654, + "arc": false + }, + { + "x": 554.8665195876597, + "y": 782.1559796315655, + "arc": false + }, + { + "x": 692.2665195876596, + "y": 477.1559796315655, + "arc": true + }, + { + "x": 554.8665195876596, + "y": 171.15597963156551, + "arc": false + }, + { + "x": 554.8665195876596, + "y": 99.9559796315655, + "arc": false + }, + { + "x": 743.2665195876596, + "y": 99.5559796315655, + "arc": false + }, + { + "x": 731.3111192088843, + "y": 477.2408812968077, + "arc": true + }, + { + "x": 743.4665195876596, + "y": 855.9559796315655, + "arc": false + } + ] + }, + { + "type": "Glass", + "path": [ + { + "x": 902.8862139284063, + "y": 59.87116664613308, + "arc": false + }, + { + "x": 923.8862139284062, + "y": 476.87116664613313, + "arc": true + }, + { + "x": 902.8862139284063, + "y": 892.8711666461334, + "arc": false + }, + { + "x": 927.2862139284064, + "y": 893.4711666461333, + "arc": false + }, + { + "x": 1042.086213928406, + "y": 476.87116664613313, + "arc": true + }, + { + "x": 928.0862139284063, + "y": 60.07116664613308, + "arc": false + } + ] + }, + { + "type": "Glass", + "path": [ + { + "x": 1078.8030812887725, + "y": 870.2034747920632, + "arc": false + }, + { + "x": 1047.0030812887726, + "y": 476.8034747920632, + "arc": true + }, + { + "x": 1078.835131110296, + "y": 83.20650963132117, + "arc": false + }, + { + "x": 1094.035131110296, + "y": 83.00650963132117, + "arc": false + }, + { + "x": 1109.2030812887726, + "y": 476.8034747920632, + "arc": true + }, + { + "x": 1094.4030812887727, + "y": 870.4034747920632, + "arc": false + } + ] + }, + { + "type": "Aperture", + "p1": { + "x": 493.31187677604976, + "y": -52.811990530366984 + }, + "p2": { + "x": 492.1375339296399, + "y": 1006.0853904395826 + }, + "p3": { + "x": 493.02968682693904, + "y": 201.6368690704776 + }, + "p4": { + "x": 492.4197238787507, + "y": 751.636530838738 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 744.4007656649395, + "y": 81.86394931925597, + "arc": false + }, + { + "x": 792.8007656649395, + "y": 81.46394931925596, + "arc": false + }, + { + "x": 921.6007656649396, + "y": 477.26394931925597, + "arc": true + }, + { + "x": 790.5890105126273, + "y": 871.1304566337509, + "arc": false + }, + { + "x": 744.4007656649396, + "y": 871.0639493192564, + "arc": false + }, + { + "x": 731.5210913079393, + "y": 476.8331177761846, + "arc": true + } + ] + }, + { + "type": "AngleSource", + "p1": { + "x": -4901.688123223949, + "y": 39.18800946963311 + }, + "p2": { + "x": -198.4525093603991, + "y": 411.0080523187663 + }, + "brightness": 5, + "emisAngle": 10 + }, + { + "type": "AngleSource", + "p1": { + "x": -4901.158212285212, + "y": 40.086839397875316 + }, + "p2": { + "x": -198.50965221754194, + "y": 411.0256125363265 + }, + "brightness": 5, + "wavelength": 460, + "emisAngle": 10 + }, + { + "type": "AngleSource", + "p1": { + "x": -4901.758212285213, + "y": 39.68683939787532 + }, + "p2": { + "x": -198.4525093603991, + "y": 411.0080523187663 + }, + "brightness": 5, + "wavelength": 650, + "emisAngle": 10 + }, + { + "type": "AngleSource", + "p1": { + "x": -4180.149661685487, + "y": 621.5256163072402 + }, + "p2": { + "x": -200.10965221754196, + "y": 503.8256125363265 + }, + "brightness": 10, + "wavelength": 450, + "emisAngle": 15 + }, + { + "type": "AngleSource", + "p1": { + "x": -4179.915355142356, + "y": 621.879724892154 + }, + "p2": { + "x": -200.10965221754196, + "y": 503.8256125363265 + }, + "brightness": 10, + "emisAngle": 15 + }, + { + "type": "AngleSource", + "p1": { + "x": -4179.97884720585, + "y": 621.8646596168718 + }, + "p2": { + "x": -200.10965221754196, + "y": 503.8256125363265 + }, + "brightness": 10, + "wavelength": 650, + "emisAngle": 15 + }, + { + "type": "Blocker", + "p1": { + "x": 54.94529648671778, + "y": -455.83671791856113 + }, + "p2": { + "x": 118.94529648671778, + "y": 8.163282081438865 + } + }, + { + "type": "Blocker", + "p1": { + "x": 119.94529648671778, + "y": 948.1632820814389 + }, + "p2": { + "x": 63.94529648671778, + "y": 1408.1632820814389 + } + }, + { + "type": "Blocker", + "p1": { + "x": 117.94529648671778, + "y": 952.1632820814389 + }, + "p2": { + "x": 491.9452964867178, + "y": 956.1632820814389 + } + }, + { + "type": "Blocker", + "p1": { + "x": 491.9452964867178, + "y": 2.163282081438865 + }, + "p2": { + "x": 116.94529648671778, + "y": 4.163282081438865 + } + }, + { + "type": "Detector", + "p1": { + "x": 3339.2398170346632, + "y": 565.4966154147722 + }, + "p2": { + "x": 3338.2398170346632, + "y": 743.4966154147722 + }, + "irradMap": true, + "binSize": 2 + }, + { + "type": "Detector", + "p1": { + "x": 3475.424017947905, + "y": 263.3708619901145 + }, + "p2": { + "x": 3472.424017947905, + "y": 520.3708619901145 + }, + "irradMap": true, + "binSize": 2 + }, + { + "type": "Blocker", + "p1": { + "x": 489.4708672629733, + "y": 876.7520571062493 + }, + "p2": { + "x": 900.13753392964, + "y": 880.7520571062493 + } + }, + { + "type": "Blocker", + "p1": { + "x": 494.8042005963065, + "y": 75.41872377291597 + }, + "p2": { + "x": 898.8042005963065, + "y": 75.41872377291595 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1098.8042005963066, + "y": 82.08539043958262 + }, + "p2": { + "x": 905.4708672629732, + "y": 52.75205710624929 + } + }, + { + "type": "Blocker", + "p1": { + "x": 902.8042005963065, + "y": 900.7520571062493 + }, + "p2": { + "x": 1096.1375339296396, + "y": 872.7520571062493 + } + }, + { + "type": "CropBox", + "p1": { + "x": -412.78113091428304, + "y": -468.41287329157103 + }, + "p4": { + "x": 3860.818869085717, + "y": 1437.1871267084289 + } + }, + { + "type": "CropBox", + "p1": { + "x": -39.18113091428313, + "y": -113.81287329157112 + }, + "p4": { + "x": 1160.8188690857169, + "y": 1086.1871267084289 + } + } + ], + "width": 6410.400000000001, + "height": 4042.4, + "rayModeDensity": 20.085536923187668, + "imageModeDensity": 0.34133188678306947, + "gridSize": 1, + "observer": { + "c": { + "x": 3532.7065387822026, + "y": 686.8089799896177 + }, + "r": 20 + }, + "origin": { + "x": 1481.1811309142831, + "y": 1536.8128732915711 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/single-ray-demo-thumbnail.avif b/cn/gallery/single-ray-demo-thumbnail.avif new file mode 100644 index 00000000..af9f3c26 Binary files /dev/null and b/cn/gallery/single-ray-demo-thumbnail.avif differ diff --git a/cn/gallery/single-ray-demo-thumbnail.jpg b/cn/gallery/single-ray-demo-thumbnail.jpg new file mode 100644 index 00000000..530dfc71 Binary files /dev/null and b/cn/gallery/single-ray-demo-thumbnail.jpg differ diff --git a/cn/gallery/single-ray-demo.avif b/cn/gallery/single-ray-demo.avif new file mode 100644 index 00000000..3f5c2b9a Binary files /dev/null and b/cn/gallery/single-ray-demo.avif differ diff --git a/cn/gallery/single-ray-demo.html b/cn/gallery/single-ray-demo.html new file mode 100644 index 00000000..2ff7a1c1 --- /dev/null +++ b/cn/gallery/single-ray-demo.html @@ -0,0 +1,172 @@ + + + + + + + 单一光线演示 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    单一光线演示

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    本模拟演示了一条光线的反射和折射。

    +
    +

    + 在模拟器中打开 +

    + + + 单一光线演示 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/single-ray-demo.jpg b/cn/gallery/single-ray-demo.jpg new file mode 100644 index 00000000..315f862c Binary files /dev/null and b/cn/gallery/single-ray-demo.jpg differ diff --git a/cn/gallery/single-ray-demo.json b/cn/gallery/single-ray-demo.json new file mode 100644 index 00000000..afe4d63c --- /dev/null +++ b/cn/gallery/single-ray-demo.json @@ -0,0 +1,272 @@ +{ + "name": "单一光线演示", + "version": 5, + "objs": [ + { + "type": "Glass", + "path": [ + { + "x": 120, + "y": 220, + "arc": false + }, + { + "x": 120, + "y": 360, + "arc": false + }, + { + "x": 680, + "y": 360, + "arc": false + }, + { + "x": 680, + "y": 220, + "arc": false + } + ] + }, + { + "type": "SingleRay", + "p1": { + "x": 642, + "y": 320 + }, + "p2": { + "x": 606, + "y": 260 + } + }, + { + "type": "SingleRay", + "p1": { + "x": 321, + "y": 320 + }, + "p2": { + "x": 241, + "y": 260 + } + }, + { + "type": "Mirror", + "p1": { + "x": 153.01718340158584, + "y": 446.79980548922975 + }, + "p2": { + "x": 1094.0104203930719, + "y": 460.27217562236774 + } + }, + { + "type": "ArcMirror", + "p1": { + "x": 1176, + "y": 671 + }, + "p2": { + "x": 144, + "y": 634 + }, + "p3": { + "x": 615, + "y": 599 + } + }, + { + "type": "SingleRay", + "p1": { + "x": 1055, + "y": 615 + }, + "p2": { + "x": 997, + "y": 513 + } + }, + { + "type": "Glass", + "path": [ + { + "x": 740, + "y": 340, + "arc": false + }, + { + "x": 740, + "y": 380, + "arc": false + }, + { + "x": 1060, + "y": 380, + "arc": false + }, + { + "x": 1060, + "y": 340, + "arc": false + } + ], + "refIndex": 2 + }, + { + "type": "Glass", + "path": [ + { + "x": 740, + "y": 180, + "arc": false + }, + { + "x": 740, + "y": 220, + "arc": false + }, + { + "x": 1060, + "y": 220, + "arc": false + }, + { + "x": 1060, + "y": 180, + "arc": false + } + ], + "refIndex": 1.2 + }, + { + "type": "Glass", + "path": [ + { + "x": 740, + "y": 220, + "arc": false + }, + { + "x": 740, + "y": 260, + "arc": false + }, + { + "x": 1060, + "y": 260, + "arc": false + }, + { + "x": 1060, + "y": 220, + "arc": false + } + ], + "refIndex": 1.4 + }, + { + "type": "Glass", + "path": [ + { + "x": 740, + "y": 260, + "arc": false + }, + { + "x": 740, + "y": 300, + "arc": false + }, + { + "x": 1060, + "y": 300, + "arc": false + }, + { + "x": 1060, + "y": 260, + "arc": false + } + ], + "refIndex": 1.6 + }, + { + "type": "Glass", + "path": [ + { + "x": 740, + "y": 300, + "arc": false + }, + { + "x": 740, + "y": 340, + "arc": false + }, + { + "x": 1060, + "y": 340, + "arc": false + }, + { + "x": 1060, + "y": 300, + "arc": false + } + ], + "refIndex": 1.8 + }, + { + "type": "SingleRay", + "p1": { + "x": 794, + "y": 100 + }, + "p2": { + "x": 834, + "y": 140 + } + }, + { + "type": "SingleRay", + "p1": { + "x": 487, + "y": 320 + }, + "p2": { + "x": 426, + "y": 250 + } + }, + { + "type": "CropBox", + "p1": { + "x": -50.03460410557148, + "y": 54.54985337243407 + }, + "p4": { + "x": 1244.3290322580647, + "y": 725.458944281525 + } + }, + { + "type": "CropBox", + "p1": { + "x": 326.3290322580649, + "y": 34.91348973607043 + }, + "p4": { + "x": 982.510850439883, + "y": 691.0953077360704 + } + } + ], + "width": 1941.5454545454545, + "height": 1318.090909090909, + "rayModeDensity": 0.14119688712824036, + "origin": { + "x": 373.62551319648054, + "y": 269.041055718475 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/solar-eclipses-thumbnail.avif b/cn/gallery/solar-eclipses-thumbnail.avif new file mode 100644 index 00000000..c8d65a98 Binary files /dev/null and b/cn/gallery/solar-eclipses-thumbnail.avif differ diff --git a/cn/gallery/solar-eclipses-thumbnail.jpg b/cn/gallery/solar-eclipses-thumbnail.jpg new file mode 100644 index 00000000..a2451ae2 Binary files /dev/null and b/cn/gallery/solar-eclipses-thumbnail.jpg differ diff --git a/cn/gallery/solar-eclipses.avif b/cn/gallery/solar-eclipses.avif new file mode 100644 index 00000000..c81cc203 Binary files /dev/null and b/cn/gallery/solar-eclipses.avif differ diff --git a/cn/gallery/solar-eclipses.html b/cn/gallery/solar-eclipses.html new file mode 100644 index 00000000..6746c0e1 --- /dev/null +++ b/cn/gallery/solar-eclipses.html @@ -0,0 +1,170 @@ + + + + + + + 日食 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    日食

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    本模拟演示了不同类型的日食。右上方的图中,月球的影子遮蔽了太阳,在中心产生了日全食,周围地区则是日偏食。右下方的图为日环食,其中由于月球距离地球较远,无法完全遮蔽太阳,在中心留下一个明亮的环(本二维模拟器中,这个“环”为阳光只来自太阳的最上方与最下方的部分),而周围地区也是日偏食。

    +
    +

    + 在模拟器中打开 +

    + + + 日食 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/solar-eclipses.jpg b/cn/gallery/solar-eclipses.jpg new file mode 100644 index 00000000..de8cc3a9 Binary files /dev/null and b/cn/gallery/solar-eclipses.jpg differ diff --git a/cn/gallery/solar-eclipses.json b/cn/gallery/solar-eclipses.json new file mode 100644 index 00000000..e5849c34 --- /dev/null +++ b/cn/gallery/solar-eclipses.json @@ -0,0 +1,264 @@ +{ + "name": "日食", + "version": 5, + "modules": { + "CircleSource": { + "numPoints": 1, + "params": [ + "r=0:1:500:100", + "N=1:1:4999:10", + "brightness=0.01:0.01:10:1" + ], + "objs": [ + { + "for": "theta=0:2pi/N:2pi-0.0001", + "type": "AngleSource", + "p1": { + "x": "`x_1+r*cos(theta)`", + "y": "`y_1+r*sin(theta)`" + }, + "p2": { + "x": "`x_1+(r+1)*cos(theta)`", + "y": "`y_1+(r+1)*sin(theta)`" + }, + "brightness": "`brightness/N`", + "emisAngle": 180 + } + ], + "maxLoopLength": 5000 + } + }, + "objs": [ + { + "type": "ModuleObj", + "module": "CircleSource", + "points": [ + { + "x": 383, + "y": 405 + } + ], + "params": { + "r": 236, + "N": 1000, + "brightness": 10 + } + }, + { + "type": "CircleBlocker", + "p1": { + "x": 1095, + "y": 234 + }, + "p2": { + "x": 1110, + "y": 251 + } + }, + { + "type": "CircleBlocker", + "p1": { + "x": 1291, + "y": 190 + }, + "p2": { + "x": 1406, + "y": 248 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 1221, + "y": 236 + }, + "p2": { + "x": 1170, + "y": 216 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 1214, + "y": 152 + }, + "p2": { + "x": 1165, + "y": 193 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 1226, + "y": 163 + }, + "p2": { + "x": 1180, + "y": 242 + }, + "arrow": true + }, + { + "type": "CircleBlocker", + "p1": { + "x": 1280, + "y": 639 + }, + "p2": { + "x": 1395, + "y": 697 + } + }, + { + "type": "CircleBlocker", + "p1": { + "x": 1044, + "y": 581 + }, + "p2": { + "x": 1059, + "y": 598 + } + }, + { + "type": "LineArrow", + "p1": { + "x": 1221, + "y": 587 + }, + "p2": { + "x": 1161, + "y": 653 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 1217, + "y": 577 + }, + "p2": { + "x": 1175, + "y": 578 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 1198, + "y": 676 + }, + "p2": { + "x": 1159, + "y": 616 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 1376.6666666666667, + "y": 415.6666666666667, + "text": "(非按比例)", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 385, + "y": 439, + "text": "太阳", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1043, + "y": 631, + "text": "月亮", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1226, + "y": 591, + "text": "日偏食", + "fontSize": 16 + }, + { + "type": "TextLabel", + "x": 1196, + "y": 704, + "text": "日环食", + "fontSize": 16 + }, + { + "type": "TextLabel", + "x": 1283, + "y": 666, + "text": "地球", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1294, + "y": 215, + "text": "地球", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1092, + "y": 280, + "text": "月亮", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1221, + "y": 154, + "text": "日偏食", + "fontSize": 16 + }, + { + "type": "TextLabel", + "x": 1226, + "y": 253, + "text": "日全食", + "fontSize": 16 + }, + { + "type": "CropBox", + "p1": { + "x": 95.99999999999994, + "y": 17.190476190476197 + }, + "p4": { + "x": 1456, + "y": 815.5238095238095 + } + }, + { + "type": "CropBox", + "p1": { + "x": 1027.6666666666667, + "y": -11.142857142857139 + }, + "p4": { + "x": 1427.6666666666667, + "y": 388.8571428571429 + } + } + ], + "width": 2040, + "height": 1478.3333333333335, + "rayModeDensity": 0.4263477291781528, + "origin": { + "x": 244.00000000000006, + "y": 322.8095238095238 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/specular-and-diffuse-reflection-thumbnail.avif b/cn/gallery/specular-and-diffuse-reflection-thumbnail.avif new file mode 100644 index 00000000..8c7bd59b Binary files /dev/null and b/cn/gallery/specular-and-diffuse-reflection-thumbnail.avif differ diff --git a/cn/gallery/specular-and-diffuse-reflection-thumbnail.jpg b/cn/gallery/specular-and-diffuse-reflection-thumbnail.jpg new file mode 100644 index 00000000..99474bee Binary files /dev/null and b/cn/gallery/specular-and-diffuse-reflection-thumbnail.jpg differ diff --git a/cn/gallery/specular-and-diffuse-reflection.avif b/cn/gallery/specular-and-diffuse-reflection.avif new file mode 100644 index 00000000..fed309fa Binary files /dev/null and b/cn/gallery/specular-and-diffuse-reflection.avif differ diff --git a/cn/gallery/specular-and-diffuse-reflection.html b/cn/gallery/specular-and-diffuse-reflection.html new file mode 100644 index 00000000..680ae311 --- /dev/null +++ b/cn/gallery/specular-and-diffuse-reflection.html @@ -0,0 +1,172 @@ + + + + + + + 镜面反射与漫反射 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    镜面反射与漫反射

    +

    + 贡献者:Steve Stonebraker +

    +
    +

    同一束光线照射在光滑表面和粗糙表面上,展示了镜面反射与漫反射之间的区别。

    +
    +

    + 在模拟器中打开 +

    + + + 镜面反射与漫反射 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/specular-and-diffuse-reflection.jpg b/cn/gallery/specular-and-diffuse-reflection.jpg new file mode 100644 index 00000000..040a448a Binary files /dev/null and b/cn/gallery/specular-and-diffuse-reflection.jpg differ diff --git a/cn/gallery/specular-and-diffuse-reflection.json b/cn/gallery/specular-and-diffuse-reflection.json new file mode 100644 index 00000000..1d8d066a --- /dev/null +++ b/cn/gallery/specular-and-diffuse-reflection.json @@ -0,0 +1,103 @@ +{ + "name": "镜面反射与漫反射", + "version": 5, + "objs": [ + { + "type": "Beam", + "p1": { + "x": 353, + "y": 376 + }, + "p2": { + "x": 291, + "y": 415 + } + }, + { + "type": "CustomMirror", + "p1": { + "x": 600, + "y": 540 + }, + "p2": { + "x": 860, + "y": 540 + }, + "eqn": "0.002\\cdot\\left(\\sin\\left(100x\\right)+\\sin\\left(70x\\right)-\\sin\\left(200x\\right)-\\sin\\left(631x\\right)+\\sin\\left(1391x\\right)-0.7\\cdot\\sin\\left(10000x\\right)\\right)" + }, + { + "type": "Mirror", + "p1": { + "x": 280, + "y": 540 + }, + "p2": { + "x": 560, + "y": 540 + } + }, + { + "type": "Beam", + "p1": { + "x": 670, + "y": 363 + }, + "p2": { + "x": 608, + "y": 402 + } + }, + { + "type": "TextLabel", + "x": 412.6823529411765, + "y": 574.3411764705883, + "text": "镜面反射", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 732.8823529411766, + "y": 576.3411764705883, + "text": "漫反射", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": 113.00480192076833, + "y": 309.7942376950782 + }, + "p4": { + "x": 1065.2048019207684, + "y": 613.9942376950781 + } + }, + { + "type": "CropBox", + "p1": { + "x": 607.1048019207683, + "y": 316.99423769507814 + }, + "p4": { + "x": 836.6048019207682, + "y": 546.4942376950781 + } + } + ], + "width": 1428.3000000000002, + "height": 780.3, + "rayModeDensity": 0.28311559552082877, + "imageModeDensity": 1.0124771987582037, + "observer": { + "c": { + "x": 886.4823529411765, + "y": 363.8411764705884 + }, + "r": 20 + }, + "origin": { + "x": 125.04519807923168, + "y": -71.7442376950782 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/spherical-lens-and-mirror-thumbnail.avif b/cn/gallery/spherical-lens-and-mirror-thumbnail.avif new file mode 100644 index 00000000..25061ca0 Binary files /dev/null and b/cn/gallery/spherical-lens-and-mirror-thumbnail.avif differ diff --git a/cn/gallery/spherical-lens-and-mirror-thumbnail.jpg b/cn/gallery/spherical-lens-and-mirror-thumbnail.jpg new file mode 100644 index 00000000..8edaa47f Binary files /dev/null and b/cn/gallery/spherical-lens-and-mirror-thumbnail.jpg differ diff --git a/cn/gallery/spherical-lens-and-mirror.avif b/cn/gallery/spherical-lens-and-mirror.avif new file mode 100644 index 00000000..6eace106 Binary files /dev/null and b/cn/gallery/spherical-lens-and-mirror.avif differ diff --git a/cn/gallery/spherical-lens-and-mirror.html b/cn/gallery/spherical-lens-and-mirror.html new file mode 100644 index 00000000..b7961fd2 --- /dev/null +++ b/cn/gallery/spherical-lens-and-mirror.html @@ -0,0 +1,172 @@ + + + + + + + 球面透镜与面镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    球面透镜与面镜

    +

    + 贡献者:Yi-Ting Tu +

    +
    +

    这个模拟演示了一束连续的光线穿过一个球面透镜和一个球面面镜。

    +
    +

    + 在模拟器中打开 +

    + + + 球面透镜与面镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/spherical-lens-and-mirror.jpg b/cn/gallery/spherical-lens-and-mirror.jpg new file mode 100644 index 00000000..2fd08433 Binary files /dev/null and b/cn/gallery/spherical-lens-and-mirror.jpg differ diff --git a/cn/gallery/spherical-lens-and-mirror.json b/cn/gallery/spherical-lens-and-mirror.json new file mode 100644 index 00000000..512c51a7 --- /dev/null +++ b/cn/gallery/spherical-lens-and-mirror.json @@ -0,0 +1,98 @@ +{ + "name": "球面透镜与面镜", + "version": 5, + "objs": [ + { + "type": "Beam", + "p1": { + "x": 179, + "y": 264 + }, + "p2": { + "x": 189, + "y": 430 + }, + "brightness": 0.41 + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 367.9709252676201, + "y": 212.0011723682411, + "arc": false + }, + { + "x": 368.02907473237985, + "y": 211.99882763175887, + "arc": false + }, + { + "x": 399.9215042051287, + "y": 334.91445547559965, + "arc": true + }, + { + "x": 378.02907473237985, + "y": 459.99882763175884, + "arc": false + }, + { + "x": 377.9709252676201, + "y": 460.0011723682411, + "arc": false + }, + { + "x": 348.3397828053595, + "y": 336.99436359655806, + "arc": true + } + ] + }, + { + "type": "ArcMirror", + "p1": { + "x": 973, + "y": 153 + }, + "p2": { + "x": 1095, + "y": 460 + }, + "p3": { + "x": 1076, + "y": 288 + } + }, + { + "type": "CropBox", + "p1": { + "x": 102.24193548387095, + "y": 110.62903225806454 + }, + "p4": { + "x": 1183.4032258064515, + "y": 652.2548387096774 + } + }, + { + "type": "CropBox", + "p1": { + "x": 146.92318971351244, + "y": -58.115384615384585 + }, + "p4": { + "x": 1130.0001127904354, + "y": 924.961538384616 + } + } + ], + "width": 1621.7419354838707, + "height": 1082.206451612903, + "rayModeDensity": 6.731513453339253, + "origin": { + "x": 168.04838709677418, + "y": 159.66129032258058 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/telescope-thumbnail.avif b/cn/gallery/telescope-thumbnail.avif new file mode 100644 index 00000000..0f8da343 Binary files /dev/null and b/cn/gallery/telescope-thumbnail.avif differ diff --git a/cn/gallery/telescope-thumbnail.jpg b/cn/gallery/telescope-thumbnail.jpg new file mode 100644 index 00000000..b7452f4b Binary files /dev/null and b/cn/gallery/telescope-thumbnail.jpg differ diff --git a/cn/gallery/telescope.avif b/cn/gallery/telescope.avif new file mode 100644 index 00000000..ad2649db Binary files /dev/null and b/cn/gallery/telescope.avif differ diff --git a/cn/gallery/telescope.html b/cn/gallery/telescope.html new file mode 100644 index 00000000..b72f0aed --- /dev/null +++ b/cn/gallery/telescope.html @@ -0,0 +1,173 @@ + + + + + + + 望远镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    望远镜

    +

    + 贡献者:Stas Fainer +

    +
    +

    模拟一个简单的望远镜,其由一个凸透镜和一个伽利略扩束镜组成,其作用为增加望远镜的角分辨率,从而更好地分离两颗遥远星体的入射光。

    +

    在下面的截图中,您可以比较有与没有扩束镜时望远镜的效果差异。

    +
    +

    + 在模拟器中打开 +

    + + + 望远镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/telescope.jpg b/cn/gallery/telescope.jpg new file mode 100644 index 00000000..7121a5a0 Binary files /dev/null and b/cn/gallery/telescope.jpg differ diff --git a/cn/gallery/telescope.json b/cn/gallery/telescope.json new file mode 100644 index 00000000..ed001012 --- /dev/null +++ b/cn/gallery/telescope.json @@ -0,0 +1,309 @@ +{ + "name": "望远镜", + "version": 5, + "objs": [ + { + "type": "Ruler", + "p1": { + "x": 700, + "y": 580 + }, + "p2": { + "x": 1200, + "y": 580 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 1120, + "y": 300 + }, + "p2": { + "x": 1120, + "y": 860 + }, + "focalLength": "-20" + }, + { + "type": "IdealLens", + "p1": { + "x": 700, + "y": 300 + }, + "p2": { + "x": 700, + "y": 860 + }, + "focalLength": "440" + }, + { + "type": "Beam", + "p1": { + "x": -1444.3486969386593, + "y": 143.9467395015365 + }, + "p2": { + "x": -1260, + "y": 2080 + } + }, + { + "type": "Beam", + "p1": { + "x": -760, + "y": -120 + }, + "p2": { + "x": -760, + "y": 1839.8127438231468 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 1160, + "y": 1120 + }, + "p2": { + "x": 1160, + "y": 1680 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1140, + "y": 1360 + }, + "p2": { + "x": 1140, + "y": 1100 + } + }, + { + "type": "Blocker", + "p1": { + "x": 540, + "y": 540 + }, + "p2": { + "x": 540, + "y": 280 + } + }, + { + "type": "Blocker", + "p1": { + "x": 540, + "y": 280 + }, + "p2": { + "x": 1480, + "y": 280 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1140, + "y": 1700 + }, + "p2": { + "x": 1480, + "y": 1700 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1480, + "y": 1700 + }, + "p2": { + "x": 1480, + "y": 1100 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 1160, + "y": 300 + }, + "p2": { + "x": 1160, + "y": 860 + } + }, + { + "type": "Blocker", + "p1": { + "x": 540, + "y": 880 + }, + "p2": { + "x": 540, + "y": 620 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1140, + "y": 1700 + }, + "p2": { + "x": 1140, + "y": 1440 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1260, + "y": 1680 + }, + "p2": { + "x": 1260, + "y": 1120 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1260, + "y": 860 + }, + "p2": { + "x": 1260, + "y": 300 + } + }, + { + "type": "Blocker", + "p1": { + "x": 540, + "y": 880 + }, + "p2": { + "x": 1480, + "y": 880 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1140, + "y": 1100 + }, + "p2": { + "x": 1480, + "y": 1100 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1480, + "y": 880 + }, + "p2": { + "x": 1480, + "y": 280 + } + }, + { + "type": "Blocker", + "p1": { + "x": -760, + "y": 840 + }, + "p2": { + "x": -760, + "y": 840 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1240, + "y": 1180 + }, + "p2": { + "x": 1240, + "y": 1180 + } + }, + { + "type": "TextLabel", + "x": -1448.6666666666663, + "y": 113.99999999999999, + "text": "来自星体2的光", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": -760.6666666666669, + "y": -146, + "text": "来自星体1的光", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1516, + "y": 392, + "text": "使用伽利略扩束镜(更好地分离两颗星体的角度)" + }, + { + "type": "TextLabel", + "x": 1257.3333333333333, + "y": 1691.3333333333333, + "text": "屏幕", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1257.3333333333337, + "y": 871.3333333333334, + "text": "屏幕", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1516, + "y": 1212, + "text": "没有扩束镜" + }, + { + "type": "CropBox", + "p1": { + "x": -1584.6526315789474, + "y": -193.93583959899763 + }, + "p4": { + "x": 2496.9473684210525, + "y": 2103.6641604010024 + } + }, + { + "type": "CropBox", + "p1": { + "x": 506.9473684210525, + "y": 151.66416040100228 + }, + "p4": { + "x": 1346.9473684210525, + "y": 991.6641604010024 + } + } + ], + "width": 6122.4, + "height": 4338.4, + "rayModeDensity": 0.10000000000000002, + "origin": { + "x": 2605.0526315789475, + "y": 1214.3358395989976 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/the-mirascope-thumbnail.avif b/cn/gallery/the-mirascope-thumbnail.avif new file mode 100644 index 00000000..3d9eb476 Binary files /dev/null and b/cn/gallery/the-mirascope-thumbnail.avif differ diff --git a/cn/gallery/the-mirascope-thumbnail.jpg b/cn/gallery/the-mirascope-thumbnail.jpg new file mode 100644 index 00000000..e97e2619 Binary files /dev/null and b/cn/gallery/the-mirascope-thumbnail.jpg differ diff --git a/cn/gallery/the-mirascope.avif b/cn/gallery/the-mirascope.avif new file mode 100644 index 00000000..f7d67a93 Binary files /dev/null and b/cn/gallery/the-mirascope.avif differ diff --git a/cn/gallery/the-mirascope.html b/cn/gallery/the-mirascope.html new file mode 100644 index 00000000..856efdc3 --- /dev/null +++ b/cn/gallery/the-mirascope.html @@ -0,0 +1,176 @@ + + + + + + + 幻象镜 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    幻象镜

    +

    + 贡献者:Mario Petitclerc +

    +
    +

    幻象镜 是一种有趣的光学幻觉演示装置,它利用两个面对面的抛物面镜来产生一个立体悬浮影像的幻觉。该装置由以下部件构成:

    +
      +
    1. 两个抛物面镜:大小完全相同,一个朝上,一个朝下,形成贝壳状结构。这些镜子被设计成让光聚焦于特定点。顶部的镜子在其顶点处有一个孔,让光线进入装置。
    2. +
    3. 一个小物体:放置在幻象镜内,通常位于顶部镜子的焦点附近,其非常接近底部镜子的顶点。
    4. +
    +

    当来自物体的光线在两个镜子之间反射时,它的方向会改变为形成一个看似逼真、立体的影像,悬浮于幻象镜的表面上方。这种幻象如此逼真,人们常常试图触摸影像,结果发现什么也没有。

    +

    幻象镜被广泛用于科学演示、玩具及新奇物品,以说明光学中反射和光线行为的原理。

    +
    +

    + 在模拟器中打开 +

    + + + 幻象镜 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/the-mirascope.jpg b/cn/gallery/the-mirascope.jpg new file mode 100644 index 00000000..65e13317 Binary files /dev/null and b/cn/gallery/the-mirascope.jpg differ diff --git a/cn/gallery/the-mirascope.json b/cn/gallery/the-mirascope.json new file mode 100644 index 00000000..536916b0 --- /dev/null +++ b/cn/gallery/the-mirascope.json @@ -0,0 +1,207 @@ +{ + "name": "幻象镜", + "version": 5, + "objs": [ + { + "type": "TextLabel", + "x": -520, + "y": 700, + "text": "物体" + }, + { + "type": "TextLabel", + "x": -640.923076923077, + "y": 360, + "text": "实像", + "alignment": "right" + }, + { + "type": "CustomMirror", + "p1": { + "x": -80, + "y": 720 + }, + "p2": { + "x": -580, + "y": 720 + }, + "eqn": "-\\frac{\\left(x-1\\right)^2}{5.5}" + }, + { + "type": "CustomMirror", + "p1": { + "x": -580, + "y": 720 + }, + "p2": { + "x": -1080, + "y": 720 + }, + "eqn": "-\\frac{\\left(x+1\\right)^2}{5.5}" + }, + { + "type": "CustomMirror", + "p1": { + "x": -80, + "y": 360 + }, + "p2": { + "x": -500, + "y": 360 + }, + "eqn": "\\frac{\\left(x-1.38\\right)^2}{6.55}" + }, + { + "type": "CustomMirror", + "p1": { + "x": -660, + "y": 360 + }, + "p2": { + "x": -1080, + "y": 360 + }, + "eqn": "\\frac{\\left(x+1.38\\right)^2}{6.55}" + }, + { + "type": "LineArrow", + "p1": { + "x": -580, + "y": 640 + }, + "p2": { + "x": -540, + "y": 680 + } + }, + { + "type": "LineArrow", + "p1": { + "x": -580, + "y": 700 + }, + "p2": { + "x": -540, + "y": 680 + } + }, + { + "type": "LineArrow", + "p1": { + "x": -580, + "y": 640 + }, + "p2": { + "x": -580, + "y": 700 + } + }, + { + "type": "AngleSource", + "p1": { + "x": -580, + "y": 700 + }, + "p2": { + "x": -620, + "y": 660 + }, + "wavelength": 610 + }, + { + "type": "AngleSource", + "p1": { + "x": -580, + "y": 640 + }, + "p2": { + "x": -540, + "y": 600 + }, + "wavelength": 480 + }, + { + "type": "AngleSource", + "p1": { + "x": -540, + "y": 680 + }, + "p2": { + "x": -500, + "y": 640 + } + }, + { + "type": "LineArrow", + "p1": { + "x": -577.8512752125674, + "y": 300.6867728934277 + }, + "p2": { + "x": -580.4512752125675, + "y": 372.08677289342774 + } + }, + { + "type": "LineArrow", + "p1": { + "x": -624.6512752125675, + "y": 349.2867728934277 + }, + "p2": { + "x": -581.4512752125675, + "y": 371.6867728934277 + } + }, + { + "type": "LineArrow", + "p1": { + "x": -624.2512752125674, + "y": 349.6867728934277 + }, + "p2": { + "x": -577.6512752125675, + "y": 301.2867728934277 + } + }, + { + "type": "CropBox", + "p1": { + "x": -1130.6301696514622, + "y": 229.40809246274705 + }, + "p4": { + "x": -35.03632349761554, + "y": 782.0025540012085 + } + }, + { + "type": "CropBox", + "p1": { + "x": -891.619302835792, + "y": 170.92437280378817 + }, + "p4": { + "x": -285.61930283579204, + "y": 776.9243728037882 + } + } + ], + "width": 1643.39076923077, + "height": 1100.3913846153848, + "rayModeDensity": 0.19602756340925195, + "imageModeDensity": 0.11889672735647365, + "observer": { + "c": { + "x": 900.7914884221375, + "y": 214.35343842603862 + }, + "r": 20 + }, + "origin": { + "x": 1404.528631189924, + "y": 44.490369075714625 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/the-principle-of-camera-imaging-thumbnail.avif b/cn/gallery/the-principle-of-camera-imaging-thumbnail.avif new file mode 100644 index 00000000..ed559519 Binary files /dev/null and b/cn/gallery/the-principle-of-camera-imaging-thumbnail.avif differ diff --git a/cn/gallery/the-principle-of-camera-imaging-thumbnail.jpg b/cn/gallery/the-principle-of-camera-imaging-thumbnail.jpg new file mode 100644 index 00000000..2773224e Binary files /dev/null and b/cn/gallery/the-principle-of-camera-imaging-thumbnail.jpg differ diff --git a/cn/gallery/the-principle-of-camera-imaging.avif b/cn/gallery/the-principle-of-camera-imaging.avif new file mode 100644 index 00000000..218698a3 Binary files /dev/null and b/cn/gallery/the-principle-of-camera-imaging.avif differ diff --git a/cn/gallery/the-principle-of-camera-imaging.html b/cn/gallery/the-principle-of-camera-imaging.html new file mode 100644 index 00000000..9edcd97b --- /dev/null +++ b/cn/gallery/the-principle-of-camera-imaging.html @@ -0,0 +1,170 @@ + + + + + + + 相机成像原理 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +
    +

    相机成像原理

    +

    + 贡献者:Liu Quanhong +

    +
    +

    本模板提供了一种交互式方法来学习相机成像原理,涵盖焦距、光圈、传感器灵敏度和背景模糊等基本主题,对学生和爱好者都有帮助。

    +
    +

    + 在模拟器中打开 +

    + + + 相机成像原理 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/the-principle-of-camera-imaging.jpg b/cn/gallery/the-principle-of-camera-imaging.jpg new file mode 100644 index 00000000..5d50a94d Binary files /dev/null and b/cn/gallery/the-principle-of-camera-imaging.jpg differ diff --git a/cn/gallery/the-principle-of-camera-imaging.json b/cn/gallery/the-principle-of-camera-imaging.json new file mode 100644 index 00000000..9a94c177 --- /dev/null +++ b/cn/gallery/the-principle-of-camera-imaging.json @@ -0,0 +1,148 @@ +{ + "name": "相机成像原理", + "version": 5, + "objs": [ + { + "type": "Blocker", + "p1": { + "x": 1060, + "y": 680 + }, + "p2": { + "x": 760, + "y": 680 + } + }, + { + "type": "Blocker", + "p1": { + "x": 1060, + "y": 400 + }, + "p2": { + "x": 760, + "y": 400 + } + }, + { + "type": "Ruler", + "p1": { + "x": 1063.0130526315788, + "y": 698.7886315789475 + }, + "p2": { + "x": -141.88572433595814, + "y": 694.8105495423805 + } + }, + { + "type": "Aperture", + "p1": { + "x": 760, + "y": 400 + }, + "p2": { + "x": 760, + "y": 680 + }, + "p3": { + "x": 760, + "y": 504.62570743711734 + }, + "p4": { + "x": 760, + "y": 575.3742925628826 + } + }, + { + "type": "TextLabel", + "x": 199.55899596667035, + "y": 367.9691032858637, + "text": "外面的物体", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 913.5043956043952, + "y": 392.9062845651083, + "text": "相机", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": -308.75172433595833, + "y": 297.48170743711717 + }, + "p4": { + "x": 1210.0014335587787, + "y": 803.2280232265911 + } + }, + { + "type": "CropBox", + "p1": { + "x": 729.7450202429152, + "y": 338.09417601318535 + }, + "p4": { + "x": 1158.518275664042, + "y": 766.8674310131854 + } + }, + { + "type": "IdealLens", + "p1": { + "x": 786.0224861903579, + "y": 405.29349691080154 + }, + "p2": { + "x": 786.3857418161693, + "y": 675.2470299262627 + }, + "focalLength": 155 + }, + { + "type": "PointSource", + "x": 432.30290724298936, + "y": 470.70739164764365, + "brightness": 0.7, + "wavelength": 434 + }, + { + "type": "PointSource", + "x": -191.5518295991161, + "y": 572.4623390160647, + "brightness": 0.7, + "wavelength": 620 + }, + { + "type": "Detector", + "p1": { + "x": 1059.5017824181016, + "y": 397.5102132692092 + }, + "p2": { + "x": 1059.5017824181016, + "y": 679.7590553744725 + }, + "irradMap": true, + "binSize": 4.5 + }, + { + "type": "TextLabel", + "x": 1066.2885915124061, + "y": 423.45358025984, + "text": "CMOS" + } + ], + "width": 2278.1297368421056, + "height": 1265.1228947368422, + "rayModeDensity": 1.224337645235499, + "origin": { + "x": 688.4400138096426, + "y": 82.20658203656706 + }, + "scale": 1, + "simulateColors": true +} \ No newline at end of file diff --git a/cn/gallery/transverse-and-longitudinal-magnification-thumbnail.avif b/cn/gallery/transverse-and-longitudinal-magnification-thumbnail.avif new file mode 100644 index 00000000..718ab0f5 Binary files /dev/null and b/cn/gallery/transverse-and-longitudinal-magnification-thumbnail.avif differ diff --git a/cn/gallery/transverse-and-longitudinal-magnification-thumbnail.jpg b/cn/gallery/transverse-and-longitudinal-magnification-thumbnail.jpg new file mode 100644 index 00000000..80b63e0b Binary files /dev/null and b/cn/gallery/transverse-and-longitudinal-magnification-thumbnail.jpg differ diff --git a/cn/gallery/transverse-and-longitudinal-magnification.avif b/cn/gallery/transverse-and-longitudinal-magnification.avif new file mode 100644 index 00000000..7bb35685 Binary files /dev/null and b/cn/gallery/transverse-and-longitudinal-magnification.avif differ diff --git a/cn/gallery/transverse-and-longitudinal-magnification.html b/cn/gallery/transverse-and-longitudinal-magnification.html new file mode 100644 index 00000000..410f2b74 --- /dev/null +++ b/cn/gallery/transverse-and-longitudinal-magnification.html @@ -0,0 +1,172 @@ + + + + + + + 横向和纵向放大率 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    横向和纵向放大率

    +

    + 贡献者:Stas Fainer +

    +
    +

    模拟焦距为 \(f\) 的理想透镜的横向和纵向放大率。横向(也称为线性)和纵向的放大率分别是 \(M_T=1-\frac{u}{f}\) 和 \(M_L=\frac{dv}{du}\),其中 \(u\) 和 \(v\) 分别是物体和图像距离我们的理想透镜的距离。另外,对于理想透镜,\(M_L=-(M_T)^2\)

    +
    +

    + 在模拟器中打开 +

    + + + 横向和纵向放大率 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/transverse-and-longitudinal-magnification.jpg b/cn/gallery/transverse-and-longitudinal-magnification.jpg new file mode 100644 index 00000000..b04f2c72 Binary files /dev/null and b/cn/gallery/transverse-and-longitudinal-magnification.jpg differ diff --git a/cn/gallery/transverse-and-longitudinal-magnification.json b/cn/gallery/transverse-and-longitudinal-magnification.json new file mode 100644 index 00000000..9b92d6ac --- /dev/null +++ b/cn/gallery/transverse-and-longitudinal-magnification.json @@ -0,0 +1,262 @@ +{ + "name": "横向和纵向放大率", + "version": 5, + "objs": [ + { + "type": "IdealLens", + "p1": { + "x": 940, + "y": 340 + }, + "p2": { + "x": 940, + "y": 860 + }, + "focalLength": "90" + }, + { + "type": "PointSource", + "x": 820, + "y": 400 + }, + { + "type": "PointSource", + "x": 820, + "y": 560 + }, + { + "type": "PointSource", + "x": 820, + "y": 520 + }, + { + "type": "PointSource", + "x": 820, + "y": 480 + }, + { + "type": "PointSource", + "x": 820, + "y": 440 + }, + { + "type": "PointSource", + "x": 120, + "y": 600 + }, + { + "type": "PointSource", + "x": 480, + "y": 600 + }, + { + "type": "PointSource", + "x": 660, + "y": 600 + }, + { + "type": "PointSource", + "x": 740, + "y": 600 + }, + { + "type": "PointSource", + "x": 800, + "y": 600 + }, + { + "type": "PointSource", + "x": 820, + "y": 600 + }, + { + "type": "TextLabel", + "x": -646.6666666666667, + "y": 470, + "text": "在这个例子中,我们有 y'_j - y'_k = M_T * (y_j - y_k),其中 j,k∈{0,1,2,3,4,5}。\n因此,例如点物体(x_0,y_0)的横向放大率是 M_T = -3,我们可以计算 -\n(x'_0 - x'_1)/(x_1 - x_0) ≈ -0.3699\n(x'_0 - x'_2)/(x_2 - x_0) ≈ -0.7297\n(x'_0 - x'_3)/(x_3 - x_0) ≈ -1.4211\n(x'_0 - x'_4)/(x_4 - x_0) ≈ -2.4545\n(x'_0 - x'_5)/(x_5 - x_0) = -5.4\n.\n.\n.\n(这个比值将趋近于纵向放大率:M_L = - (M_T)^2 = -9)" + }, + { + "type": "TextLabel", + "x": 826, + "y": 620, + "text": "(x_0,y_0)\n=(820,600)" + }, + { + "type": "TextLabel", + "x": 954, + "y": 604, + "text": "x'_1\n≈101.1" + }, + { + "type": "TextLabel", + "x": 1420, + "y": 380, + "text": "在(实)物上点击右键以查看其座标。\n绿色的方块是实际的点光源,黄色的方块是像。" + }, + { + "type": "TextLabel", + "x": 831, + "y": 416.66666666666674, + "text": "y_5=400" + }, + { + "type": "TextLabel", + "x": 660.0769230769232, + "y": 636.6666666666666, + "text": "x_3", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 831, + "y": 576.6666666666667, + "text": "y_1" + }, + { + "type": "TextLabel", + "x": 831, + "y": 536.6666666666667, + "text": "y_2" + }, + { + "type": "TextLabel", + "x": 831, + "y": 496.66666666666674, + "text": "y_3" + }, + { + "type": "TextLabel", + "x": 831, + "y": 456.66666666666674, + "text": "y_4" + }, + { + "type": "TextLabel", + "x": 1331, + "y": 1216.6666666666667, + "text": "y'_5=1200" + }, + { + "type": "TextLabel", + "x": 800.0769230769231, + "y": 626.6666666666667, + "text": "x_5", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 740.0769230769231, + "y": 636.6666666666667, + "text": "x_4", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 121.46153846153847, + "y": 636.6666666666666, + "text": "x_1=120", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 478.6923076923077, + "y": 636.6666666666667, + "text": "x_2", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1331, + "y": 736.6666666666667, + "text": "y'_1" + }, + { + "type": "TextLabel", + "x": 1331, + "y": 856.6666666666667, + "text": "y'_2" + }, + { + "type": "TextLabel", + "x": 1331, + "y": 976.6666666666667, + "text": "y'_3" + }, + { + "type": "TextLabel", + "x": 1331, + "y": 1096.6666666666667, + "text": "y'_4" + }, + { + "type": "TextLabel", + "x": 1186, + "y": 588, + "text": "x'_5" + }, + { + "type": "TextLabel", + "x": 1110, + "y": 594, + "text": "x'_4" + }, + { + "type": "TextLabel", + "x": 1047, + "y": 644, + "text": "x'_2", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1071, + "y": 584, + "text": "x'_3", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 1313, + "y": 600, + "text": "(x'_0,y'_0)=(360,600)" + }, + { + "type": "CropBox", + "p1": { + "x": -718.0452488687788, + "y": 238.79638009049768 + }, + "p4": { + "x": 2553.954751131221, + "y": 1314.7963800904977 + } + }, + { + "type": "CropBox", + "p1": { + "x": 701.9547511312212, + "y": 307.7963800904977 + }, + "p4": { + "x": 1405.9547511312212, + "y": 1011.7963800904977 + } + } + ], + "width": 4908, + "height": 2712, + "mode": "images", + "rayModeDensity": 0.48147546711372347, + "observer": { + "c": { + "x": 960, + "y": 468.49999999999994 + }, + "r": 20 + }, + "origin": { + "x": 1536.0452488687788, + "y": 579.2036199095023 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/gallery/vanishing-point-thumbnail.avif b/cn/gallery/vanishing-point-thumbnail.avif new file mode 100644 index 00000000..9256fb97 Binary files /dev/null and b/cn/gallery/vanishing-point-thumbnail.avif differ diff --git a/cn/gallery/vanishing-point-thumbnail.jpg b/cn/gallery/vanishing-point-thumbnail.jpg new file mode 100644 index 00000000..ef211e23 Binary files /dev/null and b/cn/gallery/vanishing-point-thumbnail.jpg differ diff --git a/cn/gallery/vanishing-point.avif b/cn/gallery/vanishing-point.avif new file mode 100644 index 00000000..7b14c747 Binary files /dev/null and b/cn/gallery/vanishing-point.avif differ diff --git a/cn/gallery/vanishing-point.html b/cn/gallery/vanishing-point.html new file mode 100644 index 00000000..e0cd8b63 --- /dev/null +++ b/cn/gallery/vanishing-point.html @@ -0,0 +1,173 @@ + + + + + + + 消失点 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    消失点

    +

    + 贡献者:Stas Fainer +

    +
    +

    有些光学系统将无限的平行线映射到影像平面上的一些线,使得这些线在一个点上相交,于是产生一种平行线在“无穷远处”相交的幻觉。这个交点被称为消失点。

    +

    考虑一个由焦距为 \(f\) 的理想透镜组成,位于 \(XY\) 平面上,光学轴与 \(X\)(水平)轴重合,透镜与 \(Y\) 轴重合的光学系统。对于斜率为 \(m\) ,位于 \(x<0\) 的线,其消失点之 \((x,y)\) 座标为 \((f,m f)\) 。

    +
    +

    + 在模拟器中打开 +

    + + + 消失点 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/vanishing-point.jpg b/cn/gallery/vanishing-point.jpg new file mode 100644 index 00000000..a42ec8df Binary files /dev/null and b/cn/gallery/vanishing-point.jpg differ diff --git a/cn/gallery/vanishing-point.json b/cn/gallery/vanishing-point.json new file mode 100644 index 00000000..52717965 --- /dev/null +++ b/cn/gallery/vanishing-point.json @@ -0,0 +1,323 @@ +{ + "name": "消失点", + "version": 5, + "objs": [ + { + "type": "IdealLens", + "p1": { + "x": 1000, + "y": 460 + }, + "p2": { + "x": 1000, + "y": 1340 + }, + "focalLength": "100" + }, + { + "type": "PointSource", + "x": -1520, + "y": 500 + }, + { + "type": "PointSource", + "x": -560, + "y": 500 + }, + { + "type": "PointSource", + "x": 420, + "y": 500, + "wavelength": "532" + }, + { + "type": "PointSource", + "x": 800, + "y": 500, + "wavelength": "532" + }, + { + "type": "PointSource", + "x": 800, + "y": 940, + "wavelength": "450" + }, + { + "type": "PointSource", + "x": 660, + "y": 1080, + "wavelength": "450" + }, + { + "type": "PointSource", + "x": 500, + "y": 1240, + "wavelength": "450" + }, + { + "type": "PointSource", + "x": 380, + "y": 1360, + "wavelength": "450" + }, + { + "type": "PointSource", + "x": 220, + "y": 1520, + "wavelength": "450" + }, + { + "type": "PointSource", + "x": -500, + "y": 2240, + "wavelength": "450" + }, + { + "type": "PointSource", + "x": -2180, + "y": 500 + }, + { + "type": "PointSource", + "x": -3620, + "y": 500 + }, + { + "type": "PointSource", + "x": 480, + "y": 940, + "wavelength": "580" + }, + { + "type": "PointSource", + "x": 340, + "y": 1080, + "wavelength": "580" + }, + { + "type": "PointSource", + "x": 200, + "y": 1220, + "wavelength": "580" + }, + { + "type": "PointSource", + "x": 60, + "y": 1360, + "wavelength": "580" + }, + { + "type": "PointSource", + "x": -140, + "y": 1560, + "wavelength": "580" + }, + { + "type": "PointSource", + "x": -2840, + "y": 4260, + "wavelength": "580" + }, + { + "type": "PointSource", + "x": 620, + "y": 500, + "wavelength": "532" + }, + { + "type": "PointSource", + "x": -40, + "y": 500 + }, + { + "type": "PointSource", + "x": 800, + "y": 640, + "wavelength": "660" + }, + { + "type": "PointSource", + "x": 620, + "y": 640, + "wavelength": "660" + }, + { + "type": "PointSource", + "x": 420, + "y": 640, + "wavelength": "660" + }, + { + "type": "PointSource", + "x": -40, + "y": 640, + "wavelength": "660" + }, + { + "type": "PointSource", + "x": -560, + "y": 640, + "wavelength": "660" + }, + { + "type": "PointSource", + "x": -1520, + "y": 640, + "wavelength": "660" + }, + { + "type": "PointSource", + "x": -2180, + "y": 640, + "wavelength": "660" + }, + { + "type": "PointSource", + "x": -3620, + "y": 640, + "wavelength": "660" + }, + { + "type": "Blocker", + "p1": { + "x": 1480, + "y": 1480 + }, + "p2": { + "x": 1480, + "y": 420 + } + }, + { + "type": "Blocker", + "p1": { + "x": -1820, + "y": 420 + }, + "p2": { + "x": 1480, + "y": 420 + } + }, + { + "type": "PointSource", + "x": -280, + "y": 1700, + "wavelength": "580" + }, + { + "type": "PointSource", + "x": 80, + "y": 1660, + "wavelength": "450" + }, + { + "type": "PointSource", + "x": -840, + "y": 2260, + "wavelength": "580" + }, + { + "type": "LineArrow", + "p1": { + "x": 1080, + "y": 800 + }, + "p2": { + "x": 1100, + "y": 800 + }, + "arrow": true + }, + { + "type": "LineArrow", + "p1": { + "x": 1080, + "y": 900 + }, + "p2": { + "x": 1100, + "y": 900 + }, + "arrow": true + }, + { + "type": "TextLabel", + "x": 1560, + "y": 580, + "text": "你可以验证一对斜率为 m 的平行线,经过理想透镜收敛到座标 (f,m∙f),\n通过点击“网格”按钮,并注意到每个网格单元的尺寸为20乘以20。\n你也可以验证改变理想透镜的焦距 f 时,收敛点(消失点)会如何受到影响。" + }, + { + "type": "TextLabel", + "x": 570.5714285714287, + "y": 1024, + "text": "这对平行线聚集到点B", + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 871.7142857142858, + "y": 588, + "text": "这对平行线聚集到点A", + "alignment": "right" + }, + { + "type": "TextLabel", + "x": 1054, + "y": 913.3333333333333, + "text": "A" + }, + { + "type": "TextLabel", + "x": 1054, + "y": 813.3333333333333, + "text": "B" + }, + { + "type": "TextLabel", + "x": -860, + "y": 1100, + "text": "注意这些平行线实际上并不是无穷大。" + }, + { + "type": "CropBox", + "p1": { + "x": -919.9350666565667, + "y": -23.413929707619786 + }, + "p4": { + "x": 1336.0649333434333, + "y": 1387.7860702923804 + } + }, + { + "type": "CropBox", + "p1": { + "x": 176.06493334343327, + "y": 427.18607029238 + }, + "p4": { + "x": 1156.0649333434333, + "y": 1407.18607029238 + } + } + ], + "width": 3384, + "height": 2539.2000000000003, + "mode": "images", + "rayModeDensity": 0.049787068367863944, + "observer": { + "c": { + "x": 314, + "y": 901 + }, + "r": 20 + }, + "origin": { + "x": 1483.9350666565667, + "y": 587.4139297076198 + }, + "scale": 1, + "simulateColors": true, + "backgroundImage": "vanishing-point-background.png" +} \ No newline at end of file diff --git a/cn/gallery/zoom-lens-thumbnail.avif b/cn/gallery/zoom-lens-thumbnail.avif new file mode 100644 index 00000000..a0e85aba Binary files /dev/null and b/cn/gallery/zoom-lens-thumbnail.avif differ diff --git a/cn/gallery/zoom-lens-thumbnail.jpg b/cn/gallery/zoom-lens-thumbnail.jpg new file mode 100644 index 00000000..3e962a5a Binary files /dev/null and b/cn/gallery/zoom-lens-thumbnail.jpg differ diff --git a/cn/gallery/zoom-lens.avif b/cn/gallery/zoom-lens.avif new file mode 100644 index 00000000..5484d5bd Binary files /dev/null and b/cn/gallery/zoom-lens.avif differ diff --git a/cn/gallery/zoom-lens.html b/cn/gallery/zoom-lens.html new file mode 100644 index 00000000..eaecb286 --- /dev/null +++ b/cn/gallery/zoom-lens.html @@ -0,0 +1,172 @@ + + + + + + + 变焦镜头 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + + +
    +
    +

    变焦镜头

    +

    + 贡献者:Paul Falstad +

    +
    +

    这个模拟展示了一个变焦镜头(Zoom Lens),您可以通过拖动中间的凹透镜来变焦。

    +
    +

    + 在模拟器中打开 +

    + + + 变焦镜头 + +
    +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/cn/gallery/zoom-lens.jpg b/cn/gallery/zoom-lens.jpg new file mode 100644 index 00000000..9afb3ea6 Binary files /dev/null and b/cn/gallery/zoom-lens.jpg differ diff --git a/cn/gallery/zoom-lens.json b/cn/gallery/zoom-lens.json new file mode 100644 index 00000000..473549d2 --- /dev/null +++ b/cn/gallery/zoom-lens.json @@ -0,0 +1,255 @@ +{ + "name": "变焦镜头", + "version": 5, + "objs": [ + { + "type": "Handle", + "p1": { + "x": 619.5752895752897, + "y": 598.6563706563707 + }, + "p2": { + "x": 620.1666666666666, + "y": 460.5 + }, + "controlPoints": [ + { + "dragContext": { + "part": 1, + "index": 0, + "requiresObjBarUpdate": true + }, + "targetObjIndex": 4, + "newPoint": { + "x": 603, + "y": 361 + } + }, + { + "dragContext": { + "part": 1, + "index": 1, + "requiresObjBarUpdate": true + }, + "targetObjIndex": 4, + "newPoint": { + "x": 637, + "y": 361 + } + }, + { + "dragContext": { + "part": 1, + "index": 5, + "requiresObjBarUpdate": true + }, + "targetObjIndex": 4, + "newPoint": { + "x": 613, + "y": 460.5 + } + }, + { + "dragContext": { + "part": 1, + "index": 2, + "requiresObjBarUpdate": true + }, + "targetObjIndex": 4, + "newPoint": { + "x": 628, + "y": 460.5 + } + }, + { + "dragContext": { + "part": 1, + "index": 4, + "requiresObjBarUpdate": true + }, + "targetObjIndex": 4, + "newPoint": { + "x": 603, + "y": 560 + } + }, + { + "dragContext": { + "part": 1, + "index": 3, + "requiresObjBarUpdate": true + }, + "targetObjIndex": 4, + "newPoint": { + "x": 637, + "y": 560 + } + } + ], + "transformation": "xTranslation" + }, + { + "type": "Beam", + "p1": { + "x": 140, + "y": 420 + }, + "p2": { + "x": 140, + "y": 500 + } + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 373, + "y": 358, + "arc": false + }, + { + "x": 387, + "y": 358, + "arc": false + }, + { + "x": 392, + "y": 459, + "arc": true + }, + { + "x": 387, + "y": 560, + "arc": false + }, + { + "x": 373, + "y": 560, + "arc": false + }, + { + "x": 369, + "y": 459, + "arc": true + } + ], + "refIndex": 1.7 + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 854, + "y": 360, + "arc": false + }, + { + "x": 866, + "y": 360, + "arc": false + }, + { + "x": 872.0143851941782, + "y": 460, + "arc": true + }, + { + "x": 866, + "y": 560, + "arc": false + }, + { + "x": 854, + "y": 560, + "arc": false + }, + { + "x": 852, + "y": 460, + "arc": true + } + ], + "refIndex": 1.82 + }, + { + "type": "SphericalLens", + "path": [ + { + "x": 603, + "y": 361, + "arc": false + }, + { + "x": 637, + "y": 361, + "arc": false + }, + { + "x": 628, + "y": 460.5, + "arc": true + }, + { + "x": 637, + "y": 560, + "arc": false + }, + { + "x": 603, + "y": 560, + "arc": false + }, + { + "x": 613, + "y": 460.5, + "arc": true + } + ], + "refIndex": 2.01 + }, + { + "type": "TextLabel", + "x": 617.9729729729733, + "y": 639.2972972972968, + "text": "拖拽此处可移动透镜", + "fontSize": 16, + "alignment": "center" + }, + { + "type": "TextLabel", + "x": 622.4594594594595, + "y": 326, + "text": "← 变焦 →", + "alignment": "center" + }, + { + "type": "CropBox", + "p1": { + "x": 97.25559845559837, + "y": 282.81544401544403 + }, + "p4": { + "x": 1056.2316602316603, + "y": 653.4555984555985 + } + }, + { + "type": "CropBox", + "p1": { + "x": 351.6602316602316, + "y": 198.29664702296276 + }, + "p4": { + "x": 892.9459459459459, + "y": 739.5823610229628 + } + } + ], + "width": 1438.4640926640927, + "height": 850.1281853281855, + "origin": { + "x": 142.4884169884171, + "y": -43.071428571428555 + }, + "scale": 1 +} \ No newline at end of file diff --git a/cn/index.html b/cn/index.html new file mode 100644 index 00000000..d09e0aa9 --- /dev/null +++ b/cn/index.html @@ -0,0 +1,426 @@ + + + + + + + 射线光学模拟 - PhyDemo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +

    射线光学模拟

    +

    + 建立二维几何光学场景,并实时模拟光线行为。
    完全免费,免下载,源代码公开于 GitHub。 +

    +

    + 启动程序 +

    +
    +
    + + +
    +
    +
    +

    工具

    +
    + 单一光线 +
    +

    单一光线

    + 由两点决定一条光线。 +
    +
    +
    + 光束 +
    +

    光束

    + 由一线段产生平行或发散光束,密度由「光线密度」滑杆决定。 +
    +
    +
    + 点光源 +
    +

    点光源

    + 由一点向四周发射光线,数量由「光线密度」滑杆决定。 +
    +
    +
    + 镜子 +
    +

    镜子

    + 模拟光线射到镜子时的反射。 +
    +
    +
    + 镜子(曲线) +
    +

    镜子(曲线)

    + 曲线形的镜子。可选圆弧、抛物线,或自定义函数 y = f(x)。 +
    +
    +
    + 理想曲面镜 +
    +

    理想曲面镜

    + 完全符合面镜公式(1/p + 1/q = 1/f)的理想化「曲面」镜,可直接设定其焦距。 +
    +
    +
    + 分光镜 +
    +

    分光镜

    + 能穿透一个比例的光的镜子。 +
    +
    +
    + 透光物 +
    +

    透光物

    + 模拟光线经过透光物体界面时的反射与折射。 +
    +
    +
    + 透光物(其他形状) +
    +

    透光物(其他形状)

    + 任何由线段与圆弧组成的透光物,或自定义不等式 f(x) < y < g(x)。 +
    +
    +
    + 渐变折射率透光物 +
    +

    渐变折射率透光物

    + 折射率为自订函数 n(x,y) 的材料。 +
    +
    +
    + 理想透镜 +
    +

    理想透镜

    + 完全符合薄透镜公式(1/p + 1/q = 1/f)的理想化透镜,可直接设定其焦距。 +
    +
    +
    + 遮光物 +
    +

    遮光物

    + 线段形状的吸光片,光线射到其上后就不会再射出。 +
    +
    +
    + 衍射光栅 +
    +

    衍射光栅

    + 将光线依波长分割成不同角度的衍射光栅。 +
    +
    +
    + 直尺 +
    +

    直尺

    + 指定原点与另一点。 +
    +
    +
    + 量角器 +
    +

    量角器

    + 指定圆心和圆周上一点作为零度位置。刻度单位为度。 +
    +
    +
    + 探测器 +
    +

    探测器

    + 测量通过一线段的能量流率(P)、垂直动量流率(F⊥)与水平动量流率(F∥)。单位为任意。 +
    +
    +
    +
    +
    +
    +

    视图

    +
    +
    +

    光线

    + 画出光线。当「光线密度」高时,光线呈现连续。 +
    +
    +
    + 光线 +
    +
    + 光线 +
    +
    +
    +
    +
    +

    延长光线

    + 除光线实际路径外,亦画出其延长线。橘色、灰色分别表示向后、向前的延长线。 +
    +
    +
    + 延长光线 +
    +
    +
    +
    +
    +

    所有像

    + 点出像的位置。黄点表示实像,橘点表示虚像,灰点(图中没有)表示虚物。注意「光线密度」不够高时有些像无法正常显示。 +
    +
    +
    + 所有像 +
    +
    +
    +
    +
    +

    观察者所见

    + 模拟从某位置见到的光线与像。蓝色圆形为观察者,与其相交的光线被其「观察」到。观察者无法知道光线真正的起始位置,但若其在某处相交,它会认为光线是从该处来的。光线以蓝色表示,相交处以黄色(实像)或橘色(虚像)表示。 +
    +
    +
    + 观察者所见 +
    +
    +
    +
    +
    +

    模拟色彩

    + 模拟光源的颜色(波长)、混色、遮光物与镜子的滤光,以及透光物的色散。 +
    +
    +
    + 模拟色彩 +
    +
    +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/cn/modules/modules.html b/cn/modules/modules.html new file mode 100644 index 00000000..743e56f2 --- /dev/null +++ b/cn/modules/modules.html @@ -0,0 +1,294 @@ + + + + + + + + + + + + +
    +
      +
    • 「模块」功能透过将本模拟器中现有的工具所建立的物件进行组合、特化或重新参数化,来制作新的工具。
    • +
    • 导入的模块将显示为「其他」类别中的工具。请选择并依照控制点顺序点击空白处(参见「规格」)。
    • +
    • 导入的模块将嵌入于场景的数据中,所以当原作者更新时并不会自动更新。
    • +
    +
    + + + 菲涅耳透镜 + +
    +

    菲涅耳透镜 (FresnelLens)

    +

    Yi-Ting Tu

    + + 从半圆形透光物制成的菲涅耳透镜。此作品集范例的模块化版本。 + + +
    +
    +
    + 控制点顺序 +
      +
    1. 透镜的第一个端点
    2. +
    3. 透镜的第二个端点
    4. +
    + 参数 +
      +
    • 切片数量
    • +
    • 透镜的折射率
    • +
    +
    +
    + + + 连续光谱光源 + +
    +

    连续光谱光源 (ContSpectrum)

    +

    Yi-Ting Tu

    + + 具有均匀连续光谱的光源,以指定的步长离散化。只在「模拟色彩」模式中运作。 + + +
    +
    +
    + 控制点顺序 +
      +
    1. 光线的起点
    2. +
    3. 决定光线的方向
    4. +
    + 参数 +
      +
    • 波长最小值
    • +
    • 波长的步长
    • +
    • 波长最大值
    • +
    • 总亮度
    • +
    +
    +
    + + + 圆形光源 + +
    +

    圆形光源 (CircleSource)

    +

    Yi-Ting Tu

    + + 将一系列均匀的180度点光源置于圆周上所形成的光源。 + + +
    +
    +
    + 控制点顺序 +
      +
    1. 该圆形的圆心
    2. +
    + 参数 +
      +
    • 该圆形的半径
    • +
    • 点光源的数量
    • +
    • 总亮度
    • +
    +
    +
    + + + 干扰箔 + +
    +

    干扰箔 (Chaff)

    +

    Stas Fainer, Yi-Ting Tu

    + + 矩形的干扰箔,由许多随机的镜子组成。此作品集范例的模块化版本。 + + +
    +
    +
    + 控制点顺序 +
      +
    1. 干扰箔的左上角
    2. +
    3. 干扰箔的右下角
    4. +
    + 参数 +
      +
    • 干扰箔中镜子的数量
    • +
    • 镜子的长度
    • +
    +
    +
    + + + 扩束镜 + +
    +

    扩束镜 (BeamExpander)

    +

    Yi-Ting Tu

    + + 两个理想透镜的组合,使得两者焦距之和等于两者间的距离。此组合可以扩大或缩小准直光束的直径此作品集范例的模块化版本。 + + +
    +
    +
    + 控制点顺序 +
      +
    1. 第一个透镜的中心点
    2. +
    3. 第二个透镜的第二个点
    4. +
    5. 决定共同焦点的位置
    6. +
    + 参数 +
      +
    +
    +
    + + + 光线中继 + +
    +

    光线中继 (RayRelay)

    +

    Stas Fainer, Yi-Ting Tu

    + + 一系列相同的理想透镜,焦距为 \(f\),间距为 \(d\)。若且唯若\(d\leq 4f\)时,可以保证光线轨迹不会发散。此作品集范例的模块化版本。 + + +
    +
    +
    + 控制点顺序 +
      +
    1. 第一个透镜的第一个端点
    2. +
    3. 第一个透镜的第二个端点(应与第一点有相同的 \(x\))
    4. +
    + 参数 +
      +
    • 透镜的焦距
    • +
    • 透镜之间的距离
    • +
    • 透镜的数量
    • +
    +
    +
    + + + 光纤 + +
    +

    光纤 (OpticalFiber)

    +

    josephernest, Yi-Ting Tu

    + + 指定核心和包层折射率的线状光纤。 + + +
    +
    +
    + 控制点顺序 +
      +
    1. 光纤的第一个端点
    2. +
    3. 光纤的第二个端点(应与第一个点有相同的 \(y\))
    4. +
    + 参数 +
      +
    • 核心的厚度
    • +
    • 包层的厚度
    • +
    • 核心的折射率
    • +
    • 包层的折射率
    • +
    +
    +
    + +

    客制化

    +

    您可直接在本网页程序中使用内置的JSON编辑器制作或客制化模块。请参见教程。将导入的模块客制化仅会影响目前的场景。

    + +

    贡献

    +

    欢迎您贡献项目至以上的清单。欲贡献您的模块,请参见貢獻模块

    + + + + + + + + \ No newline at end of file diff --git a/cn/modules/tutorial.html b/cn/modules/tutorial.html new file mode 100644 index 00000000..4afbbfe4 --- /dev/null +++ b/cn/modules/tutorial.html @@ -0,0 +1,197 @@ + + + + + + + 「射线光学模拟」模块制作教程 - 射线光学模拟 + + + + + + + + + + + + + + + + + + + +
    +

    「射线光学模拟」模块制作教程

    + +

    本教程将引导您完成建立自定义模块的基本步骤。这个功能可完全在本模拟器网页程序中实现,而不需要其他的开发环境。

    +

    「线光学模拟」的「模块」功能允许将物件以模块化的方式组合在一起,其中可包含自定义参数、自定义控制点与物件数组。本功能透过将本模拟器中现有的工具所建立的物件进行组合、特化或重新参数化,来制作新的工具,以扩充本模拟器的功能。例如,CircleSource模块(请参见工具->其他->导入模块)将现有的「点光源(<360°)」工具所建立的一系列点光源沿着一个圆形组合在一起,成为一个「圆形光源」工具,这在模拟器中原本并不存在。FresnelLens模块则是将「透光物->自定义函数」工具特化,使函数表示菲涅耳透镜的特定曲线,由切片数参数化,以制作一个特化的「菲涅耳透镜」工具,这在模拟器中原本也不存在。除了制作新工具外,这个功能还可以使一些光学演示更具互动性。例如,通过拖曳BeamExpander模块的第三个控制点,可以直接观察两个透镜的共同焦点位置如何影响光束宽度,而无需分别调整两个透镜的焦距。

    +

    注意并非所有的自定义控制点都需要模块。一些简单的情况可能可以通过「控制杆」功能实现(请参见模拟器右下角的帮助弹出窗口中的「群组、旋转和缩放物件」部分)。由于制作模块比建立控制杆复杂得多,您应该在考虑制作模块之前检查您的情况是否可以通过「控制杆」功能实现。比如这个例子展示了一个相对复杂但不必使用模块的自定义控制点(将两个塑料袋从水中移开)。

    + +

    内置的JSON编辑器

    +

    本应用目前没有用于建立模块的视觉界面,因此您需要直接编辑场景的JSON原始码。

    +

    您可以通过点击应用程序右上角的「设置」下拉菜单,然后勾选「显示JSON编辑器」来启用内置的JSON编辑器。原始码编辑器会出现在界面的左侧,并显示目前场景的JSON原始码。请确保您有足够大的屏幕,因为这个功能在行动装置上效果不佳。

    +

    当您使用可视化场景编辑器修改场景时,JSON编辑器中的原始码将自动更新,且更改的部分会突出显示。反之,直接在JSON编辑器中编辑原始码将相应更新场景。如果您不熟悉JSON或任何基于文字的数据格式,您可能会希望花一些时间来熟悉它。

    +

    特别是,当您将一个物件新增到场景中时,它将被新增到objs数组中。如果您将某些属性修改为非预设值,它们将作为该物件的键值对出现。

    +

    注意:如果您在本教程页面中看不到下面的iframe中的JSON编辑器,请启用它并重新加载本页,因为您需要查看原始码以了解它的运作方式。

    + +

    模块的基本概念

    +

    让我们看第一个例子。

    + +

    您会看到四段文字。通过查看JSON编辑器,您将看到前两段直接位于顶层的objs数组中,但后两段位于modules.ExampleModule.objs中。

    +

    module是一个字典,其中键是模块的名称(在本例中是ExampleModule),值是该模块的定义。特别是,modules.ExampleModule.objs数组描述了该模块中的物件(模板),这与描述场景中的物件的顶层objs数组不同。

    +

    要将模块中的物件放到场景中,我们需要一个「模块物件」,它位于顶层objs数组中,本例中是objs[2],其类型是ModuleObj,其module属性是模块的名称。

    +

    modules字典中的模块定义无法由可视化场景编辑器编辑。因此,当您点选本例中的后两段文字时,您只选择了模块物件,而不是模块中的物件。由于本例中模块定义中的文字坐标是绝对坐标,因此后两段文字无法被拖曳。我们将在后面学习到如何使用控制点来使它们可被拖曳。

    +

    当您提取模块物件时,物件栏上会有一个「取消模块化」按钮。点选后会将模块物件「展开」为构成此模块的物件,此时objs将包含所有四段文字。这个操作是不可逆的(除非点击「复原」)。

    +

    目前建议制作模块的方式为,首先使用JSON编辑器建立一个空的模块,然后使用可视化场景编辑器新增一些物件,最后使用JSON编辑器将这些物件从objs剪下并粘贴到modules.ModuleName.objs中。

    + +

    新增参数

    +

    模块中的物件可以由一组参数来定义。让我们看一个简单的例子

    + +

    这里modules.ModuleName.params是一个由形如"名称=起始值:增量:终止值:预设值"的字串构成的数组,定义了变数的名称和数值滑杆的范围。当提取模块物件时,滑杆将出现在物件栏上。

    +

    modules.ExampleModule.objs数组中,任何值都可以使用这些参数来表示。在字串中(例如TextLabeltext属性)中,带有参数的数学式被反引号包围。对于数值参数(例如TextLabelfontSize属性),您需要将其改为字串,以便您可以在其中使用反引号格式。因此每条数学式都被一对反引号和一对引号包围。这些数学式将使用math.js来计算(语法)。请参见该网页以了解您可以在数学式中使用的语法和函数。

    +

    参数的实际值位于模块物件的params属性中。这部分与模块定义不同,其可以通过滑杆直接由可视化场景编辑器编辑。

    + +

    新增控制点

    +

    为了使模块物件可被拖曳,我们需要使用一组控制点来对模块中的物件位置进行参数化。让我们看一个例子

    + +

    这里modules.ModuleName.numPoints描述了控制点的数量。控制点坐标之符号为 (x_1, y_1)、(x_2, y_2) 等等。其用在modules.ExampleModule.objs中的方式与前一节所述之参数相同。请注意索引从1开始。

    +

    控制点的实际值位于模块物件的controlPoints属性中,其可以直接由可视化场景编辑器编辑,而非如第一个例子中写死在模块定义中的坐标。每个控制点在场景中显示为两个同心的灰色圆形,并且可以被拖曳。若您拖曳模块物件的其他地方(如文字标签),则所有的控制点会一起移动。

    +

    由于我们的模块物件已经可以移动,我们可以很容易地建立多个实例,就像在本模拟器中其他的工具中一样。模块的名称显示在工具->其他菜单中,您可以选择它,然后按两个点来指定两个控制点的位置,就可建立此模块的另一个实例。您也可以使用物件栏上的「复制」按钮。

    + +

    数组与条件

    +

    使用数组和条件语法,可以建立更复杂的模块。让我们看一个例子

    + +

    modules.ExampleModule.objs中,任何数组中的物件都可以有两个特殊的键:"for""if""for"键的值是一个描述循环变数的字串,格式为"名称=起始值:增量:终止值",或者是一个包含多个这种格式的字串的数组,描述多维循环。这样的物件在数组中根据循环变数被复制多次。"if"键的值是则是一个表示布尔值的字串,使得该物件只在布尔值为真时才会包含在数组中。

    +

    为了防止意外的无穷循环,每个"for"循环的总迭代次数由模块定义中的maxLoopLength属性限制,其预设值为1000。如果需要,您可以将此属性设定为更大的值。

    + +

    内置自定义数学式功能的物件

    +

    对于已经具有自定义数学式输入的物件(例如镜子->自定义函数),JSON中的数学式属性是一个表示LaTeX数学式的字串,而不是math.js表达式。要在数学式中包含自定义参数,您必须将LaTeX数学式视为普通字串,并使用普通字串的模板语法。因此,反引号括起来的部分是math.js表达式,而反引号外部的则是LaTeX数学式。模块参数只能在math.js的部分中使用,而物件内置的自定义函数的自变量(例如\(x\))只能在LaTeX的部分中使用。以下例子产生一个形状为\(y=\cos(2\pi x+\phi)\)的镜子,其中\(\phi\)为模块参数

    + +

    未来可能会有一种统一的方式来输入数学式。

    + +

    内置形状参数化功能的物件

    +

    对于已经支持使用不同方式定义其形状的物件(目前仅有透光物->球面透镜),有特殊的JSON语法可用于在模块定义中用这些方式来定义该物件,即使在顶层objs数组中这类的物件总是以形状来定义。以下是一个例子

    + + +
    +
    + + +
    +
    + + + + + + \ No newline at end of file diff --git a/d0415105402964718010284fcfa8b2ea.js b/d0415105402964718010284fcfa8b2ea.js new file mode 100644 index 00000000..3a32c0cf --- /dev/null +++ b/d0415105402964718010284fcfa8b2ea.js @@ -0,0 +1 @@ +ace.define("ace/ext/statusbar",["require","exports","module","ace/lib/dom","ace/lib/lang"],(function(e,t,n){"use strict";var a=e("../lib/dom"),o=e("../lib/lang"),i=function(){function e(e,t){this.element=a.createElement("div"),this.element.className="ace_status-indicator",this.element.style.cssText="display: inline-block;",t.appendChild(this.element);var n=o.delayedCall(function(){this.updateStatus(e)}.bind(this)).schedule.bind(null,100);e.on("changeStatus",n),e.on("changeSelection",n),e.on("keyboardActivity",n)}return e.prototype.updateStatus=function(e){var t=[];function n(e,n){e&&t.push(e,n||"|")}n(e.keyBinding.getStatusText(e)),e.commands.recording&&n("REC");var a=e.selection,o=a.lead;if(!a.isEmpty()){var i=e.getSelectionRange();n("("+(i.end.row-i.start.row)+":"+(i.end.column-i.start.column)+")"," ")}n(o.row+":"+o.column," "),a.rangeCount&&n("["+a.rangeCount+"]"," "),t.pop(),this.element.textContent=t.join("")},e}();t.StatusBar=i})),ace.require(["ace/ext/statusbar"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d09463c099fb2c44719380623a5c68fb.js b/d09463c099fb2c44719380623a5c68fb.js new file mode 100644 index 00000000..329023ac --- /dev/null +++ b/d09463c099fb2c44719380623a5c68fb.js @@ -0,0 +1 @@ +ace.define("ace/ext/hardwrap",["require","exports","module","ace/range","ace/editor","ace/config"],(function(e,t,n){"use strict";var r=e("../range").Range;function i(e,t){for(var n=t.column||e.getOption("printMarginColumn"),i=0!=t.allowMerge,o=Math.min(t.startRow,t.endRow),a=Math.max(t.startRow,t.endRow),s=e.session;o<=a;){var l=s.getLine(o);if(l.length>n){if(h=g(l,n,5)){var c=/^\s*/.exec(l)[0];s.replace(new r(o,h.start,o,h.end),"\n"+c)}a++}else if(i&&/\S/.test(l)&&o!=a){var u=s.getLine(o+1);if(u&&/\S/.test(u)){var h,d=l.replace(/\s+$/,""),p=u.replace(/^\s+/,""),f=d+" "+p;if((h=g(f,n,5))&&h.start>d.length||f.lengthn?{start:a.index,end:a.index+a[2].length}:o&&o[2]?{start:s=t+o[2].length,end:s+o[3].length}:void 0}}}function o(e){if("insertstring"==e.command.name&&/\S/.test(e.args)){var t=e.editor,n=t.selection.cursor;if(n.column<=t.renderer.$printMarginColumn)return;var r=t.session.$undoManager.$lastDelta;i(t,{startRow:n.row,endRow:n.row,allowMerge:!1}),r!=t.session.$undoManager.$lastDelta&&t.session.markUndoGroup()}}var a=e("../editor").Editor;e("../config").defineOptions(a.prototype,"editor",{hardWrap:{set:function(e){e?this.commands.on("afterExec",o):this.commands.off("afterExec",o)},value:!1}}),t.hardWrap=i})),ace.define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/dom","ace/lib/oop","ace/lib/keys","ace/lib/event","ace/search","ace/lib/useragent","ace/search_highlight","ace/commands/multi_select_commands","ace/mode/text","ace/ext/hardwrap","ace/multi_select"],(function(e,t,n){"use strict";var r=e("../range").Range,i=e("../lib/event_emitter").EventEmitter,o=e("../lib/dom"),a=e("../lib/oop"),s=e("../lib/keys"),l=e("../lib/event"),c=e("../search").Search,u=e("../lib/useragent"),h=e("../search_highlight").SearchHighlight,d=e("../commands/multi_select_commands"),p=e("../mode/text").Mode.prototype.tokenRe,f=e("../ext/hardwrap").hardWrap;e("../multi_select");var m=function(e){this.ace=e,this.state={},this.marks={},this.options={},this.$uid=0,this.onChange=this.onChange.bind(this),this.onSelectionChange=this.onSelectionChange.bind(this),this.onBeforeEndOperation=this.onBeforeEndOperation.bind(this),this.ace.on("change",this.onChange),this.ace.on("changeSelection",this.onSelectionChange),this.ace.on("beforeEndOperation",this.onBeforeEndOperation)};function g(e){return{row:e.line,column:e.ch}}function v(e){return new y(e.row,e.column)}m.Pos=function(e,t){if(!(this instanceof y))return new y(e,t);this.line=e,this.ch=t},m.defineOption=function(e,t,n){},m.commands={redo:function(e){e.ace.redo()},undo:function(e){e.ace.undo()},newlineAndIndent:function(e){e.ace.insert("\n")},goLineLeft:function(e){e.ace.selection.moveCursorLineStart()},goLineRight:function(e){e.ace.selection.moveCursorLineEnd()}},m.keyMap={},m.addClass=m.rmClass=function(){},m.e_stop=m.e_preventDefault=l.stopEvent,m.keyName=function(e){var t=s[e.keyCode]||e.key||"";return 1==t.length&&(t=t.toUpperCase()),l.getModifierString(e).replace(/(^|-)\w/g,(function(e){return e.toUpperCase()}))+t},m.keyMap.default=function(e){return function(t){var n=t.ace.commands.commandKeyBinding[e.toLowerCase()];return n&&!1!==t.ace.execCommand(n)}},m.lookupKey=function e(t,n,r){n||(n="default"),"string"==typeof n&&(n=m.keyMap[n]||m.keyMap.default);var i="function"==typeof n?n(t):n[t];if(!1===i)return"nothing";if("..."===i)return"multi";if(null!=i&&r(i))return"handled";if(n.fallthrough){if(!Array.isArray(n.fallthrough))return e(t,n.fallthrough,r);for(var o=0;o0?(l.row+=o,l.column+=l.row==i.row?a:0):!t&&u<=0&&(l.row=n.row,l.column=n.column,0===u&&(l.bias=1))}}};var e=function(e,t,n,r){this.cm=e,this.id=t,this.row=n,this.column=r,e.marks[this.id]=this};e.prototype.clear=function(){delete this.cm.marks[this.id]},e.prototype.find=function(){return v(this)},this.setBookmark=function(t,n){var r=new e(this,this.$uid++,t.line,t.ch);return n&&n.insertLeft||(r.$insertRight=!0),this.marks[r.id]=r,r},this.moveH=function(e,t){if("char"==t){var n=this.ace.selection;n.clearSelection(),n.moveCursorBy(0,e)}},this.findPosV=function(e,t,n,r){if("page"==n){var i=this.ace.renderer.layerConfig;t*=Math.floor(i.height/i.lineHeight),n="line"}if("line"==n){var o=this.ace.session.documentToScreenPosition(e.line,e.ch);return null!=r&&(o.column=r),o.row+=t,o.row=Math.min(Math.max(0,o.row),this.ace.session.getScreenLength()-1),v(this.ace.session.screenToDocumentPosition(o.row,o.column))}},this.charCoords=function(e,t){if("div"==t||!t)return{left:(r=this.ace.session.documentToScreenPosition(e.line,e.ch)).column,top:r.row};if("local"==t){var n=this.ace.renderer,r=this.ace.session.documentToScreenPosition(e.line,e.ch),i=n.layerConfig.lineHeight,o=n.layerConfig.characterWidth,a=i*r.row;return{left:r.column*o,top:a,bottom:a+i}}},this.coordsChar=function(e,t){var n=this.ace.renderer;if("local"==t){var r=Math.max(0,Math.floor(e.top/n.lineHeight)),i=Math.max(0,Math.floor(e.left/n.characterWidth));return v(n.session.screenToDocumentPosition(r,i))}if("div"==t)throw"not implemented"},this.getSearchCursor=function(e,t,n){var r=!1,i=!1;e instanceof RegExp&&!e.global&&(r=!e.ignoreCase,e=e.source,i=!0),"\\n"==e&&(e="\n",i=!1);var o=new c;null==t.ch&&(t.ch=Number.MAX_VALUE);var a={row:t.line,column:t.ch},s=this,l=null;return{findNext:function(){return this.find(!1)},findPrevious:function(){return this.find(!0)},find:function(t){o.setOptions({needle:e,caseSensitive:r,wrap:!1,backwards:t,regExp:i,start:l||a});var n=o.find(s.ace.session);return(l=n)&&[!l.isEmpty()]},from:function(){return l&&v(l.start)},to:function(){return l&&v(l.end)},replace:function(e){l&&(l.end=s.ace.session.doc.replace(l,e))}}},this.scrollTo=function(e,t){var n=this.ace.renderer,r=n.layerConfig,i=r.maxHeight;i-=(n.$size.scrollerHeight-n.lineHeight)*n.$scrollPastEnd,null!=t&&this.ace.session.setScrollTop(Math.max(0,Math.min(t,i))),null!=e&&this.ace.session.setScrollLeft(Math.max(0,Math.min(e,r.width)))},this.scrollInfo=function(){return 0},this.scrollIntoView=function(e,t){if(e){var n=this.ace.renderer,r={top:0,bottom:t};n.scrollCursorIntoView(g(e),2*n.lineHeight/n.$size.scrollerHeight,r)}},this.getLine=function(e){return this.ace.session.getLine(e)},this.getRange=function(e,t){return this.ace.session.getTextRange(new r(e.line,e.ch,t.line,t.ch))},this.replaceRange=function(e,t,n){n||(n=t);var i=new r(t.line,t.ch,n.line,n.ch);return this.ace.session.$clipRangeToDocument(i),this.ace.session.replace(i,e)},this.replaceSelection=this.replaceSelections=function(e){var t=Array.isArray(e)&&e,n=this.ace.selection;if(this.ace.inVirtualSelectionMode)this.ace.session.replace(n.getRange(),t?e[0]||"":e);else{n.inVirtualSelectionMode=!0;var r=n.rangeList.ranges;r.length||(r=[this.ace.multiSelect.getRange()]);for(var i=r.length;i--;)this.ace.session.replace(r[i],t?e[i]||"":e);n.inVirtualSelectionMode=!1}},this.getSelection=function(){return this.ace.getSelectedText()},this.getSelections=function(){return this.listSelections().map((function(e){return this.getRange(e.anchor,e.head)}),this)},this.getInputField=function(){return this.ace.textInput.getElement()},this.getWrapperElement=function(){return this.ace.container};var t={indentWithTabs:"useSoftTabs",indentUnit:"tabSize",tabSize:"tabSize",firstLineNumber:"firstLineNumber",readOnly:"readOnly"};this.setOption=function(e,n){switch(this.state[e]=n,e){case"indentWithTabs":e=t[e],n=!n;break;case"keyMap":return void(this.state.$keyMap=n);default:e=t[e]}e&&this.ace.setOption(e,n)},this.getOption=function(e){var n,r=t[e];switch(r&&(n=this.ace.getOption(r)),e){case"indentWithTabs":return e=t[e],!n;case"keyMap":return this.state.$keyMap||"vim"}return r?n:this.state[e]},this.toggleOverwrite=function(e){return this.state.overwrite=e,this.ace.setOverwrite(e)},this.addOverlay=function(e){if(!this.$searchHighlight||!this.$searchHighlight.session){var t=new h(null,"ace_highlight-marker","text"),n=this.ace.session.addDynamicMarker(t);t.id=n.id,t.session=this.ace.session,t.destroy=function(e){t.session.off("change",t.updateOnChange),t.session.off("changeEditor",t.destroy),t.session.removeMarker(t.id),t.session=null},t.updateOnChange=function(e){var n=e.start.row;n==e.end.row?t.cache[n]=void 0:t.cache.splice(n,t.cache.length)},t.session.on("changeEditor",t.destroy),t.session.on("change",t.updateOnChange)}var r=new RegExp(e.query.source,"gmi");this.$searchHighlight=e.highlight=t,this.$searchHighlight.setRegexp(r),this.ace.renderer.updateBackMarkers()},this.removeOverlay=function(e){this.$searchHighlight&&this.$searchHighlight.session&&this.$searchHighlight.destroy()},this.getScrollInfo=function(){var e=this.ace.renderer,t=e.layerConfig;return{left:e.scrollLeft,top:e.scrollTop,height:t.maxHeight,width:t.width,clientHeight:t.height,clientWidth:t.width}},this.getValue=function(){return this.ace.getValue()},this.setValue=function(e){return this.ace.setValue(e,-1)},this.getTokenTypeAt=function(e){var t=this.ace.session.getTokenAt(e.line,e.ch);return t&&/comment|string/.test(t.type)?"string":""},this.findMatchingBracket=function(e){var t=this.ace.session.findMatchingBracket(g(e));return{to:t&&v(t)}},this.findMatchingTag=function(e){var t=this.ace.session.getMatchingTags(g(e));if(t)return{open:{from:v(t.openTag.start),to:v(t.openTag.end)},close:{from:v(t.closeTag.start),to:v(t.closeTag.end)}}},this.indentLine=function(e,t){!0===t?this.ace.session.indentRows(e,e,"\t"):!1===t&&this.ace.session.outdentRows(new r(e,0,e,0))},this.indexFromPos=function(e){return this.ace.session.doc.positionToIndex(g(e))},this.posFromIndex=function(e){return v(this.ace.session.doc.indexToPosition(e))},this.focus=function(e){return this.ace.textInput.focus()},this.blur=function(e){return this.ace.blur()},this.defaultTextHeight=function(e){return this.ace.renderer.layerConfig.lineHeight},this.scanForBracket=function(e,t,n,r){var i=r.bracketRegex.source,o=/paren|text|operator|tag/;if(1==t)var a=this.ace.session.$findClosingBracket(i.slice(1,2),g(e),o);else!(a=this.ace.session.$findOpeningBracket(i.slice(-2,-1),{row:e.line,column:e.ch+1},o))&&r.bracketRegex&&r.bracketRegex.test(this.getLine(e.line)[e.ch-1])&&(a={row:e.line,column:e.ch-1});return a&&{pos:v(a)}},this.refresh=function(){return this.ace.resize(!0)},this.getMode=function(){return{name:this.getOption("mode")}},this.execCommand=function(e){return m.commands.hasOwnProperty(e)?m.commands[e](this):"indentAuto"==e?this.ace.execCommand("autoindent"):void console.log(e+" is not implemented")},this.getLineNumber=function(e){var t=this.$lineHandleChanges;if(!t)return null;for(var n=e.row,r=0;r0)return null;n-=i.end.row-i.start.row}}return n},this.getLineHandle=function(e){return this.$lineHandleChanges||(this.$lineHandleChanges=[]),{text:this.ace.session.getLine(e),row:e}},this.releaseLineHandles=function(){this.$lineHandleChanges=void 0},this.getLastEditEnd=function(){var e=this.ace.session.$undoManager;if(e&&e.$lastDelta)return v(e.$lastDelta.end)}}.call(m.prototype),(m.StringStream=function(e,t){this.pos=this.start=0,this.string=e,this.tabSize=t||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0}).prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return this.pos==this.lineStart},peek:function(){return this.string.charAt(this.pos)||void 0},next:function(){if(this.post},eatSpace:function(){for(var e=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e},skipToEnd:function(){this.pos=this.string.length},skipTo:function(e){var t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0},backUp:function(e){this.pos-=e},column:function(){throw"not implemented"},indentation:function(){throw"not implemented"},match:function(e,t,n){if("string"!=typeof e){var r=this.string.slice(this.pos).match(e);return r&&r.index>0?null:(r&&!1!==t&&(this.pos+=r[0].length),r)}var i=function(e){return n?e.toLowerCase():e};if(i(this.string.substr(this.pos,e.length))==i(e))return!1!==t&&(this.pos+=e.length),!0},current:function(){return this.string.slice(this.start,this.pos)},hideFirstChars:function(e,t){this.lineStart+=e;try{return t()}finally{this.lineStart-=e}}},m.defineExtension=function(e,t){m.prototype[e]=t},o.importCssString(".normal-mode .ace_cursor{\n border: none;\n background-color: rgba(255,0,0,0.5);\n}\n.normal-mode .ace_hidden-cursors .ace_cursor{\n background-color: transparent;\n border: 1px solid red;\n opacity: 0.7\n}\n.ace_dialog {\n position: absolute;\n left: 0; right: 0;\n background: inherit;\n z-index: 15;\n padding: .1em .8em;\n overflow: hidden;\n color: inherit;\n}\n.ace_dialog-top {\n border-bottom: 1px solid #444;\n top: 0;\n}\n.ace_dialog-bottom {\n border-top: 1px solid #444;\n bottom: 0;\n}\n.ace_dialog input {\n border: none;\n outline: none;\n background: transparent;\n width: 20em;\n color: inherit;\n font-family: monospace;\n}","vimMode",!1),function(){function e(e,t,n){var r;return(r=e.ace.container.appendChild(document.createElement("div"))).className=n?"ace_dialog ace_dialog-bottom":"ace_dialog ace_dialog-top","string"==typeof t?r.innerHTML=t:r.appendChild(t),r}function t(e,t){e.state.currentNotificationClose&&e.state.currentNotificationClose(),e.state.currentNotificationClose=t}m.defineExtension("openDialog",(function(n,r,i){if(!this.virtualSelectionMode()){i||(i={}),t(this,null);var o=e(this,n,i.bottom),a=!1,s=this;this.state.dialog=o;var l,c=o.getElementsByTagName("input")[0];return c?(i.value&&(c.value=i.value,!1!==i.selectValueOnOpen&&c.select()),i.onInput&&m.on(c,"input",(function(e){i.onInput(e,c.value,u)})),i.onKeyUp&&m.on(c,"keyup",(function(e){i.onKeyUp(e,c.value,u)})),m.on(c,"keydown",(function(e){i&&i.onKeyDown&&i.onKeyDown(e,c.value,u)||(13==e.keyCode&&r(c.value),(27==e.keyCode||!1!==i.closeOnEnter&&13==e.keyCode)&&(m.e_stop(e),u()))})),!1!==i.closeOnBlur&&m.on(c,"blur",u),c.focus()):(l=o.getElementsByTagName("button")[0])&&(m.on(l,"click",(function(){u(),s.focus()})),!1!==i.closeOnBlur&&m.on(l,"blur",u),l.focus()),u}function u(e){if("string"==typeof e)c.value=e;else{if(a)return;if(e&&"blur"==e.type&&document.activeElement===c)return;s.state.dialog==o&&(s.state.dialog=null,s.focus()),a=!0,o.remove(),i.onClose&&i.onClose(o);var t=s;t.state.vim&&(t.state.vim.status=null,t.ace._signal("changeStatus"),t.ace.renderer.$loop.schedule(t.ace.renderer.CHANGE_CURSOR))}}})),m.defineExtension("openNotification",(function(n,r){if(!this.virtualSelectionMode()){t(this,l);var i,o=e(this,n,r&&r.bottom),a=!1,s=r&&void 0!==r.duration?r.duration:5e3;return m.on(o,"click",(function(e){m.e_preventDefault(e),l()})),s&&(i=setTimeout(l,s)),l}function l(){a||(a=!0,clearTimeout(i),o.remove())}}))}();var y=m.Pos;function C(e,t,n){if(t.line===n.line&&t.ch>=n.ch-1){var r=e.getLine(t.line).charCodeAt(t.ch);55296<=r&&r<=55551&&(n.ch+=1)}return{start:t,end:n}}var w=[{keys:"",type:"keyToKey",toKeys:"h"},{keys:"",type:"keyToKey",toKeys:"l"},{keys:"",type:"keyToKey",toKeys:"k"},{keys:"",type:"keyToKey",toKeys:"j"},{keys:"g",type:"keyToKey",toKeys:"gk"},{keys:"g",type:"keyToKey",toKeys:"gj"},{keys:"",type:"keyToKey",toKeys:"l"},{keys:"",type:"keyToKey",toKeys:"h"},{keys:"",type:"keyToKey",toKeys:"x"},{keys:"",type:"keyToKey",toKeys:"W"},{keys:"",type:"keyToKey",toKeys:"B"},{keys:"",type:"keyToKey",toKeys:"w"},{keys:"",type:"keyToKey",toKeys:"b"},{keys:"",type:"keyToKey",toKeys:"j"},{keys:"",type:"keyToKey",toKeys:"k"},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:"",context:"insert"},{keys:"",type:"keyToKey",toKeys:"",context:"insert"},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:"",context:"insert"},{keys:"s",type:"keyToKey",toKeys:"cl",context:"normal"},{keys:"s",type:"keyToKey",toKeys:"c",context:"visual"},{keys:"S",type:"keyToKey",toKeys:"cc",context:"normal"},{keys:"S",type:"keyToKey",toKeys:"VdO",context:"visual"},{keys:"",type:"keyToKey",toKeys:"0"},{keys:"",type:"keyToKey",toKeys:"$"},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:"j^",context:"normal"},{keys:"",type:"keyToKey",toKeys:"i",context:"normal"},{keys:"",type:"action",action:"toggleOverwrite",context:"insert"},{keys:"H",type:"motion",motion:"moveToTopLine",motionArgs:{linewise:!0,toJumplist:!0}},{keys:"M",type:"motion",motion:"moveToMiddleLine",motionArgs:{linewise:!0,toJumplist:!0}},{keys:"L",type:"motion",motion:"moveToBottomLine",motionArgs:{linewise:!0,toJumplist:!0}},{keys:"h",type:"motion",motion:"moveByCharacters",motionArgs:{forward:!1}},{keys:"l",type:"motion",motion:"moveByCharacters",motionArgs:{forward:!0}},{keys:"j",type:"motion",motion:"moveByLines",motionArgs:{forward:!0,linewise:!0}},{keys:"k",type:"motion",motion:"moveByLines",motionArgs:{forward:!1,linewise:!0}},{keys:"gj",type:"motion",motion:"moveByDisplayLines",motionArgs:{forward:!0}},{keys:"gk",type:"motion",motion:"moveByDisplayLines",motionArgs:{forward:!1}},{keys:"w",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!1}},{keys:"W",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!1,bigWord:!0}},{keys:"e",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!0,inclusive:!0}},{keys:"E",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!0,bigWord:!0,inclusive:!0}},{keys:"b",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!1}},{keys:"B",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!1,bigWord:!0}},{keys:"ge",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!0,inclusive:!0}},{keys:"gE",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!0,bigWord:!0,inclusive:!0}},{keys:"{",type:"motion",motion:"moveByParagraph",motionArgs:{forward:!1,toJumplist:!0}},{keys:"}",type:"motion",motion:"moveByParagraph",motionArgs:{forward:!0,toJumplist:!0}},{keys:"(",type:"motion",motion:"moveBySentence",motionArgs:{forward:!1}},{keys:")",type:"motion",motion:"moveBySentence",motionArgs:{forward:!0}},{keys:"",type:"motion",motion:"moveByPage",motionArgs:{forward:!0}},{keys:"",type:"motion",motion:"moveByPage",motionArgs:{forward:!1}},{keys:"",type:"motion",motion:"moveByScroll",motionArgs:{forward:!0,explicitRepeat:!0}},{keys:"",type:"motion",motion:"moveByScroll",motionArgs:{forward:!1,explicitRepeat:!0}},{keys:"gg",type:"motion",motion:"moveToLineOrEdgeOfDocument",motionArgs:{forward:!1,explicitRepeat:!0,linewise:!0,toJumplist:!0}},{keys:"G",type:"motion",motion:"moveToLineOrEdgeOfDocument",motionArgs:{forward:!0,explicitRepeat:!0,linewise:!0,toJumplist:!0}},{keys:"g$",type:"motion",motion:"moveToEndOfDisplayLine"},{keys:"g^",type:"motion",motion:"moveToStartOfDisplayLine"},{keys:"g0",type:"motion",motion:"moveToStartOfDisplayLine"},{keys:"0",type:"motion",motion:"moveToStartOfLine"},{keys:"^",type:"motion",motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:"+",type:"motion",motion:"moveByLines",motionArgs:{forward:!0,toFirstChar:!0}},{keys:"-",type:"motion",motion:"moveByLines",motionArgs:{forward:!1,toFirstChar:!0}},{keys:"_",type:"motion",motion:"moveByLines",motionArgs:{forward:!0,toFirstChar:!0,repeatOffset:-1}},{keys:"$",type:"motion",motion:"moveToEol",motionArgs:{inclusive:!0}},{keys:"%",type:"motion",motion:"moveToMatchedSymbol",motionArgs:{inclusive:!0,toJumplist:!0}},{keys:"f",type:"motion",motion:"moveToCharacter",motionArgs:{forward:!0,inclusive:!0}},{keys:"F",type:"motion",motion:"moveToCharacter",motionArgs:{forward:!1}},{keys:"t",type:"motion",motion:"moveTillCharacter",motionArgs:{forward:!0,inclusive:!0}},{keys:"T",type:"motion",motion:"moveTillCharacter",motionArgs:{forward:!1}},{keys:";",type:"motion",motion:"repeatLastCharacterSearch",motionArgs:{forward:!0}},{keys:",",type:"motion",motion:"repeatLastCharacterSearch",motionArgs:{forward:!1}},{keys:"'",type:"motion",motion:"goToMark",motionArgs:{toJumplist:!0,linewise:!0}},{keys:"`",type:"motion",motion:"goToMark",motionArgs:{toJumplist:!0}},{keys:"]`",type:"motion",motion:"jumpToMark",motionArgs:{forward:!0}},{keys:"[`",type:"motion",motion:"jumpToMark",motionArgs:{forward:!1}},{keys:"]'",type:"motion",motion:"jumpToMark",motionArgs:{forward:!0,linewise:!0}},{keys:"['",type:"motion",motion:"jumpToMark",motionArgs:{forward:!1,linewise:!0}},{keys:"]p",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!0,isEdit:!0,matchIndent:!0}},{keys:"[p",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!1,isEdit:!0,matchIndent:!0}},{keys:"]",type:"motion",motion:"moveToSymbol",motionArgs:{forward:!0,toJumplist:!0}},{keys:"[",type:"motion",motion:"moveToSymbol",motionArgs:{forward:!1,toJumplist:!0}},{keys:"|",type:"motion",motion:"moveToColumn"},{keys:"o",type:"motion",motion:"moveToOtherHighlightedEnd",context:"visual"},{keys:"O",type:"motion",motion:"moveToOtherHighlightedEnd",motionArgs:{sameLine:!0},context:"visual"},{keys:"d",type:"operator",operator:"delete"},{keys:"y",type:"operator",operator:"yank"},{keys:"c",type:"operator",operator:"change"},{keys:"=",type:"operator",operator:"indentAuto"},{keys:">",type:"operator",operator:"indent",operatorArgs:{indentRight:!0}},{keys:"<",type:"operator",operator:"indent",operatorArgs:{indentRight:!1}},{keys:"g~",type:"operator",operator:"changeCase"},{keys:"gu",type:"operator",operator:"changeCase",operatorArgs:{toLower:!0},isEdit:!0},{keys:"gU",type:"operator",operator:"changeCase",operatorArgs:{toLower:!1},isEdit:!0},{keys:"n",type:"motion",motion:"findNext",motionArgs:{forward:!0,toJumplist:!0}},{keys:"N",type:"motion",motion:"findNext",motionArgs:{forward:!1,toJumplist:!0}},{keys:"gn",type:"motion",motion:"findAndSelectNextInclusive",motionArgs:{forward:!0}},{keys:"gN",type:"motion",motion:"findAndSelectNextInclusive",motionArgs:{forward:!1}},{keys:"gq",type:"operator",operator:"hardWrap"},{keys:"gw",type:"operator",operator:"hardWrap",operatorArgs:{keepCursor:!0}},{keys:"x",type:"operatorMotion",operator:"delete",motion:"moveByCharacters",motionArgs:{forward:!0},operatorMotionArgs:{visualLine:!1}},{keys:"X",type:"operatorMotion",operator:"delete",motion:"moveByCharacters",motionArgs:{forward:!1},operatorMotionArgs:{visualLine:!0}},{keys:"D",type:"operatorMotion",operator:"delete",motion:"moveToEol",motionArgs:{inclusive:!0},context:"normal"},{keys:"D",type:"operator",operator:"delete",operatorArgs:{linewise:!0},context:"visual"},{keys:"Y",type:"operatorMotion",operator:"yank",motion:"expandToLine",motionArgs:{linewise:!0},context:"normal"},{keys:"Y",type:"operator",operator:"yank",operatorArgs:{linewise:!0},context:"visual"},{keys:"C",type:"operatorMotion",operator:"change",motion:"moveToEol",motionArgs:{inclusive:!0},context:"normal"},{keys:"C",type:"operator",operator:"change",operatorArgs:{linewise:!0},context:"visual"},{keys:"~",type:"operatorMotion",operator:"changeCase",motion:"moveByCharacters",motionArgs:{forward:!0},operatorArgs:{shouldMoveCursor:!0},context:"normal"},{keys:"~",type:"operator",operator:"changeCase",context:"visual"},{keys:"",type:"operatorMotion",operator:"delete",motion:"moveToStartOfLine",context:"insert"},{keys:"",type:"operatorMotion",operator:"delete",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!1},context:"insert"},{keys:"",type:"idle",context:"normal"},{keys:"",type:"action",action:"jumpListWalk",actionArgs:{forward:!0}},{keys:"",type:"action",action:"jumpListWalk",actionArgs:{forward:!1}},{keys:"",type:"action",action:"scroll",actionArgs:{forward:!0,linewise:!0}},{keys:"",type:"action",action:"scroll",actionArgs:{forward:!1,linewise:!0}},{keys:"a",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"charAfter"},context:"normal"},{keys:"A",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"eol"},context:"normal"},{keys:"A",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"endOfSelectedArea"},context:"visual"},{keys:"i",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"inplace"},context:"normal"},{keys:"gi",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"lastEdit"},context:"normal"},{keys:"I",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"firstNonBlank"},context:"normal"},{keys:"gI",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"bol"},context:"normal"},{keys:"I",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"startOfSelectedArea"},context:"visual"},{keys:"o",type:"action",action:"newLineAndEnterInsertMode",isEdit:!0,interlaceInsertRepeat:!0,actionArgs:{after:!0},context:"normal"},{keys:"O",type:"action",action:"newLineAndEnterInsertMode",isEdit:!0,interlaceInsertRepeat:!0,actionArgs:{after:!1},context:"normal"},{keys:"v",type:"action",action:"toggleVisualMode"},{keys:"V",type:"action",action:"toggleVisualMode",actionArgs:{linewise:!0}},{keys:"",type:"action",action:"toggleVisualMode",actionArgs:{blockwise:!0}},{keys:"",type:"action",action:"toggleVisualMode",actionArgs:{blockwise:!0}},{keys:"gv",type:"action",action:"reselectLastSelection"},{keys:"J",type:"action",action:"joinLines",isEdit:!0},{keys:"gJ",type:"action",action:"joinLines",actionArgs:{keepSpaces:!0},isEdit:!0},{keys:"p",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!0,isEdit:!0}},{keys:"P",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!1,isEdit:!0}},{keys:"r",type:"action",action:"replace",isEdit:!0},{keys:"@",type:"action",action:"replayMacro"},{keys:"q",type:"action",action:"enterMacroRecordMode"},{keys:"R",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{replace:!0},context:"normal"},{keys:"R",type:"operator",operator:"change",operatorArgs:{linewise:!0,fullLine:!0},context:"visual",exitVisualBlock:!0},{keys:"u",type:"action",action:"undo",context:"normal"},{keys:"u",type:"operator",operator:"changeCase",operatorArgs:{toLower:!0},context:"visual",isEdit:!0},{keys:"U",type:"operator",operator:"changeCase",operatorArgs:{toLower:!1},context:"visual",isEdit:!0},{keys:"",type:"action",action:"redo"},{keys:"m",type:"action",action:"setMark"},{keys:'"',type:"action",action:"setRegister"},{keys:"",type:"action",action:"insertRegister",context:"insert",isEdit:!0},{keys:"",type:"action",action:"oneNormalCommand",context:"insert"},{keys:"zz",type:"action",action:"scrollToCursor",actionArgs:{position:"center"}},{keys:"z.",type:"action",action:"scrollToCursor",actionArgs:{position:"center"},motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:"zt",type:"action",action:"scrollToCursor",actionArgs:{position:"top"}},{keys:"z",type:"action",action:"scrollToCursor",actionArgs:{position:"top"},motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:"zb",type:"action",action:"scrollToCursor",actionArgs:{position:"bottom"}},{keys:"z-",type:"action",action:"scrollToCursor",actionArgs:{position:"bottom"},motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:".",type:"action",action:"repeatLastEdit"},{keys:"",type:"action",action:"incrementNumberToken",isEdit:!0,actionArgs:{increase:!0,backtrack:!1}},{keys:"",type:"action",action:"incrementNumberToken",isEdit:!0,actionArgs:{increase:!1,backtrack:!1}},{keys:"",type:"action",action:"indent",actionArgs:{indentRight:!0},context:"insert"},{keys:"",type:"action",action:"indent",actionArgs:{indentRight:!1},context:"insert"},{keys:"a",type:"motion",motion:"textObjectManipulation"},{keys:"i",type:"motion",motion:"textObjectManipulation",motionArgs:{textObjectInner:!0}},{keys:"/",type:"search",searchArgs:{forward:!0,querySrc:"prompt",toJumplist:!0}},{keys:"?",type:"search",searchArgs:{forward:!1,querySrc:"prompt",toJumplist:!0}},{keys:"*",type:"search",searchArgs:{forward:!0,querySrc:"wordUnderCursor",wholeWordOnly:!0,toJumplist:!0}},{keys:"#",type:"search",searchArgs:{forward:!1,querySrc:"wordUnderCursor",wholeWordOnly:!0,toJumplist:!0}},{keys:"g*",type:"search",searchArgs:{forward:!0,querySrc:"wordUnderCursor",toJumplist:!0}},{keys:"g#",type:"search",searchArgs:{forward:!1,querySrc:"wordUnderCursor",toJumplist:!0}},{keys:":",type:"ex"}],k=w.length,S=[{name:"colorscheme",shortName:"colo"},{name:"map"},{name:"imap",shortName:"im"},{name:"nmap",shortName:"nm"},{name:"vmap",shortName:"vm"},{name:"omap",shortName:"om"},{name:"noremap",shortName:"no"},{name:"nnoremap",shortName:"nn"},{name:"vnoremap",shortName:"vn"},{name:"inoremap",shortName:"ino"},{name:"onoremap",shortName:"ono"},{name:"unmap"},{name:"mapclear",shortName:"mapc"},{name:"nmapclear",shortName:"nmapc"},{name:"vmapclear",shortName:"vmapc"},{name:"imapclear",shortName:"imapc"},{name:"omapclear",shortName:"omapc"},{name:"write",shortName:"w"},{name:"undo",shortName:"u"},{name:"redo",shortName:"red"},{name:"set",shortName:"se"},{name:"setlocal",shortName:"setl"},{name:"setglobal",shortName:"setg"},{name:"sort",shortName:"sor"},{name:"substitute",shortName:"s",possiblyAsync:!0},{name:"startinsert",shortName:"start"},{name:"nohlsearch",shortName:"noh"},{name:"yank",shortName:"y"},{name:"delmarks",shortName:"delm"},{name:"registers",shortName:"reg",excludeFromCommandHistory:!0},{name:"vglobal",shortName:"v"},{name:"delete",shortName:"d"},{name:"join",shortName:"j"},{name:"normal",shortName:"norm"},{name:"global",shortName:"g"}],x=le("");function M(e){e.setOption("disableInput",!0),e.setOption("showCursorWhenSelecting",!1),m.signal(e,"vim-mode-change",{mode:"normal"}),e.on("cursorActivity",Mt),J(e),m.on(e.getInputField(),"paste",b(e))}function A(e){e.setOption("disableInput",!1),e.off("cursorActivity",Mt),m.off(e.getInputField(),"paste",b(e)),e.state.vim=null,ut&&clearTimeout(ut)}function b(e){var t=e.state.vim;return t.onPasteFn||(t.onPasteFn=function(){t.insertMode||(e.setCursor(Se(e.getCursor(),0,1)),Ce.enterInsertMode(e,{},t))}),t.onPasteFn}var L,T=/[\d]/,E=[m.isWordChar,function(e){return e&&!m.isWordChar(e)&&!/\s/.test(e)}],O=[function(e){return/\S/.test(e)}],R=["<",">"],B=["-",'"',".",":","_","/","+"],I=/^\w$/;try{L=new RegExp("^[\\p{Lu}]$","u")}catch(e){L=/^[A-Z]$/}function N(e,t){return t>=e.firstLine()&&t<=e.lastLine()}function K(e){return/^[a-z]$/.test(e)}function P(e){return L.test(e)}function H(e){return/^\s*$/.test(e)}function _(e){return-1!=".?!".indexOf(e)}function $(e,t){for(var n=0;n1&&t.setOption("textwidth",n)}}));var F,U,z=function(){var e=100,t=-1,n=0,r=0,i=new Array(e);function o(o,a){(t+=a)>n?t=n:t0?1:-1,u=o.getCursor();do{if((s=i[(e+(t+=c))%e])&&(l=s.find())&&!be(u,l))break}while(tr)}return s}return{cachedCursor:void 0,add:function(o,a,s){var l=i[t%e];function c(n){var r=++t%e,a=i[r];a&&a.clear(),i[r]=o.setBookmark(n)}if(l){var u=l.find();u&&!be(u,a)&&c(a)}else c(a);c(s),n=t,(r=t-e+1)<0&&(r=0)},find:function(e,n){var r=t,i=o(e,n);return t=r,i&&i.find()},move:o}},Q=function(e){return e?{changes:e.changes,expectCursorActivityForChange:e.expectCursorActivityForChange}:{changes:[],expectCursorActivityForChange:!1}};function q(){this.latestRegister=void 0,this.isPlaying=!1,this.isRecording=!1,this.replaySearchQueries=[],this.onRecordingDone=void 0,this.lastInsertModeChanges=Q()}function J(e){return e.state.vim||(e.state.vim={inputState:new ce,lastEditInputState:void 0,lastEditActionCommand:void 0,lastHPos:-1,lastHSPos:-1,lastMotion:null,marks:{},insertMode:!1,insertModeReturn:!1,insertModeRepeat:void 0,visualMode:!1,visualLine:!1,visualBlock:!1,lastSelection:null,lastPastedText:null,sel:{},options:{},expectLiteralNext:!1}),e.state.vim}function G(){for(var e in F={searchQuery:null,searchIsReversed:!1,lastSubstituteReplacePart:void 0,jumpList:z(),macroModeState:new q,lastCharacterSearch:{increment:0,forward:!0,selectedCharacter:""},registerController:new pe({}),searchHistoryController:new fe,exCommandHistoryController:new fe},D){var t=D[e];t.value=t.defaultValue}}q.prototype={exitMacroRecordMode:function(){var e=F.macroModeState;e.onRecordingDone&&e.onRecordingDone(),e.onRecordingDone=void 0,e.isRecording=!1},enterMacroRecordMode:function(e,t){var n=F.registerController.getRegister(t);if(n){if(n.clear(),this.latestRegister=t,e.openDialog){var r=at("span",{class:"cm-vim-message"},"recording @"+t);this.onRecordingDone=e.openDialog(r,null,{bottom:!0})}this.isRecording=!0}}};var X,Z={enterVimMode:M,leaveVimMode:A,buildKeyMap:function(){},getRegisterController:function(){return F.registerController},resetVimGlobalState_:G,getVimGlobalState_:function(){return F},maybeInitVimState_:J,suppressErrorLogging:!1,InsertModeKey:bt,map:function(e,t,n){Ct.map(e,t,n)},unmap:function(e,t){return Ct.unmap(e,t)},noremap:function(e,t,n){Ct.map(e,t,n,!0)},mapclear:function(e){var t=w.length,n=k,r=w.slice(0,t-n);if(w=w.slice(t-n),e)for(var i=r.length-1;i>=0;i--){var o=r[i];if(e!==o.context)if(o.context)this._mapCommand(o);else{var a=["normal","insert","visual"];for(var s in a)if(a[s]!==e){var l={};for(var c in o)l[c]=o[c];l.context=a[s],this._mapCommand(l)}}}},langmap:se,vimKeyFromEvent:ae,setOption:W,getOption:j,defineOption:V,defineEx:function(e,t,n){if(t){if(0!==e.indexOf(t))throw new Error('(Vim.defineEx) "'+t+'" is not a prefix of "'+e+'", command not registered')}else t=e;yt[e]=n,Ct.commandMap_[t]={name:e,shortName:t,type:"api"}},handleKey:function(e,t,n){var r=this.findKey(e,t,n);if("function"==typeof r)return r()},multiSelectHandleKey:Nt,findKey:function(e,t,n){var r,i=J(e);function o(){if(""==t){if(i.visualMode)$e(e);else{if(!i.insertMode)return;wt(e)}return ue(e),!0}}return!1===(r=i.insertMode?function(){if(o())return!0;i.inputState.keyBuffer.push(t);var n=i.inputState.keyBuffer.join(""),r=1==t.length,a=me.matchCommand(n,w,i.inputState,"insert"),s=i.inputState.changeQueue;if("none"==a.type)return ue(e),!1;if("partial"==a.type){if(a.expectLiteralNext&&(i.expectLiteralNext=!0),U&&window.clearTimeout(U),U=r&&window.setTimeout((function(){i.insertMode&&i.inputState.keyBuffer.length&&ue(e)}),j("insertModeEscKeysTimeout")),r){var l=e.listSelections();s&&s.removed.length==l.length||(s=i.inputState.changeQueue=new he),s.inserted+=t;for(var c=0;c|./gi;i=a.exec(t);){var s=i[0],l=o.insertMode;if(X)te(s);else if(!Z.handleKey(e,s,"mapping")&&l&&o.insertMode){if("<"==s[0]){var c=s.toLowerCase().slice(1,-1),u=c.split("-");if("lt"==(c=u.pop()||""))s="<";else if("space"==c)s=" ";else if("cr"==c)s="\n";else{if(oe.hasOwnProperty(c)){Et(e,s=oe[c]);continue}s=s[0],a.lastIndex=i.index+1}}e.replaceSelection(s)}}}finally{if(Y.pop(),ee=!!Y.length&&r,!Y.length&&X){var h=X;X=null,lt(e,h)}}}var re={Return:"CR",Backspace:"BS",Delete:"Del",Escape:"Esc",Insert:"Ins",ArrowLeft:"Left",ArrowRight:"Right",ArrowUp:"Up",ArrowDown:"Down",Enter:"CR"," ":"Space"},ie={Shift:1,Alt:1,Command:1,Control:1,CapsLock:1,AltGraph:1,Dead:1,Unidentified:1},oe={};function ae(e,t){var n=e.key;if(!ie[n]){n.length>1&&"n"==n[0]&&(n=n.replace("Numpad","")),n=re[n]||n;var r="";if(e.ctrlKey&&(r+="C-"),e.altKey&&(r+="A-"),e.metaKey&&(r+="M-"),m.isMac&&e.altKey&&!e.metaKey&&!e.ctrlKey&&(r=r.slice(2)),(r||n.length>1)&&e.shiftKey&&(r+="S-"),t&&!t.expectLiteralNext&&1==n.length)if(x.keymap&&n in x.keymap)0==x.remapCtrl&&r||(n=x.keymap[n]);else if(n.charCodeAt(0)>255){var i=e.code&&e.code.slice(-1)||"";e.shiftKey||(i=i.toLowerCase()),i&&(n=i)}return(r+=n).length>1&&(r="<"+r+">"),r}}function se(e,t){x.string!==e&&(x=le(e)),x.remapCtrl=t}function le(e){var t={};if(!e)return{keymap:t,string:""};function n(e){return e.split(/\\?(.)/).filter(Boolean)}return e.split(/((?:[^\\,]|\\.)+),/).map((function(e){if(e){var r=e.split(/((?:[^\\;]|\\.)+);/);if(3==r.length){var i=n(r[1]),o=n(r[2]);if(i.length!==o.length)return;for(var a=0;a0||this.motionRepeat.length>0)&&(e=1,this.prefixRepeat.length>0&&(e*=parseInt(this.prefixRepeat.join(""),10)),this.motionRepeat.length>0&&(e*=parseInt(this.motionRepeat.join(""),10))),e},de.prototype={setText:function(e,t,n){this.keyBuffer=[e||""],this.linewise=!!t,this.blockwise=!!n},pushText:function(e,t){t&&(this.linewise||this.keyBuffer.push("\n"),this.linewise=!0),this.keyBuffer.push(e)},pushInsertModeChanges:function(e){this.insertModeChanges.push(Q(e))},pushSearchQuery:function(e){this.searchQueries.push(e)},clear:function(){this.keyBuffer=[],this.insertModeChanges=[],this.searchQueries=[],this.linewise=!1},toString:function(){return this.keyBuffer.join("")}},pe.prototype={pushText:function(e,t,n,r,i){if("_"!==e){r&&"\n"!==n.charAt(n.length-1)&&(n+="\n");var o=this.isValidRegister(e)?this.getRegister(e):null;if(o)P(e)?o.pushText(n,r):o.setText(n,r,i),"+"===e&&"undefined"!=typeof navigator&&void 0!==navigator.clipboard&&"function"==typeof navigator.clipboard.readText&&navigator.clipboard.writeText(n),this.unnamedRegister.setText(o.toString(),r);else{switch(t){case"yank":this.registers[0]=new de(n,r,i);break;case"delete":case"change":-1==n.indexOf("\n")?this.registers["-"]=new de(n,r):(this.shiftNumericRegisters_(),this.registers[1]=new de(n,r))}this.unnamedRegister.setText(n,r,i)}}},getRegister:function(e){return this.isValidRegister(e)?(e=e.toLowerCase(),this.registers[e]||(this.registers[e]=new de),this.registers[e]):this.unnamedRegister},isValidRegister:function(e){return e&&($(e,B)||I.test(e))},shiftNumericRegisters_:function(){for(var e=9;e>=2;e--)this.registers[e]=this.getRegister(""+(e-1))}},fe.prototype={nextMatch:function(e,t){var n=this.historyBuffer,r=t?-1:1;null===this.initialPrefix&&(this.initialPrefix=e);for(var i=this.iterator+r;t?i>=0:i=n.length?(this.iterator=n.length,this.initialPrefix):i<0?e:void 0},pushInput:function(e){var t=this.historyBuffer.indexOf(e);t>-1&&this.historyBuffer.splice(t,1),e.length&&this.historyBuffer.push(e)},reset:function(){this.initialPrefix=null,this.iterator=this.historyBuffer.length}};var me={matchCommand:function(e,t,n,r){var i,o=function(e,t,n,r){r.operator&&(n="operatorPending");for(var i,o=[],a=[],s=ee?t.length-k:0;s"==o.partial[0].keys.slice(-11)};for(var a=0;a"==i.keys.slice(-11)||""==i.keys.slice(-10)){var l=function(e){var t=/^.*(<[^>]+>)$/.exec(e),n=t?t[1]:e.slice(-1);if(n.length>1)switch(n){case"":n="\n";break;case"":n=" ";break;default:n=""}return n}(e);if(!l||l.length>1)return{type:"clear"};n.selectedCharacter=l}return{type:"full",command:i}},processCommand:function(e,t,n){switch(t.inputState.repeatOverride=n.repeatOverride,n.type){case"motion":this.processMotion(e,t,n);break;case"operator":this.processOperator(e,t,n);break;case"operatorMotion":this.processOperatorMotion(e,t,n);break;case"action":this.processAction(e,t,n);break;case"search":this.processSearch(e,t,n);break;case"ex":case"keyToEx":this.processEx(e,t,n)}},processMotion:function(e,t,n){t.inputState.motion=n.motion,t.inputState.motionArgs=ke(n.motionArgs),this.evalInput(e,t)},processOperator:function(e,t,n){var r=t.inputState;if(r.operator){if(r.operator==n.operator)return r.motion="expandToLine",r.motionArgs={linewise:!0},void this.evalInput(e,t);ue(e)}r.operator=n.operator,r.operatorArgs=ke(n.operatorArgs),n.keys.length>1&&(r.operatorShortcut=n.keys),n.exitVisualBlock&&(t.visualBlock=!1,He(e)),t.visualMode&&this.evalInput(e,t)},processOperatorMotion:function(e,t,n){var r=t.visualMode,i=ke(n.operatorMotionArgs);i&&r&&i.visualLine&&(t.visualLine=!0),this.processOperator(e,t,n),r||this.processMotion(e,t,n)},processAction:function(e,t,n){var r=t.inputState,i=r.getRepeat(),o=!!i,a=ke(n.actionArgs)||{};r.selectedCharacter&&(a.selectedCharacter=r.selectedCharacter),n.operator&&this.processOperator(e,t,n),n.motion&&this.processMotion(e,t,n),(n.motion||n.operator)&&this.evalInput(e,t),a.repeat=i||1,a.repeatIsExplicit=o,a.registerName=r.registerName,ue(e),t.lastMotion=null,n.isEdit&&this.recordLastEdit(t,r,n),Ce[n.action](e,a,t)},processSearch:function(e,t,n){if(e.getSearchCursor){var r=n.searchArgs.forward,i=n.searchArgs.wholeWordOnly;tt(e).setReversed(!r);var o=r?"/":"?",a=tt(e).getQuery(),s=e.getScrollInfo();switch(n.searchArgs.querySrc){case"prompt":var l=F.macroModeState;l.isPlaying?d(h=l.replaySearchQueries.shift(),!0,!1):lt(e,{onClose:function(e){d(e,!0,!0);var t=F.macroModeState;t.isRecording&&function(e,t){if(!e.isPlaying){var n=e.latestRegister,r=F.registerController.getRegister(n);r&&r.pushSearchQuery&&r.pushSearchQuery(t)}}(t,e)},prefix:o,desc:"(JavaScript regexp)",onKeyUp:function(t,n,i){var o,a,l,c=ae(t);""==c||""==c?(o=""==c,a=t.target?t.target.selectionEnd:0,i(n=F.searchHistoryController.nextMatch(n,o)||""),a&&t.target&&(t.target.selectionEnd=t.target.selectionStart=Math.min(a,t.target.value.length))):c&&""!=c&&""!=c&&F.searchHistoryController.reset();try{l=ct(e,n,!0,!0)}catch(t){}l?e.scrollIntoView(dt(e,!r,l),30):(pt(e),e.scrollTo(s.left,s.top))},onKeyDown:function(t,n,r){var i=ae(t);""==i||""==i||""==i||""==i&&""==n?(F.searchHistoryController.pushInput(n),F.searchHistoryController.reset(),ct(e,a),pt(e),e.scrollTo(s.left,s.top),m.e_stop(t),ue(e),r(),e.focus()):""==i||""==i?m.e_stop(t):""==i&&(m.e_stop(t),r(""))}});break;case"wordUnderCursor":var c=Ve(e,{noSymbol:!0}),u=!0;if(c||(c=Ve(e,{noSymbol:!1}),u=!1),!c)return st(e,"No word under cursor"),void ue(e);var h=e.getLine(c.start.line).substring(c.start.ch,c.end.ch);h=u&&i?"\\b"+h+"\\b":h.replace(/([.?*+$\[\]\/\\(){}|\-])/g,"\\$1"),F.jumpList.cachedCursor=e.getCursor(),e.setCursor(c.start),d(h,!0,!1)}}function d(r,i,o){F.searchHistoryController.pushInput(r),F.searchHistoryController.reset();try{ct(e,r,i,o)}catch(t){return st(e,"Invalid regex: "+r),void ue(e)}me.processMotion(e,t,{type:"motion",motion:"findNext",motionArgs:{forward:!0,toJumplist:n.searchArgs.toJumplist}})}},processEx:function(e,t,n){function r(t){F.exCommandHistoryController.pushInput(t),F.exCommandHistoryController.reset(),Ct.processCommand(e,t),e.state.vim&&ue(e)}function i(t,n,r){var i,o,a=ae(t);(""==a||""==a||""==a||""==a&&""==n)&&(F.exCommandHistoryController.pushInput(n),F.exCommandHistoryController.reset(),m.e_stop(t),ue(e),r(),e.focus()),""==a||""==a?(m.e_stop(t),i=""==a,o=t.target?t.target.selectionEnd:0,r(n=F.exCommandHistoryController.nextMatch(n,i)||""),o&&t.target&&(t.target.selectionEnd=t.target.selectionStart=Math.min(o,t.target.value.length))):""==a?(m.e_stop(t),r("")):a&&""!=a&&""!=a&&F.exCommandHistoryController.reset()}"keyToEx"==n.type?Ct.processCommand(e,n.exArgs.input):t.visualMode?lt(e,{onClose:r,prefix:":",value:"'<,'>",onKeyDown:i,selectValueOnOpen:!1}):lt(e,{onClose:r,prefix:":",onKeyDown:i})},evalInput:function(e,t){var n,r,i,o=t.inputState,a=o.motion,s=o.motionArgs||{},l=o.operator,c=o.operatorArgs||{},u=o.registerName,h=t.sel,d=Ae(t.visualMode?we(e,h.head):e.getCursor("head")),p=Ae(t.visualMode?we(e,h.anchor):e.getCursor("anchor")),f=Ae(d),m=Ae(p);if(l&&this.recordLastEdit(t,o),(i=void 0!==o.repeatOverride?o.repeatOverride:o.getRepeat())>0&&s.explicitRepeat?s.repeatIsExplicit=!0:(s.noRepeat||!s.explicitRepeat&&0===i)&&(i=1,s.repeatIsExplicit=!1),o.selectedCharacter&&(s.selectedCharacter=c.selectedCharacter=o.selectedCharacter),s.repeat=i,ue(e),a){var g=ge[a](e,d,s,t,o);if(t.lastMotion=ge[a],!g)return;if(s.toJumplist){l||null==e.ace.curOp||(e.ace.curOp.command.scrollIntoView="center-animate");var v=F.jumpList,w=v.cachedCursor;w?(We(e,w,g),delete v.cachedCursor):We(e,d,g)}g instanceof Array?(r=g[0],n=g[1]):n=g,n||(n=Ae(d)),t.visualMode?(t.visualBlock&&n.ch===1/0||(n=we(e,n,f)),r&&(r=we(e,r)),r=r||m,h.anchor=r,h.head=n,He(e),Je(e,t,"<",Le(r,n)?r:n),Je(e,t,">",Le(r,n)?n:r)):l||(e.ace.curOp&&(e.ace.curOp.vimDialogScroll="center-animate"),n=we(e,n,f),e.setCursor(n.line,n.ch))}if(l){if(c.lastSel){r=m;var k=c.lastSel,S=Math.abs(k.head.line-k.anchor.line),x=Math.abs(k.head.ch-k.anchor.ch);n=k.visualLine?new y(m.line+S,m.ch):k.visualBlock?new y(m.line+S,m.ch+x):k.head.line==k.anchor.line?new y(m.line,m.ch+x):new y(m.line+S,m.ch),t.visualMode=!0,t.visualLine=k.visualLine,t.visualBlock=k.visualBlock,h=t.sel={anchor:r,head:n},He(e)}else t.visualMode&&(c.lastSel={anchor:Ae(h.anchor),head:Ae(h.head),visualBlock:t.visualBlock,visualLine:t.visualLine});var M,A,b,L,T;if(t.visualMode){if(M=Te(h.head,h.anchor),A=Ee(h.head,h.anchor),b=t.visualLine||c.linewise,L=t.visualBlock?"block":b?"line":"char",T=_e(e,{anchor:(B=C(e,M,A)).start,head:B.end},L),b){var E=T.ranges;if("block"==L)for(var O=0;O0&&o&&H(o);o=i.pop())n.line--,n.ch=0;o?(n.line--,n.ch=Re(e,n.line)):n.ch=0}}(e,M,A),L="char";var B,I=!s.inclusive||b;T=_e(e,{anchor:(B=C(e,M,A)).start,head:B.end},L,I)}e.setSelections(T.ranges,T.primary),t.lastMotion=null,c.repeat=i,c.registerName=u,c.linewise=b;var N=ye[l](e,c,T.ranges,m,n);t.visualMode&&$e(e,null!=N),N&&e.setCursor(N)}},recordLastEdit:function(e,t,n){var r=F.macroModeState;r.isPlaying||(e.lastEditInputState=t,e.lastEditActionCommand=n,r.lastInsertModeChanges.changes=[],r.lastInsertModeChanges.expectCursorActivityForChange=!1,r.lastInsertModeChanges.visualBlock=e.visualBlock?e.sel.head.line-e.sel.anchor.line:0)}},ge={moveToTopLine:function(e,t,n){var r=ft(e).top+n.repeat-1;return new y(r,De(e.getLine(r)))},moveToMiddleLine:function(e){var t=ft(e),n=Math.floor(.5*(t.top+t.bottom));return new y(n,De(e.getLine(n)))},moveToBottomLine:function(e,t,n){var r=ft(e).bottom-n.repeat+1;return new y(r,De(e.getLine(r)))},expandToLine:function(e,t,n){return new y(t.line+n.repeat-1,1/0)},findNext:function(e,t,n){var r=tt(e),i=r.getQuery();if(i){var o=!n.forward;return o=r.isReversed()?!o:o,ht(e,i),dt(e,o,i,n.repeat)}},findAndSelectNextInclusive:function(e,t,n,r,i){var o=tt(e),a=o.getQuery();if(a){var s=!n.forward,l=function(e,t,n,r,i){return void 0===r&&(r=1),e.operation((function(){var o=e.getCursor(),a=e.getSearchCursor(n,o),s=a.find(!t);!i.visualMode&&s&&be(a.from(),o)&&a.find(!t);for(var l=0;lc&&i.line==c)return Qe(e,t,n,r,!0);var u=e.ace.session.getFoldLine(s);return u&&(n.forward?s>u.start.row&&(s=u.end.row+1):s=u.start.row),n.toFirstChar&&(o=De(e.getLine(s)),r.lastHPos=o),r.lastHSPos=e.charCoords(new y(s,o),"div").left,new y(s,o)},moveByDisplayLines:function(e,t,n,r){var i=t;switch(r.lastMotion){case this.moveByDisplayLines:case this.moveByScroll:case this.moveByLines:case this.moveToColumn:case this.moveToEol:break;default:r.lastHSPos=e.charCoords(i,"div").left}var o=n.repeat;if((s=e.findPosV(i,n.forward?o:-o,"line",r.lastHSPos)).hitSide)if(n.forward)var a={top:e.charCoords(s,"div").top+8,left:r.lastHSPos},s=e.coordsChar(a,"div");else{var l=e.charCoords(new y(e.firstLine(),0),"div");l.left=r.lastHSPos,s=e.coordsChar(l,"div")}return r.lastHPos=s.ch,s},moveByPage:function(e,t,n){var r=t,i=n.repeat;return e.findPosV(r,n.forward?i:-i,"page")},moveByParagraph:function(e,t,n){var r=n.forward?1:-1;return Xe(e,t,n.repeat,r)},moveBySentence:function(e,t,n){var r=n.forward?1:-1;return function(e,t,n,r){function i(e,t){if(t.pos+t.dir<0||t.pos+t.dir>=t.line.length){if(t.ln+=t.dir,!N(e,t.ln))return t.line=null,t.ln=null,void(t.pos=null);t.line=e.getLine(t.ln),t.pos=t.dir>0?0:t.line.length-1}else t.pos+=t.dir}function o(e,t,n,r){var o=""===(c=e.getLine(t)),a={line:c,ln:t,pos:n,dir:r},s={ln:a.ln,pos:a.pos},l=""===a.line;for(i(e,a);null!==a.line;){if(s.ln=a.ln,s.pos=a.pos,""===a.line&&!l)return{ln:a.ln,pos:a.pos};if(o&&""!==a.line&&!H(a.line[a.pos]))return{ln:a.ln,pos:a.pos};!_(a.line[a.pos])||o||a.pos!==a.line.length-1&&!H(a.line[a.pos+1])||(o=!0),i(e,a)}var c=e.getLine(s.ln);s.pos=0;for(var u=c.length-1;u>=0;--u)if(!H(c[u])){s.pos=u;break}return s}function a(e,t,n,r){var o={line:e.getLine(t),ln:t,pos:n,dir:r},a={ln:o.ln,pos:null},s=""===o.line;for(i(e,o);null!==o.line;){if(""===o.line&&!s)return null!==a.pos?a:{ln:o.ln,pos:o.pos};if(_(o.line[o.pos])&&null!==a.pos&&(o.ln!==a.ln||o.pos+1!==a.pos))return a;""===o.line||H(o.line[o.pos])||(s=!1,a={ln:o.ln,pos:o.pos}),i(e,o)}var l=e.getLine(a.ln);a.pos=0;for(var c=0;c0;)s=r<0?a(e,s.ln,s.pos,r):o(e,s.ln,s.pos,r),n--;return new y(s.ln,s.pos)}(e,t,n.repeat,r)},moveByScroll:function(e,t,n,r){var i,o=e.getScrollInfo(),a=n.repeat;a||(a=o.clientHeight/(2*e.defaultTextHeight()));var s=e.charCoords(t,"local");if(n.repeat=a,!(i=ge.moveByDisplayLines(e,t,n,r)))return null;var l=e.charCoords(i,"local");return e.scrollTo(null,o.top+l.top-s.top),i},moveByWords:function(e,t,n){return function(e,t,n,r,i,o){var a=Ae(t),s=[];(r&&!i||!r&&i)&&n++;for(var l=!(r&&i),c=0;c0)u.index=0;else{var f=u.lineText.length;u.index=f>0?f-1:0}u.nextCh=u.lineText.charAt(u.index)}p(u)&&(i.line=l,i.ch=u.index,t--)}return u.nextCh||u.curMoveThrough?new y(l,u.index):i}(e,n.repeat,n.forward,n.selectedCharacter)||t},moveToColumn:function(e,t,n,r){var i=n.repeat;return r.lastHPos=i-1,r.lastHSPos=e.charCoords(t,"div").left,function(e,t){var n=e.getCursor().line;return we(e,new y(n,t-1))}(e,i)},moveToEol:function(e,t,n,r){return Qe(e,t,n,r,!1)},moveToFirstNonWhiteSpaceCharacter:function(e,t){var n=t;return new y(n.line,De(e.getLine(n.line)))},moveToMatchedSymbol:function(e,t){for(var n,r=t,i=r.line,o=r.ch,a=e.getLine(i);o]/.test(a[o])?/[(){}[\]<>]/:/[(){}[\]]/;return e.findMatchingBracket(new y(i,o+1),{bracketRegex:l}).to}return r},moveToStartOfLine:function(e,t){return new y(t.line,0)},moveToLineOrEdgeOfDocument:function(e,t,n){var r=n.forward?e.lastLine():e.firstLine();return n.repeatIsExplicit&&(r=n.repeat-e.getOption("firstLineNumber")),new y(r,De(e.getLine(r)))},moveToStartOfDisplayLine:function(e){return e.execCommand("goLineLeft"),e.getCursor()},moveToEndOfDisplayLine:function(e){e.execCommand("goLineRight");var t=e.getCursor();return"before"==t.sticky&&t.ch--,t},textObjectManipulation:function(e,t,n,r){var i=n.selectedCharacter;"b"==i?i="(":"B"==i&&(i="{");var o,a,s=!n.textObjectInner;if({"(":")",")":"(","{":"}","}":"{","[":"]","]":"[","<":">",">":"<"}[i]){if(a=!0,!(o=Ye(e,t,i,s))){var l=e.getSearchCursor(new RegExp("\\"+i,"g"),t);l.find()&&(o=Ye(e,l.from(),i,s))}}else if({"'":!0,'"':!0,"`":!0}[i])a=!0,o=function(e,t,n,r){var i,o,a,s,l=Ae(t),c=e.getLine(l.line).split(""),u=c.indexOf(n);if(l.ch-1&&!i;a--)c[a]==n&&(i=a+1);else i=l.ch+1;if(i&&!o)for(a=i,s=c.length;a0;){var u=Ve(e,{inclusive:s,innerWord:!s,bigWord:"W"===i,noSymbol:"W"===i,multiline:!0},o&&o.end);u&&(o||(o=u),o.end=u.end)}else if("p"===i)if(o=Xe(e,t,n.repeat,0,s),n.linewise=!0,r.visualMode)r.visualLine||(r.visualLine=!0);else{var h=r.inputState.operatorArgs;h&&(h.linewise=!0),o.end.line--}else if("t"===i)o=function(e,t,n){var r=t;if(!m.findMatchingTag||!m.findEnclosingTag)return{start:r,end:r};var i=m.findMatchingTag(e,t)||m.findEnclosingTag(e,t);return i&&i.open&&i.close?n?{start:i.open.from,end:i.close.to}:{start:i.open.to,end:i.close.from}:{start:r,end:r}}(e,t,s);else if("s"===i){var d=e.getLine(t.line);t.ch>0&&_(d[t.ch])&&(t.ch-=1);var p=Ze(e,t,n.repeat,1,s),f=Ze(e,t,n.repeat,-1,s);H(e.getLine(f.line)[f.ch])&&H(e.getLine(p.line)[p.ch-1])&&(f={line:f.line,ch:f.ch+1}),o={start:f,end:p}}return o?e.state.vim.visualMode?function(e,t,n,r){var i,o=e.state.vim.sel,a=r?t:o.head,s=r?t:o.anchor;return Le(n,t)&&(i=n,n=t,t=i),Le(a,s)?(a=Te(t,a),s=Ee(s,n)):(s=Te(t,s),-1==(a=Se(a=Ee(a,n),0,-1)).ch&&a.line!=e.firstLine()&&(a=new y(a.line-1,Re(e,a.line-1)))),[s,a]}(e,o.start,o.end,a):[o.start,o.end]:null},repeatLastCharacterSearch:function(e,t,n){var r=F.lastCharacterSearch,i=n.repeat,o=n.forward===r.forward,a=(r.increment?1:0)*(o?-1:1);e.moveH(-a,"char"),n.inclusive=!!o;var s=qe(e,i,o,r.selectedCharacter);return s?(s.ch+=a,s):(e.moveH(a,"char"),t)}};function ve(e,t){for(var n=[],r=0;ra.line&&(s=new y(s.line-1,Number.MAX_VALUE))),e.replaceRange("",a,s),r=a}F.registerController.pushText(t.registerName,"change",i,t.linewise,n.length>1),Ce.enterInsertMode(e,{head:r},e.state.vim)},delete:function(e,t,n){var r,i,o=e.state.vim;if(o.visualBlock){i=e.getSelection();var a=ve("",n.length);e.replaceSelections(a),r=Te(n[0].head,n[0].anchor)}else{var s=n[0].anchor,l=n[0].head;t.linewise&&l.line!=e.firstLine()&&s.line==e.lastLine()&&s.line==l.line-1&&(s.line==e.firstLine()?s.ch=0:s=new y(s.line-1,Re(e,s.line-1))),i=e.getRange(s,l),e.replaceRange("",s,l),r=s,t.linewise&&(r=ge.moveToFirstNonWhiteSpaceCharacter(e,s))}return F.registerController.pushText(t.registerName,"delete",i,t.linewise,o.visualBlock),we(e,r)},indent:function(e,t,n){var r=e.state.vim;if(e.indentMore)for(var i=r.visualMode?t.repeat:1,o=0;oo&&t.linewise&&s--,t.keepCursor?r:new y(s,0)}},changeCase:function(e,t,n,r,i){for(var o=e.getSelections(),a=[],s=t.toLower,l=0;lc.top?(l.line+=(s-c.top)/i,l.line=Math.ceil(l.line),e.setCursor(l),c=e.charCoords(l,"local"),e.scrollTo(null,c.top)):e.scrollTo(null,s);else{var u=s+e.getScrollInfo().clientHeight;u=i.anchor.line?Se(i.head,0,1):new y(i.anchor.line,0)}else if("inplace"==r){if(n.visualMode)return}else"lastEdit"==r&&(o=gt(e)||o);e.setOption("disableInput",!1),t&&t.replace?(e.toggleOverwrite(!0),e.setOption("keyMap","vim-replace"),m.signal(e,"vim-mode-change",{mode:"replace"})):(e.toggleOverwrite(!1),e.setOption("keyMap","vim-insert"),m.signal(e,"vim-mode-change",{mode:"insert"})),F.macroModeState.isPlaying||(e.on("change",xt),n.insertEnd&&n.insertEnd.clear(),n.insertEnd=e.setBookmark(o,{insertLeft:!0}),m.on(e.getInputField(),"keydown",Lt)),n.visualMode&&$e(e),Ke(e,o,a)}},toggleVisualMode:function(e,t,n){var r,i=t.repeat,o=e.getCursor();if(n.visualMode)n.visualLine^t.linewise||n.visualBlock^t.blockwise?(n.visualLine=!!t.linewise,n.visualBlock=!!t.blockwise,m.signal(e,"vim-mode-change",{mode:"visual",subMode:n.visualLine?"linewise":n.visualBlock?"blockwise":""}),He(e)):$e(e);else{n.visualMode=!0,n.visualLine=!!t.linewise,n.visualBlock=!!t.blockwise;var a=C(e,o,r=we(e,new y(o.line,o.ch+i-1)));n.sel={anchor:a.start,head:a.end},m.signal(e,"vim-mode-change",{mode:"visual",subMode:n.visualLine?"linewise":n.visualBlock?"blockwise":""}),He(e),Je(e,n,"<",Te(o,r)),Je(e,n,">",Ee(o,r))}},reselectLastSelection:function(e,t,n){var r=n.lastSelection;if(n.visualMode&&Pe(e,n),r){var i=r.anchorMark.find(),o=r.headMark.find();if(!i||!o)return;n.sel={anchor:i,head:o},n.visualMode=!0,n.visualLine=r.visualLine,n.visualBlock=r.visualBlock,He(e),Je(e,n,"<",Te(i,o)),Je(e,n,">",Ee(i,o)),m.signal(e,"vim-mode-change",{mode:"visual",subMode:n.visualLine?"linewise":n.visualBlock?"blockwise":""})}},joinLines:function(e,t,n){var r,i;if(n.visualMode){if(r=e.getCursor("anchor"),Le(i=e.getCursor("head"),r)){var o=i;i=r,r=o}i.ch=Re(e,i.line)-1}else{var a=Math.max(t.repeat,2);r=e.getCursor(),i=we(e,new y(r.line+a-1,1/0))}for(var s=0,l=r.line;l1&&(r=Array(t.repeat+1).join(r));var p,f=i.linewise,m=i.blockwise;if(m){r=r.split("\n"),f&&r.pop();for(var g=0;ge.lastLine()&&e.replaceRange("\n",new y(A,0)),Re(e,A)l.length&&(r=l.length),i=new y(a.line,r)}var c=C(e,a,i);if(a=c.start,i=c.end,"\n"==o)n.visualMode||e.replaceRange("",a,i),(m.commands.newlineAndIndentContinueComment||m.commands.newlineAndIndent)(e);else{var u=e.getRange(a,i);if(u=(u=u.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,o)).replace(/[^\n]/g,o),n.visualBlock){var h=new Array(e.getOption("tabSize")+1).join(" ");u=(u=(u=e.getSelection()).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,o)).replace(/\t/g,h).replace(/[^\n]/g,o).split("\n"),e.replaceSelections(u)}else e.replaceRange(u,a,i);n.visualMode?(a=Le(s[0].anchor,s[0].head)?s[0].anchor:s[0].head,e.setCursor(a),$e(e,!1)):e.setCursor(Se(i,0,-1))}},incrementNumberToken:function(e,t){for(var n,r,i,o,a=e.getCursor(),s=e.getLine(a.line),l=/(-?)(?:(0x)([\da-f]+)|(0b|0|)(\d+))/gi;null!==(n=l.exec(s))&&(i=(r=n.index)+n[0].length,!(a.chl&&(u=-1),(l+=u)>s&&(l-=2)}return new y(o,l)}function ke(e){var t={};for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}function Se(e,t,n){return"object"==typeof t&&(n=t.ch,t=t.line),new y(e.line+t,e.ch+n)}function xe(e,t){var n=""==t.slice(-11),r=""==t.slice(-10);if(n||r){var i=t.length-(n?11:10),o=e.slice(0,i),a=t.slice(0,i);return o==a&&e.length>i?"full":0==a.indexOf(o)&&"partial"}return e==t?"full":0==t.indexOf(e)&&"partial"}function Me(e,t,n){return function(){for(var r=0;r2&&(t=Te.apply(void 0,Array.prototype.slice.call(arguments,1))),Le(e,t)?e:t}function Ee(e,t){return arguments.length>2&&(t=Ee.apply(void 0,Array.prototype.slice.call(arguments,1))),Le(e,t)?t:e}function Oe(e,t,n){var r=Le(e,t),i=Le(t,n);return r&&i}function Re(e,t){return e.getLine(t).length}function Be(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function Ie(e,t,n){var r=Re(e,t),i=new Array(n-r+1).join(" ");e.setCursor(new y(t,r)),e.replaceRange(i,e.getCursor())}function Ne(e,t){var n=[],r=e.listSelections(),i=Ae(e.clipPos(t)),o=!be(t,i),a=function(e,t){for(var n=0;na?l:0,u=r[c].anchor,h=Math.min(u.line,i.line),d=Math.max(u.line,i.line),p=u.ch,f=i.ch,m=r[c].head.ch-p,g=f-p;m>0&&g<=0?(p++,o||f--):m<0&&g>=0?(p--,s||f++):m<0&&-1==g&&(p--,f++);for(var v=h;v<=d;v++){var C={anchor:new y(v,p),head:new y(v,f)};n.push(C)}return e.setSelections(n),t.ch=f,u.ch=p,u}function Ke(e,t,n){for(var r=[],i=0;il&&(i.line=l),i.ch=Re(e,i.line)}return{ranges:[{anchor:o,head:i}],primary:0}}if("block"==n){var c=Math.min(o.line,i.line),u=o.ch,h=Math.max(o.line,i.line),d=i.ch;u=u.length){if(!l)return null;f--,r=ze(e,c,!0,a,!0);break}a?m=O[0]:(m=E[0])(u.charAt(f))||(m=E[1])}for(var g=f,v=f;m(u.charAt(v))&&v>=0;)v--;if(v++,r)g=r.to,p=r.line,(h=e.getLine(p))||0!=g||g++;else for(;m(u.charAt(g))&&g0;)v--;v||w||(v=k)}}return{start:new y(d,v),end:new y(p,g)}}function We(e,t,n){be(t,n)||F.jumpList.add(e,t,n)}function je(e,t){F.lastCharacterSearch.increment=e,F.lastCharacterSearch.forward=t.forward,F.lastCharacterSearch.selectedCharacter=t.selectedCharacter}var Fe={"(":"bracket",")":"bracket","{":"bracket","}":"bracket","[":"section","]":"section","*":"comment","/":"comment",m:"method",M:"method","#":"preprocess"},Ue={bracket:{isComplete:function(e){if(e.nextCh===e.symb){if(e.depth++,e.depth>=1)return!0}else e.nextCh===e.reverseSymb&&e.depth--;return!1}},section:{init:function(e){e.curMoveThrough=!0,e.symb=(e.forward?"]":"[")===e.symb?"{":"}"},isComplete:function(e){return 0===e.index&&e.nextCh===e.symb}},comment:{isComplete:function(e){var t="*"===e.lastCh&&"/"===e.nextCh;return e.lastCh=e.nextCh,t}},method:{init:function(e){e.symb="m"===e.symb?"{":"}",e.reverseSymb="{"===e.symb?"}":"{"},isComplete:function(e){return e.nextCh===e.symb}},preprocess:{init:function(e){e.index=0},isComplete:function(e){if("#"===e.nextCh){var t=e.lineText.match(/^#(\w+)/)[1];if("endif"===t){if(e.forward&&0===e.depth)return!0;e.depth++}else if("if"===t){if(!e.forward&&0===e.depth)return!0;e.depth--}if("else"===t&&0===e.depth)return!0}return!1}}};function ze(e,t,n,r,i){var o=t.line,a=t.ch,s=e.getLine(o),l=n?1:-1,c=r?O:E;if(i&&""==s){if(o+=l,s=e.getLine(o),!N(e,o))return null;a=n?0:s.length}for(;;){if(i&&""==s)return{from:0,to:0,line:o};for(var u=l>0?s.length:-1,h=u,d=u;a!=u;){for(var p=!1,f=0;f0?0:s.length}}function Qe(e,t,n,r,i){var o=new y(t.line+n.repeat-1,1/0),a=e.clipPos(o);return a.ch--,i||(r.lastHPos=1/0,r.lastHSPos=e.charCoords(a,"div").left),o}function qe(e,t,n,r,i){for(var o,a=i||e.getCursor(),s=a.ch,l=0;l0?1:-1;var n=e.ace.session.getFoldLine(t);n&&t+r>n.start.row&&t+r0?n.end.row:n.start.row)-t)}if(r){for(;s<=c&&c<=l&&n>0;)d(c),h(c,r)&&n--,c+=r;return new y(c,0)}var p=e.state.vim;if(p.visualLine&&h(a,1,!0)){var f=p.sel.anchor;h(f.line,-1,!0)&&(i&&f.line==a||(a+=1))}var m=u(a);for(c=a;c<=l&&n;c++)h(c,1,!0)&&(i&&u(c)==m||n--);for(o=new y(c,0),c>l&&!m?m=!0:i=!1,c=a;c>s&&(i&&u(c)!=m&&c!=a||!h(c,-1,!0));c--);return{start:new y(c,0),end:o}}function Ze(e,t,n,r,i){function o(e){e.pos+e.dir<0||e.pos+e.dir>=e.line.length?e.line=null:e.pos+=e.dir}function a(e,t,n,r){var a={line:e.getLine(t),ln:t,pos:n,dir:r};if(""===a.line)return{ln:a.ln,pos:a.pos};var s=a.pos;for(o(a);null!==a.line;){if(s=a.pos,_(a.line[a.pos])){if(i){for(o(a);null!==a.line&&H(a.line[a.pos]);)s=a.pos,o(a);return{ln:a.ln,pos:s+1}}return{ln:a.ln,pos:a.pos+1}}o(a)}return{ln:a.ln,pos:s+1}}function s(e,t,n,r){var a=e.getLine(t),s={line:a,ln:t,pos:n,dir:r};if(""===s.line)return{ln:s.ln,pos:s.pos};var l=s.pos;for(o(s);null!==s.line;){if(H(s.line[s.pos])||_(s.line[s.pos])){if(_(s.line[s.pos]))return i&&H(s.line[s.pos+1])?{ln:s.ln,pos:s.pos+1}:{ln:s.ln,pos:l}}else l=s.pos;o(s)}return s.line=a,i&&H(s.line[s.pos])?{ln:s.ln,pos:s.pos}:{ln:s.ln,pos:l}}for(var l={ln:t.line,pos:t.ch};n>0;)l=r<0?s(e,l.ln,l.pos,r):a(e,l.ln,l.pos,r),n--;return new y(l.ln,l.pos)}function Ye(e,t,n,r){var i,o,a=t,s={"(":/[()]/,")":/[()]/,"[":/[[\]]/,"]":/[[\]]/,"{":/[{}]/,"}":/[{}]/,"<":/[<>]/,">":/[<>]/}[n],l={"(":"(",")":"(","[":"[","]":"[","{":"{","}":"{","<":"<",">":"<"}[n],c=e.getLine(a.line).charAt(a.ch)===l?1:0;if(i=e.scanForBracket(new y(a.line,a.ch+c),-1,void 0,{bracketRegex:s}),o=e.scanForBracket(new y(a.line,a.ch+c),1,void 0,{bracketRegex:s}),!i||!o)return null;if(i=i.pos,o=o.pos,i.line==o.line&&i.ch>o.ch||i.line>o.line){var u=i;i=o,o=u}return r?o.ch+=1:i.ch+=1,{start:i,end:o}}function et(){}function tt(e){var t=e.state.vim;return t.searchState_||(t.searchState_=new et)}function nt(e,t){var n=rt(e,t)||[];if(!n.length)return[];var r=[];if(0===n[0]){for(var i=0;i"),n.selectionLineEnd=r&&r.line}else n.selectionLine=e.getCursor().line;else n.selectionLine=n.line,n.selectionLineEnd=n.lineEnd;var i=t.match(/^(\w+|!!|@@|[!#&*<=>@~])/);return n.commandName=i?i[1]:t.match(/.*/)[0],n},parseLineSpec_:function(e,t){var n=t.match(/^(\d+)/);if(n)return parseInt(n[1],10)-1;switch(t.next()){case".":return this.parseLineSpecOffset_(t,e.getCursor().line);case"$":return this.parseLineSpecOffset_(t,e.lastLine());case"'":var r=t.next(),i=mt(e,e.state.vim,r);if(!i)throw new Error("Mark not set");return this.parseLineSpecOffset_(t,i.line);case"-":case"+":return t.backUp(1),this.parseLineSpecOffset_(t,e.getCursor().line);default:return void t.backUp(1)}},parseLineSpecOffset_:function(e,t){var n=e.match(/^([+-])?(\d+)/);if(n){var r=parseInt(n[2],10);"-"==n[1]?t-=r:t+=r}return t},parseCommandArgs_:function(e,t,n){if(!e.eol()){t.argString=e.match(/.*/)[0];var r=n.argDelimiter||/\s+/,i=Be(t.argString).split(r);i.length&&i[0]&&(t.args=i)}},matchCommand_:function(e){for(var t=e.length;t>0;t--){var n=e.substring(0,t);if(this.commandMap_[n]){var r=this.commandMap_[n];if(0===r.name.indexOf(e))return r}}return null},buildCommandMap_:function(){this.commandMap_={};for(var e=0;e1)return"Invalid arguments";o=(l?"decimal":c&&"hex")||u&&"octal"}s[2]&&(a=new RegExp(s[2].substr(1,s[2].length-2),r?"i":""))}}();if(s)st(e,s+": "+t.argString);else{var l=t.line||e.firstLine(),c=t.lineEnd||t.line||e.lastLine();if(l!=c){var u=new y(l,0),h=new y(c,Re(e,c)),d=e.getRange(u,h).split("\n"),p=a||("decimal"==o?/(-?)([\d]+)/:"hex"==o?/(-?)(?:0x)?([0-9a-f]+)/i:"octal"==o?/([0-7]+)/:null),f="decimal"==o?10:"hex"==o?16:"octal"==o?8:null,g=[],v=[];if(o||a)for(var C=0;C=a&&t<=s:t==a);)if(n||o.from().line!=u||h)return e.scrollIntoView(o.from(),30),e.setSelection(o.from(),o.to()),c=o.from(),void(d=!1);var t,a,s,l,p;d=!0}function v(t){if(t&&t(),e.focus(),c){e.setCursor(c);var n=e.state.vim;n.exMode=!1,n.lastHPos=n.lastHSPos=c.ch}l&&l()}if(g(),!d)return t?void lt(e,{prefix:at("span","replace with ",at("strong",s)," (y/n/a/q/l)"),onKeyDown:function(t,n,r){switch(m.e_stop(t),ae(t)){case"y":f(),g();break;case"n":g();break;case"a":var i=l;l=void 0,e.operation(p),l=i;break;case"l":f();case"q":case"":case"":case"":v(r)}return d&&v(r),!0}}):(p(),void(l&&l()));st(e,"No matches for "+a.source)}(e,c,u,d,p,g,h,l,t.callback)}else st(e,"No previous substitute regular expression")},startinsert:function(e,t){ne(e,"!"==t.argString?"A":"i",{})},redo:m.commands.redo,undo:m.commands.undo,write:function(e){m.commands.save?m.commands.save(e):e.save&&e.save()},nohlsearch:function(e){pt(e)},yank:function(e){var t=Ae(e.getCursor()).line,n=e.getLine(t);F.registerController.pushText("0","yank",n,!0,!0)},delete:function(e,t){var n=t.selectionLine,r=isNaN(t.selectionLineEnd)?n:t.selectionLineEnd;ye.delete(e,{linewise:!0},[{anchor:new y(n,0),head:new y(r+1,0)}])},join:function(e,t){var n=t.selectionLine,r=isNaN(t.selectionLineEnd)?n:t.selectionLineEnd;e.setCursor(new y(n,0)),Ce.joinLines(e,{repeat:r-n},e.state.vim)},delmarks:function(e,t){if(t.argString&&Be(t.argString))for(var n=e.state.vim,r=new m.StringStream(Be(t.argString));!r.eol();){r.eatSpace();var i=r.pos;if(!r.match(/[a-zA-Z]/,!1))return void st(e,"Invalid argument: "+t.argString.substring(i));var o=r.next();if(r.match("-",!0)){if(!r.match(/[a-zA-Z]/,!1))return void st(e,"Invalid argument: "+t.argString.substring(i));var a=o,s=r.next();if(!(K(a)&&K(s)||P(a)&&P(s)))return void st(e,"Invalid argument: "+a+"-");var l=a.charCodeAt(0),c=s.charCodeAt(0);if(l>=c)return void st(e,"Invalid argument: "+t.argString.substring(i));for(var u=0;u<=c-l;u++){var h=String.fromCharCode(l+u);delete n.marks[h]}}else delete n.marks[o]}else st(e,"Argument required")}},Ct=new vt;function wt(e,t){var n=e.state.vim,r=F.macroModeState,i=F.registerController.getRegister("."),o=r.isPlaying,a=r.lastInsertModeChanges;o||(e.off("change",xt),n.insertEnd&&n.insertEnd.clear(),n.insertEnd=null,m.off(e.getInputField(),"keydown",Lt)),!o&&n.insertModeRepeat>1&&(Tt(e,n,n.insertModeRepeat-1,!0),n.lastEditInputState.repeatOverride=n.insertModeRepeat),delete n.insertModeRepeat,n.insertMode=!1,t||e.setCursor(e.getCursor().line,e.getCursor().ch-1),e.setOption("keyMap","vim"),e.setOption("disableInput",!0),e.toggleOverwrite(!1),i.setText(a.changes.join("")),m.signal(e,"vim-mode-change",{mode:"normal"}),r.isRecording&&function(e){if(!e.isPlaying){var t=e.latestRegister,n=F.registerController.getRegister(t);n&&n.pushInsertModeChanges&&n.pushInsertModeChanges(e.lastInsertModeChanges)}}(r)}function kt(e){w.unshift(e)}function St(e,t,n,r){var i=F.registerController.getRegister(r);if(":"==r)return i.keyBuffer[0]&&Ct.processCommand(e,i.keyBuffer[0]),void(n.isPlaying=!1);var o=i.keyBuffer,a=0;n.isPlaying=!0,n.replaySearchQueries=i.searchQueries.slice(0);for(var s=0;s|<\w+>|./.exec(u))[0],u=u.substring(l.index+c.length),Z.handleKey(e,c,"macro"),t.insertMode){var h=i.insertModeChanges[a++].changes;F.macroModeState.lastInsertModeChanges.changes=h,Ot(e,h,1),wt(e)}n.isPlaying=!1}function xt(e,t){var n=F.macroModeState,r=n.lastInsertModeChanges;if(!n.isPlaying)for(var i=e.state.vim;t;){if(r.expectCursorActivityForChange=!0,r.ignoreCount>1)r.ignoreCount--;else if("+input"==t.origin||"paste"==t.origin||void 0===t.origin){var o=e.listSelections().length;o>1&&(r.ignoreCount=o);var a=t.text.join("\n");if(r.maybeReset&&(r.changes=[],r.maybeReset=!1),a)if(e.state.overwrite&&!/\n/.test(a))r.changes.push([a]);else{if(a.length>1){var s=i&&i.insertEnd&&i.insertEnd.find(),l=e.getCursor();if(s&&s.line==l.line){var c=s.ch-l.ch;c>0&&c",Ee(i,r))}else t.insertMode||n||(t.lastHPos=e.getCursor().ch)}function bt(e,t){this.keyName=e,this.key=t.key,this.ctrlKey=t.ctrlKey,this.altKey=t.altKey,this.metaKey=t.metaKey,this.shiftKey=t.shiftKey}function Lt(e){var t=F.macroModeState.lastInsertModeChanges,n=m.keyName?m.keyName(e):e.key;n&&(-1==n.indexOf("Delete")&&-1==n.indexOf("Backspace")||(t.maybeReset&&(t.changes=[],t.maybeReset=!1),t.changes.push(new bt(n,e))))}function Tt(e,t,n,r){var i=F.macroModeState;i.isPlaying=!0;var o=!!t.lastEditActionCommand,a=t.inputState;function s(){o?me.processAction(e,t,t.lastEditActionCommand):me.evalInput(e,t)}function l(n){if(i.lastInsertModeChanges.changes.length>0){n=t.lastEditActionCommand?n:1;var r=i.lastInsertModeChanges;Ot(e,r.changes,n)}}if(t.inputState=t.lastEditInputState,o&&t.lastEditActionCommand.interlaceInsertRepeat)for(var c=0;c"!=t||i.insertMode||i.visualMode||!a)if(o||!a||e.ace.inVirtualSelectionMode)r=Z.handleKey(e,t,n);else{var s=It(i),l=i.inputState.changeQueueList||[];e.operation((function(){e.curOp.isVimOp=!0;var o=0;e.ace.forEachSelection((function(){var i=e.ace.selection;e.state.vim.lastHPos=null==i.$desiredColumn?i.lead.column:i.$desiredColumn,e.state.vim.inputState.changeQueue=l[o];var a=e.getCursor("head"),c=e.getCursor("anchor"),u=Le(a,c)?0:-1,h=Le(a,c)?-1:0;a=Se(a,0,u),c=Se(c,0,h),e.state.vim.sel.head=a,e.state.vim.sel.anchor=c,r=Bt(e,t,n),i.$desiredColumn=-1==e.state.vim.lastHPos?null:e.state.vim.lastHPos,e.ace.inVirtualSelectionMode&&(l[o]=e.state.vim.inputState.changeQueue),e.virtualSelectionMode()&&(e.state.vim=It(s)),o++})),e.curOp.cursorActivity&&!r&&(e.curOp.cursorActivity=!1),i.status=e.state.vim.status,e.state.vim=i,i.inputState.changeQueueList=l,i.inputState.changeQueue=null}),!0)}else e.ace.exitMultiSelectMode();return!r||i.visualMode||i.insert||i.visualMode==e.somethingSelected()||At(e,i,!0),r}Z.handleKey=function(e,t,n){return e.operation((function(){return Bt(e,t,n)}),!0)},G(),t.CodeMirror=m;var Kt=Z.maybeInitVimState_;function Pt(e,t){t.off("beforeEndOperation",Pt);var n=t.state.cm.vimCmd;n&&t.execCommand(n.exec?n:n.name,n.args),t.curOp=t.prevOp}t.handler={$id:"ace/keyboard/vim",drawCursor:function(e,t,n,i,a){var s=this.state.vim||{},l=n.characterWidth,c=n.lineHeight,u=t.top,h=t.left;s.insertMode||!(i.cursor?r.comparePoints(i.cursor,i.start)<=0:a.selection.isBackwards()||a.selection.isEmpty())&&h>l&&(h-=l),!s.insertMode&&s.status&&(u+=c/=2),o.translate(e,h,u),o.setStyle(e.style,"width",l+"px"),o.setStyle(e.style,"height",c+"px")},$getDirectionForHighlight:function(e){var t=e.state.cm;if(!Kt(t).insertMode)return e.session.selection.isBackwards()||e.session.selection.isEmpty()},handleKeyboard:function(e,t,n,r,i){var o=e.editor,a=o.state.cm,s=Kt(a);if(-1!=r){if(s.insertMode||(-1==t?(n.charCodeAt(0)>255&&e.inputKey&&(n=e.inputKey)&&4==e.inputHash&&(n=n.toUpperCase()),e.inputChar=n):4==t||0==t?e.inputKey==n&&e.inputHash==t&&e.inputChar?(n=e.inputChar,t=-1):(e.inputChar=null,e.inputKey=n,e.inputHash=t):e.inputChar=e.inputKey=null),a.state.overwrite&&s.insertMode&&"backspace"==n&&0==t)return{command:"gotoleft"};if("c"==n&&1==t&&!u.isMac&&o.getCopyText())return o.once("copy",(function(){s.insertMode?o.selection.clearSelection():a.operation((function(){$e(a)}))})),{command:"null",passEvent:!0};if("esc"==n&&!s.insertMode&&!s.visualMode&&!a.ace.inMultiSelectMode){var l=tt(a).getOverlay();l&&a.removeOverlay(l)}if(-1==t||1&t||0===t&&n.length>1){var c=s.insertMode,h=function(e,t,n,r){t.length>1&&"n"==t[0]&&(t=t.replace("numpad","")),t=Rt[t]||t;var i="";if(n.ctrlKey&&(i+="C-"),n.altKey&&(i+="A-"),(i||t.length>1)&&n.shiftKey&&(i+="S-"),r&&!r.expectLiteralNext&&1==t.length)if(x.keymap&&t in x.keymap)!1===x.remapCtrl&&i||(t=x.keymap[t]);else if(t.charCodeAt(0)>255){var o=n.code&&n.code.slice(-1)||"";n.shiftKey||(o=o.toLowerCase()),o&&(t=o)}return(i+=t).length>1&&(i="<"+i+">"),i}(0,n,i||{},s);null==s.status&&(s.status="");var d=Nt(a,h,"user");if(s=Kt(a),d&&null!=s.status?s.status+=h:null==s.status&&(s.status=""),a._signal("changeStatus"),!d&&(-1!=t||c))return;return{command:"null",passEvent:!d}}}},attach:function(e){e.state||(e.state={});var t=new m(e);function n(){var n=Kt(t).insertMode;t.ace.renderer.setStyle("normal-mode",!n),e.textInput.setCommandMode(!n),e.renderer.$keepTextAreaAtCursor=n,e.renderer.$blockCursor=!n}e.state.cm=t,e.$vimModeHandler=this,M(t),Kt(t).status=null,t.on("vim-command-done",(function(){t.virtualSelectionMode()||(Kt(t).status=null,t.ace._signal("changeStatus"),t.ace.session.markUndoGroup())})),t.on("changeStatus",(function(){t.ace.renderer.updateCursor(),t.ace._signal("changeStatus")})),t.on("vim-mode-change",(function(){t.virtualSelectionMode()||(n(),t._signal("changeStatus"))})),n(),e.renderer.$cursorLayer.drawCursor=this.drawCursor.bind(t)},detach:function(e){var t=e.state.cm;A(t),t.destroy(),e.state.cm=null,e.$vimModeHandler=null,e.renderer.$cursorLayer.drawCursor=null,e.renderer.setStyle("normal-mode",!1),e.textInput.setCommandMode(!1),e.renderer.$keepTextAreaAtCursor=!0},getStatusText:function(e){var t=e.state.cm,n=Kt(t);if(n.insertMode)return"INSERT";var r="";return n.visualMode&&(r+="VISUAL",n.visualLine&&(r+=" LINE"),n.visualBlock&&(r+=" BLOCK")),n.status&&(r+=(r?" ":"")+n.status),r}},Z.defineOption({name:"wrap",set:function(e,t){t&&t.ace.setOption("wrap",e)},type:"boolean"},!1),Z.defineEx("write","w",(function(){console.log(":write is not implemented")})),w.push({keys:"zc",type:"action",action:"fold",actionArgs:{open:!1}},{keys:"zC",type:"action",action:"fold",actionArgs:{open:!1,all:!0}},{keys:"zo",type:"action",action:"fold",actionArgs:{open:!0}},{keys:"zO",type:"action",action:"fold",actionArgs:{open:!0,all:!0}},{keys:"za",type:"action",action:"fold",actionArgs:{toggle:!0}},{keys:"zA",type:"action",action:"fold",actionArgs:{toggle:!0,all:!0}},{keys:"zf",type:"action",action:"fold",actionArgs:{open:!0,all:!0}},{keys:"zd",type:"action",action:"fold",actionArgs:{open:!0,all:!0}},{keys:"",type:"action",action:"aceCommand",actionArgs:{name:"addCursorAbove"}},{keys:"",type:"action",action:"aceCommand",actionArgs:{name:"addCursorBelow"}},{keys:"",type:"action",action:"aceCommand",actionArgs:{name:"addCursorAboveSkipCurrent"}},{keys:"",type:"action",action:"aceCommand",actionArgs:{name:"addCursorBelowSkipCurrent"}},{keys:"",type:"action",action:"aceCommand",actionArgs:{name:"selectMoreBefore"}},{keys:"",type:"action",action:"aceCommand",actionArgs:{name:"selectMoreAfter"}},{keys:"",type:"action",action:"aceCommand",actionArgs:{name:"selectNextBefore"}},{keys:"",type:"action",action:"aceCommand",actionArgs:{name:"selectNextAfter"}}),w.push({keys:"gq",type:"operator",operator:"hardWrap"}),Z.defineOperator("hardWrap",(function(e,t,n,r,i){var o=n[0].anchor.line,a=n[0].head.line;return t.linewise&&a--,f(e.ace,{startRow:o,endRow:a}),y(a,0)})),V("textwidth",void 0,"number",["tw"],(function(e,t){if(void 0!==t){if(void 0===e)return t.ace.getOption("printMarginColumn");var n=Math.round(e);n>1&&t.ace.setOption("printMarginColumn",n)}})),Ce.aceCommand=function(e,t,n){e.vimCmd=t,e.ace.inVirtualSelectionMode?e.ace.on("beforeEndOperation",Pt):Pt(0,e.ace)},Ce.fold=function(e,t,n){e.ace.execCommand(["toggleFoldWidget","toggleFoldWidget","foldOther","unfoldall"][(t.all?2:0)+(t.open?1:0)])},k=w.length,t.handler.defaultKeymap=w,t.handler.actions=Ce,t.Vim=Z})),ace.require(["ace/keyboard/vim"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d170a98bf11efc613399814ca6b8f410.js b/d170a98bf11efc613399814ca6b8f410.js new file mode 100644 index 00000000..ae33f26c --- /dev/null +++ b/d170a98bf11efc613399814ca6b8f410.js @@ -0,0 +1 @@ +ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};r.inherits(a,o),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[o.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[o.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(o,"doc-",[o.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r="/"==e.charAt(1)?2:1;return 1==r?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==r&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==r?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[o.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[o.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}r.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var r=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,a=e.findMatchingBracket({row:t,column:o});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new r(t,0,t,o-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,r,o){if('"'==o||"'"==o){var s=o,l=r.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),g=r.doc.getLine(c.row).substring(c.column,c.column+1),u=new a(r,c.row,c.column),d=u.getCurrentToken();if(g==s&&(i(d,"attribute-value")||i(d,"string")))return{text:"",selection:[1,1]};if(d||(d=u.stepBackward()),!d)return;for(;i(d,"tag-whitespace")||i(d,"whitespace");)d=u.stepBackward();var p=!g||g.match(/\s/);if(i(d,"attribute-equals")&&(p||">"==g)||i(d,"decl-attribute-equals")&&(p||"?"==g))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,r,o){var a=r.doc.getTextRange(o);if(!o.isMultiLine()&&('"'==a||"'"==a)&&r.doc.getLine(o.start.row).substring(o.start.column+1,o.start.column+2)==a)return o.end.column++,o})),this.add("autoclosing","insertion",(function(e,t,n,r,o){if(">"==o){var s=n.getSelectionRange().start,l=new a(r,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var g=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(r.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var d=l.getCurrentTokenRow(),p=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var m=c.value;if(d==s.row&&(m=m.substring(0,s.column-p)),this.voidElements&&this.voidElements.hasOwnProperty(m.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,r,o){if("\n"==o){var s=n.getCursorPosition(),l=r.getLine(s.row),c=new a(r,s.row,s.column),g=c.getCurrentToken();if(i(g,"")&&-1!==g.type.indexOf("tag-close")){if("/>"==g.value)return;for(;g&&-1===g.type.indexOf("tag-name");)g=c.stepBackward();if(!g)return;var u=g.value,d=c.getCurrentTokenRow();if(!(g=c.stepBackward())||-1!==g.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[u]||!this.voidElements){var p=r.getTokenAt(s.row,s.column+1),m=(l=r.getLine(d),this.$getIndent(l)),h=m+r.getTabString();return p&&""==a){var i=n.getSelectionRange().start,s=new o(r,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};r.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?"markbeginend"===t?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())||this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return r}if(l(a,"tag-close"))return r.selfClosing="/>"==a.value,r;r.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,r){for(var o=e.getTokens(t),a=0,i=0;ic)break;var g=this.getFoldWidgetRange(e,"all",t);if(g){if(g.start.row<=a)break;if(g.isMultiLine())t=g.end.row;else if(r==c)break}s=t}}return new o(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var r=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new o(i,r,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new o};r.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,r){return this.getFoldWidgetRangeBase(e,t,n,r)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,g=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};r.inherits(g,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e),a=o.tokens,i=o.state;if(a.length&&"comment"==a[a.length-1].type)return r;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(r+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(g.prototype),t.Mode=g})),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}]}};r.inherits(a,o),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=a})),ace.define("ace/mode/scala_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./doc_comment_highlight_rules").DocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i=function(){var e=this.createKeywordMapper({"variable.language":"this",keyword:"case|default|do|else|for|if|match|while|throw|return|try|trye|catch|finally|yield|abstract|class|def|extends|final|forSome|implicit|implicits|import|lazy|new|object|null|override|package|private|protected|sealed|super|this|trait|type|val|var|with|assert|assume|require|print|println|printf|readLine|readBoolean|readByte|readShort|readChar|readInt|readLong|readFloat|readDouble","support.function":"AbstractMethodError|AssertionError|ClassCircularityError|ClassFormatError|Deprecated|EnumConstantNotPresentException|ExceptionInInitializerError|IllegalAccessError|IllegalThreadStateException|InstantiationError|InternalError|NegativeArraySizeException|NoSuchFieldError|Override|Process|ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|SuppressWarnings|TypeNotPresentException|UnknownError|UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|InstantiationException|IndexOutOfBoundsException|ArrayIndexOutOfBoundsException|CloneNotSupportedException|NoSuchFieldException|IllegalArgumentException|NumberFormatException|SecurityException|Void|InheritableThreadLocal|IllegalStateException|InterruptedException|NoSuchMethodException|IllegalAccessException|UnsupportedOperationException|Enum|StrictMath|Package|Compiler|Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|Character|Boolean|StackTraceElement|Appendable|StringBuffer|Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|StackOverflowError|OutOfMemoryError|VirtualMachineError|ArrayStoreException|ClassCastException|LinkageError|NoClassDefFoundError|ClassNotFoundException|RuntimeException|Exception|ThreadDeath|Error|Throwable|System|ClassLoader|Cloneable|Class|CharSequence|Comparable|String|Object|Unit|Any|AnyVal|AnyRef|Null|ScalaObject|Singleton|Seq|Iterable|List|Option|Array|Char|Byte|Int|Long|Nothing|App|Application|BufferedIterator|BigDecimal|BigInt|Console|Either|Enumeration|Equiv|Fractional|Function|IndexedSeq|Integral|Iterator|Map|Numeric|Nil|NotNull|Ordered|Ordering|PartialFunction|PartialOrdering|Product|Proxy|Range|Responder|Seq|Serializable|Set|Specializable|Stream|StringContext|Symbol|Traversable|TraversableOnce|Tuple|Vector|Pair|Triple","constant.language":"true|false"},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},o.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'"""',next:"tstring"},{token:"string",regex:'"(?=.)',next:"string"},{token:"symbol.constant",regex:"'[\\w\\d_]+"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],string:[{token:"escape",regex:'\\\\"'},{token:"string",regex:'"',next:"start"},{token:"string.invalid",regex:'[^"\\\\]*$',next:"start"},{token:"string",regex:'[^"\\\\]+'}],tstring:[{token:"string",regex:'"{3,5}',next:"start"},{defaultToken:"string"}]},this.embedRules(o,"doc-",[o.getEndRule("start")])};r.inherits(i,a),t.ScalaHighlightRules=i})),ace.define("ace/mode/scala",["require","exports","module","ace/lib/oop","ace/mode/javascript","ace/mode/scala_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./javascript").Mode,a=e("./scala_highlight_rules").ScalaHighlightRules,i=function(){o.call(this),this.HighlightRules=a};r.inherits(i,o),function(){this.createWorker=function(e){return null},this.$id="ace/mode/scala"}.call(i.prototype),t.Mode=i})),ace.require(["ace/mode/scala"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d188c3ef36e0a991304717ef4bf0b118.js b/d188c3ef36e0a991304717ef4bf0b118.js new file mode 100644 index 00000000..6a5529b6 --- /dev/null +++ b/d188c3ef36e0a991304717ef4bf0b118.js @@ -0,0 +1 @@ +ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};o.inherits(a,r),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),o="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[r.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[r.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:o},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(r,"doc-",[r.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var o="/"==e.charAt(1)?2:1;return 1==o?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==o&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==o?"":"end-")+"tag-open.xml",value:e.slice(0,o)},{type:"meta.tag.tag-name.xml",value:e.substr(o)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[r.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[r.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}o.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var o=e("../range").Range,r=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var r=n[1].length,a=e.findMatchingBracket({row:t,column:r});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new o(t,0,t,r-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(r.prototype),t.MatchingBraceOutdent=r})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,o,r){if('"'==r||"'"==r){var s=r,l=o.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),u=o.doc.getLine(c.row).substring(c.column,c.column+1),d=new a(o,c.row,c.column),g=d.getCurrentToken();if(u==s&&(i(g,"attribute-value")||i(g,"string")))return{text:"",selection:[1,1]};if(g||(g=d.stepBackward()),!g)return;for(;i(g,"tag-whitespace")||i(g,"whitespace");)g=d.stepBackward();var m=!u||u.match(/\s/);if(i(g,"attribute-equals")&&(m||">"==u)||i(g,"decl-attribute-equals")&&(m||"?"==u))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,o,r){var a=o.doc.getTextRange(r);if(!r.isMultiLine()&&('"'==a||"'"==a)&&o.doc.getLine(r.start.row).substring(r.start.column+1,r.start.column+2)==a)return r.end.column++,r})),this.add("autoclosing","insertion",(function(e,t,n,o,r){if(">"==r){var s=n.getSelectionRange().start,l=new a(o,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var u=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(o.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var g=l.getCurrentTokenRow(),m=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var p=c.value;if(g==s.row&&(p=p.substring(0,s.column-m)),this.voidElements&&this.voidElements.hasOwnProperty(p.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,o,r){if("\n"==r){var s=n.getCursorPosition(),l=o.getLine(s.row),c=new a(o,s.row,s.column),u=c.getCurrentToken();if(i(u,"")&&-1!==u.type.indexOf("tag-close")){if("/>"==u.value)return;for(;u&&-1===u.type.indexOf("tag-name");)u=c.stepBackward();if(!u)return;var d=u.value,g=c.getCurrentTokenRow();if(!(u=c.stepBackward())||-1!==u.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[d]||!this.voidElements){var m=o.getTokenAt(s.row,s.column+1),p=(l=o.getLine(g),this.$getIndent(l)),h=p+o.getTabString();return m&&""==a){var i=n.getSelectionRange().start,s=new r(o,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};o.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=o.mixin({},this.voidElements),t&&o.mixin(this.optionalEndTags,t)};o.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var o=this._getFirstTagInLine(e,n);return o?o.closing||!o.tagName&&o.selfClosing?"markbeginend"===t?"end":"":!o.tagName||o.selfClosing||this.voidElements.hasOwnProperty(o.tagName.toLowerCase())||this._findEndTagInLine(e,n,o.tagName,o.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return o}if(l(a,"tag-close"))return o.selfClosing="/>"==a.value,o;o.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,o){for(var r=e.getTokens(t),a=0,i=0;ic)break;var u=this.getFoldWidgetRange(e,"all",t);if(u){if(u.start.row<=a)break;if(u.isMultiLine())t=u.end.row;else if(o==c)break}s=t}}return new r(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new r(i,o,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new r};o.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,o){return this.getFoldWidgetRangeBase(e,t,n,o)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,u=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};o.inherits(u,r),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e),a=r.tokens,i=r.state;if(a.length&&"comment"==a[a.length-1].type)return o;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(o+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(u.prototype),t.Mode=u})),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=(e("../lib/lang"),e("./text_highlight_rules").TextHighlightRules),a=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",i=t.supportFunction="rgb|rgba|url|attr|counter|counters",s=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|flex-end|flex-start|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",l=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",c=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",u=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",d=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",g=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",m=function(){var e=this.createKeywordMapper({"support.function":i,"support.constant":s,"support.type":a,"support.constant.color":l,"support.constant.fonts":c},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:u},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+u+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:u},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:d},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:g},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{token:"paren.lparen",regex:"\\{"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};o.inherits(m,r),t.CssHighlightRules=m})),ace.define("ace/mode/css_completions",["require","exports","module"],(function(e,t,n){"use strict";var o={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,double:2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{default:1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},float:{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,static:1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},r=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e)if("string"==typeof e[t]){var n=t.replace(/[A-Z]/g,(function(e){return"-"+e.toLowerCase()}));o.hasOwnProperty(n)||(o[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,o){if(this.completionsDefined||this.defineCompletions(),"ruleset"===e||"ace/mode/scss"==t.$mode.$id){var r=t.getLine(n.row).substr(0,n.column),a=/\([^)]*$/.test(r);return a&&(r=r.substr(r.lastIndexOf("(")+1)),/:[^;]+$/.test(r)?(/([\w\-]+):[^:]*$/.test(r),this.getPropertyValueCompletions(e,t,n,o)):this.getPropertyCompletions(e,t,n,o,a)}return[]},this.getPropertyCompletions=function(e,t,n,r,a){return a=a||!1,Object.keys(o).map((function(e){return{caption:e,snippet:e+": $0"+(a?"":";"),meta:"property",score:1e6}}))},this.getPropertyValueCompletions=function(e,t,n,r){var a=t.getLine(n.row).substr(0,n.column),i=(/([\w\-]+):[^:]*$/.exec(a)||{})[1];if(!i)return[];var s=[];return i in o&&"object"==typeof o[i]&&(s=Object.keys(o[i])),s.map((function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}}))}}).call(r.prototype),t.CssCompletions=r})),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=(e("../behaviour").Behaviour,e("./cstyle").CstyleBehaviour),a=e("../../token_iterator").TokenIterator,i=function(){this.inherit(r),this.add("colon","insertion",(function(e,t,n,o,r){if(":"===r&&n.selection.isEmpty()){var i=n.getCursorPosition(),s=new a(o,i.row,i.column),l=s.getCurrentToken();if(l&&l.value.match(/\s+/)&&(l=s.stepBackward()),l&&"support.type"===l.type){var c=o.doc.getLine(i.row);if(":"===c.substring(i.column,i.column+1))return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(c.substring(i.column)))return{text:":;",selection:[1,1]}}}})),this.add("colon","deletion",(function(e,t,n,o,r){var i=o.doc.getTextRange(r);if(!r.isMultiLine()&&":"===i){var s=n.getCursorPosition(),l=new a(o,s.row,s.column),c=l.getCurrentToken();if(c&&c.value.match(/\s+/)&&(c=l.stepBackward()),c&&"support.type"===c.type&&";"===o.doc.getLine(r.start.row).substring(r.end.column,r.end.column+1))return r.end.column++,r}})),this.add("semicolon","insertion",(function(e,t,n,o,r){if(";"===r&&n.selection.isEmpty()){var a=n.getCursorPosition();if(";"===o.doc.getLine(a.row).substring(a.column,a.column+1))return{text:"",selection:[1,1]}}})),this.add("!important","insertion",(function(e,t,n,o,r){if("!"===r&&n.selection.isEmpty()){var a=n.getCursorPosition(),i=o.doc.getLine(a.row);if(/^\s*(;|}|$)/.test(i.substring(a.column)))return{text:"!important",selection:[10,10]}}}))};o.inherits(i,r),t.CssBehaviour=i})),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./css_highlight_rules").CssHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./css_completions").CssCompletions,c=e("./behaviour/css").CssBehaviour,u=e("./folding/cstyle").FoldMode,d=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new c,this.$completer=new l,this.foldingRules=new u};o.inherits(d,r),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e).tokens;return r.length&&"comment"==r[r.length-1].type||t.match(/^.*\{\s*$/)&&(o+=n),o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/css",this.snippetFileId="ace/snippets/css"}.call(d.prototype),t.Mode=d})),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(e){var t="[_:a-zA-ZÀ-￿][-_:.a-zA-Z0-9À-￿]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"--\x3e",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===a&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(r.prototype),o.inherits(a,r),t.XmlHighlightRules=a})),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./css_highlight_rules").CssHighlightRules,i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./xml_highlight_rules").XmlHighlightRules,l=r.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),c=function(){s.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=l[t];return["meta.tag.punctuation."+("<"==e?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(a,"css-","style"),this.embedTagRules(new i({jsx:!1}).getRules(),"js-","script"),this.constructor===c&&this.normalizeRules()};o.inherits(c,s),t.HtmlHighlightRules=c})),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};o.inherits(a,r),function(){this.$getMode=function(e){for(var t in"string"!=typeof e&&(e=e[0]),this.subModes)if(0===e.indexOf(t))return this.subModes[t];return null},this.$tryMode=function(e,t,n,o){var r=this.$getMode(e);return r?r.getFoldWidget(t,n,o):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var o=this.$getMode(e.getState(n-1));return o&&o.getFoldWidget(e,t,n)||(o=this.$getMode(e.getState(n))),o&&o.getFoldWidget(e,t,n)||(o=this.defaultMode),o.getFoldWidgetRange(e,t,n)}}.call(a.prototype)})),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./mixed").FoldMode,a=e("./xml").FoldMode,i=e("./cstyle").FoldMode,s=t.FoldMode=function(e,t){r.call(this,new a(e,t),{"js-":new i,"css-":new i})};o.inherits(s,r)})),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../token_iterator").TokenIterator,r=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"].concat(["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"]),a={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,for:1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{for:1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,default:1},section:{},summary:{},u:{},ul:{},var:{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},i=Object.keys(a);function s(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"tag-name");)r=n.stepBackward();if(r)return r.value}var c=function(){};(function(){this.getCompletions=function(e,t,n,o){var r=t.getTokenAt(n.row,n.column);if(!r)return[];if(s(r,"tag-name")||s(r,"tag-open")||s(r,"end-tag-open"))return this.getTagCompletions(e,t,n,o);if(s(r,"tag-whitespace")||s(r,"attribute-name"))return this.getAttributeCompletions(e,t,n,o);if(s(r,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,o);var a=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(a)?this.getHTMLEntityCompletions(e,t,n,o):[]},this.getTagCompletions=function(e,t,n,o){return i.map((function(e){return{value:e,meta:"tag",score:1e6}}))},this.getAttributeCompletions=function(e,t,n,o){var i=l(t,n);if(!i)return[];var s=r;return i in a&&(s=s.concat(Object.keys(a[i]))),s.map((function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}}))},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),c=function(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"attribute-name");)r=n.stepBackward();if(r)return r.value}(t,n);if(!i)return[];var u=[];return i in a&&c in a[i]&&"object"==typeof a[i][c]&&(u=Object.keys(a[i][c])),u.map((function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}}))},this.getHTMLEntityCompletions=function(e,t,n,o){return["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"].map((function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}}))}}).call(c.prototype),t.HtmlCompletions=c})),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./text").Mode,i=e("./javascript").Mode,s=e("./css").Mode,l=e("./html_highlight_rules").HtmlHighlightRules,c=e("./behaviour/xml").XmlBehaviour,u=e("./folding/html").FoldMode,d=e("./html_completions").HtmlCompletions,g=e("../worker/worker_client").WorkerClient,m=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],p=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],h=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=l,this.$behaviour=new c,this.$completer=new d,this.createModeDelegates({"js-":i,"css-":s}),this.foldingRules=new u(this.voidElements,r.arrayToMap(p))};o.inherits(h,a),function(){this.blockComment={start:"\x3c!--",end:"--\x3e"},this.voidElements=r.arrayToMap(m),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){if(this.constructor==h){var t=new g(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t}},this.$id="ace/mode/html",this.snippetFileId="ace/snippets/html"}.call(h.prototype),t.Mode=h})),ace.define("ace/mode/curly_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./html_highlight_rules").HtmlHighlightRules,a=function(){r.call(this),this.$rules.start.unshift({token:"variable",regex:"{{",push:"curly-start"}),this.$rules["curly-start"]=[{token:"variable",regex:"}}",next:"pop"}],this.normalizeRules()};o.inherits(a,r),t.CurlyHighlightRules=a})),ace.define("ace/mode/curly",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/matching_brace_outdent","ace/mode/folding/html","ace/mode/curly_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./html").Mode,a=e("./matching_brace_outdent").MatchingBraceOutdent,i=e("./folding/html").FoldMode,s=e("./curly_highlight_rules").CurlyHighlightRules,l=function(){r.call(this),this.HighlightRules=s,this.$outdent=new a,this.foldingRules=new i};o.inherits(l,r),function(){this.$id="ace/mode/curly"}.call(l.prototype),t.Mode=l})),ace.require(["ace/mode/curly"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d1907231dc06c32481fefd6d47da973b.js b/d1907231dc06c32481fefd6d47da973b.js new file mode 100644 index 00000000..7d6e5924 --- /dev/null +++ b/d1907231dc06c32481fefd6d47da973b.js @@ -0,0 +1 @@ +ace.define("ace/ext/searchbox-css",["require","exports","module"],(function(e,t,n){n.exports='\n\n/* ------------------------------------------------------------------------------------------\n * Editor Search Form\n * --------------------------------------------------------------------------------------- */\n.ace_search {\n background-color: #ddd;\n color: #666;\n border: 1px solid #cbcbcb;\n border-top: 0 none;\n overflow: hidden;\n margin: 0;\n padding: 4px 6px 0 4px;\n position: absolute;\n top: 0;\n z-index: 99;\n white-space: normal;\n}\n.ace_search.left {\n border-left: 0 none;\n border-radius: 0px 0px 5px 0px;\n left: 0;\n}\n.ace_search.right {\n border-radius: 0px 0px 0px 5px;\n border-right: 0 none;\n right: 0;\n}\n\n.ace_search_form, .ace_replace_form {\n margin: 0 20px 4px 0;\n overflow: hidden;\n line-height: 1.9;\n}\n.ace_replace_form {\n margin-right: 0;\n}\n.ace_search_form.ace_nomatch {\n outline: 1px solid red;\n}\n\n.ace_search_field {\n border-radius: 3px 0 0 3px;\n background-color: white;\n color: black;\n border: 1px solid #cbcbcb;\n border-right: 0 none;\n outline: 0;\n padding: 0;\n font-size: inherit;\n margin: 0;\n line-height: inherit;\n padding: 0 6px;\n min-width: 17em;\n vertical-align: top;\n min-height: 1.8em;\n box-sizing: content-box;\n}\n.ace_searchbtn {\n border: 1px solid #cbcbcb;\n line-height: inherit;\n display: inline-block;\n padding: 0 6px;\n background: #fff;\n border-right: 0 none;\n border-left: 1px solid #dcdcdc;\n cursor: pointer;\n margin: 0;\n position: relative;\n color: #666;\n}\n.ace_searchbtn:last-child {\n border-radius: 0 3px 3px 0;\n border-right: 1px solid #cbcbcb;\n}\n.ace_searchbtn:disabled {\n background: none;\n cursor: default;\n}\n.ace_searchbtn:hover {\n background-color: #eef1f6;\n}\n.ace_searchbtn.prev, .ace_searchbtn.next {\n padding: 0px 0.7em\n}\n.ace_searchbtn.prev:after, .ace_searchbtn.next:after {\n content: "";\n border: solid 2px #888;\n width: 0.5em;\n height: 0.5em;\n border-width: 2px 0 0 2px;\n display:inline-block;\n transform: rotate(-45deg);\n}\n.ace_searchbtn.next:after {\n border-width: 0 2px 2px 0 ;\n}\n.ace_searchbtn_close {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;\n border-radius: 50%;\n border: 0 none;\n color: #656565;\n cursor: pointer;\n font: 16px/16px Arial;\n padding: 0;\n height: 14px;\n width: 14px;\n top: 9px;\n right: 7px;\n position: absolute;\n}\n.ace_searchbtn_close:hover {\n background-color: #656565;\n background-position: 50% 100%;\n color: white;\n}\n\n.ace_button {\n margin-left: 2px;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -o-user-select: none;\n -ms-user-select: none;\n user-select: none;\n overflow: hidden;\n opacity: 0.7;\n border: 1px solid rgba(100,100,100,0.23);\n padding: 1px;\n box-sizing: border-box!important;\n color: black;\n}\n\n.ace_button:hover {\n background-color: #eee;\n opacity:1;\n}\n.ace_button:active {\n background-color: #ddd;\n}\n\n.ace_button.checked {\n border-color: #3399ff;\n opacity:1;\n}\n\n.ace_search_options{\n margin-bottom: 3px;\n text-align: right;\n -webkit-user-select: none;\n -moz-user-select: none;\n -o-user-select: none;\n -ms-user-select: none;\n user-select: none;\n clear: both;\n}\n\n.ace_search_counter {\n float: left;\n font-family: arial;\n padding: 0 8px;\n}'})),ace.define("ace/ext/searchbox",["require","exports","module","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/ext/searchbox-css","ace/keyboard/hash_handler","ace/lib/keys","ace/config"],(function(e,t,n){"use strict";var i=e("../lib/dom"),c=e("../lib/lang"),o=e("../lib/event"),s=e("./searchbox-css"),a=e("../keyboard/hash_handler").HashHandler,r=e("../lib/keys"),h=e("../config").nls;i.importCssString(s,"ace_searchbox",!1);var l=function(){function e(e,t,n){this.activeInput;var c=i.createElement("div");i.buildDom(["div",{class:"ace_search right"},["span",{action:"hide",class:"ace_searchbtn_close"}],["div",{class:"ace_search_form"},["input",{class:"ace_search_field",placeholder:h("search-box.find.placeholder","Search for"),spellcheck:"false"}],["span",{action:"findPrev",class:"ace_searchbtn prev"},"​"],["span",{action:"findNext",class:"ace_searchbtn next"},"​"],["span",{action:"findAll",class:"ace_searchbtn",title:"Alt-Enter"},h("search-box.find-all.text","All")]],["div",{class:"ace_replace_form"},["input",{class:"ace_search_field",placeholder:h("search-box.replace.placeholder","Replace with"),spellcheck:"false"}],["span",{action:"replaceAndFindNext",class:"ace_searchbtn"},h("search-box.replace-next.text","Replace")],["span",{action:"replaceAll",class:"ace_searchbtn"},h("search-box.replace-all.text","All")]],["div",{class:"ace_search_options"},["span",{action:"toggleReplace",class:"ace_button",title:h("search-box.toggle-replace.title","Toggle Replace mode"),style:"float:left;margin-top:-2px;padding:0 5px;"},"+"],["span",{class:"ace_search_counter"}],["span",{action:"toggleRegexpMode",class:"ace_button",title:h("search-box.toggle-regexp.title","RegExp Search")},".*"],["span",{action:"toggleCaseSensitive",class:"ace_button",title:h("search-box.toggle-case.title","CaseSensitive Search")},"Aa"],["span",{action:"toggleWholeWords",class:"ace_button",title:h("search-box.toggle-whole-word.title","Whole Word Search")},"\\b"],["span",{action:"searchInSelection",class:"ace_button",title:h("search-box.toggle-in-selection.title","Search In Selection")},"S"]]],c),this.element=c.firstChild,this.setSession=this.setSession.bind(this),this.$init(),this.setEditor(e),i.importCssString(s,"ace_searchbox",e.container)}return e.prototype.setEditor=function(e){e.searchBox=this,e.renderer.scroller.appendChild(this.element),this.editor=e},e.prototype.setSession=function(e){this.searchRange=null,this.$syncOptions(!0)},e.prototype.$initElements=function(e){this.searchBox=e.querySelector(".ace_search_form"),this.replaceBox=e.querySelector(".ace_replace_form"),this.searchOption=e.querySelector("[action=searchInSelection]"),this.replaceOption=e.querySelector("[action=toggleReplace]"),this.regExpOption=e.querySelector("[action=toggleRegexpMode]"),this.caseSensitiveOption=e.querySelector("[action=toggleCaseSensitive]"),this.wholeWordOption=e.querySelector("[action=toggleWholeWords]"),this.searchInput=this.searchBox.querySelector(".ace_search_field"),this.replaceInput=this.replaceBox.querySelector(".ace_search_field"),this.searchCounter=e.querySelector(".ace_search_counter")},e.prototype.$init=function(){var e=this.element;this.$initElements(e);var t=this;o.addListener(e,"mousedown",(function(e){setTimeout((function(){t.activeInput.focus()}),0),o.stopPropagation(e)})),o.addListener(e,"click",(function(e){var n=(e.target||e.srcElement).getAttribute("action");n&&t[n]?t[n]():t.$searchBarKb.commands[n]&&t.$searchBarKb.commands[n].exec(t),o.stopPropagation(e)})),o.addCommandKeyListener(e,(function(e,n,i){var c=r.keyCodeToString(i),s=t.$searchBarKb.findKeyCommand(n,c);s&&s.exec&&(s.exec(t),o.stopEvent(e))})),this.$onChange=c.delayedCall((function(){t.find(!1,!1)})),o.addListener(this.searchInput,"input",(function(){t.$onChange.schedule(20)})),o.addListener(this.searchInput,"focus",(function(){t.activeInput=t.searchInput,t.searchInput.value&&t.highlight()})),o.addListener(this.replaceInput,"focus",(function(){t.activeInput=t.replaceInput,t.searchInput.value&&t.highlight()}))},e.prototype.setSearchRange=function(e){this.searchRange=e,e?this.searchRangeMarker=this.editor.session.addMarker(e,"ace_active-line"):this.searchRangeMarker&&(this.editor.session.removeMarker(this.searchRangeMarker),this.searchRangeMarker=null)},e.prototype.$syncOptions=function(e){i.setCssClass(this.replaceOption,"checked",this.searchRange),i.setCssClass(this.searchOption,"checked",this.searchOption.checked),this.replaceOption.textContent=this.replaceOption.checked?"-":"+",i.setCssClass(this.regExpOption,"checked",this.regExpOption.checked),i.setCssClass(this.wholeWordOption,"checked",this.wholeWordOption.checked),i.setCssClass(this.caseSensitiveOption,"checked",this.caseSensitiveOption.checked);var t=this.editor.getReadOnly();this.replaceOption.style.display=t?"none":"",this.replaceBox.style.display=this.replaceOption.checked&&!t?"":"none",this.find(!1,!1,e)},e.prototype.highlight=function(e){this.editor.session.highlight(e||this.editor.$search.$options.re),this.editor.renderer.updateBackMarkers()},e.prototype.find=function(e,t,n){var c=!this.editor.find(this.searchInput.value,{skipCurrent:e,backwards:t,wrap:!0,regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked,preventScroll:n,range:this.searchRange})&&this.searchInput.value;i.setCssClass(this.searchBox,"ace_nomatch",c),this.editor._emit("findSearchBox",{match:!c}),this.highlight(),this.updateCounter()},e.prototype.updateCounter=function(){var e=this.editor,t=e.$search.$options.re,n=t.unicode,i=0,o=0;if(t){var s=this.searchRange?e.session.getTextRange(this.searchRange):e.getValue(),a=e.session.doc.positionToIndex(e.selection.anchor);this.searchRange&&(a-=e.session.doc.positionToIndex(this.searchRange.start));for(var r,l=t.lastIndex=0;(r=t.exec(s))&&(i++,(l=r.index)<=a&&o++,!(i>999))&&(r[0]||(t.lastIndex=l+=c.skipEmptyMatch(s,l,n),!(l>=s.length))););}this.searchCounter.textContent=h("search-box.search-counter","$0 of $1",[o,i>999?"999+":i])},e.prototype.findNext=function(){this.find(!0,!1)},e.prototype.findPrev=function(){this.find(!0,!0)},e.prototype.findAll=function(){var e=!this.editor.findAll(this.searchInput.value,{regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked})&&this.searchInput.value;i.setCssClass(this.searchBox,"ace_nomatch",e),this.editor._emit("findSearchBox",{match:!e}),this.highlight(),this.hide()},e.prototype.replace=function(){this.editor.getReadOnly()||this.editor.replace(this.replaceInput.value)},e.prototype.replaceAndFindNext=function(){this.editor.getReadOnly()||(this.editor.replace(this.replaceInput.value),this.findNext())},e.prototype.replaceAll=function(){this.editor.getReadOnly()||this.editor.replaceAll(this.replaceInput.value)},e.prototype.hide=function(){this.active=!1,this.setSearchRange(null),this.editor.off("changeSession",this.setSession),this.element.style.display="none",this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb),this.editor.focus()},e.prototype.show=function(e,t){this.active=!0,this.editor.on("changeSession",this.setSession),this.element.style.display="",this.replaceOption.checked=t,e&&(this.searchInput.value=e),this.searchInput.focus(),this.searchInput.select(),this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb),this.$syncOptions(!0)},e.prototype.isFocused=function(){var e=document.activeElement;return e==this.searchInput||e==this.replaceInput},e}(),p=new a;p.bindKeys({"Ctrl-f|Command-f":function(e){var t=e.isReplace=!e.isReplace;e.replaceBox.style.display=t?"":"none",e.replaceOption.checked=!1,e.$syncOptions(),e.searchInput.focus()},"Ctrl-H|Command-Option-F":function(e){e.editor.getReadOnly()||(e.replaceOption.checked=!0,e.$syncOptions(),e.replaceInput.focus())},"Ctrl-G|Command-G":function(e){e.findNext()},"Ctrl-Shift-G|Command-Shift-G":function(e){e.findPrev()},esc:function(e){setTimeout((function(){e.hide()}))},Return:function(e){e.activeInput==e.replaceInput&&e.replace(),e.findNext()},"Shift-Return":function(e){e.activeInput==e.replaceInput&&e.replace(),e.findPrev()},"Alt-Return":function(e){e.activeInput==e.replaceInput&&e.replaceAll(),e.findAll()},Tab:function(e){(e.activeInput==e.replaceInput?e.searchInput:e.replaceInput).focus()}}),p.addCommands([{name:"toggleRegexpMode",bindKey:{win:"Alt-R|Alt-/",mac:"Ctrl-Alt-R|Ctrl-Alt-/"},exec:function(e){e.regExpOption.checked=!e.regExpOption.checked,e.$syncOptions()}},{name:"toggleCaseSensitive",bindKey:{win:"Alt-C|Alt-I",mac:"Ctrl-Alt-R|Ctrl-Alt-I"},exec:function(e){e.caseSensitiveOption.checked=!e.caseSensitiveOption.checked,e.$syncOptions()}},{name:"toggleWholeWords",bindKey:{win:"Alt-B|Alt-W",mac:"Ctrl-Alt-B|Ctrl-Alt-W"},exec:function(e){e.wholeWordOption.checked=!e.wholeWordOption.checked,e.$syncOptions()}},{name:"toggleReplace",exec:function(e){e.replaceOption.checked=!e.replaceOption.checked,e.$syncOptions()}},{name:"searchInSelection",exec:function(e){e.searchOption.checked=!e.searchRange,e.setSearchRange(e.searchOption.checked&&e.editor.getSelectionRange()),e.$syncOptions()}}]);var d=new a([{bindKey:"Esc",name:"closeSearchBar",exec:function(e){e.searchBox.hide()}}]);l.prototype.$searchBarKb=p,l.prototype.$closeSearchBarKb=d,t.SearchBox=l,t.Search=function(e,t){(e.searchBox||new l(e)).show(e.session.getTextRange(),t)}})),ace.require(["ace/ext/searchbox"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d1db2c4677dd2ee7a0c690c58798a013.js b/d1db2c4677dd2ee7a0c690c58798a013.js new file mode 100644 index 00000000..cae46cc5 --- /dev/null +++ b/d1db2c4677dd2ee7a0c690c58798a013.js @@ -0,0 +1 @@ +ace.define("ace/mode/mediawiki_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var i=e("../lib/oop"),a=e("./text_highlight_rules").TextHighlightRules,o=function(){this.$rules={start:[{include:"#switch"},{include:"#redirect"},{include:"#variable"},{include:"#comment"},{include:"#entity"},{include:"#emphasis"},{include:"#tag"},{include:"#table"},{include:"#hr"},{include:"#heading"},{include:"#link"},{include:"#list"},{include:"#template"}],"#hr":[{token:"markup.bold",regex:/^[-]{4,}/}],"#switch":[{token:"constant.language",regex:/(__NOTOC__|__FORCETOC__|__TOC__|__NOEDITSECTION__|__NEWSECTIONLINK__|__NONEWSECTIONLINK__|__NOWYSIWYG__|__NOGALLERY__|__HIDDENCAT__|__EXPECTUNUSEDCATEGORY__|__NOCONTENTCONVERT__|__NOCC__|__NOTITLECONVERT__|__NOTC__|__START__|__END__|__INDEX__|__NOINDEX__|__STATICREDIRECT__|__NOGLOBAL__|__DISAMBIG__)/}],"#redirect":[{token:["keyword.control.redirect","meta.keyword.control"],regex:/(^#REDIRECT|^#redirect|^#Redirect)(\s+)/}],"#variable":[{token:"storage.type.variable",regex:/{{{/,push:[{token:"storage.type.variable",regex:/}}}/,next:"pop"},{token:["text","variable.other","text","keyword.operator"],regex:/(\s*)(\w+)(\s*)((?:\|)?)/},{defaultToken:"storage.type.variable"}]}],"#entity":[{token:"constant.character.entity",regex:/&\w+;/}],"#list":[{token:"markup.bold",regex:/^[#*;:]+/,push:[{token:"markup.list",regex:/$/,next:"pop"},{include:"$self"},{defaultToken:"markup.list"}]}],"#template":[{token:["storage.type.function","meta.template","entity.name.function","meta.template"],regex:/({{)(\s*)([#\w: ]+)(\s*)/,push:[{token:"storage.type.function",regex:/}}/,next:"pop"},{token:["storage","meta.structure.dictionary","support.type.property-name","meta.structure.dictionary","punctuation.separator.dictionary.key-value","meta.structure.dictionary","meta.structure.dictionary.value"],regex:/(\|)(\s*)([a-zA-Z-]*)(\s*)(=)(\s*)([^|}]*)/,push:[{token:"meta.structure.dictionary",regex:/(?=}}|[|])/,next:"pop"},{defaultToken:"meta.structure.dictionary"}]},{token:["storage","meta.template.value"],regex:/(\|)(.*?)/,push:[{token:[],regex:/(?=}}|[|])/,next:"pop"},{include:"$self"},{defaultToken:"meta.template.value"}]},{defaultToken:"meta.template"}]}],"#link":[{token:["punctuation.definition.tag.begin","meta.tag.link.internal","entity.name.tag","meta.tag.link.internal","string.other.link.title","meta.tag.link.internal","punctuation.definition.tag"],regex:/(\[\[)(\s*)((?:Category|Wikipedia)?)(:?)([^\]\]\|]+)(\s*)((?:\|)*)/,push:[{token:"punctuation.definition.tag.end",regex:/\]\]/,next:"pop"},{include:"$self"},{defaultToken:"meta.tag.link.internal"}]},{token:["punctuation.definition.tag.begin","meta.tag.link.external","meta.tag.link.external","string.unquoted","punctuation.definition.tag.end"],regex:/(\[)(.*?)([\s]+)(.*?)(\])/}],"#comment":[{token:"punctuation.definition.comment.html",regex://,next:"pop"},{defaultToken:"comment.block.html"}]}],"#emphasis":[{token:["punctuation.definition.tag.begin","markup.italic.bold","punctuation.definition.tag.end"],regex:/(''''')(?!')(.*?)('''''|$)/},{token:["punctuation.definition.tag.begin","markup.bold","punctuation.definition.tag.end"],regex:/(''')(?!')(.*?)('''|$)/},{token:["punctuation.definition.tag.begin","markup.italic","punctuation.definition.tag.end"],regex:/('')(?!')(.*?)(''|$)/}],"#heading":[{token:["punctuation.definition.heading","entity.name.section","punctuation.definition.heading"],regex:/(={1,6})(.+?)(\1)(?!=)/}],"#tag":[{token:["punctuation.definition.tag.begin","entity.name.tag","meta.tag.block.ref","punctuation.definition.tag.end"],regex:/(<)(ref)((?:\s+.*?)?)(>)/,caseInsensitive:!0,push:[{token:["punctuation.definition.tag.begin","entity.name.tag","meta.tag.block.ref","punctuation.definition.tag.end"],regex:/(<\/)(ref)(\s*)(>)/,caseInsensitive:!0,next:"pop"},{include:"$self"},{defaultToken:"meta.tag.block.ref"}]},{token:["punctuation.definition.tag.begin","entity.name.tag","meta.tag.block.nowiki","punctuation.definition.tag.end"],regex:/(<)(nowiki)((?:\s+.*?)?)(>)/,caseInsensitive:!0,push:[{token:["punctuation.definition.tag.begin","entity.name.tag","meta.tag.block.nowiki","punctuation.definition.tag.end"],regex:/(<\/)(nowiki)(\s*)(>)/,caseInsensitive:!0,next:"pop"},{defaultToken:"meta.tag.block.nowiki"}]},{token:["punctuation.definition.tag.begin","entity.name.tag"],regex:/(<\/?)(noinclude|includeonly|onlyinclude)(?=\W)/,caseInsensitive:!0,push:[{token:["invalid.illegal","punctuation.definition.tag.end"],regex:/((?:\/)?)(>)/,next:"pop"},{include:"#attribute"},{defaultToken:"meta.tag.block.any"}]},{token:["punctuation.definition.tag.begin","entity.name.tag"],regex:/(<)(br|wbr|hr|meta|link)(?=\W)/,caseInsensitive:!0,push:[{token:"punctuation.definition.tag.end",regex:/\/?>/,next:"pop"},{include:"#attribute"},{defaultToken:"meta.tag.other"}]},{token:["punctuation.definition.tag.begin","entity.name.tag"],regex:/(<\/?)(div|center|span|h1|h2|h3|h4|h5|h6|bdo|em|strong|cite|dfn|code|samp|kbd|var|abbr|blockquote|q|sub|sup|p|pre|ins|del|ul|ol|li|dl|dd|dt|table|caption|thead|tfoot|tbody|colgroup|col|tr|td|th|a|img|video|source|track|tt|b|i|big|small|strike|s|u|font|ruby|rb|rp|rt|rtc|math|figure|figcaption|bdi|data|time|mark|html)(?=\W)/,caseInsensitive:!0,push:[{token:["invalid.illegal","punctuation.definition.tag.end"],regex:/((?:\/)?)(>)/,next:"pop"},{include:"#attribute"},{defaultToken:"meta.tag.block"}]},{token:["punctuation.definition.tag.begin","invalid.illegal"],regex:/(<\/)(br|wbr|hr|meta|link)(?=\W)/,caseInsensitive:!0,push:[{token:"punctuation.definition.tag.end",regex:/\/?>/,next:"pop"},{include:"#attribute"},{defaultToken:"meta.tag.other"}]}],"#caption":[{token:["meta.tag.block.table-caption","punctuation.definition.tag.begin"],regex:/^(\s*)(\|\+)/,push:[{token:"meta.tag.block.table-caption",regex:/$/,next:"pop"},{defaultToken:"meta.tag.block.table-caption"}]}],"#tr":[{token:["meta.tag.block.tr","punctuation.definition.tag.begin","meta.tag.block.tr","invalid.illegal"],regex:/^(\s*)(\|\-)([\s]*)(.*)/}],"#th":[{token:["meta.tag.block.th.heading","punctuation.definition.tag.begin","meta.tag.block.th.heading","punctuation.definition.tag","markup.bold"],regex:/^(\s*)(!)(?:(.*?)(\|))?(.*?)(?=!!|$)/,push:[{token:"meta.tag.block.th.heading",regex:/$/,next:"pop"},{token:["punctuation.definition.tag.begin","meta.tag.block.th.inline","punctuation.definition.tag","markup.bold"],regex:/(!!)(?:(.*?)(\|))?(.*?)(?=!!|$)/},{include:"$self"},{defaultToken:"meta.tag.block.th.heading"}]}],"#td":[{token:["meta.tag.block.td","punctuation.definition.tag.begin"],regex:/^(\s*)(\|)/,push:[{token:"meta.tag.block.td",regex:/$/,next:"pop"},{include:"$self"},{defaultToken:"meta.tag.block.td"}]}],"#table":[{patterns:[{name:"meta.tag.block.table",begin:"^\\s*({\\|)(.*?)$",end:"^\\s*\\|}",beginCaptures:{1:{name:"punctuation.definition.tag.begin"},2:{patterns:[{include:"#attribute"}]},3:{name:"invalid.illegal"}},endCaptures:{0:{name:"punctuation.definition.tag.end"}},patterns:[{include:"#comment"},{include:"#template"},{include:"#caption"},{include:"#tr"},{include:"#th"},{include:"#td"}]}],repository:{caption:{name:"meta.tag.block.table-caption",begin:"^\\s*(\\|\\+)",end:"$",beginCaptures:{1:{name:"punctuation.definition.tag.begin"}}},tr:{name:"meta.tag.block.tr",match:"^\\s*(\\|\\-)[\\s]*(.*)",captures:{1:{name:"punctuation.definition.tag.begin"},2:{name:"invalid.illegal"}}},th:{name:"meta.tag.block.th.heading",begin:"^\\s*(!)((.*?)(\\|))?(.*?)(?=(!!)|$)",end:"$",beginCaptures:{1:{name:"punctuation.definition.tag.begin"},3:{patterns:[{include:"#attribute"}]},4:{name:"punctuation.definition.tag"},5:{name:"markup.bold"}},patterns:[{name:"meta.tag.block.th.inline",match:"(!!)((.*?)(\\|))?(.*?)(?=(!!)|$)",captures:{1:{name:"punctuation.definition.tag.begin"},3:{patterns:[{include:"#attribute"}]},4:{name:"punctuation.definition.tag"},5:{name:"markup.bold"}}},{include:"$self"}]},td:{name:"meta.tag.block.td",begin:"^\\s*(\\|)",end:"$",beginCaptures:{1:{name:"punctuation.definition.tag.begin"},2:{patterns:[{include:"#attribute"}]},3:{name:"punctuation.definition.tag"}},patterns:[{include:"$self"}]}}}],"#attribute":[{include:"#string"},{token:"entity.other.attribute-name",regex:/\w+/}],"#string":[{token:"string.quoted.double",regex:/\"/,push:[{token:"string.quoted.double",regex:/\"/,next:"pop"},{defaultToken:"string.quoted.double"}]},{token:"string.quoted.single",regex:/\'/,push:[{token:"string.quoted.single",regex:/\'/,next:"pop"},{defaultToken:"string.quoted.single"}]}],"#url":[{token:"markup.underline.link",regex:/(?:http(?:s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:\/?#\[\]@!\$&'\(\)\*\+,;=.]+/},{token:"invalid.illegal",regex:/.*/}]},this.normalizeRules()};o.metaData={name:"MediaWiki",scopeName:"text.html.mediawiki",fileTypes:["mediawiki","wiki"]},i.inherits(o,a),t.MediaWikiHighlightRules=o})),ace.define("ace/mode/mediawiki",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/mediawiki_highlight_rules"],(function(e,t,n){"use strict";var i=e("../lib/oop"),a=e("./text").Mode,o=e("./mediawiki_highlight_rules").MediaWikiHighlightRules,u=function(){this.HighlightRules=o};i.inherits(u,a),function(){this.type="text",this.blockComment={start:"\x3c!--",end:"--\x3e"},this.$id="ace/mode/mediawiki"}.call(u.prototype),t.Mode=u})),ace.require(["ace/mode/mediawiki"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d2242507bff41457eace047e5b93394e.js b/d2242507bff41457eace047e5b93394e.js new file mode 100644 index 00000000..612d76cd --- /dev/null +++ b/d2242507bff41457eace047e5b93394e.js @@ -0,0 +1 @@ +ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,r,o){if('"'==o||"'"==o){var s=o,l=r.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),g=r.doc.getLine(c.row).substring(c.column,c.column+1),u=new a(r,c.row,c.column),d=u.getCurrentToken();if(g==s&&(i(d,"attribute-value")||i(d,"string")))return{text:"",selection:[1,1]};if(d||(d=u.stepBackward()),!d)return;for(;i(d,"tag-whitespace")||i(d,"whitespace");)d=u.stepBackward();var p=!g||g.match(/\s/);if(i(d,"attribute-equals")&&(p||">"==g)||i(d,"decl-attribute-equals")&&(p||"?"==g))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,r,o){var a=r.doc.getTextRange(o);if(!o.isMultiLine()&&('"'==a||"'"==a)&&r.doc.getLine(o.start.row).substring(o.start.column+1,o.start.column+2)==a)return o.end.column++,o})),this.add("autoclosing","insertion",(function(e,t,n,r,o){if(">"==o){var s=n.getSelectionRange().start,l=new a(r,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var g=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(r.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var d=l.getCurrentTokenRow(),p=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var h=c.value;if(d==s.row&&(h=h.substring(0,s.column-p)),this.voidElements&&this.voidElements.hasOwnProperty(h.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,r,o){if("\n"==o){var s=n.getCursorPosition(),l=r.getLine(s.row),c=new a(r,s.row,s.column),g=c.getCurrentToken();if(i(g,"")&&-1!==g.type.indexOf("tag-close")){if("/>"==g.value)return;for(;g&&-1===g.type.indexOf("tag-name");)g=c.stepBackward();if(!g)return;var u=g.value,d=c.getCurrentTokenRow();if(!(g=c.stepBackward())||-1!==g.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[u]||!this.voidElements){var p=r.getTokenAt(s.row,s.column+1),h=(l=r.getLine(d),this.$getIndent(l)),m=h+r.getTabString();return p&&""==a){var i=n.getSelectionRange().start,s=new o(r,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};r.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?"markbeginend"===t?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())||this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return r}if(l(a,"tag-close"))return r.selfClosing="/>"==a.value,r;r.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,r){for(var o=e.getTokens(t),a=0,i=0;ic)break;var g=this.getFoldWidgetRange(e,"all",t);if(g){if(g.start.row<=a)break;if(g.isMultiLine())t=g.end.row;else if(r==c)break}s=t}}return new o(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var r=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new o(i,r,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new o};r.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,r){return this.getFoldWidgetRangeBase(e,t,n,r)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};r.inherits(a,o),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[o.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[o.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(o,"doc-",[o.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r="/"==e.charAt(1)?2:1;return 1==r?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==r&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==r?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[o.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[o.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}r.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var r=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,a=e.findMatchingBracket({row:t,column:o});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new r(t,0,t,o-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,g=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};r.inherits(g,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e),a=o.tokens,i=o.state;if(a.length&&"comment"==a[a.length-1].type)return r;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(r+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(g.prototype),t.Mode=g})),ace.define("ace/mode/typescript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/javascript_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./javascript_highlight_rules").JavaScriptHighlightRules,a=function(e){var t=new o({jsx:1==(e&&e.jsx)}).getRules();t.no_regex=[{token:["storage.type","text","entity.name.function.ts"],regex:"(function)(\\s+)([a-zA-Z0-9$_¡-￿][a-zA-Z0-9d$_¡-￿]*)"},{token:"keyword",regex:"(?:\\b(constructor|declare|interface|as|AS|public|private|extends|export|super|readonly|module|namespace|abstract|implements)\\b)"},{token:["keyword","storage.type.variable.ts"],regex:"(class|type)(\\s+[a-zA-Z0-9_?.$][\\w?.$]*)"},{token:"keyword",regex:"\\b(?:super|export|import|keyof|infer)\\b"},{token:["storage.type.variable.ts"],regex:"(?:\\b(this\\.|string\\b|bool\\b|boolean\\b|number\\b|true\\b|false\\b|undefined\\b|any\\b|null\\b|(?:unique )?symbol\\b|object\\b|never\\b|enum\\b))"}].concat(t.no_regex),this.$rules=t};r.inherits(a,o),t.TypeScriptHighlightRules=a})),ace.define("ace/mode/typescript",["require","exports","module","ace/lib/oop","ace/mode/javascript","ace/mode/typescript_highlight_rules","ace/mode/folding/cstyle","ace/mode/matching_brace_outdent"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./javascript").Mode,a=e("./typescript_highlight_rules").TypeScriptHighlightRules,i=e("./folding/cstyle").FoldMode,s=e("./matching_brace_outdent").MatchingBraceOutdent,l=function(){this.HighlightRules=a,this.$outdent=new s,this.$behaviour=this.$defaultBehaviour,this.foldingRules=new i};r.inherits(l,o),function(){this.createWorker=function(e){return null},this.$id="ace/mode/typescript"}.call(l.prototype),t.Mode=l})),ace.define("ace/mode/tsx",["require","exports","module","ace/lib/oop","ace/mode/behaviour/javascript","ace/mode/folding/javascript","ace/mode/typescript"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./behaviour/javascript").JavaScriptBehaviour,a=e("./folding/javascript").FoldMode,i=e("./typescript").Mode,s=function(){i.call(this),this.$highlightRuleConfig={jsx:!0},this.foldingRules=new a,this.$behaviour=new o};r.inherits(s,i),function(){this.$id="ace/mode/tsx"}.call(s.prototype),t.Mode=s})),ace.require(["ace/mode/tsx"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d43ad5f9bad9a042b49b2592c7639c28.js b/d43ad5f9bad9a042b49b2592c7639c28.js new file mode 100644 index 00000000..8a699714 --- /dev/null +++ b/d43ad5f9bad9a042b49b2592c7639c28.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/gitignore"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d4b890206d2316955676dd69ef0f2779.js b/d4b890206d2316955676dd69ef0f2779.js new file mode 100644 index 00000000..4a86d805 --- /dev/null +++ b/d4b890206d2316955676dd69ef0f2779.js @@ -0,0 +1 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,o){"use strict";var r=e("../lib/oop"),n=e("./text_highlight_rules").TextHighlightRules,i=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},i.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}]}};r.inherits(i,n),i.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},i.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},i.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=i})),ace.define("ace/mode/rust_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/doc_comment_highlight_rules"],(function(e,t,o){"use strict";var r=e("../lib/oop"),n=e("./text_highlight_rules").TextHighlightRules,i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=/\\(?:[nrt0'"\\]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\})/.source,u=/[a-zA-Z_\xa1-\uffff][a-zA-Z0-9_\xa1-\uffff]*/.source,c=function(){var e=this.createKeywordMapper({"keyword.source.rust":"abstract|alignof|as|async|await|become|box|break|catch|continue|const|crate|default|do|dyn|else|enum|extern|for|final|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield|try","storage.type.source.rust":"Self|isize|usize|char|bool|u8|u16|u32|u64|u128|f16|f32|f64|i8|i16|i32|i64|i128|str|option|either|c_float|c_double|c_void|FILE|fpos_t|DIR|dirent|c_char|c_schar|c_uchar|c_short|c_ushort|c_int|c_uint|c_long|c_ulong|size_t|ptrdiff_t|clock_t|time_t|c_longlong|c_ulonglong|intptr_t|uintptr_t|off_t|dev_t|ino_t|pid_t|mode_t|ssize_t","constant.language.source.rust":"true|false|Some|None|Ok|Err|FALSE|TRUE","support.constant.source.rust":"EXIT_FAILURE|EXIT_SUCCESS|RAND_MAX|EOF|SEEK_SET|SEEK_CUR|SEEK_END|_IOFBF|_IONBF|_IOLBF|BUFSIZ|FOPEN_MAX|FILENAME_MAX|L_tmpnam|TMP_MAX|O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_EXCL|O_TRUNC|S_IFIFO|S_IFCHR|S_IFBLK|S_IFDIR|S_IFREG|S_IFMT|S_IEXEC|S_IWRITE|S_IREAD|S_IRWXU|S_IXUSR|S_IWUSR|S_IRUSR|F_OK|R_OK|W_OK|X_OK|STDIN_FILENO|STDOUT_FILENO|STDERR_FILENO","constant.language":"macro_rules|mac_variant"},"identifier");this.$rules={start:[{token:"variable.other.source.rust",regex:"'"+u+"(?![\\'])"},{token:"string.quoted.single.source.rust",regex:"'(?:[^'\\\\]|"+s+")'"},{token:"identifier",regex:"r#"+u+"\\b"},{stateName:"bracketedComment",onMatch:function(e,t,o){return o.unshift(this.next,e.length-1,t),"string.quoted.raw.source.rust"},regex:/r#*"/,next:[{onMatch:function(e,t,o){var r="string.quoted.raw.source.rust";return e.length>=o[1]?(e.length>o[1]&&(r="invalid"),o.shift(),o.shift(),this.next=o.shift()):this.next="",r},regex:/"#*/,next:"start"},{defaultToken:"string.quoted.raw.source.rust"}]},{token:"string.quoted.double.source.rust",regex:'"',push:[{token:"string.quoted.double.source.rust",regex:'"',next:"pop"},{token:"constant.character.escape.source.rust",regex:s},{defaultToken:"string.quoted.double.source.rust"}]},{token:["keyword.source.rust","text","entity.name.function.source.rust","punctuation"],regex:"\\b(fn)(\\s+)((?:r#)?"+u+")(<)(?!<)",push:"generics"},{token:["keyword.source.rust","text","entity.name.function.source.rust"],regex:"\\b(fn)(\\s+)((?:r#)?"+u+")"},{token:["support.constant","punctuation"],regex:"("+u+"::)(<)(?!<)",push:"generics"},{token:"support.constant",regex:u+"::"},{token:"variable.language.source.rust",regex:"\\bself\\b"},i.getStartRule("doc-start"),{token:"comment.line.doc.source.rust",regex:"///.*$"},{token:"comment.line.doc.source.rust",regex:"//!.*$"},{token:"comment.line.double-dash.source.rust",regex:"//.*$"},{token:"comment.start.block.source.rust",regex:"/\\*",stateName:"comment",push:[{token:"comment.start.block.source.rust",regex:"/\\*",push:"comment"},{token:"comment.end.block.source.rust",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.source.rust"}]},{token:["keyword.source.rust","identifier","punctuaction"],regex:"(?:(impl)|("+u+"))(<)(?!<)",stateName:"generics",push:[{token:"keyword.operator",regex:/<<|=/},{token:"punctuaction",regex:"<(?!<)",push:"generics"},{token:"variable.other.source.rust",regex:"'"+u+"(?![\\'])"},{token:"storage.type.source.rust",regex:"\\b(u8|u16|u32|u64|u128|usize|i8|i16|i32|i64|i128|isize|char|bool)\\b"},{token:"keyword",regex:"\\b(?:const|dyn)\\b"},{token:"punctuation",regex:">",next:"pop"},{include:"punctuation"},{include:"operators"},{include:"constants"},{token:"identifier",regex:"\\b"+u+"\\b"}]},{token:e,regex:u},{token:"meta.preprocessor.source.rust",regex:"\\b\\w\\(\\w\\)*!|#\\[[\\w=\\(\\)_]+\\]\\b"},{include:"punctuation"},{include:"operators"},{include:"constants"}],punctuation:[{token:"paren.lparen",regex:/[\[({]/},{token:"paren.rparen",regex:/[\])}]/},{token:"punctuation.operator",regex:/[?:,;.]/}],operators:[{token:"keyword.operator",regex:/\$|[-=]>|[-+%^=!&|<>]=?|[*/](?![*/])=?/}],constants:[{token:"constant.numeric.source.rust",regex:/\b(?:0x[a-fA-F0-9_]+|0o[0-7_]+|0b[01_]+|[0-9][0-9_]*(?!\.))(?:[iu](?:size|8|16|32|64|128))?\b/},{token:"constant.numeric.source.rust",regex:/\b(?:[0-9][0-9_]*)(?:\.[0-9][0-9_]*)?(?:[Ee][+-][0-9][0-9_]*)?(?:f32|f64)?\b/}]},this.embedRules(i,"doc-",[i.getEndRule("start")]),this.normalizeRules()};c.metaData={fileTypes:["rs","rc"],foldingStartMarker:"^.*\\bfn\\s*(\\w+\\s*)?\\([^\\)]*\\)(\\s*\\{[^\\}]*)?\\s*$",foldingStopMarker:"^\\s*\\}",name:"Rust",scopeName:"source.rust"},r.inherits(c,n),t.RustHighlightRules=c})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,o){"use strict";var r=e("../../lib/oop"),n=e("../../range").Range,i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(s,i),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,o){var r=e.getLine(o);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var n=this._getFoldWidgetBase(e,t,o);return!n&&this.startRegionRe.test(r)?"start":n},this.getFoldWidgetRange=function(e,t,o,r){var n,i=e.getLine(o);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,o);if(n=i.match(this.foldingStartMarker)){var s=n.index;if(n[1])return this.openingBracketBlock(e,n[1],o,s);var u=e.getCommentFoldRange(o,s+n[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,o):"all"!=t&&(u=null)),u}return"markbegin"!==t&&(n=i.match(this.foldingStopMarker))?(s=n.index+n[0].length,n[1]?this.closingBracketBlock(e,n[1],o,s):e.getCommentFoldRange(o,s,-1)):void 0},this.getSectionRange=function(e,t){for(var o=e.getLine(t),r=o.search(/\S/),i=t,s=o.length,u=t+=1,c=e.getLength();++ta)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=i)break;if(l.isMultiLine())t=l.end.row;else if(r==a)break}u=t}}return new n(i,s,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,o){for(var r=t.search(/\s*$/),i=e.getLength(),s=o,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,c=1;++os)return new n(s,r,o,t.length)}}.call(s.prototype)})),ace.define("ace/mode/rust",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/rust_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,o){"use strict";var r=e("../lib/oop"),n=e("./text").Mode,i=e("./rust_highlight_rules").RustHighlightRules,s=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=i,this.foldingRules=new s,this.$behaviour=this.$defaultBehaviour};r.inherits(u,n),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/",nestable:!0},this.$quotes={'"':'"'},this.$id="ace/mode/rust"}.call(u.prototype),t.Mode=u})),ace.require(["ace/mode/rust"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d4cd33f4e9d3f931c0cd936e01b290af.js b/d4cd33f4e9d3f931c0cd936e01b290af.js new file mode 100644 index 00000000..aac343f4 --- /dev/null +++ b/d4cd33f4e9d3f931c0cd936e01b290af.js @@ -0,0 +1 @@ +ace.define("ace/ext/menu_tools/settings_menu.css",["require","exports","module"],(function(e,t,a){a.exports="#ace_settingsmenu, #kbshortcutmenu {\n background-color: #F7F7F7;\n color: black;\n box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55);\n padding: 1em 0.5em 2em 1em;\n overflow: auto;\n position: absolute;\n margin: 0;\n bottom: 0;\n right: 0;\n top: 0;\n z-index: 9991;\n cursor: default;\n}\n\n.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu {\n box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25);\n background-color: rgba(255, 255, 255, 0.6);\n color: black;\n}\n\n.ace_optionsMenuEntry:hover {\n background-color: rgba(100, 100, 100, 0.1);\n transition: all 0.3s\n}\n\n.ace_closeButton {\n background: rgba(245, 146, 146, 0.5);\n border: 1px solid #F48A8A;\n border-radius: 50%;\n padding: 7px;\n position: absolute;\n right: -8px;\n top: -8px;\n z-index: 100000;\n}\n.ace_closeButton{\n background: rgba(245, 146, 146, 0.9);\n}\n.ace_optionsMenuKey {\n color: darkslateblue;\n font-weight: bold;\n}\n.ace_optionsMenuCommand {\n color: darkcyan;\n font-weight: normal;\n}\n.ace_optionsMenuEntry input, .ace_optionsMenuEntry button {\n vertical-align: middle;\n}\n\n.ace_optionsMenuEntry button[ace_selected_button=true] {\n background: #e7e7e7;\n box-shadow: 1px 0px 2px 0px #adadad inset;\n border-color: #adadad;\n}\n.ace_optionsMenuEntry button {\n background: white;\n border: 1px solid lightgray;\n margin: 0px;\n}\n.ace_optionsMenuEntry button:hover{\n background: #f0f0f0;\n}"})),ace.define("ace/ext/menu_tools/overlay_page",["require","exports","module","ace/lib/dom","ace/ext/menu_tools/settings_menu.css"],(function(e,t,a){"use strict";var o=e("../../lib/dom"),n=e("./settings_menu.css");o.importCssString(n,"settings_menu.css",!1),a.exports.overlayPage=function(e,t,a){var o=document.createElement("div"),n=!1;function i(e){27===e.keyCode&&r()}function r(){o&&(document.removeEventListener("keydown",i),o.parentNode.removeChild(o),e&&e.focus(),o=null,a&&a())}return o.style.cssText="margin: 0; padding: 0; position: fixed; top:0; bottom:0; left:0; right:0;z-index: 9990; "+(e?"background-color: rgba(0, 0, 0, 0.3);":""),o.addEventListener("click",(function(e){n||r()})),document.addEventListener("keydown",i),t.addEventListener("click",(function(e){e.stopPropagation()})),o.appendChild(t),document.body.appendChild(o),e&&e.blur(),{close:r,setIgnoreFocusOut:function(e){n=e,e&&(o.style.pointerEvents="none",t.style.pointerEvents="auto")}}}})),ace.define("ace/ext/modelist",["require","exports","module"],(function(e,t,a){"use strict";var o=[],n=function(){function e(e,t,a){var o;this.name=e,this.caption=t,this.mode="ace/mode/"+e,this.extensions=a,o=/\^/.test(a)?a.replace(/\|(\^)?/g,(function(e,t){return"$|"+(t?"^":"^.*\\.")}))+"$":"^.*\\.("+a+")$",this.extRe=new RegExp(o,"gi")}return e.prototype.supportsFile=function(e){return e.match(this.extRe)},e}(),i={ABAP:["abap"],ABC:["abc"],ActionScript:["as"],ADA:["ada|adb"],Alda:["alda"],Apache_Conf:["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"],Apex:["apex|cls|trigger|tgr"],AQL:["aql"],AsciiDoc:["asciidoc|adoc"],ASL:["dsl|asl|asl.json"],Assembly_ARM32:["s"],Assembly_x86:["asm|a"],Astro:["astro"],AutoHotKey:["ahk"],BatchFile:["bat|cmd"],BibTeX:["bib"],C_Cpp:["cpp|c|cc|cxx|h|hh|hpp|ino"],C9Search:["c9search_results"],Cirru:["cirru|cr"],Clojure:["clj|cljs"],Cobol:["CBL|COB"],coffee:["coffee|cf|cson|^Cakefile"],ColdFusion:["cfm|cfc"],Crystal:["cr"],CSharp:["cs"],Csound_Document:["csd"],Csound_Orchestra:["orc"],Csound_Score:["sco"],CSS:["css"],Curly:["curly"],Cuttlefish:["conf"],D:["d|di"],Dart:["dart"],Diff:["diff|patch"],Django:["djt|html.djt|dj.html|djhtml"],Dockerfile:["^Dockerfile"],Dot:["dot"],Drools:["drl"],Edifact:["edi"],Eiffel:["e|ge"],EJS:["ejs"],Elixir:["ex|exs"],Elm:["elm"],Erlang:["erl|hrl"],Flix:["flix"],Forth:["frt|fs|ldr|fth|4th"],Fortran:["f|f90"],FSharp:["fsi|fs|ml|mli|fsx|fsscript"],FSL:["fsl"],FTL:["ftl"],Gcode:["gcode"],Gherkin:["feature"],Gitignore:["^.gitignore"],Glsl:["glsl|frag|vert"],Gobstones:["gbs"],golang:["go"],GraphQLSchema:["gql"],Groovy:["groovy"],HAML:["haml"],Handlebars:["hbs|handlebars|tpl|mustache"],Haskell:["hs"],Haskell_Cabal:["cabal"],haXe:["hx"],Hjson:["hjson"],HTML:["html|htm|xhtml|we|wpy"],HTML_Elixir:["eex|html.eex"],HTML_Ruby:["erb|rhtml|html.erb"],INI:["ini|conf|cfg|prefs"],Io:["io"],Ion:["ion"],Jack:["jack"],Jade:["jade|pug"],Java:["java"],JavaScript:["js|jsm|cjs|mjs"],JEXL:["jexl"],JSON:["json"],JSON5:["json5"],JSONiq:["jq"],JSP:["jsp"],JSSM:["jssm|jssm_state"],JSX:["jsx"],Julia:["jl"],Kotlin:["kt|kts"],LaTeX:["tex|latex|ltx|bib"],Latte:["latte"],LESS:["less"],Liquid:["liquid"],Lisp:["lisp"],LiveScript:["ls"],Log:["log"],LogiQL:["logic|lql"],Logtalk:["lgt"],LSL:["lsl"],Lua:["lua"],LuaPage:["lp"],Lucene:["lucene"],Makefile:["^Makefile|^GNUmakefile|^makefile|^OCamlMakefile|make"],Markdown:["md|markdown"],Mask:["mask"],MATLAB:["matlab"],Maze:["mz"],MediaWiki:["wiki|mediawiki"],MEL:["mel"],MIPS:["s|asm"],MIXAL:["mixal"],MUSHCode:["mc|mush"],MySQL:["mysql"],Nasal:["nas"],Nginx:["nginx|conf"],Nim:["nim"],Nix:["nix"],NSIS:["nsi|nsh"],Nunjucks:["nunjucks|nunjs|nj|njk"],ObjectiveC:["m|mm"],OCaml:["ml|mli"],Odin:["odin"],PartiQL:["partiql|pql"],Pascal:["pas|p"],Perl:["pl|pm"],pgSQL:["pgsql"],PHP:["php|inc|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp|module"],PHP_Laravel_blade:["blade.php"],Pig:["pig"],PLSQL:["plsql"],Powershell:["ps1"],Praat:["praat|praatscript|psc|proc"],Prisma:["prisma"],Prolog:["plg|prolog"],Properties:["properties"],Protobuf:["proto"],PRQL:["prql"],Puppet:["epp|pp"],Python:["py"],QML:["qml"],R:["r"],Raku:["raku|rakumod|rakutest|p6|pl6|pm6"],Razor:["cshtml|asp"],RDoc:["Rd"],Red:["red|reds"],RHTML:["Rhtml"],Robot:["robot|resource"],RST:["rst"],Ruby:["rb|ru|gemspec|rake|^Guardfile|^Rakefile|^Gemfile"],Rust:["rs"],SaC:["sac"],SASS:["sass"],SCAD:["scad"],Scala:["scala|sbt"],Scheme:["scm|sm|rkt|oak|scheme"],Scrypt:["scrypt"],SCSS:["scss"],SH:["sh|bash|^.bashrc"],SJS:["sjs"],Slim:["slim|skim"],Smarty:["smarty|tpl"],Smithy:["smithy"],snippets:["snippets"],Soy_Template:["soy"],Space:["space"],SPARQL:["rq"],SQL:["sql"],SQLServer:["sqlserver"],Stylus:["styl|stylus"],SVG:["svg"],Swift:["swift"],Tcl:["tcl"],Terraform:["tf","tfvars","terragrunt"],Tex:["tex"],Text:["txt"],Textile:["textile"],Toml:["toml"],TSX:["tsx"],Turtle:["ttl"],Twig:["twig|swig"],Typescript:["ts|mts|cts|typescript|str"],Vala:["vala"],VBScript:["vbs|vb"],Velocity:["vm"],Verilog:["v|vh|sv|svh"],VHDL:["vhd|vhdl"],Visualforce:["vfp|component|page"],Vue:["vue"],Wollok:["wlk|wpgm|wtest"],XML:["xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl|xaml"],XQuery:["xq"],YAML:["yaml|yml"],Zeek:["zeek|bro"],Zig:["zig"]},r={ObjectiveC:"Objective-C",CSharp:"C#",golang:"Go",C_Cpp:"C and C++",Csound_Document:"Csound Document",Csound_Orchestra:"Csound",Csound_Score:"Csound Score",coffee:"CoffeeScript",HTML_Ruby:"HTML (Ruby)",HTML_Elixir:"HTML (Elixir)",FTL:"FreeMarker",PHP_Laravel_blade:"PHP (Blade Template)",Perl6:"Perl 6",AutoHotKey:"AutoHotkey / AutoIt"},s={};for(var l in i){var c=i[l],u=(r[l]||l).replace(/_/g," "),p=l.toLowerCase(),d=new n(p,u,c[0]);s[p]=d,o.push(d)}a.exports={getModeForPath:function(e){for(var t=s.text,a=e.split(/[\/\\]/).pop(),n=0;n<]/},{token:"keyword.operator.repeat.alda",regex:/\*\s*\d+/},{token:"string.quoted.operator.timing.alda",regex:/[.]|r\d*(?:s|ms)?/},{token:"text",regex:/([cdefgab])/,next:"pitch"},{token:"string.quoted.operator.timing.alda",regex:/~/,next:"timing"},{token:"punctuation.section.embedded.cram.alda",regex:/\}/,next:"timing"},{token:"constant.numeric.subchord.alda",regex:/\//},{todo:{token:"punctuation.section.embedded.cram.alda",regex:/\{/,push:[{token:"punctuation.section.embedded.cram.alda",regex:/\}/,next:"pop"},{include:"$self"}]}},{todo:{token:"keyword.control.sequence.alda",regex:/\[/,push:[{token:"keyword.control.sequence.alda",regex:/\]/,next:"pop"},{include:"$self"}]}},{token:"meta.inline.clojure.alda",regex:/\(/,push:[{token:"meta.inline.clojure.alda",regex:/\)/,next:"pop"},{include:"source.clojure"},{defaultToken:"meta.inline.clojure.alda"}]}]},this.normalizeRules()};i.metaData={scopeName:"source.alda",fileTypes:["alda"],name:"Alda"},o.inherits(i,a),t.AldaHighlightRules=i})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),a=e("../../range").Range,i=e("./fold_mode").FoldMode,r=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};o.inherits(r,i),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var o=e.getLine(n);if(this.singleLineBlockCommentRe.test(o)&&!this.startRegionRe.test(o)&&!this.tripleStarBlockCommentRe.test(o))return"";var a=this._getFoldWidgetBase(e,t,n);return!a&&this.startRegionRe.test(o)?"start":a},this.getFoldWidgetRange=function(e,t,n,o){var a,i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);if(a=i.match(this.foldingStartMarker)){var r=a.index;if(a[1])return this.openingBracketBlock(e,a[1],n,r);var l=e.getCommentFoldRange(n,r+a[0].length,1);return l&&!l.isMultiLine()&&(o?l=this.getSectionRange(e,n):"all"!=t&&(l=null)),l}return"markbegin"!==t&&(a=i.match(this.foldingStopMarker))?(r=a.index+a[0].length,a[1]?this.closingBracketBlock(e,a[1],n,r):e.getCommentFoldRange(n,r,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),o=n.search(/\S/),i=t,r=n.length,l=t+=1,s=e.getLength();++td)break;var g=this.getFoldWidgetRange(e,"all",t);if(g){if(g.start.row<=i)break;if(g.isMultiLine())t=g.end.row;else if(o==d)break}l=t}}return new a(i,r,l,e.getLine(l).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),i=e.getLength(),r=n,l=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,s=1;++nr)return new a(r,o,n,t.length)}}.call(r.prototype)})),ace.define("ace/mode/alda",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/alda_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),a=e("./text").Mode,i=e("./alda_highlight_rules").AldaHighlightRules,r=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=i,this.foldingRules=new r};o.inherits(l,a),function(){this.$id="ace/mode/alda"}.call(l.prototype),t.Mode=l})),ace.require(["ace/mode/alda"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d4f5981ee5a73d8a6e19112f2ffcb72c.js b/d4f5981ee5a73d8a6e19112f2ffcb72c.js new file mode 100644 index 00000000..e191dccd --- /dev/null +++ b/d4f5981ee5a73d8a6e19112f2ffcb72c.js @@ -0,0 +1 @@ +ace.define("ace/theme/crimson_editor-css",["require","exports","module"],(function(n,e,r){r.exports='.ace-crimson-editor .ace_gutter {\n background: #ebebeb;\n color: #333;\n overflow : hidden;\n}\n\n.ace-crimson-editor .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-crimson-editor .ace_print-margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-crimson-editor {\n background-color: #FFFFFF;\n color: rgb(64, 64, 64);\n}\n\n.ace-crimson-editor .ace_cursor {\n color: black;\n}\n\n.ace-crimson-editor .ace_invisible {\n color: rgb(191, 191, 191);\n}\n\n.ace-crimson-editor .ace_identifier {\n color: black;\n}\n\n.ace-crimson-editor .ace_keyword {\n color: blue;\n}\n\n.ace-crimson-editor .ace_constant.ace_buildin {\n color: rgb(88, 72, 246);\n}\n\n.ace-crimson-editor .ace_constant.ace_language {\n color: rgb(255, 156, 0);\n}\n\n.ace-crimson-editor .ace_constant.ace_library {\n color: rgb(6, 150, 14);\n}\n\n.ace-crimson-editor .ace_invalid {\n text-decoration: line-through;\n color: rgb(224, 0, 0);\n}\n\n.ace-crimson-editor .ace_fold {\n}\n\n.ace-crimson-editor .ace_support.ace_function {\n color: rgb(192, 0, 0);\n}\n\n.ace-crimson-editor .ace_support.ace_constant {\n color: rgb(6, 150, 14);\n}\n\n.ace-crimson-editor .ace_support.ace_type,\n.ace-crimson-editor .ace_support.ace_class {\n color: rgb(109, 121, 222);\n}\n\n.ace-crimson-editor .ace_keyword.ace_operator {\n color: rgb(49, 132, 149);\n}\n\n.ace-crimson-editor .ace_string {\n color: rgb(128, 0, 128);\n}\n\n.ace-crimson-editor .ace_comment {\n color: rgb(76, 136, 107);\n}\n\n.ace-crimson-editor .ace_comment.ace_doc {\n color: rgb(0, 102, 255);\n}\n\n.ace-crimson-editor .ace_comment.ace_doc.ace_tag {\n color: rgb(128, 159, 191);\n}\n\n.ace-crimson-editor .ace_constant.ace_numeric {\n color: rgb(0, 0, 64);\n}\n\n.ace-crimson-editor .ace_variable {\n color: rgb(0, 64, 128);\n}\n\n.ace-crimson-editor .ace_xml-pe {\n color: rgb(104, 104, 91);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_selection {\n background: rgb(181, 213, 255);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_step {\n background: rgb(252, 255, 0);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_stack {\n background: rgb(164, 229, 101);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_active-line {\n background: rgb(232, 242, 254);\n}\n\n.ace-crimson-editor .ace_gutter-active-line {\n background-color : #dcdcdc;\n}\n\n.ace-crimson-editor .ace_meta.ace_tag {\n color:rgb(28, 2, 255);\n}\n\n.ace-crimson-editor .ace_marker-layer .ace_selected-word {\n background: rgb(250, 250, 255);\n border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-crimson-editor .ace_string.ace_regex {\n color: rgb(192, 0, 192);\n}\n\n.ace-crimson-editor .ace_indent-guide {\n background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;\n}\n\n.ace-crimson-editor .ace_indent-guide-active {\n background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC") right repeat-y;\n} \n'})),ace.define("ace/theme/crimson_editor",["require","exports","module","ace/theme/crimson_editor-css","ace/lib/dom"],(function(n,e,r){e.isDark=!1,e.cssText=n("./crimson_editor-css"),e.cssClass="ace-crimson-editor",n("../lib/dom").importCssString(e.cssText,e.cssClass,!1)})),ace.require(["ace/theme/crimson_editor"],(function(n){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=n)})); \ No newline at end of file diff --git a/d542dda7308361c34af2afb9b70d755a.js b/d542dda7308361c34af2afb9b70d755a.js new file mode 100644 index 00000000..f47b0b66 --- /dev/null +++ b/d542dda7308361c34af2afb9b70d755a.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/alda"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d5999827bd3af6b813a871de344b109a.js b/d5999827bd3af6b813a871de344b109a.js new file mode 100644 index 00000000..40b35582 --- /dev/null +++ b/d5999827bd3af6b813a871de344b109a.js @@ -0,0 +1 @@ +ace.define("ace/snippets/css.snippets",["require","exports","module"],(function(n,t,e){e.exports="snippet .\n\t${1} {\n\t\t${2}\n\t}\nsnippet !\n\t !important\nsnippet bdi:m+\n\t-moz-border-image: url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${7:stretch};\nsnippet bdi:m\n\t-moz-border-image: ${1};\nsnippet bdrz:m\n\t-moz-border-radius: ${1};\nsnippet bxsh:m+\n\t-moz-box-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet bxsh:m\n\t-moz-box-shadow: ${1};\nsnippet bdi:w+\n\t-webkit-border-image: url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${7:stretch};\nsnippet bdi:w\n\t-webkit-border-image: ${1};\nsnippet bdrz:w\n\t-webkit-border-radius: ${1};\nsnippet bxsh:w+\n\t-webkit-box-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet bxsh:w\n\t-webkit-box-shadow: ${1};\nsnippet @f\n\t@font-face {\n\t\tfont-family: ${1};\n\t\tsrc: url(${2});\n\t}\nsnippet @i\n\t@import url(${1});\nsnippet @m\n\t@media ${1:print} {\n\t\t${2}\n\t}\nsnippet bg+\n\tbackground: #${1:FFF} url(${2}) ${3:0} ${4:0} ${5:no-repeat};\nsnippet bga\n\tbackground-attachment: ${1};\nsnippet bga:f\n\tbackground-attachment: fixed;\nsnippet bga:s\n\tbackground-attachment: scroll;\nsnippet bgbk\n\tbackground-break: ${1};\nsnippet bgbk:bb\n\tbackground-break: bounding-box;\nsnippet bgbk:c\n\tbackground-break: continuous;\nsnippet bgbk:eb\n\tbackground-break: each-box;\nsnippet bgcp\n\tbackground-clip: ${1};\nsnippet bgcp:bb\n\tbackground-clip: border-box;\nsnippet bgcp:cb\n\tbackground-clip: content-box;\nsnippet bgcp:nc\n\tbackground-clip: no-clip;\nsnippet bgcp:pb\n\tbackground-clip: padding-box;\nsnippet bgc\n\tbackground-color: #${1:FFF};\nsnippet bgc:t\n\tbackground-color: transparent;\nsnippet bgi\n\tbackground-image: url(${1});\nsnippet bgi:n\n\tbackground-image: none;\nsnippet bgo\n\tbackground-origin: ${1};\nsnippet bgo:bb\n\tbackground-origin: border-box;\nsnippet bgo:cb\n\tbackground-origin: content-box;\nsnippet bgo:pb\n\tbackground-origin: padding-box;\nsnippet bgpx\n\tbackground-position-x: ${1};\nsnippet bgpy\n\tbackground-position-y: ${1};\nsnippet bgp\n\tbackground-position: ${1:0} ${2:0};\nsnippet bgr\n\tbackground-repeat: ${1};\nsnippet bgr:n\n\tbackground-repeat: no-repeat;\nsnippet bgr:x\n\tbackground-repeat: repeat-x;\nsnippet bgr:y\n\tbackground-repeat: repeat-y;\nsnippet bgr:r\n\tbackground-repeat: repeat;\nsnippet bgz\n\tbackground-size: ${1};\nsnippet bgz:a\n\tbackground-size: auto;\nsnippet bgz:ct\n\tbackground-size: contain;\nsnippet bgz:cv\n\tbackground-size: cover;\nsnippet bg\n\tbackground: ${1};\nsnippet bg:ie\n\tfilter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='${1}',sizingMethod='${2:crop}');\nsnippet bg:n\n\tbackground: none;\nsnippet bd+\n\tborder: ${1:1px} ${2:solid} #${3:000};\nsnippet bdb+\n\tborder-bottom: ${1:1px} ${2:solid} #${3:000};\nsnippet bdbc\n\tborder-bottom-color: #${1:000};\nsnippet bdbi\n\tborder-bottom-image: url(${1});\nsnippet bdbi:n\n\tborder-bottom-image: none;\nsnippet bdbli\n\tborder-bottom-left-image: url(${1});\nsnippet bdbli:c\n\tborder-bottom-left-image: continue;\nsnippet bdbli:n\n\tborder-bottom-left-image: none;\nsnippet bdblrz\n\tborder-bottom-left-radius: ${1};\nsnippet bdbri\n\tborder-bottom-right-image: url(${1});\nsnippet bdbri:c\n\tborder-bottom-right-image: continue;\nsnippet bdbri:n\n\tborder-bottom-right-image: none;\nsnippet bdbrrz\n\tborder-bottom-right-radius: ${1};\nsnippet bdbs\n\tborder-bottom-style: ${1};\nsnippet bdbs:n\n\tborder-bottom-style: none;\nsnippet bdbw\n\tborder-bottom-width: ${1};\nsnippet bdb\n\tborder-bottom: ${1};\nsnippet bdb:n\n\tborder-bottom: none;\nsnippet bdbk\n\tborder-break: ${1};\nsnippet bdbk:c\n\tborder-break: close;\nsnippet bdcl\n\tborder-collapse: ${1};\nsnippet bdcl:c\n\tborder-collapse: collapse;\nsnippet bdcl:s\n\tborder-collapse: separate;\nsnippet bdc\n\tborder-color: #${1:000};\nsnippet bdci\n\tborder-corner-image: url(${1});\nsnippet bdci:c\n\tborder-corner-image: continue;\nsnippet bdci:n\n\tborder-corner-image: none;\nsnippet bdf\n\tborder-fit: ${1};\nsnippet bdf:c\n\tborder-fit: clip;\nsnippet bdf:of\n\tborder-fit: overwrite;\nsnippet bdf:ow\n\tborder-fit: overwrite;\nsnippet bdf:r\n\tborder-fit: repeat;\nsnippet bdf:sc\n\tborder-fit: scale;\nsnippet bdf:sp\n\tborder-fit: space;\nsnippet bdf:st\n\tborder-fit: stretch;\nsnippet bdi\n\tborder-image: url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${7:stretch};\nsnippet bdi:n\n\tborder-image: none;\nsnippet bdl+\n\tborder-left: ${1:1px} ${2:solid} #${3:000};\nsnippet bdlc\n\tborder-left-color: #${1:000};\nsnippet bdli\n\tborder-left-image: url(${1});\nsnippet bdli:n\n\tborder-left-image: none;\nsnippet bdls\n\tborder-left-style: ${1};\nsnippet bdls:n\n\tborder-left-style: none;\nsnippet bdlw\n\tborder-left-width: ${1};\nsnippet bdl\n\tborder-left: ${1};\nsnippet bdl:n\n\tborder-left: none;\nsnippet bdlt\n\tborder-length: ${1};\nsnippet bdlt:a\n\tborder-length: auto;\nsnippet bdrz\n\tborder-radius: ${1};\nsnippet bdr+\n\tborder-right: ${1:1px} ${2:solid} #${3:000};\nsnippet bdrc\n\tborder-right-color: #${1:000};\nsnippet bdri\n\tborder-right-image: url(${1});\nsnippet bdri:n\n\tborder-right-image: none;\nsnippet bdrs\n\tborder-right-style: ${1};\nsnippet bdrs:n\n\tborder-right-style: none;\nsnippet bdrw\n\tborder-right-width: ${1};\nsnippet bdr\n\tborder-right: ${1};\nsnippet bdr:n\n\tborder-right: none;\nsnippet bdsp\n\tborder-spacing: ${1};\nsnippet bds\n\tborder-style: ${1};\nsnippet bds:ds\n\tborder-style: dashed;\nsnippet bds:dtds\n\tborder-style: dot-dash;\nsnippet bds:dtdtds\n\tborder-style: dot-dot-dash;\nsnippet bds:dt\n\tborder-style: dotted;\nsnippet bds:db\n\tborder-style: double;\nsnippet bds:g\n\tborder-style: groove;\nsnippet bds:h\n\tborder-style: hidden;\nsnippet bds:i\n\tborder-style: inset;\nsnippet bds:n\n\tborder-style: none;\nsnippet bds:o\n\tborder-style: outset;\nsnippet bds:r\n\tborder-style: ridge;\nsnippet bds:s\n\tborder-style: solid;\nsnippet bds:w\n\tborder-style: wave;\nsnippet bdt+\n\tborder-top: ${1:1px} ${2:solid} #${3:000};\nsnippet bdtc\n\tborder-top-color: #${1:000};\nsnippet bdti\n\tborder-top-image: url(${1});\nsnippet bdti:n\n\tborder-top-image: none;\nsnippet bdtli\n\tborder-top-left-image: url(${1});\nsnippet bdtli:c\n\tborder-corner-image: continue;\nsnippet bdtli:n\n\tborder-corner-image: none;\nsnippet bdtlrz\n\tborder-top-left-radius: ${1};\nsnippet bdtri\n\tborder-top-right-image: url(${1});\nsnippet bdtri:c\n\tborder-top-right-image: continue;\nsnippet bdtri:n\n\tborder-top-right-image: none;\nsnippet bdtrrz\n\tborder-top-right-radius: ${1};\nsnippet bdts\n\tborder-top-style: ${1};\nsnippet bdts:n\n\tborder-top-style: none;\nsnippet bdtw\n\tborder-top-width: ${1};\nsnippet bdt\n\tborder-top: ${1};\nsnippet bdt:n\n\tborder-top: none;\nsnippet bdw\n\tborder-width: ${1};\nsnippet bd\n\tborder: ${1};\nsnippet bd:n\n\tborder: none;\nsnippet b\n\tbottom: ${1};\nsnippet b:a\n\tbottom: auto;\nsnippet bxsh+\n\tbox-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet bxsh\n\tbox-shadow: ${1};\nsnippet bxsh:n\n\tbox-shadow: none;\nsnippet bxz\n\tbox-sizing: ${1};\nsnippet bxz:bb\n\tbox-sizing: border-box;\nsnippet bxz:cb\n\tbox-sizing: content-box;\nsnippet cps\n\tcaption-side: ${1};\nsnippet cps:b\n\tcaption-side: bottom;\nsnippet cps:t\n\tcaption-side: top;\nsnippet cl\n\tclear: ${1};\nsnippet cl:b\n\tclear: both;\nsnippet cl:l\n\tclear: left;\nsnippet cl:n\n\tclear: none;\nsnippet cl:r\n\tclear: right;\nsnippet cp\n\tclip: ${1};\nsnippet cp:a\n\tclip: auto;\nsnippet cp:r\n\tclip: rect(${1:0} ${2:0} ${3:0} ${4:0});\nsnippet c\n\tcolor: #${1:000};\nsnippet ct\n\tcontent: ${1};\nsnippet ct:a\n\tcontent: attr(${1});\nsnippet ct:cq\n\tcontent: close-quote;\nsnippet ct:c\n\tcontent: counter(${1});\nsnippet ct:cs\n\tcontent: counters(${1});\nsnippet ct:ncq\n\tcontent: no-close-quote;\nsnippet ct:noq\n\tcontent: no-open-quote;\nsnippet ct:n\n\tcontent: normal;\nsnippet ct:oq\n\tcontent: open-quote;\nsnippet coi\n\tcounter-increment: ${1};\nsnippet cor\n\tcounter-reset: ${1};\nsnippet cur\n\tcursor: ${1};\nsnippet cur:a\n\tcursor: auto;\nsnippet cur:c\n\tcursor: crosshair;\nsnippet cur:d\n\tcursor: default;\nsnippet cur:ha\n\tcursor: hand;\nsnippet cur:he\n\tcursor: help;\nsnippet cur:m\n\tcursor: move;\nsnippet cur:p\n\tcursor: pointer;\nsnippet cur:t\n\tcursor: text;\nsnippet d\n\tdisplay: ${1};\nsnippet d:mib\n\tdisplay: -moz-inline-box;\nsnippet d:mis\n\tdisplay: -moz-inline-stack;\nsnippet d:b\n\tdisplay: block;\nsnippet d:cp\n\tdisplay: compact;\nsnippet d:ib\n\tdisplay: inline-block;\nsnippet d:itb\n\tdisplay: inline-table;\nsnippet d:i\n\tdisplay: inline;\nsnippet d:li\n\tdisplay: list-item;\nsnippet d:n\n\tdisplay: none;\nsnippet d:ri\n\tdisplay: run-in;\nsnippet d:tbcp\n\tdisplay: table-caption;\nsnippet d:tbc\n\tdisplay: table-cell;\nsnippet d:tbclg\n\tdisplay: table-column-group;\nsnippet d:tbcl\n\tdisplay: table-column;\nsnippet d:tbfg\n\tdisplay: table-footer-group;\nsnippet d:tbhg\n\tdisplay: table-header-group;\nsnippet d:tbrg\n\tdisplay: table-row-group;\nsnippet d:tbr\n\tdisplay: table-row;\nsnippet d:tb\n\tdisplay: table;\nsnippet ec\n\tempty-cells: ${1};\nsnippet ec:h\n\tempty-cells: hide;\nsnippet ec:s\n\tempty-cells: show;\nsnippet exp\n\texpression()\nsnippet fl\n\tfloat: ${1};\nsnippet fl:l\n\tfloat: left;\nsnippet fl:n\n\tfloat: none;\nsnippet fl:r\n\tfloat: right;\nsnippet f+\n\tfont: ${1:1em} ${2:Arial},${3:sans-serif};\nsnippet fef\n\tfont-effect: ${1};\nsnippet fef:eb\n\tfont-effect: emboss;\nsnippet fef:eg\n\tfont-effect: engrave;\nsnippet fef:n\n\tfont-effect: none;\nsnippet fef:o\n\tfont-effect: outline;\nsnippet femp\n\tfont-emphasize-position: ${1};\nsnippet femp:a\n\tfont-emphasize-position: after;\nsnippet femp:b\n\tfont-emphasize-position: before;\nsnippet fems\n\tfont-emphasize-style: ${1};\nsnippet fems:ac\n\tfont-emphasize-style: accent;\nsnippet fems:c\n\tfont-emphasize-style: circle;\nsnippet fems:ds\n\tfont-emphasize-style: disc;\nsnippet fems:dt\n\tfont-emphasize-style: dot;\nsnippet fems:n\n\tfont-emphasize-style: none;\nsnippet fem\n\tfont-emphasize: ${1};\nsnippet ff\n\tfont-family: ${1};\nsnippet ff:c\n\tfont-family: ${1:'Monotype Corsiva','Comic Sans MS'},cursive;\nsnippet ff:f\n\tfont-family: ${1:Capitals,Impact},fantasy;\nsnippet ff:m\n\tfont-family: ${1:Monaco,'Courier New'},monospace;\nsnippet ff:ss\n\tfont-family: ${1:Helvetica,Arial},sans-serif;\nsnippet ff:s\n\tfont-family: ${1:Georgia,'Times New Roman'},serif;\nsnippet fza\n\tfont-size-adjust: ${1};\nsnippet fza:n\n\tfont-size-adjust: none;\nsnippet fz\n\tfont-size: ${1};\nsnippet fsm\n\tfont-smooth: ${1};\nsnippet fsm:aw\n\tfont-smooth: always;\nsnippet fsm:a\n\tfont-smooth: auto;\nsnippet fsm:n\n\tfont-smooth: never;\nsnippet fst\n\tfont-stretch: ${1};\nsnippet fst:c\n\tfont-stretch: condensed;\nsnippet fst:e\n\tfont-stretch: expanded;\nsnippet fst:ec\n\tfont-stretch: extra-condensed;\nsnippet fst:ee\n\tfont-stretch: extra-expanded;\nsnippet fst:n\n\tfont-stretch: normal;\nsnippet fst:sc\n\tfont-stretch: semi-condensed;\nsnippet fst:se\n\tfont-stretch: semi-expanded;\nsnippet fst:uc\n\tfont-stretch: ultra-condensed;\nsnippet fst:ue\n\tfont-stretch: ultra-expanded;\nsnippet fs\n\tfont-style: ${1};\nsnippet fs:i\n\tfont-style: italic;\nsnippet fs:n\n\tfont-style: normal;\nsnippet fs:o\n\tfont-style: oblique;\nsnippet fv\n\tfont-variant: ${1};\nsnippet fv:n\n\tfont-variant: normal;\nsnippet fv:sc\n\tfont-variant: small-caps;\nsnippet fw\n\tfont-weight: ${1};\nsnippet fw:b\n\tfont-weight: bold;\nsnippet fw:br\n\tfont-weight: bolder;\nsnippet fw:lr\n\tfont-weight: lighter;\nsnippet fw:n\n\tfont-weight: normal;\nsnippet f\n\tfont: ${1};\nsnippet h\n\theight: ${1};\nsnippet h:a\n\theight: auto;\nsnippet l\n\tleft: ${1};\nsnippet l:a\n\tleft: auto;\nsnippet lts\n\tletter-spacing: ${1};\nsnippet lh\n\tline-height: ${1};\nsnippet lisi\n\tlist-style-image: url(${1});\nsnippet lisi:n\n\tlist-style-image: none;\nsnippet lisp\n\tlist-style-position: ${1};\nsnippet lisp:i\n\tlist-style-position: inside;\nsnippet lisp:o\n\tlist-style-position: outside;\nsnippet list\n\tlist-style-type: ${1};\nsnippet list:c\n\tlist-style-type: circle;\nsnippet list:dclz\n\tlist-style-type: decimal-leading-zero;\nsnippet list:dc\n\tlist-style-type: decimal;\nsnippet list:d\n\tlist-style-type: disc;\nsnippet list:lr\n\tlist-style-type: lower-roman;\nsnippet list:n\n\tlist-style-type: none;\nsnippet list:s\n\tlist-style-type: square;\nsnippet list:ur\n\tlist-style-type: upper-roman;\nsnippet lis\n\tlist-style: ${1};\nsnippet lis:n\n\tlist-style: none;\nsnippet mb\n\tmargin-bottom: ${1};\nsnippet mb:a\n\tmargin-bottom: auto;\nsnippet ml\n\tmargin-left: ${1};\nsnippet ml:a\n\tmargin-left: auto;\nsnippet mr\n\tmargin-right: ${1};\nsnippet mr:a\n\tmargin-right: auto;\nsnippet mt\n\tmargin-top: ${1};\nsnippet mt:a\n\tmargin-top: auto;\nsnippet m\n\tmargin: ${1};\nsnippet m:4\n\tmargin: ${1:0} ${2:0} ${3:0} ${4:0};\nsnippet m:3\n\tmargin: ${1:0} ${2:0} ${3:0};\nsnippet m:2\n\tmargin: ${1:0} ${2:0};\nsnippet m:0\n\tmargin: 0;\nsnippet m:a\n\tmargin: auto;\nsnippet mah\n\tmax-height: ${1};\nsnippet mah:n\n\tmax-height: none;\nsnippet maw\n\tmax-width: ${1};\nsnippet maw:n\n\tmax-width: none;\nsnippet mih\n\tmin-height: ${1};\nsnippet miw\n\tmin-width: ${1};\nsnippet op\n\topacity: ${1};\nsnippet op:ie\n\tfilter: progid:DXImageTransform.Microsoft.Alpha(Opacity=${1:100});\nsnippet op:ms\n\t-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=${1:100})';\nsnippet orp\n\torphans: ${1};\nsnippet o+\n\toutline: ${1:1px} ${2:solid} #${3:000};\nsnippet oc\n\toutline-color: ${1:#000};\nsnippet oc:i\n\toutline-color: invert;\nsnippet oo\n\toutline-offset: ${1};\nsnippet os\n\toutline-style: ${1};\nsnippet ow\n\toutline-width: ${1};\nsnippet o\n\toutline: ${1};\nsnippet o:n\n\toutline: none;\nsnippet ovs\n\toverflow-style: ${1};\nsnippet ovs:a\n\toverflow-style: auto;\nsnippet ovs:mq\n\toverflow-style: marquee;\nsnippet ovs:mv\n\toverflow-style: move;\nsnippet ovs:p\n\toverflow-style: panner;\nsnippet ovs:s\n\toverflow-style: scrollbar;\nsnippet ovx\n\toverflow-x: ${1};\nsnippet ovx:a\n\toverflow-x: auto;\nsnippet ovx:h\n\toverflow-x: hidden;\nsnippet ovx:s\n\toverflow-x: scroll;\nsnippet ovx:v\n\toverflow-x: visible;\nsnippet ovy\n\toverflow-y: ${1};\nsnippet ovy:a\n\toverflow-y: auto;\nsnippet ovy:h\n\toverflow-y: hidden;\nsnippet ovy:s\n\toverflow-y: scroll;\nsnippet ovy:v\n\toverflow-y: visible;\nsnippet ov\n\toverflow: ${1};\nsnippet ov:a\n\toverflow: auto;\nsnippet ov:h\n\toverflow: hidden;\nsnippet ov:s\n\toverflow: scroll;\nsnippet ov:v\n\toverflow: visible;\nsnippet pb\n\tpadding-bottom: ${1};\nsnippet pl\n\tpadding-left: ${1};\nsnippet pr\n\tpadding-right: ${1};\nsnippet pt\n\tpadding-top: ${1};\nsnippet p\n\tpadding: ${1};\nsnippet p:4\n\tpadding: ${1:0} ${2:0} ${3:0} ${4:0};\nsnippet p:3\n\tpadding: ${1:0} ${2:0} ${3:0};\nsnippet p:2\n\tpadding: ${1:0} ${2:0};\nsnippet p:0\n\tpadding: 0;\nsnippet pgba\n\tpage-break-after: ${1};\nsnippet pgba:aw\n\tpage-break-after: always;\nsnippet pgba:a\n\tpage-break-after: auto;\nsnippet pgba:l\n\tpage-break-after: left;\nsnippet pgba:r\n\tpage-break-after: right;\nsnippet pgbb\n\tpage-break-before: ${1};\nsnippet pgbb:aw\n\tpage-break-before: always;\nsnippet pgbb:a\n\tpage-break-before: auto;\nsnippet pgbb:l\n\tpage-break-before: left;\nsnippet pgbb:r\n\tpage-break-before: right;\nsnippet pgbi\n\tpage-break-inside: ${1};\nsnippet pgbi:a\n\tpage-break-inside: auto;\nsnippet pgbi:av\n\tpage-break-inside: avoid;\nsnippet pos\n\tposition: ${1};\nsnippet pos:a\n\tposition: absolute;\nsnippet pos:f\n\tposition: fixed;\nsnippet pos:r\n\tposition: relative;\nsnippet pos:s\n\tposition: static;\nsnippet q\n\tquotes: ${1};\nsnippet q:en\n\tquotes: '\\201C' '\\201D' '\\2018' '\\2019';\nsnippet q:n\n\tquotes: none;\nsnippet q:ru\n\tquotes: '\\00AB' '\\00BB' '\\201E' '\\201C';\nsnippet rz\n\tresize: ${1};\nsnippet rz:b\n\tresize: both;\nsnippet rz:h\n\tresize: horizontal;\nsnippet rz:n\n\tresize: none;\nsnippet rz:v\n\tresize: vertical;\nsnippet r\n\tright: ${1};\nsnippet r:a\n\tright: auto;\nsnippet tbl\n\ttable-layout: ${1};\nsnippet tbl:a\n\ttable-layout: auto;\nsnippet tbl:f\n\ttable-layout: fixed;\nsnippet tal\n\ttext-align-last: ${1};\nsnippet tal:a\n\ttext-align-last: auto;\nsnippet tal:c\n\ttext-align-last: center;\nsnippet tal:l\n\ttext-align-last: left;\nsnippet tal:r\n\ttext-align-last: right;\nsnippet ta\n\ttext-align: ${1};\nsnippet ta:c\n\ttext-align: center;\nsnippet ta:l\n\ttext-align: left;\nsnippet ta:r\n\ttext-align: right;\nsnippet td\n\ttext-decoration: ${1};\nsnippet td:l\n\ttext-decoration: line-through;\nsnippet td:n\n\ttext-decoration: none;\nsnippet td:o\n\ttext-decoration: overline;\nsnippet td:u\n\ttext-decoration: underline;\nsnippet te\n\ttext-emphasis: ${1};\nsnippet te:ac\n\ttext-emphasis: accent;\nsnippet te:a\n\ttext-emphasis: after;\nsnippet te:b\n\ttext-emphasis: before;\nsnippet te:c\n\ttext-emphasis: circle;\nsnippet te:ds\n\ttext-emphasis: disc;\nsnippet te:dt\n\ttext-emphasis: dot;\nsnippet te:n\n\ttext-emphasis: none;\nsnippet th\n\ttext-height: ${1};\nsnippet th:a\n\ttext-height: auto;\nsnippet th:f\n\ttext-height: font-size;\nsnippet th:m\n\ttext-height: max-size;\nsnippet th:t\n\ttext-height: text-size;\nsnippet ti\n\ttext-indent: ${1};\nsnippet ti:-\n\ttext-indent: -9999px;\nsnippet tj\n\ttext-justify: ${1};\nsnippet tj:a\n\ttext-justify: auto;\nsnippet tj:d\n\ttext-justify: distribute;\nsnippet tj:ic\n\ttext-justify: inter-cluster;\nsnippet tj:ii\n\ttext-justify: inter-ideograph;\nsnippet tj:iw\n\ttext-justify: inter-word;\nsnippet tj:k\n\ttext-justify: kashida;\nsnippet tj:t\n\ttext-justify: tibetan;\nsnippet to+\n\ttext-outline: ${1:0} ${2:0} #${3:000};\nsnippet to\n\ttext-outline: ${1};\nsnippet to:n\n\ttext-outline: none;\nsnippet tr\n\ttext-replace: ${1};\nsnippet tr:n\n\ttext-replace: none;\nsnippet tsh+\n\ttext-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet tsh\n\ttext-shadow: ${1};\nsnippet tsh:n\n\ttext-shadow: none;\nsnippet tt\n\ttext-transform: ${1};\nsnippet tt:c\n\ttext-transform: capitalize;\nsnippet tt:l\n\ttext-transform: lowercase;\nsnippet tt:n\n\ttext-transform: none;\nsnippet tt:u\n\ttext-transform: uppercase;\nsnippet tw\n\ttext-wrap: ${1};\nsnippet tw:no\n\ttext-wrap: none;\nsnippet tw:n\n\ttext-wrap: normal;\nsnippet tw:s\n\ttext-wrap: suppress;\nsnippet tw:u\n\ttext-wrap: unrestricted;\nsnippet t\n\ttop: ${1};\nsnippet t:a\n\ttop: auto;\nsnippet va\n\tvertical-align: ${1};\nsnippet va:bl\n\tvertical-align: baseline;\nsnippet va:b\n\tvertical-align: bottom;\nsnippet va:m\n\tvertical-align: middle;\nsnippet va:sub\n\tvertical-align: sub;\nsnippet va:sup\n\tvertical-align: super;\nsnippet va:tb\n\tvertical-align: text-bottom;\nsnippet va:tt\n\tvertical-align: text-top;\nsnippet va:t\n\tvertical-align: top;\nsnippet v\n\tvisibility: ${1};\nsnippet v:c\n\tvisibility: collapse;\nsnippet v:h\n\tvisibility: hidden;\nsnippet v:v\n\tvisibility: visible;\nsnippet whsc\n\twhite-space-collapse: ${1};\nsnippet whsc:ba\n\twhite-space-collapse: break-all;\nsnippet whsc:bs\n\twhite-space-collapse: break-strict;\nsnippet whsc:k\n\twhite-space-collapse: keep-all;\nsnippet whsc:l\n\twhite-space-collapse: loose;\nsnippet whsc:n\n\twhite-space-collapse: normal;\nsnippet whs\n\twhite-space: ${1};\nsnippet whs:n\n\twhite-space: normal;\nsnippet whs:nw\n\twhite-space: nowrap;\nsnippet whs:pl\n\twhite-space: pre-line;\nsnippet whs:pw\n\twhite-space: pre-wrap;\nsnippet whs:p\n\twhite-space: pre;\nsnippet wid\n\twidows: ${1};\nsnippet w\n\twidth: ${1};\nsnippet w:a\n\twidth: auto;\nsnippet wob\n\tword-break: ${1};\nsnippet wob:ba\n\tword-break: break-all;\nsnippet wob:bs\n\tword-break: break-strict;\nsnippet wob:k\n\tword-break: keep-all;\nsnippet wob:l\n\tword-break: loose;\nsnippet wob:n\n\tword-break: normal;\nsnippet wos\n\tword-spacing: ${1};\nsnippet wow\n\tword-wrap: ${1};\nsnippet wow:no\n\tword-wrap: none;\nsnippet wow:n\n\tword-wrap: normal;\nsnippet wow:s\n\tword-wrap: suppress;\nsnippet wow:u\n\tword-wrap: unrestricted;\nsnippet z\n\tz-index: ${1};\nsnippet z:a\n\tz-index: auto;\nsnippet zoo\n\tzoom: 1;\n"})),ace.define("ace/snippets/css",["require","exports","module","ace/snippets/css.snippets"],(function(n,t,e){"use strict";t.snippetText=n("./css.snippets"),t.scope="css"})),ace.require(["ace/snippets/css"],(function(n){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=n)})); \ No newline at end of file diff --git a/d5a6140d581e5c4eb200259ce372f40b.js b/d5a6140d581e5c4eb200259ce372f40b.js new file mode 100644 index 00000000..eb7c0d4d --- /dev/null +++ b/d5a6140d581e5c4eb200259ce372f40b.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/rdoc"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d5f79987405c2169278f8de37bcc9d05.js b/d5f79987405c2169278f8de37bcc9d05.js new file mode 100644 index 00000000..2e914a89 --- /dev/null +++ b/d5f79987405c2169278f8de37bcc9d05.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/luapage"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d7340300249ab98bd9b3f538a767106e.js b/d7340300249ab98bd9b3f538a767106e.js new file mode 100644 index 00000000..d66f5435 --- /dev/null +++ b/d7340300249ab98bd9b3f538a767106e.js @@ -0,0 +1 @@ +ace.define("ace/ext/static-css",["require","exports","module"],(function(e,t,n){n.exports=".ace_static_highlight {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'Source Code Pro', 'source-code-pro', 'Droid Sans Mono', monospace;\n font-size: 12px;\n white-space: pre-wrap\n}\n\n.ace_static_highlight .ace_gutter {\n width: 2em;\n text-align: right;\n padding: 0 3px 0 0;\n margin-right: 3px;\n contain: none;\n}\n\n.ace_static_highlight.ace_show_gutter .ace_line {\n padding-left: 2.6em;\n}\n\n.ace_static_highlight .ace_line { position: relative; }\n\n.ace_static_highlight .ace_gutter-cell {\n -moz-user-select: -moz-none;\n -khtml-user-select: none;\n -webkit-user-select: none;\n user-select: none;\n top: 0;\n bottom: 0;\n left: 0;\n position: absolute;\n}\n\n\n.ace_static_highlight .ace_gutter-cell:before {\n content: counter(ace_line, decimal);\n counter-increment: ace_line;\n}\n.ace_static_highlight {\n counter-reset: ace_line;\n}\n"})),ace.define("ace/ext/static_highlight",["require","exports","module","ace/edit_session","ace/layer/text","ace/ext/static-css","ace/config","ace/lib/dom","ace/lib/lang"],(function(e,t,n){"use strict";var i=e("../edit_session").EditSession,s=e("../layer/text").Text,o=e("./static-css"),r=e("../config"),a=e("../lib/dom"),c=e("../lib/lang").escapeHTML,l=function(){function e(e){this.className,this.type=e,this.style={},this.textContent=""}return e.prototype.cloneNode=function(){return this},e.prototype.appendChild=function(e){this.textContent+=e.toString()},e.prototype.toString=function(){var e=[];if("fragment"!=this.type){e.push("<",this.type),this.className&&e.push(" class='",this.className,"'");var t=[];for(var n in this.style)t.push(n,":",this.style[n]);t.length&&e.push(" style='",t.join(""),"'"),e.push(">")}return this.textContent&&e.push(this.textContent),"fragment"!=this.type&&e.push(""),e.join("")},e}(),h={createTextNode:function(e,t){return c(e)},createElement:function(e){return new l(e)},createFragment:function(){return new l("fragment")}},u=function(){this.config={},this.dom=h};u.prototype=s.prototype;var p=function(e,t,n){var i=e.className.match(/lang-(\w+)/),s=t.mode||i&&"ace/mode/"+i[1];if(!s)return!1;var o=t.theme||"ace/theme/textmate",r="",c=[];if(e.firstElementChild)for(var l=0,h=0;h=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[]/,next:"maybe_soql",merge:!1},{token:"paren.lparen",regex:/[\[({]/,next:"start",merge:!1},{token:"paren.rparen",regex:/[\])}]/,merge:!1}],maybe_soql:[{regex:/\s+/,token:"text"},{regex:/(SELECT|FIND)\b/,token:"keyword",caseInsensitive:!0,next:"soql"},{regex:"",token:"none",next:"start"}],soql:[{regex:"(:?ASC|BY|CATEGORY|CUBE|DATA|DESC|END|FIND|FIRST|FOR|FROM|GROUP|HAVING|IN|LAST|LIMIT|NETWORK|NULLS|OFFSET|ORDER|REFERENCE|RETURNING|ROLLUP|SCOPE|SELECT|SNIPPET|TRACKING|TYPEOF|UPDATE|USING|VIEW|VIEWSTAT|WHERE|WITH|AND|OR)\\b",token:"keyword",caseInsensitive:!0},{regex:"(:?target_length|toLabel|convertCurrency|count|Contact|Account|User|FIELDS)\\b",token:"support.function",caseInsensitive:!0},{token:"paren.rparen",regex:/[\]]/,next:"start",merge:!1},t("'",{escape:/\\[nb'"\\]/,error:/\\./,multiline:!1,next:"soql"}),t('"',{escape:/\\[nb'"\\]/,error:/\\./,multiline:!1,next:"soql"}),{regex:/\\./,token:"character.escape"},{regex:/[\?\&\|\!\{\}\[\]\(\)\^\~\*\:\"\'\+\-\,\.=\\\/]/,token:"keyword.operator"}],"log-start":[{token:"timestamp.invisible",regex:/^[\d:.() ]+\|/,next:"log-header"},{token:"timestamp.invisible",regex:/^ (Number of|Maximum)[^:]*:/,next:"log-comment"},{token:"invisible",regex:/^Execute Anonymous:/,next:"log-comment"},{defaultToken:"text"}],"log-comment":[{token:"log-comment",regex:/.*$/,next:"log-start"}],"log-header":[{token:"timestamp.invisible",regex:/((USER_DEBUG|\[\d+\]|DEBUG)\|)+/},{token:"keyword",regex:"(?:EXECUTION_FINISHED|EXECUTION_STARTED|CODE_UNIT_STARTED|CUMULATIVE_LIMIT_USAGE|LIMIT_USAGE_FOR_NS|CUMULATIVE_LIMIT_USAGE_END|CODE_UNIT_FINISHED)"},{regex:"",next:"log-start"}]},this.embedRules(i,"doc-",[i.getEndRule("start")]),this.normalizeRules()};o.inherits(a,r),t.ApexHighlightRules=a})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../../range").Range,i=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};o.inherits(a,i),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var o=e.getLine(n);if(this.singleLineBlockCommentRe.test(o)&&!this.startRegionRe.test(o)&&!this.tripleStarBlockCommentRe.test(o))return"";var r=this._getFoldWidgetBase(e,t,n);return!r&&this.startRegionRe.test(o)?"start":r},this.getFoldWidgetRange=function(e,t,n,o){var r,i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);if(r=i.match(this.foldingStartMarker)){var a=r.index;if(r[1])return this.openingBracketBlock(e,r[1],n,a);var s=e.getCommentFoldRange(n,a+r[0].length,1);return s&&!s.isMultiLine()&&(o?s=this.getSectionRange(e,n):"all"!=t&&(s=null)),s}return"markbegin"!==t&&(r=i.match(this.foldingStopMarker))?(a=r.index+r[0].length,r[1]?this.closingBracketBlock(e,r[1],n,a):e.getCommentFoldRange(n,a,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),o=n.search(/\S/),i=t,a=n.length,s=t+=1,l=e.getLength();++tg)break;var c=this.getFoldWidgetRange(e,"all",t);if(c){if(c.start.row<=i)break;if(c.isMultiLine())t=c.end.row;else if(o==g)break}s=t}}return new r(i,a,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),i=e.getLength(),a=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++na)return new r(a,o,n,t.length)}}.call(a.prototype)})),ace.define("ace/mode/apex",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/apex_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../mode/text").Mode,i=e("./apex_highlight_rules").ApexHighlightRules,a=e("../mode/folding/cstyle").FoldMode;function s(){r.call(this),this.HighlightRules=i,this.foldingRules=new a,this.$behaviour=this.$defaultBehaviour}o.inherits(s,r),s.prototype.lineCommentStart="//",s.prototype.blockComment={start:"/*",end:"*/"},t.Mode=s})),ace.require(["ace/mode/apex"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d78d3b050ea95b068380d975fd413fd7.js b/d78d3b050ea95b068380d975fd413fd7.js new file mode 100644 index 00000000..be67b44f --- /dev/null +++ b/d78d3b050ea95b068380d975fd413fd7.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/glsl"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d7d616d4aa8fd3f51d681242853dcde9.js b/d7d616d4aa8fd3f51d681242853dcde9.js new file mode 100644 index 00000000..9f2d197f --- /dev/null +++ b/d7d616d4aa8fd3f51d681242853dcde9.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/twig"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d83cda12aee0c87c8b381a1234bf7798.js b/d83cda12aee0c87c8b381a1234bf7798.js new file mode 100644 index 00000000..68443f6d --- /dev/null +++ b/d83cda12aee0c87c8b381a1234bf7798.js @@ -0,0 +1 @@ +ace.define("ace/snippets/sql.snippets",["require","exports","module"],(function(e,t,n){n.exports="snippet tbl\n\tcreate table ${1:table} (\n\t\t${2:columns}\n\t);\nsnippet col\n\t${1:name}\t${2:type}\t${3:default ''}\t${4:not null}\nsnippet ccol\n\t${1:name}\tvarchar2(${2:size})\t${3:default ''}\t${4:not null}\nsnippet ncol\n\t${1:name}\tnumber\t${3:default 0}\t${4:not null}\nsnippet dcol\n\t${1:name}\tdate\t${3:default sysdate}\t${4:not null}\nsnippet ind\n\tcreate index ${3:$1_$2} on ${1:table}(${2:column});\nsnippet uind\n\tcreate unique index ${1:name} on ${2:table}(${3:column});\nsnippet tblcom\n\tcomment on table ${1:table} is '${2:comment}';\nsnippet colcom\n\tcomment on column ${1:table}.${2:column} is '${3:comment}';\nsnippet addcol\n\talter table ${1:table} add (${2:column} ${3:type});\nsnippet seq\n\tcreate sequence ${1:name} start with ${2:1} increment by ${3:1} minvalue ${4:1};\nsnippet s*\n\tselect * from ${1:table}\n"})),ace.define("ace/snippets/sql",["require","exports","module","ace/snippets/sql.snippets"],(function(e,t,n){"use strict";t.snippetText=e("./sql.snippets"),t.scope="sql"})),ace.require(["ace/snippets/sql"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/d85853bab3b213652aee023adecfb690.js b/d85853bab3b213652aee023adecfb690.js new file mode 100644 index 00000000..46543238 --- /dev/null +++ b/d85853bab3b213652aee023adecfb690.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/vue"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/da740c1b29a85b999a6874b59a1baeef.js b/da740c1b29a85b999a6874b59a1baeef.js new file mode 100644 index 00000000..f4ff6dcc --- /dev/null +++ b/da740c1b29a85b999a6874b59a1baeef.js @@ -0,0 +1 @@ +ace.define("ace/theme/textmate",["require","exports","module","ace/theme/textmate-css","ace/lib/dom"],(function(e,t,s){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText=e("./textmate-css"),t.$id="ace/theme/textmate",e("../lib/dom").importCssString(t.cssText,t.cssClass,!1)})),ace.require(["ace/theme/textmate"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/db8ca5cfb6fe4aaef215f116f6991784.js b/db8ca5cfb6fe4aaef215f116f6991784.js new file mode 100644 index 00000000..4c1b0177 --- /dev/null +++ b/db8ca5cfb6fe4aaef215f116f6991784.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/svg"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/dc8240db39815020378555a4d80571c3.js b/dc8240db39815020378555a4d80571c3.js new file mode 100644 index 00000000..5b598eb4 --- /dev/null +++ b/dc8240db39815020378555a4d80571c3.js @@ -0,0 +1 @@ +ace.define("ace/snippets/tcl.snippets",["require","exports","module"],(function(n,t,e){e.exports="# #!/usr/bin/env tclsh\nsnippet #!\n\t#!/usr/bin/env tclsh\n\t\n# Process\nsnippet pro\n\tproc ${1:function_name} {${2:args}} {\n\t\t${3:#body ...}\n\t}\n#xif\nsnippet xif\n\t${1:expr}? ${2:true} : ${3:false}\n# Conditional\nsnippet if\n\tif {${1}} {\n\t\t${2:# body...}\n\t}\n# Conditional if..else\nsnippet ife\n\tif {${1}} {\n\t\t${2:# body...}\n\t} else {\n\t\t${3:# else...}\n\t}\n# Conditional if..elsif..else\nsnippet ifee\n\tif {${1}} {\n\t\t${2:# body...}\n\t} elseif {${3}} {\n\t\t${4:# elsif...}\n\t} else {\n\t\t${5:# else...}\n\t}\n# If catch then\nsnippet ifc\n\tif { [catch {${1:#do something...}} ${2:err}] } {\n\t\t${3:# handle failure...}\n\t}\n# Catch\nsnippet catch\n\tcatch {${1}} ${2:err} ${3:options}\n# While Loop\nsnippet wh\n\twhile {${1}} {\n\t\t${2:# body...}\n\t}\n# For Loop\nsnippet for\n\tfor {set ${2:var} 0} {$$2 < ${1:count}} {${3:incr} $2} {\n\t\t${4:# body...}\n\t}\n# Foreach Loop\nsnippet fore\n\tforeach ${1:x} {${2:#list}} {\n\t\t${3:# body...}\n\t}\n# after ms script...\nsnippet af\n\tafter ${1:ms} ${2:#do something}\n# after cancel id\nsnippet afc\n\tafter cancel ${1:id or script}\n# after idle\nsnippet afi\n\tafter idle ${1:script}\n# after info id\nsnippet afin\n\tafter info ${1:id}\n# Expr\nsnippet exp\n\texpr {${1:#expression here}}\n# Switch\nsnippet sw\n\tswitch ${1:var} {\n\t\t${3:pattern 1} {\n\t\t\t${4:#do something}\n\t\t}\n\t\tdefault {\n\t\t\t${2:#do something}\n\t\t}\n\t}\n# Case\nsnippet ca\n\t${1:pattern} {\n\t\t${2:#do something}\n\t}${3}\n# Namespace eval\nsnippet ns\n\tnamespace eval ${1:path} {${2:#script...}}\n# Namespace current\nsnippet nsc\n\tnamespace current\n"})),ace.define("ace/snippets/tcl",["require","exports","module","ace/snippets/tcl.snippets"],(function(n,t,e){"use strict";t.snippetText=n("./tcl.snippets"),t.scope="tcl"})),ace.require(["ace/snippets/tcl"],(function(n){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=n)})); \ No newline at end of file diff --git a/dc83a73f0eb89665520bbb6672dfa3cb.js b/dc83a73f0eb89665520bbb6672dfa3cb.js new file mode 100644 index 00000000..cbde704e --- /dev/null +++ b/dc83a73f0eb89665520bbb6672dfa3cb.js @@ -0,0 +1 @@ +ace.define("ace/mode/logtalk_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,o){"use strict";var n=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,r=function(){this.$rules={start:[{token:"punctuation.definition.comment.logtalk",regex:"/\\*",push:[{token:"punctuation.definition.comment.logtalk",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.logtalk"}]},{todo:"fix grouping",token:["comment.line.percentage.logtalk","punctuation.definition.comment.logtalk"],regex:"%.*$\\n?"},{todo:"fix grouping",token:["storage.type.opening.logtalk","punctuation.definition.storage.type.logtalk"],regex:":-\\s(?:object|protocol|category|module)(?=[(])"},{todo:"fix grouping",token:["storage.type.closing.logtalk","punctuation.definition.storage.type.logtalk"],regex:":-\\send_(?:object|protocol|category)(?=[.])"},{caseInsensitive:!1,token:"storage.type.relations.logtalk",regex:"\\b(?:complements|extends|i(?:nstantiates|mp(?:orts|lements))|specializes)(?=[(])"},{caseInsensitive:!1,todo:"fix grouping",token:["storage.modifier.others.logtalk","punctuation.definition.storage.modifier.logtalk"],regex:":-\\s(?:e(?:lse|ndif)|built_in|dynamic|synchronized|threaded)(?=[.])"},{caseInsensitive:!1,todo:"fix grouping",token:["storage.modifier.others.logtalk","punctuation.definition.storage.modifier.logtalk"],regex:":-\\s(?:c(?:alls|oinductive)|e(?:lif|n(?:coding|sure_loaded)|xport)|i(?:f|n(?:clude|itialization|fo))|reexport|set_(?:logtalk|prolog)_flag|uses)(?=[(])"},{caseInsensitive:!1,todo:"fix grouping",token:["storage.modifier.others.logtalk","punctuation.definition.storage.modifier.logtalk"],regex:":-\\s(?:alias|info|d(?:ynamic|iscontiguous)|m(?:eta_(?:non_terminal|predicate)|ode|ultifile)|p(?:ublic|r(?:otected|ivate))|op|use(?:s|_module)|synchronized)(?=[(])"},{token:"keyword.operator.message-sending.logtalk",regex:"(:|::|\\^\\^)"},{token:"keyword.operator.external-call.logtalk",regex:"([{}])"},{token:"keyword.operator.mode.logtalk",regex:"(\\?|@)"},{token:"keyword.operator.comparison.term.logtalk",regex:"(@=<|@<|@>|@>=|==|\\\\==)"},{token:"keyword.operator.comparison.arithmetic.logtalk",regex:"(=<|<|>|>=|=:=|=\\\\=)"},{token:"keyword.operator.bitwise.logtalk",regex:"(<<|>>|/\\\\|\\\\/|\\\\)"},{token:"keyword.operator.evaluable.logtalk",regex:"\\b(?:e|pi|div|mod|rem)\\b(?![-!(^~])"},{token:"keyword.operator.evaluable.logtalk",regex:"(\\*\\*|\\+|-|\\*|/|//)"},{token:"keyword.operator.misc.logtalk",regex:"(:-|!|\\\\+|,|;|--\x3e|->|=|\\=|\\.|=\\.\\.|\\^|\\bas\\b|\\bis\\b)"},{caseInsensitive:!1,token:"support.function.evaluable.logtalk",regex:"\\b(a(bs|cos|sin|tan|tan2)|c(eiling|os)|div|exp|flo(at(_(integer|fractional)_part)?|or)|log|m(ax|in|od)|r(em|ound)|s(i(n|gn)|qrt)|t(an|runcate)|xor)(?=[(])"},{token:"support.function.control.logtalk",regex:"\\b(?:true|fa(?:il|lse)|repeat|(?:instantiation|system)_error)\\b(?![-!(^~])"},{token:"support.function.control.logtalk",regex:"\\b((?:uninstantiation|type|domain|existence|permission|representation|evaluation|resource|syntax)_error)(?=[(])"},{token:"support.function.control.logtalk",regex:"\\b(?:ca(?:ll|tch)|ignore|throw|once)(?=[(])"},{token:"support.function.chars-and-bytes-io.logtalk",regex:"\\b(?:(?:get|p(?:eek|ut))_(c(?:har|ode)|byte)|nl)(?=[(])"},{token:"support.function.chars-and-bytes-io.logtalk",regex:"\\bnl\\b"},{token:"support.function.atom-term-processing.logtalk",regex:"\\b(?:atom_(?:length|c(?:hars|o(?:ncat|des)))|sub_atom|char_code|number_c(?:har|ode)s)(?=[(])"},{caseInsensitive:!1,token:"support.function.term-testing.logtalk",regex:"\\b(?:var|atom(ic)?|integer|float|c(?:allable|ompound)|n(?:onvar|umber)|ground|acyclic_term)(?=[(])"},{token:"support.function.term-comparison.logtalk",regex:"\\b(compare)(?=[(])"},{token:"support.function.term-io.logtalk",regex:"\\b(?:read(_term)?|write(?:q|_(?:canonical|term))?|(current_)?(?:char_conversion|op))(?=[(])"},{caseInsensitive:!1,token:"support.function.term-creation-and-decomposition.logtalk",regex:"\\b(arg|copy_term|functor|numbervars|term_variables)(?=[(])"},{caseInsensitive:!1,token:"support.function.term-unification.logtalk",regex:"\\b(subsumes_term|unify_with_occurs_check)(?=[(])"},{caseInsensitive:!1,token:"support.function.stream-selection-and-control.logtalk",regex:"\\b(?:(?:se|curren)t_(?:in|out)put|open|close|flush_output|stream_property|at_end_of_stream|set_stream_position)(?=[(])"},{token:"support.function.stream-selection-and-control.logtalk",regex:"\\b(?:flush_output|at_end_of_stream)\\b"},{token:"support.function.prolog-flags.logtalk",regex:"\\b((?:se|curren)t_prolog_flag)(?=[(])"},{token:"support.function.compiling-and-loading.logtalk",regex:"\\b(logtalk_(?:compile|l(?:ibrary_path|oad|oad_context)|make(_target_action)?))(?=[(])"},{token:"support.function.compiling-and-loading.logtalk",regex:"\\b(logtalk_make)\\b"},{caseInsensitive:!1,token:"support.function.event-handling.logtalk",regex:"\\b(?:(?:abolish|define)_events|current_event)(?=[(])"},{token:"support.function.implementation-defined-hooks.logtalk",regex:"\\b(?:(?:create|current|set)_logtalk_flag|halt)(?=[(])"},{token:"support.function.implementation-defined-hooks.logtalk",regex:"\\b(halt)\\b"},{token:"support.function.sorting.logtalk",regex:"\\b((key)?(sort))(?=[(])"},{caseInsensitive:!1,token:"support.function.entity-creation-and-abolishing.logtalk",regex:"\\b((c(?:reate|urrent)|abolish)_(?:object|protocol|category))(?=[(])"},{caseInsensitive:!1,token:"support.function.reflection.logtalk",regex:"\\b((object|protocol|category)_property|co(mplements_object|nforms_to_protocol)|extends_(object|protocol|category)|imp(orts_category|lements_protocol)|(instantiat|specializ)es_class)(?=[(])"},{token:"support.function.logtalk",regex:"\\b((?:for|retract)all)(?=[(])"},{caseInsensitive:!1,token:"support.function.execution-context.logtalk",regex:"\\b(?:context|parameter|se(?:lf|nder)|this)(?=[(])"},{token:"support.function.database.logtalk",regex:"\\b(?:a(?:bolish|ssert(?:a|z))|clause|retract(all)?)(?=[(])"},{token:"support.function.all-solutions.logtalk",regex:"\\b((?:bag|set)of|f(?:ind|or)all)(?=[(])"},{caseInsensitive:!1,token:"support.function.multi-threading.logtalk",regex:"\\b(threaded(_(ca(?:ll|ncel)|once|ignore|exit|peek|wait|notify))?)(?=[(])"},{caseInsensitive:!1,token:"support.function.engines.logtalk",regex:"\\b(threaded_engine(_(create|destroy|self|next(?:_reified)?|yield|post|fetch))?)(?=[(])"},{caseInsensitive:!1,token:"support.function.reflection.logtalk",regex:"\\b(?:current_predicate|predicate_property)(?=[(])"},{token:"support.function.event-handler.logtalk",regex:"\\b(?:before|after)(?=[(])"},{token:"support.function.message-forwarding-handler.logtalk",regex:"\\b(forward)(?=[(])"},{token:"support.function.grammar-rule.logtalk",regex:"\\b(?:expand_(?:goal|term)|(?:goal|term)_expansion|phrase)(?=[(])"},{token:"punctuation.definition.string.begin.logtalk",regex:"'",push:[{token:"constant.character.escape.logtalk",regex:"\\\\([\\\\abfnrtv\"']|(x[a-fA-F0-9]+|[0-7]+)\\\\)"},{token:"punctuation.definition.string.end.logtalk",regex:"'",next:"pop"},{defaultToken:"string.quoted.single.logtalk"}]},{token:"punctuation.definition.string.begin.logtalk",regex:'"',push:[{token:"constant.character.escape.logtalk",regex:"\\\\([\\\\abfnrtv\"']|(x[a-fA-F0-9]+|[0-7]+)\\\\)"},{token:"punctuation.definition.string.end.logtalk",regex:'"',next:"pop"},{defaultToken:"string.quoted.double.logtalk"}]},{token:"constant.numeric.logtalk",regex:"\\b(0b[0-1]+|0o[0-7]+|0x[0-9a-fA-F]+)\\b"},{token:"constant.numeric.logtalk",regex:"\\b(0'\\\\.|0'.|0''|0'\")"},{token:"constant.numeric.logtalk",regex:"\\b(\\d+\\.?\\d*((e|E)(\\+|-)?\\d+)?)\\b"},{token:"variable.other.logtalk",regex:"\\b([A-Z_][A-Za-z0-9_]*)\\b"}]},this.normalizeRules()};n.inherits(r,i),t.LogtalkHighlightRules=r})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,o){"use strict";var n=e("../../lib/oop"),i=e("../../range").Range,r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};n.inherits(a,r),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,o){var n=e.getLine(o);if(this.singleLineBlockCommentRe.test(n)&&!this.startRegionRe.test(n)&&!this.tripleStarBlockCommentRe.test(n))return"";var i=this._getFoldWidgetBase(e,t,o);return!i&&this.startRegionRe.test(n)?"start":i},this.getFoldWidgetRange=function(e,t,o,n){var i,r=e.getLine(o);if(this.startRegionRe.test(r))return this.getCommentRegionBlock(e,r,o);if(i=r.match(this.foldingStartMarker)){var a=i.index;if(i[1])return this.openingBracketBlock(e,i[1],o,a);var l=e.getCommentFoldRange(o,a+i[0].length,1);return l&&!l.isMultiLine()&&(n?l=this.getSectionRange(e,o):"all"!=t&&(l=null)),l}return"markbegin"!==t&&(i=r.match(this.foldingStopMarker))?(a=i.index+i[0].length,i[1]?this.closingBracketBlock(e,i[1],o,a):e.getCommentFoldRange(o,a,-1)):void 0},this.getSectionRange=function(e,t){for(var o=e.getLine(t),n=o.search(/\S/),r=t,a=o.length,l=t+=1,s=e.getLength();++tg)break;var c=this.getFoldWidgetRange(e,"all",t);if(c){if(c.start.row<=r)break;if(c.isMultiLine())t=c.end.row;else if(n==g)break}l=t}}return new i(r,a,l,e.getLine(l).length)},this.getCommentRegionBlock=function(e,t,o){for(var n=t.search(/\s*$/),r=e.getLength(),a=o,l=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,s=1;++oa)return new i(a,n,o,t.length)}}.call(a.prototype)})),ace.define("ace/mode/logtalk",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/logtalk_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,o){"use strict";var n=e("../lib/oop"),i=e("./text").Mode,r=(e("../tokenizer").Tokenizer,e("./logtalk_highlight_rules").LogtalkHighlightRules),a=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=r,this.foldingRules=new a,this.$behaviour=this.$defaultBehaviour};n.inherits(l,i),function(){this.lineCommentStart="%",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/logtalk"}.call(l.prototype),t.Mode=l})),ace.require(["ace/mode/logtalk"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/dc932cde2fbfca8e2901fb693968b131.js b/dc932cde2fbfca8e2901fb693968b131.js new file mode 100644 index 00000000..bc20d320 --- /dev/null +++ b/dc932cde2fbfca8e2901fb693968b131.js @@ -0,0 +1 @@ +ace.define("ace/theme/twilight-css",["require","exports","module"],(function(e,n,a){a.exports=".ace-twilight .ace_gutter {\n background: #232323;\n color: #E2E2E2\n}\n\n.ace-twilight .ace_print-margin {\n width: 1px;\n background: #232323\n}\n\n.ace-twilight {\n background-color: #141414;\n color: #F8F8F8\n}\n\n.ace-twilight .ace_cursor {\n color: #A7A7A7\n}\n\n.ace-twilight .ace_marker-layer .ace_selection {\n background: rgba(221, 240, 255, 0.20)\n}\n\n.ace-twilight.ace_multiselect .ace_selection.ace_start {\n box-shadow: 0 0 3px 0px #141414;\n}\n\n.ace-twilight .ace_marker-layer .ace_step {\n background: rgb(102, 82, 0)\n}\n\n.ace-twilight .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 255, 255, 0.25)\n}\n\n.ace-twilight .ace_marker-layer .ace_active-line {\n background: rgba(255, 255, 255, 0.031)\n}\n\n.ace-twilight .ace_gutter-active-line {\n background-color: rgba(255, 255, 255, 0.031)\n}\n\n.ace-twilight .ace_marker-layer .ace_selected-word {\n border: 1px solid rgba(221, 240, 255, 0.20)\n}\n\n.ace-twilight .ace_invisible {\n color: rgba(255, 255, 255, 0.25)\n}\n\n.ace-twilight .ace_keyword,\n.ace-twilight .ace_meta {\n color: #CDA869\n}\n\n.ace-twilight .ace_constant,\n.ace-twilight .ace_constant.ace_character,\n.ace-twilight .ace_constant.ace_character.ace_escape,\n.ace-twilight .ace_constant.ace_other,\n.ace-twilight .ace_heading,\n.ace-twilight .ace_markup.ace_heading,\n.ace-twilight .ace_support.ace_constant {\n color: #CF6A4C\n}\n\n.ace-twilight .ace_invalid.ace_illegal {\n color: #F8F8F8;\n background-color: rgba(86, 45, 86, 0.75)\n}\n\n.ace-twilight .ace_invalid.ace_deprecated {\n text-decoration: underline;\n font-style: italic;\n color: #D2A8A1\n}\n\n.ace-twilight .ace_support {\n color: #9B859D\n}\n\n.ace-twilight .ace_fold {\n background-color: #AC885B;\n border-color: #F8F8F8\n}\n\n.ace-twilight .ace_support.ace_function {\n color: #DAD085\n}\n\n.ace-twilight .ace_list,\n.ace-twilight .ace_markup.ace_list,\n.ace-twilight .ace_storage {\n color: #F9EE98\n}\n\n.ace-twilight .ace_entity.ace_name.ace_function,\n.ace-twilight .ace_meta.ace_tag {\n color: #AC885B\n}\n\n.ace-twilight .ace_string {\n color: #8F9D6A\n}\n\n.ace-twilight .ace_string.ace_regexp {\n color: #E9C062\n}\n\n.ace-twilight .ace_comment {\n font-style: italic;\n color: #5F5A60\n}\n\n.ace-twilight .ace_variable {\n color: #7587A6\n}\n\n.ace-twilight .ace_xml-pe {\n color: #494949\n}\n\n.ace-twilight .ace_indent-guide {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-twilight .ace_indent-guide-active {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n"})),ace.define("ace/theme/twilight",["require","exports","module","ace/theme/twilight-css","ace/lib/dom"],(function(e,n,a){n.isDark=!0,n.cssClass="ace-twilight",n.cssText=e("./twilight-css"),e("../lib/dom").importCssString(n.cssText,n.cssClass,!1)})),ace.require(["ace/theme/twilight"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/dd6d3e34e82e105b85f3dc94c559c131.js b/dd6d3e34e82e105b85f3dc94c559c131.js new file mode 100644 index 00000000..72b52a7b --- /dev/null +++ b/dd6d3e34e82e105b85f3dc94c559c131.js @@ -0,0 +1 @@ +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=(e("../lib/lang"),e("./text_highlight_rules").TextHighlightRules),a=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",i=t.supportFunction="rgb|rgba|url|attr|counter|counters",s=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|flex-end|flex-start|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",l=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",c=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",u=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",g=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",d=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",p=function(){var e=this.createKeywordMapper({"support.function":i,"support.constant":s,"support.type":a,"support.constant.color":l,"support.constant.fonts":c},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:u},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+u+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:u},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:g},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:d},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{token:"paren.lparen",regex:"\\{"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};r.inherits(p,o),t.CssHighlightRules=p})),ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};r.inherits(a,o),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[o.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[o.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(o,"doc-",[o.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r="/"==e.charAt(1)?2:1;return 1==r?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==r&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==r?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[o.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[o.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}r.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(e){var t="[_:a-zA-ZÀ-￿][-_:.a-zA-Z0-9À-￿]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"--\x3e",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===a&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(o.prototype),r.inherits(a,o),t.XmlHighlightRules=a})),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("../lib/lang"),a=e("./css_highlight_rules").CssHighlightRules,i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./xml_highlight_rules").XmlHighlightRules,l=o.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),c=function(){s.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=l[t];return["meta.tag.punctuation."+("<"==e?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(a,"css-","style"),this.embedTagRules(new i({jsx:!1}).getRules(),"js-","script"),this.constructor===c&&this.normalizeRules()};r.inherits(c,s),t.HtmlHighlightRules=c})),ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"};t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"};var i=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},s=t.constantNumericBinary={token:"constant.numeric",regex:/\b(0[bB][01](?:[01]|_(?=[01]))*)\b/},l=t.constantNumericDecimal={token:"constant.numeric",regex:/\b(0[dD](?:[1-9](?:[\d]|_(?=[\d]))*|0))\b/},c=t.constantNumericOctal={token:"constant.numeric",regex:/\b(0[oO]?(?:[1-7](?:[0-7]|_(?=[0-7]))*|0))\b/},u=t.constantNumericRational={token:"constant.numeric",regex:/\b([\d]+(?:[./][\d]+)?ri?)\b/},g=t.constantNumericComplex={token:"constant.numeric",regex:/\b([\d]i)\b/},d=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?i?\\b"},p=t.instanceVariable={token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},m=function(){var e=this.$keywords=this.createKeywordMapper({keyword:"alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|__ENCODING__|prepend","constant.language":"true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING|RUBY_PATCHLEVEL|RUBY_REVISION|RUBY_COPYRIGHT|RUBY_ENGINE|RUBY_ENGINE_VERSION|RUBY_DESCRIPTION","variable.language":"$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self","support.function":"abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many|p|warn|refine|using|module_function|extend|alias_method|private_class_method|remove_method|undef_method","invalid.deprecated":"debugger"},"identifier"),t="\\\\(?:n(?:[1-7][0-7]{0,2}|0)|[nsrtvfbae'\"\\\\]|c(?:\\\\M-)?.|M-(?:\\\\C-|\\\\c)?.|C-(?:\\\\M-)?.|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u{[\\da-fA-F]{1,6}(?:\\s[\\da-fA-F]{1,6})*})",n={"(":")","[":"]","{":"}","<":">","^":"^","|":"|","%":"%"};this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment.multiline",regex:"^=begin(?=$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:/[/](?=.*\/)/,next:"regex"},[{token:["constant.other.symbol.ruby","string.start"],regex:/(:)?(")/,push:[{token:"constant.language.escape",regex:t},{token:"paren.start",regex:/#{/,push:"start"},{token:"string.end",regex:/"/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/`/,push:[{token:"constant.language.escape",regex:t},{token:"paren.start",regex:/#{/,push:"start"},{token:"string.end",regex:/`/,next:"pop"},{defaultToken:"string"}]},{token:["constant.other.symbol.ruby","string.start"],regex:/(:)?(')/,push:[{token:"constant.language.escape",regex:/\\['\\]/},{token:"string.end",regex:/'/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/%[qwx]([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="qStateWithoutInterpolation",this.token}},{token:"string.start",regex:/%[QWX]?([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="qStateWithInterpolation",this.token}},{token:"constant.other.symbol.ruby",regex:/%[si]([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="sStateWithoutInterpolation",this.token}},{token:"constant.other.symbol.ruby",regex:/%[SI]([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="sStateWithInterpolation",this.token}},{token:"string.regexp",regex:/%[r]([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="rState",this.token}}],{token:"punctuation",regex:"::"},p,{token:"variable.global",regex:"[$][a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]*"},{token:["punctuation.operator","support.function"],regex:/(\.)([a-zA-Z_\d]+)(?=\()/},{token:["punctuation.operator","identifier"],regex:/(\.)([a-zA-Z_][a-zA-Z_\d]*)/},{token:"string.character",regex:"\\B\\?(?:"+t+"|\\S)"},{token:"punctuation.operator",regex:/\?(?=.+:)/},u,g,a,i,d,s,l,c,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r="-"==e[2]||"~"==e[2]?"indentedHeredoc":"heredoc",o=e.split(this.splitRegex);return n.push(r,o[3]),[{type:"constant",value:o[1]},{type:"string",value:o[2]},{type:"support.class",value:o[3]},{type:"string",value:o[4]}]},regex:"(<<[-~]?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return"heredoc"===t[0]||"indentedHeredoc"===t[0]?t[0]:e}},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\||\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]",onMatch:function(e,t,n){return this.next="","}"==e&&n.length>1&&"start"!=n[1]&&(n.shift(),this.next=n.shift()),this.token}},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:/[?:,;.]/}],comment:[{token:"comment.multiline",regex:"^=end(?=$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}],qStateWithInterpolation:[{token:"string.start",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"string"}},{token:"constant.language.escape",regex:t},{token:"constant.language.escape",regex:/\\./},{token:"paren.start",regex:/#{/,push:"start"},{token:"string.end",regex:/[)\]>}^|%]/,onMatch:function(e,t,r){return r.length&&e===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","string")}},{defaultToken:"string"}],qStateWithoutInterpolation:[{token:"string.start",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"string"}},{token:"constant.language.escape",regex:/\\['\\]/},{token:"constant.language.escape",regex:/\\./},{token:"string.end",regex:/[)\]>}^|%]/,onMatch:function(e,t,r){return r.length&&e===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","string")}},{defaultToken:"string"}],sStateWithoutInterpolation:[{token:"constant.other.symbol.ruby",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"constant.other.symbol.ruby"}},{token:"constant.other.symbol.ruby",regex:/[)\]>}^|%]/,onMatch:function(e,t,r){return r.length&&e===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","constant.other.symbol.ruby")}},{defaultToken:"constant.other.symbol.ruby"}],sStateWithInterpolation:[{token:"constant.other.symbol.ruby",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"constant.other.symbol.ruby"}},{token:"constant.language.escape",regex:t},{token:"constant.language.escape",regex:/\\./},{token:"paren.start",regex:/#{/,push:"start"},{token:"constant.other.symbol.ruby",regex:/[)\]>}^|%]/,onMatch:function(e,t,r){return r.length&&e===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","constant.other.symbol.ruby")}},{defaultToken:"constant.other.symbol.ruby"}],rState:[{token:"string.regexp",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"constant.language.escape"}},{token:"paren.start",regex:/#{/,push:"start"},{token:"string.regexp",regex:/\//},{token:"string.regexp",regex:/[)\]>}^|%][imxouesn]*/,onMatch:function(e,t,r){return r.length&&e[0]===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","constant.language.escape")}},{include:"regex"},{defaultToken:"string.regexp"}],regex:[{token:"regexp.keyword",regex:/\\[wWdDhHsS]/},{token:"constant.language.escape",regex:/\\[AGbBzZ]/},{token:"constant.language.escape",regex:/\\g<[a-zA-Z0-9]*>/},{token:["constant.language.escape","regexp.keyword","constant.language.escape"],regex:/(\\p{\^?)(Alnum|Alpha|Blank|Cntrl|Digit|Graph|Lower|Print|Punct|Space|Upper|XDigit|Word|ASCII|Any|Assigned|Arabic|Armenian|Balinese|Bengali|Bopomofo|Braille|Buginese|Buhid|Canadian_Aboriginal|Carian|Cham|Cherokee|Common|Coptic|Cuneiform|Cypriot|Cyrillic|Deseret|Devanagari|Ethiopic|Georgian|Glagolitic|Gothic|Greek|Gujarati|Gurmukhi|Han|Hangul|Hanunoo|Hebrew|Hiragana|Inherited|Kannada|Katakana|Kayah_Li|Kharoshthi|Khmer|Lao|Latin|Lepcha|Limbu|Linear_B|Lycian|Lydian|Malayalam|Mongolian|Myanmar|New_Tai_Lue|Nko|Ogham|Ol_Chiki|Old_Italic|Old_Persian|Oriya|Osmanya|Phags_Pa|Phoenician|Rejang|Runic|Saurashtra|Shavian|Sinhala|Sundanese|Syloti_Nagri|Syriac|Tagalog|Tagbanwa|Tai_Le|Tamil|Telugu|Thaana|Thai|Tibetan|Tifinagh|Ugaritic|Vai|Yi|Ll|Lm|Lt|Lu|Lo|Mn|Mc|Me|Nd|Nl|Pc|Pd|Ps|Pe|Pi|Pf|Po|No|Sm|Sc|Sk|So|Zs|Zl|Zp|Cc|Cf|Cn|Co|Cs|N|L|M|P|S|Z|C)(})/},{token:["constant.language.escape","invalid","constant.language.escape"],regex:/(\\p{\^?)([^/]*)(})/},{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:/[/][imxouesn]*/,next:"start"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?(?:[:=!>]|<'?[a-zA-Z]*'?>|<[=!])|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"regexp.keyword",regex:/\[\[:(?:alnum|alpha|blank|cntrl|digit|graph|lower|print|punct|space|upper|xdigit|word|ascii):\]\]/},{token:"constant.language.escape",regex:/\[\^?/,push:"regex_character_class"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword",regex:/\\[wWdDhHsS]/},{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:/&?&?\[\^?/,push:"regex_character_class"},{token:"constant.language.escape",regex:"]",next:"pop"},{token:"constant.language.escape",regex:"-"},{defaultToken:"string.regexp.characterclass"}]},this.normalizeRules()};r.inherits(m,o),t.RubyHighlightRules=m})),ace.define("ace/mode/html_ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/ruby_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./html_highlight_rules").HtmlHighlightRules,a=e("./ruby_highlight_rules").RubyHighlightRules,i=function(){o.call(this);var e=[{regex:"<%%|%%>",token:"constant.language.escape"},{token:"comment.start.erb",regex:"<%#",push:[{token:"comment.end.erb",regex:"%>",next:"pop",defaultToken:"comment"}]},{token:"support.ruby_tag",regex:"<%+(?!>)[-=]?",push:"ruby-start"}];for(var t in this.$rules)this.$rules[t].unshift.apply(this.$rules[t],e);this.embedRules(a,"ruby-",[{token:"support.ruby_tag",regex:"%>",next:"pop"},{token:"comment",regex:"#(?:[^%]|%[^>])*"}],["start"]),this.normalizeRules()};r.inherits(i,o),t.HtmlRubyHighlightRules=i})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var r=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,a=e.findMatchingBracket({row:t,column:o});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new r(t,0,t,o-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,r,o){if('"'==o||"'"==o){var s=o,l=r.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),u=r.doc.getLine(c.row).substring(c.column,c.column+1),g=new a(r,c.row,c.column),d=g.getCurrentToken();if(u==s&&(i(d,"attribute-value")||i(d,"string")))return{text:"",selection:[1,1]};if(d||(d=g.stepBackward()),!d)return;for(;i(d,"tag-whitespace")||i(d,"whitespace");)d=g.stepBackward();var p=!u||u.match(/\s/);if(i(d,"attribute-equals")&&(p||">"==u)||i(d,"decl-attribute-equals")&&(p||"?"==u))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,r,o){var a=r.doc.getTextRange(o);if(!o.isMultiLine()&&('"'==a||"'"==a)&&r.doc.getLine(o.start.row).substring(o.start.column+1,o.start.column+2)==a)return o.end.column++,o})),this.add("autoclosing","insertion",(function(e,t,n,r,o){if(">"==o){var s=n.getSelectionRange().start,l=new a(r,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var u=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(r.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var d=l.getCurrentTokenRow(),p=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var m=c.value;if(d==s.row&&(m=m.substring(0,s.column-p)),this.voidElements&&this.voidElements.hasOwnProperty(m.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,r,o){if("\n"==o){var s=n.getCursorPosition(),l=r.getLine(s.row),c=new a(r,s.row,s.column),u=c.getCurrentToken();if(i(u,"")&&-1!==u.type.indexOf("tag-close")){if("/>"==u.value)return;for(;u&&-1===u.type.indexOf("tag-name");)u=c.stepBackward();if(!u)return;var g=u.value,d=c.getCurrentTokenRow();if(!(u=c.stepBackward())||-1!==u.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[g]||!this.voidElements){var p=r.getTokenAt(s.row,s.column+1),m=(l=r.getLine(d),this.$getIndent(l)),h=m+r.getTabString();return p&&""==a){var i=n.getSelectionRange().start,s=new o(r,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};r.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?"markbeginend"===t?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())||this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return r}if(l(a,"tag-close"))return r.selfClosing="/>"==a.value,r;r.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,r){for(var o=e.getTokens(t),a=0,i=0;ic)break;var u=this.getFoldWidgetRange(e,"all",t);if(u){if(u.start.row<=a)break;if(u.isMultiLine())t=u.end.row;else if(r==c)break}s=t}}return new o(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var r=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new o(i,r,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new o};r.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,r){return this.getFoldWidgetRangeBase(e,t,n,r)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,u=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};r.inherits(u,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e),a=o.tokens,i=o.state;if(a.length&&"comment"==a[a.length-1].type)return r;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(r+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(u.prototype),t.Mode=u})),ace.define("ace/mode/css_completions",["require","exports","module"],(function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,double:2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{default:1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},float:{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,static:1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},o=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e)if("string"==typeof e[t]){var n=t.replace(/[A-Z]/g,(function(e){return"-"+e.toLowerCase()}));r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){if(this.completionsDefined||this.defineCompletions(),"ruleset"===e||"ace/mode/scss"==t.$mode.$id){var o=t.getLine(n.row).substr(0,n.column),a=/\([^)]*$/.test(o);return a&&(o=o.substr(o.lastIndexOf("(")+1)),/:[^;]+$/.test(o)?(/([\w\-]+):[^:]*$/.test(o),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r,a)}return[]},this.getPropertyCompletions=function(e,t,n,o,a){return a=a||!1,Object.keys(r).map((function(e){return{caption:e,snippet:e+": $0"+(a?"":";"),meta:"property",score:1e6}}))},this.getPropertyValueCompletions=function(e,t,n,o){var a=t.getLine(n.row).substr(0,n.column),i=(/([\w\-]+):[^:]*$/.exec(a)||{})[1];if(!i)return[];var s=[];return i in r&&"object"==typeof r[i]&&(s=Object.keys(r[i])),s.map((function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}}))}}).call(o.prototype),t.CssCompletions=o})),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=(e("../behaviour").Behaviour,e("./cstyle").CstyleBehaviour),a=e("../../token_iterator").TokenIterator,i=function(){this.inherit(o),this.add("colon","insertion",(function(e,t,n,r,o){if(":"===o&&n.selection.isEmpty()){var i=n.getCursorPosition(),s=new a(r,i.row,i.column),l=s.getCurrentToken();if(l&&l.value.match(/\s+/)&&(l=s.stepBackward()),l&&"support.type"===l.type){var c=r.doc.getLine(i.row);if(":"===c.substring(i.column,i.column+1))return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(c.substring(i.column)))return{text:":;",selection:[1,1]}}}})),this.add("colon","deletion",(function(e,t,n,r,o){var i=r.doc.getTextRange(o);if(!o.isMultiLine()&&":"===i){var s=n.getCursorPosition(),l=new a(r,s.row,s.column),c=l.getCurrentToken();if(c&&c.value.match(/\s+/)&&(c=l.stepBackward()),c&&"support.type"===c.type&&";"===r.doc.getLine(o.start.row).substring(o.end.column,o.end.column+1))return o.end.column++,o}})),this.add("semicolon","insertion",(function(e,t,n,r,o){if(";"===o&&n.selection.isEmpty()){var a=n.getCursorPosition();if(";"===r.doc.getLine(a.row).substring(a.column,a.column+1))return{text:"",selection:[1,1]}}})),this.add("!important","insertion",(function(e,t,n,r,o){if("!"===o&&n.selection.isEmpty()){var a=n.getCursorPosition(),i=r.doc.getLine(a.row);if(/^\s*(;|}|$)/.test(i.substring(a.column)))return{text:"!important",selection:[10,10]}}}))};r.inherits(i,o),t.CssBehaviour=i})),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./css_highlight_rules").CssHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./css_completions").CssCompletions,c=e("./behaviour/css").CssBehaviour,u=e("./folding/cstyle").FoldMode,g=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new c,this.$completer=new l,this.foldingRules=new u};r.inherits(g,o),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e).tokens;return o.length&&"comment"==o[o.length-1].type||t.match(/^.*\{\s*$/)&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/css",this.snippetFileId="ace/snippets/css"}.call(g.prototype),t.Mode=g})),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./fold_mode").FoldMode,a=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(a,o),function(){this.$getMode=function(e){for(var t in"string"!=typeof e&&(e=e[0]),this.subModes)if(0===e.indexOf(t))return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var o=this.$getMode(e);return o?o.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));return r&&r.getFoldWidget(e,t,n)||(r=this.$getMode(e.getState(n))),r&&r.getFoldWidget(e,t,n)||(r=this.defaultMode),r.getFoldWidgetRange(e,t,n)}}.call(a.prototype)})),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./mixed").FoldMode,a=e("./xml").FoldMode,i=e("./cstyle").FoldMode,s=t.FoldMode=function(e,t){o.call(this,new a(e,t),{"js-":new i,"css-":new i})};r.inherits(s,o)})),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../token_iterator").TokenIterator,o=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"].concat(["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"]),a={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,for:1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{for:1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,default:1},section:{},summary:{},u:{},ul:{},var:{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},i=Object.keys(a);function s(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){for(var n=new r(e,t.row,t.column),o=n.getCurrentToken();o&&!s(o,"tag-name");)o=n.stepBackward();if(o)return o.value}var c=function(){};(function(){this.getCompletions=function(e,t,n,r){var o=t.getTokenAt(n.row,n.column);if(!o)return[];if(s(o,"tag-name")||s(o,"tag-open")||s(o,"end-tag-open"))return this.getTagCompletions(e,t,n,r);if(s(o,"tag-whitespace")||s(o,"attribute-name"))return this.getAttributeCompletions(e,t,n,r);if(s(o,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,r);var a=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(a)?this.getHTMLEntityCompletions(e,t,n,r):[]},this.getTagCompletions=function(e,t,n,r){return i.map((function(e){return{value:e,meta:"tag",score:1e6}}))},this.getAttributeCompletions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in a&&(s=s.concat(Object.keys(a[i]))),s.map((function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}}))},this.getAttributeValueCompletions=function(e,t,n,o){var i=l(t,n),c=function(e,t){for(var n=new r(e,t.row,t.column),o=n.getCurrentToken();o&&!s(o,"attribute-name");)o=n.stepBackward();if(o)return o.value}(t,n);if(!i)return[];var u=[];return i in a&&c in a[i]&&"object"==typeof a[i][c]&&(u=Object.keys(a[i][c])),u.map((function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}}))},this.getHTMLEntityCompletions=function(e,t,n,r){return["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"].map((function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}}))}}).call(c.prototype),t.HtmlCompletions=c})),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("../lib/lang"),a=e("./text").Mode,i=e("./javascript").Mode,s=e("./css").Mode,l=e("./html_highlight_rules").HtmlHighlightRules,c=e("./behaviour/xml").XmlBehaviour,u=e("./folding/html").FoldMode,g=e("./html_completions").HtmlCompletions,d=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],m=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],h=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=l,this.$behaviour=new c,this.$completer=new g,this.createModeDelegates({"js-":i,"css-":s}),this.foldingRules=new u(this.voidElements,o.arrayToMap(m))};r.inherits(h,a),function(){this.blockComment={start:"\x3c!--",end:"--\x3e"},this.voidElements=o.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor==h){var t=new d(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t}},this.$id="ace/mode/html",this.snippetFileId="ace/snippets/html"}.call(h.prototype),t.Mode=h})),ace.define("ace/mode/folding/ruby",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./fold_mode").FoldMode,a=e("../../range").Range,i=e("../../token_iterator").TokenIterator,s=t.FoldMode=function(){};r.inherits(s,o),function(){this.indentKeywords={class:1,def:1,module:1,do:1,unless:1,if:1,while:1,for:1,until:1,begin:1,else:0,elsif:0,rescue:0,ensure:0,when:0,end:-1,case:1,"=begin":1,"=end":-1},this.foldingStartMarker=/(?:\s|^)(def|do|while|class|unless|module|if|for|until|begin|else|elsif|case|rescue|ensure|when)\b|({\s*$)|(=begin)/,this.foldingStopMarker=/(=end(?=$|\s.*$))|(^\s*})|\b(end)\b/,this.getFoldWidget=function(e,t,n){var r,o=e.getLine(n),a=this.foldingStartMarker.test(o),i=this.foldingStopMarker.test(o);if(a&&!i)if((r=o.match(this.foldingStartMarker))[1]){if("if"==r[1]||"else"==r[1]||"while"==r[1]||"until"==r[1]||"unless"==r[1]){if("else"==r[1]&&!1===/^\s*else\s*$/.test(o))return;if(!1===/^\s*(?:if|else|while|until|unless)\s*/.test(o))return}if("when"==r[1]&&!0===/\sthen\s/.test(o))return;if("keyword"===e.getTokenAt(n,r.index+2).type)return"start"}else{if(!r[3])return"start";if("comment.multiline"===e.getTokenAt(n,r.index+1).type)return"start"}if("markbeginend"!=t||!i||a&&i)return"";if("end"===(r=o.match(this.foldingStopMarker))[3]){if("keyword"===e.getTokenAt(n,r.index+1).type)return"end"}else{if(!r[1])return"end";if("comment.multiline"===e.getTokenAt(n,r.index+1).type)return"end"}},this.getFoldWidgetRange=function(e,t,n){var r,o=e.doc.getLine(n);return(r=this.foldingStartMarker.exec(o))?r[1]||r[3]?this.rubyBlock(e,n,r.index+2):this.openingBracketBlock(e,"{",n,r.index):(r=this.foldingStopMarker.exec(o))?"end"===r[3]&&"keyword"===e.getTokenAt(n,r.index+1).type||"=end"===r[1]&&"comment.multiline"===e.getTokenAt(n,r.index+1).type?this.rubyBlock(e,n,r.index+1):this.closingBracketBlock(e,"}",n,r.index+r[0].length):void 0},this.rubyBlock=function(e,t,n,r){var o=new i(e,t,n),s=o.getCurrentToken();if(s&&("keyword"==s.type||"comment.multiline"==s.type)){var l=s.value,c=e.getLine(t);switch(s.value){case"if":case"unless":case"while":case"until":if(!new RegExp("^\\s*"+s.value).test(c))return;var u=this.indentKeywords[l];break;case"when":if(/\sthen\s/.test(c))return;case"elsif":case"rescue":case"ensure":u=1;break;case"else":if(!new RegExp("^\\s*"+s.value+"\\s*$").test(c))return;u=1;break;default:u=this.indentKeywords[l]}var g=[l];if(u){var d=-1===u?e.getLine(t-1).length:e.getLine(t).length,p=t,m=[];if(m.push(o.getCurrentTokenRange()),o.step=-1===u?o.stepBackward:o.stepForward,"comment.multiline"==s.type){for(;s=o.step();)if("comment.multiline"===s.type)if(1==u){if(d=6,"=end"==s.value)break}else if("=begin"==s.value)break}else for(;s=o.step();){var h=!1;if("keyword"===s.type){var f=u*this.indentKeywords[s.value];switch(c=e.getLine(o.getCurrentTokenRow()),s.value){case"do":for(var x=o.$tokenIndex-1;x>=0;x--){var b=o.$rowTokens[x];if(b&&("while"==b.value||"until"==b.value||"for"==b.value)){f=0;break}}break;case"else":new RegExp("^\\s*"+s.value+"\\s*$").test(c)&&"case"!=l||(f=0,h=!0);break;case"if":case"unless":case"while":case"until":new RegExp("^\\s*"+s.value).test(c)||(f=0,h=!0);break;case"when":(/\sthen\s/.test(c)||"case"==l)&&(f=0,h=!0)}if(f>0)g.unshift(s.value);else if(f<=0&&!1===h){if(g.shift(),!g.length){if(("while"==l||"until"==l||"for"==l)&&"do"!=s.value)break;if("do"==s.value&&-1==u&&0!=f)break;if("do"!=s.value)break}0===f&&g.unshift(s.value)}}}if(!s)return null;if(r)return m.push(o.getCurrentTokenRange()),m;if(t=o.getCurrentTokenRow(),-1===u){if("comment.multiline"===s.type)var k=6;else k=e.getLine(t).length;return new a(t,k,p-1,d)}return new a(p,d,t-1,e.getLine(t-1).length)}}}}.call(s.prototype)})),ace.define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/folding/ruby"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./ruby_highlight_rules").RubyHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../range").Range,l=e("./folding/ruby").FoldMode,c=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=this.$defaultBehaviour,this.foldingRules=new l,this.indentKeywords=this.foldingRules.indentKeywords};r.inherits(c,o),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e).tokens;if(o.length&&"comment"==o[o.length-1].type)return r;if("start"==e){var a=t.match(/^.*[\{\(\[]\s*$/),i=t.match(/^\s*(class|def|module)\s.*$/),s=t.match(/.*do(\s*|\s+\|.*\|\s*)$/),l=t.match(/^\s*(if|else|when|elsif|unless|while|for|begin|rescue|ensure)\s*/);(a||i||s||l)&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return/^\s+(end|else|rescue|ensure)$/.test(t+n)||this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){var r=t.getLine(n);if(/}/.test(r))return this.$outdent.autoOutdent(t,n);var o=this.$getIndent(r),a=t.getLine(n-1),i=this.$getIndent(a),l=t.getTabString();i.length<=o.length&&o.slice(-l.length)==l&&t.remove(new s(n,o.length-l.length,n,o.length))},this.getMatching=function(e,t,n){if(null==t){var r=e.selection.lead;n=r.column,t=r.row}var o=e.getTokenAt(t,n);if(o&&o.value in this.indentKeywords)return this.foldingRules.rubyBlock(e,t,n,!0)},this.$id="ace/mode/ruby",this.snippetFileId="ace/snippets/ruby"}.call(c.prototype),t.Mode=c})),ace.define("ace/mode/html_ruby",["require","exports","module","ace/lib/oop","ace/mode/html_ruby_highlight_rules","ace/mode/html","ace/mode/javascript","ace/mode/css","ace/mode/ruby"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./html_ruby_highlight_rules").HtmlRubyHighlightRules,a=e("./html").Mode,i=e("./javascript").Mode,s=e("./css").Mode,l=e("./ruby").Mode,c=function(){a.call(this),this.HighlightRules=o,this.createModeDelegates({"js-":i,"css-":s,"ruby-":l})};r.inherits(c,a),function(){this.$id="ace/mode/html_ruby"}.call(c.prototype),t.Mode=c})),ace.require(["ace/mode/html_ruby"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/dd95c7ba45d24f75fd2ec04726836339.js b/dd95c7ba45d24f75fd2ec04726836339.js new file mode 100644 index 00000000..802803f4 --- /dev/null +++ b/dd95c7ba45d24f75fd2ec04726836339.js @@ -0,0 +1 @@ +ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(e){var t="[_:a-zA-ZÀ-￿][-_:.a-zA-Z0-9À-￿]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"--\x3e",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===a&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(o.prototype),r.inherits(a,o),t.XmlHighlightRules=a})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,r,o){if('"'==o||"'"==o){var s=o,l=r.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var g=n.getCursorPosition(),u=r.doc.getLine(g.row).substring(g.column,g.column+1),c=new a(r,g.row,g.column),d=c.getCurrentToken();if(u==s&&(i(d,"attribute-value")||i(d,"string")))return{text:"",selection:[1,1]};if(d||(d=c.stepBackward()),!d)return;for(;i(d,"tag-whitespace")||i(d,"whitespace");)d=c.stepBackward();var x=!u||u.match(/\s/);if(i(d,"attribute-equals")&&(x||">"==u)||i(d,"decl-attribute-equals")&&(x||"?"==u))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,r,o){var a=r.doc.getTextRange(o);if(!o.isMultiLine()&&('"'==a||"'"==a)&&r.doc.getLine(o.start.row).substring(o.start.column+1,o.start.column+2)==a)return o.end.column++,o})),this.add("autoclosing","insertion",(function(e,t,n,r,o){if(">"==o){var s=n.getSelectionRange().start,l=new a(r,s.row,s.column),g=l.getCurrentToken()||l.stepBackward();if(!g||!(i(g,"tag-name")||i(g,"tag-whitespace")||i(g,"attribute-name")||i(g,"attribute-equals")||i(g,"attribute-value")))return;if(i(g,"reference.attribute-value"))return;if(i(g,"attribute-value")){var u=l.getCurrentTokenColumn()+g.value.length;if(s.column/.test(r.getLine(s.row).slice(s.column)))return;for(;!i(g,"tag-name");)if("<"==(g=l.stepBackward()).value){g=l.stepForward();break}var d=l.getCurrentTokenRow(),x=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var m=g.value;if(d==s.row&&(m=m.substring(0,s.column-x)),this.voidElements&&this.voidElements.hasOwnProperty(m.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,r,o){if("\n"==o){var s=n.getCursorPosition(),l=r.getLine(s.row),g=new a(r,s.row,s.column),u=g.getCurrentToken();if(i(u,"")&&-1!==u.type.indexOf("tag-close")){if("/>"==u.value)return;for(;u&&-1===u.type.indexOf("tag-name");)u=g.stepBackward();if(!u)return;var c=u.value,d=g.getCurrentTokenRow();if(!(u=g.stepBackward())||-1!==u.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[c]||!this.voidElements){var x=r.getTokenAt(s.row,s.column+1),m=(l=r.getLine(d),this.$getIndent(l)),p=m+r.getTabString();return x&&"-1}(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?"markbeginend"===t?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())||this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return r}if(l(a,"tag-close"))return r.selfClosing="/>"==a.value,r;r.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,r){for(var o=e.getTokens(t),a=0,i=0;i/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[o.getStartRule("doc-start"),g("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[g("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(o,"doc-",[o.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r="/"==e.charAt(1)?2:1;return 1==r?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==r&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==r?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,g("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function g(e){return[{token:"comment",regex:/\/\*/,next:[o.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[o.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}r.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var r=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,a=e.findMatchingBracket({row:t,column:o});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new r(t,0,t,o-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/behaviour/javascript",["require","exports","module","ace/lib/oop","ace/token_iterator","ace/mode/behaviour/cstyle","ace/mode/behaviour/xml"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../../token_iterator").TokenIterator,a=e("../behaviour/cstyle").CstyleBehaviour,i=e("../behaviour/xml").XmlBehaviour,s=function(){var e=new i({closeCurlyBraces:!0}).getBehaviours();this.addBehaviours(e),this.inherit(a),this.add("autoclosing-fragment","insertion",(function(e,t,n,r,a){if(">"==a){var i=n.getSelectionRange().start,s=new o(r,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};r.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(i,a),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var o=this._getFoldWidgetBase(e,t,n);return!o&&this.startRegionRe.test(r)?"start":o},this.getFoldWidgetRange=function(e,t,n,r){var o,a=e.getLine(n);if(this.startRegionRe.test(a))return this.getCommentRegionBlock(e,a,n);if(o=a.match(this.foldingStartMarker)){var i=o.index;if(o[1])return this.openingBracketBlock(e,o[1],n,i);var s=e.getCommentFoldRange(n,i+o[0].length,1);return s&&!s.isMultiLine()&&(r?s=this.getSectionRange(e,n):"all"!=t&&(s=null)),s}return"markbegin"!==t&&(o=a.match(this.foldingStopMarker))?(i=o.index+o[0].length,o[1]?this.closingBracketBlock(e,o[1],n,i):e.getCommentFoldRange(n,i,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),r=n.search(/\S/),a=t,i=n.length,s=t+=1,l=e.getLength();++tg)break;var u=this.getFoldWidgetRange(e,"all",t);if(u){if(u.start.row<=a)break;if(u.isMultiLine())t=u.end.row;else if(r==g)break}s=t}}return new o(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var r=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new o(i,r,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new o};r.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,r){return this.getFoldWidgetRangeBase(e,t,n,r)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,g=e("./folding/javascript").FoldMode,u=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new g};r.inherits(u,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e),a=o.tokens,i=o.state;if(a.length&&"comment"==a[a.length-1].type)return r;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(r+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(u.prototype),t.Mode=u})),ace.define("ace/mode/svg_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./javascript_highlight_rules").JavaScriptHighlightRules,a=e("./xml_highlight_rules").XmlHighlightRules,i=function(){a.call(this),this.embedTagRules(o,"js-","script"),this.normalizeRules()};r.inherits(i,a),t.SvgHighlightRules=i})),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./fold_mode").FoldMode,a=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(a,o),function(){this.$getMode=function(e){for(var t in"string"!=typeof e&&(e=e[0]),this.subModes)if(0===e.indexOf(t))return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var o=this.$getMode(e);return o?o.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));return r&&r.getFoldWidget(e,t,n)||(r=this.$getMode(e.getState(n))),r&&r.getFoldWidget(e,t,n)||(r=this.defaultMode),r.getFoldWidgetRange(e,t,n)}}.call(a.prototype)})),ace.define("ace/mode/svg",["require","exports","module","ace/lib/oop","ace/mode/xml","ace/mode/javascript","ace/mode/svg_highlight_rules","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./xml").Mode,a=e("./javascript").Mode,i=e("./svg_highlight_rules").SvgHighlightRules,s=e("./folding/mixed").FoldMode,l=e("./folding/xml").FoldMode,g=e("./folding/cstyle").FoldMode,u=function(){o.call(this),this.HighlightRules=i,this.createModeDelegates({"js-":a}),this.foldingRules=new s(new l,{"js-":new g})};r.inherits(u,o),function(){this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.$id="ace/mode/svg"}.call(u.prototype),t.Mode=u})),ace.require(["ace/mode/svg"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/ddbc961769cd2ff4d4a7a136168ebf4c.js b/ddbc961769cd2ff4d4a7a136168ebf4c.js new file mode 100644 index 00000000..b0bc6f52 --- /dev/null +++ b/ddbc961769cd2ff4d4a7a136168ebf4c.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/soy_template"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/de/index.html b/de/index.html new file mode 100644 index 00000000..d33c5b40 --- /dev/null +++ b/de/index.html @@ -0,0 +1,426 @@ + + + + + + + Strahlenoptik-Simulation - PhyDemo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +

    Strahlenoptik-Simulation

    +

    + Erstellen und simulieren Sie 2D geometrische optische Szenen interaktiv.
    Völlig kostenlos und webbasiert. Der Quellcode ist auf GitHub verfügbar. +

    +

    + Simulator starten +

    +
    +
    + + +
    +
    +
    +

    Werkzeuge

    +
    + Strahl +
    +

    Strahl

    + Ein einzelner Lichtstrahl, der durch zwei Punkte definiert ist. +
    +
    +
    + Bündel +
    +

    Bündel

    + A parallel or divergent beam of rays emerges from a line segment, with density controlled by the 'Ray density' slider. +
    +
    +
    + Punktquelle +
    +

    Punktquelle

    + Strahlen entspringen aus einem einzigen Punkt, wobei die Zahl durch den Schieberegler "Strahl-Anzahldichte" eingestellt wird. +
    +
    +
    + Spiegel +
    +

    Spiegel

    + Simulieren Sie die Reflexion von Licht auf einem Spiegel. +
    +
    +
    + Spiegel (gebogen) +
    +

    Spiegel (gebogen)

    + Ein Spiegel, dessen Form gebogen ist. Es kann kreisförmig, parabolisch oder durch eine benutzerdefinierte Gleichung y = f(x) definiert sein. +
    +
    +
    + Ideal gebogen +
    +

    Ideal gebogen

    + Der idealisierte "gekrümmte" Spiegel, der die Spiegelgleichung (1/p + 1/q = 1/f) erfüllt. Die Brennweite kann direkt eingestellt werden. +
    +
    +
    + Strahlteiler +
    +

    Strahlteiler

    + Ein Spiegel, der einen Teil der Lichtstrahlen durchlässt. +
    +
    +
    + Gläser +
    +

    Gläser

    + Simulieren Sie die Brechung und Reflexion von Licht auf einer Oberfläche. +
    +
    +
    + Gläser (andere Formen) +
    +

    Gläser (andere Formen)

    + Glas mit beliebigen Formen, die aus Segmenten und Kreisbögen bestehen, oder Formen, die durch eine benutzerdefinierte Ungleichung f(x) < y < g(x) definiert sind. +
    +
    +
    + Gradient-index glass +
    +

    Gradient-index glass

    + Material with a custom refractive index function n(x,y). +
    +
    +
    + Ideale Linse +
    +

    Ideale Linse

    + Eine ideale Linse, die die Linsengleichung (1/p + 1/q = 1/f) erfüllt. Die Brennweite kann direkt eingestellt werden. +
    +
    +
    + Absorber +
    +

    Absorber

    + Ein linienförmiger Absorber, der die einfallenden Strahlen absorbiert. +
    +
    +
    + Diffraction Grating +
    +

    Diffraction Grating

    + A diffraction grating that splits light at an angle depending on wavelength. +
    +
    +
    + Lineal +
    +

    Lineal

    + Ein Lineal von einem Nullpunkt bis zu einem anderen Punkt. +
    +
    +
    + Winkelmesser +
    +

    Winkelmesser

    + Ein Winkelmesser, der vom Zentrum und einem anderen Punkt für die Nullrichtung definiert ist. Die Skala ist in Grad. +
    +
    +
    + Detektor +
    +

    Detektor

    + Ein Messwerkzeug für Energieflussrate (P), der Rate des senkrechten Impulsflusses (F∩) und der Rate des parallelen Impulsflusses (F∥) durch ein Segment. Die Einheiten sind willkürlich. +
    +
    +
    +
    +
    +
    +

    Ansicht

    +
    +
    +

    Strahlen

    + In dieser Ansicht werden die Lichtstrahlen angezeigt. Wenn die "Strahl-Anzahldichte" hoch ist, scheinen sie kontinuierlich zu sein. +
    +
    +
    + Strahlen +
    +
    + Strahlen +
    +
    +
    +
    +
    +

    Virtuelle Strahlen

    + In dieser Ansicht werden die Lichtstrahlen als auch ihre Verlängerungen angezeigt. Orange bezeichnet die Rückwärtsverlängerung, während Grau vorwärts deutet. +
    +
    +
    + Virtuelle Strahlen +
    +
    +
    +
    +
    +

    Alle Abbildungen

    + In dieser Ansicht wird die Position aller Bilder angezeigt. Gelb bedeutet echtes Bild, orange steht für virtuelle Bilder und grau (nicht in diesem Bild dargestellt) bedeutet virtuelles Objekt. Beachten Sie, dass einige Bilder nicht erkannt werden können, wenn die "Strahl-Anzahldichte" nicht hoch genug ist. +
    +
    +
    + Alle Abbildungen +
    +
    +
    +
    +
    +

    Beobachterperspektive

    + In dieser Ansicht werden die Strahlen und Bilder von der Beobachterperspektive angezeigt. Der blaue Punkt ist der Beobachter. Alle Strahlen, die ihn kreuzen, gelten als "wird beobachtet". Der Beobachter weiß nicht, wo die Strahlen tatsächlich beginnen, 'denkt' aber, dass sie an einem Punkt beginnen, an dem sie sich schneiden. Die Strahlen sind blau und die Punkte gelb (real) oder orange (virtuell) dargestellt. +
    +
    +
    + Beobachterperspektive +
    +
    +
    +
    +
    +

    Farben simulieren

    + Simulate colors (wavelengths) of light sources, mixture of colors, color filtering of blockers and mirrors, and chromatic dispersion of glasses. +
    +
    +
    + Farben simulieren +
    +
    +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/de0fd4fd7c2d7a4887cbc99eed91f797.js b/de0fd4fd7c2d7a4887cbc99eed91f797.js new file mode 100644 index 00000000..9c4b43e4 --- /dev/null +++ b/de0fd4fd7c2d7a4887cbc99eed91f797.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/lucene"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/de73b4d2a9ed4bcb851f9141e303636d.js b/de73b4d2a9ed4bcb851f9141e303636d.js new file mode 100644 index 00000000..77b701fd --- /dev/null +++ b/de73b4d2a9ed4bcb851f9141e303636d.js @@ -0,0 +1 @@ +ace.define("ace/mode/lucene_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,r){"use strict";var n=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:"constant.language.escape",regex:/\\[\-+&|!(){}\[\]^"~*?:\\]/},{token:"constant.character.negation",regex:"\\-"},{token:"constant.character.interro",regex:"\\?"},{token:"constant.character.required",regex:"\\+"},{token:"constant.character.asterisk",regex:"\\*"},{token:"constant.character.proximity",regex:"~(?:0\\.[0-9]+|[0-9]+)?"},{token:"keyword.operator",regex:"(AND|OR|NOT|TO)\\b"},{token:"paren.lparen",regex:"[\\(\\{\\[]"},{token:"paren.rparen",regex:"[\\)\\}\\]]"},{token:"keyword.operator",regex:/[><=^]/},{token:"constant.numeric",regex:/\d[\d.-]*/},{token:"string",regex:/"(?:\\"|[^"])*"/},{token:"keyword",regex:/(?:\\.|[^\s\-+&|!(){}\[\]^"~*?:\\])+:/,next:"maybeRegex"},{token:"term",regex:/\w+/},{token:"text",regex:/\s+/}],maybeRegex:[{token:"text",regex:/\s+/},{token:"string.regexp.start",regex:"/",next:"regex"},{regex:"",next:"start"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp.end",regex:"/[sxngimy]*",next:"start"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.escape",regex:"|[~&@]"},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"start"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"start"},{defaultToken:"string.regexp.characterclass"}]}};n.inherits(a,o),t.LuceneHighlightRules=a})),ace.define("ace/mode/lucene",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/lucene_highlight_rules"],(function(e,t,r){"use strict";var n=e("../lib/oop"),o=e("./text").Mode,a=e("./lucene_highlight_rules").LuceneHighlightRules,g=function(){this.HighlightRules=a,this.$behaviour=this.$defaultBehaviour};n.inherits(g,o),function(){this.$id="ace/mode/lucene"}.call(g.prototype),t.Mode=g})),ace.require(["ace/mode/lucene"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/docs/BaseFilter.html b/docs/BaseFilter.html new file mode 100644 index 00000000..968f8098 --- /dev/null +++ b/docs/BaseFilter.html @@ -0,0 +1,3873 @@ + + + + + JSDoc: Class: BaseFilter + + + + + + + + + + +
    + +

    Class: BaseFilter

    + + + + + + +
    + +
    + +

    BaseFilter()

    + +

    The base class for optical elements with wavelength filter functionality, including mirrors (which have the dichroic feature) and blockers.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new BaseFilter()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    filter + + +boolean + + + +

    Whether the filter feature is enabled.

    invert + + +boolean + + + +

    If true, the element interacts with the ray only if its wavelength is outside the bandwidth of the filter. If false, the element interacts with the ray only if its wavelength is within the bandwidth of the filter.

    wavelength + + +number + + + +

    The target wavelength of the filter. The unit is nm.

    bandwidth + + +number + + + +

    The bandwidth of the filter. The unit is nm.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/BaseGlass.html b/docs/BaseGlass.html new file mode 100644 index 00000000..fb8ff3ca --- /dev/null +++ b/docs/BaseGlass.html @@ -0,0 +1,4765 @@ + + + + + JSDoc: Class: BaseGlass + + + + + + + + + + +
    + +

    Class: BaseGlass

    + + + + + + +
    + +
    + +

    BaseGlass()

    + +

    The base class for glasses.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new BaseGlass()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    refIndex + + +number + + + +

    The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.

    cauchyB + + +number + + + +

    The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    fillGlass(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Fill the glass with the color that represents the refractive index. To be called in draw of a subclass when the path has been set up with canvasRenderer.ctx.beginPath(), etc.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getIncidentType(ray) → {number}

    + + + + + + +
    +

    Get whether the ray is incident from inside to outside or from outside to inside.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getRefIndexAt(point, ray) → {number}

    + + + + + + +
    +

    Get the refractive index at a point for a ray

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.

    ray + + +Ray + + + +

    The ray to be refracted.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The refractive index at the point.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayEnter(ray)

    + + + + + + +
    +

    Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that enters the glass.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayExit(ray)

    + + + + + + +
    +

    Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that exits the glass.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) → {SimulationReturn}

    + + + + + + +
    +

    Do the refraction calculation at the surface of the glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be refracted.

    rayIndex + + +number + + + +

    The index of the ray in the ray array.

    incidentPoint + + +Point + + + +

    The incident point.

    normal + + +Point + + + +

    The normal vector at the incident point.

    n1 + + +number + + + +

    The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are to be merged with the current object.

    bodyMergingObj + + +BaseGrinGlass + + + +

    The object that is to be merged with the current object.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value for onRayIncident.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn + + +
    +
    + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/BaseGrinGlass.html b/docs/BaseGrinGlass.html new file mode 100644 index 00000000..6f4ae00e --- /dev/null +++ b/docs/BaseGrinGlass.html @@ -0,0 +1,6329 @@ + + + + + JSDoc: Class: BaseGrinGlass + + + + + + + + + + +
    + +

    Class: BaseGrinGlass

    + + + + + + +
    + +
    + +

    BaseGrinGlass()

    + +

    The base class for glasses.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new BaseGrinGlass()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p + + +string + + + +

    The refractive index function (a function of x and y, related to origin) of the glass in math.js string.

    refIndexFn + + +string + + + +

    The refractive index function of the glass in LaTeX.

    p_der_x + + +string + + + +

    The x derivative of p in math.js string.

    p_der_x_tex + + +string + + + +

    The x derivative of p in LaTeX.

    p_der_y + + +string + + + +

    The y derivative of p in math.js string.

    p_der_y_tex + + +string + + + +

    The y derivative of p in LaTeX.

    origin + + +Point + + + +

    The origin of (x,y) used in the above equationns.

    fn_p + + +function + + + +

    The evaluatex function for p, where (x,y) has been shifted to the absolute coordinates.

    fn_p_der_x + + +function + + + +

    The evaluatex function for p_der_x, where (x,y) has been shifted to the absolute coordinates.

    fn_p_der_y + + +function + + + +

    The evaluatex function for p_der_y, where (x,y) has been shifted to the absolute coordinates.

    stepSize + + +number + + + +

    The step size for the ray trajectory equation.

    intersectTol + + +number + + + +

    The epsilon for the intersection calculations.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    devRefIndex(bodyMergingObj) → {BodyMergingObj}

    + + + + + + +
    +

    Receives a bodyMerging object and returns a new bodyMerging object for the region of bodyMergingObj excluding current GRIN glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    bodyMergingObj + + +BodyMergingObj + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +BodyMergingObj + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    fillGlass(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Fill the glass with the color that represents the refractive index. To be called in draw of a subclass when the path has been set up with canvasRenderer.ctx.beginPath(), etc.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getIncidentType(ray) → {number}

    + + + + + + +
    +

    Get whether the ray is incident from inside to outside or from outside to inside.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getRefIndexAt(point, ray) → {number}

    + + + + + + +
    +

    Get the refractive index at a point for a ray

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.

    ray + + +Ray + + + +

    The ray to be refracted.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The refractive index at the point.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    initFns()

    + + + + + + +
    +

    Do the partial derivatives of the refractive index function and parse the functions.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    initRefIndex(ray) → {BodyMergingObj}

    + + + + + + +
    +

    Receives a ray, and returns a bodyMerging object for the point ray.p1

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +BodyMergingObj + + +
    +
    + + + + + + + + + + + + + +

    isInsideGlass(point)

    + + + + + + +
    +

    Returns true if point is inside the glass, otherwise returns false

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    isOnBoundary(point)

    + + + + + + +
    +

    Returns true if point is on the boundary of the glass, otherwise returns false

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    isOutsideGlass(point)

    + + + + + + +
    +

    Returns true if point is outside the glass, otherwise returns false

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    multRefIndex(bodyMergingObj) → {BodyMergingObj}

    + + + + + + +
    +

    Receives a bodyMerging object and returns a new bodyMerging object for the overlapping region of bodyMergingObj and the current GRIN glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    bodyMergingObj + + +BodyMergingObj + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +BodyMergingObj + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayEnter(ray)

    + + + + + + +
    +

    Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that enters the glass.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayExit(ray)

    + + + + + + +
    +

    Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that exits the glass.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) → {SimulationReturn}

    + + + + + + +
    +

    Do the refraction calculation at the surface of the glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be refracted.

    rayIndex + + +number + + + +

    The index of the ray in the ray array.

    incidentPoint + + +Point + + + +

    The incident point.

    normal + + +Point + + + +

    The normal vector at the incident point.

    n1 + + +number + + + +

    The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are to be merged with the current object.

    bodyMergingObj + + +BaseGrinGlass + + + +

    The object that is to be merged with the current object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value for onRayIncident.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn + + +
    +
    + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +

    shiftOrigin(equation) → {string}

    + + + + + + +
    +

    Shifts the x and y variables in equation from related to this.origin to the absolute coordinates.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    equation + + +string + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +string + + +
    +
    + + + + + + + + + + + + + +

    step(p1, p2, ray)

    + + + + + + +
    +

    Receives two points inside this lens, and returns the next point to where the ray, connecting these two points, will travel, based on the ray trajectory equation (equation 11.1 in the cited text below) +Using Euler's method to solve the ray trajectory equation (based on sections 11.1 and 11.2, in the following text: https://doi.org/10.1007/BFb0012092) +x_der_s and x_der_s_prev are the x-coordinate derivatives with respect to the arc-length parameterization, at two different points (similarly for y_der_s and y_der_s_prev)

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    ray + + +Ray + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/BaseSceneObj.html b/docs/BaseSceneObj.html new file mode 100644 index 00000000..62b4de46 --- /dev/null +++ b/docs/BaseSceneObj.html @@ -0,0 +1,3535 @@ + + + + + JSDoc: Class: BaseSceneObj + + + + + + + + + + +
    + +

    Class: BaseSceneObj

    + + + + + + +
    + +
    + +

    BaseSceneObj(scene, jsonObj)

    + +

    Base class for objects (optical elements, decorations, etc.) in the scene.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new BaseSceneObj(scene, jsonObj)

    + + + + + + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    jsonObj + + +Object +| + +null + + + +

    The JSON object to be deserialized, if any.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/CanvasRenderer.html b/docs/CanvasRenderer.html new file mode 100644 index 00000000..9fd7257d --- /dev/null +++ b/docs/CanvasRenderer.html @@ -0,0 +1,1911 @@ + + + + + JSDoc: Class: CanvasRenderer + + + + + + + + + + +
    + +

    Class: CanvasRenderer

    + + + + + + +
    + +
    + +

    CanvasRenderer()

    + +

    A class to render geometric figures from geometry.js on a canvas, and to handle the transformation and background image of the canvas.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new CanvasRenderer()

    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + +

    Members

    + + + +

    backgroundImage

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    backgroundImage + + +Object +| + +null + + + +

    The background image of the scene, null if not set.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    canvas

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvas + + +Object + + + +

    The canvas of the scene.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    ctx

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ctx + + +Object + + + +

    The context of the canvas.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isSVG

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    isSVG + + +boolean + + + +

    Whether the canvas is being exported to SVG.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    lengthScale

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    lengthScale + + +number + + + +

    The scale factor of the length units of the scene.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    origin

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    origin + + +Object + + + +

    The origin of the scene in the viewport.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scale

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scale + + +number + + + +

    The scale factor (the viewport physical pixel per internal length unit) of the scene.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    drawCircle(c, coloropt)

    + + + + + + +
    +

    Draw a circle.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    c + + +Circle + + + + + + + + + + + +
    color + + +String + + + + + + <optional>
    + + + + + +
    + + 'black' + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    drawLine(l, coloropt)

    + + + + + + +
    +

    Draw a line.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    l + + +Line + + + + + + + + + + + +
    color + + +String + + + + + + <optional>
    + + + + + +
    + + 'black' + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    drawPoint(p, coloropt)

    + + + + + + +
    +

    Draw a point.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    p + + +Point + + + + + + + + + + + +
    color + + +String + + + + + + <optional>
    + + + + + +
    + + 'black' + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    drawRay(r, coloropt)

    + + + + + + +
    +

    Draw a ray.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    r + + +Line + + + + + + + + + + + +
    color + + +String + + + + + + <optional>
    + + + + + +
    + + 'black' + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    drawSegment(s, coloropt)

    + + + + + + +
    +

    Draw a segment.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    s + + +Line + + + + + + + + + + + +
    color + + +String + + + + + + <optional>
    + + + + + +
    + + 'black' + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/CanvasRenderer.js.html b/docs/CanvasRenderer.js.html new file mode 100644 index 00000000..dc3d3450 --- /dev/null +++ b/docs/CanvasRenderer.js.html @@ -0,0 +1,175 @@ + + + + + JSDoc: Source: CanvasRenderer.js + + + + + + + + + + +
    + +

    Source: CanvasRenderer.js

    + + + + + + +
    +
    +
    import * as C2S from 'canvas2svg';
    +
    +/**
    + * A class to render geometric figures from geometry.js on a canvas, and to handle the transformation and background image of the canvas.
    + * @class
    + */
    +class CanvasRenderer {
    +  constructor(ctx, origin, scale, lengthScale, backgroundImage) {
    +
    +    /** @property {Object} ctx - The context of the canvas. */
    +    this.ctx = ctx;
    +
    +    /** @property {Object} origin - The origin of the scene in the viewport. */
    +    this.origin = origin;
    +
    +    /** @property {number} scale - The scale factor (the viewport physical pixel per internal length unit) of the scene. */
    +    this.scale = scale;
    +
    +    /** @property {number} lengthScale - The scale factor of the length units of the scene. */
    +    this.lengthScale = lengthScale;
    +
    +    /** @property {Object} canvas - The canvas of the scene. */
    +    this.canvas = ctx.canvas;
    +
    +    /** @property {Object|null} backgroundImage - The background image of the scene, null if not set. */
    +    this.backgroundImage = backgroundImage;
    +
    +    if (typeof C2S !== 'undefined' && ctx.constructor === C2S) {
    +      /** @property {boolean} isSVG - Whether the canvas is being exported to SVG. */
    +      this.isSVG = true;
    +    }
    +
    +    // Initialize the canvas
    +    if (!this.isSVG) {
    +      // only do this when not being exported to SVG to avoid bug
    +      this.ctx.setTransform(1, 0, 0, 1, 0, 0);
    +      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    +      this.ctx.setTransform(this.scale, 0, 0, this.scale, this.origin.x, this.origin.y);
    +      if (this.ctx.constructor !== C2S && this.backgroundImage) {
    +        this.ctx.globalAlpha = 1;
    +        this.ctx.drawImage(this.backgroundImage, 0, 0);
    +      }
    +    }
    +  }
    +
    +  /**
    +   * Draw a point.
    +   * @param {Point} p
    +   * @param {String} [color='black']
    +   */
    +  drawPoint(p, color = 'black') {
    +    this.ctx.fillStyle = color;
    +    this.ctx.fillRect(p.x - 2.5 * this.lengthScale, p.y - 2.5 * this.lengthScale, 5 * this.lengthScale, 5 * this.lengthScale);
    +  }
    +
    +  /**
    +   * Draw a line.
    +   * @param {Line} l
    +   * @param {String} [color='black']
    +   */
    +  drawLine(l, color = 'black') {
    +    this.ctx.strokeStyle = color;
    +    this.ctx.lineWidth = 1 * this.lengthScale;
    +    this.ctx.beginPath();
    +    let ang1 = Math.atan2((l.p2.x - l.p1.x), (l.p2.y - l.p1.y));
    +    let cvsLimit = (Math.abs(l.p1.x + this.origin.x) + Math.abs(l.p1.y + this.origin.y) + this.canvas.height + this.canvas.width) / Math.min(1, this.scale);
    +    this.ctx.moveTo(l.p1.x - Math.sin(ang1) * cvsLimit, l.p1.y - Math.cos(ang1) * cvsLimit);
    +    this.ctx.lineTo(l.p1.x + Math.sin(ang1) * cvsLimit, l.p1.y + Math.cos(ang1) * cvsLimit);
    +    this.ctx.stroke();
    +  }
    +
    +  /**
    +   * Draw a ray.
    +   * @param {Line} r
    +   * @param {String} [color='black']
    +   */
    +  drawRay(r, color = 'black') {
    +    this.ctx.strokeStyle = color;
    +    this.ctx.lineWidth = 1 * this.lengthScale;
    +    let ang1, cvsLimit;
    +    if (Math.abs(r.p2.x - r.p1.x) > 1e-5 * this.lengthScale || Math.abs(r.p2.y - r.p1.y) > 1e-5 * this.lengthScale) {
    +      this.ctx.beginPath();
    +      ang1 = Math.atan2((r.p2.x - r.p1.x), (r.p2.y - r.p1.y));
    +      cvsLimit = (Math.abs(r.p1.x + this.origin.x) + Math.abs(r.p1.y + this.origin.y) + this.canvas.height + this.canvas.width) / Math.min(1, this.scale);
    +      this.ctx.moveTo(r.p1.x, r.p1.y);
    +      this.ctx.lineTo(r.p1.x + Math.sin(ang1) * cvsLimit, r.p1.y + Math.cos(ang1) * cvsLimit);
    +      this.ctx.stroke();
    +    }
    +  }
    +
    +  /**
    +   * Draw a segment.
    +   * @param {Line} s
    +   * @param {String} [color='black']
    +   */
    +  drawSegment(s, color = 'black') {
    +    this.ctx.strokeStyle = color;
    +    this.ctx.lineWidth = 1 * this.lengthScale;
    +    this.ctx.beginPath();
    +    this.ctx.moveTo(s.p1.x, s.p1.y);
    +    this.ctx.lineTo(s.p2.x, s.p2.y);
    +    this.ctx.stroke();
    +  }
    +
    +  /**
    +   * Draw a circle.
    +   * @param {Circle} c
    +   * @param {String} [color='black']
    +   */
    +  drawCircle(c, color = 'black') {
    +    this.ctx.strokeStyle = color;
    +    this.ctx.lineWidth = 1 * this.lengthScale;
    +    this.ctx.beginPath();
    +    if (typeof c.r === 'object') {
    +      let dx = c.r.p1.x - c.r.p2.x;
    +      let dy = c.r.p1.y - c.r.p2.y;
    +      this.ctx.arc(c.c.x, c.c.y, Math.sqrt(dx * dx + dy * dy), 0, Math.PI * 2, false);
    +    } else {
    +      this.ctx.arc(c.c.x, c.c.y, c.r, 0, Math.PI * 2, false);
    +    }
    +    this.ctx.stroke();
    +  }
    +}
    +
    +export default CanvasRenderer;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/Editor.html b/docs/Editor.html new file mode 100644 index 00000000..840c926e --- /dev/null +++ b/docs/Editor.html @@ -0,0 +1,8035 @@ + + + + + JSDoc: Class: Editor + + + + + + + + + + +
    + +

    Class: Editor

    + + + + + + +
    + +
    + +

    Editor(scene, canvas, simulator)

    + +

    The visual scene editor that edits the scene represented by the Scene class. This class is responsible for handling user interactions with the canvas, such as dragging objects, selecting objects, and adding objects. It also manages the undo and redo operations (by serializing/deserializing the scene to/from JSON) and the crop mode. Rendering is not done by this class, but by the Simulator class. Also, the UI update (e.g. object bar) is not done by this class. When UI update is needed, this class emits events to notify the UI to update.

    +

    When constructing or editing an object in the scene, the object itself is responsible for handling the mouse events, and the editor only passes the events to the object (including checking whether the mouse is interacting with the object). See the mouse-related methods in the BaseSceneObj class for more information. The options in the object bar when the object is selected is also managed by the populateObjBar method of the object itself (and not the editor).

    +

    In the Ray Optics Simulator web app, a single instance of this class is used to manage the scene and the canvas. Although several canvas layers are used, this class only manages the top-layered canvas where mouse or touch events are captured. +The newAction event is emitted when a new action is done by the user, and is used to create a new undo point. +When the Ace editor is enabled, it has its own undo and redo operations, and is not always in sync with the undo and redo operations of this class.

    +

    This class is not intended to be used in a Node.js environment, but can be used by other web apps to create standalone interactive optical simulations without the main UI of the Ray Optics Simulator web app.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Editor(scene, canvas, simulator)

    + + + + + + +
    +

    Create a new Editor instance.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene to be edited and simulated.

    canvas + + +HTMLCanvasElement + + + +

    The top-layered canvas for user interaction.

    simulator + + +Simulator + + + +

    The simulator.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + +

    Members

    + + + +

    UNDO_INTERVAL

    + + + + +
    +

    The minimal interval between two undo points.

    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    UNDO_LIMIT

    + + + + +
    +

    The limit of the undo data.

    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    addingModuleName

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    addingModuleName + + +string + + + +

    The name of the module that will be added when the user clicks on the canvas if addingObjType is 'ModuleObj'.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    addingObjType

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    addingObjType + + +string + + + +

    The type of the object that will be added when the user clicks on the canvas. Empty if 'Move view' tool is selected so that no object will be added.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    canvas

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvas + + +HTMLCanvasElement + + + +

    The top-layered canvas for user interaction.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    delayedValidationTimerId

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    delayedValidationTimerId + + +number + + + +

    The ID of the timer for performing a delayed validation.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    dragContext

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    dragContext + + +DragContext + + + +

    The context of the dragging or positioning action.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    draggingObjIndex

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    draggingObjIndex + + +number + + + +

    The index of the object being dragged. -1 if no object is being dragged; -3 if the scene is being dragged; -4 if the observer is being dragged.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    eventListeners

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    eventListeners + + +object + + + +

    The event listeners of the editor.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    hoveredObjIndex

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    hoveredObjIndex + + +number + + + +

    The index of the hovered object. -1 if no object is hovered.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isConstructing

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    isConstructing + + +boolean + + + +

    Whether an object is being constructed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isInCropMode

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    isInCropMode + + +boolean + + + +

    Whether the editor is in the crop mode.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    lastActionJson

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    lastActionJson + + +string + + + +

    The JSON string representing the scene when the last undo data is pushed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    lastActionTime

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    lastActionTime + + +Date + + + +

    The time when the last undo data is pushed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    lastDeviceIsTouch

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    lastDeviceIsTouch + + +boolean + + + +

    Whether the last interaction with canvas is done by a touch device.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    lastMousePos

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    lastMousePos + + +Point + + + +

    The position of the mouse in the scene when the last mousedown event is triggered.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    mousePos

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mousePos + + +Point + + + +

    The position of the mouse in the scene.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    pendingControlPointSelection

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pendingControlPointSelection + + +boolean + + + +

    Whether a user has clicked on a control point with the Ctrl key held down, and the editor is waiting to see if the user is going to select the control point for a handle.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    pendingControlPoints

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pendingControlPoints + + +Array.<ControlPoint> + + + +

    The control points to be selected for a handle when the user clicks on a control point with the Ctrl key held down.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    positioningObjIndex

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    positioningObjIndex + + +number + + + +

    The index of the object being positioned. -1 if no object is being positioned; -4 if the observer is being positioned.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene to be edited and simulated.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    selectedObjIndex

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    selectedObjIndex + + +number + + + +

    The index of the selected object. -1 if no object is selected.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    simulator

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    simulator + + +Simulator + + + +

    The simulator.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    undoData

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    undoData + + +Array.<string> + + + +

    The data for undoing, where each element is a JSON string representing the scene.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    undoIndex

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    undoIndex + + +number + + + +

    The index of the undo data currently displayed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    undoLBound

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    undoLBound + + +number + + + +

    The upper bound of the undo data index.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    undoUBound

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    undoUBound + + +number + + + +

    The lower bound of the undo data index.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    addControlPointsForHandle(controlPoints)

    + + + + + + +
    +

    Add control points for a handle (create a new handle or add to the currently consturcting handle).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    controlPoints + + +Array.<ControlPoint> + + + +

    The control points to add.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    cancelCrop()

    + + + + + + +
    +

    Exit the crop mode without exporting the cropped scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    confirmCrop(cropBox)

    + + + + + + +
    +

    Confirm the crop box and export the cropped scene.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    cropBox + + +CropBox + + + +

    The crop box.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    confirmPositioning(x, y, ctrl, shift)

    + + + + + + +
    +

    Confirm the positioning in the coordinate box.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +number + + + +

    The x-coordinate.

    y + + +number + + + +

    The y-coordinate.

    ctrl + + +boolean + + + +

    Whether the Ctrl key is pressed.

    shift + + +boolean + + + +

    Whether the Shift key is pressed.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    emit(eventName, data)

    + + + + + + +
    +

    Emit an event.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    eventName + + +string + + + +

    The name of the event.

    data + + +any + + + +

    The data to be passed to the callback functions.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    endPositioning()

    + + + + + + +
    +

    End the positioning in the coordinate box.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    enterCropMode()

    + + + + + + +
    +

    Enter the crop mode that allows the user to crop the scene for exporting.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    exportImage(cropBox)

    + + + + + + +
    +

    Export the cropped scene as a PNG image.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    cropBox + + +CropBox + + + +

    The crop box.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    exportSVG(cropBox)

    + + + + + + +
    +

    Export the cropped scene as an SVG file.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    cropBox + + +CropBox + + + +

    The crop box.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    finishHandleCreation(point)

    + + + + + + +
    +

    Finish the creation of a handle.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point for the position of the handle.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    initCanvas()

    + + + + + + +
    +

    Initialize the canvas event listeners.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    loadJSON(json)

    + + + + + + +
    +

    Load a JSON string of the scene to the editor.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    json + + +string + + + +

    The JSON string of the scene.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    on(eventName, callback)

    + + + + + + +
    +

    Add an event listener to the editor.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    eventName + + +string + + + +

    The name of the event.

    callback + + +function + + + +

    The callback function.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onActionComplete()

    + + + + + + +
    +

    Called when a change (action) is completed. This function will update the undo data, sync the JSON editor, etc.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onCanvasDblClick(e)

    + + + + + + +
    +

    Handle the equivalent of the dblclick event on the canvas.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    e + + +MouseEvent + + + +

    The event.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onCanvasMouseDown(e)

    + + + + + + +
    +

    Handle the equivalent of the mousedown event on the canvas, which can be triggered by both mouse and single touch.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    e + + +MouseEvent + + + +

    The event.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onCanvasMouseMove(e)

    + + + + + + +
    +

    Handle the equivalent of the mousemove event on the canvas, which can be triggered by both mouse and single touch.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    e + + +MouseEvent + + + +

    The event.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onCanvasMouseUp(e)

    + + + + + + +
    +

    Handle the equivalent of the mouseup event on the canvas, which can be triggered by both mouse and single touch.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    e + + +MouseEvent + + + +

    The event.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    redo()

    + + + + + + +
    +

    Redo the last edit.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    removeObj(index)

    + + + + + + +
    +

    Remove an object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    index + + +number + + + +

    The index of the object to remove.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    requireDelayedValidation()

    + + + + + + +
    +

    Require a delayed validation of the scene. The actual validation will be performed if the user is inactive for a while.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    selectObj(index)

    + + + + + + +
    +

    Select an object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    index + + +number + + + +

    The index of the object to select.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    selectionSearch(mousePos_nogrid) → {Array.<SelectionSearchResult>}

    + + + + + + +
    +

    search for best object to select at mouse position

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mousePos_nogrid + + +Point + + + +

    The mouse position in the scene (without snapping to grid).

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The search results.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Array.<SelectionSearchResult> + + +
    +
    + + + + + + + + + + + + + +

    setScale(value)

    + + + + + + +
    +

    Set the scale of the scene with respect to the center point of the canvas.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    value + + +number + + + +

    The new scale.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    setScaleWithCenter(value, centerX, centerY)

    + + + + + + +
    +

    Set the scale of the scene while keeping a given center point fixed.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    value + + +number + + + +

    The new scale factor.

    centerX + + +number + + + +

    The x-coordinate of the center point.

    centerY + + +number + + + +

    The y-coordinate of the center point.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    undo()

    + + + + + + +
    +

    Undo the last edit.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    validateDelayed()

    + + + + + + +
    +

    Perform the delayed validation of the scene. Called after the user has been inactive for a while.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Events

    + + + + + + + +

    mouseCoordinateChange

    + + + + + + +
    +

    The event when the mouse coordinate changes. This is different from the actual mousemove, since the grid snapping is considered, and the coordnates can also be updated by other events such as zooming.

    +
    + + + + + +
    Type:
    +
      +
    • + +object + + +
    • +
    + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mousePos + + +Point + + + +

    The position of the mouse in the scene. Null if the mouse is out of the canvas.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    newAction

    + + + + + + +
    +

    The event when a new action is done and the UI (e.g. code editor) should be updated.

    +
    + + + + + +
    Type:
    +
      +
    • + +object + + +
    • +
    + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    oldJSON + + +string + + + +

    The JSON string representing the scene before the action.

    newJSON + + +string + + + +

    The JSON string representing the scene after the action.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    newUndoPoint

    + + + + + + +
    +

    The event when a new undo data is pushed.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    positioningEnd

    + + + + + + +
    +

    The event when the positioning of an object ends (either confirmed or canceled).

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    positioningStart

    + + + + + + +
    +

    The event when the positioning of an object starts.

    +
    + + + + + +
    Type:
    +
      +
    • + +object + + +
    • +
    + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    dragContext + + +DragContext + + + +

    The context of the positioning action, which is the same as the drag context if the user instead drags the control point to be positioned.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    redo

    + + + + + + +
    +

    The event when the user redo an action.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    requestPositioningComfirm

    + + + + + + +
    +

    The event when the user interacts with the canvas during the positioning of an object, so that the new coordinates are assumed to be confirmed.

    +
    + + + + + +
    Type:
    +
      +
    • + +object + + +
    • +
    + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ctrl + + +boolean + + + +

    Whether the Ctrl key is held down.

    shift + + +boolean + + + +

    Whether the Shift key is held down.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    scaleChange

    + + + + + + +
    +

    The event when the scale of the scene is changed.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    sceneLoaded

    + + + + + + +
    +

    The event when the scene is loaded. If the scene contains resources that takes time to load, this event is emitted every time a resource is loaded, where the last event has the completed property set to true.

    +
    + + + + + +
    Type:
    +
      +
    • + +object + + +
    • +
    + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    needFullUpdate + + +boolean + + + +

    Whether the UI needs a full update.

    completed + + +boolean + + + +

    Whether the loading is completed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    selectionChange

    + + + + + + +
    +

    The event when the selection changes. This may also be triggered if the same object is selected again.

    +
    + + + + + +
    Type:
    +
      +
    • + +object + + +
    • +
    + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    oldIndex + + +number + + + +

    The index of the previously selected object.

    newIndex + + +number + + + +

    The index of the newly selected object.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    undo

    + + + + + + +
    +

    The event when the user undo an action.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/Editor.js.html b/docs/Editor.js.html new file mode 100644 index 00000000..bbecb27c --- /dev/null +++ b/docs/Editor.js.html @@ -0,0 +1,1291 @@ + + + + + JSDoc: Source: Editor.js + + + + + + + + + + +
    + +

    Source: Editor.js

    + + + + + + +
    +
    +
    /**
    + * @file {@link Editor} is the main class for visually editing the {@link Scene} data. It manages the user interactions with the canvas, such as dragging objects, selecting objects, and adding objects. It also manages the undo and redo operations and the crop mode.
    + */
    +
    +import geometry from './geometry.js';
    +import * as sceneObjs from './sceneObjs.js';
    +import Mouse from './Mouse.js';
    +import * as C2S from 'canvas2svg';
    +import { saveAs } from 'file-saver';
    +import Scene from './Scene.js';
    +import Simulator from './Simulator.js';
    +
    +/**
    + * @typedef {Object} DragContext
    + * @property {number} part - The index of the part within the object being dragged. 0 for the whole object.
    + * @property {Point} [targetPoint] - The target point where the user is dragging. This is recognized by the editor so that it can be used for popping up the coordinate box (when the user double-clicks or right-clicks such a point), or binding to a handle (when the user holds Ctrl and clicks such a point).
    + * @property {Point} [targetPoint_] - If this property is set instead of setting `targetPoint`, then the point will not be used for the coordinate box or handle, but is still recognized by the editor when deciding which part of which object the user want to interact with.
    + * @property {boolean} [requiresObjBarUpdate] - Whether the object bar should be updated during the dragging.
    + * @property {string} [cursor] - The cursor to be used during hovering and dragging.
    + * @property {SnapContext} [snapContext] - The snap context.
    + * @property {boolean} [hasDuplicated] - Whether the object is duplicated during the dragging. This is true when the user holds the Ctrl key and drags the whole object. Only set by the editor.
    + * @property {BaseSceneObj} [originalObj] - The original object when the dragging starts. Only set by the editor.
    + * @property {boolean} [isByHandle] - Whether the dragging is initiated by dragging a handle. Only set by the editor.
    + */
    +
    +/**
    + * @typedef {Object} SelectionSearchResult
    + * @property {DragContext} dragContext - The drag context.
    + * @property {number} targetObjIndex - The index of the target object.
    + */
    +
    +/**
    + * @typedef {Object} ControlPoint
    + * @property {DragContext} dragContext - The drag context of the virtual mouse that is dragging the control point.
    + * @property {Point} newPoint - The new position of the control point.
    + */
    +
    +/**
    + * @typedef {Object} SnapContext
    + * @property {boolean} [locked] - Whether the snapping direction is locked.
    + * @property {number} [i0] - The index of the locked direction.
    + */
    +
    +/**
    + * The visual scene editor that edits the scene represented by the {@link Scene} class. This class is responsible for handling user interactions with the canvas, such as dragging objects, selecting objects, and adding objects. It also manages the undo and redo operations (by serializing/deserializing the scene to/from JSON) and the crop mode. Rendering is not done by this class, but by the {@link Simulator} class. Also, the UI update (e.g. object bar) is not done by this class. When UI update is needed, this class emits events to notify the UI to update.
    + * 
    + * When constructing or editing an object in the scene, the object itself is responsible for handling the mouse events, and the editor only passes the events to the object (including checking whether the mouse is interacting with the object). See the mouse-related methods in the {@link BaseSceneObj} class for more information. The options in the object bar when the object is selected is also managed by the `populateObjBar` method of the object itself (and not the editor).
    + * 
    + * In the Ray Optics Simulator web app, a single instance of this class is used to manage the scene and the canvas. Although several canvas layers are used, this class only manages the top-layered canvas where mouse or touch events are captured. 
    + * The `newAction` event is emitted when a new action is done by the user, and is used to create a new undo point.
    + * When the Ace editor is enabled, it has its own undo and redo operations, and is not always in sync with the undo and redo operations of this class.
    + * 
    + * This class is not intended to be used in a Node.js environment, but can be used by other web apps to create standalone interactive optical simulations without the main UI of the Ray Optics Simulator web app.
    + * @class
    + */
    +class Editor {
    +
    +  /**
    +   * The limit of the undo data.
    +   */
    +  static UNDO_LIMIT = 50;
    +
    +  /**
    +   * The minimal interval between two undo points.
    +   */
    +  static UNDO_INTERVAL = 250;
    +
    +  /**
    +   * Create a new Editor instance.
    +   * @param {Scene} scene - The scene to be edited and simulated.
    +   * @param {HTMLCanvasElement} canvas - The top-layered canvas for user interaction.
    +   * @param {Simulator} simulator - The simulator.
    +   */
    +  constructor(scene, canvas, simulator) {
    +    /** @property {Scene} scene - The scene to be edited and simulated. */
    +    this.scene = scene;
    +
    +    this.scene.editor = this;
    +
    +    /** @property {HTMLCanvasElement} canvas - The top-layered canvas for user interaction. */
    +    this.canvas = canvas;
    +
    +    /** @property {Simulator} simulator - The simulator. */
    +    this.simulator = simulator;
    +
    +    /** @property {boolean} lastDeviceIsTouch - Whether the last interaction with `canvas` is done by a touch device. */
    +    this.lastDeviceIsTouch = false;
    +
    +    /** @property {Point} mousePos - The position of the mouse in the scene. */
    +    this.mousePos = geometry.point(0, 0);
    +
    +    /** @property {Point} lastMousePos - The position of the mouse in the scene when the last mousedown event is triggered. */
    +    this.lastMousePos = geometry.point(0, 0);
    +
    +    /** @property {boolean} isConstructing - Whether an object is being constructed. */
    +    this.isConstructing = false;
    +
    +    /** @property {number} draggingObjIndex - The index of the object being dragged. -1 if no object is being dragged; -3 if the scene is being dragged; -4 if the observer is being dragged. */
    +    this.draggingObjIndex = -1;
    +
    +    /** @property {number} positioningObjIndex - The index of the object being positioned. -1 if no object is being positioned; -4 if the observer is being positioned. */
    +    this.positioningObjIndex = -1;
    +
    +    /** @property {DragContext} dragContext - The context of the dragging or positioning action. */
    +    this.dragContext = {};
    +
    +    /** @property {number} selectedObjIndex - The index of the selected object. -1 if no object is selected. */
    +    this.selectedObjIndex = -1;
    +
    +    /** @property {number} hoveredObjIndex - The index of the hovered object. -1 if no object is hovered. */
    +    this.hoveredObjIndex = -1;
    +
    +    /** @property {string} addingObjType - The type of the object that will be added when the user clicks on the canvas. Empty if 'Move view' tool is selected so that no object will be added. */
    +    this.addingObjType = '';
    +
    +    /** @property {string[]} undoData - The data for undoing, where each element is a JSON string representing the scene. */
    +    this.undoData = [this.scene.toJSON()];
    +
    +    /** @property {Date} lastActionTime - The time when the last undo data is pushed. */
    +    this.lastActionTime = new Date();
    +
    +    /** @property {string} lastActionJson - The JSON string representing the scene when the last undo data is pushed. */
    +    this.lastActionJson = this.scene.toJSON();
    +
    +    /** @property {number} undoIndex - The index of the undo data currently displayed. */
    +    this.undoIndex = 0;
    +
    +    /** @property {number} undoLBound - The upper bound of the undo data index. */
    +    this.undoLBound = 0;
    +
    +    /** @property {number} undoUBound - The lower bound of the undo data index. */
    +    this.undoUBound = 0;
    +
    +    /** @property {boolean} isInCropMode - Whether the editor is in the crop mode. */
    +    this.isInCropMode = false;
    +
    +    /** @property {boolean} pendingControlPointSelection - Whether a user has clicked on a control point with the Ctrl key held down, and the editor is waiting to see if the user is going to select the control point for a handle. */
    +    this.pendingControlPointSelection = false;
    +
    +    /** @property {ControlPoint[]} pendingControlPoints - The control points to be selected for a handle when the user clicks on a control point with the Ctrl key held down. */
    +    this.pendingControlPoints = [];
    +
    +    /** @property {string} addingModuleName - The name of the module that will be added when the user clicks on the canvas if `addingObjType` is 'ModuleObj'. */
    +    this.addingModuleName = '';
    +
    +    /** @property {object} eventListeners - The event listeners of the editor. */
    +    this.eventListeners = {};
    +
    +    /** @property {number} delayedValidationTimerId - The ID of the timer for performing a delayed validation. */
    +    this.delayedValidationTimerId = -1;
    +
    +    this.initCanvas();
    +  }
    +
    +  /**
    +   * Add an event listener to the editor.
    +   * @param {string} eventName - The name of the event.
    +   * @param {function} callback - The callback function.
    +   */
    +  on(eventName, callback) {
    +    if (!this.eventListeners[eventName]) {
    +      this.eventListeners[eventName] = [];
    +    }
    +    this.eventListeners[eventName].push(callback);
    +  }
    +
    +  /**
    +   * Emit an event.
    +   * @param {string} eventName - The name of the event.
    +   * @param {any} data - The data to be passed to the callback functions.
    +   */
    +  emit(eventName, data) {
    +    if (this.eventListeners[eventName]) {
    +      this.eventListeners[eventName].forEach(callback => callback(data));
    +    }
    +  }
    +
    +  /**
    +   * The event when the mouse coordinate changes. This is different from the actual mousemove, since the grid snapping is considered, and the coordnates can also be updated by other events such as zooming.
    +   * @event Editor#mouseCoordinateChange
    +   * @type {object}
    +   * @property {Point} mousePos - The position of the mouse in the scene. Null if the mouse is out of the canvas.
    +   */
    +
    +  /**
    +   * The event when the selection changes. This may also be triggered if the same object is selected again.
    +   * @event Editor#selectionChange
    +   * @type {object}
    +   * @property {number} oldIndex - The index of the previously selected object.
    +   * @property {number} newIndex - The index of the newly selected object.
    +   */
    +
    +  /**
    +   * The event when the user interacts with the canvas during the positioning of an object, so that the new coordinates are assumed to be confirmed.
    +   * @event Editor#requestPositioningComfirm
    +   * @type {object}
    +   * @property {boolean} ctrl - Whether the Ctrl key is held down.
    +   * @property {boolean} shift - Whether the Shift key is held down.
    +   */
    +
    +  /**
    +   * The event when the positioning of an object starts.
    +   * @event Editor#positioningStart
    +   * @type {object}
    +   * @property {DragContext} dragContext - The context of the positioning action, which is the same as the drag context if the user instead drags the control point to be positioned.
    +   */
    +
    +  /**
    +   * The event when the positioning of an object ends (either confirmed or canceled).
    +   * @event Editor#positioningEnd
    +   */
    +
    +  /**
    +   * The event when the scene is loaded. If the scene contains resources that takes time to load, this event is emitted every time a resource is loaded, where the last event has the `completed` property set to `true`.
    +   * @event Editor#sceneLoaded
    +   * @type {object}
    +   * @property {boolean} needFullUpdate - Whether the UI needs a full update.
    +   * @property {boolean} completed - Whether the loading is completed.
    +   */
    +
    +  /**
    +   * The event when a new action is done and the UI (e.g. code editor) should be updated.
    +   * @event Editor#newAction
    +   * @type {object}
    +   * @property {string} oldJSON - The JSON string representing the scene before the action.
    +   * @property {string} newJSON - The JSON string representing the scene after the action.
    +   */
    +
    +  /**
    +   * The event when the scale of the scene is changed.
    +   * @event Editor#scaleChange
    +   */
    +
    +  /**
    +   * The event when a new undo data is pushed.
    +   * @event Editor#newUndoPoint
    +   */
    +
    +  /**
    +   * The event when the user undo an action.
    +   * @event Editor#undo
    +   */
    +
    +  /**
    +   * The event when the user redo an action.
    +   * @event Editor#redo
    +   */
    +
    +  /**
    +   * The event when the error and warning messages in the UI should be updated.
    +   * @event requestUpdateErrorAndWarning
    +   */
    +
    +  /**
    +   * Initialize the canvas event listeners.
    +   */
    +  initCanvas() {
    +
    +    let lastTouchTime = -1;
    +
    +    const self = this;
    +
    +    this.canvas.addEventListener('mousedown', function (e) {
    +      if (self.lastDeviceIsTouch && Date.now() - lastTouchTime < 500) return;
    +      self.lastDeviceIsTouch = false;
    +
    +      if (self.scene.error) {
    +        self.canvas.style.cursor = 'not-allowed';
    +        return;
    +      }
    +
    +      self.canvas.focus();
    +      self.onCanvasMouseDown(e);
    +    });
    +
    +    this.canvas.addEventListener('mousemove', function (e) {
    +      //console.log("mousemove");
    +      if (self.lastDeviceIsTouch && Date.now() - lastTouchTime < 500) return;
    +      self.lastDeviceIsTouch = false;
    +
    +      if (self.scene.error) {
    +        self.canvas.style.cursor = 'not-allowed';
    +        return;
    +      }
    +
    +      self.onCanvasMouseMove(e);
    +    });
    +
    +    this.canvas.addEventListener('mouseup', function (e) {
    +      if (self.lastDeviceIsTouch && Date.now() - lastTouchTime < 500) return;
    +      self.lastDeviceIsTouch = false;
    +
    +      if (self.scene.error) {
    +        self.canvas.style.cursor = 'not-allowed';
    +        return;
    +      }
    +
    +      //console.log("mouseup");
    +      self.onCanvasMouseUp(e);
    +    });
    +
    +    this.canvas.addEventListener('mouseout', function (e) {
    +      if (self.lastDeviceIsTouch && Date.now() - lastTouchTime < 500) return;
    +      self.lastDeviceIsTouch = false;
    +      if (self.draggingObjIndex != -1) {
    +        self.onCanvasMouseUp(e);
    +      }
    +      self.hoveredObjIndex = -1;
    +
    +      self.emit('mouseCoordinateChange', { mousePos: null });
    +      self.simulator.updateSimulation(true, true)
    +    });
    +
    +
    +    let lastZoomTime = 0;
    +    let zoomThrottle = 100; // 100 ms between zooms
    +
    +    this.canvas.addEventListener('wheel', function (e) {
    +      var now = Date.now();
    +      if (now - lastZoomTime < zoomThrottle) return; // Too soon since the last zoom
    +      lastZoomTime = now;
    +
    +      // cross-browser wheel delta
    +      var e = window.event || e; // old IE support
    +      var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
    +      var d = self.scene.scale * self.scene.lengthScale;
    +      if (delta < 0) {
    +        d = self.scene.scale * self.scene.lengthScale - 0.25;
    +      } else if (delta > 0) {
    +        d = self.scene.scale * self.scene.lengthScale + 0.25;
    +      }
    +      d = Math.max(0.25, Math.min(5.00, d)) * 100;
    +      self.setScaleWithCenter(d / self.scene.lengthScale / 100, (e.pageX - e.target.offsetLeft) / self.scene.scale, (e.pageY - e.target.offsetTop) / self.scene.scale);
    +      self.onActionComplete();
    +      //window.toolBarViewModel.zoom.value(d);
    +      self.onCanvasMouseMove(e);
    +      return false;
    +    }, false);
    +
    +    let initialPinchDistance = null;
    +    let lastScale = 1;
    +    let lastX = 0;
    +    let lastY = 0;
    +
    +    this.canvas.addEventListener('touchstart', function (e) {
    +      if (self.scene.error) return;
    +      self.lastDeviceIsTouch = true;
    +      lastTouchTime = Date.now();
    +      if (e.touches.length === 2) {
    +        // Pinch to zoom
    +        e.preventDefault();
    +        lastX = (e.touches[0].pageX + e.touches[1].pageX) / 2;
    +        lastY = (e.touches[0].pageY + e.touches[1].pageY) / 2;
    +        if (self.isConstructing || self.draggingObjIndex >= 0) {
    +          self.onCanvasMouseUp(e);
    +          self.undo();
    +        } else {
    +          self.onCanvasMouseUp(e);
    +        }
    +      } else {
    +        //console.log("touchstart");
    +        self.canvas.focus();
    +        self.onCanvasMouseMove(e);
    +        self.onCanvasMouseDown(e);
    +      }
    +    });
    +
    +
    +    this.canvas.addEventListener('touchmove', function (e) {
    +      if (self.scene.error) return;
    +      self.lastDeviceIsTouch = true;
    +      lastTouchTime = Date.now();
    +      e.preventDefault();
    +      //console.log("touchmove");
    +      if (e.touches.length === 2) {
    +        // Pinch to zoom
    +
    +        // Calculate current distance between two touches
    +        const dx = e.touches[0].clientX - e.touches[1].clientX;
    +        const dy = e.touches[0].clientY - e.touches[1].clientY;
    +        const distance = Math.sqrt(dx * dx + dy * dy);
    +
    +        // If initialPinchDistance is null, this is the first move event of the pinch
    +        // Set initial distance
    +        if (initialPinchDistance === null) {
    +          initialPinchDistance = distance;
    +          lastScale = self.scene.scale;
    +        }
    +
    +        // Calculate the scaling factor
    +        const scaleFactor = distance / initialPinchDistance;
    +
    +        // Update scale based on previous scale and scaling factor
    +        let newScale = lastScale * scaleFactor;
    +
    +        newScale = Math.max(0.25 / self.scene.lengthScale, Math.min(5.00 / self.scene.lengthScale, newScale));
    +
    +        // Calculate the mid point between the two touches
    +        const x = (e.touches[0].pageX + e.touches[1].pageX) / 2;
    +        const y = (e.touches[0].pageY + e.touches[1].pageY) / 2;
    +
    +        // Calculate the change in scale relative to the center point
    +        const dx2 = x - lastX;
    +        const dy2 = y - lastY;
    +
    +        // Apply the translation
    +        self.scene.origin.x += dx2;
    +        self.scene.origin.y += dy2;
    +
    +        // Apply the scale transformation
    +        self.setScaleWithCenter(newScale, (x - e.target.offsetLeft) / self.scene.scale, (y - e.target.offsetTop) / self.scene.scale);
    +
    +        // Update last values
    +        lastX = x;
    +        lastY = y;
    +
    +      } else {
    +        self.onCanvasMouseMove(e);
    +      }
    +    });
    +
    +    this.canvas.addEventListener('touchend', function (e) {
    +      if (self.scene.error) return;
    +      self.lastDeviceIsTouch = true;
    +      lastTouchTime = Date.now();
    +      //console.log("touchend");
    +      if (e.touches.length < 2) {
    +        initialPinchDistance = null;
    +        self.onCanvasMouseUp(e);
    +        self.onActionComplete();
    +      }
    +    });
    +
    +    this.canvas.addEventListener('touchcancel', function (e) {
    +      if (self.scene.error) return;
    +      self.lastDeviceIsTouch = true;
    +      lastTouchTime = Date.now();
    +      //console.log("touchcancel");
    +      initialPinchDistance = null;
    +      if (self.isConstructing || self.draggingObjIndex >= 0) {
    +        self.onCanvasMouseUp(e);
    +        self.undo();
    +      } else {
    +        self.onCanvasMouseUp(e);
    +      }
    +    });
    +
    +    this.canvas.addEventListener('dblclick', function (e) {
    +      if (self.scene.error) return;
    +      self.onCanvasDblClick(e);
    +    });
    +  }
    +
    +
    +  /**
    +   * Handle the equivalent of the mousedown event on the canvas, which can be triggered by both mouse and single touch.
    +   * @param {MouseEvent} e - The event.
    +   */
    +  onCanvasMouseDown(e) {
    +    if (e.changedTouches) {
    +      var et = e.changedTouches[0];
    +    } else {
    +      var et = e;
    +    }
    +    var mousePos_nogrid = geometry.point((et.pageX - e.target.offsetLeft - this.scene.origin.x) / this.scene.scale, (et.pageY - e.target.offsetTop - this.scene.origin.y) / this.scene.scale); // The real position of the mouse
    +    this.lastMousePos = mousePos_nogrid;
    +    if (this.positioningObjIndex != -1) {
    +      this.emit('requestPositioningComfirm', { ctrl: e.ctrlKey, shift: e.shiftKey });
    +      if (!(e.which && e.which == 3)) {
    +        return;
    +      }
    +    }
    +
    +
    +    if (!((e.which && (e.which == 1 || e.which == 3)) || (e.changedTouches))) {
    +      return;
    +    }
    +
    +    if (this.scene.snapToGrid) {
    +      this.mousePos = geometry.point(Math.round(((et.pageX - e.target.offsetLeft - this.scene.origin.x) / this.scene.scale) / this.scene.gridSize) * this.scene.gridSize, Math.round(((et.pageY - e.target.offsetTop - this.scene.origin.y) / this.scene.scale) / this.scene.gridSize) * this.scene.gridSize);
    +
    +    }
    +    else {
    +      this.mousePos = mousePos_nogrid;
    +    }
    +
    +
    +    if (this.isConstructing) {
    +      if ((e.which && e.which == 1) || (e.changedTouches)) {
    +        // Only react for left click
    +        // If an obj is being created, pass the action to it
    +        if (this.selectedObjIndex != this.scene.objs.length - 1) {
    +          this.selectObj(this.scene.objs.length - 1); // Keep the constructing obj selected
    +        }
    +        const ret = this.scene.objs[this.scene.objs.length - 1].onConstructMouseDown(new Mouse(mousePos_nogrid, this.scene, this.lastDeviceIsTouch), e.ctrlKey, e.shiftKey);
    +        if (ret && ret.isDone) {
    +          this.isConstructing = false;
    +        }
    +        if (ret && ret.requiresObjBarUpdate) {
    +          this.selectObj(this.selectedObjIndex);
    +        }
    +        this.simulator.updateSimulation(!this.scene.objs[this.scene.objs.length - 1].constructor.isOptical, true);
    +      }
    +    }
    +    else {
    +      // lockObjs prevents selection, but alt overrides it
    +      if ((!(this.scene.lockObjs) != (e.altKey && this.addingObjType != '')) && !(e.which == 3)) {
    +
    +        this.dragContext = {};
    +
    +        if (this.scene.mode == 'observer') {
    +          if (geometry.distanceSquared(mousePos_nogrid, this.scene.observer.c) < this.scene.observer.r * this.scene.observer.r) {
    +            // The mousePos clicked the observer
    +            this.draggingObjIndex = -4;
    +            this.dragContext = {};
    +            this.dragContext.mousePos0 = this.mousePos; // Mouse position when the user starts dragging
    +            this.dragContext.mousePos1 = this.mousePos; // Mouse position at the last moment during dragging
    +            this.dragContext.snapContext = {};
    +            return;
    +          }
    +        }
    +
    +        var rets = this.selectionSearch(mousePos_nogrid);
    +        var ret = rets[0];
    +        if (ret.targetObjIndex != -1) {
    +          if (!e.ctrlKey && this.scene.objs.length > 0 && this.scene.objs[0].constructor.type == "Handle" && this.scene.objs[0].notDone) {
    +            // User is creating a handle
    +            this.removeObj(0);
    +            ret.targetObjIndex--;
    +          }
    +          this.selectObj(ret.targetObjIndex);
    +          this.dragContext = ret.dragContext;
    +          this.dragContext.originalObj = this.scene.objs[ret.targetObjIndex].serialize(); // Store the obj status before dragging
    +          this.dragContext.hasDuplicated = false;
    +          this.draggingObjIndex = ret.targetObjIndex;
    +          if (e.ctrlKey && this.dragContext.targetPoint) {
    +            this.pendingControlPointSelection = true;
    +            this.pendingControlPoints = rets;
    +          }
    +          return;
    +        }
    +      }
    +
    +      if (this.draggingObjIndex == -1) {
    +        // The mousePos clicked the blank area
    +        if (this.scene.objs.length > 0 && this.scene.objs[0].constructor.type == "Handle" && this.scene.objs[0].notDone) {
    +          // User is creating a handle
    +          this.finishHandleCreation(this.mousePos);
    +          return;
    +        }
    +        if ((this.addingObjType == '') || (e.which == 3)) {
    +          // To drag the entire scene
    +          this.draggingObjIndex = -3;
    +          this.dragContext = {};
    +          this.dragContext.mousePos0 = this.mousePos; // Mouse position when the user starts dragging
    +          this.dragContext.mousePos1 = this.mousePos; // Mouse position at the last moment during dragging
    +          this.dragContext.mousePos2 = this.scene.origin; //Original origin.
    +          this.dragContext.snapContext = {};
    +          this.selectObj(-1);
    +        }
    +        else {
    +          // Create a new object
    +          this.isConstructing = true;
    +          let referenceObj = {};
    +          if (this.scene.objs[this.selectedObjIndex]) {
    +            if (this.scene.objs[this.selectedObjIndex].constructor.type == this.addingObjType) {
    +              referenceObj = this.scene.objs[this.selectedObjIndex].serialize();
    +            }
    +          }
    +          this.scene.pushObj(new sceneObjs[this.addingObjType](this.scene, referenceObj));
    +
    +          const ret = this.scene.objs[this.scene.objs.length - 1].onConstructMouseDown(new Mouse(mousePos_nogrid, this.scene, this.lastDeviceIsTouch));
    +          if (ret && ret.isDone) {
    +            this.isConstructing = false;
    +          }
    +          this.selectObj(this.scene.objs.length - 1);
    +          this.simulator.updateSimulation(!this.scene.objs[this.scene.objs.length - 1].constructor.isOptical, true);
    +        }
    +      }
    +    }
    +  }
    +
    +  /**
    +   * Handle the equivalent of the mousemove event on the canvas, which can be triggered by both mouse and single touch.
    +   * @param {MouseEvent} e - The event.
    +   */
    +  onCanvasMouseMove(e) {
    +
    +    this.pendingControlPointSelection = false;
    +    if (e.changedTouches) {
    +      var et = e.changedTouches[0];
    +    } else {
    +      var et = e;
    +    }
    +    var mousePos_nogrid = geometry.point((et.pageX - e.target.offsetLeft - this.scene.origin.x) / this.scene.scale, (et.pageY - e.target.offsetTop - this.scene.origin.y) / this.scene.scale); // The real position of the mouse
    +    var mousePos2;
    +    if (this.scene.snapToGrid && !(e.altKey && !this.isConstructing)) {
    +      mousePos2 = geometry.point(Math.round(((et.pageX - e.target.offsetLeft - this.scene.origin.x) / this.scene.scale) / this.scene.gridSize) * this.scene.gridSize, Math.round(((et.pageY - e.target.offsetTop - this.scene.origin.y) / this.scene.scale) / this.scene.gridSize) * this.scene.gridSize);
    +    }
    +    else {
    +      mousePos2 = mousePos_nogrid;
    +    }
    +
    +    if (!this.isConstructing && this.draggingObjIndex == -1 && !this.scene.lockObjs) {
    +      // highlight object under mousePos cursor
    +      var ret = this.selectionSearch(mousePos_nogrid)[0];
    +      //console.log(mousePos_nogrid);
    +      if (this.hoveredObjIndex != ret.targetObjIndex) {
    +        this.hoveredObjIndex = ret.targetObjIndex;
    +        this.simulator.updateSimulation(true, true);
    +      }
    +      if (ret.dragContext) {
    +        if (ret.dragContext.cursor) {
    +          this.canvas.style.cursor = ret.dragContext.cursor;
    +        } else if (ret.dragContext.targetPoint || ret.dragContext.targetPoint_) {
    +          this.canvas.style.cursor = 'pointer';
    +        } else if (ret.dragContext.part == 0) {
    +          this.canvas.style.cursor = 'move';
    +        } else {
    +          this.canvas.style.cursor = '';
    +        }
    +      } else {
    +        if (this.scene.mode == 'observer' && geometry.distanceSquared(this.mousePos, this.scene.observer.c) < this.scene.observer.r * this.scene.observer.r) {
    +          this.canvas.style.cursor = 'pointer';
    +        } else {
    +          this.canvas.style.cursor = '';
    +        }
    +      }
    +    }
    +
    +    if (mousePos2.x == this.mousePos.x && mousePos2.y == this.mousePos.y) {
    +      return;
    +    }
    +    this.mousePos = mousePos2;
    +
    +    this.emit('mouseCoordinateChange', { mousePos: this.mousePos });
    +
    +
    +    if (this.isConstructing) {
    +      // highlight object being constructed
    +      this.hoveredObjIndex = this.scene.objs.length - 1;
    +
    +      // If some object is being created, pass the action to it
    +      const ret = this.scene.objs[this.scene.objs.length - 1].onConstructMouseMove(new Mouse(this.mousePos, this.scene, this.lastDeviceIsTouch), e.ctrlKey, e.shiftKey);
    +      if (ret && ret.isDone) {
    +        this.isConstructing = false;
    +      }
    +      if (ret && ret.requiresObjBarUpdate) {
    +        this.selectObj(this.selectedObjIndex);
    +      }
    +      this.simulator.updateSimulation(!this.scene.objs[this.scene.objs.length - 1].constructor.isOptical, true);
    +    }
    +    else {
    +      if (this.draggingObjIndex == -4) {
    +        if (e.shiftKey) {
    +          var mousePos_snapped = (new Mouse(this.mousePos, this.scene, this.lastDeviceIsTouch)).getPosSnappedToDirection(this.dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }], this.dragContext.snapContext);
    +        }
    +        else {
    +          var mousePos_snapped = this.mousePos;
    +          this.dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +        }
    +
    +        var mouseDiffX = (mousePos_snapped.x - this.dragContext.mousePos1.x); // The X difference between the mouse position now and at the previous moment
    +        var mouseDiffY = (mousePos_snapped.y - this.dragContext.mousePos1.y); // The Y difference between the mouse position now and at the previous moment
    +
    +        this.scene.observer.c.x += mouseDiffX;
    +        this.scene.observer.c.y += mouseDiffY;
    +
    +        // Update the mouse position
    +        this.dragContext.mousePos1 = mousePos_snapped;
    +        this.simulator.updateSimulation(false, true);
    +      }
    +
    +      if (this.draggingObjIndex >= 0) {
    +        // Here the mouse is dragging an object
    +
    +        this.scene.objs[this.draggingObjIndex].onDrag(new Mouse(mousePos_nogrid, this.scene, this.lastDeviceIsTouch, e.altKey * 1), this.dragContext, e.ctrlKey, e.shiftKey);
    +        // If dragging an entire object, then when Ctrl is hold, clone the object
    +        if (this.dragContext.part == 0) {
    +          if (e.ctrlKey && !this.dragContext.hasDuplicated) {
    +
    +            this.scene.pushObj(new sceneObjs[this.scene.objs[this.draggingObjIndex].constructor.type](this.scene, this.dragContext.originalObj));
    +            this.dragContext.hasDuplicated = true;
    +          }
    +          if (!e.ctrlKey && this.dragContext.hasDuplicated) {
    +            this.scene.objs.length--;
    +            this.dragContext.hasDuplicated = false;
    +          }
    +        }
    +
    +        this.simulator.updateSimulation(!this.scene.objs[this.draggingObjIndex].constructor.isOptical, true);
    +
    +        if (this.dragContext.requiresObjBarUpdate) {
    +          this.selectObj(this.selectedObjIndex);
    +        }
    +      }
    +
    +      if (this.draggingObjIndex == -3 && this.dragContext.mousePos1) {
    +        // Move the entire scene
    +        // Here mousePos is the currect mouse position, dragContext.mousePos1 is the mouse position at the previous moment
    +
    +        var mouseDiffX = (this.mousePos.x - this.dragContext.mousePos1.x); // The X difference between the mouse position now and at the previous moment
    +        var mouseDiffY = (this.mousePos.y - this.dragContext.mousePos1.y); // The Y difference between the mouse position now and at the previous moment
    +        this.scene.origin.x = mouseDiffX * this.scene.scale + this.dragContext.mousePos2.x;
    +        this.scene.origin.y = mouseDiffY * this.scene.scale + this.dragContext.mousePos2.y;
    +        this.simulator.updateSimulation();
    +      }
    +
    +
    +    }
    +  }
    +
    +  /**
    +   * Handle the equivalent of the mouseup event on the canvas, which can be triggered by both mouse and single touch.
    +   * @param {MouseEvent} e - The event.
    +   */
    +  onCanvasMouseUp(e) {
    +    if (this.isConstructing) {
    +      if ((e.which && e.which == 1) || (e.changedTouches)) {
    +        // If an object is being created, pass the action to it
    +        const ret = this.scene.objs[this.scene.objs.length - 1].onConstructMouseUp(new Mouse(this.mousePos, this.scene, this.lastDeviceIsTouch), e.ctrlKey, e.shiftKey);
    +        if (ret && ret.isDone) {
    +          this.isConstructing = false;
    +        }
    +        if (ret && ret.requiresObjBarUpdate) {
    +          this.selectObj(this.selectedObjIndex);
    +        }
    +        this.simulator.updateSimulation(!this.scene.objs[this.scene.objs.length - 1].constructor.isOptical, true);
    +        if (!this.isConstructing) {
    +          // The object says the contruction is done
    +          this.onActionComplete();
    +          if (this.scene.lockObjs) {
    +            this.hoveredObjIndex = -1;
    +            this.simulator.updateSimulation(true, true);
    +          }
    +        }
    +      }
    +    }
    +    else {
    +      if (this.pendingControlPointSelection) {
    +        this.pendingControlPointSelection = false
    +        this.addControlPointsForHandle(this.pendingControlPoints);
    +      }
    +      if (e.which && e.which == 3 && this.draggingObjIndex == -3 && this.mousePos.x == this.dragContext.mousePos0.x && this.mousePos.y == this.dragContext.mousePos0.y) {
    +        this.draggingObjIndex = -1;
    +        this.dragContext = {};
    +        this.onCanvasDblClick(e);
    +        return;
    +      }
    +      this.onActionComplete();
    +      this.draggingObjIndex = -1;
    +      this.dragContext = {};
    +    }
    +
    +  }
    +
    +
    +  /**
    +   * Handle the equivalent of the dblclick event on the canvas.
    +   * @param {MouseEvent} e - The event.
    +   */
    +  onCanvasDblClick(e) {
    +    //console.log("dblclick");
    +    this.mousePos = geometry.point((e.pageX - e.target.offsetLeft - this.scene.origin.x) / this.scene.scale, (e.pageY - e.target.offsetTop - this.scene.origin.y) / this.scene.scale); // The real position of the mouse (never use grid here)
    +    if (this.isConstructing) {
    +    }
    +    else if (new Mouse(this.mousePos, this.scene, this.lastDeviceIsTouch).isOnPoint(this.lastMousePos)) {
    +      this.dragContext = {};
    +      if (this.scene.mode == 'observer') {
    +        if (geometry.distanceSquared(this.mousePos, this.scene.observer.c) < this.scene.observer.r * this.scene.observer.r) {
    +
    +          // The mousePos clicked the observer
    +          this.positioningObjIndex = -4;
    +          this.dragContext = {};
    +          this.dragContext.targetPoint = geometry.point(this.scene.observer.c.x, this.scene.observer.c.y);
    +          this.dragContext.snapContext = {};
    +
    +          this.emit('positioningStart', { dragContext: this.dragContext });
    +
    +          return;
    +        }
    +      }
    +
    +      var ret = this.selectionSearch(this.mousePos)[0];
    +      if (ret.targetObjIndex != -1 && ret.dragContext.targetPoint) {
    +        this.selectObj(ret.targetObjIndex);
    +        this.dragContext = ret.dragContext;
    +        this.dragContext.originalObj = this.scene.objs[ret.targetObjIndex].serialize(); // Store the obj status before dragging
    +
    +        this.dragContext.hasDuplicated = false;
    +        this.positioningObjIndex = ret.targetObjIndex;
    +
    +        this.emit('positioningStart', { dragContext: this.dragContext });
    +
    +      }
    +    }
    +
    +  }
    +
    +  /**
    +   * search for best object to select at mouse position
    +   * @param {Point} mousePos_nogrid - The mouse position in the scene (without snapping to grid).
    +   * @returns {SelectionSearchResult[]} - The search results.
    +   */
    +  selectionSearch(mousePos_nogrid) {
    +    var i;
    +    var click_lensq = Infinity;
    +    var click_lensq_temp;
    +    var targetObjIndex = -1;
    +    var targetIsPoint = false;
    +    var dragContext;
    +    var targetIsSelected = false;
    +    var results = [];
    +
    +    for (var i = 0; i < this.scene.objs.length; i++) {
    +      if (typeof this.scene.objs[i] != 'undefined') {
    +        let dragContext_ = this.scene.objs[i].checkMouseOver(new Mouse(mousePos_nogrid, this.scene, this.lastDeviceIsTouch));
    +        if (dragContext_) {
    +          // the mouse is over the object
    +
    +          if (dragContext_.targetPoint || dragContext_.targetPoint_) {
    +            // The mousePos clicked a point
    +            if (!targetIsPoint) {
    +              targetIsPoint = true; // If the mouse can click a point, then it must click a point
    +              results = [];
    +            }
    +            var click_lensq_temp = geometry.distanceSquared(mousePos_nogrid, (dragContext_.targetPoint || dragContext_.targetPoint_));
    +            if (click_lensq_temp <= click_lensq || targetObjIndex == this.selectedObjIndex) {
    +              // In case of clicking a point, choose the one nearest to the mouse
    +              // But if the object is the selected object, the points from this object have the highest priority.
    +              targetObjIndex = i;
    +              click_lensq = click_lensq_temp;
    +              dragContext = dragContext_;
    +              if (!targetIsSelected) {
    +                results.unshift({ dragContext: dragContext, targetObjIndex: targetObjIndex });
    +              } else {
    +                results.push({ dragContext: dragContext, targetObjIndex: targetObjIndex });
    +              }
    +              if (targetObjIndex == this.selectedObjIndex) targetIsSelected = true;
    +            }
    +          } else if (!targetIsPoint) {
    +            // If not clicking a point, and until now not clicking any point
    +            targetObjIndex = i; // If clicking non-point, choose the most newly created one
    +            dragContext = dragContext_;
    +            results.unshift({ dragContext: dragContext, targetObjIndex: targetObjIndex });
    +          }
    +        }
    +      }
    +    }
    +    if (results.length == 0) {
    +      results.push({ targetObjIndex: -1 });
    +    }
    +    return results;
    +  }
    +
    +  /**
    +   * Add control points for a handle (create a new handle or add to the currently consturcting handle).
    +   * @param {ControlPoint[]} controlPoints - The control points to add.
    +   */
    +  addControlPointsForHandle(controlPoints) {
    +    if (!(this.scene.objs[0].constructor.type == "Handle" && this.scene.objs[0].notDone)) {
    +      this.scene.unshiftObj(new sceneObjs["Handle"](this.scene, { notDone: true }));
    +      if (this.selectedObjIndex >= 0) this.selectedObjIndex++;
    +      for (var i in controlPoints) {
    +        controlPoints[i].targetObjIndex++;
    +      }
    +    }
    +    for (var i in controlPoints) {
    +      this.scene.objs[0].addControlPoint(controlPoints[i]);
    +    }
    +    this.simulator.updateSimulation(true, true);
    +  }
    +
    +  /**
    +   * Finish the creation of a handle.
    +   * @param {Point} point - The point for the position of the handle.
    +   */
    +  finishHandleCreation(point) {
    +    this.scene.objs[0].finishHandle(point);
    +    this.simulator.updateSimulation(true, true);
    +    this.selectObj(0);
    +  }
    +
    +  /**
    +   * Select an object.
    +   * @param {number} index - The index of the object to select.
    +   */
    +  selectObj(index) {
    +    if (index < 0 || index >= this.scene.objs.length) {
    +      // If this object does not exist
    +      this.emit('selectionChange', { oldIndex: this.selectedObjIndex, newIndex: -1 });
    +      this.selectedObjIndex = -1;
    +      
    +      return;
    +    }
    +    this.emit('selectionChange', { oldIndex: this.selectedObjIndex, newIndex: index });
    +    this.selectedObjIndex = index;
    +  }
    +
    +  /**
    +   * Confirm the positioning in the coordinate box.
    +   * @param {number} x - The x-coordinate.
    +   * @param {number} y - The y-coordinate.
    +   * @param {boolean} ctrl - Whether the Ctrl key is pressed.
    +   * @param {boolean} shift - Whether the Shift key is pressed.
    +   */
    +  confirmPositioning(x, y, ctrl, shift) {
    +
    +
    +    if (this.positioningObjIndex == -4) {
    +      // Observer
    +      this.scene.observer.c.x = x;
    +      this.scene.observer.c.y = y;
    +      this.simulator.updateSimulation(false, true);
    +    }
    +    else {
    +      // Object
    +      this.scene.objs[this.positioningObjIndex].onDrag(new Mouse(geometry.point(x, y), this.scene, this.lastDeviceIsTouch, 2), this.dragContext, ctrl, shift);
    +      this.simulator.updateSimulation(!this.scene.objs[this.positioningObjIndex].constructor.isOptical, true);
    +    }
    +
    +    this.onActionComplete();
    +
    +    this.endPositioning();
    +  }
    +
    +  /**
    +   * End the positioning in the coordinate box.
    +   */
    +  endPositioning() {
    +    this.emit('positioningEnd');
    +    this.positioningObjIndex = -1;
    +    this.dragContext = {};
    +  }
    +
    +  /**
    +   * Remove an object.
    +   * @param {number} index - The index of the object to remove.
    +   */
    +  removeObj(index) {
    +    this.isConstructing = false;
    +    this.scene.removeObj(index);
    +
    +    this.selectedObjIndex--;
    +    this.selectObj(this.selectedObjIndex);
    +  }
    +
    +  /**
    +   * Set the scale of the scene with respect to the center point of the canvas.
    +   * @param {number} value - The new scale.
    +   */
    +  setScale(value) {
    +    this.setScaleWithCenter(value, this.canvas.width / this.scene.scale / 2, this.canvas.height / this.scene.scale / 2);
    +  }
    +  
    +  /**
    +   * Set the scale of the scene while keeping a given center point fixed.
    +   * @param {number} value - The new scale factor.
    +   * @param {number} centerX - The x-coordinate of the center point.
    +   * @param {number} centerY - The y-coordinate of the center point.
    +   */
    +  setScaleWithCenter(value, centerX, centerY) {
    +    this.scene.setScaleWithCenter(value, centerX, centerY);
    +    this.emit('scaleChange');
    +    
    +    this.simulator.updateSimulation();
    +  }
    +
    +  /**
    +   * Load a JSON string of the scene to the editor.
    +   * @param {string} json - The JSON string of the scene.
    +   */
    +  loadJSON(json) {
    +    const self = this;
    +    this.scene.setViewportSize(this.canvas.width / this.simulator.dpr, this.canvas.height / this.simulator.dpr);
    +    this.scene.loadJSON(json, function (needFullUpdate, completed) {
    +      self.emit('sceneLoaded', { needFullUpdate: needFullUpdate, completed: completed });
    +      if (needFullUpdate) {
    +        self.simulator.updateSimulation();
    +      } else {
    +        // Partial update (e.g. when the background image is loaded)
    +        setTimeout(function () {
    +          self.simulator.updateSimulation(true, true);
    +        }, 1);
    +      }
    +    });
    +    this.selectObj(-1);
    +    this.lastActionJson = json;
    +    this.simulator.updateSimulation();
    +  }
    +
    +  /**
    +   * Called when a change (action) is completed. This function will update the undo data, sync the JSON editor, etc.
    +   */
    +  onActionComplete() {
    +    if (this.scene.error) {
    +      return;
    +    }
    +
    +    const newJSON = this.scene.toJSON();
    +    const oldJSON = this.lastActionJson;
    +    this.lastActionJson = newJSON;
    +    this.emit('newAction', { newJSON: newJSON, oldJSON: oldJSON });
    +
    +    this.emit('requestUpdateErrorAndWarning');
    +    this.requireDelayedValidation();
    +
    +    if (new Date() - this.lastActionTime > Editor.UNDO_INTERVAL) {
    +      this.undoIndex = (this.undoIndex + 1) % Editor.UNDO_LIMIT;
    +      this.emit('newUndoPoint');
    +      
    +      this.undoUBound = this.undoIndex;
    +      if (this.undoUBound == this.undoLBound) {
    +        // The limit of undo is reached
    +        this.undoLBound = (this.undoLBound + 1) % Editor.UNDO_LIMIT;
    +      }
    +    }
    +
    +    this.undoData[this.undoIndex] = this.lastActionJson;
    +
    +    this.lastActionTime = new Date();
    +  }
    +
    +  /**
    +   * Undo the last edit.
    +   */
    +  undo() {
    +    if (this.isConstructing) {
    +      const constructingObjType = this.scene.objs[this.scene.objs.length - 1].constructor.type;
    +      const ret = this.scene.objs[this.scene.objs.length - 1].onConstructUndo();
    +      if (ret && ret.isCancelled) {
    +        this.isConstructing = false;
    +        this.scene.objs.length--;
    +        this.selectObj(-1);
    +      }
    +      this.simulator.updateSimulation(!sceneObjs[constructingObjType].isOptical, true);
    +      return;
    +    }
    +    if (this.positioningObjIndex != -1) {
    +      // If the user is entering coordinates when clicked the undo, then only stop the coordinates entering rather than do the real undo
    +      this.endPositioning();
    +      return;
    +    }
    +    if (this.undoIndex == this.undoLBound)
    +      // The lower bound of undo data is reached
    +      return;
    +    this.undoIndex = (this.undoIndex + (Editor.UNDO_LIMIT - 1)) % Editor.UNDO_LIMIT;
    +    this.loadJSON(this.undoData[this.undoIndex]);
    +    this.emit('undo');
    +
    +    this.requireDelayedValidation();
    +  }
    +
    +  /**
    +   * Redo the last edit.
    +   */
    +  redo() {
    +    this.isConstructing = false;
    +    this.endPositioning();
    +    if (this.undoIndex == this.undoUBound)
    +      // The lower bound of undo data is reached
    +      return;
    +    this.undoIndex = (this.undoIndex + 1) % Editor.UNDO_LIMIT;
    +    this.loadJSON(this.undoData[this.undoIndex]);
    +    this.emit('redo');
    +
    +    this.requireDelayedValidation();
    +  }
    +
    +  /**
    +   * Enter the crop mode that allows the user to crop the scene for exporting.
    +   */
    +  enterCropMode() {
    +    this.isInCropMode = true;
    +
    +    // Search objs for existing cropBox
    +    var cropBoxIndex = -1;
    +    for (var i = 0; i < this.scene.objs.length; i++) {
    +      if (this.scene.objs[i].constructor.type == 'CropBox') {
    +        cropBoxIndex = i;
    +        break;
    +      }
    +    }
    +    if (cropBoxIndex == -1) {
    +      // Create a new cropBox
    +      this.scene.pushObj(new sceneObjs['CropBox'](this.scene, {
    +        p1: geometry.point((this.canvas.width * 0.2 / this.simulator.dpr - this.scene.origin.x) / this.scene.scale, ((120 + (this.canvas.height - 120) * 0.2) / this.simulator.dpr - this.scene.origin.y) / this.scene.scale),
    +        p4: geometry.point((this.canvas.width * 0.8 / this.simulator.dpr - this.scene.origin.x) / this.scene.scale, ((120 + (this.canvas.height - 120) * 0.8) / this.simulator.dpr - this.scene.origin.y) / this.scene.scale),
    +      }));
    +      cropBoxIndex = this.scene.objs.length - 1;
    +    }
    +
    +    this.selectObj(cropBoxIndex);
    +
    +    this.simulator.updateSimulation(true, true);
    +  }
    +
    +  /**
    +   * Confirm the crop box and export the cropped scene.
    +   * @param {CropBox} cropBox - The crop box.
    +   */
    +  confirmCrop(cropBox) {
    +    if (cropBox.format == 'svg') {
    +      this.exportSVG(cropBox);
    +    } else {
    +      this.exportImage(cropBox);
    +    }
    +    this.isInCropMode = false;
    +    this.selectObj(-1);
    +    this.simulator.updateSimulation(true, true);
    +  }
    +
    +  /**
    +   * Exit the crop mode without exporting the cropped scene.
    +   */
    +  cancelCrop() {
    +    this.isInCropMode = false;
    +    this.selectObj(-1);
    +    this.simulator.updateSimulation(true, true);
    +  }
    +
    +  /**
    +   * Export the cropped scene as an SVG file.
    +   * @param {CropBox} cropBox - The crop box.
    +   */
    +  exportSVG(cropBox) {
    +    const self = this;
    +    const exportingScene = new Scene();
    +    exportingScene.backgroundImage = this.scene.backgroundImage;
    +    exportingScene.loadJSON(this.scene.toJSON(), function (needFullUpdate, completed) {
    +      if (!completed) {
    +        return;
    +      }
    +
    +      exportingScene.scale = 1;
    +      exportingScene.origin = { x: -cropBox.p1.x * exportingScene.scale, y: -cropBox.p1.y * exportingScene.scale };
    +
    +      const imageWidth = cropBox.p4.x - cropBox.p1.x;
    +      const imageHeight = cropBox.p4.y - cropBox.p1.y;
    +
    +      const ctxSVG = new C2S(imageWidth, imageHeight);
    +      ctxSVG.fillStyle = "black";
    +      ctxSVG.fillRect(0, 0, imageWidth, imageHeight);
    +
    +      const exportSimulator = new Simulator(exportingScene, ctxSVG, null, null, null, null, false, cropBox.rayCountLimit || 1e7);
    +
    +      function onSimulationEnd() {
    +        const blob = new Blob([ctxSVG.getSerializedSvg()], { type: 'image/svg+xml' });
    +        saveAs(blob, (self.scene.name || "export") + ".svg");
    +      }
    +
    +      exportSimulator.on('simulationComplete', onSimulationEnd);
    +      exportSimulator.on('simulationStop', onSimulationEnd);
    +
    +      exportSimulator.updateSimulation();
    +    });
    +  }
    +
    +  /**
    +   * Export the cropped scene as a PNG image.
    +   * @param {CropBox} cropBox - The crop box.
    +   */
    +  exportImage(cropBox) {
    +    const self = this;
    +    const exportingScene = new Scene();
    +    exportingScene.backgroundImage = this.scene.backgroundImage;
    +    exportingScene.loadJSON(this.scene.toJSON(), function (needFullUpdate, completed) {
    +      if (!completed) {
    +        return;
    +      }
    +
    +      exportingScene.scale = cropBox.width / (cropBox.p4.x - cropBox.p1.x);
    +      exportingScene.origin = { x: -cropBox.p1.x * exportingScene.scale, y: -cropBox.p1.y * exportingScene.scale };
    +
    +      const imageWidth = cropBox.width;
    +      const imageHeight = cropBox.width * (cropBox.p4.y - cropBox.p1.y) / (cropBox.p4.x - cropBox.p1.x);
    +
    +      const canvases = [];
    +      const ctxs = [];
    +      for (let i = 0; i < 4; i++) {
    +        canvases.push(document.createElement('canvas'));
    +        ctxs.push(canvases[i].getContext('2d'));
    +        canvases[i].width = imageWidth;
    +        canvases[i].height = imageHeight;
    +      }
    +
    +      const exportSimulator = new Simulator(exportingScene, ctxs[0], ctxs[1], ctxs[2], ctxs[3], document.createElement('canvas').getContext('2d'), false, cropBox.rayCountLimit || 1e7);
    +
    +      function onSimulationEnd() {
    +        const finalCanvas = document.createElement('canvas');
    +        finalCanvas.width = imageWidth;
    +        finalCanvas.height = imageHeight;
    +        const finalCtx = finalCanvas.getContext('2d');
    +        finalCtx.fillStyle = "black";
    +        finalCtx.fillRect(0, 0, cropBox.width, cropBox.width * (cropBox.p4.y - cropBox.p1.y) / (cropBox.p4.x - cropBox.p1.x));
    +        finalCtx.drawImage(canvases[1], 0, 0);
    +        finalCtx.drawImage(canvases[3], 0, 0);
    +        finalCtx.drawImage(canvases[0], 0, 0);
    +        finalCtx.drawImage(canvases[2], 0, 0);
    +
    +        finalCanvas.toBlob(function (blob) {
    +          saveAs(blob, (self.scene.name || "export") + ".png");
    +        });
    +      }
    +
    +      exportSimulator.on('simulationComplete', onSimulationEnd);
    +      exportSimulator.on('simulationStop', onSimulationEnd);
    +
    +      exportSimulator.updateSimulation();
    +    });
    +  }
    +
    +  /**
    +   * Require a delayed validation of the scene. The actual validation will be performed if the user is inactive for a while.
    +   */
    +  requireDelayedValidation() {
    +    if (this.scene.error) {
    +      return;
    +    }
    +
    +    if (this.delayedValidationTimerId) {
    +      clearTimeout(this.delayedValidationTimerId);
    +    }
    +
    +    const self = this;
    +    this.delayedValidationTimerId = setTimeout(function () {
    +      self.validateDelayed()
    +     }, this.scene.warning ? 500 : 5000);
    +  }
    +
    +  /**
    +   * Perform the delayed validation of the scene. Called after the user has been inactive for a while.
    +   */
    +  validateDelayed() {
    +    this.scene.validateDelayed();
    +    this.emit('requestUpdateErrorAndWarning');
    +  }
    +
    +}
    +
    +export default Editor;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/Mouse.html b/docs/Mouse.html new file mode 100644 index 00000000..639efdbf --- /dev/null +++ b/docs/Mouse.html @@ -0,0 +1,1270 @@ + + + + + JSDoc: Class: Mouse + + + + + + + + + + +
    + +

    Class: Mouse

    + + + + + + +
    + +
    + +

    Mouse(pos, scene, isTouch, overrideGrid)

    + +

    The Mouse class encapsulates the state of the mouse within the scene.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Mouse(pos, scene, isTouch, overrideGrid)

    + + + + + + +
    +

    Create a Mouse object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDefaultDescription
    pos + + +geometry.point + + + + + +

    The position of the mouse within the scene.

    scene + + +Scene + + + + + +

    The scene in which the mouse operates.

    isTouch + + +boolean + + + + + + false + +

    Indicates whether the mouse input comes from a touch screen.

    overrideGrid + + +number + + + + + + 0 + +

    Indicates how the grid is overridden (0: not overridden, 1: invert the on/off of the grid, 2: always off).

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + +

    Methods

    + + + + + + + +

    getClickExtent(isPoint) → {number}

    + + + + + + +
    +

    Calculates the effective click extent based on whether the target is a point or a line, +and adjusts for touchscreen input if applicable.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    isPoint + + +boolean + + + +

    Specifies whether the target is a point (true) or a line (false).

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The calculated click extent.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getPosSnappedToDirection(basePoint, directions, snapContext) → {geometry.point}

    + + + + + + +
    +

    Get the mouse position snapped to a set of suggested directions.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    basePoint + + +geometry.point + + + +

    The base point for the snapping.

    directions + + +Array + + + +

    The directions to snap to, each a vector with x and y components.

    snapContext + + +Object + + + +

    The object storing the internal state of the snapping process.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The mouse position snapped to some direction.

    +
    + + + +
    +
    + Type +
    +
    + +geometry.point + + +
    +
    + + + + + + + + + + + + + +

    getPosSnappedToGrid() → {geometry.point}

    + + + + + + +
    +

    Get the mouse position snapped to the grid if the grid is enabled.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The mouse position snapped to the grid.

    +
    + + + +
    +
    + Type +
    +
    + +geometry.point + + +
    +
    + + + + + + + + + + + + + +

    isOnLine(line) → {boolean}

    + + + + + + +
    +

    Determines if the mouse is currently over a given line.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    line + + +geometry.line + + + +

    The line to check against the mouse position.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the mouse is on the given line, false otherwise.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    isOnPoint(point) → {boolean}

    + + + + + + +
    +

    Determines if the mouse is currently over a given point.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +geometry.point + + + +

    The point to check against the mouse position.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the mouse is on the given point, false otherwise.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    isOnSegment(segment) → {boolean}

    + + + + + + +
    +

    Determines if the mouse is currently over a given line segment.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    segment + + +geometry.line + + + +

    The line segment to check against the mouse position.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the mouse is on the given line segment, false otherwise.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/Mouse.js.html b/docs/Mouse.js.html new file mode 100644 index 00000000..72e902b8 --- /dev/null +++ b/docs/Mouse.js.html @@ -0,0 +1,182 @@ + + + + + JSDoc: Source: Mouse.js + + + + + + + + + + +
    + +

    Source: Mouse.js

    + + + + + + +
    +
    +
    import geometry from './geometry.js';
    +
    +/**
    + * The Mouse class encapsulates the state of the mouse within the scene.
    + * @class
    + */
    +class Mouse {
    +  static CLICK_EXTENT_LINE = 10;
    +  static CLICK_EXTENT_POINT = 10;
    +  static TOUCHSCREEN_EXTENT_RATIO = 2;
    +  static SNAP_TO_DIRECTION_LOCK_LIMIT = 30;
    +
    +  /**
    +   * Create a Mouse object.
    +   * @param {geometry.point} pos - The position of the mouse within the scene.
    +   * @param {Scene} scene - The scene in which the mouse operates.
    +   * @param {boolean} isTouch - Indicates whether the mouse input comes from a touch screen.
    +   * @param {number} overrideGrid - Indicates how the grid is overridden (0: not overridden, 1: invert the on/off of the grid, 2: always off).
    +   */
    +  constructor(pos, scene, isTouch = false, overrideGrid = 0) {
    +    this.pos = pos;
    +    this.scene = scene;
    +    this.isTouch = isTouch;
    +    this.overrideGrid = overrideGrid;
    +  }
    +
    +  /**
    +   * Calculates the effective click extent based on whether the target is a point or a line,
    +   * and adjusts for touchscreen input if applicable.
    +   * @param {boolean} isPoint - Specifies whether the target is a point (true) or a line (false).
    +   * @returns {number} The calculated click extent.
    +   */
    +  getClickExtent(isPoint) {
    +    let clickExtent;
    +    if (isPoint) {
    +      clickExtent = Mouse.CLICK_EXTENT_POINT / this.scene.scale;
    +    } else {
    +      clickExtent = Mouse.CLICK_EXTENT_LINE / this.scene.scale;
    +    }
    +    if (this.isTouch) {
    +      clickExtent *= Mouse.TOUCHSCREEN_EXTENT_RATIO;
    +    }
    +    return clickExtent;
    +  }
    +
    +  /**
    +   * Determines if the mouse is currently over a given point.
    +   * @param {geometry.point} point - The point to check against the mouse position.
    +   * @returns {boolean} True if the mouse is on the given point, false otherwise.
    +   */
    +  isOnPoint(point) {
    +    return geometry.distanceSquared(this.pos, point) < this.getClickExtent(true) * this.getClickExtent(true);
    +  }
    +
    +  /**
    +   * Determines if the mouse is currently over a given line segment.
    +   * @param {geometry.line} segment - The line segment to check against the mouse position.
    +   * @returns {boolean} True if the mouse is on the given line segment, false otherwise.
    +   */
    +  isOnSegment(segment) {
    +    var d_per = Math.pow((this.pos.x - segment.p1.x) * (segment.p1.y - segment.p2.y) + (this.pos.y - segment.p1.y) * (segment.p2.x - segment.p1.x), 2) / ((segment.p1.y - segment.p2.y) * (segment.p1.y - segment.p2.y) + (segment.p2.x - segment.p1.x) * (segment.p2.x - segment.p1.x)); // Similar to the distance between the mouse and the line
    +    var d_par = (segment.p2.x - segment.p1.x) * (this.pos.x - segment.p1.x) + (segment.p2.y - segment.p1.y) * (this.pos.y - segment.p1.y); // Similar to the projected point of the mouse on the line
    +    return d_per < this.getClickExtent() * this.getClickExtent() && d_par >= 0 && d_par <= geometry.segmentLengthSquared(segment);
    +  }
    +
    +  /**
    +   * Determines if the mouse is currently over a given line.
    +   * @param {geometry.line} line - The line to check against the mouse position.
    +   * @returns {boolean} True if the mouse is on the given line, false otherwise.
    +   */
    +  isOnLine(line) {
    +    var d_per = Math.pow((this.pos.x - line.p1.x) * (line.p1.y - line.p2.y) + (this.pos.y - line.p1.y) * (line.p2.x - line.p1.x), 2) / ((line.p1.y - line.p2.y) * (line.p1.y - line.p2.y) + (line.p2.x - line.p1.x) * (line.p2.x - line.p1.x)); // Similar to the distance between the mouse and the line
    +    return d_per < this.getClickExtent() * this.getClickExtent();
    +  }
    +
    +  /**
    +   * Get the mouse position snapped to the grid if the grid is enabled.
    +   * @returns {geometry.point} The mouse position snapped to the grid.
    +   */
    +  getPosSnappedToGrid() {
    +    //console.log(this.overrideGrid)
    +    if ((this.overrideGrid === 0 && this.scene.snapToGrid) || (this.overrideGrid === 1 && !this.scene.snapToGrid)) {
    +      return geometry.point(
    +        Math.round(this.pos.x / this.scene.gridSize) * this.scene.gridSize,
    +        Math.round(this.pos.y / this.scene.gridSize) * this.scene.gridSize
    +      );
    +    } else {
    +      return this.pos;
    +    }
    +  }
    +
    +  /**
    +   * Get the mouse position snapped to a set of suggested directions.
    +   * @param {geometry.point} basePoint - The base point for the snapping.
    +   * @param {Array} directions - The directions to snap to, each a vector with x and y components.
    +   * @param {Object} snapContext - The object storing the internal state of the snapping process.
    +   * @returns {geometry.point} The mouse position snapped to some direction.
    +   */
    +  getPosSnappedToDirection(basePoint, directions, snapContext) {
    +    const pos = this.getPosSnappedToGrid();
    +    var x = pos.x - basePoint.x;
    +    var y = pos.y - basePoint.y;
    +
    +    if (snapContext && snapContext.locked) {
    +      // The snap has been locked
    +      var k = (directions[snapContext.i0].x * x + directions[snapContext.i0].y * y) / (directions[snapContext.i0].x * directions[snapContext.i0].x + directions[snapContext.i0].y * directions[snapContext.i0].y);
    +      return geometry.point(basePoint.x + k * directions[snapContext.i0].x, basePoint.y + k * directions[snapContext.i0].y);
    +    } else {
    +      var i0;
    +      var d_sq;
    +      var d0_sq = Infinity;
    +      for (var i = 0; i < directions.length; i++) {
    +        d_sq = (directions[i].y * x - directions[i].x * y) * (directions[i].y * x - directions[i].x * y) / (directions[i].x * directions[i].x + directions[i].y * directions[i].y);
    +        if (d_sq < d0_sq) {
    +          d0_sq = d_sq;
    +          i0 = i;
    +        }
    +      }
    +
    +      if (snapContext && x * x + y * y > Mouse.SNAP_TO_DIRECTION_LOCK_LIMIT * Mouse.SNAP_TO_DIRECTION_LOCK_LIMIT / this.scene.scale / this.scene.scale) {
    +        // lock the snap
    +        snapContext.locked = true;
    +        snapContext.i0 = i0;
    +      }
    +
    +      var k = (directions[i0].x * x + directions[i0].y * y) / (directions[i0].x * directions[i0].x + directions[i0].y * directions[i0].y);
    +      return geometry.point(basePoint.x + k * directions[i0].x, basePoint.y + k * directions[i0].y);
    +    }
    +  }
    +}
    +
    +export default Mouse;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/ObjBar.html b/docs/ObjBar.html new file mode 100644 index 00000000..1c6f9b39 --- /dev/null +++ b/docs/ObjBar.html @@ -0,0 +1,4240 @@ + + + + + JSDoc: Class: ObjBar + + + + + + + + + + +
    + +

    Class: ObjBar

    + + + + + + +
    + +
    + +

    ObjBar()

    + +

    The object bar class, which is used to create the options/controls for the selected scene object.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new ObjBar()

    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + +

    Members

    + + + +

    elem

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    elem + + +HTMLElement + + + +

    The element the inputs will be populated to

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    eventListeners

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    eventListeners + + +object + + + +

    The event listeners of the obj bar.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    pendingEvent

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pendingEvent + + +function +| + +null + + + +

    The pending event to be called in case the scene object loses focus before the input is finished

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    shouldApplyToAll

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    shouldApplyToAll + + +boolean + + + +

    Whether the "Apply to all" checkbox is checked

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    shouldShowAdvanced

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    shouldShowAdvanced + + +boolean + + + +

    Whether the advanced options should be shown

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    targetObj

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    targetObj + + +SceneObject +| + +null + + + +

    The scene object whose options are being edited

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    titleElem

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    titleElem + + +HTMLElement + + + +

    The element that contains the title of the object bar

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    createBoolean(label, value, func, info, updateOnChangeopt)

    + + + + + + +
    +

    Create a boolean input in the object bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    label + + +string + + + + + + + + + + + +

    The label for the input.

    value + + +boolean + + + + + + + + + + + +

    The initial value.

    func + + +objBarValueChangeCallback + + + + + + + + + + + +

    The function to call when the value changes.

    info + + +string +| + +null + + + + + + + + + + + +

    The HTML content for the popover info box. If null (default), no info box is created.

    updateOnChange + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    Whether to update the entire obj bar (e.g. show different options) when the checkbox changes.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    createButton(label, func, updateOnChangeopt, iconopt)

    + + + + + + +
    +

    Create a button in the object bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    label + + +string + + + + + + + + + + + +

    The label for the button.

    func + + +function + + + + + + + + + + + +

    The function to call when the button is clicked.

    updateOnChange + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    Whether to update the entire obj bar (e.g. show different options) when the button is clicked.

    icon + + +string +| + +null + + + + + + <optional>
    + + + + + +
    + + null + +

    The svg icon for the button. If null (default), a default button is created.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    createDropdown(label, value, options, func, info, updateOnChangeopt)

    + + + + + + +
    +

    Create a dropdown input in the object bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    label + + +string + + + + + + + + + + + +

    The label for the input.

    value + + +string + + + + + + + + + + + +

    The initial value.

    options + + +Object +| + +Array + + + + + + + + + + + +

    The options for the dropdown. If an array, the keys are the same as the values.

    func + + +objBarValueChangeCallback + + + + + + + + + + + +

    The function to call when the value changes.

    info + + +string +| + +null + + + + + + + + + + + +

    The HTML content for the popover info box. If null (default), no info box is created.

    updateOnChange + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    Whether to update the entire obj bar (e.g. show different options) when the dropdown changes.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    createEquation(label, value, func, info)

    + + + + + + +
    +

    Create an equation input (where the value is a LaTeX string) in the object bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    label + + +string + + + +

    The label for the input.

    value + + +string + + + +

    The initial value.

    func + + +objBarValueChangeCallback + + + +

    The function to call when the value changes.

    info + + +string +| + +null + + + +

    The HTML content for the popover info box. If null (default), no info box is created.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    createInfoBox(info, elemopt)

    + + + + + + +
    +

    Create an popover info icon in the object bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDescription
    info + + +string + + + + + + + + + +

    The HTML content for the popover info box.

    elem + + +HTMLElement + + + + + + <optional>
    + + + + + +

    The element to append the info icon to. If not provided, the object bar element is used.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    createNote(content)

    + + + + + + +
    +

    Create a note in the object bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    content + + +string + + + +

    The HTML content for the note.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    createNumber(label, min, max, step, value, func, info, hideSlider)

    + + + + + + +
    +

    Create a number input in the object bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    label + + +string + + + +

    The label for the input.

    min + + +number + + + +

    The minimum value for the slider.

    max + + +number + + + +

    The maximum value for the slider.

    step + + +number + + + +

    The step value for the slider.

    value + + +number + + + +

    The initial value.

    func + + +objBarValueChangeCallback + + + +

    The function to call when the value changes.

    info + + +string +| + +null + + + +

    The HTML content for the popover info box. If null (default), no info box is created.

    hideSlider + + +boolean + + + +

    Whether to hide the slider (that is, only show the text input). Default is false.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    createText(label, value, func)

    + + + + + + +
    +

    Create a text input in the object bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    label + + +string + + + +

    The label for the input.

    value + + +string + + + +

    The initial value.

    func + + +objBarValueChangeCallback + + + +

    The function to call when the value changes.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    createTuple(label, value, func, info)

    + + + + + + +
    +

    Create a tuple input in the object bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    label + + +string + + + +

    The label for the input.

    value + + +string + + + +

    The initial value.

    func + + +objBarValueChangeCallback + + + +

    The function to call when the value changes.

    info + + +string +| + +null + + + +

    The HTML content for the popover info box. If null (default), no info box is created.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    emit(eventName, data)

    + + + + + + +
    +

    Emit an event.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    eventName + + +string + + + +

    The name of the event.

    data + + +any + + + +

    The data to be passed to the callback functions.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    on(eventName, callback)

    + + + + + + +
    +

    Add an event listener to the obj bar.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    eventName + + +string + + + +

    The name of the event.

    callback + + +function + + + +

    The callback function.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    setOption(func)

    + + + + + + +
    +

    Do the callback function that set the option. +Whether it is for all objects or just the selected one depends on the "Apply to all" checkbox.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    func + + +objBarValueChangeCallback + + + +

    The function to call.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    setTitle(title)

    + + + + + + +
    +

    Set the title of the object bar. If the title is empty, the title element is hidden.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    title + + +string + + + +

    The title of the object bar.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    showAdvanced(condition) → {boolean}

    + + + + + + +
    +

    Determine whether to create the advanced options ("More options...") in the object bar. +If this function is called, either it means that the advanced options should be populated, or the "More options..." button will be shown.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    condition + + +boolean + + + +

    The condition (of the scene object itself or some global option) to determine whether to show the advanced options.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the advanced options should be populated.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    Events

    + + + + + + + +

    edit

    + + + + + + +
    +

    The event when some value is changed but the editing may not be finished yet.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    editEnd

    + + + + + + +
    +

    The event when the editing is finished.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    requestUpdate

    + + + + + + +
    +

    The event when the entire obj bar should be updated.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    showAdvancedEnabled

    + + + + + + +
    +

    The event when the advanced options should be enabled.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    enabled + + +boolean + + + +

    Whether the advanced options should be enabled.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/ObjBar.js.html b/docs/ObjBar.js.html new file mode 100644 index 00000000..28f172c2 --- /dev/null +++ b/docs/ObjBar.js.html @@ -0,0 +1,672 @@ + + + + + JSDoc: Source: ObjBar.js + + + + + + + + + + +
    + +

    Source: ObjBar.js

    + + + + + + +
    +
    +
    import * as bootstrap from 'bootstrap';
    +import MathQuill from 'mathquill';
    +
    +const MQ = MathQuill.getInterface(2);
    +
    +/**
    + * The object bar class, which is used to create the options/controls for the selected scene object.
    + * @class
    + */
    +class ObjBar {
    +  constructor(elem, titleElem) {
    +
    +    /** @property {HTMLElement} elem - The element the inputs will be populated to */
    +    this.elem = elem;
    +
    +    /** @property {HTMLElement} titleElem - The element that contains the title of the object bar */
    +    this.titleElem = titleElem;
    +
    +    /** @property {boolean} shouldApplyToAll - Whether the "Apply to all" checkbox is checked */
    +    this.shouldApplyToAll = false;
    +
    +    /** @property {boolean} shouldShowAdvanced - Whether the advanced options should be shown */
    +    this.shouldShowAdvanced = false;
    +
    +    /** @property {SceneObject|null} targetObj - The scene object whose options are being edited */
    +    this.targetObj = null;
    +
    +    /** @property {function|null} pendingEvent - The pending event to be called in case the scene object loses focus before the input is finished */
    +    this.pendingEvent = null;
    +
    +    /** @property {object} eventListeners - The event listeners of the obj bar. */
    +    this.eventListeners = {};
    +  }
    +
    +  /**
    +   * Add an event listener to the obj bar.
    +   * @param {string} eventName - The name of the event.
    +   * @param {function} callback - The callback function.
    +   */
    +  on(eventName, callback) {
    +    if (!this.eventListeners[eventName]) {
    +      this.eventListeners[eventName] = [];
    +    }
    +    this.eventListeners[eventName].push(callback);
    +  }
    +
    +  /**
    +   * Emit an event.
    +   * @param {string} eventName - The name of the event.
    +   * @param {any} data - The data to be passed to the callback functions.
    +   */
    +  emit(eventName, data) {
    +    if (this.eventListeners[eventName]) {
    +      this.eventListeners[eventName].forEach(callback => callback(data));
    +    }
    +  }
    +
    +  /**
    +   * The event when some value is changed but the editing may not be finished yet.
    +   * @event ObjBar#edit
    +   */
    +
    +  /**
    +   * The event when the editing is finished.
    +   * @event ObjBar#editEnd
    +   */
    +
    +  /**
    +   * The event when the entire obj bar should be updated.
    +   * @event ObjBar#requestUpdate
    +   */
    +
    +  /**
    +   * The event when the advanced options should be enabled.
    +   * @event ObjBar#showAdvancedEnabled
    +   * @param {boolean} enabled - Whether the advanced options should be enabled.
    +   */
    +
    +  /**
    +   * The callback function for when a value changes.
    +   * If "Apply to all" is checked, this function will be called for each scene object of the same type.
    +   * @callback objBarValueChangeCallback
    +   * @param {Object} obj - The scene object whose value changed.
    +   * @param {any} value - The new value.
    +   */
    +
    +  /**
    +   * Set the title of the object bar. If the title is empty, the title element is hidden.
    +   * @param {string} title - The title of the object bar.
    +   */
    +  setTitle(title) {
    +    if (title) {
    +      this.titleElem.style.display = 'inline';
    +      this.titleElem.innerHTML = title;
    +    } else {
    +      this.titleElem.style.display = 'none';
    +    }
    +
    +    // If the title ends with the full-width parentheses, change the padding-right to avoid over-spacing.
    +    if (title.endsWith('\uFF09')) {
    +      this.titleElem.style.paddingRight = '0em';
    +    } else {
    +      this.titleElem.style.paddingRight = '0.4em';
    +    }
    +  }
    +
    +  /**
    +   * Create a number input in the object bar.
    +   * @param {string} label - The label for the input.
    +   * @param {number} min - The minimum value for the slider.
    +   * @param {number} max - The maximum value for the slider.
    +   * @param {number} step - The step value for the slider.
    +   * @param {number} value - The initial value.
    +   * @param {objBarValueChangeCallback} func - The function to call when the value changes.
    +   * @param {string|null} info - The HTML content for the popover info box. If null (default), no info box is created.
    +   * @param {boolean} hideSlider - Whether to hide the slider (that is, only show the text input). Default is false.
    +   */
    +  createNumber(label, min, max, step, value, func, info, hideSlider) {
    +    var nobr = document.createElement('span');
    +    nobr.className = 'obj-bar-nobr';
    +
    +    if (info) {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label;
    +      nobr.appendChild(p_name);
    +      this.createInfoBox(info, nobr);
    +    } else {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label + '&nbsp;';
    +      nobr.appendChild(p_name);
    +    }
    +
    +
    +    var objOption_text = document.createElement('input');
    +    objOption_text.type = 'text';
    +    if (value == Infinity) {
    +      objOption_text.value = 'inf';
    +    } else if (value == -Infinity) {
    +      objOption_text.value = '-inf';
    +    } else {
    +      // Round to 6 decimal places
    +      objOption_text.value = Math.round(value * 1000000) / 1000000;
    +    }
    +    objOption_text.className = 'obj-bar-editable obj-bar-number';
    +    nobr.appendChild(objOption_text);
    +
    +    var objOption_range = document.createElement('input');
    +    objOption_range.type = 'range';
    +    objOption_range.min = min;
    +    objOption_range.max = max;
    +    objOption_range.step = step;
    +    objOption_range.value = value;
    +    objOption_range.className = 'form-range';
    +    if (hideSlider) {
    +      objOption_range.style.display = 'none';
    +    }
    +    nobr.appendChild(objOption_range);
    +
    +    this.elem.appendChild(nobr);
    +
    +    var space = document.createTextNode(' ');
    +    this.elem.appendChild(space);
    +
    +    const self = this;
    +
    +    objOption_range.oninput = function () {
    +      objOption_text.value = objOption_range.value;
    +      self.setOption(function (obj) {
    +        func(obj, objOption_range.value * 1);
    +      });
    +    };
    +
    +    objOption_range.onmouseup = function () {
    +      this.blur();
    +      self.emit('editEnd', null);
    +    };
    +
    +    objOption_range.ontouchend = function () {
    +      this.blur();
    +      self.setOption(function (obj) {
    +        func(obj, objOption_range.value * 1);
    +      });
    +      self.emit('editEnd', null);
    +    };
    +    objOption_text.onchange = function () {
    +      if (objOption_text.value.toLowerCase().startsWith('inf')) {
    +        var value = Infinity;
    +      } else if (objOption_text.value.toLowerCase().startsWith('-inf')) {
    +        var value = -Infinity;
    +      } else {
    +        var value = objOption_text.value * 1;
    +      }
    +      objOption_range.value = value;
    +      self.setOption(function (obj) {
    +        func(obj, value);
    +      });
    +      self.emit('editEnd', null);
    +    };
    +    objOption_text.onkeydown = function (e) {
    +      e.cancelBubble = true;
    +      if (e.stopPropagation) e.stopPropagation();
    +    };
    +    objOption_text.onclick = function (e) {
    +      this.select();
    +    };
    +  }
    +
    +
    +  /**
    +   * Create a tuple input in the object bar.
    +   * @param {string} label - The label for the input.
    +   * @param {string} value - The initial value.
    +   * @param {objBarValueChangeCallback} func - The function to call when the value changes.
    +   * @param {string|null} info - The HTML content for the popover info box. If null (default), no info box is created.
    +   */
    +  createTuple(label, value, func, info) {
    +    var nobr = document.createElement('span');
    +    nobr.className = 'obj-bar-nobr';
    +
    +
    +
    +    if (info) {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label;
    +      nobr.appendChild(p_name);
    +      this.createInfoBox(info, nobr);
    +    } else {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label + '&nbsp;';
    +      nobr.appendChild(p_name);
    +    }
    +
    +
    +    var objOption_text = document.createElement('input');
    +    objOption_text.type = 'text';
    +    objOption_text.value = value;
    +    objOption_text.style.width = '100px';
    +    objOption_text.className = 'obj-bar-editable';
    +    nobr.appendChild(objOption_text);
    +
    +    this.elem.appendChild(nobr);
    +
    +    var space = document.createTextNode(' ');
    +    this.elem.appendChild(space);
    +
    +    const self = this;
    +
    +    objOption_text.onchange = function () {
    +      self.setOption(function (obj) {
    +        func(obj, objOption_text.value);
    +      });
    +    };
    +    objOption_text.onkeydown = function (e) {
    +      e.cancelBubble = true;
    +      if (e.stopPropagation) e.stopPropagation();
    +    };
    +    objOption_text.onblur = function () {
    +      self.emit('editEnd', null);
    +    };
    +  }
    +
    +  /**
    +   * Create a text input in the object bar.
    +   * @param {string} label - The label for the input.
    +   * @param {string} value - The initial value.
    +   * @param {objBarValueChangeCallback} func - The function to call when the value changes.
    +   */
    +  createText(label, value, func) {
    +    var p_name = document.createElement('span');
    +    p_name.innerHTML = '&nbsp;' + label + '&nbsp;';
    +    this.elem.appendChild(p_name);
    +    var objOption_text = document.createElement('textarea');
    +    objOption_text.className = 'obj-bar-editable';
    +    objOption_text.value = value;
    +    objOption_text.cols = 25;
    +    objOption_text.rows = 1;
    +    this.elem.appendChild(objOption_text);
    +    var space = document.createTextNode(' ');
    +    this.elem.appendChild(space);
    +
    +    const self = this;
    +
    +    var textEditEndTimerId = null;
    +
    +    objOption_text.oninput = function () {
    +      // if user starts adding more than one line, auto expand the text area
    +      if (objOption_text.value.split('\n').length > 1 && objOption_text.rows == 1) {
    +        objOption_text.rows = 3;
    +      }
    +      self.setOption(function (obj) {
    +        func(obj, objOption_text.value);
    +      });
    +
    +      if (textEditEndTimerId) {
    +        clearTimeout(textEditEndTimerId);
    +      }
    +      textEditEndTimerId = setTimeout(function () {
    +        self.emit('editEnd', null);
    +      }, 1000);
    +    };
    +    objOption_text.onkeydown = function (e) {
    +      e.cancelBubble = true;
    +      if (e.stopPropagation) e.stopPropagation();
    +    };
    +    objOption_text.onblur = function () {
    +      self.emit('editEnd', null);
    +    };
    +    this.pendingEvent = function () {
    +      if (textEditEndTimerId) {
    +        clearTimeout(textEditEndTimerId);
    +      }
    +      self.emit('editEnd', null);
    +    };
    +  }
    +
    +  /**
    +   * Create a boolean input in the object bar.
    +   * @param {string} label - The label for the input.
    +   * @param {boolean} value - The initial value.
    +   * @param {objBarValueChangeCallback} func - The function to call when the value changes.
    +   * @param {string|null} info - The HTML content for the popover info box. If null (default), no info box is created.
    +   * @param {boolean} [updateOnChange=false] - Whether to update the entire obj bar (e.g. show different options) when the checkbox changes.
    +   */
    +  createBoolean(label, value, func, info, updateOnChange = false) {
    +    var nobr = document.createElement('span');
    +    nobr.className = 'obj-bar-nobr';
    +
    +    if (info) {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label;
    +      nobr.appendChild(p_name);
    +      this.createInfoBox(info, nobr);
    +    } else {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label + '&nbsp;';
    +      nobr.appendChild(p_name);
    +    }
    +
    +    var wrapper = document.createElement('span');
    +    wrapper.className = 'form-switch';
    +
    +    var objOption_checkbox = document.createElement('input');
    +    objOption_checkbox.className = 'form-check-input';
    +    objOption_checkbox.type = 'checkbox';
    +    objOption_checkbox.checked = value;
    +
    +    wrapper.appendChild(objOption_checkbox);
    +    nobr.appendChild(wrapper);
    +    this.elem.appendChild(nobr);
    +    var space = document.createTextNode(' ');
    +    this.elem.appendChild(space);
    +
    +    const self = this;
    +
    +    objOption_checkbox.onchange = function () {
    +      this.blur();
    +      self.setOption(function (obj) {
    +        func(obj, objOption_checkbox.checked);
    +      });
    +      self.emit('editEnd', null);
    +      if (updateOnChange) {
    +        setTimeout(function () {
    +          self.emit('requestUpdate', null);
    +        }, 250);
    +      }
    +    };
    +  }
    +
    +  /**
    +   * Create an equation input (where the value is a LaTeX string) in the object bar.
    +   * @param {string} label - The label for the input.
    +   * @param {string} value - The initial value.
    +   * @param {objBarValueChangeCallback} func - The function to call when the value changes.
    +   * @param {string|null} info - The HTML content for the popover info box. If null (default), no info box is created.
    +   */
    +  createEquation(label, value, func, info) {
    +    var nobr = document.createElement('span');
    +    nobr.className = 'obj-bar-nobr';
    +
    +    if (info) {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label;
    +      nobr.appendChild(p_name);
    +      this.createInfoBox(info, nobr);
    +    } else {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label + '&nbsp;';
    +      nobr.appendChild(p_name);
    +    }
    +
    +    var eqnContainer = document.createElement('span');
    +    var eqnSpan = document.createElement('span');
    +    eqnSpan.className = 'obj-bar-editable';
    +    eqnSpan.style.paddingLeft = '3px';
    +    eqnSpan.style.paddingRight = '3px';
    +    eqnContainer.appendChild(eqnSpan);
    +    eqnContainer.addEventListener('keydown', function (e) {
    +      e.cancelBubble = true;
    +      if (e.stopPropagation) e.stopPropagation();
    +    });
    +    nobr.appendChild(eqnContainer);
    +    this.elem.appendChild(nobr);
    +    var space = document.createTextNode(' ');
    +    this.elem.appendChild(space);
    +
    +    const self = this;
    +
    +    var mathField = MQ.MathField(eqnSpan, {
    +      spaceBehavesLikeTab: true,
    +      leftRightIntoCmdGoes: 'up',
    +      restrictMismatchedBrackets: true,
    +      sumStartsWithNEquals: true,
    +      supSubsRequireOperand: true,
    +      charsThatBreakOutOfSupSub: '+-=<>',
    +      autoSubscriptNumerals: true,
    +      autoCommands: 'pi theta lambda sqrt sum',
    +      autoOperatorNames: 'sin cos tan sec csc cot sinh cosh tanh log exp arcsin arccos arctan asin acos atan arcsinh arccosh arctanh asinh acosh atanh floor round ceil trunc sign sgn max min abs',
    +      maxDepth: 10,
    +      handlers: {
    +        enter: function () {
    +          self.setOption(function (obj) {
    +            func(obj, mathField.latex());
    +          });
    +          self.emit('editEnd', null);
    +        }
    +      }
    +    });
    +
    +    mathField.el().querySelector('textarea').addEventListener('focusout', function () {
    +      if (self.pendingEvent) {
    +        self.pendingEvent();
    +      }
    +      self.pendingEvent = null;
    +    });
    +
    +    mathField.el().querySelector('textarea').addEventListener('focusin', function () {
    +      self.pendingEvent = function () {
    +        self.setOption(function (obj) {
    +          func(obj, mathField.latex());
    +        });
    +        self.emit('editEnd', null);
    +      };
    +    });
    +
    +    setTimeout(function () {
    +      mathField.latex(value);
    +    }, 1);
    +  }
    +
    +
    +  /**
    +   * Create a dropdown input in the object bar.
    +   * @param {string} label - The label for the input.
    +   * @param {string} value - The initial value.
    +   * @param {Object|Array} options - The options for the dropdown. If an array, the keys are the same as the values.
    +   * @param {objBarValueChangeCallback} func - The function to call when the value changes.
    +   * @param {string|null} info - The HTML content for the popover info box. If null (default), no info box is created.
    +   * @param {boolean} [updateOnChange=false] - Whether to update the entire obj bar (e.g. show different options) when the dropdown changes.
    +   */
    +  createDropdown(label, value, options, func, info, updateOnChange = false) {
    +    var nobr = document.createElement('span');
    +    nobr.className = 'obj-bar-nobr';
    +
    +    if (info) {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label;
    +      nobr.appendChild(p_name);
    +      this.createInfoBox(info, nobr);
    +    } else {
    +      var p_name = document.createElement('span');
    +      p_name.innerHTML = label + '&nbsp;';
    +      nobr.appendChild(p_name);
    +    }
    +
    +    const isArray = Array.isArray(options);
    +    var dropdown = document.createElement('select');
    +    dropdown.className = 'obj-bar-editable';
    +    for (let key in options) {
    +      var option = document.createElement('option');
    +      option.value = isArray ? options[key] : key;
    +      option.textContent = options[key];
    +      option.style.color = 'black';
    +      if (option.value == value) option.selected = true;
    +      dropdown.appendChild(option);
    +    }
    +
    +    nobr.appendChild(dropdown);
    +    this.elem.appendChild(nobr);
    +    var space = document.createTextNode(' ');
    +    this.elem.appendChild(space);
    +
    +    const self = this;
    +
    +    dropdown.onchange = function () {
    +      self.setOption(function (obj) {
    +        func(obj, dropdown.value);
    +      });
    +      if (updateOnChange) {
    +        self.emit('requestUpdate', null);
    +      }
    +      self.emit('editEnd', null);
    +    };
    +    dropdown.onclick = function (e) {
    +      //this.select();
    +    };
    +  }
    +
    +  /**
    +   * Create a button in the object bar.
    +   * @param {string} label - The label for the button.
    +   * @param {function} func - The function to call when the button is clicked.
    +   * @param {boolean} [updateOnChange=false] - Whether to update the entire obj bar (e.g. show different options) when the button is clicked.
    +   * @param {string|null} [icon=null] - The svg icon for the button. If null (default), a default button is created.
    +   */
    +  createButton(label, func, updateOnChange = false, icon = null) {
    +    var button = document.createElement('button');
    +    if (icon) {
    +      button.innerHTML = icon;
    +      button.className = 'btn';
    +      button.setAttribute('data-bs-toggle', 'tooltip');
    +      button.setAttribute('title', label);
    +      button.setAttribute('data-bs-placement', 'bottom');
    +      new bootstrap.Tooltip(button);
    +    } else {
    +      button.className = 'btn btn-secondary';
    +      button.innerHTML = label;
    +    }
    +
    +    const self = this;
    +
    +    button.onclick = function () {
    +      const isOptical = self.targetObj.constructor.isOptical;
    +      this.blur();
    +      func(self.targetObj);
    +      if (updateOnChange) {
    +        self.emit('requestUpdate', null);
    +      }
    +      self.emit('edit', null);
    +      self.emit('editEnd', null);
    +    };
    +    this.elem.appendChild(button);
    +    var space = document.createTextNode(' ');
    +    this.elem.appendChild(space);
    +  }
    +
    +  /**
    +   * Create an popover info icon in the object bar.
    +   * @param {string} info - The HTML content for the popover info box.
    +   * @param {HTMLElement} [elem] - The element to append the info icon to. If not provided, the object bar element is used.
    +   */
    +  createInfoBox(info, elem) {
    +    var infoIcon = document.createElement('span');
    +    infoIcon.className = 'info-icon';
    +    infoIcon.innerHTML = `
    +    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16">
    +      <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
    +      <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
    +    </svg>
    +    `;
    +    infoIcon.style.cursor = 'pointer';
    +    infoIcon.setAttribute('data-bs-toggle', 'popover');
    +    infoIcon.setAttribute('data-bs-trigger', 'click');
    +    infoIcon.setAttribute('data-bs-placement', 'bottom');
    +    infoIcon.setAttribute('data-bs-html', 'true');
    +    infoIcon.setAttribute('data-bs-content', info);
    +
    +    if (!elem) elem = this.elem;
    +
    +    elem.appendChild(infoIcon);
    +    new bootstrap.Popover(infoIcon);
    +  }
    +
    +  /**
    +   * Create a note in the object bar.
    +   * @param {string} content - The HTML content for the note.
    +   */
    +  createNote(content) {
    +    var note = document.createElement('span');
    +    note.innerHTML = content;
    +    note.style.marginLeft = "0.2em";
    +    note.style.marginRight = "0.2em";
    +    note.style.color = "white";
    +    this.elem.appendChild(note);
    +  }
    +
    +  /**
    +   * Do the callback function that set the option.
    +   * Whether it is for all objects or just the selected one depends on the "Apply to all" checkbox.
    +   * @param {objBarValueChangeCallback} func - The function to call.
    +   */
    +  setOption(func) {
    +    if (!this.shouldApplyToAll) {
    +      func(this.targetObj);
    +    }
    +    else {
    +      for (var i = 0; i < this.targetObj.scene.objs.length; i++) {
    +        if (this.targetObj.scene.objs[i].constructor.type == this.targetObj.constructor.type) {
    +          func(this.targetObj.scene.objs[i]);
    +        }
    +      }
    +    }
    +    this.emit('edit', null);
    +  }
    +
    +  /**
    +   * Determine whether to create the advanced options ("More options...") in the object bar.
    +   * If this function is called, either it means that the advanced options should be populated, or the "More options..." button will be shown.
    +   * @param {boolean} condition - The condition (of the scene object itself or some global option) to determine whether to show the advanced options.
    +   * @returns {boolean} Whether the advanced options should be populated.
    +   */
    +  showAdvanced(condition) {
    +    if (this.shouldShowAdvanced || condition) {
    +      return true
    +    } else {
    +      this.emit('showAdvancedEnabled', true);
    +      return false
    +    }
    +  }
    +
    +}
    +
    +export default ObjBar;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/Scene.html b/docs/Scene.html new file mode 100644 index 00000000..544003cf --- /dev/null +++ b/docs/Scene.html @@ -0,0 +1,2380 @@ + + + + + JSDoc: Class: Scene + + + + + + + + + + +
    + +

    Class: Scene

    + + + + + + +
    + +
    + +

    Scene()

    + +

    Represents the optical scene for simulation. The scene contains the instances of scene objects (from sceneObjs) and the settings of the simulation. Scene objects include optical elements (e.g. mirrors, lenses), detectors, decorations (e.g. rulers, text labels), and special objects (e.g. handles, cropboxes). It also contains the module definitions used in the scene. Since the settings of the scene may affect the behavior of the scene objects, a reference to the scene is also stored in each scene object.

    +

    The data represented by the scene can be serialized to JSON and deserialized from JSON. The JSON data format of the scene is versioned, and the version number is stored in the JSON data. The scene is backward-compatible with older versions of the JSON data format, and the scene is converted to the current version when loaded. Note that the background image of the scene is not serialized, and the viewport size is adapted to the current viewport when deserialized.

    +

    In the Ray Optics Simulator web app, a single instance is used, representing the current scene being edited and simulated, and is the main data structure of the app. The scene is serialized or deserialized to/from JSON when saving, loading, sync with URL, or undo/redo. +Some scene-unrelated settings for the app (e.g. whether to show the status box) are not stored in the scene but in the browser's local storage.

    +

    This class can also be used by other projects, including those running in a standalone environment (e.g. Node.js).

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Scene()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    name + + +string + + + +

    The name of the scene.

    modules + + +Object.<string, ModuleDef> + + + +

    The definitions of modules used in the scene.

    objs + + +Array.<BaseSceneObj> + + + +

    The objects (optical elements and/or decorations created by the user with "Tools") in the scene.

    mode + + +string + + + +

    The mode of the scene. Possible values: 'rays' (Rays), 'extended' (Extended Rays), 'images' (All Images), 'observer' (Seen by Observer).

    rayModeDensity + + +number + + + +

    The density of rays in 'rays' and 'extended' modes.

    imageModeDensity + + +number + + + +

    The density of rays in 'images' and 'observer' modes.

    showGrid + + +boolean + + + +

    The "Grid" option indicating if the grid is visible.

    snapToGrid + + +boolean + + + +

    The "Snap to Grid" option indicating if mouse actions are snapped to the grid.

    lockObjs + + +boolean + + + +

    The "Lock Objects" option indicating if the objects are locked.

    gridSize + + +number + + + +

    The size of the grid.

    observer + + +Circle +| + +null + + + +

    The observer of the scene, null if not set.

    lengthScale + + +number + + + +

    The length scale used in line width, default font size, etc in the scene.

    origin + + +Point + + + +

    The origin of the scene in the viewport.

    scale + + +number + + + +

    The scale factor (the viewport CSS pixel per internal length unit) of the scene.

    width + + +number + + + +

    The width (in CSS pixels) of the viewport.

    height + + +number + + + +

    The height (in CSS pixels) of the viewport.

    simulateColors + + +boolean + + + +

    The "Simulate Color" option indicating if the color (wavelength) of the rays is simulated (also affecting whether the options of color filtering or Cauchy coefficients of some objects are shown.)

    symbolicBodyMerging + + +boolean + + + +

    The "Symbolic body-merging" option in the gradient-index glass objects (which is a global option), indicating if the symbolic math is used to calculate the effective refractive index resulting from the "body-merging" of several gradient-index glass objects.

    randomSeed + + +string +| + +null + + + +

    The seed for the random number generator used in the simulation, null if using randomly generated seed. Using a seed allows the simulation to be deterministic for the same version of this app when randomness is used. However, reproducibility is only guaranteed if the scene is just loaded (that is, no other editing has been done on the scene). Also, reproducibility is not guaranteed across different versions of the app.

    rng + + +function + + + +

    The random number generator.

    backgroundImage + + +Object +| + +null + + + +

    The background image of the scene, null if not set.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + +

    Members

    + + + +

    opticalObjs

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    opticalObjs + + +Array.<BaseSceneObj> + + + +

    The objects in the scene which are optical. Module objects are expanded recursively. If the user edits only the non-optical part of the scene, then the content of this array will not change.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    rayDensity

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    rayDensity + + +number + + + +

    The mode-dependent ray density.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    addModule(moduleName, moduleDef) → {boolean}

    + + + + + + +
    +

    Add a module definition.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    moduleName + + +string + + + +
    moduleDef + + +ModuleDef + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the module is successfully added.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    cloneObj(index) → {BaseSceneObj}

    + + + + + + +
    +

    Clone the object at an index.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    index + + +number + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The cloned object

    +
    + + + +
    +
    + Type +
    +
    + +BaseSceneObj + + +
    +
    + + + + + + + + + + + + + +

    cloneObjsByHandle(index)

    + + + + + + +
    +

    Clone the objects bound to the handle at an index.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    index + + +number + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    loadJSON(json, callback)

    + + + + + + +
    +

    Load the scene from JSON.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    json + + +string + + + +
    callback + + +loadJSONCallback + + + +

    The callback function when the entire scene or a resource (e.g. image) is loaded.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    pushObj(obj)

    + + + + + + +
    +

    Add an object to the scene.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    obj + + +BaseSceneObj + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    removeModule(moduleName)

    + + + + + + +
    +

    Remove a given module and demodulize all corresponding module objects.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    moduleName + + +string + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    removeObj(index)

    + + + + + + +
    +

    Remove the object at an index.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    index + + +number + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    setScaleWithCenter(value, centerX, centerY)

    + + + + + + +
    +

    Set the scale of the scene while keeping a given center point fixed.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    value + + +number + + + +

    The new scale factor.

    centerX + + +number + + + +

    The x-coordinate of the center point.

    centerY + + +number + + + +

    The y-coordinate of the center point.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    unshiftObj(obj)

    + + + + + + +
    +

    Add an object to the scene at the beginning of the list.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    obj + + +BaseSceneObj + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    validateDelayed()

    + + + + + + +
    +

    Perform an delayed validation on the scene and generate warnings if necessary. This method should not be called when the editing is in progress.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/Scene.js.html b/docs/Scene.js.html new file mode 100644 index 00000000..c827c1cc --- /dev/null +++ b/docs/Scene.js.html @@ -0,0 +1,468 @@ + + + + + JSDoc: Source: Scene.js + + + + + + + + + + +
    + +

    Source: Scene.js

    + + + + + + +
    +
    +
    /**
    + * @file {@link Scene} is the class representing the optical scene for simulation, containing the instances from {@link sceneObjs} (optical elements, decorations, etc) and the settings of the scene. It is the main data structure of the app and can be serialized to (and deserialized from) JSON.
    + */
    +
    +import * as sceneObjs from './sceneObjs.js';
    +import { versionUpdate } from './versionUpdate.js';
    +import i18next from 'i18next';
    +import seedrandom from 'seedrandom';
    +
    +/**
    + * The version of the JSON data format of the scene, which matches the major version number of the app starting from version 5.0.
    + * @const {number}
    + */
    +export const DATA_VERSION = 5;
    +
    +/**
    + * Represents the optical scene for simulation. The scene contains the instances of scene objects (from {@link sceneObjs}) and the settings of the simulation. Scene objects include optical elements (e.g. mirrors, lenses), detectors, decorations (e.g. rulers, text labels), and special objects (e.g. handles, cropboxes). It also contains the module definitions used in the scene. Since the settings of the scene may affect the behavior of the scene objects, a reference to the scene is also stored in each scene object.
    + * 
    + * The data represented by the scene can be serialized to JSON and deserialized from JSON. The JSON data format of the scene is versioned, and the version number is stored in the JSON data. The scene is backward-compatible with older versions of the JSON data format, and the scene is converted to the current version when loaded. Note that the background image of the scene is not serialized, and the viewport size is adapted to the current viewport when deserialized.
    + * 
    + * In the Ray Optics Simulator web app, a single instance is used, representing the current scene being edited and simulated, and is the main data structure of the app. The scene is serialized or deserialized to/from JSON when saving, loading, sync with URL, or undo/redo.
    + * Some scene-unrelated settings for the app (e.g. whether to show the status box) are not stored in the scene but in the browser's local storage.
    + * 
    + * This class can also be used by other projects, including those running in a standalone environment (e.g. Node.js).
    + * @class
    + * @property {string} name - The name of the scene.
    + * @property {Object<string,ModuleDef>} modules - The definitions of modules used in the scene.
    + * @property {Array<BaseSceneObj>} objs - The objects (optical elements and/or decorations created by the user with "Tools") in the scene.
    + * @property {string} mode - The mode of the scene. Possible values: 'rays' (Rays), 'extended' (Extended Rays), 'images' (All Images), 'observer' (Seen by Observer).
    + * @property {number} rayModeDensity - The density of rays in 'rays' and 'extended' modes.
    + * @property {number} imageModeDensity - The density of rays in 'images' and 'observer' modes.
    + * @property {boolean} showGrid - The "Grid" option indicating if the grid is visible.
    + * @property {boolean} snapToGrid - The "Snap to Grid" option indicating if mouse actions are snapped to the grid.
    + * @property {boolean} lockObjs - The "Lock Objects" option indicating if the objects are locked.
    + * @property {number} gridSize - The size of the grid.
    + * @property {Circle|null} observer - The observer of the scene, null if not set.
    + * @property {number} lengthScale - The length scale used in line width, default font size, etc in the scene.
    + * @property {Point} origin - The origin of the scene in the viewport.
    + * @property {number} scale - The scale factor (the viewport CSS pixel per internal length unit) of the scene.
    + * @property {number} width - The width (in CSS pixels) of the viewport.
    + * @property {number} height - The height (in CSS pixels) of the viewport.
    + * @property {boolean} simulateColors - The "Simulate Color" option indicating if the color (wavelength) of the rays is simulated (also affecting whether the options of color filtering or Cauchy coefficients of some objects are shown.)
    + * @property {boolean} symbolicBodyMerging - The "Symbolic body-merging" option in the gradient-index glass objects (which is a global option), indicating if the symbolic math is used to calculate the effective refractive index resulting from the "body-merging" of several gradient-index glass objects.
    + * @property {string|null} randomSeed - The seed for the random number generator used in the simulation, null if using randomly generated seed. Using a seed allows the simulation to be deterministic for the same version of this app when randomness is used. However, reproducibility is only guaranteed if the scene is just loaded (that is, no other editing has been done on the scene). Also, reproducibility is not guaranteed across different versions of the app.
    + * @property {function} rng - The random number generator.
    + * @property {Object|null} backgroundImage - The background image of the scene, null if not set.
    + */
    +class Scene {
    +  static serializableDefaults = {
    +    name: '',
    +    modules: {},
    +    objs: [],
    +    mode: 'rays',
    +    rayModeDensity: 0.1,
    +    imageModeDensity: 1,
    +    showGrid: false,
    +    snapToGrid: false,
    +    lockObjs: false,
    +    gridSize: 20,
    +    observer: null,
    +    lengthScale: 1,
    +    origin: { x: 0, y: 0 },
    +    scale: 1,
    +    width: 1500,
    +    height: 900,
    +    simulateColors: false,
    +    symbolicBodyMerging: false,
    +    randomSeed: null
    +  };
    +
    +  constructor() {
    +    this.backgroundImage = null;
    +    this.error = null;
    +    this.warning = null;
    +    this.rng = new seedrandom(new Date().getTime().toString());
    +    this.loadJSON(JSON.stringify({ version: DATA_VERSION }), () => { });
    +  }
    +
    +  /**
    +  * Set the size (in CSS pixels) for the viewport of the scene.
    +  * @method setViewportSize
    +  * @param {number} width
    +  * @param {number} height
    +  */
    +  setViewportSize(width, height) {
    +    this.width = width;
    +    this.height = height;
    +  }
    +
    +
    +  /** @property {number} rayDensity - The mode-dependent ray density. */
    +  get rayDensity() {
    +    return this.mode == 'rays' || this.mode == 'extended' ? this.rayModeDensity : this.imageModeDensity;
    +  }
    +
    +  set rayDensity(val) {
    +    if (this.mode == 'rays' || this.mode == 'extended') {
    +      this.rayModeDensity = val;
    +    } else {
    +      this.imageModeDensity = val;
    +    }
    +  }
    +
    +  /** @property {Array<BaseSceneObj>} opticalObjs - The objects in the scene which are optical. Module objects are expanded recursively. If the user edits only the non-optical part of the scene, then the content of this array will not change. */
    +  get opticalObjs() {
    +    function expandObjs(objs) {
    +      let expandedObjs = [];
    +      for (let obj of objs) {
    +        if (obj.constructor === sceneObjs['ModuleObj']) {
    +          expandedObjs = expandedObjs.concat(expandObjs(obj.objs));
    +        } else {
    +          expandedObjs.push(obj);
    +        }
    +      }
    +      return expandedObjs;
    +    }
    +
    +    return expandObjs(this.objs).filter(obj => obj.constructor.isOptical);
    +  }
    +
    +  /**
    +   * The callback function when the entire scene or a resource (e.g. image) is loaded.
    +   * @callback loadJSONCallback
    +   * @param {boolean} needFullUpdate - Whether the scene needs a full update.
    +   * @param {boolean} completed - Whether the scene is completely loaded.
    +   */
    +
    +  /**
    +  * Load the scene from JSON.
    +  * @param {string} json
    +  * @param {loadJSONCallback} callback - The callback function when the entire scene or a resource (e.g. image) is loaded.
    +  */
    +  loadJSON(json, callback) {
    +    this.error = null;
    +    this.warning = null;
    +    try {
    +      let jsonData = JSON.parse(json);
    +
    +      // Convert the scene from old versions if necessary.
    +      if (!jsonData.version || jsonData.version < DATA_VERSION) {
    +        jsonData = versionUpdate(jsonData);
    +      } else if (jsonData.version > DATA_VERSION) {
    +        // Newer than the current version
    +        throw new Error('The version of the scene is newer than the current version of the simulator.');
    +      }
    +
    +      const serializableDefaults = Scene.serializableDefaults;
    +
    +      const originalWidth = this.width || serializableDefaults.width;
    +      const originalHeight = this.height || serializableDefaults.height;
    +
    +      // Take the approximated size of the current viewport, which may be different from that of the scene to be loaded.
    +      const approximatedWidth = Math.ceil(originalWidth / 100) * 100;
    +      const approximatedHeight = Math.ceil(originalHeight / 100) * 100;
    +
    +      // Set the properties of the scene. Use the default properties if the JSON data does not contain them.
    +      for (let key in serializableDefaults) {
    +        if (!(key in jsonData)) {
    +          jsonData[key] = JSON.parse(JSON.stringify(serializableDefaults[key]));
    +        }
    +        this[key] = jsonData[key];
    +      }
    +
    +      // Rescale the scene to fit the current viewport.
    +      let rescaleFactor = 1;
    +
    +      if (jsonData.width / jsonData.height > approximatedWidth / approximatedHeight) {
    +        rescaleFactor = jsonData.width / approximatedWidth;
    +      } else {
    +        rescaleFactor = jsonData.height / approximatedHeight;
    +      }
    +
    +      this.scale = jsonData.scale / rescaleFactor;
    +      this.origin.x = jsonData.origin.x / rescaleFactor;
    +      this.origin.y = jsonData.origin.y / rescaleFactor;
    +      this.width = originalWidth;
    +      this.height = originalHeight;
    +
    +      // Load the random number generator.
    +      if (this.randomSeed) {
    +        this.rng = new seedrandom(this.randomSeed);
    +      } else {
    +        this.rng = new seedrandom(new Date().getTime().toString());
    +      }
    +
    +      // Load the objects in the scene.
    +      this.objs = jsonData.objs.map(objData =>
    +        new sceneObjs[objData.type](this, objData)
    +      );
    +
    +      // Load the background image.
    +      if (jsonData.backgroundImage) {
    +        this.backgroundImage = new Image();
    +        this.backgroundImage.src = "../gallery/" + jsonData.backgroundImage;
    +        this.backgroundImage.onload = function (e1) {
    +          callback(false, true);
    +        }
    +        callback(true, false);
    +      } else {
    +        // The JSON data does not contain the background image. Currently this does not mean that we should clear the background image (as the undo/redo history does not currently store it). However, this may change in the future.
    +        callback(true, true);
    +      }
    +    } catch (e) {
    +      this.error = e.toString();
    +      this.objs = [];
    +      callback(true, true);
    +    }
    +  }
    +
    +  /**
    +   * Convert the scene to JSON.
    +   * @method toJSON
    +   * @returns {string} The JSON string representing the scene.
    +   */
    +  toJSON() {
    +    let jsonData = { version: DATA_VERSION };
    +
    +    // Put the name of the scene first.
    +    if (this.name) {
    +      jsonData.name = this.name;
    +    }
    +
    +    // And then the module definitions.
    +    if (Object.keys(this.modules).length > 0) {
    +      jsonData.modules = this.modules;
    +    }
    +
    +    // Serialize the objects in the scene.
    +    jsonData.objs = this.objs.map(obj => obj.serialize());
    +
    +    // Use approximated size of the current viewport.
    +    const approximatedWidth = Math.ceil(this.width / 100) * 100;
    +    const approximatedHeight = Math.ceil(this.height / 100) * 100;
    +    jsonData.width = approximatedWidth;
    +    jsonData.height = approximatedHeight;
    +
    +    // Export the rest of non-default properties.
    +    const serializableDefaults = Scene.serializableDefaults;
    +    for (let propName in serializableDefaults) {
    +      if (!jsonData.hasOwnProperty(propName)) {
    +        const stringifiedValue = JSON.stringify(this[propName]);
    +        const stringifiedDefault = JSON.stringify(serializableDefaults[propName]);
    +        if (stringifiedValue !== stringifiedDefault) {
    +          jsonData[propName] = JSON.parse(stringifiedValue);
    +        }
    +      }
    +    }
    +
    +    return JSON.stringify(jsonData, null, 2);
    +  }
    +
    +  /**
    +   * Add an object to the scene.
    +   * @param {BaseSceneObj} obj
    +   */
    +  pushObj(obj) {
    +    this.objs.push(obj);
    +    obj.scene = this;
    +  }
    +
    +  /**
    +   * Add an object to the scene at the beginning of the list.
    +   * @param {BaseSceneObj} obj
    +   */
    +  unshiftObj(obj) {
    +    this.objs.unshift(obj);
    +    obj.scene = this;
    +    
    +    // Update `targetObjIndex` of all handle objects.
    +    for (var i in this.objs) {
    +      if (this.objs[i].constructor.type == "Handle") {
    +        for (var j in this.objs[i].controlPoints) {
    +          this.objs[i].controlPoints[j].targetObjIndex++;
    +        }
    +      }
    +    }
    +  }
    +
    +  /**
    +   * Remove the object at an index.
    +   * @param {number} index
    +   */
    +  removeObj(index) {
    +    for (var i = index; i < this.objs.length - 1; i++) {
    +      let oldObj = this.objs[i+1].serialize();
    +      this.objs[i] = new sceneObjs[oldObj.type](this, oldObj);
    +    }
    +  
    +    for (var i in this.objs) {
    +      if (this.objs[i].constructor.type == "Handle") {
    +        for (var j in this.objs[i].controlPoints) {
    +          if (this.objs[i].controlPoints[j].targetObjIndex > index) {
    +            this.objs[i].controlPoints[j].targetObjIndex--;
    +          } else if (this.objs[i].controlPoints[j].targetObjIndex == index) {
    +            this.objs[i].controlPoints = [];
    +            break;
    +          }
    +        }
    +      }
    +    }
    +
    +    this.objs.length = this.objs.length - 1;
    +  }
    +
    +  /**
    +   * Clone the object at an index.
    +   * @param {number} index
    +   * @returns {BaseSceneObj} The cloned object
    +   */
    +  cloneObj(index) {
    +    let oldObj = this.objs[index].serialize();
    +    this.objs[this.objs.length] = new sceneObjs[oldObj.type](this, oldObj);
    +    return this.objs[this.objs.length - 1];
    +  }
    +
    +  /**
    +   * Clone the objects bound to the handle at an index.
    +   * @param {number} index
    +   */
    +  cloneObjsByHandle(index) {
    +    let handle = this.objs[index];
    +    if (handle.constructor.type !== "Handle") {
    +      return;
    +    }
    +
    +    var indices = [];
    +    for (var j in handle.controlPoints) {
    +      if (indices.indexOf(handle.controlPoints[j].targetObjIndex) == -1) {
    +        indices.push(handle.controlPoints[j].targetObjIndex);
    +      }
    +    }
    +    //console.log(indices);
    +    for (var j in indices) {
    +      if (this.objs[indices[j]].constructor.type != "Handle") {
    +        this.cloneObj(indices[j]);
    +      }
    +    }
    +  }
    +
    +  /**
    +   * Add a module definition.
    +   * @param {string} moduleName
    +   * @param {ModuleDef} moduleDef
    +   * @returns {boolean} Whether the module is successfully added.
    +   */
    +  addModule(moduleName, moduleDef) {
    +    this.modules[moduleName] = moduleDef;
    +
    +    // Update all module objects.
    +    for (let i in this.objs) {
    +      if (this.objs[i].constructor.type === "ModuleObj") {
    +        this.objs[i] = new sceneObjs.ModuleObj(this, this.objs[i].serialize());
    +      }
    +    }
    +
    +    return true;
    +  }
    +
    +  /**
    +   * Remove a given module and demodulize all corresponding module objects.
    +   * @param {string} moduleName 
    +   */
    +  removeModule(moduleName) {
    +    mainLoop: while (true) {
    +      for (let obj of this.objs) {
    +        if (obj.constructor.type === "ModuleObj" && obj.module === moduleName) {
    +          obj.demodulize();
    +          continue mainLoop;
    +        }
    +      }
    +      break;
    +    }
    +
    +    delete this.modules[moduleName];
    +  }
    +
    +  /**
    +   * Set the scale of the scene while keeping a given center point fixed.
    +   * @param {number} value - The new scale factor.
    +   * @param {number} centerX - The x-coordinate of the center point.
    +   * @param {number} centerY - The y-coordinate of the center point.
    +   */
    +  setScaleWithCenter(value, centerX, centerY) {
    +    const scaleChange = value - this.scale;
    +    this.origin.x *= value / this.scale;
    +    this.origin.y *= value / this.scale;
    +    this.origin.x -= centerX * scaleChange;
    +    this.origin.y -= centerY * scaleChange;
    +    this.scale = value;
    +  }
    +
    +  /**
    +   * Perform an delayed validation on the scene and generate warnings if necessary. This method should not be called when the editing is in progress.
    +   */
    +  validateDelayed() {
    +    if (this.error) {
    +      return;
    +    }
    +    this.warning = null;
    +  
    +    // Check if there are identical optical objects
    +    const opticalObjs = this.opticalObjs;
    +  
    +    if (opticalObjs.length < 100) {
    +      const stringifiedObjs = opticalObjs.map(obj => JSON.stringify(obj));
    +      for (var i = 0; i < opticalObjs.length; i++) {
    +        for (var j = i + 1; j < opticalObjs.length; j++) {
    +          if (stringifiedObjs[i] == stringifiedObjs[j]) {
    +            this.warning = `opticalObjs[${i}]==[${j}] ${opticalObjs[i].constructor.type}: ` + i18next.t('simulator:generalWarnings.identicalObjects');
    +            break;
    +          }
    +        }
    +      }
    +    }
    +  }
    +};
    +
    +export default Scene;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/Simulator.html b/docs/Simulator.html new file mode 100644 index 00000000..e1419afc --- /dev/null +++ b/docs/Simulator.html @@ -0,0 +1,3851 @@ + + + + + JSDoc: Class: Simulator + + + + + + + + + + +
    + +

    Class: Simulator

    + + + + + + +
    + +
    + +

    Simulator(scene, ctxMain, ctxBelowLight, ctxAboveLight, ctxGrid, ctxVirtual, enableTimer, rayCountLimitopt)

    + +

    The simulator class, which simulates the optical system described by the Scene class and renders the scene (optical elements, decorations, rays, etc) on the canvas layers.

    +

    When a ray interacts with an object (optical element) in the scene, the object itself is responsible for handling the interaction, and the simulator only call the related methods of the object. See onSimulationStart, checkRayIntersects and onRayIncident in the BaseSceneObj class for more information. The rendering of the object is also a method draw of the object itself called by the simulator.

    +

    In the Ray Optics Simulator web app, a single instance of this class is used in the entire session to simulate the scene interactively. updateSimulation is called whenever the scene is updated. If the simulation is too long, the simulator will automatically pause and resume to prevent the browser from not responding, and emit the simulationPause event to notify the UI to update the simulation status. When exporting the scene to PNG or SVG, a new instance of this class is created and updateSimulation is called once to render the scene without pausing.

    +

    This class can also be used by other projects, including those running in a standalone environment (e.g. Node.js) to simulate and render the scene without the UI. Note however that even if one is only interested in the numerical results (e.g. detector readings), the canvas layers are still required for the simulator to work properly. In the future, a headless mode may be implemented to allow the simulator to run without the canvas layers.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Simulator(scene, ctxMain, ctxBelowLight, ctxAboveLight, ctxGrid, ctxVirtual, enableTimer, rayCountLimitopt)

    + + + + + + +
    +

    Creates a new Simulator instance.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    scene + + +Scene + + + + + + + + + + + +

    The scene to be simulated.

    ctxMain + + +CanvasRenderingContext2D +| + +C2S + + + + + + + + + + + +

    The default context for drawing the scene.

    ctxBelowLight + + +CanvasRenderingContext2D +| + +C2S + + + + + + + + + + + +

    The context for drawing the scene below the light layer.

    ctxAboveLight + + +CanvasRenderingContext2D +| + +C2S + + + + + + + + + + + +

    The context for drawing the scene above the light layer.

    ctxGrid + + +CanvasRenderingContext2D +| + +C2S + + + + + + + + + + + +

    The context for drawing the grid layer.

    ctxVirtual + + +CanvasRenderingContext2D + + + + + + + + + + + +

    The virtual context for color adjustment.

    enableTimer + + +boolean + + + + + + + + + + + +

    Whether to enable the timer for the simulation.

    rayCountLimit + + +number + + + + + + <optional>
    + + + + + +
    + + Infinity + +

    The maximum number of processed rays in the simulation.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + +

    Members

    + + + +

    MIN_RAY_SEGMENT_LENGTH

    + + + + +
    +

    The minimal length between two interactions with rays (when smaller than this, the interaction will be ignored). Also the threshold for surface merging.

    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    brightnessScale

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    brightnessScale + + +number + + + +

    The brightness scale of the simulation. 0 if undetermined, -1 if inconsistent.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    ctxAboveLight

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ctxAboveLight + + +CanvasRenderingContext2D +| + +C2S + + + +

    The context for drawing the this.scene above the light layer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    ctxBelowLight

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ctxBelowLight + + +CanvasRenderingContext2D +| + +C2S + + + +

    The context for drawing the this.scene below the light layer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    ctxGrid

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ctxGrid + + +CanvasRenderingContext2D +| + +C2S + + + +

    The context for drawing the grid layer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    ctxMain

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ctxMain + + +CanvasRenderingContext2D +| + +C2S + + + +

    The default context for drawing the this.scene. If other layers are present, this is the context for drawing the light layer only.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    ctxVirtual

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ctxVirtual + + +CanvasRenderingContext2D + + + +

    The virtual context for color adjustment.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    dpr

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    dpr + + +number + + + +

    The device pixel ratio of the canvases.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    enableTimer

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    enableTimer + + +boolean + + + +

    Whether to enable the timer for the simulation so that it automatically pauses and resumes when the simulation is too long.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string + + + +

    The error message of the simulation.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    eventListeners

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    eventListeners + + +object + + + +

    The event listeners of the simulator.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isSVG

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    isSVG + + +boolean + + + +

    Whether the canvas is being exported to SVG.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    pendingRays

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pendingRays + + +Array.<Ray> + + + +

    The rays to be processed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    processedRayCount

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    processedRayCount + + +number + + + +

    The number of rays processed in the simulation.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    rayCountLimit

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    rayCountLimit + + +number + + + +

    The maximum number of processed rays in the simulation. When this limit is reached, the simulation will stop.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene to be simulated.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    shouldSimulatorStop

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    shouldSimulatorStop + + +boolean + + + +

    Whether the simulation should stop immediately in the next step of the timer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    simulationStartTime

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    simulationStartTime + + +Date + + + +

    The time when the simulation starts.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    simulationTimerId

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    simulationTimerId + + +number + + + +

    The ID of the timer for the simulation.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    totalTruncation

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    totalTruncation + + +number + + + +

    The total truncated brightness of rays in the infinite series of internal reflection during the simulation.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string + + + +

    The warning message of the simulation.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    emit(eventName, data)

    + + + + + + +
    +

    Emit an event.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    eventName + + +string + + + +

    The name of the event.

    data + + +any + + + +

    The data to be passed to the callback functions.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    on(eventName, callback)

    + + + + + + +
    +

    Add an event listener to the simulator.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    eventName + + +string + + + +

    The name of the event.

    callback + + +function + + + +

    The callback function.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    stopSimulation() → {void}

    + + + + + + +
    +

    Stop the simulation.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +void + + +
    +
    + + + + + + + + + + + + + +

    updateSimulation(skipLight, skipGrid) → {void}

    + + + + + + +
    +

    Run the simulation and draw the this.scene on the canvases.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    skipLight + + +boolean + + + +

    Whether to skip the light layer.

    skipGrid + + +boolean + + + +

    Whether to skip the grid layer.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +void + + +
    +
    + + + + + + + + + + + + + +

    validate() → {void}

    + + + + + + +
    +

    Check the simulation and display warnings or errors if necessary.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +void + + +
    +
    + + + + + + + + + + + + + +

    Events

    + + + + + + + +

    simulationComplete

    + + + + + + +
    +

    The event emitted when the simulation completes (all the rays are processed completely).

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    simulationPause

    + + + + + + +
    +

    The event emitted when the simulation pauses (when the timer is enabled and the maximum continue running time is exceeded).

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    simulationStart

    + + + + + + +
    +

    The event emitted when the simulation starts.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    simulationStop

    + + + + + + +
    +

    The event emitted when the simulation stops (when the maximum number of processed rays is reached or if the user force stop the simulation).

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/Simulator.js.html b/docs/Simulator.js.html new file mode 100644 index 00000000..d8f918ae --- /dev/null +++ b/docs/Simulator.js.html @@ -0,0 +1,886 @@ + + + + + JSDoc: Source: Simulator.js + + + + + + + + + + +
    + +

    Source: Simulator.js

    + + + + + + +
    +
    +
    /**
    + * @file {@link Simulator} is the class for simulating the optical system described by the {@link Scene} class and rendering the scene (optical elements, decorations, rays, etc) on the canvas layers. It can also be used in a standalone environment (e.g. Node.js).
    + */
    +
    +import CanvasRenderer from './CanvasRenderer.js';
    +import geometry from './geometry.js';
    +import * as C2S from 'canvas2svg';
    +import * as sceneObjs from './sceneObjs.js';
    +
    +/**
    + * @typedef {Object} Ray
    + * @property {Point} p1 - The starting point of the ray.
    + * @property {Point} p2 - Another point on the ray.
    + * @property {number} brightness_s - he intensity of the s-polarization component of the ray.
    + * @property {number} brightness_p - The intensity of the p-polarization component of the ray. In this simulator the two polarization components are assumed to be of no phase coherence.
    + * @property {number} [wavelength] - The wavelength of the ray in nanometers. Only has effect when "Simulate Colors" is on.
    + * @property {boolean} gap - Whether the ray is the first ray in a bunch of "continuous" rays. This is for the detection of images to work correctly. The intersection of two rays is considered as a candidate of an image only if the second ray has `gap === false`.
    + * @property {boolean} isNew - Whether the ray is just emitted by a source. This is to avoid drawing trivial initial extensions in the "Extended rays" mode.
    + */
    +
    +/**
    + * The simulator class, which simulates the optical system described by the {@link Scene} class and renders the scene (optical elements, decorations, rays, etc) on the canvas layers.
    + * 
    + * When a ray interacts with an object (optical element) in the scene, the object itself is responsible for handling the interaction, and the simulator only call the related methods of the object. See `onSimulationStart`, `checkRayIntersects` and `onRayIncident` in the {@link BaseSceneObj} class for more information. The rendering of the object is also a method `draw` of the object itself called by the simulator.
    + * 
    + * In the Ray Optics Simulator web app, a single instance of this class is used in the entire session to simulate the scene interactively. `updateSimulation` is called whenever the scene is updated. If the simulation is too long, the simulator will automatically pause and resume to prevent the browser from not responding, and emit the `simulationPause` event to notify the UI to update the simulation status. When exporting the scene to PNG or SVG, a new instance of this class is created and `updateSimulation` is called once to render the scene without pausing.
    + * 
    + * This class can also be used by other projects, including those running in a standalone environment (e.g. Node.js) to simulate and render the scene without the UI. Note however that even if one is only interested in the numerical results (e.g. detector readings), the canvas layers are still required for the simulator to work properly. In the future, a headless mode may be implemented to allow the simulator to run without the canvas layers.
    + * @class
    + */
    +class Simulator {
    +  
    +  /**
    +   * The minimal length between two interactions with rays (when smaller than this, the interaction will be ignored). Also the threshold for surface merging.
    +   */
    +  static MIN_RAY_SEGMENT_LENGTH = 1e-6;
    +  static MIN_RAY_SEGMENT_LENGTH_SQUARED = Simulator.MIN_RAY_SEGMENT_LENGTH * Simulator.MIN_RAY_SEGMENT_LENGTH;
    +
    +  static UV_WAVELENGTH = 380;
    +  static VIOLET_WAVELENGTH = 420;
    +  static BLUE_WAVELENGTH = 460;
    +  static CYAN_WAVELENGTH = 500;
    +  static GREEN_WAVELENGTH = 540;
    +  static YELLOW_WAVELENGTH = 580;
    +  static RED_WAVELENGTH = 620;
    +  static INFRARED_WAVELENGTH = 700;
    +
    +  /**
    +   * Creates a new Simulator instance.
    +   * @param {Scene} scene - The scene to be simulated.
    +   * @param {CanvasRenderingContext2D|C2S} ctxMain - The default context for drawing the scene.
    +   * @param {CanvasRenderingContext2D|C2S} ctxBelowLight - The context for drawing the scene below the light layer.
    +   * @param {CanvasRenderingContext2D|C2S} ctxAboveLight - The context for drawing the scene above the light layer.
    +   * @param {CanvasRenderingContext2D|C2S} ctxGrid - The context for drawing the grid layer.
    +   * @param {CanvasRenderingContext2D} ctxVirtual - The virtual context for color adjustment.
    +   * @param {boolean} enableTimer - Whether to enable the timer for the simulation.
    +   * @param {number} [rayCountLimit=Infinity] - The maximum number of processed rays in the simulation.
    +   */
    +  constructor(scene, ctxMain, ctxBelowLight, ctxAboveLight, ctxGrid, ctxVirtual, enableTimer, rayCountLimit = Infinity) {
    +    /** @property {Scene} scene - The scene to be simulated. */
    +    this.scene = scene;
    +
    +    this.scene.simulator = this; // This circular reference is currently only used by Detector to access `totalTruncation` and CropBox to access `processedRayCount`.
    +
    +    /** @property {CanvasRenderingContext2D|C2S} ctxMain - The default context for drawing the this.scene. If other layers are present, this is the context for drawing the light layer only. */
    +    this.ctxMain = ctxMain;
    +
    +    /** @property {CanvasRenderingContext2D|C2S} ctxBelowLight - The context for drawing the this.scene below the light layer. */
    +    this.ctxBelowLight = ctxBelowLight;
    +
    +    /** @property {CanvasRenderingContext2D|C2S} ctxAboveLight - The context for drawing the this.scene above the light layer. */
    +    this.ctxAboveLight = ctxAboveLight;
    +
    +    /** @property {CanvasRenderingContext2D|C2S} ctxGrid - The context for drawing the grid layer. */
    +    this.ctxGrid = ctxGrid;
    +
    +    /** @property {CanvasRenderingContext2D} ctxVirtual - The virtual context for color adjustment. */
    +    this.ctxVirtual = ctxVirtual;
    +
    +    if (typeof C2S !== 'undefined' && ctxMain.constructor === C2S) {
    +      /** @property {boolean} isSVG - Whether the canvas is being exported to SVG. */
    +      this.isSVG = true;
    +    }
    +
    +    /** @property {number} dpr - The device pixel ratio of the canvases. */
    +    this.dpr = 1;
    +
    +    /** @property {boolean} enableTimer - Whether to enable the timer for the simulation so that it automatically pauses and resumes when the simulation is too long. */
    +    this.enableTimer = enableTimer;
    +
    +    /** @property {number} rayCountLimit - The maximum number of processed rays in the simulation. When this limit is reached, the simulation will stop. */
    +    this.rayCountLimit = rayCountLimit;
    +
    +    /** @property {Ray[]} pendingRays - The rays to be processed. */
    +    this.pendingRays = [];
    +
    +    /** @property {number} simulationTimerId - The ID of the timer for the simulation. */
    +    this.simulationTimerId = -1;
    +
    +    /** @property {boolean} shouldSimulatorStop - Whether the simulation should stop immediately in the next step of the timer. */
    +    this.shouldSimulatorStop = false;
    +
    +    /** @property {Date} simulationStartTime - The time when the simulation starts. */
    +    this.simulationStartTime = null;
    +
    +    /** @property {number} totalTruncation - The total truncated brightness of rays in the infinite series of internal reflection during the simulation. */
    +    this.totalTruncation = 0;
    +
    +    /** @property {number} brightnessScale - The brightness scale of the simulation. 0 if undetermined, -1 if inconsistent. */
    +    this.brightnessScale = 0;
    +
    +    /** @property {number} processedRayCount - The number of rays processed in the simulation. */
    +    this.processedRayCount = 0;
    +
    +    /** @property {string} error - The error message of the simulation. */
    +    this.error = null;
    +
    +    /** @property {string} warning - The warning message of the simulation. */
    +    this.warning = null;
    +
    +    /** @property {object} eventListeners - The event listeners of the simulator. */
    +    this.eventListeners = {};
    +  }
    +
    +  /**
    +   * Add an event listener to the simulator.
    +   * @param {string} eventName - The name of the event.
    +   * @param {function} callback - The callback function.
    +   */
    +  on(eventName, callback) {
    +    if (!this.eventListeners[eventName]) {
    +      this.eventListeners[eventName] = [];
    +    }
    +    this.eventListeners[eventName].push(callback);
    +  }
    +
    +  /**
    +   * Emit an event.
    +   * @param {string} eventName - The name of the event.
    +   * @param {any} data - The data to be passed to the callback functions.
    +   */
    +  emit(eventName, data) {
    +    if (this.eventListeners[eventName]) {
    +      this.eventListeners[eventName].forEach(callback => callback(data));
    +    }
    +  }
    +
    +  /**
    +   * The event emitted when the simulation starts.
    +   * @event Simulator#simulationStart
    +   */
    +
    +  /**
    +   * The event emitted when the simulation pauses (when the timer is enabled and the maximum continue running time is exceeded).
    +   * @event Simulator#simulationPause
    +   */
    +
    +  /**
    +   * The event emitted when the simulation completes (all the rays are processed completely).
    +   * @event Simulator#simulationComplete
    +   */
    +
    +  /**
    +   * The event emitted when the simulation stops (when the maximum number of processed rays is reached or if the user force stop the simulation).
    +   * @event Simulator#simulationStop
    +   */
    +
    +  /**
    +   * The event when the error and warning messages in the UI should be updated.
    +   * @event requestUpdateErrorAndWarning
    +   */
    +
    +  /**
    +   * Run the simulation and draw the this.scene on the canvases.
    +   * @param {boolean} skipLight - Whether to skip the light layer.
    +   * @param {boolean} skipGrid - Whether to skip the grid layer.
    +   * @returns {void}
    +   */
    +  updateSimulation(skipLight, skipGrid) {
    +    if (!skipLight) {
    +      this.totalTruncation = 0;
    +      this.brightnessScale = 0;
    +      //clearError();
    +      //clearWarning();
    +      this.simulationStartTime = new Date();
    +      this.emit('simulationStart', null);
    +    }
    +
    +    if (!skipLight && this.simulationTimerId != -1) {
    +      // If still handling the last draw, then stop
    +      clearTimeout(this.simulationTimerId);
    +      this.simulationTimerId = -1;
    +    }
    +
    +    if (this.ctxBelowLight && this.ctxAboveLight) {
    +      this.canvasRendererBelowLight = new CanvasRenderer(this.ctxBelowLight, { x: this.scene.origin.x * this.dpr, y: this.scene.origin.y * this.dpr }, (this.scene.scale * this.dpr), this.scene.lengthScale, this.scene.backgroundImage);
    +      this.canvasRendererAboveLight = new CanvasRenderer(this.ctxAboveLight, { x: this.scene.origin.x * this.dpr, y: this.scene.origin.y * this.dpr }, (this.scene.scale * this.dpr), this.scene.lengthScale);
    +    }
    +
    +    if (!skipLight) {
    +      this.canvasRendererMain = new CanvasRenderer(this.ctxMain, { x: this.scene.origin.x * this.dpr, y: this.scene.origin.y * this.dpr }, (this.scene.scale * this.dpr), this.scene.lengthScale);
    +
    +      if (this.isSVG) {
    +        this.ctxMain.translate(this.scene.origin.x / (this.scene.scale * this.dpr), this.scene.origin.y / (this.scene.scale * this.dpr));
    +        this.ctxMain.globalAlpha = 1;
    +      } else {
    +        this.ctxAboveLight.globalAlpha = 1;
    +      }
    +      this.pendingRays = [];
    +      this.processedRayCount = 0;
    +    }
    +
    +    if (!skipGrid && this.ctxGrid) {
    +
    +      this.canvasRendererGrid = new CanvasRenderer(this.ctxGrid, { x: this.scene.origin.x * this.dpr, y: this.scene.origin.y * this.dpr }, (this.scene.scale * this.dpr), this.scene.lengthScale);
    +
    +      if (this.scene.showGrid) {
    +        // Draw the grid
    +
    +        this.ctxGrid.save();
    +        this.ctxGrid.setTransform((this.scene.scale * this.dpr), 0, 0, (this.scene.scale * this.dpr), 0, 0);
    +        var dashstep = 4 * this.scene.lengthScale;
    +
    +        this.ctxGrid.strokeStyle = 'rgb(255,255,255,0.25)';
    +        this.ctxGrid.lineWidth = 1 * this.scene.lengthScale;
    +
    +        var dashPattern;
    +        if (dashstep * this.scene.scale <= 2) {
    +          // The dash pattern is too dense, so we just draw a solid line
    +          dashPattern = [];
    +        } else {
    +          // Set up the dash pattern: [dash length, space length]
    +          var dashPattern = [dashstep * 0.5, dashstep * 0.5];
    +        }
    +
    +        // Apply the dash pattern to the context
    +        this.ctxGrid.setLineDash(dashPattern);
    +
    +        // Draw vertical dashed lines
    +        this.ctxGrid.beginPath();
    +        for (var x = this.scene.origin.x / this.scene.scale % this.scene.gridSize; x <= this.ctxGrid.canvas.width / (this.scene.scale * this.dpr); x += this.scene.gridSize) {
    +          this.ctxGrid.moveTo(x, this.scene.origin.y / this.scene.scale % this.scene.gridSize - this.scene.gridSize);
    +          this.ctxGrid.lineTo(x, this.ctxGrid.canvas.height / (this.scene.scale * this.dpr));
    +        }
    +        this.ctxGrid.stroke();
    +
    +        // Draw horizontal dashed lines
    +        this.ctxGrid.beginPath();
    +        for (var y = this.scene.origin.y / this.scene.scale % this.scene.gridSize; y <= this.ctxGrid.canvas.height / (this.scene.scale * this.dpr); y += this.scene.gridSize) {
    +          this.ctxGrid.moveTo(this.scene.origin.x / this.scene.scale % this.scene.gridSize - this.scene.gridSize, y);
    +          this.ctxGrid.lineTo(this.ctxGrid.canvas.width / (this.scene.scale * this.dpr), y);
    +        }
    +        this.ctxGrid.stroke();
    +        this.ctxGrid.setLineDash([]);
    +        this.ctxGrid.restore();
    +      }
    +    }
    +
    +
    +    if (!(!this.ctxBelowLight && skipLight)) {
    +      // Sort the objects with z-index.
    +      var mapped = this.scene.objs.map(function (obj, i) {
    +        return { index: i, value: obj.getZIndex() };
    +      });
    +      mapped.sort(function (a, b) {
    +        return a.value - b.value;
    +      });
    +      // Draw the objects
    +      for (var j = 0; j < this.scene.objs.length; j++) {
    +        var i = mapped[j].index;
    +        
    +        if (this.scene.editor) {
    +          var isHovered = this.scene.editor.hoveredObjIndex === i;
    +        } else {
    +          var isHovered = false;
    +        }
    +        this.scene.objs[i].draw((!this.ctxBelowLight) ? this.canvasRendererMain : this.canvasRendererBelowLight, false, isHovered);
    +
    +      }
    +
    +      if (!skipLight) {
    +        // Initialize the simulation (e.g. add the rays and reset the detector readings)
    +        for (let obj of this.scene.opticalObjs) {
    +          const ret = obj.onSimulationStart();
    +          if (ret) {
    +            if (ret.newRays) {
    +              for (let newRay of ret.newRays) {
    +                this.pendingRays.push(newRay);
    +              }
    +            }
    +            if (ret.truncation) {
    +              this.totalTruncation += ret.truncation;
    +            }
    +            if (ret.brightnessScale) {
    +              if (this.brightnessScale == 0) {
    +                this.brightnessScale = ret.brightnessScale;
    +              } else if (this.brightnessScale != ret.brightnessScale) {
    +                this.brightnessScale = -1;
    +              }
    +            }
    +          }
    +        }
    +      }
    +
    +    }
    +
    +    if (!skipLight) {
    +      this.leftRayCount = 0;
    +      this.last_s_obj_index = -1;
    +      this.last_ray = null;
    +      this.last_intersection = null;
    +      this.pendingRaysIndex = -1;
    +      this.firstBreak = true;
    +      this.processRays();
    +    }
    +
    +    if (skipLight) {
    +      // Draw the "above light" layer of this.scene.objs. Note that we only draw this when skipLight is true because otherwise processRays() will be called and the "above light" layer will still be drawn, since draw() is called again in processRays() with skipLight set to true.
    +
    +      for (var i = 0; i < this.scene.objs.length; i++) {
    +        if (this.scene.editor) {
    +          var isHovered = this.scene.editor.hoveredObjIndex === i;
    +        } else {
    +          var isHovered = false;
    +        }
    +        this.scene.objs[i].draw((!this.ctxAboveLight) ? this.canvasRendererMain : this.canvasRendererAboveLight, true, isHovered); // Draw this.scene.objs[i]
    +      }
    +      if (this.scene.mode == 'observer') {
    +        // Draw the observer
    +        this.ctxAboveLight.globalAlpha = 1;
    +        this.ctxAboveLight.beginPath();
    +        this.ctxAboveLight.fillStyle = 'blue';
    +        this.ctxAboveLight.arc(this.scene.observer.c.x, this.scene.observer.c.y, this.scene.observer.r, 0, Math.PI * 2, false);
    +        this.ctxAboveLight.fill();
    +      }
    +    }
    +
    +    this.emit('requestUpdateErrorAndWarning');
    +
    +  }
    +
    +  /**
    +   * Process the rays in `this.pendingRays` during the simulation.
    +   * @returns {void}
    +   * @private
    +   */
    +  processRays() {
    +    this.simulationTimerId = -1;
    +    var st_time = new Date();
    +    var alpha0 = 1;
    +    this.ctxMain.globalAlpha = alpha0;
    +    var observed;
    +    var s_obj;
    +    var s_obj_index;
    +    var s_point;
    +    var s_point_temp;
    +    var s_lensq;
    +    var s_lensq_temp;
    +    var observed_point;
    +    var observed_intersection;
    +    var rpd;
    +    var surfaceMergingObjs = [];
    +
    +    const opticalObjs = this.scene.opticalObjs;
    +
    +    if (this.scene.simulateColors) {
    +      this.ctxMain.globalCompositeOperation = 'screen';
    +    }
    +
    +    while (true) {
    +      if (new Date() - st_time > 50 && this.enableTimer) {
    +        // If already run for 200ms
    +        // Pause for 10ms and continue (prevent not responding)
    +        this.simulationTimerId = setTimeout(() => this.processRays(), this.firstBreak ? 100 : 1);
    +        this.firstBreak = false;
    +
    +        this.emit('simulationPause', null);
    +
    +        this.updateSimulation(true, true); // Redraw the opticalObjs to avoid outdated information (e.g. detector readings).
    +
    +        this.validate();
    +        return;
    +      }
    +      if (this.processedRayCount > this.rayCountLimit) {
    +        this.shouldSimulatorStop = true;
    +        break;
    +      }
    +      if (this.shouldSimulatorStop) break;
    +      if (this.pendingRaysIndex >= this.pendingRays.length) {
    +        if (this.leftRayCount == 0) {
    +          break;
    +        }
    +        this.leftRayCount = 0;
    +        this.last_s_obj_index = -1;
    +        this.last_ray = null;
    +        this.last_intersection = null;
    +        this.pendingRaysIndex = -1;
    +        continue;
    +      }
    +      this.pendingRaysIndex++;
    +
    +
    +
    +
    +
    +      var j = this.pendingRaysIndex;
    +      if (this.pendingRays[j]) {
    +        // Start handling this.pendingRays[j]
    +        // Test which object will this ray shoot on first
    +
    +        // Search every object intersected with the ray, and find which intersection is the nearest
    +        s_obj = null; // The current nearest object in search
    +        s_obj_index = -1;
    +        s_point = null;  // The intersection
    +        surfaceMergingObjs = []; // The objects whose surface is to be merged with s_obj
    +        s_lensq = Infinity;
    +        observed = false; // Whether this.pendingRays[j] is observed by the observer
    +        for (var i = 0; i < opticalObjs.length; i++) {
    +          // Test whether opticalObjs[i] intersects with the ray
    +          s_point_temp = opticalObjs[i].checkRayIntersects(this.pendingRays[j]);
    +          if (s_point_temp) {
    +            // Here opticalObjs[i] intersects with the ray at s_point_temp
    +            s_lensq_temp = geometry.distanceSquared(this.pendingRays[j].p1, s_point_temp);
    +            if (s_point && geometry.distanceSquared(s_point_temp, s_point) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale && (opticalObjs[i].constructor.supportsSurfaceMerging || s_obj.constructor.supportsSurfaceMerging)) {
    +              // The ray is shot on two objects at the same time, and at least one of them supports surface merging
    +
    +              if (s_obj.constructor.supportsSurfaceMerging) {
    +                if (opticalObjs[i].constructor.supportsSurfaceMerging) {
    +                  // Both of them supports surface merging (e.g. two glasses with one common edge
    +                  surfaceMergingObjs[surfaceMergingObjs.length] = opticalObjs[i];
    +                }
    +                else {
    +                  // Only the first shot object supports surface merging
    +                  // Set the object to be shot to be the one not supporting surface merging (e.g. if one surface of a glass coincides with a blocker, then only block the ray)
    +                  s_obj = opticalObjs[i];
    +                  s_obj_index = i;
    +                  s_point = s_point_temp;
    +                  s_lensq = s_lensq_temp;
    +
    +                  surfaceMergingObjs = [];
    +                }
    +              }
    +            }
    +            else if (s_lensq_temp < s_lensq && s_lensq_temp > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +              s_obj = opticalObjs[i]; // Update the object to be shot
    +              s_obj_index = i;
    +              s_point = s_point_temp;
    +              s_lensq = s_lensq_temp;
    +
    +              surfaceMergingObjs = [];
    +            }
    +          }
    +        }
    +        if (this.scene.simulateColors) {
    +          var color = Simulator.wavelengthToColor(this.pendingRays[j].wavelength, (this.pendingRays[j].brightness_s + this.pendingRays[j].brightness_p), !this.isSVG);
    +        } else {
    +          this.ctxMain.globalAlpha = alpha0 * (this.pendingRays[j].brightness_s + this.pendingRays[j].brightness_p);
    +        }
    +        // If not shot on any object
    +        if (s_lensq == Infinity) {
    +          if (this.scene.mode == 'rays' || this.scene.mode == 'extended') {
    +            if (this.scene.simulateColors) {
    +              this.canvasRendererMain.drawRay(this.pendingRays[j], color); // Draw the ray
    +            } else {
    +              this.canvasRendererMain.drawRay(this.pendingRays[j], 'rgb(255,255,128)'); // Draw the ray
    +            }
    +          }
    +          if (this.scene.mode == 'extended' && !this.pendingRays[j].isNew) {
    +            if (this.scene.simulateColors) {
    +              this.ctxMain.setLineDash([2 * this.scene.lengthScale, 2 * this.scene.lengthScale]);
    +              this.canvasRendererMain.drawRay(geometry.line(this.pendingRays[j].p1, geometry.point(this.pendingRays[j].p1.x * 2 - this.pendingRays[j].p2.x, this.pendingRays[j].p1.y * 2 - this.pendingRays[j].p2.y)), color); // Draw the extension of the ray
    +              this.ctxMain.setLineDash([]);
    +            } else {
    +              this.canvasRendererMain.drawRay(geometry.line(this.pendingRays[j].p1, geometry.point(this.pendingRays[j].p1.x * 2 - this.pendingRays[j].p2.x, this.pendingRays[j].p1.y * 2 - this.pendingRays[j].p2.y)), 'rgb(255,128,0)'); // Draw the extension of the ray
    +            }
    +          }
    +
    +          if (this.scene.mode == 'observer') {
    +            observed_point = geometry.lineCircleIntersections(this.pendingRays[j], this.scene.observer)[2];
    +            if (observed_point) {
    +              if (geometry.intersectionIsOnRay(observed_point, this.pendingRays[j])) {
    +                observed = true;
    +              }
    +            }
    +          }
    +        }
    +        else {
    +          // Here the ray will be shot on s_obj at s_point after traveling for s_len
    +          if (this.scene.mode == 'rays' || this.scene.mode == 'extended') {
    +            if (this.scene.simulateColors) {
    +              this.canvasRendererMain.drawSegment(geometry.line(this.pendingRays[j].p1, s_point), color); // Draw the ray
    +            } else {
    +              this.canvasRendererMain.drawSegment(geometry.line(this.pendingRays[j].p1, s_point), 'rgb(255,255,128)'); // Draw the ray
    +            }
    +          }
    +          if (this.scene.mode == 'extended' && !this.pendingRays[j].isNew) {
    +            if (this.scene.simulateColors) {
    +              this.ctxMain.setLineDash([2 * this.scene.lengthScale, 2 * this.scene.lengthScale]);
    +              this.canvasRendererMain.drawRay(geometry.line(this.pendingRays[j].p1, geometry.point(this.pendingRays[j].p1.x * 2 - this.pendingRays[j].p2.x, this.pendingRays[j].p1.y * 2 - this.pendingRays[j].p2.y)), color); // Draw the backward extension of the ray
    +              this.ctxMain.setLineDash([1 * this.scene.lengthScale, 5 * this.scene.lengthScale]);
    +              this.canvasRendererMain.drawRay(geometry.line(s_point, geometry.point(s_point.x * 2 - this.pendingRays[j].p1.x, s_point.y * 2 - this.pendingRays[j].p1.y)), color); // Draw the forward extension of the ray
    +              this.ctxMain.setLineDash([]);
    +            } else {
    +              this.canvasRendererMain.drawRay(geometry.line(this.pendingRays[j].p1, geometry.point(this.pendingRays[j].p1.x * 2 - this.pendingRays[j].p2.x, this.pendingRays[j].p1.y * 2 - this.pendingRays[j].p2.y)), 'rgb(255,128,0)'); // Draw the backward extension of the ray
    +              this.canvasRendererMain.drawRay(geometry.line(s_point, geometry.point(s_point.x * 2 - this.pendingRays[j].p1.x, s_point.y * 2 - this.pendingRays[j].p1.y)), 'rgb(80,80,80)'); // Draw the forward extension of the ray
    +            }
    +
    +          }
    +
    +          if (this.scene.mode == 'observer') {
    +            observed_point = geometry.lineCircleIntersections(this.pendingRays[j], this.scene.observer)[2];
    +
    +            if (observed_point) {
    +
    +              if (geometry.intersectionIsOnSegment(observed_point, geometry.line(this.pendingRays[j].p1, s_point))) {
    +                observed = true;
    +              }
    +            }
    +          }
    +        }
    +        if (this.scene.mode == 'observer' && this.last_ray) {
    +          if (!this.pendingRays[j].gap) {
    +            observed_intersection = geometry.linesIntersection(this.pendingRays[j], this.last_ray); // The intersection of the observed rays
    +
    +            if (observed) {
    +              if (this.last_intersection && geometry.distanceSquared(this.last_intersection, observed_intersection) < 25 * this.scene.lengthScale * this.scene.lengthScale) {
    +                // If the intersections are near each others
    +                if (geometry.intersectionIsOnRay(observed_intersection, geometry.line(observed_point, this.pendingRays[j].p1)) && geometry.distanceSquared(observed_point, this.pendingRays[j].p1) > 1e-5 * this.scene.lengthScale * this.scene.lengthScale) {
    +
    +
    +                  if (this.scene.simulateColors) {
    +                    var color = Simulator.wavelengthToColor(this.pendingRays[j].wavelength, (this.pendingRays[j].brightness_s + this.pendingRays[j].brightness_p) * 0.5, !this.isSVG);
    +                  } else {
    +                    this.ctxMain.globalAlpha = alpha0 * ((this.pendingRays[j].brightness_s + this.pendingRays[j].brightness_p) + (this.last_ray.brightness_s + this.last_ray.brightness_p)) * 0.5;
    +                  }
    +                  if (s_point) {
    +                    rpd = (observed_intersection.x - this.pendingRays[j].p1.x) * (s_point.x - this.pendingRays[j].p1.x) + (observed_intersection.y - this.pendingRays[j].p1.y) * (s_point.y - this.pendingRays[j].p1.y);
    +                  }
    +                  else {
    +                    rpd = (observed_intersection.x - this.pendingRays[j].p1.x) * (this.pendingRays[j].p2.x - this.pendingRays[j].p1.x) + (observed_intersection.y - this.pendingRays[j].p1.y) * (this.pendingRays[j].p2.y - this.pendingRays[j].p1.y);
    +                  }
    +                  if (rpd < 0) {
    +                    // Virtual image
    +                    if (this.scene.simulateColors) {
    +                      this.ctxMain.fillStyle = color;
    +                      this.ctxMain.fillRect(observed_intersection.x - 1.5 * this.scene.lengthScale, observed_intersection.y - 1.5 * this.scene.lengthScale, 3 * this.scene.lengthScale, 3 * this.scene.lengthScale);
    +                    } else {
    +                      this.canvasRendererMain.drawPoint(observed_intersection, 'rgb(255,128,0)'); // Draw the image
    +                    }
    +                  }
    +                  else if (rpd < s_lensq) {
    +                    // Real image
    +                    if (this.scene.simulateColors) {
    +                      this.canvasRendererMain.drawPoint(observed_intersection, color); // Draw the image
    +                    } else {
    +                      this.canvasRendererMain.drawPoint(observed_intersection, 'rgb(255,255,128)'); // Draw the image
    +                    }
    +                  }
    +                  if (this.scene.simulateColors) {
    +                    this.ctxMain.setLineDash([1 * this.scene.lengthScale, 2 * this.scene.lengthScale]);
    +                    this.canvasRendererMain.drawSegment(geometry.line(observed_point, observed_intersection), color); // Draw the observed ray
    +                    this.ctxMain.setLineDash([]);
    +                  } else {
    +                    this.canvasRendererMain.drawSegment(geometry.line(observed_point, observed_intersection), 'rgb(0,0,255)'); // Draw the observed ray
    +                  }
    +                }
    +                else {
    +                  if (this.scene.simulateColors) {
    +                    this.ctxMain.setLineDash([1 * this.scene.lengthScale, 2 * this.scene.lengthScale]);
    +                    this.canvasRendererMain.drawRay(geometry.line(observed_point, this.pendingRays[j].p1), color); // Draw the observed ray
    +                    this.ctxMain.setLineDash([]);
    +                  } else {
    +                    this.canvasRendererMain.drawRay(geometry.line(observed_point, this.pendingRays[j].p1), 'rgb(0,0,255)'); // Draw the observed ray
    +                  }
    +                }
    +              }
    +              else {
    +                if (this.last_intersection) {
    +                  if (this.scene.simulateColors) {
    +                    this.ctxMain.setLineDash([1 * this.scene.lengthScale, 2 * this.scene.lengthScale]);
    +                    this.canvasRendererMain.drawRay(geometry.line(observed_point, this.pendingRays[j].p1), color); // Draw the observed ray
    +                    this.ctxMain.setLineDash([]);
    +                  } else {
    +                    this.canvasRendererMain.drawRay(geometry.line(observed_point, this.pendingRays[j].p1), 'rgb(0,0,255)'); // Draw the observed ray
    +                  }
    +                }
    +              }
    +            }
    +            this.last_intersection = observed_intersection;
    +          }
    +          else {
    +            this.last_intersection = null;
    +          }
    +        }
    +
    +        if (this.scene.mode == 'images' && this.last_ray) {
    +          if (!this.pendingRays[j].gap) {
    +
    +            observed_intersection = geometry.linesIntersection(this.pendingRays[j], this.last_ray);
    +            if (this.last_intersection && geometry.distanceSquared(this.last_intersection, observed_intersection) < 25 * this.scene.lengthScale * this.scene.lengthScale) {
    +              if (this.scene.simulateColors) {
    +                var color = Simulator.wavelengthToColor(this.pendingRays[j].wavelength, (this.pendingRays[j].brightness_s + this.pendingRays[j].brightness_p) * 0.5, !this.isSVG);
    +              } else {
    +                this.ctxMain.globalAlpha = alpha0 * ((this.pendingRays[j].brightness_s + this.pendingRays[j].brightness_p) + (this.last_ray.brightness_s + this.last_ray.brightness_p)) * 0.5;
    +              }
    +
    +              if (s_point) {
    +                rpd = (observed_intersection.x - this.pendingRays[j].p1.x) * (s_point.x - this.pendingRays[j].p1.x) + (observed_intersection.y - this.pendingRays[j].p1.y) * (s_point.y - this.pendingRays[j].p1.y);
    +              }
    +              else {
    +                rpd = (observed_intersection.x - this.pendingRays[j].p1.x) * (this.pendingRays[j].p2.x - this.pendingRays[j].p1.x) + (observed_intersection.y - this.pendingRays[j].p1.y) * (this.pendingRays[j].p2.y - this.pendingRays[j].p1.y);
    +              }
    +
    +              if (rpd < 0) {
    +                // Virtual image
    +                if (this.scene.simulateColors) {
    +                  this.ctxMain.fillStyle = color;
    +                  this.ctxMain.fillRect(observed_intersection.x - 1.5 * this.scene.lengthScale, observed_intersection.y - 1.5 * this.scene.lengthScale, 3 * this.scene.lengthScale, 3 * this.scene.lengthScale);
    +                } else {
    +                  this.canvasRendererMain.drawPoint(observed_intersection, 'rgb(255,128,0)'); // Draw the image
    +                }
    +              }
    +              else if (rpd < s_lensq) {
    +                // Real image
    +                if (this.scene.simulateColors) {
    +                  this.canvasRendererMain.drawPoint(observed_intersection, color); // Draw the image
    +                } else {
    +                  this.canvasRendererMain.drawPoint(observed_intersection, 'rgb(255,255,128)'); // Draw the image
    +                }
    +              }
    +              else {
    +                // Virtual object
    +                if (this.scene.simulateColors) {
    +                  this.ctxMain.fillStyle = color;
    +                  this.ctxMain.fillRect(observed_intersection.x - 0.5 * this.scene.lengthScale, observed_intersection.y - 0.5 * this.scene.lengthScale, 1 * this.scene.lengthScale, 1 * this.scene.lengthScale);
    +                } else {
    +                  this.canvasRendererMain.drawPoint(observed_intersection, 'rgb(80,80,80)');
    +                }
    +              }
    +            }
    +            this.last_intersection = observed_intersection;
    +          }
    +
    +        }
    +
    +        if (this.last_s_obj_index != s_obj_index) {
    +          this.pendingRays[j].gap = true;
    +        }
    +        this.pendingRays[j].isNew = false;
    +
    +        this.last_ray = { p1: this.pendingRays[j].p1, p2: this.pendingRays[j].p2 };
    +        this.last_s_obj_index = s_obj_index;
    +        if (s_obj) {
    +          const ret = s_obj.onRayIncident(this.pendingRays[j], j, s_point, surfaceMergingObjs);
    +          if (ret) {
    +            if (ret.isAbsorbed) {
    +              this.pendingRays[j] = null;
    +            }
    +            if (ret.newRays) {
    +              for (let newRay of ret.newRays) {
    +                this.pendingRays.push(newRay);
    +              }
    +            }
    +            if (ret.truncation) {
    +              this.totalTruncation += ret.truncation;
    +            }
    +          }
    +        }
    +        else {
    +          this.pendingRays[j] = null;
    +        }
    +
    +        this.processedRayCount = this.processedRayCount + 1;
    +        if (this.pendingRays[j]) {
    +          this.leftRayCount = this.leftRayCount + 1;
    +        }
    +      }
    +    }
    +
    +    //}
    +    if (this.scene.simulateColors && !this.isSVG) {
    +      // Inverse transformation of the color adjustment made in Simulator.wavelengthToColor.
    +      // This is to avoid the color satiation problem when using the 'lighter' composition.
    +      // Currently not supported when exporting to SVG.
    +
    +
    +      this.ctxVirtual.canvas.width = this.ctxMain.canvas.width;
    +      this.ctxVirtual.canvas.height = this.ctxMain.canvas.height;
    +
    +      this.ctxVirtual.drawImage(this.ctxMain.canvas, 0, 0);
    +
    +      var imageData = this.ctxVirtual.getImageData(0.0, 0.0, this.ctxVirtual.canvas.width, this.ctxVirtual.canvas.height);
    +      var data = imageData.data;
    +      for (var i = 0; i < data.length; i += 4) {
    +        if (data[i + 3] == 0) continue; // Skip transparent pixels
    +        var a0 = data[i + 3] / 256;
    +        var R = - Math.log(1 - (data[i] / 256)) * a0;
    +        var G = - Math.log(1 - (data[i + 1] / 256)) * a0;
    +        var B = - Math.log(1 - (data[i + 2] / 256)) * a0;
    +        var factor = Math.max(R, G, B);
    +        var r = 255 * R / factor;
    +        var g = 255 * G / factor;
    +        var b = 255 * B / factor;
    +        data[i] = r;
    +        data[i + 1] = g;
    +        data[i + 2] = b;
    +        data[i + 3] = 255 * Math.min(factor, 1);
    +      }
    +      this.ctxVirtual.putImageData(imageData, 0, 0);
    +      this.ctxMain.globalCompositeOperation = 'source-over';
    +
    +      this.ctxMain.setTransform(1, 0, 0, 1, 0, 0);
    +      this.ctxMain.clearRect(0, 0, this.ctxMain.canvas.width, this.ctxMain.canvas.height);
    +      this.ctxMain.drawImage(this.ctxVirtual.canvas, 0, 0);
    +      this.ctxAboveLight.setTransform(this.scene.scale * this.dpr, 0, 0, this.scene.scale * this.dpr, this.scene.origin.x * this.dpr, this.scene.origin.y * this.dpr);
    +    }
    +    this.ctxMain.globalAlpha = 1.0;
    +    
    +    this.updateSimulation(true, true);
    +
    +    this.validate();
    +
    +    if (this.shouldSimulatorStop) {
    +      this.emit('simulationStop', null);
    +      
    +      this.shouldSimulatorStop = false;
    +    } else {
    +      this.emit('simulationComplete', null);
    +    }
    +  }
    +
    +  /**
    +   * Stop the simulation.
    +   * @returns {void}
    +   */
    +  stopSimulation() {
    +    if (this.simulationTimerId != -1) {
    +      this.shouldSimulatorStop = true;
    +    }
    +  }
    +
    +  /**
    +   * Check the simulation and display warnings or errors if necessary.
    +   * @returns {void}
    +   */
    +  validate() {
    +    if (this.brightnessScale == -1) {
    +      let hasDetector = false;
    +      for (let obj of this.scene.opticalObjs) {
    +        if (obj instanceof sceneObjs["Detector"]) {
    +          hasDetector = true;
    +          break;
    +        }
    +      }
    +      if (hasDetector || this.scene.simulateColors) {
    +        this.warning = i18next.t('simulator:generalWarnings.brightnessInconsistent');
    +      } else {
    +        this.warning = null;
    +      }
    +    } else {
    +      this.warning = null;
    +    }
    +  }
    +
    +  static wavelengthToColor(wavelength, brightness, transform) {
    +    // From https://scienceprimer.com/javascript-code-convert-light-wavelength-color
    +    var R,
    +      G,
    +      B,
    +      alpha,
    +      wl = wavelength;
    +
    +    if (wl >= Simulator.UV_WAVELENGTH && wl < Simulator.VIOLET_WAVELENGTH) {
    +      R = 0.5;
    +      G = 0;
    +      B = 1;
    +    } else if (wl >= Simulator.VIOLET_WAVELENGTH && wl < Simulator.BLUE_WAVELENGTH) {
    +      R = -0.5 * (wl - Simulator.BLUE_WAVELENGTH) / (Simulator.BLUE_WAVELENGTH - Simulator.VIOLET_WAVELENGTH);
    +      G = 0;
    +      B = 1;
    +    } else if (wl >= Simulator.BLUE_WAVELENGTH && wl < Simulator.CYAN_WAVELENGTH) {
    +      R = 0;
    +      G = (wl - Simulator.BLUE_WAVELENGTH) / (Simulator.CYAN_WAVELENGTH - Simulator.BLUE_WAVELENGTH);
    +      B = 1;
    +    } else if (wl >= Simulator.CYAN_WAVELENGTH && wl < Simulator.GREEN_WAVELENGTH) {
    +      R = 0;
    +      G = 1;
    +      B = -1 * (wl - Simulator.GREEN_WAVELENGTH) / (Simulator.GREEN_WAVELENGTH - Simulator.CYAN_WAVELENGTH);
    +    } else if (wl >= Simulator.GREEN_WAVELENGTH && wl < Simulator.YELLOW_WAVELENGTH) {
    +      R = (wl - Simulator.GREEN_WAVELENGTH) / (Simulator.YELLOW_WAVELENGTH - Simulator.GREEN_WAVELENGTH);
    +      G = 1;
    +      B = 0;
    +    } else if (wl >= Simulator.YELLOW_WAVELENGTH && wl < Simulator.RED_WAVELENGTH) {
    +      R = 1;
    +      G = -1 * (wl - Simulator.RED_WAVELENGTH) / (Simulator.RED_WAVELENGTH - Simulator.YELLOW_WAVELENGTH);
    +      B = 0.0;
    +    } else if (wl >= Simulator.RED_WAVELENGTH && wl <= Simulator.INFRARED_WAVELENGTH) {
    +      R = 1;
    +      G = 0;
    +      B = 0;
    +    } else {
    +      R = 0;
    +      G = 0;
    +      B = 0;
    +    }
    +
    +    // intensty is lower at the edges of the visible spectrum.
    +    if (wl > Simulator.INFRARED_WAVELENGTH || wl < Simulator.UV_WAVELENGTH) {
    +      alpha = 0;
    +    } else if (wl > Simulator.RED_WAVELENGTH) {
    +      alpha = (Simulator.INFRARED_WAVELENGTH - wl) / (Simulator.INFRARED_WAVELENGTH - Simulator.RED_WAVELENGTH);
    +    } else if (wl < Simulator.VIOLET_WAVELENGTH) {
    +      alpha = (wl - Simulator.UV_WAVELENGTH) / (Simulator.VIOLET_WAVELENGTH - Simulator.UV_WAVELENGTH);
    +    } else {
    +      alpha = 1;
    +    }
    +
    +    R *= alpha * brightness;
    +    G *= alpha * brightness;
    +    B *= alpha * brightness;
    +
    +    if (transform) {
    +      // Adjust color to make (R,G,B) linear when using the 'screen' composition.
    +      // This is to avoid the color satiation problem when using the 'lighter' composition.
    +      // Currently not supported when exporting to SVG as it is currently under draft in CSS Color 4 
    +      R = 1 - Math.exp(-R);
    +      G = 1 - Math.exp(-G);
    +      B = 1 - Math.exp(-B);
    +    }
    +
    +    return "rgb(" + Math.round(R * 255) + "," + Math.round(G * 255) + "," + Math.round(B * 255) + ")";
    +
    +  }
    +}
    +
    +export default Simulator;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/app.js.html b/docs/app.js.html new file mode 100644 index 00000000..3a584341 --- /dev/null +++ b/docs/app.js.html @@ -0,0 +1,2052 @@ + + + + + JSDoc: Source: app.js + + + + + + + + + + +
    + +

    Source: app.js

    + + + + + + +
    +
    +
    /**
    + * @file `app.js` is the main entry point for the Ray Optics Simulator web app. It handles the initialzation of the UI and the main instances of {@link Scene}, {@link Simulator} and {@link Editor}, and binds events to them. It also handles some app-level operation such as loading files.
    + */
    +
    +import * as bootstrap from 'bootstrap';
    +import 'bootstrap/scss/bootstrap.scss';
    +import '../css/style.scss';
    +import * as $ from 'jquery';
    +import Editor from './Editor.js';
    +import Simulator from './Simulator.js';
    +import geometry from './geometry.js';
    +import Scene from './Scene.js';
    +import { DATA_VERSION } from './Scene.js';
    +import ObjBar from './ObjBar.js';
    +import * as ace from 'ace-builds';
    +import "ace-builds/webpack-resolver";
    +import 'ace-builds/src-noconflict/theme-github_dark';
    +import 'ace-builds/src-noconflict/mode-json';
    +import "ace-builds/src-noconflict/worker-json";
    +import { Range } from 'ace-builds';
    +import * as sceneObjs from './sceneObjs.js';
    +import { saveAs } from 'file-saver';
    +import i18next, { t } from 'i18next';
    +import HttpBackend from 'i18next-http-backend';
    +
    +const isDevelopment = process.env.NODE_ENV === 'development';
    +
    +async function startApp() {
    +  await i18next.use(HttpBackend).init({
    +    lng: window.lang,
    +    debug: isDevelopment,
    +    fallbackLng: 'en',
    +    load: 'currentOnly',
    +    ns: ['main', 'simulator'],
    +    backend: {
    +      loadPath: '../locales/{{lng}}/{{ns}}.json',
    +    },
    +    interpolation: {
    +      escapeValue: false
    +    }
    +  });
    +
    +  try {
    +    if (localStorage.rayOpticsHelp == "off") {
    +      popoversEnabled = false;
    +      document.getElementById('show_help_popups').checked = false;
    +    }
    +  } catch { }
    +  initUIText();
    +  initTools();
    +  initModes();
    +
    +  let dpr = window.devicePixelRatio || 1;
    +
    +  canvas = document.getElementById('canvasAboveLight');
    +  canvasBelowLight = document.getElementById('canvasBelowLight');
    +  canvasLight = document.getElementById('canvasLight');
    +  canvasGrid = document.getElementById('canvasGrid');
    +
    +  canvas.width = window.innerWidth * dpr;
    +  canvas.height = window.innerHeight * dpr;
    +
    +  canvasBelowLight.width = window.innerWidth * dpr;
    +  canvasBelowLight.height = window.innerHeight * dpr;
    +
    +  canvasLight.width = window.innerWidth * dpr;
    +  canvasLight.height = window.innerHeight * dpr;
    +
    +  canvasGrid.width = window.innerWidth * dpr;
    +  canvasGrid.height = window.innerHeight * dpr;
    +
    +  objBar = new ObjBar(document.getElementById('obj_bar_main'), document.getElementById('obj_name'));
    +
    +  objBar.on('showAdvancedEnabled', function (enabled) {
    +    if (enabled) {
    +      document.getElementById('showAdvanced').style.display = '';
    +      document.getElementById('showAdvanced_mobile_container').style.display = '';
    +    } else {
    +      document.getElementById('showAdvanced').style.display = 'none';
    +      document.getElementById('showAdvanced_mobile_container').style.display = 'none';
    +    }
    +  });
    +
    +  objBar.on('edit', function () {
    +    simulator.updateSimulation(!objBar.targetObj.constructor.isOptical, true);
    +  });
    +
    +  objBar.on('editEnd', function () {
    +    editor.onActionComplete();
    +  });
    +
    +  objBar.on('requestUpdate', function () {
    +    editor.selectObj(editor.selectedObjIndex);
    +  });
    +
    +  document.getElementById('apply_to_all').addEventListener('change', function () {
    +    objBar.shouldApplyToAll = this.checked;
    +  });
    +
    +  scene = new Scene();
    +
    +  simulator = new Simulator(scene,
    +    canvasLight.getContext('2d'),
    +    canvasBelowLight.getContext('2d'),
    +    canvasAboveLight.getContext('2d'),
    +    canvasGrid.getContext('2d'),
    +    document.createElement('canvas').getContext('2d'),
    +    true
    +  );
    +
    +  simulator.dpr = dpr;
    +
    +  simulator.on('simulationStart', function () {
    +    document.getElementById('forceStop').style.display = 'none';
    +  });
    +
    +  simulator.on('simulationPause', function () {
    +    document.getElementById('forceStop').style.display = '';
    +    document.getElementById('simulatorStatus').innerHTML = i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.rayCount'), value: simulator.processedRayCount}) + '<br>' + i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.totalTruncation'), value: simulator.totalTruncation.toFixed(3)}) + '<br>' + i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.brightnessScale'), value: ((simulator.brightnessScale <= 0) ? "-" : simulator.brightnessScale.toFixed(3))}) + '<br>' + i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.timeElapsed') + ' (ms)', value: (new Date() - simulator.simulationStartTime)}) + '<br>';
    +  });
    +
    +  simulator.on('simulationStop', function () {
    +    document.getElementById('simulatorStatus').innerHTML = i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.rayCount'), value: simulator.processedRayCount}) + '<br>' + i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.totalTruncation'), value: simulator.totalTruncation.toFixed(3)}) + '<br>' + i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.brightnessScale'), value: ((simulator.brightnessScale <= 0) ? "-" : simulator.brightnessScale.toFixed(3))}) + '<br>' + i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.timeElapsed') + ' (ms)', value: (new Date() - simulator.simulationStartTime)}) + '<br>' + i18next.t('simulator:statusBox.forceStopped');
    +    document.getElementById('forceStop').style.display = 'none';
    +  });
    +
    +  simulator.on('simulationComplete', function () {
    +    document.getElementById('simulatorStatus').innerHTML = i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.rayCount'), value: simulator.processedRayCount}) + '<br>' + i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.totalTruncation'), value: simulator.totalTruncation.toFixed(3)}) + '<br>' + i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.brightnessScale'), value: ((simulator.brightnessScale <= 0) ? "-" : simulator.brightnessScale.toFixed(3))}) + '<br>' + i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.timeElapsed') + ' (ms)', value: (new Date() - simulator.simulationStartTime)});
    +    document.getElementById('forceStop').style.display = 'none';
    +  });
    +
    +  simulator.on('requestUpdateErrorAndWarning', function () {
    +    updateErrorAndWarning();
    +  });
    +
    +  editor = new Editor(scene, canvas, simulator);
    +
    +  editor.on('positioningStart', function (e) {
    +    document.getElementById('xybox').style.left = (e.dragContext.targetPoint.x * scene.scale + scene.origin.x) + 'px';
    +    document.getElementById('xybox').style.top = (e.dragContext.targetPoint.y * scene.scale + scene.origin.y) + 'px';
    +    document.getElementById('xybox').value = '(' + (e.dragContext.targetPoint.x) + ',' + (e.dragContext.targetPoint.y) + ')';
    +    document.getElementById('xybox').size = document.getElementById('xybox').value.length;
    +    document.getElementById('xybox').style.display = '';
    +    document.getElementById('xybox').select();
    +    document.getElementById('xybox').setSelectionRange(1, document.getElementById('xybox').value.length - 1);
    +    //console.log("show xybox");
    +    xyBox_cancelContextMenu = true;
    +  });
    +
    +  editor.on('requestPositioningComfirm', function (e) {
    +    confirmPositioning(e.ctrl, e.shift);
    +  });
    +
    +  editor.on('positioningEnd', function (e) {
    +    document.getElementById('xybox').style.display = 'none';
    +  });
    +
    +  editor.on('mouseCoordinateChange', function (e) {
    +    if (e.mousePos) {
    +      const mousePosDigits = Math.max(Math.round(Math.log10(scene.scale)), 0);
    +      document.getElementById('mouseCoordinates').innerHTML = i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.mouseCoordinates'), value: "(" + e.mousePos.x.toFixed(mousePosDigits) + ", " + e.mousePos.y.toFixed(mousePosDigits) + ")"});
    +    } else {
    +      document.getElementById('mouseCoordinates').innerHTML = i18next.t('main:meta.colon', {name: i18next.t('simulator:statusBox.mouseCoordinates'), value: '-'});
    +    }
    +  });
    +
    +  editor.emit('mouseCoordinateChange', { mousePos: null });
    +
    +  editor.on('selectionChange', function (e) {
    +    hideAllPopovers();
    +    if (objBar.pendingEvent) {
    +      // If the user is in the middle of editing a value, then clearing the innerHTML of obj_bar_main will cause the change event not to fire, so we need to manually fire it.
    +      objBar.pendingEvent();
    +      objBar.pendingEvent = null;
    +    }
    +
    +    if (e.newIndex >= 0) {
    +      objBar.targetObj = scene.objs[e.newIndex];
    +
    +      document.getElementById('showAdvanced').style.display = 'none';
    +      document.getElementById('showAdvanced_mobile_container').style.display = 'none';
    +
    +      document.getElementById('obj_bar_main').style.display = '';
    +      document.getElementById('obj_bar_main').innerHTML = '';
    +      scene.objs[e.newIndex].populateObjBar(objBar);
    +
    +      if (document.getElementById('obj_bar_main').innerHTML != '') {
    +        for (var i = 0; i < scene.objs.length; i++) {
    +          if (i != e.newIndex && scene.objs[i].constructor.type == scene.objs[e.newIndex].constructor.type) {
    +            // If there is an object with the same type, then show "Apply to All"
    +            document.getElementById('apply_to_all_box').style.display = '';
    +            document.getElementById('apply_to_all_mobile_container').style.display = '';
    +            break;
    +          }
    +          if (i == scene.objs.length - 1) {
    +            document.getElementById('apply_to_all_box').style.display = 'none';
    +            document.getElementById('apply_to_all_mobile_container').style.display = 'none';
    +          }
    +        }
    +      } else {
    +        document.getElementById('apply_to_all_box').style.display = 'none';
    +        document.getElementById('apply_to_all_mobile_container').style.display = 'none';
    +      }
    +
    +
    +      document.getElementById('obj_bar').style.display = '';
    +    } else {
    +      document.getElementById('obj_bar').style.display = 'none';
    +      objBar.shouldShowAdvanced = false;
    +    }
    +  });
    +
    +  editor.on('sceneLoaded', function (e) {
    +    document.getElementById('welcome').style.display = 'none';
    +    if (e.needFullUpdate) {
    +      // Update the UI for the loaded scene.
    +
    +      if (scene.name) {
    +        document.title = scene.name + " - " + i18next.t('main:pages.simulator') + ' - ' + i18next.t('main:project.name');
    +        document.getElementById('save_name').value = scene.name;
    +      } else {
    +        document.title = i18next.t('main:pages.simulator') + ' - ' + i18next.t('main:project.name');
    +      }
    +
    +      if (Object.keys(scene.modules).length > 0) {
    +        updateModuleObjsMenu();
    +      }
    +
    +      document.getElementById('showGrid').checked = scene.showGrid;
    +      document.getElementById('showGrid_more').checked = scene.showGrid;
    +      document.getElementById('showGrid_mobile').checked = scene.showGrid;
    +
    +      document.getElementById('snapToGrid').checked = scene.snapToGrid;
    +      document.getElementById('snapToGrid_more').checked = scene.snapToGrid;
    +      document.getElementById('snapToGrid_mobile').checked = scene.snapToGrid;
    +
    +      document.getElementById('lockObjs').checked = scene.lockObjs;
    +      document.getElementById('lockObjs_more').checked = scene.lockObjs;
    +      document.getElementById('lockObjs_mobile').checked = scene.lockObjs;
    +
    +      if (scene.observer) {
    +        document.getElementById('observer_size').value = Math.round(scene.observer.r * 2 * 1000000) / 1000000;
    +        document.getElementById('observer_size_mobile').value = Math.round(scene.observer.r * 2 * 1000000) / 1000000;
    +      } else {
    +        document.getElementById('observer_size').value = 40;
    +        document.getElementById('observer_size_mobile').value = 40;
    +      }
    +
    +      document.getElementById('gridSize').value = scene.gridSize;
    +      document.getElementById('gridSize_mobile').value = scene.gridSize;
    +
    +      document.getElementById('lengthScale').value = scene.lengthScale;
    +      document.getElementById('lengthScale_mobile').value = scene.lengthScale;
    +
    +      document.getElementById("zoom").innerText = Math.round(scene.scale * scene.lengthScale * 100) + '%';
    +      document.getElementById("zoom_mobile").innerText = Math.round(scene.scale * scene.lengthScale * 100) + '%';
    +      document.getElementById('simulateColors').checked = scene.simulateColors;
    +      document.getElementById('simulateColors_mobile').checked = scene.simulateColors;
    +      modebtn_clicked(scene.mode);
    +      document.getElementById('mode_' + scene.mode).checked = true;
    +      document.getElementById('mode_' + scene.mode + '_mobile').checked = true;
    +      editor.selectObj(editor.selectedObjIndex);
    +    }
    +  });
    +
    +  editor.on('newAction', function (e) {
    +    if (aceEditor && e.newJSON != e.oldJSON && !aceEditor.isFocused()) {
    +
    +      // Calculate the position of the first and last character that has changed
    +      var minLen = Math.min(e.newJSON.length, e.oldJSON.length);
    +      var startChar = 0;
    +      while (startChar < minLen && e.newJSON[startChar] == e.oldJSON[startChar]) {
    +        startChar++;
    +      }
    +      var endChar = 0;
    +      while (endChar < minLen && e.newJSON[e.newJSON.length - 1 - endChar] == e.oldJSON[e.oldJSON.length - 1 - endChar]) {
    +        endChar++;
    +      }
    +
    +      // Convert the character positions to line numbers
    +      var startLineNum = e.newJSON.substr(0, startChar).split("\n").length - 1;
    +      var endLineNum = e.newJSON.substr(0, e.newJSON.length - endChar).split("\n").length - 1;
    +
    +      // Set selection range to highlight changes using the Range object
    +      var selectionRange = new Range(startLineNum, 0, endLineNum + 1, 0);
    +
    +      lastCodeChangeIsFromScene = true;
    +      aceEditor.setValue(e.newJSON);
    +      aceEditor.selection.setSelectionRange(selectionRange);
    +
    +      // Scroll to the first line that has changed
    +      aceEditor.scrollToLine(startLineNum, true, true, function () { });
    +    }
    +
    +
    +    syncUrl();
    +    warning = "";
    +    hasUnsavedChange = true;
    +  });
    +
    +  editor.on('newUndoPoint', function (e) {
    +    document.getElementById('undo').disabled = false;
    +    document.getElementById('redo').disabled = true;
    +    document.getElementById('undo_mobile').disabled = false;
    +    document.getElementById('redo_mobile').disabled = true;
    +  });
    +
    +  editor.on('undo', function (e) {
    +    document.getElementById('redo').disabled = false;
    +    document.getElementById('redo_mobile').disabled = false;
    +    if (editor.undoIndex == editor.undoLBound) {
    +      // The lower bound of undo data is reached
    +      document.getElementById('undo').disabled = true;
    +      document.getElementById('undo_mobile').disabled = true;
    +    }
    +    if (aceEditor) {
    +      aceEditor.session.setValue(editor.lastActionJson);
    +    }
    +    syncUrl();
    +  });
    +
    +  editor.on('redo', function (e) {
    +    document.getElementById('undo').disabled = false;
    +    document.getElementById('undo_mobile').disabled = false;
    +    if (editor.undoIndex == editor.undoUBound) {
    +      // The lower bound of undo data is reached
    +      document.getElementById('redo').disabled = true;
    +      document.getElementById('redo_mobile').disabled = true;
    +    }
    +    if (aceEditor) {
    +      aceEditor.session.setValue(editor.lastActionJson);
    +    }
    +    syncUrl();
    +  });
    +
    +  editor.on('scaleChange', function (e) {
    +    document.getElementById("zoom").innerText = Math.round(scene.scale * scene.lengthScale * 100) + '%';
    +    document.getElementById("zoom_mobile").innerText = Math.round(scene.scale * scene.lengthScale * 100) + '%';
    +  });
    +
    +  editor.on('requestUpdateErrorAndWarning', function () {
    +    updateErrorAndWarning();
    +  });
    +
    +  init();
    +
    +  document.getElementById('undo').disabled = true;
    +  document.getElementById('redo').disabled = true;
    +
    +  document.getElementById('undo_mobile').disabled = true;
    +  document.getElementById('redo_mobile').disabled = true;
    +
    +
    +  window.onresize = function (e) {
    +    if (simulator && window.devicePixelRatio) {
    +      simulator.dpr = window.devicePixelRatio;
    +    }
    +    if (scene) {
    +      scene.setViewportSize(canvas.width / simulator.dpr, canvas.height / simulator.dpr);
    +      if (editor) {
    +        editor.onActionComplete();
    +      }
    +    }
    +    if (simulator.ctxAboveLight) {
    +      canvas.width = window.innerWidth * simulator.dpr;
    +      canvas.height = window.innerHeight * simulator.dpr;
    +      canvasBelowLight.width = window.innerWidth * simulator.dpr;
    +      canvasBelowLight.height = window.innerHeight * simulator.dpr;
    +      canvasLight.width = window.innerWidth * simulator.dpr;
    +      canvasLight.height = window.innerHeight * simulator.dpr;
    +      canvasGrid.width = window.innerWidth * simulator.dpr;
    +      canvasGrid.height = window.innerHeight * simulator.dpr;
    +      simulator.updateSimulation();
    +    }
    +  };
    +
    +  window.onkeydown = function (e) {
    +    //Ctrl+Z
    +    if (e.ctrlKey && e.keyCode == 90) {
    +      if (document.getElementById('undo').disabled == false) {
    +        editor.undo();
    +      }
    +      return false;
    +    }
    +    //Ctrl+D
    +    if (e.ctrlKey && e.keyCode == 68) {
    +      if (editor.selectedObjIndex != -1) {
    +        if (scene.objs[editor.selectedObjIndex].constructor.type == 'Handle') {
    +          scene.cloneObjsByHandle(editor.selectedObjIndex);
    +        } else {
    +          scene.cloneObj(editor.selectedObjIndex);
    +        }
    +
    +        simulator.updateSimulation(!scene.objs[editor.selectedObjIndex].constructor.isOptical, true);
    +        editor.onActionComplete();
    +      }
    +      return false;
    +    }
    +    //Ctrl+Y
    +    if (e.ctrlKey && e.keyCode == 89) {
    +      document.getElementById('redo').onclick();
    +    }
    +
    +    //Ctrl+S
    +    if (e.ctrlKey && e.keyCode == 83) {
    +      save();
    +      return false;
    +    }
    +
    +    //Ctrl+O
    +    if (e.ctrlKey && e.keyCode == 79) {
    +      document.getElementById('open').onclick();
    +      return false;
    +    }
    +
    +    //esc
    +    if (e.keyCode == 27) {
    +      if (editor.isConstructing) {
    +        editor.undo();
    +      }
    +    }
    +
    +    //Delete
    +    if (e.keyCode == 46 || e.keyCode == 8) {
    +      if (editor.selectedObjIndex != -1) {
    +        var selectedObjType = scene.objs[editor.selectedObjIndex].constructor.type;
    +        editor.removeObj(editor.selectedObjIndex);
    +        simulator.updateSimulation(!sceneObjs[selectedObjType].isOptical, true);
    +        editor.onActionComplete();
    +      }
    +      return false;
    +    }
    +
    +    //Arrow Keys
    +    if (e.keyCode >= 37 && e.keyCode <= 40) {
    +      var step = scene.snapToGrid ? scene.gridSize : 1;
    +      if (editor.selectedObjIndex >= 0) {
    +        if (e.keyCode == 37) {
    +          scene.objs[editor.selectedObjIndex].move(-step, 0);
    +        }
    +        if (e.keyCode == 38) {
    +          scene.objs[editor.selectedObjIndex].move(0, -step);
    +        }
    +        if (e.keyCode == 39) {
    +          scene.objs[editor.selectedObjIndex].move(step, 0);
    +        }
    +        if (e.keyCode == 40) {
    +          scene.objs[editor.selectedObjIndex].move(0, step);
    +        }
    +        simulator.updateSimulation(!scene.objs[editor.selectedObjIndex].constructor.isOptical, true);
    +      }
    +      else if (scene.mode == 'observer') {
    +        if (e.keyCode == 37) {
    +          scene.observer.c.x -= step;
    +        }
    +        if (e.keyCode == 38) {
    +          scene.observer.c.y -= step;
    +        }
    +        if (e.keyCode == 39) {
    +          scene.observer.c.x += step;
    +        }
    +        if (e.keyCode == 40) {
    +          scene.observer.c.y += step;
    +        }
    +        simulator.updateSimulation(false, true);
    +      }
    +      else {
    +        // TODO: Is this a historical remnant? Should the expected behavior be to change `scene.origin` instead? Note however that some users may be using the current behavior to align the scene with the background image or the grid.
    +        for (var i = 0; i < scene.objs.length; i++) {
    +          if (e.keyCode == 37) {
    +            scene.objs[i].move(-step, 0);
    +          }
    +          if (e.keyCode == 38) {
    +            scene.objs[i].move(0, -step);
    +          }
    +          if (e.keyCode == 39) {
    +            scene.objs[i].move(step, 0);
    +          }
    +          if (e.keyCode == 40) {
    +            scene.objs[i].move(0, step);
    +          }
    +        }
    +        simulator.updateSimulation();
    +      }
    +    }
    +  };
    +
    +  window.onkeyup = function (e) {
    +    //Arrow Keys
    +    if (e.keyCode >= 37 && e.keyCode <= 40) {
    +      editor.onActionComplete();
    +    }
    +  };
    +
    +  document.getElementById('undo').onclick = function () {
    +    this.blur();
    +    editor.undo();
    +  }
    +  document.getElementById('undo_mobile').onclick = document.getElementById('undo').onclick;
    +  document.getElementById('redo').onclick = function () {
    +    this.blur();
    +    editor.redo();
    +  }
    +  document.getElementById('redo_mobile').onclick = document.getElementById('redo').onclick;
    +  document.getElementById('reset').onclick = function () {
    +    history.replaceState('', document.title, window.location.pathname + window.location.search);
    +    init();
    +    document.getElementById("welcome_loading").style.display = 'none';
    +    document.getElementById("welcome_instruction").style.display = '';
    +    document.getElementById('welcome').style.display = '';
    +    editor.onActionComplete();
    +    hasUnsavedChange = false;
    +    if (aceEditor) {
    +      aceEditor.session.setValue(editor.lastActionJson);
    +    }
    +  };
    +  document.getElementById('reset_mobile').onclick = document.getElementById('reset').onclick
    +
    +  document.getElementById('get_link').onclick = getLink;
    +  document.getElementById('get_link_mobile').onclick = getLink;
    +  document.getElementById('export_svg').onclick = function () {
    +    editor.enterCropMode();
    +  };
    +  document.getElementById('export_svg_mobile').onclick = function () {
    +    editor.enterCropMode();
    +  };
    +  document.getElementById('open').onclick = function () {
    +    document.getElementById('openfile').click();
    +  };
    +  document.getElementById('open_mobile').onclick = document.getElementById('open').onclick
    +  document.getElementById('view_gallery').onclick = function () {
    +    window.open(mapURL('/gallery'));
    +  };
    +  document.getElementById('view_gallery_mobile').onclick = document.getElementById('view_gallery').onclick;
    +
    +
    +  document.getElementById('openfile').onchange = function () {
    +    openFile(this.files[0]);
    +  };
    +
    +  document.getElementById('simulateColors').onclick = function () {
    +    scene.simulateColors = this.checked;
    +    document.getElementById('simulateColors').checked = scene.simulateColors;
    +    document.getElementById('simulateColors_mobile').checked = scene.simulateColors;
    +    editor.selectObj(editor.selectedObjIndex);
    +    this.blur();
    +    simulator.updateSimulation(false, true);
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('simulateColors_mobile').onclick = document.getElementById('simulateColors').onclick;
    +
    +  document.getElementById('show_help_popups').onclick = function () {
    +    this.blur();
    +    popoversEnabled = this.checked;
    +    localStorage.rayOpticsHelp = popoversEnabled ? "on" : "off";
    +  };
    +
    +  document.getElementById('show_json_editor').onclick = function () {
    +    this.blur();
    +
    +    document.getElementById('show_json_editor').checked = this.checked;
    +    document.getElementById('show_json_editor_mobile').checked = this.checked;
    +
    +    if (this.checked) {
    +      enableJsonEditor();
    +    } else {
    +      disableJsonEditor();
    +    }
    +
    +    localStorage.rayOpticsShowJsonEditor = this.checked ? "on" : "off";
    +  };
    +  document.getElementById('show_json_editor_mobile').onclick = document.getElementById('show_json_editor').onclick;
    +
    +  if (typeof (Storage) !== "undefined" && localStorage.rayOpticsShowJsonEditor && localStorage.rayOpticsShowJsonEditor == "on") {
    +    enableJsonEditor();
    +    document.getElementById('show_json_editor').checked = true;
    +    document.getElementById('show_json_editor_mobile').checked = true;
    +  } else {
    +    document.getElementById('show_json_editor').checked = false;
    +    document.getElementById('show_json_editor_mobile').checked = false;
    +  }
    +
    +  document.getElementById('show_status').onclick = function () {
    +    this.blur();
    +
    +    document.getElementById('show_status').checked = this.checked;
    +    document.getElementById('show_status_mobile').checked = this.checked;
    +
    +    document.getElementById('status').style.display = this.checked ? '' : 'none';
    +    localStorage.rayOpticsShowStatus = this.checked ? "on" : "off";
    +  };
    +  document.getElementById('show_status_mobile').onclick = document.getElementById('show_status').onclick;
    +
    +  if (typeof (Storage) !== "undefined" && localStorage.rayOpticsShowStatus && localStorage.rayOpticsShowStatus == "on") {
    +    document.getElementById('show_status').checked = true;
    +    document.getElementById('show_status_mobile').checked = true;
    +    document.getElementById('status').style.display = '';
    +  } else {
    +    document.getElementById('show_status').checked = false;
    +    document.getElementById('show_status_mobile').checked = false;
    +    document.getElementById('status').style.display = 'none';
    +  }
    +
    +  document.getElementById('auto_sync_url').onclick = function () {
    +    this.blur();
    +
    +    document.getElementById('auto_sync_url').checked = this.checked;
    +    document.getElementById('auto_sync_url_mobile').checked = this.checked;
    +
    +    localStorage.rayOpticsAutoSyncUrl = this.checked ? "on" : "off";
    +    autoSyncUrl = this.checked;
    +
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('auto_sync_url_mobile').onclick = document.getElementById('auto_sync_url').onclick;
    +
    +  if (typeof (Storage) !== "undefined" && localStorage.rayOpticsAutoSyncUrl && localStorage.rayOpticsAutoSyncUrl == "on") {
    +    document.getElementById('auto_sync_url').checked = true;
    +    document.getElementById('auto_sync_url_mobile').checked = true;
    +    autoSyncUrl = true;
    +  } else {
    +    document.getElementById('auto_sync_url').checked = false;
    +    document.getElementById('auto_sync_url_mobile').checked = false;
    +    autoSyncUrl = false;
    +  }
    +
    +  document.getElementById('gridSize').onchange = function () {
    +    scene.gridSize = parseFloat(this.value);
    +    document.getElementById('gridSize').value = scene.gridSize;
    +    document.getElementById('gridSize_mobile').value = scene.gridSize;
    +    simulator.updateSimulation(true, false);
    +    editor.onActionComplete();
    +  }
    +  document.getElementById('gridSize_mobile').onchange = document.getElementById('gridSize').onchange;
    +
    +  document.getElementById('gridSize').onclick = function () {
    +    this.select();
    +  }
    +  document.getElementById('gridSize_mobile').onclick = document.getElementById('gridSize').onclick;
    +
    +  document.getElementById('gridSize').onkeydown = function (e) {
    +    e.cancelBubble = true;
    +    if (e.stopPropagation) e.stopPropagation();
    +  };
    +  document.getElementById('gridSize_mobile').onkeydown = document.getElementById('gridSize').onkeydown;
    +
    +  document.getElementById('observer_size').onchange = function () {
    +    document.getElementById('observer_size').value = this.value;
    +    document.getElementById('observer_size_mobile').value = this.value;
    +    if (scene.observer) {
    +      scene.observer.r = parseFloat(this.value) * 0.5;
    +    }
    +    simulator.updateSimulation(false, true);
    +    editor.onActionComplete();
    +  }
    +  document.getElementById('observer_size_mobile').onchange = document.getElementById('observer_size').onchange;
    +
    +  document.getElementById('observer_size').onclick = function () {
    +    this.select();
    +  }
    +  document.getElementById('observer_size_mobile').onclick = document.getElementById('observer_size').onclick;
    +
    +  document.getElementById('observer_size').onkeydown = function (e) {
    +    e.cancelBubble = true;
    +    if (e.stopPropagation) e.stopPropagation();
    +  };
    +  document.getElementById('observer_size_mobile').onkeydown = document.getElementById('observer_size').onkeydown;
    +
    +  document.getElementById('lengthScale').onchange = function () {
    +    scene.lengthScale = parseFloat(this.value);
    +    if (isNaN(scene.lengthScale)) {
    +      scene.lengthScale = 1;
    +    }
    +    if (scene.lengthScale < 0.1) {
    +      scene.lengthScale = 0.1;
    +    }
    +    if (scene.lengthScale > 10) {
    +      scene.lengthScale = 10;
    +    }
    +    document.getElementById('lengthScale').value = scene.lengthScale;
    +    document.getElementById('lengthScale_mobile').value = scene.lengthScale;
    +    editor.setScale(scene.scale);
    +    simulator.updateSimulation();
    +    editor.onActionComplete();
    +  }
    +  document.getElementById('lengthScale_mobile').onchange = document.getElementById('lengthScale').onchange;
    +
    +  document.getElementById('lengthScale').onclick = function () {
    +    this.select();
    +  }
    +  document.getElementById('lengthScale_mobile').onclick = document.getElementById('lengthScale').onclick;
    +
    +  document.getElementById('lengthScale').onkeydown = function (e) {
    +    e.cancelBubble = true;
    +    if (e.stopPropagation) e.stopPropagation();
    +  };
    +  document.getElementById('lengthScale_mobile').onkeydown = document.getElementById('lengthScale').onkeydown;
    +
    +
    +  document.getElementById('zoomPlus').onclick = function () {
    +    editor.setScale(scene.scale * 1.1);
    +    editor.onActionComplete();
    +    this.blur();
    +  }
    +  document.getElementById('zoomMinus').onclick = function () {
    +    editor.setScale(scene.scale / 1.1);
    +    editor.onActionComplete();
    +    this.blur();
    +  }
    +  document.getElementById('zoomPlus_mobile').onclick = document.getElementById('zoomPlus').onclick;
    +  document.getElementById('zoomMinus_mobile').onclick = document.getElementById('zoomMinus').onclick;
    +
    +
    +  document.getElementById('rayDensity').oninput = function () {
    +    scene.rayDensity = Math.exp(this.value);
    +    document.getElementById('rayDensity').value = this.value;
    +    document.getElementById('rayDensity_more').value = this.value;
    +    document.getElementById('rayDensity_mobile').value = this.value;
    +    simulator.updateSimulation(false, true);
    +  };
    +  document.getElementById('rayDensity_more').oninput = document.getElementById('rayDensity').oninput;
    +  document.getElementById('rayDensity_mobile').oninput = document.getElementById('rayDensity').oninput;
    +
    +  document.getElementById('rayDensity').onmouseup = function () {
    +    scene.rayDensity = Math.exp(this.value); // For browsers not supporting oninput
    +    document.getElementById('rayDensity').value = this.value;
    +    document.getElementById('rayDensity_more').value = this.value;
    +    document.getElementById('rayDensity_mobile').value = this.value;
    +    this.blur();
    +    simulator.updateSimulation(false, true);
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('rayDensity_more').onmouseup = document.getElementById('rayDensity').onmouseup;
    +  document.getElementById('rayDensity_mobile').onmouseup = document.getElementById('rayDensity').onmouseup;
    +
    +  document.getElementById('rayDensity').ontouchend = function () {
    +    scene.rayDensity = Math.exp(this.value); // For browsers not supporting oninput
    +    document.getElementById('rayDensity').value = this.value;
    +    document.getElementById('rayDensity_more').value = this.value;
    +    document.getElementById('rayDensity_mobile').value = this.value;
    +    this.blur();
    +    simulator.updateSimulation(false, true);
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('rayDensity_more').ontouchend = document.getElementById('rayDensity').ontouchend;
    +  document.getElementById('rayDensity_mobile').ontouchend = document.getElementById('rayDensity').ontouchend;
    +
    +  document.getElementById('rayDensityPlus').onclick = function () {
    +    const rayDensityValue = Math.log(scene.rayDensity) * 1.0 + 0.1;
    +    scene.rayDensity = Math.exp(rayDensityValue);
    +    document.getElementById('rayDensity').value = rayDensityValue;
    +    document.getElementById('rayDensity_more').value = rayDensityValue;
    +    document.getElementById('rayDensity_mobile').value = rayDensityValue;
    +    this.blur();
    +    simulator.updateSimulation(false, true);
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('rayDensityMinus').onclick = function () {
    +    const rayDensityValue = Math.log(scene.rayDensity) * 1.0 - 0.1;
    +    scene.rayDensity = Math.exp(rayDensityValue);
    +    document.getElementById('rayDensity').value = rayDensityValue;
    +    document.getElementById('rayDensity_more').value = rayDensityValue;
    +    document.getElementById('rayDensity_mobile').value = rayDensityValue;
    +    this.blur();
    +    simulator.updateSimulation(false, true);
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('rayDensityPlus_mobile').onclick = document.getElementById('rayDensityPlus').onclick;
    +  document.getElementById('rayDensityMinus_mobile').onclick = document.getElementById('rayDensityMinus').onclick;
    +  document.getElementById('rayDensityPlus_more').onclick = document.getElementById('rayDensityPlus').onclick;
    +  document.getElementById('rayDensityMinus_more').onclick = document.getElementById('rayDensityMinus').onclick;
    +
    +
    +  document.getElementById('snapToGrid').onclick = function (e) {
    +    document.getElementById('snapToGrid').checked = e.target.checked;
    +    document.getElementById('snapToGrid_more').checked = e.target.checked;
    +    document.getElementById('snapToGrid_mobile').checked = e.target.checked;
    +    scene.snapToGrid = e.target.checked;
    +    this.blur();
    +    editor.onActionComplete();
    +    //simulator.updateSimulation();
    +  };
    +  document.getElementById('snapToGrid_more').onclick = document.getElementById('snapToGrid').onclick;
    +  document.getElementById('snapToGrid_mobile').onclick = document.getElementById('snapToGrid').onclick;
    +
    +  document.getElementById('showGrid').onclick = function (e) {
    +    document.getElementById('showGrid').checked = e.target.checked;
    +    document.getElementById('showGrid_more').checked = e.target.checked;
    +    document.getElementById('showGrid_mobile').checked = e.target.checked;
    +    scene.showGrid = e.target.checked;
    +    this.blur();
    +    simulator.updateSimulation(true, false);
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('showGrid_more').onclick = document.getElementById('showGrid').onclick;
    +  document.getElementById('showGrid_mobile').onclick = document.getElementById('showGrid').onclick;
    +
    +  document.getElementById('lockObjs').onclick = function (e) {
    +    document.getElementById('lockObjs').checked = e.target.checked;
    +    document.getElementById('lockObjs_more').checked = e.target.checked;
    +    document.getElementById('lockObjs_mobile').checked = e.target.checked;
    +    scene.lockObjs = e.target.checked;
    +    this.blur();
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('lockObjs_more').onclick = document.getElementById('lockObjs').onclick;
    +  document.getElementById('lockObjs_mobile').onclick = document.getElementById('lockObjs').onclick;
    +
    +  document.getElementById('forceStop').onclick = function () {
    +    simulator.stopSimulation();
    +  };
    +
    +  document.getElementById('apply_to_all').onclick = function () {
    +    this.blur();
    +    const checked = this.checked;
    +    document.getElementById('apply_to_all').checked = checked;
    +    document.getElementById('apply_to_all_mobile').checked = checked;
    +  }
    +  document.getElementById('apply_to_all_mobile').onclick = document.getElementById('apply_to_all').onclick;
    +
    +  document.getElementById('copy').onclick = function () {
    +    this.blur();
    +    if (scene.objs[editor.selectedObjIndex].constructor.type == 'Handle') {
    +      scene.cloneObjsByHandle(editor.selectedObjIndex);
    +      scene.objs[editor.selectedObjIndex].move(scene.gridSize, scene.gridSize);
    +    } else {
    +      scene.cloneObj(editor.selectedObjIndex).move(scene.gridSize, scene.gridSize);
    +    }
    +    editor.selectObj(scene.objs.length - 1);
    +    simulator.updateSimulation(!scene.objs[editor.selectedObjIndex].constructor.isOptical, true);
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('copy_mobile').onclick = document.getElementById('copy').onclick;
    +
    +  document.getElementById('delete').onclick = function () {
    +    var selectedObjType = scene.objs[editor.selectedObjIndex].constructor.type;
    +    this.blur();
    +    editor.removeObj(editor.selectedObjIndex);
    +    simulator.updateSimulation(!sceneObjs[selectedObjType].isOptical, true);
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('delete_mobile').onclick = document.getElementById('delete').onclick;
    +
    +  document.getElementById('unselect').onclick = function () {
    +    editor.selectObj(-1);
    +    simulator.updateSimulation(true, true);
    +    editor.onActionComplete();
    +  };
    +  document.getElementById('unselect_mobile').onclick = document.getElementById('unselect').onclick;
    +
    +  document.getElementById('showAdvanced').onclick = function () {
    +    objBar.shouldShowAdvanced = true;
    +    editor.selectObj(editor.selectedObjIndex);
    +  };
    +  document.getElementById('showAdvanced_mobile').onclick = document.getElementById('showAdvanced').onclick;
    +
    +
    +
    +  document.getElementById('save_name').onkeydown = function (e) {
    +    if (e.keyCode == 13) {
    +      //enter
    +      document.getElementById('save_confirm').onclick();
    +    }
    +
    +    e.cancelBubble = true;
    +    if (e.stopPropagation) e.stopPropagation();
    +  };
    +  document.getElementById('save_confirm').onclick = save;
    +  document.getElementById('save_rename').onclick = rename;
    +
    +  document.getElementById('xybox').onkeydown = function (e) {
    +    //console.log(e.keyCode)
    +    if (e.keyCode == 13) {
    +      //enter
    +      confirmPositioning(e.ctrlKey, e.shiftKey);
    +    }
    +    if (e.keyCode == 27) {
    +      //esc
    +      editor.endPositioning();
    +    }
    +
    +    e.cancelBubble = true;
    +    if (e.stopPropagation) e.stopPropagation();
    +  };
    +
    +  document.getElementById('xybox').oninput = function (e) {
    +    this.size = this.value.length;
    +  };
    +
    +  document.getElementById('xybox').addEventListener('contextmenu', function (e) {
    +    if (xyBox_cancelContextMenu) {
    +      e.preventDefault();
    +      xyBox_cancelContextMenu = false;
    +    }
    +  }, false);
    +
    +
    +  window.ondragenter = function (e) {
    +    e.stopPropagation();
    +    e.preventDefault();
    +  };
    +
    +  window.ondragover = function (e) {
    +    e.stopPropagation();
    +    e.preventDefault();
    +  };
    +
    +  window.ondrop = function (e) {
    +    e.stopPropagation();
    +    e.preventDefault();
    +
    +    var dt = e.dataTransfer;
    +    if (dt.files[0]) {
    +      var files = dt.files;
    +      openFile(files[0]);
    +    }
    +    else {
    +      var fileString = dt.getData('text');
    +      editor.loadJSON(fileString);
    +      editor.onActionComplete();
    +    }
    +  };
    +
    +  canvas.addEventListener('contextmenu', function (e) {
    +    e.preventDefault();
    +  }, false);
    +
    +  canvas.addEventListener('mousedown', function (e) {
    +    error = null;
    +  }, false);
    +
    +  window.onerror = function (msg, url) {
    +    error = `Error: ${msg} at ${url}`;
    +    document.getElementById('welcome').style.display = 'none';
    +    updateErrorAndWarning();
    +  }
    +
    +  // Update the scene when the URL changes
    +  window.onpopstate = function (event) {
    +    if (window.location.hash.length > 70) {
    +      // The URL contains a compressed JSON scene.
    +      require('json-url')('lzma').decompress(window.location.hash.substr(1)).then(json => {
    +        scene.backgroundImage = null;
    +        editor.loadJSON(JSON.stringify(json));
    +        editor.onActionComplete();
    +        hasUnsavedChange = false;
    +        if (aceEditor) {
    +          aceEditor.session.setValue(editor.lastActionJson);
    +        }
    +      }).catch(e => {
    +        error = "JsonUrl: " + e;
    +        document.getElementById('welcome').style.display = 'none';
    +        updateErrorAndWarning();
    +      });;
    +    } else if (window.location.hash.length > 1) {
    +      // The URL contains a link to a gallery item.
    +      openSample(window.location.hash.substr(1) + ".json");
    +      history.replaceState('', document.title, window.location.pathname + window.location.search);
    +    }
    +  };
    +
    +  window.onpopstate();
    +
    +  window.addEventListener('message', function (event) {
    +    if (event.data && event.data.rayOpticsModuleName) {
    +      importModule(event.data.rayOpticsModuleName + '.json');
    +    }
    +  });
    +
    +  document.getElementById('toolbar-loading').style.display = 'none';
    +  document.getElementById('toolbar-wrapper').style.display = '';
    +  document.getElementById('saveModal').style.display = '';
    +  document.getElementById('languageModal').style.display = '';
    +  document.getElementById('footer-left').style.display = '';
    +  document.getElementById('footer-right').style.display = '';
    +  document.getElementById('canvas-container').style.display = '';
    +}
    +
    +startApp();
    +
    +
    +var canvas;
    +var canvasBelowLight;
    +var canvasLight;
    +var canvasGrid;
    +var scene;
    +var editor;
    +var simulator;
    +var objBar;
    +var xyBox_cancelContextMenu = false;
    +var hasUnsavedChange = false;
    +var autoSyncUrl = false;
    +var warning = null;
    +var error = null;
    +
    +
    +const f = function (e) {
    +  const list = document.getElementsByClassName('mobile-dropdown-menu');
    +  let maxScrollHeight = 0;
    +  for (let ele of list) {
    +    const inner = ele.children[0];
    +    if (inner.scrollHeight > maxScrollHeight) {
    +      maxScrollHeight = inner.scrollHeight;
    +    }
    +  }
    +  for (let ele of list) {
    +    ele.style.height = maxScrollHeight + 'px';
    +  }
    +}
    +document.getElementById('toolbar-mobile').addEventListener('shown.bs.dropdown', f);
    +document.getElementById('toolbar-mobile').addEventListener('hidden.bs.dropdown', f);
    +
    +function resetDropdownButtons() {
    +  // Remove the 'selected' class from all dropdown buttons
    +  document.querySelectorAll('.btn.dropdown-toggle.selected').forEach(function (button) {
    +    button.classList.remove('selected');
    +  });
    +  document.querySelectorAll('.btn.mobile-dropdown-trigger.selected').forEach(function (button) {
    +    button.classList.remove('selected');
    +  });
    +}
    +
    +document.addEventListener('DOMContentLoaded', function () {
    +
    +  document.getElementById('more-options-dropdown').addEventListener('click', function (e) {
    +    e.stopPropagation();
    +  });
    +
    +  document.getElementById('mobile-dropdown-options').addEventListener('click', function (e) {
    +    e.stopPropagation();
    +  });
    +
    +  // Listen for changes to any radio input within a dropdown
    +  document.querySelectorAll('.dropdown-menu input[type="radio"]').forEach(function (input) {
    +    input.addEventListener('change', function () {
    +      if (input.checked) {
    +        // Reset other dropdown buttons
    +        if (!input.id.includes('mobile')) {
    +          resetDropdownButtons();
    +
    +          // Get the associated dropdown button using the aria-labelledby attribute
    +          let dropdownButton = document.getElementById(input.closest('.dropdown-menu').getAttribute('aria-labelledby'));
    +
    +          // Style the button to indicate selection.
    +          dropdownButton.classList.add('selected');
    +        } else if (input.name == 'toolsradio_mobile') {
    +          resetDropdownButtons();
    +
    +          // Get the associated mobile trigger button
    +          let groupId = input.parentElement.parentElement.id.replace('mobile-dropdown-', '');
    +          let toggle = document.getElementById(`mobile-dropdown-trigger-${groupId}`);
    +          if (toggle != null) {
    +            // Style the button to indicate selection.
    +            toggle.classList.add('selected');
    +          }
    +        }
    +      }
    +    });
    +  });
    +
    +  // Listen for changes to standalone radio inputs (outside dropdowns)
    +  document.querySelectorAll('input[type="radio"].btn-check').forEach(function (input) {
    +    if (input.name == 'toolsradio' && !input.closest('.dropdown-menu') && !input.id.includes('mobile')) { // Check if the radio is not inside a dropdown
    +      input.addEventListener('change', function () {
    +        if (input.checked) {
    +          // Reset dropdown buttons
    +          resetDropdownButtons();
    +        }
    +      });
    +    }
    +  });
    +
    +});
    +
    +function initUIText() {
    +  setText('processing_text', i18next.t('simulator:footer.processing'));
    +  setText('reset', i18next.t('simulator:file.reset.title'));
    +  setText('save', i18next.t('simulator:file.save.title'));
    +  setText('open', i18next.t('simulator:file.open.title'), null, i18next.t('simulator:file.open.description'));
    +  setText('export_svg', i18next.t('simulator:file.export.title'));
    +  setText('get_link', i18next.t('simulator:file.copyLink.title'), null, i18next.t('simulator:file.copyLink.description'));
    +  setText('view_gallery', i18next.t('simulator:file.viewGallery.title'), null, i18next.t('simulator:file.viewGallery.description'));
    +  setText('undo', null, i18next.t('simulator:file.undo.title'));
    +  setText('redo', null, i18next.t('simulator:file.redo.title'));
    +  setText('file_text', i18next.t('simulator:file.title'));
    +  setText('sourceToolsDropdown', i18next.t('main:tools.categories.lightSource'));
    +  setText('tool_SingleRay_label', i18next.t('main:tools.SingleRay.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.SingleRay.description'), sub: i18next.t('main:tools.SingleRay.instruction')}), 'SingleRay.svg');
    +  setText('tool_Beam_label', i18next.t('main:tools.Beam.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.Beam.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'Beam.svg');
    +  setText('tool_PointSource_label', i18next.t('main:tools.PointSource.title') + ' (360\u00B0)', null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.PointSource.description'), sub: i18next.t('main:tools.common.clickInstruction')}), 'PointSource.svg');
    +  setText('tool_AngleSource_label', i18next.t('main:tools.PointSource.title') + ' (<360\u00B0)', null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.AngleSource.description'), sub: i18next.t('main:tools.SingleRay.instruction')}), 'AngleSource.svg');
    +  setText('mirrorToolsDropdown', i18next.t('main:tools.categories.mirror'));
    +  setText('tool_Mirror_label', i18next.t('main:tools.Mirror.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.Mirror.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'Mirror.svg');
    +  setText('tool_ArcMirror_label', i18next.t('main:tools.ArcMirror.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.ArcMirror.description'), sub: i18next.t('main:tools.ArcMirror.instruction')}), 'ArcMirror.svg');
    +  setText('tool_ParabolicMirror_label', i18next.t('main:tools.ParabolicMirror.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.ParabolicMirror.description'), sub: i18next.t('main:tools.ParabolicMirror.instruction')}), 'ParabolicMirror.svg');
    +  setText('tool_CustomMirror_label', i18next.t('main:tools.CustomMirror.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.CustomMirror.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'CustomMirror.svg');
    +  setText('tool_IdealMirror_label', i18next.t('main:tools.IdealMirror.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.IdealMirror.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'IdealMirror.svg');
    +  setText('tool_BeamSplitter_label', i18next.t('main:tools.BeamSplitter.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.BeamSplitter.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'BeamSplitter.svg');
    +  setText('glassToolsDropdown', i18next.t('main:tools.categories.glass'));
    +  setText('tool_PlaneGlass_label', i18next.t('main:tools.PlaneGlass.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.PlaneGlass.description'), sub: i18next.t('main:tools.PlaneGlass.instruction')}), 'PlaneGlass.svg');
    +  setText('tool_CircleGlass_label', i18next.t('main:tools.CircleGlass.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.CircleGlass.description'), sub: i18next.t('main:tools.common.circleInstruction')}), 'CircleGlass.svg');
    +  setText('tool_Glass_label', i18next.t('main:tools.Glass.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.Glass.description'), sub: i18next.t('main:tools.Glass.instruction')}), 'Glass.svg');
    +  setText('tool_CustomGlass_label', i18next.t('main:tools.CustomGlass.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.CustomGlass.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'CustomGlass.svg');
    +  setText('tool_IdealLens_label', i18next.t('main:tools.IdealLens.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.IdealLens.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'IdealLens.svg');
    +  setText('tool_SphericalLens_label', i18next.t('main:tools.SphericalLens.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.SphericalLens.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'SphericalLens.svg');
    +  setText('tool_CircleGrinGlass_label', i18next.t('main:tools.CircleGrinGlass.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.CircleGrinGlass.description'), sub: i18next.t('main:tools.common.circleInstruction')}), 'CircleGrinGlass.svg');
    +  setText('tool_GrinGlass_label', i18next.t('main:tools.GrinGlass.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.GrinGlass.description'), sub: i18next.t('main:tools.GrinGlass.instruction')}) + '<br>' + i18next.t('main:tools.GrinGlass.warning'), 'GrinGlass.svg');
    +  setText('blockerToolsDropdown', i18next.t('main:tools.categories.blocker'));
    +  setText('tool_Blocker_label', i18next.t('main:tools.Blocker.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.Blocker.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'Blocker.svg');
    +  setText('tool_CircleBlocker_label', i18next.t('main:tools.CircleBlocker.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.CircleBlocker.description'), sub: i18next.t('main:tools.common.circleInstruction')}), 'CircleBlocker.svg');
    +  setText('tool_Aperture_label', i18next.t('main:tools.Aperture.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.Aperture.description'), sub: i18next.t('main:tools.Aperture.instruction')}), 'Aperture.svg');
    +  setText('tool_DiffractionGrating_label', i18next.t('main:tools.DiffractionGrating.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.DiffractionGrating.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'DiffractionGrating.svg');
    +  setText('moreToolsDropdown', i18next.t('main:tools.categories.other'));
    +  setText('tool_Ruler_label', i18next.t('main:tools.Ruler.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.Ruler.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'Ruler.svg');
    +  setText('tool_Protractor_label', i18next.t('main:tools.Protractor.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.Protractor.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'Protractor.svg');
    +  setText('tool_Detector_label', i18next.t('main:tools.Detector.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.Detector.description'), sub: i18next.t('main:tools.common.lineInstruction')}), 'Detector.svg');
    +  setText('tool_TextLabel_label', i18next.t('main:tools.TextLabel.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.TextLabel.description'), sub: i18next.t('main:tools.common.clickInstruction')}));
    +  setText('tool_LineArrow_label', i18next.t('main:tools.LineArrow.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.LineArrow.description'), sub: i18next.t('main:tools.common.lineInstruction')}));
    +  setText('tool_Drawing_label', i18next.t('main:tools.Drawing.title'), null, i18next.t('main:meta.parentheses', {main: i18next.t('main:tools.Drawing.description'), sub: i18next.t('main:tools.Drawing.instruction')}));
    +  setText('import_modules', '<i>' + i18next.t('main:tools.modules.import') + '</i>');
    +  setText('tool__label', null, i18next.t('main:tools.moveView.title'), i18next.t('main:tools.moveView.description'));
    +  setText('tools_text', i18next.t('main:tools.title'));
    +  setText('mode_rays_label', null, i18next.t('main:view.rays.title'), i18next.t('main:view.rays.description'), 'normal.svg');
    +  setText('mode_extended_label', null, i18next.t('main:view.extended.title'), i18next.t('main:view.extended.description') + '<br>' + i18next.t('main:view.extended.simulateColorsNote'), 'extended_rays.svg');
    +  setText('mode_images_label', null, i18next.t('main:view.images.title'), i18next.t('main:view.images.description') + '<br>' + i18next.t('main:view.images.simulateColorsNote'), 'all_images.svg');
    +  setText('mode_observer_label', null, i18next.t('main:view.observer.title'), i18next.t('main:meta.parentheses', {main: i18next.t('main:view.observer.description'), sub: i18next.t('main:view.observer.instruction')}) + '<br>' + i18next.t('main:view.observer.simulateColorsNote'), 'seen_by_observer.svg');
    +  setText('view_text', i18next.t('main:view.title'));
    +  setText('rayDensity_popover', null, null, i18next.t('simulator:settings.rayDensity.description'));
    +  setText('rayDensity_text', i18next.t('simulator:settings.rayDensity.title'));
    +  setText('showGrid_label', null, i18next.t('simulator:settings.layoutAids.showGrid'));
    +  setText('snapToGrid_label', null, i18next.t('simulator:settings.layoutAids.snapToGrid'));
    +  setText('lockObjs_label', null, i18next.t('simulator:settings.layoutAids.lockObjs'));
    +  setText('layoutAids_text', i18next.t('simulator:settings.layoutAids.title'));
    +  setText('rayDensity_more_popover', null, null, i18next.t('simulator:settings.rayDensity.description'));
    +  setText('rayDensity_more_text', i18next.t('simulator:settings.rayDensity.title'));
    +  setText('layoutAids_more_text', i18next.t('simulator:settings.layoutAids.title'));
    +  setText('showGrid_more_label', null, i18next.t('simulator:settings.layoutAids.showGrid'));
    +  setText('snapToGrid_more_label', null, i18next.t('simulator:settings.layoutAids.snapToGrid'));
    +  setText('lockObjs_more_label', null, i18next.t('simulator:settings.layoutAids.lockObjs'));
    +  setText('simulateColors_popover', null, null, i18next.t('main:simulateColors.description') + '<br>' + i18next.t('main:simulateColors.instruction') + '<br>' + i18next.t('main:simulateColors.warning'));
    +  setText('simulateColors_text', i18next.t('main:simulateColors.title'));
    +  setText('gridSize_popover', null, null, i18next.t('simulator:sceneObjs.common.lengthUnitInfo'));
    +  setText('gridSize_text', i18next.t('simulator:settings.gridSize.title'));
    +  setText('observer_size_popover', null, null, i18next.t('simulator:sceneObjs.common.lengthUnitInfo'));
    +  setText('observer_size_text', i18next.t('simulator:settings.observerSize.title'));
    +  setText('lengthScale_popover', null, null, i18next.t('simulator:settings.lengthScale.description'));
    +  setText('lengthScale_text', i18next.t('simulator:settings.lengthScale.title'));
    +  setText('zoom_text', i18next.t('simulator:settings.zoom.title'));
    +  setText('language_text', i18next.t('simulator:settings.language.title'));
    +  setText('auto_sync_url_popover', null, null, i18next.t('simulator:settings.autoSyncUrl.description'));
    +  setText('auto_sync_url_text', i18next.t('simulator:settings.autoSyncUrl.title'));
    +  setText('show_json_editor_popover', null, null, i18next.t('simulator:settings.showJsonEditor.description'));
    +  setText('show_json_editor_text', i18next.t('simulator:settings.showJsonEditor.title'));
    +  setText('show_status_popover', null, null, i18next.t('simulator:settings.showStatusBox.description'));
    +  setText('show_status_text', i18next.t('simulator:settings.showStatusBox.title'));
    +  setText('show_help_popups_popover', null, null, i18next.t('simulator:settings.showHelpPopups.description'));
    +  setText('show_help_popups_text', i18next.t('simulator:settings.showHelpPopups.title'));
    +  setText('advanced-help', i18next.t('simulator:settings.advancedHelp'));
    +  setText('settings_text', i18next.t('simulator:settings.title'));
    +  setText('moreSettings_text', i18next.t('simulator:settings.more'));
    +  setText('reset_mobile', i18next.t('simulator:file.reset.title'));
    +  setText('save_button', i18next.t('simulator:file.save.title'));
    +  setText('open_mobile', i18next.t('simulator:file.open.title'));
    +  setText('export_svg_mobile', i18next.t('simulator:file.export.title'));
    +  setText('get_link_mobile', i18next.t('simulator:file.copyLink.title'));
    +  setText('view_gallery_mobile', i18next.t('simulator:file.viewGallery.title'));
    +  setText('tools_mobile_text', i18next.t('main:tools.title'));
    +  setText('tool_lightSource__text', i18next.t('main:tools.categories.lightSource'));
    +  setText('tool_mirror__text', i18next.t('main:tools.categories.mirror'));
    +  setText('tool_glass__text', i18next.t('main:tools.categories.glass'));
    +  setText('tool_blocker__text', i18next.t('main:tools.categories.blocker'));
    +  setText('tool_more__text', i18next.t('main:tools.categories.other'));
    +  setText('tool__mobile_label', i18next.t('main:tools.moveView.title'));
    +  setText('tool_SingleRay_mobile_label', i18next.t('main:tools.SingleRay.title'));
    +  setText('tool_Beam_mobile_label', i18next.t('main:tools.Beam.title'));
    +  setText('tool_PointSource_mobile_label', i18next.t('main:tools.PointSource.title') + ' (360\u00B0)');
    +  setText('tool_AngleSource_mobile_label', i18next.t('main:tools.PointSource.title') + ' (<360\u00B0)');
    +  setText('tool_Mirror_mobile_label', i18next.t('main:tools.Mirror.title'));
    +  setText('tool_ArcMirror_mobile_label', i18next.t('main:tools.ArcMirror.title'));
    +  setText('tool_ParabolicMirror_mobile_label', i18next.t('main:tools.ParabolicMirror.title'));
    +  setText('tool_CustomMirror_mobile_label', i18next.t('main:tools.CustomMirror.title'));
    +  setText('tool_IdealMirror_mobile_label', i18next.t('main:tools.IdealMirror.title'));
    +  setText('tool_BeamSplitter_mobile_label', i18next.t('main:tools.BeamSplitter.title'));
    +  setText('tool_PlaneGlass_mobile_label', i18next.t('main:tools.PlaneGlass.title'));
    +  setText('tool_CircleGlass_mobile_label', i18next.t('main:tools.CircleGlass.title'));
    +  setText('tool_Glass_mobile_label', i18next.t('main:tools.Glass.title'));
    +  setText('tool_CustomGlass_mobile_label', i18next.t('main:tools.CustomGlass.title'));
    +  setText('tool_IdealLens_mobile_label', i18next.t('main:tools.IdealLens.title'));
    +  setText('tool_SphericalLens_mobile_label', i18next.t('main:tools.SphericalLens.title'));
    +  setText('tool_CircleGrinGlass_mobile_label', i18next.t('main:tools.CircleGrinGlass.title'));
    +  setText('tool_GrinGlass_mobile_label', i18next.t('main:tools.GrinGlass.title'));
    +  setText('tool_Blocker_mobile_label', i18next.t('main:tools.Blocker.title'));
    +  setText('tool_CircleBlocker_mobile_label', i18next.t('main:tools.CircleBlocker.title'));
    +  setText('tool_Aperture_mobile_label', i18next.t('main:tools.Aperture.title'));
    +  setText('tool_DiffractionGrating_mobile_label', i18next.t('main:tools.DiffractionGrating.title'));
    +  setText('tool_Ruler_mobile_label', i18next.t('main:tools.Ruler.title'));
    +  setText('tool_Protractor_mobile_label', i18next.t('main:tools.Protractor.title'));
    +  setText('tool_Detector_mobile_label', i18next.t('main:tools.Detector.title'));
    +  setText('tool_TextLabel_mobile_label', i18next.t('main:tools.TextLabel.title'));
    +  setText('tool_LineArrow_mobile_label', i18next.t('main:tools.LineArrow.title'));
    +  setText('tool_Drawing_mobile_label', i18next.t('main:tools.Drawing.title'));
    +  setText('import_modules_mobile', '<i>' + i18next.t('main:tools.modules.import') + '</i>');
    +  setText('view_mobile_text', i18next.t('main:view.title'));
    +  setText('mode_rays_mobile_label', i18next.t('main:view.rays.title'));
    +  setText('mode_extended_mobile_label', i18next.t('main:view.extended.title'));
    +  setText('mode_images_mobile_label', i18next.t('main:view.images.title'));
    +  setText('mode_observer_mobile_label', i18next.t('main:view.observer.title'));
    +  setText('moreSettings_text_mobile', i18next.t('simulator:settings.more'));
    +  setText('rayDensity_mobile_text', i18next.t('simulator:settings.rayDensity.title'));
    +  setText('showGrid_text', i18next.t('simulator:settings.layoutAids.showGrid'));
    +  setText('snapToGrid_text', i18next.t('simulator:settings.layoutAids.snapToGrid'));
    +  setText('lockObjs_text', i18next.t('simulator:settings.layoutAids.lockObjs'));
    +  setText('simulateColors_mobile_text', i18next.t('main:simulateColors.title'));
    +  setText('gridSize_mobile_text', i18next.t('simulator:settings.gridSize.title'));
    +  setText('observer_size_mobile_text', i18next.t('simulator:settings.observerSize.title'));
    +  setText('lengthScale_mobile_text', i18next.t('simulator:settings.lengthScale.title'));
    +  setText('zoom_mobile_text', i18next.t('simulator:settings.zoom.title'));
    +  setText('auto_sync_url_mobile_text', i18next.t('simulator:settings.autoSyncUrl.title'));
    +  setText('show_json_editor_mobile_text', i18next.t('simulator:settings.showJsonEditor.title'));
    +  setText('show_status_mobile_text', i18next.t('simulator:settings.showStatusBox.title'));
    +  setText('language_mobile_text', i18next.t('simulator:settings.language.title'));
    +  setText('showAdvanced', i18next.t('simulator:objBar.showAdvanced.title'));
    +  setText('apply_to_all_label', null, i18next.t('simulator:objBar.applyToAll.title'));
    +  setText('copy', null, i18next.t('simulator:objBar.duplicate.title'));
    +  setText('delete', null, i18next.t('simulator:objBar.delete.title'));
    +  setText('unselect', null, null, i18next.t('simulator:objBar.unselect.description'));
    +  setText('showAdvanced_mobile', i18next.t('simulator:objBar.showAdvanced.title'));
    +  setText('apply_to_all_mobile_label', i18next.t('simulator:objBar.applyToAll.title'));
    +  setText('copy_mobile', i18next.t('simulator:objBar.duplicate.title'));
    +  setText('delete_mobile', i18next.t('simulator:objBar.delete.title'));
    +  setText('unselect_mobile', i18next.t('simulator:objBar.unselect.title'));
    +  setText('staticBackdropLabel_save', i18next.t('simulator:file.save.title'));
    +  setText('save_name_label', i18next.t('simulator:saveModal.fileName'));
    +  setText('save_description', '<ul><li>' + i18next.t('simulator:saveModal.description.autoSync') + '</li><li>' + i18next.t('simulator:saveModal.description.rename') + '</li><li>' + parseLinks(i18next.t('simulator:saveModal.description.contribute')) + '</li></ul>');
    +  setText('save_confirm', i18next.t('simulator:file.save.title'));
    +  setText('save_rename', i18next.t('simulator:saveModal.rename'));
    +  setText('save_cancel_button', i18next.t('simulator:common.cancelButton'));
    +  setText('staticBackdropLabel_language', i18next.t('simulator:settings.language.title'));
    +  setText('language_list_title', i18next.t('simulator:settings.language.title'));
    +  setText('translated_text', i18next.t('simulator:languageModal.translatedFraction'));
    +  setText('translate', i18next.t('simulator:languageModal.helpTranslate'));
    +  setText('close_language', i18next.t('simulator:common.closeButton'));
    +  setText('staticBackdropLabel_module', i18next.t('simulator:moduleModal.title'));
    +  setText('modules_tutorial', i18next.t('simulator:moduleModal.makeCustomModules'));
    +  setText('close_module', i18next.t('simulator:common.closeButton'));
    +  setText('home', null, i18next.t('main:pages.home'));
    +  setText('help_popover_text', '<b>' + i18next.t('simulator:footer.helpPopup.constrainedDragging.title') + '</b><p>' + i18next.t('simulator:footer.helpPopup.constrainedDragging.description') + '</p><b>' + i18next.t('simulator:footer.helpPopup.groupRotateScale.title') + '</b><p>' + i18next.t('simulator:footer.helpPopup.groupRotateScale.description') + '</p><b>' + i18next.t('simulator:footer.helpPopup.editCoordinates.title') + '</b><p>' + i18next.t('simulator:footer.helpPopup.editCoordinates.description') + '</p><b>' + i18next.t('simulator:footer.helpPopup.keyboardShortcuts.title') + '</b><p>' + i18next.t('simulator:footer.helpPopup.keyboardShortcuts.description') + '</p><b>' + i18next.t('simulator:footer.helpPopup.contactUs.title') + '</b><p>' + parseLinks(i18next.t('simulator:footer.helpPopup.contactUs.description')) + '</p><p>' + parseLinks(i18next.t('simulator:footer.helpPopup.contactUs.contribute')) + '</p>');
    +  setText('about', i18next.t('main:pages.about'));
    +  setText('github', null, i18next.t('main:pages.github'));
    +
    +
    +  document.getElementById('language').innerHTML = window.localeData[lang].name;
    +  document.getElementById('language_mobile').innerHTML = window.localeData[lang].name;
    +
    +  // Populate the language list
    +  const languageList = document.getElementById('language_list');
    +  
    +  for (const locale in window.localeData) {
    +    const languageName = window.localeData[locale].name;
    +    const completeness = Math.round(window.localeData[locale].numStrings / window.localeData.en.numStrings * 100);
    +    /*
    +    languageList.innerHTML += `
    +      <a href="?${locale}" class="btn btn-primary dropdown-item d-flex align-items-center" onclick="if (autoSyncUrl && !hasUnsavedChange) {event.preventDefault(); event.stopPropagation(); navigateToNewQuery('${locale}')}">
    +        <div class="d-flex w-100">
    +          <div class="col">
    +            ${languageName}
    +          </div>
    +          <div class="col text-end">
    +            ${completeness}%
    +          </div>
    +        </div>
    +      </a>
    +    `;
    +    */
    +    const a = document.createElement('a');
    +    a.href = '?' + locale;
    +    a.classList.add('btn', 'btn-primary', 'dropdown-item', 'd-flex', 'align-items-center');
    +    a.addEventListener('click', function (event) {
    +      if (autoSyncUrl && !hasUnsavedChange) {
    +        event.preventDefault();
    +        event.stopPropagation();
    +        navigateToNewQuery(locale);
    +      }
    +    });
    +
    +    const div = document.createElement('div');
    +    div.classList.add('d-flex', 'w-100');
    +
    +    const div1 = document.createElement('div');
    +    div1.classList.add('col');
    +    div1.innerHTML = languageName;
    +
    +    const div2 = document.createElement('div');
    +    div2.classList.add('col', 'text-end');
    +    div2.innerHTML = completeness + '%';
    +
    +    div.appendChild(div1);
    +    div.appendChild(div2);
    +    a.appendChild(div);
    +    languageList.appendChild(a);
    +  }
    +
    +  document.title = i18next.t('main:pages.simulator') + ' - ' + i18next.t('main:project.name');
    +  document.getElementById('home').href = mapURL('/home');
    +  document.getElementById('about').href = mapURL('/about');
    +  document.getElementById('moduleIframe').src = mapURL('/modules/modules');
    +  document.getElementById('modules_tutorial').href = mapURL('/modules/tutorial');
    +}
    +
    +function navigateToNewQuery(newQuery) {
    +  let currentUrl = window.location.href;
    +  let baseUrl = currentUrl.split('?')[0];  // Remove current query if exists
    +  baseUrl = baseUrl.split('#')[0];         // Further remove the hash to get the base URL
    +
    +  let hash = window.location.hash;         // Capture the existing hash
    +  let newUrl = baseUrl + "?" + newQuery + hash;  // Construct the new URL with the query and hash
    +
    +  window.location.href = newUrl;  // Set the new URL
    +}
    +
    +function setText(id, text, title, popover, image) {
    +  const elem = document.getElementById(id);
    +
    +  if (text != null) {
    +    elem.innerHTML = text;
    +  }
    +  
    +  if (popoversEnabled) {
    +    if (title != null) {
    +      elem.setAttribute('title', title);
    +    }
    +
    +    if (popover != null) {
    +      // Popover
    +      if (image != null) {
    +        const content = '<img src="../img/' + image + '" class="popover-image" id="dynamic-popover-image">' + popover;
    +        elem.setAttribute('data-bs-toggle', 'popover');
    +        elem.setAttribute('data-bs-trigger', 'hover');
    +        elem.setAttribute('data-bs-html', 'true');
    +        elem.setAttribute('data-bs-content', content);
    +
    +        // Update popover size after image is loaded
    +        elem.addEventListener('inserted.bs.popover', function () {
    +          const imgElement = document.querySelectorAll('#dynamic-popover-image');
    +          imgElement[imgElement.length - 1].addEventListener('load', function () {
    +            bootstrap.Popover.getInstance(elem).update();
    +          });
    +        });
    +      } else {
    +        elem.setAttribute('data-bs-toggle', 'popover');
    +        elem.setAttribute('data-bs-trigger', 'hover');
    +        elem.setAttribute('data-bs-html', 'true');
    +        elem.setAttribute('data-bs-content', popover);
    +      }
    +
    +      // Initialize the popover
    +      new bootstrap.Popover(elem);
    +    } else if (title != null) {
    +      // Tooltip
    +      elem.setAttribute('title', title);
    +      elem.setAttribute('data-bs-toggle', 'tooltip');
    +      elem.setAttribute('data-bs-trigger', 'hover');
    +      elem.setAttribute('data-bs-placement', 'bottom');
    +
    +      // Initialize the tooltip
    +      new bootstrap.Tooltip(elem);
    +    }
    +  } else {
    +    if (text == null && title != null) {
    +      elem.setAttribute('title', title);
    +      elem.setAttribute('data-bs-toggle', 'tooltip');
    +      elem.setAttribute('data-bs-trigger', 'hover');
    +      elem.setAttribute('data-bs-placement', 'bottom');
    +
    +      // Initialize the tooltip
    +      new bootstrap.Tooltip(elem);
    +    }
    +  }
    +}
    +
    +
    +
    +var popoversEnabled = true;
    +
    +
    +document.getElementById('show_help_popups').checked = popoversEnabled;
    +
    +
    +var currentMobileToolGroupId = null;
    +
    +function initTools() {
    +
    +  const allElements = document.querySelectorAll('*');
    +
    +  allElements.forEach(element => {
    +    if (element.id && element.id.startsWith('mobile-dropdown-trigger-')) {
    +      const toolGroupId = element.id.replace('mobile-dropdown-trigger-', '');
    +      const toolGroup = document.getElementById(`mobile-dropdown-${toolGroupId}`);
    +
    +      element.addEventListener('click', (event) => {
    +        // Show the corresponding tool group in the mobile tool dropdown.
    +        event.stopPropagation();
    +        const originalWidth = $("#mobile-dropdown-tools-root").width();
    +        const originalMarginLeft = parseInt($("#mobile-dropdown-tools-root").css("margin-left"), 10);
    +        const originalMarginRight = parseInt($("#mobile-dropdown-tools-root").css("margin-right"), 10);
    +        $("#mobile-dropdown-tools-root").animate({ "margin-left": -originalWidth, "margin-right": originalWidth }, 300, function () {
    +          $(this).hide();
    +          toolGroup.style.display = '';
    +          $(this).css({
    +            "margin-left": originalMarginLeft + "px",
    +            "margin-right": originalMarginRight + "px"
    +          });
    +          f();
    +        });
    +
    +        currentMobileToolGroupId = toolGroupId;
    +      });
    +    }
    +
    +    if (element.id && element.id.startsWith('tool_')) {
    +      const toolId = element.id.replace('tool_', '').replace('_mobile', '');
    +      element.addEventListener('click', (event) => {
    +        //console.log('tool_' + toolId);
    +        toolbtn_clicked(toolId);
    +      });
    +    }
    +  });
    +
    +  document.getElementById('mobile-tools').addEventListener('click', (event) => {
    +    // Hide the mobile tool dropdown.
    +    if (currentMobileToolGroupId != null) {
    +      document.getElementById(`mobile-dropdown-${currentMobileToolGroupId}`).style.display = 'none';
    +      document.getElementById('mobile-dropdown-tools-root').style.display = '';
    +      f();
    +    }
    +  });
    +
    +}
    +
    +
    +
    +function initModes() {
    +  const allElements = document.querySelectorAll('*');
    +
    +  allElements.forEach(element => {
    +    if (element.id && element.id.startsWith('mode_')) {
    +      const modeId = element.id.replace('mode_', '').replace('_mobile', '');
    +      element.addEventListener('click', (event) => {
    +        //console.log('mode_' + modeId);
    +        modebtn_clicked(modeId);
    +        editor.onActionComplete();
    +      });
    +    }
    +  });
    +}
    +
    +function hideAllPopovers() {
    +  document.querySelectorAll('[data-bs-original-title]').forEach(function (element) {
    +    var popoverInstance = bootstrap.Popover.getInstance(element);
    +    if (popoverInstance) {
    +      popoverInstance.hide();
    +    }
    +    var tooltipInstance = bootstrap.Tooltip.getInstance(element);
    +    if (tooltipInstance) {
    +      tooltipInstance.hide();
    +    }
    +  });
    +}
    +
    +document.getElementById('help-dropdown').addEventListener('click', function (e) {
    +  e.stopPropagation();
    +});
    +
    +var aceEditor;
    +var lastCodeChangeIsFromScene = false;
    +
    +function enableJsonEditor() {
    +  aceEditor = ace.edit("jsonEditor");
    +  aceEditor.setTheme("ace/theme/github_dark");
    +  aceEditor.session.setMode("ace/mode/json");
    +  aceEditor.session.setUseWrapMode(true);
    +  aceEditor.session.setUseSoftTabs(true);
    +  aceEditor.session.setTabSize(2);
    +  aceEditor.setHighlightActiveLine(false)
    +  aceEditor.container.style.background = "transparent"
    +  aceEditor.container.getElementsByClassName('ace_gutter')[0].style.background = "transparent"
    +  aceEditor.session.setValue(editor.lastActionJson);
    +
    +  var debounceTimer;
    +
    +  aceEditor.session.on('change', function (delta) {
    +    if (lastCodeChangeIsFromScene) {
    +      setTimeout(function () {
    +        lastCodeChangeIsFromScene = false;
    +      }, 100);
    +      return;
    +    }
    +    clearTimeout(debounceTimer);
    +    debounceTimer = setTimeout(function () {
    +      editor.loadJSON(aceEditor.session.getValue());
    +      error = null;
    +      const newJsonCode = editor.lastActionJson;
    +      if (!scene.error) {
    +        syncUrl();
    +        editor.requireDelayedValidation();
    +      }
    +    }, 500);
    +  });
    +
    +  document.getElementById('footer-left').style.left = '400px';
    +  document.getElementById('sideBar').style.display = '';
    +}
    +
    +function updateModuleObjsMenu() {
    +  for (let suffix of ['', '_mobile']) {
    +    const moduleStartLi = document.getElementById('module_start' + suffix);
    +
    +    // Remove all children after moduleStartLi
    +    while (moduleStartLi.nextElementSibling) {
    +      moduleStartLi.nextElementSibling.remove();
    +    }
    +
    +    // Add all module objects to the menu after moduleStartLi
    +    for (let moduleName of Object.keys(scene.modules)) {
    +      const moduleLi = document.createElement('li');
    +
    +      const moduleRadio = document.createElement('input');
    +      moduleRadio.type = 'radio';
    +      moduleRadio.name = 'toolsradio' + suffix;
    +      moduleRadio.id = 'moduleTool_' + moduleName + suffix;
    +      moduleRadio.classList.add('btn-check');
    +      moduleRadio.autocomplete = 'off';
    +      moduleRadio.addEventListener('change', function () {
    +        if (moduleRadio.checked) {
    +          resetDropdownButtons();
    +          document.getElementById('moreToolsDropdown').classList.add('selected');
    +          document.getElementById('mobile-dropdown-trigger-more').classList.add('selected');
    +          toolbtn_clicked('ModuleObj');
    +          editor.addingModuleName = moduleName;
    +        }
    +      });
    +
    +      const moduleLabel = document.createElement('label');
    +      moduleLabel.classList.add('btn', 'shadow-none', 'btn-primary', 'dropdown-item', 'd-flex', 'w-100');
    +      moduleLabel.htmlFor = 'moduleTool_' + moduleName + suffix;
    +
    +      const moduleNameDiv = document.createElement('div');
    +      moduleNameDiv.classList.add('col');
    +      moduleNameDiv.style.fontFamily = 'monospace';
    +      moduleNameDiv.innerText = moduleName;
    +      moduleLabel.appendChild(moduleNameDiv);
    +
    +
    +      const removeButtonDiv = document.createElement('div');
    +      removeButtonDiv.classList.add('col', 'text-end');
    +      const removeButton = document.createElement('button');
    +      removeButton.classList.add('btn');
    +      removeButton.style.color = 'gray';
    +      removeButton.style.padding = '0px';
    +      //removeButton.style.margin = '0px';
    +      removeButton.style.fontSize = '10px';
    +      removeButton.innerHTML = `
    +      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash3" viewBox="-4 0 16 20">
    +        <path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5ZM11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3A1.5 1.5 0 0 0 5 1.5v1H2.506a.58.58 0 0 0-.01 0H1.5a.5.5 0 0 0 0 1h.538l.853 10.66A2 2 0 0 0 4.885 16h6.23a2 2 0 0 0 1.994-1.84l.853-10.66h.538a.5.5 0 0 0 0-1h-.995a.59.59 0 0 0-.01 0H11Zm1.958 1-.846 10.58a1 1 0 0 1-.997.92h-6.23a1 1 0 0 1-.997-.92L3.042 3.5h9.916Zm-7.487 1a.5.5 0 0 1 .528.47l.5 8.5a.5.5 0 0 1-.998.06L5 5.03a.5.5 0 0 1 .47-.53Zm5.058 0a.5.5 0 0 1 .47.53l-.5 8.5a.5.5 0 1 1-.998-.06l.5-8.5a.5.5 0 0 1 .528-.47ZM8 4.5a.5.5 0 0 1 .5.5v8.5a.5.5 0 0 1-1 0V5a.5.5 0 0 1 .5-.5Z"/>
    +      </svg>
    +      `;
    +      removeButton.setAttribute('data-bs-toggle', 'tooltip');
    +      removeButton.setAttribute('title', i18next.t('main:tools.modules.remove'));
    +      removeButton.setAttribute('data-bs-placement', 'right');
    +      new bootstrap.Tooltip(removeButton);
    +      removeButton.addEventListener('click', function () {
    +        console.log(moduleName);
    +        scene.removeModule(moduleName);
    +        if (editor.addingObjType == 'ModuleObj' && editor.addingModuleName == moduleName) {
    +          toolbtn_clicked('');  // Deselect the module object tool
    +        }
    +        simulator.updateSimulation(false, true);
    +        hideAllPopovers();
    +        updateModuleObjsMenu();
    +        editor.onActionComplete();
    +      });
    +      removeButtonDiv.appendChild(removeButton);
    +
    +      moduleLabel.appendChild(removeButtonDiv);
    +      moduleLi.appendChild(moduleRadio);
    +      moduleLi.appendChild(moduleLabel);
    +      moduleStartLi.after(moduleLi);
    +
    +    }
    +  }
    +
    +}
    +
    +function disableJsonEditor() {
    +  aceEditor.destroy();
    +  aceEditor = null;
    +  document.getElementById('footer-left').style.left = '0px';
    +  document.getElementById('sideBar').style.display = 'none';
    +}
    +
    +function updateErrorAndWarning() {
    +  let errors = [];
    +  let warnings = [];
    +
    +  if (error) {
    +    errors.push("App: " + error);
    +  }
    +
    +  if (warning) {
    +    warnings.push("App: " + warning);
    +  }
    +
    +  if (scene.error) {
    +    errors.push("Scene: " + scene.error);
    +  }
    +
    +  if (scene.warning) {
    +    warnings.push("Scene: " + scene.warning);
    +  }
    +
    +  if (simulator.error) {
    +    errors.push("Simulator: " + simulator.error);
    +  }
    +
    +  if (simulator.warning) {
    +    warnings.push("Simulator: " + simulator.warning);
    +  }
    +
    +  for (let i in scene.objs) {
    +    let error = scene.objs[i].getError();
    +    if (error) {
    +      errors.push(`objs[${i}] ${scene.objs[i].constructor.type}: ${error}`);
    +    }
    +
    +    let warning = scene.objs[i].getWarning();
    +    if (warning) {
    +      warnings.push(`objs[${i}] ${scene.objs[i].constructor.type}: ${warning}`);
    +    }
    +  }
    +
    +  if (errors.length > 0) {
    +    document.getElementById('errorText').innerText = errors.join('\n');
    +    document.getElementById('error').style.display = '';
    +  } else {
    +    document.getElementById('error').style.display = 'none';
    +  }
    +
    +  if (warnings.length > 0) {
    +    document.getElementById('warningText').innerText = warnings.join('\n');
    +    document.getElementById('warning').style.display = '';
    +  } else {
    +    document.getElementById('warning').style.display = 'none';
    +  }
    +}
    +
    +function openSample(name) {
    +  var client = new XMLHttpRequest();
    +  client.open('GET', '../gallery/' + name);
    +  client.onload = function () {
    +    if (client.status >= 300) {
    +      error = "openSample: HTTP Request Error: " + client.status;
    +      document.getElementById('welcome').style.display = 'none';
    +      updateErrorAndWarning();
    +      return;
    +    }
    +    scene.backgroundImage = null;
    +    editor.loadJSON(client.responseText);
    +
    +    editor.onActionComplete();
    +    hasUnsavedChange = false;
    +    if (aceEditor) {
    +      aceEditor.session.setValue(editor.lastActionJson);
    +    }
    +  }
    +  client.onerror = function () {
    +    error = "openSample: HTTP Request Error";
    +    document.getElementById('welcome').style.display = 'none';
    +    updateErrorAndWarning();
    +  }
    +  client.ontimeout = function () {
    +    error = "openSample: HTTP Request Timeout";
    +    document.getElementById('welcome').style.display = 'none';
    +    updateErrorAndWarning();
    +  }
    +
    +  client.send();
    +}
    +
    +function importModule(name) {
    +  var client = new XMLHttpRequest();
    +  client.open('GET', '../modules/' + name);
    +  client.onload = function () {
    +    document.getElementById('welcome').style.display = 'none';
    +    if (client.status >= 300) {
    +      error = "importModule: HTTP Request Error: " + client.status;
    +      updateErrorAndWarning();
    +      return;
    +    }
    +    try {
    +      const moduleJSON = JSON.parse(client.responseText);
    +      for (let moduleName in moduleJSON.modules) {
    +        if (moduleJSON.modules.hasOwnProperty(moduleName)) {
    +          let newModuleName = moduleName;
    +          if (scene.modules[moduleName] && JSON.stringify(scene.modules[moduleName]) != JSON.stringify(moduleJSON.modules[moduleName])) {
    +            newModuleName = prompt(i18next.t('simulator:moduleModal.conflict'), moduleName);
    +            if (!newModuleName) {
    +              continue;
    +            }
    +          }
    +          scene.addModule(newModuleName, moduleJSON.modules[moduleName]);
    +        }
    +      }
    +    } catch (e) {
    +      error = "importModule: " + e.toString();
    +      updateErrorAndWarning();
    +      return;
    +    }
    +    simulator.updateSimulation(false, true);
    +    editor.onActionComplete();
    +    updateModuleObjsMenu();
    +  }
    +  client.onerror = function () {
    +    error = "importModule: HTTP Request Error";
    +    document.getElementById('welcome').style.display = 'none';
    +    updateErrorAndWarning();
    +  }
    +  client.ontimeout = function () {
    +    error = "importModule: HTTP Request Timeout";
    +    document.getElementById('welcome').style.display = 'none';
    +    updateErrorAndWarning();
    +  }
    +
    +  client.send();
    +}
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +function init() {
    +  document.title = i18next.t('main:pages.simulator') + ' - ' + i18next.t('main:project.name');
    +  document.getElementById('save_name').value = "";
    +
    +  editor.isConstructing = false;
    +  editor.endPositioning();
    +
    +  scene.backgroundImage = null;
    +  scene.loadJSON(JSON.stringify({ version: DATA_VERSION }), () => { });
    +  scene.origin = geometry.point(0, 0);
    +  scene.scale = 1;
    +
    +  let dpr = window.devicePixelRatio || 1;
    +
    +  scene.setViewportSize(canvas.width / dpr, canvas.height / dpr);
    +
    +  editor.selectObj(-1);
    +
    +  document.getElementById("rayDensity").value = scene.rayModeDensity;
    +  document.getElementById("rayDensity_more").value = scene.rayModeDensity;
    +  document.getElementById("rayDensity_mobile").value = scene.rayModeDensity;
    +  document.getElementById("zoom").innerText = Math.round(scene.scale * scene.lengthScale * 100) + '%';
    +  document.getElementById("zoom_mobile").innerText = Math.round(scene.scale * scene.lengthScale * 100) + '%';
    +  toolbtn_clicked('');
    +  modebtn_clicked('rays');
    +  scene.backgroundImage = null;
    +
    +  //Reset new UI.
    +
    +  resetDropdownButtons();
    +  updateModuleObjsMenu();
    +
    +  document.getElementById('tool_').checked = true;
    +  document.getElementById('tool__mobile').checked = true;
    +  document.getElementById('mode_rays').checked = true;
    +  document.getElementById('mode_rays_mobile').checked = true;
    +
    +  document.getElementById('lockObjs').checked = false;
    +  document.getElementById('snapToGrid').checked = false;
    +  document.getElementById('showGrid').checked = false;
    +
    +  document.getElementById('lockObjs_more').checked = false;
    +  document.getElementById('snapToGrid_more').checked = false;
    +  document.getElementById('showGrid_more').checked = false;
    +
    +  document.getElementById('lockObjs_mobile').checked = false;
    +  document.getElementById('snapToGrid_mobile').checked = false;
    +  document.getElementById('showGrid_mobile').checked = false;
    +
    +  document.getElementById('simulateColors').checked = false;
    +  document.getElementById('simulateColors_mobile').checked = false;
    +
    +  document.getElementById('apply_to_all').checked = false;
    +  document.getElementById('apply_to_all_mobile').checked = false;
    +
    +  document.getElementById('gridSize').value = scene.gridSize;
    +  document.getElementById('gridSize_mobile').value = scene.gridSize;
    +
    +  document.getElementById('observer_size').value = 40;
    +  document.getElementById('observer_size_mobile').value = 40;
    +
    +  document.getElementById('lengthScale').value = scene.lengthScale;
    +  document.getElementById('lengthScale_mobile').value = scene.lengthScale;
    +
    +  simulator.updateSimulation();
    +}
    +
    +
    +
    +
    +
    +var lastFullURL = "";
    +var syncUrlTimerId = -1;
    +
    +function syncUrl() {
    +  if (!autoSyncUrl) return;
    +  if (document.getElementById('welcome').style.display != 'none') return;
    +
    +  if (syncUrlTimerId != -1) {
    +    clearTimeout(syncUrlTimerId);
    +  }
    +  syncUrlTimerId = setTimeout(function () {
    +    var compressed = require('json-url')('lzma').compress(JSON.parse(editor.lastActionJson)).then(output => {
    +      var fullURL = "https://phydemo.app/ray-optics/simulator/#" + output;
    +      if (fullURL.length > 2041) {
    +        warning = i18next.t('simulator:generalWarnings.autoSyncUrlTooLarge');
    +        updateErrorAndWarning();
    +      } else {
    +        if (Math.abs(fullURL.length - lastFullURL.length) > 200) {
    +          // If the length of the scene change significantly, push a new history state to prevent accidental data loss.
    +          lastFullURL = fullURL;
    +          window.history.pushState(undefined, undefined, '#' + output);
    +        } else {
    +          lastFullURL = fullURL;
    +          window.history.replaceState(undefined, undefined, '#' + output);
    +        }
    +        hasUnsavedChange = false;
    +        warning = "";
    +        updateErrorAndWarning();
    +      }
    +    });
    +  }, 1000);
    +}
    +
    +
    +function toolbtn_clicked(tool, e) {
    +  if (tool != "") {
    +    document.getElementById('welcome').style.display = 'none';
    +  }
    +  editor.addingObjType = tool;
    +}
    +
    +
    +function modebtn_clicked(mode1) {
    +  scene.mode = mode1;
    +  if (scene.mode == 'images' || scene.mode == 'observer') {
    +    document.getElementById("rayDensity").value = Math.log(scene.imageModeDensity);
    +    document.getElementById("rayDensity_more").value = Math.log(scene.imageModeDensity);
    +    document.getElementById("rayDensity_mobile").value = Math.log(scene.imageModeDensity);
    +  }
    +  else {
    +    document.getElementById("rayDensity").value = Math.log(scene.rayModeDensity);
    +    document.getElementById("rayDensity_more").value = Math.log(scene.rayModeDensity);
    +    document.getElementById("rayDensity_mobile").value = Math.log(scene.rayModeDensity);
    +  }
    +  if (scene.mode == 'observer' && !scene.observer) {
    +    // Initialize the observer
    +    scene.observer = geometry.circle(geometry.point((canvas.width * 0.5 / simulator.dpr - scene.origin.x) / scene.scale, (canvas.height * 0.5 / simulator.dpr - scene.origin.y) / scene.scale), parseFloat(document.getElementById('observer_size').value) * 0.5);
    +  }
    +
    +
    +  simulator.updateSimulation(false, true);
    +}
    +
    +
    +
    +
    +function rename() {
    +  scene.name = document.getElementById('save_name').value;
    +  if (scene.name) {
    +    document.title = scene.name + " - " + i18next.t('main:pages.simulator') + ' - ' + i18next.t('main:project.name');
    +  } else {
    +    document.title = i18next.t('main:pages.simulator') + ' - ' + i18next.t('main:project.name');
    +  }
    +  editor.onActionComplete();
    +}
    +
    +function save() {
    +  rename();
    +
    +  var blob = new Blob([editor.lastActionJson], { type: 'application/json' });
    +  saveAs(blob, (scene.name || "scene") + ".json");
    +  var saveModal = bootstrap.Modal.getInstance(document.getElementById('saveModal'));
    +  if (saveModal) {
    +    saveModal.hide();
    +  }
    +  hasUnsavedChange = false;
    +}
    +
    +function openFile(readFile) {
    +  var reader = new FileReader();
    +  reader.readAsText(readFile);
    +  reader.onload = function (evt) {
    +    var fileString = evt.target.result;
    +
    +    let isJSON = true;
    +    try {
    +      const parsed = JSON.parse(fileString);
    +      if (typeof parsed !== 'object' || parsed === null) {
    +        isJSON = false;
    +      }
    +    } catch (e) {
    +      isJSON = false;
    +    }
    +
    +    if (isJSON) {
    +      // Load the scene file
    +      editor.loadJSON(fileString);
    +      hasUnsavedChange = false;
    +      editor.onActionComplete();
    +      if (aceEditor) {
    +        aceEditor.session.setValue(editor.lastActionJson);
    +      }
    +    } else {
    +      // Load the background image file
    +      reader.onload = function (e) {
    +        scene.backgroundImage = new Image();
    +        scene.backgroundImage.src = e.target.result;
    +        scene.backgroundImage.onload = function (e1) {
    +          simulator.updateSimulation(true, true);
    +        }
    +        scene.backgroundImage.onerror = function (e1) {
    +          scene.backgroundImage = null;
    +          error = "openFile: The file is neither a valid JSON scene nor an image file.";
    +          updateErrorAndWarning();
    +        }
    +      }
    +      reader.readAsDataURL(readFile);
    +    }
    +  };
    +
    +}
    +
    +function getLink() {
    +  require('json-url')('lzma').compress(JSON.parse(editor.lastActionJson)).then(output => {
    +    var fullURL = "https://phydemo.app/ray-optics/simulator/#" + output;
    +    lastFullURL = fullURL;
    +    window.history.pushState(undefined, undefined, '#' + output);
    +    //console.log(fullURL.length);
    +    navigator.clipboard.writeText(fullURL);
    +    if (fullURL.length > 2041) {
    +      alert(i18next.t('simulator:generalWarnings.shareLinkTooLong'));
    +    } else {
    +      hasUnsavedChange = false;
    +    }
    +  });
    +}
    +
    +
    +window.onbeforeunload = function (e) {
    +  if (hasUnsavedChange) {
    +    return "You have unsaved change.";
    +  }
    +}
    +
    +function confirmPositioning(ctrl, shift) {
    +  var xyData = JSON.parse('[' + document.getElementById('xybox').value.replace(/\(|\)/g, '') + ']');
    +  if (xyData.length == 2) {
    +    editor.confirmPositioning(xyData[0], xyData[1], ctrl, shift);
    +  }
    +}
    +
    +
    +function mapURL(url) {
    +  const localeData = window.localeData[window.lang];
    +  const route = (localeData.route !== undefined) ? localeData.route : '/' + window.lang;
    +  const rootURL = '..'
    +  const urlMap = {
    +    "/home": rootURL + route + '/',
    +    "/gallery": rootURL + (localeData.gallery ? route : '') + '/gallery/',
    +    "/modules/modules": rootURL + (localeData.modules ? route : '') + '/modules/modules.html',
    +    "/modules/tutorial": rootURL + (localeData.moduleTutorial ? route : '') + '/modules/tutorial',
    +    "/about": rootURL + (localeData.about ? route : '') + '/about',
    +    "/email": "mailto:ray-optics@phydemo.app",
    +    "/github": "https://github.com/ricktu288/ray-optics",
    +    "/github/issues": "https://github.com/ricktu288/ray-optics/issues",
    +    "/github/discussions": "https://github.com/ricktu288/ray-optics/discussions",
    +    "/contributing": "https://github.com/ricktu288/ray-optics/blob/master/CONTRIBUTING.md",
    +    "/contributing/gallery": "https://github.com/ricktu288/ray-optics/blob/master/CONTRIBUTING.md#contributing-items-to-the-gallery",
    +    "/contributing/modules": "https://github.com/ricktu288/ray-optics/blob/master/CONTRIBUTING.md#contributing-modules",
    +  };
    +  return urlMap[url] || url;
    +}
    +
    +// Parse the markdown-like links in the text with mapURL and return the HTML.
    +function parseLinks(text) {
    +  return text.replace(/\[([^\]]+)\]\(([^\)]+)\)/g, function (match, text, url) {
    +    return `<a href="${mapURL(url)}" target="_blank">${text}</a>`;
    +  });
    +}
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/fonts/OpenSans-Bold-webfont.eot b/docs/fonts/OpenSans-Bold-webfont.eot new file mode 100644 index 00000000..5d20d916 Binary files /dev/null and b/docs/fonts/OpenSans-Bold-webfont.eot differ diff --git a/docs/fonts/OpenSans-Bold-webfont.svg b/docs/fonts/OpenSans-Bold-webfont.svg new file mode 100644 index 00000000..3ed7be4b --- /dev/null +++ b/docs/fonts/OpenSans-Bold-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Bold-webfont.woff b/docs/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 00000000..1205787b Binary files /dev/null and b/docs/fonts/OpenSans-Bold-webfont.woff differ diff --git a/docs/fonts/OpenSans-BoldItalic-webfont.eot b/docs/fonts/OpenSans-BoldItalic-webfont.eot new file mode 100644 index 00000000..1f639a15 Binary files /dev/null and b/docs/fonts/OpenSans-BoldItalic-webfont.eot differ diff --git a/docs/fonts/OpenSans-BoldItalic-webfont.svg b/docs/fonts/OpenSans-BoldItalic-webfont.svg new file mode 100644 index 00000000..6a2607b9 --- /dev/null +++ b/docs/fonts/OpenSans-BoldItalic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-BoldItalic-webfont.woff b/docs/fonts/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 00000000..ed760c06 Binary files /dev/null and b/docs/fonts/OpenSans-BoldItalic-webfont.woff differ diff --git a/docs/fonts/OpenSans-Italic-webfont.eot b/docs/fonts/OpenSans-Italic-webfont.eot new file mode 100644 index 00000000..0c8a0ae0 Binary files /dev/null and b/docs/fonts/OpenSans-Italic-webfont.eot differ diff --git a/docs/fonts/OpenSans-Italic-webfont.svg b/docs/fonts/OpenSans-Italic-webfont.svg new file mode 100644 index 00000000..e1075dcc --- /dev/null +++ b/docs/fonts/OpenSans-Italic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Italic-webfont.woff b/docs/fonts/OpenSans-Italic-webfont.woff new file mode 100644 index 00000000..ff652e64 Binary files /dev/null and b/docs/fonts/OpenSans-Italic-webfont.woff differ diff --git a/docs/fonts/OpenSans-Light-webfont.eot b/docs/fonts/OpenSans-Light-webfont.eot new file mode 100644 index 00000000..14868406 Binary files /dev/null and b/docs/fonts/OpenSans-Light-webfont.eot differ diff --git a/docs/fonts/OpenSans-Light-webfont.svg b/docs/fonts/OpenSans-Light-webfont.svg new file mode 100644 index 00000000..11a472ca --- /dev/null +++ b/docs/fonts/OpenSans-Light-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Light-webfont.woff b/docs/fonts/OpenSans-Light-webfont.woff new file mode 100644 index 00000000..e7860748 Binary files /dev/null and b/docs/fonts/OpenSans-Light-webfont.woff differ diff --git a/docs/fonts/OpenSans-LightItalic-webfont.eot b/docs/fonts/OpenSans-LightItalic-webfont.eot new file mode 100644 index 00000000..8f445929 Binary files /dev/null and b/docs/fonts/OpenSans-LightItalic-webfont.eot differ diff --git a/docs/fonts/OpenSans-LightItalic-webfont.svg b/docs/fonts/OpenSans-LightItalic-webfont.svg new file mode 100644 index 00000000..431d7e35 --- /dev/null +++ b/docs/fonts/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,1835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-LightItalic-webfont.woff b/docs/fonts/OpenSans-LightItalic-webfont.woff new file mode 100644 index 00000000..43e8b9e6 Binary files /dev/null and b/docs/fonts/OpenSans-LightItalic-webfont.woff differ diff --git a/docs/fonts/OpenSans-Regular-webfont.eot b/docs/fonts/OpenSans-Regular-webfont.eot new file mode 100644 index 00000000..6bbc3cf5 Binary files /dev/null and b/docs/fonts/OpenSans-Regular-webfont.eot differ diff --git a/docs/fonts/OpenSans-Regular-webfont.svg b/docs/fonts/OpenSans-Regular-webfont.svg new file mode 100644 index 00000000..25a39523 --- /dev/null +++ b/docs/fonts/OpenSans-Regular-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Regular-webfont.woff b/docs/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 00000000..e231183d Binary files /dev/null and b/docs/fonts/OpenSans-Regular-webfont.woff differ diff --git a/docs/geometry.html b/docs/geometry.html new file mode 100644 index 00000000..3f497c70 --- /dev/null +++ b/docs/geometry.html @@ -0,0 +1,3058 @@ + + + + + JSDoc: Namespace: geometry + + + + + + + + + + +
    + +

    Namespace: geometry

    + + + + + + +
    + +
    + +

    geometry

    + + +
    + +
    +
    + + +

    The geometry module, which provides basic geometric figures and operations.

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + +

    Methods

    + + + + + + + +

    (static) circle(c, r)

    + + + + + + +
    +

    Create a circle

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    c + + +Point + + + +

    The center point of the circle.

    r + + +number +| + +Point + + + +

    The radius of the circle or a point on the circle.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    (static) cross(p1, p2) → {Number}

    + + + + + + +
    +

    Calculate the cross product, where the two points are treated as vectors.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Number + + +
    +
    + + + + + + + + + + + + + +

    (static) distance(p1, p2) → {Number}

    + + + + + + +
    +

    Calculate the distance between two points.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Number + + +
    +
    + + + + + + + + + + + + + +

    (static) distanceSquared(p1, p2) → {Number}

    + + + + + + +
    +

    Calculate the squared distance between two points.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Number + + +
    +
    + + + + + + + + + + + + + +

    (static) dot(p1, p2) → {Number}

    + + + + + + +
    +

    Calculate the dot product, where the two points are treated as vectors.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Number + + +
    +
    + + + + + + + + + + + + + +

    (static) intersectionIsOnRay(p1, r1) → {Boolean}

    + + + + + + +
    +

    Test if a point on the extension of a ray is actually on the ray.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    r1 + + +Line + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Boolean + + +
    +
    + + + + + + + + + + + + + +

    (static) intersectionIsOnSegment(p1, s1) → {Boolean}

    + + + + + + +
    +

    Test if a point on the extension of a segment is actually on the segment.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    s1 + + +Line + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Boolean + + +
    +
    + + + + + + + + + + + + + +

    (static) line(p1, p2) → {Line}

    + + + + + + +
    +

    Create a line, which also represents a ray or a segment. +When used as a line, p1 and p2 are two distinct points on the line. +When used as a ray, p1 is the starting point and p2 is another point on the ray. +When used as a segment, p1 and p2 are the two endpoints of the segment.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Line + + +
    +
    + + + + + + + + + + + + + +

    (static) lineCircleIntersections(l1, c1) → {Array.<Point>}

    + + + + + + +
    +

    Calculate the intersections of a line and a circle.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    l1 + + +Line + + + +
    c1 + + +Circle + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Array.<Point> + + +
    +
    + + + + + + + + + + + + + +

    (static) linesIntersection(l1, l2) → {Point}

    + + + + + + +
    +

    Calculate the intersection of two lines.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    l1 + + +Line + + + +
    l2 + + +Line + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Point + + +
    +
    + + + + + + + + + + + + + +

    (static) midpoint(p1, p2) → {Point}

    + + + + + + +
    +

    Calculate the midpoint between two points.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Point + + +
    +
    + + + + + + + + + + + + + +

    (static) parallelLineThroughPoint(l1, p1) → {Line}

    + + + + + + +
    +

    Calculate the line though p1 and parallel to l1.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    l1 + + +Line + + + +
    p1 + + +Point + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Line + + +
    +
    + + + + + + + + + + + + + +

    (static) perpendicularBisector(l1) → {Line}

    + + + + + + +
    +

    Calculate the perpendicular bisector of a segment.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    l1 + + +Line + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Line + + +
    +
    + + + + + + + + + + + + + +

    (static) point(x, y) → {Point}

    + + + + + + +
    +

    Create a point

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +number + + + +

    The x-coordinate of the point.

    y + + +number + + + +

    The y-coordinate of the point.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Point + + +
    +
    + + + + + + + + + + + + + +

    (static) segmentLength(seg) → {Number}

    + + + + + + +
    +

    Calculate the length of a line segment.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    seg + + +Line + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Number + + +
    +
    + + + + + + + + + + + + + +

    (static) segmentLengthSquared(seg) → {Number}

    + + + + + + +
    +

    Calculate the squared length of a line segment.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    seg + + +Line + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Number + + +
    +
    + + + + + + + + + + + + + +

    (static) segmentMidpoint(l1) → {Point}

    + + + + + + +
    +

    Calculate the midpoint of a segment.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    l1 + + +Line + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +Point + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/geometry.js.html b/docs/geometry.js.html new file mode 100644 index 00000000..e8b82e88 --- /dev/null +++ b/docs/geometry.js.html @@ -0,0 +1,292 @@ + + + + + JSDoc: Source: geometry.js + + + + + + + + + + +
    + +

    Source: geometry.js

    + + + + + + +
    +
    +
    /**
    + * @typedef {Object} Point
    + * @property {number} x
    + * @property {number} y
    + */
    +
    +/**
    + * @typedef {Object} Line
    + * @property {Point} p1
    + * @property {Point} p2
    + */
    +
    +/**
    + * @typedef {Object} Circle
    + * @property {Point} c
    + * @property {number|Line} r
    + */
    +
    +/**
    + * The geometry module, which provides basic geometric figures and operations.
    + * @namespace geometry
    + */
    +const geometry = {
    +
    +  /**
    +   * Create a point
    +   * @param {number} x - The x-coordinate of the point.
    +   * @param {number} y - The y-coordinate of the point.
    +   * @returns {Point}
    +   */
    +  point: function (x, y) { return { x: x, y: y } },
    +
    +  /**
    +   * Create a line, which also represents a ray or a segment.
    +   * When used as a line, p1 and p2 are two distinct points on the line.
    +   * When used as a ray, p1 is the starting point and p2 is another point on the ray.
    +   * When used as a segment, p1 and p2 are the two endpoints of the segment.
    +   * @param {Point} p1
    +   * @param {Point} p2
    +   * @returns {Line}
    +   */
    +  line: function (p1, p2) { return { p1: p1, p2: p2 } },
    +
    +  /**
    +   * Create a circle
    +   * @param {Point} c - The center point of the circle.
    +   * @param {number|Point} r - The radius of the circle or a point on the circle.
    +   */
    +  circle: function (c, r) {
    +    if (typeof r == 'object') {
    +      return { c: c, r: geometry.line(c, r) }
    +    } else {
    +      return { c: c, r: r }
    +    }
    +  },
    +
    +  /**
    +  * Calculate the dot product, where the two points are treated as vectors.
    +  * @param {Point} p1
    +  * @param {Point} p2
    +  * @return {Number}
    +  **/
    +  dot: function (p1, p2) {
    +    return p1.x * p2.x + p1.y * p2.y;
    +  },
    +
    +  /**
    +  * Calculate the cross product, where the two points are treated as vectors.
    +  * @param {Point} p1
    +  * @param {Point} p2
    +  * @return {Number}
    +  **/
    +  cross: function (p1, p2) {
    +    return p1.x * p2.y - p1.y * p2.x;
    +  },
    +
    +  /**
    +  * Calculate the intersection of two lines.
    +  * @param {Line} l1
    +  * @param {Line} l2
    +  * @return {Point}
    +  **/
    +  linesIntersection: function (l1, l2) {
    +    var A = l1.p2.x * l1.p1.y - l1.p1.x * l1.p2.y;
    +    var B = l2.p2.x * l2.p1.y - l2.p1.x * l2.p2.y;
    +    var xa = l1.p2.x - l1.p1.x;
    +    var xb = l2.p2.x - l2.p1.x;
    +    var ya = l1.p2.y - l1.p1.y;
    +    var yb = l2.p2.y - l2.p1.y;
    +    return geometry.point((A * xb - B * xa) / (xa * yb - xb * ya), (A * yb - B * ya) / (xa * yb - xb * ya));
    +  },
    +
    +  /**
    +   * Calculate the intersections of a line and a circle.
    +   * @param {Line} l1
    +   * @param {Circle} c1
    +   * @return {Point[]}
    +   */
    +  lineCircleIntersections: function (l1, c1) {
    +    var xa = l1.p2.x - l1.p1.x;
    +    var ya = l1.p2.y - l1.p1.y;
    +    var cx = c1.c.x;
    +    var cy = c1.c.y;
    +    var r_sq = (typeof c1.r == 'object') ? ((c1.r.p1.x - c1.r.p2.x) * (c1.r.p1.x - c1.r.p2.x) + (c1.r.p1.y - c1.r.p2.y) * (c1.r.p1.y - c1.r.p2.y)) : (c1.r * c1.r);
    +
    +    var l = Math.sqrt(xa * xa + ya * ya);
    +    var ux = xa / l;
    +    var uy = ya / l;
    +
    +    var cu = ((cx - l1.p1.x) * ux + (cy - l1.p1.y) * uy);
    +    var px = l1.p1.x + cu * ux;
    +    var py = l1.p1.y + cu * uy;
    +
    +
    +    var d = Math.sqrt(r_sq - (px - cx) * (px - cx) - (py - cy) * (py - cy));
    +
    +    var ret = [];
    +    ret[1] = geometry.point(px + ux * d, py + uy * d);
    +    ret[2] = geometry.point(px - ux * d, py - uy * d);
    +
    +    return ret;
    +  },
    +
    +
    +  /**
    +   * Test if a point on the extension of a ray is actually on the ray.
    +   * @param {Point} p1
    +   * @param {Line} r1
    +   * @return {Boolean}
    +   */
    +  intersectionIsOnRay: function (p1, r1) {
    +    return (p1.x - r1.p1.x) * (r1.p2.x - r1.p1.x) + (p1.y - r1.p1.y) * (r1.p2.y - r1.p1.y) >= 0;
    +  },
    +
    +
    +  /**
    +   * Test if a point on the extension of a segment is actually on the segment.
    +   * @param {Point} p1
    +   * @param {Line} s1
    +   * @return {Boolean}
    +   */
    +  intersectionIsOnSegment: function (p1, s1) {
    +    return (p1.x - s1.p1.x) * (s1.p2.x - s1.p1.x) + (p1.y - s1.p1.y) * (s1.p2.y - s1.p1.y) >= 0 && (p1.x - s1.p2.x) * (s1.p1.x - s1.p2.x) + (p1.y - s1.p2.y) * (s1.p1.y - s1.p2.y) >= 0;
    +  },
    +
    +  /**
    +   * Calculate the length of a line segment.
    +   * @param {Line} seg
    +   * @return {Number}
    +   */
    +  segmentLength: function (seg) {
    +    return Math.sqrt(geometry.segmentLengthSquared(seg));
    +  },
    +
    +  /**
    +   * Calculate the squared length of a line segment.
    +   * @param {Line} seg
    +   * @return {Number}
    +   */
    +  segmentLengthSquared: function (seg) {
    +    return geometry.distanceSquared(seg.p1, seg.p2);
    +  },
    +
    +  /**
    +   * Calculate the distance between two points.
    +   * @param {Point} p1
    +   * @param {Point} p2
    +   * @return {Number}
    +   */
    +  distance: function (p1, p2) {
    +    return Math.sqrt(geometry.distanceSquared(p1, p2));
    +  },
    +
    +  /**
    +   * Calculate the squared distance between two points.
    +   * @param {Point} p1
    +   * @param {Point} p2
    +   * @return {Number}
    +   */
    +  distanceSquared: function (p1, p2) {
    +    var dx = p1.x - p2.x;
    +    var dy = p1.y - p2.y;
    +    return dx * dx + dy * dy;
    +  },
    +
    +
    +  /**
    +   * Calculate the midpoint of a segment.
    +   * @param {Line} l1
    +   * @return {Point}
    +   */
    +  segmentMidpoint: function (l1) {
    +    var nx = (l1.p1.x + l1.p2.x) * 0.5;
    +    var ny = (l1.p1.y + l1.p2.y) * 0.5;
    +    return geometry.point(nx, ny);
    +  },
    +
    +
    +  /**
    +   * Calculate the midpoint between two points.
    +   * @param {Point} p1
    +   * @param {Point} p2
    +   * @return {Point}
    +   */
    +  midpoint: function (p1, p2) {
    +    var nx = (p1.x + p2.x) * 0.5;
    +    var ny = (p1.y + p2.y) * 0.5;
    +    return geometry.point(nx, ny);
    +  },
    +
    +  /**
    +   * Calculate the perpendicular bisector of a segment.
    +   * @param {Line} l1
    +   * @return {Line}
    +   */
    +  perpendicularBisector: function (l1) {
    +    return geometry.line(
    +      geometry.point(
    +        (-l1.p1.y + l1.p2.y + l1.p1.x + l1.p2.x) * 0.5,
    +        (l1.p1.x - l1.p2.x + l1.p1.y + l1.p2.y) * 0.5
    +      ),
    +      geometry.point(
    +        (l1.p1.y - l1.p2.y + l1.p1.x + l1.p2.x) * 0.5,
    +        (-l1.p1.x + l1.p2.x + l1.p1.y + l1.p2.y) * 0.5
    +      )
    +    );
    +  },
    +
    +  /**
    +  * Calculate the line though p1 and parallel to l1.
    +  * @param {Line} l1
    +  * @param {Point} p1
    +  * @return {Line}
    +  */
    +  parallelLineThroughPoint: function (l1, p1) {
    +    var dx = l1.p2.x - l1.p1.x;
    +    var dy = l1.p2.y - l1.p1.y;
    +    return geometry.line(p1, geometry.point(p1.x + dx, p1.y + dy));
    +  }
    +};
    +
    +export default geometry;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/global.html b/docs/global.html new file mode 100644 index 00000000..088b934b --- /dev/null +++ b/docs/global.html @@ -0,0 +1,4102 @@ + + + + + JSDoc: Global + + + + + + + + + + +
    + +

    Global

    + + + + + + +
    + +
    + +

    + + +
    + +
    +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + + + + + + + + + + +

    Members

    + + + +

    (constant) DATA_VERSION :number

    + + + + +
    +

    The version of the JSON data format of the scene, which matches the major version number of the app starting from version 5.0.

    +
    + + + +
    Type:
    +
      +
    • + +number + + +
    • +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    CircleObjMixin(Base) → {T}

    + + + + + + +
    +

    The mixin for the scene objects that are defined by a circle.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    Base + + +T + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +T + + +
    +
    + + + + + + + + + + + + + +

    LineObjMixin(Base) → {T}

    + + + + + + +
    +

    The mixin for the scene objects that are defined by a line segment.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    Base + + +T + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +T + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectsShape(ray) → {Point}

    + + + + + + +
    +

    Check if a ray intersects the circle. +In the child class, this can be called from the checkRayIntersects method.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The intersection point, or null if there is no intersection.

    +
    + + + +
    +
    + Type +
    +
    + +Point + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectsShape(ray) → {Point}

    + + + + + + +
    +

    Check if a ray intersects the line segment. +In the child class, this can be called from the checkRayIntersects method.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The intersection point, or null if there is no intersection.

    +
    + + + +
    +
    + Type +
    +
    + +Point + + +
    +
    + + + + + + + + + + + + + +

    setViewportSize(width, height)

    + + + + + + +
    +

    Set the size (in CSS pixels) for the viewport of the scene.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    width + + +number + + + +
    height + + +number + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    toJSON() → {string}

    + + + + + + +
    +

    Convert the scene to JSON.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The JSON string representing the scene.

    +
    + + + +
    +
    + Type +
    +
    + +string + + +
    +
    + + + + + + + + + + + + + +

    versionUpdate(jsonData) → {Object}

    + + + + + + +
    +

    Update the scene JSON data to the latest version.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    jsonData + + +Object + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The updated JSON data.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + +

    Type Definitions

    + + + +

    BodyMergingObj

    + + + + +
    +

    Every ray has a temporary bodyMerging object ("bodyMergingObj") as a property (this property exists only while the ray is inside a region of one or several overlapping grin objects - e.g. CircleGrinGlass and GrinGlass), which gets updated as the ray enters/exits into/from grin objects, using the "multRefIndex"/"devRefIndex" function, respectively.

    +
    + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    fn_p + + +function + + + +

    The refractive index function for the equivalent region of the simulation.

    fn_p_der_x + + +function + + + +

    The x derivative of fn_p for the equivalent region of the simulation.

    fn_p_der_y + + +function + + + +

    The y derivative of fn_p for the equivalent region of the simulation.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    Circle

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    c + + +Point + + + +
    r + + +number +| + +Line + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    ConstructReturn

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDescription
    isDone + + +boolean + + + + + + <optional>
    + + + +

    Whether the construction is done.

    requiresObjBarUpdate + + +boolean + + + + + + <optional>
    + + + +

    Whether the object bar should be updated.

    isCancelled + + +boolean + + + + + + <optional>
    + + + +

    Whether the construction is cancelled.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    ControlPoint

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    dragContext + + +DragContext + + + +

    The drag context of the virtual mouse that is dragging the control point.

    newPoint + + +Point + + + +

    The new position of the control point.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    DragContext

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDescription
    part + + +number + + + + + + + +

    The index of the part within the object being dragged. 0 for the whole object.

    targetPoint + + +Point + + + + + + <optional>
    + + + +

    The target point where the user is dragging. This is recognized by the editor so that it can be used for popping up the coordinate box (when the user double-clicks or right-clicks such a point), or binding to a handle (when the user holds Ctrl and clicks such a point).

    targetPoint_ + + +Point + + + + + + <optional>
    + + + +

    If this property is set instead of setting targetPoint, then the point will not be used for the coordinate box or handle, but is still recognized by the editor when deciding which part of which object the user want to interact with.

    requiresObjBarUpdate + + +boolean + + + + + + <optional>
    + + + +

    Whether the object bar should be updated during the dragging.

    cursor + + +string + + + + + + <optional>
    + + + +

    The cursor to be used during hovering and dragging.

    snapContext + + +SnapContext + + + + + + <optional>
    + + + +

    The snap context.

    hasDuplicated + + +boolean + + + + + + <optional>
    + + + +

    Whether the object is duplicated during the dragging. This is true when the user holds the Ctrl key and drags the whole object. Only set by the editor.

    originalObj + + +BaseSceneObj + + + + + + <optional>
    + + + +

    The original object when the dragging starts. Only set by the editor.

    isByHandle + + +boolean + + + + + + <optional>
    + + + +

    Whether the dragging is initiated by dragging a handle. Only set by the editor.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    Line

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    ModuleDef

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    numPoints + + +number + + + +

    The number of control points of the module.

    params + + +Array.<string> + + + +

    The parameters of the module.

    objs + + +Array.<Object> + + + +

    The objects in the module in the form of JSON objects with template syntax.

    maxLoopLength + + +number + + + +

    The maximum length of the list in for loops to prevent infinite loops.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    Point

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +number + + + +
    y + + +number + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    Ray

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDescription
    p1 + + +Point + + + + + + + +

    The starting point of the ray.

    p2 + + +Point + + + + + + + +

    Another point on the ray.

    brightness_s + + +number + + + + + + + +

    he intensity of the s-polarization component of the ray.

    brightness_p + + +number + + + + + + + +

    The intensity of the p-polarization component of the ray. In this simulator the two polarization components are assumed to be of no phase coherence.

    wavelength + + +number + + + + + + <optional>
    + + + +

    The wavelength of the ray in nanometers. Only has effect when "Simulate Colors" is on.

    gap + + +boolean + + + + + + + +

    Whether the ray is the first ray in a bunch of "continuous" rays. This is for the detection of images to work correctly. The intersection of two rays is considered as a candidate of an image only if the second ray has gap === false.

    isNew + + +boolean + + + + + + + +

    Whether the ray is just emitted by a source. This is to avoid drawing trivial initial extensions in the "Extended rays" mode.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    SelectionSearchResult

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    dragContext + + +DragContext + + + +

    The drag context.

    targetObjIndex + + +number + + + +

    The index of the target object.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    SimulationReturn

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDescription
    isAbsorbed + + +boolean + + + + + + <optional>
    + + + +

    Whether the object absorbs the ray.

    newRays + + +Array.<Ray> + + + + + + <optional>
    + + + +

    The new rays to be added.

    truncation + + +number + + + + + + <optional>
    + + + +

    The brightness of truncated rays due to numerical cutoff (e.g. after a large number of partial internal reflections within a glass). This is used to estimate the error of the simulation.

    brightnessScale + + +number + + + + + + <optional>
    + + + +

    The actual brightness of the ray divided by the brightness inferred from the properties of the object. This should be 1 when "ray density" is high enough. When "ray density" is low, the calculated brightness of the individual rays will be too high (alpha value for rendering will be larger than 1). In this case, the object should rescale all the brightness of the rays by a factor to keep the maximum alpha value to be 1. This factor should be returned here and is used to generate warnings.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    SnapContext

    + + + + + + +
    Type:
    +
      +
    • + +Object + + +
    • +
    + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDescription
    locked + + +boolean + + + + + + <optional>
    + + + +

    Whether the snapping direction is locked.

    i0 + + +number + + + + + + <optional>
    + + + +

    The index of the locked direction.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + +

    loadJSONCallback(needFullUpdate, completed)

    + + + + + + +
    +

    The callback function when the entire scene or a resource (e.g. image) is loaded.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    needFullUpdate + + +boolean + + + +

    Whether the scene needs a full update.

    completed + + +boolean + + + +

    Whether the scene is completely loaded.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    objBarValueChangeCallback(obj, value)

    + + + + + + +
    +

    The callback function for when a value changes. +If "Apply to all" is checked, this function will be called for each scene object of the same type.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    obj + + +Object + + + +

    The scene object whose value changed.

    value + + +any + + + +

    The new value.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +

    Events

    + + + + + + + +

    requestUpdateErrorAndWarning

    + + + + + + +
    +

    The event when the error and warning messages in the UI should be updated.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    requestUpdateErrorAndWarning

    + + + + + + +
    +

    The event when the error and warning messages in the UI should be updated.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..34022dd8 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,530 @@ + + + + + JSDoc: Home + + + + + + + + + + +
    + +

    Home

    + + + + + + + + +

    + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +

    Editor.js

    + + +
    + +
    +
    + + +

    Editor is the main class for visually editing the Scene data. It manages the user interactions with the canvas, such as dragging objects, selecting objects, and adding objects. It also manages the undo and redo operations and the crop mode.

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + +
    + +
    + +

    Scene.js

    + + +
    + +
    +
    + + +

    Scene is the class representing the optical scene for simulation, containing the instances from sceneObjs (optical elements, decorations, etc) and the settings of the scene. It is the main data structure of the app and can be serialized to (and deserialized from) JSON.

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + +
    + +
    + +

    Simulator.js

    + + +
    + +
    +
    + + +

    Simulator is the class for simulating the optical system described by the Scene class and rendering the scene (optical elements, decorations, rays, etc) on the canvas layers. It can also be used in a standalone environment (e.g. Node.js).

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + +
    + +
    + +

    app.js

    + + +
    + +
    +
    + + +

    app.js is the main entry point for the Ray Optics Simulator web app. It handles the initialzation of the UI and the main instances of Scene, Simulator and Editor, and binds events to them. It also handles some app-level operation such as loading files.

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + +
    + +
    + +

    sceneObjs.js

    + + +
    + +
    +
    + + +

    sceneObjs is the namespace for all the classes representing objects that can be added to the scene. Scene objects include optical elements (e.g. mirrors, lenses), detectors, decorations (e.g. rulers, text labels), and special objects (e.g. handles, cropboxes).

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.AngleSource.html b/docs/sceneObjs.AngleSource.html new file mode 100644 index 00000000..5242e01d --- /dev/null +++ b/docs/sceneObjs.AngleSource.html @@ -0,0 +1,3760 @@ + + + + + JSDoc: Class: AngleSource + + + + + + + + + + +
    + +

    Class: AngleSource

    + + + + + + +
    + +
    + +

    + sceneObjs.AngleSource()

    + +

    Finite angle point source

    +

    Tools -> Light source -> Point source (<360deg)

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new AngleSource()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The position of the point source.

    p2 + + +Point + + + +

    Another point on the reference line.

    brightness + + +number + + + +

    The brightness of the point source.

    wavelength + + +number + + + +

    The wavelength of the point source in nm. Only effective when "Simulate Colors" is on.

    emisAngle + + +number + + + +

    The angle of emission in degrees.

    symmetric + + +boolean + + + +

    Whether the emission is symmetric about the reference line. If not, the emission is only on one side of the reference line.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Aperture.html b/docs/sceneObjs.Aperture.html new file mode 100644 index 00000000..bd8c8594 --- /dev/null +++ b/docs/sceneObjs.Aperture.html @@ -0,0 +1,3972 @@ + + + + + JSDoc: Class: Aperture + + + + + + + + + + +
    + +

    Class: Aperture

    + + + + + + +
    + +
    + +

    + sceneObjs.Aperture()

    + +

    Aperture / filter with a hole.

    +

    Tools -> Blocker -> Aperture

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Aperture()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint of the aperture.

    p2 + + +Point + + + +

    The second endpoint of the aperture.

    p3 + + +Point + + + +

    The first endpoint of the hole.

    p4 + + +Point + + + +

    The second endpoint of the hole.

    filter + + +boolean + + + +

    Whether it is a filter.

    invert + + +boolean + + + +

    If true, the ray with wavelength outside the bandwidth is blocked. If false, the ray with wavelength inside the bandwidth is blocked.

    wavelength + + +number + + + +

    The target wavelength if filter is enabled. The unit is nm.

    bandwidth + + +number + + + +

    The bandwidth if filter is enabled. The unit is nm.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.ArcMirror.html b/docs/sceneObjs.ArcMirror.html new file mode 100644 index 00000000..219af77a --- /dev/null +++ b/docs/sceneObjs.ArcMirror.html @@ -0,0 +1,3949 @@ + + + + + JSDoc: Class: ArcMirror + + + + + + + + + + +
    + +

    Class: ArcMirror

    + + + + + + +
    + +
    + +

    + sceneObjs.ArcMirror()

    + +

    Mirror with shape of a circular arc.

    +

    Tools -> Mirror -> Circular Arc

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new ArcMirror()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint.

    p2 + + +Point + + + +

    The second endpoint.

    p3 + + +Point + + + +

    The control point on the arc.

    filter + + +boolean + + + +

    Whether it is a dichroic mirror.

    invert + + +boolean + + + +

    If true, the ray with wavelength outside the bandwidth is reflected. If false, the ray with wavelength inside the bandwidth is reflected.

    wavelength + + +number + + + +

    The target wavelength if dichroic is enabled. The unit is nm.

    bandwidth + + +number + + + +

    The bandwidth if dichroic is enabled. The unit is nm.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Beam.html b/docs/sceneObjs.Beam.html new file mode 100644 index 00000000..5f5b0949 --- /dev/null +++ b/docs/sceneObjs.Beam.html @@ -0,0 +1,3894 @@ + + + + + JSDoc: Class: Beam + + + + + + + + + + +
    + +

    Class: Beam

    + + + + + + +
    + +
    + +

    + sceneObjs.Beam()

    + +

    A parallel or divergent beam of light.

    +

    Tools -> Light source -> beam

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Beam()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint of the segment perpendicular to the beam.

    p2 + + +Point + + + +

    The second endpoint of the segment perpendicular to the beam.

    brightness + + +number + + + +

    The brightness of the beam.

    wavelength + + +number + + + +

    The wavelength of the beam in nm. Only effective when "Simulate Colors" is on.

    emisAngle + + +number + + + +

    The angle of divergence in degrees.

    lambert + + +boolean + + + +

    Whether the beam is Lambertian.

    random + + +boolean + + + +

    Whether the beam is random.

    randomNumbers + + +Array.<number> + + + +

    Random numbers used for random beam.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    initRandom()

    + + + + + + +
    +

    Utility methods

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.BeamSplitter.html b/docs/sceneObjs.BeamSplitter.html new file mode 100644 index 00000000..cacc6816 --- /dev/null +++ b/docs/sceneObjs.BeamSplitter.html @@ -0,0 +1,3949 @@ + + + + + JSDoc: Class: BeamSplitter + + + + + + + + + + +
    + +

    Class: BeamSplitter

    + + + + + + +
    + +
    + +

    + sceneObjs.BeamSplitter()

    + +

    Beam splitter.

    +

    Tools -> Mirror -> Beam splitter

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new BeamSplitter()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint.

    p2 + + +Point + + + +

    The second endpoint.

    transRatio + + +number + + + +

    The transmission ratio.

    filter + + +boolean + + + +

    Whether it is a dichroic beam splitter.

    invert + + +boolean + + + +

    If true, the ray with wavelength outside the bandwidth interacts with the beam splitter. If false, the ray with wavelength inside the bandwidth interacts with the beam splitter.

    wavelength + + +number + + + +

    The target wavelength if dichroic is enabled. The unit is nm.

    bandwidth + + +number + + + +

    The bandwidth if dichroic is enabled. The unit is nm.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Blocker.html b/docs/sceneObjs.Blocker.html new file mode 100644 index 00000000..7a50e7de --- /dev/null +++ b/docs/sceneObjs.Blocker.html @@ -0,0 +1,3926 @@ + + + + + JSDoc: Class: Blocker + + + + + + + + + + +
    + +

    Class: Blocker

    + + + + + + +
    + +
    + +

    + sceneObjs.Blocker()

    + +

    Line blocker / filter.

    +

    Tools -> Blocker -> Line Blocker

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Blocker()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint.

    p2 + + +Point + + + +

    The second endpoint.

    filter + + +boolean + + + +

    Whether it is a filter.

    invert + + +boolean + + + +

    If true, the ray with wavelength outside the bandwidth is blocked. If false, the ray with wavelength inside the bandwidth is blocked.

    wavelength + + +number + + + +

    The target wavelength if filter is enabled. The unit is nm.

    bandwidth + + +number + + + +

    The bandwidth if filter is enabled. The unit is nm.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.CircleBlocker.html b/docs/sceneObjs.CircleBlocker.html new file mode 100644 index 00000000..f59e2b66 --- /dev/null +++ b/docs/sceneObjs.CircleBlocker.html @@ -0,0 +1,3926 @@ + + + + + JSDoc: Class: CircleBlocker + + + + + + + + + + +
    + +

    Class: CircleBlocker

    + + + + + + +
    + +
    + +

    + sceneObjs.CircleBlocker()

    + +

    Circle blocker / filter.

    +

    Tools -> Blocker -> Circle Blocker

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new CircleBlocker()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The center of the circle.

    p2 + + +Point + + + +

    A point on the circle.

    filter + + +boolean + + + +

    Whether it is a filter.

    invert + + +boolean + + + +

    If true, the ray with wavelength outside the bandwidth is blocked. If false, the ray with wavelength inside the bandwidth is blocked.

    wavelength + + +number + + + +

    The target wavelength if filter is enabled. The unit is nm.

    bandwidth + + +number + + + +

    The bandwidth if filter is enabled. The unit is nm.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.CircleGlass.html b/docs/sceneObjs.CircleGlass.html new file mode 100644 index 00000000..22b5bfcb --- /dev/null +++ b/docs/sceneObjs.CircleGlass.html @@ -0,0 +1,4843 @@ + + + + + JSDoc: Class: CircleGlass + + + + + + + + + + +
    + +

    Class: CircleGlass

    + + + + + + +
    + +
    + +

    + sceneObjs.CircleGlass()

    + +

    Glass of the shape of a circle.

    +

    Tools -> Glass -> Circle

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new CircleGlass()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The center of the circle.

    p2 + + +Point + + + +

    A point on the boundary of the circle.

    refIndex + + +number + + + +

    The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.

    cauchyB + + +number + + + +

    The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    fillGlass(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Fill the glass with the color that represents the refractive index. To be called in draw of a subclass when the path has been set up with canvasRenderer.ctx.beginPath(), etc.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getIncidentType(ray) → {number}

    + + + + + + +
    +

    Get whether the ray is incident from inside to outside or from outside to inside.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getRefIndexAt(point, ray) → {number}

    + + + + + + +
    +

    Get the refractive index at a point for a ray

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.

    ray + + +Ray + + + +

    The ray to be refracted.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The refractive index at the point.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayEnter(ray)

    + + + + + + +
    +

    Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that enters the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayExit(ray)

    + + + + + + +
    +

    Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that exits the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) → {SimulationReturn}

    + + + + + + +
    +

    Do the refraction calculation at the surface of the glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be refracted.

    rayIndex + + +number + + + +

    The index of the ray in the ray array.

    incidentPoint + + +Point + + + +

    The incident point.

    normal + + +Point + + + +

    The normal vector at the incident point.

    n1 + + +number + + + +

    The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are to be merged with the current object.

    bodyMergingObj + + +BaseGrinGlass + + + +

    The object that is to be merged with the current object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value for onRayIncident.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn + + +
    +
    + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.CircleGrinGlass.html b/docs/sceneObjs.CircleGrinGlass.html new file mode 100644 index 00000000..fa2df8eb --- /dev/null +++ b/docs/sceneObjs.CircleGrinGlass.html @@ -0,0 +1,6238 @@ + + + + + JSDoc: Class: CircleGrinGlass + + + + + + + + + + +
    + +

    Class: CircleGrinGlass

    + + + + + + +
    + +
    + +

    + sceneObjs.CircleGrinGlass()

    + +

    Gradient-index glass of the shape of a circle.

    +

    Tools -> Glass -> Gradient-index Circle

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new CircleGrinGlass()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The center of the circle.

    p2 + + +Point + + + +

    A point on the boundary of the circle.

    refIndexFn + + +string + + + +

    The refractive index function in x and y in LaTeX format.

    origin + + +Point + + + +

    The origin of the (x,y) coordinates used in the refractive index function.

    stepSize + + +number + + + +

    The step size for the ray trajectory equation.

    intersectTol + + +number + + + +

    The epsilon for the intersection calculations.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    devRefIndex(bodyMergingObj) → {BodyMergingObj}

    + + + + + + +
    +

    Receives a bodyMerging object and returns a new bodyMerging object for the region of bodyMergingObj excluding current GRIN glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    bodyMergingObj + + +BodyMergingObj + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +BodyMergingObj + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    fillGlass(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Fill the glass with the color that represents the refractive index. To be called in draw of a subclass when the path has been set up with canvasRenderer.ctx.beginPath(), etc.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getIncidentType(ray) → {number}

    + + + + + + +
    +

    Get whether the ray is incident from inside to outside or from outside to inside.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getRefIndexAt(point, ray) → {number}

    + + + + + + +
    +

    Get the refractive index at a point for a ray

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.

    ray + + +Ray + + + +

    The ray to be refracted.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The refractive index at the point.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    initFns()

    + + + + + + +
    +

    Do the partial derivatives of the refractive index function and parse the functions.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    initRefIndex(ray) → {BodyMergingObj}

    + + + + + + +
    +

    Receives a ray, and returns a bodyMerging object for the point ray.p1

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +BodyMergingObj + + +
    +
    + + + + + + + + + + + + + +

    isInsideGlass(point)

    + + + + + + +
    +

    Returns true if point is inside the glass, otherwise returns false

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +
    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    isOnBoundary(point)

    + + + + + + +
    +

    Returns true if point is on the boundary of the glass, otherwise returns false

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +
    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    isOutsideGlass(point)

    + + + + + + +
    +

    Returns true if point is outside the glass, otherwise returns false

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +
    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    multRefIndex(bodyMergingObj) → {BodyMergingObj}

    + + + + + + +
    +

    Receives a bodyMerging object and returns a new bodyMerging object for the overlapping region of bodyMergingObj and the current GRIN glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    bodyMergingObj + + +BodyMergingObj + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +BodyMergingObj + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayEnter(ray)

    + + + + + + +
    +

    Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that enters the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayExit(ray)

    + + + + + + +
    +

    Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that exits the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) → {SimulationReturn}

    + + + + + + +
    +

    Do the refraction calculation at the surface of the glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be refracted.

    rayIndex + + +number + + + +

    The index of the ray in the ray array.

    incidentPoint + + +Point + + + +

    The incident point.

    normal + + +Point + + + +

    The normal vector at the incident point.

    n1 + + +number + + + +

    The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are to be merged with the current object.

    bodyMergingObj + + +BaseGrinGlass + + + +

    The object that is to be merged with the current object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value for onRayIncident.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn + + +
    +
    + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +

    shiftOrigin(equation) → {string}

    + + + + + + +
    +

    Shifts the x and y variables in equation from related to this.origin to the absolute coordinates.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    equation + + +string + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +string + + +
    +
    + + + + + + + + + + + + + +

    step(p1, p2, ray)

    + + + + + + +
    +

    Receives two points inside this lens, and returns the next point to where the ray, connecting these two points, will travel, based on the ray trajectory equation (equation 11.1 in the cited text below) +Using Euler's method to solve the ray trajectory equation (based on sections 11.1 and 11.2, in the following text: https://doi.org/10.1007/BFb0012092) +x_der_s and x_der_s_prev are the x-coordinate derivatives with respect to the arc-length parameterization, at two different points (similarly for y_der_s and y_der_s_prev)

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    ray + + +Ray + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.CropBox.html b/docs/sceneObjs.CropBox.html new file mode 100644 index 00000000..11937211 --- /dev/null +++ b/docs/sceneObjs.CropBox.html @@ -0,0 +1,3783 @@ + + + + + JSDoc: Class: CropBox + + + + + + + + + + +
    + +

    Class: CropBox

    + + + + + + +
    + +
    + +

    + sceneObjs.CropBox()

    + +

    The crop box

    +

    File -> Export as PNG/SVG

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new CropBox()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The top left corner of the crop box.

    p2 + + +Point + + + +

    The top right corner of the crop box.

    p3 + + +Point + + + +

    The bottom left corner of the crop box.

    p4 + + +Point + + + +

    The bottom right corner of the crop box.

    format + + +string + + + +

    The format of the image to be exported.

    width + + +number + + + +

    The width of the image to be exported. Not effective when the format is 'svg'.

    rayCountLimit + + +number + + + +

    The maximum number of rays to be traced. This is to avoid infinite loop. If not set, the default value is determined by the simulator and depends on format.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.CustomGlass.html b/docs/sceneObjs.CustomGlass.html new file mode 100644 index 00000000..4376c82b --- /dev/null +++ b/docs/sceneObjs.CustomGlass.html @@ -0,0 +1,4935 @@ + + + + + JSDoc: Class: CustomGlass + + + + + + + + + + +
    + +

    Class: CustomGlass

    + + + + + + +
    + +
    + +

    + sceneObjs.CustomGlass()

    + +

    Glass defined by a custom inequality.

    +

    Tools -> Glass -> Custom equation

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new CustomGlass()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The point corresponding to (-1,0) in the coordinate system of the equation.

    p2 + + +Point + + + +

    The point corresponding to (1,0) in the coordinate system of the equation.

    eqn1 + + +string + + + +

    The equation of the surface with smaller y. The variable is x.

    eqn2 + + +string + + + +

    The equation of the surface with larger y. The variable is x.

    refIndex + + +number + + + +

    The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.

    cauchyB + + +number + + + +

    The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.

    path + + +Array.<Point> + + + +

    The points on the calculated curve.

    tmp_i + + +number + + + +

    The index of the point on the curve where the ray is incident.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    fillGlass(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Fill the glass with the color that represents the refractive index. To be called in draw of a subclass when the path has been set up with canvasRenderer.ctx.beginPath(), etc.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getIncidentType(ray) → {number}

    + + + + + + +
    +

    Get whether the ray is incident from inside to outside or from outside to inside.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getRefIndexAt(point, ray) → {number}

    + + + + + + +
    +

    Get the refractive index at a point for a ray

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.

    ray + + +Ray + + + +

    The ray to be refracted.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The refractive index at the point.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayEnter(ray)

    + + + + + + +
    +

    Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that enters the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayExit(ray)

    + + + + + + +
    +

    Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that exits the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) → {SimulationReturn}

    + + + + + + +
    +

    Do the refraction calculation at the surface of the glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be refracted.

    rayIndex + + +number + + + +

    The index of the ray in the ray array.

    incidentPoint + + +Point + + + +

    The incident point.

    normal + + +Point + + + +

    The normal vector at the incident point.

    n1 + + +number + + + +

    The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are to be merged with the current object.

    bodyMergingObj + + +BaseGrinGlass + + + +

    The object that is to be merged with the current object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value for onRayIncident.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn + + +
    +
    + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.CustomMirror.html b/docs/sceneObjs.CustomMirror.html new file mode 100644 index 00000000..c645d02f --- /dev/null +++ b/docs/sceneObjs.CustomMirror.html @@ -0,0 +1,3995 @@ + + + + + JSDoc: Class: CustomMirror + + + + + + + + + + +
    + +

    Class: CustomMirror

    + + + + + + +
    + +
    + +

    + sceneObjs.CustomMirror()

    + +

    Mirror with shape defined by a custom equation.

    +

    Tools -> Mirror -> Custom equation

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new CustomMirror()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The point corresponding to (-1,0) in the coordinate system of the equation.

    p2 + + +Point + + + +

    The point corresponding to (1,0) in the coordinate system of the equation.

    eqn + + +string + + + +

    The equation of the mirror. The variable is x.

    filter + + +boolean + + + +

    Whether it is a dichroic mirror.

    invert + + +boolean + + + +

    If true, the ray with wavelength outside the bandwidth is reflected. If false, the ray with wavelength inside the bandwidth is reflected.

    wavelength + + +number + + + +

    The target wavelength if dichroic is enabled. The unit is nm.

    bandwidth + + +number + + + +

    The bandwidth if dichroic is enabled. The unit is nm.

    tmp_points + + +Array.<Point> + + + +

    The points on the curve.

    tmp_i + + +number + + + +

    The index of the point on the curve where the ray is incident.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Detector.html b/docs/sceneObjs.Detector.html new file mode 100644 index 00000000..9e1c0746 --- /dev/null +++ b/docs/sceneObjs.Detector.html @@ -0,0 +1,3806 @@ + + + + + JSDoc: Class: Detector + + + + + + + + + + +
    + +

    Class: Detector

    + + + + + + +
    + +
    + +

    + sceneObjs.Detector()

    + +

    The detector tool

    +

    Tools -> Other -> Detector

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Detector()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint of the line segment.

    p2 + + +Point + + + +

    The second endpoint of the line segment.

    irradMap + + +boolean + + + +

    Whether to display the irradiance map.

    binSize + + +number + + + +

    The size of the bin for the irradiance map.

    power + + +number + + + +

    The measured power through the detector.

    normal + + +number + + + +

    The measured normal force through the detector.

    shear + + +number + + + +

    The measured shear force through the detector.

    binData + + +Array.<number> + + + +

    The measured data for the irradiance map.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.DiffractionGrating.html b/docs/sceneObjs.DiffractionGrating.html new file mode 100644 index 00000000..d9d78aea --- /dev/null +++ b/docs/sceneObjs.DiffractionGrating.html @@ -0,0 +1,3784 @@ + + + + + JSDoc: Class: DiffractionGrating + + + + + + + + + + +
    + +

    Class: DiffractionGrating

    + + + + + + +
    + +
    + +

    + sceneObjs.DiffractionGrating()

    + +

    Diffraction Grating

    +

    Tools -> Blocker -> Diffraction Grating

    +

    It is in the blocker category since the model we use is a blocker with slits.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new DiffractionGrating()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint of the line segment.

    p2 + + +Point + + + +

    The second endpoint of the line segment.

    lineDensity + + +number + + + +

    The number of lines per millimeter.

    customBrightness + + +boolean + + + +

    Whether the output brightness are customized.

    brightnesses + + +Array.<number> + + + +

    The brightnesses of the diffracted rays for m = 0, 1, -1, 2, -2, ... when customBrightness is true. The number is to be normalized to the brightness of the incident ray. The values not in the array are set to 0.

    slitRatio + + +number + + + +

    The ratio of the slit width to the line interval.

    mirrored + + +boolean + + + +

    Whether the diffraction grating is reflective.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Drawing.html b/docs/sceneObjs.Drawing.html new file mode 100644 index 00000000..8e5dad8c --- /dev/null +++ b/docs/sceneObjs.Drawing.html @@ -0,0 +1,3779 @@ + + + + + JSDoc: Class: Drawing + + + + + + + + + + +
    + +

    Class: Drawing

    + + + + + + +
    + +
    + +

    + sceneObjs.Drawing()

    + +

    Drawing tool

    +

    Tools -> Other -> Drawing

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Drawing()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    strokes + + +Array.<Array.<number>> + + + +

    The strokes of the drawing. Each element represents a stroke, which is an array of coordinates ordered as [x1, y1, x2, y2, ...]. The coordinates are rounded to reduce the size of the JSON data.

    isDrawing + + +boolean + + + +

    Whether the user is drawing (before "stop drawing" is clicked).

    isMouseDown + + +boolean + + + +

    Temperary indication of whether the mouse is down (during the drawing stage).

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    round()

    + + + + + + +
    +

    Round the coordinates of the strokes to integers times the length scale (to reduce the size of the JSON data).

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Glass.html b/docs/sceneObjs.Glass.html new file mode 100644 index 00000000..f222c8bf --- /dev/null +++ b/docs/sceneObjs.Glass.html @@ -0,0 +1,4843 @@ + + + + + JSDoc: Class: Glass + + + + + + + + + + +
    + +

    Class: Glass

    + + + + + + +
    + +
    + +

    + sceneObjs.Glass()

    + +

    Glass of the shape consists of line segments or circular arcs.

    +

    Tools -> Glass -> Polygon / Circular Arcs

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Glass()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    path + + +Array.<object> + + + +

    The path of the glass. Each element is an object with x and y properties for coordinates, and a boolean arc. If path[i].arc === false, it means that path[i-1]--path[i] and path[i]--path[i+1] are line segments, if path[i].arc === true, it means that path[i-1]--path[i]--path[i+1] is a circular arc.

    notDone + + +boolean + + + +

    Whether the user is still drawing the glass.

    refIndex + + +number + + + +

    The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.

    cauchyB + + +number + + + +

    The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    fillGlass(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Fill the glass with the color that represents the refractive index. To be called in draw of a subclass when the path has been set up with canvasRenderer.ctx.beginPath(), etc.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getIncidentType(ray) → {number}

    + + + + + + +
    +

    Get whether the ray is incident from inside to outside or from outside to inside.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getRefIndexAt(point, ray) → {number}

    + + + + + + +
    +

    Get the refractive index at a point for a ray

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.

    ray + + +Ray + + + +

    The ray to be refracted.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The refractive index at the point.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayEnter(ray)

    + + + + + + +
    +

    Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that enters the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayExit(ray)

    + + + + + + +
    +

    Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that exits the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) → {SimulationReturn}

    + + + + + + +
    +

    Do the refraction calculation at the surface of the glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be refracted.

    rayIndex + + +number + + + +

    The index of the ray in the ray array.

    incidentPoint + + +Point + + + +

    The incident point.

    normal + + +Point + + + +

    The normal vector at the incident point.

    n1 + + +number + + + +

    The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are to be merged with the current object.

    bodyMergingObj + + +BaseGrinGlass + + + +

    The object that is to be merged with the current object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value for onRayIncident.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn + + +
    +
    + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.GrinGlass.html b/docs/sceneObjs.GrinGlass.html new file mode 100644 index 00000000..a4f1a32d --- /dev/null +++ b/docs/sceneObjs.GrinGlass.html @@ -0,0 +1,6238 @@ + + + + + JSDoc: Class: GrinGlass + + + + + + + + + + +
    + +

    Class: GrinGlass

    + + + + + + +
    + +
    + +

    + sceneObjs.GrinGlass()

    + +

    Gradient-index glass of the shape of a polygon

    +

    Tools -> Glass -> Gradient-index polygon

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new GrinGlass()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    path + + +Array.<Point> + + + +

    The path of the glass. Each element is an object with x and y properties for coordinates.

    notDone + + +boolean + + + +

    Whether the user is still drawing the glass.

    refIndexFn + + +string + + + +

    The refractive index function in x and y in LaTeX format.

    origin + + +Point + + + +

    The origin of the (x,y) coordinates used in the refractive index function.

    stepSize + + +number + + + +

    The step size for the ray trajectory equation.

    intersectTol + + +number + + + +

    The epsilon for the intersection calculations.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    devRefIndex(bodyMergingObj) → {BodyMergingObj}

    + + + + + + +
    +

    Receives a bodyMerging object and returns a new bodyMerging object for the region of bodyMergingObj excluding current GRIN glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    bodyMergingObj + + +BodyMergingObj + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +BodyMergingObj + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    fillGlass(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Fill the glass with the color that represents the refractive index. To be called in draw of a subclass when the path has been set up with canvasRenderer.ctx.beginPath(), etc.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getIncidentType(ray) → {number}

    + + + + + + +
    +

    Get whether the ray is incident from inside to outside or from outside to inside.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getRefIndexAt(point, ray) → {number}

    + + + + + + +
    +

    Get the refractive index at a point for a ray

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.

    ray + + +Ray + + + +

    The ray to be refracted.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The refractive index at the point.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    initFns()

    + + + + + + +
    +

    Do the partial derivatives of the refractive index function and parse the functions.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    initRefIndex(ray) → {BodyMergingObj}

    + + + + + + +
    +

    Receives a ray, and returns a bodyMerging object for the point ray.p1

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +BodyMergingObj + + +
    +
    + + + + + + + + + + + + + +

    isInsideGlass(point)

    + + + + + + +
    +

    Returns true if point is inside the glass, otherwise returns false

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +
    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    isOnBoundary(point)

    + + + + + + +
    +

    Returns true if point is on the boundary of the glass, otherwise returns false

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +
    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    isOutsideGlass(point)

    + + + + + + +
    +

    Returns true if point is outside the glass, otherwise returns false

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +
    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    multRefIndex(bodyMergingObj) → {BodyMergingObj}

    + + + + + + +
    +

    Receives a bodyMerging object and returns a new bodyMerging object for the overlapping region of bodyMergingObj and the current GRIN glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    bodyMergingObj + + +BodyMergingObj + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +BodyMergingObj + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayEnter(ray)

    + + + + + + +
    +

    Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that enters the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayExit(ray)

    + + + + + + +
    +

    Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that exits the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) → {SimulationReturn}

    + + + + + + +
    +

    Do the refraction calculation at the surface of the glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be refracted.

    rayIndex + + +number + + + +

    The index of the ray in the ray array.

    incidentPoint + + +Point + + + +

    The incident point.

    normal + + +Point + + + +

    The normal vector at the incident point.

    n1 + + +number + + + +

    The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are to be merged with the current object.

    bodyMergingObj + + +BaseGrinGlass + + + +

    The object that is to be merged with the current object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value for onRayIncident.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn + + +
    +
    + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +

    shiftOrigin(equation) → {string}

    + + + + + + +
    +

    Shifts the x and y variables in equation from related to this.origin to the absolute coordinates.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    equation + + +string + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +string + + +
    +
    + + + + + + + + + + + + + +

    step(p1, p2, ray)

    + + + + + + +
    +

    Receives two points inside this lens, and returns the next point to where the ray, connecting these two points, will travel, based on the ray trajectory equation (equation 11.1 in the cited text below) +Using Euler's method to solve the ray trajectory equation (based on sections 11.1 and 11.2, in the following text: https://doi.org/10.1007/BFb0012092) +x_der_s and x_der_s_prev are the x-coordinate derivatives with respect to the arc-length parameterization, at two different points (similarly for y_der_s and y_der_s_prev)

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +
    p2 + + +Point + + + +
    ray + + +Ray + + + +
    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Handle.html b/docs/sceneObjs.Handle.html new file mode 100644 index 00000000..2731bbf1 --- /dev/null +++ b/docs/sceneObjs.Handle.html @@ -0,0 +1,4239 @@ + + + + + JSDoc: Class: Handle + + + + + + + + + + +
    + +

    Class: Handle

    + + + + + + +
    + +
    + +

    + sceneObjs.Handle()

    + +

    The handle created when holding ctrl and click several points.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Handle()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The position of the handle.

    p2 + + +Point + + + +

    The position of the rotation/scale center.

    controlPoints + + +Array.<ControlPoint> + + + +

    The control points bound to the handle.

    transformation + + +string + + + +

    The transformation applied to the control points when dragging the handle, with the corresponding arrows marked on the handle. Possible values are "default", "translation", "xTranslation", "yTranslation", "rotation", "scaling". The "default" is the only behavior in older versions where no arrow is marked on the handle, and the transformation is determined by the ctrl and shift keys.

    notDone + + +boolean + + + +

    Whether the construction of the handle is complete.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    addControlPoint(controlPoint)

    + + + + + + +
    +

    Add (bind) a control point to the handle.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    controlPoint + + +ControlPoint + + + +

    The control point to be bound.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    drawArrowHead(canvasRenderer, x, y, angle, size)

    + + + + + + +
    +

    Draw an filled arrow head at the given position with the given angle and size.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    x + + +number + + + +

    The x-coordinate of the arrow head.

    y + + +number + + + +

    The y-coordinate of the arrow head.

    angle + + +number + + + +

    The angle of the arrow head.

    size + + +number + + + +

    The size of the arrow head.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    finishHandle(point)

    + + + + + + +
    +

    Finish creating the handle.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The position of the handle.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.IdealLens.html b/docs/sceneObjs.IdealLens.html new file mode 100644 index 00000000..40503015 --- /dev/null +++ b/docs/sceneObjs.IdealLens.html @@ -0,0 +1,3691 @@ + + + + + JSDoc: Class: IdealLens + + + + + + + + + + +
    + +

    Class: IdealLens

    + + + + + + +
    + +
    + +

    + sceneObjs.IdealLens()

    + +

    Ideal lens

    +

    Tools -> Glass -> Ideal Lens

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new IdealLens()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint.

    p2 + + +Point + + + +

    The second endpoint.

    focalLength + + +number + + + +

    The focal length.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.IdealMirror.html b/docs/sceneObjs.IdealMirror.html new file mode 100644 index 00000000..8c694723 --- /dev/null +++ b/docs/sceneObjs.IdealMirror.html @@ -0,0 +1,3857 @@ + + + + + JSDoc: Class: IdealMirror + + + + + + + + + + +
    + +

    Class: IdealMirror

    + + + + + + +
    + +
    + +

    + sceneObjs.IdealMirror()

    + +

    Ideal curved mirror that follows the mirror equation exactly.

    +

    Tools -> Mirror -> Ideal curved mirror

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new IdealMirror()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint.

    p2 + + +Point + + + +

    The second endpoint.

    focalLength + + +number + + + +

    The focal length. The Cartesian sign convention is not used. But if the Cartesian sign convention is enabled (as a preference setting), the focal length changes sign in the UI.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.LineArrow.html b/docs/sceneObjs.LineArrow.html new file mode 100644 index 00000000..27525815 --- /dev/null +++ b/docs/sceneObjs.LineArrow.html @@ -0,0 +1,3802 @@ + + + + + JSDoc: Class: LineArrow + + + + + + + + + + +
    + +

    Class: LineArrow

    + + + + + + +
    + +
    + +

    + sceneObjs.LineArrow()

    + +

    Line or arrow decoration

    +

    Tools -> Other -> Line / Arrow

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new LineArrow()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint.

    p2 + + +Point + + + +

    The second endpoint.

    arrow + + +boolean + + + +

    Whether an arrow is pointing from the first endpoint.

    backArrow + + +boolean + + + +

    Whether an arrow is pointing from the second endpoint.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    drawArrow()

    + + + + + + +
    +

    Utility method

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Mirror.html b/docs/sceneObjs.Mirror.html new file mode 100644 index 00000000..da0da185 --- /dev/null +++ b/docs/sceneObjs.Mirror.html @@ -0,0 +1,3926 @@ + + + + + JSDoc: Class: Mirror + + + + + + + + + + +
    + +

    Class: Mirror

    + + + + + + +
    + +
    + +

    + sceneObjs.Mirror()

    + +

    Mirror with shape of a line segment.

    +

    Tools -> Mirror -> Segment

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Mirror()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint.

    p2 + + +Point + + + +

    The second endpoint.

    filter + + +boolean + + + +

    Whether it is a dichroic mirror.

    invert + + +boolean + + + +

    If true, the ray with wavelength outside the bandwidth is reflected. If false, the ray with wavelength inside the bandwidth is reflected.

    wavelength + + +number + + + +

    The target wavelength if dichroic is enabled. The unit is nm.

    bandwidth + + +number + + + +

    The bandwidth if dichroic is enabled. The unit is nm.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.ModuleObj.html b/docs/sceneObjs.ModuleObj.html new file mode 100644 index 00000000..ee7d93a0 --- /dev/null +++ b/docs/sceneObjs.ModuleObj.html @@ -0,0 +1,4645 @@ + + + + + JSDoc: Class: ModuleObj + + + + + + + + + + +
    + +

    Class: ModuleObj

    + + + + + + +
    + +
    + +

    + sceneObjs.ModuleObj()

    + +

    The class for a module object. +This feature is experimental and may be changed in the future without backward compatibility. +Currently, there is no UI for creating a module object. You can create a module object by directly editing the JSON data of the scene.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new ModuleObj()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    module + + +string + + + +

    The name of the module.

    moduleDef + + +ModuleDef + + + +

    The definition of the module.

    points + + +Array.<Point> + + + +

    The control points of the module.

    params + + +Object + + + +

    The parameters of the module.

    objs + + +Array.<BaseSceneObj> + + + +

    The expanded objects in the module.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    demodulize()

    + + + + + + +
    +

    Demodulize the module object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    expandArray(arr, params) → {Array}

    + + + + + + +
    +

    Expand an array with template syntax, where the string values of the array are interpreted with template syntax. Arrays and objects are expanded recursively. If an object in the array has a key "for", then the object is expanded multiple times with the given range of values. If the value of "for" is a string, then the range is interpreted with parseVariableRange. If the value of "for" is an array of strings, then each string is witn parseVariableRange and there are multiple loop variable. If an object in the array has a key "if", then the object is included only if the condition is true.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    arr + + +Array + + + +

    The array with template syntax.

    params + + +Object + + + +

    The parameters to be used for evaluating the expressions.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The expanded array.

    +
    + + + +
    +
    + Type +
    +
    + +Array + + +
    +
    + + + + + + + + + + + + + +

    expandObject(obj, params) → {Object}

    + + + + + + +
    +

    Expand a (JavaScript) object with template syntax, where the string values of the object are interpreted with template syntax. Arrays and other objects are expanded recursively.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    obj + + +Object + + + +

    The object with template syntax.

    params + + +Object + + + +

    The parameters to be used for evaluating the expressions.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The expanded object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +

    expandObjs()

    + + + + + + +
    +

    Expand the objects in the module.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    expandString(str, params) → {number|string}

    + + + + + + +
    +

    Expand a string with template syntax, where the format "eqn" is replaced with the value of "eqn" interpreted as an ASCIIMath expression with a given set of parameters. If the entire string is a single equation, then the result is a number. Otherwise, the result is a string.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    str + + +string + + + +

    The string with template syntax.

    params + + +Object + + + +

    The parameters to be used for evaluating the expressions.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The expanded string.

    +
    + + + +
    +
    + Type +
    +
    + +number +| + +string + + +
    +
    + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    parseVariableRange(str, params) → {Object}

    + + + + + + +
    +

    Parse the variable range description of the form "name=start:step:end" or "name=start:step:end:default", where start, step, and end are math.js strings.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    str + + +string + + + +

    The variable range description.

    params + + +Object + + + +

    The parameters to be used for evaluating the expressions.

    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The parsed variable range.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.ParabolicMirror.html b/docs/sceneObjs.ParabolicMirror.html new file mode 100644 index 00000000..e0cd50c9 --- /dev/null +++ b/docs/sceneObjs.ParabolicMirror.html @@ -0,0 +1,3996 @@ + + + + + JSDoc: Class: ParabolicMirror + + + + + + + + + + +
    + +

    Class: ParabolicMirror

    + + + + + + +
    + +
    + +

    + sceneObjs.ParabolicMirror()

    + +

    Parabolic mirror.

    +

    Tools -> Mirror -> Parabolic

    +

    The current implementation is based on CustomMirror.js, but this should be changed to an analytical solution in the future.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new ParabolicMirror()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint.

    p2 + + +Point + + + +

    The second endpoint.

    p3 + + +Point + + + +

    The vertex.

    filter + + +boolean + + + +

    Whether it is a dichroic mirror.

    invert + + +boolean + + + +

    If true, the ray with wavelength outside the bandwidth is reflected. If false, the ray with wavelength inside the bandwidth is reflected.

    wavelength + + +number + + + +

    The target wavelength if dichroic is enabled. The unit is nm.

    bandwidth + + +number + + + +

    The bandwidth if dichroic is enabled. The unit is nm.

    tmp_points + + +Array.<Point> + + + +

    The points on the parabola.

    tmp_i + + +number + + + +

    The index of the point on the parabola where the ray is incident.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersectFilter(ray) → {boolean}

    + + + + + + +
    +

    Checks if the ray interacts with the filter at the level of the wavelength.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • If true, the ray interacts with the filter at the level of the wavelength.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.PlaneGlass.html b/docs/sceneObjs.PlaneGlass.html new file mode 100644 index 00000000..a6a9cac5 --- /dev/null +++ b/docs/sceneObjs.PlaneGlass.html @@ -0,0 +1,4843 @@ + + + + + JSDoc: Class: PlaneGlass + + + + + + + + + + +
    + +

    Class: PlaneGlass

    + + + + + + +
    + +
    + +

    + sceneObjs.PlaneGlass()

    + +

    Glass of the shape of a half-plane.

    +

    Tools -> Glass -> Half-plane

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new PlaneGlass()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    A point on the boundary of the half-plane.

    p2 + + +Point + + + +

    Another point on the boundary of the half-plane.

    refIndex + + +number + + + +

    The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.

    cauchyB + + +number + + + +

    The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    fillGlass(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Fill the glass with the color that represents the refractive index. To be called in draw of a subclass when the path has been set up with canvasRenderer.ctx.beginPath(), etc.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getIncidentType(ray) → {number}

    + + + + + + +
    +

    Get whether the ray is incident from inside to outside or from outside to inside.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getRefIndexAt(point, ray) → {number}

    + + + + + + +
    +

    Get the refractive index at a point for a ray

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.

    ray + + +Ray + + + +

    The ray to be refracted.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The refractive index at the point.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayEnter(ray)

    + + + + + + +
    +

    Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that enters the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayExit(ray)

    + + + + + + +
    +

    Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that exits the glass.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) → {SimulationReturn}

    + + + + + + +
    +

    Do the refraction calculation at the surface of the glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be refracted.

    rayIndex + + +number + + + +

    The index of the ray in the ray array.

    incidentPoint + + +Point + + + +

    The incident point.

    normal + + +Point + + + +

    The normal vector at the incident point.

    n1 + + +number + + + +

    The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are to be merged with the current object.

    bodyMergingObj + + +BaseGrinGlass + + + +

    The object that is to be merged with the current object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value for onRayIncident.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn + + +
    +
    + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.PointSource.html b/docs/sceneObjs.PointSource.html new file mode 100644 index 00000000..21a92565 --- /dev/null +++ b/docs/sceneObjs.PointSource.html @@ -0,0 +1,3714 @@ + + + + + JSDoc: Class: PointSource + + + + + + + + + + +
    + +

    Class: PointSource

    + + + + + + +
    + +
    + +

    + sceneObjs.PointSource()

    + +

    360 degree point source

    +

    Tools -> Light Source -> Point source (360deg)

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new PointSource()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +number + + + +

    The x coordinate of the point source.

    y + + +number + + + +

    The y coordinate of the point source.

    brightness + + +number + + + +

    The brightness of the point source.

    wavelength + + +number + + + +

    The wavelength of the light emitted by the point source in nm. Only effective when "Simulate Colors" is on.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Protractor.html b/docs/sceneObjs.Protractor.html new file mode 100644 index 00000000..2fca6aed --- /dev/null +++ b/docs/sceneObjs.Protractor.html @@ -0,0 +1,3668 @@ + + + + + JSDoc: Class: Protractor + + + + + + + + + + +
    + +

    Class: Protractor

    + + + + + + +
    + +
    + +

    + sceneObjs.Protractor()

    + +

    The protractor tool

    +

    Tools -> Other -> Protractor

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Protractor()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The center of the protractor.

    p2 + + +Point + + + +

    The zero point on the protractor.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.Ruler.html b/docs/sceneObjs.Ruler.html new file mode 100644 index 00000000..14e723df --- /dev/null +++ b/docs/sceneObjs.Ruler.html @@ -0,0 +1,3691 @@ + + + + + JSDoc: Class: Ruler + + + + + + + + + + +
    + +

    Class: Ruler

    + + + + + + +
    + +
    + +

    + sceneObjs.Ruler()

    + +

    The ruler tool

    +

    Tools -> Other -> Ruler

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new Ruler()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The first endpoint of the line segment.

    p2 + + +Point + + + +

    The second endpoint of the line segment.

    scaleInterval + + +number + + + +

    The scale interval of the ruler.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.SingleRay.html b/docs/sceneObjs.SingleRay.html new file mode 100644 index 00000000..98acd4ff --- /dev/null +++ b/docs/sceneObjs.SingleRay.html @@ -0,0 +1,3714 @@ + + + + + JSDoc: Class: SingleRay + + + + + + + + + + +
    + +

    Class: SingleRay

    + + + + + + +
    + +
    + +

    + sceneObjs.SingleRay()

    + +

    A single ray of light.

    +

    Tools -> Light source -> Single ray

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new SingleRay()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    p1 + + +Point + + + +

    The start point of the ray.

    p2 + + +Point + + + +

    Another point on the ray.

    brightness + + +number + + + +

    The brightness of the ray.

    wavelength + + +number + + + +

    The wavelength of the ray in nm. Only effective when "Simulate Colors" is on.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.SphericalLens.html b/docs/sceneObjs.SphericalLens.html new file mode 100644 index 00000000..a0e96e4b --- /dev/null +++ b/docs/sceneObjs.SphericalLens.html @@ -0,0 +1,4914 @@ + + + + + JSDoc: Class: SphericalLens + + + + + + + + + + +
    + +

    Class: SphericalLens

    + + + + + + +
    + +
    + +

    + sceneObjs.SphericalLens()

    + +

    Spherical lens.

    +

    Tools -> Glass -> Spherical Lens

    +

    It is essentially a special case of sceneObjs['Glass'] that has the shape of a lens, but it provides a more user-friendly interface to create a lens using more familliar parameters. +In the state where the lens is built, it behaves exactly like sceneObjs['Glass'], and p1, p2, and parames are null. But when the lens is not built (which happens when the user enters a set of invalid parameters, or if the JSON data is defined using parameters directly), it is defined using p1, p2, and params, and path is null.

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new SphericalLens()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    path + + +Array.<object> + + + +

    The path of the lens if it is built.

    defBy + + +string + + + +

    The way the lens is defined. Either 'DR1R2' or 'DFfdBfd'.

    p1 + + +Point + + + +

    The intersection of the perpendicular bisector of the segment for the d parameter with the top edge of the lens, if it is not built.

    p2 + + +Point + + + +

    The intersection of the perpendicular bisector of the segment for the d parameter with the bottom edge of the lens, if it is not built.

    params + + +object + + + +

    The parameters of the lens if it is not built. It has the following properties: d, r1, and r2 if defBy is 'DR1R2', and d, ffd, and bfd if defBy is 'DFfdBfd'.

    refIndex + + +number + + + +

    The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.

    cauchyB + + +number + + + +

    The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    fillGlass(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Fill the glass with the color that represents the refractive index. To be called in draw of a subclass when the path has been set up with canvasRenderer.ctx.beginPath(), etc.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getIncidentType(ray) → {number}

    + + + + + + +
    +

    Get whether the ray is incident from inside to outside or from outside to inside.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be checked.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getRefIndexAt(point, ray) → {number}

    + + + + + + +
    +

    Get the refractive index at a point for a ray

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    point + + +Point + + + +

    The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.

    ray + + +Ray + + + +

    The ray to be refracted.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The refractive index at the point.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayEnter(ray)

    + + + + + + +
    +

    Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that enters the glass.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayExit(ray)

    + + + + + + +
    +

    Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike onRayIncident which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface. For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray that exits the glass.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) → {SimulationReturn}

    + + + + + + +
    +

    Do the refraction calculation at the surface of the glass.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray to be refracted.

    rayIndex + + +number + + + +

    The index of the ray in the ray array.

    incidentPoint + + +Point + + + +

    The incident point.

    normal + + +Point + + + +

    The normal vector at the incident point.

    n1 + + +number + + + +

    The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are to be merged with the current object.

    bodyMergingObj + + +BaseGrinGlass + + + +

    The object that is to be merged with the current object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value for onRayIncident.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn + + +
    +
    + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.TextLabel.html b/docs/sceneObjs.TextLabel.html new file mode 100644 index 00000000..3d2a3c22 --- /dev/null +++ b/docs/sceneObjs.TextLabel.html @@ -0,0 +1,3829 @@ + + + + + JSDoc: Class: TextLabel + + + + + + + + + + +
    + +

    Class: TextLabel

    + + + + + + +
    + +
    + +

    + sceneObjs.TextLabel()

    + +

    Text label

    +

    Tools -> Other -> Text

    + + +
    + +
    +
    + + + + +

    Constructor

    + + + +

    new TextLabel()

    + + + + + + + + + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +number + + + +

    The x coordinate.

    y + + +number + + + +

    The y coordinate.

    text + + +string + + + +

    The text content.

    fontSize + + +number + + + +

    The font size.

    font + + +string + + + +

    The font name.

    fontStyle + + +string + + + +

    The font style.

    alignment + + +string + + + +

    The font alignment.

    smallCaps + + +boolean + + + +

    Whether the text is in small caps.

    angle + + +number + + + +

    The angle of the text in degrees.

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + +

    Extends

    + + + + + + + + + + + + + + + + + + + + +

    Members

    + + + +

    error

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    error + + +string +| + +null + + + +

    The error message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    isOptical

    + + + + +
    +

    Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    scene

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    scene + + +Scene + + + +

    The scene the object belongs to.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    serializableDefaults

    + + + + +
    +

    The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    supportsSurfaceMerging

    + + + + +
    +

    Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)

    +
    + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    type

    + + + + +
    +

    The type of the object.

    +
    + + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + +

    warning

    + + + + + + + + + + +
    Properties:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    warning + + +string +| + +null + + + +

    The warning message of the object.

    + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +

    Methods

    + + + + + + + +

    arePropertiesDefault(propertyNames) → {boolean}

    + + + + + + +
    +

    Check whether the given properties of the object are all the default values.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    propertyNames + + +Array.<string> + + + +

    The property names to be checked.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    Whether the properties are all the default values.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + + + + + + + + + +

    checkMouseOver(mouse) → {DragContext|null}

    + + + + + + +
    +

    Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The drag context if the user starts dragging at this position, or null if the mouse is not over the object.

    +
    + + + +
    +
    + Type +
    +
    + +DragContext +| + +null + + +
    +
    + + + + + + + + + + + + + +

    checkRayIntersects(ray) → {Point|null}

    + + + + + + +
    +

    Check whether the object intersects with the given ray. +Called during the ray tracing when ray is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +
      +
    • The intersection (closest to the beginning of the ray) if they intersect.
    • +
    +
    + + + +
    +
    + Type +
    +
    + +Point +| + +null + + +
    +
    + + + + + + + + + + + + + +

    draw(canvasRenderer, isAboveLight, isHovered)

    + + + + + + +
    +

    Draw the object on the canvas. +Called once before the simulator renders the light with isAboveLight === false and once after with isAboveLight === true. +Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canvasRenderer + + +CanvasRenderer + + + +

    The canvas renderer.

    isAboveLight + + +boolean + + + +

    Whether the rendering layer is above the light layer.

    isHovered + + +boolean + + + +

    Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    getError() → {string|null}

    + + + + + + +
    +

    Get the error message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The error message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getWarning() → {string|null}

    + + + + + + +
    +

    Get the warning message of the object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The warning message.

    +
    + + + +
    +
    + Type +
    +
    + +string +| + +null + + +
    +
    + + + + + + + + + + + + + +

    getZIndex() → {number}

    + + + + + + +
    +

    Get the z-index of the object for the sequence of drawing. +Called before the simulator starts to draw the scene.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The z-index. The smaller the number is, the earlier draw is called.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + + + + + +

    move(diffX, diffY)

    + + + + + + +
    +

    Move the object by the given displacement. +Called when the user use arrow keys to move the object.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    diffX + + +number + + + +

    The x-coordinate displacement.

    diffY + + +number + + + +

    The y-coordinate displacement.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onConstructMouseDown(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse down event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseMove(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse move event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructMouseUp(mouse, ctrl, shift) → {ConstructReturn}

    + + + + + + +
    +

    Mouse up event when the object is being constructed by the user.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onConstructUndo() → {ConstructReturn}

    + + + + + + +
    +

    Undo event when the object is being constructed by the user.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +ConstructReturn + + +
    +
    + + + + + + + + + + + + + +

    onDrag(mouse, dragContext, ctrl, shift)

    + + + + + + +
    +

    The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to DragContext which is returned by checkMouseOver. dragContext can be modified during the dragging.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    mouse + + +Mouse + + + +

    The mouse object.

    dragContext + + +DragContext + + + +

    The drag context.

    ctrl + + +boolean + + + +

    Whether the control key is pressed.

    shift + + +boolean + + + +

    Whether the shift key is pressed.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) → {SimulationReturn|null}

    + + + + + + +
    +

    The event when a ray is incident on the object. +Called during the ray tracing when ray has been calculated to be incident on the object at the incidentPoint. Perform the interaction between ray and the object. Implemented only by optical elements that affects or detect rays. +If ray is absorbed by the object, return { isAbsorbed: true }. +If there is a primary outgoing ray, directly modify ray to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray. +If there are secondary rays to be emitted, return { newRays: [ray1, ray2, ...] }. Note that if there are more than one secondary rays, image detection does not work in the current version, and rayN.gap should be set to true. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the newRays array. +Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as truncation.

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ray + + +Ray + + + +

    The ray.

    rayIndex + + +number + + + +

    The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.

    incidentPoint + + +Point + + + +

    The point where the ray is incident on the object, which is the intersection point found by checkRayIntersects.

    surfaceMergingObjs + + +Array.<BaseSceneObj> + + + +

    The objects that are merged with the current object. If two or more objects with supportsSurfaceMerging === true has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have onRayIncident being called, and the other objects will be in surfaceMergingObjs. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).

    + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    onSimulationStart() → {SimulationReturn|null}

    + + + + + + +
    +

    The event when the simulation starts. +If this object is a light source, it should emit rays here by setting newRays. If the object is a detector, it may do some initialization here.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The return value.

    +
    + + + +
    +
    + Type +
    +
    + +SimulationReturn +| + +null + + +
    +
    + + + + + + + + + + + + + +

    populateObjBar(objBar)

    + + + + + + +
    +

    Populate the object bar. +Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).

    +
    + + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objBar + + +ObjBar + + + +

    The object bar to be populated.

    + + + + + + +
    + + + + + + + + +
    Overrides:
    +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +

    serialize() → {Object}

    + + + + + + +
    +

    Serializes the object to a JSON object.

    +
    + + + + + + + + + + + + + +
    + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The serialized JSON object.

    +
    + + + +
    +
    + Type +
    +
    + +Object + + +
    +
    + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.html b/docs/sceneObjs.html new file mode 100644 index 00000000..4527673d --- /dev/null +++ b/docs/sceneObjs.html @@ -0,0 +1,234 @@ + + + + + JSDoc: Namespace: sceneObjs + + + + + + + + + + +
    + +

    Namespace: sceneObjs

    + + + + + + +
    + +
    + +

    sceneObjs

    + + +
    + +
    +
    + + +

    The namespace for all the classes representing objects that can be added to the scene. Scene objects include optical elements (e.g. mirrors, lenses), detectors, decorations (e.g. rulers, text labels), and special objects (e.g. handles, cropboxes).

    +

    Each class represents a type of objects, and defines the rendering of the object, the options in the object bar when selected, how the mouse interacts with the object, and how the object interacts with light rays. The base class for all scene objects is BaseSceneObj, which provides common properties and methods for all scene objects. Child base classes are used for common optical interactions: BaseFilter (for mirrors and blockes), BaseGlass, and BaseGrinGlass. +Mixins are used for common user interactions based on shapes: LineObjMixin and CircleObjMixin. +The directory structure in src/simulator/js/sceneObjs is organized according to the toolbars in the app, which is not always the same as the class inheritance structure. For example, IdealLens is categorized under "Glass" in the app, but is not a subclass of BaseGlass.

    +

    In the Ray Optics Simulator web app, a single instance of Scene is used. The scene objects created by the users are stored in the objs property of that instance, each a instance of a class defined in this namespace.

    +

    The classes can also be used by other projects, including those running in a standalone environment (e.g. Node.js).

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + +
    + + + + + + +

    Classes

    + +
    +
    AngleSource
    +
    + +
    Aperture
    +
    + +
    ArcMirror
    +
    + +
    Beam
    +
    + +
    BeamSplitter
    +
    + +
    Blocker
    +
    + +
    CircleBlocker
    +
    + +
    CircleGlass
    +
    + +
    CircleGrinGlass
    +
    + +
    CropBox
    +
    + +
    CustomGlass
    +
    + +
    CustomMirror
    +
    + +
    Detector
    +
    + +
    DiffractionGrating
    +
    + +
    Drawing
    +
    + +
    Glass
    +
    + +
    GrinGlass
    +
    + +
    Handle
    +
    + +
    IdealLens
    +
    + +
    IdealMirror
    +
    + +
    LineArrow
    +
    + +
    Mirror
    +
    + +
    ModuleObj
    +
    + +
    ParabolicMirror
    +
    + +
    PlaneGlass
    +
    + +
    PointSource
    +
    + +
    Protractor
    +
    + +
    Ruler
    +
    + +
    SingleRay
    +
    + +
    SphericalLens
    +
    + +
    TextLabel
    +
    +
    + + + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + +
    + + + + + + + \ No newline at end of file diff --git a/docs/sceneObjs.js.html b/docs/sceneObjs.js.html new file mode 100644 index 00000000..f2b1acaa --- /dev/null +++ b/docs/sceneObjs.js.html @@ -0,0 +1,97 @@ + + + + + JSDoc: Source: sceneObjs.js + + + + + + + + + + +
    + +

    Source: sceneObjs.js

    + + + + + + +
    +
    +
    /**
    + * @file {@link sceneObjs} is the namespace for all the classes representing objects that can be added to the scene. Scene objects include optical elements (e.g. mirrors, lenses), detectors, decorations (e.g. rulers, text labels), and special objects (e.g. handles, cropboxes).
    + */
    +
    +/**
    + * The namespace for all the classes representing objects that can be added to the scene. Scene objects include optical elements (e.g. mirrors, lenses), detectors, decorations (e.g. rulers, text labels), and special objects (e.g. handles, cropboxes).
    + * 
    + * Each class represents a type of objects, and defines the rendering of the object, the options in the object bar when selected, how the mouse interacts with the object, and how the object interacts with light rays. The base class for all scene objects is {@link BaseSceneObj}, which provides common properties and methods for all scene objects. Child base classes are used for common optical interactions: {@link BaseFilter} (for mirrors and blockes), {@link BaseGlass}, and {@link BaseGrinGlass}.
    + * Mixins are used for common user interactions based on shapes: {@link LineObjMixin} and {@link CircleObjMixin}.
    + * The directory structure in `src/simulator/js/sceneObjs` is organized according to the toolbars in the app, which is not always the same as the class inheritance structure. For example, `IdealLens` is categorized under "Glass" in the app, but is not a subclass of `BaseGlass`.
    + * 
    + * In the Ray Optics Simulator web app, a single instance of {@link Scene} is used. The scene objects created by the users are stored in the `objs` property of that instance, each a instance of a class defined in this namespace.
    + * 
    + * The classes can also be used by other projects, including those running in a standalone environment (e.g. Node.js).
    + * @namespace sceneObjs
    + */
    +export const SingleRay = require('./sceneObjs/lightSource/SingleRay.js').default;
    +export const Beam = require('./sceneObjs/lightSource/Beam.js').default;
    +export const PointSource = require('./sceneObjs/lightSource/PointSource.js').default;
    +export const AngleSource = require('./sceneObjs/lightSource/AngleSource.js').default;
    +export const Mirror = require('./sceneObjs/mirror/Mirror.js').default;
    +export const ArcMirror = require('./sceneObjs/mirror/ArcMirror.js').default;
    +export const ParabolicMirror = require('./sceneObjs/mirror/ParabolicMirror.js').default;
    +export const CustomMirror = require('./sceneObjs/mirror/CustomMirror.js').default;
    +export const IdealMirror = require('./sceneObjs/mirror/IdealMirror.js').default;
    +export const BeamSplitter = require('./sceneObjs/mirror/BeamSplitter.js').default;
    +export const PlaneGlass = require('./sceneObjs/glass/PlaneGlass.js').default;
    +export const CircleGlass = require('./sceneObjs/glass/CircleGlass.js').default;
    +export const Glass = require('./sceneObjs/glass/Glass.js').default;
    +export const CustomGlass = require('./sceneObjs/glass/CustomGlass.js').default;
    +export const IdealLens = require('./sceneObjs/glass/IdealLens.js').default;
    +export const SphericalLens = require('./sceneObjs/glass/SphericalLens.js').default;
    +export const CircleGrinGlass = require('./sceneObjs/glass/CircleGrinGlass.js').default;
    +export const GrinGlass = require('./sceneObjs/glass/GrinGlass.js').default;
    +export const Blocker = require('./sceneObjs/blocker/Blocker.js').default;
    +export const CircleBlocker = require('./sceneObjs/blocker/CircleBlocker.js').default;
    +export const Aperture = require('./sceneObjs/blocker/Aperture.js').default;
    +export const DiffractionGrating = require('./sceneObjs/blocker/DiffractionGrating.js').default;
    +export const Ruler = require('./sceneObjs/other/Ruler.js').default;
    +export const Protractor = require('./sceneObjs/other/Protractor.js').default;
    +export const Detector = require('./sceneObjs/other/Detector.js').default;
    +export const TextLabel = require('./sceneObjs/other/TextLabel.js').default;
    +export const LineArrow = require('./sceneObjs/other/LineArrow.js').default;
    +export const Drawing = require('./sceneObjs/other/Drawing.js').default;
    +export const Handle = require('./sceneObjs/special/Handle.js').default;
    +export const CropBox = require('./sceneObjs/special/CropBox.js').default;
    +export const ModuleObj = require('./sceneObjs/special/ModuleObj.js').default;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_BaseFilter.js.html b/docs/sceneObjs_BaseFilter.js.html new file mode 100644 index 00000000..9b1ecf87 --- /dev/null +++ b/docs/sceneObjs_BaseFilter.js.html @@ -0,0 +1,102 @@ + + + + + JSDoc: Source: sceneObjs/BaseFilter.js + + + + + + + + + + +
    + +

    Source: sceneObjs/BaseFilter.js

    + + + + + + +
    +
    +
    import BaseSceneObj from './BaseSceneObj.js';
    +import Simulator from '../Simulator.js';
    +import i18next from 'i18next';
    +
    +/**
    + * The base class for optical elements with wavelength filter functionality, including mirrors (which have the dichroic feature) and blockers.
    + * @class
    + * @extends BaseSceneObj
    + * @property {boolean} filter - Whether the filter feature is enabled.
    + * @property {boolean} invert - If true, the element interacts with the ray only if its wavelength is outside the bandwidth of the filter. If false, the element interacts with the ray only if its wavelength is within the bandwidth of the filter.
    + * @property {number} wavelength - The target wavelength of the filter. The unit is nm.
    + * @property {number} bandwidth - The bandwidth of the filter. The unit is nm.
    + */
    +class BaseFilter extends BaseSceneObj {
    +
    +  populateObjBar(objBar) {
    +    if (this.scene.simulateColors) {
    +      objBar.createBoolean(i18next.t('simulator:sceneObjs.BaseFilter.filter'), this.filter, function (obj, value) {
    +        obj.filter = value;
    +        obj.wavelength = obj.wavelength;
    +        obj.invert = obj.invert;
    +        obj.bandwidth = obj.bandwidth;
    +      }, null, true);
    +      if (this.filter) {
    +        objBar.createBoolean(i18next.t('simulator:sceneObjs.BaseFilter.invert'), this.invert, function (obj, value) {
    +          if (obj.filter) {
    +            obj.invert = value;
    +          }
    +        });
    +        objBar.createNumber(i18next.t('simulator:sceneObjs.common.wavelength') + ' (nm)', Simulator.UV_WAVELENGTH, Simulator.INFRARED_WAVELENGTH, 1, this.wavelength, function (obj, value) {
    +          obj.wavelength = value;
    +        });
    +        objBar.createNumber("± " + i18next.t('simulator:sceneObjs.BaseFilter.bandwidth') + ' (nm)', 0, (Simulator.INFRARED_WAVELENGTH - Simulator.UV_WAVELENGTH), 1, this.bandwidth, function (obj, value) {
    +          obj.bandwidth = value;
    +        });
    +      }
    +    }
    +  }
    +
    +  /**
    +   * Checks if the ray interacts with the filter at the level of the wavelength.
    +   * @param {Ray} ray - The ray to be checked.
    +   * @returns {boolean} - If true, the ray interacts with the filter at the level of the wavelength.
    +   */
    +  checkRayIntersectFilter(ray) {
    +    var dichroicEnabled = this.scene.simulateColors && this.filter && this.wavelength;
    +    var rayHueMatchesMirror =  Math.abs(this.wavelength - ray.wavelength) <= this.bandwidth;
    +    return !dichroicEnabled || (rayHueMatchesMirror != this.invert);
    +  }
    +};
    +
    +export default BaseFilter;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_BaseGlass.js.html b/docs/sceneObjs_BaseGlass.js.html new file mode 100644 index 00000000..f3ddf29d --- /dev/null +++ b/docs/sceneObjs_BaseGlass.js.html @@ -0,0 +1,315 @@ + + + + + JSDoc: Source: sceneObjs/BaseGlass.js + + + + + + + + + + +
    + +

    Source: sceneObjs/BaseGlass.js

    + + + + + + +
    +
    +
    import BaseSceneObj from './BaseSceneObj.js';
    +import i18next from 'i18next';
    +import geometry from '../geometry.js';
    +
    +/**
    + * The base class for glasses.
    + * @class
    + * @extends BaseSceneObj
    + * @property {number} refIndex - The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.
    + * @property {number} cauchyB - The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.
    + */
    +class BaseGlass extends BaseSceneObj {
    +
    +  populateObjBar(objBar) {
    +    if (this.scene.simulateColors) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.BaseGlass.cauchyCoeff') + " A", 1, 3, 0.01, this.refIndex, function (obj, value) {
    +        obj.refIndex = value * 1;
    +      }, '<p>*' + i18next.t('simulator:sceneObjs.BaseGlass.refIndexInfo.relative') + '</p><p>' + i18next.t('simulator:sceneObjs.BaseGlass.refIndexInfo.effective') + '</p>');
    +      objBar.createNumber("B(μm²)", 0.0001, 0.02, 0.0001, this.cauchyB, function (obj, value) {
    +        obj.cauchyB = value;
    +      });
    +    } else {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.BaseGlass.refIndex') + '*', 0.5, 2.5, 0.01, this.refIndex, function (obj, value) {
    +        obj.refIndex = value * 1;
    +      }, '<p>*' + i18next.t('simulator:sceneObjs.BaseGlass.refIndexInfo.relative') + '</p><p>' + i18next.t('simulator:sceneObjs.BaseGlass.refIndexInfo.effective') + '</p>');
    +    }
    +  }
    +
    +  getZIndex() {
    +    return this.refIndex * (-1); // The material with (relative) refractive index < 1 should be draw after the one with > 1 so that the color subtraction in fillGlass works.
    +  }
    +
    +  /* Utility methods */
    +
    +  /**
    +   * Fill the glass with the color that represents the refractive index. To be called in `draw` of a subclass when the path has been set up with `canvasRenderer.ctx.beginPath()`, etc.
    +   * @param {CanvasRenderer} canvasRenderer - The canvas renderer.
    +   * @param {boolean} isAboveLight - Whether the rendering layer is above the light layer.
    +   * @param {boolean} isHovered - Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.
    +   */
    +  fillGlass(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    const n = this.refIndex;
    +
    +    if (isAboveLight) {
    +      // Draw the highlight only
    +      ctx.globalAlpha = 0.1;
    +      ctx.fillStyle = isHovered ? 'cyan' : ('transparent');
    +      ctx.fill('evenodd');
    +      ctx.globalAlpha = 1;
    +      return;
    +    }
    +    if (n >= 1) {
    +      ctx.globalCompositeOperation = 'lighter';
    +      var alpha = Math.log(n) / Math.log(1.5) * 0.2;
    +      if (!canvasRenderer.isSVG) {
    +        ctx.fillStyle = "rgb(" + Math.round(alpha * 255) + "," + Math.round(alpha * 255) + "," + Math.round(alpha * 255) + ")";
    +      } else {
    +        ctx.globalAlpha = alpha;
    +        ctx.fillStyle = "white";
    +      }
    +      ctx.fill('evenodd');
    +      ctx.globalAlpha = 1;
    +      ctx.globalCompositeOperation = 'source-over';
    +
    +    } else {
    +      var alpha = Math.log(1 / n) / Math.log(1.5) * 0.2;
    +      if (!canvasRenderer.isSVG) {
    +        // Subtract the gray color.
    +        // Use a trick to make the color become red (indicating nonphysical) if the total refractive index is lower than one.
    +
    +        // A trick to work around a buggy behavior in some browser (at least in Google Chrome 105 on macOS 12.2.1 on iMac 2021) that the color in the lower left corner of the canvas is filled to the glass. Reason unknown.
    +        // TODO: Find out the reason behind this behavior.
    +        var imageData = ctx.getImageData(0.0, 0.0, ctx.canvas.width, ctx.canvas.height);
    +        var data = imageData.data;
    +        ctx.putImageData(imageData, 0, 0);
    +
    +        ctx.globalCompositeOperation = 'difference';
    +        ctx.fillStyle = "rgb(" + (alpha * 100) + "%," + (0) + "%," + (0) + "%)";
    +        ctx.fill('evenodd');
    +
    +        ctx.setTransform(1, 0, 0, 1, 0, 0);
    +        ctx.fillStyle = "white";
    +        ctx.globalAlpha = 1;
    +        ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    +        ctx.setTransform(canvasRenderer.scale, 0, 0, canvasRenderer.scale, canvasRenderer.origin.x, canvasRenderer.origin.y);
    +
    +        ctx.globalCompositeOperation = 'lighter';
    +
    +        ctx.fillStyle = "rgb(" + (0) + "%," + (alpha * 100) + "%," + (alpha * 100) + "%)";
    +        ctx.fill('evenodd');
    +
    +        ctx.globalCompositeOperation = 'difference';
    +
    +        ctx.setTransform(1, 0, 0, 1, 0, 0);
    +        ctx.fillStyle = "white";
    +        ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    +        ctx.setTransform(canvasRenderer.scale, 0, 0, canvasRenderer.scale, canvasRenderer.origin.x, canvasRenderer.origin.y);
    +
    +        ctx.globalCompositeOperation = 'source-over';
    +        ctx.globalAlpha = 1;
    +      } else {
    +        // canvas2svg does not support globalCompositeOperation. Use the old appearance.
    +        ctx.globalAlpha = 1;
    +        ctx.strokeStyle = isHovered ? 'cyan' : ('rgb(70,70,70)');
    +        ctx.lineWidth = 1 * ls;
    +        ctx.stroke();
    +      }
    +    }
    +  }
    +
    +  /**
    +   * Do the refraction calculation at the surface of the glass.
    +   * @param {Ray} ray - The ray to be refracted.
    +   * @param {number} rayIndex - The index of the ray in the ray array.
    +   * @param {Point} incidentPoint - The incident point.
    +   * @param {Point} normal - The normal vector at the incident point.
    +   * @param {number} n1 - The effective refractive index of the current object (after determining the direction of incident of the current object, but before merging the surface with other objects).
    +   * @param {Array<BaseSceneObj>} surfaceMergingObjs - The objects that are to be merged with the current object.
    +   * @param {BaseGrinGlass} bodyMergingObj - The object that is to be merged with the current object.
    +   * @returns {SimulationReturn} The return value for `onRayIncident`.
    +   */
    +  refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, bodyMergingObj) {
    +
    +    // Surface merging
    +    for (var i = 0; i < surfaceMergingObjs.length; i++) {
    +      let incidentType = surfaceMergingObjs[i].getIncidentType(ray);
    +      if (incidentType == 1) {
    +        // From inside to outside
    +        n1 *= surfaceMergingObjs[i].getRefIndexAt(incidentPoint, ray);
    +        surfaceMergingObjs[i].onRayExit(ray);
    +      } else if (incidentType == -1) {
    +        // From outside to inside
    +        n1 /= surfaceMergingObjs[i].getRefIndexAt(incidentPoint, ray);
    +        surfaceMergingObjs[i].onRayEnter(ray);
    +      } else if (incidentType == 0) {
    +        // Equivalent to not intersecting with the obj (e.g. two interfaces overlap)
    +        //n1=n1;
    +      } else {
    +        // Situation that may cause bugs (e.g. incident on an edge point)
    +        // To prevent shooting the ray to a wrong direction, absorb the ray
    +        return {
    +          isAbsorbed: true
    +        };
    +      }
    +    }
    +
    +    var normal_len = Math.sqrt(normal.x * normal.x + normal.y * normal.y);
    +    var normal_x = normal.x / normal_len;
    +    var normal_y = normal.y / normal_len;
    +
    +    var ray_len = Math.sqrt((ray.p2.x - ray.p1.x) * (ray.p2.x - ray.p1.x) + (ray.p2.y - ray.p1.y) * (ray.p2.y - ray.p1.y));
    +
    +    var ray_x = (ray.p2.x - ray.p1.x) / ray_len;
    +    var ray_y = (ray.p2.y - ray.p1.y) / ray_len;
    +
    +
    +    // Reference http://en.wikipedia.org/wiki/Snell%27s_law#Vector_form
    +
    +    var cos1 = -normal_x * ray_x - normal_y * ray_y;
    +    var sq1 = 1 - n1 * n1 * (1 - cos1 * cos1);
    +
    +
    +    if (sq1 < 0) {
    +      // Total internal reflection
    +      ray.p1 = incidentPoint;
    +      ray.p2 = geometry.point(incidentPoint.x + ray_x + 2 * cos1 * normal_x, incidentPoint.y + ray_y + 2 * cos1 * normal_y);
    +      if (bodyMergingObj) {
    +        ray.bodyMergingObj = bodyMergingObj;
    +      }
    +    } else {
    +      // Refraction
    +      var cos2 = Math.sqrt(sq1);
    +
    +      var R_s = Math.pow((n1 * cos1 - cos2) / (n1 * cos1 + cos2), 2);
    +      var R_p = Math.pow((n1 * cos2 - cos1) / (n1 * cos2 + cos1), 2);
    +      // Reference http://en.wikipedia.org/wiki/Fresnel_equations#Definitions_and_power_equations
    +
    +      let newRays = [];
    +      let truncation = 0;
    +
    +      // Handle the reflected ray
    +      var ray2 = geometry.line(incidentPoint, geometry.point(incidentPoint.x + ray_x + 2 * cos1 * normal_x, incidentPoint.y + ray_y + 2 * cos1 * normal_y));
    +      ray2.brightness_s = ray.brightness_s * R_s;
    +      ray2.brightness_p = ray.brightness_p * R_p;
    +      ray2.wavelength = ray.wavelength;
    +      ray2.gap = ray.gap;
    +      if (bodyMergingObj) {
    +        ray2.bodyMergingObj = bodyMergingObj;
    +      }
    +      if (ray2.brightness_s + ray2.brightness_p > 0.01) {
    +        newRays.push(ray2);
    +      } else {
    +        truncation += ray2.brightness_s + ray2.brightness_p;
    +        if (!ray.gap) {
    +          var amp = Math.floor(0.01 / ray2.brightness_s + ray2.brightness_p) + 1;
    +          if (rayIndex % amp == 0) {
    +            ray2.brightness_s = ray2.brightness_s * amp;
    +            ray2.brightness_p = ray2.brightness_p * amp;
    +            newRays.push(ray2);
    +          }
    +        }
    +      }
    +
    +      // Handle the refracted ray
    +      ray.p1 = incidentPoint;
    +      ray.p2 = geometry.point(incidentPoint.x + n1 * ray_x + (n1 * cos1 - cos2) * normal_x, incidentPoint.y + n1 * ray_y + (n1 * cos1 - cos2) * normal_y);
    +      ray.brightness_s = ray.brightness_s * (1 - R_s);
    +      ray.brightness_p = ray.brightness_p * (1 - R_p);
    +
    +      return {
    +        newRays: newRays,
    +        truncation: truncation
    +      };
    +    }
    +  }
    +
    +
    +  /**
    +   * Get the refractive index at a point for a ray
    +   * @param {Point} point - The point to get the refractive index. For normal glasses, this parameter is not used. But it will be used in GRIN glasses.
    +   * @param {Ray} ray - The ray to be refracted.
    +   * @returns {number} - The refractive index at the point.
    +   */
    +  getRefIndexAt(point, ray) {
    +    if (this.scene.simulateColors) {
    +      return this.refIndex + this.cauchyB / (ray.wavelength * ray.wavelength * 0.000001);
    +    } else {
    +      return this.refIndex;
    +    }
    +  }
    +
    +
    +  /* Abstract methods */
    +
    +  /**
    +   * Get whether the ray is incident from inside to outside or from outside to inside.
    +   * @param {Ray} ray - The ray to be checked.
    +   * @returns {number} - 1 if the ray is incident from inside to outside, -1 if the ray is incident from outside to inside, 0 if the ray is equivalent to not intersecting the glass (e.g. intersecting with two overlapping surfaces of the glass), and NaN for other situations (e.g. parallel to a surface).
    +   */
    +  getIncidentType(ray) {
    +    // To be implemented in subclasses.
    +  }
    +
    +  /**
    +   * Handle the event when a ray enters the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike `onRayIncident` which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface.  For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.
    +   * @param {Ray} ray - The ray that enters the glass.
    +   */
    +  onRayEnter(ray) {
    +    // Nothing to do for normal glasses.
    +  }
    +
    +  /**
    +   * Handle the event when a ray exits the glass. This is called during the surface merging process, and is called by the glass object who is handling the surface merging, rather than by the simulator. Unlike `onRayIncident` which is only called for one representative object who is responsible for handling the surface merging, this function is called for every object that consistute the merged surface.  For notmal glasses nothing needs to be done in this function, but for GRIN glasses, the body-merging object in the ray should be updated here, so that the ray knows that it now feels a different refractive index gradient.
    +   * @param {Ray} ray - The ray that exits the glass.
    +   */
    +  onRayExit(ray) {
    +    // Nothing to do for normal glasses.
    +  }
    +
    +};
    +
    +export default BaseGlass;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_BaseGrinGlass.js.html b/docs/sceneObjs_BaseGrinGlass.js.html new file mode 100644 index 00000000..c2266ee4 --- /dev/null +++ b/docs/sceneObjs_BaseGrinGlass.js.html @@ -0,0 +1,364 @@ + + + + + JSDoc: Source: sceneObjs/BaseGrinGlass.js + + + + + + + + + + +
    + +

    Source: sceneObjs/BaseGrinGlass.js

    + + + + + + +
    +
    +
    import BaseGlass from './BaseGlass.js';
    +import geometry from '../geometry.js';
    +import Simulator from '../Simulator.js';
    +import i18next from 'i18next';
    +import { evaluateLatex } from '../equation.js';
    +import { parseTex } from 'tex-math-parser'
    +import * as math from 'mathjs';
    +
    +/**
    + * @typedef {Object} BodyMergingObj
    + * Every ray has a temporary bodyMerging object ("bodyMergingObj") as a property (this property exists only while the ray is inside a region of one or several overlapping grin objects - e.g. CircleGrinGlass and GrinGlass), which gets updated as the ray enters/exits into/from grin objects, using the "multRefIndex"/"devRefIndex" function, respectively.
    + * @property {function} fn_p - The refractive index function for the equivalent region of the simulation.
    + * @property {function} fn_p_der_x - The x derivative of `fn_p` for the equivalent region of the simulation.
    + * @property {function} fn_p_der_y - The y derivative of `fn_p` for the equivalent region of the simulation.
    + */
    +
    +/**
    + * The base class for glasses.
    + * @class
    + * @extends BaseGlass
    + * @property {string} p - The refractive index function (a function of x and y, related to `origin`) of the glass in math.js string.
    + * @property {string} refIndexFn - The refractive index function of the glass in LaTeX.
    + * @property {string} p_der_x - The x derivative of `p` in math.js string.
    + * @property {string} p_der_x_tex - The x derivative of `p` in LaTeX.
    + * @property {string} p_der_y - The y derivative of `p` in math.js string.
    + * @property {string} p_der_y_tex - The y derivative of `p` in LaTeX.
    + * @property {Point} origin - The origin of (x,y) used in the above equationns.
    + * @property {function} fn_p - The evaluatex function for `p`, where (x,y) has been shifted to the absolute coordinates.
    + * @property {function} fn_p_der_x - The evaluatex function for `p_der_x`, where (x,y) has been shifted to the absolute coordinates.
    + * @property {function} fn_p_der_y - The evaluatex function for `p_der_y`, where (x,y) has been shifted to the absolute coordinates.
    + * @property {number} stepSize - The step size for the ray trajectory equation.
    + * @property {number} intersectTol - The epsilon for the intersection calculations.
    + */
    +class BaseGrinGlass extends BaseGlass {
    +
    +  constructor(scene, jsonObj) {
    +    super(scene, jsonObj);
    +    this.initFns();
    +  }
    +
    +  populateObjBar(objBar) {
    +    if (!this.fn_p) {
    +      this.initFns();
    +    }
    +    objBar.createEquation('n(x,y) = ', this.refIndexFn, function (obj, value) {
    +      obj.refIndexFn = value;
    +      obj.initFns();
    +    }, '<ul><li>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.refIndexFnInfo.constants') + '<br><code>pi e</code></li><li>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.refIndexFnInfo.operators') + '<br><code>+ - * / ^</code></li><li>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.refIndexFnInfo.functions') + '<br><code>sqrt sin cos tan sec csc cot sinh cosh tanh log arcsin arccos arctan</code></li><li>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.refIndexFnInfo.lambda', {lambda: '<code>lambda</code>'}) + '</li><li>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.refIndexFnInfo.diff') + '</li><li>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.refIndexFnInfo.origin') + '</li><li>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.refIndexFnInfo.accuracy') + '</li></ul>');
    +
    +    objBar.createTuple(i18next.t('simulator:sceneObjs.BaseGrinGlass.refIndexFnOrigin'), '(' + this.origin.x + ',' + this.origin.y + ')', function (obj, value) {
    +      const commaPosition = value.indexOf(',');
    +      if (commaPosition != -1) {
    +        const n_origin_x = parseFloat(value.slice(1, commaPosition));
    +        const n_origin_y = parseFloat(value.slice(commaPosition + 1, -1));
    +        obj.origin = geometry.point(n_origin_x, n_origin_y);
    +        obj.initFns();
    +      }
    +    });
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['stepSize']))) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.BaseGrinGlass.stepSize'), 0.1 * this.scene.lengthScale, 1 * this.scene.lengthScale, 0.1 * this.scene.lengthScale, this.stepSize, function (obj, value) {
    +        obj.stepSize = parseFloat(value);
    +      }, '<p>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.stepSizeInfo') + '</p>');
    +    }
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['intersectTol']))) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.BaseGrinGlass.intersectTol'), 1e-3, 1e-2, 1e-3, this.intersectTol, function (obj, value) {
    +        obj.intersectTol = parseFloat(value);
    +      }, '<p>' + i18next.t(`simulator:sceneObjs.${this.constructor.type}.epsInfo.units`) + '</p><p>' + i18next.t(`simulator:sceneObjs.${this.constructor.type}.epsInfo.functions`) + '</p>');
    +    }
    +
    +    const scene = this.scene;
    +    if (objBar.showAdvanced(this.scene.symbolicBodyMerging)) {
    +      objBar.createBoolean(i18next.t('simulator:sceneObjs.BaseGrinGlass.symbolicBodyMerging'), this.scene.symbolicBodyMerging, function (obj, value) {
    +        obj.scene.symbolicBodyMerging = value;
    +      }, '<p>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.symbolicBodyMergingInfo.all') + '</p><p>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.symbolicBodyMergingInfo.impl') + '</p><p>' + i18next.t('simulator:sceneObjs.BaseGrinGlass.symbolicBodyMergingInfo.implNote') + '</p>');
    +    }
    +  }
    +
    +  getZIndex() {
    +    return 0;
    +  }
    +
    +  fillGlass(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +
    +    if (isAboveLight) {
    +      // Draw the highlight only
    +      ctx.globalAlpha = 0.1;
    +      ctx.fillStyle = isHovered ? 'cyan' : ('transparent');
    +      ctx.fill('evenodd');
    +      ctx.globalAlpha = 1;
    +      return;
    +    }
    +    ctx.fillStyle = "rgba(255,0,255,0.15)";
    +    ctx.fill('evenodd');
    +    ctx.globalAlpha = 1;
    +  }
    +
    +  getRefIndexAt(point, ray) {
    +    return this.fn_p({ x: point.x, y: point.y, z: ray.wavelength || Simulator.GREEN_WAVELENGTH });
    +  }
    +
    +  onRayEnter(ray) {
    +    if (!ray.bodyMergingObj) {
    +      ray.bodyMergingObj = this.initRefIndex(ray);
    +    }
    +    ray.bodyMergingObj = this.multRefIndex(ray.bodyMergingObj);
    +  }
    +
    +  onRayExit(ray) {
    +    if (!ray.bodyMergingObj) {
    +      ray.bodyMergingObj = this.initRefIndex(ray);
    +    }
    +    ray.bodyMergingObj = this.devRefIndex(ray.bodyMergingObj);
    +  }
    +
    +
    +  /* Utility Methods */
    +
    +  /**
    +   * Do the partial derivatives of the refractive index function and parse the functions.
    +   */
    +  initFns() {
    +    this.error = null;
    +    try {
    +      this.p = parseTex(this.refIndexFn.replaceAll("\\lambda", "z")).toString().replaceAll("\\cdot", "*").replaceAll("\\frac", "/");
    +      this.p_der_x = math.derivative(this.p, 'x').toString();
    +      this.p_der_x_tex = math.parse(this.p_der_x).toTex().replaceAll("{+", "{"); // 'evaluateLatex' function can't and can handle expressions of the form '...num^{+exp}...' and '...num^{exp}...', respectively, where num and exp are numbers
    +      this.p_der_y = math.derivative(this.p, 'y').toString();
    +      this.p_der_y_tex = math.parse(this.p_der_y).toTex().replaceAll("{+", "{");
    +      this.fn_p = evaluateLatex(this.shiftOrigin(this.refIndexFn.replaceAll("\\lambda", "z")));
    +      this.fn_p_der_x = evaluateLatex(this.shiftOrigin(this.p_der_x_tex));
    +      this.fn_p_der_y = evaluateLatex(this.shiftOrigin(this.p_der_y_tex));
    +    } catch (e) {
    +      delete this.fn_p;
    +      delete this.fn_p_der_x;
    +      delete this.fn_p_der_y;
    +      this.error = e.toString();
    +    }
    +  }
    +
    +  /**
    +   * Shifts the x and y variables in `equation` from related to `this.origin` to  the absolute coordinates.
    +   * @param {string} equation
    +   * @returns {string} 
    +   */
    +  shiftOrigin(equation) {
    +    return equation.replaceAll("x", "(x-" + this.origin.x + ")").replaceAll("y", "(y-" + this.origin.y + ")");
    +  }
    +  
    +  /**
    +   * Receives a bodyMerging object and returns a new bodyMerging object for the overlapping region of `bodyMergingObj` and the current GRIN glass.
    +   * @param {BodyMergingObj} bodyMergingObj 
    +   * @returns {BodyMergingObj}
    +   */
    +  multRefIndex(bodyMergingObj) {
    +    if (this.scene.symbolicBodyMerging) {
    +      let mul_p = math.simplify('(' + bodyMergingObj.p + ')*' + '(' + this.shiftOrigin(this.p) + ')').toString();
    +
    +      let mul_fn_p = evaluateLatex(math.parse(mul_p).toTex());
    +
    +      let mul_fn_p_der_x = evaluateLatex(math.derivative(mul_p, 'x').toTex());
    +
    +      let mul_fn_p_der_y = evaluateLatex(math.derivative(mul_p, 'y').toTex());
    +
    +      return { p: mul_p, fn_p: mul_fn_p, fn_p_der_x: mul_fn_p_der_x, fn_p_der_y: mul_fn_p_der_y };
    +    } else {
    +      let [fn_p, fn_p_der_x, fn_p_der_y, new_fn_p, new_fn_p_der_x, new_fn_p_der_y] = [this.fn_p, this.fn_p_der_x, this.fn_p_der_y, bodyMergingObj.fn_p, bodyMergingObj.fn_p_der_x, bodyMergingObj.fn_p_der_y];
    +
    +      let mul_fn_p = (function (fn_p, new_fn_p) {
    +        return function (param) {
    +          return fn_p(param) * new_fn_p(param);
    +        };
    +      })(fn_p, new_fn_p);
    +
    +      let mul_fn_p_der_x = (function (fn_p, fn_p_der_x, new_fn_p, new_fn_p_der_x) {
    +        return function (param) {
    +          return fn_p(param) * new_fn_p_der_x(param) + fn_p_der_x(param) * new_fn_p(param); // product chain rule
    +        };
    +      })(fn_p, fn_p_der_x, new_fn_p, new_fn_p_der_x);
    +
    +      let mul_fn_p_der_y = (function (fn_p, fn_p_der_y, new_fn_p, new_fn_p_der_y) {
    +        return function (param) {
    +          return fn_p(param) * new_fn_p_der_y(param) + fn_p_der_y(param) * new_fn_p(param); // product chain rule
    +        };
    +      })(fn_p, fn_p_der_y, new_fn_p, new_fn_p_der_y);
    +
    +      return { fn_p: mul_fn_p, fn_p_der_x: mul_fn_p_der_x, fn_p_der_y: mul_fn_p_der_y };
    +    }
    +  }
    +
    +  /**
    +   * Receives a bodyMerging object and returns a new bodyMerging object for the region of `bodyMergingObj` excluding current GRIN glass.
    +   * @param {BodyMergingObj} bodyMergingObj 
    +   * @returns {BodyMergingObj}
    +   */
    +  devRefIndex(bodyMergingObj) {
    +    if (this.scene.symbolicBodyMerging) {
    +      let dev_p = math.simplify('(' + bodyMergingObj.p + ')/' + '(' + this.shiftOrigin(this.p) + ')').toString();
    +
    +      let dev_fn_p = evaluateLatex(math.parse(dev_p).toTex());
    +
    +      let dev_fn_p_der_x = evaluateLatex(math.derivative(dev_p, 'x').toTex());
    +
    +      let dev_fn_p_der_y = evaluateLatex(math.derivative(dev_p, 'y').toTex());
    +
    +      return { p: dev_p, fn_p: dev_fn_p, fn_p_der_x: dev_fn_p_der_x, fn_p_der_y: dev_fn_p_der_y };
    +    } else {
    +      let [fn_p, fn_p_der_x, fn_p_der_y, new_fn_p, new_fn_p_der_x, new_fn_p_der_y] = [this.fn_p, this.fn_p_der_x, this.fn_p_der_y, bodyMergingObj.fn_p, bodyMergingObj.fn_p_der_x, bodyMergingObj.fn_p_der_y];
    +
    +      let dev_fn_p = (function (fn_p, new_fn_p) {
    +        return function (param) {
    +          return new_fn_p(param) / fn_p(param);
    +        };
    +      })(fn_p, new_fn_p);
    +
    +      let dev_fn_p_der_x = (function (fn_p, fn_p_der_x, new_fn_p, new_fn_p_der_x) {
    +        return function (param) {
    +          return new_fn_p_der_x(param) / fn_p(param) - new_fn_p(param) * fn_p_der_x(param) / (fn_p(param) ** 2); // product chain rule
    +        };
    +      })(fn_p, fn_p_der_x, new_fn_p, new_fn_p_der_x);
    +
    +      let dev_fn_p_der_y = (function (fn_p, fn_p_der_y, new_fn_p, new_fn_p_der_y) {
    +        return function (param) {
    +          return new_fn_p_der_y(param) / fn_p(param) - new_fn_p(param) * fn_p_der_y(param) / (fn_p(param) ** 2); // product chain rule
    +        };
    +      })(fn_p, fn_p_der_y, new_fn_p, new_fn_p_der_y);
    +
    +      return { fn_p: dev_fn_p, fn_p_der_x: dev_fn_p_der_x, fn_p_der_y: dev_fn_p_der_y };
    +    }
    +  }
    +
    +  /**
    +   * Receives a ray, and returns a bodyMerging object for the point ray.p1
    +   * @param {Ray} ray 
    +   * @returns {BodyMergingObj}
    +   */
    +  initRefIndex(ray) {
    +    let obj_tmp;
    +    for (let obj of this.scene.opticalObjs) {
    +      if ((obj instanceof BaseGrinGlass) && (obj.isOnBoundary(ray.p1) || obj.isInsideGlass(ray.p1))) {
    +        if (!obj_tmp) {
    +          obj_tmp = {};
    +          obj_tmp.p = obj.shiftOrigin(obj.p);
    +          obj_tmp.fn_p = obj.fn_p;
    +          obj_tmp.fn_p_der_x = obj.fn_p_der_x;
    +          obj_tmp.fn_p_der_y = obj.fn_p_der_y;
    +        } else {
    +          obj_tmp = obj.multRefIndex(obj_tmp);
    +        }
    +      }
    +    }
    +    if (!obj_tmp) {
    +      obj_tmp = { p: 1, fn_p: function () { return 1; }, fn_p_der_x: function () { return 0; }, fn_p_der_y: function () { return 0; } };
    +    }
    +    return obj_tmp;
    +  }
    +
    +  /**
    +   * Receives two points inside this lens, and returns the next point to where the ray, connecting these two points, will travel, based on the ray trajectory equation (equation 11.1 in the cited text below)
    +   * Using Euler's method to solve the ray trajectory equation (based on sections 11.1 and 11.2, in the following text: https://doi.org/10.1007/BFb0012092)
    +  x_der_s and x_der_s_prev are the x-coordinate derivatives with respect to the arc-length parameterization, at two different points (similarly for y_der_s and y_der_s_prev)
    +   * @param {Point} p1
    +   * @param {Point} p2
    +   * @param {Ray} ray
    +   */
    +  step(p1, p2, ray) {
    +    const len = geometry.distance(p1, p2);
    +    const x = p2.x;
    +    const y = p2.y;
    +    const x_der_s_prev = (p2.x - p1.x) / len;
    +    const y_der_s_prev = Math.sign(p2.y - p1.y) * Math.sqrt(1 - x_der_s_prev ** 2);
    +
    +    const x_der_s = x_der_s_prev + this.stepSize * (ray.bodyMergingObj.fn_p_der_x({ x: x, y: y, z: ray.wavelength || Simulator.GREEN_WAVELENGTH }) * (1 - x_der_s_prev ** 2) - ray.bodyMergingObj.fn_p_der_y({ x: x, y: y, z: ray.wavelength || Simulator.GREEN_WAVELENGTH }) * x_der_s_prev * y_der_s_prev) / ray.bodyMergingObj.fn_p({ x: x, y: y, z: ray.wavelength || Simulator.GREEN_WAVELENGTH });
    +    const y_der_s = y_der_s_prev + this.stepSize * (ray.bodyMergingObj.fn_p_der_y({ x: x, y: y, z: ray.wavelength || Simulator.GREEN_WAVELENGTH }) * (1 - y_der_s_prev ** 2) - ray.bodyMergingObj.fn_p_der_x({ x: x, y: y, z: ray.wavelength || Simulator.GREEN_WAVELENGTH }) * x_der_s_prev * y_der_s_prev) / ray.bodyMergingObj.fn_p({ x: x, y: y, z: ray.wavelength || Simulator.GREEN_WAVELENGTH });
    +
    +    const x_new = x + this.stepSize * x_der_s;
    +    const y_new = y + this.stepSize * y_der_s;
    +
    +    return geometry.point(x_new, y_new);
    +  }
    +
    +
    +
    +
    +  /* Abstract methods */
    +
    +  /**
    +   * Returns `true` if `point` is outside the glass, otherwise returns `false`
    +   * @param {Point} point 
    +   */
    +  isOutsideGlass(point) {
    +    // To be implemented in subclasses.
    +  }
    +
    +  /**
    +   * Returns `true` if `point` is inside the glass, otherwise returns `false`
    +   * @param {Point} point 
    +   */
    +  isInsideGlass(point) {
    +    // To be implemented in subclasses.
    +  }
    +
    +  /**
    +   * Returns `true` if `point` is on the boundary of the glass, otherwise returns `false`
    +   * @param {Point} point 
    +   */
    +  isOnBoundary(point) {
    +    // To be implemented in subclasses.
    +  }
    +
    +};
    +
    +export default BaseGrinGlass;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_BaseSceneObj.js.html b/docs/sceneObjs_BaseSceneObj.js.html new file mode 100644 index 00000000..e50d9fe1 --- /dev/null +++ b/docs/sceneObjs_BaseSceneObj.js.html @@ -0,0 +1,312 @@ + + + + + JSDoc: Source: sceneObjs/BaseSceneObj.js + + + + + + + + + + +
    + +

    Source: sceneObjs/BaseSceneObj.js

    + + + + + + +
    +
    +
    /**
    + * @typedef {Object} ConstructReturn
    + * @property {boolean} [isDone] - Whether the construction is done.
    + * @property {boolean} [requiresObjBarUpdate] - Whether the object bar should be updated.
    + * @property {boolean} [isCancelled] - Whether the construction is cancelled.
    + */
    +
    +/**
    + * @typedef {Object} SimulationReturn
    + * @property {boolean} [isAbsorbed] - Whether the object absorbs the ray.
    + * @property {Array<Ray>} [newRays] - The new rays to be added.
    + * @property {number} [truncation] - The brightness of truncated rays due to numerical cutoff (e.g. after a large number of partial internal reflections within a glass). This is used to estimate the error of the simulation.
    + * @property {number} [brightnessScale] - The actual brightness of the ray divided by the brightness inferred from the properties of the object. This should be 1 when "ray density" is high enough. When "ray density" is low, the calculated brightness of the individual rays will be too high (alpha value for rendering will be larger than 1). In this case, the object should rescale all the brightness of the rays by a factor to keep the maximum alpha value to be 1. This factor should be returned here and is used to generate warnings.
    + */
    +
    +/**
    + * Base class for objects (optical elements, decorations, etc.) in the scene.
    + * @class
    + */
    +class BaseSceneObj {
    +
    +  /**
    +   * @param {Scene} scene - The scene the object belongs to.
    +   * @param {Object|null} jsonObj - The JSON object to be deserialized, if any.
    +   */
    +  constructor(scene, jsonObj) {
    +    /** @property {Scene} scene - The scene the object belongs to. */
    +    this.scene = scene;
    +    /** @property {string|null} error - The error message of the object. */
    +    this.error = null;
    +    /** @property {string|null} warning - The warning message of the object. */
    +    this.warning = null;
    +
    +    const serializableDefaults = this.constructor.serializableDefaults;
    +    for (const propName in serializableDefaults) {
    +      const stringifiedDefault = JSON.stringify(serializableDefaults[propName]);
    +      if (jsonObj && jsonObj.hasOwnProperty(propName)) {
    +        const stringifiedValue = JSON.stringify(jsonObj[propName]);
    +        this[propName] = JSON.parse(stringifiedValue);
    +      } else {
    +        this[propName] = JSON.parse(stringifiedDefault);
    +      }
    +    }
    +  }
    +
    +  /**
    +   * Serializes the object to a JSON object.
    +   * @returns {Object} The serialized JSON object.
    +   */
    +  serialize() {
    +    const jsonObj = { type: this.constructor.type };
    +    const serializableDefaults = this.constructor.serializableDefaults;
    +
    +    for (const propName in serializableDefaults) {
    +      const stringifiedValue = JSON.stringify(this[propName]);
    +      const stringifiedDefault = JSON.stringify(serializableDefaults[propName]);
    +      if (stringifiedValue !== stringifiedDefault) {
    +        jsonObj[propName] = JSON.parse(stringifiedValue);
    +      }
    +    }
    +
    +    return jsonObj;
    +  }
    +  
    +  /**
    +   * Check whether the given properties of the object are all the default values.
    +   * @param {string[]} propertyNames - The property names to be checked.
    +   * @returns {boolean} Whether the properties are all the default values.
    +   */
    +  arePropertiesDefault(propertyNames) {
    +    const serializableDefaults = this.constructor.serializableDefaults;
    +    for (const propName of propertyNames) {
    +      const stringifiedValue = JSON.stringify(this[propName]);
    +      const stringifiedDefault = JSON.stringify(serializableDefaults[propName]);
    +      if (stringifiedValue !== stringifiedDefault) {
    +        return false;
    +      }
    +    }
    +    return true;
    +  }
    +  
    +  /**
    +   * The type of the object.
    +   */
    +  static type = '';
    +
    +  /**
    +   * The default values of the properties of the object which are to be serialized. The keys are the property names and the values are the default values. If some properties is default, they will not be serialized and will be deserialized to the default values.
    +   */
    +  static serializableDefaults = {};
    +
    +  /**
    +   * Whether the object is optical (i.e. is a light source, interacts with rays, or detects rays).
    +   */
    +  static isOptical = false;
    +
    +  /**
    +   * Whether the object supports surface merging. (This is currently only for glasses, where the surfaces of two glasses are merged to form a single surface if the surfaces overlap.)
    +   */
    +  static supportsSurfaceMerging = false;
    +
    +  /**
    +   * Populate the object bar.
    +   * Called when the user selects the object (it is selected automatically when the user creates it, so the construction may not be completed at this stage).
    +   * @param {ObjBar} objBar - The object bar to be populated.
    +   */
    +  populateObjBar(objBar) {
    +    // Do nothing by default
    +  }
    +
    +  /**
    +   * Get the z-index of the object for the sequence of drawing.
    +   * Called before the simulator starts to draw the scene.
    +   * @returns {number} The z-index. The smaller the number is, the earlier `draw` is called.
    +   */
    +  getZIndex() {
    +    return 0;
    +  }
    +
    +  /**
    +   * Draw the object on the canvas.
    +   * Called once before the simulator renders the light with `isAboveLight === false` and once after with `isAboveLight === true`.
    +   * Due to historical reason, some objects use this function to do some initialization. This should be avoided in the future.
    +   * @param {CanvasRenderer} canvasRenderer - The canvas renderer.
    +   * @param {boolean} isAboveLight - Whether the rendering layer is above the light layer.
    +   * @param {boolean} isHovered - Whether the object is hovered by the mouse, which determines the style of the object to be drawn, e.g., with lighlighted color.
    +   */
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    // Do nothing by default
    +  }
    +
    +  /**
    +   * Move the object by the given displacement.
    +   * Called when the user use arrow keys to move the object.
    +   * @param {number} diffX - The x-coordinate displacement.
    +   * @param {number} diffY - The y-coordinate displacement.
    +   */
    +  move(diffX, diffY) {
    +    // Do nothing by default
    +  }
    +
    +  /**
    +   * Mouse down event when the object is being constructed by the user.
    +   * @param {Mouse} mouse - The mouse object.
    +   * @param {boolean} ctrl - Whether the control key is pressed.
    +   * @param {boolean} shift - Whether the shift key is pressed.
    +   * @returns {ConstructReturn} The return value.
    +   */
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    // Do nothing by default
    +  }
    +
    +  /**
    +   * Mouse move event when the object is being constructed by the user.
    +   * @param {Mouse} mouse - The mouse object.
    +   * @param {boolean} ctrl - Whether the control key is pressed.
    +   * @param {boolean} shift - Whether the shift key is pressed.
    +   * @returns {ConstructReturn} The return value.
    +   */
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    // Do nothing by default
    +  }
    +
    +  /**
    +   * Mouse up event when the object is being constructed by the user.
    +   * @param {Mouse} mouse - The mouse object.
    +   * @param {boolean} ctrl - Whether the control key is pressed.
    +   * @param {boolean} shift - Whether the shift key is pressed.
    +   * @returns {ConstructReturn} The return value.
    +   */
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    // Do nothing by default
    +  }
    +
    +  /**
    +   * Undo event when the object is being constructed by the user.
    +   * @returns {ConstructReturn} The return value.
    +   */
    +  onConstructUndo() {
    +    return {
    +      isCancelled: true
    +    }
    +  }
    +
    +  /**
    +   * Check whether the mouse is over the object, which is called when the user moves the mouse over the scene. This is used for deciding the highlighting of the object, and also for deciding that if the user starts dragging at this position, which part of the object should be dragged.
    +   * @param {Mouse} mouse - The mouse object.
    +   * @returns {DragContext|null} The drag context if the user starts dragging at this position, or null if the mouse is not over the object.
    +   */
    +  checkMouseOver(mouse) {
    +    return null;
    +  }
    +
    +  /**
    +   * The event when the user drags the object, which is fired on every step during the dragging. The object should be updated according to `DragContext` which is returned by `checkMouseOver`. `dragContext` can be modified during the dragging.
    +   * @param {Mouse} mouse - The mouse object.
    +   * @param {DragContext} dragContext - The drag context.
    +   * @param {boolean} ctrl - Whether the control key is pressed.
    +   * @param {boolean} shift - Whether the shift key is pressed.
    +   */
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    // Do nothing by default
    +  }
    +
    +  /**
    +   * The event when the simulation starts.
    +   * If this object is a light source, it should emit rays here by setting `newRays`. If the object is a detector, it may do some initialization here.
    +   * @returns {SimulationReturn|null} The return value.
    +   */
    +  onSimulationStart() {
    +    // Do nothing by default
    +  }
    +
    +  
    +
    +  /**
    +   * Check whether the object intersects with the given ray.
    +   * Called during the ray tracing when `ray` is to be tested whether it intersects with the object. Find whether they intersect and find the nearset intersection if so. Implemented only by optical elements that affects or detect rays.
    +   * @param {Ray} ray - The ray.
    +   * @returns {Point|null} - The intersection (closest to the beginning of the ray) if they intersect.
    +   */
    +  checkRayIntersects(ray) {
    +    return null;
    +  }
    +
    +
    +  /**
    +   * The event when a ray is incident on the object.
    +   * Called during the ray tracing when `ray` has been calculated to be incident on the object at the `incidentPoint`. Perform the interaction between `ray` and the object. Implemented only by optical elements that affects or detect rays.
    +   * If `ray` is absorbed by the object, return `{ isAbsorbed: true }`.
    +   * If there is a primary outgoing ray, directly modify `ray` to be the outgoing ray. This includes the case when the object is a detector that does not modify the direction of the ray.
    +   * If there are secondary rays to be emitted, return `{ newRays: [ray1, ray2, ...] }`. Note that if there are more than one secondary rays, image detection does not work in the current version, and `rayN.gap` should be set to `true`. But for future support, the secondary ray which is to be of the same continuous bunch or rays should have consistent index in the `newRays` array.
    +   * Sometimes keeping tracks of all the rays may result in infinite loop (such as in a glass). Depending on the situation, some rays with brightness below a certain threshold (such as 0.01) may be truncated. In this case, the brightness of the truncated rays should be returned as `truncation`.
    +   * @param {Ray} ray - The ray.
    +   * @param {number} rayIndex - The index of the ray in the array of all rays currently in the scene in the simulator. In particular, in a bunch of continuous rays, the rays are ordered by the time they are emitted, and the index is the order of emission. This can be used to downsample the rays and increase the individual brightness if it is too low.
    +   * @param {Point} incidentPoint - The point where the ray is incident on the object, which is the intersection point found by `checkRayIntersects`.
    +   * @param {Array<BaseSceneObj>} surfaceMergingObjs - The objects that are merged with the current object. If two or more objects with `supportsSurfaceMerging === true` has overlapping surfaces (often acheived by using the grid), and if a ray is incident on those surfaces together, only one of the object will be have `onRayIncident` being called, and the other objects will be in `surfaceMergingObjs`. In this case, this function must also deal with the combination of the surface before doing the actual interaction. Note that treating them as two very close surfaces may not give the correct result due to an essential discontinuity of ray optics (which is smoothed out at the scale of the wavelength in reality).
    +   * @returns {SimulationReturn|null} The return value.
    +   */
    +  onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) {
    +    // Do nothing by default
    +  }
    +
    +  /**
    +   * Get the error message of the object.
    +   * @returns {string|null} The error message.
    +   */
    +  getError() {
    +    return this.error;
    +  }
    +
    +  /**
    +   * Get the warning message of the object.
    +   * @returns {string|null} The warning message.
    +   */
    +  getWarning() {
    +    return this.warning;
    +  }
    +
    +}
    +
    +export default BaseSceneObj;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_CircleObjMixin.js.html b/docs/sceneObjs_CircleObjMixin.js.html new file mode 100644 index 00000000..893f10a9 --- /dev/null +++ b/docs/sceneObjs_CircleObjMixin.js.html @@ -0,0 +1,188 @@ + + + + + JSDoc: Source: sceneObjs/CircleObjMixin.js + + + + + + + + + + +
    + +

    Source: sceneObjs/CircleObjMixin.js

    + + + + + + +
    +
    +
    import geometry from '../geometry.js';
    +import Simulator from '../Simulator.js';
    +
    +/**
    + * The mixin for the scene objects that are defined by a circle.
    + * @template {typeof BaseSceneObj} T
    + * @param {T} Base 
    + * @returns {T}
    + */
    +const CircleObjMixin = Base => class extends Base {
    +
    +  move(diffX, diffY) {
    +    // Move the first point
    +    this.p1.x = this.p1.x + diffX;
    +    this.p1.y = this.p1.y + diffY;
    +    // Move the second point
    +    this.p2.x = this.p2.x + diffX;
    +    this.p2.y = this.p2.y + diffY;
    +  }
    +  
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    if (!this.constructionPoint) {
    +      // Initialize the construction stage.
    +      this.constructionPoint = mouse.getPosSnappedToGrid();
    +      this.p1 = this.constructionPoint;
    +      this.p2 = this.constructionPoint;
    +    }
    +    if (shift) {
    +      this.p2 = mouse.getPosSnappedToDirection(this.constructionPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +    } else {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +    }
    +  }
    +
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    if (shift) {
    +      this.p2 = mouse.getPosSnappedToDirection(this.constructionPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +    } else {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +    }
    +
    +    this.p1 = this.constructionPoint;
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    if (!mouse.isOnPoint(this.p1)) {
    +      delete this.constructionPoint;
    +      return {
    +        isDone: true
    +      };
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (mouse.isOnPoint(this.p1) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p2)) {
    +      dragContext.part = 1;
    +      dragContext.targetPoint = geometry.point(this.p1.x, this.p1.y);
    +      return dragContext;
    +    }
    +    if (mouse.isOnPoint(this.p2)) {
    +      dragContext.part = 2;
    +      dragContext.targetPoint = geometry.point(this.p2.x, this.p2.y);
    +      return dragContext;
    +    }
    +    if (Math.abs(geometry.distance(this.p1, mouse.pos) - geometry.segmentLength(this)) < mouse.getClickExtent()) {
    +      const mousePos = mouse.getPosSnappedToGrid();
    +      dragContext.part = 0;
    +      dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +      dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +      dragContext.snapContext = {};
    +      return dragContext;
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    if (dragContext.part == 1) {
    +      // Dragging the center point
    +      const basePoint = dragContext.originalObj.p2;
    +
    +      this.p1 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +      this.p2 = basePoint;
    +    }
    +    if (dragContext.part == 2) {
    +      // Dragging the point on the circumference
    +      const basePoint = dragContext.originalObj.p1;
    +
    +      this.p2 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +      this.p1 = basePoint;
    +    }
    +    if (dragContext.part == 0) {
    +      // Dragging the entire circle
    +
    +      if (shift) {
    +        var mousePos = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }, { x: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y), y: -(dragContext.originalObj.p2.x - dragContext.originalObj.p1.x) }], dragContext.snapContext);
    +      } else {
    +        var mousePos = mouse.getPosSnappedToGrid();
    +        dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +      }
    +
    +      const mouseDiffX = dragContext.mousePos1.x - mousePos.x; // The X difference between the mouse position now and at the previous moment
    +      const mouseDiffY = dragContext.mousePos1.y - mousePos.y; // The Y difference between the mouse position now and at the previous moment The Y difference between the mouse position now and at the previous moment
    +      // Move the center point
    +      this.p1.x = this.p1.x - mouseDiffX;
    +      this.p1.y = this.p1.y - mouseDiffY;
    +      // Move the point on the circumference
    +      this.p2.x = this.p2.x - mouseDiffX;
    +      this.p2.y = this.p2.y - mouseDiffY;
    +      // Update the mouse position
    +      dragContext.mousePos1 = mousePos;
    +    }
    +  }
    +
    +  /**
    +   * Check if a ray intersects the circle.
    +   * In the child class, this can be called from the `checkRayIntersects` method.
    +   * @param {Ray} ray - The ray.
    +   * @returns {Point} The intersection point, or null if there is no intersection.
    +   */
    +  checkRayIntersectsShape(ray) {
    +    const rp_temp = geometry.lineCircleIntersections(geometry.line(ray.p1, ray.p2), geometry.circle(this.p1, this.p2));
    +    const rp_exist = [];
    +    const rp_lensq = [];
    +    for (let i = 1; i <= 2; i++) {
    +      rp_exist[i] = geometry.intersectionIsOnRay(rp_temp[i], ray) && geometry.distanceSquared(rp_temp[i], ray.p1) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale;
    +      rp_lensq[i] = geometry.distanceSquared(ray.p1, rp_temp[i]);
    +    }
    +
    +    if (rp_exist[1] && ((!rp_exist[2]) || rp_lensq[1] < rp_lensq[2])) {
    +      return rp_temp[1];
    +    }
    +    if (rp_exist[2] && ((!rp_exist[1]) || rp_lensq[2] < rp_lensq[1])) {
    +      return rp_temp[2];
    +    }
    +  }
    +};
    +
    +export default CircleObjMixin;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_LineObjMixin.js.html b/docs/sceneObjs_LineObjMixin.js.html new file mode 100644 index 00000000..e5ffa235 --- /dev/null +++ b/docs/sceneObjs_LineObjMixin.js.html @@ -0,0 +1,182 @@ + + + + + JSDoc: Source: sceneObjs/LineObjMixin.js + + + + + + + + + + +
    + +

    Source: sceneObjs/LineObjMixin.js

    + + + + + + +
    +
    +
    import geometry from '../geometry.js';
    +import BaseSceneObj from './BaseSceneObj.js';
    +
    +/**
    + * The mixin for the scene objects that are defined by a line segment.
    + * @template {typeof BaseSceneObj} T
    + * @param {T} Base 
    + * @returns {T}
    + */
    +const LineObjMixin = Base => class extends Base {
    +
    +  move(diffX, diffY) {
    +    // Move the first point
    +    this.p1.x = this.p1.x + diffX;
    +    this.p1.y = this.p1.y + diffY;
    +    // Move the second point
    +    this.p2.x = this.p2.x + diffX;
    +    this.p2.y = this.p2.y + diffY;
    +  }
    +  
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    if (!this.constructionPoint) {
    +      // Initialize the construction stage.
    +      this.constructionPoint = mouse.getPosSnappedToGrid();
    +      this.p1 = this.constructionPoint;
    +      this.p2 = this.constructionPoint;
    +    }
    +    if (shift) {
    +      this.p2 = mouse.getPosSnappedToDirection(this.constructionPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +    } else {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +    }
    +  }
    +
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    if (shift) {
    +      this.p2 = mouse.getPosSnappedToDirection(this.constructionPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +    } else {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +    }
    +
    +    this.p1 = ctrl ? geometry.point(2 * this.constructionPoint.x - this.p2.x, 2 * this.constructionPoint.y - this.p2.y) : this.constructionPoint;
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    if (!mouse.isOnPoint(this.p1)) {
    +      delete this.constructionPoint;
    +      return {
    +        isDone: true
    +      };
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (mouse.isOnPoint(this.p1) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p2)) {
    +      dragContext.part = 1;
    +      dragContext.targetPoint = geometry.point(this.p1.x, this.p1.y);
    +      return dragContext;
    +    }
    +    if (mouse.isOnPoint(this.p2)) {
    +      dragContext.part = 2;
    +      dragContext.targetPoint = geometry.point(this.p2.x, this.p2.y);
    +      return dragContext;
    +    }
    +    if (mouse.isOnSegment(this)) {
    +      const mousePos = mouse.getPosSnappedToGrid();
    +      dragContext.part = 0;
    +      dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +      dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +      dragContext.snapContext = {};
    +      return dragContext;
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    var basePoint;
    +    if (dragContext.part == 1) {
    +      // Dragging the first endpoint Dragging the first endpoint
    +      basePoint = ctrl ? geometry.segmentMidpoint(dragContext.originalObj) : dragContext.originalObj.p2;
    +
    +      this.p1 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +      this.p2 = ctrl ? geometry.point(2 * basePoint.x - this.p1.x, 2 * basePoint.y - this.p1.y) : basePoint;
    +    }
    +    if (dragContext.part == 2) {
    +      // Dragging the second endpoint Dragging the second endpoint
    +      basePoint = ctrl ? geometry.segmentMidpoint(dragContext.originalObj) : dragContext.originalObj.p1;
    +
    +      this.p2 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +      this.p1 = ctrl ? geometry.point(2 * basePoint.x - this.p2.x, 2 * basePoint.y - this.p2.y) : basePoint;
    +    }
    +    if (dragContext.part == 0) {
    +      // Dragging the entire line
    +
    +      if (shift) {
    +        var mousePos = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }, { x: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y), y: -(dragContext.originalObj.p2.x - dragContext.originalObj.p1.x) }], dragContext.snapContext);
    +      } else {
    +        var mousePos = mouse.getPosSnappedToGrid();
    +        dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +      }
    +
    +      var mouseDiffX = dragContext.mousePos1.x - mousePos.x; // The X difference between the mouse position now and at the previous moment
    +      var mouseDiffY = dragContext.mousePos1.y - mousePos.y; // The Y difference between the mouse position now and at the previous moment The Y difference between the mouse position now and at the previous moment
    +      // Move the first point
    +      this.p1.x = this.p1.x - mouseDiffX;
    +      this.p1.y = this.p1.y - mouseDiffY;
    +      // Move the second point
    +      this.p2.x = this.p2.x - mouseDiffX;
    +      this.p2.y = this.p2.y - mouseDiffY;
    +      // Update the mouse position
    +      dragContext.mousePos1 = mousePos;
    +    }
    +  }
    +
    +  /**
    +   * Check if a ray intersects the line segment.
    +   * In the child class, this can be called from the `checkRayIntersects` method.
    +   * @param {Ray} ray - The ray.
    +   * @returns {Point} The intersection point, or null if there is no intersection.
    +   */
    +  checkRayIntersectsShape(ray) {
    +    var rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.p1, this.p2));
    +
    +    if (geometry.intersectionIsOnSegment(rp_temp, this) && geometry.intersectionIsOnRay(rp_temp, ray)) {
    +      return rp_temp;
    +    } else {
    +      return null;
    +    }
    +  }
    +};
    +
    +export default LineObjMixin;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_blocker_Aperture.js.html b/docs/sceneObjs_blocker_Aperture.js.html new file mode 100644 index 00000000..fdc61177 --- /dev/null +++ b/docs/sceneObjs_blocker_Aperture.js.html @@ -0,0 +1,316 @@ + + + + + JSDoc: Source: sceneObjs/blocker/Aperture.js + + + + + + + + + + +
    + +

    Source: sceneObjs/blocker/Aperture.js

    + + + + + + +
    +
    +
    import BaseFilter from '../BaseFilter.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Aperture / filter with a hole.
    + * 
    + * Tools -> Blocker -> Aperture
    + * @class
    + * @extends BaseFilter
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint of the aperture.
    + * @property {Point} p2 - The second endpoint of the aperture.
    + * @property {Point} p3 - The first endpoint of the hole.
    + * @property {Point} p4 - The second endpoint of the hole.
    + * @property {boolean} filter - Whether it is a filter.
    + * @property {boolean} invert - If true, the ray with wavelength outside the bandwidth is blocked. If false, the ray with wavelength inside the bandwidth is blocked.
    + * @property {number} wavelength - The target wavelength if filter is enabled. The unit is nm.
    + * @property {number} bandwidth - The bandwidth if filter is enabled. The unit is nm.
    + */
    +class Aperture extends BaseFilter {
    +  static type = 'Aperture';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    p3: null,
    +    p4: null,
    +    filter: false,
    +    invert: false,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    bandwidth: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.Aperture.title'));
    +
    +    var originalDiameter = geometry.distance(this.p3, this.p4);
    +
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.Aperature.diameter'), 0, 100 * this.scene.lengthScale, 1 * this.scene.lengthScale, originalDiameter, function (obj, value) {
    +      var t = 0.5 * (1 - value / geometry.distance(obj.p1, obj.p2));
    +      obj.p3 = geometry.point(obj.p1.x * (1 - t) + obj.p2.x * t, obj.p1.y * (1 - t) + obj.p2.y * t);
    +      obj.p4 = geometry.point(obj.p1.x * t + obj.p2.x * (1 - t), obj.p1.y * t + obj.p2.y * (1 - t));
    +    }, i18next.t('simulator:sceneObjs.common.lengthUnitInfo'));
    +
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +    
    +    ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(70,35,10)');
    +    ctx.lineWidth = 3 * ls;
    +    ctx.lineCap = 'butt';
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p3.x, this.p3.y);
    +    ctx.stroke();
    +    ctx.beginPath();
    +    ctx.moveTo(this.p2.x, this.p2.y);
    +    ctx.lineTo(this.p4.x, this.p4.y);
    +    ctx.stroke();
    +    ctx.lineWidth = 1 * ls;
    +    if (isHovered) {
    +      ctx.fillStyle = 'magenta';
    +      ctx.fillRect(this.p3.x - 1.5 * ls, this.p3.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.p4.x - 1.5 * ls, this.p4.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  move(diffX, diffY) {
    +    this.p1.x = this.p1.x + diffX;
    +    this.p1.y = this.p1.y + diffY;
    +    this.p2.x = this.p2.x + diffX;
    +    this.p2.y = this.p2.y + diffY;
    +    this.p3.x = this.p3.x + diffX;
    +    this.p3.y = this.p3.y + diffY;
    +    this.p4.x = this.p4.x + diffX;
    +    this.p4.y = this.p4.y + diffY;
    +  }
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    if (!this.constructionPoint) {
    +      // Initialize the construction stage.
    +      this.constructionPoint = mouse.getPosSnappedToGrid();
    +      this.p1 = this.constructionPoint;
    +      this.p2 = this.constructionPoint;
    +    }
    +
    +    if (shift) {
    +      this.p2 = mouse.getPosSnappedToDirection(this.p1, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +    } else {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +    }
    +
    +    this.p3 = geometry.point(this.p1.x * 0.6 + this.p2.x * 0.4, this.p1.y * 0.6 + this.p2.y * 0.4);
    +    this.p4 = geometry.point(this.p1.x * 0.4 + this.p2.x * 0.6, this.p1.y * 0.4 + this.p2.y * 0.6);
    +  }
    +
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    if (shift) {
    +      this.p2 = mouse.getPosSnappedToDirection(this.constructionPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +    } else {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +    }
    +
    +    this.p1 = ctrl ? geometry.point(2 * this.constructionPoint.x - this.p2.x, 2 * this.constructionPoint.y - this.p2.y) : this.constructionPoint;
    +
    +    this.p3 = geometry.point(this.p1.x * 0.6 + this.p2.x * 0.4, this.p1.y * 0.6 + this.p2.y * 0.4);
    +    this.p4 = geometry.point(this.p1.x * 0.4 + this.p2.x * 0.6, this.p1.y * 0.4 + this.p2.y * 0.6);
    +
    +    return {
    +      requiresObjBarUpdate: true
    +    }
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    if (!mouse.isOnPoint(this.p1)) {
    +      delete this.constructionPoint;
    +      return {
    +        isDone: true,
    +        requiresObjBarUpdate: true
    +      };
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    if (mouse.isOnPoint(this.p1) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p2)) {
    +      return {
    +        part: 1,
    +        targetPoint: geometry.point(this.p1.x, this.p1.y)
    +      };
    +    }
    +    if (mouse.isOnPoint(this.p2)) {
    +      return {
    +        part: 2,
    +        targetPoint: geometry.point(this.p2.x, this.p2.y)
    +      };
    +    }
    +    if (mouse.isOnPoint(this.p3) && geometry.distanceSquared(mouse.pos, this.p3) <= geometry.distanceSquared(mouse.pos, this.p4)) {
    +      return {
    +        part: 3,
    +        targetPoint: geometry.point(this.p3.x, this.p3.y),
    +        requiresObjBarUpdate: true
    +      };
    +    }
    +    if (mouse.isOnPoint(this.p4)) {
    +      return {
    +        part: 4,
    +        targetPoint: geometry.point(this.p4.x, this.p4.y),
    +        requiresObjBarUpdate: true
    +      };
    +    }
    +
    +    var segment1 = geometry.line(this.p1, this.p3);
    +    var segment2 = geometry.line(this.p2, this.p4);
    +    if (mouse.isOnSegment(segment1) || mouse.isOnSegment(segment2)) {
    +      const mousePos = mouse.getPosSnappedToGrid();
    +      return {
    +        part: 0,
    +        mousePos0: mousePos,
    +        mousePos1: mousePos,
    +        snapContext: {}
    +      };
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    var basePoint;
    +
    +    var originalDiameter = geometry.distance(this.p3, this.p4);
    +    if (dragContext.part == 1 || dragContext.part == 2) {
    +      if (dragContext.part == 1) {
    +        // Dragging the first endpoint Dragging the first endpoint
    +        basePoint = ctrl ? geometry.segmentMidpoint(dragContext.originalObj) : dragContext.originalObj.p2;
    +
    +        this.p1 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +        this.p2 = ctrl ? geometry.point(2 * basePoint.x - this.p1.x, 2 * basePoint.y - this.p1.y) : basePoint;
    +      } else {
    +        // Dragging the second endpoint Dragging the second endpoint
    +        basePoint = ctrl ? geometry.segmentMidpoint(dragContext.originalObj) : dragContext.originalObj.p1;
    +
    +        this.p2 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +        this.p1 = ctrl ? geometry.point(2 * basePoint.x - this.p2.x, 2 * basePoint.y - this.p2.y) : basePoint;
    +      }
    +
    +      var t = 0.5 * (1 - originalDiameter / geometry.distance(this.p1, this.p2));
    +      this.p3 = geometry.point(this.p1.x * (1 - t) + this.p2.x * t, this.p1.y * (1 - t) + this.p2.y * t);
    +      this.p4 = geometry.point(this.p1.x * t + this.p2.x * (1 - t), this.p1.y * t + this.p2.y * (1 - t));
    +    } else if (dragContext.part == 3 || dragContext.part == 4) {
    +      if (dragContext.part == 3) {
    +        basePoint = geometry.segmentMidpoint(this);
    +
    +        this.p3 = mouse.getPosSnappedToDirection(basePoint, [{ x: (dragContext.originalObj.p4.x - dragContext.originalObj.p3.x), y: (dragContext.originalObj.p4.y - dragContext.originalObj.p3.y) }]);
    +        this.p4 = geometry.point(2 * basePoint.x - this.p3.x, 2 * basePoint.y - this.p3.y);
    +      } else {
    +        basePoint = geometry.segmentMidpoint(this);
    +
    +        this.p4 = mouse.getPosSnappedToDirection(basePoint, [{ x: (dragContext.originalObj.p4.x - dragContext.originalObj.p3.x), y: (dragContext.originalObj.p4.y - dragContext.originalObj.p3.y) }]);
    +        this.p3 = geometry.point(2 * basePoint.x - this.p4.x, 2 * basePoint.y - this.p4.y);
    +      }
    +    } else if (dragContext.part == 0) {
    +      // Dragging the entire line
    +
    +      if (shift) {
    +        var mousePos = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }, { x: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y), y: -(dragContext.originalObj.p2.x - dragContext.originalObj.p1.x) }], dragContext.snapContext);
    +      } else {
    +        var mousePos = mouse.getPosSnappedToGrid();
    +        dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +      }
    +
    +      var mouseDiffX = dragContext.mousePos1.x - mousePos.x; // The X difference between the mouse position now and at the previous moment
    +      var mouseDiffY = dragContext.mousePos1.y - mousePos.y; // The Y difference between the mouse position now and at the previous moment
    +      // Move the first point
    +      this.p1.x = this.p1.x - mouseDiffX;
    +      this.p1.y = this.p1.y - mouseDiffY;
    +      // Move the second point
    +      this.p2.x = this.p2.x - mouseDiffX;
    +      this.p2.y = this.p2.y - mouseDiffY;
    +
    +      this.p3.x = this.p3.x - mouseDiffX;
    +      this.p3.y = this.p3.y - mouseDiffY;
    +
    +      this.p4.x = this.p4.x - mouseDiffX;
    +      this.p4.y = this.p4.y - mouseDiffY;
    +
    +      // Update the mouse position
    +      dragContext.mousePos1 = mousePos;
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.checkRayIntersectFilter(ray)) {
    +      var segment1 = geometry.line(this.p1, this.p3);
    +      var segment2 = geometry.line(this.p2, this.p4);
    +
    +      var rp_temp1 = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), segment1);
    +      if (geometry.intersectionIsOnSegment(rp_temp1, segment1) && geometry.intersectionIsOnRay(rp_temp1, ray)) {
    +        return rp_temp1;
    +      }
    +
    +      var rp_temp2 = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), segment2);
    +      if (geometry.intersectionIsOnSegment(rp_temp2, segment2) && geometry.intersectionIsOnRay(rp_temp2, ray)) {
    +        return rp_temp2;
    +      }
    +    }
    +
    +    return null;
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    return {
    +      isAbsorbed: true
    +    };
    +  }
    +};
    +
    +export default Aperture;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_blocker_Blocker.js.html b/docs/sceneObjs_blocker_Blocker.js.html new file mode 100644 index 00000000..39ca3c02 --- /dev/null +++ b/docs/sceneObjs_blocker_Blocker.js.html @@ -0,0 +1,122 @@ + + + + + JSDoc: Source: sceneObjs/blocker/Blocker.js + + + + + + + + + + +
    + +

    Source: sceneObjs/blocker/Blocker.js

    + + + + + + +
    +
    +
    import BaseFilter from '../BaseFilter.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +
    +/**
    + * Line blocker / filter.
    + * 
    + * Tools -> Blocker -> Line Blocker
    + * @class
    + * @extends BaseFilter
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint.
    + * @property {Point} p2 - The second endpoint.
    + * @property {boolean} filter - Whether it is a filter.
    + * @property {boolean} invert - If true, the ray with wavelength outside the bandwidth is blocked. If false, the ray with wavelength inside the bandwidth is blocked.
    + * @property {number} wavelength - The target wavelength if filter is enabled. The unit is nm.
    + * @property {number} bandwidth - The bandwidth if filter is enabled. The unit is nm.
    + */
    +class Blocker extends LineObjMixin(BaseFilter) {
    +  static type = 'Blocker';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    filter: false,
    +    invert: false,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    bandwidth: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.Blocker.title'));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +
    +    ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(70,35,10)');
    +    ctx.lineWidth = 3 * ls;
    +    ctx.lineCap = 'butt';
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.stroke();
    +    ctx.lineWidth = 1 * ls;
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.checkRayIntersectFilter(ray)) {
    +      return this.checkRayIntersectsShape(ray);
    +    } else {
    +      return null;
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    return {
    +      isAbsorbed: true
    +    };
    +  }
    +};
    +
    +export default Blocker;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_blocker_CircleBlocker.js.html b/docs/sceneObjs_blocker_CircleBlocker.js.html new file mode 100644 index 00000000..65a0b3ec --- /dev/null +++ b/docs/sceneObjs_blocker_CircleBlocker.js.html @@ -0,0 +1,124 @@ + + + + + JSDoc: Source: sceneObjs/blocker/CircleBlocker.js + + + + + + + + + + +
    + +

    Source: sceneObjs/blocker/CircleBlocker.js

    + + + + + + +
    +
    +
    import BaseFilter from '../BaseFilter.js';
    +import CircleObjMixin from '../CircleObjMixin.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Circle blocker / filter.
    + * 
    + * Tools -> Blocker -> Circle Blocker
    + * @class
    + * @extends BaseFilter
    + * @memberof sceneObjs
    + * @property {Point} p1 - The center of the circle.
    + * @property {Point} p2 - A point on the circle.
    + * @property {boolean} filter - Whether it is a filter.
    + * @property {boolean} invert - If true, the ray with wavelength outside the bandwidth is blocked. If false, the ray with wavelength inside the bandwidth is blocked.
    + * @property {number} wavelength - The target wavelength if filter is enabled. The unit is nm.
    + * @property {number} bandwidth - The bandwidth if filter is enabled. The unit is nm.
    + */
    +class CircleBlocker extends CircleObjMixin(BaseFilter) {
    +  static type = 'CircleBlocker';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    filter: false,
    +    invert: false,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    bandwidth: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.CircleBlocker.title'));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.beginPath();
    +    ctx.arc(this.p1.x, this.p1.y, geometry.segmentLength(this), 0, Math.PI * 2);
    +    ctx.lineWidth = 3 * ls;
    +    ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(70,35,10)');
    +    //ctx.fillStyle="indigo";
    +
    +    ctx.stroke();
    +    ctx.fillStyle = 'red';
    +    ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +
    +    ctx.lineWidth = 1 * ls;
    +    if (isHovered) {
    +      ctx.fillStyle = 'magenta';
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.checkRayIntersectFilter(ray)) {
    +      return this.checkRayIntersectsShape(ray);
    +    } else {
    +      return null;
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    return {
    +      isAbsorbed: true
    +    };
    +  }
    +};
    +
    +export default CircleBlocker;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_blocker_DiffractionGrating.js.html b/docs/sceneObjs_blocker_DiffractionGrating.js.html new file mode 100644 index 00000000..2f4e0639 --- /dev/null +++ b/docs/sceneObjs_blocker_DiffractionGrating.js.html @@ -0,0 +1,230 @@ + + + + + JSDoc: Source: sceneObjs/blocker/DiffractionGrating.js + + + + + + + + + + +
    + +

    Source: sceneObjs/blocker/DiffractionGrating.js

    + + + + + + +
    +
    +
    import LineObjMixin from '../LineObjMixin.js';
    +import BaseSceneObj from '../BaseSceneObj.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Diffraction Grating
    + * 
    + * Tools -> Blocker -> Diffraction Grating
    + * 
    + * It is in the blocker category since the model we use is a blocker with slits.
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint of the line segment.
    + * @property {Point} p2 - The second endpoint of the line segment.
    + * @property {number} lineDensity - The number of lines per millimeter.
    + * @property {boolean} customBrightness - Whether the output brightness are customized.
    + * @property {number[]} brightnesses - The brightnesses of the diffracted rays for m = 0, 1, -1, 2, -2, ... when `customBrightness` is true. The number is to be normalized to the brightness of the incident ray. The values not in the array are set to 0.
    + * @property {number} slitRatio - The ratio of the slit width to the line interval.
    + * @property {boolean} mirrored - Whether the diffraction grating is reflective.
    + */
    +class DiffractionGrating extends LineObjMixin(BaseSceneObj) {
    +  static type = 'DiffractionGrating';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    lineDensity: 1000,
    +    customBrightness: false,
    +    brightnesses: [1, 0.5, 0.5],
    +    slitRatio: 0.5,
    +    mirrored: false
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.DiffractionGrating.title'));
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.DiffractionGrating.lineDensity', {lengthUnit: 'mm'}), 1, 2500, 5, this.lineDensity, function (obj, value) {
    +      obj.lineDensity = value;
    +    });
    +
    +    objBar.createBoolean(i18next.t('simulator:sceneObjs.DiffractionGrating.customBrightness'), this.customBrightness, function (obj, value) {
    +      obj.customBrightness = value;
    +    }, i18next.t('simulator:sceneObjs.DiffractionGrating.customBrightnessInfo'), true);
    +
    +    if (this.customBrightness) {
    +      objBar.createTuple('', this.brightnesses.join(', '), function (obj, value) {
    +        obj.brightnesses = value.split(',').map(parseFloat);
    +      });
    +    } else if (objBar.showAdvanced(!this.arePropertiesDefault(['slitRatio']))) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.DiffractionGrating.slitRatio'), 0, 1, 0.001, this.slitRatio, function (obj, value) {
    +        obj.slitRatio = value;
    +      });
    +    }
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['mirrored']))) {
    +      objBar.createBoolean(i18next.t('simulator:sceneObjs.DiffractionGrating.mirrored'), this.mirrored, function (obj, value) {
    +        obj.mirrored = value;
    +      });
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +    
    +    if (this.mirrored) {
    +      ctx.strokeStyle = isHovered ? 'cyan' : 'rgb(168,168,168)';
    +      ctx.beginPath();
    +      ctx.moveTo(this.p1.x, this.p1.y);
    +      ctx.lineTo(this.p2.x, this.p2.y);
    +      ctx.stroke();
    +    }
    +    ctx.strokeStyle = isHovered ? 'cyan' : 'rgb(124,62,18)';
    +    ctx.lineWidth = 2 * ls;
    +    ctx.lineCap = 'butt';
    +    ctx.beginPath();
    +    if (this.customBrightness) {
    +      ctx.setLineDash([2 * ls, 2 * ls]);
    +    } else {
    +      ctx.setLineDash([4 * (1 - this.slitRatio) * ls, 4 * this.slitRatio * ls]);
    +    }
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.stroke();
    +    ctx.setLineDash([]);
    +    ctx.lineWidth = 1 * ls;
    +  }
    +
    +  onSimulationStart() {
    +    this.warning = null;
    +    if (this.scene.mode == 'images' || this.scene.mode == 'observer') {
    +      this.warning = (this.warning || "") + i18next.t('simulator:sceneObjs.common.imageDetectionWarning');
    +    }
    +
    +    if (!this.scene.simulateColors) {
    +      this.warning = (this.warning || "") + i18next.t('simulator:sceneObjs.common.nonSimulateColorsWarning');
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    return this.checkRayIntersectsShape(ray);
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    const mm_in_nm = 1 / 1000000;
    +    var rx = ray.p1.x - incidentPoint.x;
    +    var ry = ray.p1.y - incidentPoint.y;
    +    var mx = this.p2.x - this.p1.x;
    +    var my = this.p2.y - this.p1.y;
    +
    +    var wavelength = (ray.wavelength || Simulator.GREEN_WAVELENGTH) * mm_in_nm;
    +    var interval = 1 / this.lineDensity;
    +    var slit_width = interval * this.slitRatio;
    +
    +    //Find which side the incoming ray is hitting the diffraction line segment
    +    var crossProduct = rx * my - ry * mx;
    +    var left_point = crossProduct > 0 ? this.p1 : this.p2;
    +
    +    //If mirrored, reflect the rays rather than pass them
    +    var mirror = this.mirrored ? -1 : 1;
    +
    +    //Find angles
    +    var theta_left = Math.PI - Math.atan2(left_point.y - incidentPoint.y, left_point.x - incidentPoint.x);
    +    var theta_i = Math.PI - Math.atan2(ry, rx);
    +    var incidence_angle = Math.PI / 2 - (theta_left < theta_i ? theta_left + 2 * Math.PI - theta_i : theta_left - theta_i);
    +
    +    var m_min = -Math.floor(interval / wavelength * (1 - Math.sin(incidence_angle)));
    +    var m_max = -Math.ceil(interval / wavelength * (-1 - Math.sin(incidence_angle)));
    +
    +    let newRays = [];
    +
    +    for (var m = m_min; m <= m_max; m++) {
    +      var diffracted_angle = Math.asin(Math.sin(incidence_angle) - m * wavelength / interval);
    +
    +      var rot_c = Math.cos(mirror * (-Math.PI / 2 - diffracted_angle));
    +      var rot_s = Math.sin(mirror * (-Math.PI / 2 - diffracted_angle));
    +      var diffracted_ray = geometry.line(incidentPoint, geometry.point(incidentPoint.x + (left_point.x - incidentPoint.x) * rot_c - (left_point.y - incidentPoint.y) * rot_s, incidentPoint.y + (left_point.x - incidentPoint.x) * rot_s + (left_point.y - incidentPoint.y) * rot_c));
    +
    +      // Calculate intensity
    +      if (this.customBrightness) {
    +        var intensity = this.brightnesses[m<=0 ? -2*m : 2*m-1] || 0;
    +      } else {
    +        // Treat the gratings as a blocker with slits
    +        var phase_diff = 2 * Math.PI * slit_width / wavelength * (Math.sin(incidence_angle) - Math.sin(diffracted_angle))
    +        var sinc_arg = (phase_diff == 0) ? 1 : Math.sin(phase_diff / 2) / (phase_diff / 2);
    +
    +        // This formula may not be accurate when `diffracted_angle` is large. This is warned in the popover of the tool.
    +        var intensity = slit_width * slit_width / (interval * interval) * Math.pow(sinc_arg, 2);
    +      }
    +
    +      if (intensity == 0) {
    +        continue;
    +      }
    +      
    +      diffracted_ray.wavelength = ray.wavelength;
    +      diffracted_ray.brightness_s = ray.brightness_s * intensity;
    +      diffracted_ray.brightness_p = ray.brightness_p * intensity;
    +
    +      // There is currently no good way to make image detection work here. So just set gap to true to disable image detection for the diffracted rays.
    +      diffracted_ray.gap = true;
    +
    +      newRays.push(diffracted_ray);
    +    }
    +
    +    return {
    +      isAbsorbed: true,
    +      newRays: newRays
    +    };
    +  }
    +};
    +
    +export default DiffractionGrating;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_glass_CircleGlass.js.html b/docs/sceneObjs_glass_CircleGlass.js.html new file mode 100644 index 00000000..72264650 --- /dev/null +++ b/docs/sceneObjs_glass_CircleGlass.js.html @@ -0,0 +1,141 @@ + + + + + JSDoc: Source: sceneObjs/glass/CircleGlass.js + + + + + + + + + + +
    + +

    Source: sceneObjs/glass/CircleGlass.js

    + + + + + + +
    +
    +
    import BaseGlass from '../BaseGlass.js';
    +import CircleObjMixin from '../CircleObjMixin.js';
    +import i18next from 'i18next';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Glass of the shape of a circle.
    + * 
    + * Tools -> Glass -> Circle
    + * @class
    + * @extends BaseGlass
    + * @memberof sceneObjs
    + * @property {Point} p1 - The center of the circle.
    + * @property {Point} p2 - A point on the boundary of the circle.
    + * @property {number} refIndex - The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.
    + * @property {number} cauchyB - The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.
    + */
    +class CircleGlass extends CircleObjMixin(BaseGlass) {
    +  static type = 'CircleGlass';
    +  static isOptical = true;
    +  static supportsSurfaceMerging = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    refIndex: 1.5,
    +    cauchyB: 0.004
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:meta.parentheses', { main: i18next.t('main:tools.categories.glass'), sub: i18next.t('main:tools.CircleGlass.title') }));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.beginPath();
    +    ctx.arc(this.p1.x, this.p1.y, geometry.segmentLength(this), 0, Math.PI * 2, false);
    +    this.fillGlass(canvasRenderer, isAboveLight, isHovered);
    +    ctx.lineWidth = 1;
    +    ctx.fillStyle = 'red';
    +    ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    if (isHovered) {
    +      ctx.fillStyle = 'magenta';
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.refIndex <= 0) return;
    +    return this.checkRayIntersectsShape(ray);
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) {
    +    var midpoint = geometry.segmentMidpoint(geometry.line(ray.p1, incidentPoint));
    +    var d = geometry.distanceSquared(this.p1, this.p2) - geometry.distanceSquared(this.p1, midpoint);
    +    if (d > 0) {
    +      // From inside to outside
    +      var n1 = this.getRefIndexAt(incidentPoint, ray);
    +      var normal = { x: this.p1.x - incidentPoint.x, y: this.p1.y - incidentPoint.y };
    +    } else if (d < 0) {
    +      // From outside to inside
    +      var n1 = 1 / this.getRefIndexAt(incidentPoint, ray);
    +      var normal = { x: incidentPoint.x - this.p1.x, y: incidentPoint.y - this.p1.y };
    +    } else {
    +      // Situation that may cause bugs (e.g. incident on an edge point)
    +      // To prevent shooting the ray to a wrong direction, absorb the ray
    +      return {
    +        isAbsorbed: true
    +      };
    +    }
    +
    +    return this.refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, ray.bodyMergingObj);
    +  }
    +
    +  getIncidentType(ray) {
    +    var midpoint = geometry.segmentMidpoint(geometry.line(ray.p1, this.checkRayIntersects(ray)));
    +    var d = geometry.distanceSquared(this.p1, this.p2) - geometry.distanceSquared(this.p1, midpoint);
    +    if (d > 0) {
    +      return 1; // From inside to outside
    +    }
    +    if (d < 0) {
    +      return -1; // From outside to inside
    +    }
    +    return NaN;
    +  }
    +};
    +
    +export default CircleGlass;
    +
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_glass_CircleGrinGlass.js.html b/docs/sceneObjs_glass_CircleGrinGlass.js.html new file mode 100644 index 00000000..77614421 --- /dev/null +++ b/docs/sceneObjs_glass_CircleGrinGlass.js.html @@ -0,0 +1,204 @@ + + + + + JSDoc: Source: sceneObjs/glass/CircleGrinGlass.js + + + + + + + + + + +
    + +

    Source: sceneObjs/glass/CircleGrinGlass.js

    + + + + + + +
    +
    +
    import BaseGrinGlass from '../BaseGrinGlass.js';
    +import CircleObjMixin from '../CircleObjMixin.js';
    +import i18next from 'i18next';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Gradient-index glass of the shape of a circle.
    + * 
    + * Tools -> Glass -> Gradient-index Circle
    + * @class
    + * @extends BaseGrinGlass
    + * @memberof sceneObjs
    + * @property {Point} p1 - The center of the circle.
    + * @property {Point} p2 - A point on the boundary of the circle.
    + * @property {string} refIndexFn - The refractive index function in x and y in LaTeX format.
    + * @property {Point} origin - The origin of the (x,y) coordinates used in the refractive index function.
    + * @property {number} stepSize - The step size for the ray trajectory equation.
    + * @property {number} intersectTol - The epsilon for the intersection calculations.
    + */
    +class CircleGrinGlass extends CircleObjMixin(BaseGrinGlass) {
    +  static type = 'CircleGrinGlass';
    +  static isOptical = true;
    +  static supportsSurfaceMerging = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    refIndexFn: '1+e^{-\\frac{x^2+y^2}{50^2}}',
    +    origin: { x: 0, y: 0 },
    +    stepSize: 1,
    +    intersectTol: 1e-3
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.CircleGrinGlass.title'));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.beginPath();
    +    ctx.arc(this.p1.x, this.p1.y, geometry.segmentLength(this), 0, Math.PI * 2, false);
    +    this.fillGlass(canvasRenderer, isAboveLight, isHovered);
    +    ctx.lineWidth = 1 * ls;
    +    ctx.fillStyle = 'red';
    +    ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    if (isHovered) {
    +      ctx.fillStyle = 'magenta';
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    super.onConstructMouseDown(mouse, ctrl, shift);
    +    this.origin = geometry.point(this.p1.x, this.p1.y);
    +    this.initFns();
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.notDone) { return; }
    +    if (!this.fn_p) {
    +      this.initFns();
    +    }
    +    if (this.isInsideGlass(ray.p1) || this.isOnBoundary(ray.p1)) // if the first point of the ray is inside the circle, or on its boundary
    +    {
    +      let len = geometry.distance(ray.p1, ray.p2);
    +      let x = ray.p1.x + (this.stepSize / len) * (ray.p2.x - ray.p1.x);
    +      let y = ray.p1.y + (this.stepSize / len) * (ray.p2.y - ray.p1.y);
    +      const intersection_point = geometry.point(x, y);
    +      if (this.isInsideGlass(intersection_point)) // if intersection_point is inside the circle
    +        return intersection_point;
    +    }
    +    return this.checkRayIntersectsShape(ray);
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) {
    +    if (!this.fn_p) {
    +      // This means that some error has been occuring eariler in parsing the equation.
    +      return {
    +        isAbsorbed: true
    +      };
    +    }
    +    try {
    +      this.error = null;
    +
    +      if ((this.isInsideGlass(ray.p1) || this.isOutsideGlass(ray.p1)) && this.isOnBoundary(incidentPoint)) // if the ray is hitting the circle from the outside, or from the inside (meaning that the point incidentPoint is on the boundary of the circle, and the point ray.p1 is inside/outside the circle)
    +      {
    +        let r_bodyMerging_obj = ray.bodyMergingObj; // save the current bodyMergingObj of the ray, to pass it later to the reflected ray in the 'refract' function
    +
    +        var midpoint = geometry.segmentMidpoint(geometry.line(ray.p1, incidentPoint));
    +        var d = geometry.distanceSquared(this.p1, this.p2) - geometry.distanceSquared(this.p1, midpoint);
    +        if (d > 0) {
    +          // From inside to outside
    +          var n1 = this.getRefIndexAt(incidentPoint, ray);
    +          var normal = { x: this.p1.x - incidentPoint.x, y: this.p1.y - incidentPoint.y };
    +          this.onRayExit(ray);
    +        } else if (d < 0) {
    +          // From outside to inside
    +          var n1 = 1 / this.getRefIndexAt(incidentPoint, ray);
    +          var normal = { x: incidentPoint.x - this.p1.x, y: incidentPoint.y - this.p1.y };
    +          this.onRayEnter(ray);
    +        } else {
    +          // The situation that may cause bugs (e.g. incident on an edge point)
    +          // To prevent shooting the ray to a wrong direction, absorb the ray
    +          return {
    +            isAbsorbed: true
    +          };
    +        }
    +        return this.refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, r_bodyMerging_obj);
    +      } else {
    +        if (ray.bodyMergingObj === undefined)
    +          ray.bodyMergingObj = this.initRefIndex(ray); // Initialize the bodyMerging object of the ray
    +        const next_point = this.step(ray.p1, incidentPoint, ray);
    +        ray.p1 = incidentPoint;
    +        ray.p2 = next_point;
    +      }
    +    } catch (e) {
    +      this.error = e.toString();
    +      return {
    +        isAbsorbed: true
    +      };
    +    }
    +  }
    +
    +  getIncidentType(ray) {
    +    var midpoint = geometry.segmentMidpoint(geometry.line(ray.p1, this.checkRayIntersectsShape(ray)));
    +    var d = geometry.distanceSquared(this.p1, this.p2) - geometry.distanceSquared(this.p1, midpoint);
    +    if (d > 0) {
    +      return 1; // From inside to outside
    +    }
    +    if (d < 0) {
    +      return -1; // From outside to inside
    +    }
    +    return NaN;
    +  }
    +
    +  isOutsideGlass(point) {
    +    const R_squared = geometry.distanceSquared(this.p1, this.p2);
    +    return (geometry.distanceSquared(this.p1, point) - R_squared - this.intersectTol > 0 && geometry.distanceSquared(this.p1, point) - R_squared + this.intersectTol > 0);
    +  }
    +
    +  isInsideGlass(point) {
    +    const R_squared = geometry.distanceSquared(this.p1, this.p2);
    +    return (geometry.distanceSquared(this.p1, point) - R_squared - this.intersectTol < 0 && geometry.distanceSquared(this.p1, point) - R_squared + this.intersectTol < 0);
    +  }
    +
    +  isOnBoundary(point) {
    +    const R_squared = geometry.distanceSquared(this.p1, this.p2);
    +    return (geometry.distanceSquared(this.p1, point) - R_squared - this.intersectTol < 0 && geometry.distanceSquared(this.p1, point) - R_squared + this.intersectTol > 0);
    +  }
    +};
    +
    +export default CircleGrinGlass;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_glass_CustomGlass.js.html b/docs/sceneObjs_glass_CustomGlass.js.html new file mode 100644 index 00000000..837ab40a --- /dev/null +++ b/docs/sceneObjs_glass_CustomGlass.js.html @@ -0,0 +1,354 @@ + + + + + JSDoc: Source: sceneObjs/glass/CustomGlass.js + + + + + + + + + + +
    + +

    Source: sceneObjs/glass/CustomGlass.js

    + + + + + + +
    +
    +
    import BaseGlass from '../BaseGlass.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +import { evaluateLatex } from '../../equation.js';
    +
    +/**
    + * Glass defined by a custom inequality.
    + * 
    + * Tools -> Glass -> Custom equation
    + * @class
    + * @extends BaseGlass
    + * @memberof sceneObjs
    + * @property {Point} p1 - The point corresponding to (-1,0) in the coordinate system of the equation.
    + * @property {Point} p2 - The point corresponding to (1,0) in the coordinate system of the equation.
    + * @property {string} eqn1 - The equation of the surface with smaller y. The variable is x.
    + * @property {string} eqn2 - The equation of the surface with larger y. The variable is x.
    + * @property {number} refIndex - The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.
    + * @property {number} cauchyB - The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.
    + * @property {Array<Point>} path - The points on the calculated curve.
    + * @property {number} tmp_i - The index of the point on the curve where the ray is incident.
    + */
    +class CustomGlass extends LineObjMixin(BaseGlass) {
    +  static type = 'CustomGlass';
    +  static isOptical = true;
    +  static supportsSurfaceMerging = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    eqn1: "0",
    +    eqn2: "0.5\\cdot\\sqrt{1-x^2}",
    +    refIndex: 1.5,
    +    cauchyB: 0.004
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.categories.glass'));
    +    objBar.createEquation('', this.eqn1, function (obj, value) {
    +      obj.eqn1 = value;
    +    }, '<ul><li>' + i18next.t('simulator:sceneObjs.common.eqnInfo.constants') + '<br><code>pi e</code></li><li>' + i18next.t('simulator:sceneObjs.common.eqnInfo.operators') + '<br><code>+ - * / ^</code></li><li>' + i18next.t('simulator:sceneObjs.common.eqnInfo.functions') + '<br><code>sqrt sin cos tan sec csc cot sinh cosh tanh log exp arcsin arccos arctan arcsinh arccosh arctanh floor round ceil trunc sgn max min abs</code></li></ul>');
    +    objBar.createEquation(' < y < ', this.eqn2, function (obj, value) {
    +      obj.eqn2 = value;
    +    });
    +
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +    
    +    if (isAboveLight) {
    +      if (this.path) {
    +        this.drawGlass(canvasRenderer, isAboveLight, isHovered);
    +      }
    +      return;
    +    }
    +
    +    var fns;
    +    try {
    +      fns = [evaluateLatex(this.eqn1), evaluateLatex(this.eqn2)];
    +    } catch (e) {
    +      delete this.path;
    +      ctx.fillStyle = "red"
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      this.error = e.toString();
    +      return;
    +    }
    +
    +    this.path = [{ x: this.p1.x, y: this.p1.y }];
    +    for (var side = 0; side <= 1; side++) {
    +      var p1 = (side == 0) ? this.p1 : this.p2;
    +      var p2 = (side == 0) ? this.p2 : this.p1;
    +      var p12d = geometry.distance(p1, p2);
    +      var dir1 = [(p2.x - p1.x) / p12d, (p2.y - p1.y) / p12d];
    +      var dir2 = [dir1[1], -dir1[0]];
    +      var x0 = p12d / 2;
    +      var i;
    +      var lastError = "";
    +      var hasPoints = false;
    +      for (i = -0.1 * this.scene.lengthScale; i < p12d + 0.09 * this.scene.lengthScale; i += 0.1 * this.scene.lengthScale) {
    +        var ix = i + 0.05 * this.scene.lengthScale;
    +        if (ix < 0) ix = 0;
    +        if (ix > p12d) ix = p12d;
    +        var x = ix - x0;
    +        var scaled_x = 2 * x / p12d;
    +        var scaled_y;
    +        try {
    +          scaled_y = ((side == 0) ? 1 : (-1)) * fns[side]({ x: ((side == 0) ? scaled_x : (-scaled_x)) });
    +          if (side == 1 && -scaled_y < fns[0]({ x: -scaled_x })) {
    +            lastError = "Curve generation error: f(x) > g(x) at x = " + (-scaled_x);
    +          }
    +          var y = scaled_y * p12d * 0.5;
    +          var pt = geometry.point(p1.x + dir1[0] * ix + dir2[0] * y, p1.y + dir1[1] * ix + dir2[1] * y);
    +          this.path.push(pt);
    +          hasPoints = true;
    +        } catch (e) {
    +          lastError = e;
    +        }
    +      }
    +      if (!hasPoints || lastError.startsWith("Curve generation error:")) {
    +        delete this.path;
    +        ctx.fillStyle = "red"
    +        ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +        ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +        this.error = lastError.toString();
    +        return;
    +      }
    +    }
    +
    +    if (isHovered) {
    +      ctx.fillStyle = 'rgb(255,0,0)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +
    +    this.drawGlass(canvasRenderer, isAboveLight, isHovered);
    +
    +    this.error = null;
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (mouse.isOnPoint(this.p1) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p2)) {
    +      dragContext.part = 1;
    +      dragContext.targetPoint = geometry.point(this.p1.x, this.p1.y);
    +      return dragContext;
    +    }
    +    if (mouse.isOnPoint(this.p2)) {
    +      dragContext.part = 2;
    +      dragContext.targetPoint = geometry.point(this.p2.x, this.p2.y);
    +      return dragContext;
    +    }
    +
    +    if (!this.path) return false;
    +    for (let i = 0; i < this.path.length - 1; i++) {
    +      if (mouse.isOnSegment(geometry.line(this.path[i], this.path[(i+1)%this.path.length]))) {
    +        const mousePos = mouse.getPosSnappedToGrid();
    +        dragContext.part = 0;
    +        dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +        dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +        dragContext.snapContext = {};
    +        return dragContext;
    +      }
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (!this.path) return;
    +    if (this.refIndex <= 0) return;
    +
    +    var s_lensq = Infinity;
    +    var s_lensq_temp;
    +    var s_point = null;
    +    var s_point_temp = null;
    +    var s_point_index = -1;
    +    var rp_exist = [];
    +    var rp_lensq = [];
    +    var rp_temp;
    +
    +    var p1;
    +    var p2;
    +    var p3;
    +    var center;
    +    var r;
    +
    +    for (var i = 0; i < this.path.length; i++) {
    +      s_point_temp = null;
    +      //Line segment i->i+1
    +      var rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length]));
    +
    +      if (geometry.intersectionIsOnSegment(rp_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length])) && geometry.intersectionIsOnRay(rp_temp, ray) && geometry.distanceSquared(ray.p1, rp_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +        s_lensq_temp = geometry.distanceSquared(ray.p1, rp_temp);
    +        s_point_temp = rp_temp;
    +      }
    +
    +      if (s_point_temp) {
    +        if (s_point && geometry.distanceSquared(s_point_temp, s_point) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale && s_point_index != i - 1) {
    +          // The ray shots on a point where the upper and the lower surfaces overlap.
    +          return;
    +        } else if (s_lensq_temp < s_lensq) {
    +          s_lensq = s_lensq_temp;
    +          s_point = s_point_temp;
    +          s_point_index = i;
    +        }
    +      }
    +    }
    +    if (s_point) {
    +      this.tmp_i = s_point_index;
    +      return s_point;
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) {
    +    var incidentData = this.getIncidentData(ray);
    +    var incidentType = incidentData.incidentType;
    +    if (incidentType == 1) {
    +      // From inside to outside
    +      var n1 = this.getRefIndexAt(incidentPoint, ray);
    +    } else if (incidentType == -1) {
    +      // From outside to inside
    +      var n1 = 1 / this.getRefIndexAt(incidentPoint, ray);
    +    } else if (incidentType == 0) {
    +      // Equivalent to not intersecting with the object (e.g. two interfaces overlap)
    +      var n1 = 1;
    +    } else {
    +      // The situation that may cause bugs (e.g. incident on an edge point)
    +      // To prevent shooting the ray to a wrong direction, absorb the ray
    +      return {
    +        isAbsorbed: true
    +      };
    +    }
    +
    +    return this.refract(ray, rayIndex, incidentPoint, incidentData.normal, n1, surfaceMergingObjs, ray.bodyMergingthis);
    +  }
    +
    +  getIncidentData(ray) {
    +    var i = this.tmp_i;
    +    var pts = this.path;
    +
    +    var s_point = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length]));
    +    var incidentPoint = s_point;
    +
    +    var s_lensq = geometry.distanceSquared(ray.p1, s_point);
    +
    +    var rdots = (ray.p2.x - ray.p1.x) * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) + (ray.p2.y - ray.p1.y) * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y);
    +    var rcrosss = (ray.p2.x - ray.p1.x) * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y) - (ray.p2.y - ray.p1.y) * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x);
    +    var ssq = (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) + (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y) * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y);
    +
    +    var normal_x = rdots * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) - ssq * (ray.p2.x - ray.p1.x);
    +    var normal_y = rdots * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y) - ssq * (ray.p2.y - ray.p1.y);
    +
    +    if (rcrosss < 0) {
    +      var incidentType = 1; // From inside to outside
    +    } else {
    +      var incidentType = -1; // From outside to inside
    +    }
    +
    +    // Use a simple trick to smooth out the normal vector so that image detection works.
    +    // However, a more proper numerical algorithm from the beginning (especially to handle singularities) is still desired.
    +
    +    var seg = geometry.line(pts[i % pts.length], pts[(i + 1) % pts.length]);
    +    var rx = ray.p1.x - incidentPoint.x;
    +    var ry = ray.p1.y - incidentPoint.y;
    +    var mx = seg.p2.x - seg.p1.x;
    +    var my = seg.p2.y - seg.p1.y;
    +
    +    var frac;
    +    if (Math.abs(mx) > Math.abs(my)) {
    +      frac = (incidentPoint.x - seg.p1.x) / mx;
    +    } else {
    +      frac = (incidentPoint.y - seg.p1.y) / my;
    +    }
    +
    +    var segA;
    +    if (frac < 0.5) {
    +      segA = geometry.line(pts[(i - 1 + pts.length) % pts.length], pts[i % pts.length]);
    +    } else {
    +      segA = geometry.line(pts[(i + 1) % pts.length], pts[(i + 2) % pts.length]);
    +    }
    +
    +    var rdotsA = (ray.p2.x - ray.p1.x) * (segA.p2.x - segA.p1.x) + (ray.p2.y - ray.p1.y) * (segA.p2.y - segA.p1.y);
    +    var ssqA = (segA.p2.x - segA.p1.x) * (segA.p2.x - segA.p1.x) + (segA.p2.y - segA.p1.y) * (segA.p2.y - segA.p1.y);
    +
    +    var normal_xA = rdotsA * (segA.p2.x - segA.p1.x) - ssqA * (ray.p2.x - ray.p1.x);
    +    var normal_yA = rdotsA * (segA.p2.y - segA.p1.y) - ssqA * (ray.p2.y - ray.p1.y);
    +
    +    var normal_xFinal;
    +    var normal_yFinal;
    +
    +    if (frac < 0.5) {
    +      normal_xFinal = normal_x * (0.5 + frac) + normal_xA * (0.5 - frac);
    +      normal_yFinal = normal_y * (0.5 + frac) + normal_yA * (0.5 - frac);
    +    } else {
    +      normal_xFinal = normal_xA * (frac - 0.5) + normal_x * (1.5 - frac);
    +      normal_yFinal = normal_yA * (frac - 0.5) + normal_y * (1.5 - frac);
    +    }
    +
    +    return { s_point: s_point, normal: { x: normal_xFinal, y: normal_yFinal }, incidentType: incidentType };
    +  }
    +  
    +
    +  /* Utility methods */
    +
    +  drawGlass(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    ctx.beginPath();
    +    ctx.moveTo(this.path[0].x, this.path[0].y);
    +    for (var i = 1; i < this.path.length; i++) {
    +      ctx.lineTo(this.path[i].x, this.path[i].y);
    +    }
    +    this.fillGlass(canvasRenderer, isAboveLight, isHovered);
    +  }
    +};
    +
    +export default CustomGlass;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_glass_Glass.js.html b/docs/sceneObjs_glass_Glass.js.html new file mode 100644 index 00000000..0e743c15 --- /dev/null +++ b/docs/sceneObjs_glass_Glass.js.html @@ -0,0 +1,638 @@ + + + + + JSDoc: Source: sceneObjs/glass/Glass.js + + + + + + + + + + +
    + +

    Source: sceneObjs/glass/Glass.js

    + + + + + + +
    +
    +
    import BaseGlass from '../BaseGlass.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Glass of the shape consists of line segments or circular arcs.
    + * 
    + * Tools -> Glass -> Polygon / Circular Arcs
    + * @class
    + * @extends BaseGlass
    + * @memberof sceneObjs
    + * @property {Array<object>} path - The path of the glass. Each element is an object with `x` and `y` properties for coordinates, and a boolean `arc`. If `path[i].arc === false`, it means that `path[i-1]`--`path[i]` and `path[i]`--`path[i+1]` are line segments, if `path[i].arc === true`, it means that `path[i-1]`--`path[i]`--`path[i+1]` is a circular arc.
    + * @property {boolean} notDone - Whether the user is still drawing the glass.
    + * @property {number} refIndex - The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.
    + * @property {number} cauchyB - The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.
    + */
    +class Glass extends BaseGlass {
    +  static type = 'Glass';
    +  static isOptical = true;
    +  static supportsSurfaceMerging = true;
    +  static serializableDefaults = {
    +    path: [],
    +    notDone: false,
    +    refIndex: 1.5,
    +    cauchyB: 0.004
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.categories.glass'));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    var p1;
    +    var p2;
    +    var p3;
    +    var center;
    +    var r;
    +    var a1;
    +    var a2;
    +    var a3;
    +    var acw;
    +
    +    if (this.notDone) {
    +      // The user has not finish drawing the object yet
    +
    +      if (this.path.length === 2 && this.path[0].x === this.path[1].x && this.path[0].y === this.path[1].y) {
    +        ctx.fillStyle = 'rgb(255,0,0)';
    +        ctx.fillRect(this.path[0].x - 1.5 * ls, this.path[0].y - 1.5 * ls, 3 * ls, 3 * ls);
    +        return;
    +      }
    +      ctx.beginPath();
    +      ctx.moveTo(this.path[0].x, this.path[0].y);
    +
    +      for (var i = 0; i < this.path.length - 1; i++) {
    +        if (this.path[(i + 1)].arc && !this.path[i].arc && i < this.path.length - 2) {
    +          p1 = geometry.point(this.path[i].x, this.path[i].y);
    +          p2 = geometry.point(this.path[(i + 2)].x, this.path[(i + 2)].y);
    +          p3 = geometry.point(this.path[(i + 1)].x, this.path[(i + 1)].y);
    +          center = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(p1, p3)), geometry.perpendicularBisector(geometry.line(p2, p3)));
    +          if (isFinite(center.x) && isFinite(center.y)) {
    +            r = geometry.distance(center, p3);
    +            a1 = Math.atan2(p1.y - center.y, p1.x - center.x);
    +            a2 = Math.atan2(p2.y - center.y, p2.x - center.x);
    +            a3 = Math.atan2(p3.y - center.y, p3.x - center.x);
    +            acw = (a2 < a3 && a3 < a1) || (a1 < a2 && a2 < a3) || (a3 < a1 && a1 < a2); // The rotation direction of p1->p3->p2. True indicates counterclockwise
    +
    +            ctx.arc(center.x, center.y, r, a1, a2, acw);
    +          } else {
    +            // The three points on the arc is colinear. Treat as a line segment.
    +            ctx.lineTo(this.path[(i + 2)].x, this.path[(i + 2)].y);
    +          }
    +        } else {
    +          ctx.lineTo(this.path[(i + 1)].x, this.path[(i + 1)].y);
    +        }
    +      }
    +      ctx.globalAlpha = 1;
    +      ctx.strokeStyle = 'rgb(128,128,128)';
    +      ctx.lineWidth = 1 * ls;
    +      ctx.stroke();
    +    } else {
    +      // The user has completed drawing the object
    +      ctx.beginPath();
    +      ctx.moveTo(this.path[0].x, this.path[0].y);
    +
    +      for (var i = 0; i < this.path.length; i++) {
    +        if (this.path[(i + 1) % this.path.length].arc && !this.path[i % this.path.length].arc) {
    +          p1 = geometry.point(this.path[i % this.path.length].x, this.path[i % this.path.length].y);
    +          p2 = geometry.point(this.path[(i + 2) % this.path.length].x, this.path[(i + 2) % this.path.length].y);
    +          p3 = geometry.point(this.path[(i + 1) % this.path.length].x, this.path[(i + 1) % this.path.length].y);
    +          center = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(p1, p3)), geometry.perpendicularBisector(geometry.line(p2, p3)));
    +          if (isFinite(center.x) && isFinite(center.y)) {
    +            r = geometry.distance(center, p3);
    +            a1 = Math.atan2(p1.y - center.y, p1.x - center.x);
    +            a2 = Math.atan2(p2.y - center.y, p2.x - center.x);
    +            a3 = Math.atan2(p3.y - center.y, p3.x - center.x);
    +            acw = (a2 < a3 && a3 < a1) || (a1 < a2 && a2 < a3) || (a3 < a1 && a1 < a2); // The rotation direction of p1->p3->p2. True indicates counterclockwise
    +
    +            ctx.arc(center.x, center.y, r, a1, a2, acw);
    +          } else {
    +            // The three points on the arc is colinear. Treat as a line segment.
    +            ctx.lineTo(this.path[(i + 2) % this.path.length].x, this.path[(i + 2) % this.path.length].y);
    +          }
    +        } else if (!this.path[(i + 1) % this.path.length].arc && !this.path[i % this.path.length].arc) {
    +          ctx.lineTo(this.path[(i + 1) % this.path.length].x, this.path[(i + 1) % this.path.length].y);
    +        }
    +      }
    +      this.fillGlass(canvasRenderer, isAboveLight, isHovered);
    +    }
    +    ctx.lineWidth = 1;
    +
    +    if (isHovered) {
    +      for (var i = 0; i < this.path.length; i++) {
    +        if (typeof this.path[i].arc != 'undefined') {
    +          if (this.path[i].arc) {
    +            ctx.fillStyle = 'rgb(255,0,255)';
    +            ctx.fillRect(this.path[i].x - 1.5 * ls, this.path[i].y - 1.5 * ls, 3 * ls, 3 * ls);
    +          } else {
    +            ctx.fillStyle = 'rgb(255,0,0)';
    +            ctx.fillRect(this.path[i].x - 1.5 * ls, this.path[i].y - 1.5 * ls, 3 * ls, 3 * ls);
    +          }
    +        }
    +      }
    +    }
    +  }
    +
    +  move(diffX, diffY) {
    +    for (var i = 0; i < this.path.length; i++) {
    +      this.path[i].x += diffX;
    +      this.path[i].y += diffY;
    +    }
    +  }
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    if (!this.notDone) {
    +      // Initialize the construction stage
    +      this.notDone = true;
    +      this.path = [{ x: mousePos.x, y: mousePos.y, arc: false }];
    +    }
    +
    +    if (this.path.length > 1) {
    +      if (this.path.length > 3 && mouse.isOnPoint(this.path[0])) {
    +        // Clicked the first point
    +        this.path.length--;
    +        this.notDone = false;
    +        return;
    +      }
    +      this.path[this.path.length - 1] = { x: mousePos.x, y: mousePos.y }; // Move the last point
    +      this.path[this.path.length - 1].arc = true;
    +    }
    +  }
    +
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    if (!this.notDone) { return; }
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    if (typeof this.path[this.path.length - 1].arc != 'undefined') {
    +      if (this.path[this.path.length - 1].arc && Math.sqrt(Math.pow(this.path[this.path.length - 1].x - mousePos.x, 2) + Math.pow(this.path[this.path.length - 1].y - mousePos.y, 2)) >= 5 * this.scene.lengthScale) {
    +        this.path[this.path.length] = mousePos;
    +      }
    +    } else {
    +      this.path[this.path.length - 1] = { x: mousePos.x, y: mousePos.y }; // Move the last point
    +    }
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    if (!this.notDone) {
    +      return {
    +        isDone: true
    +      };
    +    }
    +    if (this.path.length > 3 && mouse.isOnPoint(this.path[0])) {
    +      // Mouse released at the first point
    +      this.path.length--;
    +      this.notDone = false;
    +      return {
    +        isDone: true
    +      };
    +    }
    +    if (this.path[this.path.length - 2] && !this.path[this.path.length - 2].arc && mouse.isOnPoint(this.path[this.path.length - 2])) {
    +      delete this.path[this.path.length - 1].arc;
    +    } else {
    +      const mousePos = mouse.getPosSnappedToGrid();
    +      this.path[this.path.length - 1] = { x: mousePos.x, y: mousePos.y }; // Move the last point
    +      this.path[this.path.length - 1].arc = false;
    +      this.path[this.path.length] = { x: mousePos.x, y: mousePos.y }; // Create a new point
    +    }
    +  }
    +
    +  onConstructUndo() {
    +    if (this.path.length <= 2) {
    +      return {
    +        isCancelled: true
    +      };
    +    } else {
    +      this.path.pop();
    +      if (this.path[this.path.length - 2].arc) {
    +        this.path.pop();
    +      }
    +      delete this.path[this.path.length - 1].arc
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +
    +    var p1;
    +    var p2;
    +    var p3;
    +    var center;
    +    var r;
    +    var a1;
    +    var a2;
    +    var a3;
    +
    +
    +    var click_lensq = Infinity;
    +    var click_lensq_temp;
    +    var targetPoint_index = -1;
    +    for (var i = 0; i < this.path.length; i++) {
    +      if (mouse.isOnPoint(this.path[i])) {
    +        click_lensq_temp = geometry.distanceSquared(mouse.pos, this.path[i]);
    +        if (click_lensq_temp <= click_lensq) {
    +          click_lensq = click_lensq_temp;
    +          targetPoint_index = i;
    +        }
    +      }
    +    }
    +    if (targetPoint_index != -1) {
    +      dragContext.part = 1;
    +      dragContext.index = targetPoint_index;
    +      dragContext.targetPoint = geometry.point(this.path[targetPoint_index].x, this.path[targetPoint_index].y);
    +      return dragContext;
    +    }
    +
    +    for (var i = 0; i < this.path.length; i++) {
    +      if (this.path[(i + 1) % this.path.length].arc && !this.path[i % this.path.length].arc) {
    +        p1 = geometry.point(this.path[i % this.path.length].x, this.path[i % this.path.length].y);
    +        p2 = geometry.point(this.path[(i + 2) % this.path.length].x, this.path[(i + 2) % this.path.length].y);
    +        p3 = geometry.point(this.path[(i + 1) % this.path.length].x, this.path[(i + 1) % this.path.length].y);
    +        center = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(p1, p3)), geometry.perpendicularBisector(geometry.line(p2, p3)));
    +        if (isFinite(center.x) && isFinite(center.y)) {
    +          r = geometry.distance(center, p3);
    +          a1 = Math.atan2(p1.y - center.y, p1.x - center.x);
    +          a2 = Math.atan2(p2.y - center.y, p2.x - center.x);
    +          a3 = Math.atan2(p3.y - center.y, p3.x - center.x);
    +          var a_m = Math.atan2(mouse.pos.y - center.y, mouse.pos.x - center.x);
    +          if (Math.abs(geometry.distance(center, mouse.pos) - r) < mouse.getClickExtent() && (((a2 < a3 && a3 < a1) || (a1 < a2 && a2 < a3) || (a3 < a1 && a1 < a2)) == ((a2 < a_m && a_m < a1) || (a1 < a2 && a2 < a_m) || (a_m < a1 && a1 < a2)))) {
    +            // Dragging the entire this
    +            const mousePos = mouse.getPosSnappedToGrid();
    +            dragContext.part = 0;
    +            dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +            dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +            dragContext.snapContext = {};
    +            return dragContext;
    +          }
    +        } else {
    +          // The three points on the arc is colinear. Treat as a line segment.
    +          if (mouse.isOnSegment(geometry.line(this.path[(i) % this.path.length], this.path[(i + 2) % this.path.length]))) {
    +            // Dragging the entire this
    +            const mousePos = mouse.getPosSnappedToGrid();
    +            dragContext.part = 0;
    +            dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +            dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +            dragContext.snapContext = {};
    +            return dragContext;
    +          }
    +        }
    +      } else if (!this.path[(i + 1) % this.path.length].arc && !this.path[i % this.path.length].arc) {
    +        if (mouse.isOnSegment(geometry.line(this.path[(i) % this.path.length], this.path[(i + 1) % this.path.length]))) {
    +          // Dragging the entire this
    +          const mousePos = mouse.getPosSnappedToGrid();
    +          dragContext.part = 0;
    +          dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +          dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +          dragContext.snapContext = {};
    +          return dragContext;
    +        }
    +      }
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +
    +    if (dragContext.part == 1) {
    +      this.path[dragContext.index].x = mousePos.x;
    +      this.path[dragContext.index].y = mousePos.y;
    +    }
    +
    +    if (dragContext.part == 0) {
    +      if (shift) {
    +        var mousePosSnapped = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }], dragContext.snapContext);
    +      } else {
    +        var mousePosSnapped = mouse.getPosSnappedToGrid();
    +        dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +      }
    +      this.move(mousePosSnapped.x - dragContext.mousePos1.x, mousePosSnapped.y - dragContext.mousePos1.y);
    +      dragContext.mousePos1 = mousePosSnapped;
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.notDone || this.refIndex <= 0) return;
    +
    +    var s_lensq = Infinity;
    +    var s_lensq_temp;
    +    var s_point = null;
    +    var s_point_temp = null;
    +    var rp_exist = [];
    +    var rp_lensq = [];
    +    var rp_temp;
    +
    +    var p1;
    +    var p2;
    +    var p3;
    +    var center;
    +    var r;
    +
    +    for (var i = 0; i < this.path.length; i++) {
    +      s_point_temp = null;
    +      if (this.path[(i + 1) % this.path.length].arc && !this.path[i % this.path.length].arc) {
    +        // The arc i->i+1->i+2
    +        p1 = geometry.point(this.path[i % this.path.length].x, this.path[i % this.path.length].y);
    +        p2 = geometry.point(this.path[(i + 2) % this.path.length].x, this.path[(i + 2) % this.path.length].y);
    +        p3 = geometry.point(this.path[(i + 1) % this.path.length].x, this.path[(i + 1) % this.path.length].y);
    +        center = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(p1, p3)), geometry.perpendicularBisector(geometry.line(p2, p3)));
    +        if (isFinite(center.x) && isFinite(center.y)) {
    +          r = geometry.distance(center, p3);
    +          rp_temp = geometry.lineCircleIntersections(geometry.line(ray.p1, ray.p2), geometry.circle(center, p2));
    +          for (var ii = 1; ii <= 2; ii++) {
    +            rp_exist[ii] = !geometry.intersectionIsOnSegment(geometry.linesIntersection(geometry.line(p1, p2), geometry.line(p3, rp_temp[ii])), geometry.line(p3, rp_temp[ii])) && geometry.intersectionIsOnRay(rp_temp[ii], ray) && geometry.distanceSquared(rp_temp[ii], ray.p1) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale;
    +            rp_lensq[ii] = geometry.distanceSquared(ray.p1, rp_temp[ii]);
    +          }
    +          if (rp_exist[1] && ((!rp_exist[2]) || rp_lensq[1] < rp_lensq[2]) && rp_lensq[1] > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +            s_point_temp = rp_temp[1];
    +            s_lensq_temp = rp_lensq[1];
    +          }
    +          if (rp_exist[2] && ((!rp_exist[1]) || rp_lensq[2] < rp_lensq[1]) && rp_lensq[2] > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +            s_point_temp = rp_temp[2];
    +            s_lensq_temp = rp_lensq[2];
    +          }
    +        } else {
    +          // The three points on the arc is colinear. Treat as a line segment.
    +          var rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 2) % this.path.length]));
    +
    +          if (geometry.intersectionIsOnSegment(rp_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 2) % this.path.length])) && geometry.intersectionIsOnRay(rp_temp, ray) && geometry.distanceSquared(ray.p1, rp_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +            s_lensq_temp = geometry.distanceSquared(ray.p1, rp_temp);
    +            s_point_temp = rp_temp;
    +          }
    +        }
    +      } else if (!this.path[(i + 1) % this.path.length].arc && !this.path[i % this.path.length].arc) {
    +        //Line segment i->i+1
    +        var rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length]));
    +
    +        if (geometry.intersectionIsOnSegment(rp_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length])) && geometry.intersectionIsOnRay(rp_temp, ray) && geometry.distanceSquared(ray.p1, rp_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +          s_lensq_temp = geometry.distanceSquared(ray.p1, rp_temp);
    +          s_point_temp = rp_temp;
    +        }
    +      }
    +      if (s_point_temp) {
    +        if (s_lensq_temp < s_lensq) {
    +          s_lensq = s_lensq_temp;
    +          s_point = s_point_temp;
    +        }
    +      }
    +    }
    +    if (s_point) {
    +      return s_point;
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) {
    +    if (this.notDone) { return; }
    +
    +    var incidentData = this.getIncidentData(ray);
    +    var incidentType = incidentData.incidentType;
    +    if (incidentType == 1) {
    +      // From inside to outside
    +      var n1 = this.getRefIndexAt(incidentPoint, ray);
    +    } else if (incidentType == -1) {
    +      // From outside to inside
    +      var n1 = 1 / this.getRefIndexAt(incidentPoint, ray);
    +    } else if (incidentType == 0) {
    +      // Equivalent to not intersecting with the object (e.g. two interfaces overlap)
    +      var n1 = 1;
    +    } else {
    +      // The situation that may cause bugs (e.g. incident on an edge point)
    +      // To prevent shooting the ray to a wrong direction, absorb the ray
    +      return {
    +        isAbsorbed: true
    +      };
    +    }
    +
    +    return this.refract(ray, rayIndex, incidentPoint, incidentData.normal, n1, surfaceMergingObjs, ray.bodyMergingthis);
    +  }
    +
    +  getIncidentType(ray) {
    +    return this.getIncidentData(ray).incidentType;
    +  }
    +
    +
    +  /* Utility function */
    +
    +  getIncidentData(ray) {
    +    var s_lensq = Infinity;
    +    var s_lensq_temp;
    +    var s_point = null;
    +    var s_point_temp = null;
    +    var s_point_index;
    +
    +    var surfaceMultiplicity = 1; // How many time the surfaces coincide
    +
    +    var rp_on_ray = [];
    +    var rp_exist = [];
    +    var rp_lensq = [];
    +    var rp_temp;
    +
    +    var rp2_exist = [];
    +    var rp2_lensq = [];
    +    var rp2_temp;
    +
    +    var normal_x;
    +    var normal_x_temp;
    +
    +    var normal_y;
    +    var normal_y_temp;
    +
    +    var rdots;
    +    var ssq;
    +
    +    var nearEdge = false;
    +    var nearEdge_temp = false;
    +
    +    var p1;
    +    var p2;
    +    var p3;
    +    var center;
    +    var ray2 = geometry.line(ray.p1, geometry.point(ray.p2.x + this.scene.rng() * 1e-5, ray.p2.y + this.scene.rng() * 1e-5)); // The ray to test the inside/outside (the test ray)
    +    var ray_intersect_count = 0; // The intersection count (odd means from outside)
    +
    +    for (var i = 0; i < this.path.length; i++) {
    +      s_point_temp = null;
    +      nearEdge_temp = false;
    +      if (this.path[(i + 1) % this.path.length].arc && !this.path[i % this.path.length].arc) {
    +        // The arc i->i+1->i+2
    +        p1 = geometry.point(this.path[i % this.path.length].x, this.path[i % this.path.length].y);
    +        p2 = geometry.point(this.path[(i + 2) % this.path.length].x, this.path[(i + 2) % this.path.length].y);
    +        p3 = geometry.point(this.path[(i + 1) % this.path.length].x, this.path[(i + 1) % this.path.length].y);
    +        center = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(p1, p3)), geometry.perpendicularBisector(geometry.line(p2, p3)));
    +        if (isFinite(center.x) && isFinite(center.y)) {
    +          rp_temp = geometry.lineCircleIntersections(geometry.line(ray.p1, ray.p2), geometry.circle(center, p2));
    +          rp2_temp = geometry.lineCircleIntersections(geometry.line(ray2.p1, ray2.p2), geometry.circle(center, p2));
    +          for (var ii = 1; ii <= 2; ii++) {
    +            rp_on_ray[ii] = geometry.intersectionIsOnRay(rp_temp[ii], ray);
    +            rp_exist[ii] = rp_on_ray[ii] && !geometry.intersectionIsOnSegment(geometry.linesIntersection(geometry.line(p1, p2), geometry.line(p3, rp_temp[ii])), geometry.line(p3, rp_temp[ii])) && geometry.distanceSquared(rp_temp[ii], ray.p1) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale;
    +            rp_lensq[ii] = geometry.distanceSquared(ray.p1, rp_temp[ii]);
    +
    +            rp2_exist[ii] = !geometry.intersectionIsOnSegment(geometry.linesIntersection(geometry.line(p1, p2), geometry.line(p3, rp2_temp[ii])), geometry.line(p3, rp2_temp[ii])) && geometry.intersectionIsOnRay(rp2_temp[ii], ray2) && geometry.distanceSquared(rp2_temp[ii], ray2.p1) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale;
    +            rp2_lensq[ii] = geometry.distanceSquared(ray2.p1, rp2_temp[ii]);
    +          }
    +
    +          if (rp_exist[1] && ((!rp_exist[2]) || rp_lensq[1] < rp_lensq[2]) && rp_lensq[1] > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +            s_point_temp = rp_temp[1];
    +            s_lensq_temp = rp_lensq[1];
    +            if (rp_on_ray[2] && rp_lensq[1] < rp_lensq[2]) {
    +              //The ray is from outside to inside (with respect to the arc itself)
    +              normal_x_temp = s_point_temp.x - center.x;
    +              normal_y_temp = s_point_temp.y - center.y;
    +            } else {
    +              normal_x_temp = center.x - s_point_temp.x;
    +              normal_y_temp = center.y - s_point_temp.y;
    +            }
    +          }
    +          if (rp_exist[2] && ((!rp_exist[1]) || rp_lensq[2] < rp_lensq[1]) && rp_lensq[2] > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +            s_point_temp = rp_temp[2];
    +            s_lensq_temp = rp_lensq[2];
    +            if (rp_on_ray[1] && rp_lensq[2] < rp_lensq[1]) {
    +              //The ray is from outside to inside (with respect to the arc itself)
    +              normal_x_temp = s_point_temp.x - center.x;
    +              normal_y_temp = s_point_temp.y - center.y;
    +            } else {
    +              normal_x_temp = center.x - s_point_temp.x;
    +              normal_y_temp = center.y - s_point_temp.y;
    +            }
    +          }
    +          if (rp2_exist[1] && rp2_lensq[1] > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +            ray_intersect_count++;
    +          }
    +          if (rp2_exist[2] && rp2_lensq[2] > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +            ray_intersect_count++;
    +          }
    +
    +          // Test if too close to an edge
    +          if (s_point_temp && (geometry.distanceSquared(s_point_temp, p1) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale || geometry.distanceSquared(s_point_temp, p2) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale)) {
    +            nearEdge_temp = true;
    +          }
    +
    +        } else {
    +          // The three points on the arc is colinear. Treat as a line segment.
    +          rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 2) % this.path.length]));
    +
    +          rp2_temp = geometry.linesIntersection(geometry.line(ray2.p1, ray2.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 2) % this.path.length]));
    +          if (geometry.intersectionIsOnSegment(rp_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 2) % this.path.length])) && geometry.intersectionIsOnRay(rp_temp, ray) && geometry.distanceSquared(ray.p1, rp_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +            s_lensq_temp = geometry.distanceSquared(ray.p1, rp_temp);
    +            s_point_temp = rp_temp;
    +
    +            rdots = (ray.p2.x - ray.p1.x) * (this.path[(i + 2) % this.path.length].x - this.path[i % this.path.length].x) + (ray.p2.y - ray.p1.y) * (this.path[(i + 2) % this.path.length].y - this.path[i % this.path.length].y);
    +            ssq = (this.path[(i + 2) % this.path.length].x - this.path[i % this.path.length].x) * (this.path[(i + 2) % this.path.length].x - this.path[i % this.path.length].x) + (this.path[(i + 2) % this.path.length].y - this.path[i % this.path.length].y) * (this.path[(i + 2) % this.path.length].y - this.path[i % this.path.length].y);
    +
    +            normal_x_temp = rdots * (this.path[(i + 2) % this.path.length].x - this.path[i % this.path.length].x) - ssq * (ray.p2.x - ray.p1.x);
    +            normal_y_temp = rdots * (this.path[(i + 2) % this.path.length].y - this.path[i % this.path.length].y) - ssq * (ray.p2.y - ray.p1.y);
    +
    +
    +          }
    +
    +          if (geometry.intersectionIsOnSegment(rp2_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 2) % this.path.length])) && geometry.intersectionIsOnRay(rp2_temp, ray2) && geometry.distanceSquared(ray2.p1, rp2_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +            ray_intersect_count++;
    +          }
    +
    +          // Test if too close to an edge
    +          if (s_point_temp && (geometry.distanceSquared(s_point_temp, this.path[i % this.path.length]) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale || geometry.distanceSquared(s_point_temp, this.path[(i + 2) % this.path.length]) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale)) {
    +            nearEdge_temp = true;
    +          }
    +        }
    +      } else if (!this.path[(i + 1) % this.path.length].arc && !this.path[i % this.path.length].arc) {
    +        //Line segment i->i+1
    +        rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length]));
    +
    +        rp2_temp = geometry.linesIntersection(geometry.line(ray2.p1, ray2.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length]));
    +        if (geometry.intersectionIsOnSegment(rp_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length])) && geometry.intersectionIsOnRay(rp_temp, ray) && geometry.distanceSquared(ray.p1, rp_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +          s_lensq_temp = geometry.distanceSquared(ray.p1, rp_temp);
    +          s_point_temp = rp_temp;
    +
    +          rdots = (ray.p2.x - ray.p1.x) * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) + (ray.p2.y - ray.p1.y) * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y);
    +          ssq = (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) + (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y) * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y);
    +
    +          normal_x_temp = rdots * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) - ssq * (ray.p2.x - ray.p1.x);
    +          normal_y_temp = rdots * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y) - ssq * (ray.p2.y - ray.p1.y);
    +
    +
    +        }
    +
    +        if (geometry.intersectionIsOnSegment(rp2_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length])) && geometry.intersectionIsOnRay(rp2_temp, ray2) && geometry.distanceSquared(ray2.p1, rp2_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +          ray_intersect_count++;
    +        }
    +
    +        // Test if too close to an edge
    +        if (s_point_temp && (geometry.distanceSquared(s_point_temp, this.path[i % this.path.length]) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale || geometry.distanceSquared(s_point_temp, this.path[(i + 1) % this.path.length]) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale)) {
    +          nearEdge_temp = true;
    +        }
    +      }
    +      if (s_point_temp) {
    +        if (s_point && geometry.distanceSquared(s_point_temp, s_point) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +          // Self surface merging
    +          surfaceMultiplicity++;
    +        } else if (s_lensq_temp < s_lensq) {
    +          s_lensq = s_lensq_temp;
    +          s_point = s_point_temp;
    +          s_point_index = i;
    +          normal_x = normal_x_temp;
    +          normal_y = normal_y_temp;
    +          nearEdge = nearEdge_temp;
    +          surfaceMultiplicity = 1;
    +        }
    +      }
    +    }
    +
    +
    +    if (nearEdge) {
    +      var incidentType = NaN; // Incident on an edge point
    +    } else if (surfaceMultiplicity % 2 == 0) {
    +      var incidentType = 0; // Equivalent to not intersecting with the object
    +    } else if (ray_intersect_count % 2 == 1) {
    +      var incidentType = 1; // From inside to outside
    +    } else {
    +      var incidentType = -1; // From outside to inside
    +    }
    +
    +    return { s_point: s_point, normal: { x: normal_x, y: normal_y }, incidentType: incidentType };
    +  }
    +};
    +
    +export default Glass;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_glass_GrinGlass.js.html b/docs/sceneObjs_glass_GrinGlass.js.html new file mode 100644 index 00000000..6bef26a4 --- /dev/null +++ b/docs/sceneObjs_glass_GrinGlass.js.html @@ -0,0 +1,458 @@ + + + + + JSDoc: Source: sceneObjs/glass/GrinGlass.js + + + + + + + + + + +
    + +

    Source: sceneObjs/glass/GrinGlass.js

    + + + + + + +
    +
    +
    import BaseGrinGlass from '../BaseGrinGlass.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Gradient-index glass of the shape of a polygon
    + * 
    + * Tools -> Glass -> Gradient-index polygon
    + * @class
    + * @extends BaseGrinGlass
    + * @memberof sceneObjs
    + * @property {Array<Point>} path - The path of the glass. Each element is an object with `x` and `y` properties for coordinates.
    + * @property {boolean} notDone - Whether the user is still drawing the glass.
    + * @property {string} refIndexFn - The refractive index function in x and y in LaTeX format.
    + * @property {Point} origin - The origin of the (x,y) coordinates used in the refractive index function.
    + * @property {number} stepSize - The step size for the ray trajectory equation.
    + * @property {number} intersectTol - The epsilon for the intersection calculations.
    + */
    +class GrinGlass extends BaseGrinGlass {
    +  static type = 'GrinGlass';
    +  static isOptical = true;
    +  static supportsSurfaceMerging = true;
    +  static serializableDefaults = {
    +    path: [],
    +    notDone: false,
    +    refIndexFn: '1.1+0.1\\cdot\\cos\\left(0.1\\cdot y\\right)',
    +    origin: { x: 0, y: 0 },
    +    stepSize: 1,
    +    intersectTol: 1e-3
    +  };
    +  
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.GrinGlass.title'));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.notDone) {
    +      if (this.path.length === 2 && this.path[0].x === this.path[1].x && this.path[0].y === this.path[1].y) {
    +        ctx.fillStyle = 'rgb(255,0,0)';
    +        ctx.fillRect(this.path[0].x - 1.5 * ls, this.path[0].y - 1.5 * ls, 3 * ls, 3 * ls);
    +        return;
    +      }
    +      
    +      // The user has not finish drawing the object yet
    +      ctx.beginPath();
    +      ctx.moveTo(this.path[0].x, this.path[0].y);
    +
    +      for (var i = 0; i < this.path.length - 1; i++) {
    +        ctx.lineTo(this.path[(i + 1)].x, this.path[(i + 1)].y);
    +      }
    +      ctx.globalAlpha = 1;
    +      ctx.strokeStyle = 'rgb(128,128,128)';
    +      ctx.lineWidth = 1 * ls;
    +      ctx.stroke();
    +    } else {
    +      // The user has completed drawing the object
    +      ctx.beginPath();
    +      ctx.moveTo(this.path[0].x, this.path[0].y);
    +
    +      for (var i = 0; i < this.path.length; i++) {
    +        ctx.lineTo(this.path[(i + 1) % this.path.length].x, this.path[(i + 1) % this.path.length].y);
    +      }
    +      this.fillGlass(canvasRenderer, isAboveLight, isHovered);
    +    }
    +    ctx.lineWidth = 1;
    +
    +
    +    if (isHovered) {
    +      for (var i = 0; i < this.path.length; i++) {
    +        ctx.fillStyle = 'rgb(255,0,0)';
    +        ctx.fillRect(this.path[i].x - 1.5 * ls, this.path[i].y - 1.5 * ls, 3 * ls, 3 * ls);
    +      }
    +    }
    +  }
    +
    +  move(diffX, diffY) {
    +    for (var i = 0; i < this.path.length; i++) {
    +      this.path[i].x += diffX;
    +      this.path[i].y += diffY;
    +    }
    +  }
    +
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    if (!this.notDone) {
    +      // Initialize the construction stage
    +      this.notDone = true;
    +      this.path = [{ x: mousePos.x, y: mousePos.y }];
    +    }
    +
    +    if (this.path.length > 3 && mouse.isOnPoint(this.path[0])) {
    +      // Clicked the first point
    +      this.path.length--;
    +      this.notDone = false;
    +      return {
    +        isDone: true
    +      };
    +    }
    +    this.path.push({ x: mousePos.x, y: mousePos.y }); // Create a new point
    +  }
    +
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    this.path[this.path.length - 1] = { x: mousePos.x, y: mousePos.y }; // Move the last point
    +  }
    +
    +  onConstructUndo() {
    +    if (this.path.length <= 2) {
    +      return {
    +        isCancelled: true
    +      };
    +    } else {
    +      this.path.pop();
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +
    +    var click_lensq = Infinity;
    +    var click_lensq_temp;
    +    var targetPoint_index = -1;
    +    for (var i = 0; i < this.path.length; i++) {
    +      if (mouse.isOnPoint(this.path[i])) {
    +        click_lensq_temp = geometry.distanceSquared(mouse.pos, this.path[i]);
    +        if (click_lensq_temp <= click_lensq) {
    +          click_lensq = click_lensq_temp;
    +          targetPoint_index = i;
    +        }
    +      }
    +    }
    +    if (targetPoint_index != -1) {
    +      dragContext.part = 1;
    +      dragContext.index = targetPoint_index;
    +      dragContext.targetPoint = geometry.point(this.path[targetPoint_index].x, this.path[targetPoint_index].y);
    +      return dragContext;
    +    }
    +
    +    for (var i = 0; i < this.path.length; i++) {
    +      if (mouse.isOnSegment(geometry.line(this.path[(i) % this.path.length], this.path[(i + 1) % this.path.length]))) {
    +        // Dragging the entire this
    +        const mousePos = mouse.getPosSnappedToGrid();
    +        dragContext.part = 0;
    +        dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +        dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +        dragContext.snapContext = {};
    +        return dragContext;
    +      }
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +
    +    if (dragContext.part == 1) {
    +      this.path[dragContext.index].x = mousePos.x;
    +      this.path[dragContext.index].y = mousePos.y;
    +    }
    +
    +    if (dragContext.part == 0) {
    +      if (shift) {
    +        var mousePosSnapped = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }], dragContext.snapContext);
    +      } else {
    +        var mousePosSnapped = mouse.getPosSnappedToGrid();
    +        dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +      }
    +      this.move(mousePosSnapped.x - dragContext.mousePos1.x, mousePosSnapped.y - dragContext.mousePos1.y);
    +      dragContext.mousePos1 = mousePosSnapped;
    +    }
    +  }
    +
    +
    +  checkRayIntersects(ray) {
    +    if (this.notDone) { return; }
    +    if (!this.fn_p) {
    +      this.initFns();
    +    }
    +    if (this.isInsideGlass(ray.p1) || this.isOnBoundary(ray.p1)) // if the first point of the ray is inside the circle, or on its boundary
    +    {
    +      let len = geometry.distance(ray.p1, ray.p2);
    +      let x = ray.p1.x + (this.stepSize / len) * (ray.p2.x - ray.p1.x);
    +      let y = ray.p1.y + (this.stepSize / len) * (ray.p2.y - ray.p1.y);
    +      const intersection_point = geometry.point(x, y);
    +      if (this.isInsideGlass(intersection_point)) // if intersection_point is inside the circle
    +        return intersection_point;
    +    }
    +
    +    var s_lensq = Infinity;
    +    var s_lensq_temp;
    +    var s_point = null;
    +    var s_point_temp = null;
    +    var rp_temp;
    +
    +    for (var i = 0; i < this.path.length; i++) {
    +      s_point_temp = null;
    +      
    +      //Line segment i->i+1
    +      var rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length]));
    +
    +      if (geometry.intersectionIsOnSegment(rp_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length])) && geometry.intersectionIsOnRay(rp_temp, ray) && geometry.distanceSquared(ray.p1, rp_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +        s_lensq_temp = geometry.distanceSquared(ray.p1, rp_temp);
    +        s_point_temp = rp_temp;
    +      
    +      }
    +      if (s_point_temp) {
    +        if (s_lensq_temp < s_lensq) {
    +          s_lensq = s_lensq_temp;
    +          s_point = s_point_temp;
    +        }
    +      }
    +    }
    +    if (s_point) {
    +      return s_point;
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) {
    +    if (!this.fn_p) {
    +      // This means that some error has been occuring eariler in parsing the equation.
    +      return {
    +        isAbsorbed: true
    +      };
    +    }
    +    try {
    +      this.error = null;
    +
    +      if ((this.isInsideGlass(ray.p1) || this.isOutsideGlass(ray.p1)) && this.isOnBoundary(incidentPoint)) // if the ray is hitting the circle from the outside, or from the inside (meaning that the point incidentPoint is on the boundary of the circle, and the point ray.p1 is inside/outside the circle)
    +      {
    +        let r_bodyMerging_obj = ray.bodyMergingObj; // save the current bodyMergingObj of the ray, to pass it later to the reflected ray in the 'refract' function
    +
    +        var incidentData = this.getIncidentData(ray);
    +        var incidentType = incidentData.incidentType;
    +        if (incidentType == 1) {
    +          // From inside to outside
    +          var n1 = this.getRefIndexAt(incidentPoint, ray);
    +          this.onRayExit(ray);
    +        } else if (incidentType == -1) {
    +          // From outside to inside
    +          var n1 = 1 / this.getRefIndexAt(incidentPoint, ray);
    +          this.onRayEnter(ray);
    +        } else if (incidentType == 0) {
    +          // Equivalent to not intersecting with the object (e.g. two interfaces overlap)
    +          var n1 = 1;
    +        } else {
    +          // The situation that may cause bugs (e.g. incident on an edge point)
    +          // To prevent shooting the ray to a wrong direction, absorb the ray
    +          return {
    +            isAbsorbed: true
    +          };
    +        }
    +        return this.refract(ray, rayIndex, incidentData.s_point, incidentData.normal, n1, surfaceMergingObjs, r_bodyMerging_obj);
    +      } else {
    +        if (ray.bodyMergingObj === undefined)
    +          ray.bodyMergingObj = this.initRefIndex(ray); // Initialize the bodyMerging object of the ray
    +        const next_point = this.step(ray.p1, incidentPoint, ray);
    +        ray.p1 = incidentPoint;
    +        ray.p2 = next_point;
    +      }
    +    } catch (e) {
    +      this.error = e.toString();
    +      return {
    +        isAbsorbed: true
    +      };
    +    }
    +  }
    +
    +  getIncidentType(ray) {
    +    return this.getIncidentData(ray).incidentType;
    +  }
    +
    +  isOutsideGlass(point) {
    +    return (!this.isOnBoundary(point) && this.countIntersections(point) % 2 == 0)
    +  }
    +
    +  isInsideGlass(point) {
    +    return (!this.isOnBoundary(point) && this.countIntersections(point) % 2 == 1)
    +  }
    +  
    +  isOnBoundary(p3) {
    +    for (let i = 0; i < this.path.length; i++) {
    +      let p1 = this.path[i];
    +      let p2 = this.path[(i + 1) % this.path.length];
    +      let p1_p2 = geometry.point(p2.x - p1.x, p2.y - p1.y);
    +      let p1_p3 = geometry.point(p3.x - p1.x, p3.y - p1.y);
    +      if (geometry.cross(p1_p2, p1_p3) - this.intersectTol < 0 && geometry.cross(p1_p2, p1_p3) + this.intersectTol > 0) // if p1_p2 and p1_p3 are collinear
    +      {
    +        let dot_p2_p3 = geometry.dot(p1_p2, p1_p3);
    +        let p1_p2_squared = geometry.distanceSquared(p1, p2);
    +        if (p1_p2_squared - dot_p2_p3 + this.intersectTol >= 0 && dot_p2_p3 + this.intersectTol >= 0) // if the projection of the segment p1_p3 onto the segment p1_p2, is contained in the segment p1_p2
    +          return true;
    +      }
    +    }
    +    return false;
    +  }
    +
    +  /* Utility methods */
    +
    +  getIncidentData(ray) {
    +    var s_lensq = Infinity;
    +    var s_lensq_temp;
    +    var s_point = null;
    +    var s_point_temp = null;
    +    var s_point_index;
    +
    +    var surfaceMultiplicity = 1; // How many time the surfaces coincide
    +
    +    var rp_temp;
    +
    +    var rp2_temp;
    +
    +    var normal_x;
    +    var normal_x_temp;
    +
    +    var normal_y;
    +    var normal_y_temp;
    +
    +    var rdots;
    +    var ssq;
    +
    +    var nearEdge = false;
    +    var nearEdge_temp = false;
    +
    +    var ray2 = geometry.line(ray.p1, geometry.point(ray.p2.x + this.scene.rng() * 1e-5, ray.p2.y + this.scene.rng() * 1e-5)); // The ray to test the inside/outside (the test ray)
    +    var ray_intersect_count = 0; // The intersection count (odd means from outside)
    +
    +    for (var i = 0; i < this.path.length; i++) {
    +      s_point_temp = null;
    +      nearEdge_temp = false;
    +      rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length]));
    +
    +      rp2_temp = geometry.linesIntersection(geometry.line(ray2.p1, ray2.p2), geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length]));
    +      if (geometry.intersectionIsOnSegment(rp_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length])) && geometry.intersectionIsOnRay(rp_temp, ray) && geometry.distanceSquared(ray.p1, rp_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +        s_lensq_temp = geometry.distanceSquared(ray.p1, rp_temp);
    +        s_point_temp = rp_temp;
    +
    +        rdots = (ray.p2.x - ray.p1.x) * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) + (ray.p2.y - ray.p1.y) * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y);
    +        ssq = (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) + (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y) * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y);
    +
    +        normal_x_temp = rdots * (this.path[(i + 1) % this.path.length].x - this.path[i % this.path.length].x) - ssq * (ray.p2.x - ray.p1.x);
    +        normal_y_temp = rdots * (this.path[(i + 1) % this.path.length].y - this.path[i % this.path.length].y) - ssq * (ray.p2.y - ray.p1.y);
    +
    +      }
    +
    +      if (geometry.intersectionIsOnSegment(rp2_temp, geometry.line(this.path[i % this.path.length], this.path[(i + 1) % this.path.length])) && geometry.intersectionIsOnRay(rp2_temp, ray2) && geometry.distanceSquared(ray2.p1, rp2_temp) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +        ray_intersect_count++;
    +      }
    +
    +      // Test if too close to an edge
    +      if (s_point_temp && (geometry.distanceSquared(s_point_temp, this.path[i % this.path.length]) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale || geometry.distanceSquared(s_point_temp, this.path[(i + 1) % this.path.length]) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale)) {
    +        nearEdge_temp = true;
    +      }
    +      
    +      if (s_point_temp) {
    +        if (s_point && geometry.distanceSquared(s_point_temp, s_point) < Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale) {
    +          // Self surface merging
    +          surfaceMultiplicity++;
    +        } else if (s_lensq_temp < s_lensq) {
    +          s_lensq = s_lensq_temp;
    +          s_point = s_point_temp;
    +          s_point_index = i;
    +          normal_x = normal_x_temp;
    +          normal_y = normal_y_temp;
    +          nearEdge = nearEdge_temp;
    +          surfaceMultiplicity = 1;
    +        }
    +      }
    +    }
    +
    +
    +    if (nearEdge) {
    +      var incidentType = NaN; // Incident on an edge point
    +    } else if (surfaceMultiplicity % 2 == 0) {
    +      var incidentType = 0; // Equivalent to not intersecting with the object
    +    } else if (ray_intersect_count % 2 == 1) {
    +      var incidentType = 1; // From inside to outside
    +    } else {
    +      var incidentType = -1; // From outside to inside
    +    }
    +
    +    return { s_point: s_point, normal: { x: normal_x, y: normal_y }, incidentType: incidentType };
    +  }
    +
    +  // Implementation of the "crossing number algorithm" (see - https://en.wikipedia.org/wiki/Point_in_polygon)
    +  countIntersections(p3) {
    +    var cnt = 0;
    +    for (let i = 0; i < this.path.length; i++) {
    +      let p1 = this.path[i];
    +      let p2 = this.path[(i + 1) % this.path.length];
    +      let y_max = Math.max(p1.y, p2.y);
    +      let y_min = Math.min(p1.y, p2.y);
    +      if ((y_max - p3.y - this.intersectTol > 0 && y_max - p3.y + this.intersectTol > 0) && (y_min - p3.y - this.intersectTol < 0 && y_min - p3.y + this.intersectTol < 0)) {
    +        if (p1.x == p2.x && (p1.x - p3.x + this.intersectTol > 0 && p1.x - p3.x - this.intersectTol > 0)) // in case the current segment is vertical
    +          cnt++;
    +        else if ((p1.x + ((p3.y - p1.y) / (p2.y - p1.y)) * (p2.x - p1.x)) - p3.x - this.intersectTol > 0 && (p1.x + ((p3.y - p1.y) / (p2.y - p1.y)) * (p2.x - p1.x)) - p3.x + this.intersectTol > 0)
    +          cnt++;
    +      }
    +    }
    +    return cnt; // Returns the number of intersections between a horizontal ray (that originates from the point - p3) and the Free-shape glass object - this.
    +  }
    +};
    +
    +export default GrinGlass;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_glass_IdealLens.js.html b/docs/sceneObjs_glass_IdealLens.js.html new file mode 100644 index 00000000..0657899b --- /dev/null +++ b/docs/sceneObjs_glass_IdealLens.js.html @@ -0,0 +1,201 @@ + + + + + JSDoc: Source: sceneObjs/glass/IdealLens.js + + + + + + + + + + +
    + +

    Source: sceneObjs/glass/IdealLens.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Ideal lens
    + * 
    + * Tools -> Glass -> Ideal Lens
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint.
    + * @property {Point} p2 - The second endpoint.
    + * @property {number} focalLength - The focal length.
    + */
    +class IdealLens extends LineObjMixin(BaseSceneObj) {
    +  static type = 'IdealLens';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    focalLength: 100
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.IdealLens.title'));
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.common.focalLength'), -1000 * this.scene.lengthScale, 1000 * this.scene.lengthScale, 1 * this.scene.lengthScale, this.focalLength, function (obj, value) {
    +      obj.focalLength = value;
    +    }, i18next.t('simulator:sceneObjs.common.lengthUnitInfo'));
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +    
    +    var len = Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +    var par_x = (this.p2.x - this.p1.x) / len;
    +    var par_y = (this.p2.y - this.p1.y) / len;
    +    var per_x = par_y;
    +    var per_y = -par_x;
    +
    +    var arrow_size_per = 5 * ls;
    +    var arrow_size_par = 5 * ls;
    +    var center_size = 2 * ls;
    +
    +    // Draw the line segment
    +    ctx.strokeStyle = isHovered ? 'cyan' : ('rgb(128,128,128)');
    +    ctx.globalAlpha = 1 / ((Math.abs(this.focalLength / this.scene.lengthScale) / 100) + 1);
    +    ctx.lineWidth = 4 * ls;
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.stroke();
    +    ctx.lineWidth = 1 * ls;
    +
    +    ctx.globalAlpha = 1;
    +    ctx.fillStyle = 'rgb(255,0,0)';
    +
    +    // Draw the center point of the lens
    +    var center = geometry.segmentMidpoint(this);
    +    ctx.strokeStyle = 'rgb(255,255,255)';
    +    ctx.beginPath();
    +    ctx.moveTo(center.x - per_x * center_size, center.y - per_y * center_size);
    +    ctx.lineTo(center.x + per_x * center_size, center.y + per_y * center_size);
    +    ctx.stroke();
    +
    +    if (this.focalLength > 0) {
    +      // Draw the arrow (p1)
    +      ctx.beginPath();
    +      ctx.moveTo(this.p1.x - par_x * arrow_size_par, this.p1.y - par_y * arrow_size_par);
    +      ctx.lineTo(this.p1.x + par_x * arrow_size_par + per_x * arrow_size_per, this.p1.y + par_y * arrow_size_par + per_y * arrow_size_per);
    +      ctx.lineTo(this.p1.x + par_x * arrow_size_par - per_x * arrow_size_per, this.p1.y + par_y * arrow_size_par - per_y * arrow_size_per);
    +      ctx.fill();
    +
    +      // Draw the arrow (p2)
    +      ctx.beginPath();
    +      ctx.moveTo(this.p2.x + par_x * arrow_size_par, this.p2.y + par_y * arrow_size_par);
    +      ctx.lineTo(this.p2.x - par_x * arrow_size_par + per_x * arrow_size_per, this.p2.y - par_y * arrow_size_par + per_y * arrow_size_per);
    +      ctx.lineTo(this.p2.x - par_x * arrow_size_par - per_x * arrow_size_per, this.p2.y - par_y * arrow_size_par - per_y * arrow_size_per);
    +      ctx.fill();
    +    }
    +
    +    if (this.focalLength < 0) {
    +      // Draw the arrow (p1)
    +      ctx.beginPath();
    +      ctx.moveTo(this.p1.x + par_x * arrow_size_par, this.p1.y + par_y * arrow_size_par);
    +      ctx.lineTo(this.p1.x - par_x * arrow_size_par + per_x * arrow_size_per, this.p1.y - par_y * arrow_size_par + per_y * arrow_size_per);
    +      ctx.lineTo(this.p1.x - par_x * arrow_size_par - per_x * arrow_size_per, this.p1.y - par_y * arrow_size_par - per_y * arrow_size_per);
    +      ctx.fill();
    +
    +      // Draw the arrow (p2)
    +      ctx.beginPath();
    +      ctx.moveTo(this.p2.x - par_x * arrow_size_par, this.p2.y - par_y * arrow_size_par);
    +      ctx.lineTo(this.p2.x + par_x * arrow_size_par + per_x * arrow_size_per, this.p2.y + par_y * arrow_size_par + per_y * arrow_size_per);
    +      ctx.lineTo(this.p2.x + par_x * arrow_size_par - per_x * arrow_size_per, this.p2.y + par_y * arrow_size_par - per_y * arrow_size_per);
    +      ctx.fill();
    +    }
    +
    +    if (isHovered) {
    +      // show focal length
    +      var mp = geometry.segmentMidpoint(this);
    +      ctx.fillStyle = 'rgb(255,0,255)';
    +      ctx.fillRect(mp.x + this.focalLength * per_x - 1.5 * ls, mp.y + this.focalLength * per_y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(mp.x - this.focalLength * per_x - 1.5 * ls, mp.y - this.focalLength * per_y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    return this.checkRayIntersectsShape(ray);
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    var lens_length = geometry.segmentLength(this);
    +    var main_line_unitvector_x = (-this.p1.y + this.p2.y) / lens_length;
    +    var main_line_unitvector_y = (this.p1.x - this.p2.x) / lens_length;
    +    var mid_point = geometry.segmentMidpoint(this);
    +
    +    var twoF_point_1 = geometry.point(mid_point.x + main_line_unitvector_x * 2 * this.focalLength, mid_point.y + main_line_unitvector_y * 2 * this.focalLength);  // The first point at two focal lengths
    +    var twoF_point_2 = geometry.point(mid_point.x - main_line_unitvector_x * 2 * this.focalLength, mid_point.y - main_line_unitvector_y * 2 * this.focalLength);  // The second point at two focal lengths
    +
    +    var twoF_line_near, twoF_line_far;
    +    if (geometry.distanceSquared(ray.p1, twoF_point_1) < geometry.distanceSquared(ray.p1, twoF_point_2)) {
    +      // The first point at two focal lengths is on the same side as the ray
    +      twoF_line_near = geometry.parallelLineThroughPoint(this, twoF_point_1);
    +      twoF_line_far = geometry.parallelLineThroughPoint(this, twoF_point_2);
    +    } else {
    +      // The second point at two focal lengths is on the same side as the ray
    +      twoF_line_near = geometry.parallelLineThroughPoint(this, twoF_point_2);
    +      twoF_line_far = geometry.parallelLineThroughPoint(this, twoF_point_1);
    +    }
    +
    +    if (this.focalLength > 0) {
    +      // Converging lens
    +      ray.p2 = geometry.linesIntersection(twoF_line_far, geometry.line(mid_point, geometry.linesIntersection(twoF_line_near, ray)));
    +      ray.p1 = incidentPoint;
    +    } else {
    +      // Diverging lens
    +      ray.p2 = geometry.linesIntersection(twoF_line_far, geometry.line(incidentPoint, geometry.linesIntersection(twoF_line_near, geometry.line(mid_point, geometry.linesIntersection(twoF_line_far, ray)))));
    +      ray.p1 = incidentPoint;
    +    }
    +  }
    +};
    +
    +export default IdealLens;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_glass_PlaneGlass.js.html b/docs/sceneObjs_glass_PlaneGlass.js.html new file mode 100644 index 00000000..49d3aa45 --- /dev/null +++ b/docs/sceneObjs_glass_PlaneGlass.js.html @@ -0,0 +1,185 @@ + + + + + JSDoc: Source: sceneObjs/glass/PlaneGlass.js + + + + + + + + + + +
    + +

    Source: sceneObjs/glass/PlaneGlass.js

    + + + + + + +
    +
    +
    import BaseGlass from '../BaseGlass.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Glass of the shape of a half-plane.
    + * 
    + * Tools -> Glass -> Half-plane
    + * @class
    + * @extends BaseGlass
    + * @memberof sceneObjs
    + * @property {Point} p1 - A point on the boundary of the half-plane.
    + * @property {Point} p2 - Another point on the boundary of the half-plane.
    + * @property {number} refIndex - The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.
    + * @property {number} cauchyB - The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.
    + */
    +class PlaneGlass extends LineObjMixin(BaseGlass) {
    +  static type = 'PlaneGlass';
    +  static isOptical = true;
    +  static supportsSurfaceMerging = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    refIndex: 1.5,
    +    cauchyB: 0.004
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:meta.parentheses', { main: i18next.t('main:tools.categories.glass'), sub: i18next.t('main:tools.PlaneGlass.title') }));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +
    +    var len = Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +    var par_x = (this.p2.x - this.p1.x) / len;
    +    var par_y = (this.p2.y - this.p1.y) / len;
    +    var per_x = par_y;
    +    var per_y = -par_x;
    +
    +    var sufficientlyLargeDistance = (Math.abs(this.p1.x + this.scene.origin.x) + Math.abs(this.p1.y + this.scene.origin.y) + ctx.canvas.height + ctx.canvas.width) / Math.min(1, this.scene.scale);
    +
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x - par_x * sufficientlyLargeDistance, this.p1.y - par_y * sufficientlyLargeDistance);
    +    ctx.lineTo(this.p1.x + par_x * sufficientlyLargeDistance, this.p1.y + par_y * sufficientlyLargeDistance);
    +    ctx.lineTo(this.p1.x + (par_x - per_x) * sufficientlyLargeDistance, this.p1.y + (par_y - per_y) * sufficientlyLargeDistance);
    +    ctx.lineTo(this.p1.x - (par_x + per_x) * sufficientlyLargeDistance, this.p1.y - (par_y + per_y) * sufficientlyLargeDistance);
    +
    +    this.fillGlass(canvasRenderer, isAboveLight, isHovered);
    +
    +    if (isHovered) {
    +      ctx.fillStyle = 'magenta';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (mouse.isOnPoint(this.p1) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p2)) {
    +      dragContext.part = 1;
    +      dragContext.targetPoint = geometry.point(this.p1.x, this.p1.y);
    +      return dragContext;
    +    }
    +    if (mouse.isOnPoint(this.p2)) {
    +      dragContext.part = 2;
    +      dragContext.targetPoint = geometry.point(this.p2.x, this.p2.y);
    +      return dragContext;
    +    }
    +    if (mouse.isOnLine(this)) {
    +      const mousePos = mouse.getPosSnappedToGrid();
    +      dragContext.part = 0;
    +      dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +      dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +      dragContext.snapContext = {};
    +      return dragContext;
    +    }
    +  }
    +
    +
    +  checkRayIntersects(ray) {
    +    if (this.refIndex <= 0) return;
    +    var rp_temp = geometry.linesIntersection(ray, this);
    +
    +    if (geometry.intersectionIsOnRay(rp_temp, ray)) {
    +      return rp_temp;
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint, surfaceMergingObjs) {
    +
    +    var rdots = (ray.p2.x - ray.p1.x) * (this.p2.x - this.p1.x) + (ray.p2.y - ray.p1.y) * (this.p2.y - this.p1.y);
    +    var ssq = (this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y);
    +    var normal = { x: rdots * (this.p2.x - this.p1.x) - ssq * (ray.p2.x - ray.p1.x), y: rdots * (this.p2.y - this.p1.y) - ssq * (ray.p2.y - ray.p1.y) };
    +
    +    var incidentType = this.getIncidentType(ray);
    +    if (incidentType == 1) {
    +      // From inside to outside
    +      var n1 = this.getRefIndexAt(incidentPoint, ray);
    +    } else if (incidentType == -1) {
    +      // From outside to inside
    +      var n1 = 1 / this.getRefIndexAt(incidentPoint, ray);
    +    } else {
    +      // Situation that may cause bugs (e.g. incident on an edge point)
    +      // To prevent shooting the ray to a wrong direction, absorb the ray
    +      return {
    +        isAbsorbed: true
    +      };
    +    }
    +
    +    return this.refract(ray, rayIndex, incidentPoint, normal, n1, surfaceMergingObjs, ray.bodyMergingObj);
    +  }
    +
    +  getIncidentType(ray) {
    +    var rcrosss = (ray.p2.x - ray.p1.x) * (this.p2.y - this.p1.y) - (ray.p2.y - ray.p1.y) * (this.p2.x - this.p1.x);
    +    if (rcrosss > 0) {
    +      return 1; // From inside to outside
    +    }
    +    if (rcrosss < 0) {
    +      return -1; // From outside to inside
    +    }
    +    return NaN;
    +  }
    +};
    +
    +export default PlaneGlass;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_glass_SphericalLens.js.html b/docs/sceneObjs_glass_SphericalLens.js.html new file mode 100644 index 00000000..cd06bbe7 --- /dev/null +++ b/docs/sceneObjs_glass_SphericalLens.js.html @@ -0,0 +1,704 @@ + + + + + JSDoc: Source: sceneObjs/glass/SphericalLens.js + + + + + + + + + + +
    + +

    Source: sceneObjs/glass/SphericalLens.js

    + + + + + + +
    +
    +
    import Glass from './Glass.js';
    +import geometry from '../../geometry.js';
    +import i18next from 'i18next';
    +
    +/**
    + * Spherical lens.
    + * 
    + * Tools -> Glass -> Spherical Lens
    + * 
    + * It is essentially a special case of `sceneObjs['Glass']` that has the shape of a lens, but it provides a more user-friendly interface to create a lens using more familliar parameters.
    + * In the state where the lens is built, it behaves exactly like `sceneObjs['Glass']`, and `p1`, `p2`, and `parames` are null. But when the lens is not built (which happens when the user enters a set of invalid parameters, or if the JSON data is defined using parameters directly), it is defined using `p1`, `p2`, and `params`, and `path` is null.
    + * @class
    + * @extends sceneObjs.Glass
    + * @memberof sceneObjs
    + * @property {Array<object>} path - The path of the lens if it is built.
    + * @property {string} defBy - The way the lens is defined. Either 'DR1R2' or 'DFfdBfd'.
    + * @property {Point} p1 - The intersection of the perpendicular bisector of the segment for the `d` parameter with the top edge of the lens, if it is not built.
    + * @property {Point} p2 - The intersection of the perpendicular bisector of the segment for the `d` parameter with the bottom edge of the lens, if it is not built.
    + * @property {object} params - The parameters of the lens if it is not built. It has the following properties: `d`, `r1`, and `r2` if `defBy` is 'DR1R2', and `d`, `ffd`, and `bfd` if `defBy` is 'DFfdBfd'.
    + * @property {number} refIndex - The refractive index of the glass, or the Cauchy coefficient A of the glass if "Simulate Colors" is on.
    + * @property {number} cauchyB - The Cauchy coefficient B of the glass if "Simulate Colors" is on, in micrometer squared.
    + */
    +class SphericalLens extends Glass {
    +  static type = 'SphericalLens';
    +  static isOptical = true;
    +  static supportsSurfaceMerging = true;
    +  static serializableDefaults = {
    +    path: null,
    +    defBy: 'DR1R2',
    +    p1: null,
    +    p2: null,
    +    params: null,
    +    refIndex: 1.5,
    +    cauchyB: 0.004
    +  };
    +
    +  constructor(scene, jsonObj) {
    +    super(scene, jsonObj);
    +
    +    if (!this.path && this.p1 && this.p2) {
    +      // If the lens is not built in the JSON data, build the lens here.
    +      if (this.defBy == 'DR1R2') {
    +        this.createLensWithDR1R2(this.params.d, this.params.r1, this.params.r2);
    +      } else if (this.defBy == 'DFfdBfd') {
    +        this.createLensWithDFfdBfd(this.params.d, this.params.ffd, this.params.bfd);
    +      }
    +    }
    +  }
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.SphericalLens.title'));
    +    objBar.createDropdown('', this.defBy, {
    +      'DR1R2': i18next.t('simulator:sceneObjs.SphericalLens.defBy.radiiOfCurvature'),
    +      'DFfdBfd': i18next.t('simulator:sceneObjs.SphericalLens.defBy.focalDistances')
    +    }, function (obj, value) {
    +      obj.defBy = value;
    +    }, null, true);
    +
    +    if (this.defBy == 'DR1R2') {
    +      var params = this.getDR1R2();
    +      var r1 = params.r1;
    +      var r2 = params.r2;
    +      var d = params.d;
    +
    +      objBar.createNumber('R<sub>1</sub>', 0, 100, 1, r1, function (obj, value) {
    +        var params = obj.getDR1R2();
    +        var r2 = params.r2;
    +        var d = params.d;
    +        obj.createLensWithDR1R2(d, value, r2);
    +      }, null, true);
    +      objBar.createNumber('R<sub>2</sub>', 0, 100, 1, r2, function (obj, value) {
    +        var params = obj.getDR1R2();
    +        var r1 = params.r1;
    +        var d = params.d;
    +        obj.createLensWithDR1R2(d, r1, value);
    +      }, null, true);
    +      objBar.createNumber('d', 0, 100, 1, d, function (obj, value) {
    +        var params = obj.getDR1R2();
    +        var r1 = params.r1;
    +        var r2 = params.r2;
    +        obj.createLensWithDR1R2(value, r1, r2);
    +      }, null, true);
    +    } else if (this.defBy == 'DFfdBfd') {
    +      objBar.createInfoBox('<img src="../img/FFD_BFD.svg" width=100%>');
    +
    +      var params = this.getDFfdBfd();
    +      var d = params.d;
    +      var ffd = params.ffd;
    +      var bfd = params.bfd;
    +
    +      objBar.createNumber('FFD', 0, 100, 1, ffd, function (obj, value) {
    +        var params = obj.getDFfdBfd();
    +        var d = params.d;
    +        var bfd = params.bfd;
    +        obj.createLensWithDFfdBfd(d, value, bfd);
    +      }, null, true);
    +      objBar.createNumber('BFD', 0, 100, 1, bfd, function (obj, value) {
    +        var params = obj.getDFfdBfd();
    +        var d = params.d;
    +        var ffd = params.ffd;
    +        obj.createLensWithDFfdBfd(d, ffd, value);
    +      }, null, true);
    +      objBar.createNumber('d', 0, 100, 1, d, function (obj, value) {
    +        var params = obj.getDFfdBfd();
    +        var ffd = params.ffd;
    +        var bfd = params.bfd;
    +        obj.createLensWithDFfdBfd(value, ffd, bfd);
    +      }, null, true);
    +    }
    +
    +    if (this.scene.simulateColors) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.BaseGlass.cauchyCoeff') + " A", 1, 3, 0.01, this.refIndex, function (obj, value) {
    +        var old_params = obj.getDFfdBfd();
    +        obj.refIndex = value * 1;
    +        if (obj.defBy == 'DFfdBfd') {
    +          // If the lens is defined by d,ffd,bfd, we need to rebuild the lens with the new refractive index so that the focal distances are correct.
    +          obj.createLensWithDFfdBfd(old_params.d, old_params.ffd, old_params.bfd);
    +        }
    +      }, '<p>*' + i18next.t('simulator:sceneObjs.BaseGlass.refIndexInfo.relative') + '</p><p>' + i18next.t('simulator:sceneObjs.BaseGlass.refIndexInfo.effective') + '</p>');
    +      objBar.createNumber("B(μm²)", 0.0001, 0.02, 0.0001, this.cauchyB, function (obj, value) {
    +        var old_params = obj.getDFfdBfd();
    +        obj.cauchyB = value;
    +        if (obj.defBy == 'DFfdBfd') {
    +          // If the lens is defined by d,ffd,bfd, we need to rebuild the lens with the new refractive index so that the focal distances are correct.
    +          obj.createLensWithDFfdBfd(old_params.d, old_params.ffd, old_params.bfd);
    +        }
    +      });
    +    } else {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.BaseGlass.refIndex') + '*', 0.5, 2.5, 0.01, this.refIndex, function (obj, value) {
    +        var old_params = obj.getDFfdBfd();
    +        obj.refIndex = value * 1;
    +        if (obj.defBy == 'DFfdBfd') {
    +          // If the lens is defined by d,ffd,bfd, we need to rebuild the lens with the new refractive index so that the focal distances are correct.
    +          obj.createLensWithDFfdBfd(old_params.d, old_params.ffd, old_params.bfd);
    +        }
    +      }, '<p>*' + i18next.t('simulator:sceneObjs.BaseGlass.refIndexInfo.relative') + '</p><p>' + i18next.t('simulator:sceneObjs.BaseGlass.refIndexInfo.effective') + '</p>');
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1 && this.p2 && this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +
    +    if (!this.path) {
    +      if (this.p1 && this.p2) {
    +        ctx.fillStyle = 'rgb(255,0,0)';
    +        ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +        ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      }
    +      return;
    +    }
    +    super.draw(canvasRenderer, isAboveLight, isHovered);
    +
    +    var p1 = geometry.midpoint(this.path[0], this.path[1]);
    +    var p2 = geometry.midpoint(this.path[3], this.path[4]);
    +    var len = Math.hypot(p1.x - p2.x, p1.y - p2.y);
    +    var dx = (p2.x - p1.x) / len;
    +    var dy = (p2.y - p1.y) / len;
    +    var dpx = dy;
    +    var dpy = -dx;
    +
    +    if (isHovered) {
    +      // Draw the focal points
    +
    +      var params = this.getDFfdBfd();
    +      var ffd = params.ffd;
    +      var bfd = params.bfd;
    +
    +      ctx.fillStyle = 'rgb(255,0,255)';
    +      ctx.fillRect(this.path[2].x + bfd * dpx - 1.5 * ls, this.path[2].y + bfd * dpy - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.path[5].x - ffd * dpx - 1.5 * ls, this.path[5].y - ffd * dpy - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  move(diffX, diffY) {
    +    if (this.path) {
    +      super.move(diffX, diffY);
    +    } else if (this.p1 && this.p2) {
    +      this.p1.x += diffX;
    +      this.p1.y += diffY;
    +      this.p2.x += diffX;
    +      this.p2.y += diffY;
    +    }
    +  }
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    if (!this.constructionPoint) {
    +      // Initialize the construction stage.
    +      this.constructionPoint = mouse.getPosSnappedToGrid();
    +      this.p1 = this.constructionPoint;
    +      this.p2 = this.constructionPoint;
    +      this.path = null;
    +      this.params = null;
    +    }
    +    if (shift) {
    +      this.p2 = mouse.getPosSnappedToDirection(this.constructionPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +    } else {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +    }
    +
    +    this.createLens();
    +
    +    return {
    +      requiresObjBarUpdate: true
    +    }
    +  }
    +
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    if (shift) {
    +      this.p2 = mouse.getPosSnappedToDirection(this.constructionPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +    } else {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +    }
    +
    +    this.p1 = ctrl ? geometry.point(2 * this.constructionPoint.x - this.p2.x, 2 * this.constructionPoint.y - this.p2.y) : this.constructionPoint;
    +
    +    this.createLens();
    +
    +    return {
    +      requiresObjBarUpdate: true
    +    }
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    if (!mouse.isOnPoint(this.p1)) {
    +      this.p1 = null;
    +      this.p2 = null;
    +      this.params = null;
    +      delete this.constructionPoint;
    +      return {
    +        isDone: true,
    +        requiresObjBarUpdate: true
    +      };
    +    }
    +  }
    +  
    +  onConstructUndo() {
    +    return {
    +      isCancelled: true
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (!this.path) {
    +      if (this.p1 && this.p2) {
    +        if (mouse.isOnPoint(this.p1)) {
    +          dragContext.part = -1;
    +          dragContext.targetPoint = this.p1;
    +          return dragContext;
    +        }
    +        if (mouse.isOnPoint(this.p2)) {
    +          dragContext.part = -1;
    +          dragContext.targetPoint = this.p2;
    +          return dragContext;
    +        }
    +      }
    +      return null;
    +    };
    +    dragContext = super.checkMouseOver(mouse);
    +    if (dragContext) {
    +      if (dragContext.part != 0) {
    +        dragContext.requiresObjBarUpdate = true;
    +      }
    +      
    +      return dragContext;
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    if (dragContext.part == -1) return;
    +    var p1 = geometry.midpoint(this.path[0], this.path[1]);
    +    var p2 = geometry.midpoint(this.path[3], this.path[4]);
    +    var len = Math.hypot(p1.x - p2.x, p1.y - p2.y);
    +    var dx = (p2.x - p1.x) / len;
    +    var dy = (p2.y - p1.y) / len;
    +    var dpx = dy;
    +    var dpy = -dx;
    +    var cx = (p1.x + p2.x) * .5;
    +    var cy = (p1.y + p2.y) * .5;
    +    var othick = Math.hypot(this.path[0].x - p1.x, this.path[0].y - p1.y);
    +    var cthick2 = Math.hypot(this.path[2].x - cx, this.path[2].y - cy);
    +    var cthick5 = Math.hypot(this.path[5].x - cx, this.path[5].y - cy);
    +    var oldx, oldy;
    +    if (dragContext.part == 1) {
    +      oldx = this.path[dragContext.index].x;
    +      oldy = this.path[dragContext.index].y;
    +    }
    +
    +    super.onDrag(mouse, dragContext, ctrl, shift);
    +
    +    if (dragContext.isByHandle) return;
    +    if (dragContext.part != 1)
    +      return;
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    if (dragContext.index == 2 || dragContext.index == 5) {
    +      // keep center points on optical axis
    +      var off = (mousePos.x - cx) * dpx + (mousePos.y - cy) * dpy;
    +      this.path[dragContext.index] = { x: cx + dpx * off, y: cy + dpy * off, arc: true };
    +    } else {
    +      var thick = Math.abs(((mousePos.x - cx) * dpx + (mousePos.y - cy) * dpy));
    +      // adjust center thickness to match so curvature is the same
    +      cthick2 += thick - othick;
    +      cthick5 += thick - othick;
    +      var mpt = this.path[dragContext.index];
    +      var lchange = (mpt.x - oldx) * dx + (mpt.y - oldy) * dy;
    +      // adjust length
    +      if (dragContext.index < 2) {
    +        p1.x += lchange * dx;
    +        p1.y += lchange * dy;
    +      } else {
    +        p2.x += lchange * dx;
    +        p2.y += lchange * dy;
    +      }
    +
    +      len = Math.hypot(p1.x - p2.x, p1.y - p2.y);
    +      dx = (p2.x - p1.x) / len;
    +      dy = (p2.y - p1.y) / len;
    +      dpx = dy;
    +      dpy = -dx;
    +      cx = (p1.x + p2.x) * .5;
    +      cy = (p1.y + p2.y) * .5;
    +
    +      // recreate lens
    +      this.path[0] = { x: p1.x - dpx * thick, y: p1.y - dpy * thick, arc: false };
    +      this.path[1] = { x: p1.x + dpx * thick, y: p1.y + dpy * thick, arc: false };
    +      this.path[2] = { x: cx + dpx * cthick2, y: cy + dpy * cthick2, arc: true };
    +      this.path[3] = { x: p2.x + dpx * thick, y: p2.y + dpy * thick, arc: false };
    +      this.path[4] = { x: p2.x - dpx * thick, y: p2.y - dpy * thick, arc: false };
    +      this.path[5] = { x: cx - dpx * cthick5, y: cy - dpy * cthick5, arc: true };
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (!this.path) return false;
    +    return super.checkRayIntersects(ray);
    +  }
    +
    +  /* Utility methods */
    +
    +
    +  createLens() {
    +    var p1 = this.p1 || geometry.midpoint(this.path[0], this.path[1]);
    +    var p2 = this.p2 || geometry.midpoint(this.path[3], this.path[4]);
    +    var len = Math.hypot(p1.x - p2.x, p1.y - p2.y);
    +    var dx = (p2.x - p1.x) / len;
    +    var dy = (p2.y - p1.y) / len;
    +    var dpx = dy;
    +    var dpy = -dx;
    +    var cx = (p1.x + p2.x) * .5;
    +    var cy = (p1.y + p2.y) * .5;
    +    const thick = 10 * this.scene.lengthScale;
    +    // create lens
    +    if (!this.path) this.path = [];
    +    this.path[0] = { x: p1.x - dpx * thick, y: p1.y - dpy * thick, arc: false };
    +    this.path[1] = { x: p1.x + dpx * thick, y: p1.y + dpy * thick, arc: false };
    +    this.path[2] = { x: cx + dpx * thick * 2, y: cy + dpy * thick * 2, arc: true };
    +    this.path[3] = { x: p2.x + dpx * thick, y: p2.y + dpy * thick, arc: false };
    +    this.path[4] = { x: p2.x - dpx * thick, y: p2.y - dpy * thick, arc: false };
    +    this.path[5] = { x: cx - dpx * thick * 2, y: cy - dpy * thick * 2, arc: true };
    +  }
    +
    +  createLensWithDR1R2(d, r1, r2) {
    +    this.error = null;
    +
    +    if (!this.path) {
    +      var p1 = this.p1;
    +      var p2 = this.p2;
    +    } else {
    +      var old_params = this.getDR1R2();
    +      var p1 = geometry.midpoint(this.path[0], this.path[1]);
    +      var p2 = geometry.midpoint(this.path[3], this.path[4]);
    +      var old_d = old_params.d;
    +      var old_r1 = old_params.r1;
    +      var old_r2 = old_params.r2;
    +      var old_length = Math.hypot(p1.x - p2.x, p1.y - p2.y);
    +
    +      if (old_r1 < Infinity && old_r1 > -Infinity) {
    +        var old_curveShift1 = old_r1 - Math.sqrt(old_r1 * old_r1 - old_length * old_length / 4) * Math.sign(old_r1);
    +      } else {
    +        var old_curveShift1 = 0;
    +      }
    +
    +      if (old_r2 < Infinity && old_r2 > -Infinity) {
    +        var old_curveShift2 = old_r2 - Math.sqrt(old_r2 * old_r2 - old_length * old_length / 4) * Math.sign(old_r2);
    +      } else {
    +        var old_curveShift2 = 0;
    +      }
    +
    +      var old_edgeShift1 = old_d / 2 - old_curveShift1;
    +      var old_edgeShift2 = old_d / 2 + old_curveShift2;
    +    }
    +
    +    var len = Math.hypot(p1.x - p2.x, p1.y - p2.y);
    +    var dx = (p2.x - p1.x) / len;
    +    var dy = (p2.y - p1.y) / len;
    +    var dpx = dy;
    +    var dpy = -dx;
    +
    +    if (old_params) {
    +      // Correct p1 and p2 so that this.path[2] and this.path[5] will move symmetrically from the old lens.
    +      var correction = (old_edgeShift1 - old_edgeShift2) / 2;
    +      p1.x += dpx * correction;
    +      p1.y += dpy * correction;
    +      p2.x += dpx * correction;
    +      p2.y += dpy * correction;
    +    }
    +
    +
    +
    +    var cx = (p1.x + p2.x) * .5;
    +    var cy = (p1.y + p2.y) * .5;
    +
    +
    +    if (r1 < Infinity && r1 > -Infinity) {
    +      var curveShift1 = r1 - Math.sqrt(r1 * r1 - len * len / 4) * Math.sign(r1);
    +    } else {
    +      var curveShift1 = 0;
    +    }
    +
    +    if (r2 < Infinity && r2 > -Infinity) {
    +      var curveShift2 = r2 - Math.sqrt(r2 * r2 - len * len / 4) * Math.sign(r2);
    +    } else {
    +      var curveShift2 = 0;
    +    }
    +
    +    var edgeShift1 = d / 2 - curveShift1;
    +    var edgeShift2 = d / 2 + curveShift2;
    +
    +    //console.log([edgeShift1,edgeShift2,d])
    +
    +    if (isNaN(curveShift1) || isNaN(curveShift2)) {
    +      // invalid lens. Store the parameters so we can restore them later.
    +      this.p1 = p1;
    +      this.p2 = p2;
    +      this.path = null;
    +      this.params = { r1: r1, r2: r2, d: d };
    +      this.error = 'Invalid lens parameters';
    +    } else {
    +      // create lens
    +      if (!this.path) this.path = [];
    +      this.path[0] = { x: p1.x - dpx * edgeShift1, y: p1.y - dpy * edgeShift1, arc: false };
    +      this.path[1] = { x: p1.x + dpx * edgeShift2, y: p1.y + dpy * edgeShift2, arc: false };
    +      this.path[2] = { x: cx + dpx * (d / 2), y: cy + dpy * (d / 2), arc: true };
    +      this.path[3] = { x: p2.x + dpx * edgeShift2, y: p2.y + dpy * edgeShift2, arc: false };
    +      this.path[4] = { x: p2.x - dpx * edgeShift1, y: p2.y - dpy * edgeShift1, arc: false };
    +      this.path[5] = { x: cx - dpx * (d / 2), y: cy - dpy * (d / 2), arc: true };
    +      if (this.p1) {
    +        this.p1 = null;
    +        this.p2 = null;
    +      }
    +      if (this.params) this.params = null;
    +    }
    +  }
    +
    +  createLensWithDFfdBfd(d, ffd, bfd) {
    +    this.error = null;
    +
    +    if (!this.path) {
    +      var p1 = this.p1;
    +      var p2 = this.p2;
    +    } else {
    +      var old_params = this.getDR1R2();
    +      var p1 = geometry.midpoint(this.path[0], this.path[1]);
    +      var p2 = geometry.midpoint(this.path[3], this.path[4]);
    +      var old_d = old_params.d;
    +      var old_r1 = old_params.r1;
    +      var old_r2 = old_params.r2;
    +      var old_length = Math.hypot(p1.x - p2.x, p1.y - p2.y);
    +
    +      if (old_r1 < Infinity && old_r1 > -Infinity) {
    +        var old_curveShift1 = old_r1 - Math.sqrt(old_r1 * old_r1 - old_length * old_length / 4) * Math.sign(old_r1);
    +      } else {
    +        var old_curveShift1 = 0;
    +      }
    +
    +      if (old_r2 < Infinity && old_r2 > -Infinity) {
    +        var old_curveShift2 = old_r2 - Math.sqrt(old_r2 * old_r2 - old_length * old_length / 4) * Math.sign(old_r2);
    +      } else {
    +        var old_curveShift2 = 0;
    +      }
    +
    +      var old_edgeShift1 = old_d / 2 - old_curveShift1;
    +      var old_edgeShift2 = old_d / 2 + old_curveShift2;
    +    }
    +
    +    var len = Math.hypot(p1.x - p2.x, p1.y - p2.y);
    +    var dx = (p2.x - p1.x) / len;
    +    var dy = (p2.y - p1.y) / len;
    +    var dpx = dy;
    +    var dpy = -dx;
    +
    +    if (old_params) {
    +      // Correct p1 and p2 so that this.path[2] and this.path[5] will move symmetrically from the old lens.
    +      var correction = (old_edgeShift1 - old_edgeShift2) / 2;
    +      p1.x += dpx * correction;
    +      p1.y += dpy * correction;
    +      p2.x += dpx * correction;
    +      p2.y += dpy * correction;
    +    }
    +
    +    var n = this.getRefIndexAt(null, {wavelength: 546});
    +
    +    // Solve for r1 and r2
    +
    +    var r1_1 = (d * (-1 + n) * (d + 2 * ffd * n - Math.sqrt(d ** 2 + 4 * bfd * ffd * n ** 2))) / (2 * n * (d + (-bfd + ffd) * n));
    +    var r2_1 = -(d * (-1 + n) * (d + 2 * bfd * n - Math.sqrt(d ** 2 + 4 * bfd * ffd * n ** 2))) / (2 * n * (d + (bfd - ffd) * n));
    +
    +    var r1_2 = (d * (-1 + n) * (d + 2 * ffd * n + Math.sqrt(d ** 2 + 4 * bfd * ffd * n ** 2))) / (2 * n * (d + (-bfd + ffd) * n));
    +    var r2_2 = -(d * (-1 + n) * (d + 2 * bfd * n + Math.sqrt(d ** 2 + 4 * bfd * ffd * n ** 2))) / (2 * n * (d + (bfd - ffd) * n));
    +
    +    
    +
    +    if (!isNaN(r1_1) && !isNaN(r2_1) && (isNaN(r1_2) || isNaN(r2_2))) {
    +      // If only the first solution is valid, use that.
    +      var r1 = r1_1;
    +      var r2 = r2_1;
    +      this.createLensWithDR1R2(d, r1, r2);
    +      if (!this.path) {
    +        // If the lens is invalid as defined by d,r1,r2, still store the d,ffl,bfl parameters instead so the user may enter another set of d,ffl,bfl to get a valid lens.
    +        this.params = { d: d, ffd: ffd, bfd: bfd };
    +        this.error = 'Invalid lens parameters';
    +      }
    +    } else if (!isNaN(r1_2) && !isNaN(r2_2) && (isNaN(r1_1) || isNaN(r2_1))) {
    +      // If only the second solution is valid, use that.
    +      var r1 = r1_2;
    +      var r2 = r2_2;
    +      this.createLensWithDR1R2(d, r1, r2);
    +      if (!this.path) {
    +        // If the lens is invalid as defined by d,r1,r2, still store the d,ffl,bfl parameters instead so the user may enter another set of d,ffl,bfl to get a valid lens.
    +        this.params = { d: d, ffd: ffd, bfd: bfd };
    +        this.error = 'Invalid lens parameters';
    +      }
    +    } else if (!isNaN(r1_1) && !isNaN(r2_1) && !isNaN(r1_2) && !isNaN(r2_2)) {
    +      // If both solutions are valid, and if the old lens is valid, prefer the solution that is closest to the old lens.
    +      if (old_params) {
    +        var old_r1_1_diff = Math.abs(old_r1 - r1_1);
    +        var old_r2_1_diff = Math.abs(old_r2 - r2_1);
    +        var old_r1_2_diff = Math.abs(old_r1 - r1_2);
    +        var old_r2_2_diff = Math.abs(old_r2 - r2_2);
    +
    +        if (old_r1_1_diff + old_r2_1_diff < old_r1_2_diff + old_r2_2_diff) {
    +          var r1_a = r1_1;
    +          var r2_a = r2_1;
    +          var r1_b = r1_2;
    +          var r2_b = r2_2;
    +        } else {
    +          var r1_a = r1_2;
    +          var r2_a = r2_2;
    +          var r1_b = r1_1;
    +          var r2_b = r2_1;
    +        }
    +      } else {
    +        // If the old lens is invalid, prefer the solution with the smaller radius of curvature.
    +        if (Math.abs(r1_1) + Math.abs(r2_1) < Math.abs(r1_2) + Math.abs(r2_2)) {
    +          var r1_a = r1_1;
    +          var r2_a = r2_1;
    +          var r1_b = r1_2;
    +          var r2_b = r2_2;
    +        } else {
    +          var r1_a = r1_2;
    +          var r2_a = r2_2;
    +          var r1_b = r1_1;
    +          var r2_b = r2_1;
    +        }
    +      }
    +
    +      // Try the preferred solution first.
    +      var r1 = r1_a;
    +      var r2 = r2_a;
    +      this.createLensWithDR1R2(d, r1, r2);
    +      if (!this.path) {
    +        // Try the other solution if the preferred solution gives an invalid set of d,r1,r2.
    +        r1 = r1_b;
    +        r2 = r2_b;
    +        this.createLensWithDR1R2(d, r1, r2);
    +        if (!this.path) {
    +          // If the lens is still invalid, still store the d,ffl,bfl parameters instead so the user may enter another set of d,ffl,bfl to get a valid lens.
    +          this.params = { d: d, ffd: ffd, bfd: bfd };
    +          this.error = 'Invalid lens parameters';
    +        }
    +      }
    +    } else {
    +      // invalid lens. Store the parameters so we can restore them later.
    +      this.p1 = p1;
    +      this.p2 = p2;
    +      this.path = null;
    +      this.params = { d: d, ffd: ffd, bfd: bfd };
    +      this.error = 'Invalid lens parameters';
    +      return;
    +    }
    +  }
    +
    +  getDR1R2() {
    +    if (this.params) return this.params;
    +
    +    // get radii of curvature
    +    var center1 = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(this.path[1], this.path[2])),
    +      geometry.perpendicularBisector(geometry.line(this.path[3], this.path[2])));
    +    var r2 = geometry.distance(center1, this.path[2]);
    +    var center2 = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(this.path[4], this.path[5])),
    +      geometry.perpendicularBisector(geometry.line(this.path[0], this.path[5])));
    +    var r1 = geometry.distance(center2, this.path[5]);
    +
    +    var p1 = geometry.midpoint(this.path[0], this.path[1]);
    +    var p2 = geometry.midpoint(this.path[3], this.path[4]);
    +    var len = Math.hypot(p1.x - p2.x, p1.y - p2.y);
    +    var dx = (p2.x - p1.x) / len;
    +    var dy = (p2.y - p1.y) / len;
    +    var dpx = dy;
    +    var dpy = -dx;
    +    var cx = (p1.x + p2.x) * .5;
    +    var cy = (p1.y + p2.y) * .5;
    +    var d = geometry.distance(this.path[2], this.path[5]);
    +
    +    // correct sign
    +    if (dpx * (center1.x - this.path[2].x) + dpy * (center1.y - this.path[2].y) < 0)
    +      r2 = -r2;
    +    if (dpx * (center2.x - this.path[5].x) + dpy * (center2.y - this.path[5].y) < 0)
    +      r1 = -r1;
    +
    +    if (isNaN(r1)) {
    +      r1 = Infinity;
    +    }
    +    if (isNaN(r2)) {
    +      r2 = Infinity;
    +    }
    +    return { d: d, r1: r1, r2: r2 };
    +  }
    +
    +  getDFfdBfd() {
    +    if (this.params) return this.params;
    +
    +    var dR1R2 = this.getDR1R2();
    +    var r1 = dR1R2.r1;
    +    var r2 = dR1R2.r2;
    +    var d = dR1R2.d;
    +    var n = this.getRefIndexAt(null, {wavelength: 546});
    +
    +    var f = 1 / ((n - 1) * (1 / r1 - 1 / r2 + (n - 1) * d / (n * r1 * r2)));
    +    var ffd = f * (1 + (n - 1) * d / (n * r2));
    +    var bfd = f * (1 - (n - 1) * d / (n * r1));
    +
    +    return { d: d, ffd: ffd, bfd: bfd };
    +  }
    +};
    +
    +export default SphericalLens;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_lightSource_AngleSource.js.html b/docs/sceneObjs_lightSource_AngleSource.js.html new file mode 100644 index 00000000..f3e62c8b --- /dev/null +++ b/docs/sceneObjs_lightSource_AngleSource.js.html @@ -0,0 +1,161 @@ + + + + + JSDoc: Source: sceneObjs/lightSource/AngleSource.js + + + + + + + + + + +
    + +

    Source: sceneObjs/lightSource/AngleSource.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +import i18next from 'i18next';
    +
    +/**
    + * Finite angle point source
    + * 
    + * Tools -> Light source -> Point source (<360deg)
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The position of the point source.
    + * @property {Point} p2 - Another point on the reference line.
    + * @property {number} brightness - The brightness of the point source.
    + * @property {number} wavelength - The wavelength of the point source in nm. Only effective when "Simulate Colors" is on.
    + * @property {number} emisAngle - The angle of emission in degrees.
    + * @property {boolean} symmetric - Whether the emission is symmetric about the reference line. If not, the emission is only on one side of the reference line.
    + */
    +class AngleSource extends LineObjMixin(BaseSceneObj) {
    +  static type = 'AngleSource';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    brightness: 0.5,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    emisAngle: 36.001,
    +    symmetric: true
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.PointSource.title') + ' (<360\u00B0)');
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.common.brightness'), 0.01, 1, 0.01, this.brightness, function (obj, value) {
    +      obj.brightness = value;
    +    }, '<p>' + i18next.t('simulator:sceneObjs.common.brightnessInfo.rayDensity') + '</p><p>' + i18next.t('simulator:sceneObjs.common.brightnessInfo.rayDensitySlider') + '</p>');
    +    if (this.scene.simulateColors) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.common.wavelength') + ' (nm)', Simulator.UV_WAVELENGTH, Simulator.INFRARED_WAVELENGTH, 1, this.wavelength, function (obj, value) {
    +        obj.wavelength = value;
    +      });
    +    }
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.common.emisAngle') + ' (°)', 0, 180, 1, this.emisAngle, function (obj, value) {
    +      obj.emisAngle = value;
    +    });
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['symmetric']))) {
    +      objBar.createBoolean(i18next.t('simulator:sceneObjs.AngleSource.symmetric'), this.symmetric, function (obj, value) {
    +        obj.symmetric = value;
    +      });
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.fillStyle = isHovered ? 'cyan' : (this.scene.simulateColors ? Simulator.wavelengthToColor(this.wavelength, 1) : 'rgb(0,255,0)');
    +    ctx.fillRect(this.p1.x - 2.5 * ls, this.p1.y - 2.5 * ls, 5 * ls, 5 * ls);
    +    if (this.scene.simulateColors) {
    +      ctx.fillStyle = isHovered ? 'cyan' : ('rgb(255,255,255)');
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +    ctx.fillStyle = isHovered ? 'cyan' : ('rgb(255,0,0)');
    +    ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +  }
    +
    +  onSimulationStart() {
    +    var s = Math.PI * 2 / parseInt(this.scene.rayDensity * 500);
    +    var i0 = (this.scene.mode == 'observer') ? (-s * 2 + 1e-6) : 0;
    +
    +    var ang, x1, y1, iStart, iEnd;
    +    if (this.symmetric) {
    +      iStart = (i0 - (Math.PI / 180.0 * this.emisAngle) / 2.0);
    +      iEnd = (i0 + (Math.PI / 180.0 * this.emisAngle) / 2.0 - 1e-5);
    +    } else {
    +      iStart = i0;
    +      iEnd = (i0 + (Math.PI / 180.0 * this.emisAngle) - 1e-5);
    +    }
    +
    +    let newRays = [];
    +
    +    for (var i = iStart; i < iEnd; i = i + s) {
    +      var r = Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +
    +      ang = i + Math.atan2(this.p2.y - this.p1.y, this.p2.x - this.p1.x);
    +
    +      x1 = this.p1.x + r * Math.cos(ang);
    +      y1 = this.p1.y + r * Math.sin(ang);
    +
    +      var ray1 = geometry.line(geometry.point(this.p1.x, this.p1.y), geometry.point(x1, y1));
    +
    +      ray1.brightness_s = Math.min(this.brightness / this.scene.rayDensity, 1) * 0.5;
    +      ray1.brightness_p = Math.min(this.brightness / this.scene.rayDensity, 1) * 0.5;
    +      if (this.scene.simulateColors) {
    +        ray1.wavelength = this.wavelength;
    +      }
    +      ray1.isNew = true;
    +      if (i == i0) {
    +        ray1.gap = true;
    +      }
    +      newRays.push(ray1);
    +    }
    +
    +    return {
    +      newRays: newRays,
    +      brightnessScale: Math.min(this.brightness / this.scene.rayDensity, 1) / (this.brightness / this.scene.rayDensity)
    +    };
    +  }
    +};
    +
    +export default AngleSource;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_lightSource_Beam.js.html b/docs/sceneObjs_lightSource_Beam.js.html new file mode 100644 index 00000000..e3d84345 --- /dev/null +++ b/docs/sceneObjs_lightSource_Beam.js.html @@ -0,0 +1,229 @@ + + + + + JSDoc: Source: sceneObjs/lightSource/Beam.js + + + + + + + + + + +
    + +

    Source: sceneObjs/lightSource/Beam.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +import i18next from 'i18next';
    +
    +/**
    + * A parallel or divergent beam of light.
    + * 
    + * Tools -> Light source -> beam
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint of the segment perpendicular to the beam.
    + * @property {Point} p2 - The second endpoint of the segment perpendicular to the beam.
    + * @property {number} brightness - The brightness of the beam.
    + * @property {number} wavelength - The wavelength of the beam in nm. Only effective when "Simulate Colors" is on.
    + * @property {number} emisAngle - The angle of divergence in degrees.
    + * @property {boolean} lambert - Whether the beam is Lambertian.
    + * @property {boolean} random - Whether the beam is random.
    + * @property {Array<number>} randomNumbers - Random numbers used for random beam.
    + */
    +class Beam extends LineObjMixin(BaseSceneObj) {
    +  static type = 'Beam';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    brightness: 0.5,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    emisAngle: 0.0,
    +    lambert: false,
    +    random: false
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.Beam.title'));
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.common.brightness'), 0.01 / this.scene.lengthScale, 1 / this.scene.lengthScale, 0.01 / this.scene.lengthScale, this.brightness, function (obj, value) {
    +      obj.brightness = value;
    +    }, '<p>' + i18next.t('simulator:sceneObjs.common.brightnessInfo.rayDensity') + '</p><p>' + i18next.t('simulator:sceneObjs.common.brightnessInfo.rayDensitySlider') + '</p>');
    +    if (this.scene.simulateColors) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.common.wavelength') + ' (nm)', Simulator.UV_WAVELENGTH, Simulator.INFRARED_WAVELENGTH, 1, this.wavelength, function (obj, value) {
    +        obj.wavelength = value;
    +      });
    +    }
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['emisAngle', 'lambert', 'random']))) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.common.emisAngle') + ' (°)', 0, 180, 1, this.emisAngle, function (obj, value) {
    +        obj.emisAngle = value;
    +      });
    +      objBar.createBoolean(i18next.t('simulator:sceneObjs.common.lambert'), this.lambert, function (obj, value) {
    +        obj.lambert = value;
    +      });
    +      objBar.createBoolean(i18next.t('simulator:sceneObjs.common.random'), this.random, function (obj, value) {
    +        obj.random = value;
    +      });
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +
    +    var a_l = Math.atan2(this.p1.x - this.p2.x, this.p1.y - this.p2.y) - Math.PI / 2;
    +    ctx.strokeStyle = isHovered ? 'cyan' : (this.scene.simulateColors ? Simulator.wavelengthToColor(this.wavelength, 1) : 'rgb(0,255,0)');
    +    ctx.lineWidth = 4 * ls;
    +    ctx.lineCap = 'butt';
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x + Math.sin(a_l) * 2 * ls, this.p1.y + Math.cos(a_l) * 2 * ls);
    +    ctx.lineTo(this.p2.x + Math.sin(a_l) * 2 * ls, this.p2.y + Math.cos(a_l) * 2 * ls);
    +    ctx.stroke();
    +
    +    ctx.strokeStyle = 'rgba(128,128,128,255)';
    +    ctx.lineWidth = 2 * ls;
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.stroke();
    +    ctx.lineWidth = 1 * ls;
    +    ctx.lineCap = 'butt';
    +  }
    +
    +  onSimulationStart() {
    +    if ((this.scene.mode == 'images' || this.scene.mode == 'observer') && (this.emisAngle > 0 || this.random)) {
    +      this.warning = i18next.t('simulator:sceneObjs.Beam.imageDetectionWarning');
    +    } else {
    +      this.warning = null;
    +    }
    +
    +    var n = geometry.segmentLength(this) * this.scene.rayDensity / this.scene.lengthScale;
    +    var stepX = (this.p2.x - this.p1.x) / n;
    +    var stepY = (this.p2.y - this.p1.y) / n;
    +    var s = Math.PI * 2 / parseInt(this.scene.rayDensity * 500);
    +    var sizeX = (this.p2.x - this.p1.x);
    +    var sizeY = (this.p2.y - this.p1.y);
    +    var normal = Math.atan2(stepX, stepY) + Math.PI / 2.0;
    +    var halfAngle = this.emisAngle / 180.0 * Math.PI * 0.5;
    +    var numnAngledRays = 1.0 + Math.floor(halfAngle / s) * 2.0;
    +    var rayBrightness = 1.0 / numnAngledRays;
    +    this.initRandom();
    +
    +    let newRays = [];
    +
    +    if (!this.random) {
    +      for (var i = 0.5; i <= n; i++) {
    +        var x = this.p1.x + i * stepX;
    +        var y = this.p1.y + i * stepY;
    +        newRays.push(this.newRay(x, y, normal, 0.0, i == 0, rayBrightness));
    +        for (var angle = s; angle < halfAngle; angle += s) {
    +          newRays.push(this.newRay(x, y, normal, angle, i == 0, rayBrightness));
    +          newRays.push(this.newRay(x, y, normal, -angle, i == 0, rayBrightness));
    +        }
    +      }
    +    } else {
    +      for (var i = 0; i < n * numnAngledRays; i++) {
    +        const position = this.getRandom(i * 2);
    +        const angle = this.getRandom(i * 2 + 1);
    +        newRays.push(this.newRay(
    +          this.p1.x + position * sizeX,
    +          this.p1.y + position * sizeY,
    +          normal,
    +          (angle * 2 - 1) * halfAngle,
    +          i == 0,
    +          rayBrightness));
    +      }
    +    }
    +
    +    return {
    +      newRays: newRays,
    +      brightnessScale: Math.min(this.brightness * this.scene.lengthScale / this.scene.rayDensity * rayBrightness, 1) / (this.brightness * this.scene.lengthScale / this.scene.rayDensity * rayBrightness)
    +    };
    +  }
    +
    +
    +  /** Utility methods */
    +
    +  initRandom() {
    +    if (this.randomNumbers == undefined || !this.random) {
    +      this.clearRandom();
    +    }
    +  }
    +
    +  clearRandom() {
    +    this.randomNumbers = [];
    +  }
    +
    +  getRandom(i) {
    +    for (let j = this.randomNumbers.length; j <= i; j++) {
    +      this.randomNumbers.push(this.scene.rng());
    +    }
    +    return this.randomNumbers[i];
    +  }
    +
    +  newRay(x, y, normal, angle, gap, brightness_factor = 1.0) {
    +    var ray1 = geometry.line(geometry.point(x, y), geometry.point(x + Math.sin(normal + angle), y + Math.cos(normal + angle)));
    +    ray1.brightness_s = Math.min(this.brightness * this.scene.lengthScale / this.scene.rayDensity * brightness_factor, 1) * 0.5;
    +    ray1.brightness_p = Math.min(this.brightness * this.scene.lengthScale / this.scene.rayDensity * brightness_factor, 1) * 0.5;
    +    if (this.lambert) {
    +      const lambert = Math.cos(angle)
    +      ray1.brightness_s *= lambert;
    +      ray1.brightness_p *= lambert;
    +    }
    +    ray1.isNew = true;
    +    if (this.scene.simulateColors) {
    +      ray1.wavelength = this.wavelength;
    +    }
    +    ray1.gap = gap;
    +
    +    return ray1;
    +  }
    +};
    +
    +export default Beam;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_lightSource_PointSource.js.html b/docs/sceneObjs_lightSource_PointSource.js.html new file mode 100644 index 00000000..63372fe3 --- /dev/null +++ b/docs/sceneObjs_lightSource_PointSource.js.html @@ -0,0 +1,167 @@ + + + + + JSDoc: Source: sceneObjs/lightSource/PointSource.js + + + + + + + + + + +
    + +

    Source: sceneObjs/lightSource/PointSource.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +import i18next from 'i18next';
    +
    +/**
    + * 360 degree point source
    + * 
    + * Tools -> Light Source -> Point source (360deg)
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {number} x - The x coordinate of the point source.
    + * @property {number} y - The y coordinate of the point source.
    + * @property {number} brightness - The brightness of the point source.
    + * @property {number} wavelength - The wavelength of the light emitted by the point source in nm. Only effective when "Simulate Colors" is on.
    + */
    +class PointSource extends BaseSceneObj {
    +  static type = 'PointSource';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    x: null,
    +    y: null,
    +    brightness: 0.5,
    +    wavelength: Simulator.GREEN_WAVELENGTH
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.PointSource.title') + ' (360\u00B0)');
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.common.brightness'), 0.01, 1, 0.01, this.brightness, function (obj, value) {
    +      obj.brightness = value;
    +    }, '<p>' + i18next.t('simulator:sceneObjs.common.brightnessInfo.rayDensity') + '</p><p>' + i18next.t('simulator:sceneObjs.common.brightnessInfo.rayDensitySlider') + '</p>');
    +    if (this.scene.simulateColors) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.common.wavelength') + ' (nm)', Simulator.UV_WAVELENGTH, Simulator.INFRARED_WAVELENGTH, 1, this.wavelength, function (obj, value) {
    +        obj.wavelength = value;
    +      });
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.fillStyle = this.scene.simulateColors ? Simulator.wavelengthToColor(this.wavelength, 1) : isHovered ? 'cyan' : ('rgb(0,255,0)');
    +    ctx.fillRect(this.x - 2.5 * ls, this.y - 2.5 * ls, 5 * ls, 5 * ls);
    +    if (this.scene.simulateColors) {
    +      ctx.fillStyle = isHovered ? 'cyan' : ('rgb(255,255,255)');
    +      ctx.fillRect(this.x - 1.5 * ls, this.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  move(diffX, diffY) {
    +    this.x += diffX;
    +    this.y += diffY;
    +  }
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    this.x = mousePos.x;
    +    this.y = mousePos.y;
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    return {
    +      isDone: true
    +    };
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (mouse.isOnPoint(this)) {
    +      dragContext.part = 0;
    +      dragContext.targetPoint = geometry.point(this.x, this.y);
    +      dragContext.snapContext = {};
    +      return dragContext;
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    if (shift) {
    +      var mousePos = mouse.getPosSnappedToDirection(dragContext.targetPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }], dragContext.snapContext);
    +    } else {
    +      var mousePos = mouse.getPosSnappedToGrid();
    +      dragContext.snapContext = {};
    +    }
    +
    +    this.x = mousePos.x;
    +    this.y = mousePos.y;
    +  }
    +
    +  onSimulationStart() {
    +    let newRays = [];
    +
    +    var s = Math.PI * 2 / parseInt(this.scene.rayDensity * 500);
    +    var i0 = (this.scene.mode == 'observer') ? (-s * 2 + 1e-6) : 0;
    +    for (var i = i0; i < (Math.PI * 2 - 1e-5); i = i + s) {
    +      var ray1 = geometry.line(geometry.point(this.x, this.y), geometry.point(this.x + Math.sin(i), this.y + Math.cos(i)));
    +      ray1.brightness_s = Math.min(this.brightness / this.scene.rayDensity, 1) * 0.5;
    +      ray1.brightness_p = Math.min(this.brightness / this.scene.rayDensity, 1) * 0.5;
    +      ray1.isNew = true;
    +      if (this.scene.simulateColors) {
    +        ray1.wavelength = this.wavelength;
    +      }
    +      if (i == i0) {
    +        ray1.gap = true;
    +      }
    +      newRays.push(ray1);
    +    }
    +
    +    return {
    +      newRays: newRays,
    +      brightnessScale: Math.min(this.brightness / this.scene.rayDensity, 1) / (this.brightness / this.scene.rayDensity)
    +    };
    +  }
    +};
    +
    +export default PointSource;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_lightSource_SingleRay.js.html b/docs/sceneObjs_lightSource_SingleRay.js.html new file mode 100644 index 00000000..f01e48fd --- /dev/null +++ b/docs/sceneObjs_lightSource_SingleRay.js.html @@ -0,0 +1,116 @@ + + + + + JSDoc: Source: sceneObjs/lightSource/SingleRay.js + + + + + + + + + + +
    + +

    Source: sceneObjs/lightSource/SingleRay.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +import i18next from 'i18next';
    +
    +/**
    + * A single ray of light.
    + * 
    + * Tools -> Light source -> Single ray
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The start point of the ray.
    + * @property {Point} p2 - Another point on the ray.
    + * @property {number} brightness - The brightness of the ray.
    + * @property {number} wavelength - The wavelength of the ray in nm. Only effective when "Simulate Colors" is on.
    + */
    +class SingleRay extends LineObjMixin(BaseSceneObj) {
    +  static type = 'SingleRay';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    brightness: 1,
    +    wavelength: Simulator.GREEN_WAVELENGTH
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.SingleRay.title'));
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.common.brightness'), 0.01, 1, 0.01, this.brightness, function (obj, value) {
    +      obj.brightness = value;
    +    });
    +    if (this.scene.simulateColors) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.common.wavelength') + ' (nm)', Simulator.UV_WAVELENGTH, Simulator.INFRARED_WAVELENGTH, 1, this.wavelength, function (obj, value) {
    +        obj.wavelength = value;
    +      });
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.fillStyle = isHovered ? 'cyan' : (this.scene.simulateColors ? Simulator.wavelengthToColor(this.wavelength, 1) : 'rgb(255,0,0)');
    +    ctx.fillRect(this.p1.x - 2.5 * ls, this.p1.y - 2.5 * ls, 5 * ls, 5 * ls);
    +    ctx.fillStyle = isHovered ? 'cyan' : ('rgb(255,0,0)');
    +    ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +  }
    +
    +  onSimulationStart() {
    +    var ray1 = geometry.line(this.p1, this.p2);
    +    ray1.brightness_s = 0.5 * this.brightness;
    +    ray1.brightness_p = 0.5 * this.brightness;
    +    if (this.scene.simulateColors) {
    +      ray1.wavelength = this.wavelength;
    +    }
    +    ray1.gap = true;
    +    ray1.isNew = true;
    +    return {
    +      newRays: [ray1]
    +    };
    +  }
    +};
    +
    +export default SingleRay;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_mirror_ArcMirror.js.html b/docs/sceneObjs_mirror_ArcMirror.js.html new file mode 100644 index 00000000..ad40d119 --- /dev/null +++ b/docs/sceneObjs_mirror_ArcMirror.js.html @@ -0,0 +1,349 @@ + + + + + JSDoc: Source: sceneObjs/mirror/ArcMirror.js + + + + + + + + + + +
    + +

    Source: sceneObjs/mirror/ArcMirror.js

    + + + + + + +
    +
    +
    import BaseFilter from '../BaseFilter.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Mirror with shape of a circular arc.
    + * 
    + * Tools -> Mirror -> Circular Arc
    + * @class
    + * @extends BaseFilter
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint.
    + * @property {Point} p2 - The second endpoint.
    + * @property {Point} p3 - The control point on the arc.
    + * @property {boolean} filter - Whether it is a dichroic mirror.
    + * @property {boolean} invert - If true, the ray with wavelength outside the bandwidth is reflected. If false, the ray with wavelength inside the bandwidth is reflected.
    + * @property {number} wavelength - The target wavelength if dichroic is enabled. The unit is nm.
    + * @property {number} bandwidth - The bandwidth if dichroic is enabled. The unit is nm.
    + */
    +class ArcMirror extends BaseFilter {
    +  static type = 'ArcMirror';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    p3: null,
    +    filter: false,
    +    invert: false,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    bandwidth: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:meta.parentheses', { main: i18next.t('main:tools.categories.mirror'), sub: i18next.t('main:tools.ArcMirror.title') }));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.fillStyle = 'rgb(255,0,255)';
    +    if (this.p3 && this.p2) {
    +      var center = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(this.p1, this.p3)), geometry.perpendicularBisector(geometry.line(this.p2, this.p3)));
    +      if (isFinite(center.x) && isFinite(center.y)) {
    +        var r = geometry.distance(center, this.p3);
    +        var a1 = Math.atan2(this.p1.y - center.y, this.p1.x - center.x);
    +        var a2 = Math.atan2(this.p2.y - center.y, this.p2.x - center.x);
    +        var a3 = Math.atan2(this.p3.y - center.y, this.p3.x - center.x);
    +        ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(168,168,168)');
    +        ctx.lineWidth = 1 * ls;
    +        ctx.beginPath();
    +        ctx.arc(center.x, center.y, r, a1, a2, (a2 < a3 && a3 < a1) || (a1 < a2 && a2 < a3) || (a3 < a1 && a1 < a2));
    +        ctx.stroke();
    +        if (isHovered) {
    +          ctx.fillRect(this.p3.x - 1.5 * ls, this.p3.y - 1.5 * ls, 3 * ls, 3 * ls);
    +          ctx.fillStyle = 'rgb(255,0,0)';
    +          ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +          ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +        }
    +      } else {
    +        // The three points on the arc is colinear. Treat as a line segment.
    +        ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(168,168,168)');
    +        ctx.lineWidth = 1 * ls;
    +        ctx.beginPath();
    +        ctx.moveTo(this.p1.x, this.p1.y);
    +        ctx.lineTo(this.p2.x, this.p2.y);
    +        ctx.stroke();
    +
    +        ctx.fillRect(this.p3.x - 1.5 * ls, this.p3.y - 1.5 * ls, 3 * ls, 3 * ls);
    +        ctx.fillStyle = 'rgb(255,0,0)';
    +        ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +        ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      }
    +    } else if (this.p2) {
    +      ctx.fillStyle = 'rgb(255,0,0)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    } else {
    +      ctx.fillStyle = 'rgb(255,0,0)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  move(diffX, diffY) {
    +    this.p1.x = this.p1.x + diffX;
    +    this.p1.y = this.p1.y + diffY;
    +    this.p2.x = this.p2.x + diffX;
    +    this.p2.y = this.p2.y + diffY;
    +    this.p3.x = this.p3.x + diffX;
    +    this.p3.y = this.p3.y + diffY;
    +  }
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    if (!this.constructionPoint) {
    +      // Initialize the construction stage.
    +      this.constructionPoint = mouse.getPosSnappedToGrid();
    +      this.p1 = this.constructionPoint;
    +      this.p2 = null;
    +      this.p3 = null;
    +    }
    +
    +    if (!this.p2 && !this.p3) {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +      return;
    +    }
    +
    +    if (this.p2 && !this.p3 && !mouse.isOnPoint(this.p1)) {
    +      if (shift) {
    +        this.p2 = mouse.getPosSnappedToDirection(this.p1, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +      } else {
    +        this.p2 = mouse.getPosSnappedToGrid();
    +      }
    +      this.p3 = mouse.getPosSnappedToGrid();
    +      return;
    +    }
    +  }
    +
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    if (!this.p3 && !mouse.isOnPoint(this.p1)) {
    +      if (shift) {
    +        this.p2 = mouse.getPosSnappedToDirection(this.constructionPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +      } else {
    +        this.p2 = mouse.getPosSnappedToGrid();
    +      }
    +
    +      this.p1 = ctrl ? geometry.point(2 * this.constructionPoint.x - this.p2.x, 2 * this.constructionPoint.y - this.p2.y) : this.constructionPoint;
    +
    +      return;
    +    }
    +    if (this.p3) {
    +      this.p3 = mouse.getPosSnappedToGrid();
    +      return;
    +    }
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    if (this.p2 && !this.p3 && !mouse.isOnPoint(this.p1)) {
    +      this.p3 = mouse.getPosSnappedToGrid();
    +      return;
    +    }
    +    if (this.p3 && !mouse.isOnPoint(this.p2)) {
    +      this.p3 = mouse.getPosSnappedToGrid();
    +      delete this.constructionPoint;
    +      return {
    +        isDone: true
    +      };
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (mouse.isOnPoint(this.p1) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p2) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p3)) {
    +      dragContext.part = 1;
    +      dragContext.targetPoint = geometry.point(this.p1.x, this.p1.y);
    +      return dragContext;
    +    }
    +    if (mouse.isOnPoint(this.p2) && geometry.distanceSquared(mouse.pos, this.p2) <= geometry.distanceSquared(mouse.pos, this.p3)) {
    +      dragContext.part = 2;
    +      dragContext.targetPoint = geometry.point(this.p2.x, this.p2.y);
    +      return dragContext;
    +    }
    +    if (mouse.isOnPoint(this.p3)) {
    +      dragContext.part = 3;
    +      dragContext.targetPoint = geometry.point(this.p3.x, this.p3.y);
    +      return dragContext;
    +    }
    +
    +    var center = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(this.p1, this.p3)), geometry.perpendicularBisector(geometry.line(this.p2, this.p3)));
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    if (isFinite(center.x) && isFinite(center.y)) {
    +      var r = geometry.distance(center, this.p3);
    +      var a1 = Math.atan2(this.p1.y - center.y, this.p1.x - center.x);
    +      var a2 = Math.atan2(this.p2.y - center.y, this.p2.x - center.x);
    +      var a3 = Math.atan2(this.p3.y - center.y, this.p3.x - center.x);
    +      var a_m = Math.atan2(mouse.pos.y - center.y, mouse.pos.x - center.x);
    +      if (Math.abs(geometry.distance(center, mouse.pos) - r) < mouse.getClickExtent() && (((a2 < a3 && a3 < a1) || (a1 < a2 && a2 < a3) || (a3 < a1 && a1 < a2)) == ((a2 < a_m && a_m < a1) || (a1 < a2 && a2 < a_m) || (a_m < a1 && a1 < a2)))) {
    +        // Dragging the entire obj
    +        dragContext.part = 0;
    +        dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +        dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +        dragContext.snapContext = {};
    +        return dragContext;
    +      }
    +    } else {
    +      // The three points on the arc is colinear. Treat as a line segment.
    +      if (mouse.isOnSegment(this)) {
    +        dragContext.part = 0;
    +        dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +        dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +        dragContext.snapContext = {};
    +        return dragContext;
    +      }
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    var basePoint;
    +    if (dragContext.part == 1) {
    +      // Dragging the first endpoint
    +      basePoint = ctrl ? geometry.segmentMidpoint(dragContext.originalObj) : dragContext.originalObj.p2;
    +
    +      this.p1 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +      this.p2 = ctrl ? geometry.point(2 * basePoint.x - this.p1.x, 2 * basePoint.y - this.p1.y) : basePoint;
    +    }
    +    if (dragContext.part == 2) {
    +      // Dragging the second endpoint
    +      basePoint = ctrl ? geometry.segmentMidpoint(dragContext.originalObj) : dragContext.originalObj.p1;
    +
    +      this.p2 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +      this.p1 = ctrl ? geometry.point(2 * basePoint.x - this.p2.x, 2 * basePoint.y - this.p2.y) : basePoint;
    +    }
    +    if (dragContext.part == 3) {
    +      // Dragging the third endpoint
    +      this.p3 = mouse.getPosSnappedToGrid();
    +    }
    +    if (dragContext.part == 0) {
    +      // Dragging the entire obj
    +      if (shift) {
    +        var mousePos = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }, { x: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y), y: -(dragContext.originalObj.p2.x - dragContext.originalObj.p1.x) }], dragContext.snapContext);
    +      } else {
    +        var mousePos = mouse.getPosSnappedToGrid();;
    +        dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +      }
    +
    +      var mouseDiffX = dragContext.mousePos1.x - mousePos.x; // The X difference between the mouse position now and at the previous moment
    +      var mouseDiffY = dragContext.mousePos1.y - mousePos.y; // The Y difference between the mouse position now and at the previous moment
    +      // Move the first point
    +      this.p1.x = this.p1.x - mouseDiffX;
    +      this.p1.y = this.p1.y - mouseDiffY;
    +      // Move the second point
    +      this.p2.x = this.p2.x - mouseDiffX;
    +      this.p2.y = this.p2.y - mouseDiffY;
    +
    +      this.p3.x = this.p3.x - mouseDiffX;
    +      this.p3.y = this.p3.y - mouseDiffY;
    +
    +      // Update the mouse position
    +      dragContext.mousePos1 = mousePos;
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.checkRayIntersectFilter(ray)) {
    +      if (!this.p3) { return null; }
    +      var center = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(this.p1, this.p3)), geometry.perpendicularBisector(geometry.line(this.p2, this.p3)));
    +      if (isFinite(center.x) && isFinite(center.y)) {
    +        var rp_temp = geometry.lineCircleIntersections(geometry.line(ray.p1, ray.p2), geometry.circle(center, this.p2));
    +        var rp_exist = [];
    +        var rp_lensq = [];
    +        for (var i = 1; i <= 2; i++) {
    +          rp_exist[i] = !geometry.intersectionIsOnSegment(geometry.linesIntersection(geometry.line(this.p1, this.p2), geometry.line(this.p3, rp_temp[i])), geometry.line(this.p3, rp_temp[i])) && geometry.intersectionIsOnRay(rp_temp[i], ray) && geometry.distanceSquared(rp_temp[i], ray.p1) > Simulator.MIN_RAY_SEGMENT_LENGTH_SQUARED * this.scene.lengthScale * this.scene.lengthScale;
    +          rp_lensq[i] = geometry.distanceSquared(ray.p1, rp_temp[i]);
    +        }
    +        if (rp_exist[1] && ((!rp_exist[2]) || rp_lensq[1] < rp_lensq[2])) { return rp_temp[1]; }
    +        if (rp_exist[2] && ((!rp_exist[1]) || rp_lensq[2] < rp_lensq[1])) { return rp_temp[2]; }
    +      } else {
    +        // The three points on the arc is colinear. Treat as a line segment.
    +        var rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(this.p1, this.p2));
    +
    +        if (geometry.intersectionIsOnSegment(rp_temp, this) && geometry.intersectionIsOnRay(rp_temp, ray)) {
    +          return rp_temp;
    +        } else {
    +          return null;
    +        }
    +      }
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    var rx = ray.p1.x - incidentPoint.x;
    +    var ry = ray.p1.y - incidentPoint.y;
    +    var mx = this.p2.x - this.p1.x;
    +    var my = this.p2.y - this.p1.y;
    +
    +    var center = geometry.linesIntersection(geometry.perpendicularBisector(geometry.line(this.p1, this.p3)), geometry.perpendicularBisector(geometry.line(this.p2, this.p3)));
    +    if (isFinite(center.x) && isFinite(center.y)) {
    +      var cx = center.x - incidentPoint.x;
    +      var cy = center.y - incidentPoint.y;
    +      var c_sq = cx * cx + cy * cy;
    +      var r_dot_c = rx * cx + ry * cy;
    +      ray.p1 = incidentPoint;
    +      ray.p2 = geometry.point(incidentPoint.x - c_sq * rx + 2 * r_dot_c * cx, incidentPoint.y - c_sq * ry + 2 * r_dot_c * cy);
    +    } else {
    +      // The three points on the arc is colinear. Treat as a line segment.
    +
    +      var rx = ray.p1.x - incidentPoint.x;
    +      var ry = ray.p1.y - incidentPoint.y;
    +      var mx = this.p2.x - this.p1.x;
    +      var my = this.p2.y - this.p1.y;
    +
    +      ray.p1 = incidentPoint;
    +      ray.p2 = geometry.point(incidentPoint.x + rx * (my * my - mx * mx) - 2 * ry * mx * my, incidentPoint.y + ry * (mx * mx - my * my) - 2 * rx * mx * my);
    +    }
    +  }
    +};
    +
    +export default ArcMirror;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_mirror_BeamSplitter.js.html b/docs/sceneObjs_mirror_BeamSplitter.js.html new file mode 100644 index 00000000..60683778 --- /dev/null +++ b/docs/sceneObjs_mirror_BeamSplitter.js.html @@ -0,0 +1,154 @@ + + + + + JSDoc: Source: sceneObjs/mirror/BeamSplitter.js + + + + + + + + + + +
    + +

    Source: sceneObjs/mirror/BeamSplitter.js

    + + + + + + +
    +
    +
    import BaseFilter from '../BaseFilter.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Beam splitter.
    + * 
    + * Tools -> Mirror -> Beam splitter
    + * @class
    + * @extends BaseFilter
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint.
    + * @property {Point} p2 - The second endpoint.
    + * @property {number} transRatio - The transmission ratio.
    + * @property {boolean} filter - Whether it is a dichroic beam splitter.
    + * @property {boolean} invert - If true, the ray with wavelength outside the bandwidth interacts with the beam splitter. If false, the ray with wavelength inside the bandwidth interacts with the beam splitter.
    + * @property {number} wavelength - The target wavelength if dichroic is enabled. The unit is nm.
    + * @property {number} bandwidth - The bandwidth if dichroic is enabled. The unit is nm.
    + */
    +class BeamSplitter extends LineObjMixin(BaseFilter) {
    +  static type = 'BeamSplitter';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    transRatio: 0.5,
    +    filter: false,
    +    invert: false,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    bandwidth: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.BeamSplitter.title'));
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.BeamSplitter.transRatio'), 0, 1, 0.01, this.transRatio, function (obj, value) {
    +      obj.transRatio = value;
    +    });
    +
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +    
    +    ctx.strokeStyle = isHovered ? 'cyan' : ('rgb(100,100,168)');
    +    ctx.lineWidth = 1 * ls;
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.stroke();
    +    ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(100,100,168)');
    +    ctx.setLineDash([15 * ls, 15 * ls]);
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.stroke();
    +    ctx.setLineDash([]);
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.checkRayIntersectFilter(ray)) {
    +      return this.checkRayIntersectsShape(ray);
    +    } else {
    +      return null;
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    var rx = ray.p1.x - incidentPoint.x;
    +    var ry = ray.p1.y - incidentPoint.y;
    +
    +    ray.p1 = incidentPoint;
    +    var mx = this.p2.x - this.p1.x;
    +    var my = this.p2.y - this.p1.y;
    +    ray.p2 = geometry.point(incidentPoint.x + rx * (my * my - mx * mx) - 2 * ry * mx * my, incidentPoint.y + ry * (mx * mx - my * my) - 2 * rx * mx * my);
    +    var ray2 = geometry.line(incidentPoint, geometry.point(incidentPoint.x - rx, incidentPoint.y - ry));
    +    var transmission = this.transRatio;
    +    ray2.brightness_s = transmission * ray.brightness_s;
    +    ray2.brightness_p = transmission * ray.brightness_p;
    +    ray2.wavelength = ray.wavelength;
    +    ray.brightness_s *= (1 - transmission);
    +    ray.brightness_p *= (1 - transmission);
    +    if (ray2.brightness_s + ray2.brightness_p > .01) {
    +      return {
    +        newRays: [ray2]
    +      };
    +    } else {
    +      return {
    +        truncation: ray2.brightness_s + ray2.brightness_p
    +      };
    +    }
    +  }
    +};
    +
    +export default BeamSplitter;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_mirror_CustomMirror.js.html b/docs/sceneObjs_mirror_CustomMirror.js.html new file mode 100644 index 00000000..ef16d907 --- /dev/null +++ b/docs/sceneObjs_mirror_CustomMirror.js.html @@ -0,0 +1,283 @@ + + + + + JSDoc: Source: sceneObjs/mirror/CustomMirror.js + + + + + + + + + + +
    + +

    Source: sceneObjs/mirror/CustomMirror.js

    + + + + + + +
    +
    +
    import BaseFilter from '../BaseFilter.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +import { evaluateLatex } from '../../equation.js';
    +
    +/**
    + * Mirror with shape defined by a custom equation.
    + * 
    + * Tools -> Mirror -> Custom equation
    + * @class
    + * @extends BaseFilter
    + * @memberof sceneObjs
    + * @property {Point} p1 - The point corresponding to (-1,0) in the coordinate system of the equation.
    + * @property {Point} p2 - The point corresponding to (1,0) in the coordinate system of the equation.
    + * @property {string} eqn - The equation of the mirror. The variable is x.
    + * @property {boolean} filter - Whether it is a dichroic mirror.
    + * @property {boolean} invert - If true, the ray with wavelength outside the bandwidth is reflected. If false, the ray with wavelength inside the bandwidth is reflected.
    + * @property {number} wavelength - The target wavelength if dichroic is enabled. The unit is nm.
    + * @property {number} bandwidth - The bandwidth if dichroic is enabled. The unit is nm.
    + * @property {Array<Point>} tmp_points - The points on the curve.
    + * @property {number} tmp_i - The index of the point on the curve where the ray is incident.
    + */
    +class CustomMirror extends LineObjMixin(BaseFilter) {
    +  static type = 'CustomMirror';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    eqn: "0.5\\cdot\\sqrt{1-x^2}",
    +    filter: false,
    +    invert: false,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    bandwidth: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.categories.mirror'));
    +    objBar.createEquation('y = ', this.eqn, function (obj, value) {
    +      obj.eqn = value;
    +    }, '<ul><li>' + i18next.t('simulator:sceneObjs.common.eqnInfo.constants') + '<br><code>pi e</code></li><li>' + i18next.t('simulator:sceneObjs.common.eqnInfo.operators') + '<br><code>+ - * / ^</code></li><li>' + i18next.t('simulator:sceneObjs.common.eqnInfo.functions') + '<br><code>sqrt sin cos tan sec csc cot sinh cosh tanh log exp arcsin arccos arctan arcsinh arccosh arctanh floor round ceil trunc sgn max min abs</code></li></ul>');
    +    
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +
    +    var fn;
    +    try {
    +      fn = evaluateLatex(this.eqn);
    +    } catch (e) {
    +      delete this.tmp_points;
    +      ctx.fillStyle = "red"
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      this.error = e.toString();
    +      return;
    +    }
    +    ctx.fillStyle = 'rgb(255,0,255)';
    +    var p12d = geometry.distance(this.p1, this.p2);
    +    // unit vector from p1 to p2
    +    var dir1 = [(this.p2.x - this.p1.x) / p12d, (this.p2.y - this.p1.y) / p12d];
    +    // perpendicular direction
    +    var dir2 = [dir1[1], -dir1[0]];
    +    // get height of (this section of) parabola
    +    var x0 = p12d / 2;
    +    var i;
    +    ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(168,168,168)');
    +    ctx.lineWidth = 1 * ls;
    +    ctx.beginPath();
    +    this.tmp_points = [];
    +    var lastError = "";
    +    for (i = -0.1 * this.scene.lengthScale; i < p12d + 0.09 * this.scene.lengthScale; i += 0.1 * this.scene.lengthScale) {
    +      // avoid using exact integers to avoid problems with detecting intersections
    +      var ix = i + 0.05 * this.scene.lengthScale;
    +      if (ix < 0) ix = 0;
    +      if (ix > p12d) ix = p12d;
    +      var x = ix - x0;
    +      var scaled_x = 2 * x / p12d;
    +      var scaled_y;
    +      try {
    +        scaled_y = fn({ x: scaled_x, "pi": Math.PI });
    +        var y = scaled_y * p12d * 0.5;
    +        var pt = geometry.point(this.p1.x + dir1[0] * ix + dir2[0] * y, this.p1.y + dir1[1] * ix + dir2[1] * y);
    +        if (i == -0.1) {
    +          ctx.moveTo(pt.x, pt.y);
    +        } else {
    +          ctx.lineTo(pt.x, pt.y);
    +        }
    +        this.tmp_points.push(pt);
    +      } catch (e) {
    +        lastError = e;
    +      }
    +    }
    +    if (this.tmp_points.length == 0) {
    +      delete this.tmp_points;
    +      ctx.fillStyle = "red"
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      this.error = lastError.toString();
    +      return;
    +    }
    +    ctx.stroke();
    +    if (isHovered) {
    +      ctx.fillStyle = 'rgb(255,0,0)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +
    +    this.error = null;
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (mouse.isOnPoint(this.p1) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p2)) {
    +      dragContext.part = 1;
    +      dragContext.targetPoint = geometry.point(this.p1.x, this.p1.y);
    +      return dragContext;
    +    }
    +    if (mouse.isOnPoint(this.p2)) {
    +      dragContext.part = 2;
    +      dragContext.targetPoint = geometry.point(this.p2.x, this.p2.y);
    +      return dragContext;
    +    }
    +
    +    if (!this.tmp_points) return;
    +    var i;
    +    var pts = this.tmp_points;
    +    for (i = 0; i < pts.length - 1; i++) {
    +
    +      var seg = geometry.line(pts[i], pts[i + 1]);
    +      if (mouse.isOnSegment(seg)) {
    +        // Dragging the entire this
    +        const mousePos = mouse.getPosSnappedToGrid();
    +        dragContext.part = 0;
    +        dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +        dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +        dragContext.snapContext = {};
    +        return dragContext;
    +      }
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (!this.tmp_points || !this.checkRayIntersectFilter(ray)) return;
    +    var i, j;
    +    var pts = this.tmp_points;
    +    var dir = geometry.distance(this.p2, ray.p1) > geometry.distance(this.p1, ray.p1);
    +    var incidentPoint;
    +    for (j = 0; j < pts.length - 1; j++) {
    +      i = dir ? j : (pts.length - 2 - j);
    +      var rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(pts[i], pts[i + 1]));
    +      var seg = geometry.line(pts[i], pts[i + 1]);
    +      // need Simulator.MIN_RAY_SEGMENT_LENGTH check to handle a ray that reflects off mirror multiple times
    +      if (geometry.distance(ray.p1, rp_temp) < Simulator.MIN_RAY_SEGMENT_LENGTH * this.scene.lengthScale)
    +        continue;
    +      if (geometry.intersectionIsOnSegment(rp_temp, seg) && geometry.intersectionIsOnRay(rp_temp, ray)) {
    +        if (!incidentPoint || geometry.distance(ray.p1, rp_temp) < geometry.distance(ray.p1, incidentPoint)) {
    +          incidentPoint = rp_temp;
    +          this.tmp_i = i;
    +        }
    +      }
    +    }
    +    if (incidentPoint) return incidentPoint;
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    var rx = ray.p1.x - incidentPoint.x;
    +    var ry = ray.p1.y - incidentPoint.y;
    +    var i = this.tmp_i;
    +    var pts = this.tmp_points;
    +    var seg = geometry.line(pts[i], pts[i + 1]);
    +    var mx = seg.p2.x - seg.p1.x;
    +    var my = seg.p2.y - seg.p1.y;
    +
    +
    +    ray.p1 = incidentPoint;
    +    var frac;
    +    if (Math.abs(mx) > Math.abs(my)) {
    +      frac = (incidentPoint.x - seg.p1.x) / mx;
    +    } else {
    +      frac = (incidentPoint.y - seg.p1.y) / my;
    +    }
    +
    +    if ((i == 0 && frac < 0.5) || (i == pts.length - 2 && frac >= 0.5)) {
    +      ray.p2 = geometry.point(incidentPoint.x + rx * (my * my - mx * mx) - 2 * ry * mx * my, incidentPoint.y + ry * (mx * mx - my * my) - 2 * rx * mx * my);
    +    } else {
    +      // Use a simple trick to smooth out the slopes of outgoing rays so that image detection works.
    +      // However, a more proper numerical algorithm from the beginning (especially to handle singularities) is still desired.
    +
    +      var outx = incidentPoint.x + rx * (my * my - mx * mx) - 2 * ry * mx * my;
    +      var outy = incidentPoint.y + ry * (mx * mx - my * my) - 2 * rx * mx * my;
    +
    +      var segA;
    +      if (frac < 0.5) {
    +        segA = geometry.line(pts[i - 1], pts[i]);
    +      } else {
    +        segA = geometry.line(pts[i + 1], pts[i + 2]);
    +      }
    +      var rxA = ray.p1.x - incidentPoint.x;
    +      var ryA = ray.p1.y - incidentPoint.y;
    +      var mxA = segA.p2.x - segA.p1.x;
    +      var myA = segA.p2.y - segA.p1.y;
    +
    +      var outxA = incidentPoint.x + rxA * (myA * myA - mxA * mxA) - 2 * ryA * mxA * myA;
    +      var outyA = incidentPoint.y + ryA * (mxA * mxA - myA * myA) - 2 * rxA * mxA * myA;
    +
    +      var outxFinal;
    +      var outyFinal;
    +
    +      if (frac < 0.5) {
    +        outxFinal = outx * (0.5 + frac) + outxA * (0.5 - frac);
    +        outyFinal = outy * (0.5 + frac) + outyA * (0.5 - frac);
    +      } else {
    +        outxFinal = outxA * (frac - 0.5) + outx * (1.5 - frac);
    +        outyFinal = outyA * (frac - 0.5) + outy * (1.5 - frac);
    +      }
    +      //console.log(frac);
    +      ray.p2 = geometry.point(outxFinal, outyFinal);
    +    }
    +  }
    +};
    +
    +export default CustomMirror;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_mirror_IdealMirror.js.html b/docs/sceneObjs_mirror_IdealMirror.js.html new file mode 100644 index 00000000..63cb1162 --- /dev/null +++ b/docs/sceneObjs_mirror_IdealMirror.js.html @@ -0,0 +1,226 @@ + + + + + JSDoc: Source: sceneObjs/mirror/IdealMirror.js + + + + + + + + + + +
    + +

    Source: sceneObjs/mirror/IdealMirror.js

    + + + + + + +
    +
    +
    import BaseFilter from '../BaseFilter.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Ideal curved mirror that follows the mirror equation exactly.
    + * 
    + * Tools -> Mirror -> Ideal curved mirror
    + * @class
    + * @extends BaseFilter
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint.
    + * @property {Point} p2 - The second endpoint.
    + * @property {number} focalLength - The focal length. The Cartesian sign convention is not used. But if the Cartesian sign convention is enabled (as a preference setting), the focal length changes sign in the UI.
    + */
    +class IdealMirror extends LineObjMixin(BaseFilter) {
    +  static type = 'IdealMirror';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    focalLength: 100,
    +    filter: false,
    +    invert: false,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    bandwidth: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.IdealMirror.title'));
    +    var cartesianSign = false;
    +    if (localStorage && localStorage.rayOpticsCartesianSign) {
    +      cartesianSign = localStorage.rayOpticsCartesianSign == "true";
    +    }
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.common.focalLength'), -1000 * this.scene.lengthScale, 1000 * this.scene.lengthScale, 1 * this.scene.lengthScale, this.focalLength * (cartesianSign ? -1 : 1), function (obj, value) {
    +      obj.focalLength = value * (cartesianSign ? -1 : 1);
    +    }, i18next.t('simulator:sceneObjs.common.lengthUnitInfo'));
    +    if (objBar.showAdvanced(cartesianSign)) {
    +      objBar.createBoolean(i18next.t('simulator:sceneObjs.IdealMirror.cartesianSign'), cartesianSign, function (obj, value) {
    +        localStorage.rayOpticsCartesianSign = value ? "true" : "false";
    +      }, null, true);
    +    }
    +
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +
    +    var len = Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +    var par_x = (this.p2.x - this.p1.x) / len;
    +    var par_y = (this.p2.y - this.p1.y) / len;
    +    var per_x = par_y;
    +    var per_y = -par_x;
    +
    +    var arrow_size_per = 5 * ls;
    +    var arrow_size_par = 5 * ls;
    +    var center_size = 1 * ls;
    +
    +    // Draw the line segment
    +    ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(168,168,168)');
    +    ctx.globalAlpha = 1;
    +    ctx.lineWidth = 1 * ls;
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.stroke();
    +    ctx.lineWidth = 1 * ls;
    +
    +
    +    // Draw the center point of the mirror
    +    var center = geometry.segmentMidpoint(this);
    +    ctx.strokeStyle = 'rgb(255,255,255)';
    +    ctx.beginPath();
    +    ctx.moveTo(center.x - per_x * center_size, center.y - per_y * center_size);
    +    ctx.lineTo(center.x + per_x * center_size, center.y + per_y * center_size);
    +    ctx.stroke();
    +
    +
    +    ctx.fillStyle = 'rgb(255,0,0)';
    +
    +
    +    // Draw the arrow for the two-sided version
    +    if (this.focalLength < 0) {
    +      // Draw the arrow (p1)
    +      ctx.beginPath();
    +      ctx.moveTo(this.p1.x - par_x * arrow_size_par, this.p1.y - par_y * arrow_size_par);
    +      ctx.lineTo(this.p1.x + par_x * arrow_size_par + per_x * arrow_size_per, this.p1.y + par_y * arrow_size_par + per_y * arrow_size_per);
    +      ctx.lineTo(this.p1.x + par_x * arrow_size_par - per_x * arrow_size_per, this.p1.y + par_y * arrow_size_par - per_y * arrow_size_per);
    +      ctx.fill();
    +
    +      // Draw the arrow (p2)
    +      ctx.beginPath();
    +      ctx.moveTo(this.p2.x + par_x * arrow_size_par, this.p2.y + par_y * arrow_size_par);
    +      ctx.lineTo(this.p2.x - par_x * arrow_size_par + per_x * arrow_size_per, this.p2.y - par_y * arrow_size_par + per_y * arrow_size_per);
    +      ctx.lineTo(this.p2.x - par_x * arrow_size_par - per_x * arrow_size_per, this.p2.y - par_y * arrow_size_par - per_y * arrow_size_per);
    +      ctx.fill();
    +    }
    +    if (this.focalLength > 0) {
    +      // Draw the arrow (p1)
    +      ctx.beginPath();
    +      ctx.moveTo(this.p1.x + par_x * arrow_size_par, this.p1.y + par_y * arrow_size_par);
    +      ctx.lineTo(this.p1.x - par_x * arrow_size_par + per_x * arrow_size_per, this.p1.y - par_y * arrow_size_par + per_y * arrow_size_per);
    +      ctx.lineTo(this.p1.x - par_x * arrow_size_par - per_x * arrow_size_per, this.p1.y - par_y * arrow_size_par - per_y * arrow_size_per);
    +      ctx.fill();
    +
    +      // Draw the arrow (p2)
    +      ctx.beginPath();
    +      ctx.moveTo(this.p2.x - par_x * arrow_size_par, this.p2.y - par_y * arrow_size_par);
    +      ctx.lineTo(this.p2.x + par_x * arrow_size_par + per_x * arrow_size_per, this.p2.y + par_y * arrow_size_par + per_y * arrow_size_per);
    +      ctx.lineTo(this.p2.x + par_x * arrow_size_par - per_x * arrow_size_per, this.p2.y + par_y * arrow_size_par - per_y * arrow_size_per);
    +      ctx.fill();
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.checkRayIntersectFilter(ray)) {
    +      return this.checkRayIntersectsShape(ray);
    +    } else {
    +      return null;
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    var mirror_length = geometry.segmentLength(this);
    +    var main_line_unitvector_x = (-this.p1.y + this.p2.y) / mirror_length;
    +    var main_line_unitvector_y = (this.p1.x - this.p2.x) / mirror_length;
    +    var mid_point = geometry.segmentMidpoint(this);
    +
    +    var twoF_point_1 = geometry.point(mid_point.x + main_line_unitvector_x * 2 * this.focalLength, mid_point.y + main_line_unitvector_y * 2 * this.focalLength);  // The first point at two focal lengths
    +    var twoF_point_2 = geometry.point(mid_point.x - main_line_unitvector_x * 2 * this.focalLength, mid_point.y - main_line_unitvector_y * 2 * this.focalLength);  // The second point at two focal lengths
    +
    +    var twoF_line_near, twoF_line_far;
    +    if (geometry.distanceSquared(ray.p1, twoF_point_1) < geometry.distanceSquared(ray.p1, twoF_point_2)) {
    +      // The first point at two focal lengths is on the same side as the ray
    +      twoF_line_near = geometry.parallelLineThroughPoint(this, twoF_point_1);
    +      twoF_line_far = geometry.parallelLineThroughPoint(this, twoF_point_2);
    +    } else {
    +      // The second point at two focal lengths is on the same side as the ray
    +      twoF_line_near = geometry.parallelLineThroughPoint(this, twoF_point_2);
    +      twoF_line_far = geometry.parallelLineThroughPoint(this, twoF_point_1);
    +    }
    +
    +    if (this.focalLength > 0) {
    +      ray.p2 = geometry.linesIntersection(twoF_line_far, geometry.line(mid_point, geometry.linesIntersection(twoF_line_near, ray)));
    +      ray.p1 = geometry.point(incidentPoint.x, incidentPoint.y);
    +    } else {
    +      ray.p2 = geometry.linesIntersection(twoF_line_far, geometry.line(incidentPoint, geometry.linesIntersection(twoF_line_near, geometry.line(mid_point, geometry.linesIntersection(twoF_line_far, ray)))));
    +      ray.p1 = geometry.point(incidentPoint.x, incidentPoint.y);
    +    }
    +
    +    // The above calculation is for an ideal lens, now mirror it.
    +    
    +    ray.p1.x = 2 * ray.p1.x - ray.p2.x;
    +    ray.p1.y = 2 * ray.p1.y - ray.p2.y;
    +
    +    var rx = ray.p1.x - incidentPoint.x;
    +    var ry = ray.p1.y - incidentPoint.y;
    +    var mx = this.p2.x - this.p1.x;
    +    var my = this.p2.y - this.p1.y;
    +
    +    ray.p1 = incidentPoint;
    +    ray.p2 = geometry.point(incidentPoint.x + rx * (my * my - mx * mx) - 2 * ry * mx * my, incidentPoint.y + ry * (mx * mx - my * my) - 2 * rx * mx * my);
    +  }
    +};
    +
    +export default IdealMirror;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_mirror_Mirror.js.html b/docs/sceneObjs_mirror_Mirror.js.html new file mode 100644 index 00000000..07fa636a --- /dev/null +++ b/docs/sceneObjs_mirror_Mirror.js.html @@ -0,0 +1,125 @@ + + + + + JSDoc: Source: sceneObjs/mirror/Mirror.js + + + + + + + + + + +
    + +

    Source: sceneObjs/mirror/Mirror.js

    + + + + + + +
    +
    +
    import BaseFilter from '../BaseFilter.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Mirror with shape of a line segment.
    + * 
    + * Tools -> Mirror -> Segment
    + * @class
    + * @extends BaseFilter
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint.
    + * @property {Point} p2 - The second endpoint.
    + * @property {boolean} filter - Whether it is a dichroic mirror.
    + * @property {boolean} invert - If true, the ray with wavelength outside the bandwidth is reflected. If false, the ray with wavelength inside the bandwidth is reflected.
    + * @property {number} wavelength - The target wavelength if dichroic is enabled. The unit is nm.
    + * @property {number} bandwidth - The bandwidth if dichroic is enabled. The unit is nm.
    + */
    +class Mirror extends LineObjMixin(BaseFilter) {
    +  static type = 'Mirror';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    filter: false,
    +    invert: false,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    bandwidth: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:meta.parentheses', { main: i18next.t('main:tools.categories.mirror'), sub: i18next.t('main:tools.Mirror.title') }));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +
    +    ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(168,168,168)');
    +    ctx.lineWidth = 1 * ls;
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.stroke();
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (this.checkRayIntersectFilter(ray)) {
    +      return this.checkRayIntersectsShape(ray);
    +    } else {
    +      return null;
    +    }
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    var rx = ray.p1.x - incidentPoint.x;
    +    var ry = ray.p1.y - incidentPoint.y;
    +    var mx = this.p2.x - this.p1.x;
    +    var my = this.p2.y - this.p1.y;
    +
    +    ray.p1 = incidentPoint;
    +    ray.p2 = geometry.point(incidentPoint.x + rx * (my * my - mx * mx) - 2 * ry * mx * my, incidentPoint.y + ry * (mx * mx - my * my) - 2 * rx * mx * my);
    +  }
    +};
    +
    +export default Mirror;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_mirror_ParabolicMirror.js.html b/docs/sceneObjs_mirror_ParabolicMirror.js.html new file mode 100644 index 00000000..2289401f --- /dev/null +++ b/docs/sceneObjs_mirror_ParabolicMirror.js.html @@ -0,0 +1,373 @@ + + + + + JSDoc: Source: sceneObjs/mirror/ParabolicMirror.js + + + + + + + + + + +
    + +

    Source: sceneObjs/mirror/ParabolicMirror.js

    + + + + + + +
    +
    +
    import BaseFilter from '../BaseFilter.js';
    +import i18next from 'i18next';
    +import Simulator from '../../Simulator.js';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Parabolic mirror.
    + * 
    + * Tools -> Mirror -> Parabolic
    + * 
    + * The current implementation is based on `CustomMirror.js`, but this should be changed to an analytical solution in the future.
    + * @class
    + * @extends BaseFilter
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint.
    + * @property {Point} p2 - The second endpoint.
    + * @property {Point} p3 - The vertex.
    + * @property {boolean} filter - Whether it is a dichroic mirror.
    + * @property {boolean} invert - If true, the ray with wavelength outside the bandwidth is reflected. If false, the ray with wavelength inside the bandwidth is reflected.
    + * @property {number} wavelength - The target wavelength if dichroic is enabled. The unit is nm.
    + * @property {number} bandwidth - The bandwidth if dichroic is enabled. The unit is nm.
    + * @property {Array<Point>} tmp_points - The points on the parabola.
    + * @property {number} tmp_i - The index of the point on the parabola where the ray is incident.
    + */
    +class ParabolicMirror extends BaseFilter {
    +  static type = 'ParabolicMirror';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    p3: null,
    +    filter: false,
    +    invert: false,
    +    wavelength: Simulator.GREEN_WAVELENGTH,
    +    bandwidth: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:meta.parentheses', { main: i18next.t('main:tools.categories.mirror'), sub: i18next.t('main:tools.ParabolicMirror.title') }));
    +    super.populateObjBar(objBar);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.fillStyle = 'rgb(255,0,255)';
    +    if (this.p3 && this.p2) {
    +      var p12d = geometry.distance(this.p1, this.p2);
    +      // unit vector from p1 to p2
    +      var dir1 = [(this.p2.x - this.p1.x) / p12d, (this.p2.y - this.p1.y) / p12d];
    +      // perpendicular direction
    +      var dir2 = [dir1[1], -dir1[0]];
    +      // get height of (this section of) parabola
    +      var height = (this.p3.x - this.p1.x) * dir2[0] + (this.p3.y - this.p1.y) * dir2[1];
    +      // reposition p3 to be at vertex
    +      this.p3 = geometry.point((this.p1.x + this.p2.x) * .5 + dir2[0] * height, (this.p1.y + this.p2.y) * .5 + dir2[1] * height);
    +
    +      var x0 = p12d / 2;
    +      var a = height / (x0 * x0); // y=ax^2
    +      var i;
    +      ctx.strokeStyle = isHovered ? 'cyan' : ((this.scene.simulateColors && this.wavelength && this.filter) ? Simulator.wavelengthToColor(this.wavelength || Simulator.GREEN_WAVELENGTH, 1) : 'rgb(168,168,168)');
    +      ctx.lineWidth = 1 * ls;
    +      ctx.beginPath();
    +      this.tmp_points = [geometry.point(this.p1.x, this.p1.y)];
    +      ctx.moveTo(this.p1.x, this.p1.y);
    +      for (i = 0.1 * this.scene.lengthScale; i < p12d; i += 0.1 * this.scene.lengthScale) {
    +        // avoid using exact integers to avoid problems with detecting intersections
    +        var ix = i + .001 * this.scene.lengthScale;
    +        var x = ix - x0;
    +        var y = height - a * x * x;
    +        var pt = geometry.point(this.p1.x + dir1[0] * ix + dir2[0] * y, this.p1.y + dir1[1] * ix + dir2[1] * y);
    +        ctx.lineTo(pt.x, pt.y);
    +        this.tmp_points.push(pt);
    +      }
    +      ctx.stroke();
    +      if (isHovered) {
    +        ctx.fillRect(this.p3.x - 1.5 * ls, this.p3.y - 1.5 * ls, 3 * ls, 3 * ls);
    +        var focusx = (this.p1.x + this.p2.x) * .5 + dir2[0] * (height - 1 / (4 * a));
    +        var focusy = (this.p1.y + this.p2.y) * .5 + dir2[1] * (height - 1 / (4 * a));
    +        ctx.fillRect(focusx - 1.5 * ls, focusy - 1.5 * ls, 3 * ls, 3 * ls);
    +        ctx.fillStyle = 'rgb(255,0,0)';
    +        ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +        ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      }
    +    } else if (this.p2) {
    +      ctx.fillStyle = 'rgb(255,0,0)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      ctx.fillRect(this.p2.x - 1.5 * ls, this.p2.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    } else {
    +      ctx.fillStyle = 'rgb(255,0,0)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    }
    +  }
    +
    +  move(diffX, diffY) {
    +    this.p1.x = this.p1.x + diffX;
    +    this.p1.y = this.p1.y + diffY;
    +    this.p2.x = this.p2.x + diffX;
    +    this.p2.y = this.p2.y + diffY;
    +    this.p3.x = this.p3.x + diffX;
    +    this.p3.y = this.p3.y + diffY;
    +  }
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    if (!this.constructionPoint) {
    +      // Initialize the construction stage.
    +      this.constructionPoint = mouse.getPosSnappedToGrid();
    +      this.p1 = this.constructionPoint;
    +      this.p2 = null;
    +      this.p3 = null;
    +    }
    +
    +    if (!this.p2 && !this.p3) {
    +      this.p2 = mouse.getPosSnappedToGrid();
    +      return;
    +    }
    +
    +    if (this.p2 && !this.p3 && !mouse.isOnPoint(this.p1)) {
    +      if (shift) {
    +        this.p2 = mouse.getPosSnappedToDirection(this.p1, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +      } else {
    +        this.p2 = mouse.getPosSnappedToGrid();
    +      }
    +      this.p3 = mouse.getPosSnappedToGrid();
    +      return;
    +    }
    +  }
    +
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    if (!this.p3 && !mouse.isOnPoint(this.p1)) {
    +      if (shift) {
    +        this.p2 = mouse.getPosSnappedToDirection(this.constructionPoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }]);
    +      } else {
    +        this.p2 = mouse.getPosSnappedToGrid();
    +      }
    +
    +      this.p1 = ctrl ? geometry.point(2 * this.constructionPoint.x - this.p2.x, 2 * this.constructionPoint.y - this.p2.y) : this.constructionPoint;
    +
    +      return;
    +    }
    +    if (this.p3) {
    +      this.p3 = mouse.getPosSnappedToGrid();
    +      return;
    +    }
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    if (this.p2 && !this.p3 && !mouse.isOnPoint(this.p1)) {
    +      this.p3 = mouse.getPosSnappedToGrid();
    +      return;
    +    }
    +    if (this.p3 && !mouse.isOnPoint(this.p2)) {
    +      this.p3 = mouse.getPosSnappedToGrid();
    +      delete this.constructionPoint;
    +      return {
    +        isDone: true
    +      };
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (mouse.isOnPoint(this.p1) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p2) && geometry.distanceSquared(mouse.pos, this.p1) <= geometry.distanceSquared(mouse.pos, this.p3)) {
    +      dragContext.part = 1;
    +      dragContext.targetPoint = geometry.point(this.p1.x, this.p1.y);
    +      return dragContext;
    +    }
    +    if (this.p2 && mouse.isOnPoint(this.p2) && geometry.distanceSquared(mouse.pos, this.p2) <= geometry.distanceSquared(mouse.pos, this.p3)) {
    +      dragContext.part = 2;
    +      dragContext.targetPoint = geometry.point(this.p2.x, this.p2.y);
    +      return dragContext;
    +    }
    +    if (this.p3 && mouse.isOnPoint(this.p3)) {
    +      dragContext.part = 3;
    +      dragContext.targetPoint = geometry.point(this.p3.x, this.p3.y);
    +      return dragContext;
    +    }
    +
    +    if (!this.tmp_points) return;
    +    var i;
    +    var pts = this.tmp_points;
    +    for (i = 0; i < pts.length - 1; i++) {
    +      var seg = geometry.line(pts[i], pts[i + 1]);
    +      if (mouse.isOnSegment(seg)) {
    +        const mousePos = mouse.getPosSnappedToGrid();
    +        dragContext.part = 0;
    +        dragContext.mousePos0 = mousePos;
    +        dragContext.mousePos1 = mousePos;
    +        dragContext.snapContext = {};
    +        return dragContext;
    +      }
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    var basePoint;
    +    if (dragContext.part == 1) {
    +      // Dragging the first endpoint
    +      basePoint = ctrl ? geometry.segmentMidpoint(dragContext.originalObj) : dragContext.originalObj.p2;
    +
    +      this.p1 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +      this.p2 = ctrl ? geometry.point(2 * basePoint.x - this.p1.x, 2 * basePoint.y - this.p1.y) : basePoint;
    +    }
    +    if (dragContext.part == 2) {
    +      // Dragging the second endpoint
    +      basePoint = ctrl ? geometry.segmentMidpoint(dragContext.originalObj) : dragContext.originalObj.p1;
    +
    +      this.p2 = shift ? mouse.getPosSnappedToDirection(basePoint, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }]) : mouse.getPosSnappedToGrid();
    +      this.p1 = ctrl ? geometry.point(2 * basePoint.x - this.p2.x, 2 * basePoint.y - this.p2.y) : basePoint;
    +    }
    +    if (dragContext.part == 3) {
    +      // Dragging the third endpoint
    +      this.p3 = mouse.getPosSnappedToGrid();
    +    }
    +    if (dragContext.part == 0) {
    +      // Dragging the entire obj
    +      if (shift) {
    +        var mousePos = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: (dragContext.originalObj.p2.x - dragContext.originalObj.p1.x), y: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y) }, { x: (dragContext.originalObj.p2.y - dragContext.originalObj.p1.y), y: -(dragContext.originalObj.p2.x - dragContext.originalObj.p1.x) }], dragContext.snapContext);
    +      } else {
    +        var mousePos = mouse.getPosSnappedToGrid();;
    +        dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +      }
    +
    +      var mouseDiffX = dragContext.mousePos1.x - mousePos.x; // The X difference between the mouse position now and at the previous moment
    +      var mouseDiffY = dragContext.mousePos1.y - mousePos.y; // The Y difference between the mouse position now and at the previous moment
    +      // Move the first point
    +      this.p1.x = this.p1.x - mouseDiffX;
    +      this.p1.y = this.p1.y - mouseDiffY;
    +      // Move the second point
    +      this.p2.x = this.p2.x - mouseDiffX;
    +      this.p2.y = this.p2.y - mouseDiffY;
    +
    +      this.p3.x = this.p3.x - mouseDiffX;
    +      this.p3.y = this.p3.y - mouseDiffY;
    +
    +      // Update the mouse position
    +      dragContext.mousePos1 = mousePos;
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    if (!this.p3) { return; }
    +    if (!this.tmp_points || !this.checkRayIntersectFilter(ray)) return;
    +    var i, j;
    +    var pts = this.tmp_points;
    +    var dir = geometry.distance(this.p2, ray.p1) > geometry.distance(this.p1, ray.p1);
    +    var incidentPoint;
    +    for (j = 0; j < pts.length - 1; j++) {
    +      i = dir ? j : (pts.length - 2 - j);
    +      var rp_temp = geometry.linesIntersection(geometry.line(ray.p1, ray.p2), geometry.line(pts[i], pts[i + 1]));
    +      var seg = geometry.line(pts[i], pts[i + 1]);
    +      // need Simulator.MIN_RAY_SEGMENT_LENGTH check to handle a ray that reflects off mirror multiple times
    +      if (geometry.distance(ray.p1, rp_temp) < Simulator.MIN_RAY_SEGMENT_LENGTH * this.scene.lengthScale)
    +        continue;
    +      if (geometry.intersectionIsOnSegment(rp_temp, seg) && geometry.intersectionIsOnRay(rp_temp, ray)) {
    +        if (!incidentPoint || geometry.distance(ray.p1, rp_temp) < geometry.distance(ray.p1, incidentPoint)) {
    +          incidentPoint = rp_temp;
    +          this.tmp_i = i;
    +        }
    +      }
    +    }
    +    if (incidentPoint) return incidentPoint;
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    var rx = ray.p1.x - incidentPoint.x;
    +    var ry = ray.p1.y - incidentPoint.y;
    +    var i = this.tmp_i;
    +    var pts = this.tmp_points;
    +    var seg = geometry.line(pts[i], pts[i + 1]);
    +    var mx = seg.p2.x - seg.p1.x;
    +    var my = seg.p2.y - seg.p1.y;
    +
    +
    +    ray.p1 = incidentPoint;
    +    var frac;
    +    if (Math.abs(mx) > Math.abs(my)) {
    +      frac = (incidentPoint.x - seg.p1.x) / mx;
    +    } else {
    +      frac = (incidentPoint.y - seg.p1.y) / my;
    +    }
    +
    +    if ((i == 0 && frac < 0.5) || (i == pts.length - 2 && frac >= 0.5)) {
    +      ray.p2 = geometry.point(incidentPoint.x + rx * (my * my - mx * mx) - 2 * ry * mx * my, incidentPoint.y + ry * (mx * mx - my * my) - 2 * rx * mx * my);
    +    } else {
    +      // Use a simple trick to smooth out the slopes of outgoing rays so that image detection works.
    +      // However, a more proper numerical algorithm from the beginning (especially to handle singularities) is still desired.
    +
    +      var outx = incidentPoint.x + rx * (my * my - mx * mx) - 2 * ry * mx * my;
    +      var outy = incidentPoint.y + ry * (mx * mx - my * my) - 2 * rx * mx * my;
    +
    +      var segA;
    +      if (frac < 0.5) {
    +        segA = geometry.line(pts[i - 1], pts[i]);
    +      } else {
    +        segA = geometry.line(pts[i + 1], pts[i + 2]);
    +      }
    +      var rxA = ray.p1.x - incidentPoint.x;
    +      var ryA = ray.p1.y - incidentPoint.y;
    +      var mxA = segA.p2.x - segA.p1.x;
    +      var myA = segA.p2.y - segA.p1.y;
    +
    +      var outxA = incidentPoint.x + rxA * (myA * myA - mxA * mxA) - 2 * ryA * mxA * myA;
    +      var outyA = incidentPoint.y + ryA * (mxA * mxA - myA * myA) - 2 * rxA * mxA * myA;
    +
    +      var outxFinal;
    +      var outyFinal;
    +
    +      if (frac < 0.5) {
    +        outxFinal = outx * (0.5 + frac) + outxA * (0.5 - frac);
    +        outyFinal = outy * (0.5 + frac) + outyA * (0.5 - frac);
    +      } else {
    +        outxFinal = outxA * (frac - 0.5) + outx * (1.5 - frac);
    +        outyFinal = outyA * (frac - 0.5) + outy * (1.5 - frac);
    +      }
    +      //console.log(frac);
    +      ray.p2 = geometry.point(outxFinal, outyFinal);
    +    }
    +  }
    +};
    +
    +export default ParabolicMirror;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_other_Detector.js.html b/docs/sceneObjs_other_Detector.js.html new file mode 100644 index 00000000..bafd1df1 --- /dev/null +++ b/docs/sceneObjs_other_Detector.js.html @@ -0,0 +1,239 @@ + + + + + JSDoc: Source: sceneObjs/other/Detector.js + + + + + + + + + + +
    + +

    Source: sceneObjs/other/Detector.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * The detector tool
    + * 
    + * Tools -> Other -> Detector
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint of the line segment.
    + * @property {Point} p2 - The second endpoint of the line segment.
    + * @property {boolean} irradMap - Whether to display the irradiance map.
    + * @property {number} binSize - The size of the bin for the irradiance map.
    + * @property {number} power - The measured power through the detector.
    + * @property {number} normal - The measured normal force through the detector.
    + * @property {number} shear - The measured shear force through the detector.
    + * @property {Array<number>} binData - The measured data for the irradiance map.
    + */
    +class Detector extends LineObjMixin(BaseSceneObj) {
    +  static type = 'Detector';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    irradMap: false,
    +    binSize: 1
    +  };
    +
    +  constructor(scene, properties) {
    +    super(scene, properties);
    +
    +    // Initialize the quantities to be measured
    +    this.power = 0;
    +    this.normal = 0;
    +    this.shear = 0;
    +    this.binData = null;
    +  }
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.Detector.title'));
    +    objBar.createInfoBox('<ul><li>' + i18next.t('simulator:sceneObjs.Detector.info.P') + '</li><li>' + i18next.t('simulator:sceneObjs.Detector.info.Fperp') + '</li><li>' + i18next.t('simulator:sceneObjs.Detector.info.Fpar') + '</li><li>' + i18next.t('simulator:sceneObjs.Detector.info.irradiance') + '</li><li>' + i18next.t('simulator:sceneObjs.Detector.info.length') + '</li><li>' + i18next.t('simulator:sceneObjs.Detector.info.B') + '</li><li>' + i18next.t('simulator:sceneObjs.Detector.info.s') + '</li><li>' + i18next.t('simulator:sceneObjs.Detector.info.truncation') + '</li></ul>');
    +
    +    objBar.createBoolean(i18next.t('simulator:sceneObjs.Detector.irradMap'), this.irradMap, function (obj, value) {
    +      obj.irradMap = value;
    +    }, null, true);
    +
    +    if (this.irradMap) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.Detector.binSize'), 0.01 * this.scene.lengthScale, 10 * this.scene.lengthScale, 0.01 * this.scene.lengthScale, this.binSize, function (obj, value) {
    +        obj.binSize = value;
    +      }, i18next.t('simulator:sceneObjs.common.lengthUnitInfo'));
    +
    +      const self = this;
    +
    +      objBar.createButton(i18next.t('simulator:sceneObjs.Detector.exportData'), function (obj) {
    +        // Export the irradiance map to a CSV file
    +        var binSize = obj.binSize;
    +        var binNum = Math.ceil(Math.sqrt((obj.p2.x - obj.p1.x) * (obj.p2.x - obj.p1.x) + (obj.p2.y - obj.p1.y) * (obj.p2.y - obj.p1.y)) / binSize);
    +        var binData = obj.binData;
    +        var csv = "data:text/csv;charset=utf-8,";
    +
    +        // Write the header
    +        csv += "Position,Irradiance\n";
    +
    +        // Write the data
    +        for (var i = 0; i < binNum; i++) {
    +          csv += i * binSize + "," + (binData[i] / binSize) + "\n";
    +        }
    +        var encodedUri = encodeURI(csv);
    +
    +        // Download the file
    +        var link = document.createElement("a");
    +        link.setAttribute("href", encodedUri);
    +        link.setAttribute("download", (self.scene.name || "irradiance_map") + ".csv");
    +        document.body.appendChild(link);
    +        link.click();
    +      });
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (!isAboveLight) {
    +      ctx.globalCompositeOperation = 'lighter';
    +
    +      ctx.strokeStyle = isHovered ? 'cyan' : ('rgb(192,192,192)');
    +      ctx.lineWidth = 1 * ls;
    +      ctx.setLineDash([5 * ls, 5 * ls]);
    +      ctx.beginPath();
    +      ctx.moveTo(this.p1.x, this.p1.y);
    +      ctx.lineTo(this.p2.x, this.p2.y);
    +      ctx.stroke();
    +      ctx.setLineDash([]);
    +
    +      ctx.globalCompositeOperation = 'source-over';
    +    } else {
    +      ctx.globalCompositeOperation = 'lighter';
    +      var len = Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +
    +      var accuracy = Math.max(-Math.floor(Math.log10(this.scene.simulator.totalTruncation)), 0);
    +      if (this.scene.simulator.totalTruncation > 0 && accuracy <= 2) {
    +        var str1 = "P=" + this.power.toFixed(accuracy) + "±" + this.scene.simulator.totalTruncation.toFixed(accuracy);
    +        var str2 = "F⊥=" + this.normal.toFixed(accuracy) + "±" + this.scene.simulator.totalTruncation.toFixed(accuracy);
    +        var str3 = "F∥=" + this.shear.toFixed(accuracy) + "±" + this.scene.simulator.totalTruncation.toFixed(accuracy);
    +      } else {
    +        var str1 = "P=" + this.power.toFixed(2);
    +        var str2 = "F⊥=" + this.normal.toFixed(2);
    +        var str3 = "F∥=" + this.shear.toFixed(2);
    +      }
    +
    +      ctx.font = (16 * ls) + 'px Arial';
    +      ctx.textAlign = 'right';
    +      ctx.textBaseline = 'top';
    +      ctx.fillStyle = isHovered ? 'cyan' : ('rgb(192,192,192)');
    +      ctx.fillText(str1, this.p2.x, this.p2.y);
    +      ctx.fillText(str2, this.p2.x, this.p2.y + 20 * ls);
    +      ctx.fillText(str3, this.p2.x, this.p2.y + 40 * ls);
    +      ctx.globalCompositeOperation = 'source-over';
    +
    +      if (this.irradMap && this.binData) {
    +        // Define the unit vector of the x-axis of the plot (parallel to obj) and the y-axis of the plot (perpendicular to obj)
    +        var len = Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +        var ux = (this.p2.x - this.p1.x) / len;
    +        var uy = (this.p2.y - this.p1.y) / len;
    +        var vx = uy;
    +        var vy = -ux;
    +
    +        // Draw the irradiance map
    +        ctx.lineWidth = 1 * ls;
    +        ctx.strokeStyle = isHovered ? 'cyan' : ('rgb(255,255,255)');
    +        ctx.fillStyle = 'blue';
    +        ctx.beginPath();
    +        ctx.moveTo(this.p1.x, this.p1.y);
    +        for (var i = 0; i < this.binData.length; i++) {
    +          ctx.lineTo(this.p1.x + ux * i * this.binSize + vx * this.binData[i] / this.binSize * 20 * ls * ls, this.p1.y + uy * i * this.binSize + vy * this.binData[i] / this.binSize * 20 * ls * ls);
    +          ctx.lineTo(this.p1.x + ux * (i + 1) * this.binSize + vx * this.binData[i] / this.binSize * 20 * ls * ls, this.p1.y + uy * (i + 1) * this.binSize + vy * this.binData[i] / this.binSize * 20 * ls * ls);
    +        }
    +        ctx.lineTo(this.p2.x, this.p2.y);
    +        ctx.fill();
    +        ctx.stroke();
    +      }
    +    }
    +  }
    +
    +  onSimulationStart() {
    +    this.power = 0;
    +    this.normal = 0;
    +    this.shear = 0;
    +
    +    if (this.irradMap) {
    +      var binSize = this.binSize;
    +      var binNum = Math.ceil(Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y)) / binSize);
    +      var binData = [];
    +      for (var i = 0; i < binNum; i++) {
    +        binData[i] = 0;
    +      }
    +      this.binData = binData;
    +    }
    +  }
    +
    +  checkRayIntersects(ray) {
    +    return this.checkRayIntersectsShape(ray);
    +  }
    +
    +  onRayIncident(ray, rayIndex, incidentPoint) {
    +    var rcrosss = (ray.p2.x - ray.p1.x) * (this.p2.y - this.p1.y) - (ray.p2.y - ray.p1.y) * (this.p2.x - this.p1.x);
    +    var sint = rcrosss / Math.sqrt((ray.p2.x - ray.p1.x) * (ray.p2.x - ray.p1.x) + (ray.p2.y - ray.p1.y) * (ray.p2.y - ray.p1.y)) / Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +    var cost = ((ray.p2.x - ray.p1.x) * (this.p2.x - this.p1.x) + (ray.p2.y - ray.p1.y) * (this.p2.y - this.p1.y)) / Math.sqrt((ray.p2.x - ray.p1.x) * (ray.p2.x - ray.p1.x) + (ray.p2.y - ray.p1.y) * (ray.p2.y - ray.p1.y)) / Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +    ray.p2 = geometry.point(incidentPoint.x + ray.p2.x - ray.p1.x, incidentPoint.y + ray.p2.y - ray.p1.y);
    +    ray.p1 = geometry.point(incidentPoint.x, incidentPoint.y);
    +
    +    this.power += Math.sign(rcrosss) * (ray.brightness_s + ray.brightness_p);
    +    this.normal += Math.sign(rcrosss) * sint * (ray.brightness_s + ray.brightness_p);
    +    this.shear -= Math.sign(rcrosss) * cost * (ray.brightness_s + ray.brightness_p);
    +
    +    if (this.irradMap && this.binData) {
    +      var binSize = this.binSize;
    +      var binNum = Math.ceil(Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y)) / binSize);
    +      var binIndex = Math.floor(Math.sqrt((incidentPoint.x - this.p1.x) * (incidentPoint.x - this.p1.x) + (incidentPoint.y - this.p1.y) * (incidentPoint.y - this.p1.y)) / binSize);
    +      this.binData[binIndex] += Math.sign(rcrosss) * (ray.brightness_s + ray.brightness_p);
    +    }
    +  }
    +};
    +
    +export default Detector;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_other_Drawing.js.html b/docs/sceneObjs_other_Drawing.js.html new file mode 100644 index 00000000..53e52c26 --- /dev/null +++ b/docs/sceneObjs_other_Drawing.js.html @@ -0,0 +1,202 @@ + + + + + JSDoc: Source: sceneObjs/other/Drawing.js + + + + + + + + + + +
    + +

    Source: sceneObjs/other/Drawing.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import i18next from 'i18next';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Drawing tool
    + * 
    + * Tools -> Other -> Drawing
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Array<Array<number>>} strokes - The strokes of the drawing. Each element represents a stroke, which is an array of coordinates ordered as `[x1, y1, x2, y2, ...]`. The coordinates are rounded to reduce the size of the JSON data.
    + * @property {boolean} isDrawing - Whether the user is drawing (before "stop drawing" is clicked).
    + * @property {boolean} isMouseDown - Temperary indication of whether the mouse is down (during the drawing stage).
    + */
    +class Drawing extends BaseSceneObj {
    +  static type = 'Drawing';
    +  static serializableDefaults = {
    +    strokes: [],
    +    isDrawing: false
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.Drawing.title'));
    +    if (this.isDrawing) {
    +      objBar.createButton(i18next.t('simulator:sceneObjs.Drawing.finishDrawing'), function (obj) {
    +        obj.isDrawing = false;
    +        if (obj.scene.editor.isConstructing) {
    +          obj.scene.editor.isConstructing = false;
    +        }
    +      }, true);
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.strokeStyle = isHovered ? 'cyan' : 'white';
    +    ctx.lineWidth = 1 * ls;
    +    ctx.beginPath();
    +    for (const stroke of this.strokes) {
    +      ctx.moveTo(stroke[0], stroke[1]);
    +      for (let i = 2; i < stroke.length; i += 2) {
    +        ctx.lineTo(stroke[i], stroke[i + 1]);
    +      }
    +    }
    +    ctx.stroke();
    +  }
    +
    +  move(diffX, diffY) {
    +    let roundedDiffX = this.round(diffX);
    +    let roundedDiffY = this.round(diffY);
    +    for (const stroke of this.strokes) {
    +      for (let i = 0; i < stroke.length; i += 2) {
    +        stroke[i] += roundedDiffX;
    +        stroke[i + 1] += roundedDiffY;
    +      }
    +    }
    +  }
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    if (!this.isDrawing) {
    +      // Initialize the drawing
    +      this.isDrawing = true;
    +      this.strokes = [];
    +    }
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    this.strokes.push([this.round(mousePos.x), this.round(mousePos.y)]);
    +    this.isMouseDown = true;
    +  }
    +
    +  onConstructMouseMove(mouse, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    if (!this.isMouseDown) return;
    +    if (this.strokes.length === 0 || this.strokes[this.strokes.length - 1].length < 2) return;
    +
    +    const distanceSq = (this.strokes[this.strokes.length - 1][this.strokes[this.strokes.length - 1].length - 2] - mousePos.x) ** 2 + (this.strokes[this.strokes.length - 1][this.strokes[this.strokes.length - 1].length - 1] - mousePos.y) ** 2;
    +    
    +    if (distanceSq < 4 * this.scene.lengthScale * this.scene.lengthScale) return;
    +
    +    this.strokes[this.strokes.length - 1].push(this.round(mousePos.x), this.round(mousePos.y));
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    this.isMouseDown = false;
    +  }
    +
    +  onConstructUndo() {
    +    if (this.strokes.length < 2) {
    +      return {
    +        isCancelled: true
    +      }
    +    } else {
    +      this.strokes.pop();
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    for (const stroke of this.strokes) {
    +      for (let i = 0; i < stroke.length - 2; i += 2) {
    +        if (mouse.isOnSegment(geometry.line(geometry.point(stroke[i], stroke[i + 1]), geometry.point(stroke[i + 2], stroke[i + 3])))) {
    +          const mousePos = mouse.getPosSnappedToGrid();
    +          const roundedMousePos = geometry.point(this.round(mousePos.x), this.round(mousePos.y));
    +          dragContext.part = 0;
    +          dragContext.mousePos0 = roundedMousePos; // Mouse position when the user starts dragging
    +          dragContext.mousePos1 = roundedMousePos; // Mouse position at the last moment during dragging
    +          dragContext.snapContext = {};
    +          return dragContext;
    +        }
    +      }
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    if (shift) {
    +      var mousePos = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }], dragContext.snapContext);
    +    } else {
    +      var mousePos = mouse.getPosSnappedToGrid();
    +      dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +    }
    +
    +    const roundedMousePos = geometry.point(this.round(mousePos.x), this.round(mousePos.y));
    +
    +    var mouseDiffX = dragContext.mousePos1.x - roundedMousePos.x; // The X difference between the mouse position now and at the previous moment
    +    var mouseDiffY = dragContext.mousePos1.y - roundedMousePos.y; // The Y difference between the mouse position now and at the previous moment
    +
    +    if (dragContext.part == 0) {
    +      for (const stroke of this.strokes) {
    +        for (let i = 0; i < stroke.length; i += 2) {
    +          stroke[i] -= mouseDiffX;
    +          stroke[i + 1] -= mouseDiffY;
    +        }
    +      }
    +    }
    +
    +    // Update the mouse position
    +    dragContext.mousePos1 = roundedMousePos;
    +  }
    +
    +  /* Utility functions */
    +
    +  /**
    +   * Round the coordinates of the strokes to integers times the length scale (to reduce the size of the JSON data).
    +   */
    +  round(num) {
    +    return Math.round(num / this.scene.lengthScale) * this.scene.lengthScale;
    +  }
    +};
    +
    +export default Drawing;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_other_LineArrow.js.html b/docs/sceneObjs_other_LineArrow.js.html new file mode 100644 index 00000000..43a4c343 --- /dev/null +++ b/docs/sceneObjs_other_LineArrow.js.html @@ -0,0 +1,129 @@ + + + + + JSDoc: Source: sceneObjs/other/LineArrow.js + + + + + + + + + + +
    + +

    Source: sceneObjs/other/LineArrow.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +
    +/**
    + * Line or arrow decoration
    + * 
    + * Tools -> Other -> Line / Arrow
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint.
    + * @property {Point} p2 - The second endpoint.
    + * @property {boolean} arrow - Whether an arrow is pointing from the first endpoint.
    + * @property {boolean} backArrow - Whether an arrow is pointing from the second endpoint.
    + */
    +class LineArrow extends LineObjMixin(BaseSceneObj) {
    +  static type = 'LineArrow';
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    arrow: false,
    +    backArrow: false
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.LineArrow.title'));
    +    objBar.createBoolean(i18next.t('simulator:sceneObjs.LineArrow.arrow'), this.arrow, function (obj, value) {
    +      obj.arrow = value;
    +    });
    +
    +    objBar.createBoolean(i18next.t('simulator:sceneObjs.LineArrow.backArrow'), this.backArrow, function (obj, value) {
    +      obj.backArrow = value;
    +    });
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +    
    +    ctx.strokeStyle = isHovered ? 'cyan' : 'white';
    +    ctx.lineWidth = 1 * ls;
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.stroke();
    +    if (this.arrow) {
    +      this.drawArrow(canvasRenderer, this.p1, this.p2);
    +    }
    +    if (this.backArrow) {
    +      this.drawArrow(canvasRenderer, this.p2, this.p1);
    +    }
    +  }
    +  
    +
    +  /** Utility method */
    +
    +  drawArrow(canvasRenderer, p1, p2) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    const angle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
    +    const len = 10 * ls;
    +    ctx.beginPath();
    +    ctx.moveTo(p2.x, p2.y);
    +    ctx.lineTo(p2.x - len * Math.cos(angle - Math.PI / 6), p2.y - len * Math.sin(angle - Math.PI / 6));
    +    ctx.moveTo(p2.x, p2.y);
    +    ctx.lineTo(p2.x - len * Math.cos(angle + Math.PI / 6), p2.y - len * Math.sin(angle + Math.PI / 6));
    +    ctx.stroke();
    +  }
    +};
    +
    +export default LineArrow;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_other_Protractor.js.html b/docs/sceneObjs_other_Protractor.js.html new file mode 100644 index 00000000..c9b5bf31 --- /dev/null +++ b/docs/sceneObjs_other_Protractor.js.html @@ -0,0 +1,160 @@ + + + + + JSDoc: Source: sceneObjs/other/Protractor.js + + + + + + + + + + +
    + +

    Source: sceneObjs/other/Protractor.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import i18next from 'i18next';
    +import CircleObjMixin from '../CircleObjMixin.js';
    +
    +/**
    + * The protractor tool
    + * 
    + * Tools -> Other -> Protractor
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The center of the protractor.
    + * @property {Point} p2 - The zero point on the protractor.
    + */
    +class Protractor extends CircleObjMixin(BaseSceneObj) {
    +  static type = 'Protractor';
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.Protractor.title'));
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (!isAboveLight) {
    +      ctx.globalCompositeOperation = 'lighter';
    +      var r = Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +      var scale_width_limit = 5 * ls;
    +
    +      var scale_step = 1;
    +      var scale_step_mid = 5;
    +      var scale_step_long = 10;
    +      var scale_len = 10 * ls;
    +      var scale_len_mid = 15 * ls;
    +      var scale_len_long = 20 * ls;
    +
    +      ctx.strokeStyle = isHovered ? 'cyan' : ('rgb(128,128,128)');
    +      ctx.font = 'bold ' + (14 * ls) + 'px Arial';
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +
    +      if (r * scale_step * Math.PI / 180 < scale_width_limit) {
    +        // The scale is too small
    +        scale_step = 2;
    +        scale_step_mid = 10;
    +        scale_step_long = 30;
    +      }
    +      if (r * scale_step * Math.PI / 180 < scale_width_limit) {
    +        // The scale is too small
    +        scale_step = 5;
    +        scale_step_mid = 10;
    +        scale_step_long = 30;
    +        scale_len = 5 * ls;
    +        scale_len_mid = 8 * ls;
    +        scale_len_long = 10 * ls;
    +        ctx.font = 'bold ' + (10 * ls) + 'px Arial';
    +      }
    +      if (r * scale_step * Math.PI / 180 < scale_width_limit) {
    +        // The scale is too small
    +        scale_step = 10;
    +        scale_step_mid = 30;
    +        scale_step_long = 90;
    +      }
    +
    +      ctx.textAlign = 'center';
    +      ctx.textBaseline = 'top';
    +
    +      ctx.lineWidth = 1 * ls;
    +
    +      ctx.beginPath();
    +      ctx.arc(this.p1.x, this.p1.y, r, 0, Math.PI * 2, false);
    +
    +      var ang, x, y;
    +      for (var i = 0; i < 360; i += scale_step) {
    +        ang = i * Math.PI / 180 + Math.atan2(this.p2.y - this.p1.y, this.p2.x - this.p1.x);
    +        ctx.moveTo(this.p1.x + r * Math.cos(ang), this.p1.y + r * Math.sin(ang));
    +        if (i % scale_step_long == 0) {
    +          x = this.p1.x + (r - scale_len_long) * Math.cos(ang);
    +          y = this.p1.y + (r - scale_len_long) * Math.sin(ang);
    +          ctx.lineTo(x, y);
    +          if (canvasRenderer.isSVG) ctx.stroke();
    +          ctx.save();
    +          ctx.translate(x, y);
    +          ctx.rotate(ang + Math.PI * 0.5);
    +          ctx.fillText((i > 180) ? (360 - i) : i, 0, 0);
    +          ctx.restore();
    +        } else if (i % scale_step_mid == 0) {
    +          ctx.lineTo(this.p1.x + (r - scale_len_mid) * Math.cos(ang), this.p1.y + (r - scale_len_mid) * Math.sin(ang));
    +        } else {
    +          ctx.lineTo(this.p1.x + (r - scale_len) * Math.cos(ang), this.p1.y + (r - scale_len) * Math.sin(ang));
    +        }
    +      }
    +      ctx.stroke();
    +
    +      ctx.globalCompositeOperation = 'source-over';
    +    }
    +    ctx.fillStyle = 'red';
    +    ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +    if (isHovered) {
    +      ctx.fillStyle = 'magenta';
    +      ctx.fillRect(this.p2.x - 2.5 * ls, this.p2.y - 2.5 * ls, 5 * ls, 5 * ls);
    +    }
    +  }
    +};
    +
    +export default Protractor;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_other_Ruler.js.html b/docs/sceneObjs_other_Ruler.js.html new file mode 100644 index 00000000..1482c2fd --- /dev/null +++ b/docs/sceneObjs_other_Ruler.js.html @@ -0,0 +1,170 @@ + + + + + JSDoc: Source: sceneObjs/other/Ruler.js + + + + + + + + + + +
    + +

    Source: sceneObjs/other/Ruler.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import LineObjMixin from '../LineObjMixin.js';
    +import i18next from 'i18next';
    +
    +/**
    + * The ruler tool
    + * 
    + * Tools -> Other -> Ruler
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The first endpoint of the line segment.
    + * @property {Point} p2 - The second endpoint of the line segment.
    + * @property {number} scaleInterval - The scale interval of the ruler.
    + */
    +class Ruler extends LineObjMixin(BaseSceneObj) {
    +  static type = 'Ruler';
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    scaleInterval: 10
    +  };
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.Ruler.title'));
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.Ruler.scaleInterval'), 0, 10, 1, this.scaleInterval, function (obj, value) {
    +      obj.scaleInterval = value;
    +    }, i18next.t('simulator:sceneObjs.common.lengthUnitInfo'), true);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    if (isAboveLight) return;
    +
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    if (this.p1.x == this.p2.x && this.p1.y == this.p2.y) {
    +      ctx.fillStyle = 'rgb(128,128,128)';
    +      ctx.fillRect(this.p1.x - 1.5 * ls, this.p1.y - 1.5 * ls, 3 * ls, 3 * ls);
    +      return;
    +    }
    +    
    +    ctx.globalCompositeOperation = 'lighter';
    +    var len = Math.sqrt((this.p2.x - this.p1.x) * (this.p2.x - this.p1.x) + (this.p2.y - this.p1.y) * (this.p2.y - this.p1.y));
    +    var par_x = (this.p2.x - this.p1.x) / len;
    +    var par_y = (this.p2.y - this.p1.y) / len;
    +    var per_x = par_y;
    +    var per_y = -par_x;
    +    var ang = Math.atan2(this.p2.y - this.p1.y, this.p2.x - this.p1.x);
    +
    +    var scale_step = this.scaleInterval;
    +    var scale_step_mid = scale_step * 5;
    +    var scale_step_long = scale_step * 10;
    +    var scale_len = 10 * ls;
    +    var scale_len_mid = 15 * ls;
    +
    +    ctx.strokeStyle = isHovered ? 'cyan' : ('rgb(128,128,128)');
    +    ctx.font = (14 * ls) + 'px Arial';
    +    ctx.fillStyle = 'rgb(128,128,128)';
    +    if (ang > Math.PI * (-0.25) && ang <= Math.PI * 0.25) {
    +      //↘~↗
    +      var scale_direction = -1;
    +      var scale_len_long = 20 * ls;
    +      var text_ang = ang;
    +      ctx.textAlign = 'center';
    +      ctx.textBaseline = 'top';
    +    } else if (ang > Math.PI * (-0.75) && ang <= Math.PI * (-0.25)) {
    +      //↗~↖
    +      var scale_direction = 1;
    +      var scale_len_long = 15 * ls;
    +      var text_ang = ang - Math.PI * (-0.5);
    +      ctx.textAlign = 'right';
    +      ctx.textBaseline = 'middle';
    +    } else if (ang > Math.PI * 0.75 || ang <= Math.PI * (-0.75)) {
    +      //↖~↙
    +      var scale_direction = 1;
    +      var scale_len_long = 20 * ls;
    +      var text_ang = ang - Math.PI;
    +      ctx.textAlign = 'center';
    +      ctx.textBaseline = 'top';
    +    } else {
    +      //↙~↘
    +      var scale_direction = -1;
    +      var scale_len_long = 15 * ls;
    +      var text_ang = ang - Math.PI * 0.5;
    +      ctx.textAlign = 'right';
    +      ctx.textBaseline = 'middle';
    +    }
    +
    +    ctx.lineWidth = 1 * ls;
    +
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    var x, y;
    +    for (var i = 0; i <= len; i += scale_step) {
    +      ctx.moveTo(this.p1.x + i * par_x, this.p1.y + i * par_y);
    +      if (i % scale_step_long == 0) {
    +        x = this.p1.x + i * par_x + scale_direction * scale_len_long * per_x;
    +        y = this.p1.y + i * par_y + scale_direction * scale_len_long * per_y;
    +        ctx.lineTo(x, y);
    +        if (canvasRenderer.isSVG) ctx.stroke();
    +        ctx.save();
    +        ctx.translate(x, y);
    +        ctx.rotate(text_ang);
    +        ctx.fillText(i, 0, 0);
    +        ctx.restore();
    +      } else if (i % scale_step_mid == 0) {
    +        ctx.lineTo(this.p1.x + i * par_x + scale_direction * scale_len_mid * per_x, this.p1.y + i * par_y + scale_direction * scale_len_mid * per_y);
    +      } else {
    +        ctx.lineTo(this.p1.x + i * par_x + scale_direction * scale_len * per_x, this.p1.y + i * par_y + scale_direction * scale_len * per_y);
    +      }
    +    }
    +    ctx.stroke();
    +
    +    ctx.globalCompositeOperation = 'source-over';
    +  }
    +};
    +
    +export default Ruler;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_other_TextLabel.js.html b/docs/sceneObjs_other_TextLabel.js.html new file mode 100644 index 00000000..8038dc40 --- /dev/null +++ b/docs/sceneObjs_other_TextLabel.js.html @@ -0,0 +1,250 @@ + + + + + JSDoc: Source: sceneObjs/other/TextLabel.js + + + + + + + + + + +
    + +

    Source: sceneObjs/other/TextLabel.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import i18next from 'i18next';
    +import geometry from '../../geometry.js';
    +
    +/**
    + * Text label
    + * 
    + * Tools -> Other -> Text
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {number} x - The x coordinate.
    + * @property {number} y - The y coordinate.
    + * @property {string} text - The text content.
    + * @property {number} fontSize - The font size.
    + * @property {string} font - The font name.
    + * @property {string} fontStyle - The font style.
    + * @property {string} alignment - The font alignment.
    + * @property {boolean} smallCaps - Whether the text is in small caps.
    + * @property {number} angle - The angle of the text in degrees.
    + */
    +class TextLabel extends BaseSceneObj {
    +  static type = 'TextLabel';
    +  static serializableDefaults = {
    +    x: null,
    +    y: null,
    +    text: '',
    +    fontSize: 24,
    +    font: 'Serif',
    +    fontStyle: 'Normal',
    +    alignment: 'left',
    +    smallCaps: false,
    +    angle: 0
    +  };
    +
    +  // generic list of web safe fonts
    +  static fonts = [
    +    'Serif',
    +    'Arial',
    +    'Helvetica',
    +    'Times New Roman',
    +    'Georgia',
    +    'Courier New',
    +    'Verdana',
    +    'Tahoma',
    +    'Trebuchet MS',
    +    'Impact',
    +    'Lucida Sans'
    +  ];
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:tools.TextLabel.title'));
    +    objBar.createText('', this.text, function (obj, value) {
    +      obj.text = value;
    +    });
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['fontSize']))) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.TextLabel.fontSize'), 6, 96, 1, this.fontSize, function (obj, value) {
    +        obj.fontSize = value;
    +      }, null, true);
    +    }
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['font']))) {
    +      objBar.createDropdown(i18next.t('simulator:sceneObjs.TextLabel.font'), this.font, this.constructor.fonts, function (obj, value) {
    +        obj.font = value;
    +      });
    +    }
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['fontStyle']))) {
    +      objBar.createDropdown(i18next.t('simulator:sceneObjs.TextLabel.fontStyle'), this.fontStyle, {
    +        'Normal': i18next.t('simulator:sceneObjs.TextLabel.fontStyles.normal'),
    +        'Bold': i18next.t('simulator:sceneObjs.TextLabel.fontStyles.bold'),
    +        'Italic': i18next.t('simulator:sceneObjs.TextLabel.fontStyles.italic'),
    +        'Bold Italic': i18next.t('simulator:sceneObjs.TextLabel.fontStyles.boldItalic'),
    +        'Oblique': i18next.t('simulator:sceneObjs.TextLabel.fontStyles.oblique'),
    +        'Bold Oblique': i18next.t('simulator:sceneObjs.TextLabel.fontStyles.boldOblique')
    +      }, function (obj, value) {
    +        obj.fontStyle = value;
    +      });
    +    }
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['alignment']))) {
    +      objBar.createDropdown(i18next.t('simulator:sceneObjs.TextLabel.alignment'), this.alignment, {
    +        'left': i18next.t('simulator:sceneObjs.TextLabel.alignments.left'),
    +        'center': i18next.t('simulator:sceneObjs.TextLabel.alignments.center'),
    +        'right': i18next.t('simulator:sceneObjs.TextLabel.alignments.right')
    +      }, function (obj, value) {
    +        obj.alignment = value;
    +      });
    +    }
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['smallCaps']))) {
    +      objBar.createBoolean(i18next.t('simulator:sceneObjs.TextLabel.smallCaps'), this.smallCaps, function (obj, value) {
    +        obj.smallCaps = value;
    +      });
    +    }
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['angle']))) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.TextLabel.angle') + ' (°)', 0, 360, 1, this.angle, function (obj, value) {
    +        obj.angle = value;
    +      }, null, true);
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.fillStyle = isHovered ? 'cyan' : ('white');
    +    ctx.textAlign = this.alignment;
    +    ctx.textBaseline = 'bottom';
    +
    +    let font = '';
    +    if (this.fontStyle && this.fontStyle != 'Normal') font += this.fontStyle + ' ';
    +    if (this.smallCaps) font += 'small-caps '
    +    font += this.fontSize + 'px ' + this.font;
    +    ctx.font = font;
    +
    +    ctx.save();
    +    ctx.translate(this.x, this.y);
    +    ctx.rotate(-this.angle / 180 * Math.PI);
    +    let y_offset = 0;
    +    this.left = 0;
    +    this.right = 0;
    +    this.up = 0;
    +    this.down = 0;
    +    this.text.split('\n').forEach(line => {
    +      ctx.fillText(line, 0, y_offset);
    +      let lineDimensions = ctx.measureText(line);
    +      this.left = Math.max(this.left, lineDimensions.actualBoundingBoxLeft);
    +      this.right = Math.max(this.right, lineDimensions.actualBoundingBoxRight);
    +      this.up = Math.max(this.up, lineDimensions.actualBoundingBoxAscent - y_offset);
    +      this.down = Math.max(this.down, -lineDimensions.actualBoundingBoxDescent + y_offset);
    +      if (lineDimensions.fontBoundingBoxAscent) {
    +        y_offset += lineDimensions.fontBoundingBoxAscent + lineDimensions.fontBoundingBoxDescent;
    +      } else {
    +        y_offset += this.fontSize * 1.5;
    +      }
    +    });
    +    ctx.restore();
    +    // precompute triganometry for faster calculations in 'clicked' function
    +    this.sin_angle = Math.sin(this.angle / 180 * Math.PI);
    +    this.cos_angle = Math.cos(this.angle / 180 * Math.PI);
    +  }
    +
    +  move(diffX, diffY) {
    +    this.x = this.x + diffX;
    +    this.y = this.y + diffY;
    +  }
    +  
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    this.x = mousePos.x;
    +    this.y = mousePos.y;
    +    this.text = i18next.t('simulator:sceneObjs.TextLabel.textHere');
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    return {
    +      isDone: true
    +    };
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +
    +    // translate and rotate the mouse point into the text's reference frame for easy comparison
    +    let relativeMouseX = mouse.pos.x - this.x
    +    let relativeMouseY = mouse.pos.y - this.y
    +    let rotatedMouseX = relativeMouseX * this.cos_angle - relativeMouseY * this.sin_angle;
    +    let rotatedMouseY = relativeMouseY * this.cos_angle + relativeMouseX * this.sin_angle;
    +    if (rotatedMouseX >= -this.left && rotatedMouseX <= this.right &&
    +      rotatedMouseY <= this.down && rotatedMouseY >= -this.up) {
    +      dragContext.part = 0;
    +      dragContext.mousePos0 = geometry.point(mouse.pos.x, mouse.pos.y);
    +      dragContext.mousePos0Snapped = mouse.getPosSnappedToGrid();
    +      dragContext.targetPoint_ = geometry.point(this.x, this.y); // Avoid setting 'targetPoint' (otherwise the xybox will appear and move the text to incorrect coordinates).
    +      dragContext.snapContext = {};
    +      return dragContext;
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    if (shift) {
    +      var mousePos = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }], dragContext.snapContext);
    +    } else {
    +      var mousePos = mouse.getPosSnappedToGrid();
    +      dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +    }
    +
    +    // 'dragContext.targetPoint_' object placement position (bottom left)
    +    // 'dragContext.mousePos0' is coordiates of where the drag started, not snapped
    +    // 'dragContext.mousePos0Snapped' is coordiates of where the drag started, snapped to grid
    +    // new location  =  current location (snapped)  +  object placement location  -  where drag started (snapped)
    +    this.x = mousePos.x + dragContext.targetPoint_.x - dragContext.mousePos0Snapped.x;
    +    this.y = mousePos.y + dragContext.targetPoint_.y - dragContext.mousePos0Snapped.y;
    +  }
    +};
    +
    +export default TextLabel;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_special_CropBox.js.html b/docs/sceneObjs_special_CropBox.js.html new file mode 100644 index 00000000..4756581c --- /dev/null +++ b/docs/sceneObjs_special_CropBox.js.html @@ -0,0 +1,286 @@ + + + + + JSDoc: Source: sceneObjs/special/CropBox.js + + + + + + + + + + +
    + +

    Source: sceneObjs/special/CropBox.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import geometry from '../../geometry.js';
    +import i18next from 'i18next';
    +
    +/**
    + * The crop box
    + * 
    + * File -> Export as PNG/SVG
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The top left corner of the crop box.
    + * @property {Point} p2 - The top right corner of the crop box.
    + * @property {Point} p3 - The bottom left corner of the crop box.
    + * @property {Point} p4 - The bottom right corner of the crop box.
    + * @property {string} format - The format of the image to be exported.
    + * @property {number} width - The width of the image to be exported. Not effective when the format is 'svg'.
    + * @property {number} rayCountLimit - The maximum number of rays to be traced. This is to avoid infinite loop. If not set, the default value is determined by the simulator and depends on `format`.
    + */
    +class CropBox extends BaseSceneObj {
    +  static type = 'CropBox';
    +  static serializableDefaults = {
    +    p1: null,
    +    p4: null,
    +    format: 'png',
    +    width: 1920,
    +    rayCountLimit: null
    +  };
    +
    +  constructor(scene, jsonObj) {
    +    super(scene, jsonObj);
    +
    +    // Infer `p2` and `p3` from `p1` and `p4`.
    +    if (this.p1 && this.p4) {
    +      this.p2 = geometry.point(this.p4.x, this.p1.y);
    +      this.p3 = geometry.point(this.p1.x, this.p4.y);
    +    }
    +  }
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('simulator:sceneObjs.CropBox.title'));
    +
    +    var width = geometry.distance(this.p1, this.p2);
    +    var height = geometry.distance(this.p1, this.p3);
    +
    +    objBar.createNumber(i18next.t('simulator:sceneObjs.CropBox.cropBoxSize'), 0, 1000, 1, width, function (obj, value) {
    +      obj.p2 = geometry.point(obj.p1.x + 1 * value, obj.p2.y);
    +      obj.p4 = geometry.point(obj.p3.x + 1 * value, obj.p4.y);
    +    }, null, true);
    +    objBar.createNumber('x', 0, 1000, 1, height, function (obj, value) {
    +      obj.p3 = geometry.point(obj.p3.x, obj.p1.y + 1 * value);
    +      obj.p4 = geometry.point(obj.p4.x, obj.p2.y + 1 * value);
    +    }, null, true);
    +
    +    objBar.createDropdown(i18next.t('simulator:sceneObjs.CropBox.format'), this.format, {
    +      'png': 'PNG',
    +      'svg': 'SVG'
    +    }, function (obj, value) {
    +      obj.format = value;
    +    }, null, true);
    +
    +    if (this.format != 'svg') {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.CropBox.width'), 0, 1000, 1, this.width, function (obj, value) {
    +        obj.width = 1 * value;
    +      }, null, true);
    +    }
    +
    +    const rayCountLimit = this.rayCountLimit || (this.format === 'svg' ? 1e4 : 1e7);
    +
    +    if (objBar.showAdvanced(!this.arePropertiesDefault(['rayCountLimit']))) {
    +      objBar.createNumber(i18next.t('simulator:sceneObjs.CropBox.rayCountLimit'), 0, 1e7, 1, rayCountLimit, function (obj, value) {
    +        obj.rayCountLimit = value;
    +        if (this.scene.simulator.processedRayCount > obj.rayCountLimit) {
    +          obj.warning = i18next.t('simulator:sceneObjs.CropBox.rayCountWarning');
    +        } else {
    +          obj.warning = null;
    +        }
    +      }, null, true);
    +    }
    +
    +    const self = this;
    +    objBar.createButton(i18next.t('simulator:common.saveButton'), function (obj) {
    +      self.warning = null;
    +      self.scene.editor.confirmCrop(obj);
    +    });
    +    objBar.createButton(i18next.t('simulator:common.cancelButton'), function (obj) {
    +      self.warning = null;
    +      self.scene.editor.cancelCrop();
    +    });
    +
    +    this.warning = null;
    +
    +    if (this.format === 'svg') {
    +      if (this.scene.simulateColors) {
    +        this.warning = i18next.t('simulator:sceneObjs.CropBox.svgWarning');
    +      }
    +
    +      // Check if there are any objects with `refIndex < 1`
    +      for (var obj of this.scene.opticalObjs) {
    +        if (obj.refIndex && obj.refIndex < 1) {
    +          this.warning = i18next.t('simulator:sceneObjs.CropBox.svgWarning');
    +          break;
    +        }
    +      }
    +    }
    +
    +    if (this.scene.simulator.processedRayCount > rayCountLimit) {
    +      this.warning = i18next.t('simulator:sceneObjs.CropBox.rayCountWarning');
    +    }
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    if (!(this.scene.editor && this.scene.editor.isInCropMode)) return;
    +
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    ctx.strokeStyle = isHovered ? 'cyan' : 'white';
    +    ctx.lineWidth = 1 * ls;
    +    ctx.beginPath();
    +    ctx.moveTo(this.p1.x, this.p1.y);
    +    ctx.lineTo(this.p2.x, this.p2.y);
    +    ctx.lineTo(this.p4.x, this.p4.y);
    +    ctx.lineTo(this.p3.x, this.p3.y);
    +    ctx.lineTo(this.p1.x, this.p1.y);
    +    ctx.stroke();
    +    ctx.fillStyle = isHovered ? 'cyan' : 'white';
    +    ctx.beginPath();
    +    ctx.arc(this.p1.x, this.p1.y, 5 * ls, 0, 2 * Math.PI);
    +    ctx.fill();
    +    ctx.beginPath();
    +    ctx.arc(this.p2.x, this.p2.y, 5 * ls, 0, 2 * Math.PI);
    +    ctx.fill();
    +    ctx.beginPath();
    +    ctx.arc(this.p3.x, this.p3.y, 5 * ls, 0, 2 * Math.PI);
    +    ctx.fill();
    +    ctx.beginPath();
    +    ctx.arc(this.p4.x, this.p4.y, 5 * ls, 0, 2 * Math.PI);
    +    ctx.fill();
    +  }
    +
    +  move(diffX, diffY) {
    +    this.p1.x += diffX;
    +    this.p1.y += diffY;
    +    this.p2.x += diffX;
    +    this.p2.y += diffY;
    +    this.p3.x += diffX;
    +    this.p3.y += diffY;
    +    this.p4.x += diffX;
    +    this.p4.y += diffY;
    +  }
    +
    +  checkMouseOver(mouse) {
    +    if (!(this.scene.editor && this.scene.editor.isInCropMode)) return false;
    +    if (mouse.isOnPoint(this.p1)) {
    +      return { part: 1, targetPoint: geometry.point(this.p1.x, this.p1.y), cursor: 'nwse-resize', requiresObjBarUpdate: true };
    +    }
    +    if (mouse.isOnPoint(this.p2)) {
    +      return { part: 2, targetPoint: geometry.point(this.p2.x, this.p2.y), cursor: 'nesw-resize', requiresObjBarUpdate: true };
    +    }
    +    if (mouse.isOnPoint(this.p3)) {
    +      return { part: 3, targetPoint: geometry.point(this.p3.x, this.p3.y), cursor: 'nesw-resize', requiresObjBarUpdate: true };
    +    }
    +    if (mouse.isOnPoint(this.p4)) {
    +      return { part: 4, targetPoint: geometry.point(this.p4.x, this.p4.y), cursor: 'nwse-resize', requiresObjBarUpdate: true };
    +    }
    +    if (mouse.isOnSegment(geometry.line(this.p1, this.p2))) {
    +      return { part: 5, cursor: 'ns-resize', requiresObjBarUpdate: true };
    +    }
    +    if (mouse.isOnSegment(geometry.line(this.p2, this.p4))) {
    +      return { part: 6, cursor: 'ew-resize', requiresObjBarUpdate: true };
    +    }
    +    if (mouse.isOnSegment(geometry.line(this.p3, this.p4))) {
    +      return { part: 7, cursor: 'ns-resize', requiresObjBarUpdate: true };
    +    }
    +    if (mouse.isOnSegment(geometry.line(this.p1, this.p3))) {
    +      return { part: 8, cursor: 'ew-resize', requiresObjBarUpdate: true };
    +    }
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    if (this.p1.x < mousePos.x && mousePos.x < this.p2.x && this.p1.y < mousePos.y && mousePos.y < this.p3.y) {
    +      return { part: 0, mousePos0: mousePos, mousePos1: mousePos, snapContext: {} };
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    if (dragContext.part == 1) {
    +      this.p1.x = mousePos.x;
    +      this.p1.y = mousePos.y;
    +      this.p2.y = mousePos.y;
    +      this.p3.x = mousePos.x;
    +    } else if (dragContext.part == 2) {
    +      this.p2.x = mousePos.x;
    +      this.p2.y = mousePos.y;
    +      this.p1.y = mousePos.y;
    +      this.p4.x = mousePos.x;
    +    } else if (dragContext.part == 3) {
    +      this.p3.x = mousePos.x;
    +      this.p3.y = mousePos.y;
    +      this.p1.x = mousePos.x;
    +      this.p4.y = mousePos.y;
    +    } else if (dragContext.part == 4) {
    +      this.p4.x = mousePos.x;
    +      this.p4.y = mousePos.y;
    +      this.p2.x = mousePos.x;
    +      this.p3.y = mousePos.y;
    +    } else if (dragContext.part == 5) {
    +      this.p1.y = mousePos.y;
    +      this.p2.y = mousePos.y;
    +    } else if (dragContext.part == 6) {
    +      this.p2.x = mousePos.x;
    +      this.p4.x = mousePos.x;
    +    } else if (dragContext.part == 7) {
    +      this.p3.y = mousePos.y;
    +      this.p4.y = mousePos.y;
    +    } else if (dragContext.part == 8) {
    +      this.p1.x = mousePos.x;
    +      this.p3.x = mousePos.x;
    +    } else if (dragContext.part == 0) {
    +      const mousePosSnapped = shift ? mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }], dragContext.snapContext) : mouse.getPosSnappedToGrid();
    +      const mouseDiffX = dragContext.mousePos1.x - mousePosSnapped.x;
    +      const mouseDiffY = dragContext.mousePos1.y - mousePosSnapped.y;
    +      this.p1.x -= mouseDiffX;
    +      this.p1.y -= mouseDiffY;
    +      this.p2.x -= mouseDiffX;
    +      this.p2.y -= mouseDiffY;
    +      this.p3.x -= mouseDiffX;
    +      this.p3.y -= mouseDiffY;
    +      this.p4.x -= mouseDiffX;
    +      this.p4.y -= mouseDiffY;
    +      dragContext.mousePos1 = mousePosSnapped;
    +    }
    +  }
    +};
    +
    +export default CropBox;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_special_Handle.js.html b/docs/sceneObjs_special_Handle.js.html new file mode 100644 index 00000000..521f73fe --- /dev/null +++ b/docs/sceneObjs_special_Handle.js.html @@ -0,0 +1,397 @@ + + + + + JSDoc: Source: sceneObjs/special/Handle.js + + + + + + + + + + +
    + +

    Source: sceneObjs/special/Handle.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import geometry from '../../geometry.js';
    +import Mouse from '../../Mouse.js';
    +import i18next from 'i18next';
    +
    +/**
    + * The handle created when holding ctrl and click several points.
    + * @class
    + * @extends BaseSceneObj
    + * @memberof sceneObjs
    + * @property {Point} p1 - The position of the handle.
    + * @property {Point} p2 - The position of the rotation/scale center.
    + * @property {Array<ControlPoint>} controlPoints - The control points bound to the handle.
    + * @property {string} transformation - The transformation applied to the control points when dragging the handle, with the corresponding arrows marked on the handle. Possible values are "default", "translation", "xTranslation", "yTranslation", "rotation", "scaling". The "default" is the only behavior in older versions where no arrow is marked on the handle, and the transformation is determined by the ctrl and shift keys.
    + * @property {boolean} notDone - Whether the construction of the handle is complete.
    + */
    +class Handle extends BaseSceneObj {
    +  static type = 'Handle';
    +  static isOptical = true; // As the handle may bind to objects which are optical, this should be regarded as true.
    +  static serializableDefaults = {
    +    p1: null,
    +    p2: null,
    +    controlPoints: [],
    +    transformation: "default",
    +    notDone: false
    +  };
    +
    +  serialize() {
    +    let jsonObj = super.serialize();
    +
    +    if (jsonObj.controlPoints) {
    +      // Remove some redundent properties in the control points to reduce the size of the JSON.
    +      jsonObj.controlPoints = jsonObj.controlPoints.map(controlPoint => {
    +        let controlPointCopy = JSON.parse(JSON.stringify(controlPoint));
    +        delete controlPointCopy.dragContext.originalObj; // This should be inferred from `scene.objs[controlPoint.targetObjIndex]` directly.
    +        delete controlPointCopy.dragContext.hasDuplicated; // Always false.
    +        delete controlPointCopy.dragContext.isByHandle; // Always true.
    +        delete controlPointCopy.dragContext.targetPoint; // The target point is already stored in the newPoint.
    +        delete controlPointCopy.dragContext.snapContext; // Snapping is not possible with the handle.
    +
    +        return controlPointCopy;
    +      });
    +    }
    +
    +    return jsonObj;
    +  }
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('simulator:sceneObjs.Handle.handle'));
    +    objBar.createDropdown(i18next.t('simulator:sceneObjs.Handle.transformation'), this.transformation, {
    +      'default': i18next.t('simulator:common.defaultOption'),
    +      'translation': i18next.t('simulator:sceneObjs.Handle.transformations.translation'),
    +      'xTranslation': i18next.t('simulator:sceneObjs.Handle.transformations.xTranslation'),
    +      'yTranslation': i18next.t('simulator:sceneObjs.Handle.transformations.yTranslation'),
    +      'rotation': i18next.t('simulator:sceneObjs.Handle.transformations.rotation'),
    +      'scaling': i18next.t('simulator:sceneObjs.Handle.transformations.scaling')
    +    }, function (obj, value) {
    +      obj.transformation = value;
    +    }, null, true);
    +  }
    +
    +  getZIndex() {
    +    return -Infinity;
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +    ctx.lineWidth = 1 * ls;
    +
    +    if (this.transformation == "default" || isHovered) {
    +      for (var i in this.controlPoints) {
    +        ctx.globalAlpha = 1;
    +        ctx.beginPath();
    +        ctx.strokeStyle = this.notDone ? 'cyan' : isHovered ? 'cyan' : ('gray');
    +        ctx.setLineDash([2 * ls, 2 * ls]);
    +        ctx.arc(this.controlPoints[i].newPoint.x, this.controlPoints[i].newPoint.y, 5 * ls, 0, Math.PI * 2, false);
    +        ctx.stroke();
    +        ctx.setLineDash([]);
    +      }
    +    }
    +
    +    const arrowLineWidthCross = 5 * ls;
    +    const arrowLineWidthSingle = 8 * ls;
    +    const arrowLengthCross = 30 * ls;
    +    const arrowLengthSingle = 28 * ls;
    +    const arrowHeadSizeCross = 8 * ls;
    +    const arrowHeadSizeSingle = 12 * ls;
    +
    +    if (!this.notDone) {
    +      ctx.globalAlpha = 1;
    +      // Draw the handle arrow according to the transformation
    +      switch (this.transformation) {
    +        case "default":
    +          ctx.beginPath();
    +          ctx.strokeStyle = isHovered ? 'cyan' : ('gray');
    +          ctx.arc(this.p1.x, this.p1.y, 2 * ls, 0, Math.PI * 2, false);
    +          ctx.stroke();
    +          ctx.beginPath();
    +          ctx.arc(this.p1.x, this.p1.y, 5 * ls, 0, Math.PI * 2, false);
    +          ctx.stroke();
    +          break;
    +        case "translation":
    +          // Cross arrows
    +          ctx.beginPath();
    +          ctx.strokeStyle = isHovered ? 'cyan' : ('white');
    +          ctx.fillStyle = isHovered ? 'cyan' : ('white');
    +          ctx.lineWidth = arrowLineWidthCross;
    +          ctx.moveTo(this.p1.x - arrowLengthCross / 2, this.p1.y);
    +          ctx.lineTo(this.p1.x + arrowLengthCross / 2, this.p1.y);
    +          ctx.stroke();
    +          ctx.beginPath();
    +          ctx.moveTo(this.p1.x, this.p1.y - arrowLengthCross / 2);
    +          ctx.lineTo(this.p1.x, this.p1.y + arrowLengthCross / 2);
    +          ctx.stroke();
    +          this.drawArrowHead(canvasRenderer, this.p1.x + (arrowLengthCross + arrowHeadSizeCross) / 2, this.p1.y, 0, arrowHeadSizeCross);
    +          this.drawArrowHead(canvasRenderer, this.p1.x, this.p1.y + (arrowLengthCross + arrowHeadSizeCross) / 2, Math.PI / 2, arrowHeadSizeCross);
    +          this.drawArrowHead(canvasRenderer, this.p1.x - (arrowLengthCross + arrowHeadSizeCross) / 2, this.p1.y, Math.PI, arrowHeadSizeCross);
    +          this.drawArrowHead(canvasRenderer, this.p1.x, this.p1.y - (arrowLengthCross + arrowHeadSizeCross) / 2, -Math.PI / 2, arrowHeadSizeCross);
    +          break;
    +        case "xTranslation":
    +          // Horizontal arrow
    +          ctx.beginPath();
    +          ctx.strokeStyle = isHovered ? 'cyan' : ('white');
    +          ctx.fillStyle = isHovered ? 'cyan' : ('white');
    +          ctx.lineWidth = arrowLineWidthSingle;
    +          ctx.moveTo(this.p1.x - arrowLengthSingle / 2, this.p1.y);
    +          ctx.lineTo(this.p1.x + arrowLengthSingle / 2, this.p1.y);
    +          ctx.stroke();
    +          this.drawArrowHead(canvasRenderer, this.p1.x + (arrowLengthSingle + arrowHeadSizeSingle) / 2, this.p1.y, 0, arrowHeadSizeSingle);
    +          this.drawArrowHead(canvasRenderer, this.p1.x - (arrowLengthSingle + arrowHeadSizeSingle) / 2, this.p1.y, Math.PI, arrowHeadSizeSingle);
    +          break;
    +        case "yTranslation":
    +          // Vertical arrow
    +          ctx.beginPath();
    +          ctx.strokeStyle = isHovered ? 'cyan' : ('white');
    +          ctx.fillStyle = isHovered ? 'cyan' : ('white');
    +          ctx.lineWidth = arrowLineWidthSingle;
    +          ctx.moveTo(this.p1.x, this.p1.y - arrowLengthSingle / 2);
    +          ctx.lineTo(this.p1.x, this.p1.y + arrowLengthSingle / 2);
    +          ctx.stroke();
    +          this.drawArrowHead(canvasRenderer, this.p1.x, this.p1.y + (arrowLengthSingle + arrowHeadSizeSingle) / 2, Math.PI / 2, arrowHeadSizeSingle);
    +          this.drawArrowHead(canvasRenderer, this.p1.x, this.p1.y - (arrowLengthSingle + arrowHeadSizeSingle) / 2, -Math.PI / 2, arrowHeadSizeSingle);
    +          break;
    +        case "rotation":
    +          // A bent arrow
    +          ctx.beginPath();
    +          ctx.strokeStyle = isHovered ? 'cyan' : ('white');
    +          ctx.fillStyle = isHovered ? 'cyan' : ('white');
    +          ctx.lineWidth = arrowLineWidthSingle;
    +          //const radius = geometry.distance(this.p1, this.p2);
    +          const radius = 40 * ls;
    +          const angle = Math.atan2(this.p1.y - this.p2.y, this.p1.x - this.p2.x);
    +          const center = geometry.point(this.p1.x - radius * Math.cos(angle), this.p1.y - radius * Math.sin(angle));
    +          const angle1 = angle - arrowLengthSingle / radius / 2;
    +          const angle1_ = angle - (arrowLengthSingle + arrowHeadSizeSingle) / radius / 2;
    +          const angle2 = angle + arrowLengthSingle / radius / 2;
    +          const angle2_ = angle + (arrowLengthSingle + arrowHeadSizeSingle) / radius / 2;
    +          ctx.arc(center.x, center.y, radius, angle1, angle2);
    +          ctx.stroke();
    +          this.drawArrowHead(canvasRenderer, center.x + radius * Math.cos(angle2_), center.y + radius * Math.sin(angle2_), angle2 + Math.PI / 2, arrowHeadSizeSingle);
    +          this.drawArrowHead(canvasRenderer, center.x + radius * Math.cos(angle1_), center.y + radius * Math.sin(angle1_), angle1 - Math.PI / 2, arrowHeadSizeSingle);
    +          break;
    +        case "scaling":
    +          // An arrow with different arrow head sizes
    +          ctx.beginPath();
    +          ctx.strokeStyle = isHovered ? 'cyan' : ('white');
    +          ctx.fillStyle = isHovered ? 'cyan' : ('white');
    +          ctx.lineWidth = arrowLineWidthSingle;
    +          const radialAngle = Math.atan2(this.p1.y - this.p2.y, this.p1.x - this.p2.x);
    +          const arrowHeadSizeLarge = 14 * ls;
    +          const arrowHeadSizeSmall = 10 * ls;
    +          ctx.beginPath();
    +          ctx.moveTo(this.p1.x - arrowLengthSingle / 2 * Math.cos(radialAngle), this.p1.y - arrowLengthSingle / 2 * Math.sin(radialAngle));
    +          ctx.lineTo(this.p1.x + arrowLengthSingle / 2 * Math.cos(radialAngle), this.p1.y + arrowLengthSingle / 2 * Math.sin(radialAngle));
    +          ctx.stroke();
    +          this.drawArrowHead(canvasRenderer, this.p1.x + (arrowLengthSingle + arrowHeadSizeLarge) / 2 * Math.cos(radialAngle), this.p1.y + (arrowLengthSingle + arrowHeadSizeLarge) / 2 * Math.sin(radialAngle), radialAngle, arrowHeadSizeLarge);
    +          this.drawArrowHead(canvasRenderer, this.p1.x - (arrowLengthSingle + arrowHeadSizeSmall) / 2 * Math.cos(radialAngle), this.p1.y - (arrowLengthSingle + arrowHeadSizeSmall) / 2 * Math.sin(radialAngle), radialAngle + Math.PI, arrowHeadSizeSmall);
    +      }
    +
    +      // Draw the rotation/scale center
    +      ctx.lineWidth = 1 * ls;
    +      if (this.transformation == "default" || this.transformation == "rotation" || this.transformation == "scaling") {
    +        ctx.strokeStyle = isHovered ? 'cyan' : ('gray');
    +        ctx.beginPath();
    +        ctx.moveTo(this.p2.x - 5 * ls, this.p2.y);
    +        ctx.lineTo(this.p2.x + 5 * ls, this.p2.y);
    +        ctx.stroke();
    +        ctx.beginPath();
    +        ctx.moveTo(this.p2.x, this.p2.y - 5 * ls);
    +        ctx.lineTo(this.p2.x, this.p2.y + 5 * ls);
    +        ctx.stroke();
    +      }
    +    }
    +  }
    +
    +  move(diffX, diffY) {
    +    this.p1.x = this.p1.x + diffX;
    +    this.p1.y = this.p1.y + diffY;
    +    this.p2.x = this.p2.x + diffX;
    +    this.p2.y = this.p2.y + diffY;
    +    for (var i in this.controlPoints) {
    +      this.controlPoints[i].dragContext.originalObj = this.scene.objs[this.controlPoints[i].targetObjIndex].serialize();
    +      this.controlPoints[i].dragContext.isByHandle = true;
    +      this.controlPoints[i].dragContext.hasDuplicated = false;
    +      this.controlPoints[i].dragContext.targetPoint = { x: this.controlPoints[i].newPoint.x, y: this.controlPoints[i].newPoint.y };
    +      this.controlPoints[i].dragContext.snapContext = {};
    +
    +      this.controlPoints[i].newPoint.x = this.controlPoints[i].newPoint.x + diffX;
    +      this.controlPoints[i].newPoint.y = this.controlPoints[i].newPoint.y + diffY;
    +      this.scene.objs[this.controlPoints[i].targetObjIndex].onDrag(new Mouse(JSON.parse(JSON.stringify(this.controlPoints[i].newPoint)), this.scene, false, 2), JSON.parse(JSON.stringify(this.controlPoints[i].dragContext)), false, false);
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +    if (this.notDone) return;
    +    if (mouse.isOnPoint(this.p1) || (this.transformation != "default" && geometry.distance(this.p1, mouse.pos) < 20 * this.scene.lengthScale)) {
    +      dragContext.part = 1;
    +      dragContext.targetPoint_ = geometry.point(this.p1.x, this.p1.y);
    +      dragContext.mousePos0 = geometry.point(this.p1.x, this.p1.y);
    +      dragContext.snapContext = {};
    +      return dragContext;
    +    }
    +    if ((this.transformation == "default" || this.transformation == "rotation" || this.transformation == "scaling") && mouse.isOnPoint(this.p2)) {
    +      dragContext.part = 2;
    +      dragContext.targetPoint = geometry.point(this.p2.x, this.p2.y);
    +      dragContext.mousePos0 = geometry.point(this.p2.x, this.p2.y);
    +      dragContext.snapContext = {};
    +      return dragContext;
    +    }
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    if (this.notDone) return;
    +    if (shift) {
    +      var mousePos = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }], dragContext.snapContext);
    +    } else {
    +      var mousePos = mouse.getPosSnappedToGrid();
    +      dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +    }
    +    if (dragContext.part == 1) {
    +      if ((ctrl && shift) || this.transformation == "scaling") { 
    +        // Scaling
    +        var factor = geometry.distance(this.p2, mouse.pos) / geometry.distance(this.p2, dragContext.targetPoint_)
    +        if (factor < 1e-5) return;
    +        var center = this.p2;
    +        var trans = function (p) {
    +          p.x = (p.x - center.x) * factor + center.x;
    +          p.y = (p.y - center.y) * factor + center.y;
    +        };
    +      } else if (ctrl || this.transformation == "rotation") {
    +        // Rotation
    +        var theta = Math.atan2(this.p2.y - mouse.pos.y, this.p2.x - mouse.pos.x) - Math.atan2(this.p2.y - dragContext.targetPoint_.y, this.p2.x - dragContext.targetPoint_.x);
    +        var center = this.p2;
    +        var trans = function (p) {
    +          var x = p.x - center.x;
    +          var y = p.y - center.y;
    +          p.x = Math.cos(theta) * x - Math.sin(theta) * y + center.x;
    +          p.y = Math.sin(theta) * x + Math.cos(theta) * y + center.y;
    +        };
    +      } else {
    +        // Translation
    +        var diffX = this.transformation == "yTranslation" ? 0 : mousePos.x - dragContext.targetPoint_.x;
    +        var diffY = this.transformation == "xTranslation" ? 0 : mousePos.y - dragContext.targetPoint_.y;
    +        var trans = function (p) {
    +          p.x += diffX;
    +          p.y += diffY;
    +        };
    +      }
    +
    +      // Do the transformation
    +      trans(this.p1);
    +      trans(this.p2);
    +      for (var i in this.controlPoints) {
    +        this.controlPoints[i].dragContext.originalObj = this.scene.objs[this.controlPoints[i].targetObjIndex].serialize();
    +        this.controlPoints[i].dragContext.isByHandle = true;
    +        this.controlPoints[i].dragContext.hasDuplicated = false;
    +        this.controlPoints[i].dragContext.targetPoint = { x: this.controlPoints[i].newPoint.x, y: this.controlPoints[i].newPoint.y };
    +        this.controlPoints[i].dragContext.snapContext = {};
    +        trans(this.controlPoints[i].newPoint);
    +        this.scene.objs[this.controlPoints[i].targetObjIndex].onDrag(new Mouse(JSON.parse(JSON.stringify(this.controlPoints[i].newPoint)), this.scene, false, 2), JSON.parse(JSON.stringify(this.controlPoints[i].dragContext)), false, false);
    +      }
    +      dragContext.targetPoint_.x = this.p1.x;
    +      dragContext.targetPoint_.y = this.p1.y;
    +    }
    +
    +    if (dragContext.part == 2) {
    +      this.p2.x = mousePos.x;
    +      this.p2.y = mousePos.y;
    +    }
    +  }
    +
    +  /**
    +   * Add (bind) a control point to the handle.
    +   * @param {ControlPoint} controlPoint - The control point to be bound.
    +   */
    +  addControlPoint(controlPoint) {
    +    controlPoint.dragContext.originalObj = this.scene.objs[controlPoint.targetObjIndex];
    +    controlPoint.dragContext.isByHandle = true;
    +    controlPoint.dragContext.hasDuplicated = false;
    +    controlPoint.newPoint = controlPoint.dragContext.targetPoint;
    +    controlPoint = JSON.parse(JSON.stringify(controlPoint));
    +    this.controlPoints.push(controlPoint);
    +  }
    +
    +  /**
    +   * Finish creating the handle.
    +   * @param {Point} point - The position of the handle.
    +   */
    +  finishHandle(point) {
    +    this.p1 = point;
    +    var totalX = 0;
    +    var totalY = 0;
    +    for (var i in this.controlPoints) {
    +      totalX += this.controlPoints[i].newPoint.x;
    +      totalY += this.controlPoints[i].newPoint.y;
    +    }
    +    this.p2 = geometry.point(totalX / this.controlPoints.length, totalY / this.controlPoints.length);
    +    this.notDone = false;
    +  }
    +
    +  /**
    +   * Draw an filled arrow head at the given position with the given angle and size.
    +   * @param {CanvasRenderer} canvasRenderer - The canvas renderer.
    +   * @param {number} x - The x-coordinate of the arrow head.
    +   * @param {number} y - The y-coordinate of the arrow head.
    +   * @param {number} angle - The angle of the arrow head.
    +   * @param {number} size - The size of the arrow head.
    +   */
    +  drawArrowHead(canvasRenderer, x, y, angle, size) {
    +    const ctx = canvasRenderer.ctx;
    +    ctx.save();
    +    ctx.translate(x, y);
    +    ctx.rotate(angle);
    +    ctx.beginPath();
    +    ctx.moveTo(0, 0);
    +    ctx.lineTo(-size, -size);
    +    ctx.lineTo(-size, size);
    +    ctx.closePath();
    +    ctx.fill();
    +    ctx.restore();
    +  }
    +
    +};
    +
    +export default Handle;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/sceneObjs_special_ModuleObj.js.html b/docs/sceneObjs_special_ModuleObj.js.html new file mode 100644 index 00000000..a04a4daf --- /dev/null +++ b/docs/sceneObjs_special_ModuleObj.js.html @@ -0,0 +1,543 @@ + + + + + JSDoc: Source: sceneObjs/special/ModuleObj.js + + + + + + + + + + +
    + +

    Source: sceneObjs/special/ModuleObj.js

    + + + + + + +
    +
    +
    import BaseSceneObj from '../BaseSceneObj.js';
    +import geometry from '../../geometry.js';
    +import i18next from 'i18next';
    +import * as sceneObjs from '../../sceneObjs.js';
    +import * as math from 'mathjs';
    +
    +/**
    + * @typedef {Object} ModuleDef
    + * @property {number} numPoints - The number of control points of the module.
    + * @property {Array<string>} params - The parameters of the module.
    + * @property {Array<Object>} objs - The objects in the module in the form of JSON objects with template syntax.
    + * @property {number} maxLoopLength - The maximum length of the list in for loops to prevent infinite loops.
    + */
    +
    +/**
    + * The class for a module object.
    + * This feature is experimental and may be changed in the future without backward compatibility.
    + * Currently, there is no UI for creating a module object. You can create a module object by directly editing the JSON data of the scene.
    + * @class
    + * @memberof sceneObjs
    + * @extends BaseSceneObj
    + * @property {string} module - The name of the module.
    + * @property {ModuleDef} moduleDef - The definition of the module.
    + * @property {Array<Point>} points - The control points of the module.
    + * @property {Object} params - The parameters of the module.
    + * @property {Array<BaseSceneObj>} objs - The expanded objects in the module.
    + */
    +class ModuleObj extends BaseSceneObj {
    +  static type = 'ModuleObj';
    +  static isOptical = true;
    +  static serializableDefaults = {
    +    module: null,
    +    points: null,
    +    params: null,
    +    notDone: false
    +  };
    +
    +  constructor(scene, jsonObj) {
    +    super(scene, jsonObj);
    +
    +    if (!this.module) return;
    +    this.moduleDef = this.scene.modules[this.module];
    +
    +    // Initialize the control points if not defined
    +    if (!this.points) {
    +      this.points = [];
    +      for (let i = 0; i < this.moduleDef.numPoints; i++) {
    +        this.points.push(geometry.point(0, 0));
    +      }
    +    }
    +
    +    // Initialize the parameters if not defined
    +    if (!this.params) {
    +      this.params = {};
    +      for (let param of this.moduleDef.params) {
    +        const parsed = this.parseVariableRange(param, {});
    +        this.params[parsed.name] = parsed.defaultVal;
    +      }
    +    }
    +
    +    // Expand the objects
    +    this.objs = [];
    +    this.expandObjs();
    +  }
    +
    +  populateObjBar(objBar) {
    +    objBar.setTitle(i18next.t('main:meta.colon', { name: i18next.t('simulator:sceneObjs.ModuleObj.module'), value: '<span style="font-family: monospace; padding-right:2px">' + this.module + '</span>' }));
    +
    +    if (this.notDone) return;
    +
    +    try {
    +      for (let param of this.moduleDef.params) {
    +        const parsed = this.parseVariableRange(param, {});
    +        objBar.createNumber('<span style="font-family: monospace;">' + parsed.name + '</span>', parsed.start, parsed.end, parsed.step, this.params[parsed.name], function (obj, value) {
    +          obj.params[parsed.name] = value;
    +          obj.expandObjs();
    +        });
    +      }
    +    } catch (e) {
    +      this.error = e;
    +    }
    +
    +    objBar.createButton(i18next.t('simulator:sceneObjs.ModuleObj.demodulize'), function (obj) {
    +      obj.demodulize();
    +    }, false, `
    +    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-down-left" viewBox="0 0 16 16">
    +      <path fill-rule="evenodd" d="M7.364 12.5a.5.5 0 0 0 .5.5H14.5a1.5 1.5 0 0 0 1.5-1.5v-10A1.5 1.5 0 0 0 14.5 0h-10A1.5 1.5 0 0 0 3 1.5v6.636a.5.5 0 1 0 1 0V1.5a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 .5.5v10a.5.5 0 0 1-.5.5H7.864a.5.5 0 0 0-.5.5"/>
    +      <path fill-rule="evenodd" d="M0 15.5a.5.5 0 0 0 .5.5h5a.5.5 0 0 0 0-1H1.707l8.147-8.146a.5.5 0 0 0-.708-.708L1 14.293V10.5a.5.5 0 0 0-1 0z"/>
    +    </svg>
    +    `);
    +  }
    +
    +  draw(canvasRenderer, isAboveLight, isHovered) {
    +    const ctx = canvasRenderer.ctx;
    +    const ls = canvasRenderer.lengthScale;
    +
    +    // Sort the expanded objects with z-index.
    +    let mapped = this.objs.map(function(obj, i) {
    +      return {index: i, value: obj.getZIndex()};
    +    });
    +    mapped.sort(function(a, b) {
    +      return a.value - b.value;
    +    });
    +    // Draw the expanded objects
    +    for (let j = 0; j < this.objs.length; j++) {
    +      let i = mapped[j].index;
    +      this.objs[i].draw(canvasRenderer, isAboveLight, isHovered);
    +    }
    +
    +    // Draw the control points
    +    ctx.lineWidth = 1 * ls;
    +    for (let point of this.points) {
    +      ctx.beginPath();
    +      ctx.strokeStyle = isHovered ? 'cyan' : ('gray');
    +      ctx.arc(point.x, point.y, 2 * ls, 0, Math.PI * 2, false);
    +      ctx.stroke();
    +      ctx.beginPath();
    +      ctx.arc(point.x, point.y, 5 * ls, 0, Math.PI * 2, false);
    +      ctx.stroke();
    +    }
    +  }
    +
    +  move(diffX, diffY) {
    +    // Note that translational symmetry is not guaranteed for the module. Some may have absolute positions. So instead of calling `move` of the expanded objects, we move the control points directly to maintain consistency of expansion.
    +
    +    if (this.points.length === 0) {
    +      return;
    +    }
    +
    +    // Move the control points
    +    for (let point of this.points) {
    +      point.x += diffX;
    +      point.y += diffY;
    +    }
    +    this.expandObjs();
    +  }
    +
    +  onConstructMouseDown(mouse, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +    if (!this.notDone) {
    +      // Initialize the construction stage
    +      this.notDone = true;
    +      if (this.module !== this.scene.editor.addingModuleName) {
    +        this.module = this.scene.editor.addingModuleName;
    +        this.moduleDef = this.scene.modules[this.module];
    +        // Initialize the parameters
    +        this.params = {};
    +        for (let param of this.moduleDef.params) {
    +          const parsed = this.parseVariableRange(param, {});
    +          this.params[parsed.name] = parsed.defaultVal;
    +        }
    +      }
    +      this.points = [];
    +      this.objs = [];
    +    }
    +
    +    if (this.points.length < this.moduleDef.numPoints) {
    +      this.points.push({ x: mousePos.x, y: mousePos.y });
    +    }
    +    if (this.points.length == this.moduleDef.numPoints) {
    +      // All control points have been added.
    +      this.notDone = false;
    +
    +      // Expand the objects
    +      this.expandObjs();
    +      return {
    +        requiresObjBarUpdate: true
    +      };
    +    }
    +  }
    +
    +  onConstructMouseUp(mouse, ctrl, shift) {
    +    if (this.points.length == this.moduleDef.numPoints) {
    +      return {
    +        isDone: true
    +      };
    +    }
    +  }
    +
    +  checkMouseOver(mouse) {
    +    let dragContext = {};
    +
    +    // Check if the mouse is on any control point
    +    let click_lensq = Infinity;
    +    let click_lensq_temp;
    +    let targetPoint_index = -1;
    +    for (var i = 0; i < this.points.length; i++) {
    +      if (mouse.isOnPoint(this.points[i])) {
    +        click_lensq_temp = geometry.distanceSquared(mouse.pos, this.points[i]);
    +        if (click_lensq_temp <= click_lensq) {
    +          click_lensq = click_lensq_temp;
    +          targetPoint_index = i;
    +        }
    +      }
    +    }
    +    if (targetPoint_index != -1) {
    +      dragContext.part = 1;
    +      dragContext.index = targetPoint_index;
    +      dragContext.targetPoint = geometry.point(this.points[targetPoint_index].x, this.points[targetPoint_index].y);
    +      return dragContext;
    +    }
    +
    +    // Check if the mouse is on any expanded object
    +    for (let obj of this.objs) {
    +      let dragContext1 = obj.checkMouseOver(mouse);
    +      if (dragContext1) {
    +        // If the mouse is on any expanded object, then the entire module is considered to be hovered. However, dragging the entire module object is allowed only when there are control points. Otherwise the module is defined with absolute positions and hence cannot be dragged.
    +
    +        if (this.points.length === 0) {
    +          dragContext.part = -1;
    +          if (dragContext1.targetPoint) {
    +            // Here the mouse is on a control point of the expanded object which is not a control point of the module. The user may expect that the control point is draggable but it is not. So we change the cursor to not-allowed to warn the user.
    +            dragContext.cursor = 'not-allowed';
    +          } else {
    +            dragContext.cursor = 'pointer';
    +          }
    +          return dragContext;
    +        } else {
    +          const mousePos = mouse.getPosSnappedToGrid();
    +          dragContext.part = 0;
    +          dragContext.mousePos0 = mousePos; // Mouse position when the user starts dragging
    +          dragContext.mousePos1 = mousePos; // Mouse position at the last moment during dragging
    +          dragContext.snapContext = {};
    +          return dragContext;
    +        }
    +      }
    +    }
    +
    +    return null;
    +  }
    +
    +  onDrag(mouse, dragContext, ctrl, shift) {
    +    const mousePos = mouse.getPosSnappedToGrid();
    +
    +    if (dragContext.part == 1) {
    +      this.points[dragContext.index].x = mousePos.x;
    +      this.points[dragContext.index].y = mousePos.y;
    +    }
    +
    +    if (dragContext.part == 0) {
    +      if (shift) {
    +        var mousePosSnapped = mouse.getPosSnappedToDirection(dragContext.mousePos0, [{ x: 1, y: 0 }, { x: 0, y: 1 }], dragContext.snapContext);
    +      } else {
    +        var mousePosSnapped = mouse.getPosSnappedToGrid();
    +        dragContext.snapContext = {}; // Unlock the dragging direction when the user release the shift key
    +      }
    +      this.move(mousePosSnapped.x - dragContext.mousePos1.x, mousePosSnapped.y - dragContext.mousePos1.y);
    +      dragContext.mousePos1 = mousePosSnapped;
    +    }
    +
    +    this.expandObjs();
    +  }
    +
    +  getError() {
    +    if (this.error) {
    +      return this.error;
    +    } else {
    +      let errors = [];
    +      for (let i in this.objs) {
    +        let error = this.objs[i].getError();
    +        if (error) {
    +          errors.push(`obj.objs[${i}] ${this.objs[i].constructor.type}: ${error}`);
    +        }
    +      }
    +      
    +      if (errors.length > 0) {
    +        return "In expanded objects:\n" + errors.join("\n");
    +      }
    +    }
    +
    +    return null;
    +  }
    +
    +  getWarning() {
    +    let warnings = [];
    +    for (let i in this.objs) {
    +      let warning = this.objs[i].getWarning();
    +      if (warning) {
    +        warnings.push(`obj.objs[${i}] ${this.objs[i].constructor.type}: ${warning}`);
    +      }
    +    }
    +
    +    if (warnings.length > 0) {
    +      return "In expanded objects:\n" + warnings.join("\n");
    +    }
    +
    +    return null;
    +  }
    +
    +
    +
    +  // Optical methods are not implemented for the module class, since the simulator operates on `scene.opticalObjs` which already expands all the modules.
    +
    +  /* Utility methods */
    +
    +
    +  /**
    +   * Parse the variable range description of the form "name=start:step:end" or "name=start:step:end:default", where start, step, and end are math.js strings.
    +   * @param {string} str - The variable range description.
    +   * @param {Object} params - The parameters to be used for evaluating the expressions.
    +   * @returns {Object} The parsed variable range.
    +   */
    +  parseVariableRange(str, params) {
    +    try {
    +      let parts = str.split('=');
    +      let name = parts[0].trim();
    +      let parts2 = parts[1].split(':');
    +      let start = parts2[0];
    +      let step = parts2[1];
    +      let end = parts2[2];
    +      let default_ = parts2.length == 4 ? parts2[3] : null;
    +      let startVal = math.evaluate(start, params);
    +      let stepVal = math.evaluate(step, params);
    +      let endVal = math.evaluate(end, params);
    +      let defaultVal = default_ === null ? startVal : math.evaluate(default_, params);
    +      return {name: name, start: startVal, step: stepVal, end: endVal, defaultVal: defaultVal};
    +    } catch (e) {
    +      throw `error parsing variable range "${str}" with parameters ${JSON.stringify(params)}: ${e}`;
    +    }
    +  }
    +
    +  /**
    +   * Expand a string with template syntax, where the format "`eqn`" is replaced with the value of "eqn" interpreted as an ASCIIMath expression with a given set of parameters. If the entire string is a single equation, then the result is a number. Otherwise, the result is a string.
    +   * @param {string} str - The string with template syntax.
    +   * @param {Object} params - The parameters to be used for evaluating the expressions.
    +   * @returns {number|string} The expanded string.
    +   */
    +  expandString(str, params) {
    +    try {
    +      let parts = str.split('`');
    +      if (parts.length == 3 && parts[0] == '' && parts[2] == '') {
    +
    +        return math.evaluate(parts[1], params);
    +      } else {
    +        let result = '';
    +        for (let i = 0; i < parts.length; i++) {
    +          if (i % 2 == 0) {
    +            result += parts[i];
    +          } else {
    +            result += math.evaluate(parts[i], params);
    +          }
    +        }
    +        return result;
    +      }
    +    } catch (e) {
    +      throw `error expanding string "${str}" with parameters ${JSON.stringify(params)}: ${e}`;
    +    }
    +  }
    +
    +  /**
    +   * Expand a (JavaScript) object with template syntax, where the string values of the object are interpreted with template syntax. Arrays and other objects are expanded recursively.
    +   * @param {Object} obj - The object with template syntax.
    +   * @param {Object} params - The parameters to be used for evaluating the expressions.
    +   * @returns {Object} The expanded object.
    +   */
    +  expandObject(obj, params) {
    +    let result = {};
    +    for (let key in obj) {
    +      if (key === 'for' || key === 'if') {
    +        continue;
    +      } else if (typeof obj[key] === 'string') {
    +        result[key] = this.expandString(obj[key], params);
    +      } else if (Array.isArray(obj[key])) {
    +        result[key] = this.expandArray(obj[key], params);
    +      } else if (typeof obj[key] === 'object') {
    +        result[key] = this.expandObject(obj[key], params);
    +      } else {
    +        result[key] = obj[key];
    +      }
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * Expand an array with template syntax, where the string values of the array are interpreted with template syntax. Arrays and objects are expanded recursively. If an object in the array has a key "for", then the object is expanded multiple times with the given range of values. If the value of "for" is a string, then the range is interpreted with `parseVariableRange`. If the value of "for" is an array of strings, then each string is witn `parseVariableRange` and there are multiple loop variable. If an object in the array has a key "if", then the object is included only if the condition is true.
    +   * @param {Array} arr - The array with template syntax.
    +   * @param {Object} params - The parameters to be used for evaluating the expressions.
    +   * @returns {Array} The expanded array.
    +   */
    +  expandArray(arr, params) {
    +    let result = [];
    +    for (let obj of arr) {
    +      try {
    +        if ('for' in obj) {
    +          let forObj = obj['for'];
    +          let loopVars = [];
    +          if (typeof forObj === 'string') {
    +            loopVars.push(this.parseVariableRange(forObj, params));
    +          } else if (Array.isArray(forObj)) {
    +            for (let forObj1 of forObj) {
    +              loopVars.push(this.parseVariableRange(forObj1, params));
    +            }
    +          }
    +
    +          const self = this;
    +
    +          // Expand `loopVars` to a list of objects, each a key-value pair of loop variable names and values (the Cartesian product of the ranges)
    +          function expandLoopVars(loopVars) {
    +            if (loopVars.length == 0) {
    +              return [params];
    +            } else {
    +              let result = [];
    +              let loopVars1 = loopVars.slice(1);
    +              const loopLength = (loopVars[0].end - loopVars[0].start) / loopVars[0].step + 1;
    +              if (loopLength > (self.moduleDef.maxLoopLength || 1000)) {
    +                throw `The length of the loop variable "${loopVars[0].name}" is too large. Please set maxLoopLength to a larger value.`;
    +              }
    +              for (let value = loopVars[0].start; value <= loopVars[0].end; value += loopVars[0].step) {
    +                for (let obj of expandLoopVars(loopVars1)) {
    +                  let obj1 = Object.assign({}, obj);
    +                  obj1[loopVars[0].name] = value;
    +                  result.push(obj1);
    +                }
    +              }
    +              return result;
    +            }
    +          }
    +
    +          const loopParams = expandLoopVars(loopVars);
    +
    +          if (loopParams.length > (this.moduleDef.maxLoopLength || 1000)) {
    +            throw `The length of the loop is too large. Please set maxLoopLength to a larger value.`;
    +          } else {
    +            for (let loopParam of loopParams) {
    +              if ('if' in obj && !math.evaluate(obj['if'], loopParam)) {
    +                continue;
    +              }
    +              result.push(this.expandObject(obj, loopParam));
    +            }
    +          }
    +
    +        } else if ('if' in obj) {
    +          if (math.evaluate(obj['if'], params)) {
    +            result.push(this.expandObject(obj, params));
    +          }
    +        } else if (typeof obj === 'string') {
    +          result.push(this.expandString(obj, params));
    +        } else if (Array.isArray(obj)) {
    +          result.push(this.expandArray(obj, params));
    +        } else if (typeof obj === 'object') {
    +          result.push(this.expandObject(obj, params));
    +        } else {
    +          result.push(obj);
    +        }
    +      } catch (e) {
    +        throw `error expanding object ${JSON.stringify(obj)} in array with parameters ${JSON.stringify(params)}: ${e}`;
    +      }
    +    }
    +    return result;
    +  }
    +
    +  /**
    +   * Expand the objects in the module.
    +   */
    +  expandObjs() {
    +    // Construct the full parameters including the coordinates of points with names "x_1", "y_1", "x_2", "y_2", ...
    +    const fullParams = {};
    +    for (let name in this.params) {
    +      fullParams[name] = this.params[name];
    +    }
    +    for (let i = 0; i < this.points.length; i++) {
    +      fullParams['x_' + (i+1)] = this.points[i].x;
    +      fullParams['y_' + (i+1)] = this.points[i].y;
    +    }
    +
    +    fullParams['random'] = this.scene.rng;
    +    
    +    this.error = null;
    +
    +    try {
    +      const expandedObjs = this.expandArray(this.moduleDef.objs, fullParams);
    +
    +      this.objs = expandedObjs.map(objData =>
    +        new sceneObjs[objData.type](this.scene, objData)
    +      );
    +    } catch (e) {
    +      this.error = e;
    +    }
    +  }
    +
    +  /**
    +   * Demodulize the module object.
    +   */
    +  demodulize() {
    +    // Remove the module object and add the expanded objects to the scene
    +    this.scene.removeObj(this.scene.objs.indexOf(this));
    +    for (let obj of this.objs) {
    +      this.scene.objs.push(obj);
    +    }
    +  }
    +}
    +
    +export default ModuleObj;
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/docs/scripts/linenumber.js b/docs/scripts/linenumber.js new file mode 100644 index 00000000..4354785c --- /dev/null +++ b/docs/scripts/linenumber.js @@ -0,0 +1,25 @@ +/*global document */ +(() => { + const source = document.getElementsByClassName('prettyprint source linenums'); + let i = 0; + let lineNumber = 0; + let lineId; + let lines; + let totalLines; + let anchorHash; + + if (source && source[0]) { + anchorHash = document.location.hash.substring(1); + lines = source[0].getElementsByTagName('li'); + totalLines = lines.length; + + for (; i < totalLines; i++) { + lineNumber++; + lineId = `line${lineNumber}`; + lines[i].id = lineId; + if (lineId === anchorHash) { + lines[i].className += ' selected'; + } + } + } +})(); diff --git a/docs/scripts/prettify/Apache-License-2.0.txt b/docs/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/docs/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/docs/scripts/prettify/lang-css.js b/docs/scripts/prettify/lang-css.js new file mode 100644 index 00000000..041e1f59 --- /dev/null +++ b/docs/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/docs/scripts/prettify/prettify.js b/docs/scripts/prettify/prettify.js new file mode 100644 index 00000000..eef5ad7e --- /dev/null +++ b/docs/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p th:last-child { border-right: 1px solid #ddd; } + +.ancestors, .attribs { color: #999; } +.ancestors a, .attribs a +{ + color: #999 !important; + text-decoration: none; +} + +.clear +{ + clear: both; +} + +.important +{ + font-weight: bold; + color: #950B02; +} + +.yes-def { + text-indent: -1000px; +} + +.type-signature { + color: #aaa; +} + +.name, .signature { + font-family: Consolas, Monaco, 'Andale Mono', monospace; +} + +.details { margin-top: 14px; border-left: 2px solid #DDD; } +.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } +.details dd { margin-left: 70px; } +.details ul { margin: 0; } +.details ul { list-style-type: none; } +.details li { margin-left: 30px; padding-top: 6px; } +.details pre.prettyprint { margin: 0 } +.details .object-value { padding-top: 0; } + +.description { + margin-bottom: 1em; + margin-top: 1em; +} + +.code-caption +{ + font-style: italic; + font-size: 107%; + margin: 0; +} + +.source +{ + border: 1px solid #ddd; + width: 80%; + overflow: auto; +} + +.prettyprint.source { + width: inherit; +} + +.source code +{ + font-size: 100%; + line-height: 18px; + display: block; + padding: 4px 12px; + margin: 0; + background-color: #fff; + color: #4D4E53; +} + +.prettyprint code span.line +{ + display: inline-block; +} + +.prettyprint.linenums +{ + padding-left: 70px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.prettyprint.linenums ol +{ + padding-left: 0; +} + +.prettyprint.linenums li +{ + border-left: 3px #ddd solid; +} + +.prettyprint.linenums li.selected, +.prettyprint.linenums li.selected * +{ + background-color: lightyellow; +} + +.prettyprint.linenums li * +{ + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.params .name, .props .name, .name code { + color: #4D4E53; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 100%; +} + +.params td.description > p:first-child, +.props td.description > p:first-child +{ + margin-top: 0; + padding-top: 0; +} + +.params td.description > p:last-child, +.props td.description > p:last-child +{ + margin-bottom: 0; + padding-bottom: 0; +} + +.disabled { + color: #454545; +} diff --git a/docs/styles/prettify-jsdoc.css b/docs/styles/prettify-jsdoc.css new file mode 100644 index 00000000..5a2526e3 --- /dev/null +++ b/docs/styles/prettify-jsdoc.css @@ -0,0 +1,111 @@ +/* JSDoc prettify.js theme */ + +/* plain text */ +.pln { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* string content */ +.str { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a keyword */ +.kwd { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a comment */ +.com { + font-weight: normal; + font-style: italic; +} + +/* a type name */ +.typ { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a literal value */ +.lit { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* punctuation */ +.pun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp open bracket */ +.opn { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp close bracket */ +.clo { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a markup tag name */ +.tag { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute name */ +.atn { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute value */ +.atv { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a declaration */ +.dec { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a variable name */ +.var { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a function name */ +.fun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} diff --git a/docs/styles/prettify-tomorrow.css b/docs/styles/prettify-tomorrow.css new file mode 100644 index 00000000..b6f92a78 --- /dev/null +++ b/docs/styles/prettify-tomorrow.css @@ -0,0 +1,132 @@ +/* Tomorrow Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* Pretty printing styles. Used with prettify.js. */ +/* SPAN elements with the classes below are added by prettyprint. */ +/* plain text */ +.pln { + color: #4d4d4c; } + +@media screen { + /* string content */ + .str { + color: #718c00; } + + /* a keyword */ + .kwd { + color: #8959a8; } + + /* a comment */ + .com { + color: #8e908c; } + + /* a type name */ + .typ { + color: #4271ae; } + + /* a literal value */ + .lit { + color: #f5871f; } + + /* punctuation */ + .pun { + color: #4d4d4c; } + + /* lisp open bracket */ + .opn { + color: #4d4d4c; } + + /* lisp close bracket */ + .clo { + color: #4d4d4c; } + + /* a markup tag name */ + .tag { + color: #c82829; } + + /* a markup attribute name */ + .atn { + color: #f5871f; } + + /* a markup attribute value */ + .atv { + color: #3e999f; } + + /* a declaration */ + .dec { + color: #f5871f; } + + /* a variable name */ + .var { + color: #c82829; } + + /* a function name */ + .fun { + color: #4271ae; } } +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { + color: #060; } + + .kwd { + color: #006; + font-weight: bold; } + + .com { + color: #600; + font-style: italic; } + + .typ { + color: #404; + font-weight: bold; } + + .lit { + color: #044; } + + .pun, .opn, .clo { + color: #440; } + + .tag { + color: #006; + font-weight: bold; } + + .atn { + color: #404; } + + .atv { + color: #060; } } +/* Style */ +/* +pre.prettyprint { + background: white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 12px; + line-height: 1.5; + border: 1px solid #ccc; + padding: 10px; } +*/ + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; } + +/* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L4, +li.L5, +li.L6, +li.L7, +li.L8, +li.L9 { + /* */ } + +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { + /* */ } diff --git a/docs/versionUpdate.js.html b/docs/versionUpdate.js.html new file mode 100644 index 00000000..f0754736 --- /dev/null +++ b/docs/versionUpdate.js.html @@ -0,0 +1,313 @@ + + + + + JSDoc: Source: versionUpdate.js + + + + + + + + + + +
    + +

    Source: versionUpdate.js

    + + + + + + +
    +
    +
    const scene_update = {
    +  "rayDensity_light": "rayModeDensity",
    +  "rayDensity_images": "imageModeDensity",
    +  "grid": "snapToGrid",
    +  "lockobjs": "lockObjs",
    +  "colorMode": "simulateColors",
    +  "symbolicGrin": "symbolicBodyMerging"
    +}
    +
    +const mode_update = {
    +  "light": "rays",
    +  "extended_light": "extended"
    +}
    +
    +const obj_update = {
    +  "laser": {
    +    "type": "SingleRay",
    +    "p": "brightness"
    +  },
    +  "parallel": {
    +    "type": "Beam",
    +    "p": "brightness",
    +    "divergence": "emisAngle"
    +  },
    +  "radiant": {
    +    "type": "PointSource",
    +    "p": "brightness"
    +  },
    +  "led": {
    +    "type": "AngleSource",
    +    "p": "emisAngle"
    +  },
    +  "mirror": {
    +    "type": "Mirror",
    +    "isDichroic": "filter",
    +    "isDichroicFilter": "invert"
    +  },
    +  "arcmirror": {
    +    "type": "ArcMirror",
    +    "isDichroic": "filter",
    +    "isDichroicFilter": "invert"
    +  },
    +  "parabolicmirror": {
    +    "type": "ParabolicMirror",
    +    "isDichroic": "filter",
    +    "isDichroicFilter": "invert"
    +  },
    +  "curvedmirror": {
    +    "type": "CustomMirror",
    +    "p": "eqn",
    +    "isDichroic": "filter",
    +    "isDichroicFilter": "invert"
    +  },
    +  "idealmirror": {
    +    "type": "IdealMirror",
    +    "p": "focalLength",
    +    "isDichroic": "filter",
    +    "isDichroicFilter": "invert"
    +  },
    +  "beamsplitter": {
    +    "type": "BeamSplitter",
    +    "p": "transRatio",
    +    "isDichroic": "filter",
    +    "isDichroicFilter": "invert"
    +  },
    +  "halfplane": {
    +    "type": "PlaneGlass",
    +    "p": "refIndex",
    +    "cauchyCoeff": "cauchyB"
    +  },
    +  "circlelens": {
    +    "type": "CircleGlass",
    +    "p": "refIndex",
    +    "cauchyCoeff": "cauchyB"
    +  },
    +  "refractor": {
    +    "type": "Glass",
    +    "p": "refIndex",
    +    "cauchyCoeff": "cauchyB"
    +  },
    +  "curvedglass": {
    +    "type": "CustomGlass",
    +    "p": "refIndex",
    +    "cauchyCoeff": "cauchyB"
    +  },
    +  "lens": {
    +    "type": "IdealLens",
    +    "p": "focalLength"
    +  },
    +  "sphericallens": {
    +    "type": "SphericalLens",
    +    "p": "refIndex",
    +    "cauchyCoeff": "cauchyB",
    +    "definedBy": "defBy"
    +  },
    +  "grin_circlelens": {
    +    "type": "CircleGrinGlass",
    +    "p_tex": "refIndexFn",
    +    "step_size": "stepSize",
    +    "eps": "intersectTol"
    +  },
    +  "grin_refractor": {
    +    "type": "GrinGlass",
    +    "p_tex": "refIndexFn",
    +    "step_size": "stepSize",
    +    "eps": "intersectTol"
    +  },
    +  "blackline": {
    +    "type": "Blocker",
    +    "isDichroic": "filter",
    +    "isDichroicFilter": "invert"
    +  },
    +  "blackcircle": {
    +    "type": "CircleBlocker",
    +    "isDichroic": "filter",
    +    "isDichroicFilter": "invert"
    +  },
    +  "aperture": {
    +    "type": "Aperture",
    +    "isDichroic": "filter",
    +    "isDichroicFilter": "invert"
    +  },
    +  "diffractiongrating": {
    +    "type": "DiffractionGrating",
    +    "line_density": "lineDensity",
    +    "slit_ratio": "slitRatio"
    +  },
    +  "ruler": {
    +    "type": "Ruler",
    +    "p": "scaleInterval"
    +  },
    +  "protractor": {
    +    "type": "Protractor"
    +  },
    +  "power": {
    +    "type": "Detector",
    +    "irradianceMap": "irradMap"
    +  },
    +  "text": {
    +    "type": "TextLabel",
    +    "p": "text",
    +    "fontName": "font",
    +    "fontAlignment": "alignment",
    +    "fontSmallCaps": "smallCaps",
    +    "fontAngle": "angle"
    +  },
    +  "line": {
    +    "type": "LineArrow",
    +    "arrow1": "arrow",
    +    "arrow2": "backArrow"
    +  },
    +  "drawing": {
    +    "type": "Drawing",
    +    "points": "strokes"
    +  },
    +  "handle": {
    +    "type": "Handle"
    +  },
    +  "cropbox": {
    +    "type": "CropBox"
    +  }
    +}
    +
    +/**
    + * Update the scene JSON data to the latest version.
    + * @param {Object} jsonData 
    + * @returns {Object} The updated JSON data.
    + */
    +export function versionUpdate(jsonData) {
    +  if (!jsonData.version) {
    +    // Chrome App version 1.0 and earlier (2011/11/1--2014/6/29)
    +
    +    let str1 = JSON.stringify(jsonData).replace(/"point"|"xxa"|"aH"/g, '1').replace(/"circle"|"xxf"/g, '5').replace(/"k"/g, '"objs"').replace(/"L"/g, '"p1"').replace(/"G"/g, '"p2"').replace(/"F"/g, '"p3"').replace(/"bA"/g, '"exist"').replace(/"aa"/g, '"parallel"').replace(/"ba"/g, '"mirror"').replace(/"bv"/g, '"lens"').replace(/"av"/g, '"notDone"').replace(/"bP"/g, '"lightAlpha"').replace(/"ab"|"observed_light"|"observed_images"/g, '"observer"');
    +    jsonData = JSON.parse(str1);
    +    if (!jsonData.objs) {
    +      jsonData = { objs: jsonData };
    +    }
    +    if (!jsonData.mode) {
    +      jsonData.mode = 'light';
    +    }
    +    if (!jsonData.rayDensity_light) {
    +      jsonData.rayDensity_light = 1;
    +    }
    +    if (!jsonData.rayDensity_images) {
    +      jsonData.rayDensity_images = 1;
    +    }
    +    if (!jsonData.scale) {
    +      jsonData.scale = 1;
    +    }
    +    jsonData.version = 1;
    +  }
    +
    +  if (jsonData.version == 1) {
    +    // Chrome App versions 1.1 to 1.2 (2014/6/30--2015/3/2)
    +    jsonData.origin = { x: 0, y: 0 };
    +    jsonData.version = 2;
    +  }
    +
    +  if (jsonData.version == 2) {
    +    // Chrome App version 2.0 and web app versions 2.x to 4.x (2015/3/3--2024/5/20)
    +
    +    // Update scene properties
    +    for (let key in scene_update) {
    +      if (jsonData[key] !== undefined) {
    +        jsonData[scene_update[key]] = jsonData[key];
    +        delete jsonData[key];
    +      }
    +    }
    +
    +    // Update mode
    +    if (jsonData.mode in mode_update) {
    +      jsonData.mode = mode_update[jsonData.mode];
    +    }
    +
    +    // Update object types and their properties
    +    jsonData.objs = jsonData.objs.map(objData => {
    +      if (objData.type in obj_update) {
    +        for (let key in obj_update[objData.type]) {
    +          if (key !== "type" && objData[key] !== undefined) {
    +            objData[obj_update[objData.type][key]] = objData[key];
    +            delete objData[key];
    +          }
    +        }
    +        objData.type = obj_update[objData.type].type;
    +      }
    +      return objData;
    +    });
    +
    +    // Update deep properties
    +    function updateProperties(obj) {
    +      if (typeof obj === 'object' && obj !== null) {
    +        if (obj.exist !== undefined) {
    +          delete obj.exist;
    +        }
    +        if (typeof obj.type === 'number') {
    +          delete obj.type;
    +        }
    +        if (obj.byHandle !== undefined) {
    +          delete obj.byHandle;
    +        }
    +        if (obj.targetObj_index !== undefined) {
    +          obj.targetObjIndex = obj.targetObj_index;
    +          delete obj.targetObj_index;
    +        }
    +        if (obj.mousePart !== undefined) {
    +          obj.dragContext = obj.mousePart;
    +          delete obj.mousePart;
    +        }
    +
    +        for (let key in obj) {
    +          updateProperties(obj[key]);
    +        }
    +      }
    +    }
    +    updateProperties(jsonData);
    +
    +
    +    // Data version number 3 and 4 do not exist since app version 3.x and 4.x do not change the data format. The next app release will be called version 5.0 so the data version number is updated to 5 to match the app version. Starting from this version, the data version number will always match the app version major number.
    +    jsonData.version = 5;
    +  }
    +
    +  return jsonData;
    +}
    +
    +
    + + + + +
    + + + +
    + + + + + + + diff --git a/e00b330413304d60c26e164da7f9fe0c.js b/e00b330413304d60c26e164da7f9fe0c.js new file mode 100644 index 00000000..05d6eab0 --- /dev/null +++ b/e00b330413304d60c26e164da7f9fe0c.js @@ -0,0 +1 @@ +ace.define("ace/mode/assembly_arm32_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,s,t){"use strict";var l=e("../lib/oop"),a=e("./text_highlight_rules").TextHighlightRules,r=function(){this.$rules={start:[{token:"keyword.control.assembly",regex:"\\b(?:cpsid|cpsie|cps|setend|(?:srs|rfe)(?:ia|ib|da|db|fd|ed|fa|ea)|bkpt|nop|pld|cdp2|mrc2|mrrc2|mcr2|mcrr2|ldc2|stc2|(?:add|adc|sub|sbc|rsb|rsc|mul|mla|umull|umlal|smull|smlal|mvn|and|eor|orr|bic)(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?s?|(?:(?:q|qd)?(?:add|sub)|umaal|smul(?:b|t)(?:b|t)|smulw(?:b|t)|smla(?:b|t)(?:b|t)|smlaw(?:b|t)|smlal(?:b|t)(?:b|t)|smuadx?|smladx?|smlaldx?|smusdx?|smlsdx?|smlsldx?|smmulr?|smmlar?|smmlsr?|mia|miaph|mia(?:b|t)(?:b|t)|clz|(?:s|q|sh|u|uq|uh)(?:add16|sub16|add8|sub8|addsubx|subaddx)|usad8|usada8|mrs|msr|mra|mar|cpy|tst|teq|cmp|cmn|ssat|ssat16|usat|usat16|pkhbt|pkhtb|sxth|sxtb16|sxtb|uxth|uxtb16|uxtb|sxtah|sxtab16|sxtab|uxtah|uxtab16|uxtab|rev|rev16|revsh|sel|b|bl|bx|blx|bxj|swi|svc|ldrex|strex|cdp|mrc|mrrc|mcr|mcrr|ldc|stc)(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?|ldr(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?(?:t|b|bt|sb|h|sh|d)?|str(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?(?:t|b|bt|h|d)?|(?:ldm|stm)(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?(?:ia|ib|da|db|fd|ed|fa|ea)|swp(?:eq|ne|cs|hs|cc|lo|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al)?b?|mov(?:t|w)?)\\b",caseInsensitive:!0},{token:"variable.parameter.register.assembly",regex:"\\b(?:r0|r1|r2|r3|r4|r5|r6|r7|r8|r9|r10|r11|r12|r13|r14|r15|fp|ip|sp|lr|pc|cpsr|spsr|c|f|s|x|lsl|lsr|asr|ror|rrx)\\b",caseInsensitive:!0},{token:"constant.character.hexadecimal.assembly",regex:"#0x[A-F0-9]+",caseInsensitive:!0},{token:"constant.character.decimal.assembly",regex:"#[0-9]+"},{token:"string.assembly",regex:/'([^\\']|\\.)*'/},{token:"string.assembly",regex:/"([^\\"]|\\.)*"/},{token:"support.function.directive.assembly",regex:"(?:.section|.global|.text|.asciz|.asciiz|.ascii|.align|.byte|.end|.data|.equ|.extern|.include)"},{token:"entity.name.function.assembly",regex:"^\\s*%%[\\w.]+?:$"},{token:"entity.name.function.assembly",regex:"^\\s*%\\$[\\w.]+?:$"},{token:"entity.name.function.assembly",regex:"^[\\w.]+?:"},{token:"entity.name.function.assembly",regex:"^[\\w.]+?\\b"},{token:"comment.assembly",regex:"\\/\\*",next:"comment"},{token:"comment.assembly",regex:"(?:;|//|@).*$"}],comment:[{token:"comment.assembly",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}]},this.normalizeRules()};r.metaData={fileTypes:["s"],name:"Assembly ARM32",scopeName:"source.assembly"},l.inherits(r,a),s.AssemblyARM32HighlightRules=r})),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],(function(e,s,t){"use strict";var l=e("../../lib/oop"),a=e("./fold_mode").FoldMode,r=e("../../range").Range,i=s.FoldMode=function(){};l.inherits(i,a),function(){this.commentBlock=function(e,s){var t=/\S/,l=e.getLine(s),a=l.search(t);if(-1!=a&&"#"==l[a]){for(var i=l.length,o=e.getLength(),n=s,c=s;++sn){var d=e.getLine(c).length;return new r(n,i,c,d)}}},this.getFoldWidgetRange=function(e,s,t){var l=this.indentationBlock(e,t);return l||(l=this.commentBlock(e,t))||void 0},this.getFoldWidget=function(e,s,t){var l=e.getLine(t),a=l.search(/\S/),r=e.getLine(t+1),i=e.getLine(t-1),o=i.search(/\S/),n=r.search(/\S/);if(-1==a)return e.foldWidgets[t-1]=-1!=o&&o|<-|\u2192/},{token:"keyword.operator",regex:/[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]+/},{token:"operator.punctuation",regex:/[,;`]/},{regex:o+r+"+\\.?",token:function(e){return"."==e[e.length-1]?"entity.name.function":"constant.language"}},{regex:"^"+n+r+"+",token:function(e){return"constant.language"}},{token:e,regex:"[\\w\\xff-\\u218e\\u2455-\\uffff]+\\b"},{regex:"{-#?",token:"comment.start",onMatch:function(e,t,n){return this.next=2==e.length?"blockComment":"docComment",this.token}},{token:"variable.language",regex:/\[markdown\|/,next:"markdown"},{token:"paren.lparen",regex:/[\[({]/},{token:"paren.rparen",regex:/[\])}]/}],markdown:[{regex:/\|\]/,next:"start"},{defaultToken:"string"}],blockComment:[{regex:"{-",token:"comment.start",push:"blockComment"},{regex:"-}",token:"comment.end",next:"pop"},{defaultToken:"comment"}],docComment:[{regex:"{-",token:"comment.start",push:"docComment"},{regex:"-}",token:"comment.end",next:"pop"},{defaultToken:"doc.comment"}],string:[{token:"constant.language.escape",regex:t},{token:"text",regex:/\\(\s|$)/,next:"stringGap"},{token:"string.end",regex:'"',next:"start"},{defaultToken:"string"}],stringGap:[{token:"text",regex:/\\/,next:"string"},{token:"error",regex:"",next:"start"}]},this.normalizeRules()};o.inherits(i,r),t.ElmHighlightRules=i})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../../range").Range,i=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};o.inherits(a,i),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var o=e.getLine(n);if(this.singleLineBlockCommentRe.test(o)&&!this.startRegionRe.test(o)&&!this.tripleStarBlockCommentRe.test(o))return"";var r=this._getFoldWidgetBase(e,t,n);return!r&&this.startRegionRe.test(o)?"start":r},this.getFoldWidgetRange=function(e,t,n,o){var r,i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);if(r=i.match(this.foldingStartMarker)){var a=r.index;if(r[1])return this.openingBracketBlock(e,r[1],n,a);var s=e.getCommentFoldRange(n,a+r[0].length,1);return s&&!s.isMultiLine()&&(o?s=this.getSectionRange(e,n):"all"!=t&&(s=null)),s}return"markbegin"!==t&&(r=i.match(this.foldingStopMarker))?(a=r.index+r[0].length,r[1]?this.closingBracketBlock(e,r[1],n,a):e.getCommentFoldRange(n,a,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),o=n.search(/\S/),i=t,a=n.length,s=t+=1,g=e.getLength();++tl)break;var c=this.getFoldWidgetRange(e,"all",t);if(c){if(c.start.row<=i)break;if(c.isMultiLine())t=c.end.row;else if(o==l)break}s=t}}return new r(i,a,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),i=e.getLength(),a=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,g=1;++na)return new r(a,o,n,t.length)}}.call(a.prototype)})),ace.define("ace/mode/elm",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/elm_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,i=e("./elm_highlight_rules").ElmHighlightRules,a=e("./folding/cstyle").FoldMode,s=function(){this.HighlightRules=i,this.foldingRules=new a,this.$behaviour=this.$defaultBehaviour};o.inherits(s,r),function(){this.lineCommentStart="--",this.blockComment={start:"{-",end:"-}",nestable:!0},this.$id="ace/mode/elm"}.call(s.prototype),t.Mode=s})),ace.require(["ace/mode/elm"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e2b38a8393be2cf23f3894ace3efb1c3.js b/e2b38a8393be2cf23f3894ace3efb1c3.js new file mode 100644 index 00000000..1fdf20b8 --- /dev/null +++ b/e2b38a8393be2cf23f3894ace3efb1c3.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/mask"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e2fe8f0d4fd950b20b30fabaea96b3f8.js b/e2fe8f0d4fd950b20b30fabaea96b3f8.js new file mode 100644 index 00000000..91d45f3a --- /dev/null +++ b/e2fe8f0d4fd950b20b30fabaea96b3f8.js @@ -0,0 +1 @@ +ace.define("ace/snippets/jsp.snippets",["require","exports","module"],(function(t,n,e){e.exports='snippet @page\n\t<%@page contentType="text/html" pageEncoding="UTF-8"%>\nsnippet jstl\n\t<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>\n\t<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>\nsnippet jstl:c\n\t<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>\nsnippet jstl:fn\n\t<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>\nsnippet cpath\n\t${pageContext.request.contextPath}\nsnippet cout\n\t\nsnippet cset\n\t\nsnippet cremove\n\t\nsnippet ccatch\n\t\nsnippet cif\n\t\n\t\t${2}\n\t\nsnippet cchoose\n\t\n\t\t${1}\n\t\nsnippet cwhen\n\t\n\t\t${2}\n\t\nsnippet cother\n\t\n\t\t${1}\n\t\nsnippet cfore\n\t\n\t\t${4:}\n\t\nsnippet cfort\n\t${2:item1,item2,item3}\n\t\n\t\t${5:}\n\t\nsnippet cparam\n\t\nsnippet cparam+\n\t\n\tcparam+${3}\nsnippet cimport\n\t\nsnippet cimport+\n\t\n\t\t\n\t\tcparam+${4}\n\t\nsnippet curl\n\t\n\t${3}\nsnippet curl+\n\t\n\t\t\n\t\tcparam+${6}\n\t\n\t${3}\nsnippet credirect\n\t\nsnippet contains\n\t${fn:contains(${1:string}, ${2:substr})}\nsnippet contains:i\n\t${fn:containsIgnoreCase(${1:string}, ${2:substr})}\nsnippet endswith\n\t${fn:endsWith(${1:string}, ${2:suffix})}\nsnippet escape\n\t${fn:escapeXml(${1:string})}\nsnippet indexof\n\t${fn:indexOf(${1:string}, ${2:substr})}\nsnippet join\n\t${fn:join(${1:collection}, ${2:delims})}\nsnippet length\n\t${fn:length(${1:collection_or_string})}\nsnippet replace\n\t${fn:replace(${1:string}, ${2:substr}, ${3:replace})}\nsnippet split\n\t${fn:split(${1:string}, ${2:delims})}\nsnippet startswith\n\t${fn:startsWith(${1:string}, ${2:prefix})}\nsnippet substr\n\t${fn:substring(${1:string}, ${2:begin}, ${3:end})}\nsnippet substr:a\n\t${fn:substringAfter(${1:string}, ${2:substr})}\nsnippet substr:b\n\t${fn:substringBefore(${1:string}, ${2:substr})}\nsnippet lc\n\t${fn:toLowerCase(${1:string})}\nsnippet uc\n\t${fn:toUpperCase(${1:string})}\nsnippet trim\n\t${fn:trim(${1:string})}\n'})),ace.define("ace/snippets/jsp",["require","exports","module","ace/snippets/jsp.snippets"],(function(t,n,e){"use strict";n.snippetText=t("./jsp.snippets"),n.scope="jsp"})),ace.require(["ace/snippets/jsp"],(function(t){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=t)})); \ No newline at end of file diff --git a/e37ac12436bcd0536ec98ae8470a1228.js b/e37ac12436bcd0536ec98ae8470a1228.js new file mode 100644 index 00000000..1fdbc2fb --- /dev/null +++ b/e37ac12436bcd0536ec98ae8470a1228.js @@ -0,0 +1 @@ +ace.define("ace/mode/zeek_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,o){"use strict";var r=e("../lib/oop"),n=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:"comment.line",regex:"#.*$"},{token:"string.double",regex:/"/,next:"string-state"},{token:"string.regexp",regex:"(/)(?=.*/)",next:"pattern-state"},{token:["keyword.other","meta.preprocessor"],regex:/(@(?:load-plugin|load-sigs|load|unload))(.*$)/},{token:"keyword.other",regex:/@(?:DEBUG|DIR|FILENAME|deprecated|if|ifdef|ifndef|else|endif)/},{token:["keyword.other","meta.preprocessor","keyword.operator","meta.preprocessor"],regex:/(@prefixes)(\s*)(\+?=)(.*$)/},{token:"storage.modifier.attribute",regex:/\&\b(?:redef|priority|log|optional|default|add_func|delete_func|expire_func|read_expire|write_expire|create_expire|synchronized|persistent|rotate_interval|rotate_size|encrypt|raw_output|mergeable|error_handler|type_column|deprecated)\b/},{token:"constant.language",regex:/\b(?:T|F)\b/},{token:"constant.numeric.port",regex:/\b\d{1,5}\/(?:udp|tcp|icmp|unknown)\b/},{token:"constant.numeric.addr",regex:/\b(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\b/,comment:"IPv4 address"},{token:"constant.numeric.addr",regex:/\[(?:[0-9a-fA-F]{0,4}:){2,7}(?:[0-9a-fA-F]{0,4})?(?:(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2})\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{1,2}))?\]/,comment:"IPv6 address"},{token:"constant.numeric.float.decimal.interval",regex:/(?:(?:\d*\.\d*(?:[eE][+-]?\d+)?|\d*[eE][+-]?\d+|\d*\.\d*)|\d+)\s*(?:day|hr|min|msec|usec|sec)s?/},{token:"constant.numeric.float.decimal",regex:/\d*\.\d*(?:[eE][+-]?\d+)?|\d*[eE][+-]?\d+|\d*\.\d*/},{token:"constant.numeric.hostname",regex:/\b[A-Za-z0-9][A-Za-z0-9\-]*(?:\.[A-Za-z0-9][A-Za-z0-9\-]*)+\b/},{token:"constant.numeric.integer.hexadecimal",regex:/\b0x[0-9a-fA-F]+\b/},{token:"constant.numeric.integer.decimal",regex:/\b\d+\b/},{token:"keyword.operator",regex:/==|!=|<=|<|>=|>/},{token:"keyword.operator",regex:/(&&)|(\|\|)|(!)/},{token:"keyword.operator",regex:/=|\+=|-=/},{token:"keyword.operator",regex:/\+\+|\+|--|-|\*|\/|%/},{token:"keyword.operator",regex:/&|\||\^|~/},{token:"keyword.operator",regex:/\b(?:in|as|is)\b/},{token:"punctuation.terminator",regex:/;/},{token:"punctuation.accessor",regex:/\??\$/},{token:"punctuation.accessor",regex:/::/},{token:"keyword.operator",regex:/\?/},{token:"punctuation.separator",regex:/:/},{token:"punctuation.separator",regex:/,/},{token:["keyword.other","meta.namespace","entity.name.namespace"],regex:/(module)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)/},{token:"keyword.other",regex:/\bexport\b/},{token:"keyword.control.conditional",regex:/\b(?:if|else)\b/},{token:"keyword.control",regex:/\b(?:for|while)\b/},{token:"keyword.control",regex:/\b(?:return|break|next|continue|fallthrough)\b/},{token:"keyword.control",regex:/\b(?:switch|default|case)\b/},{token:"keyword.other",regex:/\b(?:add|delete)\b/},{token:"keyword.other",regex:/\bprint\b/},{token:"keyword.control",regex:/\b(?:when|timeout|schedule)\b/},{token:["keyword.other","meta.struct.record","entity.name.struct.record","meta.struct.record","punctuation.separator","meta.struct.record","storage.type.struct.record"],regex:/\b(type)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(\s*)(:)(\s*\b)(record)\b/},{token:["keyword.other","meta.enum","entity.name.enum","meta.enum","punctuation.separator","meta.enum","storage.type.enum"],regex:/\b(type)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(\s*)(:)(\s*\b)(enum)\b/},{token:["keyword.other","meta.type","entity.name.type","meta.type","punctuation.separator"],regex:/\b(type)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(\s*)(:)/},{token:["keyword.other","meta.struct.record","storage.type.struct.record","meta.struct.record","entity.name.struct.record"],regex:/\b(redef)(\s+)(record)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)\b/},{token:["keyword.other","meta.enum","storage.type.enum","meta.enum","entity.name.enum"],regex:/\b(redef)(\s+)(enum)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)\b/},{token:["storage.type","text","entity.name.function.event"],regex:/\b(event)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(?=s*\()/},{token:["storage.type","text","entity.name.function.hook"],regex:/\b(hook)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(?=s*\()/},{token:["storage.type","text","entity.name.function"],regex:/\b(function)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)(?=s*\()/},{token:"keyword.other",regex:/\bredef\b/},{token:"storage.type",regex:/\bany\b/},{token:"storage.type",regex:/\b(?:enum|record|set|table|vector)\b/},{token:["storage.type","text","keyword.operator","text","storage.type"],regex:/\b(opaque)(\s+)(of)(\s+)([A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*)\b/},{token:"keyword.operator",regex:/\bof\b/},{token:"storage.type",regex:/\b(?:addr|bool|count|double|file|int|interval|pattern|port|string|subnet|time)\b/},{token:"storage.type",regex:/\b(?:function|hook|event)\b/},{token:"storage.modifier",regex:/\b(?:global|local|const|option)\b/},{token:"entity.name.function.call",regex:/\b[A-Za-z_][A-Za-z_0-9]*(?:::[A-Za-z_][A-Za-z_0-9]*)*(?=s*\()/},{token:"punctuation.section.block.begin",regex:/\{/},{token:"punctuation.section.block.end",regex:/\}/},{token:"punctuation.section.brackets.begin",regex:/\[/},{token:"punctuation.section.brackets.end",regex:/\]/},{token:"punctuation.section.parens.begin",regex:/\(/},{token:"punctuation.section.parens.end",regex:/\)/}],"string-state":[{token:"constant.character.escape",regex:/\\./},{token:"string.double",regex:/"/,next:"start"},{token:"constant.other.placeholder",regex:/%-?[0-9]*(\.[0-9]+)?[DTdxsefg]/},{token:"string.double",regex:"."}],"pattern-state":[{token:"constant.character.escape",regex:/\\./},{token:"string.regexp",regex:"/",next:"start"},{token:"string.regexp",regex:"."}]},this.normalizeRules()};a.metaData={fileTypes:["bro","zeek"],name:"Zeek",scopeName:"source.zeek"},r.inherits(a,n),t.ZeekHighlightRules=a})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,o){"use strict";var r=e("../../lib/oop"),n=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(i,a),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,o){var r=e.getLine(o);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var n=this._getFoldWidgetBase(e,t,o);return!n&&this.startRegionRe.test(r)?"start":n},this.getFoldWidgetRange=function(e,t,o,r){var n,a=e.getLine(o);if(this.startRegionRe.test(a))return this.getCommentRegionBlock(e,a,o);if(n=a.match(this.foldingStartMarker)){var i=n.index;if(n[1])return this.openingBracketBlock(e,n[1],o,i);var s=e.getCommentFoldRange(o,i+n[0].length,1);return s&&!s.isMultiLine()&&(r?s=this.getSectionRange(e,o):"all"!=t&&(s=null)),s}return"markbegin"!==t&&(n=a.match(this.foldingStopMarker))?(i=n.index+n[0].length,n[1]?this.closingBracketBlock(e,n[1],o,i):e.getCommentFoldRange(o,i,-1)):void 0},this.getSectionRange=function(e,t){for(var o=e.getLine(t),r=o.search(/\S/),a=t,i=o.length,s=t+=1,g=e.getLength();++tc)break;var d=this.getFoldWidgetRange(e,"all",t);if(d){if(d.start.row<=a)break;if(d.isMultiLine())t=d.end.row;else if(r==c)break}s=t}}return new n(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,o){for(var r=t.search(/\s*$/),a=e.getLength(),i=o,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,g=1;++oi)return new n(i,r,o,t.length)}}.call(i.prototype)})),ace.define("ace/mode/zeek",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/zeek_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,o){"use strict";var r=e("../lib/oop"),n=e("./text").Mode,a=e("./zeek_highlight_rules").ZeekHighlightRules,i=e("./folding/cstyle").FoldMode,s=function(){this.HighlightRules=a,this.foldingRules=new i};r.inherits(s,n),function(){this.lineCommentStart="#",this.$id="ace/mode/zeek"}.call(s.prototype),t.Mode=s})),ace.require(["ace/mode/zeek"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e4917fa7632b01d28e99304d32d989f7.js b/e4917fa7632b01d28e99304d32d989f7.js new file mode 100644 index 00000000..304c733f --- /dev/null +++ b/e4917fa7632b01d28e99304d32d989f7.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/protobuf"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e5dec17f3116be7e2b2307e43cd14e86.js b/e5dec17f3116be7e2b2307e43cd14e86.js new file mode 100644 index 00000000..253e3249 --- /dev/null +++ b/e5dec17f3116be7e2b2307e43cd14e86.js @@ -0,0 +1 @@ +ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};o.inherits(a,r),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),o="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[r.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[r.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:o},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(r,"doc-",[r.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var o="/"==e.charAt(1)?2:1;return 1==o?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==o&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==o?"":"end-")+"tag-open.xml",value:e.slice(0,o)},{type:"meta.tag.tag-name.xml",value:e.substr(o)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[r.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[r.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}o.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var o=e("../range").Range,r=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var r=n[1].length,a=e.findMatchingBracket({row:t,column:r});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new o(t,0,t,r-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(r.prototype),t.MatchingBraceOutdent=r})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,o,r){if('"'==r||"'"==r){var s=r,l=o.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),u=o.doc.getLine(c.row).substring(c.column,c.column+1),d=new a(o,c.row,c.column),g=d.getCurrentToken();if(u==s&&(i(g,"attribute-value")||i(g,"string")))return{text:"",selection:[1,1]};if(g||(g=d.stepBackward()),!g)return;for(;i(g,"tag-whitespace")||i(g,"whitespace");)g=d.stepBackward();var m=!u||u.match(/\s/);if(i(g,"attribute-equals")&&(m||">"==u)||i(g,"decl-attribute-equals")&&(m||"?"==u))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,o,r){var a=o.doc.getTextRange(r);if(!r.isMultiLine()&&('"'==a||"'"==a)&&o.doc.getLine(r.start.row).substring(r.start.column+1,r.start.column+2)==a)return r.end.column++,r})),this.add("autoclosing","insertion",(function(e,t,n,o,r){if(">"==r){var s=n.getSelectionRange().start,l=new a(o,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var u=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(o.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var g=l.getCurrentTokenRow(),m=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var p=c.value;if(g==s.row&&(p=p.substring(0,s.column-m)),this.voidElements&&this.voidElements.hasOwnProperty(p.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,o,r){if("\n"==r){var s=n.getCursorPosition(),l=o.getLine(s.row),c=new a(o,s.row,s.column),u=c.getCurrentToken();if(i(u,"")&&-1!==u.type.indexOf("tag-close")){if("/>"==u.value)return;for(;u&&-1===u.type.indexOf("tag-name");)u=c.stepBackward();if(!u)return;var d=u.value,g=c.getCurrentTokenRow();if(!(u=c.stepBackward())||-1!==u.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[d]||!this.voidElements){var m=o.getTokenAt(s.row,s.column+1),p=(l=o.getLine(g),this.$getIndent(l)),h=p+o.getTabString();return m&&""==a){var i=n.getSelectionRange().start,s=new r(o,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};o.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=o.mixin({},this.voidElements),t&&o.mixin(this.optionalEndTags,t)};o.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var o=this._getFirstTagInLine(e,n);return o?o.closing||!o.tagName&&o.selfClosing?"markbeginend"===t?"end":"":!o.tagName||o.selfClosing||this.voidElements.hasOwnProperty(o.tagName.toLowerCase())||this._findEndTagInLine(e,n,o.tagName,o.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return o}if(l(a,"tag-close"))return o.selfClosing="/>"==a.value,o;o.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,o){for(var r=e.getTokens(t),a=0,i=0;ic)break;var u=this.getFoldWidgetRange(e,"all",t);if(u){if(u.start.row<=a)break;if(u.isMultiLine())t=u.end.row;else if(o==c)break}s=t}}return new r(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new r(i,o,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new r};o.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,o){return this.getFoldWidgetRangeBase(e,t,n,o)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,u=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};o.inherits(u,r),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e),a=r.tokens,i=r.state;if(a.length&&"comment"==a[a.length-1].type)return o;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(o+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(u.prototype),t.Mode=u})),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=(e("../lib/lang"),e("./text_highlight_rules").TextHighlightRules),a=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",i=t.supportFunction="rgb|rgba|url|attr|counter|counters",s=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|flex-end|flex-start|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",l=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",c=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",u=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",d=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",g=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",m=function(){var e=this.createKeywordMapper({"support.function":i,"support.constant":s,"support.type":a,"support.constant.color":l,"support.constant.fonts":c},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:u},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+u+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:u},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:d},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:g},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{token:"paren.lparen",regex:"\\{"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};o.inherits(m,r),t.CssHighlightRules=m})),ace.define("ace/mode/css_completions",["require","exports","module"],(function(e,t,n){"use strict";var o={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,double:2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{default:1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},float:{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,static:1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},r=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e)if("string"==typeof e[t]){var n=t.replace(/[A-Z]/g,(function(e){return"-"+e.toLowerCase()}));o.hasOwnProperty(n)||(o[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,o){if(this.completionsDefined||this.defineCompletions(),"ruleset"===e||"ace/mode/scss"==t.$mode.$id){var r=t.getLine(n.row).substr(0,n.column),a=/\([^)]*$/.test(r);return a&&(r=r.substr(r.lastIndexOf("(")+1)),/:[^;]+$/.test(r)?(/([\w\-]+):[^:]*$/.test(r),this.getPropertyValueCompletions(e,t,n,o)):this.getPropertyCompletions(e,t,n,o,a)}return[]},this.getPropertyCompletions=function(e,t,n,r,a){return a=a||!1,Object.keys(o).map((function(e){return{caption:e,snippet:e+": $0"+(a?"":";"),meta:"property",score:1e6}}))},this.getPropertyValueCompletions=function(e,t,n,r){var a=t.getLine(n.row).substr(0,n.column),i=(/([\w\-]+):[^:]*$/.exec(a)||{})[1];if(!i)return[];var s=[];return i in o&&"object"==typeof o[i]&&(s=Object.keys(o[i])),s.map((function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}}))}}).call(r.prototype),t.CssCompletions=r})),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=(e("../behaviour").Behaviour,e("./cstyle").CstyleBehaviour),a=e("../../token_iterator").TokenIterator,i=function(){this.inherit(r),this.add("colon","insertion",(function(e,t,n,o,r){if(":"===r&&n.selection.isEmpty()){var i=n.getCursorPosition(),s=new a(o,i.row,i.column),l=s.getCurrentToken();if(l&&l.value.match(/\s+/)&&(l=s.stepBackward()),l&&"support.type"===l.type){var c=o.doc.getLine(i.row);if(":"===c.substring(i.column,i.column+1))return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(c.substring(i.column)))return{text:":;",selection:[1,1]}}}})),this.add("colon","deletion",(function(e,t,n,o,r){var i=o.doc.getTextRange(r);if(!r.isMultiLine()&&":"===i){var s=n.getCursorPosition(),l=new a(o,s.row,s.column),c=l.getCurrentToken();if(c&&c.value.match(/\s+/)&&(c=l.stepBackward()),c&&"support.type"===c.type&&";"===o.doc.getLine(r.start.row).substring(r.end.column,r.end.column+1))return r.end.column++,r}})),this.add("semicolon","insertion",(function(e,t,n,o,r){if(";"===r&&n.selection.isEmpty()){var a=n.getCursorPosition();if(";"===o.doc.getLine(a.row).substring(a.column,a.column+1))return{text:"",selection:[1,1]}}})),this.add("!important","insertion",(function(e,t,n,o,r){if("!"===r&&n.selection.isEmpty()){var a=n.getCursorPosition(),i=o.doc.getLine(a.row);if(/^\s*(;|}|$)/.test(i.substring(a.column)))return{text:"!important",selection:[10,10]}}}))};o.inherits(i,r),t.CssBehaviour=i})),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./css_highlight_rules").CssHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./css_completions").CssCompletions,c=e("./behaviour/css").CssBehaviour,u=e("./folding/cstyle").FoldMode,d=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new c,this.$completer=new l,this.foldingRules=new u};o.inherits(d,r),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e).tokens;return r.length&&"comment"==r[r.length-1].type||t.match(/^.*\{\s*$/)&&(o+=n),o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/css",this.snippetFileId="ace/snippets/css"}.call(d.prototype),t.Mode=d})),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(e){var t="[_:a-zA-ZÀ-￿][-_:.a-zA-Z0-9À-￿]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"--\x3e",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===a&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(r.prototype),o.inherits(a,r),t.XmlHighlightRules=a})),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./css_highlight_rules").CssHighlightRules,i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./xml_highlight_rules").XmlHighlightRules,l=r.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),c=function(){s.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=l[t];return["meta.tag.punctuation."+("<"==e?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(a,"css-","style"),this.embedTagRules(new i({jsx:!1}).getRules(),"js-","script"),this.constructor===c&&this.normalizeRules()};o.inherits(c,s),t.HtmlHighlightRules=c})),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};o.inherits(a,r),function(){this.$getMode=function(e){for(var t in"string"!=typeof e&&(e=e[0]),this.subModes)if(0===e.indexOf(t))return this.subModes[t];return null},this.$tryMode=function(e,t,n,o){var r=this.$getMode(e);return r?r.getFoldWidget(t,n,o):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var o=this.$getMode(e.getState(n-1));return o&&o.getFoldWidget(e,t,n)||(o=this.$getMode(e.getState(n))),o&&o.getFoldWidget(e,t,n)||(o=this.defaultMode),o.getFoldWidgetRange(e,t,n)}}.call(a.prototype)})),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./mixed").FoldMode,a=e("./xml").FoldMode,i=e("./cstyle").FoldMode,s=t.FoldMode=function(e,t){r.call(this,new a(e,t),{"js-":new i,"css-":new i})};o.inherits(s,r)})),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../token_iterator").TokenIterator,r=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"].concat(["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"]),a={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,for:1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{for:1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,default:1},section:{},summary:{},u:{},ul:{},var:{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},i=Object.keys(a);function s(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"tag-name");)r=n.stepBackward();if(r)return r.value}var c=function(){};(function(){this.getCompletions=function(e,t,n,o){var r=t.getTokenAt(n.row,n.column);if(!r)return[];if(s(r,"tag-name")||s(r,"tag-open")||s(r,"end-tag-open"))return this.getTagCompletions(e,t,n,o);if(s(r,"tag-whitespace")||s(r,"attribute-name"))return this.getAttributeCompletions(e,t,n,o);if(s(r,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,o);var a=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(a)?this.getHTMLEntityCompletions(e,t,n,o):[]},this.getTagCompletions=function(e,t,n,o){return i.map((function(e){return{value:e,meta:"tag",score:1e6}}))},this.getAttributeCompletions=function(e,t,n,o){var i=l(t,n);if(!i)return[];var s=r;return i in a&&(s=s.concat(Object.keys(a[i]))),s.map((function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}}))},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),c=function(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"attribute-name");)r=n.stepBackward();if(r)return r.value}(t,n);if(!i)return[];var u=[];return i in a&&c in a[i]&&"object"==typeof a[i][c]&&(u=Object.keys(a[i][c])),u.map((function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}}))},this.getHTMLEntityCompletions=function(e,t,n,o){return["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"].map((function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}}))}}).call(c.prototype),t.HtmlCompletions=c})),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./text").Mode,i=e("./javascript").Mode,s=e("./css").Mode,l=e("./html_highlight_rules").HtmlHighlightRules,c=e("./behaviour/xml").XmlBehaviour,u=e("./folding/html").FoldMode,d=e("./html_completions").HtmlCompletions,g=e("../worker/worker_client").WorkerClient,m=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],p=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],h=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=l,this.$behaviour=new c,this.$completer=new d,this.createModeDelegates({"js-":i,"css-":s}),this.foldingRules=new u(this.voidElements,r.arrayToMap(p))};o.inherits(h,a),function(){this.blockComment={start:"\x3c!--",end:"--\x3e"},this.voidElements=r.arrayToMap(m),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){if(this.constructor==h){var t=new g(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t}},this.$id="ace/mode/html",this.snippetFileId="ace/snippets/html"}.call(h.prototype),t.Mode=h})),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}]}};o.inherits(a,r),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=a})),ace.define("ace/mode/csharp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./doc_comment_highlight_rules").DocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i=function(){var e=this.createKeywordMapper({"variable.language":"this",keyword:"abstract|async|await|event|new|struct|as|explicit|null|switch|base|extern|object|this|bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|delegate|internal|partial|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|string|var|dynamic","constant.language":"null|true|false"},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},r.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:/'(?:.|\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n]))?'/},{token:"string",start:'"',end:'"|$',next:[{token:"constant.language.escape",regex:/\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/},{token:"invalid",regex:/\\./}]},{token:"string",start:'@"',end:'"',next:[{token:"constant.language.escape",regex:'""'}]},{token:"string",start:/\$"/,end:'"|$',next:[{token:"constant.language.escape",regex:/\\(:?$)|{{/},{token:"constant.language.escape",regex:/\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/},{token:"invalid",regex:/\\./}]},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"keyword",regex:"^\\s*#(if|else|elif|endif|define|undef|warning|error|line|region|endregion|pragma)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}]},this.embedRules(r,"doc-",[r.getEndRule("start")]),this.normalizeRules()};o.inherits(i,a),t.CSharpHighlightRules=i})),ace.define("ace/mode/razor_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/doc_comment_highlight_rules","ace/mode/html_highlight_rules","ace/mode/csharp_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=(e("./doc_comment_highlight_rules").DocCommentHighlightRules,e("./html_highlight_rules").HtmlHighlightRules),i=e("./csharp_highlight_rules").CSharpHighlightRules,s=function(){i.call(this);var e="in-braces";this.$rules.start.unshift({regex:"[\\[({]",onMatch:function(t,n,o){var r=/razor-[^\-]+-/.exec(n)[0];return o.unshift(t),o.unshift(r+e),this.next=r+e,"paren.lparen"}},{start:"@\\*",end:"\\*@",token:"comment"});var t={"{":"}","[":"]","(":")"};this.$rules[e]=r.deepCopy(this.$rules.start),this.$rules[e].unshift({regex:"[\\])}]",onMatch:function(e,n,o){var r=o[1];return t[r]!==e?"invalid.illegal":(o.shift(),o.shift(),this.next=function(e,t){return"function"==typeof t?t(e):t}(e,o[0])||"start","paren.rparen")}})};o.inherits(s,i);var l=function(){a.call(this);var e={"@{":"}","@(":")","@functions{":"}"},t={regex:"[})]",onMatch:function(t,n,o){var r=o[1];return e[r]!==t?"invalid.illegal":(o.shift(),o.shift(),this.next=o.shift()||"start","punctuation.block.razor")}},n=[{start:"@\\*",end:"\\*@",token:"comment"},{token:["meta.directive.razor","text","identifier"],regex:"^(\\s*@model)(\\s+)(.+)$"},{regex:"@[({]|@functions{",onMatch:function(e,t,n){return n.unshift(e),n.unshift("razor-block-start"),this.next="razor-block-start","punctuation.block.razor"}},{regex:"@(?![{(])",onMatch:function(e,t,n){return n.unshift("razor-short-start"),this.next="razor-short-start","punctuation.short.razor"}}];for(var o in this.$rules)this.$rules[o].unshift.apply(this.$rules[o],n);this.embedRules(s,"razor-block-",[t],["start"]),this.embedRules(s,"razor-short-",[{token:"",regex:"(?=[^A-Za-z_\\.()\\[\\]])",next:"pop"}],["start"]),this.normalizeRules()};o.inherits(l,a),t.RazorHighlightRules=l,t.RazorLangHighlightRules=s})),ace.define("ace/mode/razor_completions",["require","exports","module","ace/token_iterator"],(function(e,t,n){"use strict";e("../token_iterator").TokenIterator;var o=["abstract","as","base","bool","break","byte","case","catch","char","checked","class","const","continue","decimal","default","delegate","do","double","else","enum","event","explicit","extern","false","finally","fixed","float","for","foreach","goto","if","implicit","in","int","interface","internal","is","lock","long","namespace","new","null","object","operator","out","override","params","private","protected","public","readonly","ref","return","sbyte","sealed","short","sizeof","stackalloc","static","string","struct","switch","this","throw","true","try","typeof","uint","ulong","unchecked","unsafe","ushort","using","var","virtual","void","volatile","while"],r=["Html","Model","Url","Layout"],a=function(){};(function(){this.getCompletions=function(e,t,n,o){return-1==e.lastIndexOf("razor-short-start")&&-1==e.lastIndexOf("razor-block-start")?[]:t.getTokenAt(n.row,n.column)?-1!=e.lastIndexOf("razor-short-start")?this.getShortStartCompletions(e,t,n,o):-1!=e.lastIndexOf("razor-block-start")?this.getKeywordCompletions(e,t,n,o):void 0:[]},this.getShortStartCompletions=function(e,t,n,o){return r.map((function(e){return{value:e,meta:"keyword",score:1e6}}))},this.getKeywordCompletions=function(e,t,n,a){return r.concat(o).map((function(e){return{value:e,meta:"keyword",score:1e6}}))}}).call(a.prototype),t.RazorCompletions=a})),ace.define("ace/mode/razor",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/razor_highlight_rules","ace/mode/razor_completions","ace/mode/html_completions"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./html").Mode,a=e("./razor_highlight_rules").RazorHighlightRules,i=e("./razor_completions").RazorCompletions,s=e("./html_completions").HtmlCompletions,l=function(){r.call(this),this.$highlightRules=new a,this.$completer=new i,this.$htmlCompleter=new s};o.inherits(l,r),function(){this.getCompletions=function(e,t,n,o){var r=this.$completer.getCompletions(e,t,n,o),a=this.$htmlCompleter.getCompletions(e,t,n,o);return r.concat(a)},this.createWorker=function(e){return null},this.$id="ace/mode/razor",this.snippetFileId="ace/snippets/razor"}.call(l.prototype),t.Mode=l})),ace.require(["ace/mode/razor"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e61779df91186b23e7adf2d1968b2708.js b/e61779df91186b23e7adf2d1968b2708.js new file mode 100644 index 00000000..ac70ffd2 --- /dev/null +++ b/e61779df91186b23e7adf2d1968b2708.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/handlebars"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e63fce237243190962fcc3b12b387e1b.js b/e63fce237243190962fcc3b12b387e1b.js new file mode 100644 index 00000000..7511c60d --- /dev/null +++ b/e63fce237243190962fcc3b12b387e1b.js @@ -0,0 +1 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,i=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},i.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}]}};r.inherits(i,o),i.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},i.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},i.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=i})),ace.define("ace/mode/c_cpp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./doc_comment_highlight_rules").DocCommentHighlightRules,i=e("./text_highlight_rules").TextHighlightRules,s=t.cFunctions="hypot|hypotf|hypotl|sscanf|system|snprintf|scanf|scalbn|scalbnf|scalbnl|scalbln|scalblnf|scalblnl|sin|sinh|sinhf|sinhl|sinf|sinl|signal|signbit|strstr|strspn|strncpy|strncat|strncmp|strcspn|strchr|strcoll|strcpy|strcat|strcmp|strtoimax|strtod|strtoul|strtoull|strtoumax|strtok|strtof|strtol|strtold|strtoll|strerror|strpbrk|strftime|strlen|strrchr|strxfrm|sprintf|setjmp|setvbuf|setlocale|setbuf|sqrt|sqrtf|sqrtl|swscanf|swprintf|srand|nearbyint|nearbyintf|nearbyintl|nexttoward|nexttowardf|nexttowardl|nextafter|nextafterf|nextafterl|nan|nanf|nanl|csin|csinh|csinhf|csinhl|csinf|csinl|csqrt|csqrtf|csqrtl|ccos|ccosh|ccoshf|ccosf|ccosl|cimag|cimagf|cimagl|ctime|ctan|ctanh|ctanhf|ctanhl|ctanf|ctanl|cos|cosh|coshf|coshl|cosf|cosl|conj|conjf|conjl|copysign|copysignf|copysignl|cpow|cpowf|cpowl|cproj|cprojf|cprojl|ceil|ceilf|ceill|cexp|cexpf|cexpl|clock|clog|clogf|clogl|clearerr|casin|casinh|casinhf|casinhl|casinf|casinl|cacos|cacosh|cacoshf|cacoshl|cacosf|cacosl|catan|catanh|catanhf|catanhl|catanf|catanl|calloc|carg|cargf|cargl|cabs|cabsf|cabsl|creal|crealf|creall|cbrt|cbrtf|cbrtl|time|toupper|tolower|tan|tanh|tanhf|tanhl|tanf|tanl|trunc|truncf|truncl|tgamma|tgammaf|tgammal|tmpnam|tmpfile|isspace|isnormal|isnan|iscntrl|isinf|isdigit|isunordered|isupper|ispunct|isprint|isfinite|iswspace|iswcntrl|iswctype|iswdigit|iswupper|iswpunct|iswprint|iswlower|iswalnum|iswalpha|iswgraph|iswxdigit|iswblank|islower|isless|islessequal|islessgreater|isalnum|isalpha|isgreater|isgreaterequal|isgraph|isxdigit|isblank|ilogb|ilogbf|ilogbl|imaxdiv|imaxabs|div|difftime|_Exit|ungetc|ungetwc|pow|powf|powl|puts|putc|putchar|putwc|putwchar|perror|printf|erf|erfc|erfcf|erfcl|erff|erfl|exit|exp|exp2|exp2f|exp2l|expf|expl|expm1|expm1f|expm1l|vsscanf|vsnprintf|vscanf|vsprintf|vswscanf|vswprintf|vprintf|vfscanf|vfprintf|vfwscanf|vfwprintf|vwscanf|vwprintf|va_start|va_copy|va_end|va_arg|qsort|fscanf|fsetpos|fseek|fclose|ftell|fopen|fdim|fdimf|fdiml|fpclassify|fputs|fputc|fputws|fputwc|fprintf|feholdexcept|fesetenv|fesetexceptflag|fesetround|feclearexcept|fetestexcept|feof|feupdateenv|feraiseexcept|ferror|fegetenv|fegetexceptflag|fegetround|fflush|fwscanf|fwide|fwprintf|fwrite|floor|floorf|floorl|fabs|fabsf|fabsl|fgets|fgetc|fgetpos|fgetws|fgetwc|freopen|free|fread|frexp|frexpf|frexpl|fmin|fminf|fminl|fmod|fmodf|fmodl|fma|fmaf|fmal|fmax|fmaxf|fmaxl|ldiv|ldexp|ldexpf|ldexpl|longjmp|localtime|localeconv|log|log1p|log1pf|log1pl|log10|log10f|log10l|log2|log2f|log2l|logf|logl|logb|logbf|logbl|labs|lldiv|llabs|llrint|llrintf|llrintl|llround|llroundf|llroundl|lrint|lrintf|lrintl|lround|lroundf|lroundl|lgamma|lgammaf|lgammal|wscanf|wcsstr|wcsspn|wcsncpy|wcsncat|wcsncmp|wcscspn|wcschr|wcscoll|wcscpy|wcscat|wcscmp|wcstoimax|wcstod|wcstoul|wcstoull|wcstoumax|wcstok|wcstof|wcstol|wcstold|wcstoll|wcstombs|wcspbrk|wcsftime|wcslen|wcsrchr|wcsrtombs|wcsxfrm|wctob|wctomb|wcrtomb|wprintf|wmemset|wmemchr|wmemcpy|wmemcmp|wmemmove|assert|asctime|asin|asinh|asinhf|asinhl|asinf|asinl|acos|acosh|acoshf|acoshl|acosf|acosl|atoi|atof|atol|atoll|atexit|atan|atanh|atanhf|atanhl|atan2|atan2f|atan2l|atanf|atanl|abs|abort|gets|getc|getchar|getenv|getwc|getwchar|gmtime|rint|rintf|rintl|round|roundf|roundl|rename|realloc|rewind|remove|remquo|remquof|remquol|remainder|remainderf|remainderl|rand|raise|bsearch|btowc|modf|modff|modfl|memset|memchr|memcpy|memcmp|memmove|mktime|malloc|mbsinit|mbstowcs|mbsrtowcs|mbtowc|mblen|mbrtowc|mbrlen",a=function(e){var t=this.$keywords=this.createKeywordMapper(Object.assign({"keyword.control":"break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while|catch|operator|try|throw|using","storage.type":"asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|int8_t|int16_t|int32_t|int64_t|long|short|signed|size_t|struct|typedef|uint8_t|uint16_t|uint32_t|uint64_t|union|unsigned|void|class|wchar_t|template|char16_t|char32_t","storage.modifier":"const|extern|register|restrict|static|volatile|inline|private|protected|public|friend|explicit|virtual|export|mutable|typename|constexpr|new|delete|alignas|alignof|decltype|noexcept|thread_local","keyword.operator":"and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|const_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace","variable.language":"this","constant.language":"NULL|true|false|TRUE|FALSE|nullptr","support.function.C99.c":s},e),"identifier"),n=/\\(?:['"?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F\d]{2}|u[a-fA-F\d]{4}U[a-fA-F\d]{8}|.)/.source,r="%"+/(\d+\$)?/.source+/[#0\- +']*/.source+/[,;:_]?/.source+/((-?\d+)|\*(-?\d+\$)?)?/.source+/(\.((-?\d+)|\*(-?\d+\$)?)?)?/.source+/(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)?/.source+/(\[[^"\]]+\]|[diouxXDOUeEfFgGaACcSspn%])/.source;this.$rules={start:[{token:"comment",regex:"//$",next:"start"},{token:"comment",regex:"//",next:"singleLineComment"},o.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:"'(?:"+n+"|.)?'"},{token:"string.start",regex:'"',stateName:"qqstring",next:[{token:"string",regex:/\\\s*$/,next:"qqstring"},{token:"constant.language.escape",regex:n},{token:"constant.language.escape",regex:r},{token:"string.end",regex:'"|$',next:"start"},{defaultToken:"string"}]},{token:"string.start",regex:'R"\\(',stateName:"rawString",next:[{token:"string.end",regex:'\\)"',next:"start"},{defaultToken:"string"}]},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"keyword",regex:"#\\s*(?:include|import|pragma|line|define|undef)\\b",next:"directive"},{token:"keyword",regex:"#\\s*(?:endif|if|ifdef|else|elif|ifndef)\\b"},{token:t,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*"},{token:"keyword.operator",regex:/--|\+\+|<<=|>>=|>>>=|<>|&&|\|\||\?:|[*%\/+\-&\^|~!<>=]=?/},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],singleLineComment:[{token:"comment",regex:/\\$/,next:"singleLineComment"},{token:"comment",regex:/$/,next:"start"},{defaultToken:"comment"}],directive:[{token:"constant.other.multiline",regex:/\\/},{token:"constant.other.multiline",regex:/.*\\/},{token:"constant.other",regex:"\\s*<.+?>",next:"start"},{token:"constant.other",regex:'\\s*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]',next:"start"},{token:"constant.other",regex:"\\s*['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']",next:"start"},{token:"constant.other",regex:/[^\\\/]+/,next:"start"}]},this.embedRules(o,"doc-",[o.getEndRule("start")]),this.normalizeRules()};r.inherits(a,i),t.c_cppHighlightRules=a})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var r=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,i=e.findMatchingBracket({row:t,column:o});if(!i||i.row==t)return 0;var s=this.$getIndent(e.getLine(i.row));e.replace(new r(t,0,t,o-1),s)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../../range").Range,i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(s,i),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var o=this._getFoldWidgetBase(e,t,n);return!o&&this.startRegionRe.test(r)?"start":o},this.getFoldWidgetRange=function(e,t,n,r){var o,i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);if(o=i.match(this.foldingStartMarker)){var s=o.index;if(o[1])return this.openingBracketBlock(e,o[1],n,s);var a=e.getCommentFoldRange(n,s+o[0].length,1);return a&&!a.isMultiLine()&&(r?a=this.getSectionRange(e,n):"all"!=t&&(a=null)),a}return"markbegin"!==t&&(o=i.match(this.foldingStopMarker))?(s=o.index+o[0].length,o[1]?this.closingBracketBlock(e,o[1],n,s):e.getCommentFoldRange(n,s,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),r=n.search(/\S/),i=t,s=n.length,a=t+=1,c=e.getLength();++tl)break;var g=this.getFoldWidgetRange(e,"all",t);if(g){if(g.start.row<=i)break;if(g.isMultiLine())t=g.end.row;else if(r==l)break}a=t}}return new o(i,s,a,e.getLine(a).length)},this.getCommentRegionBlock=function(e,t,n){for(var r=t.search(/\s*$/),i=e.getLength(),s=n,a=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,c=1;++ns)return new o(s,r,n,t.length)}}.call(s.prototype)})),ace.define("ace/mode/c_cpp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/c_cpp_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,i=e("./c_cpp_highlight_rules").c_cppHighlightRules,s=e("./matching_brace_outdent").MatchingBraceOutdent,a=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=i,this.$outdent=new s,this.$behaviour=this.$defaultBehaviour,this.foldingRules=new a};r.inherits(c,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e),i=o.tokens,s=o.state;if(i.length&&"comment"==i[i.length-1].type)return r;if("start"==e)(a=t.match(/^.*[\{\(\[]\s*$/))&&(r+=n);else if("doc-start"==e){if("start"==s)return"";var a;(a=t.match(/^\s*(\/?)\*/))&&(a[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/c_cpp",this.snippetFileId="ace/snippets/c_cpp"}.call(c.prototype),t.Mode=c})),ace.define("ace/mode/nix_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,i=function(){var e=this.createKeywordMapper({"constant.language.nix":"true|false","keyword.control.nix":"with|import|if|else|then|inherit","keyword.declaration.nix":"let|in|rec"},"identifier");this.$rules={start:[{token:"comment",regex:/#.*$/},{token:"comment",regex:/\/\*/,next:"comment"},{token:"constant",regex:"<[^>]+>"},{regex:"(==|!=|<=?|>=?)",token:["keyword.operator.comparison.nix"]},{regex:"((?:[+*/%-]|\\~)=)",token:["keyword.operator.assignment.arithmetic.nix"]},{regex:"=",token:"keyword.operator.assignment.nix"},{token:"string",regex:"''",next:"qqdoc"},{token:"string",regex:"'",next:"qstring"},{token:"string",regex:'"',push:"qqstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{regex:"}",token:function(e,t,n){return n[1]&&"q"==n[1].charAt(0)?"constant.language.escape":"text"},next:"pop"}],comment:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],qqdoc:[{token:"constant.language.escape",regex:/\$\{/,push:"start"},{token:"string",regex:"''",next:"pop"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:/\$\{/,push:"start"},{token:"string",regex:'"',next:"pop"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:/\$\{/,push:"start"},{token:"string",regex:"'",next:"pop"},{defaultToken:"string"}]},this.normalizeRules()};r.inherits(i,o),t.NixHighlightRules=i})),ace.define("ace/mode/nix",["require","exports","module","ace/lib/oop","ace/mode/c_cpp","ace/mode/nix_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./c_cpp").Mode,i=e("./nix_highlight_rules").NixHighlightRules,s=e("./folding/cstyle").FoldMode,a=function(){o.call(this),this.HighlightRules=i,this.foldingRules=new s,this.$behaviour=this.$defaultBehaviour};r.inherits(a,o),function(){this.lineCommentStart="#",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/nix"}.call(a.prototype),t.Mode=a})),ace.require(["ace/mode/nix"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e6ad50b520736b595970c9e07029c3f1.js b/e6ad50b520736b595970c9e07029c3f1.js new file mode 100644 index 00000000..b0542221 --- /dev/null +++ b/e6ad50b520736b595970c9e07029c3f1.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/typescript"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e7e1a807af3160b342e0a3550cf8f7c5.js b/e7e1a807af3160b342e0a3550cf8f7c5.js new file mode 100644 index 00000000..fb26182e --- /dev/null +++ b/e7e1a807af3160b342e0a3550cf8f7c5.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/autohotkey"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e7f37e0f2b6113039c45a326264c4d36.js b/e7f37e0f2b6113039c45a326264c4d36.js new file mode 100644 index 00000000..e57db6ae --- /dev/null +++ b/e7f37e0f2b6113039c45a326264c4d36.js @@ -0,0 +1 @@ +ace.define("ace/mode/eiffel_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,r){"use strict";var n=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,i=function(){var e=this.createKeywordMapper({"constant.language":"Void","constant.language.boolean":"True|False","variable.language":"Current|Result","keyword.operator":"and|implies|or|xor",keyword:"across|agent|alias|all|attached|as|assign|attribute|check|class|convert|create|debug|deferred|detachable|do|else|elseif|end|ensure|expanded|export|external|feature|from|frozen|if|inherit|inspect|invariant|like|local|loop|not|note|obsolete|old|once|Precursor|redefine|rename|require|rescue|retry|select|separate|some|then|undefine|until|variant|when"},"identifier",!0),t=/(?:[^"%\b\f\v]|%[A-DFHLNQR-V%'"()<>]|%\/(?:0[xX][\da-fA-F](?:_*[\da-fA-F])*|0[cC][0-7](?:_*[0-7])*|0[bB][01](?:_*[01])*|\d(?:_*\d)*)\/)+?/;this.$rules={start:[{token:"string.quoted.other",regex:/"\[/,next:"aligned_verbatim_string"},{token:"string.quoted.other",regex:/"\{/,next:"non-aligned_verbatim_string"},{token:"string.quoted.double",regex:/"(?:[^%\b\f\n\r\v]|%[A-DFHLNQR-V%'"()<>]|%\/(?:0[xX][\da-fA-F](?:_*[\da-fA-F])*|0[cC][0-7](?:_*[0-7])*|0[bB][01](?:_*[01])*|\d(?:_*\d)*)\/)*?"/},{token:"comment.line.double-dash",regex:/--.*/},{token:"constant.character",regex:/'(?:[^%\b\f\n\r\t\v]|%[A-DFHLNQR-V%'"()<>]|%\/(?:0[xX][\da-fA-F](?:_*[\da-fA-F])*|0[cC][0-7](?:_*[0-7])*|0[bB][01](?:_*[01])*|\d(?:_*\d)*)\/)'/},{token:"constant.numeric",regex:/\b0(?:[xX][\da-fA-F](?:_*[\da-fA-F])*|[cC][0-7](?:_*[0-7])*|[bB][01](?:_*[01])*)\b/},{token:"constant.numeric",regex:/(?:\d(?:_*\d)*)?\.(?:(?:\d(?:_*\d)*)?[eE][+-]?)?\d(?:_*\d)*|\d(?:_*\d)*\.?/},{token:"paren.lparen",regex:/[\[({]|<<|\|\(/},{token:"paren.rparen",regex:/[\])}]|>>|\|\)/},{token:"keyword.operator",regex:/:=|->|\.(?=\w)|[;,:?]/},{token:"keyword.operator",regex:/\\\\|\|\.\.\||\.\.|\/[~\/]?|[><\/]=?|[-+*^=~]/},{token:function(t){var r=e(t);return"identifier"===r&&t===t.toUpperCase()&&(r="entity.name.type"),r},regex:/[a-zA-Z][a-zA-Z\d_]*\b/},{token:"text",regex:/\s+/}],aligned_verbatim_string:[{token:"string",regex:/]"/,next:"start"},{token:"string",regex:t}],"non-aligned_verbatim_string":[{token:"string.quoted.other",regex:/}"/,next:"start"},{token:"string.quoted.other",regex:t}]}};n.inherits(i,o),t.EiffelHighlightRules=i})),ace.define("ace/mode/eiffel",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/eiffel_highlight_rules"],(function(e,t,r){"use strict";var n=e("../lib/oop"),o=e("./text").Mode,i=e("./eiffel_highlight_rules").EiffelHighlightRules,a=function(){this.HighlightRules=i,this.$behaviour=this.$defaultBehaviour};n.inherits(a,o),function(){this.lineCommentStart="--",this.$id="ace/mode/eiffel"}.call(a.prototype),t.Mode=a})),ace.require(["ace/mode/eiffel"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e874d975c9128dc6eb9a513d088bed9f.js b/e874d975c9128dc6eb9a513d088bed9f.js new file mode 100644 index 00000000..39c835a6 --- /dev/null +++ b/e874d975c9128dc6eb9a513d088bed9f.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/assembly_x86"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e9382a0e67b22188c75e9418de1c9295.js b/e9382a0e67b22188c75e9418de1c9295.js new file mode 100644 index 00000000..17623800 --- /dev/null +++ b/e9382a0e67b22188c75e9418de1c9295.js @@ -0,0 +1 @@ +ace.define("ace/mode/ion_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var i=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,r=function(){var e={token:this.createKeywordMapper({"constant.language.bool.ion":"TRUE|FALSE","constant.language.null.ion":"NULL.NULL|NULL.BOOL|NULL.INT|NULL.FLOAT|NULL.DECIMAL|NULL.TIMESTAMP|NULL.STRING|NULL.SYMBOL|NULL.BLOB|NULL.CLOB|NULL.STRUCT|NULL.LIST|NULL.SEXP|NULL"},"constant.other.symbol.identifier.ion",!0),regex:"\\b\\w+(?:\\.\\w+)?\\b"};this.$rules={start:[{include:"value"}],value:[{include:"whitespace"},{include:"comment"},{include:"annotation"},{include:"string"},{include:"number"},{include:"keywords"},{include:"symbol"},{include:"clob"},{include:"blob"},{include:"struct"},{include:"list"},{include:"sexp"}],sexp:[{token:"punctuation.definition.sexp.begin.ion",regex:"\\(",push:[{token:"punctuation.definition.sexp.end.ion",regex:"\\)",next:"pop"},{include:"comment"},{include:"value"},{token:"storage.type.symbol.operator.ion",regex:"[\\!\\#\\%\\&\\*\\+\\-\\./\\;\\<\\=\\>\\?\\@\\^\\`\\|\\~]+"}]}],comment:[{token:"comment.line.ion",regex:"//[^\\n]*"},{token:"comment.block.ion",regex:"/\\*",push:[{token:"comment.block.ion",regex:"[*]/",next:"pop"},{token:"comment.block.ion",regex:"[^*/]+"},{token:"comment.block.ion",regex:"[*/]+"}]}],list:[{token:"punctuation.definition.list.begin.ion",regex:"\\[",push:[{token:"punctuation.definition.list.end.ion",regex:"\\]",next:"pop"},{include:"comment"},{include:"value"},{token:"punctuation.definition.list.separator.ion",regex:","}]}],struct:[{token:"punctuation.definition.struct.begin.ion",regex:"\\{",push:[{token:"punctuation.definition.struct.end.ion",regex:"\\}",next:"pop"},{include:"comment"},{include:"value"},{token:"punctuation.definition.struct.separator.ion",regex:",|:"}]}],blob:[{token:["punctuation.definition.blob.begin.ion","string.other.blob.ion","punctuation.definition.blob.end.ion"],regex:'(\\{\\{)([^"]*)(\\}\\})'}],clob:[{token:["punctuation.definition.clob.begin.ion","string.other.clob.ion","punctuation.definition.clob.end.ion"],regex:'(\\{\\{)("[^"]*")(\\}\\})'}],symbol:[{token:"storage.type.symbol.quoted.ion",regex:"(['])((?:(?:\\\\')|(?:[^']))*?)(['])"},{token:"storage.type.symbol.identifier.ion",regex:"[\\$_a-zA-Z][\\$_a-zA-Z0-9]*"}],number:[{token:"constant.numeric.timestamp.ion",regex:"\\d{4}(?:-\\d{2})?(?:-\\d{2})?T(?:\\d{2}:\\d{2})(?::\\d{2})?(?:\\.\\d+)?(?:Z|[-+]\\d{2}:\\d{2})?"},{token:"constant.numeric.timestamp.ion",regex:"\\d{4}-\\d{2}-\\d{2}T?"},{token:"constant.numeric.integer.binary.ion",regex:"-?0[bB][01](?:_?[01])*"},{token:"constant.numeric.integer.hex.ion",regex:"-?0[xX][0-9a-fA-F](?:_?[0-9a-fA-F])*"},{token:"constant.numeric.float.ion",regex:"-?(?:0|[1-9](?:_?\\d)*)(?:\\.(?:\\d(?:_?\\d)*)?)?(?:[eE][+-]?\\d+)"},{token:"constant.numeric.float.ion",regex:"(?:[-+]inf)|(?:nan)"},{token:"constant.numeric.decimal.ion",regex:"-?(?:0|[1-9](?:_?\\d)*)(?:(?:(?:\\.(?:\\d(?:_?\\d)*)?)(?:[dD][+-]?\\d+)|\\.(?:\\d(?:_?\\d)*)?)|(?:[dD][+-]?\\d+))"},{token:"constant.numeric.integer.ion",regex:"-?(?:0|[1-9](?:_?\\d)*)"}],string:[{token:["punctuation.definition.string.begin.ion","string.quoted.double.ion","punctuation.definition.string.end.ion"],regex:'(["])((?:(?:\\\\")|(?:[^"]))*?)(["])'},{token:"punctuation.definition.string.begin.ion",regex:"'{3}",push:[{token:"punctuation.definition.string.end.ion",regex:"'{3}",next:"pop"},{token:"string.quoted.triple.ion",regex:"(?:\\\\'|[^'])+"},{token:"string.quoted.triple.ion",regex:"'"}]}],annotation:[{token:["variable.language.annotation.ion","punctuation.definition.annotation.ion"],regex:/('(?:[^'\\]|\\.)*')\s*(::)/},{token:["variable.language.annotation.ion","punctuation.definition.annotation.ion"],regex:"([\\$_a-zA-Z][\\$_a-zA-Z0-9]*)\\s*(::)"}],whitespace:[{token:"text.ion",regex:"\\s+"}]},this.$rules.keywords=[e],this.normalizeRules()};i.inherits(r,o),t.IonHighlightRules=r})),ace.define("ace/mode/partiql_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/ion_highlight_rules"],(function(e,t,n){"use strict";var i=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,r=e("./ion_highlight_rules").IonHighlightRules,a=function(){var e={token:this.createKeywordMapper({"constant.language.partiql":"MISSING|FALSE|NULL|TRUE","keyword.other.partiql":"PIVOT|UNPIVOT|LIMIT|TUPLE|REMOVE|INDEX|CONFLICT|DO|NOTHING|RETURNING|MODIFIED|NEW|OLD|LET|ABSOLUTE|ACTION|ADD|ALL|ALLOCATE|ALTER|AND|ANY|ARE|AS|ASC|ASSERTION|AT|AUTHORIZATION|BEGIN|BETWEEN|BIT_LENGTH|BY|CASCADE|CASCADED|CASE|CATALOG|CHAR|CHARACTER_LENGTH|CHAR_LENGTH|CHECK|CLOSE|COLLATE|COLLATION|COLUMN|COMMIT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONTINUE|CONVERT|CORRESPONDING|CREATE|CROSS|CURRENT|CURSOR|DEALLOCATE|DEC|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DESC|DESCRIBE|DESCRIPTOR|DIAGNOSTICS|DISCONNECT|DISTINCT|DOMAIN|DROP|ELSE|END|END-EXEC|ESCAPE|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXTERNAL|EXTRACT|FETCH|FIRST|FOR|FOREIGN|FOUND|FROM|FULL|GET|GLOBAL|GO|GOTO|GRANT|GROUP|HAVING|IDENTITY|IMMEDIATE|IN|INDICATOR|INITIALLY|INNER|INPUT|INSENSITIVE|INSERT|INTERSECT|INTERVAL|INTO|IS|ISOLATION|JOIN|KEY|LANGUAGE|LAST|LEFT|LEVEL|LIKE|LOCAL|LOWER|MATCH|MODULE|NAMES|NATIONAL|NATURAL|NCHAR|NEXT|NO|NOT|OCTET_LENGTH|OF|ON|ONLY|OPEN|OPTION|OR|ORDER|OUTER|OUTPUT|OVERLAPS|PAD|PARTIAL|POSITION|PRECISION|PREPARE|PRESERVE|PRIMARY|PRIOR|PRIVILEGES|PROCEDURE|PUBLIC|READ|REAL|REFERENCES|RELATIVE|RESTRICT|REVOKE|RIGHT|ROLLBACK|ROWS|SCHEMA|SCROLL|SECTION|SELECT|SESSION|SET|SIZE|SOME|SPACE|SQL|SQLCODE|SQLERROR|SQLSTATE|TABLE|TEMPORARY|THEN|TIME|TO|TRANSACTION|TRANSLATE|TRANSLATION|UNION|UNIQUE|UNKNOWN|UPDATE|UPPER|USAGE|USER|USING|VALUE|VALUES|VIEW|WHEN|WHENEVER|WHERE|WITH|WORK|WRITE|ZONE","storage.type.partiql":"BOOL|BOOLEAN|STRING|SYMBOL|CLOB|BLOB|STRUCT|LIST|SEXP|BAG|CHARACTER|DATE|DECIMAL|DOUBLE|FLOAT|INT|INTEGER|NUMERIC|SMALLINT|TIMESTAMP|VARCHAR|VARYING","support.function.aggregation.partiql":"AVG|COUNT|MAX|MIN|SUM","support.function.partiql":"CAST|COALESCE|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|EXISTS|DATE_ADD|DATE_DIFF|NULLIF|SESSION_USER|SUBSTRING|SYSTEM_USER|TRIM"},"variable.language.identifier.partiql",!0),regex:"\\b\\w+\\b"};this.$rules={start:[{include:"whitespace"},{include:"comment"},{include:"value"}],value:[{include:"whitespace"},{include:"comment"},{include:"tuple_value"},{include:"collection_value"},{include:"scalar_value"}],scalar_value:[{include:"string"},{include:"number"},{include:"keywords"},{include:"identifier"},{include:"embed-ion"},{include:"operator"},{include:"punctuation"}],punctuation:[{token:"punctuation.partiql",regex:"[;:()\\[\\]\\{\\},.]"}],operator:[{token:"keyword.operator.partiql",regex:"[+*/<>=~!@#%&|?^-]+"}],identifier:[{token:"variable.language.identifier.quoted.partiql",regex:'(["])((?:(?:\\\\.)|(?:[^"\\\\]))*?)(["])'},{token:"variable.language.identifier.at.partiql",regex:"@\\w+"},{token:"variable.language.identifier.partiql",regex:"\\b\\w+(?:\\.\\w+)?\\b"}],number:[{token:"constant.numeric.partiql",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"}],string:[{token:["punctuation.definition.string.begin.partiql","string.quoted.single.partiql","punctuation.definition.string.end.partiql"],regex:"(['])((?:(?:\\\\.)|(?:[^'\\\\]))*?)(['])"}],collection_value:[{include:"array_value"},{include:"bag_value"}],bag_value:[{token:"punctuation.definition.bag.begin.partiql",regex:"<<",push:[{token:"punctuation.definition.bag.end.partiql",regex:">>",next:"pop"},{include:"comment"},{token:"punctuation.definition.bag.separator.partiql",regex:","},{include:"value"}]}],comment:[{token:"comment.line.partiql",regex:"--.*"},{token:"comment.block.partiql",regex:"/\\*",push:"comment__1"}],comment__1:[{token:"comment.block.partiql",regex:"[*]/",next:"pop"},{token:"comment.block.partiql",regex:"[^*/]+"},{token:"comment.block.partiql",regex:"/\\*",push:"comment__1"},{token:"comment.block.partiql",regex:"[*/]+"}],array_value:[{token:"punctuation.definition.array.begin.partiql",regex:"\\[",push:[{token:"punctuation.definition.array.end.partiql",regex:"\\]",next:"pop"},{include:"comment"},{token:"punctuation.definition.array.separator.partiql",regex:","},{include:"value"}]}],tuple_value:[{token:"punctuation.definition.tuple.begin.partiql",regex:"\\{",push:[{token:"punctuation.definition.tuple.end.partiql",regex:"\\}",next:"pop"},{include:"comment"},{token:"punctuation.definition.tuple.separator.partiql",regex:",|:"},{include:"value"}]}],whitespace:[{token:"text.partiql",regex:"\\s+"}]},this.$rules.keywords=[e],this.$rules["embed-ion"]=[{token:"punctuation.definition.ion.begin.partiql",regex:"`",next:"ion-start"}],this.embedRules(r,"ion-",[{token:"punctuation.definition.ion.end.partiql",regex:"`",next:"start"}]),this.normalizeRules()};i.inherits(a,o),t.PartiqlHighlightRules=a})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var i=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,r=e.findMatchingBracket({row:t,column:o});if(!r||r.row==t)return 0;var a=this.$getIndent(e.getLine(r.row));e.replace(new i(t,0,t,o-1),a)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var i=e("../../lib/oop"),o=e("../../range").Range,r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};i.inherits(a,r),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var i=e.getLine(n);if(this.singleLineBlockCommentRe.test(i)&&!this.startRegionRe.test(i)&&!this.tripleStarBlockCommentRe.test(i))return"";var o=this._getFoldWidgetBase(e,t,n);return!o&&this.startRegionRe.test(i)?"start":o},this.getFoldWidgetRange=function(e,t,n,i){var o,r=e.getLine(n);if(this.startRegionRe.test(r))return this.getCommentRegionBlock(e,r,n);if(o=r.match(this.foldingStartMarker)){var a=o.index;if(o[1])return this.openingBracketBlock(e,o[1],n,a);var l=e.getCommentFoldRange(n,a+o[0].length,1);return l&&!l.isMultiLine()&&(i?l=this.getSectionRange(e,n):"all"!=t&&(l=null)),l}return"markbegin"!==t&&(o=r.match(this.foldingStopMarker))?(a=o.index+o[0].length,o[1]?this.closingBracketBlock(e,o[1],n,a):e.getCommentFoldRange(n,a,-1)):void 0},this.getSectionRange=function(e,t){for(var n=e.getLine(t),i=n.search(/\S/),r=t,a=n.length,l=t+=1,u=e.getLength();++tc)break;var g=this.getFoldWidgetRange(e,"all",t);if(g){if(g.start.row<=r)break;if(g.isMultiLine())t=g.end.row;else if(i==c)break}l=t}}return new o(r,a,l,e.getLine(l).length)},this.getCommentRegionBlock=function(e,t,n){for(var i=t.search(/\s*$/),r=e.getLength(),a=n,l=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,u=1;++na)return new o(a,i,n,t.length)}}.call(a.prototype)})),ace.define("ace/mode/partiql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/partiql_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var i=e("../lib/oop"),o=e("./text").Mode,r=e("./partiql_highlight_rules").PartiqlHighlightRules,a=e("./matching_brace_outdent").MatchingBraceOutdent,l=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=r,this.$outdent=new a,this.$behaviour=this.$defaultBehaviour,this.foldingRules=new l};i.inherits(u,o),function(){this.lineCommentStart="--",this.blockComment={start:"/*",end:"*/",nestable:!0},this.getNextLineIndent=function(e,t,n){var i=this.$getIndent(t);return"start"==e&&t.match(/^.*[\{\(\[]\s*$/)&&(i+=n),i},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/partiql"}.call(u.prototype),t.Mode=u})),ace.require(["ace/mode/partiql"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/e9c8f7e13e00284ce126890bf7ac46fd.js b/e9c8f7e13e00284ce126890bf7ac46fd.js new file mode 100644 index 00000000..236de653 --- /dev/null +++ b/e9c8f7e13e00284ce126890bf7ac46fd.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/ion"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/eaa55a522fb2cb2f0287711f42344984.js b/eaa55a522fb2cb2f0287711f42344984.js new file mode 100644 index 00000000..4f76fe6b --- /dev/null +++ b/eaa55a522fb2cb2f0287711f42344984.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/asciidoc"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/eb0b62e1895dcf7491419aa728f00c38.js b/eb0b62e1895dcf7491419aa728f00c38.js new file mode 100644 index 00000000..83c37e7e --- /dev/null +++ b/eb0b62e1895dcf7491419aa728f00c38.js @@ -0,0 +1 @@ +ace.define("ace/theme/solarized_light-css",["require","exports","module"],(function(e,a,n){n.exports='.ace-solarized-light .ace_gutter {\n background: #fbf1d3;\n color: #333\n}\n\n.ace-solarized-light .ace_print-margin {\n width: 1px;\n background: #e8e8e8\n}\n\n.ace-solarized-light {\n background-color: #FDF6E3;\n color: #586E75\n}\n\n.ace-solarized-light .ace_cursor {\n color: #000000\n}\n\n.ace-solarized-light .ace_marker-layer .ace_selection {\n background: rgba(7, 54, 67, 0.09)\n}\n\n.ace-solarized-light.ace_multiselect .ace_selection.ace_start {\n box-shadow: 0 0 3px 0px #FDF6E3;\n}\n\n.ace-solarized-light .ace_marker-layer .ace_step {\n background: rgb(255, 255, 0)\n}\n\n.ace-solarized-light .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(147, 161, 161, 0.50)\n}\n\n.ace-solarized-light .ace_marker-layer .ace_active-line {\n background: #EEE8D5\n}\n\n.ace-solarized-light .ace_gutter-active-line {\n background-color : #EDE5C1\n}\n\n.ace-solarized-light .ace_marker-layer .ace_selected-word {\n border: 1px solid #7f9390\n}\n\n.ace-solarized-light .ace_invisible {\n color: rgba(147, 161, 161, 0.50)\n}\n\n.ace-solarized-light .ace_keyword,\n.ace-solarized-light .ace_meta,\n.ace-solarized-light .ace_support.ace_class,\n.ace-solarized-light .ace_support.ace_type {\n color: #859900\n}\n\n.ace-solarized-light .ace_constant.ace_character,\n.ace-solarized-light .ace_constant.ace_other {\n color: #CB4B16\n}\n\n.ace-solarized-light .ace_constant.ace_language {\n color: #B58900\n}\n\n.ace-solarized-light .ace_constant.ace_numeric {\n color: #D33682\n}\n\n.ace-solarized-light .ace_fold {\n background-color: #268BD2;\n border-color: #586E75\n}\n\n.ace-solarized-light .ace_entity.ace_name.ace_function,\n.ace-solarized-light .ace_entity.ace_name.ace_tag,\n.ace-solarized-light .ace_support.ace_function,\n.ace-solarized-light .ace_variable,\n.ace-solarized-light .ace_variable.ace_language {\n color: #268BD2\n}\n\n.ace-solarized-light .ace_storage {\n color: #073642\n}\n\n.ace-solarized-light .ace_string {\n color: #2AA198\n}\n\n.ace-solarized-light .ace_string.ace_regexp {\n color: #D30102\n}\n\n.ace-solarized-light .ace_comment,\n.ace-solarized-light .ace_entity.ace_other.ace_attribute-name {\n color: #93A1A1\n}\n\n.ace-solarized-light .ace_indent-guide {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHjy8NJ/AAjgA5fzQUmBAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-solarized-light .ace_indent-guide-active {\n background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAZSURBVHjaYvj///9/hivKyv8BAAAA//8DACLqBhbvk+/eAAAAAElFTkSuQmCC") right repeat-y;\n} \n'})),ace.define("ace/theme/solarized_light",["require","exports","module","ace/theme/solarized_light-css","ace/lib/dom"],(function(e,a,n){a.isDark=!1,a.cssClass="ace-solarized-light",a.cssText=e("./solarized_light-css"),e("../lib/dom").importCssString(a.cssText,a.cssClass,!1)})),ace.require(["ace/theme/solarized_light"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/ec7b3f184238605a5239da7559e6cff9.js b/ec7b3f184238605a5239da7559e6cff9.js new file mode 100644 index 00000000..27c46187 --- /dev/null +++ b/ec7b3f184238605a5239da7559e6cff9.js @@ -0,0 +1 @@ +ace.define("ace/mode/xquery/jsoniq_lexer",["require","exports","module"],(function(e,a,t){t.exports=function a(t,n,r){var s="function"==typeof e&&e;function o(i,c){if(!n[i]){if(!t[i]){var k="function"==typeof e&&e;if(!c&&k)return k(i,!0);if(s)return s(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[i]={exports:{}};t[i][0].call(l.exports,(function(e){return o(t[i][1][e]||e)}),l,l.exports,a,t,n,r)}return n[i].exports}for(var i=0;iu?u:i),n=o,r=i,s=0):x(o,i,0,s,a)}function d(){r!=o&&(n=r,r=o,c.whitespace(n,r))}function p(e){0==s&&(s=function(e){for(var a;30==(a=v(e)););return a}(e),o=l,i=b)}function h(e){0==s&&(s=v(e),o=l,i=b)}function x(e,a,t,n,r){throw new m.ParseException(e,a,t,n,r)}function v(a){var t=!1;l=b;for(var n=b,r=e.INITIAL[a],s=0,o=4095&r;0!=o;){var i,c=n>4))+e.MAP1[h>>5]]];else{c<56320&&(h=n=56320&&h<57344&&(++n,c=((1023&c)<<10)+(1023&h)+65536,t=!0);for(var m=0,g=5,f=3;;f=g+m>>1){if(e.MAP2[f]>c)g=f-1;else{if(!(e.MAP2[6+f]g){i=0;break}}}s=o;var d=(i<<12)+o-1;(o=e.TRANSITION[(15&d)+e.TRANSITION[d>>4]])>4095&&(r=o,o&=4095,b=n)}if(0==(r>>=12))return(h=(b=n-1)=56320&&h<57344&&--b,x(l,b,s,-1,-1);if(t)for(var p=r>>9;p>0;--p){var h;(h=--b=56320&&h<57344&&--b}else b-=r>>9;return(511&r)-1}this.ParseException=function(e,a,t,n,r){var s=e,o=a,i=t,c=n,k=r;this.getBegin=function(){return s},this.getEnd=function(){return o},this.getState=function(){return i},this.getExpected=function(){return k},this.getOffending=function(){return c},this.getMessage=function(){return c<0?"lexical analysis failed":"syntax error"}},this.getInput=function(){return k},this.getOffendingToken=function(a){var t=a.getOffending();return t>=0?e.TOKEN[t]:null},this.getExpectedTokenSet=function(a){return a.getExpected()<0?e.getTokenSet(-a.getState()):[e.TOKEN[a.getExpected()]]},this.getErrorMessage=function(e){var a=this.getExpectedTokenSet(e),t=this.getOffendingToken(e),n=k.substring(0,e.getBegin()).split("\n"),r=n.length,s=n[r-1].length+1,o=e.getEnd()-e.getBegin();return e.getMessage()+(null==t?"":", found "+t)+"\nwhile expecting "+(1==a.length?a[0]:"["+a.join(", ")+"]")+"\n"+(0==o||null!=t?"":"after successfully scanning "+o+" characters beginning ")+"at line "+r+", column "+s+":\n..."+k.substring(e.getBegin(),Math.min(k.length,e.getBegin()+64))+"..."},this.parse_start=function(){switch(c.startNonterminal("start",r),p(14),s){case 58:f(58);break;case 57:f(57);break;case 59:f(59);break;case 43:f(43);break;case 45:f(45);break;case 44:f(44);break;case 37:f(37);break;case 41:f(41);break;case 277:f(277);break;case 274:f(274);break;case 42:f(42);break;case 46:f(46);break;case 52:f(52);break;case 65:f(65);break;case 66:f(66);break;case 49:f(49);break;case 51:f(51);break;case 56:f(56);break;case 54:f(54);break;case 36:f(36);break;case 276:f(276);break;case 40:f(40);break;case 5:f(5);break;case 4:f(4);break;case 6:f(6);break;case 15:f(15);break;case 16:f(16);break;case 18:f(18);break;case 19:f(19);break;case 20:f(20);break;case 8:f(8);break;case 9:f(9);break;case 7:f(7);break;case 35:f(35);break;default:g()}c.endNonterminal("start",r)},this.parse_StartTag=function(){switch(c.startNonterminal("StartTag",r),p(8),s){case 61:f(61);break;case 53:f(53);break;case 29:f(29);break;case 60:f(60);break;case 37:f(37);break;case 41:f(41);break;default:f(35)}c.endNonterminal("StartTag",r)},this.parse_TagContent=function(){switch(c.startNonterminal("TagContent",r),h(11),s){case 25:f(25);break;case 9:f(9);break;case 10:f(10);break;case 58:f(58);break;case 57:f(57);break;case 21:f(21);break;case 31:f(31);break;case 275:f(275);break;case 278:f(278);break;case 274:f(274);break;default:f(35)}c.endNonterminal("TagContent",r)},this.parse_AposAttr=function(){switch(c.startNonterminal("AposAttr",r),h(10),s){case 23:f(23);break;case 27:f(27);break;case 21:f(21);break;case 31:f(31);break;case 275:f(275);break;case 278:f(278);break;case 274:f(274);break;case 41:f(41);break;default:f(35)}c.endNonterminal("AposAttr",r)},this.parse_QuotAttr=function(){switch(c.startNonterminal("QuotAttr",r),h(9),s){case 22:f(22);break;case 26:f(26);break;case 21:f(21);break;case 31:f(31);break;case 275:f(275);break;case 278:f(278);break;case 274:f(274);break;case 37:f(37);break;default:f(35)}c.endNonterminal("QuotAttr",r)},this.parse_CData=function(){switch(c.startNonterminal("CData",r),h(1),s){case 14:f(14);break;case 67:f(67);break;default:f(35)}c.endNonterminal("CData",r)},this.parse_XMLComment=function(){switch(c.startNonterminal("XMLComment",r),h(0),s){case 12:f(12);break;case 50:f(50);break;default:f(35)}c.endNonterminal("XMLComment",r)},this.parse_PI=function(){switch(c.startNonterminal("PI",r),h(3),s){case 13:f(13);break;case 62:f(62);break;case 63:f(63);break;default:f(35)}c.endNonterminal("PI",r)},this.parse_Pragma=function(){switch(c.startNonterminal("Pragma",r),h(2),s){case 11:f(11);break;case 38:f(38);break;case 39:f(39);break;default:f(35)}c.endNonterminal("Pragma",r)},this.parse_Comment=function(){switch(c.startNonterminal("Comment",r),h(4),s){case 55:f(55);break;case 44:f(44);break;case 32:f(32);break;default:f(35)}c.endNonterminal("Comment",r)},this.parse_CommentDoc=function(){switch(c.startNonterminal("CommentDoc",r),h(6),s){case 33:f(33);break;case 34:f(34);break;case 55:f(55);break;case 44:f(44);break;default:f(35)}c.endNonterminal("CommentDoc",r)},this.parse_QuotString=function(){switch(c.startNonterminal("QuotString",r),h(5),s){case 3:f(3);break;case 2:f(2);break;case 1:f(1);break;case 37:f(37);break;default:f(35)}c.endNonterminal("QuotString",r)},this.parse_AposString=function(){switch(c.startNonterminal("AposString",r),h(7),s){case 21:f(21);break;case 31:f(31);break;case 23:f(23);break;case 24:f(24);break;case 41:f(41);break;default:f(35)}c.endNonterminal("AposString",r)},this.parse_Prefix=function(){c.startNonterminal("Prefix",r),p(13),d(),function(){switch(c.startNonterminal("NCName",r),s){case 28:f(28);break;case 68:f(68);break;case 73:f(73);break;case 77:f(77);break;case 78:f(78);break;case 82:f(82);break;case 86:f(86);break;case 87:f(87);break;case 88:f(88);break;case 92:f(92);break;case 103:f(103);break;case 107:f(107);break;case 111:f(111);break;case 116:f(116);break;case 120:f(120);break;case 121:f(121);break;case 124:f(124);break;case 126:f(126);break;case 129:f(129);break;case 135:f(135);break;case 144:f(144);break;case 146:f(146);break;case 148:f(148);break;case 149:f(149);break;case 158:f(158);break;case 160:f(160);break;case 161:f(161);break;case 162:f(162);break;case 170:f(170);break;case 172:f(172);break;case 176:f(176);break;case 178:f(178);break;case 179:f(179);break;case 184:f(184);break;case 196:f(196);break;case 198:f(198);break;case 199:f(199);break;case 218:f(218);break;case 222:f(222);break;case 234:f(234);break;case 235:f(235);break;case 246:f(246);break;case 247:f(247);break;case 252:f(252);break;case 264:f(264);break;case 268:f(268);break;case 71:f(71);break;case 72:f(72);break;case 80:f(80);break;case 91:f(91);break;case 94:f(94);break;case 101:f(101);break;case 106:f(106);break;case 108:f(108);break;case 109:f(109);break;case 110:f(110);break;case 117:f(117);break;case 118:f(118);break;case 119:f(119);break;case 122:f(122);break;case 127:f(127);break;case 132:f(132);break;case 133:f(133);break;case 134:f(134);break;case 143:f(143);break;case 150:f(150);break;case 151:f(151);break;case 157:f(157);break;case 163:f(163);break;case 168:f(168);break;case 180:f(180);break;case 182:f(182);break;case 183:f(183);break;case 189:f(189);break;case 200:f(200);break;case 204:f(204);break;case 210:f(210);break;case 211:f(211);break;case 214:f(214);break;case 216:f(216);break;case 217:f(217);break;case 224:f(224);break;case 225:f(225);break;case 227:f(227);break;case 233:f(233);break;case 241:f(241);break;case 242:f(242);break;case 248:f(248);break;case 251:f(251);break;case 254:f(254);break;case 258:f(258);break;case 260:f(260);break;case 272:f(272);break;case 70:f(70);break;case 79:f(79);break;case 81:f(81);break;case 83:f(83);break;case 84:f(84);break;case 89:f(89);break;case 96:f(96);break;case 99:f(99);break;case 100:f(100);break;case 102:f(102);break;case 104:f(104);break;case 123:f(123);break;case 130:f(130);break;case 131:f(131);break;case 139:f(139);break;case 152:f(152);break;case 153:f(153);break;case 159:f(159);break;case 169:f(169);break;case 190:f(190);break;case 197:f(197);break;case 201:f(201);break;case 220:f(220);break;case 223:f(223);break;case 226:f(226);break;case 232:f(232);break;case 238:f(238);break;case 249:f(249);break;case 250:f(250);break;case 255:f(255);break;case 259:f(259);break;case 261:f(261);break;case 265:f(265);break;case 95:f(95);break;case 174:f(174);break;default:f(219)}c.endNonterminal("NCName",r)}(),c.endNonterminal("Prefix",r)},this.parse__EQName=function(){c.startNonterminal("_EQName",r),p(12),d(),g(),c.endNonterminal("_EQName",r)}};n.getTokenSet=function(e){for(var a=[],t=e<0?-e:4095&INITIAL[e],r=0;r<279;r+=32)for(var s=r,o=2066*(r>>5)+t-1,i=o>>2,c=i>>2,k=n.EXPECTED[(3&o)+n.EXPECTED[(3&i)+n.EXPECTED[(3&c)+n.EXPECTED[c>>2]]]];0!=k;k>>>=1,++s)1&k&&a.push(n.TOKEN[s]);return a},n.MAP0=[67,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,18,18,18,18,18,18,18,18,19,20,21,22,23,24,25,26,27,28,29,30,27,31,31,31,31,31,31,31,31,31,31,32,31,31,33,31,31,31,31,31,31,34,35,36,37,31,37,38,39,40,41,42,43,44,45,46,31,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,31,62,63,64,65,37],n.MAP1=[108,124,214,214,214,214,214,214,214,214,214,214,214,214,214,214,156,181,181,181,181,181,214,215,213,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,247,261,277,293,309,347,363,379,416,416,416,408,331,323,331,323,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,433,433,433,433,433,433,433,316,331,331,331,331,331,331,331,331,394,416,416,417,415,416,416,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,330,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,416,67,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,18,18,18,18,18,18,18,18,19,20,21,22,23,24,25,26,27,28,29,30,27,31,31,31,31,31,31,31,31,31,31,31,31,31,31,37,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,32,31,31,33,31,31,31,31,31,31,34,35,36,37,31,37,38,39,40,41,42,43,44,45,46,31,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,31,62,63,64,65,37,37,37,37,37,37,37,37,37,37,37,37,31,31,37,37,37,37,37,37,37,66,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66],n.MAP2=[57344,63744,64976,65008,65536,983040,63743,64975,65007,65533,983039,1114111,37,31,37,31,31,37],n.INITIAL=[1,2,49155,57348,5,6,7,8,9,10,11,12,13,14,15],n.TRANSITION=[19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,17408,19288,17439,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,22126,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17672,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,19469,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,36919,18234,18262,18278,18294,18320,18336,18361,18397,18419,18432,18304,18448,18485,18523,18553,18583,18599,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,18825,18841,18871,18906,18944,18960,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19074,36169,17439,36866,17466,36890,36866,22314,19105,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,22126,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17672,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,19469,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,36919,18234,18262,18278,18294,18320,18336,18361,18397,18419,18432,18304,18448,18485,18523,18553,18583,18599,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,18825,18841,18871,18906,18944,18960,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22182,19288,19121,36866,17466,18345,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19273,19552,19304,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19332,17423,19363,36866,17466,17537,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,18614,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,19391,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,19427,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36154,19288,19457,36866,17466,17740,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22780,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22375,22197,18469,36866,17466,36890,36866,21991,24018,22987,17556,17575,22288,17486,17509,17525,18373,21331,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,19485,19501,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19537,22390,19568,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19596,19611,19457,36866,17466,36890,36866,18246,19627,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22242,20553,19457,36866,17466,36890,36866,18648,30477,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36472,19288,19457,36866,17466,17809,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,21770,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,19643,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,19672,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,20538,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,17975,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22345,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19726,19742,21529,24035,23112,26225,23511,27749,27397,24035,34360,24035,24036,23114,35166,23114,23114,19758,23511,35247,23511,23511,28447,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,24254,19821,23511,23511,23511,23511,23512,19441,36539,24035,24035,24035,24035,19846,19869,23114,23114,23114,28618,32187,19892,23511,23511,23511,34585,20402,36647,24035,24035,24036,23114,33757,23114,23114,23029,20271,23511,27070,23511,23511,30562,24035,24035,29274,26576,23114,23114,31118,23036,29695,23511,23511,32431,23634,30821,24035,23110,19913,23114,23467,31261,23261,34299,19932,24035,32609,19965,35389,19984,27689,19830,29391,29337,20041,22643,35619,33728,20062,20121,20166,35100,26145,20211,23008,19876,20208,20227,25670,20132,26578,27685,20141,20243,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36094,19288,19457,36866,17466,21724,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22735,19552,20287,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22750,19288,21529,24035,23112,28056,23511,29483,28756,24035,24035,24035,24036,23114,23114,23114,23114,20327,23511,23511,23511,23511,31156,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,24254,20371,23511,23511,23511,23511,27443,20395,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,29457,29700,23511,23511,23511,23511,33444,20402,24035,24035,24035,24036,23114,23114,23114,23114,28350,20421,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,20447,20475,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,20523,22257,20569,20783,21715,17603,20699,20837,20614,20630,21149,20670,21405,17486,17509,17525,18373,19179,20695,20716,20732,20755,19194,18042,21641,20592,20779,20598,21412,17470,17591,20896,17468,17619,20799,20700,21031,20744,20699,20828,18075,21259,20581,20853,18048,20868,20884,17756,17784,17800,17825,17854,21171,21200,20931,20947,21378,20955,20971,18086,20645,21002,20986,18178,17960,18012,18381,18064,29176,21044,21438,21018,21122,21393,21060,21844,21094,20654,17493,18150,18166,18214,25967,20763,21799,21110,21830,21138,21246,21301,18336,18361,21165,21187,20812,21216,21232,21287,21317,18553,21347,21363,21428,21454,21271,21483,21499,21515,21575,21467,18712,21591,21633,21078,18189,18198,20679,21657,21701,21074,21687,21740,21756,21786,21815,21860,21876,21892,21946,21962,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36457,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,36813,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,21981,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,22151,22007,18884,17900,17922,17944,18178,17960,18012,18381,18064,27898,17884,18890,17906,17928,22042,25022,18130,36931,36963,17493,18150,18166,22070,22112,25026,18134,36935,18262,18278,18294,18320,18336,18361,22142,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36109,19288,18469,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22167,19288,19457,36866,17466,17768,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22227,36487,22273,36866,17466,36890,36866,19316,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18749,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,22304,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,19580,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22330,19089,19457,36866,17466,18721,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22765,19347,19457,36866,17466,36890,36866,18114,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29116,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34541,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,22540,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29116,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29908,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29116,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22561,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,23837,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22584,23511,23511,23511,23511,29116,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36442,19288,21605,24035,23112,28137,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,31568,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22690,19288,19457,36866,17466,36890,36866,21991,27584,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,22659,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22360,19552,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22675,22811,19457,36866,17466,36890,36866,19133,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,22827,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36139,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36064,19288,22865,22881,32031,22897,22913,22956,29939,24035,24035,24035,23003,23114,23114,23114,23024,22420,23511,23511,23511,23052,29116,23073,29268,24035,25563,26915,23106,23131,23114,23114,23159,23181,23197,23248,23511,23511,23282,23305,22493,32364,24035,33472,30138,26325,31770,33508,27345,33667,23114,23321,23473,23351,35793,36576,23511,23375,22500,24145,24035,29197,20192,24533,23440,23114,19017,23459,22839,23489,23510,23511,33563,23528,32076,25389,24035,26576,23561,23583,23114,32683,22516,23622,23655,23511,23634,35456,37144,23110,23683,34153,20499,32513,25824,23705,24035,24035,23111,23114,19874,27078,33263,19830,24035,23112,19872,27741,23266,24036,23114,30243,20507,32241,20150,31862,27464,35108,23727,23007,35895,34953,26578,27685,20141,24569,31691,19787,33967,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36427,19552,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29116,19803,24035,24035,24035,27027,26576,23114,23114,23114,31471,23756,22468,23511,23511,23511,34687,23772,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,23788,24035,24035,24035,21559,23828,23114,23114,23114,25086,22839,23853,23511,23511,23511,23876,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,31761,23909,23953,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36049,19288,21605,30825,23112,23987,23511,24003,31001,27617,24034,24035,24036,24052,24089,23114,23114,22420,24109,24168,23511,23511,29116,24188,27609,20017,29516,24035,26576,24222,19968,23114,24252,33811,22468,24270,33587,23511,24320,27443,22493,24035,24035,24035,24035,24339,23113,23114,23114,23114,28128,28618,29700,23511,23511,23511,28276,34564,20402,24035,24035,32929,24036,23114,23114,23114,24357,23029,22839,23511,23511,23511,24377,25645,24035,34112,24035,26576,23114,26643,23114,32683,22516,23511,25638,23511,23711,24035,24395,27809,23114,24414,20499,24432,30917,23628,24035,30680,23111,23114,30233,27078,25748,24452,24035,23112,19872,27741,23266,24036,23114,24475,19829,26577,26597,26154,24519,24556,24596,23007,20046,20132,26578,24634,20141,24569,31691,24679,24727,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36412,19288,21605,19943,34861,32618,26027,29483,32016,32050,36233,24776,35574,24801,24819,32671,31289,22420,24868,24886,20087,26849,29116,19803,24035,24035,24035,36228,26576,23114,23114,23114,24981,33811,22468,23511,23511,23511,29028,27443,22493,24923,27965,24035,24035,32797,24946,23443,23114,23114,29636,24997,22849,28252,23511,23511,23511,25042,25110,24035,24035,34085,24036,25133,23114,23114,25152,23029,22839,25169,23511,36764,23511,25645,30403,24035,25186,26576,31806,24093,25212,32683,22516,32713,26245,34293,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,32406,23111,23114,28676,30944,27689,25234,24035,23112,19872,37063,23266,24036,23114,30243,20379,26100,29218,20211,30105,25257,25284,23007,20046,20132,26578,27685,20141,24569,24834,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36034,19288,21671,25314,25072,25330,25346,25362,29939,29951,35288,29984,23812,27216,25405,25424,30456,22584,26292,25461,25480,31592,29116,25516,34963,25545,27007,25579,33937,25614,25661,25686,34872,25702,25718,25734,25769,25795,25811,25840,22493,26533,25856,24035,25876,30763,27481,25909,23114,28987,25936,25954,29700,25983,23511,31412,26043,26063,22568,29241,29592,26116,31216,35383,26170,34783,26194,26221,22839,26241,26261,22477,26283,26308,27306,31035,24655,26576,29854,33386,26341,32683,22516,32153,30926,26361,19996,26381,35463,26397,26424,34646,26478,35605,31386,26494,35567,31964,22940,23689,25218,30309,32289,19830,33605,23112,32109,27733,27084,24496,35886,35221,26525,36602,26549,26558,26574,26594,26613,26629,26666,26700,26578,27685,23740,24285,31691,26733,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36397,19552,18991,25887,28117,32618,26776,29483,29939,26802,24035,24035,24036,28664,23114,23114,23114,22420,30297,23511,23511,23511,29116,19803,24035,24035,24035,25559,26576,23114,23114,23114,30525,33811,22468,23511,23511,23511,28725,27443,22493,24035,24035,27249,24035,24035,23113,23114,23114,26827,23114,28618,29700,23511,23511,26845,23511,34564,20402,24035,24035,26979,24036,23114,23114,23114,24974,23029,22839,23511,23511,23511,26865,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,33305,24035,25598,23114,19874,34253,27689,19830,24035,23112,19872,27741,23266,24036,23114,26886,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,26931,24569,26439,26947,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36019,19288,26995,24035,23112,32618,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,27043,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,27061,23511,23511,23511,23511,23512,24694,24035,24035,29978,24035,24035,23113,23114,33114,23114,23114,30010,29700,23511,35913,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,27155,26576,23114,23114,30447,23036,29695,23511,23511,30935,20099,24152,25529,27100,34461,27121,22625,29156,26009,27137,30422,31903,31655,28870,27171,32439,31731,19830,27232,22612,27265,26786,25494,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,20342,27288,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,27322,27339,28020,27361,27382,29939,24035,24035,32581,24036,23114,23114,23114,27425,22420,23511,23511,23511,27442,28306,19803,24035,24035,24035,24035,26710,23114,23114,23114,23114,32261,22468,23511,23511,23511,23511,35719,24694,29510,24035,24035,24035,24035,26717,23114,23114,23114,23114,28618,32217,23511,23511,23511,23511,34585,20402,24035,24035,24035,27459,23114,23114,23114,36252,23029,20271,23511,23511,23511,28840,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,27480,34483,28401,29761,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36382,19288,21605,27497,27517,28504,28898,27569,29939,29401,27600,27323,27633,19025,27662,23114,27705,22420,20483,27721,23511,27765,28306,19803,23540,24035,24610,27781,27805,26650,23114,28573,32990,25920,22468,26870,23511,26684,34262,34737,25057,34622,24035,24035,23971,24206,27825,27847,23114,23114,27865,27885,35766,27914,23511,23511,32766,32844,27934,28795,26909,27955,26092,27988,25445,28005,28036,28052,21965,23511,32196,19897,28072,28102,36534,21541,23801,28153,28180,28197,28221,23036,32695,28251,28268,28292,23667,34825,23930,24580,28322,28344,31627,28366,25996,23628,24035,24035,23111,23114,19874,27078,27689,35625,33477,33359,27674,28393,33992,24036,23114,30243,19829,28417,28433,28463,23008,19876,20208,23007,20046,20132,28489,28520,20141,24569,31691,19787,28550,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,24694,28589,24035,24035,24035,24035,28608,23114,23114,23114,23114,28618,20431,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36004,19288,28634,31951,28565,28702,28718,28741,32544,20175,28792,32086,20105,28811,29059,29862,28856,22420,28886,30354,23359,28922,28306,28952,23888,26320,36506,24035,29331,28968,36609,23114,29003,31661,27061,30649,27366,23511,29023,27918,24694,24035,24035,23893,33094,30867,23113,23114,23114,29044,34184,30010,29700,23511,23511,29081,29102,34585,20402,27789,24035,24035,24036,23114,29132,23114,23114,23029,20271,23511,29153,23511,23511,30562,30174,24035,24035,27409,25438,23114,23114,29172,36668,31332,23511,23511,29192,30144,24035,23110,30203,23114,23467,31544,23261,23628,24035,22545,23111,23114,29213,27078,27689,29234,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,29257,23008,19876,20208,28768,29290,29320,34776,29353,20141,22435,29378,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36367,19288,21605,34616,19006,32618,31497,31507,36216,20184,24035,34393,29424,34668,23114,34900,29447,22420,30360,23511,37089,29473,28306,19803,29499,24398,24035,24035,26576,31799,29532,29550,23114,33811,22468,32298,29571,31184,23511,23512,37127,36628,29589,24035,24135,24035,23113,29608,23114,27831,29634,28618,29652,30037,23511,24172,29671,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,29555,29690,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,29719,24035,23110,29738,23114,23467,34035,29756,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,29777,34364,28181,30243,29799,31920,27272,27185,23008,31126,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29828,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35989,19552,19687,35139,28649,29878,29894,29924,29939,23224,23085,31969,24036,35173,24752,24803,23114,22420,31190,30318,24870,23511,28306,29967,23967,24035,24035,24035,26576,3e4,23114,23114,23114,33811,22468,30026,23511,23511,23511,23512,26078,24035,24035,24035,30053,37137,30071,23114,23114,33368,25136,28618,30723,23511,23511,37096,31356,34585,20402,30092,30127,30160,24036,35740,30219,24960,30259,23029,20271,34042,30285,30342,30376,23289,30055,30400,30419,30438,32640,33532,33514,30472,18792,26267,24323,23057,30493,23639,20008,30196,33188,30517,20075,23511,30541,23628,30578,33928,28776,30594,19874,30610,30637,19830,30677,27646,19872,25779,23266,23232,35016,30243,30696,29812,30712,30746,27206,30779,30807,23007,33395,20132,26578,27685,31703,22928,31691,19787,31079,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36352,19288,23335,30841,26131,30888,30904,30986,29939,24035,24704,31017,20025,23114,26178,31051,31095,22420,23511,22524,31142,31172,28534,31206,35497,25196,24035,28592,24503,23114,31239,31285,23114,31305,31321,31355,31372,31407,23511,30556,24694,24035,27501,19805,24035,24035,23113,23114,31428,24066,23114,28618,29700,23511,31837,18809,23511,34585,31448,24035,24035,24035,23090,23114,23114,23114,23114,31619,35038,23511,23511,23511,23511,33714,24035,33085,24035,29431,23114,31467,23114,23143,31487,23511,31523,23511,35195,36783,24035,30111,23567,23114,23467,31543,31560,23628,24035,24035,23111,23114,19874,30953,31584,34508,24035,31608,26345,37055,23266,31643,31677,31719,31747,31786,31822,26898,23008,19876,31859,23007,20046,20132,26578,27685,20141,24569,31691,31878,31936,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35974,19288,21605,27972,35663,31985,29655,32001,36715,24785,25893,23545,31912,19853,19916,25938,24540,22420,31843,29674,29573,32735,28936,19803,24035,24035,32047,24035,26576,23114,23114,27544,23114,33811,22468,23511,23511,32161,23511,23512,32066,24035,33313,24035,24035,24035,23113,27426,32102,23114,23114,28618,32125,23511,32144,23511,23511,33569,20402,24035,27045,24035,24036,23114,23114,28328,23114,30076,32177,23511,23511,30384,23511,30562,24035,24035,24035,26576,23114,23114,23114,23595,32212,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,22635,25753,32233,32257,32277,19829,26577,26597,20211,23008,19876,32322,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,32352,35285,32380,34196,33016,30661,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,32404,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,32422,23511,23511,23511,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,30269,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,19949,24035,23111,32455,19874,31269,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36337,19552,19209,21617,26509,32475,32491,32529,29939,24035,32578,25241,32597,23114,32634,29007,32656,22420,23511,32729,26365,32751,28306,32788,32882,24035,24035,32813,36727,23114,33182,23114,27553,33235,32829,23511,32706,23511,28906,28377,26962,32881,32904,32898,32920,24035,32953,23114,32977,26408,23114,28164,33006,23511,33039,35774,23511,32306,20402,33076,30872,24035,24036,25408,33110,28979,23114,23029,20271,35835,33130,33054,23511,30562,33148,24035,24035,33167,23114,23114,33775,23036,20459,23511,23511,25464,24646,24035,24035,22446,23114,23114,25627,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,31391,33204,33220,33251,33287,26577,26597,20211,33329,19876,33345,23007,20046,20132,26578,27685,28473,22599,31691,33411,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35959,19288,21907,27243,29843,32618,33427,31507,29939,33460,34090,24035,24036,33493,24416,33530,23114,22420,33548,24379,33585,23511,28306,19803,33603,24202,24035,24035,25593,33749,28205,23114,23114,32388,22468,33853,33060,23511,23511,31339,33621,24035,24035,34397,24618,30757,33663,23114,23114,33683,35684,28618,26678,23511,23511,32506,33699,34585,20402,24035,32562,26973,24036,23114,23114,33377,33773,23029,20271,23511,23511,30621,23511,23860,24035,33791,21553,26576,36558,23114,33809,23036,32857,26047,23511,33827,23634,24035,24035,23110,23114,23114,31252,23511,33845,23628,24035,24459,23111,23114,33869,27078,30791,29783,24035,24742,19872,33895,23266,26462,19710,33879,33919,26577,26597,24123,24930,21930,20208,30501,33953,25268,20252,33983,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36322,19552,23390,33634,35154,34008,34024,34058,35544,34106,34128,26811,33151,34144,34169,34212,23114,34228,34244,34278,34315,23511,34331,34347,34380,34413,24035,24663,26576,34429,34453,34477,29534,33811,22468,34499,34524,34557,25170,34580,35436,23937,34601,24035,24341,26453,23113,34638,34662,23114,24236,28618,34684,34703,34729,23511,35352,34753,34799,24035,34815,32558,34848,34888,35814,34923,23165,29137,23606,30326,30730,34939,33023,30562,36848,34979,24035,24847,34996,23114,23114,35032,29695,35054,23511,23511,35091,33296,35124,24296,28235,24361,36276,32772,35067,35189,27301,30855,24852,22452,35211,35237,35316,25500,35270,23405,24304,35304,29362,24036,23114,35332,19829,26577,26597,20211,23008,19876,20208,35368,28823,23920,32336,35405,20141,24569,31691,35421,35479,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35944,22795,21605,33647,35877,35513,30962,35529,34073,35557,24035,24035,20405,31107,23114,23114,23114,35590,34713,23511,23511,23511,35641,19803,29408,32937,25298,24035,35657,23115,27849,24760,35679,26205,22468,23511,35700,24907,24901,35075,31893,34980,24035,24035,24035,24035,23113,35009,23114,23114,23114,28618,35716,30970,23511,23511,23511,34585,23215,24035,24035,24035,24036,35735,23114,23114,23114,27105,35756,35790,23511,23511,23511,35254,35446,24035,24035,31223,35809,23114,23114,23036,36825,35830,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,31031,20355,19872,33903,23266,24036,23114,28686,19829,26577,26597,20211,23008,23424,20208,24711,31065,24486,26578,27685,20141,19773,35851,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36307,19288,21605,35494,19702,32618,33437,31507,29939,25117,24035,27939,24036,27869,23114,26829,23114,22420,23494,23511,33132,23511,28306,19803,24035,34832,24035,24035,26576,23114,25153,23114,23114,33811,22468,23511,23511,35911,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35929,19288,21605,25860,23112,36185,23511,36201,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,26748,24035,24035,24035,24035,24035,36249,23114,23114,23114,23114,28618,28835,23511,23511,23511,23511,34585,20402,24035,27151,24035,26760,23114,27989,23114,23114,36268,20271,23511,24436,23511,29703,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36292,19288,21605,36503,21922,32618,34534,31507,36522,24035,33793,24035,35864,23114,23114,36555,23417,22420,23511,23511,36574,26020,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,36592,24035,24035,36625,24035,24035,23113,23114,32961,23114,23114,29618,29700,23511,29086,23511,23511,34585,20402,36644,24035,24035,24036,29740,23114,23114,23114,29065,36663,31527,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,31451,23112,36684,23511,36700,29939,24035,24035,24035,30185,23114,23114,23114,27526,22420,23511,23511,23511,32865,28306,19803,36743,24035,27017,24035,26576,27535,23114,31432,23114,33811,22468,33271,23511,32128,23511,23512,24694,24035,27196,24035,24035,24035,23113,32459,23114,23114,23114,28618,29700,33829,36762,23511,23511,34585,20402,24035,36746,24035,29722,23114,23114,34437,23114,34907,20271,23511,23511,18801,23511,23206,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,36837,24035,24035,33739,23114,23114,25094,23511,23261,23628,24035,36780,23111,24073,19874,27078,35344,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22720,19288,36799,36866,17466,36890,36864,21991,22211,22987,17556,17575,22288,17486,17509,17525,18373,17631,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,36883,36906,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22705,19288,19457,36866,17466,36890,36866,19375,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36124,19288,36951,36866,17466,36890,36866,21991,22404,22987,17556,17575,22288,17486,17509,17525,18373,18567,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,36979,36995,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36139,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18027,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36139,19288,21529,24035,23112,23033,23511,31507,25377,24035,24035,24035,24036,23114,23114,23114,23114,37040,23511,23511,23511,23511,28086,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,24254,37079,23511,23511,23511,23511,23512,34766,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,37112,37160,18469,36866,17466,36890,36866,17656,37174,22987,17556,17575,22288,17486,17509,17525,18373,18537,22984,17553,17572,22285,18780,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,36883,36906,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,53264,18,49172,57366,24,8192,28,102432,127011,110630,114730,106539,127011,127011,127011,53264,18,18,0,0,57366,0,24,24,24,0,28,28,28,28,102432,0,0,127011,0,2220032,110630,0,0,0,114730,106539,0,2170880,2170880,2170880,2170880,0,0,0,2170880,2170880,2170880,3002368,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2576384,2215936,2215936,2215936,2416640,2424832,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2543616,2215936,2215936,2215936,2215936,2215936,2629632,2215936,2617344,2215936,2215936,2215936,2215936,2215936,2215936,2691072,2215936,2707456,2215936,2715648,2215936,2723840,2764800,2215936,2215936,2797568,2215936,2822144,2215936,2215936,2854912,2215936,2215936,2215936,2912256,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,180224,0,0,2174976,0,0,2170880,2617344,2170880,2170880,2170880,2170880,2170880,2170880,2691072,2170880,2707456,2170880,2715648,2170880,2723840,2764800,2170880,2170880,2797568,2170880,2170880,2797568,2170880,2822144,2170880,2170880,2854912,2170880,2170880,2170880,2912256,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2609152,2215936,2215936,2215936,2215936,2215936,2215936,2654208,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,184599,280,0,2174976,0,0,2215936,3117056,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,544,0,546,0,0,2179072,0,0,0,552,0,0,2170880,2170880,2170880,3117056,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,0,0,0,2158592,2158592,2232320,2232320,0,2240512,2240512,0,0,0,644,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,3129344,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2400256,2215936,2215936,2215936,2215936,2711552,2170880,2170880,2170880,2170880,2170880,2760704,2768896,2789376,2813952,2170880,2170880,2170880,2875392,2904064,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2453504,2457600,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,167936,0,0,0,0,2174976,0,0,2215936,2215936,2514944,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2592768,2215936,2215936,2215936,2215936,2215936,2215936,2215936,32768,0,0,0,0,0,2174976,32768,0,2633728,2215936,2215936,2215936,2215936,2215936,2215936,2711552,2215936,2215936,2215936,2215936,2215936,2760704,2768896,2789376,2813952,2215936,2215936,2215936,2875392,2904064,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2174976,0,65819,2215936,2215936,3031040,2215936,3055616,2215936,2215936,2215936,2215936,3092480,2215936,2215936,3125248,2215936,2215936,2215936,2215936,2215936,2215936,3002368,2215936,2215936,2170880,2170880,2494464,2170880,2170880,0,0,2215936,2215936,2215936,2215936,2215936,2215936,3198976,2215936,0,0,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,0,0,0,2379776,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2445312,2170880,2465792,2473984,2170880,2170880,2170880,2170880,2170880,2170880,2523136,2170880,2170880,2641920,2170880,2170880,2170880,2699264,2170880,2727936,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2879488,2170880,2916352,2170880,2170880,2170880,2879488,2170880,2916352,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3026944,2170880,2170880,3063808,2170880,2170880,3112960,2170880,2170880,3133440,2170880,2170880,3112960,2170880,2170880,3133440,2170880,2170880,2170880,3162112,2170880,2170880,3182592,3186688,2170880,2379776,2215936,2523136,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2596864,2215936,2621440,2215936,2215936,2641920,2215936,2215936,0,0,0,0,0,0,2179072,548,0,0,0,0,287,2170880,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3117056,2170880,2170880,2170880,2170880,2215936,2215936,2699264,2215936,2727936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2879488,2215936,2916352,2215936,2215936,0,0,0,0,188416,0,2179072,0,0,0,0,0,287,2170880,0,2171019,2171019,2171019,2400395,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3031179,2171019,3055755,2171019,2171019,2215936,3133440,2215936,2215936,2215936,3162112,2215936,2215936,3182592,3186688,2215936,0,0,0,0,0,0,0,0,0,0,2171019,2171019,2171019,2171019,2171019,2171019,2523275,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2597003,2171019,2621579,2170880,2170880,2170880,3162112,2170880,2170880,3182592,3186688,2170880,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,24,24,0,4337664,28,2170880,2170880,2170880,2629632,2170880,2170880,2170880,2170880,2719744,2744320,2170880,2170880,2170880,2834432,2838528,2170880,2908160,2170880,2170880,2936832,2215936,2215936,2215936,2215936,2719744,2744320,2215936,2215936,2215936,2834432,2838528,2215936,2908160,2215936,2215936,2936832,2215936,2215936,2985984,2215936,2994176,2215936,2215936,3014656,2215936,3059712,3076096,3088384,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2445312,2215936,2465792,2473984,2215936,2215936,2215936,2215936,2215936,2215936,2171166,2171166,2171166,2171166,2171166,0,0,0,2171166,2171166,2171166,2171166,2171166,2171166,2171019,2171019,2494603,2171019,2171019,2215936,2215936,2215936,3215360,0,0,0,0,0,0,0,0,0,0,0,0,0,2379776,2170880,2170880,2170880,2170880,2985984,2170880,2994176,2170880,2170880,3016168,2170880,3059712,3076096,3088384,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,124,124,0,128,128,2170880,2170880,2170880,3215360,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2486272,2170880,2170880,2506752,2170880,2170880,2170880,2535424,2539520,2170880,2170880,2588672,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2920448,2170880,2170880,2170880,2990080,2170880,2170880,2170880,2170880,3051520,2170880,2170880,2170880,2170880,2170880,2170880,3170304,0,2387968,2392064,2170880,2170880,2433024,2170880,2170880,2170880,3170304,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2486272,2215936,2215936,2506752,2215936,2215936,2215936,2535424,2539520,2215936,2215936,2588672,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2174976,136,0,2215936,2215936,2920448,2215936,2215936,2215936,2990080,2215936,2215936,2215936,2215936,3051520,2215936,2215936,2215936,2215936,2215936,2215936,2215936,3108864,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,3026944,2215936,2215936,3063808,2215936,2215936,3112960,2215936,2215936,2215936,3170304,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2453504,2457600,2170880,2170880,2170880,2486272,2170880,2170880,2506752,2170880,2170880,2170880,2537049,2539520,2170880,2170880,2588672,2170880,2170880,2170880,1508,2170880,2170880,2170880,1512,2170880,2920448,2170880,2170880,2170880,2990080,2170880,2170880,2170880,2461696,2170880,2170880,2170880,2510848,2170880,2170880,2170880,2170880,2580480,2170880,2605056,2637824,2170880,2170880,18,0,0,0,0,0,0,0,0,2220032,0,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2686976,2748416,2170880,2170880,2170880,2924544,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3121152,2170880,2170880,3145728,3158016,3166208,2170880,2420736,2428928,2170880,2478080,2170880,2170880,2170880,2170880,0,0,2170880,2170880,2170880,2170880,2646016,2670592,0,0,3145728,3158016,3166208,2387968,2392064,2215936,2215936,2433024,2215936,2461696,2215936,2215936,2215936,2510848,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,0,0,2170880,2215936,2215936,2580480,2215936,2605056,2637824,2215936,2215936,2686976,2748416,2215936,2215936,2215936,2924544,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,0,286,2170880,2215936,2215936,2215936,2215936,2215936,3121152,2215936,2215936,3145728,3158016,3166208,2387968,2392064,2170880,2170880,2433024,2170880,2461696,2170880,2170880,2170880,2510848,2170880,2170880,1625,2170880,2170880,2580480,2170880,2605056,2637824,2170880,647,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2576384,2170880,2170880,2170880,2170880,2170880,2609152,2170880,2170880,2686976,0,0,2748416,2170880,2170880,0,2170880,2924544,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,24,0,0,28,28,2170880,3141632,2215936,2420736,2428928,2215936,2478080,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2646016,2670592,2752512,2756608,2846720,2961408,2215936,2998272,2215936,3010560,2215936,2215936,2215936,3141632,2170880,2420736,2428928,2752512,2756608,0,2846720,2961408,2170880,2998272,2170880,3010560,2170880,2170880,2170880,3141632,2170880,2170880,2490368,2215936,2490368,2215936,2215936,2215936,2547712,2555904,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2174976,245760,0,3129344,2170880,2170880,2490368,2170880,2170880,2170880,0,0,2547712,2555904,2170880,2170880,2170880,0,0,0,0,0,0,0,0,0,2220032,0,0,45056,0,2584576,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2170880,2170880,2170880,2170880,0,0,0,2170880,2170880,2158592,0,0,0,0,0,0,0,0,2220032,0,0,0,0,0,0,0,0,1482,97,97,97,97,97,97,97,1354,97,97,97,97,97,97,97,97,1148,97,97,97,97,97,97,97,2584576,2170880,2170880,1512,0,2170880,2170880,2170880,2170880,2170880,2170880,2441216,2170880,2527232,2170880,2600960,2170880,2850816,2170880,2170880,2170880,3022848,2215936,2441216,2215936,2527232,2215936,2600960,2215936,2850816,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,0,287,2170880,2215936,3022848,2170880,2441216,2170880,2527232,0,0,2170880,2600960,2170880,0,2850816,2170880,2170880,2170880,2170880,2170880,2523136,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2596864,2170880,2621440,2170880,2170880,2641920,2170880,2170880,2170880,3022848,2170880,2519040,2170880,2170880,2170880,2170880,2170880,2215936,2519040,2215936,2215936,2215936,2215936,2215936,2170880,2170880,2170880,2453504,2457600,2170880,2170880,2170880,2170880,2170880,2170880,2514944,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2592768,2170880,2170880,2519040,0,2024,2170880,2170880,0,2170880,2170880,2170880,2396160,2170880,2170880,2170880,2170880,3018752,2396160,2215936,2215936,2215936,2215936,3018752,2396160,0,2024,2170880,2170880,2170880,2170880,3018752,2170880,2650112,2965504,2170880,2215936,2650112,2965504,2215936,0,0,2170880,2650112,2965504,2170880,2551808,2170880,2551808,2215936,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,141,45,45,67,67,67,67,67,224,67,67,238,67,67,67,67,67,67,67,1288,67,67,67,67,67,67,67,67,67,469,67,67,67,67,67,67,0,2551808,2170880,2170880,2215936,0,2170880,2170880,2215936,0,2170880,2170880,2215936,0,2170880,2977792,2977792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53264,18,49172,57366,24,8192,29,102432,127011,110630,114730,106539,127011,127011,127011,53264,18,18,49172,0,0,0,24,24,24,0,28,28,28,28,102432,127,0,0,0,0,0,0,0,0,0,0,140,2170880,2170880,2170880,2416640,0,0,0,0,2220032,110630,0,0,0,114730,106539,136,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,4256099,4256099,24,24,0,28,28,2170880,2461696,2170880,2170880,2170880,2510848,2170880,2170880,0,2170880,2170880,2580480,2170880,2605056,2637824,2170880,2170880,2170880,2547712,2555904,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3129344,2215936,2215936,543,543,545,545,0,0,2179072,0,550,551,551,0,287,2171166,2171166,18,0,0,0,0,0,0,0,0,2220032,0,0,645,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,149,2584576,2170880,2170880,0,0,2170880,2170880,2170880,2170880,2170880,2170880,2441216,2170880,2527232,2170880,2600960,2519040,0,0,2170880,2170880,0,2170880,2170880,2170880,2396160,2170880,2170880,2170880,2170880,3018752,2396160,2215936,2215936,2215936,2215936,3018752,2396160,0,0,2170880,2170880,2170880,2170880,3018752,2170880,2650112,2965504,53264,18,49172,57366,24,155648,28,102432,155648,155687,114730,106539,0,0,155648,53264,18,18,49172,0,57366,0,24,24,24,0,28,28,28,28,102432,0,0,0,0,2220032,0,94208,0,0,114730,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,208896,18,278528,24,24,0,28,28,53264,18,159765,57366,24,8192,28,102432,0,110630,114730,106539,0,0,0,53264,18,18,49172,0,57366,0,24,24,24,0,28,139394,28,28,102432,131,0,0,0,2220032,110630,0,0,0,114730,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,32768,53264,0,18,18,24,24,0,28,28,0,546,0,0,2183168,0,0,552,832,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2170880,2609152,2170880,2170880,2170880,2170880,2170880,2170880,2654208,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,3198976,2215936,0,1084,0,1088,0,1092,0,0,0,0,0,41606,0,0,0,0,45,45,45,45,45,937,0,0,0,0,2220032,110630,0,0,0,114730,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3198976,2170880,0,0,644,0,0,0,2215936,3117056,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,826,0,828,0,0,2183168,0,0,830,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2592768,2170880,2170880,2170880,2170880,2633728,2170880,2170880,2170880,2170880,2170880,2170880,2711552,2170880,2170880,2170880,2170880,2170880,2760704,53264,18,49172,57366,24,8192,28,172066,172032,110630,172066,106539,0,0,172032,53264,18,18,49172,0,57366,0,24,24,24,16384,28,28,28,28,102432,0,98304,0,0,2220032,110630,0,0,0,0,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3198976,2170880,0,0,45056,0,0,0,53264,18,49172,57366,25,8192,30,102432,0,110630,114730,106539,0,0,176219,53264,18,18,49172,0,57366,0,124,124,124,0,128,128,128,128,102432,128,0,0,0,0,0,0,0,0,0,0,140,2170880,2170880,2170880,2416640,0,546,0,0,2183168,0,65536,552,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2646016,2670592,2752512,2756608,2846720,2961408,2170880,2998272,2170880,3010560,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,3198976,2215936,0,0,0,0,0,0,65536,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,143,45,45,67,67,67,67,67,227,67,67,67,67,67,67,67,67,67,1824,67,1826,67,67,67,67,17,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,32768,120,121,18,18,49172,0,57366,0,24,24,24,0,28,28,28,28,102432,67,67,37139,37139,24853,24853,0,0,2179072,548,0,65820,65820,0,287,97,0,0,97,97,0,97,97,97,45,45,45,45,2033,45,67,67,67,67,0,0,97,97,97,97,45,45,67,67,0,369,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,978,0,546,70179,0,2183168,0,0,552,0,97,97,97,97,97,97,97,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,1013,67,67,67,67,67,67,67,67,67,67,473,67,67,67,67,483,67,67,1025,67,67,67,67,67,67,67,67,67,67,67,67,67,97,97,97,97,97,0,0,97,97,97,97,1119,97,97,97,97,97,97,97,97,97,97,97,97,1359,97,97,97,67,67,1584,67,67,67,67,67,67,67,67,67,67,67,67,67,497,67,67,1659,45,45,45,45,45,45,45,45,45,1667,45,45,45,45,45,169,45,45,45,45,45,45,45,45,45,45,45,1668,45,45,45,45,67,67,1694,67,67,67,67,67,67,67,67,67,67,67,67,67,774,67,67,1713,97,97,97,97,97,97,97,0,97,97,1723,97,97,97,97,0,45,45,45,45,45,45,1538,45,45,45,45,45,1559,45,45,1561,45,45,45,45,45,45,45,687,45,45,45,45,45,45,45,45,448,45,45,45,45,45,45,67,67,67,67,1771,1772,67,67,67,67,67,67,67,67,97,97,97,97,0,0,0,97,67,67,67,67,67,1821,67,67,67,67,67,67,1827,67,67,67,0,0,0,0,0,0,97,97,1614,97,97,97,97,97,603,97,97,605,97,97,608,97,97,97,97,0,1532,45,45,45,45,45,45,45,45,45,45,450,45,45,45,45,67,67,97,97,97,97,97,97,0,0,1839,97,97,97,97,0,0,97,97,97,97,97,45,45,45,45,45,45,45,67,67,67,67,67,67,67,97,1883,97,1885,97,0,1888,0,97,97,0,97,97,1848,97,97,97,97,1852,45,45,45,45,45,45,45,384,391,45,45,45,45,45,45,45,385,45,45,45,45,45,45,45,45,1237,45,45,45,45,45,45,67,0,97,97,97,97,0,0,0,97,97,97,97,97,97,45,45,45,45,45,45,45,1951,45,45,45,45,45,45,45,45,67,67,67,67,1963,97,2023,0,97,97,0,97,97,97,45,45,45,45,45,45,67,67,1994,67,1995,67,67,67,67,67,67,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,97,97,0,0,0,0,2220032,110630,0,0,0,114730,106539,137,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2793472,2805760,2170880,2830336,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3031040,2170880,3055616,2170880,2170880,67,67,37139,37139,24853,24853,0,0,281,549,0,65820,65820,0,287,97,0,0,97,97,0,97,97,97,45,45,2031,2032,45,45,67,67,67,67,67,67,67,67,67,67,67,67,1769,67,0,546,70179,549,549,0,0,552,0,97,97,97,97,97,97,97,45,45,45,45,45,45,1858,45,641,0,0,0,0,41606,926,0,0,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,456,67,0,0,0,1313,0,0,0,1096,1319,0,0,0,0,97,97,97,97,97,97,97,97,1110,97,97,97,97,67,67,67,67,1301,1476,0,0,0,0,1307,1478,0,0,0,0,0,0,0,0,97,97,97,97,1486,97,1487,97,1313,1480,0,0,0,0,1319,0,97,97,97,97,97,97,97,97,97,566,97,97,97,97,97,97,67,67,67,1476,0,1478,0,1480,0,97,97,97,97,97,97,97,45,1853,45,1855,45,45,45,45,53264,18,49172,57366,26,8192,31,102432,0,110630,114730,106539,0,0,225368,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,32768,53264,18,18,49172,163840,57366,0,24,24,229376,0,28,28,28,229376,102432,0,0,0,0,2220167,110630,0,0,0,114730,106539,0,2171019,2171019,2171019,2171019,2592907,2171019,2171019,2171019,2171019,2633867,2171019,2171019,2171019,2171019,2171019,2171019,2654347,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3117195,2171019,2171019,2171019,2171019,2240641,0,0,0,0,0,0,0,0,368,0,140,2171019,2171019,2171019,2416779,2424971,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2617483,2171019,2171019,2642059,2171019,2171019,2171019,2699403,2171019,2728075,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3215499,2215936,2215936,2215936,2215936,2215936,2437120,2215936,2215936,2171019,2822283,2171019,2171019,2855051,2171019,2171019,2171019,2912395,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3002507,2171019,2171019,2215936,2215936,2494464,2215936,2215936,2215936,2171166,2171166,2416926,2425118,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2576670,2171166,2617630,2171166,2171166,2171166,2171166,2171166,2171166,2691358,2171166,2707742,2171166,2715934,2171166,2724126,2765086,2171166,2171166,2797854,2171166,2822430,2171166,2171166,2855198,2171166,2171166,2171166,2912542,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2793758,2806046,2171166,2830622,2171166,2171166,2171166,2171166,2171166,2171166,2171166,3109150,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2543902,2171166,2171166,2171166,2171166,2171166,2629918,2793611,2805899,2171019,2830475,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,0,546,0,0,2183168,0,0,552,0,2171166,2171166,2171166,2400542,2171166,2171166,2171166,0,2171166,2171166,2171166,0,2171166,2920734,2171166,2171166,2171166,2990366,2171166,2171166,2171166,2171166,3117342,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,0,53264,0,18,18,4329472,2232445,0,2240641,4337664,2711691,2171019,2171019,2171019,2171019,2171019,2760843,2769035,2789515,2814091,2171019,2171019,2171019,2875531,2904203,2171019,2171019,3092619,2171019,2171019,3125387,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3199115,2171019,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2453504,2457600,2215936,2215936,2215936,2215936,2215936,2215936,2793472,2805760,2215936,2830336,2215936,2215936,2215936,2215936,2215936,2215936,2170880,2170880,2170880,2170880,2170880,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2494464,2170880,2170880,2171166,2171166,2634014,2171166,2171166,2171166,2171166,2171166,2171166,2711838,2171166,2171166,2171166,2171166,2171166,2760990,2769182,2789662,2814238,2171166,2171166,2171166,2875678,2904350,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,3199262,2171166,0,0,0,0,0,0,0,0,0,2379915,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2445451,2171019,2465931,2474123,2171019,2171019,3113099,2171019,2171019,3133579,2171019,2171019,2171019,3162251,2171019,2171019,3182731,3186827,2171019,2379776,2879627,2171019,2916491,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3027083,2171019,2171019,3063947,2699550,2171166,2728222,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2879774,2171166,2916638,2171166,2171166,2171166,2171166,2171166,2609438,2171166,2171166,2171166,2171166,2171166,2171166,2654494,2171166,2171166,2171166,2171166,2171166,2445598,2171166,2466078,2474270,2171166,2171166,2171166,2171166,2171166,2171166,2523422,2171019,2437259,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2543755,2171019,2171019,2171019,2584715,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2908299,2171019,2171019,2936971,2171019,2171019,2986123,2171019,2994315,2171019,2171019,3014795,2171019,3059851,3076235,3088523,2171166,2171166,2986270,2171166,2994462,2171166,2171166,3014942,2171166,3059998,3076382,3088670,2171166,2171166,2171166,2171166,2171166,2171166,3027230,2171166,2171166,3064094,2171166,2171166,3113246,2171166,2171166,3133726,2506891,2171019,2171019,2171019,2535563,2539659,2171019,2171019,2588811,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2691211,2171019,2707595,2171019,2715787,2171019,2723979,2764939,2171019,2171019,2797707,2215936,2215936,3170304,0,0,0,0,0,0,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2453790,2457886,2171166,2171166,2171166,2486558,2171166,2171166,2507038,2171166,2171166,2171166,2535710,2539806,2171166,2171166,2588958,2171166,2171166,2171166,2171166,2515230,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2593054,2171166,2171166,2171166,2171166,3051806,2171166,2171166,2171166,2171166,2171166,2171166,3170590,0,2388107,2392203,2171019,2171019,2433163,2171019,2461835,2171019,2171019,2171019,2510987,2171019,2171019,2171019,2171019,2580619,2171019,2605195,2637963,2171019,2171019,2171019,2920587,2171019,2171019,2171019,2990219,2171019,2171019,2171019,2171019,3051659,2171019,2171019,2171019,2453643,2457739,2171019,2171019,2171019,2171019,2171019,2171019,2515083,2171019,2171019,2171019,2171019,2646155,2670731,2752651,2756747,2846859,2961547,2171019,2998411,2171019,3010699,2171019,2171019,2687115,2748555,2171019,2171019,2171019,2924683,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3121291,2171019,2171019,2171019,3170443,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2486272,2215936,2215936,2506752,3145867,3158155,3166347,2387968,2392064,2215936,2215936,2433024,2215936,2461696,2215936,2215936,2215936,2510848,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,0,553,2170880,2215936,2215936,2215936,2215936,2215936,3121152,2215936,2215936,3145728,3158016,3166208,2388254,2392350,2171166,2171166,2433310,2171166,2461982,2171166,2171166,2171166,2511134,2171166,2171166,0,2171166,2171166,2580766,2171166,2605342,2638110,2171166,2171166,2171166,2171166,3031326,2171166,3055902,2171166,2171166,2171166,2171166,3092766,2171166,2171166,3125534,2171166,2171166,2171166,3162398,2171166,2171166,3182878,3186974,2171166,0,0,0,2171019,2171019,2171019,2171019,3109003,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2215936,2215936,2215936,2400256,2215936,2215936,2215936,2215936,2171166,2687262,0,0,2748702,2171166,2171166,0,2171166,2924830,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2597150,2171166,2621726,2171166,2171166,2642206,2171166,2171166,2171166,2171166,3121438,2171166,2171166,3146014,3158302,3166494,2171019,2420875,2429067,2171019,2478219,2171019,2171019,2171019,2171019,2547851,2556043,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3129483,2215936,2171019,3141771,2215936,2420736,2428928,2215936,2478080,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2646016,2670592,2752512,2756608,2846720,2961408,2215936,2998272,2215936,3010560,2215936,2215936,2215936,3141632,2171166,2421022,2429214,2171166,2478366,2171166,2171166,2171166,2171166,0,0,2171166,2171166,2171166,2171166,2646302,2670878,0,0,0,0,37,110630,0,0,0,114730,106539,0,45,45,45,45,45,1405,1406,45,45,45,45,1409,45,45,45,45,45,1415,45,45,45,45,45,45,45,45,45,45,1238,45,45,45,45,67,2752798,2756894,0,2847006,2961694,2171166,2998558,2171166,3010846,2171166,2171166,2171166,3141918,2171019,2171019,2490507,3129344,2171166,2171166,2490654,2171166,2171166,2171166,0,0,2547998,2556190,2171166,2171166,2171166,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,45,167,45,45,45,45,185,187,45,45,198,45,45,0,2171166,2171166,2171166,2171166,2171166,2171166,3129630,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2576523,2171019,2171019,2171019,2171019,2171019,2609291,2171019,2215936,2215936,2215936,2215936,2215936,2215936,3002368,2215936,2215936,2171166,2171166,2494750,2171166,2171166,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,147,2584576,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2171166,2171166,2171166,2171166,0,0,0,2171166,2171166,2171166,2171166,0,0,0,2171166,2171166,2171166,3002654,2171166,2171166,2171019,2171019,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2175257,0,0,2584862,2171166,2171166,0,0,2171166,2171166,2171166,2171166,2171166,2171019,2441355,2171019,2527371,2171019,2601099,2171019,2850955,2171019,2171019,2171019,3022987,2215936,2441216,2215936,2527232,2215936,2600960,2215936,2850816,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,69632,287,2170880,2215936,3022848,2171166,2441502,2171166,2527518,0,0,2171166,2601246,2171166,0,2851102,2171166,2171166,2171166,2171166,2720030,2744606,2171166,2171166,2171166,2834718,2838814,2171166,2908446,2171166,2171166,2937118,3023134,2171019,2519179,2171019,2171019,2171019,2171019,2171019,2215936,2519040,2215936,2215936,2215936,2215936,2215936,2171166,2171166,2171166,3215646,0,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2486411,2171019,2171019,2171019,2629771,2171019,2171019,2171019,2171019,2719883,2744459,2171019,2171019,2171019,2834571,2838667,2171019,2519326,0,0,2171166,2171166,0,2171166,2171166,2171166,2396299,2171019,2171019,2171019,2171019,3018891,2396160,2215936,2215936,2215936,2215936,3018752,2396446,0,0,2171166,2171166,2171166,2171166,3019038,2171019,2650251,2965643,2171019,2215936,2650112,2965504,2215936,0,0,2171166,2650398,2965790,2171166,2551947,2171019,2551808,2215936,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,144,45,45,67,67,67,67,67,228,67,67,67,67,67,67,67,67,67,1929,97,97,97,97,0,0,0,2552094,2171166,2171019,2215936,0,2171166,2171019,2215936,0,2171166,2171019,2215936,0,2171166,2977931,2977792,2978078,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,1321,97,131072,0,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,24,24,0,28,28,0,140,0,2379776,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2445312,2170880,2465792,2473984,2170880,2170880,2170880,2584576,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2170880,2170880,2170880,3162112,2170880,2170880,3182592,3186688,2170880,0,140,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3002368,2170880,2170880,2215936,2215936,2494464,2215936,2215936,2215936,2215936,2215936,2215936,3215360,544,0,0,0,544,0,546,0,0,0,546,0,0,2183168,0,0,552,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,0,2170880,2170880,2170880,0,2170880,2920448,2170880,2170880,2170880,2990080,2170880,2170880,552,0,0,0,552,0,287,0,2170880,2170880,2170880,2170880,2170880,2437120,2170880,2170880,18,0,0,0,0,0,0,0,0,2220032,0,0,644,0,2215936,2215936,3170304,544,0,546,0,552,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3198976,2170880,0,0,0,140,0,0,53264,18,49172,57366,24,8192,28,102432,249856,110630,114730,106539,0,0,32768,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,151640,53264,18,18,49172,0,57366,0,24,24,24,0,28,28,28,28,0,0,0,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2416640,53264,18,49172,57366,24,8192,28,102432,253952,110630,114730,106539,0,0,32856,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,192512,53264,18,18,49172,0,57366,0,2232445,184320,2232445,0,2240641,2240641,184320,2240641,102432,0,0,0,221184,2220032,110630,0,0,0,114730,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3108864,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,0,0,0,45056,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,24,24,0,127,127,53264,18,49172,258071,24,8192,28,102432,0,110630,114730,106539,0,0,32768,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,204800,53264,18,49172,57366,24,27,28,102432,0,110630,114730,106539,0,0,0,53264,18,49172,57366,24,8192,28,33,0,33,33,33,0,0,0,53264,18,18,49172,0,57366,0,24,24,24,16384,28,28,28,28,0,0,0,0,0,0,0,0,0,0,139,2170880,2170880,2170880,2416640,67,67,37139,37139,24853,24853,0,70179,0,0,0,65820,65820,369,287,97,0,0,97,97,0,97,97,97,45,2030,45,45,45,45,67,1573,67,67,67,67,67,67,67,67,67,67,67,1699,67,67,67,67,25403,546,70179,0,0,66365,66365,552,0,97,97,97,97,97,97,97,97,1355,97,97,97,1358,97,97,97,641,0,0,0,925,41606,0,0,0,0,45,45,45,45,45,45,45,1187,45,45,45,45,45,0,1480,0,0,0,0,1319,0,97,97,97,97,97,97,97,97,97,592,97,97,97,97,97,97,97,97,97,97,1531,45,45,45,45,45,45,45,45,45,45,45,45,1680,45,45,45,641,0,924,0,925,41606,0,0,0,0,45,45,45,45,45,45,1186,45,45,45,45,45,45,67,67,37139,37139,24853,24853,0,70179,282,0,0,65820,65820,369,287,97,0,0,97,97,0,97,2028,97,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,1767,67,67,67,0,0,0,0,0,0,1612,97,97,97,97,97,97,0,1785,97,97,97,97,97,97,0,0,97,97,97,97,1790,97,0,0,2170880,2170880,3051520,2170880,2170880,2170880,2170880,2170880,2170880,3170304,241664,2387968,2392064,2170880,2170880,2433024,53264,19,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,274432,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,270336,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,1134711,53264,18,49172,57366,24,8192,28,102432,0,1126440,1126440,1126440,0,0,1126400,53264,18,49172,57366,24,8192,28,102432,36,110630,114730,106539,0,0,217088,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,94,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,96,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,24666,53264,18,18,49172,0,57366,0,24,24,24,126,28,28,28,28,102432,53264,122,123,49172,0,57366,0,24,24,24,0,28,28,28,28,102432,2170880,2170880,4256099,0,0,0,0,0,0,0,0,2220032,0,0,0,0,0,0,0,0,1319,0,0,0,0,97,97,97,97,97,97,97,1109,97,97,97,97,1113,132,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,146,150,45,45,45,45,45,175,45,180,45,186,45,189,45,45,203,67,256,67,67,270,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,97,293,297,97,97,97,97,97,322,97,327,97,333,97,0,0,97,2026,0,2027,97,97,45,45,45,45,45,45,67,67,67,1685,67,67,67,67,67,67,67,1690,67,336,97,97,350,97,97,0,53264,0,18,18,24,24,356,28,28,0,0,0,0,0,0,0,0,0,0,140,2170880,2170880,2170880,2416640,2424832,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2617344,2170880,45,439,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,525,67,67,67,67,67,67,67,67,67,67,67,0,0,0,0,0,0,0,0,0,0,0,0,97,97,97,97,622,97,97,97,97,97,97,97,97,97,97,97,97,1524,97,97,1527,369,648,45,45,45,45,45,45,45,45,45,659,45,45,45,45,408,45,45,45,45,45,45,45,45,45,45,45,1239,45,45,45,67,729,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,762,67,746,67,67,67,67,67,67,67,67,67,759,67,67,67,67,0,0,0,1477,0,1086,0,0,0,1479,0,1090,67,67,796,67,67,799,67,67,67,67,67,67,67,67,67,67,67,67,1291,67,67,67,811,67,67,67,67,67,816,67,67,67,67,67,67,67,37689,544,25403,546,70179,0,0,66365,66365,552,833,97,97,97,97,97,97,97,97,1380,0,0,0,45,45,45,45,45,1185,45,45,45,45,45,45,45,386,45,45,45,45,45,45,45,45,1810,45,45,45,45,45,45,67,97,97,844,97,97,97,97,97,97,97,97,97,857,97,97,97,0,97,97,97,0,97,97,97,97,97,97,97,97,97,97,45,45,45,97,97,97,894,97,97,897,97,97,97,97,97,97,97,97,97,0,0,0,1382,45,45,45,97,909,97,97,97,97,97,914,97,97,97,97,97,97,97,923,67,67,1079,67,67,67,67,67,37689,1085,25403,1089,66365,1093,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,148,1114,97,97,97,97,97,97,1122,97,97,97,97,97,97,97,97,97,606,97,97,97,97,97,97,97,97,97,97,1173,97,97,97,97,97,12288,0,925,0,1179,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,145,45,45,67,67,67,67,67,1762,67,67,67,1766,67,67,67,67,67,67,528,67,67,67,67,67,67,67,67,67,97,97,97,97,97,0,1934,67,67,1255,67,67,67,67,67,67,67,67,67,67,67,67,67,1035,67,67,67,67,67,67,1297,67,67,67,67,67,67,0,0,0,0,0,0,97,97,97,97,97,97,97,97,97,97,1111,97,97,97,97,97,97,1327,97,97,97,97,97,97,97,97,97,97,97,97,33344,97,97,97,1335,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,0,97,97,1377,97,97,97,97,97,97,0,1179,0,45,45,45,45,670,45,45,45,45,45,45,45,45,45,45,45,430,45,45,45,45,67,67,1438,67,67,1442,67,67,67,67,67,67,67,67,67,67,67,67,1592,67,67,67,1451,67,67,67,67,67,67,67,67,67,67,1458,67,67,67,67,0,0,1305,0,0,0,0,0,1311,0,0,0,1317,0,0,0,0,0,0,0,97,97,1322,97,97,1491,97,97,1495,97,97,97,97,97,97,97,97,97,97,0,45,45,45,45,45,45,45,45,45,45,45,45,1551,45,1553,45,1504,97,97,97,97,97,97,97,97,97,97,1513,97,97,97,97,0,45,45,45,45,1536,45,45,45,45,1540,45,67,67,67,67,67,1585,67,67,67,67,67,67,67,67,67,67,67,67,1700,67,67,67,97,1648,97,97,97,97,97,97,97,97,0,45,45,45,45,45,45,45,45,45,45,1541,0,97,97,97,97,0,1940,0,97,97,97,97,97,97,45,45,2011,45,45,45,2015,67,67,2017,67,67,67,2021,97,67,67,812,67,67,67,67,67,67,67,67,67,67,67,37689,544,97,97,97,910,97,97,97,97,97,97,97,97,97,97,97,923,0,0,0,45,45,45,45,1184,45,45,45,45,1188,45,45,45,45,1414,45,45,45,1417,45,1419,45,45,45,45,45,443,45,45,45,45,45,45,453,45,45,67,67,67,67,1244,67,67,67,67,1248,67,67,67,67,67,67,67,0,37139,24853,0,0,0,282,41098,65820,97,1324,97,97,97,97,1328,97,97,97,97,97,97,97,97,97,0,0,930,45,45,45,45,97,97,97,97,1378,97,97,97,97,0,1179,0,45,45,45,45,671,45,45,45,45,45,45,45,45,45,45,45,975,45,45,45,45,67,67,1923,67,1925,67,67,1927,67,97,97,97,97,97,0,0,97,97,97,97,1985,45,45,45,45,45,45,1560,45,45,45,45,45,45,45,45,45,946,45,45,950,45,45,45,0,97,97,97,1939,0,0,0,97,1943,97,97,1945,97,45,45,45,669,45,45,45,45,45,45,45,45,45,45,45,45,990,45,45,45,67,257,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,337,97,97,97,97,97,0,53264,0,18,18,24,24,356,28,28,0,0,0,0,0,0,0,0,0,0,370,2170880,2170880,2170880,2416640,401,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,459,461,67,67,67,67,67,67,67,67,475,67,480,67,67,67,67,67,67,1054,67,67,67,67,67,67,67,67,67,67,1698,67,67,67,67,67,484,67,67,487,67,67,67,67,67,67,67,67,67,67,67,67,67,1459,67,67,97,556,558,97,97,97,97,97,97,97,97,572,97,577,97,97,0,0,1896,97,97,97,97,97,97,1903,45,45,45,45,983,45,45,45,45,988,45,45,45,45,45,45,1195,45,45,45,45,45,45,45,45,45,45,1549,45,45,45,45,45,581,97,97,584,97,97,97,97,97,97,97,97,97,97,97,97,97,1153,97,97,369,0,45,45,45,45,45,45,45,45,45,45,45,662,45,45,45,684,45,45,45,45,45,45,45,45,45,45,45,45,1004,45,45,45,67,67,67,749,67,67,67,67,67,67,67,67,67,761,67,67,67,67,67,67,1068,67,67,67,1071,67,67,67,67,1076,794,795,67,67,67,67,67,67,67,67,67,67,67,67,67,67,0,544,97,97,97,97,847,97,97,97,97,97,97,97,97,97,859,97,0,0,2025,97,20480,97,97,2029,45,45,45,45,45,45,67,67,67,1575,67,67,67,67,67,67,67,67,67,1775,67,67,67,97,97,97,97,892,893,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1515,97,993,994,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,992,67,67,67,1284,67,67,67,67,67,67,67,67,67,67,67,67,67,1607,67,67,97,1364,97,97,97,97,97,97,97,97,97,97,97,97,97,97,596,97,45,1556,1557,45,45,45,45,45,45,45,45,45,45,45,45,45,45,696,45,1596,1597,67,67,67,67,67,67,67,67,67,67,67,67,67,67,499,67,97,97,97,1621,97,97,97,97,97,97,97,97,97,97,97,97,97,1346,97,97,97,97,1740,97,97,97,97,45,45,45,45,45,45,45,45,45,45,1678,45,45,45,45,45,67,97,97,97,97,97,97,1836,0,97,97,97,97,97,0,0,97,97,97,1984,97,45,45,45,45,45,45,1808,45,45,45,45,45,45,45,45,67,739,67,67,67,67,67,744,45,45,1909,45,45,45,45,45,45,45,67,1917,67,1918,67,67,67,67,67,67,1247,67,67,67,67,67,67,67,67,67,67,532,67,67,67,67,67,67,1922,67,67,67,67,67,67,67,97,1930,97,1931,97,0,0,97,97,0,97,97,97,45,45,45,45,45,45,67,67,67,67,1576,67,67,67,67,1580,67,67,0,97,97,1938,97,0,0,0,97,97,97,97,97,97,45,45,45,699,45,45,45,704,45,45,45,45,45,45,45,45,987,45,45,45,45,45,45,45,67,67,97,97,97,97,0,0,97,97,97,2006,97,97,97,97,0,45,1533,45,45,45,45,45,45,45,45,45,1416,45,45,45,45,45,45,45,45,722,723,45,45,45,45,45,45,2045,67,67,67,2047,0,0,97,97,97,2051,45,45,67,67,0,0,0,0,925,41606,0,0,0,0,45,45,45,45,45,45,409,45,45,45,45,45,45,45,45,45,1957,45,67,67,67,67,67,1836,97,97,45,67,0,97,45,67,0,97,45,67,0,97,45,45,67,67,67,1761,67,67,67,1764,67,67,67,67,67,67,67,494,67,67,67,67,67,67,67,67,67,787,67,67,67,67,67,67,45,45,420,45,45,422,45,45,425,45,45,45,45,45,45,45,387,45,45,45,45,397,45,45,45,67,460,67,67,67,67,67,67,67,67,67,67,67,67,67,67,515,67,485,67,67,67,67,67,67,67,67,67,67,67,67,67,498,67,67,67,67,67,97,0,2039,97,97,97,97,97,45,45,45,45,1426,45,45,45,67,67,67,67,67,67,67,67,67,1689,67,67,67,97,557,97,97,97,97,97,97,97,97,97,97,97,97,97,97,612,97,582,97,97,97,97,97,97,97,97,97,97,97,97,97,595,97,97,97,97,97,896,97,97,97,97,97,97,97,97,97,97,885,97,97,97,97,97,45,939,45,45,45,45,943,45,45,45,45,45,45,45,45,45,45,1916,67,67,67,67,67,45,67,67,67,67,67,67,67,1015,67,67,67,67,1019,67,67,67,67,67,67,1271,67,67,67,67,67,67,1277,67,67,67,67,67,67,1287,67,67,67,67,67,67,67,67,67,67,804,67,67,67,67,67,1077,67,67,67,67,67,67,67,37689,0,25403,0,66365,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2437120,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2543616,2170880,2170880,2170880,2170880,2170880,2629632,1169,97,1171,97,97,97,97,97,97,97,12288,0,925,0,1179,0,0,0,0,925,41606,0,0,0,0,45,45,45,45,936,45,45,67,67,214,67,220,67,67,233,67,243,67,248,67,67,67,67,67,67,1298,67,67,67,67,0,0,0,0,0,0,97,97,97,97,97,1617,97,0,0,0,45,45,45,1183,45,45,45,45,45,45,45,45,45,393,45,45,45,45,45,45,67,67,1243,67,67,67,67,67,67,67,67,67,67,67,67,67,1074,67,67,1281,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,776,1323,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,907,45,1412,45,45,45,45,45,45,45,1418,45,45,45,45,45,45,686,45,45,45,690,45,45,695,45,45,67,67,67,67,67,1465,67,67,67,67,67,67,67,67,67,67,67,97,97,97,1712,97,97,97,97,1741,97,97,97,45,45,45,45,45,45,45,45,45,426,45,45,45,45,45,45,67,67,67,1924,67,67,67,67,67,97,97,97,97,97,0,0,97,97,1983,97,97,45,45,1987,45,1988,45,0,97,97,97,97,0,0,0,1942,97,97,97,97,97,45,45,45,700,45,45,45,45,45,45,45,45,45,45,711,45,45,153,45,45,166,45,176,45,181,45,45,188,191,196,45,204,255,258,263,67,271,67,67,0,37139,24853,0,0,0,282,41098,65820,97,97,97,294,97,300,97,97,313,97,323,97,328,97,97,335,338,343,97,351,97,97,0,53264,0,18,18,24,24,356,28,28,0,0,0,0,0,0,0,0,41098,0,140,45,45,45,45,1404,45,45,45,45,45,45,45,45,45,45,1411,67,67,486,67,67,67,67,67,67,67,67,67,67,67,67,67,1251,67,67,501,67,67,67,67,67,67,67,67,67,67,67,67,513,67,67,67,67,67,67,1443,67,67,67,67,67,67,67,67,67,67,1263,67,67,67,67,67,97,97,583,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1526,97,598,97,97,97,97,97,97,97,97,97,97,97,97,610,97,97,0,97,97,1796,97,97,97,97,97,97,97,45,45,45,45,45,1744,45,45,45,369,0,651,45,653,45,654,45,656,45,45,45,660,45,45,45,45,1558,45,45,45,45,45,45,45,45,1566,45,45,681,45,683,45,45,45,45,45,45,45,45,691,692,694,45,45,45,716,45,45,45,45,45,45,45,45,45,45,45,45,709,45,45,712,45,714,45,45,45,718,45,45,45,45,45,45,45,726,45,45,45,733,45,45,45,45,67,67,67,67,67,67,67,67,67,67,67,67,1691,67,67,747,67,67,67,67,67,67,67,67,67,760,67,67,67,0,0,0,0,0,0,97,1613,97,97,97,97,97,97,1509,97,97,97,97,97,97,97,97,97,0,1179,0,45,45,45,45,67,764,67,67,67,67,768,67,770,67,67,67,67,67,67,67,67,97,97,97,97,0,0,0,1977,67,778,779,781,67,67,67,67,67,67,788,789,67,67,792,793,67,67,67,813,67,67,67,67,67,67,67,67,67,824,37689,544,25403,546,70179,0,0,66365,66365,552,0,836,97,838,97,839,97,841,97,97,97,845,97,97,97,97,97,97,97,97,97,858,97,97,0,1728,97,97,97,0,97,97,97,97,97,97,97,97,97,97,45,1802,45,97,97,862,97,97,97,97,866,97,868,97,97,97,97,97,97,0,0,97,97,1788,97,97,97,0,0,97,97,876,877,879,97,97,97,97,97,97,886,887,97,97,890,891,97,97,97,97,97,97,97,899,97,97,97,903,97,97,97,0,97,97,97,0,97,97,97,97,97,97,97,1646,97,97,97,97,911,97,97,97,97,97,97,97,97,97,922,923,45,955,45,957,45,45,45,45,45,45,45,45,45,45,45,45,195,45,45,45,45,45,981,982,45,45,45,45,45,45,989,45,45,45,45,45,170,45,45,45,45,45,45,45,45,45,45,411,45,45,45,45,45,67,1023,67,67,67,67,67,67,1031,67,1033,67,67,67,67,67,67,67,817,819,67,67,67,67,67,37689,544,67,1065,67,67,67,67,67,67,67,67,67,67,67,67,67,67,516,67,67,1078,67,67,1081,1082,67,67,37689,0,25403,0,66365,0,0,0,0,0,0,0,0,2171166,2171166,2171166,2171166,2171166,2437406,2171166,2171166,97,1115,97,1117,97,97,97,97,97,97,1125,97,1127,97,97,97,0,97,97,97,0,97,97,97,97,1644,97,97,97,0,97,97,97,0,97,97,1642,97,97,97,97,97,97,625,97,97,97,97,97,97,97,97,97,316,97,97,97,97,97,97,97,97,97,1159,97,97,97,97,97,97,97,97,97,97,97,97,97,1502,97,97,97,97,97,1172,97,97,1175,1176,97,97,12288,0,925,0,1179,0,0,0,0,925,41606,0,0,0,0,45,45,45,935,45,45,45,1233,45,45,45,1236,45,45,45,45,45,45,45,67,67,67,67,67,67,1873,67,67,45,45,1218,45,45,45,1223,45,45,45,45,45,45,45,1230,45,45,67,67,215,219,222,67,230,67,67,244,246,249,67,67,67,67,67,67,1882,97,97,97,97,0,0,0,97,97,97,97,97,97,45,1904,45,1905,45,67,67,67,67,67,1258,67,1260,67,67,67,67,67,67,67,67,67,495,67,67,67,67,67,67,67,67,1283,67,67,67,67,67,67,67,1290,67,67,67,67,67,67,67,818,67,67,67,67,67,67,37689,544,67,67,1295,67,67,67,67,67,67,67,67,0,0,0,0,0,0,2174976,0,0,97,97,97,1326,97,97,97,97,97,97,97,97,97,97,97,97,97,1514,97,97,97,97,97,1338,97,1340,97,97,97,97,97,97,97,97,97,97,97,1500,97,97,1503,97,1363,97,97,97,97,97,97,97,1370,97,97,97,97,97,97,97,563,97,97,97,97,97,97,578,97,1375,97,97,97,97,97,97,97,97,0,1179,0,45,45,45,45,685,45,45,45,45,45,45,45,45,45,45,45,1003,45,45,45,45,67,67,67,1463,67,67,67,67,67,67,67,67,67,67,67,67,67,1778,97,97,97,97,97,1518,97,97,97,97,97,97,97,97,97,97,97,97,609,97,97,97,45,1542,45,45,45,45,45,45,45,1548,45,45,45,45,45,1554,45,1570,1571,45,67,67,67,67,67,67,1578,67,67,67,67,67,67,67,1055,67,67,67,67,67,1061,67,67,1582,67,67,67,67,67,67,67,1588,67,67,67,67,67,1594,67,67,67,67,67,97,2038,0,97,97,97,97,97,2044,45,45,45,995,45,45,45,45,1e3,45,45,45,45,45,45,45,1809,45,1811,45,45,45,45,45,67,1610,1611,67,1476,0,1478,0,1480,0,97,97,97,97,97,97,1618,1647,1649,97,97,97,1652,97,1654,1655,97,0,45,45,45,1658,45,45,67,67,216,67,67,67,67,234,67,67,67,67,252,254,1845,97,97,97,97,97,97,97,45,45,45,45,45,45,45,45,945,45,947,45,45,45,45,45,67,67,67,67,67,1881,97,97,97,97,97,0,0,0,97,97,97,97,97,1902,45,45,45,45,45,45,1908,45,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,1921,67,67,67,67,67,67,67,67,97,97,97,97,97,0,0,0,97,97,0,97,1937,97,97,1940,0,0,97,97,97,97,97,97,1947,1948,1949,45,45,45,1952,45,1954,45,45,45,45,1959,1960,1961,67,67,67,67,67,67,1455,67,67,67,67,67,67,67,67,67,67,757,67,67,67,67,67,67,1964,67,1966,67,67,67,67,1971,1972,1973,97,0,0,0,97,97,1104,97,97,97,97,97,97,97,97,97,97,884,97,97,97,889,97,97,1978,97,0,0,1981,97,97,97,97,45,45,45,45,45,45,736,45,67,67,67,67,67,67,67,67,67,67,67,1018,67,67,67,45,67,67,67,67,0,2049,97,97,97,97,45,45,67,67,0,0,0,0,925,41606,0,0,0,0,45,933,45,45,45,45,1234,45,45,45,45,45,45,45,45,45,45,67,97,97,288,97,97,97,97,97,97,317,97,97,97,97,97,97,0,0,97,1787,97,97,97,97,0,0,45,45,378,45,45,45,45,45,390,45,45,45,45,45,45,45,424,45,45,45,431,433,45,45,45,67,1050,67,67,67,67,67,67,67,67,67,67,67,67,67,67,518,67,97,97,97,1144,97,97,97,97,97,97,97,97,97,97,97,97,632,97,97,97,97,97,97,97,1367,97,97,97,97,97,97,97,97,97,97,97,855,97,97,97,97,67,97,97,97,97,97,97,1837,0,97,97,97,97,97,0,0,0,1897,97,97,97,97,97,45,45,45,45,45,1208,45,45,45,45,45,45,45,45,45,45,724,45,45,45,45,45,97,2010,45,45,45,45,45,45,2016,67,67,67,67,67,67,2022,45,2046,67,67,67,0,0,2050,97,97,97,45,45,67,67,0,0,0,0,925,41606,0,0,0,0,932,45,45,45,45,45,1222,45,45,45,45,45,45,45,45,45,45,1227,45,45,45,45,45,133,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,45,701,702,45,45,705,706,45,45,45,45,45,45,703,45,45,45,45,45,45,45,45,45,719,45,45,45,45,45,725,45,45,45,369,649,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1216,25403,546,70179,0,0,66365,66365,552,834,97,97,97,97,97,97,97,1342,97,97,97,97,97,97,97,97,0,97,97,97,97,97,97,97,1799,97,97,45,45,45,1569,45,45,45,1572,67,67,67,67,67,67,67,67,67,67,67,0,0,0,1306,0,67,67,67,1598,67,67,67,67,67,67,67,67,1606,67,67,1609,97,97,97,1650,97,97,1653,97,97,97,0,45,45,1657,45,45,45,1206,45,45,45,45,45,45,45,45,45,45,45,45,1421,45,45,45,1703,67,67,67,67,67,67,67,67,67,67,97,97,1711,97,97,0,1895,0,97,97,97,97,97,97,45,45,45,45,45,958,45,960,45,45,45,45,45,45,45,45,1913,45,45,1915,67,67,67,67,67,67,67,466,67,67,67,67,67,67,481,67,45,1749,45,45,45,45,45,45,45,45,1755,45,45,45,45,45,173,45,45,45,45,45,45,45,45,45,45,974,45,45,45,45,45,67,67,67,67,67,1773,67,67,67,67,67,67,67,97,97,97,97,1886,0,0,0,97,97,67,2035,2036,67,67,97,0,0,97,2041,2042,97,97,45,45,45,45,1662,45,45,45,45,45,45,45,45,45,45,45,1397,45,45,45,45,151,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,437,205,45,67,67,67,218,67,67,67,67,67,67,67,67,67,67,67,1047,67,67,67,67,97,97,97,97,298,97,97,97,97,97,97,97,97,97,97,97,870,97,97,97,97,97,97,97,97,352,97,0,53264,0,18,18,24,24,0,28,28,0,0,0,0,0,0,365,0,41098,0,140,45,45,45,45,45,1427,45,45,67,67,67,67,67,67,67,1435,520,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1037,617,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,923,45,1232,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,67,67,1919,67,1759,45,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1021,45,154,45,162,45,45,45,45,45,45,45,45,45,45,45,45,964,45,45,45,206,45,67,67,67,67,221,67,229,67,67,67,67,67,67,67,67,530,67,67,67,67,67,67,67,67,755,67,67,67,67,67,67,67,67,785,67,67,67,67,67,67,67,67,802,67,67,67,807,67,67,67,97,97,97,97,353,97,0,53264,0,18,18,24,24,0,28,28,0,0,0,0,0,0,366,0,0,0,140,2170880,2170880,2170880,2416640,402,45,45,45,45,45,45,45,410,45,45,45,45,45,45,45,674,45,45,45,45,45,45,45,45,389,45,394,45,45,398,45,45,45,45,441,45,45,45,45,45,447,45,45,45,454,45,45,67,67,67,67,67,67,67,67,67,67,67,1768,67,67,67,67,67,488,67,67,67,67,67,67,67,496,67,67,67,67,67,67,67,1774,67,67,67,67,67,97,97,97,97,0,0,97,97,97,0,97,97,97,97,97,97,97,97,67,67,523,67,67,527,67,67,67,67,67,533,67,67,67,540,97,97,97,585,97,97,97,97,97,97,97,593,97,97,97,97,97,97,1784,0,97,97,97,97,97,97,0,0,97,97,97,97,97,97,0,0,0,18,18,24,24,0,28,28,97,97,620,97,97,624,97,97,97,97,97,630,97,97,97,637,713,45,45,45,45,45,45,721,45,45,45,45,45,45,45,45,1197,45,45,45,45,45,45,45,45,730,732,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,1581,67,45,67,67,67,67,1012,67,67,67,67,67,67,67,67,67,67,67,1059,67,67,67,67,67,1024,67,67,67,67,67,67,67,67,67,67,67,67,67,67,775,67,67,67,67,1066,67,67,67,67,67,67,67,67,67,67,67,67,479,67,67,67,67,67,67,1080,67,67,67,67,37689,0,25403,0,66365,0,0,0,0,0,0,0,287,0,0,0,287,0,2379776,2170880,2170880,97,97,97,1118,97,97,97,97,97,97,97,97,97,97,97,97,920,97,97,0,0,0,0,45,1181,45,45,45,45,45,45,45,45,45,45,45,432,45,45,45,45,45,45,1219,45,45,45,45,45,45,1226,45,45,45,45,45,45,959,45,45,45,45,45,45,45,45,45,184,45,45,45,45,202,45,1241,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1266,67,1268,67,67,67,67,67,67,67,67,67,67,67,67,1279,67,67,67,67,67,272,67,0,37139,24853,0,0,0,0,41098,65820,67,67,67,67,67,1286,67,67,67,67,67,67,67,67,67,1293,67,67,67,1296,67,67,67,67,67,67,67,0,0,0,0,0,281,94,0,0,97,97,97,1366,97,97,97,97,97,97,97,97,97,1373,97,97,18,0,139621,0,0,0,0,0,0,364,0,0,367,0,97,1376,97,97,97,97,97,97,97,0,0,0,45,45,1384,45,45,67,208,67,67,67,67,67,67,237,67,67,67,67,67,67,67,1069,1070,67,67,67,67,67,67,67,0,37140,24854,0,0,0,0,41098,65821,45,1423,45,45,45,45,45,45,67,67,1431,67,67,67,67,67,67,67,1083,37689,0,25403,0,66365,0,0,0,1436,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1830,67,1452,1453,67,67,67,67,1456,67,67,67,67,67,67,67,67,67,771,67,67,67,67,67,67,1461,67,67,67,1464,67,1466,67,67,67,67,67,67,1470,67,67,67,67,67,67,1587,67,67,67,67,67,67,67,67,1595,1489,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1129,97,1505,1506,97,97,97,97,1510,97,97,97,97,97,97,97,97,97,1163,1164,97,97,97,97,97,1516,97,97,97,1519,97,1521,97,97,97,97,97,97,1525,97,97,18,0,139621,0,0,0,0,0,0,364,0,0,367,41606,67,67,67,67,67,1586,67,67,67,67,67,67,67,67,67,67,67,1276,67,67,67,67,67,67,67,67,67,1600,67,67,67,67,67,67,67,67,67,67,67,1301,0,0,0,1307,97,97,1620,97,97,97,97,97,97,97,1627,97,97,97,97,97,97,913,97,97,97,97,919,97,97,97,0,97,97,97,1781,97,97,0,0,97,97,97,97,97,97,0,0,97,97,97,97,97,97,0,1792,1860,45,1862,1863,45,1865,45,67,67,67,67,67,67,67,67,1875,67,1877,1878,67,1880,67,97,97,97,97,97,1887,0,1889,97,97,18,0,139621,0,0,0,0,0,0,364,237568,0,367,0,97,1893,0,0,0,97,1898,1899,97,1901,97,45,45,45,45,45,2014,45,67,67,67,67,67,2020,67,97,1989,45,1990,45,45,45,67,67,67,67,67,67,1996,67,1997,67,67,67,67,67,273,67,0,37139,24853,0,0,0,0,41098,65820,67,67,97,97,97,97,0,0,97,97,2005,0,97,2007,97,97,18,0,139621,0,0,0,642,0,133,364,0,0,367,41606,0,97,97,2056,2057,0,2059,45,67,0,97,45,67,0,97,45,45,67,209,67,67,67,223,67,67,67,67,67,67,67,67,67,786,67,67,67,791,67,67,45,45,940,45,45,45,45,45,45,45,45,45,45,45,45,45,45,727,45,45,67,67,67,67,67,67,67,67,1016,67,67,67,67,67,67,67,67,37689,0,25403,0,66365,0,0,0,133,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,142,45,45,67,210,67,67,67,225,67,67,239,67,67,67,250,67,67,67,67,67,464,67,67,67,67,67,476,67,67,67,67,67,67,67,1709,67,67,67,97,97,97,97,97,97,0,0,97,97,97,97,97,1843,0,67,259,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,289,97,97,97,303,97,97,97,97,97,97,97,97,97,97,901,97,97,97,97,97,339,97,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,0,358,0,0,0,0,0,0,41098,0,140,45,45,45,45,45,1953,45,1955,45,45,45,67,67,67,67,67,67,67,1687,1688,67,67,67,67,45,45,405,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1203,45,458,67,67,67,67,67,67,67,67,67,470,477,67,67,67,67,67,67,67,1970,97,97,97,1974,0,0,0,97,1103,97,97,97,97,97,97,97,97,97,97,97,1372,97,97,97,97,67,522,67,67,67,67,67,67,67,67,67,67,67,536,67,67,67,67,67,67,1696,67,67,67,67,67,67,67,1701,67,555,97,97,97,97,97,97,97,97,97,567,574,97,97,97,97,97,301,97,309,97,97,97,97,97,97,97,97,97,900,97,97,97,905,97,97,97,619,97,97,97,97,97,97,97,97,97,97,97,633,97,97,18,0,139621,0,0,362,0,0,0,364,0,0,367,41606,369,649,45,45,45,45,45,45,45,45,45,45,45,45,663,664,67,67,67,67,750,751,67,67,67,67,758,67,67,67,67,67,67,67,1272,67,67,67,67,67,67,67,67,67,1057,1058,67,67,67,67,67,67,67,67,797,67,67,67,67,67,67,67,67,67,67,67,67,512,67,67,67,97,97,97,97,895,97,97,97,97,97,97,97,97,97,97,97,902,97,97,97,97,67,67,1051,67,67,67,67,67,67,67,67,67,67,67,1062,67,67,67,67,67,491,67,67,67,67,67,67,67,67,67,67,67,1302,0,0,0,1308,97,97,97,97,1145,97,97,97,97,97,97,97,97,97,97,97,1139,97,97,97,97,1156,97,97,97,97,97,97,1161,97,97,97,97,97,1166,97,97,18,640,139621,0,641,0,0,0,0,364,0,0,367,41606,67,67,67,67,1257,67,67,67,67,67,67,67,67,67,67,67,0,0,1305,0,0,97,97,1337,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1630,97,67,1474,67,67,0,0,0,0,0,0,0,0,0,0,0,0,0,2380062,2171166,2171166,97,1529,97,97,0,45,45,45,45,45,45,45,45,45,45,45,1228,45,45,45,45,67,67,67,67,1707,67,67,67,67,67,67,97,97,97,97,97,0,0,0,97,1891,1739,97,97,97,97,97,97,45,45,45,45,45,45,45,45,45,1198,45,1200,45,45,45,45,97,97,1894,0,0,97,97,97,97,97,97,45,45,45,45,45,672,45,45,45,45,45,45,45,45,45,45,45,1420,45,45,45,45,67,67,1965,67,1967,67,67,67,97,97,97,97,0,1976,0,97,97,45,67,0,97,45,67,0,97,45,67,0,97,45,97,97,1979,0,0,97,1982,97,97,97,1986,45,45,45,45,45,735,45,45,67,67,67,67,67,67,67,67,67,67,67,67,67,1770,67,67,2e3,97,97,97,2002,0,97,97,97,0,97,97,97,97,97,97,1798,97,97,97,45,45,45,2034,67,67,67,67,97,0,0,2040,97,97,97,97,45,45,45,45,1752,45,45,45,1753,1754,45,45,45,45,45,45,383,45,45,45,45,45,45,45,45,45,675,45,45,45,45,45,45,438,45,45,45,45,45,445,45,45,45,45,45,45,45,45,67,1430,67,67,67,67,67,67,67,67,67,524,67,67,67,67,67,531,67,67,67,67,67,67,67,67,37689,0,25403,0,66365,0,0,1096,97,97,97,621,97,97,97,97,97,628,97,97,97,97,97,97,0,53264,0,18,18,24,24,356,28,28,665,45,45,45,45,45,45,45,45,45,676,45,45,45,45,45,942,45,45,45,45,45,45,45,45,45,45,707,708,45,45,45,45,763,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,809,810,67,67,67,67,783,67,67,67,67,67,67,67,67,67,67,67,0,1303,0,0,0,97,861,97,97,97,97,97,97,97,97,97,97,97,97,97,97,613,97,45,45,956,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1215,45,67,67,67,67,1027,67,67,67,67,1032,67,67,67,67,67,67,67,67,37689,0,25403,0,66365,0,0,1097,1064,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1075,67,1098,0,0,97,97,97,97,97,97,97,97,97,97,97,97,97,331,97,97,97,97,1158,97,97,97,97,97,97,97,97,97,97,97,97,97,594,97,97,1309,0,0,0,1315,0,0,0,0,0,0,0,0,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1374,97,45,45,1543,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1240,67,67,1583,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1252,67,97,97,97,1635,97,97,97,0,97,97,97,97,97,97,97,97,1800,97,45,45,45,97,97,1793,97,97,97,97,97,97,97,97,97,97,45,45,45,1743,45,45,45,1746,45,0,97,97,97,97,97,1851,97,45,45,45,45,1856,45,45,45,45,1864,45,45,67,67,1869,67,67,67,67,1874,67,0,97,97,45,67,2058,97,45,67,0,97,45,67,0,97,45,45,67,211,67,67,67,67,67,67,240,67,67,67,67,67,67,67,1444,67,67,67,67,67,67,67,67,67,509,67,67,67,67,67,67,67,67,67,268,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,290,97,97,97,305,97,97,319,97,97,97,330,97,97,18,640,139621,0,641,0,0,0,0,364,0,643,367,41606,97,97,348,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,0,364,0,367,41098,369,140,45,45,45,45,380,45,45,45,45,45,45,395,45,45,45,400,369,0,45,45,45,45,45,45,45,45,658,45,45,45,45,45,972,45,45,45,45,45,45,45,45,45,45,427,45,45,45,45,45,745,67,67,67,67,67,67,67,67,756,67,67,67,67,67,67,67,67,37689,1086,25403,1090,66365,1094,0,0,97,843,97,97,97,97,97,97,97,97,854,97,97,97,97,97,97,1121,97,97,97,97,1126,97,97,97,97,45,980,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1400,45,67,67,67,1011,67,67,67,67,67,67,67,67,67,67,67,0,1304,0,0,0,1190,45,45,1193,1194,45,45,45,45,45,1199,45,1201,45,45,45,45,1911,45,45,45,45,45,67,67,67,67,67,67,67,1579,67,67,67,67,45,1205,45,45,45,45,45,45,45,45,1211,45,45,45,45,45,984,45,45,45,45,45,45,45,45,45,45,45,1550,45,45,45,45,45,1217,45,45,45,45,45,45,1225,45,45,45,45,1229,45,45,45,1388,45,45,45,45,45,45,1396,45,45,45,45,45,444,45,45,45,45,45,45,45,45,45,67,67,1574,67,67,67,67,67,67,67,67,67,67,1590,67,67,67,67,67,1254,67,67,67,67,67,1259,67,1261,67,67,67,67,1265,67,67,67,67,67,67,1708,67,67,67,67,97,97,97,97,97,97,0,0,97,97,97,97,97,0,0,67,67,67,67,1285,67,67,67,67,1289,67,67,67,67,67,67,67,67,37689,1087,25403,1091,66365,1095,0,0,97,97,97,97,1339,97,1341,97,97,97,97,1345,97,97,97,97,97,561,97,97,97,97,97,573,97,97,97,97,97,97,1717,97,0,97,97,97,97,97,97,97,591,97,97,97,97,97,97,97,97,97,1329,97,97,97,97,97,97,97,97,97,97,1351,97,97,97,97,97,97,1357,97,97,97,97,97,588,97,97,97,97,97,97,97,97,97,97,568,97,97,97,97,97,97,97,1365,97,97,97,97,1369,97,97,97,97,97,97,97,97,97,1356,97,97,97,97,97,97,45,45,1403,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1399,45,45,45,1413,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1669,45,1422,45,45,1425,45,45,1428,45,1429,67,67,67,67,67,67,67,67,1468,67,67,67,67,67,67,67,67,529,67,67,67,67,67,67,539,67,67,1475,67,0,0,0,0,0,0,0,0,0,0,0,0,140,2170880,2170880,2170880,2416640,97,97,1530,97,0,45,45,1534,45,45,45,45,45,45,45,45,1956,45,45,67,67,67,67,67,67,67,67,67,1599,67,67,1601,67,67,67,67,67,67,67,67,67,803,67,67,67,67,67,67,1632,97,1634,0,97,97,97,1640,97,97,97,1643,97,97,1645,97,97,97,97,97,912,97,97,97,97,97,97,97,97,97,0,0,0,45,45,45,45,45,45,1660,1661,45,45,45,45,1665,1666,45,45,45,45,45,1670,1692,1693,67,67,67,67,67,1697,67,67,67,67,67,67,67,1702,97,97,1714,1715,97,97,97,97,0,1721,1722,97,97,97,97,97,97,1353,97,97,97,97,97,97,97,97,1362,1726,97,0,0,97,97,97,0,97,97,97,1734,97,97,97,97,97,848,849,97,97,97,97,856,97,97,97,97,97,354,0,53264,0,18,18,24,24,0,28,28,45,45,1750,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1681,45,0,1846,97,97,97,97,97,97,45,45,1854,45,45,45,45,1859,67,67,67,1879,67,67,97,97,1884,97,97,0,0,0,97,97,97,1105,97,97,97,97,97,97,97,97,97,97,1344,97,97,97,1347,97,1892,97,0,0,0,97,97,97,1900,97,97,45,45,45,45,45,997,45,45,45,45,45,45,45,45,45,45,1002,45,45,1005,1006,45,67,67,67,67,67,1926,67,67,1928,97,97,97,97,97,0,0,97,97,97,0,97,97,97,97,97,97,1737,97,0,97,97,97,97,0,0,0,97,97,1944,97,97,1946,45,45,45,1544,45,45,45,45,45,45,45,45,45,45,45,45,190,45,45,45,152,155,45,163,45,45,177,179,182,45,45,45,193,197,45,45,45,1672,45,45,45,45,45,1677,45,1679,45,45,45,45,996,45,45,45,45,45,45,45,45,45,45,45,1212,45,45,45,45,67,260,264,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,97,295,299,302,97,310,97,97,324,326,329,97,97,97,0,97,97,1639,0,1641,97,97,97,97,97,97,97,97,1511,97,97,97,97,97,97,97,97,1523,97,97,97,97,97,97,97,97,1719,97,97,97,97,97,97,97,97,1720,97,97,97,97,97,97,97,312,97,97,97,97,97,97,97,97,1123,97,97,97,97,97,97,97,340,344,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,0,364,0,367,41098,369,140,45,45,373,375,419,45,45,45,45,45,45,45,45,45,428,45,45,435,45,45,45,1751,45,45,45,45,45,45,45,45,45,45,45,45,1410,45,45,45,67,67,67,505,67,67,67,67,67,67,67,67,67,514,67,67,67,67,67,67,1969,67,97,97,97,97,0,0,0,97,97,45,67,0,97,45,67,0,97,2064,2065,0,2066,45,521,67,67,67,67,67,67,67,67,67,67,534,67,67,67,67,67,67,465,67,67,67,474,67,67,67,67,67,67,67,1467,67,67,67,67,67,67,67,67,67,97,97,97,97,97,1933,0,97,97,97,602,97,97,97,97,97,97,97,97,97,611,97,97,18,640,139621,358,641,0,0,0,0,364,0,0,367,0,618,97,97,97,97,97,97,97,97,97,97,631,97,97,97,97,97,881,97,97,97,97,97,97,97,97,97,97,569,97,97,97,97,97,369,0,45,652,45,45,45,45,45,657,45,45,45,45,45,45,1235,45,45,45,45,45,45,45,45,67,67,67,1432,67,67,67,67,67,67,67,766,67,67,67,67,67,67,67,67,773,67,67,67,0,1305,0,1311,0,1317,97,97,97,97,97,97,97,1624,97,97,97,97,97,97,97,97,0,97,97,97,1724,97,97,97,777,67,67,782,67,67,67,67,67,67,67,67,67,67,67,67,535,67,67,67,67,67,67,67,814,67,67,67,67,67,67,67,67,67,37689,544,25403,546,70179,0,0,66365,66365,552,0,97,837,97,97,97,97,97,97,1496,97,97,97,97,97,97,97,97,97,97,918,97,97,97,97,0,842,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1168,97,97,97,97,864,97,97,97,97,97,97,97,97,871,97,97,97,0,1637,97,97,0,97,97,97,97,97,97,97,97,97,97,1801,45,45,97,875,97,97,880,97,97,97,97,97,97,97,97,97,97,97,1151,1152,97,97,97,67,67,67,1040,67,67,67,67,67,67,67,67,67,67,67,67,790,67,67,67,1180,0,649,45,45,45,45,45,45,45,45,45,45,45,45,45,200,45,45,67,67,67,1454,67,67,67,67,67,67,67,67,67,67,67,67,806,67,67,67,0,0,0,1481,0,1094,0,0,97,1483,97,97,97,97,97,97,304,97,97,318,97,97,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,97,97,97,1507,97,97,97,97,97,97,97,97,97,97,97,97,1332,97,97,97,1619,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1631,97,1633,97,0,97,97,97,0,97,97,97,97,97,97,97,97,97,1381,0,0,45,45,45,45,97,97,1727,0,97,97,97,0,97,97,97,97,97,97,97,97,626,97,97,97,97,97,97,636,45,45,1760,67,67,67,67,67,67,67,1765,67,67,67,67,67,67,67,1299,67,67,67,0,0,0,0,0,0,97,97,97,97,1616,97,97,1803,45,45,45,45,1807,45,45,45,45,45,1813,45,45,45,67,67,1684,67,67,67,67,67,67,67,67,67,67,67,822,67,67,37689,544,67,67,1818,67,67,67,67,1822,67,67,67,67,67,1828,67,67,67,67,67,97,0,0,97,97,97,97,97,45,45,45,2012,2013,45,45,67,67,67,2018,2019,67,67,97,67,97,97,97,1833,97,97,0,0,97,97,1840,97,97,0,0,97,97,97,0,97,97,1733,97,1735,97,97,97,0,97,97,97,1849,97,97,97,45,45,45,45,45,1857,45,45,45,1910,45,1912,45,45,1914,45,67,67,67,67,67,67,67,67,67,67,1017,67,67,1020,67,45,1861,45,45,45,45,45,67,67,67,67,67,1872,67,67,67,67,67,67,752,67,67,67,67,67,67,67,67,67,67,1446,67,67,67,67,67,1876,67,67,67,67,67,97,97,97,97,97,0,0,0,1890,97,97,97,97,97,1134,97,97,97,97,97,97,97,97,97,97,570,97,97,97,97,580,1935,97,97,97,97,0,0,0,97,97,97,97,97,97,45,45,45,45,1906,45,67,67,67,67,2048,0,97,97,97,97,45,45,67,67,0,0,0,0,925,41606,0,0,0,931,45,45,45,45,45,45,1674,45,1676,45,45,45,45,45,45,45,446,45,45,45,45,45,45,45,67,67,67,67,1871,67,67,67,67,0,97,97,45,67,0,97,2060,2061,0,2063,45,67,0,97,45,45,156,45,45,45,45,45,45,45,45,45,192,45,45,45,45,1673,45,45,45,45,45,45,45,45,45,45,45,429,45,45,45,45,67,67,67,269,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,349,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,0,364,0,367,41098,369,140,45,45,374,45,45,67,67,213,217,67,67,67,67,67,242,67,247,67,253,45,45,698,45,45,45,45,45,45,45,45,45,45,45,45,45,399,45,45,0,0,0,0,925,41606,0,929,0,0,45,45,45,45,45,45,1391,45,45,1395,45,45,45,45,45,45,423,45,45,45,45,45,45,45,436,45,67,67,67,67,1041,67,1043,67,67,67,67,67,67,67,67,67,67,1776,67,67,97,97,97,1099,0,0,97,97,97,97,97,97,97,97,97,97,97,97,97,888,97,97,97,1131,97,97,97,97,1135,97,1137,97,97,97,97,97,97,97,1497,97,97,97,97,97,97,97,97,97,883,97,97,97,97,97,97,1310,0,0,0,1316,0,0,0,0,1100,0,0,0,97,97,97,97,97,1107,97,97,97,97,97,97,97,97,1343,97,97,97,97,97,97,1348,0,0,1317,0,0,0,0,0,97,97,97,97,97,97,97,97,97,97,97,1112,97,45,1804,45,45,45,45,45,45,45,45,45,45,45,45,45,67,1868,67,1870,67,67,67,67,67,1817,67,67,1819,67,67,67,67,67,67,67,67,67,67,67,67,823,67,37689,544,67,97,1832,97,97,1834,97,0,0,97,97,97,97,97,0,0,97,97,97,0,1732,97,97,97,97,97,97,97,850,97,97,97,97,97,97,97,97,97,1177,0,0,925,0,0,0,0,97,97,97,97,0,0,1941,97,97,97,97,97,97,45,45,45,1991,1992,45,67,67,67,67,67,67,67,67,67,1998,134,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,45,941,45,45,944,45,45,45,45,45,45,952,45,45,207,67,67,67,67,67,226,67,67,67,67,67,67,67,67,67,820,67,67,67,67,37689,544,369,650,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1682,25403,546,70179,0,0,66365,66365,552,835,97,97,97,97,97,97,97,1522,97,97,97,97,97,97,97,97,0,97,97,97,97,97,97,1725,67,67,67,1695,67,67,67,67,67,67,67,67,67,67,67,67,1034,67,1036,67,67,67,265,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,97,296,97,97,97,97,314,97,97,97,97,332,334,97,97,97,97,97,1146,1147,97,97,97,97,97,97,97,97,97,97,1626,97,97,97,97,97,97,345,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,0,364,0,367,41098,369,140,45,372,45,45,45,1220,45,45,45,45,45,45,45,45,45,45,45,45,1213,45,45,45,45,404,406,45,45,45,45,45,45,45,45,45,45,45,45,45,434,45,45,45,440,45,45,45,45,45,45,45,45,451,452,45,45,45,67,1683,67,67,67,1686,67,67,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,67,67,67,67,490,492,67,67,67,67,67,67,67,67,67,67,67,1447,67,67,1450,67,67,67,67,67,526,67,67,67,67,67,67,67,67,537,538,67,67,67,67,67,506,67,67,508,67,67,511,67,67,67,67,0,1476,0,0,0,0,0,1478,0,0,0,0,0,0,0,0,97,97,1484,97,97,97,97,97,97,865,97,97,97,97,97,97,97,97,97,97,1499,97,97,97,97,97,97,97,97,97,587,589,97,97,97,97,97,97,97,97,97,97,629,97,97,97,97,97,97,97,97,97,623,97,97,97,97,97,97,97,97,634,635,97,97,97,97,97,1160,97,97,97,97,97,97,97,97,97,97,97,1628,97,97,97,97,369,0,45,45,45,45,45,655,45,45,45,45,45,45,45,45,999,45,1001,45,45,45,45,45,45,45,45,715,45,45,45,720,45,45,45,45,45,45,45,45,728,25403,546,70179,0,0,66365,66365,552,0,97,97,97,97,97,840,97,97,97,97,97,1174,97,97,97,97,0,0,925,0,0,0,0,0,0,0,1100,97,97,97,97,97,97,97,97,627,97,97,97,97,97,97,97,938,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,680,45,968,45,970,45,973,45,45,45,45,45,45,45,45,45,45,962,45,45,45,45,45,979,45,45,45,45,45,985,45,45,45,45,45,45,45,45,45,1224,45,45,45,45,45,45,45,45,688,45,45,45,45,45,45,45,1007,1008,67,67,67,67,67,1014,67,67,67,67,67,67,67,67,67,1045,67,67,67,67,67,67,67,1038,67,67,67,67,67,67,1044,67,1046,67,1049,67,67,67,67,67,67,800,67,67,67,67,67,67,808,67,67,0,0,0,1102,97,97,97,97,97,1108,97,97,97,97,97,97,306,97,97,97,97,97,97,97,97,97,97,1371,97,97,97,97,97,97,97,97,1132,97,97,97,97,97,97,1138,97,1140,97,1143,97,97,97,97,97,1352,97,97,97,97,97,97,97,97,97,97,869,97,97,97,97,97,45,1191,45,45,45,45,45,1196,45,45,45,45,45,45,45,45,1407,45,45,45,45,45,45,45,45,986,45,45,45,45,45,45,991,45,67,67,67,1256,67,67,67,67,67,67,67,67,67,67,67,67,1048,67,67,67,97,1336,97,97,97,97,97,97,97,97,97,97,97,97,97,97,615,97,1386,45,1387,45,45,45,45,45,45,45,45,45,45,45,45,45,455,45,457,45,45,1424,45,45,45,45,45,67,67,67,67,1433,67,1434,67,67,67,67,67,767,67,67,67,67,67,67,67,67,67,67,67,1591,67,1593,67,67,45,45,1805,45,45,45,45,45,45,45,45,45,1814,45,45,1816,67,67,67,67,1820,67,67,67,67,67,67,67,67,67,1829,67,67,67,67,67,815,67,67,67,67,821,67,67,67,37689,544,67,1831,97,97,97,97,1835,0,0,97,97,97,97,97,0,0,97,97,97,1731,97,97,97,97,97,97,97,97,97,853,97,97,97,97,97,97,0,97,97,97,97,1850,97,97,45,45,45,45,45,45,45,45,1547,45,45,45,45,45,45,45,45,1664,45,45,45,45,45,45,45,45,961,45,45,45,45,965,45,967,1907,45,45,45,45,45,45,45,45,45,67,67,67,67,67,1920,0,1936,97,97,97,0,0,0,97,97,97,97,97,97,45,45,67,67,67,67,67,67,1763,67,67,67,67,67,67,67,67,1056,67,67,67,67,67,67,67,67,1273,67,67,67,67,67,67,67,67,1457,67,67,67,67,67,67,67,67,97,97,97,97,0,0,28672,97,45,67,67,67,67,0,0,97,97,97,97,45,45,67,67,2054,97,97,291,97,97,97,97,97,97,320,97,97,97,97,97,97,307,97,97,97,97,97,97,97,97,97,97,12288,0,925,926,1179,0,45,377,45,45,45,381,45,45,392,45,45,396,45,45,45,45,971,45,45,45,45,45,45,45,45,45,45,45,45,1756,45,45,45,67,67,67,67,463,67,67,67,467,67,67,478,67,67,482,67,67,67,67,67,1028,67,67,67,67,67,67,67,67,67,67,67,67,1469,67,67,1472,67,502,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1460,67,97,97,97,97,560,97,97,97,564,97,97,575,97,97,579,97,97,97,97,97,1368,97,97,97,97,97,97,97,97,97,97,0,0,925,0,0,930,97,599,97,97,97,97,97,97,97,97,97,97,97,97,97,97,872,97,45,666,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1758,0,362,0,0,925,41606,0,0,0,0,45,45,934,45,45,45,164,168,174,178,45,45,45,45,45,194,45,45,45,165,45,45,45,45,45,45,45,45,45,199,45,45,45,67,67,1010,67,67,67,67,67,67,67,67,67,67,67,67,1060,67,67,67,67,67,67,1052,1053,67,67,67,67,67,67,67,67,67,67,1063,97,1157,97,97,97,97,97,97,97,97,97,97,97,97,1167,97,97,97,97,97,1379,97,97,97,0,0,0,45,1383,45,45,45,1806,45,45,45,45,45,45,1812,45,45,45,45,67,67,67,67,67,1577,67,67,67,67,67,67,67,753,67,67,67,67,67,67,67,67,67,1262,67,67,67,67,67,67,67,1282,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1471,67,45,1402,45,45,45,45,45,45,45,45,45,45,45,45,45,45,417,45,67,1462,67,67,67,67,67,67,67,67,67,67,67,67,67,67,37689,544,97,1517,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1128,97,97,97,97,1636,97,97,97,0,97,97,97,97,97,97,97,97,851,97,97,97,97,97,97,97,67,67,1705,67,67,67,67,67,67,67,67,97,97,97,97,97,97,0,0,97,97,97,97,1842,0,0,1779,97,97,97,1782,97,0,0,97,97,97,97,97,97,0,0,97,97,97,1789,97,97,0,0,0,97,1847,97,97,97,97,97,45,45,45,45,45,45,45,45,1675,45,45,45,45,45,45,45,45,737,738,67,740,67,741,67,743,67,67,67,67,67,67,1968,67,67,97,97,97,97,0,0,0,97,97,45,67,0,97,45,67,2062,97,45,67,0,97,45,67,67,97,97,2001,97,0,0,2004,97,97,0,97,97,97,97,1797,97,97,97,97,97,45,45,45,67,261,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,292,97,97,97,97,311,315,321,325,97,97,97,97,97,97,1623,97,97,97,97,97,97,97,97,97,97,1330,97,97,1333,1334,97,341,97,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,363,364,0,367,41098,369,140,45,45,45,45,1221,45,45,45,45,45,45,45,45,45,45,45,413,45,45,416,45,376,45,45,45,45,382,45,45,45,45,45,45,45,45,45,45,1408,45,45,45,45,45,403,45,45,45,45,45,45,45,45,45,45,414,45,45,45,418,67,67,67,462,67,67,67,67,468,67,67,67,67,67,67,67,67,1602,67,1604,67,67,67,67,67,67,67,67,489,67,67,67,67,67,67,67,67,67,67,500,67,67,67,67,67,1067,67,67,67,67,67,1072,67,67,67,67,67,67,274,0,37139,24853,0,0,0,0,41098,65820,67,67,504,67,67,67,67,67,67,67,510,67,67,67,517,519,541,67,37139,37139,24853,24853,0,70179,0,0,0,65820,65820,369,287,554,97,97,97,559,97,97,97,97,565,97,97,97,97,97,97,97,1718,0,97,97,97,97,97,97,97,898,97,97,97,97,97,97,906,97,97,97,97,586,97,97,97,97,97,97,97,97,97,97,597,97,97,97,97,97,1520,97,97,97,97,97,97,97,97,97,97,0,45,1656,45,45,45,97,97,601,97,97,97,97,97,97,97,607,97,97,97,614,616,638,97,18,0,139621,0,0,0,0,0,0,364,0,0,367,41606,369,0,45,45,45,45,45,45,45,45,45,45,661,45,45,45,407,45,45,45,45,45,45,45,45,45,45,45,45,45,1815,45,67,45,667,45,45,45,45,45,45,45,45,45,45,678,45,45,45,421,45,45,45,45,45,45,45,45,45,45,45,45,976,977,45,45,45,682,45,45,45,45,45,45,45,45,45,45,693,45,45,697,67,67,748,67,67,67,67,754,67,67,67,67,67,67,67,67,67,1274,67,67,67,67,67,67,67,67,765,67,67,67,67,769,67,67,67,67,67,67,67,67,67,1589,67,67,67,67,67,67,67,67,780,67,67,784,67,67,67,67,67,67,67,67,67,67,67,1777,67,97,97,97,97,97,97,846,97,97,97,97,852,97,97,97,97,97,97,97,1742,45,45,45,45,45,45,45,1747,97,97,97,863,97,97,97,97,867,97,97,97,97,97,97,97,308,97,97,97,97,97,97,97,97,97,97,12288,1178,925,0,1179,0,97,97,97,878,97,97,882,97,97,97,97,97,97,97,97,97,97,12288,0,925,0,1179,0,908,97,97,97,97,97,97,97,97,97,97,97,97,97,97,0,0,925,0,0,0,954,45,45,45,45,45,45,45,45,45,45,963,45,45,966,45,45,157,45,45,171,45,45,45,45,45,45,45,45,45,45,948,45,45,45,45,45,1022,67,67,1026,67,67,67,1030,67,67,67,67,67,67,67,67,67,1603,1605,67,67,67,1608,67,67,67,1039,67,67,1042,67,67,67,67,67,67,67,67,67,67,471,67,67,67,67,67,0,1100,0,97,97,97,97,97,97,97,97,97,97,97,97,97,904,97,97,97,97,1116,97,97,1120,97,97,97,1124,97,97,97,97,97,97,562,97,97,97,571,97,97,97,97,97,97,97,97,97,1133,97,97,1136,97,97,97,97,97,97,97,97,915,917,97,97,97,97,97,0,97,1170,97,97,97,97,97,97,97,97,0,0,925,0,0,0,0,0,41606,0,0,0,0,45,45,45,45,45,45,1993,67,67,67,67,67,67,67,67,67,67,1275,67,67,67,1278,67,0,0,0,45,45,1182,45,45,45,45,45,45,45,45,45,1189,1204,45,45,45,1207,45,45,1209,45,1210,45,45,45,45,45,45,1546,45,45,45,45,45,45,45,45,45,689,45,45,45,45,45,45,1231,45,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,236,67,67,67,67,67,67,67,801,67,67,67,805,67,67,67,67,67,1242,67,67,67,67,67,67,67,67,67,1249,67,67,67,67,67,67,507,67,67,67,67,67,67,67,67,67,67,1300,0,0,0,0,0,1267,67,67,1269,67,1270,67,67,67,67,67,67,67,67,67,1280,97,1349,97,1350,97,97,97,97,97,97,97,97,97,1360,97,97,97,0,1980,97,97,97,97,97,45,45,45,45,45,45,673,45,45,45,45,677,45,45,45,45,1401,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,953,67,1437,67,1440,67,67,67,67,1445,67,67,67,1448,67,67,67,67,67,67,1029,67,67,67,67,67,67,67,67,67,67,1825,67,67,67,67,67,1473,67,67,67,0,0,0,0,0,0,0,0,0,0,0,0,1320,0,834,97,97,97,97,1490,97,1493,97,97,97,97,1498,97,97,97,1501,97,97,97,0,97,1638,97,0,97,97,97,97,97,97,97,97,916,97,97,97,97,97,97,0,1528,97,97,97,0,45,45,45,1535,45,45,45,45,45,45,45,1867,67,67,67,67,67,67,67,67,67,97,97,97,97,1932,0,0,1555,45,45,45,45,45,45,45,45,45,45,45,45,45,1567,45,45,158,45,45,172,45,45,45,183,45,45,45,45,201,45,45,67,212,67,67,67,67,231,235,241,245,67,67,67,67,67,67,493,67,67,67,67,67,67,67,67,67,67,472,67,67,67,67,67,97,97,97,97,1651,97,97,97,97,97,0,45,45,45,45,45,45,45,1539,45,45,45,67,1704,67,1706,67,67,67,67,67,67,67,97,97,97,97,97,97,0,0,97,97,97,1841,97,0,1844,97,97,97,97,1716,97,97,97,0,97,97,97,97,97,97,97,590,97,97,97,97,97,97,97,97,97,0,0,0,45,45,45,1385,1748,45,45,45,45,45,45,45,45,45,45,45,45,45,1757,45,45,159,45,45,45,45,45,45,45,45,45,45,45,45,45,415,45,45,97,97,1780,97,97,97,0,0,1786,97,97,97,97,97,0,0,97,97,1730,0,97,97,97,97,97,1736,97,1738,67,97,97,97,97,97,97,0,1838,97,97,97,97,97,0,0,97,1729,97,0,97,97,97,97,97,97,97,97,1162,97,97,97,1165,97,97,97,45,1950,45,45,45,45,45,45,45,45,1958,67,67,67,1962,67,67,67,67,67,1246,67,67,67,67,67,67,67,67,67,67,67,97,1710,97,97,97,1999,67,97,97,97,97,0,2003,97,97,97,0,97,97,2008,2009,45,67,67,67,67,0,0,97,97,97,97,45,2052,67,2053,0,0,0,0,925,41606,0,0,930,0,45,45,45,45,45,45,1392,45,1394,45,45,45,45,45,45,45,1545,45,45,45,45,45,45,45,45,45,45,1563,1565,45,45,45,1568,0,97,2055,45,67,0,97,45,67,0,97,45,67,28672,97,45,45,160,45,45,45,45,45,45,45,45,45,45,45,45,45,679,45,45,67,67,266,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,346,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,362,0,364,0,367,41098,369,140,371,45,45,45,379,45,45,45,388,45,45,45,45,45,45,45,45,1663,45,45,45,45,45,45,45,45,45,449,45,45,45,45,45,67,67,542,37139,37139,24853,24853,0,70179,0,0,0,65820,65820,369,287,97,97,97,97,97,1622,97,97,97,97,97,97,97,1629,97,97,0,1794,1795,97,97,97,97,97,97,97,97,45,45,45,45,45,45,1745,45,45,97,639,18,0,139621,0,0,0,0,0,0,364,0,0,367,41606,45,731,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,67,67,251,67,67,67,67,67,798,67,67,67,67,67,67,67,67,67,67,67,67,1073,67,67,67,860,97,97,97,97,97,97,97,97,97,97,97,97,97,97,873,0,0,1101,97,97,97,97,97,97,97,97,97,97,97,97,97,921,97,0,67,67,67,67,1245,67,67,67,67,67,67,67,67,67,67,67,67,1250,67,67,1253,0,0,1312,0,0,0,1318,0,0,0,0,0,0,97,97,97,97,1106,97,97,97,97,97,97,97,97,97,1149,97,97,97,97,97,1155,97,97,1325,97,97,97,97,97,97,97,97,97,97,97,97,97,1141,97,97,67,67,1439,67,1441,67,67,67,67,67,67,67,67,67,67,67,67,1264,67,67,67,97,97,1492,97,1494,97,97,97,97,97,97,97,97,97,97,97,1331,97,97,97,97,67,67,67,2037,67,97,0,0,97,97,97,2043,97,45,45,45,442,45,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,67,232,67,67,67,67,67,67,67,67,1823,67,67,67,67,67,67,67,67,97,97,97,97,1975,0,0,97,874,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1142,97,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,65,86,117,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,63,84,115,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,61,82,113,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,59,80,111,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,57,78,109,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,55,76,107,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,53,74,105,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,51,72,103,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,49,70,101,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,47,68,99,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,45,67,97,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,213085,53264,18,49172,57366,24,8192,28,102432,0,0,0,44,0,0,32863,53264,18,49172,57366,24,8192,28,102432,0,41,41,41,0,0,1138688,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,0,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,89,53264,18,18,49172,0,57366,0,24,24,24,0,127,127,127,127,102432,67,262,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,342,97,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,360,0,0,364,0,367,41098,369,140,45,45,45,45,717,45,45,45,45,45,45,45,45,45,45,45,412,45,45,45,45,45,67,1009,67,67,67,67,67,67,67,67,67,67,67,67,67,1292,67,67,1294,67,67,67,67,67,67,67,67,67,67,0,0,0,0,0,0,97,97,97,1615,97,97,97,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,66,87,118,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,64,85,116,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,62,83,114,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,60,81,112,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,58,79,110,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,56,77,108,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,54,75,106,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,52,73,104,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,50,71,102,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,48,69,100,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,46,67,98,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,233472,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,69724,53264,18,18,49172,0,57366,262144,24,24,24,0,28,28,28,28,102432,45,45,161,45,45,45,45,45,45,45,45,45,45,45,45,45,710,45,45,28,139621,359,0,0,0,364,0,367,41098,369,140,45,45,45,45,1389,45,45,45,45,45,45,45,45,45,45,45,949,45,45,45,45,67,503,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1449,67,67,97,600,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1154,97,0,0,0,0,925,41606,927,0,0,0,45,45,45,45,45,45,1866,67,67,67,67,67,67,67,67,67,67,772,67,67,67,67,67,45,45,969,45,45,45,45,45,45,45,45,45,45,45,45,45,951,45,45,45,45,1192,45,45,45,45,45,45,45,45,45,45,45,45,45,1202,45,45,0,0,0,1314,0,0,0,0,0,0,0,0,0,97,97,97,97,97,97,97,1488,67,67,267,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,347,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,361,0,0,364,0,367,41098,369,140,45,45,45,45,734,45,45,45,67,67,67,67,67,742,67,67,45,45,668,45,45,45,45,45,45,45,45,45,45,45,45,45,1214,45,45,1130,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1361,97,45,45,1671,45,45,45,45,45,45,45,45,45,45,45,45,45,1552,45,45,0,0,0,0,2220032,0,0,1130496,0,0,0,0,2170880,2171020,2170880,2170880,18,0,0,131072,0,0,0,90112,0,2220032,0,0,0,0,0,0,0,0,97,97,97,1485,97,97,97,97,0,45,45,45,45,45,1537,45,45,45,45,45,1390,45,1393,45,45,45,45,1398,45,45,45,2170880,2171167,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2576384,2215936,3117056,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2174976,0,0,0,0,0,0,2183168,0,0,0,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2721252,2744320,2170880,2170880,2170880,2834432,2840040,2170880,2908160,2170880,2170880,2936832,2170880,2170880,2985984,2170880,2994176,2170880,2170880,3014656,2170880,3059712,3076096,3088384,2170880,2170880,2170880,2170880,0,0,0,0,2220032,0,0,0,1142784,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3215360,2215936,2215936,2215936,2215936,2215936,2437120,2215936,2215936,2215936,3117056,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,543,0,545,0,0,2183168,0,0,831,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,3031040,2170880,3055616,2170880,2170880,2170880,2170880,3092480,2170880,2170880,3125248,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3198976,2170880,0,0,0,0,0,0,67,67,37139,37139,24853,24853,0,0,0,0,0,65820,65820,0,287,97,97,97,97,97,1783,0,0,97,97,97,97,97,97,0,0,97,97,97,97,97,97,1791,0,0,546,70179,0,0,0,0,552,0,97,97,97,97,97,97,97,604,97,97,97,97,97,97,97,97,97,97,1150,97,97,97,97,97,147456,147456,147456,147456,147456,147456,147456,147456,147456,147456,147456,147456,0,0,147456,0,0,0,0,925,41606,0,928,0,0,45,45,45,45,45,45,998,45,45,45,45,45,45,45,45,45,1562,45,1564,45,45,45,45,0,2158592,2158592,0,0,0,0,2232320,2232320,2232320,0,2240512,2240512,2240512,2240512,0,0,0,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2416640],n.EXPECTED=[291,300,304,341,315,309,305,295,319,323,327,329,296,333,337,339,342,346,350,294,356,360,312,367,352,371,363,375,379,383,387,391,395,726,399,405,518,684,405,405,405,405,808,405,405,405,512,405,405,405,431,405,405,406,405,405,404,405,405,405,405,405,405,405,908,631,410,415,405,414,419,608,405,429,602,405,435,443,405,441,641,478,405,447,451,450,456,643,461,460,762,679,465,469,741,473,477,482,486,492,932,931,523,498,504,720,405,510,596,405,516,941,580,522,929,527,590,589,897,939,534,538,547,551,555,559,563,567,571,969,575,708,690,689,579,584,634,405,594,731,405,600,882,405,606,895,786,452,612,405,615,620,876,624,628,638,647,651,655,659,663,667,676,683,688,695,694,791,405,699,437,405,706,714,405,712,825,870,405,718,724,769,768,823,730,735,745,751,422,755,759,425,766,902,810,587,775,888,887,405,773,992,405,779,962,405,785,781,986,790,795,797,506,500,499,801,805,814,820,829,833,837,841,845,849,853,857,861,616,865,869,868,488,405,874,816,405,880,738,405,886,892,543,405,901,906,913,912,918,494,541,922,926,936,945,949,953,957,530,966,973,960,702,701,405,979,981,405,985,747,405,990,998,914,405,996,1004,672,975,974,1014,1002,1008,670,1012,405,405,405,405,405,401,1018,1022,1026,1106,1071,1111,1111,1111,1082,1145,1030,1101,1034,1038,1106,1106,1106,1106,1046,1206,1052,1106,1072,1111,1111,1042,1134,1065,1111,1112,1056,1160,1207,1062,1204,1208,1069,1106,1106,1106,1076,1111,1207,1161,1122,1205,1064,1094,1106,1106,1107,1111,1111,1111,1078,1086,1207,1092,1098,1046,1058,1106,1106,1110,1111,1111,1116,1120,1161,1126,1202,1104,1106,1145,1146,1129,1138,1088,1151,1048,1157,1153,1132,1141,1165,1107,1111,1172,1179,1109,1183,1175,1143,1147,1187,1108,1191,1195,1144,1199,1168,1212,1216,1220,1224,1228,1232,1236,1557,1247,1241,1241,1038,1434,1241,1241,1241,1241,1254,1275,1617,1241,1280,1287,1241,1241,1241,1287,1241,2114,1291,1241,1243,1241,2049,1824,2094,2095,1520,1309,1241,1241,1302,1241,1321,1311,1241,1241,1313,1778,1325,1336,1241,1241,1325,1330,1353,1241,1241,1695,1354,1241,1241,1241,1294,1686,1331,1241,1696,1368,1241,1338,1370,1241,1392,1399,1364,2017,1406,2016,1405,1716,1406,1407,1422,1417,1421,1241,1241,1241,1349,1426,1241,1774,1756,1241,1773,1241,1241,1345,1964,1812,1432,1241,1241,1345,1993,1459,1241,1241,1241,1395,1848,1767,1465,1241,1241,1394,1847,1242,1477,1241,1241,1428,1241,1445,1492,1241,1241,1438,1241,1499,1241,1241,1241,1455,1241,1818,1448,1241,1250,1241,2026,1623,1449,1241,1612,1616,1241,1614,1241,1257,1241,1241,1985,1292,1586,1512,1241,1517,2050,1526,1674,1519,1524,1647,2051,1532,1537,1551,1544,1550,1555,1561,1571,1578,1584,1590,1591,1653,1595,1602,1606,1610,1634,1628,1640,1633,1645,1241,1241,1241,1469,1241,1970,1651,1241,1270,1241,1241,1819,1449,1241,1293,1664,1241,1241,1481,1485,1574,1672,1241,1241,1513,1317,1487,1684,1241,1241,1533,1299,1694,1241,1241,1295,1241,1241,1241,1546,1700,1241,1241,1707,1241,1713,1241,1849,1715,1241,1720,1241,1276,1267,1241,1241,2107,1657,1864,1241,1881,1241,1326,1292,1241,1685,1358,1724,1338,1241,1363,1362,1342,1340,1361,1339,1833,1372,1360,1833,1833,1342,1343,1835,1341,1731,1738,1344,1241,1745,1241,1379,1241,1241,2092,1241,1388,1761,1754,1241,1386,1241,1400,1760,1241,1241,1241,1598,1734,1241,1241,1241,1635,1645,1241,1780,1766,1241,1241,1332,1771,1241,1241,1629,2079,1241,1242,1784,1241,1241,1680,1639,2063,1790,1241,1241,1741,1241,1241,1800,1241,1241,1762,1473,1241,1806,1241,1241,1786,1240,1709,1241,1241,1241,1668,1811,1241,1940,1241,1401,1974,1241,1408,1413,1382,1241,1816,1241,1241,1802,2086,1811,1241,1817,1945,1823,2095,2095,2047,2094,2046,2080,1241,1409,1312,1376,2096,2048,1241,1241,1807,1241,1241,1241,2035,1241,1241,1828,1241,2057,2061,1241,1241,1843,1241,2059,1241,1241,1241,1690,1847,1241,1241,1241,1703,2102,1848,1241,1241,1853,1292,1848,1241,2016,1857,1241,2002,1868,1241,1436,1241,1241,1271,1305,1241,1874,1241,1241,1884,2037,1892,1241,1890,1241,1461,1241,1241,1795,1241,1241,1891,1241,1878,1241,1888,1241,1888,1905,1896,2087,1912,1903,1241,1911,1906,1916,1905,2027,1863,1925,2088,1859,1861,1922,1927,1931,1935,1494,1241,1241,1918,1907,1939,1917,1944,1949,1241,1241,1451,1955,1241,1241,1241,1796,1727,2061,1241,1241,1899,1241,1660,1968,1241,1241,1951,1678,1978,1241,1241,1241,1839,1241,1241,1984,1982,1241,1488,1241,1241,1624,1450,1989,1241,1241,1241,1870,1995,1292,1241,1241,1958,1261,1241,1996,1241,1241,1241,2039,2008,1241,1241,1750,2e3,1241,1256,2001,1960,1241,1564,1241,1504,1241,1241,1442,1241,1241,1564,1528,1263,1241,1508,1241,1241,1468,1498,2006,1540,2015,1539,2014,1748,2013,1539,1831,2014,2012,1500,1567,2022,2021,1241,1580,1241,1241,2033,2037,1791,2045,2031,1241,1621,1241,1641,2044,1241,1241,1241,2093,1241,1241,2055,1241,1241,2067,1241,1283,1241,1241,1241,2101,2071,1241,1241,1241,2073,1848,2040,1241,1241,1241,2077,1241,1241,2106,1241,1241,2084,1241,2111,1241,1241,1381,1380,1241,1241,1241,2100,1241,2129,2118,2122,2126,2197,2133,3010,2825,2145,2698,2156,2226,2160,2161,2165,2174,2293,2194,2630,2201,2203,2152,3019,2226,2263,2209,2213,2218,2269,2292,2269,2269,2184,2226,2238,2148,2151,3017,2245,2214,2269,2269,2185,2226,2292,2269,2291,2269,2269,2269,2292,2205,3019,2226,2226,2160,2160,2160,2261,2160,2160,2160,2262,2276,2160,2160,2277,2216,2283,2216,2269,2269,2268,2269,2267,2269,2269,2269,2271,2568,2292,2269,2293,2269,2182,2190,2269,2186,2226,2226,2226,2226,2227,2160,2160,2160,2160,2263,2160,2275,2277,2282,2215,2217,2269,2269,2291,2269,2269,2293,2291,2269,2220,2269,2295,2294,2269,2269,2305,2233,2262,2278,2218,2269,2234,2226,2226,2228,2160,2160,2160,2289,2220,2294,2294,2269,2269,2304,2269,2160,2160,2287,2269,2269,2305,2269,2269,2312,2269,2269,2225,2226,2160,2287,2289,2219,2304,2295,2314,2234,2226,2314,2269,2226,2226,2160,2288,2219,2222,2304,2296,2269,2224,2160,2160,2269,2302,2294,2314,2224,2226,2288,2220,2294,2269,2290,2269,2269,2293,2269,2269,2269,2269,2270,2221,2313,2225,2227,2160,2300,2269,2225,2261,2309,2234,2229,2223,2318,2318,2318,2328,2336,2340,2344,2350,2637,2712,2358,2362,2372,2135,2378,2398,2135,2135,2135,2135,2136,2417,2241,2135,2378,2135,2135,2980,2984,2135,3006,2135,2135,2135,2945,2931,2425,2400,2135,2135,2135,2954,2135,2481,2433,2135,2135,2988,2824,2135,2135,2482,2434,2135,2135,2440,2445,2452,2135,2135,2998,3002,2961,2441,2446,2453,2463,2974,2135,2135,2135,2140,2642,2709,2459,2470,2465,2135,2135,3005,2135,2135,2987,2823,2458,2469,2464,2975,2135,2135,2135,2353,2488,2447,2324,2974,2135,2409,2459,2448,2135,2961,2487,2446,2476,2323,2973,2135,2135,2135,2354,2476,2974,2135,2135,2135,2957,2135,2135,2960,2135,2135,2135,2363,2409,2459,2474,2465,2487,2571,2973,2135,2135,2168,2973,2135,2135,2135,2959,2135,2135,2135,2506,2135,2957,2488,2170,2135,2135,2135,2960,2135,2818,2493,2135,2135,3033,2135,2135,2135,2934,2819,2494,2135,2135,2135,2976,2780,2499,2135,2135,2135,3e3,2968,2135,2935,2135,2135,2135,2364,2507,2135,2135,2934,2135,2135,2780,2492,2507,2135,2135,2506,2780,2135,2135,2782,2780,2135,2782,2135,2783,2374,2514,2135,2135,2135,3007,2530,2974,2135,2135,2135,3008,2135,2135,2134,2135,2526,2531,2975,2135,2135,3042,2581,2575,2956,2135,2135,2135,2394,2135,2508,2535,2840,2844,2495,2135,2135,2136,2684,2537,2842,2846,2135,2136,2561,2581,2551,2536,2841,2845,2975,3043,2582,2843,2555,2135,3040,3044,2538,2844,2975,2135,2135,2253,2644,2672,2542,2554,2135,2135,2346,2873,2551,2555,2135,2135,2135,2381,2559,2565,2538,2553,2135,2560,2914,2576,2590,2135,2135,2135,2408,2136,2596,2624,2135,2135,2135,2409,2135,2618,2597,3008,2135,2135,2380,2956,2601,2135,2135,2135,2410,2620,2624,2135,2136,2383,2135,2135,2783,2623,2135,2135,2393,2888,2136,2621,3008,2135,2618,2618,2622,2135,2135,2405,2414,2619,2384,2624,2135,2136,2950,2135,2138,2135,2139,2135,2604,2623,2135,2140,2878,2665,2957,2622,2135,2135,2428,2762,2606,2612,2135,2135,2501,2586,2604,3038,2135,2604,3036,2387,2958,2386,2135,2141,2135,2421,2387,2385,2135,2385,2384,2384,2135,2386,2628,2384,2135,2135,2501,2596,2591,2135,2135,2135,2400,2135,2634,2135,2135,2559,2580,2575,2648,2135,2135,2135,2429,2649,2135,2135,2135,2435,2654,2658,2135,2135,2135,2436,2649,2178,2659,2135,2135,2595,2601,2669,2677,2135,2135,2616,2957,2879,2665,2691,2135,2363,2367,2900,2878,2664,2690,2975,2877,2643,2670,2974,2671,2975,2135,2135,2619,2608,2669,2673,2135,2135,2653,2177,2672,2135,2135,2135,2486,2168,2251,2255,2695,2974,2709,2135,2135,2135,2487,2169,2399,2716,2975,2135,2363,2770,2776,2640,2717,2135,2135,2729,2135,2135,2641,2718,2135,2135,2135,2505,2135,2640,2257,2974,2135,2727,2975,2135,2365,2332,2895,2957,2135,2959,2135,2365,2749,2754,2959,2958,2958,2135,2380,2793,2799,2135,2735,2738,2135,2381,2135,2135,2940,2974,2135,2744,2135,2135,2739,2519,2976,2745,2135,2135,2135,2509,2755,2135,2135,2135,2510,2772,2778,2135,2135,2740,2520,2135,2771,2777,2135,2135,2759,2750,2792,2798,2135,2135,2781,2392,2779,2135,2135,2135,2521,2135,2679,2248,2135,2135,2681,2480,2135,2135,2786,3e3,2135,2679,2683,2135,2135,2416,2135,2135,2135,2525,2135,2730,2135,2135,2135,2560,2581,2135,2805,2135,2135,2804,2962,2832,2974,2135,2382,2135,2135,2958,2135,2135,2960,2135,2829,2833,2975,2961,2965,2969,2973,2968,2972,2135,2135,2135,2641,2135,2515,2966,2970,2851,2478,2135,2135,2808,2135,2809,2135,2135,2135,2722,2852,2479,2135,2135,2815,2135,2135,2766,2853,2480,2135,2857,2479,2135,2388,2723,2135,2364,2331,2894,2858,2480,2135,2135,2850,2478,2135,2135,2135,2806,2864,2135,2399,2256,2974,2865,2135,2135,2862,2135,2135,2135,2685,2807,2865,2135,2135,2807,2863,2135,2135,2135,2686,2884,2807,2135,2809,2807,2135,2135,2807,2806,2705,2810,2808,2700,2869,2702,2702,2702,2704,2883,2135,2135,2135,2730,2884,2135,2135,2135,2731,2321,2546,2135,2135,2876,2255,2889,2322,2547,2135,2401,2135,2135,2135,2949,2367,2893,2544,2973,2906,2973,2135,2135,2877,2663,2368,2901,2907,2974,2366,2899,2905,2972,2920,2974,2135,2135,2911,2900,2920,2363,2913,2918,2465,2941,2975,2135,2135,2924,2928,2974,2945,2931,2135,2135,2135,2765,2136,2955,2135,2135,2939,2931,2380,2135,2135,2380,2135,2135,2135,2780,2507,2137,2135,2137,2135,2139,2135,2806,2810,2135,2135,2135,2992,2135,2135,2962,2966,2970,2974,2135,2135,2787,3014,2135,2521,2993,2135,2135,2135,2803,2135,2135,2135,2618,2607,2997,3001,2135,2135,2963,2967,2971,2975,2135,2135,2791,2797,2135,3009,2999,3003,2787,3001,2135,2135,2964,2968,2785,2999,3003,2135,2135,2135,2804,2785,2999,3004,2135,2135,2135,2807,2135,2135,3023,2135,2135,2135,2811,2135,2135,3027,2135,2135,2135,2837,2968,3028,2135,2135,2135,2875,2135,2784,3029,2135,2408,2457,2446,0,14,0,-2120220672,1610612736,-2074083328,-2002780160,-2111830528,1073872896,1342177280,1075807216,4096,16384,2048,8192,0,8192,0,0,0,0,1,0,0,0,2,0,-2145386496,8388608,1073741824,0,2147483648,2147483648,2097152,2097152,2097152,536870912,0,0,134217728,33554432,1536,268435456,268435456,268435456,268435456,128,256,32,0,65536,131072,524288,16777216,268435456,2147483648,1572864,1835008,640,32768,65536,262144,1048576,2097152,196608,196800,196608,196608,0,131072,131072,131072,196608,196624,196608,196624,196608,196608,128,4096,16384,16384,2048,0,4,0,0,2147483648,2097152,0,1024,32,32,0,65536,1572864,1048576,32768,32768,32768,32768,196608,196608,196608,64,64,196608,196608,131072,131072,131072,131072,268435456,268435456,64,196736,196608,196608,196608,131072,196608,196608,16384,4,4,4,2,32,32,65536,1048576,12582912,1073741824,0,0,2,8,16,96,2048,32768,0,0,131072,268435456,268435456,268435456,256,256,196608,196672,196608,196608,196608,196608,4,0,256,256,256,256,32,32,32768,32,32,32,32,32768,268435456,268435456,268435456,196608,196608,196608,196624,196608,196608,196608,16,16,16,268435456,196608,64,64,64,196608,196608,196608,196672,268435456,64,64,196608,196608,16,196608,196608,196608,268435456,64,196608,131072,262144,4194304,25165824,33554432,134217728,268435456,268435456,196608,262152,8,256,512,3072,16384,200,-1073741816,8392713,40,8392718,520,807404072,40,520,100663304,0,0,-540651761,-540651761,257589048,0,262144,0,0,3,8,256,0,4,6,4100,8388612,0,0,0,3,4,8,256,512,1024,0,2097152,0,0,-537854471,-537854471,0,100663296,0,0,1,2,0,0,0,16384,0,0,0,96,14336,0,0,0,7,8,234881024,0,0,0,8,0,0,0,0,262144,0,0,16,64,384,512,0,1,1,0,12582912,0,0,0,0,33554432,67108864,-606084144,-606084144,-606084138,0,0,28,32,768,1966080,-608174080,0,0,0,14,35056,16,64,896,24576,98304,98304,131072,262144,524288,1048576,4194304,25165824,1048576,62914560,134217728,-805306368,0,384,512,16384,65536,131072,262144,29360128,33554432,134217728,268435456,1073741824,2147483648,262144,524288,1048576,29360128,33554432,524288,1048576,16777216,33554432,134217728,268435456,1073741824,0,0,0,123856,1966080,0,64,384,16384,65536,131072,16384,65536,524288,268435456,2147483648,0,0,524288,2147483648,0,0,1,16,0,256,524288,0,0,0,25,96,128,-537854471,0,0,0,32,7404800,-545259520,0,0,0,60,0,249,64768,1048576,6291456,6291456,25165824,100663296,402653184,1073741824,96,128,1280,2048,4096,57344,6291456,57344,6291456,8388608,16777216,33554432,201326592,1342177280,2147483648,0,57344,6291456,8388608,100663296,134217728,2147483648,0,0,0,1,8,16,64,128,64,128,256,1024,131072,131072,131072,262144,524288,16777216,57344,6291456,8388608,67108864,134217728,64,256,1024,2048,4096,57344,64,256,0,24576,32768,6291456,67108864,134217728,0,1,64,256,24576,32768,4194304,32768,4194304,67108864,0,0,64,256,0,0,24576,32768,0,16384,4194304,67108864,64,16384,0,0,1,64,256,16384,4194304,67108864,0,0,0,16384,0,16384,16384,0,-470447874,-470447874,-470447874,0,0,128,0,0,8,96,2048,32768,262144,8388608,35056,1376256,-471859200,0,0,14,16,224,2048,32768,2097152,4194304,8388608,-486539264,0,96,128,2048,32768,262144,2097152,262144,2097152,8388608,33554432,536870912,1073741824,2147483648,0,1610612736,2147483648,0,0,1,524288,1048576,12582912,0,0,0,151311,264503296,2097152,8388608,33554432,1610612736,2147483648,262144,8388608,33554432,536870912,67108864,4194304,0,4194304,0,4194304,4194304,0,0,524288,8388608,536870912,1073741824,2147483648,1,4097,8388609,96,2048,32768,1073741824,2147483648,0,96,2048,2147483648,0,0,96,2048,0,0,1,12582912,0,0,0,0,1641895695,1641895695,0,0,0,249,7404800,15,87808,1835008,1639972864,0,768,5120,16384,65536,1835008,1835008,12582912,16777216,1610612736,0,3,4,8,768,4096,65536,0,0,256,512,786432,8,256,512,4096,16384,1835008,16384,1835008,12582912,1610612736,0,0,0,256,0,0,0,4,8,16,32,1,2,8,256,16384,524288,16384,524288,1048576,12582912,1610612736,0,0,0,8388608,0,0,0,524288,4194304,0,0,0,8388608,-548662288,-548662288,-548662288,0,0,256,16384,65536,520093696,-1073741824,0,0,0,16777216,0,16,32,960,4096,4980736,520093696,1073741824,0,32,896,4096,57344,1048576,6291456,8388608,16777216,100663296,134217728,268435456,2147483648,0,512,786432,4194304,33554432,134217728,268435456,0,786432,4194304,134217728,268435456,0,524288,4194304,268435456,0,0,0,0,0,4194304,4194304,-540651761,0,0,0,2,4,8,16,96,128,264503296,-805306368,0,0,0,8,256,512,19456,131072,3072,16384,131072,262144,8388608,16777216,512,1024,2048,16384,131072,262144,131072,262144,8388608,33554432,201326592,268435456,0,3,4,256,1024,2048,57344,16384,131072,8388608,33554432,134217728,268435456,0,3,256,1024,16384,131072,33554432,134217728,1073741824,2147483648,0,0,256,524288,2147483648,0,3,256,33554432,134217728,1073741824,0,1,2,33554432,1,2,134217728,1073741824,0,1,2,134217728,0,0,0,64,0,0,0,16,32,896,4096,786432,4194304,16777216,33554432,201326592,268435456,1073741824,2147483648,0,0,0,15,0,4980736,4980736,4980736,70460,70460,3478332,0,0,1008,4984832,520093696,60,4864,65536,0,0,0,12,16,32,256,512,4096,65536,0,0,0,67108864,0,0,0,12,0,256,512,65536,0,0,1024,512,131072,131072,4,16,32,65536,0,4,16,32,0,0,0,4,16,0,0,16384,67108864,0,0,1,24,96,128,256,1024],n.TOKEN=["(0)","JSONChar","JSONCharRef","JSONPredefinedCharRef","ModuleDecl","Annotation","OptionDecl","Operator","Variable","Tag","EndTag","PragmaContents","DirCommentContents","DirPIContents","CDataSectionContents","AttrTest","Wildcard","EQName","IntegerLiteral","DecimalLiteral","DoubleLiteral","PredefinedEntityRef","'\"\"'","EscapeApos","AposChar","ElementContentChar","QuotAttrContentChar","AposAttrContentChar","NCName","QName","S","CharRef","CommentContents","DocTag","DocCommentContents","EOF","'!'","'\"'","'#'","'#)'","'$$'","''''","'('","'(#'","'(:'","'(:~'","')'","'*'","'*'","','","'--\x3e'","'.'","'/'","'/>'","':'","':)'","';'","'\x3c!--'","''","'?'","'?>'","'NaN'","'['","']'","']]>'","'after'","'all'","'allowing'","'ancestor'","'ancestor-or-self'","'and'","'any'","'append'","'array'","'as'","'ascending'","'at'","'attribute'","'base-uri'","'before'","'boundary-space'","'break'","'by'","'case'","'cast'","'castable'","'catch'","'check'","'child'","'collation'","'collection'","'comment'","'constraint'","'construction'","'contains'","'content'","'context'","'continue'","'copy'","'copy-namespaces'","'count'","'decimal-format'","'decimal-separator'","'declare'","'default'","'delete'","'descendant'","'descendant-or-self'","'descending'","'diacritics'","'different'","'digit'","'distance'","'div'","'document'","'document-node'","'element'","'else'","'empty'","'empty-sequence'","'encoding'","'end'","'entire'","'eq'","'every'","'exactly'","'except'","'exit'","'external'","'first'","'following'","'following-sibling'","'for'","'foreach'","'foreign'","'from'","'ft-option'","'ftand'","'ftnot'","'ftor'","'function'","'ge'","'greatest'","'group'","'grouping-separator'","'gt'","'idiv'","'if'","'import'","'in'","'index'","'infinity'","'inherit'","'insensitive'","'insert'","'instance'","'integrity'","'intersect'","'into'","'is'","'item'","'json'","'json-item'","'key'","'language'","'last'","'lax'","'le'","'least'","'let'","'levels'","'loop'","'lowercase'","'lt'","'minus-sign'","'mod'","'modify'","'module'","'most'","'namespace'","'namespace-node'","'ne'","'next'","'no'","'no-inherit'","'no-preserve'","'node'","'nodes'","'not'","'object'","'occurs'","'of'","'on'","'only'","'option'","'or'","'order'","'ordered'","'ordering'","'paragraph'","'paragraphs'","'parent'","'pattern-separator'","'per-mille'","'percent'","'phrase'","'position'","'preceding'","'preceding-sibling'","'preserve'","'previous'","'processing-instruction'","'relationship'","'rename'","'replace'","'return'","'returning'","'revalidation'","'same'","'satisfies'","'schema'","'schema-attribute'","'schema-element'","'score'","'self'","'sensitive'","'sentence'","'sentences'","'skip'","'sliding'","'some'","'stable'","'start'","'stemming'","'stop'","'strict'","'strip'","'structured-item'","'switch'","'text'","'then'","'thesaurus'","'times'","'to'","'treat'","'try'","'tumbling'","'type'","'typeswitch'","'union'","'unique'","'unordered'","'updating'","'uppercase'","'using'","'validate'","'value'","'variable'","'version'","'weight'","'when'","'where'","'while'","'wildcards'","'window'","'with'","'without'","'word'","'words'","'xquery'","'zero-digit'","'{'","'{{'","'|'","'}'","'}}'"]},{}],"/node_modules/xqlint/lib/lexers/jsoniq_lexer.js":[function(e,a,t){"use strict";var n=e("./JSONiqTokenizer").JSONiqTokenizer,r=e("./lexer").Lexer,s="NaN|after|allowing|ancestor|ancestor-or-self|and|append|array|as|ascending|at|attribute|base-uri|before|boundary-space|break|by|case|cast|castable|catch|child|collation|comment|constraint|construction|contains|context|continue|copy|copy-namespaces|count|decimal-format|decimal-separator|declare|default|delete|descendant|descendant-or-self|descending|digit|div|document|document-node|element|else|empty|empty-sequence|encoding|end|eq|every|except|exit|external|false|first|following|following-sibling|for|from|ft-option|function|ge|greatest|group|grouping-separator|gt|idiv|if|import|in|index|infinity|insert|instance|integrity|intersect|into|is|item|json|json-item|jsoniq|last|lax|le|least|let|loop|lt|minus-sign|mod|modify|module|namespace|namespace-node|ne|next|node|nodes|not|null|object|of|only|option|or|order|ordered|ordering|paragraphs|parent|pattern-separator|per-mille|percent|preceding|preceding-sibling|previous|processing-instruction|rename|replace|return|returning|revalidation|satisfies|schema|schema-attribute|schema-element|score|select|self|sentences|sliding|some|stable|start|strict|switch|text|then|times|to|treat|true|try|tumbling|type|typeswitch|union|unordered|updating|validate|value|variable|version|when|where|while|window|with|words|xquery|zero-digit".split("|"),o=s.map((function(e){return{name:"'"+e+"'",token:"keyword"}})),i=s.map((function(e){return{name:"'"+e+"'",token:"text",next:function(e){e.pop()}}})),c="constant.language",k="constant",u="comment",l="xml-pe",b="constant.buildin",m=function(e){return"'"+e+"'"},g={start:[{name:m("(#"),token:b,next:function(e){e.push("Pragma")}},{name:m("(:"),token:"comment",next:function(e){e.push("Comment")}},{name:m("(:~"),token:"comment.doc",next:function(e){e.push("CommentDoc")}},{name:m("\x3c!--"),token:u,next:function(e){e.push("XMLComment")}},{name:m("1&&e.pop()}},{name:m("{"),token:"text",next:function(e){e.push("start")}}].concat(o),_EQName:[{name:"EQName",token:"text",next:function(e){e.pop()}}].concat(i),Prefix:[{name:"NCName",token:"text",next:function(e){e.pop()}}].concat(i),StartTag:[{name:m(">"),token:"meta.tag",next:function(e){e.push("TagContent")}},{name:"QName",token:"entity.other.attribute-name"},{name:m("="),token:"text"},{name:m("''"),token:"string",next:function(e){e.push("AposAttr")}},{name:m('"'),token:"string",next:function(e){e.push("QuotAttr")}},{name:m("/>"),token:"meta.tag.r",next:function(e){e.pop()}}],TagContent:[{name:"ElementContentChar",token:"text"},{name:m(""),token:c,next:function(e){e.pop()}}],PI:[{name:"DirPIContents",token:l},{name:m("?"),token:l},{name:m("?>"),token:l,next:function(e){e.pop()}}],AposString:[{name:m("''"),token:"string",next:function(e){e.pop()}},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:"EscapeApos",token:"constant.language.escape"},{name:"AposChar",token:"string"}],QuotString:[{name:m('"'),token:"string",next:function(e){e.pop()}},{name:"JSONPredefinedCharRef",token:"constant.language.escape"},{name:"JSONCharRef",token:"constant.language.escape"},{name:"JSONChar",token:"string"}]};t.JSONiqLexer=function(){return new r(n,g)}},{"./JSONiqTokenizer":"/node_modules/xqlint/lib/lexers/JSONiqTokenizer.js","./lexer":"/node_modules/xqlint/lib/lexers/lexer.js"}],"/node_modules/xqlint/lib/lexers/lexer.js":[function(e,a,t){"use strict";var n=function(e){var a=e;this.tokens=[],this.reset=function(){this.tokens=[]},this.startNonterminal=function(){},this.endNonterminal=function(){},this.terminal=function(e,t,n){this.tokens.push({name:e,value:a.substring(t,n)})},this.whitespace=function(e,t){this.tokens.push({name:"WS",value:a.substring(e,t)})}};t.Lexer=function(e,a){this.tokens=[],this.getLineTokens=function(t,r){r="start"!==r&&r?r:'["start"]';for(var s=JSON.parse(r),o=new n(t),i=new e(t,o),c=[];;){var k=s[s.length-1];try{o.tokens=[],i["parse_"+k]();var u=null;o.tokens.length>1&&"WS"===o.tokens[0].name&&(c.push({type:"text",value:o.tokens[0].value}),o.tokens.splice(0,1));for(var l=o.tokens[0],b=a[k],m=0;m-1}var i=function(){this.add("string_dquotes","insertion",(function(e,a,t,n,r){if('"'==r||"'"==r){var i=r,c=n.doc.getTextRange(t.getSelectionRange());if(""!==c&&"'"!==c&&'"'!=c&&t.getWrapBehavioursEnabled())return{text:i+c+i,selection:!1};var k=t.getCursorPosition(),u=n.doc.getLine(k.row).substring(k.column,k.column+1),l=new s(n,k.row,k.column),b=l.getCurrentToken();if(u==i&&(o(b,"attribute-value")||o(b,"string")))return{text:"",selection:[1,1]};if(b||(b=l.stepBackward()),!b)return;for(;o(b,"tag-whitespace")||o(b,"whitespace");)b=l.stepBackward();var m=!u||u.match(/\s/);if(o(b,"attribute-equals")&&(m||">"==u)||o(b,"decl-attribute-equals")&&(m||"?"==u))return{text:i+i,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,a,t,n,r){var s=n.doc.getTextRange(r);if(!r.isMultiLine()&&('"'==s||"'"==s)&&n.doc.getLine(r.start.row).substring(r.start.column+1,r.start.column+2)==s)return r.end.column++,r})),this.add("autoclosing","insertion",(function(e,a,t,n,r){if(">"==r){var i=t.getSelectionRange().start,c=new s(n,i.row,i.column),k=c.getCurrentToken()||c.stepBackward();if(!k||!(o(k,"tag-name")||o(k,"tag-whitespace")||o(k,"attribute-name")||o(k,"attribute-equals")||o(k,"attribute-value")))return;if(o(k,"reference.attribute-value"))return;if(o(k,"attribute-value")){var u=c.getCurrentTokenColumn()+k.value.length;if(i.column/.test(n.getLine(i.row).slice(i.column)))return;for(;!o(k,"tag-name");)if("<"==(k=c.stepBackward()).value){k=c.stepForward();break}var b=c.getCurrentTokenRow(),m=c.getCurrentTokenColumn();if(o(c.stepBackward(),"end-tag-open"))return;var g=k.value;if(b==i.row&&(g=g.substring(0,i.column-m)),this.voidElements&&this.voidElements.hasOwnProperty(g.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,a,t,n,r){if("\n"==r){var i=t.getCursorPosition(),c=n.getLine(i.row),k=new s(n,i.row,i.column),u=k.getCurrentToken();if(o(u,"")&&-1!==u.type.indexOf("tag-close")){if("/>"==u.value)return;for(;u&&-1===u.type.indexOf("tag-name");)u=k.stepBackward();if(!u)return;var l=u.value,b=k.getCurrentTokenRow();if(!(u=k.stepBackward())||-1!==u.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[l]||!this.voidElements){var m=n.getTokenAt(i.row,i.column+1),g=(c=n.getLine(b),this.$getIndent(c)),f=g+n.getTabString();return m&&""==r){var s=t.getCursorPosition(),o=new i(n,s.row,s.column),k=o.getCurrentToken(),u=!1;if(e=JSON.parse(e).pop(),k&&">"===k.value||"StartTag"!==e)return;if(k&&(c(k,"meta.tag")||c(k,"text")&&k.value.match("/")))u=!0;else do{k=o.stepBackward()}while(k&&(c(k,"string")||c(k,"keyword.operator")||c(k,"entity.attribute-name")||c(k,"text")));var l=o.stepBackward();if(!k||!c(k,"meta.tag")||null!==l&&l.value.match("/"))return;var b=k.value.substring(1);return u&&(b=b.substring(0,s.column-k.start)),{text:">",selection:[1,1]}}}))};n.inherits(k,r),a.XQueryBehaviour=k})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,a,t){"use strict";var n=e("../../lib/oop"),r=e("../../range").Range,s=e("./fold_mode").FoldMode,o=a.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};n.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,a,t){var n=e.getLine(t);if(this.singleLineBlockCommentRe.test(n)&&!this.startRegionRe.test(n)&&!this.tripleStarBlockCommentRe.test(n))return"";var r=this._getFoldWidgetBase(e,a,t);return!r&&this.startRegionRe.test(n)?"start":r},this.getFoldWidgetRange=function(e,a,t,n){var r,s=e.getLine(t);if(this.startRegionRe.test(s))return this.getCommentRegionBlock(e,s,t);if(r=s.match(this.foldingStartMarker)){var o=r.index;if(r[1])return this.openingBracketBlock(e,r[1],t,o);var i=e.getCommentFoldRange(t,o+r[0].length,1);return i&&!i.isMultiLine()&&(n?i=this.getSectionRange(e,t):"all"!=a&&(i=null)),i}return"markbegin"!==a&&(r=s.match(this.foldingStopMarker))?(o=r.index+r[0].length,r[1]?this.closingBracketBlock(e,r[1],t,o):e.getCommentFoldRange(t,o,-1)):void 0},this.getSectionRange=function(e,a){for(var t=e.getLine(a),n=t.search(/\S/),s=a,o=t.length,i=a+=1,c=e.getLength();++ak)break;var u=this.getFoldWidgetRange(e,"all",a);if(u){if(u.start.row<=s)break;if(u.isMultiLine())a=u.end.row;else if(n==k)break}i=a}}return new r(s,o,i,e.getLine(i).length)},this.getCommentRegionBlock=function(e,a,t){for(var n=a.search(/\s*$/),s=e.getLength(),o=t,i=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,c=1;++to)return new r(o,n,t,a.length)}}.call(o.prototype)})),ace.define("ace/mode/jsoniq",["require","exports","module","ace/worker/worker_client","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/xquery/jsoniq_lexer","ace/range","ace/mode/behaviour/xquery","ace/mode/folding/cstyle","ace/anchor"],(function(e,a,t){"use strict";var n=e("../worker/worker_client").WorkerClient,r=e("../lib/oop"),s=e("./text").Mode,o=e("./text_highlight_rules").TextHighlightRules,i=e("./xquery/jsoniq_lexer").JSONiqLexer,c=e("../range").Range,k=e("./behaviour/xquery").XQueryBehaviour,u=e("./folding/cstyle").FoldMode,l=e("../anchor").Anchor,b=function(){this.$tokenizer=new i,this.$behaviour=new k,this.foldingRules=new u,this.$highlightRules=new o};r.inherits(b,s),function(){this.completer={getCompletions:function(e,a,t,n,r){if(!a.$worker)return r();a.$worker.emit("complete",{data:{pos:t,prefix:n}}),a.$worker.on("complete",(function(e){r(null,e.data)}))}},this.getNextLineIndent=function(e,a,t){var n=this.$getIndent(a);return a.match(/\s*(?:then|else|return|[{\(]|<\w+>)\s*$/)&&(n+=t),n},this.checkOutdent=function(e,a,t){return!!/^\s+$/.test(a)&&/^\s*[\}\)]/.test(t)},this.autoOutdent=function(e,a,t){var n=a.getLine(t).match(/^(\s*[\}\)])/);if(!n)return 0;var r=n[1].length,s=a.findMatchingBracket({row:t,column:r});if(!s||s.row==t)return 0;var o=this.$getIndent(a.getLine(s.row));a.replace(new c(t,0,t,r-1),o)},this.toggleCommentLines=function(e,a,t,n){var r,s,o=!0,i=/^\s*\(:(.*):\)/;for(r=t;r<=n;r++)if(!i.test(a.getLine(r))){o=!1;break}var k=new c(0,0,0,0);for(r=t;r<=n;r++)s=a.getLine(r),k.start.row=r,k.end.row=r,k.end.column=s.length,a.replace(k,o?s.match(i)[1]:"(:"+s+":)")},this.createWorker=function(e){var a=new n(["ace"],"ace/mode/xquery_worker","XQueryWorker"),t=this;return a.attachToDocument(e.getDocument()),a.on("ok",(function(a){e.clearAnnotations()})),a.on("markers",(function(a){e.clearAnnotations(),t.addMarkers(a.data,e)})),a},this.removeMarkers=function(e){var a=e.getMarkers(!1);for(var t in a)0===a[t].clazz.indexOf("language_highlight_")&&e.removeMarker(t);for(var n=0;n|<=|=>|==|~=|=|\\:|\\.\\.\\.|\\.\\."},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+|\\w+"}]},this.normalizeRules()};r.inherits(i,o),t.LuaHighlightRules=i})),ace.define("ace/mode/folding/lua",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./fold_mode").FoldMode,i=e("../../range").Range,a=e("../../token_iterator").TokenIterator,l=t.FoldMode=function(){};r.inherits(l,o),function(){this.foldingStartMarker=/\b(function|then|do|repeat)\b|{\s*$|(\[=*\[)/,this.foldingStopMarker=/\bend\b|^\s*}|\]=*\]/,this.getFoldWidget=function(e,t,n){var r=e.getLine(n),o=this.foldingStartMarker.test(r),i=this.foldingStopMarker.test(r);if(o&&!i){var a;if("then"==(a=r.match(this.foldingStartMarker))[1]&&/\belseif\b/.test(r))return;if(a[1]){if("keyword"===e.getTokenAt(n,a.index+1).type)return"start"}else{if(!a[2])return"start";if("bracketedComment"==(l=e.bgTokenizer.getState(n)||"")[0]||"bracketedString"==l[0])return"start"}}if("markbeginend"!=t||!i||o&&i)return"";if("end"===(a=r.match(this.foldingStopMarker))[0]){if("keyword"===e.getTokenAt(n,a.index+1).type)return"end"}else{if("]"!==a[0][0])return"end";var l;if("bracketedComment"==(l=e.bgTokenizer.getState(n-1)||"")[0]||"bracketedString"==l[0])return"end"}},this.getFoldWidgetRange=function(e,t,n){var r,o=e.doc.getLine(n);return(r=this.foldingStartMarker.exec(o))?r[1]?this.luaBlock(e,n,r.index+1):r[2]?e.getCommentFoldRange(n,r.index+1):this.openingBracketBlock(e,"{",n,r.index):(r=this.foldingStopMarker.exec(o))?"end"===r[0]&&"keyword"===e.getTokenAt(n,r.index+1).type?this.luaBlock(e,n,r.index+1):"]"===r[0][0]?e.getCommentFoldRange(n,r.index+1):this.closingBracketBlock(e,"}",n,r.index+r[0].length):void 0},this.luaBlock=function(e,t,n,r){var o=new a(e,t,n),l={function:1,do:1,then:1,elseif:-1,end:-1,repeat:1,until:-1},s=o.getCurrentToken();if(s&&"keyword"==s.type){var u=s.value,g=[u],d=l[u];if(d){var c=-1===d?o.getCurrentTokenColumn():e.getLine(t).length,h=t;for(o.step=-1===d?o.stepBackward:o.stepForward;s=o.step();)if("keyword"===s.type){var f=d*l[s.value];if(f>0)g.unshift(s.value);else if(f<=0){if(g.shift(),!g.length&&"elseif"!=s.value)break;0===f&&g.unshift(s.value)}}return s?r?o.getCurrentTokenRange():(t=o.getCurrentTokenRow(),-1===d?new i(t,e.getLine(t).length,h,c):new i(h,c,t,o.getCurrentTokenColumn())):null}}}}.call(l.prototype)})),ace.define("ace/mode/lua",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/lua_highlight_rules","ace/mode/folding/lua","ace/range","ace/worker/worker_client"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,i=e("./lua_highlight_rules").LuaHighlightRules,a=e("./folding/lua").FoldMode,l=e("../range").Range,s=e("../worker/worker_client").WorkerClient,u=function(){this.HighlightRules=i,this.foldingRules=new a,this.$behaviour=this.$defaultBehaviour};r.inherits(u,o),function(){this.lineCommentStart="--",this.blockComment={start:"--[[",end:"--]]"};var e={function:1,then:1,do:1,else:1,elseif:1,repeat:1,end:-1,until:-1},t=["else","elseif","end","until"];this.getNextLineIndent=function(t,n,r){var o=this.$getIndent(n),i=0,a=this.getTokenizer().getLineTokens(n,t).tokens;return"start"==t&&(i=function(t){for(var n=0,r=0;r0?1:0}(a)),i>0?o+r:i<0&&o.substr(o.length-r.length)==r&&!this.checkOutdent(t,n,"\n")?o.substr(0,o.length-r.length):o},this.checkOutdent=function(e,n,r){if("\n"!=r&&"\r"!=r&&"\r\n"!=r)return!1;if(n.match(/^\s*[\)\}\]]$/))return!0;var o=this.getTokenizer().getLineTokens(n.trim(),e).tokens;return!(!o||!o.length)&&"keyword"==o[0].type&&-1!=t.indexOf(o[0].value)},this.getMatching=function(t,n,r){if(null==n){var o=t.selection.lead;r=o.column,n=o.row}var i=t.getTokenAt(n,r);if(i&&i.value in e)return this.foldingRules.luaBlock(t,n,r,!0)},this.autoOutdent=function(e,t,n){var r=t.getLine(n).match(/^\s*/)[0].length;if(r&&n){var o=this.getMatching(t,n,r+1);if(o&&o.start.row!=n){var i=this.$getIndent(t.getLine(o.start.row));i.length!=r&&(t.replace(new l(n,0,n,r),i),t.outdentRows(new l(n+1,0,n+1,0)))}}},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/lua_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/lua",this.snippetFileId="ace/snippets/lua"}.call(u.prototype),t.Mode=u})),ace.require(["ace/mode/lua"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/ecdb4966f685f3e44b1f28fae46827a3.js b/ecdb4966f685f3e44b1f28fae46827a3.js new file mode 100644 index 00000000..2e67b253 --- /dev/null +++ b/ecdb4966f685f3e44b1f28fae46827a3.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/logiql"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/ecff3d4bbf59ef41230960af46098e74.js b/ecff3d4bbf59ef41230960af46098e74.js new file mode 100644 index 00000000..16a83710 --- /dev/null +++ b/ecff3d4bbf59ef41230960af46098e74.js @@ -0,0 +1 @@ +ace.define("ace/theme/github_dark-css",["require","exports","module"],(function(a,e,c){c.exports=".ace-github-dark .ace_gutter {\n background: #24292e;\n color: #7388b5\n}\n\n.ace-github-dark .ace_print-margin {\n width: 1px;\n background: #00204b\n}\n\n.ace-github-dark {\n background-color: #24292e;\n color: #FFFFFF\n}\n\n.ace-github-dark .ace_constant.ace_other,\n.ace-github-dark .ace_cursor {\n color: #FFFFFF\n}\n\n.ace-github-dark .ace_marker-layer .ace_selection {\n background: #003F8E\n}\n\n.ace-github-dark.ace_multiselect .ace_selection.ace_start {\n box-shadow: 0 0 3px 0px #24292e;\n}\n\n.ace-github-dark .ace_marker-layer .ace_step {\n background: rgb(127, 111, 19)\n}\n\n.ace-github-dark .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #404F7D\n}\n\n.ace-github-dark .ace_marker-layer .ace_active-line {\n background: #00346E\n}\n\n.ace-github-dark .ace_gutter-active-line {\n background-color: #24292e\n}\n\n.ace-github-dark .ace_marker-layer .ace_selected-word {\n border: 1px solid #003F8E\n}\n\n.ace-github-dark .ace_invisible {\n color: #404F7D\n}\n\n.ace-github-dark .ace_keyword,\n.ace-github-dark .ace_meta,\n.ace-github-dark .ace_storage,\n.ace-github-dark .ace_storage.ace_type,\n.ace-github-dark .ace_support.ace_type {\n color: #ff7b72\n}\n\n.ace-github-dark .ace_keyword.ace_operator {\n color: #79c0ff\n}\n\n.ace-github-dark .ace_constant.ace_character,\n.ace-github-dark .ace_constant.ace_language,\n.ace-github-dark .ace_constant.ace_numeric,\n.ace-github-dark .ace_keyword.ace_other.ace_unit,\n.ace-github-dark .ace_support.ace_constant,\n.ace-github-dark .ace_variable.ace_parameter {\n color: #FFC58F\n}\n\n.ace-github-dark .ace_invalid {\n color: #FFFFFF;\n background-color: #F99DA5\n}\n\n.ace-github-dark .ace_invalid.ace_deprecated {\n color: #FFFFFF;\n background-color: #ff7b72\n}\n\n.ace-github-dark .ace_fold {\n background-color: #BBDAFF;\n border-color: #FFFFFF\n}\n\n.ace-github-dark .ace_entity.ace_name.ace_function,\n.ace-github-dark .ace_support.ace_function,\n.ace-github-dark .ace_variable {\n color: #BBDAFF\n}\n\n.ace-github-dark .ace_support.ace_class,\n.ace-github-dark .ace_support.ace_type {\n color: #FFEEAD\n}\n\n.ace-github-dark .ace_heading,\n.ace-github-dark .ace_markup.ace_heading,\n.ace-github-dark .ace_string {\n color: #9fcef6\n}\n\n.ace-github-dark .ace_entity.ace_name.ace_tag,\n.ace-github-dark .ace_entity.ace_other.ace_attribute-name,\n.ace-github-dark .ace_meta.ace_tag,\n.ace-github-dark .ace_string.ace_regexp,\n.ace-github-dark .ace_variable {\n color: #FF9DA4\n}\n\n.ace-github-dark .ace_comment {\n color: #7285B7\n}\n\n.ace-github-dark .ace_indent-guide {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYJDzqfwPAANXAeNsiA+ZAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-github-dark .ace_indent-guide-active {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n\n.ace-github-dark .ace_constant.ace_buildin {\n color: #0086B3;\n}\n\n.ace-github-dark .ace_variable.ace_language {\n color: #ffffff;\n}\n "})),ace.define("ace/theme/github_dark",["require","exports","module","ace/theme/github_dark-css","ace/lib/dom"],(function(a,e,c){e.isDark=!0,e.cssClass="ace-github-dark",e.cssText=a("./github_dark-css"),a("../lib/dom").importCssString(e.cssText,e.cssClass,!1)})),ace.require(["ace/theme/github_dark"],(function(a){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=a)})); \ No newline at end of file diff --git a/ee41eb1fd1d1c87c45e818b5a8a65cf8.js b/ee41eb1fd1d1c87c45e818b5a8a65cf8.js new file mode 100644 index 00000000..5cc71fb4 --- /dev/null +++ b/ee41eb1fd1d1c87c45e818b5a8a65cf8.js @@ -0,0 +1 @@ +ace.define("ace/theme/tomorrow_night_eighties-css",["require","exports","module"],(function(e,o,n){n.exports=".ace-tomorrow-night-eighties .ace_gutter {\n background: #272727;\n color: #CCC\n}\n\n.ace-tomorrow-night-eighties .ace_print-margin {\n width: 1px;\n background: #272727\n}\n\n.ace-tomorrow-night-eighties {\n background-color: #2D2D2D;\n color: #CCCCCC\n}\n\n.ace-tomorrow-night-eighties .ace_constant.ace_other,\n.ace-tomorrow-night-eighties .ace_cursor {\n color: #CCCCCC\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_selection {\n background: #515151\n}\n\n.ace-tomorrow-night-eighties.ace_multiselect .ace_selection.ace_start {\n box-shadow: 0 0 3px 0px #2D2D2D;\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_step {\n background: rgb(102, 82, 0)\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #6A6A6A\n}\n\n.ace-tomorrow-night-bright .ace_stack {\n background: rgb(66, 90, 44)\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_active-line {\n background: #393939\n}\n\n.ace-tomorrow-night-eighties .ace_gutter-active-line {\n background-color: #393939\n}\n\n.ace-tomorrow-night-eighties .ace_marker-layer .ace_selected-word {\n border: 1px solid #515151\n}\n\n.ace-tomorrow-night-eighties .ace_invisible {\n color: #6A6A6A\n}\n\n.ace-tomorrow-night-eighties .ace_keyword,\n.ace-tomorrow-night-eighties .ace_meta,\n.ace-tomorrow-night-eighties .ace_storage,\n.ace-tomorrow-night-eighties .ace_storage.ace_type,\n.ace-tomorrow-night-eighties .ace_support.ace_type {\n color: #CC99CC\n}\n\n.ace-tomorrow-night-eighties .ace_keyword.ace_operator {\n color: #66CCCC\n}\n\n.ace-tomorrow-night-eighties .ace_constant.ace_character,\n.ace-tomorrow-night-eighties .ace_constant.ace_language,\n.ace-tomorrow-night-eighties .ace_constant.ace_numeric,\n.ace-tomorrow-night-eighties .ace_keyword.ace_other.ace_unit,\n.ace-tomorrow-night-eighties .ace_support.ace_constant,\n.ace-tomorrow-night-eighties .ace_variable.ace_parameter {\n color: #F99157\n}\n\n.ace-tomorrow-night-eighties .ace_invalid {\n color: #CDCDCD;\n background-color: #F2777A\n}\n\n.ace-tomorrow-night-eighties .ace_invalid.ace_deprecated {\n color: #CDCDCD;\n background-color: #CC99CC\n}\n\n.ace-tomorrow-night-eighties .ace_fold {\n background-color: #6699CC;\n border-color: #CCCCCC\n}\n\n.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_function,\n.ace-tomorrow-night-eighties .ace_support.ace_function,\n.ace-tomorrow-night-eighties .ace_variable {\n color: #6699CC\n}\n\n.ace-tomorrow-night-eighties .ace_support.ace_class,\n.ace-tomorrow-night-eighties .ace_support.ace_type {\n color: #FFCC66\n}\n\n.ace-tomorrow-night-eighties .ace_heading,\n.ace-tomorrow-night-eighties .ace_markup.ace_heading,\n.ace-tomorrow-night-eighties .ace_string {\n color: #99CC99\n}\n\n.ace-tomorrow-night-eighties .ace_comment {\n color: #999999\n}\n\n.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_tag,\n.ace-tomorrow-night-eighties .ace_entity.ace_other.ace_attribute-name,\n.ace-tomorrow-night-eighties .ace_meta.ace_tag,\n.ace-tomorrow-night-eighties .ace_variable {\n color: #F2777A\n}\n\n.ace-tomorrow-night-eighties .ace_indent-guide {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ09NrYAgMjP4PAAtGAwchHMyAAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-tomorrow-night-eighties .ace_indent-guide-active {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n"})),ace.define("ace/theme/tomorrow_night_eighties",["require","exports","module","ace/theme/tomorrow_night_eighties-css","ace/lib/dom"],(function(e,o,n){o.isDark=!0,o.cssClass="ace-tomorrow-night-eighties",o.cssText=e("./tomorrow_night_eighties-css"),e("../lib/dom").importCssString(o.cssText,o.cssClass,!1)})),ace.require(["ace/theme/tomorrow_night_eighties"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/ee5d36473f84db2af26d82efd69a38ec.js b/ee5d36473f84db2af26d82efd69a38ec.js new file mode 100644 index 00000000..b1dd5425 --- /dev/null +++ b/ee5d36473f84db2af26d82efd69a38ec.js @@ -0,0 +1 @@ +ace.define("ace/theme/cobalt-css",["require","exports","module"],(function(a,c,e){e.exports=".ace-cobalt .ace_gutter {\n background: #011e3a;\n color: rgb(128,145,160)\n}\n\n.ace-cobalt .ace_print-margin {\n width: 1px;\n background: #555555\n}\n\n.ace-cobalt {\n background-color: #002240;\n color: #FFFFFF\n}\n\n.ace-cobalt .ace_cursor {\n color: #FFFFFF\n}\n\n.ace-cobalt .ace_marker-layer .ace_selection {\n background: rgba(179, 101, 57, 0.75)\n}\n\n.ace-cobalt.ace_multiselect .ace_selection.ace_start {\n box-shadow: 0 0 3px 0px #002240;\n}\n\n.ace-cobalt .ace_marker-layer .ace_step {\n background: rgb(127, 111, 19)\n}\n\n.ace-cobalt .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 255, 255, 0.15)\n}\n\n.ace-cobalt .ace_marker-layer .ace_active-line {\n background: rgba(0, 0, 0, 0.35)\n}\n\n.ace-cobalt .ace_gutter-active-line {\n background-color: rgba(0, 0, 0, 0.35)\n}\n\n.ace-cobalt .ace_marker-layer .ace_selected-word {\n border: 1px solid rgba(179, 101, 57, 0.75)\n}\n\n.ace-cobalt .ace_invisible {\n color: rgba(255, 255, 255, 0.15)\n}\n\n.ace-cobalt .ace_keyword,\n.ace-cobalt .ace_meta {\n color: #FF9D00\n}\n\n.ace-cobalt .ace_constant,\n.ace-cobalt .ace_constant.ace_character,\n.ace-cobalt .ace_constant.ace_character.ace_escape,\n.ace-cobalt .ace_constant.ace_other {\n color: #FF628C\n}\n\n.ace-cobalt .ace_invalid {\n color: #F8F8F8;\n background-color: #800F00\n}\n\n.ace-cobalt .ace_support {\n color: #80FFBB\n}\n\n.ace-cobalt .ace_support.ace_constant {\n color: #EB939A\n}\n\n.ace-cobalt .ace_fold {\n background-color: #FF9D00;\n border-color: #FFFFFF\n}\n\n.ace-cobalt .ace_support.ace_function {\n color: #FFB054\n}\n\n.ace-cobalt .ace_storage {\n color: #FFEE80\n}\n\n.ace-cobalt .ace_entity {\n color: #FFDD00\n}\n\n.ace-cobalt .ace_string {\n color: #3AD900\n}\n\n.ace-cobalt .ace_string.ace_regexp {\n color: #80FFC2\n}\n\n.ace-cobalt .ace_comment {\n font-style: italic;\n color: #0088FF\n}\n\n.ace-cobalt .ace_heading,\n.ace-cobalt .ace_markup.ace_heading {\n color: #C8E4FD;\n background-color: #001221\n}\n\n.ace-cobalt .ace_list,\n.ace-cobalt .ace_markup.ace_list {\n background-color: #130D26\n}\n\n.ace-cobalt .ace_variable {\n color: #CCCCCC\n}\n\n.ace-cobalt .ace_variable.ace_language {\n color: #FF80E1\n}\n\n.ace-cobalt .ace_meta.ace_tag {\n color: #9EFFFF\n}\n\n.ace-cobalt .ace_indent-guide {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHCLSvkPAAP3AgSDTRd4AAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-cobalt .ace_indent-guide-active {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n"})),ace.define("ace/theme/cobalt",["require","exports","module","ace/theme/cobalt-css","ace/lib/dom"],(function(a,c,e){c.isDark=!0,c.cssClass="ace-cobalt",c.cssText=a("./cobalt-css"),a("../lib/dom").importCssString(c.cssText,c.cssClass,!1)})),ace.require(["ace/theme/cobalt"],(function(a){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=a)})); \ No newline at end of file diff --git a/ef87482c92662e8b69a21f47588474ea.js b/ef87482c92662e8b69a21f47588474ea.js new file mode 100644 index 00000000..0d3a0f1a --- /dev/null +++ b/ef87482c92662e8b69a21f47588474ea.js @@ -0,0 +1 @@ +ace.define("ace/snippets/velocity.snippets",["require","exports","module"],(function(e,t,n){n.exports='# macro\nsnippet #macro\n\t#macro ( ${1:macroName} ${2:\\$var1, [\\$var2, ...]} )\n\t\t${3:## macro code}\n\t#end\n# foreach\nsnippet #foreach\n\t#foreach ( ${1:\\$item} in ${2:\\$collection} )\n\t\t${3:## foreach code}\n\t#end\n# if\nsnippet #if\n\t#if ( ${1:true} )\n\t\t${0}\n\t#end\n# if ... else\nsnippet #ife\n\t#if ( ${1:true} )\n\t\t${2}\n\t#else\n\t\t${0}\n\t#end\n#import\nsnippet #import\n\t#import ( "${1:path/to/velocity/format}" )\n# set\nsnippet #set\n\t#set ( $${1:var} = ${0} )\n'})),ace.define("ace/snippets/velocity",["require","exports","module","ace/snippets/velocity.snippets"],(function(e,t,n){"use strict";t.snippetText=e("./velocity.snippets"),t.scope="velocity",t.includeScopes=["html","javascript","css"]})),ace.require(["ace/snippets/velocity"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/efc14cdf19554635e477781704353ec2.js b/efc14cdf19554635e477781704353ec2.js new file mode 100644 index 00000000..65bc72cc --- /dev/null +++ b/efc14cdf19554635e477781704353ec2.js @@ -0,0 +1 @@ +ace.require(["ace/snippets/aql"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/eff4371180dfac54de25ed3a0105d82f.js b/eff4371180dfac54de25ed3a0105d82f.js new file mode 100644 index 00000000..c0d59f5c --- /dev/null +++ b/eff4371180dfac54de25ed3a0105d82f.js @@ -0,0 +1 @@ +ace.define("ace/snippets/django.snippets",["require","exports","module"],(function(e,t,n){n.exports="# Model Fields\n\n# Note: Optional arguments are using defaults that match what Django will use\n# as a default, e.g. with max_length fields. Doing this as a form of self\n# documentation and to make it easy to know whether you should override the\n# default or not.\n\n# Note: Optional arguments that are booleans will use the opposite since you\n# can either not specify them, or override them, e.g. auto_now_add=False.\n\nsnippet auto\n\t${1:FIELDNAME} = models.AutoField(${2})\nsnippet bool\n\t${1:FIELDNAME} = models.BooleanField(${2:default=True})\nsnippet char\n\t${1:FIELDNAME} = models.CharField(max_length=${2}${3:, blank=True})\nsnippet comma\n\t${1:FIELDNAME} = models.CommaSeparatedIntegerField(max_length=${2}${3:, blank=True})\nsnippet date\n\t${1:FIELDNAME} = models.DateField(${2:auto_now_add=True, auto_now=True}${3:, blank=True, null=True})\nsnippet datetime\n\t${1:FIELDNAME} = models.DateTimeField(${2:auto_now_add=True, auto_now=True}${3:, blank=True, null=True})\nsnippet decimal\n\t${1:FIELDNAME} = models.DecimalField(max_digits=${2}, decimal_places=${3})\nsnippet email\n\t${1:FIELDNAME} = models.EmailField(max_length=${2:75}${3:, blank=True})\nsnippet file\n\t${1:FIELDNAME} = models.FileField(upload_to=${2:path/for/upload}${3:, max_length=100})\nsnippet filepath\n\t${1:FIELDNAME} = models.FilePathField(path=${2:\"/abs/path/to/dir\"}${3:, max_length=100}${4:, match=\"*.ext\"}${5:, recursive=True}${6:, blank=True, })\nsnippet float\n\t${1:FIELDNAME} = models.FloatField(${2})\nsnippet image\n\t${1:FIELDNAME} = models.ImageField(upload_to=${2:path/for/upload}${3:, height_field=height, width_field=width}${4:, max_length=100})\nsnippet int\n\t${1:FIELDNAME} = models.IntegerField(${2})\nsnippet ip\n\t${1:FIELDNAME} = models.IPAddressField(${2})\nsnippet nullbool\n\t${1:FIELDNAME} = models.NullBooleanField(${2})\nsnippet posint\n\t${1:FIELDNAME} = models.PositiveIntegerField(${2})\nsnippet possmallint\n\t${1:FIELDNAME} = models.PositiveSmallIntegerField(${2})\nsnippet slug\n\t${1:FIELDNAME} = models.SlugField(max_length=${2:50}${3:, blank=True})\nsnippet smallint\n\t${1:FIELDNAME} = models.SmallIntegerField(${2})\nsnippet text\n\t${1:FIELDNAME} = models.TextField(${2:blank=True})\nsnippet time\n\t${1:FIELDNAME} = models.TimeField(${2:auto_now_add=True, auto_now=True}${3:, blank=True, null=True})\nsnippet url\n\t${1:FIELDNAME} = models.URLField(${2:verify_exists=False}${3:, max_length=200}${4:, blank=True})\nsnippet xml\n\t${1:FIELDNAME} = models.XMLField(schema_path=${2:None}${3:, blank=True})\n# Relational Fields\nsnippet fk\n\t${1:FIELDNAME} = models.ForeignKey(${2:OtherModel}${3:, related_name=''}${4:, limit_choices_to=}${5:, to_field=''})\nsnippet m2m\n\t${1:FIELDNAME} = models.ManyToManyField(${2:OtherModel}${3:, related_name=''}${4:, limit_choices_to=}${5:, symmetrical=False}${6:, through=''}${7:, db_table=''})\nsnippet o2o\n\t${1:FIELDNAME} = models.OneToOneField(${2:OtherModel}${3:, parent_link=True}${4:, related_name=''}${5:, limit_choices_to=}${6:, to_field=''})\n\n# Code Skeletons\n\nsnippet form\n\tclass ${1:FormName}(forms.Form):\n\t\t\"\"\"${2:docstring}\"\"\"\n\t\t${3}\n\nsnippet model\n\tclass ${1:ModelName}(models.Model):\n\t\t\"\"\"${2:docstring}\"\"\"\n\t\t${3}\n\t\t\n\t\tclass Meta:\n\t\t\t${4}\n\t\t\n\t\tdef __unicode__(self):\n\t\t\t${5}\n\t\t\n\t\tdef save(self, force_insert=False, force_update=False):\n\t\t\t${6}\n\t\t\n\t\t@models.permalink\n\t\tdef get_absolute_url(self):\n\t\t\treturn ('${7:view_or_url_name}' ${8})\n\nsnippet modeladmin\n\tclass ${1:ModelName}Admin(admin.ModelAdmin):\n\t\t${2}\n\t\n\tadmin.site.register($1, $1Admin)\n\t\nsnippet tabularinline\n\tclass ${1:ModelName}Inline(admin.TabularInline):\n\t\tmodel = $1\n\nsnippet stackedinline\n\tclass ${1:ModelName}Inline(admin.StackedInline):\n\t\tmodel = $1\n\nsnippet r2r\n\treturn render_to_response('${1:template.html}', {\n\t\t\t${2}\n\t\t}${3:, context_instance=RequestContext(request)}\n\t)\n"})),ace.define("ace/snippets/django",["require","exports","module","ace/snippets/django.snippets"],(function(e,t,n){"use strict";t.snippetText=e("./django.snippets"),t.scope="django"})),ace.require(["ace/snippets/django"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/es/index.html b/es/index.html new file mode 100644 index 00000000..7fb64274 --- /dev/null +++ b/es/index.html @@ -0,0 +1,426 @@ + + + + + + + Simulación de trazado de rayos - PhyDemo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +

    Simulación de trazado de rayos

    +

    + Crear y simular escenas 2D de óptica geométrica de manera interactiva.
    Totalmente gratuito y basado en web. El código fuente está disponible en GitHub. +

    +

    + Iniciar simulador +

    +
    +
    + + +
    +
    +
    +

    Herramientas

    +
    + Rayo único +
    +

    Rayo único

    + Un único rayo de luz definido mediante dos puntos. +
    +
    +
    + Haz +
    +

    Haz

    + Un haz de rayos paralelo o divergente emerge de un segmento de recta, con una densidad controlada por el deslizante 'Densidad de rayos' +
    +
    +
    + Fuente puntual +
    +

    Fuente puntual

    + Los rayos emergen de un único punto, con un número controlado por el deslizante 'Densidad de rayos'. +
    +
    +
    + Espejo +
    +

    Espejo

    + Simular la reflexión de la luz en un espejo. +
    +
    +
    + Espejo (Curvado) +
    +

    Espejo (Curvado)

    + Un espejo cuya forma es curva. Puede ser circular, parabólico o definido mediante una ecuación de la forma y = f(x). +
    +
    +
    + Curvo ideal +
    +

    Curvo ideal

    + Un espejo 'curvo' ideal que obedece exactamente la ecuación del espejo (1/p + 1/q = 1/f). La longitud focal puede establecerse directamente. +
    +
    +
    + Separador de haz +
    +

    Separador de haz

    + Un espejo que transmite un porcentaje de la luz incidente. +
    +
    +
    + Vidrio +
    +

    Vidrio

    + Simular la refracción y la reflexión de luz sobre una superficie. +
    +
    +
    + Vidrio (Otras formas) +
    +

    Vidrio (Otras formas)

    + Vidrio con otras formas construidas a partir de segmentos de lineas y arcos, o formas definidas mediante una desigualdad de la forma f(x) < y < g(x). +
    +
    +
    + Polígono con gradiente de índice +
    +

    Polígono con gradiente de índice

    + Material with a custom refractive index function n(x,y). +
    +
    +
    + Lente ideal +
    +

    Lente ideal

    + Una lente ideal que obedece exactamente la ecuación de las lentes delgadas (1/p + 1/q = 1/f). La longitud focal se puede establecer directamente. +
    +
    +
    + Bloqueador +
    +

    Bloqueador

    + Un bloqueador de luz recto que absorbe los rayos incidentes. +
    +
    +
    + Diffraction Grating +
    +

    Diffraction Grating

    + A diffraction grating that splits light at an angle depending on wavelength. +
    +
    +
    + Regla +
    +

    Regla

    + Una regla desde un punto cero hasta otro punto. +
    +
    +
    + Transportador +
    +

    Transportador

    + Un transportador definido desde el centro y otro punto para la dirección cero. La escala está en grados. +
    +
    +
    + Detector +
    +

    Detector

    + Una herramienta para medir el flujo de energía (P), el momento perpendicular de flujo (F⊥), y el momento paralelo de flujo (F∥) a través de un segmento de recta. Las unidades son arbitrarias. +
    +
    +
    +
    +
    +
    +

    Vista

    +
    +
    +

    Rayos

    + Mostrar los rayos. Cuando la 'Densidad de rayos' es elevada, estos parecen continuos. +
    +
    +
    + Rayos +
    +
    + Rayos +
    +
    +
    +
    +
    +

    Rayos extendidos

    + Mostrar los rayos y su extensión. El color naranja indica extensiones hacia atrás, y el gris indica hacia delante. +
    +
    +
    + Rayos extendidos +
    +
    +
    +
    +
    +

    Todas las imágenes

    + Mostrar la posición de todas las imágenes. Los puntos amarillos indican imágenes reales, naranjas indican imágenes virtuales, y grises (ninguno en esta figura) indican objetos virtuales. Cabe notar que algunas imágenes no se pueden detectar si 'Densidad de rayos' no es suficientemente elevada. +
    +
    +
    + Todas las imágenes +
    +
    +
    +
    +
    +

    Visto por el observador

    + Simular los rayos y las imágenes vistos desde una posición. El circulo azul es el observador. Cualquier rayo que lo cruce se considera 'observado'. El observador no sabe donde inician los rayos, pero puede pensar que tienen inicio en algún(os) punto(s) si se intersectan ahí. Los rayos se muestran en azul, y los puntos en amarillo (reales) o naranja (virtuales). +
    +
    +
    + Visto por el observador +
    +
    +
    +
    +
    +

    Simular colores

    + Simular colores (longitudes de onda), mezclas de colores, filtros de color de bloqueadores y espejos y dispersión cromática de vidrios. +
    +
    +
    + Simular colores +
    +
    +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/f13b8474637a47ca4401e1674e391466.js b/f13b8474637a47ca4401e1674e391466.js new file mode 100644 index 00000000..74a525c0 --- /dev/null +++ b/f13b8474637a47ca4401e1674e391466.js @@ -0,0 +1 @@ +ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};r.inherits(a,o),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[o.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[o.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(o,"doc-",[o.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r="/"==e.charAt(1)?2:1;return 1==r?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==r&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==r?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[o.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[o.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}r.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var r=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,a=e.findMatchingBracket({row:t,column:o});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new r(t,0,t,o-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,r,o){if('"'==o||"'"==o){var s=o,l=r.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),g=r.doc.getLine(c.row).substring(c.column,c.column+1),u=new a(r,c.row,c.column),d=u.getCurrentToken();if(g==s&&(i(d,"attribute-value")||i(d,"string")))return{text:"",selection:[1,1]};if(d||(d=u.stepBackward()),!d)return;for(;i(d,"tag-whitespace")||i(d,"whitespace");)d=u.stepBackward();var p=!g||g.match(/\s/);if(i(d,"attribute-equals")&&(p||">"==g)||i(d,"decl-attribute-equals")&&(p||"?"==g))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,r,o){var a=r.doc.getTextRange(o);if(!o.isMultiLine()&&('"'==a||"'"==a)&&r.doc.getLine(o.start.row).substring(o.start.column+1,o.start.column+2)==a)return o.end.column++,o})),this.add("autoclosing","insertion",(function(e,t,n,r,o){if(">"==o){var s=n.getSelectionRange().start,l=new a(r,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var g=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(r.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var d=l.getCurrentTokenRow(),p=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var h=c.value;if(d==s.row&&(h=h.substring(0,s.column-p)),this.voidElements&&this.voidElements.hasOwnProperty(h.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,r,o){if("\n"==o){var s=n.getCursorPosition(),l=r.getLine(s.row),c=new a(r,s.row,s.column),g=c.getCurrentToken();if(i(g,"")&&-1!==g.type.indexOf("tag-close")){if("/>"==g.value)return;for(;g&&-1===g.type.indexOf("tag-name");)g=c.stepBackward();if(!g)return;var u=g.value,d=c.getCurrentTokenRow();if(!(g=c.stepBackward())||-1!==g.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[u]||!this.voidElements){var p=r.getTokenAt(s.row,s.column+1),h=(l=r.getLine(d),this.$getIndent(l)),x=h+r.getTabString();return p&&""==a){var i=n.getSelectionRange().start,s=new o(r,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};r.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?"markbeginend"===t?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())||this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return r}if(l(a,"tag-close"))return r.selfClosing="/>"==a.value,r;r.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,r){for(var o=e.getTokens(t),a=0,i=0;ic)break;var g=this.getFoldWidgetRange(e,"all",t);if(g){if(g.start.row<=a)break;if(g.isMultiLine())t=g.end.row;else if(r==c)break}s=t}}return new o(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var r=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new o(i,r,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new o};r.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,r){return this.getFoldWidgetRangeBase(e,t,n,r)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,g=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};r.inherits(g,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e),a=o.tokens,i=o.state;if(a.length&&"comment"==a[a.length-1].type)return r;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(r+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(g.prototype),t.Mode=g})),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}]}};r.inherits(a,o),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=a})),ace.define("ace/mode/groovy_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./doc_comment_highlight_rules").DocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i=function(){var e=this.createKeywordMapper({"variable.language":"this",keyword:"assert|with|abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|def|float|native|super|while","support.function":"AbstractMethodError|AssertionError|ClassCircularityError|ClassFormatError|Deprecated|EnumConstantNotPresentException|ExceptionInInitializerError|IllegalAccessError|IllegalThreadStateException|InstantiationError|InternalError|NegativeArraySizeException|NoSuchFieldError|Override|Process|ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|SuppressWarnings|TypeNotPresentException|UnknownError|UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|InstantiationException|IndexOutOfBoundsException|ArrayIndexOutOfBoundsException|CloneNotSupportedException|NoSuchFieldException|IllegalArgumentException|NumberFormatException|SecurityException|Void|InheritableThreadLocal|IllegalStateException|InterruptedException|NoSuchMethodException|IllegalAccessException|UnsupportedOperationException|Enum|StrictMath|Package|Compiler|Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|Character|Boolean|StackTraceElement|Appendable|StringBuffer|Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|StackOverflowError|OutOfMemoryError|VirtualMachineError|ArrayStoreException|ClassCastException|LinkageError|NoClassDefFoundError|ClassNotFoundException|RuntimeException|Exception|ThreadDeath|Error|Throwable|System|ClassLoader|Cloneable|Class|CharSequence|Comparable|String|Object","constant.language":"null|Infinity|NaN|undefined"},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},o.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'"""',next:"qqstring"},{token:"string",regex:"'''",next:"qstring"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\?:|\\?\\.|\\*\\.|<=>|=~|==~|\\.@|\\*\\.@|\\.&|as|in|is|!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:/\\(?:u[0-9A-Fa-f]{4}|.|$)/},{token:"constant.language.escape",regex:/\$[\w\d]+/},{token:"constant.language.escape",regex:/\$\{[^"\}]+\}?/},{token:"string",regex:'"{3,5}',next:"start"},{token:"string",regex:".+?"}],qstring:[{token:"constant.language.escape",regex:/\\(?:u[0-9A-Fa-f]{4}|.|$)/},{token:"string",regex:"'{3,5}",next:"start"},{token:"string",regex:".+?"}]},this.embedRules(o,"doc-",[o.getEndRule("start")])};r.inherits(i,a),t.GroovyHighlightRules=i})),ace.define("ace/mode/groovy",["require","exports","module","ace/lib/oop","ace/mode/javascript","ace/mode/groovy_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./javascript").Mode,a=e("./groovy_highlight_rules").GroovyHighlightRules,i=function(){o.call(this),this.HighlightRules=a,this.$behaviour=this.$defaultBehaviour};r.inherits(i,o),function(){this.createWorker=function(e){return null},this.$id="ace/mode/groovy"}.call(i.prototype),t.Mode=i})),ace.require(["ace/mode/groovy"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/f15362a7feef894b2e7f706252e6c510.js b/f15362a7feef894b2e7f706252e6c510.js new file mode 100644 index 00000000..499eb283 --- /dev/null +++ b/f15362a7feef894b2e7f706252e6c510.js @@ -0,0 +1 @@ +ace.define("ace/ext/simple_tokenizer",["require","exports","module","ace/tokenizer","ace/layer/text_util"],(function(e,t,n){"use strict";var i=e("../tokenizer").Tokenizer,o=e("../layer/text_util").isTextToken,r=function(){function e(e,t){this._lines=e.split(/\r\n|\r|\n/),this._states=[],this._tokenizer=t}return e.prototype.getTokens=function(e){var t=this._lines[e],n=this._states[e-1],i=this._tokenizer.getLineTokens(t,n);return this._states[e]=i.state,i.tokens},e.prototype.getLength=function(){return this._lines.length},e}();n.exports={tokenize:function(e,t){for(var n=new r(e,new i(t.getRules())),s=[],u=0;ug){var l=e.getLine(c).length;return new n(g,s,c,l)}}},this.getFoldWidgetRange=function(e,t,o){var r=this.indentationBlock(e,o);return r||(r=this.commentBlock(e,o))||void 0},this.getFoldWidget=function(e,t,o){var r=e.getLine(o),i=r.search(/\S/),n=e.getLine(o+1),s=e.getLine(o-1),a=s.search(/\S/),g=n.search(/\S/);if(-1==i)return e.foldWidgets[o-1]=-1!=a&&a'+n.command+' : '+n.key+""}),"");r.id="kbshortcutmenu",r.innerHTML="

    Keyboard Shortcuts

    "+a+"",o(n,r)}}(this)},n.commands.addCommands([{name:"showKeyboardShortcuts",bindKey:{win:"Ctrl-Alt-h",mac:"Command-Alt-h"},exec:function(e,n){e.showKeyboardShortcuts()}}])}})),ace.require(["ace/ext/keybinding_menu"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/f6b33aded7ae7504bfcc4550925cccb0.js b/f6b33aded7ae7504bfcc4550925cccb0.js new file mode 100644 index 00000000..b19f832b --- /dev/null +++ b/f6b33aded7ae7504bfcc4550925cccb0.js @@ -0,0 +1 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,i){"use strict";var o=e("../lib/oop"),n=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}]}};o.inherits(a,n),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=a})),ace.define("ace/mode/edifact_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,i){"use strict";var o=e("../lib/oop"),n=e("./doc_comment_highlight_rules").DocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,r=function(){var e=this.createKeywordMapper({"variable.language":"this",keyword:"BY|SE|ON|INV|JP|UNOA","entity.name.segment":"ADR|AGR|AJT|ALC|ALI|APP|APR|ARD|ARR|ASI|ATT|AUT|BAS|BGM|BII|BUS|CAV|CCD|CCI|CDI|CDS|CDV|CED|CIN|CLA|CLI|CMP|CNI|CNT|COD|COM|COT|CPI|CPS|CPT|CST|CTA|CUX|DAM|DFN|DGS|DII|DIM|DLI|DLM|DMS|DOC|DRD|DSG|DSI|DTM|EDT|EFI|ELM|ELU|ELV|EMP|EQA|EQD|EQN|ERC|ERP|EVE|FCA|FII|FNS|FNT|FOR|FSQ|FTX|GDS|GEI|GID|GIN|GIR|GOR|GPO|GRU|HAN|HYN|ICD|IDE|IFD|IHC|IMD|IND|INP|INV|IRQ|LAN|LIN|LOC|MEA|MEM|MKS|MOA|MSG|MTD|NAD|NAT|PAC|PAI|PAS|PCC|PCD|PCI|PDI|PER|PGI|PIA|PNA|POC|PRC|PRI|PRV|PSD|PTY|PYT|QRS|QTY|QUA|QVR|RCS|REL|RFF|RJL|RNG|ROD|RSL|RTE|SAL|SCC|SCD|SEG|SEL|SEQ|SFI|SGP|SGU|SPR|SPS|STA|STC|STG|STS|TAX|TCC|TDT|TEM|TMD|TMP|TOD|TPL|TRU|TSR|UNB|UNZ|UNT|UGH|UGT|UNS|VLI","entity.name.header":"UNH","constant.language":"null|Infinity|NaN|undefined","support.function":""},"identifier");this.$rules={start:[{token:"punctuation.operator",regex:"\\+.\\+"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+"},{token:"punctuation.operator",regex:"\\:|'"},{token:"identifier",regex:"\\:D\\:"}]},this.embedRules(n,"doc-",[n.getEndRule("start")])};r.metaData={fileTypes:["edi"],keyEquivalent:"^~E",name:"Edifact",scopeName:"source.edifact"},o.inherits(r,a),t.EdifactHighlightRules=r})),ace.define("ace/mode/edifact",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/edifact_highlight_rules"],(function(e,t,i){"use strict";var o=e("../lib/oop"),n=e("./text").Mode,a=e("./edifact_highlight_rules").EdifactHighlightRules,r=function(){this.HighlightRules=a,this.$behaviour=this.$defaultBehaviour};o.inherits(r,n),function(){this.$id="ace/mode/edifact",this.snippetFileId="ace/snippets/edifact"}.call(r.prototype),t.Mode=r})),ace.require(["ace/mode/edifact"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/f6d7091e70dee6c74956acfef2464d08.js b/f6d7091e70dee6c74956acfef2464d08.js new file mode 100644 index 00000000..646b301d --- /dev/null +++ b/f6d7091e70dee6c74956acfef2464d08.js @@ -0,0 +1 @@ +ace.define("ace/snippets/erlang.snippets",["require","exports","module"],(function(n,t,e){e.exports="# module and export all\nsnippet mod\n\t-module(${1:`Filename('', 'my')`}).\n\t\n\t-compile([export_all]).\n\t\n\tstart() ->\n\t ${2}\n\t\n\tstop() ->\n\t ok.\n# define directive\nsnippet def\n\t-define(${1:macro}, ${2:body}).${3}\n# export directive\nsnippet exp\n\t-export([${1:function}/${2:arity}]).\n# include directive\nsnippet inc\n\t-include(\"${1:file}\").${2}\n# behavior directive\nsnippet beh\n\t-behaviour(${1:behaviour}).${2}\n# if expression\nsnippet if\n\tif\n\t ${1:guard} ->\n\t ${2:body}\n\tend\n# case expression\nsnippet case\n\tcase ${1:expression} of\n\t ${2:pattern} ->\n\t ${3:body};\n\tend\n# anonymous function\nsnippet fun\n\tfun (${1:Parameters}) -> ${2:body} end${3}\n# try...catch\nsnippet try\n\ttry\n\t ${1}\n\tcatch\n\t ${2:_:_} -> ${3:got_some_exception}\n\tend\n# record directive\nsnippet rec\n\t-record(${1:record}, {\n\t ${2:field}=${3:value}}).${4}\n# todo comment\nsnippet todo\n\t%% TODO: ${1}\n## Snippets below (starting with '%') are in EDoc format.\n## See http://www.erlang.org/doc/apps/edoc/chapter.html#id56887 for more details\n# doc comment\nsnippet %d\n\t%% @doc ${1}\n# end of doc comment\nsnippet %e\n\t%% @end\n# specification comment\nsnippet %s\n\t%% @spec ${1}\n# private function marker\nsnippet %p\n\t%% @private\n# OTP application\nsnippet application\n\t-module(${1:`Filename('', 'my')`}).\n\n\t-behaviour(application).\n\n\t-export([start/2, stop/1]).\n\n\tstart(_Type, _StartArgs) ->\n\t case ${2:root_supervisor}:start_link() of\n\t {ok, Pid} ->\n\t {ok, Pid};\n\t Other ->\n\t\t {error, Other}\n\t end.\n\n\tstop(_State) ->\n\t ok.\t\n# OTP supervisor\nsnippet supervisor\n\t-module(${1:`Filename('', 'my')`}).\n\n\t-behaviour(supervisor).\n\n\t%% API\n\t-export([start_link/0]).\n\n\t%% Supervisor callbacks\n\t-export([init/1]).\n\n\t-define(SERVER, ?MODULE).\n\n\tstart_link() ->\n\t supervisor:start_link({local, ?SERVER}, ?MODULE, []).\n\n\tinit([]) ->\n\t Server = {${2:my_server}, {$2, start_link, []},\n\t permanent, 2000, worker, [$2]},\n\t Children = [Server],\n\t RestartStrategy = {one_for_one, 0, 1},\n\t {ok, {RestartStrategy, Children}}.\n# OTP gen_server\nsnippet gen_server\n\t-module(${1:`Filename('', 'my')`}).\n\n\t-behaviour(gen_server).\n\n\t%% API\n\t-export([\n\t start_link/0\n\t ]).\n\n\t%% gen_server callbacks\n\t-export([init/1, handle_call/3, handle_cast/2, handle_info/2,\n\t terminate/2, code_change/3]).\n\n\t-define(SERVER, ?MODULE).\n\n\t-record(state, {}).\n\n\t%%%===================================================================\n\t%%% API\n\t%%%===================================================================\n\n\tstart_link() ->\n\t gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).\n\n\t%%%===================================================================\n\t%%% gen_server callbacks\n\t%%%===================================================================\n\n\tinit([]) ->\n\t {ok, #state{}}.\n\n\thandle_call(_Request, _From, State) ->\n\t Reply = ok,\n\t {reply, Reply, State}.\n\n\thandle_cast(_Msg, State) ->\n\t {noreply, State}.\n\n\thandle_info(_Info, State) ->\n\t {noreply, State}.\n\n\tterminate(_Reason, _State) ->\n\t ok.\n\n\tcode_change(_OldVsn, State, _Extra) ->\n\t {ok, State}.\n\n\t%%%===================================================================\n\t%%% Internal functions\n\t%%%===================================================================\n\n"})),ace.define("ace/snippets/erlang",["require","exports","module","ace/snippets/erlang.snippets"],(function(n,t,e){"use strict";t.snippetText=n("./erlang.snippets"),t.scope="erlang"})),ace.require(["ace/snippets/erlang"],(function(n){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=n)})); \ No newline at end of file diff --git a/f9a0bb7f948ede9bf3f34989aef482db.js b/f9a0bb7f948ede9bf3f34989aef482db.js new file mode 100644 index 00000000..e2ab28b3 --- /dev/null +++ b/f9a0bb7f948ede9bf3f34989aef482db.js @@ -0,0 +1 @@ +ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};o.inherits(a,r),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),o="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[r.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[r.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:o},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:o},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(r,"doc-",[r.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var o="/"==e.charAt(1)?2:1;return 1==o?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==o&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==o?"":"end-")+"tag-open.xml",value:e.slice(0,o)},{type:"meta.tag.tag-name.xml",value:e.substr(o)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[r.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[r.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}o.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var o=e("../range").Range,r=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var r=n[1].length,a=e.findMatchingBracket({row:t,column:r});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new o(t,0,t,r-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(r.prototype),t.MatchingBraceOutdent=r})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,o,r){if('"'==r||"'"==r){var s=r,l=o.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),u=o.doc.getLine(c.row).substring(c.column,c.column+1),d=new a(o,c.row,c.column),g=d.getCurrentToken();if(u==s&&(i(g,"attribute-value")||i(g,"string")))return{text:"",selection:[1,1]};if(g||(g=d.stepBackward()),!g)return;for(;i(g,"tag-whitespace")||i(g,"whitespace");)g=d.stepBackward();var m=!u||u.match(/\s/);if(i(g,"attribute-equals")&&(m||">"==u)||i(g,"decl-attribute-equals")&&(m||"?"==u))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,o,r){var a=o.doc.getTextRange(r);if(!r.isMultiLine()&&('"'==a||"'"==a)&&o.doc.getLine(r.start.row).substring(r.start.column+1,r.start.column+2)==a)return r.end.column++,r})),this.add("autoclosing","insertion",(function(e,t,n,o,r){if(">"==r){var s=n.getSelectionRange().start,l=new a(o,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var u=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(o.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var g=l.getCurrentTokenRow(),m=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var p=c.value;if(g==s.row&&(p=p.substring(0,s.column-m)),this.voidElements&&this.voidElements.hasOwnProperty(p.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,o,r){if("\n"==r){var s=n.getCursorPosition(),l=o.getLine(s.row),c=new a(o,s.row,s.column),u=c.getCurrentToken();if(i(u,"")&&-1!==u.type.indexOf("tag-close")){if("/>"==u.value)return;for(;u&&-1===u.type.indexOf("tag-name");)u=c.stepBackward();if(!u)return;var d=u.value,g=c.getCurrentTokenRow();if(!(u=c.stepBackward())||-1!==u.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[d]||!this.voidElements){var m=o.getTokenAt(s.row,s.column+1),p=(l=o.getLine(g),this.$getIndent(l)),h=p+o.getTabString();return m&&""==a){var i=n.getSelectionRange().start,s=new r(o,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};o.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=o.mixin({},this.voidElements),t&&o.mixin(this.optionalEndTags,t)};o.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var o=this._getFirstTagInLine(e,n);return o?o.closing||!o.tagName&&o.selfClosing?"markbeginend"===t?"end":"":!o.tagName||o.selfClosing||this.voidElements.hasOwnProperty(o.tagName.toLowerCase())||this._findEndTagInLine(e,n,o.tagName,o.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return o}if(l(a,"tag-close"))return o.selfClosing="/>"==a.value,o;o.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,o){for(var r=e.getTokens(t),a=0,i=0;ic)break;var u=this.getFoldWidgetRange(e,"all",t);if(u){if(u.start.row<=a)break;if(u.isMultiLine())t=u.end.row;else if(o==c)break}s=t}}return new r(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var o=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new r(i,o,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new r};o.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,o){return this.getFoldWidgetRangeBase(e,t,n,o)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,u=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};o.inherits(u,r),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e),a=r.tokens,i=r.state;if(a.length&&"comment"==a[a.length-1].type)return o;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(o+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(u.prototype),t.Mode=u})),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=(e("../lib/lang"),e("./text_highlight_rules").TextHighlightRules),a=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",i=t.supportFunction="rgb|rgba|url|attr|counter|counters",s=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|flex-end|flex-start|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",l=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",c=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",u=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",d=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",g=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",m=function(){var e=this.createKeywordMapper({"support.function":i,"support.constant":s,"support.type":a,"support.constant.color":l,"support.constant.fonts":c},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:u},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+u+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:u},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:d},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:g},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{token:"paren.lparen",regex:"\\{"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};o.inherits(m,r),t.CssHighlightRules=m})),ace.define("ace/mode/css_completions",["require","exports","module"],(function(e,t,n){"use strict";var o={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,double:2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{default:1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},float:{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,static:1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},r=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e)if("string"==typeof e[t]){var n=t.replace(/[A-Z]/g,(function(e){return"-"+e.toLowerCase()}));o.hasOwnProperty(n)||(o[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,o){if(this.completionsDefined||this.defineCompletions(),"ruleset"===e||"ace/mode/scss"==t.$mode.$id){var r=t.getLine(n.row).substr(0,n.column),a=/\([^)]*$/.test(r);return a&&(r=r.substr(r.lastIndexOf("(")+1)),/:[^;]+$/.test(r)?(/([\w\-]+):[^:]*$/.test(r),this.getPropertyValueCompletions(e,t,n,o)):this.getPropertyCompletions(e,t,n,o,a)}return[]},this.getPropertyCompletions=function(e,t,n,r,a){return a=a||!1,Object.keys(o).map((function(e){return{caption:e,snippet:e+": $0"+(a?"":";"),meta:"property",score:1e6}}))},this.getPropertyValueCompletions=function(e,t,n,r){var a=t.getLine(n.row).substr(0,n.column),i=(/([\w\-]+):[^:]*$/.exec(a)||{})[1];if(!i)return[];var s=[];return i in o&&"object"==typeof o[i]&&(s=Object.keys(o[i])),s.map((function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}}))}}).call(r.prototype),t.CssCompletions=r})),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=(e("../behaviour").Behaviour,e("./cstyle").CstyleBehaviour),a=e("../../token_iterator").TokenIterator,i=function(){this.inherit(r),this.add("colon","insertion",(function(e,t,n,o,r){if(":"===r&&n.selection.isEmpty()){var i=n.getCursorPosition(),s=new a(o,i.row,i.column),l=s.getCurrentToken();if(l&&l.value.match(/\s+/)&&(l=s.stepBackward()),l&&"support.type"===l.type){var c=o.doc.getLine(i.row);if(":"===c.substring(i.column,i.column+1))return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(c.substring(i.column)))return{text:":;",selection:[1,1]}}}})),this.add("colon","deletion",(function(e,t,n,o,r){var i=o.doc.getTextRange(r);if(!r.isMultiLine()&&":"===i){var s=n.getCursorPosition(),l=new a(o,s.row,s.column),c=l.getCurrentToken();if(c&&c.value.match(/\s+/)&&(c=l.stepBackward()),c&&"support.type"===c.type&&";"===o.doc.getLine(r.start.row).substring(r.end.column,r.end.column+1))return r.end.column++,r}})),this.add("semicolon","insertion",(function(e,t,n,o,r){if(";"===r&&n.selection.isEmpty()){var a=n.getCursorPosition();if(";"===o.doc.getLine(a.row).substring(a.column,a.column+1))return{text:"",selection:[1,1]}}})),this.add("!important","insertion",(function(e,t,n,o,r){if("!"===r&&n.selection.isEmpty()){var a=n.getCursorPosition(),i=o.doc.getLine(a.row);if(/^\s*(;|}|$)/.test(i.substring(a.column)))return{text:"!important",selection:[10,10]}}}))};o.inherits(i,r),t.CssBehaviour=i})),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text").Mode,a=e("./css_highlight_rules").CssHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./css_completions").CssCompletions,c=e("./behaviour/css").CssBehaviour,u=e("./folding/cstyle").FoldMode,d=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new c,this.$completer=new l,this.foldingRules=new u};o.inherits(d,r),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var o=this.$getIndent(t),r=this.getTokenizer().getLineTokens(t,e).tokens;return r.length&&"comment"==r[r.length-1].type||t.match(/^.*\{\s*$/)&&(o+=n),o},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/css",this.snippetFileId="ace/snippets/css"}.call(d.prototype),t.Mode=d})),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("./text_highlight_rules").TextHighlightRules,a=function(e){var t="[_:a-zA-ZÀ-￿][-_:.a-zA-Z0-9À-￿]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"--\x3e",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===a&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(r.prototype),o.inherits(a,r),t.XmlHighlightRules=a})),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./css_highlight_rules").CssHighlightRules,i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./xml_highlight_rules").XmlHighlightRules,l=r.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),c=function(){s.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=l[t];return["meta.tag.punctuation."+("<"==e?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(a,"css-","style"),this.embedTagRules(new i({jsx:!1}).getRules(),"js-","script"),this.constructor===c&&this.normalizeRules()};o.inherits(c,s),t.HtmlHighlightRules=c})),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./fold_mode").FoldMode,a=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};o.inherits(a,r),function(){this.$getMode=function(e){for(var t in"string"!=typeof e&&(e=e[0]),this.subModes)if(0===e.indexOf(t))return this.subModes[t];return null},this.$tryMode=function(e,t,n,o){var r=this.$getMode(e);return r?r.getFoldWidget(t,n,o):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var o=this.$getMode(e.getState(n-1));return o&&o.getFoldWidget(e,t,n)||(o=this.$getMode(e.getState(n))),o&&o.getFoldWidget(e,t,n)||(o=this.defaultMode),o.getFoldWidgetRange(e,t,n)}}.call(a.prototype)})),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var o=e("../../lib/oop"),r=e("./mixed").FoldMode,a=e("./xml").FoldMode,i=e("./cstyle").FoldMode,s=t.FoldMode=function(e,t){r.call(this,new a(e,t),{"js-":new i,"css-":new i})};o.inherits(s,r)})),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],(function(e,t,n){"use strict";var o=e("../token_iterator").TokenIterator,r=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"].concat(["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"]),a={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,for:1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{for:1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,default:1},section:{},summary:{},u:{},ul:{},var:{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},i=Object.keys(a);function s(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"tag-name");)r=n.stepBackward();if(r)return r.value}var c=function(){};(function(){this.getCompletions=function(e,t,n,o){var r=t.getTokenAt(n.row,n.column);if(!r)return[];if(s(r,"tag-name")||s(r,"tag-open")||s(r,"end-tag-open"))return this.getTagCompletions(e,t,n,o);if(s(r,"tag-whitespace")||s(r,"attribute-name"))return this.getAttributeCompletions(e,t,n,o);if(s(r,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,o);var a=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(a)?this.getHTMLEntityCompletions(e,t,n,o):[]},this.getTagCompletions=function(e,t,n,o){return i.map((function(e){return{value:e,meta:"tag",score:1e6}}))},this.getAttributeCompletions=function(e,t,n,o){var i=l(t,n);if(!i)return[];var s=r;return i in a&&(s=s.concat(Object.keys(a[i]))),s.map((function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}}))},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),c=function(e,t){for(var n=new o(e,t.row,t.column),r=n.getCurrentToken();r&&!s(r,"attribute-name");)r=n.stepBackward();if(r)return r.value}(t,n);if(!i)return[];var u=[];return i in a&&c in a[i]&&"object"==typeof a[i][c]&&(u=Object.keys(a[i][c])),u.map((function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}}))},this.getHTMLEntityCompletions=function(e,t,n,o){return["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"].map((function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}}))}}).call(c.prototype),t.HtmlCompletions=c})),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],(function(e,t,n){"use strict";var o=e("../lib/oop"),r=e("../lib/lang"),a=e("./text").Mode,i=e("./javascript").Mode,s=e("./css").Mode,l=e("./html_highlight_rules").HtmlHighlightRules,c=e("./behaviour/xml").XmlBehaviour,u=e("./folding/html").FoldMode,d=e("./html_completions").HtmlCompletions,g=e("../worker/worker_client").WorkerClient,m=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],p=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],h=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=l,this.$behaviour=new c,this.$completer=new d,this.createModeDelegates({"js-":i,"css-":s}),this.foldingRules=new u(this.voidElements,r.arrayToMap(p))};o.inherits(h,a),function(){this.blockComment={start:"\x3c!--",end:"--\x3e"},this.voidElements=r.arrayToMap(m),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,o){return this.$completer.getCompletions(e,t,n,o)},this.createWorker=function(e){if(this.constructor==h){var t=new g(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t}},this.$id="ace/mode/html",this.snippetFileId="ace/snippets/html"}.call(h.prototype),t.Mode=h})),ace.require(["ace/mode/html"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/f9bfa6a6410f75b5729fee89b56e3a86.js b/f9bfa6a6410f75b5729fee89b56e3a86.js new file mode 100644 index 00000000..6fef2b8d --- /dev/null +++ b/f9bfa6a6410f75b5729fee89b56e3a86.js @@ -0,0 +1 @@ +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=(e("../lib/lang"),e("./text_highlight_rules").TextHighlightRules),a=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",i=t.supportFunction="rgb|rgba|url|attr|counter|counters",s=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|flex-end|flex-start|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",l=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",c=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",u=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",g=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",d=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",p=function(){var e=this.createKeywordMapper({"support.function":i,"support.constant":s,"support.type":a,"support.constant.color":l,"support.constant.fonts":c},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:u},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+u+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:u},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:g},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:d},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{token:"paren.lparen",regex:"\\{"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};r.inherits(p,o),t.CssHighlightRules=p})),ace.define("ace/mode/jsdoc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(){this.$rules={start:[{token:["comment.doc.tag","comment.doc.text","lparen.doc"],regex:"(@(?:param|member|typedef|property|namespace|var|const|callback))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:["rparen.doc","text.doc","variable.parameter.doc","lparen.doc","variable.parameter.doc","rparen.doc"],regex:/(})(\s*)(?:([\w=:\/\.]+)|(?:(\[)([\w=:\/\.\-\'\" ]+)(\])))/,next:"pop"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","lparen.doc"],regex:"(@(?:returns?|yields|type|this|suppress|public|protected|private|package|modifies|implements|external|exception|throws|enum|define|extends))(\\s*)({)",push:[{token:"lparen.doc",regex:"{",push:[{include:"doc-syntax"},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"}]},{token:"rparen.doc",regex:"}|(?=$)",next:"pop"},{include:"doc-syntax"},{defaultToken:"text.doc"}]},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:'(@(?:alias|memberof|instance|module|name|lends|namespace|external|this|template|requires|param|implements|function|extends|typedef|mixes|constructor|var|memberof\\!|event|listens|exports|class|constructs|interface|emits|fires|throws|const|callback|borrows|augments))(\\s+)(\\w[\\w#.:/~"\\-]*)?'},{token:["comment.doc.tag","text.doc","variable.parameter.doc"],regex:"(@method)(\\s+)(\\w[\\w.\\(\\)]*)"},{token:"comment.doc.tag",regex:"@access\\s+(?:private|public|protected)"},{token:"comment.doc.tag",regex:"@kind\\s+(?:class|constant|event|external|file|function|member|mixin|module|namespace|typedef)"},{token:"comment.doc.tag",regex:"@\\w+(?=\\s|$)"},a.getTagRule(),{defaultToken:"comment.doc.body",caseInsensitive:!0}],"doc-syntax":[{token:"operator.doc",regex:/[|:]/},{token:"paren.doc",regex:/[\[\]]/}]},this.normalizeRules()};r.inherits(a,o),a.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},a.getStartRule=function(e){return{token:"comment.doc",regex:/\/\*\*(?!\/)/,next:e}},a.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.JsDocCommentHighlightRules=a})),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/jsdoc_comment_highlight_rules","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./jsdoc_comment_highlight_rules").JsDocCommentHighlightRules,a=e("./text_highlight_rules").TextHighlightRules,i="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",s=function(e){var t={"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Symbol|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static|constructor","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},n=this.createKeywordMapper(t,"identifier"),r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)",a="(function)(\\s*)(\\*?)",s={token:["identifier","text","paren.lparen"],regex:"(\\b(?!"+Object.values(t).join("|")+"\\b)"+i+")(\\s*)(\\()"};this.$rules={no_regex:[o.getStartRule("doc-start"),c("no_regex"),s,{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(=)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))("+i+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","storage.type","text","paren.lparen"],regex:"("+i+")(\\s*)(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)"+a+"(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:"support.constant",regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|debug|time|trace|timeEnd|assert)\b/},{token:n,regex:i},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:"keyword.operator",regex:/=/},{token:["storage.type","text","storage.type","text","paren.lparen"],regex:a+"(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","storage.type","text","text","entity.name.function","text","paren.lparen"],regex:"(function)(?:(?:(\\s*)(\\*)(\\s*))|(\\s+))(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:"prototype"},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|lter|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward|rEach)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:i},{regex:"",token:"empty",next:"no_regex"}],start:[o.getStartRule("doc-start"),c("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],default_parameter:[{token:"string",regex:"'(?=.)",push:[{token:"string",regex:"'|$",next:"pop"},{include:"qstring"}]},{token:"string",regex:'"(?=.)',push:[{token:"string",regex:'"|$',next:"pop"},{include:"qqstring"}]},{token:"constant.language",regex:"null|Infinity|NaN|undefined"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:"punctuation.operator",regex:",",next:"function_arguments"},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],function_arguments:[c("function_arguments"),{token:"variable.parameter",regex:i},{token:"punctuation.operator",regex:","},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){if(this.next="{"==e?this.nextState:"","{"==e&&n.length)n.unshift("start",t);else if("}"==e&&n.length&&(n.shift(),this.next=n.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]},{token:["variable.parameter","text"],regex:"("+i+")(\\s*)(?=\\=>)"},{token:"paren.lparen",regex:"(\\()(?=[^\\(]+\\s*=>)",next:"function_arguments"},{token:"variable.language",regex:"(?:(?:(?:Weak)?(?:Set|Map))|Promise)\\b"}),this.$rules.function_arguments.unshift({token:"keyword.operator",regex:"=",next:"default_parameter"},{token:"keyword.operator",regex:"\\.{3}"}),this.$rules.property.unshift({token:"support.function",regex:"(findIndex|repeat|startsWith|endsWith|includes|isSafeInteger|trunc|cbrt|log2|log10|sign|then|catch|finally|resolve|reject|race|any|all|allSettled|keys|entries|isInteger)\\b(?=\\()"},{token:"constant.language",regex:"(?:MAX_SAFE_INTEGER|MIN_SAFE_INTEGER|EPSILON)\\b"}),e&&0==e.jsx||l.call(this)),this.embedRules(o,"doc-",[o.getEndRule("no_regex")]),this.normalizeRules()};function l(){var e=i.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r="/"==e.charAt(1)?2:1;return 1==r?(t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++):2==r&&t==this.nextState&&(n[1]--,(!n[1]||n[1]<0)&&(n.shift(),n.shift())),[{type:"meta.tag.punctuation."+(1==r?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"))",next:"jsxAttributes",nextState:"jsx"};this.$rules.start.unshift(t);var n={regex:"{",token:"paren.quasi.start",push:"start"};this.$rules.jsx=[n,t,{include:"reference"},{defaultToken:"string.xml"}],this.$rules.jsxAttributes=[{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",onMatch:function(e,t,n){return t==n[0]&&n.shift(),2==e.length&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,c("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function c(e){return[{token:"comment",regex:/\/\*/,next:[o.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[o.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}r.inherits(s,a),t.JavaScriptHighlightRules=s})),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=function(e){var t="[_:a-zA-ZÀ-￿][-_:.a-zA-Z0-9À-￿]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"--\x3e",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===a&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(o.prototype),r.inherits(a,o),t.XmlHighlightRules=a})),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("../lib/lang"),a=e("./css_highlight_rules").CssHighlightRules,i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./xml_highlight_rules").XmlHighlightRules,l=o.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),c=function(){s.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=l[t];return["meta.tag.punctuation."+("<"==e?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(a,"css-","style"),this.embedTagRules(new i({jsx:!1}).getRules(),"js-","script"),this.constructor===c&&this.normalizeRules()};r.inherits(c,s),t.HtmlHighlightRules=c})),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],(function(e,t,n){"use strict";var r=e("../range").Range,o=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var n=e.getLine(t).match(/^(\s*\})/);if(!n)return 0;var o=n[1].length,a=e.findMatchingBracket({row:t,column:o});if(!a||a.row==t)return 0;var i=this.$getIndent(e.getLine(a.row));e.replace(new r(t,0,t,o-1),i)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(o.prototype),t.MatchingBraceOutdent=o})),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../behaviour").Behaviour,a=e("../../token_iterator").TokenIterator;function i(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var s=function(){this.add("string_dquotes","insertion",(function(e,t,n,r,o){if('"'==o||"'"==o){var s=o,l=r.doc.getTextRange(n.getSelectionRange());if(""!==l&&"'"!==l&&'"'!=l&&n.getWrapBehavioursEnabled())return{text:s+l+s,selection:!1};var c=n.getCursorPosition(),u=r.doc.getLine(c.row).substring(c.column,c.column+1),g=new a(r,c.row,c.column),d=g.getCurrentToken();if(u==s&&(i(d,"attribute-value")||i(d,"string")))return{text:"",selection:[1,1]};if(d||(d=g.stepBackward()),!d)return;for(;i(d,"tag-whitespace")||i(d,"whitespace");)d=g.stepBackward();var p=!u||u.match(/\s/);if(i(d,"attribute-equals")&&(p||">"==u)||i(d,"decl-attribute-equals")&&(p||"?"==u))return{text:s+s,selection:[1,1]}}})),this.add("string_dquotes","deletion",(function(e,t,n,r,o){var a=r.doc.getTextRange(o);if(!o.isMultiLine()&&('"'==a||"'"==a)&&r.doc.getLine(o.start.row).substring(o.start.column+1,o.start.column+2)==a)return o.end.column++,o})),this.add("autoclosing","insertion",(function(e,t,n,r,o){if(">"==o){var s=n.getSelectionRange().start,l=new a(r,s.row,s.column),c=l.getCurrentToken()||l.stepBackward();if(!c||!(i(c,"tag-name")||i(c,"tag-whitespace")||i(c,"attribute-name")||i(c,"attribute-equals")||i(c,"attribute-value")))return;if(i(c,"reference.attribute-value"))return;if(i(c,"attribute-value")){var u=l.getCurrentTokenColumn()+c.value.length;if(s.column/.test(r.getLine(s.row).slice(s.column)))return;for(;!i(c,"tag-name");)if("<"==(c=l.stepBackward()).value){c=l.stepForward();break}var d=l.getCurrentTokenRow(),p=l.getCurrentTokenColumn();if(i(l.stepBackward(),"end-tag-open"))return;var m=c.value;if(d==s.row&&(m=m.substring(0,s.column-p)),this.voidElements&&this.voidElements.hasOwnProperty(m.toLowerCase()))return;return{text:">",selection:[1,1]}}})),this.add("autoindent","insertion",(function(e,t,n,r,o){if("\n"==o){var s=n.getCursorPosition(),l=r.getLine(s.row),c=new a(r,s.row,s.column),u=c.getCurrentToken();if(i(u,"")&&-1!==u.type.indexOf("tag-close")){if("/>"==u.value)return;for(;u&&-1===u.type.indexOf("tag-name");)u=c.stepBackward();if(!u)return;var g=u.value,d=c.getCurrentTokenRow();if(!(u=c.stepBackward())||-1!==u.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[g]||!this.voidElements){var p=r.getTokenAt(s.row,s.column+1),m=(l=r.getLine(d),this.$getIndent(l)),h=m+r.getTabString();return p&&""==a){var i=n.getSelectionRange().start,s=new o(r,i.row,i.column),l=s.getCurrentToken()||s.stepBackward();if(!l)return;if("<"==l.value)return{text:">",selection:[1,1]}}}))};r.inherits(s,a),t.JavaScriptBehaviour=s})),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("../../range").Range,a=e("./fold_mode").FoldMode,i=t.FoldMode=function(e,t){a.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(i,a);var s=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?"markbeginend"===t?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())||this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/"==a.value;break}return r}if(l(a,"tag-close"))return r.selfClosing="/>"==a.value,r;r.start.column+=a.value.length}return null},this._findEndTagInLine=function(e,t,n,r){for(var o=e.getTokens(t),a=0,i=0;ic)break;var u=this.getFoldWidgetRange(e,"all",t);if(u){if(u.start.row<=a)break;if(u.isMultiLine())t=u.end.row;else if(r==c)break}s=t}}return new o(a,i,s,e.getLine(s).length)},this.getCommentRegionBlock=function(e,t,n){for(var r=t.search(/\s*$/),a=e.getLength(),i=n,s=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,l=1;++ni)return new o(i,r,n,t.length)}}.call(i.prototype)})),ace.define("ace/mode/folding/javascript",["require","exports","module","ace/lib/oop","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./xml").FoldMode,a=e("./cstyle").FoldMode,i=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end))),this.xmlFoldMode=new o};r.inherits(i,a),function(){this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){return this.getFoldWidgetBase(e,t,n)||this.xmlFoldMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n,r){return this.getFoldWidgetRangeBase(e,t,n,r)||this.xmlFoldMode.getFoldWidgetRange(e,t,n)}}.call(i.prototype)})),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/javascript","ace/mode/folding/javascript"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./behaviour/javascript").JavaScriptBehaviour,c=e("./folding/javascript").FoldMode,u=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new l,this.foldingRules=new c};r.inherits(u,o),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.$pairQuotesAfter={"`":/\w/},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e),a=o.tokens,i=o.state;if(a.length&&"comment"==a[a.length-1].type)return r;if("start"==e||"no_regex"==e)t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/)&&(r+=n);else if("doc-start"==e&&("start"==i||"no_regex"==i))return"";return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/javascript",this.snippetFileId="ace/snippets/javascript"}.call(u.prototype),t.Mode=u})),ace.define("ace/mode/css_completions",["require","exports","module"],(function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,double:2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{default:1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},float:{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,static:1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},o=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e)if("string"==typeof e[t]){var n=t.replace(/[A-Z]/g,(function(e){return"-"+e.toLowerCase()}));r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){if(this.completionsDefined||this.defineCompletions(),"ruleset"===e||"ace/mode/scss"==t.$mode.$id){var o=t.getLine(n.row).substr(0,n.column),a=/\([^)]*$/.test(o);return a&&(o=o.substr(o.lastIndexOf("(")+1)),/:[^;]+$/.test(o)?(/([\w\-]+):[^:]*$/.test(o),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r,a)}return[]},this.getPropertyCompletions=function(e,t,n,o,a){return a=a||!1,Object.keys(r).map((function(e){return{caption:e,snippet:e+": $0"+(a?"":";"),meta:"property",score:1e6}}))},this.getPropertyValueCompletions=function(e,t,n,o){var a=t.getLine(n.row).substr(0,n.column),i=(/([\w\-]+):[^:]*$/.exec(a)||{})[1];if(!i)return[];var s=[];return i in r&&"object"==typeof r[i]&&(s=Object.keys(r[i])),s.map((function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}}))}}).call(o.prototype),t.CssCompletions=o})),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=(e("../behaviour").Behaviour,e("./cstyle").CstyleBehaviour),a=e("../../token_iterator").TokenIterator,i=function(){this.inherit(o),this.add("colon","insertion",(function(e,t,n,r,o){if(":"===o&&n.selection.isEmpty()){var i=n.getCursorPosition(),s=new a(r,i.row,i.column),l=s.getCurrentToken();if(l&&l.value.match(/\s+/)&&(l=s.stepBackward()),l&&"support.type"===l.type){var c=r.doc.getLine(i.row);if(":"===c.substring(i.column,i.column+1))return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(c.substring(i.column)))return{text:":;",selection:[1,1]}}}})),this.add("colon","deletion",(function(e,t,n,r,o){var i=r.doc.getTextRange(o);if(!o.isMultiLine()&&":"===i){var s=n.getCursorPosition(),l=new a(r,s.row,s.column),c=l.getCurrentToken();if(c&&c.value.match(/\s+/)&&(c=l.stepBackward()),c&&"support.type"===c.type&&";"===r.doc.getLine(o.start.row).substring(o.end.column,o.end.column+1))return o.end.column++,o}})),this.add("semicolon","insertion",(function(e,t,n,r,o){if(";"===o&&n.selection.isEmpty()){var a=n.getCursorPosition();if(";"===r.doc.getLine(a.row).substring(a.column,a.column+1))return{text:"",selection:[1,1]}}})),this.add("!important","insertion",(function(e,t,n,r,o){if("!"===o&&n.selection.isEmpty()){var a=n.getCursorPosition(),i=r.doc.getLine(a.row);if(/^\s*(;|}|$)/.test(i.substring(a.column)))return{text:"!important",selection:[10,10]}}}))};r.inherits(i,o),t.CssBehaviour=i})),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./css_highlight_rules").CssHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../worker/worker_client").WorkerClient,l=e("./css_completions").CssCompletions,c=e("./behaviour/css").CssBehaviour,u=e("./folding/cstyle").FoldMode,g=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=new c,this.$completer=new l,this.foldingRules=new u};r.inherits(g,o),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e).tokens;return o.length&&"comment"==o[o.length-1].type||t.match(/^.*\{\s*$/)&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new s(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t},this.$id="ace/mode/css",this.snippetFileId="ace/snippets/css"}.call(g.prototype),t.Mode=g})),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./fold_mode").FoldMode,a=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(a,o),function(){this.$getMode=function(e){for(var t in"string"!=typeof e&&(e=e[0]),this.subModes)if(0===e.indexOf(t))return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var o=this.$getMode(e);return o?o.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));return r&&r.getFoldWidget(e,t,n)||(r=this.$getMode(e.getState(n))),r&&r.getFoldWidget(e,t,n)||(r=this.defaultMode),r.getFoldWidgetRange(e,t,n)}}.call(a.prototype)})),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./mixed").FoldMode,a=e("./xml").FoldMode,i=e("./cstyle").FoldMode,s=t.FoldMode=function(e,t){o.call(this,new a(e,t),{"js-":new i,"css-":new i})};r.inherits(s,o)})),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../token_iterator").TokenIterator,o=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"].concat(["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"]),a={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,for:1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{for:1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,default:1},section:{},summary:{},u:{},ul:{},var:{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},i=Object.keys(a);function s(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){for(var n=new r(e,t.row,t.column),o=n.getCurrentToken();o&&!s(o,"tag-name");)o=n.stepBackward();if(o)return o.value}var c=function(){};(function(){this.getCompletions=function(e,t,n,r){var o=t.getTokenAt(n.row,n.column);if(!o)return[];if(s(o,"tag-name")||s(o,"tag-open")||s(o,"end-tag-open"))return this.getTagCompletions(e,t,n,r);if(s(o,"tag-whitespace")||s(o,"attribute-name"))return this.getAttributeCompletions(e,t,n,r);if(s(o,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,r);var a=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(a)?this.getHTMLEntityCompletions(e,t,n,r):[]},this.getTagCompletions=function(e,t,n,r){return i.map((function(e){return{value:e,meta:"tag",score:1e6}}))},this.getAttributeCompletions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in a&&(s=s.concat(Object.keys(a[i]))),s.map((function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}}))},this.getAttributeValueCompletions=function(e,t,n,o){var i=l(t,n),c=function(e,t){for(var n=new r(e,t.row,t.column),o=n.getCurrentToken();o&&!s(o,"attribute-name");)o=n.stepBackward();if(o)return o.value}(t,n);if(!i)return[];var u=[];return i in a&&c in a[i]&&"object"==typeof a[i][c]&&(u=Object.keys(a[i][c])),u.map((function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}}))},this.getHTMLEntityCompletions=function(e,t,n,r){return["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"].map((function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}}))}}).call(c.prototype),t.HtmlCompletions=c})),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("../lib/lang"),a=e("./text").Mode,i=e("./javascript").Mode,s=e("./css").Mode,l=e("./html_highlight_rules").HtmlHighlightRules,c=e("./behaviour/xml").XmlBehaviour,u=e("./folding/html").FoldMode,g=e("./html_completions").HtmlCompletions,d=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],m=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],h=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=l,this.$behaviour=new c,this.$completer=new g,this.createModeDelegates({"js-":i,"css-":s}),this.foldingRules=new u(this.voidElements,o.arrayToMap(m))};r.inherits(h,a),function(){this.blockComment={start:"\x3c!--",end:"--\x3e"},this.voidElements=o.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor==h){var t=new d(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",(function(t){e.setAnnotations(t.data)})),t.on("terminate",(function(){e.clearAnnotations()})),t}},this.$id="ace/mode/html",this.snippetFileId="ace/snippets/html"}.call(h.prototype),t.Mode=h})),ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text_highlight_rules").TextHighlightRules,a=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"};t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"};var i=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},s=t.constantNumericBinary={token:"constant.numeric",regex:/\b(0[bB][01](?:[01]|_(?=[01]))*)\b/},l=t.constantNumericDecimal={token:"constant.numeric",regex:/\b(0[dD](?:[1-9](?:[\d]|_(?=[\d]))*|0))\b/},c=t.constantNumericOctal={token:"constant.numeric",regex:/\b(0[oO]?(?:[1-7](?:[0-7]|_(?=[0-7]))*|0))\b/},u=t.constantNumericRational={token:"constant.numeric",regex:/\b([\d]+(?:[./][\d]+)?ri?)\b/},g=t.constantNumericComplex={token:"constant.numeric",regex:/\b([\d]i)\b/},d=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?i?\\b"},p=t.instanceVariable={token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},m=function(){var e=this.$keywords=this.createKeywordMapper({keyword:"alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|__ENCODING__|prepend","constant.language":"true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING|RUBY_PATCHLEVEL|RUBY_REVISION|RUBY_COPYRIGHT|RUBY_ENGINE|RUBY_ENGINE_VERSION|RUBY_DESCRIPTION","variable.language":"$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self","support.function":"abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many|p|warn|refine|using|module_function|extend|alias_method|private_class_method|remove_method|undef_method","invalid.deprecated":"debugger"},"identifier"),t="\\\\(?:n(?:[1-7][0-7]{0,2}|0)|[nsrtvfbae'\"\\\\]|c(?:\\\\M-)?.|M-(?:\\\\C-|\\\\c)?.|C-(?:\\\\M-)?.|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u{[\\da-fA-F]{1,6}(?:\\s[\\da-fA-F]{1,6})*})",n={"(":")","[":"]","{":"}","<":">","^":"^","|":"|","%":"%"};this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment.multiline",regex:"^=begin(?=$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:/[/](?=.*\/)/,next:"regex"},[{token:["constant.other.symbol.ruby","string.start"],regex:/(:)?(")/,push:[{token:"constant.language.escape",regex:t},{token:"paren.start",regex:/#{/,push:"start"},{token:"string.end",regex:/"/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/`/,push:[{token:"constant.language.escape",regex:t},{token:"paren.start",regex:/#{/,push:"start"},{token:"string.end",regex:/`/,next:"pop"},{defaultToken:"string"}]},{token:["constant.other.symbol.ruby","string.start"],regex:/(:)?(')/,push:[{token:"constant.language.escape",regex:/\\['\\]/},{token:"string.end",regex:/'/,next:"pop"},{defaultToken:"string"}]},{token:"string.start",regex:/%[qwx]([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="qStateWithoutInterpolation",this.token}},{token:"string.start",regex:/%[QWX]?([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="qStateWithInterpolation",this.token}},{token:"constant.other.symbol.ruby",regex:/%[si]([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="sStateWithoutInterpolation",this.token}},{token:"constant.other.symbol.ruby",regex:/%[SI]([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="sStateWithInterpolation",this.token}},{token:"string.regexp",regex:/%[r]([(\[<{^|%])/,onMatch:function(e,t,n){n.length&&(n=[]);var r=e[e.length-1];return n.unshift(r,t),this.next="rState",this.token}}],{token:"punctuation",regex:"::"},p,{token:"variable.global",regex:"[$][a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]*"},{token:["punctuation.operator","support.function"],regex:/(\.)([a-zA-Z_\d]+)(?=\()/},{token:["punctuation.operator","identifier"],regex:/(\.)([a-zA-Z_][a-zA-Z_\d]*)/},{token:"string.character",regex:"\\B\\?(?:"+t+"|\\S)"},{token:"punctuation.operator",regex:/\?(?=.+:)/},u,g,a,i,d,s,l,c,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r="-"==e[2]||"~"==e[2]?"indentedHeredoc":"heredoc",o=e.split(this.splitRegex);return n.push(r,o[3]),[{type:"constant",value:o[1]},{type:"string",value:o[2]},{type:"support.class",value:o[3]},{type:"string",value:o[4]}]},regex:"(<<[-~]?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return"heredoc"===t[0]||"indentedHeredoc"===t[0]?t[0]:e}},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\||\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]",onMatch:function(e,t,n){return this.next="","}"==e&&n.length>1&&"start"!=n[1]&&(n.shift(),this.next=n.shift()),this.token}},{token:"text",regex:"\\s+"},{token:"punctuation.operator",regex:/[?:,;.]/}],comment:[{token:"comment.multiline",regex:"^=end(?=$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}],qStateWithInterpolation:[{token:"string.start",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"string"}},{token:"constant.language.escape",regex:t},{token:"constant.language.escape",regex:/\\./},{token:"paren.start",regex:/#{/,push:"start"},{token:"string.end",regex:/[)\]>}^|%]/,onMatch:function(e,t,r){return r.length&&e===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","string")}},{defaultToken:"string"}],qStateWithoutInterpolation:[{token:"string.start",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"string"}},{token:"constant.language.escape",regex:/\\['\\]/},{token:"constant.language.escape",regex:/\\./},{token:"string.end",regex:/[)\]>}^|%]/,onMatch:function(e,t,r){return r.length&&e===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","string")}},{defaultToken:"string"}],sStateWithoutInterpolation:[{token:"constant.other.symbol.ruby",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"constant.other.symbol.ruby"}},{token:"constant.other.symbol.ruby",regex:/[)\]>}^|%]/,onMatch:function(e,t,r){return r.length&&e===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","constant.other.symbol.ruby")}},{defaultToken:"constant.other.symbol.ruby"}],sStateWithInterpolation:[{token:"constant.other.symbol.ruby",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"constant.other.symbol.ruby"}},{token:"constant.language.escape",regex:t},{token:"constant.language.escape",regex:/\\./},{token:"paren.start",regex:/#{/,push:"start"},{token:"constant.other.symbol.ruby",regex:/[)\]>}^|%]/,onMatch:function(e,t,r){return r.length&&e===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","constant.other.symbol.ruby")}},{defaultToken:"constant.other.symbol.ruby"}],rState:[{token:"string.regexp",regex:/[(\[<{]/,onMatch:function(e,t,n){return n.length&&e===n[0]?(n.unshift(e,t),this.token):"constant.language.escape"}},{token:"paren.start",regex:/#{/,push:"start"},{token:"string.regexp",regex:/\//},{token:"string.regexp",regex:/[)\]>}^|%][imxouesn]*/,onMatch:function(e,t,r){return r.length&&e[0]===n[r[0]]?(r.shift(),this.next=r.shift(),this.token):(this.next="","constant.language.escape")}},{include:"regex"},{defaultToken:"string.regexp"}],regex:[{token:"regexp.keyword",regex:/\\[wWdDhHsS]/},{token:"constant.language.escape",regex:/\\[AGbBzZ]/},{token:"constant.language.escape",regex:/\\g<[a-zA-Z0-9]*>/},{token:["constant.language.escape","regexp.keyword","constant.language.escape"],regex:/(\\p{\^?)(Alnum|Alpha|Blank|Cntrl|Digit|Graph|Lower|Print|Punct|Space|Upper|XDigit|Word|ASCII|Any|Assigned|Arabic|Armenian|Balinese|Bengali|Bopomofo|Braille|Buginese|Buhid|Canadian_Aboriginal|Carian|Cham|Cherokee|Common|Coptic|Cuneiform|Cypriot|Cyrillic|Deseret|Devanagari|Ethiopic|Georgian|Glagolitic|Gothic|Greek|Gujarati|Gurmukhi|Han|Hangul|Hanunoo|Hebrew|Hiragana|Inherited|Kannada|Katakana|Kayah_Li|Kharoshthi|Khmer|Lao|Latin|Lepcha|Limbu|Linear_B|Lycian|Lydian|Malayalam|Mongolian|Myanmar|New_Tai_Lue|Nko|Ogham|Ol_Chiki|Old_Italic|Old_Persian|Oriya|Osmanya|Phags_Pa|Phoenician|Rejang|Runic|Saurashtra|Shavian|Sinhala|Sundanese|Syloti_Nagri|Syriac|Tagalog|Tagbanwa|Tai_Le|Tamil|Telugu|Thaana|Thai|Tibetan|Tifinagh|Ugaritic|Vai|Yi|Ll|Lm|Lt|Lu|Lo|Mn|Mc|Me|Nd|Nl|Pc|Pd|Ps|Pe|Pi|Pf|Po|No|Sm|Sc|Sk|So|Zs|Zl|Zp|Cc|Cf|Cn|Co|Cs|N|L|M|P|S|Z|C)(})/},{token:["constant.language.escape","invalid","constant.language.escape"],regex:/(\\p{\^?)([^/]*)(})/},{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:/[/][imxouesn]*/,next:"start"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?(?:[:=!>]|<'?[a-zA-Z]*'?>|<[=!])|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"regexp.keyword",regex:/\[\[:(?:alnum|alpha|blank|cntrl|digit|graph|lower|print|punct|space|upper|xdigit|word|ascii):\]\]/},{token:"constant.language.escape",regex:/\[\^?/,push:"regex_character_class"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword",regex:/\\[wWdDhHsS]/},{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:/&?&?\[\^?/,push:"regex_character_class"},{token:"constant.language.escape",regex:"]",next:"pop"},{token:"constant.language.escape",regex:"-"},{defaultToken:"string.regexp.characterclass"}]},this.normalizeRules()};r.inherits(m,o),t.RubyHighlightRules=m})),ace.define("ace/mode/folding/ruby",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"],(function(e,t,n){"use strict";var r=e("../../lib/oop"),o=e("./fold_mode").FoldMode,a=e("../../range").Range,i=e("../../token_iterator").TokenIterator,s=t.FoldMode=function(){};r.inherits(s,o),function(){this.indentKeywords={class:1,def:1,module:1,do:1,unless:1,if:1,while:1,for:1,until:1,begin:1,else:0,elsif:0,rescue:0,ensure:0,when:0,end:-1,case:1,"=begin":1,"=end":-1},this.foldingStartMarker=/(?:\s|^)(def|do|while|class|unless|module|if|for|until|begin|else|elsif|case|rescue|ensure|when)\b|({\s*$)|(=begin)/,this.foldingStopMarker=/(=end(?=$|\s.*$))|(^\s*})|\b(end)\b/,this.getFoldWidget=function(e,t,n){var r,o=e.getLine(n),a=this.foldingStartMarker.test(o),i=this.foldingStopMarker.test(o);if(a&&!i)if((r=o.match(this.foldingStartMarker))[1]){if("if"==r[1]||"else"==r[1]||"while"==r[1]||"until"==r[1]||"unless"==r[1]){if("else"==r[1]&&!1===/^\s*else\s*$/.test(o))return;if(!1===/^\s*(?:if|else|while|until|unless)\s*/.test(o))return}if("when"==r[1]&&!0===/\sthen\s/.test(o))return;if("keyword"===e.getTokenAt(n,r.index+2).type)return"start"}else{if(!r[3])return"start";if("comment.multiline"===e.getTokenAt(n,r.index+1).type)return"start"}if("markbeginend"!=t||!i||a&&i)return"";if("end"===(r=o.match(this.foldingStopMarker))[3]){if("keyword"===e.getTokenAt(n,r.index+1).type)return"end"}else{if(!r[1])return"end";if("comment.multiline"===e.getTokenAt(n,r.index+1).type)return"end"}},this.getFoldWidgetRange=function(e,t,n){var r,o=e.doc.getLine(n);return(r=this.foldingStartMarker.exec(o))?r[1]||r[3]?this.rubyBlock(e,n,r.index+2):this.openingBracketBlock(e,"{",n,r.index):(r=this.foldingStopMarker.exec(o))?"end"===r[3]&&"keyword"===e.getTokenAt(n,r.index+1).type||"=end"===r[1]&&"comment.multiline"===e.getTokenAt(n,r.index+1).type?this.rubyBlock(e,n,r.index+1):this.closingBracketBlock(e,"}",n,r.index+r[0].length):void 0},this.rubyBlock=function(e,t,n,r){var o=new i(e,t,n),s=o.getCurrentToken();if(s&&("keyword"==s.type||"comment.multiline"==s.type)){var l=s.value,c=e.getLine(t);switch(s.value){case"if":case"unless":case"while":case"until":if(!new RegExp("^\\s*"+s.value).test(c))return;var u=this.indentKeywords[l];break;case"when":if(/\sthen\s/.test(c))return;case"elsif":case"rescue":case"ensure":u=1;break;case"else":if(!new RegExp("^\\s*"+s.value+"\\s*$").test(c))return;u=1;break;default:u=this.indentKeywords[l]}var g=[l];if(u){var d=-1===u?e.getLine(t-1).length:e.getLine(t).length,p=t,m=[];if(m.push(o.getCurrentTokenRange()),o.step=-1===u?o.stepBackward:o.stepForward,"comment.multiline"==s.type){for(;s=o.step();)if("comment.multiline"===s.type)if(1==u){if(d=6,"=end"==s.value)break}else if("=begin"==s.value)break}else for(;s=o.step();){var h=!1;if("keyword"===s.type){var f=u*this.indentKeywords[s.value];switch(c=e.getLine(o.getCurrentTokenRow()),s.value){case"do":for(var x=o.$tokenIndex-1;x>=0;x--){var b=o.$rowTokens[x];if(b&&("while"==b.value||"until"==b.value||"for"==b.value)){f=0;break}}break;case"else":new RegExp("^\\s*"+s.value+"\\s*$").test(c)&&"case"!=l||(f=0,h=!0);break;case"if":case"unless":case"while":case"until":new RegExp("^\\s*"+s.value).test(c)||(f=0,h=!0);break;case"when":(/\sthen\s/.test(c)||"case"==l)&&(f=0,h=!0)}if(f>0)g.unshift(s.value);else if(f<=0&&!1===h){if(g.shift(),!g.length){if(("while"==l||"until"==l||"for"==l)&&"do"!=s.value)break;if("do"==s.value&&-1==u&&0!=f)break;if("do"!=s.value)break}0===f&&g.unshift(s.value)}}}if(!s)return null;if(r)return m.push(o.getCurrentTokenRange()),m;if(t=o.getCurrentTokenRow(),-1===u){if("comment.multiline"===s.type)var k=6;else k=e.getLine(t).length;return new a(t,k,p-1,d)}return new a(p,d,t-1,e.getLine(t-1).length)}}}}.call(s.prototype)})),ace.define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/folding/ruby"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./text").Mode,a=e("./ruby_highlight_rules").RubyHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../range").Range,l=e("./folding/ruby").FoldMode,c=function(){this.HighlightRules=a,this.$outdent=new i,this.$behaviour=this.$defaultBehaviour,this.foldingRules=new l,this.indentKeywords=this.foldingRules.indentKeywords};r.inherits(c,o),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),o=this.getTokenizer().getLineTokens(t,e).tokens;if(o.length&&"comment"==o[o.length-1].type)return r;if("start"==e){var a=t.match(/^.*[\{\(\[]\s*$/),i=t.match(/^\s*(class|def|module)\s.*$/),s=t.match(/.*do(\s*|\s+\|.*\|\s*)$/),l=t.match(/^\s*(if|else|when|elsif|unless|while|for|begin|rescue|ensure)\s*/);(a||i||s||l)&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return/^\s+(end|else|rescue|ensure)$/.test(t+n)||this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){var r=t.getLine(n);if(/}/.test(r))return this.$outdent.autoOutdent(t,n);var o=this.$getIndent(r),a=t.getLine(n-1),i=this.$getIndent(a),l=t.getTabString();i.length<=o.length&&o.slice(-l.length)==l&&t.remove(new s(n,o.length-l.length,n,o.length))},this.getMatching=function(e,t,n){if(null==t){var r=e.selection.lead;n=r.column,t=r.row}var o=e.getTokenAt(t,n);if(o&&o.value in this.indentKeywords)return this.foldingRules.rubyBlock(e,t,n,!0)},this.$id="ace/mode/ruby",this.snippetFileId="ace/snippets/ruby"}.call(c.prototype),t.Mode=c})),ace.define("ace/mode/ejs",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/javascript_highlight_rules","ace/lib/oop","ace/mode/html","ace/mode/javascript","ace/mode/css","ace/mode/ruby"],(function(e,t,n){"use strict";var r=e("../lib/oop"),o=e("./html_highlight_rules").HtmlHighlightRules,a=e("./javascript_highlight_rules").JavaScriptHighlightRules,i=function(e,t){for(var n in o.call(this),e||(e="(?:<%|<\\?|{{)"),t||(t="(?:%>|\\?>|}})"),this.$rules)this.$rules[n].unshift({token:"markup.list.meta.tag",regex:e+"(?![>}])[-=]?",push:"ejs-start"});this.embedRules(new a({jsx:!1}).getRules(),"ejs-",[{token:"markup.list.meta.tag",regex:"-?"+t,next:"pop"},{token:"comment",regex:"//.*?"+t,next:"pop"}]),this.normalizeRules()};r.inherits(i,o),t.EjsHighlightRules=i,r=e("../lib/oop");var s=e("./html").Mode,l=e("./javascript").Mode,c=e("./css").Mode,u=(e("./ruby").Mode,function(){s.call(this),this.HighlightRules=i,this.createModeDelegates({"js-":l,"css-":c,"ejs-":l})});r.inherits(u,s),function(){this.$id="ace/mode/ejs"}.call(u.prototype),t.Mode=u})),ace.require(["ace/mode/ejs"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/fa0c561bb37040fc8145e5c70ea64912.js b/fa0c561bb37040fc8145e5c70ea64912.js new file mode 100644 index 00000000..af78b164 --- /dev/null +++ b/fa0c561bb37040fc8145e5c70ea64912.js @@ -0,0 +1 @@ +ace.define("ace/mode/autohotkey_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],(function(e,t,r){"use strict";var o=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,l=function(){this.$rules={start:[{token:"comment.line.ahk",regex:"(?:^| );.*$"},{token:"comment.block.ahk",regex:"/\\*",push:[{token:"comment.block.ahk",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.ahk"}]},{token:"doc.comment.ahk",regex:"#cs",push:[{token:"doc.comment.ahk",regex:"#ce",next:"pop"},{defaultToken:"doc.comment.ahk"}]},{token:"keyword.command.ahk",regex:"(?:\\b|^)(?:allowsamelinecomments|clipboardtimeout|commentflag|errorstdout|escapechar|hotkeyinterval|hotkeymodifiertimeout|hotstring|include|includeagain|installkeybdhook|installmousehook|keyhistory|ltrim|maxhotkeysperinterval|maxmem|maxthreads|maxthreadsbuffer|maxthreadsperhotkey|noenv|notrayicon|persistent|singleinstance|usehook|winactivateforce|autotrim|blockinput|click|clipwait|continue|control|controlclick|controlfocus|controlget|controlgetfocus|controlgetpos|controlgettext|controlmove|controlsend|controlsendraw|controlsettext|coordmode|critical|detecthiddentext|detecthiddenwindows|drive|driveget|drivespacefree|edit|endrepeat|envadd|envdiv|envget|envmult|envset|envsub|envupdate|exit|exitapp|fileappend|filecopy|filecopydir|filecreatedir|filecreateshortcut|filedelete|filegetattrib|filegetshortcut|filegetsize|filegettime|filegetversion|fileinstall|filemove|filemovedir|fileread|filereadline|filerecycle|filerecycleempty|fileremovedir|fileselectfile|fileselectfolder|filesetattrib|filesettime|formattime|getkeystate|gosub|goto|groupactivate|groupadd|groupclose|groupdeactivate|gui|guicontrol|guicontrolget|hideautoitwin|hotkey|ifequal|ifexist|ifgreater|ifgreaterorequal|ifinstring|ifless|iflessorequal|ifmsgbox|ifnotequal|ifnotexist|ifnotinstring|ifwinactive|ifwinexist|ifwinnotactive|ifwinnotexist|imagesearch|inidelete|iniread|iniwrite|input|inputbox|keyhistory|keywait|listhotkeys|listlines|listvars|menu|mouseclick|mouseclickdrag|mousegetpos|mousemove|msgbox|onexit|outputdebug|pause|pixelgetcolor|pixelsearch|postmessage|process|progress|random|regdelete|regread|regwrite|reload|repeat|run|runas|runwait|send|sendevent|sendinput|sendmode|sendplay|sendmessage|sendraw|setbatchlines|setcapslockstate|setcontroldelay|setdefaultmousespeed|setenv|setformat|setkeydelay|setmousedelay|setnumlockstate|setscrolllockstate|setstorecapslockmode|settimer|settitlematchmode|setwindelay|setworkingdir|shutdown|sleep|sort|soundbeep|soundget|soundgetwavevolume|soundplay|soundset|soundsetwavevolume|splashimage|splashtextoff|splashtexton|splitpath|statusbargettext|statusbarwait|stringcasesense|stringgetpos|stringleft|stringlen|stringlower|stringmid|stringreplace|stringright|stringsplit|stringtrimleft|stringtrimright|stringupper|suspend|sysget|thread|tooltip|transform|traytip|urldownloadtofile|while|winactivate|winactivatebottom|winclose|winget|wingetactivestats|wingetactivetitle|wingetclass|wingetpos|wingettext|wingettitle|winhide|winkill|winmaximize|winmenuselectitem|winminimize|winminimizeall|winminimizeallundo|winmove|winrestore|winset|winsettitle|winshow|winwait|winwaitactive|winwaitclose|winwaitnotactive)\\b",caseInsensitive:!0},{token:"keyword.control.ahk",regex:"(?:\\b|^)(?:if|else|return|loop|break|for|while|global|local|byref)\\b",caseInsensitive:!0},{token:"support.function.ahk",regex:"(?:\\b|^)(?:abs|acos|asc|asin|atan|ceil|chr|cos|dllcall|exp|fileexist|floor|getkeystate|il_add|il_create|il_destroy|instr|substr|isfunc|islabel|ln|log|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|mod|onmessage|numget|numput|registercallback|regexmatch|regexreplace|round|sin|tan|sqrt|strlen|sb_seticon|sb_setparts|sb_settext|tv_add|tv_delete|tv_getchild|tv_getcount|tv_getnext|tv_get|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist)\\b",caseInsensitive:!0},{token:"variable.predefined.ahk",regex:"(?:\\b|^)(?:a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_formatfloat|a_formatinteger|a_gui|a_guievent|a_guicontrol|a_guicontrolevent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|programfiles|a_programfiles|a_programs|a_programscommon|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel)\\b",caseInsensitive:!0},{token:"support.constant.ahk",regex:"(?:\\b|^)(?:shift|lshift|rshift|alt|lalt|ralt|control|lcontrol|rcontrol|ctrl|lctrl|rctrl|lwin|rwin|appskey|altdown|altup|shiftdown|shiftup|ctrldown|ctrlup|lwindown|lwinup|rwindown|rwinup|lbutton|rbutton|mbutton|wheelup|wheelleft|wheelright|wheeldown|xbutton1|xbutton2|joy1|joy2|joy3|joy4|joy5|joy6|joy7|joy8|joy9|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy30|joy31|joy32|joyx|joyy|joyz|joyr|joyu|joyv|joypov|joyname|joybuttons|joyaxes|joyinfo|space|tab|enter|escape|esc|backspace|bs|delete|del|insert|ins|pgup|pgdn|home|end|up|down|left|right|printscreen|ctrlbreak|pause|scrolllock|capslock|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadmult|numpadadd|numpadsub|numpaddiv|numpaddot|numpaddel|numpadins|numpadclear|numpadup|numpaddown|numpadleft|numpadright|numpadhome|numpadend|numpadpgup|numpadpgdn|numpadenter|f1|f2|f3|f4|f5|f6|f7|f8|f9|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f20|f21|f22|f23|f24|browser_back|browser_forward|browser_refresh|browser_stop|browser_search|browser_favorites|browser_home|volume_mute|volume_down|volume_up|media_next|media_prev|media_stop|media_play_pause|launch_mail|launch_media|launch_app1|launch_app2)\\b",caseInsensitive:!0},{token:"variable.parameter",regex:"(?:\\b|^)(?:pixel|mouse|screen|relative|rgb|ltrim|rtrim|join|low|belownormal|normal|abovenormal|high|realtime|ahk_id|ahk_pid|ahk_class|ahk_group|between|contains|in|is|integer|float|integerfast|floatfast|number|digit|xdigit|alpha|upper|lower|alnum|time|date|not|or|and|alwaysontop|topmost|top|bottom|transparent|transcolor|redraw|region|id|idlast|processname|minmax|controllist|count|list|capacity|statuscd|eject|lock|unlock|label|filesystem|label|setlabel|serial|type|status|static|seconds|minutes|hours|days|read|parse|logoff|close|error|single|tray|add|rename|check|uncheck|togglecheck|enable|disable|toggleenable|default|nodefault|standard|nostandard|color|delete|deleteall|icon|noicon|tip|click|show|mainwindow|nomainwindow|useerrorlevel|text|picture|pic|groupbox|button|checkbox|radio|dropdownlist|ddl|combobox|listbox|listview|datetime|monthcal|updown|slider|tab|tab2|statusbar|treeview|iconsmall|tile|report|sortdesc|nosort|nosorthdr|grid|hdr|autosize|range|xm|ym|ys|xs|xp|yp|font|resize|owner|submit|nohide|minimize|maximize|restore|noactivate|na|cancel|destroy|center|margin|maxsize|minsize|owndialogs|guiescape|guiclose|guisize|guicontextmenu|guidropfiles|tabstop|section|altsubmit|wrap|hscroll|vscroll|border|top|bottom|buttons|expand|first|imagelist|lines|wantctrla|wantf2|vis|visfirst|number|uppercase|lowercase|limit|password|multi|wantreturn|group|background|bold|italic|strike|underline|norm|backgroundtrans|theme|caption|delimiter|minimizebox|maximizebox|sysmenu|toolwindow|flash|style|exstyle|check3|checked|checkedgray|readonly|password|hidden|left|right|center|notab|section|move|focus|hide|choose|choosestring|text|pos|enabled|disabled|visible|lastfound|lastfoundexist|alttab|shiftalttab|alttabmenu|alttabandmenu|alttabmenudismiss|notimers|interrupt|priority|waitclose|blind|raw|unicode|deref|pow|bitnot|bitand|bitor|bitxor|bitshiftleft|bitshiftright|yes|no|ok|cancel|abort|retry|ignore|tryagain|on|off|all|hkey_local_machine|hkey_users|hkey_current_user|hkey_classes_root|hkey_current_config|hklm|hku|hkcu|hkcr|hkcc|reg_sz|reg_expand_sz|reg_multi_sz|reg_dword|reg_qword|reg_binary|reg_link|reg_resource_list|reg_full_resource_descriptor|reg_resource_requirements_list|reg_dword_big_endian)\\b",caseInsensitive:!0},{keywordMap:{"constant.language":"And|ByRef|Case|Const|ContinueCase|ContinueLoop|Default|Dim|Do|Else|ElseIf|EndFunc|EndIf|EndSelect|EndSwitch|EndWith|Enum|Exit|ExitLoop|False|For|Func|Global|If|In|Local|Next|Not|Or|ReDim|Return|Select|Step|Switch|Then|To|True|Until|WEnd|While|With|Abs|ACos|AdlibDisable|AdlibEnable|Asc|AscW|ASin|Assign|ATan|AutoItSetOption|AutoItWinGetTitle|AutoItWinSetTitle|Beep|Binary|BinaryLen|BinaryMid|BinaryToString|BitAND|BitNOT|BitOR|BitRotate|BitShift|BitXOR|BlockInput|Break|Call|CDTray|Ceiling|Chr|ChrW|ClipGet|ClipPut|ConsoleRead|ConsoleWrite|ConsoleWriteError|ControlClick|ControlCommand|ControlDisable|ControlEnable|ControlFocus|ControlGetFocus|ControlGetHandle|ControlGetPos|ControlGetText|ControlHide|ControlListView|ControlMove|ControlSend|ControlSetText|ControlShow|ControlTreeView|Cos|Dec|DirCopy|DirCreate|DirGetSize|DirMove|DirRemove|DllCall|DllCallbackFree|DllCallbackGetPtr|DllCallbackRegister|DllClose|DllOpen|DllStructCreate|DllStructGetData|DllStructGetPtr|DllStructGetSize|DllStructSetData|DriveGetDrive|DriveGetFileSystem|DriveGetLabel|DriveGetSerial|DriveGetType|DriveMapAdd|DriveMapDel|DriveMapGet|DriveSetLabel|DriveSpaceFree|DriveSpaceTotal|DriveStatus|EnvGet|EnvSet|EnvUpdate|Eval|Execute|Exp|FileChangeDir|FileClose|FileCopy|FileCreateNTFSLink|FileCreateShortcut|FileDelete|FileExists|FileFindFirstFile|FileFindNextFile|FileGetAttrib|FileGetLongName|FileGetShortcut|FileGetShortName|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileOpen|FileOpenDialog|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileSaveDialog|FileSelectFolder|FileSetAttrib|FileSetTime|FileWrite|FileWriteLine|Floor|FtpSetProxy|GUICreate|GUICtrlCreateAvi|GUICtrlCreateButton|GUICtrlCreateCheckbox|GUICtrlCreateCombo|GUICtrlCreateContextMenu|GUICtrlCreateDate|GUICtrlCreateDummy|GUICtrlCreateEdit|GUICtrlCreateGraphic|GUICtrlCreateGroup|GUICtrlCreateIcon|GUICtrlCreateInput|GUICtrlCreateLabel|GUICtrlCreateList|GUICtrlCreateListView|GUICtrlCreateListViewItem|GUICtrlCreateMenu|GUICtrlCreateMenuItem|GUICtrlCreateMonthCal|GUICtrlCreateObj|GUICtrlCreatePic|GUICtrlCreateProgress|GUICtrlCreateRadio|GUICtrlCreateSlider|GUICtrlCreateTab|GUICtrlCreateTabItem|GUICtrlCreateTreeView|GUICtrlCreateTreeViewItem|GUICtrlCreateUpdown|GUICtrlDelete|GUICtrlGetHandle|GUICtrlGetState|GUICtrlRead|GUICtrlRecvMsg|GUICtrlRegisterListViewSort|GUICtrlSendMsg|GUICtrlSendToDummy|GUICtrlSetBkColor|GUICtrlSetColor|GUICtrlSetCursor|GUICtrlSetData|GUICtrlSetFont|GUICtrlSetDefColor|GUICtrlSetDefBkColor|GUICtrlSetGraphic|GUICtrlSetImage|GUICtrlSetLimit|GUICtrlSetOnEvent|GUICtrlSetPos|GUICtrlSetResizing|GUICtrlSetState|GUICtrlSetStyle|GUICtrlSetTip|GUIDelete|GUIGetCursorInfo|GUIGetMsg|GUIGetStyle|GUIRegisterMsg|GUISetAccelerators()|GUISetBkColor|GUISetCoord|GUISetCursor|GUISetFont|GUISetHelp|GUISetIcon|GUISetOnEvent|GUISetState|GUISetStyle|GUIStartGroup|GUISwitch|Hex|HotKeySet|HttpSetProxy|HWnd|InetGet|InetGetSize|IniDelete|IniRead|IniReadSection|IniReadSectionNames|IniRenameSection|IniWrite|IniWriteSection|InputBox|Int|IsAdmin|IsArray|IsBinary|IsBool|IsDeclared|IsDllStruct|IsFloat|IsHWnd|IsInt|IsKeyword|IsNumber|IsObj|IsPtr|IsString|Log|MemGetStats|Mod|MouseClick|MouseClickDrag|MouseDown|MouseGetCursor|MouseGetPos|MouseMove|MouseUp|MouseWheel|MsgBox|Number|ObjCreate|ObjEvent|ObjGet|ObjName|Opt|Ping|PixelChecksum|PixelGetColor|PixelSearch|PluginClose|PluginOpen|ProcessClose|ProcessExists|ProcessGetStats|ProcessList|ProcessSetPriority|ProcessWait|ProcessWaitClose|ProgressOff|ProgressOn|ProgressSet|Ptr|Random|RegDelete|RegEnumKey|RegEnumVal|RegRead|RegWrite|Round|Run|RunAs|RunAsWait|RunWait|Send|SendKeepActive|SetError|SetExtended|ShellExecute|ShellExecuteWait|Shutdown|Sin|Sleep|SoundPlay|SoundSetWaveVolume|SplashImageOn|SplashOff|SplashTextOn|Sqrt|SRandom|StatusbarGetText|StderrRead|StdinWrite|StdioClose|StdoutRead|String|StringAddCR|StringCompare|StringFormat|StringInStr|StringIsAlNum|StringIsAlpha|StringIsASCII|StringIsDigit|StringIsFloat|StringIsInt|StringIsLower|StringIsSpace|StringIsUpper|StringIsXDigit|StringLeft|StringLen|StringLower|StringMid|StringRegExp|StringRegExpReplace|StringReplace|StringRight|StringSplit|StringStripCR|StringStripWS|StringToBinary|StringTrimLeft|StringTrimRight|StringUpper|Tan|TCPAccept|TCPCloseSocket|TCPConnect|TCPListen|TCPNameToIP|TCPRecv|TCPSend|TCPShutdown|TCPStartup|TimerDiff|TimerInit|ToolTip|TrayCreateItem|TrayCreateMenu|TrayGetMsg|TrayItemDelete|TrayItemGetHandle|TrayItemGetState|TrayItemGetText|TrayItemSetOnEvent|TrayItemSetState|TrayItemSetText|TraySetClick|TraySetIcon|TraySetOnEvent|TraySetPauseIcon|TraySetState|TraySetToolTip|TrayTip|UBound|UDPBind|UDPCloseSocket|UDPOpen|UDPRecv|UDPSend|UDPShutdown|UDPStartup|VarGetType|WinActivate|WinActive|WinClose|WinExists|WinFlash|WinGetCaretPos|WinGetClassList|WinGetClientSize|WinGetHandle|WinGetPos|WinGetProcess|WinGetState|WinGetText|WinGetTitle|WinKill|WinList|WinMenuSelectItem|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinSetOnTop|WinSetState|WinSetTitle|WinSetTrans|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive|ArrayAdd|ArrayBinarySearch|ArrayConcatenate|ArrayDelete|ArrayDisplay|ArrayFindAll|ArrayInsert|ArrayMax|ArrayMaxIndex|ArrayMin|ArrayMinIndex|ArrayPop|ArrayPush|ArrayReverse|ArraySearch|ArraySort|ArraySwap|ArrayToClip|ArrayToString|ArrayTrim|ChooseColor|ChooseFont|ClipBoard_ChangeChain|ClipBoard_Close|ClipBoard_CountFormats|ClipBoard_Empty|ClipBoard_EnumFormats|ClipBoard_FormatStr|ClipBoard_GetData|ClipBoard_GetDataEx|ClipBoard_GetFormatName|ClipBoard_GetOpenWindow|ClipBoard_GetOwner|ClipBoard_GetPriorityFormat|ClipBoard_GetSequenceNumber|ClipBoard_GetViewer|ClipBoard_IsFormatAvailable|ClipBoard_Open|ClipBoard_RegisterFormat|ClipBoard_SetData|ClipBoard_SetDataEx|ClipBoard_SetViewer|ClipPutFile|ColorConvertHSLtoRGB|ColorConvertRGBtoHSL|ColorGetBlue|ColorGetGreen|ColorGetRed|Date_Time_CompareFileTime|Date_Time_DOSDateTimeToArray|Date_Time_DOSDateTimeToFileTime|Date_Time_DOSDateTimeToStr|Date_Time_DOSDateToArray|Date_Time_DOSDateToStr|Date_Time_DOSTimeToArray|Date_Time_DOSTimeToStr|Date_Time_EncodeFileTime|Date_Time_EncodeSystemTime|Date_Time_FileTimeToArray|Date_Time_FileTimeToDOSDateTime|Date_Time_FileTimeToLocalFileTime|Date_Time_FileTimeToStr|Date_Time_FileTimeToSystemTime|Date_Time_GetFileTime|Date_Time_GetLocalTime|Date_Time_GetSystemTime|Date_Time_GetSystemTimeAdjustment|Date_Time_GetSystemTimeAsFileTime|Date_Time_GetSystemTimes|Date_Time_GetTickCount|Date_Time_GetTimeZoneInformation|Date_Time_LocalFileTimeToFileTime|Date_Time_SetFileTime|Date_Time_SetLocalTime|Date_Time_SetSystemTime|Date_Time_SetSystemTimeAdjustment|Date_Time_SetTimeZoneInformation|Date_Time_SystemTimeToArray|Date_Time_SystemTimeToDateStr|Date_Time_SystemTimeToDateTimeStr|Date_Time_SystemTimeToFileTime|Date_Time_SystemTimeToTimeStr|Date_Time_SystemTimeToTzSpecificLocalTime|Date_Time_TzSpecificLocalTimeToSystemTime|DateAdd|DateDayOfWeek|DateDaysInMonth|DateDiff|DateIsLeapYear|DateIsValid|DateTimeFormat|DateTimeSplit|DateToDayOfWeek|DateToDayOfWeekISO|DateToDayValue|DateToMonth|DayValueToDate|DebugBugReportEnv|DebugOut|DebugSetup|Degree|EventLog__Backup|EventLog__Clear|EventLog__Close|EventLog__Count|EventLog__DeregisterSource|EventLog__Full|EventLog__Notify|EventLog__Oldest|EventLog__Open|EventLog__OpenBackup|EventLog__Read|EventLog__RegisterSource|EventLog__Report|FileCountLines|FileCreate|FileListToArray|FilePrint|FileReadToArray|FileWriteFromArray|FileWriteLog|FileWriteToLine|GDIPlus_ArrowCapCreate|GDIPlus_ArrowCapDispose|GDIPlus_ArrowCapGetFillState|GDIPlus_ArrowCapGetHeight|GDIPlus_ArrowCapGetMiddleInset|GDIPlus_ArrowCapGetWidth|GDIPlus_ArrowCapSetFillState|GDIPlus_ArrowCapSetHeight|GDIPlus_ArrowCapSetMiddleInset|GDIPlus_ArrowCapSetWidth|GDIPlus_BitmapCloneArea|GDIPlus_BitmapCreateFromFile|GDIPlus_BitmapCreateFromGraphics|GDIPlus_BitmapCreateFromHBITMAP|GDIPlus_BitmapCreateHBITMAPFromBitmap|GDIPlus_BitmapDispose|GDIPlus_BitmapLockBits|GDIPlus_BitmapUnlockBits|GDIPlus_BrushClone|GDIPlus_BrushCreateSolid|GDIPlus_BrushDispose|GDIPlus_BrushGetType|GDIPlus_CustomLineCapDispose|GDIPlus_Decoders|GDIPlus_DecodersGetCount|GDIPlus_DecodersGetSize|GDIPlus_Encoders|GDIPlus_EncodersGetCLSID|GDIPlus_EncodersGetCount|GDIPlus_EncodersGetParamList|GDIPlus_EncodersGetParamListSize|GDIPlus_EncodersGetSize|GDIPlus_FontCreate|GDIPlus_FontDispose|GDIPlus_FontFamilyCreate|GDIPlus_FontFamilyDispose|GDIPlus_GraphicsClear|GDIPlus_GraphicsCreateFromHDC|GDIPlus_GraphicsCreateFromHWND|GDIPlus_GraphicsDispose|GDIPlus_GraphicsDrawArc|GDIPlus_GraphicsDrawBezier|GDIPlus_GraphicsDrawClosedCurve|GDIPlus_GraphicsDrawCurve|GDIPlus_GraphicsDrawEllipse|GDIPlus_GraphicsDrawImage|GDIPlus_GraphicsDrawImageRect|GDIPlus_GraphicsDrawImageRectRect|GDIPlus_GraphicsDrawLine|GDIPlus_GraphicsDrawPie|GDIPlus_GraphicsDrawPolygon|GDIPlus_GraphicsDrawRect|GDIPlus_GraphicsDrawString|GDIPlus_GraphicsDrawStringEx|GDIPlus_GraphicsFillClosedCurve|GDIPlus_GraphicsFillEllipse|GDIPlus_GraphicsFillPie|GDIPlus_GraphicsFillRect|GDIPlus_GraphicsGetDC|GDIPlus_GraphicsGetSmoothingMode|GDIPlus_GraphicsMeasureString|GDIPlus_GraphicsReleaseDC|GDIPlus_GraphicsSetSmoothingMode|GDIPlus_GraphicsSetTransform|GDIPlus_ImageDispose|GDIPlus_ImageGetGraphicsContext|GDIPlus_ImageGetHeight|GDIPlus_ImageGetWidth|GDIPlus_ImageLoadFromFile|GDIPlus_ImageSaveToFile|GDIPlus_ImageSaveToFileEx|GDIPlus_MatrixCreate|GDIPlus_MatrixDispose|GDIPlus_MatrixRotate|GDIPlus_ParamAdd|GDIPlus_ParamInit|GDIPlus_PenCreate|GDIPlus_PenDispose|GDIPlus_PenGetAlignment|GDIPlus_PenGetColor|GDIPlus_PenGetCustomEndCap|GDIPlus_PenGetDashCap|GDIPlus_PenGetDashStyle|GDIPlus_PenGetEndCap|GDIPlus_PenGetWidth|GDIPlus_PenSetAlignment|GDIPlus_PenSetColor|GDIPlus_PenSetCustomEndCap|GDIPlus_PenSetDashCap|GDIPlus_PenSetDashStyle|GDIPlus_PenSetEndCap|GDIPlus_PenSetWidth|GDIPlus_RectFCreate|GDIPlus_Shutdown|GDIPlus_Startup|GDIPlus_StringFormatCreate|GDIPlus_StringFormatDispose|GetIP|GUICtrlAVI_Close|GUICtrlAVI_Create|GUICtrlAVI_Destroy|GUICtrlAVI_Open|GUICtrlAVI_OpenEx|GUICtrlAVI_Play|GUICtrlAVI_Seek|GUICtrlAVI_Show|GUICtrlAVI_Stop|GUICtrlButton_Click|GUICtrlButton_Create|GUICtrlButton_Destroy|GUICtrlButton_Enable|GUICtrlButton_GetCheck|GUICtrlButton_GetFocus|GUICtrlButton_GetIdealSize|GUICtrlButton_GetImage|GUICtrlButton_GetImageList|GUICtrlButton_GetState|GUICtrlButton_GetText|GUICtrlButton_GetTextMargin|GUICtrlButton_SetCheck|GUICtrlButton_SetFocus|GUICtrlButton_SetImage|GUICtrlButton_SetImageList|GUICtrlButton_SetSize|GUICtrlButton_SetState|GUICtrlButton_SetStyle|GUICtrlButton_SetText|GUICtrlButton_SetTextMargin|GUICtrlButton_Show|GUICtrlComboBox_AddDir|GUICtrlComboBox_AddString|GUICtrlComboBox_AutoComplete|GUICtrlComboBox_BeginUpdate|GUICtrlComboBox_Create|GUICtrlComboBox_DeleteString|GUICtrlComboBox_Destroy|GUICtrlComboBox_EndUpdate|GUICtrlComboBox_FindString|GUICtrlComboBox_FindStringExact|GUICtrlComboBox_GetComboBoxInfo|GUICtrlComboBox_GetCount|GUICtrlComboBox_GetCurSel|GUICtrlComboBox_GetDroppedControlRect|GUICtrlComboBox_GetDroppedControlRectEx|GUICtrlComboBox_GetDroppedState|GUICtrlComboBox_GetDroppedWidth|GUICtrlComboBox_GetEditSel|GUICtrlComboBox_GetEditText|GUICtrlComboBox_GetExtendedUI|GUICtrlComboBox_GetHorizontalExtent|GUICtrlComboBox_GetItemHeight|GUICtrlComboBox_GetLBText|GUICtrlComboBox_GetLBTextLen|GUICtrlComboBox_GetList|GUICtrlComboBox_GetListArray|GUICtrlComboBox_GetLocale|GUICtrlComboBox_GetLocaleCountry|GUICtrlComboBox_GetLocaleLang|GUICtrlComboBox_GetLocalePrimLang|GUICtrlComboBox_GetLocaleSubLang|GUICtrlComboBox_GetMinVisible|GUICtrlComboBox_GetTopIndex|GUICtrlComboBox_InitStorage|GUICtrlComboBox_InsertString|GUICtrlComboBox_LimitText|GUICtrlComboBox_ReplaceEditSel|GUICtrlComboBox_ResetContent|GUICtrlComboBox_SelectString|GUICtrlComboBox_SetCurSel|GUICtrlComboBox_SetDroppedWidth|GUICtrlComboBox_SetEditSel|GUICtrlComboBox_SetEditText|GUICtrlComboBox_SetExtendedUI|GUICtrlComboBox_SetHorizontalExtent|GUICtrlComboBox_SetItemHeight|GUICtrlComboBox_SetMinVisible|GUICtrlComboBox_SetTopIndex|GUICtrlComboBox_ShowDropDown|GUICtrlComboBoxEx_AddDir|GUICtrlComboBoxEx_AddString|GUICtrlComboBoxEx_BeginUpdate|GUICtrlComboBoxEx_Create|GUICtrlComboBoxEx_CreateSolidBitMap|GUICtrlComboBoxEx_DeleteString|GUICtrlComboBoxEx_Destroy|GUICtrlComboBoxEx_EndUpdate|GUICtrlComboBoxEx_FindStringExact|GUICtrlComboBoxEx_GetComboBoxInfo|GUICtrlComboBoxEx_GetComboControl|GUICtrlComboBoxEx_GetCount|GUICtrlComboBoxEx_GetCurSel|GUICtrlComboBoxEx_GetDroppedControlRect|GUICtrlComboBoxEx_GetDroppedControlRectEx|GUICtrlComboBoxEx_GetDroppedState|GUICtrlComboBoxEx_GetDroppedWidth|GUICtrlComboBoxEx_GetEditControl|GUICtrlComboBoxEx_GetEditSel|GUICtrlComboBoxEx_GetEditText|GUICtrlComboBoxEx_GetExtendedStyle|GUICtrlComboBoxEx_GetExtendedUI|GUICtrlComboBoxEx_GetImageList|GUICtrlComboBoxEx_GetItem|GUICtrlComboBoxEx_GetItemEx|GUICtrlComboBoxEx_GetItemHeight|GUICtrlComboBoxEx_GetItemImage|GUICtrlComboBoxEx_GetItemIndent|GUICtrlComboBoxEx_GetItemOverlayImage|GUICtrlComboBoxEx_GetItemParam|GUICtrlComboBoxEx_GetItemSelectedImage|GUICtrlComboBoxEx_GetItemText|GUICtrlComboBoxEx_GetItemTextLen|GUICtrlComboBoxEx_GetList|GUICtrlComboBoxEx_GetListArray|GUICtrlComboBoxEx_GetLocale|GUICtrlComboBoxEx_GetLocaleCountry|GUICtrlComboBoxEx_GetLocaleLang|GUICtrlComboBoxEx_GetLocalePrimLang|GUICtrlComboBoxEx_GetLocaleSubLang|GUICtrlComboBoxEx_GetMinVisible|GUICtrlComboBoxEx_GetTopIndex|GUICtrlComboBoxEx_InitStorage|GUICtrlComboBoxEx_InsertString|GUICtrlComboBoxEx_LimitText|GUICtrlComboBoxEx_ReplaceEditSel|GUICtrlComboBoxEx_ResetContent|GUICtrlComboBoxEx_SetCurSel|GUICtrlComboBoxEx_SetDroppedWidth|GUICtrlComboBoxEx_SetEditSel|GUICtrlComboBoxEx_SetEditText|GUICtrlComboBoxEx_SetExtendedStyle|GUICtrlComboBoxEx_SetExtendedUI|GUICtrlComboBoxEx_SetImageList|GUICtrlComboBoxEx_SetItem|GUICtrlComboBoxEx_SetItemEx|GUICtrlComboBoxEx_SetItemHeight|GUICtrlComboBoxEx_SetItemImage|GUICtrlComboBoxEx_SetItemIndent|GUICtrlComboBoxEx_SetItemOverlayImage|GUICtrlComboBoxEx_SetItemParam|GUICtrlComboBoxEx_SetItemSelectedImage|GUICtrlComboBoxEx_SetMinVisible|GUICtrlComboBoxEx_SetTopIndex|GUICtrlComboBoxEx_ShowDropDown|GUICtrlDTP_Create|GUICtrlDTP_Destroy|GUICtrlDTP_GetMCColor|GUICtrlDTP_GetMCFont|GUICtrlDTP_GetMonthCal|GUICtrlDTP_GetRange|GUICtrlDTP_GetRangeEx|GUICtrlDTP_GetSystemTime|GUICtrlDTP_GetSystemTimeEx|GUICtrlDTP_SetFormat|GUICtrlDTP_SetMCColor|GUICtrlDTP_SetMCFont|GUICtrlDTP_SetRange|GUICtrlDTP_SetRangeEx|GUICtrlDTP_SetSystemTime|GUICtrlDTP_SetSystemTimeEx|GUICtrlEdit_AppendText|GUICtrlEdit_BeginUpdate|GUICtrlEdit_CanUndo|GUICtrlEdit_CharFromPos|GUICtrlEdit_Create|GUICtrlEdit_Destroy|GUICtrlEdit_EmptyUndoBuffer|GUICtrlEdit_EndUpdate|GUICtrlEdit_Find|GUICtrlEdit_FmtLines|GUICtrlEdit_GetFirstVisibleLine|GUICtrlEdit_GetLimitText|GUICtrlEdit_GetLine|GUICtrlEdit_GetLineCount|GUICtrlEdit_GetMargins|GUICtrlEdit_GetModify|GUICtrlEdit_GetPasswordChar|GUICtrlEdit_GetRECT|GUICtrlEdit_GetRECTEx|GUICtrlEdit_GetSel|GUICtrlEdit_GetText|GUICtrlEdit_GetTextLen|GUICtrlEdit_HideBalloonTip|GUICtrlEdit_InsertText|GUICtrlEdit_LineFromChar|GUICtrlEdit_LineIndex|GUICtrlEdit_LineLength|GUICtrlEdit_LineScroll|GUICtrlEdit_PosFromChar|GUICtrlEdit_ReplaceSel|GUICtrlEdit_Scroll|GUICtrlEdit_SetLimitText|GUICtrlEdit_SetMargins|GUICtrlEdit_SetModify|GUICtrlEdit_SetPasswordChar|GUICtrlEdit_SetReadOnly|GUICtrlEdit_SetRECT|GUICtrlEdit_SetRECTEx|GUICtrlEdit_SetRECTNP|GUICtrlEdit_SetRectNPEx|GUICtrlEdit_SetSel|GUICtrlEdit_SetTabStops|GUICtrlEdit_SetText|GUICtrlEdit_ShowBalloonTip|GUICtrlEdit_Undo|GUICtrlHeader_AddItem|GUICtrlHeader_ClearFilter|GUICtrlHeader_ClearFilterAll|GUICtrlHeader_Create|GUICtrlHeader_CreateDragImage|GUICtrlHeader_DeleteItem|GUICtrlHeader_Destroy|GUICtrlHeader_EditFilter|GUICtrlHeader_GetBitmapMargin|GUICtrlHeader_GetImageList|GUICtrlHeader_GetItem|GUICtrlHeader_GetItemAlign|GUICtrlHeader_GetItemBitmap|GUICtrlHeader_GetItemCount|GUICtrlHeader_GetItemDisplay|GUICtrlHeader_GetItemFlags|GUICtrlHeader_GetItemFormat|GUICtrlHeader_GetItemImage|GUICtrlHeader_GetItemOrder|GUICtrlHeader_GetItemParam|GUICtrlHeader_GetItemRect|GUICtrlHeader_GetItemRectEx|GUICtrlHeader_GetItemText|GUICtrlHeader_GetItemWidth|GUICtrlHeader_GetOrderArray|GUICtrlHeader_GetUnicodeFormat|GUICtrlHeader_HitTest|GUICtrlHeader_InsertItem|GUICtrlHeader_Layout|GUICtrlHeader_OrderToIndex|GUICtrlHeader_SetBitmapMargin|GUICtrlHeader_SetFilterChangeTimeout|GUICtrlHeader_SetHotDivider|GUICtrlHeader_SetImageList|GUICtrlHeader_SetItem|GUICtrlHeader_SetItemAlign|GUICtrlHeader_SetItemBitmap|GUICtrlHeader_SetItemDisplay|GUICtrlHeader_SetItemFlags|GUICtrlHeader_SetItemFormat|GUICtrlHeader_SetItemImage|GUICtrlHeader_SetItemOrder|GUICtrlHeader_SetItemParam|GUICtrlHeader_SetItemText|GUICtrlHeader_SetItemWidth|GUICtrlHeader_SetOrderArray|GUICtrlHeader_SetUnicodeFormat|GUICtrlIpAddress_ClearAddress|GUICtrlIpAddress_Create|GUICtrlIpAddress_Destroy|GUICtrlIpAddress_Get|GUICtrlIpAddress_GetArray|GUICtrlIpAddress_GetEx|GUICtrlIpAddress_IsBlank|GUICtrlIpAddress_Set|GUICtrlIpAddress_SetArray|GUICtrlIpAddress_SetEx|GUICtrlIpAddress_SetFocus|GUICtrlIpAddress_SetFont|GUICtrlIpAddress_SetRange|GUICtrlIpAddress_ShowHide|GUICtrlListBox_AddFile|GUICtrlListBox_AddString|GUICtrlListBox_BeginUpdate|GUICtrlListBox_Create|GUICtrlListBox_DeleteString|GUICtrlListBox_Destroy|GUICtrlListBox_Dir|GUICtrlListBox_EndUpdate|GUICtrlListBox_FindInText|GUICtrlListBox_FindString|GUICtrlListBox_GetAnchorIndex|GUICtrlListBox_GetCaretIndex|GUICtrlListBox_GetCount|GUICtrlListBox_GetCurSel|GUICtrlListBox_GetHorizontalExtent|GUICtrlListBox_GetItemData|GUICtrlListBox_GetItemHeight|GUICtrlListBox_GetItemRect|GUICtrlListBox_GetItemRectEx|GUICtrlListBox_GetListBoxInfo|GUICtrlListBox_GetLocale|GUICtrlListBox_GetLocaleCountry|GUICtrlListBox_GetLocaleLang|GUICtrlListBox_GetLocalePrimLang|GUICtrlListBox_GetLocaleSubLang|GUICtrlListBox_GetSel|GUICtrlListBox_GetSelCount|GUICtrlListBox_GetSelItems|GUICtrlListBox_GetSelItemsText|GUICtrlListBox_GetText|GUICtrlListBox_GetTextLen|GUICtrlListBox_GetTopIndex|GUICtrlListBox_InitStorage|GUICtrlListBox_InsertString|GUICtrlListBox_ItemFromPoint|GUICtrlListBox_ReplaceString|GUICtrlListBox_ResetContent|GUICtrlListBox_SelectString|GUICtrlListBox_SelItemRange|GUICtrlListBox_SelItemRangeEx|GUICtrlListBox_SetAnchorIndex|GUICtrlListBox_SetCaretIndex|GUICtrlListBox_SetColumnWidth|GUICtrlListBox_SetCurSel|GUICtrlListBox_SetHorizontalExtent|GUICtrlListBox_SetItemData|GUICtrlListBox_SetItemHeight|GUICtrlListBox_SetLocale|GUICtrlListBox_SetSel|GUICtrlListBox_SetTabStops|GUICtrlListBox_SetTopIndex|GUICtrlListBox_Sort|GUICtrlListBox_SwapString|GUICtrlListBox_UpdateHScroll|GUICtrlListView_AddArray|GUICtrlListView_AddColumn|GUICtrlListView_AddItem|GUICtrlListView_AddSubItem|GUICtrlListView_ApproximateViewHeight|GUICtrlListView_ApproximateViewRect|GUICtrlListView_ApproximateViewWidth|GUICtrlListView_Arrange|GUICtrlListView_BeginUpdate|GUICtrlListView_CancelEditLabel|GUICtrlListView_ClickItem|GUICtrlListView_CopyItems|GUICtrlListView_Create|GUICtrlListView_CreateDragImage|GUICtrlListView_CreateSolidBitMap|GUICtrlListView_DeleteAllItems|GUICtrlListView_DeleteColumn|GUICtrlListView_DeleteItem|GUICtrlListView_DeleteItemsSelected|GUICtrlListView_Destroy|GUICtrlListView_DrawDragImage|GUICtrlListView_EditLabel|GUICtrlListView_EnableGroupView|GUICtrlListView_EndUpdate|GUICtrlListView_EnsureVisible|GUICtrlListView_FindInText|GUICtrlListView_FindItem|GUICtrlListView_FindNearest|GUICtrlListView_FindParam|GUICtrlListView_FindText|GUICtrlListView_GetBkColor|GUICtrlListView_GetBkImage|GUICtrlListView_GetCallbackMask|GUICtrlListView_GetColumn|GUICtrlListView_GetColumnCount|GUICtrlListView_GetColumnOrder|GUICtrlListView_GetColumnOrderArray|GUICtrlListView_GetColumnWidth|GUICtrlListView_GetCounterPage|GUICtrlListView_GetEditControl|GUICtrlListView_GetExtendedListViewStyle|GUICtrlListView_GetGroupInfo|GUICtrlListView_GetGroupViewEnabled|GUICtrlListView_GetHeader|GUICtrlListView_GetHotCursor|GUICtrlListView_GetHotItem|GUICtrlListView_GetHoverTime|GUICtrlListView_GetImageList|GUICtrlListView_GetISearchString|GUICtrlListView_GetItem|GUICtrlListView_GetItemChecked|GUICtrlListView_GetItemCount|GUICtrlListView_GetItemCut|GUICtrlListView_GetItemDropHilited|GUICtrlListView_GetItemEx|GUICtrlListView_GetItemFocused|GUICtrlListView_GetItemGroupID|GUICtrlListView_GetItemImage|GUICtrlListView_GetItemIndent|GUICtrlListView_GetItemParam|GUICtrlListView_GetItemPosition|GUICtrlListView_GetItemPositionX|GUICtrlListView_GetItemPositionY|GUICtrlListView_GetItemRect|GUICtrlListView_GetItemRectEx|GUICtrlListView_GetItemSelected|GUICtrlListView_GetItemSpacing|GUICtrlListView_GetItemSpacingX|GUICtrlListView_GetItemSpacingY|GUICtrlListView_GetItemState|GUICtrlListView_GetItemStateImage|GUICtrlListView_GetItemText|GUICtrlListView_GetItemTextArray|GUICtrlListView_GetItemTextString|GUICtrlListView_GetNextItem|GUICtrlListView_GetNumberOfWorkAreas|GUICtrlListView_GetOrigin|GUICtrlListView_GetOriginX|GUICtrlListView_GetOriginY|GUICtrlListView_GetOutlineColor|GUICtrlListView_GetSelectedColumn|GUICtrlListView_GetSelectedCount|GUICtrlListView_GetSelectedIndices|GUICtrlListView_GetSelectionMark|GUICtrlListView_GetStringWidth|GUICtrlListView_GetSubItemRect|GUICtrlListView_GetTextBkColor|GUICtrlListView_GetTextColor|GUICtrlListView_GetToolTips|GUICtrlListView_GetTopIndex|GUICtrlListView_GetUnicodeFormat|GUICtrlListView_GetView|GUICtrlListView_GetViewDetails|GUICtrlListView_GetViewLarge|GUICtrlListView_GetViewList|GUICtrlListView_GetViewRect|GUICtrlListView_GetViewSmall|GUICtrlListView_GetViewTile|GUICtrlListView_HideColumn|GUICtrlListView_HitTest|GUICtrlListView_InsertColumn|GUICtrlListView_InsertGroup|GUICtrlListView_InsertItem|GUICtrlListView_JustifyColumn|GUICtrlListView_MapIDToIndex|GUICtrlListView_MapIndexToID|GUICtrlListView_RedrawItems|GUICtrlListView_RegisterSortCallBack|GUICtrlListView_RemoveAllGroups|GUICtrlListView_RemoveGroup|GUICtrlListView_Scroll|GUICtrlListView_SetBkColor|GUICtrlListView_SetBkImage|GUICtrlListView_SetCallBackMask|GUICtrlListView_SetColumn|GUICtrlListView_SetColumnOrder|GUICtrlListView_SetColumnOrderArray|GUICtrlListView_SetColumnWidth|GUICtrlListView_SetExtendedListViewStyle|GUICtrlListView_SetGroupInfo|GUICtrlListView_SetHotItem|GUICtrlListView_SetHoverTime|GUICtrlListView_SetIconSpacing|GUICtrlListView_SetImageList|GUICtrlListView_SetItem|GUICtrlListView_SetItemChecked|GUICtrlListView_SetItemCount|GUICtrlListView_SetItemCut|GUICtrlListView_SetItemDropHilited|GUICtrlListView_SetItemEx|GUICtrlListView_SetItemFocused|GUICtrlListView_SetItemGroupID|GUICtrlListView_SetItemImage|GUICtrlListView_SetItemIndent|GUICtrlListView_SetItemParam|GUICtrlListView_SetItemPosition|GUICtrlListView_SetItemPosition32|GUICtrlListView_SetItemSelected|GUICtrlListView_SetItemState|GUICtrlListView_SetItemStateImage|GUICtrlListView_SetItemText|GUICtrlListView_SetOutlineColor|GUICtrlListView_SetSelectedColumn|GUICtrlListView_SetSelectionMark|GUICtrlListView_SetTextBkColor|GUICtrlListView_SetTextColor|GUICtrlListView_SetToolTips|GUICtrlListView_SetUnicodeFormat|GUICtrlListView_SetView|GUICtrlListView_SetWorkAreas|GUICtrlListView_SimpleSort|GUICtrlListView_SortItems|GUICtrlListView_SubItemHitTest|GUICtrlListView_UnRegisterSortCallBack|GUICtrlMenu_AddMenuItem|GUICtrlMenu_AppendMenu|GUICtrlMenu_CheckMenuItem|GUICtrlMenu_CheckRadioItem|GUICtrlMenu_CreateMenu|GUICtrlMenu_CreatePopup|GUICtrlMenu_DeleteMenu|GUICtrlMenu_DestroyMenu|GUICtrlMenu_DrawMenuBar|GUICtrlMenu_EnableMenuItem|GUICtrlMenu_FindItem|GUICtrlMenu_FindParent|GUICtrlMenu_GetItemBmp|GUICtrlMenu_GetItemBmpChecked|GUICtrlMenu_GetItemBmpUnchecked|GUICtrlMenu_GetItemChecked|GUICtrlMenu_GetItemCount|GUICtrlMenu_GetItemData|GUICtrlMenu_GetItemDefault|GUICtrlMenu_GetItemDisabled|GUICtrlMenu_GetItemEnabled|GUICtrlMenu_GetItemGrayed|GUICtrlMenu_GetItemHighlighted|GUICtrlMenu_GetItemID|GUICtrlMenu_GetItemInfo|GUICtrlMenu_GetItemRect|GUICtrlMenu_GetItemRectEx|GUICtrlMenu_GetItemState|GUICtrlMenu_GetItemStateEx|GUICtrlMenu_GetItemSubMenu|GUICtrlMenu_GetItemText|GUICtrlMenu_GetItemType|GUICtrlMenu_GetMenu|GUICtrlMenu_GetMenuBackground|GUICtrlMenu_GetMenuBarInfo|GUICtrlMenu_GetMenuContextHelpID|GUICtrlMenu_GetMenuData|GUICtrlMenu_GetMenuDefaultItem|GUICtrlMenu_GetMenuHeight|GUICtrlMenu_GetMenuInfo|GUICtrlMenu_GetMenuStyle|GUICtrlMenu_GetSystemMenu|GUICtrlMenu_InsertMenuItem|GUICtrlMenu_InsertMenuItemEx|GUICtrlMenu_IsMenu|GUICtrlMenu_LoadMenu|GUICtrlMenu_MapAccelerator|GUICtrlMenu_MenuItemFromPoint|GUICtrlMenu_RemoveMenu|GUICtrlMenu_SetItemBitmaps|GUICtrlMenu_SetItemBmp|GUICtrlMenu_SetItemBmpChecked|GUICtrlMenu_SetItemBmpUnchecked|GUICtrlMenu_SetItemChecked|GUICtrlMenu_SetItemData|GUICtrlMenu_SetItemDefault|GUICtrlMenu_SetItemDisabled|GUICtrlMenu_SetItemEnabled|GUICtrlMenu_SetItemGrayed|GUICtrlMenu_SetItemHighlighted|GUICtrlMenu_SetItemID|GUICtrlMenu_SetItemInfo|GUICtrlMenu_SetItemState|GUICtrlMenu_SetItemSubMenu|GUICtrlMenu_SetItemText|GUICtrlMenu_SetItemType|GUICtrlMenu_SetMenu|GUICtrlMenu_SetMenuBackground|GUICtrlMenu_SetMenuContextHelpID|GUICtrlMenu_SetMenuData|GUICtrlMenu_SetMenuDefaultItem|GUICtrlMenu_SetMenuHeight|GUICtrlMenu_SetMenuInfo|GUICtrlMenu_SetMenuStyle|GUICtrlMenu_TrackPopupMenu|GUICtrlMonthCal_Create|GUICtrlMonthCal_Destroy|GUICtrlMonthCal_GetColor|GUICtrlMonthCal_GetColorArray|GUICtrlMonthCal_GetCurSel|GUICtrlMonthCal_GetCurSelStr|GUICtrlMonthCal_GetFirstDOW|GUICtrlMonthCal_GetFirstDOWStr|GUICtrlMonthCal_GetMaxSelCount|GUICtrlMonthCal_GetMaxTodayWidth|GUICtrlMonthCal_GetMinReqHeight|GUICtrlMonthCal_GetMinReqRect|GUICtrlMonthCal_GetMinReqRectArray|GUICtrlMonthCal_GetMinReqWidth|GUICtrlMonthCal_GetMonthDelta|GUICtrlMonthCal_GetMonthRange|GUICtrlMonthCal_GetMonthRangeMax|GUICtrlMonthCal_GetMonthRangeMaxStr|GUICtrlMonthCal_GetMonthRangeMin|GUICtrlMonthCal_GetMonthRangeMinStr|GUICtrlMonthCal_GetMonthRangeSpan|GUICtrlMonthCal_GetRange|GUICtrlMonthCal_GetRangeMax|GUICtrlMonthCal_GetRangeMaxStr|GUICtrlMonthCal_GetRangeMin|GUICtrlMonthCal_GetRangeMinStr|GUICtrlMonthCal_GetSelRange|GUICtrlMonthCal_GetSelRangeMax|GUICtrlMonthCal_GetSelRangeMaxStr|GUICtrlMonthCal_GetSelRangeMin|GUICtrlMonthCal_GetSelRangeMinStr|GUICtrlMonthCal_GetToday|GUICtrlMonthCal_GetTodayStr|GUICtrlMonthCal_GetUnicodeFormat|GUICtrlMonthCal_HitTest|GUICtrlMonthCal_SetColor|GUICtrlMonthCal_SetCurSel|GUICtrlMonthCal_SetDayState|GUICtrlMonthCal_SetFirstDOW|GUICtrlMonthCal_SetMaxSelCount|GUICtrlMonthCal_SetMonthDelta|GUICtrlMonthCal_SetRange|GUICtrlMonthCal_SetSelRange|GUICtrlMonthCal_SetToday|GUICtrlMonthCal_SetUnicodeFormat|GUICtrlRebar_AddBand|GUICtrlRebar_AddToolBarBand|GUICtrlRebar_BeginDrag|GUICtrlRebar_Create|GUICtrlRebar_DeleteBand|GUICtrlRebar_Destroy|GUICtrlRebar_DragMove|GUICtrlRebar_EndDrag|GUICtrlRebar_GetBandBackColor|GUICtrlRebar_GetBandBorders|GUICtrlRebar_GetBandBordersEx|GUICtrlRebar_GetBandChildHandle|GUICtrlRebar_GetBandChildSize|GUICtrlRebar_GetBandCount|GUICtrlRebar_GetBandForeColor|GUICtrlRebar_GetBandHeaderSize|GUICtrlRebar_GetBandID|GUICtrlRebar_GetBandIdealSize|GUICtrlRebar_GetBandLength|GUICtrlRebar_GetBandLParam|GUICtrlRebar_GetBandMargins|GUICtrlRebar_GetBandMarginsEx|GUICtrlRebar_GetBandRect|GUICtrlRebar_GetBandRectEx|GUICtrlRebar_GetBandStyle|GUICtrlRebar_GetBandStyleBreak|GUICtrlRebar_GetBandStyleChildEdge|GUICtrlRebar_GetBandStyleFixedBMP|GUICtrlRebar_GetBandStyleFixedSize|GUICtrlRebar_GetBandStyleGripperAlways|GUICtrlRebar_GetBandStyleHidden|GUICtrlRebar_GetBandStyleHideTitle|GUICtrlRebar_GetBandStyleNoGripper|GUICtrlRebar_GetBandStyleTopAlign|GUICtrlRebar_GetBandStyleUseChevron|GUICtrlRebar_GetBandStyleVariableHeight|GUICtrlRebar_GetBandText|GUICtrlRebar_GetBarHeight|GUICtrlRebar_GetBKColor|GUICtrlRebar_GetColorScheme|GUICtrlRebar_GetRowCount|GUICtrlRebar_GetRowHeight|GUICtrlRebar_GetTextColor|GUICtrlRebar_GetToolTips|GUICtrlRebar_GetUnicodeFormat|GUICtrlRebar_HitTest|GUICtrlRebar_IDToIndex|GUICtrlRebar_MaximizeBand|GUICtrlRebar_MinimizeBand|GUICtrlRebar_MoveBand|GUICtrlRebar_SetBandBackColor|GUICtrlRebar_SetBandForeColor|GUICtrlRebar_SetBandHeaderSize|GUICtrlRebar_SetBandID|GUICtrlRebar_SetBandIdealSize|GUICtrlRebar_SetBandLength|GUICtrlRebar_SetBandLParam|GUICtrlRebar_SetBandStyle|GUICtrlRebar_SetBandStyleBreak|GUICtrlRebar_SetBandStyleChildEdge|GUICtrlRebar_SetBandStyleFixedBMP|GUICtrlRebar_SetBandStyleFixedSize|GUICtrlRebar_SetBandStyleGripperAlways|GUICtrlRebar_SetBandStyleHidden|GUICtrlRebar_SetBandStyleHideTitle|GUICtrlRebar_SetBandStyleNoGripper|GUICtrlRebar_SetBandStyleTopAlign|GUICtrlRebar_SetBandStyleUseChevron|GUICtrlRebar_SetBandStyleVariableHeight|GUICtrlRebar_SetBandText|GUICtrlRebar_SetBKColor|GUICtrlRebar_SetColorScheme|GUICtrlRebar_SetTextColor|GUICtrlRebar_SetToolTips|GUICtrlRebar_SetUnicodeFormat|GUICtrlRebar_ShowBand|GUICtrlSlider_ClearSel|GUICtrlSlider_ClearTics|GUICtrlSlider_Create|GUICtrlSlider_Destroy|GUICtrlSlider_GetBuddy|GUICtrlSlider_GetChannelRect|GUICtrlSlider_GetLineSize|GUICtrlSlider_GetNumTics|GUICtrlSlider_GetPageSize|GUICtrlSlider_GetPos|GUICtrlSlider_GetPTics|GUICtrlSlider_GetRange|GUICtrlSlider_GetRangeMax|GUICtrlSlider_GetRangeMin|GUICtrlSlider_GetSel|GUICtrlSlider_GetSelEnd|GUICtrlSlider_GetSelStart|GUICtrlSlider_GetThumbLength|GUICtrlSlider_GetThumbRect|GUICtrlSlider_GetThumbRectEx|GUICtrlSlider_GetTic|GUICtrlSlider_GetTicPos|GUICtrlSlider_GetToolTips|GUICtrlSlider_GetUnicodeFormat|GUICtrlSlider_SetBuddy|GUICtrlSlider_SetLineSize|GUICtrlSlider_SetPageSize|GUICtrlSlider_SetPos|GUICtrlSlider_SetRange|GUICtrlSlider_SetRangeMax|GUICtrlSlider_SetRangeMin|GUICtrlSlider_SetSel|GUICtrlSlider_SetSelEnd|GUICtrlSlider_SetSelStart|GUICtrlSlider_SetThumbLength|GUICtrlSlider_SetTic|GUICtrlSlider_SetTicFreq|GUICtrlSlider_SetTipSide|GUICtrlSlider_SetToolTips|GUICtrlSlider_SetUnicodeFormat|GUICtrlStatusBar_Create|GUICtrlStatusBar_Destroy|GUICtrlStatusBar_EmbedControl|GUICtrlStatusBar_GetBorders|GUICtrlStatusBar_GetBordersHorz|GUICtrlStatusBar_GetBordersRect|GUICtrlStatusBar_GetBordersVert|GUICtrlStatusBar_GetCount|GUICtrlStatusBar_GetHeight|GUICtrlStatusBar_GetIcon|GUICtrlStatusBar_GetParts|GUICtrlStatusBar_GetRect|GUICtrlStatusBar_GetRectEx|GUICtrlStatusBar_GetText|GUICtrlStatusBar_GetTextFlags|GUICtrlStatusBar_GetTextLength|GUICtrlStatusBar_GetTextLengthEx|GUICtrlStatusBar_GetTipText|GUICtrlStatusBar_GetUnicodeFormat|GUICtrlStatusBar_GetWidth|GUICtrlStatusBar_IsSimple|GUICtrlStatusBar_Resize|GUICtrlStatusBar_SetBkColor|GUICtrlStatusBar_SetIcon|GUICtrlStatusBar_SetMinHeight|GUICtrlStatusBar_SetParts|GUICtrlStatusBar_SetSimple|GUICtrlStatusBar_SetText|GUICtrlStatusBar_SetTipText|GUICtrlStatusBar_SetUnicodeFormat|GUICtrlStatusBar_ShowHide|GUICtrlTab_Create|GUICtrlTab_DeleteAllItems|GUICtrlTab_DeleteItem|GUICtrlTab_DeselectAll|GUICtrlTab_Destroy|GUICtrlTab_FindTab|GUICtrlTab_GetCurFocus|GUICtrlTab_GetCurSel|GUICtrlTab_GetDisplayRect|GUICtrlTab_GetDisplayRectEx|GUICtrlTab_GetExtendedStyle|GUICtrlTab_GetImageList|GUICtrlTab_GetItem|GUICtrlTab_GetItemCount|GUICtrlTab_GetItemImage|GUICtrlTab_GetItemParam|GUICtrlTab_GetItemRect|GUICtrlTab_GetItemRectEx|GUICtrlTab_GetItemState|GUICtrlTab_GetItemText|GUICtrlTab_GetRowCount|GUICtrlTab_GetToolTips|GUICtrlTab_GetUnicodeFormat|GUICtrlTab_HighlightItem|GUICtrlTab_HitTest|GUICtrlTab_InsertItem|GUICtrlTab_RemoveImage|GUICtrlTab_SetCurFocus|GUICtrlTab_SetCurSel|GUICtrlTab_SetExtendedStyle|GUICtrlTab_SetImageList|GUICtrlTab_SetItem|GUICtrlTab_SetItemImage|GUICtrlTab_SetItemParam|GUICtrlTab_SetItemSize|GUICtrlTab_SetItemState|GUICtrlTab_SetItemText|GUICtrlTab_SetMinTabWidth|GUICtrlTab_SetPadding|GUICtrlTab_SetToolTips|GUICtrlTab_SetUnicodeFormat|GUICtrlToolbar_AddBitmap|GUICtrlToolbar_AddButton|GUICtrlToolbar_AddButtonSep|GUICtrlToolbar_AddString|GUICtrlToolbar_ButtonCount|GUICtrlToolbar_CheckButton|GUICtrlToolbar_ClickAccel|GUICtrlToolbar_ClickButton|GUICtrlToolbar_ClickIndex|GUICtrlToolbar_CommandToIndex|GUICtrlToolbar_Create|GUICtrlToolbar_Customize|GUICtrlToolbar_DeleteButton|GUICtrlToolbar_Destroy|GUICtrlToolbar_EnableButton|GUICtrlToolbar_FindToolbar|GUICtrlToolbar_GetAnchorHighlight|GUICtrlToolbar_GetBitmapFlags|GUICtrlToolbar_GetButtonBitmap|GUICtrlToolbar_GetButtonInfo|GUICtrlToolbar_GetButtonInfoEx|GUICtrlToolbar_GetButtonParam|GUICtrlToolbar_GetButtonRect|GUICtrlToolbar_GetButtonRectEx|GUICtrlToolbar_GetButtonSize|GUICtrlToolbar_GetButtonState|GUICtrlToolbar_GetButtonStyle|GUICtrlToolbar_GetButtonText|GUICtrlToolbar_GetColorScheme|GUICtrlToolbar_GetDisabledImageList|GUICtrlToolbar_GetExtendedStyle|GUICtrlToolbar_GetHotImageList|GUICtrlToolbar_GetHotItem|GUICtrlToolbar_GetImageList|GUICtrlToolbar_GetInsertMark|GUICtrlToolbar_GetInsertMarkColor|GUICtrlToolbar_GetMaxSize|GUICtrlToolbar_GetMetrics|GUICtrlToolbar_GetPadding|GUICtrlToolbar_GetRows|GUICtrlToolbar_GetString|GUICtrlToolbar_GetStyle|GUICtrlToolbar_GetStyleAltDrag|GUICtrlToolbar_GetStyleCustomErase|GUICtrlToolbar_GetStyleFlat|GUICtrlToolbar_GetStyleList|GUICtrlToolbar_GetStyleRegisterDrop|GUICtrlToolbar_GetStyleToolTips|GUICtrlToolbar_GetStyleTransparent|GUICtrlToolbar_GetStyleWrapable|GUICtrlToolbar_GetTextRows|GUICtrlToolbar_GetToolTips|GUICtrlToolbar_GetUnicodeFormat|GUICtrlToolbar_HideButton|GUICtrlToolbar_HighlightButton|GUICtrlToolbar_HitTest|GUICtrlToolbar_IndexToCommand|GUICtrlToolbar_InsertButton|GUICtrlToolbar_InsertMarkHitTest|GUICtrlToolbar_IsButtonChecked|GUICtrlToolbar_IsButtonEnabled|GUICtrlToolbar_IsButtonHidden|GUICtrlToolbar_IsButtonHighlighted|GUICtrlToolbar_IsButtonIndeterminate|GUICtrlToolbar_IsButtonPressed|GUICtrlToolbar_LoadBitmap|GUICtrlToolbar_LoadImages|GUICtrlToolbar_MapAccelerator|GUICtrlToolbar_MoveButton|GUICtrlToolbar_PressButton|GUICtrlToolbar_SetAnchorHighlight|GUICtrlToolbar_SetBitmapSize|GUICtrlToolbar_SetButtonBitMap|GUICtrlToolbar_SetButtonInfo|GUICtrlToolbar_SetButtonInfoEx|GUICtrlToolbar_SetButtonParam|GUICtrlToolbar_SetButtonSize|GUICtrlToolbar_SetButtonState|GUICtrlToolbar_SetButtonStyle|GUICtrlToolbar_SetButtonText|GUICtrlToolbar_SetButtonWidth|GUICtrlToolbar_SetCmdID|GUICtrlToolbar_SetColorScheme|GUICtrlToolbar_SetDisabledImageList|GUICtrlToolbar_SetDrawTextFlags|GUICtrlToolbar_SetExtendedStyle|GUICtrlToolbar_SetHotImageList|GUICtrlToolbar_SetHotItem|GUICtrlToolbar_SetImageList|GUICtrlToolbar_SetIndent|GUICtrlToolbar_SetIndeterminate|GUICtrlToolbar_SetInsertMark|GUICtrlToolbar_SetInsertMarkColor|GUICtrlToolbar_SetMaxTextRows|GUICtrlToolbar_SetMetrics|GUICtrlToolbar_SetPadding|GUICtrlToolbar_SetParent|GUICtrlToolbar_SetRows|GUICtrlToolbar_SetStyle|GUICtrlToolbar_SetStyleAltDrag|GUICtrlToolbar_SetStyleCustomErase|GUICtrlToolbar_SetStyleFlat|GUICtrlToolbar_SetStyleList|GUICtrlToolbar_SetStyleRegisterDrop|GUICtrlToolbar_SetStyleToolTips|GUICtrlToolbar_SetStyleTransparent|GUICtrlToolbar_SetStyleWrapable|GUICtrlToolbar_SetToolTips|GUICtrlToolbar_SetUnicodeFormat|GUICtrlToolbar_SetWindowTheme|GUICtrlTreeView_Add|GUICtrlTreeView_AddChild|GUICtrlTreeView_AddChildFirst|GUICtrlTreeView_AddFirst|GUICtrlTreeView_BeginUpdate|GUICtrlTreeView_ClickItem|GUICtrlTreeView_Create|GUICtrlTreeView_CreateDragImage|GUICtrlTreeView_CreateSolidBitMap|GUICtrlTreeView_Delete|GUICtrlTreeView_DeleteAll|GUICtrlTreeView_DeleteChildren|GUICtrlTreeView_Destroy|GUICtrlTreeView_DisplayRect|GUICtrlTreeView_DisplayRectEx|GUICtrlTreeView_EditText|GUICtrlTreeView_EndEdit|GUICtrlTreeView_EndUpdate|GUICtrlTreeView_EnsureVisible|GUICtrlTreeView_Expand|GUICtrlTreeView_ExpandedOnce|GUICtrlTreeView_FindItem|GUICtrlTreeView_FindItemEx|GUICtrlTreeView_GetBkColor|GUICtrlTreeView_GetBold|GUICtrlTreeView_GetChecked|GUICtrlTreeView_GetChildCount|GUICtrlTreeView_GetChildren|GUICtrlTreeView_GetCount|GUICtrlTreeView_GetCut|GUICtrlTreeView_GetDropTarget|GUICtrlTreeView_GetEditControl|GUICtrlTreeView_GetExpanded|GUICtrlTreeView_GetFirstChild|GUICtrlTreeView_GetFirstItem|GUICtrlTreeView_GetFirstVisible|GUICtrlTreeView_GetFocused|GUICtrlTreeView_GetHeight|GUICtrlTreeView_GetImageIndex|GUICtrlTreeView_GetImageListIconHandle|GUICtrlTreeView_GetIndent|GUICtrlTreeView_GetInsertMarkColor|GUICtrlTreeView_GetISearchString|GUICtrlTreeView_GetItemByIndex|GUICtrlTreeView_GetItemHandle|GUICtrlTreeView_GetItemParam|GUICtrlTreeView_GetLastChild|GUICtrlTreeView_GetLineColor|GUICtrlTreeView_GetNext|GUICtrlTreeView_GetNextChild|GUICtrlTreeView_GetNextSibling|GUICtrlTreeView_GetNextVisible|GUICtrlTreeView_GetNormalImageList|GUICtrlTreeView_GetParentHandle|GUICtrlTreeView_GetParentParam|GUICtrlTreeView_GetPrev|GUICtrlTreeView_GetPrevChild|GUICtrlTreeView_GetPrevSibling|GUICtrlTreeView_GetPrevVisible|GUICtrlTreeView_GetScrollTime|GUICtrlTreeView_GetSelected|GUICtrlTreeView_GetSelectedImageIndex|GUICtrlTreeView_GetSelection|GUICtrlTreeView_GetSiblingCount|GUICtrlTreeView_GetState|GUICtrlTreeView_GetStateImageIndex|GUICtrlTreeView_GetStateImageList|GUICtrlTreeView_GetText|GUICtrlTreeView_GetTextColor|GUICtrlTreeView_GetToolTips|GUICtrlTreeView_GetTree|GUICtrlTreeView_GetUnicodeFormat|GUICtrlTreeView_GetVisible|GUICtrlTreeView_GetVisibleCount|GUICtrlTreeView_HitTest|GUICtrlTreeView_HitTestEx|GUICtrlTreeView_HitTestItem|GUICtrlTreeView_Index|GUICtrlTreeView_InsertItem|GUICtrlTreeView_IsFirstItem|GUICtrlTreeView_IsParent|GUICtrlTreeView_Level|GUICtrlTreeView_SelectItem|GUICtrlTreeView_SelectItemByIndex|GUICtrlTreeView_SetBkColor|GUICtrlTreeView_SetBold|GUICtrlTreeView_SetChecked|GUICtrlTreeView_SetCheckedByIndex|GUICtrlTreeView_SetChildren|GUICtrlTreeView_SetCut|GUICtrlTreeView_SetDropTarget|GUICtrlTreeView_SetFocused|GUICtrlTreeView_SetHeight|GUICtrlTreeView_SetIcon|GUICtrlTreeView_SetImageIndex|GUICtrlTreeView_SetIndent|GUICtrlTreeView_SetInsertMark|GUICtrlTreeView_SetInsertMarkColor|GUICtrlTreeView_SetItemHeight|GUICtrlTreeView_SetItemParam|GUICtrlTreeView_SetLineColor|GUICtrlTreeView_SetNormalImageList|GUICtrlTreeView_SetScrollTime|GUICtrlTreeView_SetSelected|GUICtrlTreeView_SetSelectedImageIndex|GUICtrlTreeView_SetState|GUICtrlTreeView_SetStateImageIndex|GUICtrlTreeView_SetStateImageList|GUICtrlTreeView_SetText|GUICtrlTreeView_SetTextColor|GUICtrlTreeView_SetToolTips|GUICtrlTreeView_SetUnicodeFormat|GUICtrlTreeView_Sort|GUIImageList_Add|GUIImageList_AddBitmap|GUIImageList_AddIcon|GUIImageList_AddMasked|GUIImageList_BeginDrag|GUIImageList_Copy|GUIImageList_Create|GUIImageList_Destroy|GUIImageList_DestroyIcon|GUIImageList_DragEnter|GUIImageList_DragLeave|GUIImageList_DragMove|GUIImageList_Draw|GUIImageList_DrawEx|GUIImageList_Duplicate|GUIImageList_EndDrag|GUIImageList_GetBkColor|GUIImageList_GetIcon|GUIImageList_GetIconHeight|GUIImageList_GetIconSize|GUIImageList_GetIconSizeEx|GUIImageList_GetIconWidth|GUIImageList_GetImageCount|GUIImageList_GetImageInfoEx|GUIImageList_Remove|GUIImageList_ReplaceIcon|GUIImageList_SetBkColor|GUIImageList_SetIconSize|GUIImageList_SetImageCount|GUIImageList_Swap|GUIScrollBars_EnableScrollBar|GUIScrollBars_GetScrollBarInfoEx|GUIScrollBars_GetScrollBarRect|GUIScrollBars_GetScrollBarRGState|GUIScrollBars_GetScrollBarXYLineButton|GUIScrollBars_GetScrollBarXYThumbBottom|GUIScrollBars_GetScrollBarXYThumbTop|GUIScrollBars_GetScrollInfo|GUIScrollBars_GetScrollInfoEx|GUIScrollBars_GetScrollInfoMax|GUIScrollBars_GetScrollInfoMin|GUIScrollBars_GetScrollInfoPage|GUIScrollBars_GetScrollInfoPos|GUIScrollBars_GetScrollInfoTrackPos|GUIScrollBars_GetScrollPos|GUIScrollBars_GetScrollRange|GUIScrollBars_Init|GUIScrollBars_ScrollWindow|GUIScrollBars_SetScrollInfo|GUIScrollBars_SetScrollInfoMax|GUIScrollBars_SetScrollInfoMin|GUIScrollBars_SetScrollInfoPage|GUIScrollBars_SetScrollInfoPos|GUIScrollBars_SetScrollRange|GUIScrollBars_ShowScrollBar|GUIToolTip_Activate|GUIToolTip_AddTool|GUIToolTip_AdjustRect|GUIToolTip_BitsToTTF|GUIToolTip_Create|GUIToolTip_DelTool|GUIToolTip_Destroy|GUIToolTip_EnumTools|GUIToolTip_GetBubbleHeight|GUIToolTip_GetBubbleSize|GUIToolTip_GetBubbleWidth|GUIToolTip_GetCurrentTool|GUIToolTip_GetDelayTime|GUIToolTip_GetMargin|GUIToolTip_GetMarginEx|GUIToolTip_GetMaxTipWidth|GUIToolTip_GetText|GUIToolTip_GetTipBkColor|GUIToolTip_GetTipTextColor|GUIToolTip_GetTitleBitMap|GUIToolTip_GetTitleText|GUIToolTip_GetToolCount|GUIToolTip_GetToolInfo|GUIToolTip_HitTest|GUIToolTip_NewToolRect|GUIToolTip_Pop|GUIToolTip_PopUp|GUIToolTip_SetDelayTime|GUIToolTip_SetMargin|GUIToolTip_SetMaxTipWidth|GUIToolTip_SetTipBkColor|GUIToolTip_SetTipTextColor|GUIToolTip_SetTitle|GUIToolTip_SetToolInfo|GUIToolTip_SetWindowTheme|GUIToolTip_ToolExists|GUIToolTip_ToolToArray|GUIToolTip_TrackActivate|GUIToolTip_TrackPosition|GUIToolTip_TTFToBits|GUIToolTip_Update|GUIToolTip_UpdateTipText|HexToString|IE_Example|IE_Introduction|IE_VersionInfo|IEAction|IEAttach|IEBodyReadHTML|IEBodyReadText|IEBodyWriteHTML|IECreate|IECreateEmbedded|IEDocGetObj|IEDocInsertHTML|IEDocInsertText|IEDocReadHTML|IEDocWriteHTML|IEErrorHandlerDeRegister|IEErrorHandlerRegister|IEErrorNotify|IEFormElementCheckBoxSelect|IEFormElementGetCollection|IEFormElementGetObjByName|IEFormElementGetValue|IEFormElementOptionSelect|IEFormElementRadioSelect|IEFormElementSetValue|IEFormGetCollection|IEFormGetObjByName|IEFormImageClick|IEFormReset|IEFormSubmit|IEFrameGetCollection|IEFrameGetObjByName|IEGetObjById|IEGetObjByName|IEHeadInsertEventScript|IEImgClick|IEImgGetCollection|IEIsFrameSet|IELinkClickByIndex|IELinkClickByText|IELinkGetCollection|IELoadWait|IELoadWaitTimeout|IENavigate|IEPropertyGet|IEPropertySet|IEQuit|IETableGetCollection|IETableWriteToArray|IETagNameAllGetCollection|IETagNameGetCollection|Iif|INetExplorerCapable|INetGetSource|INetMail|INetSmtpMail|IsPressed|MathCheckDiv|Max|MemGlobalAlloc|MemGlobalFree|MemGlobalLock|MemGlobalSize|MemGlobalUnlock|MemMoveMemory|MemMsgBox|MemShowError|MemVirtualAlloc|MemVirtualAllocEx|MemVirtualFree|MemVirtualFreeEx|Min|MouseTrap|NamedPipes_CallNamedPipe|NamedPipes_ConnectNamedPipe|NamedPipes_CreateNamedPipe|NamedPipes_CreatePipe|NamedPipes_DisconnectNamedPipe|NamedPipes_GetNamedPipeHandleState|NamedPipes_GetNamedPipeInfo|NamedPipes_PeekNamedPipe|NamedPipes_SetNamedPipeHandleState|NamedPipes_TransactNamedPipe|NamedPipes_WaitNamedPipe|Net_Share_ConnectionEnum|Net_Share_FileClose|Net_Share_FileEnum|Net_Share_FileGetInfo|Net_Share_PermStr|Net_Share_ResourceStr|Net_Share_SessionDel|Net_Share_SessionEnum|Net_Share_SessionGetInfo|Net_Share_ShareAdd|Net_Share_ShareCheck|Net_Share_ShareDel|Net_Share_ShareEnum|Net_Share_ShareGetInfo|Net_Share_ShareSetInfo|Net_Share_StatisticsGetSvr|Net_Share_StatisticsGetWrk|Now|NowCalc|NowCalcDate|NowDate|NowTime|PathFull|PathMake|PathSplit|ProcessGetName|ProcessGetPriority|Radian|ReplaceStringInFile|RunDOS|ScreenCapture_Capture|ScreenCapture_CaptureWnd|ScreenCapture_SaveImage|ScreenCapture_SetBMPFormat|ScreenCapture_SetJPGQuality|ScreenCapture_SetTIFColorDepth|ScreenCapture_SetTIFCompression|Security__AdjustTokenPrivileges|Security__GetAccountSid|Security__GetLengthSid|Security__GetTokenInformation|Security__ImpersonateSelf|Security__IsValidSid|Security__LookupAccountName|Security__LookupAccountSid|Security__LookupPrivilegeValue|Security__OpenProcessToken|Security__OpenThreadToken|Security__OpenThreadTokenEx|Security__SetPrivilege|Security__SidToStringSid|Security__SidTypeStr|Security__StringSidToSid|SendMessage|SendMessageA|SetDate|SetTime|Singleton|SoundClose|SoundLength|SoundOpen|SoundPause|SoundPlay|SoundPos|SoundResume|SoundSeek|SoundStatus|SoundStop|SQLite_Changes|SQLite_Close|SQLite_Display2DResult|SQLite_Encode|SQLite_ErrCode|SQLite_ErrMsg|SQLite_Escape|SQLite_Exec|SQLite_FetchData|SQLite_FetchNames|SQLite_GetTable|SQLite_GetTable2d|SQLite_LastInsertRowID|SQLite_LibVersion|SQLite_Open|SQLite_Query|SQLite_QueryFinalize|SQLite_QueryReset|SQLite_QuerySingleRow|SQLite_SaveMode|SQLite_SetTimeout|SQLite_Shutdown|SQLite_SQLiteExe|SQLite_Startup|SQLite_TotalChanges|StringAddComma|StringBetween|StringEncrypt|StringInsert|StringProper|StringRepeat|StringReverse|StringSplit|StringToHex|TCPIpToName|TempFile|TicksToTime|Timer_Diff|Timer_GetTimerID|Timer_Init|Timer_KillAllTimers|Timer_KillTimer|Timer_SetTimer|TimeToTicks|VersionCompare|viClose|viExecCommand|viFindGpib|viGpibBusReset|viGTL|viOpen|viSetAttribute|viSetTimeout|WeekNumberISO|WinAPI_AttachConsole|WinAPI_AttachThreadInput|WinAPI_Beep|WinAPI_BitBlt|WinAPI_CallNextHookEx|WinAPI_Check|WinAPI_ClientToScreen|WinAPI_CloseHandle|WinAPI_CommDlgExtendedError|WinAPI_CopyIcon|WinAPI_CreateBitmap|WinAPI_CreateCompatibleBitmap|WinAPI_CreateCompatibleDC|WinAPI_CreateEvent|WinAPI_CreateFile|WinAPI_CreateFont|WinAPI_CreateFontIndirect|WinAPI_CreateProcess|WinAPI_CreateSolidBitmap|WinAPI_CreateSolidBrush|WinAPI_CreateWindowEx|WinAPI_DefWindowProc|WinAPI_DeleteDC|WinAPI_DeleteObject|WinAPI_DestroyIcon|WinAPI_DestroyWindow|WinAPI_DrawEdge|WinAPI_DrawFrameControl|WinAPI_DrawIcon|WinAPI_DrawIconEx|WinAPI_DrawText|WinAPI_EnableWindow|WinAPI_EnumDisplayDevices|WinAPI_EnumWindows|WinAPI_EnumWindowsPopup|WinAPI_EnumWindowsTop|WinAPI_ExpandEnvironmentStrings|WinAPI_ExtractIconEx|WinAPI_FatalAppExit|WinAPI_FillRect|WinAPI_FindExecutable|WinAPI_FindWindow|WinAPI_FlashWindow|WinAPI_FlashWindowEx|WinAPI_FloatToInt|WinAPI_FlushFileBuffers|WinAPI_FormatMessage|WinAPI_FrameRect|WinAPI_FreeLibrary|WinAPI_GetAncestor|WinAPI_GetAsyncKeyState|WinAPI_GetClassName|WinAPI_GetClientHeight|WinAPI_GetClientRect|WinAPI_GetClientWidth|WinAPI_GetCurrentProcess|WinAPI_GetCurrentProcessID|WinAPI_GetCurrentThread|WinAPI_GetCurrentThreadId|WinAPI_GetCursorInfo|WinAPI_GetDC|WinAPI_GetDesktopWindow|WinAPI_GetDeviceCaps|WinAPI_GetDIBits|WinAPI_GetDlgCtrlID|WinAPI_GetDlgItem|WinAPI_GetFileSizeEx|WinAPI_GetFocus|WinAPI_GetForegroundWindow|WinAPI_GetIconInfo|WinAPI_GetLastError|WinAPI_GetLastErrorMessage|WinAPI_GetModuleHandle|WinAPI_GetMousePos|WinAPI_GetMousePosX|WinAPI_GetMousePosY|WinAPI_GetObject|WinAPI_GetOpenFileName|WinAPI_GetOverlappedResult|WinAPI_GetParent|WinAPI_GetProcessAffinityMask|WinAPI_GetSaveFileName|WinAPI_GetStdHandle|WinAPI_GetStockObject|WinAPI_GetSysColor|WinAPI_GetSysColorBrush|WinAPI_GetSystemMetrics|WinAPI_GetTextExtentPoint32|WinAPI_GetWindow|WinAPI_GetWindowDC|WinAPI_GetWindowHeight|WinAPI_GetWindowLong|WinAPI_GetWindowRect|WinAPI_GetWindowText|WinAPI_GetWindowThreadProcessId|WinAPI_GetWindowWidth|WinAPI_GetXYFromPoint|WinAPI_GlobalMemStatus|WinAPI_GUIDFromString|WinAPI_GUIDFromStringEx|WinAPI_HiWord|WinAPI_InProcess|WinAPI_IntToFloat|WinAPI_InvalidateRect|WinAPI_IsClassName|WinAPI_IsWindow|WinAPI_IsWindowVisible|WinAPI_LoadBitmap|WinAPI_LoadImage|WinAPI_LoadLibrary|WinAPI_LoadLibraryEx|WinAPI_LoadShell32Icon|WinAPI_LoadString|WinAPI_LocalFree|WinAPI_LoWord|WinAPI_MakeDWord|WinAPI_MAKELANGID|WinAPI_MAKELCID|WinAPI_MakeLong|WinAPI_MessageBeep|WinAPI_Mouse_Event|WinAPI_MoveWindow|WinAPI_MsgBox|WinAPI_MulDiv|WinAPI_MultiByteToWideChar|WinAPI_MultiByteToWideCharEx|WinAPI_OpenProcess|WinAPI_PointFromRect|WinAPI_PostMessage|WinAPI_PrimaryLangId|WinAPI_PtInRect|WinAPI_ReadFile|WinAPI_ReadProcessMemory|WinAPI_RectIsEmpty|WinAPI_RedrawWindow|WinAPI_RegisterWindowMessage|WinAPI_ReleaseCapture|WinAPI_ReleaseDC|WinAPI_ScreenToClient|WinAPI_SelectObject|WinAPI_SetBkColor|WinAPI_SetCapture|WinAPI_SetCursor|WinAPI_SetDefaultPrinter|WinAPI_SetDIBits|WinAPI_SetEvent|WinAPI_SetFocus|WinAPI_SetFont|WinAPI_SetHandleInformation|WinAPI_SetLastError|WinAPI_SetParent|WinAPI_SetProcessAffinityMask|WinAPI_SetSysColors|WinAPI_SetTextColor|WinAPI_SetWindowLong|WinAPI_SetWindowPos|WinAPI_SetWindowsHookEx|WinAPI_SetWindowText|WinAPI_ShowCursor|WinAPI_ShowError|WinAPI_ShowMsg|WinAPI_ShowWindow|WinAPI_StringFromGUID|WinAPI_SubLangId|WinAPI_SystemParametersInfo|WinAPI_TwipsPerPixelX|WinAPI_TwipsPerPixelY|WinAPI_UnhookWindowsHookEx|WinAPI_UpdateLayeredWindow|WinAPI_UpdateWindow|WinAPI_ValidateClassName|WinAPI_WaitForInputIdle|WinAPI_WaitForMultipleObjects|WinAPI_WaitForSingleObject|WinAPI_WideCharToMultiByte|WinAPI_WindowFromPoint|WinAPI_WriteConsole|WinAPI_WriteFile|WinAPI_WriteProcessMemory|WinNet_AddConnection|WinNet_AddConnection2|WinNet_AddConnection3|WinNet_CancelConnection|WinNet_CancelConnection2|WinNet_CloseEnum|WinNet_ConnectionDialog|WinNet_ConnectionDialog1|WinNet_DisconnectDialog|WinNet_DisconnectDialog1|WinNet_EnumResource|WinNet_GetConnection|WinNet_GetConnectionPerformance|WinNet_GetLastError|WinNet_GetNetworkInformation|WinNet_GetProviderName|WinNet_GetResourceInformation|WinNet_GetResourceParent|WinNet_GetUniversalName|WinNet_GetUser|WinNet_OpenEnum|WinNet_RestoreConnection|WinNet_UseConnection|Word_VersionInfo|WordAttach|WordCreate|WordDocAdd|WordDocAddLink|WordDocAddPicture|WordDocClose|WordDocFindReplace|WordDocGetCollection|WordDocLinkGetCollection|WordDocOpen|WordDocPrint|WordDocPropertyGet|WordDocPropertySet|WordDocSave|WordDocSaveAs|WordErrorHandlerDeRegister|WordErrorHandlerRegister|WordErrorNotify|WordMacroRun|WordPropertyGet|WordPropertySet|WordQuit|ce|comments-end|comments-start|cs|include|include-once|NoTrayIcon|RequireAdmin|AutoIt3Wrapper_Au3Check_Parameters|AutoIt3Wrapper_Au3Check_Stop_OnWarning|AutoIt3Wrapper_Change2CUI|AutoIt3Wrapper_Compression|AutoIt3Wrapper_cvsWrapper_Parameters|AutoIt3Wrapper_Icon|AutoIt3Wrapper_Outfile|AutoIt3Wrapper_Outfile_Type|AutoIt3Wrapper_Plugin_Funcs|AutoIt3Wrapper_Res_Comment|AutoIt3Wrapper_Res_Description|AutoIt3Wrapper_Res_Field|AutoIt3Wrapper_Res_File_Add|AutoIt3Wrapper_Res_Fileversion|AutoIt3Wrapper_Res_FileVersion_AutoIncrement|AutoIt3Wrapper_Res_Icon_Add|AutoIt3Wrapper_Res_Language|AutoIt3Wrapper_Res_LegalCopyright|AutoIt3Wrapper_res_requestedExecutionLevel|AutoIt3Wrapper_Res_SaveSource|AutoIt3Wrapper_Run_After|AutoIt3Wrapper_Run_Au3check|AutoIt3Wrapper_Run_Before|AutoIt3Wrapper_Run_cvsWrapper|AutoIt3Wrapper_Run_Debug_Mode|AutoIt3Wrapper_Run_Obfuscator|AutoIt3Wrapper_Run_Tidy|AutoIt3Wrapper_Tidy_Stop_OnError|AutoIt3Wrapper_UseAnsi|AutoIt3Wrapper_UseUpx|AutoIt3Wrapper_UseX64|AutoIt3Wrapper_Version|EndRegion|forceref|Obfuscator_Ignore_Funcs|Obfuscator_Ignore_Variables|Obfuscator_Parameters|Region|Tidy_Parameters"},regex:"\\w+\\b"},{keywordMap:{"variable.function":"AppDataCommonDir|AppDataDir|AutoItExe|AutoItPID|AutoItUnicode|AutoItVersion|AutoItX64|COM_EventObj|CommonFilesDir|Compiled|ComputerName|ComSpec|CR|CRLF|DesktopCommonDir|DesktopDepth|DesktopDir|DesktopHeight|DesktopRefresh|DesktopWidth|DocumentsCommonDir|error|exitCode|exitMethod|extended|FavoritesCommonDir|FavoritesDir|GUI_CtrlHandle|GUI_CtrlId|GUI_DragFile|GUI_DragId|GUI_DropId|GUI_WinHandle|HomeDrive|HomePath|HomeShare|HotKeyPressed|HOUR|InetGetActive|InetGetBytesRead|IPAddress1|IPAddress2|IPAddress3|IPAddress4|KBLayout|LF|LogonDNSDomain|LogonDomain|LogonServer|MDAY|MIN|MON|MyDocumentsDir|NumParams|OSBuild|OSLang|OSServicePack|OSTYPE|OSVersion|ProcessorArch|ProgramFilesDir|ProgramsCommonDir|ProgramsDir|ScriptDir|ScriptFullPath|ScriptLineNumber|ScriptName|SEC|StartMenuCommonDir|StartMenuDir|StartupCommonDir|StartupDir|SW_DISABLE|SW_ENABLE|SW_HIDE|SW_LOCK|SW_MAXIMIZE|SW_MINIMIZE|SW_RESTORE|SW_SHOW|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWMINNOACTIVE|SW_SHOWNA|SW_SHOWNOACTIVATE|SW_SHOWNORMAL|SW_UNLOCK|SystemDir|TAB|TempDir|TRAY_ID|TrayIconFlashing|TrayIconVisible|UserName|UserProfileDir|WDAY|WindowsDir|WorkingDir|YDAY|YEAR"},regex:"@\\w+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"keyword.operator.ahk",regex:"=|==|<>|:=|<|>|\\*|\\/|\\+|:|\\?|\\-"},{token:"punctuation.ahk",regex:/#|`|::|,|%/},{token:"paren",regex:/[{}()]/},{token:["punctuation.quote.double","string.quoted.ahk","punctuation.quote.double"],regex:'(")((?:[^"]|"")*)(")'},{token:["label.ahk","punctuation.definition.label.ahk"],regex:"^([^: ]+)(:)(?!:)"}]},this.normalizeRules()};l.metaData={name:"AutoHotKey",scopeName:"source.ahk",fileTypes:["ahk"],foldingStartMarker:"^\\s*/\\*|^(?![^{]*?;|[^{]*?/\\*(?!.*?\\*/.*?\\{)).*?\\{\\s*($|;|/\\*(?!.*?\\*/.*\\S))",foldingStopMarker:"^\\s*\\*/|^\\s*\\}"},o.inherits(l,i),t.AutoHotKeyHighlightRules=l})),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],(function(e,t,r){"use strict";var o=e("../../lib/oop"),i=e("../../range").Range,l=e("./fold_mode").FoldMode,a=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};o.inherits(a,l),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,r){var o=e.getLine(r);if(this.singleLineBlockCommentRe.test(o)&&!this.startRegionRe.test(o)&&!this.tripleStarBlockCommentRe.test(o))return"";var i=this._getFoldWidgetBase(e,t,r);return!i&&this.startRegionRe.test(o)?"start":i},this.getFoldWidgetRange=function(e,t,r,o){var i,l=e.getLine(r);if(this.startRegionRe.test(l))return this.getCommentRegionBlock(e,l,r);if(i=l.match(this.foldingStartMarker)){var a=i.index;if(i[1])return this.openingBracketBlock(e,i[1],r,a);var n=e.getCommentFoldRange(r,a+i[0].length,1);return n&&!n.isMultiLine()&&(o?n=this.getSectionRange(e,r):"all"!=t&&(n=null)),n}return"markbegin"!==t&&(i=l.match(this.foldingStopMarker))?(a=i.index+i[0].length,i[1]?this.closingBracketBlock(e,i[1],r,a):e.getCommentFoldRange(r,a,-1)):void 0},this.getSectionRange=function(e,t){for(var r=e.getLine(t),o=r.search(/\S/),l=t,a=r.length,n=t+=1,I=e.getLength();++tG)break;var _=this.getFoldWidgetRange(e,"all",t);if(_){if(_.start.row<=l)break;if(_.isMultiLine())t=_.end.row;else if(o==G)break}n=t}}return new i(l,a,n,e.getLine(n).length)},this.getCommentRegionBlock=function(e,t,r){for(var o=t.search(/\s*$/),l=e.getLength(),a=r,n=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,I=1;++ra)return new i(a,o,r,t.length)}}.call(a.prototype)})),ace.define("ace/mode/autohotkey",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/autohotkey_highlight_rules","ace/mode/folding/cstyle"],(function(e,t,r){"use strict";var o=e("../lib/oop"),i=e("./text").Mode,l=e("./autohotkey_highlight_rules").AutoHotKeyHighlightRules,a=e("./folding/cstyle").FoldMode,n=function(){this.HighlightRules=l,this.foldingRules=new a,this.$behaviour=this.$defaultBehaviour};o.inherits(n,i),function(){this.lineCommentStart=";",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/autohotkey"}.call(n.prototype),t.Mode=n})),ace.require(["ace/mode/autohotkey"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/fac0ce75e0690947a9e9e6f5b35c1ea8.js b/fac0ce75e0690947a9e9e6f5b35c1ea8.js new file mode 100644 index 00000000..49a49e15 --- /dev/null +++ b/fac0ce75e0690947a9e9e6f5b35c1ea8.js @@ -0,0 +1 @@ +ace.define("ace/occur",["require","exports","module","ace/lib/oop","ace/search","ace/edit_session","ace/search_highlight","ace/lib/dom"],(function(e,n,t){"use strict";var o,r=this&&this.__extends||(o=function(e,n){return o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,n){e.__proto__=n}||function(e,n){for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t])},o(e,n)},function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function t(){this.constructor=e}o(e,n),e.prototype=null===n?Object.create(n):(t.prototype=n.prototype,new t)}),a=e("./lib/oop"),i=e("./search").Search,s=e("./edit_session").EditSession,c=e("./search_highlight").SearchHighlight,l=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return r(n,e),n.prototype.enter=function(e,n){if(!n.needle)return!1;var t=e.getCursorPosition();this.displayOccurContent(e,n);var o=this.originalToOccurPosition(e.session,t);return e.moveCursorToPosition(o),!0},n.prototype.exit=function(e,n){var t=n.translatePosition&&e.getCursorPosition(),o=t&&this.occurToOriginalPosition(e.session,t);return this.displayOriginalContent(e),o&&e.moveCursorToPosition(o),!0},n.prototype.highlight=function(e,n){(e.$occurHighlight=e.$occurHighlight||e.addDynamicMarker(new c(null,"ace_occur-highlight","text"))).setRegexp(n),e._emit("changeBackMarker")},n.prototype.displayOccurContent=function(e,n){this.$originalSession=e.session;var t=this.matchingLines(e.session,n),o=t.map((function(e){return e.content})),r=new s(o.join("\n"));r.$occur=this,r.$occurMatchingLines=t,e.setSession(r),this.$useEmacsStyleLineStart=this.$originalSession.$useEmacsStyleLineStart,r.$useEmacsStyleLineStart=this.$useEmacsStyleLineStart,this.highlight(r,n.re),r._emit("changeBackMarker")},n.prototype.displayOriginalContent=function(e){e.setSession(this.$originalSession),this.$originalSession.$useEmacsStyleLineStart=this.$useEmacsStyleLineStart},n.prototype.originalToOccurPosition=function(e,n){var t=e.$occurMatchingLines,o={row:0,column:0};if(!t)return o;for(var r=0;r30&&this.$data.shift()},append:function(e){var n=this.$data.length-1,t=this.$data[n]||"";e&&(t+=e),t&&(this.$data[n]=t)},get:function(e){return e=e||1,this.$data.slice(this.$data.length-e,this.$data.length).reverse().join("\n")},pop:function(){return this.$data.length>1&&this.$data.pop(),this.get()},rotate:function(){return this.$data.unshift(this.$data.pop()),this.get()}}})),ace.require(["ace/keyboard/emacs"],(function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)})); \ No newline at end of file diff --git a/fb393a7455b47f3d4fc30cf219d5145c.js b/fb393a7455b47f3d4fc30cf219d5145c.js new file mode 100644 index 00000000..5e1c1efc --- /dev/null +++ b/fb393a7455b47f3d4fc30cf219d5145c.js @@ -0,0 +1 @@ +!function(e){if(!(void 0!==e.window&&e.document||e.require&&e.define)){e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,r,n,i){postMessage({type:"error",data:{message:e,data:i&&i.data,file:t,line:r,col:n,stack:i&&i.stack}})},e.normalizeModule=function(t,r){if(-1!==r.indexOf("!")){var n=r.split("!");return e.normalizeModule(t,n[0])+"!"+e.normalizeModule(t,n[1])}if("."==r.charAt(0)){var i=t.split("/").slice(0,-1).join("/");for(r=(i?i+"/":"")+r;-1!==r.indexOf(".")&&o!=r;){var o=r;r=r.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return r},e.require=function(t,r){if(r||(r=t,t=null),!r.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");r=e.normalizeModule(t,r);var n=e.require.modules[r];if(n)return n.initialized||(n.initialized=!0,n.exports=n.factory().exports),n.exports;if(!e.require.tlns)return console.log("unable to load "+r);var i=function(e,t){for(var r=e,n="";r;){var i=t[r];if("string"==typeof i)return i+n;if(i)return i.location.replace(/\/*$/,"/")+(n||i.main||i.name);if(!1===i)return"";var o=r.lastIndexOf("/");if(-1===o)break;n=r.substr(o)+n,r=r.slice(0,o)}return e}(r,e.require.tlns);return".js"!=i.slice(-3)&&(i+=".js"),e.require.id=r,e.require.modules[r]={},importScripts(i),e.require(t,r)},e.require.modules={},e.require.tlns={},e.define=function(t,r,n){if(2==arguments.length?(n=r,"string"!=typeof t&&(r=t,t=e.require.id)):1==arguments.length&&(n=t,r=[],t=e.require.id),"function"==typeof n){r.length||(r=["require","exports","module"]);var i=function(r){return e.require(t,r)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=n.apply(this,r.slice(0,n.length).map((function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}})));return t&&(e.exports=t),e}}}else e.require.modules[t]={exports:n,initialized:!0}},e.define.amd={},e.require.tlns={},e.initBaseUrls=function(e){for(var t in e)this.require.tlns[t]=e[t]},e.initSender=function(){var t=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),n=function(){};return function(){r.implement(this,t),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(n.prototype),new n};var t=e.main=null,r=e.sender=null;e.onmessage=function(n){var i=n.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(t[i.command])t[i.command].apply(t,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),r=e.sender=e.initSender();var o=this.require(i.module)[i.classname];t=e.main=new o(r)}}}}(this),ace.define("ace/lib/oop",[],(function(e,t,r){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var r in t)e[r]=t[r];return e},t.implement=function(e,r){t.mixin(e,r)}})),ace.define("ace/lib/deep_copy",[],(function(e,t,r){t.deepCopy=function e(t){if("object"!=typeof t||!t)return t;var r;if(Array.isArray(t)){r=[];for(var n=0;n0;)1&t&&(r+=e),(t>>=1)&&(e+=e);return r};var n=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(n,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var r in e)t[r]=e[r];return t},t.copyArray=function(e){for(var t=[],r=0,n=e.length;r65535?2:1}})),ace.define("ace/apply_delta",[],(function(e,t,r){"use strict";t.applyDelta=function(e,t,r){var n=t.start.row,i=t.start.column,o=e[n]||"";switch(t.action){case"insert":if(1===t.lines.length)e[n]=o.substring(0,i)+t.lines[0]+o.substring(i);else{var a=[n,1].concat(t.lines);e.splice.apply(e,a),e[n]=o.substring(0,i)+e[n],e[n+t.lines.length-1]+=o.substring(i)}break;case"remove":var s=t.end.column,l=t.end.row;n===l?e[n]=o.substring(0,i)+o.substring(s):e.splice(n,l-n+1,o.substring(0,i)+e[l].substring(s))}}})),ace.define("ace/lib/event_emitter",[],(function(e,t,r){"use strict";var n={},i=function(){this.propagationStopped=!0},o=function(){this.defaultPrevented=!0};n._emit=n._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var r=this._eventRegistry[e]||[],n=this._defaultHandlers[e];if(r.length||n){"object"==typeof t&&t||(t={}),t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=o),r=r.slice();for(var a=0;a ["+this.end.row+"/"+this.end.column+"]"},e.prototype.contains=function(e,t){return 0==this.compare(e,t)},e.prototype.compareRange=function(e){var t,r=e.end,n=e.start;return 1==(t=this.compare(r.row,r.column))?1==(t=this.compare(n.row,n.column))?2:0==t?1:0:-1==t?-2:-1==(t=this.compare(n.row,n.column))?-1:1==t?42:0},e.prototype.comparePoint=function(e){return this.compare(e.row,e.column)},e.prototype.containsRange=function(e){return 0==this.comparePoint(e.start)&&0==this.comparePoint(e.end)},e.prototype.intersects=function(e){var t=this.compareRange(e);return-1==t||0==t||1==t},e.prototype.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},e.prototype.isStart=function(e,t){return this.start.row==e&&this.start.column==t},e.prototype.setStart=function(e,t){"object"==typeof e?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},e.prototype.setEnd=function(e,t){"object"==typeof e?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},e.prototype.inside=function(e,t){return 0==this.compare(e,t)&&!this.isEnd(e,t)&&!this.isStart(e,t)},e.prototype.insideStart=function(e,t){return 0==this.compare(e,t)&&!this.isEnd(e,t)},e.prototype.insideEnd=function(e,t){return 0==this.compare(e,t)&&!this.isStart(e,t)},e.prototype.compare=function(e,t){return this.isMultiLine()||e!==this.start.row?ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0:tthis.end.column?1:0},e.prototype.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},e.prototype.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},e.prototype.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},e.prototype.clipRows=function(t,r){if(this.end.row>r)var n={row:r+1,column:0};else this.end.rowr)var i={row:r+1,column:0};else this.start.rowthis.row)){var t=function(e,t,r){var n="insert"==e.action,i=(n?1:-1)*(e.end.row-e.start.row),o=(n?1:-1)*(e.end.column-e.start.column),s=e.start,l=n?s:e.end;return a(t,s,r)?{row:t.row,column:t.column}:a(l,t,!r)?{row:t.row+i,column:t.column+(t.row==l.row?o:0)}:{row:s.row,column:s.column}}(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(t.row,t.column,!0)}},e.prototype.setPosition=function(e,t,r){var n;if(n=r?{row:e,column:t}:this.$clipPositionToDocument(e,t),this.row!=n.row||this.column!=n.column){var i={row:this.row,column:this.column};this.row=n.row,this.column=n.column,this._signal("change",{old:i,value:n})}},e.prototype.detach=function(){this.document.off("change",this.$onChange)},e.prototype.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},e.prototype.$clipPositionToDocument=function(e,t){var r={};return e>=this.document.getLength()?(r.row=Math.max(0,this.document.getLength()-1),r.column=this.document.getLine(r.row).length):e<0?(r.row=0,r.column=0):(r.row=e,r.column=Math.min(this.document.getLine(r.row).length,Math.max(0,t))),t<0&&(r.column=0),r},e}();function a(e,t,r){var n=r?e.column<=t.column:e.column=r&&(e=r-1,t=void 0);var n=this.getLine(e);return null==t&&(t=n.length),{row:e,column:t=Math.min(Math.max(t,0),n.length)}},e.prototype.clonePos=function(e){return{row:e.row,column:e.column}},e.prototype.pos=function(e,t){return{row:e,column:t}},e.prototype.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},e.prototype.insertFullLines=function(e,t){var r=0;(e=Math.min(Math.max(e,0),this.getLength()))0,n=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},e.prototype.replace=function(e,t){return e instanceof a||(e=a.fromPoints(e.start,e.end)),0===t.length&&e.isEmpty()?e.start:t==this.getTextRange(e)?e.end:(this.remove(e),t?this.insert(e.start,t):e.start)},e.prototype.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},e.prototype.applyDelta=function(e,t){var r="insert"==e.action;(r?e.lines.length<=1&&!e.lines[0]:!a.comparePoints(e.start,e.end))||(r&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e)))},e.prototype.$safeApplyDelta=function(e){var t=this.$lines.length;("remove"==e.action&&e.start.row=t.$lines.length)throw(s=new Error("Invalid delta")).data={path:o.$path,linesLength:t.$lines.length,start:a.start,end:a.end},s;t.applyDelta(a,!0)}if(o.$timeout)return r.schedule(o.$timeout);o.onUpdate()}))};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(o.prototype)})),ace.define("ace/mode/css/csslint",[],(function(e,t,r){var n=function(){var e=e||{},t=function(){var e;return e=function t(r,n,i){function o(s,l){if(!n[s]){if(!r[s]){var c="function"==typeof e&&e;if(!l&&c)return c(s,!0);if(a)return a(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var h=n[s]={exports:{}};r[s][0].call(h.exports,(function(e){return o(r[s][1][e]||e)}),h,h.exports,t,r,n,i)}return n[s].exports}for(var a="function"==typeof e&&e,s=0;s"===e?this.type="child":"+"===e?this.type="adjacent-sibling":"~"===e&&(this.type="sibling")}o.prototype=new n,o.prototype.constructor=o},{"../util/SyntaxUnit":26,"./Parser":6}],3:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/StringReader"),i=e("../util/SyntaxError");function o(e,t){this.match=function(t){var r;return t.mark(),(r=e(t))?t.drop():t.restore(),r},this.toString="function"==typeof t?t:function(){return t}}o.prec={MOD:5,SEQ:4,ANDAND:3,OROR:2,ALT:1},o.parse=function(e){var t,r,a,s,l,c,u,h,d;if(t=new n(e),r=function(e){var r=t.readMatch(e);if(null===r)throw new i("Expected "+e,t.getLine(),t.getCol());return r},a=function(){for(var e=[s()];null!==t.readMatch(" | ");)e.push(s());return 1===e.length?e[0]:o.alt.apply(o,e)},s=function(){for(var e=[l()];null!==t.readMatch(" || ");)e.push(l());return 1===e.length?e[0]:o.oror.apply(o,e)},l=function(){for(var e=[c()];null!==t.readMatch(" && ");)e.push(c());return 1===e.length?e[0]:o.andand.apply(o,e)},c=function(){for(var e=[u()];null!==t.readMatch(/^ (?![&|\]])/);)e.push(u());return 1===e.length?e[0]:o.seq.apply(o,e)},u=function(){var e=h();if(null!==t.readMatch("?"))return e.question();if(null!==t.readMatch("*"))return e.star();if(null!==t.readMatch("+"))return e.plus();if(null!==t.readMatch("#"))return e.hash();if(null!==t.readMatch(/^\{\s*/)){var n=r(/^\d+/);r(/^\s*,\s*/);var i=r(/^\d+/);return r(/^\s*\}/),e.braces(Number(n),Number(i))}return e},h=function(){if(null!==t.readMatch("[ ")){var e=a();return r(" ]"),e}return o.fromType(r(/^[^ ?*+#{]+/))},d=a(),!t.eof())throw new i("Expected end of string",t.getLine(),t.getCol());return d},o.cast=function(e){return e instanceof o?e:o.parse(e)},o.fromType=function(t){var r=e("./ValidationTypes");return new o((function(e){return e.hasNext()&&r.isType(e,t)}),t)},o.seq=function(){var e=Array.prototype.slice.call(arguments).map(o.cast);return 1===e.length?e[0]:new o((function(t){var r,n=!0;for(r=0;n&&rr&&(n="[ "+n+" ]"),n}))},o.alt=function(){var e=Array.prototype.slice.call(arguments).map(o.cast);return 1===e.length?e[0]:new o((function(t){var r,n=!1;for(r=0;!n&&rr&&(n="[ "+n+" ]"),n}))},o.many=function(t){var r=Array.prototype.slice.call(arguments,1).reduce((function(t,r){if(r.expand){var n=e("./ValidationTypes");t.push.apply(t,n.complex[r.expand].options)}else t.push(o.cast(r));return t}),[]);!0===t&&(t=r.map((function(){return!0})));var n=new o((function(e){var n=[],i=0,o=0,a=function(s){for(var l=0;l0;for(var s=0;sn&&(i="[ "+i+" ]"),i}));return n.options=r,n},o.andand=function(){var e=Array.prototype.slice.call(arguments);return e.unshift(!0),o.many.apply(o,e)},o.oror=function(){var e=Array.prototype.slice.call(arguments);return e.unshift(!1),o.many.apply(o,e)},o.prototype={constructor:o,match:function(){throw new Error("unimplemented")},toString:function(){throw new Error("unimplemented")},func:function(){return this.match.bind(this)},then:function(e){return o.seq(this,e)},or:function(e){return o.alt(this,e)},andand:function(e){return o.many(!0,this,e)},oror:function(e){return o.many(!1,this,e)},star:function(){return this.braces(0,1/0,"*")},plus:function(){return this.braces(1,1/0,"+")},question:function(){return this.braces(0,1,"?")},hash:function(){return this.braces(1,1/0,"#",o.cast(","))},braces:function(e,t,r,n){var i=this,a=n?n.then(this):this;return r||(r="{"+e+","+t+"}"),new o((function(r){var o;for(o=0;o0&&n?a.match(r):i.match(r));o++);return o>=e}),(function(){return i.toString(o.prec.MOD)+r}))}}},{"../util/StringReader":24,"../util/SyntaxError":25,"./ValidationTypes":21}],4:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/SyntaxUnit"),i=e("./Parser");function o(e,t){n.call(this,"("+e+(null!==t?":"+t:"")+")",e.startLine,e.startCol,i.MEDIA_FEATURE_TYPE),this.name=e,this.value=t}o.prototype=new n,o.prototype.constructor=o},{"../util/SyntaxUnit":26,"./Parser":6}],5:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/SyntaxUnit"),i=e("./Parser");function o(e,t,r,o,a){n.call(this,(e?e+" ":"")+(t||"")+(t&&r.length>0?" and ":"")+r.join(" and "),o,a,i.MEDIA_QUERY_TYPE),this.modifier=e,this.mediaType=t,this.features=r}o.prototype=new n,o.prototype.constructor=o},{"../util/SyntaxUnit":26,"./Parser":6}],6:[function(e,t,r){"use strict";t.exports=w;var n=e("../util/EventTarget"),i=e("../util/SyntaxError"),o=e("../util/SyntaxUnit"),a=e("./Combinator"),s=e("./MediaFeature"),l=e("./MediaQuery"),c=e("./PropertyName"),u=e("./PropertyValue"),h=e("./PropertyValuePart"),d=e("./Selector"),p=e("./SelectorPart"),f=e("./SelectorSubPart"),m=e("./TokenStream"),g=e("./Tokens"),b=e("./Validation");function w(e){n.call(this),this.options=e||{},this._tokenStream=null}w.DEFAULT_TYPE=0,w.COMBINATOR_TYPE=1,w.MEDIA_FEATURE_TYPE=2,w.MEDIA_QUERY_TYPE=3,w.PROPERTY_NAME_TYPE=4,w.PROPERTY_VALUE_TYPE=5,w.PROPERTY_VALUE_PART_TYPE=6,w.SELECTOR_TYPE=7,w.SELECTOR_PART_TYPE=8,w.SELECTOR_SUB_PART_TYPE=9,w.prototype=function(){var e,t=new n,r={__proto__:null,constructor:w,DEFAULT_TYPE:0,COMBINATOR_TYPE:1,MEDIA_FEATURE_TYPE:2,MEDIA_QUERY_TYPE:3,PROPERTY_NAME_TYPE:4,PROPERTY_VALUE_TYPE:5,PROPERTY_VALUE_PART_TYPE:6,SELECTOR_TYPE:7,SELECTOR_PART_TYPE:8,SELECTOR_SUB_PART_TYPE:9,_stylesheet:function(){var e,t,r,n=this._tokenStream;for(this.fire("startstylesheet"),this._charset(),this._skipCruft();n.peek()===g.IMPORT_SYM;)this._import(),this._skipCruft();for(;n.peek()===g.NAMESPACE_SYM;)this._namespace(),this._skipCruft();for(r=n.peek();r>g.EOF;){try{switch(r){case g.MEDIA_SYM:this._media(),this._skipCruft();break;case g.PAGE_SYM:this._page(),this._skipCruft();break;case g.FONT_FACE_SYM:this._font_face(),this._skipCruft();break;case g.KEYFRAMES_SYM:this._keyframes(),this._skipCruft();break;case g.VIEWPORT_SYM:this._viewport(),this._skipCruft();break;case g.DOCUMENT_SYM:this._document(),this._skipCruft();break;case g.SUPPORTS_SYM:this._supports(),this._skipCruft();break;case g.UNKNOWN_SYM:if(n.get(),this.options.strict)throw new i("Unknown @ rule.",n.LT(0).startLine,n.LT(0).startCol);for(this.fire({type:"error",error:null,message:"Unknown @ rule: "+n.LT(0).value+".",line:n.LT(0).startLine,col:n.LT(0).startCol}),e=0;n.advance([g.LBRACE,g.RBRACE])===g.LBRACE;)e++;for(;e;)n.advance([g.RBRACE]),e--;break;case g.S:this._readWhitespace();break;default:if(!this._ruleset())switch(r){case g.CHARSET_SYM:throw t=n.LT(1),this._charset(!1),new i("@charset not allowed here.",t.startLine,t.startCol);case g.IMPORT_SYM:throw t=n.LT(1),this._import(!1),new i("@import not allowed here.",t.startLine,t.startCol);case g.NAMESPACE_SYM:throw t=n.LT(1),this._namespace(!1),new i("@namespace not allowed here.",t.startLine,t.startCol);default:n.get(),this._unexpectedToken(n.token())}}}catch(e){if(!(e instanceof i)||this.options.strict)throw e;this.fire({type:"error",error:e,message:e.message,line:e.line,col:e.col})}r=n.peek()}r!==g.EOF&&this._unexpectedToken(n.token()),this.fire("endstylesheet")},_charset:function(e){var t,r,n,i=this._tokenStream;i.match(g.CHARSET_SYM)&&(r=i.token().startLine,n=i.token().startCol,this._readWhitespace(),i.mustMatch(g.STRING),t=i.token().value,this._readWhitespace(),i.mustMatch(g.SEMICOLON),!1!==e&&this.fire({type:"charset",charset:t,line:r,col:n}))},_import:function(e){var t,r,n,i=this._tokenStream;i.mustMatch(g.IMPORT_SYM),r=i.token(),this._readWhitespace(),i.mustMatch([g.STRING,g.URI]),t=i.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/,"$1"),this._readWhitespace(),n=this._media_query_list(),i.mustMatch(g.SEMICOLON),this._readWhitespace(),!1!==e&&this.fire({type:"import",uri:t,media:n,line:r.startLine,col:r.startCol})},_namespace:function(e){var t,r,n,i,o=this._tokenStream;o.mustMatch(g.NAMESPACE_SYM),t=o.token().startLine,r=o.token().startCol,this._readWhitespace(),o.match(g.IDENT)&&(n=o.token().value,this._readWhitespace()),o.mustMatch([g.STRING,g.URI]),i=o.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this._readWhitespace(),o.mustMatch(g.SEMICOLON),this._readWhitespace(),!1!==e&&this.fire({type:"namespace",prefix:n,uri:i,line:t,col:r})},_supports:function(e){var t,r,n=this._tokenStream;if(n.match(g.SUPPORTS_SYM)){for(t=n.token().startLine,r=n.token().startCol,this._readWhitespace(),this._supports_condition(),this._readWhitespace(),n.mustMatch(g.LBRACE),this._readWhitespace(),!1!==e&&this.fire({type:"startsupports",line:t,col:r});this._ruleset(););n.mustMatch(g.RBRACE),this._readWhitespace(),this.fire({type:"endsupports",line:t,col:r})}},_supports_condition:function(){var e,t=this._tokenStream;if(t.match(g.IDENT))"not"===(e=t.token().value.toLowerCase())?(t.mustMatch(g.S),this._supports_condition_in_parens()):t.unget();else for(this._supports_condition_in_parens(),this._readWhitespace();t.peek()===g.IDENT;)"and"!==(e=t.LT(1).value.toLowerCase())&&"or"!==e||(t.mustMatch(g.IDENT),this._readWhitespace(),this._supports_condition_in_parens(),this._readWhitespace())},_supports_condition_in_parens:function(){var e=this._tokenStream;e.match(g.LPAREN)?(this._readWhitespace(),e.match(g.IDENT)?"not"===e.token().value.toLowerCase()?(this._readWhitespace(),this._supports_condition(),this._readWhitespace(),e.mustMatch(g.RPAREN)):(e.unget(),this._supports_declaration_condition(!1)):(this._supports_condition(),this._readWhitespace(),e.mustMatch(g.RPAREN))):this._supports_declaration_condition()},_supports_declaration_condition:function(e){var t=this._tokenStream;!1!==e&&t.mustMatch(g.LPAREN),this._readWhitespace(),this._declaration(),t.mustMatch(g.RPAREN)},_media:function(){var e,t,r,n=this._tokenStream;for(n.mustMatch(g.MEDIA_SYM),e=n.token().startLine,t=n.token().startCol,this._readWhitespace(),r=this._media_query_list(),n.mustMatch(g.LBRACE),this._readWhitespace(),this.fire({type:"startmedia",media:r,line:e,col:t});;)if(n.peek()===g.PAGE_SYM)this._page();else if(n.peek()===g.FONT_FACE_SYM)this._font_face();else if(n.peek()===g.VIEWPORT_SYM)this._viewport();else if(n.peek()===g.DOCUMENT_SYM)this._document();else if(n.peek()===g.SUPPORTS_SYM)this._supports();else if(n.peek()===g.MEDIA_SYM)this._media();else if(!this._ruleset())break;n.mustMatch(g.RBRACE),this._readWhitespace(),this.fire({type:"endmedia",media:r,line:e,col:t})},_media_query_list:function(){var e=this._tokenStream,t=[];for(this._readWhitespace(),e.peek()!==g.IDENT&&e.peek()!==g.LPAREN||t.push(this._media_query());e.match(g.COMMA);)this._readWhitespace(),t.push(this._media_query());return t},_media_query:function(){var e=this._tokenStream,t=null,r=null,n=null,i=[];if(e.match(g.IDENT)&&("only"!==(r=e.token().value.toLowerCase())&&"not"!==r?(e.unget(),r=null):n=e.token()),this._readWhitespace(),e.peek()===g.IDENT?(t=this._media_type(),null===n&&(n=e.token())):e.peek()===g.LPAREN&&(null===n&&(n=e.LT(1)),i.push(this._media_expression())),null===t&&0===i.length)return null;for(this._readWhitespace();e.match(g.IDENT);)"and"!==e.token().value.toLowerCase()&&this._unexpectedToken(e.token()),this._readWhitespace(),i.push(this._media_expression());return new l(r,t,i,n.startLine,n.startCol)},_media_type:function(){return this._media_feature()},_media_expression:function(){var e,t,r=this._tokenStream,n=null;return r.mustMatch(g.LPAREN),this._readWhitespace(),e=this._media_feature(),this._readWhitespace(),r.match(g.COLON)&&(this._readWhitespace(),t=r.LT(1),n=this._expression()),r.mustMatch(g.RPAREN),this._readWhitespace(),new s(e,n?new o(n,t.startLine,t.startCol):null)},_media_feature:function(){var e=this._tokenStream;return this._readWhitespace(),e.mustMatch(g.IDENT),o.fromToken(e.token())},_page:function(){var e,t,r=this._tokenStream,n=null,i=null;r.mustMatch(g.PAGE_SYM),e=r.token().startLine,t=r.token().startCol,this._readWhitespace(),r.match(g.IDENT)&&"auto"===(n=r.token().value).toLowerCase()&&this._unexpectedToken(r.token()),r.peek()===g.COLON&&(i=this._pseudo_page()),this._readWhitespace(),this.fire({type:"startpage",id:n,pseudo:i,line:e,col:t}),this._readDeclarations(!0,!0),this.fire({type:"endpage",id:n,pseudo:i,line:e,col:t})},_margin:function(){var e,t,r=this._tokenStream,n=this._margin_sym();return!!n&&(e=r.token().startLine,t=r.token().startCol,this.fire({type:"startpagemargin",margin:n,line:e,col:t}),this._readDeclarations(!0),this.fire({type:"endpagemargin",margin:n,line:e,col:t}),!0)},_margin_sym:function(){var e=this._tokenStream;return e.match([g.TOPLEFTCORNER_SYM,g.TOPLEFT_SYM,g.TOPCENTER_SYM,g.TOPRIGHT_SYM,g.TOPRIGHTCORNER_SYM,g.BOTTOMLEFTCORNER_SYM,g.BOTTOMLEFT_SYM,g.BOTTOMCENTER_SYM,g.BOTTOMRIGHT_SYM,g.BOTTOMRIGHTCORNER_SYM,g.LEFTTOP_SYM,g.LEFTMIDDLE_SYM,g.LEFTBOTTOM_SYM,g.RIGHTTOP_SYM,g.RIGHTMIDDLE_SYM,g.RIGHTBOTTOM_SYM])?o.fromToken(e.token()):null},_pseudo_page:function(){var e=this._tokenStream;return e.mustMatch(g.COLON),e.mustMatch(g.IDENT),e.token().value},_font_face:function(){var e,t,r=this._tokenStream;r.mustMatch(g.FONT_FACE_SYM),e=r.token().startLine,t=r.token().startCol,this._readWhitespace(),this.fire({type:"startfontface",line:e,col:t}),this._readDeclarations(!0),this.fire({type:"endfontface",line:e,col:t})},_viewport:function(){var e,t,r=this._tokenStream;r.mustMatch(g.VIEWPORT_SYM),e=r.token().startLine,t=r.token().startCol,this._readWhitespace(),this.fire({type:"startviewport",line:e,col:t}),this._readDeclarations(!0),this.fire({type:"endviewport",line:e,col:t})},_document:function(){var e,t=this._tokenStream,r=[],n="";for(t.mustMatch(g.DOCUMENT_SYM),e=t.token(),/^@-([^-]+)-/.test(e.value)&&(n=RegExp.$1),this._readWhitespace(),r.push(this._document_function());t.match(g.COMMA);)this._readWhitespace(),r.push(this._document_function());t.mustMatch(g.LBRACE),this._readWhitespace(),this.fire({type:"startdocument",functions:r,prefix:n,line:e.startLine,col:e.startCol});for(var i=!0;i;)switch(t.peek()){case g.PAGE_SYM:this._page();break;case g.FONT_FACE_SYM:this._font_face();break;case g.VIEWPORT_SYM:this._viewport();break;case g.MEDIA_SYM:this._media();break;case g.KEYFRAMES_SYM:this._keyframes();break;case g.DOCUMENT_SYM:this._document();break;default:i=Boolean(this._ruleset())}t.mustMatch(g.RBRACE),e=t.token(),this._readWhitespace(),this.fire({type:"enddocument",functions:r,prefix:n,line:e.startLine,col:e.startCol})},_document_function:function(){var e,t=this._tokenStream;return t.match(g.URI)?(e=t.token().value,this._readWhitespace()):e=this._function(),e},_operator:function(e){var t=this._tokenStream,r=null;return(t.match([g.SLASH,g.COMMA])||e&&t.match([g.PLUS,g.STAR,g.MINUS]))&&(r=t.token(),this._readWhitespace()),r?h.fromToken(r):null},_combinator:function(){var e,t=this._tokenStream,r=null;return t.match([g.PLUS,g.GREATER,g.TILDE])&&(e=t.token(),r=new a(e.value,e.startLine,e.startCol),this._readWhitespace()),r},_unary_operator:function(){var e=this._tokenStream;return e.match([g.MINUS,g.PLUS])?e.token().value:null},_property:function(){var e,t,r,n=this._tokenStream,i=null,o=null,a="";if(n.peek()===g.STAR&&this.options.starHack&&(n.get(),o=(e=n.token()).value,t=e.startLine,r=e.startCol),n.peek()===g.MINUS&&(n.get(),a=(e=n.token()).value,t=e.startLine,r=e.startCol),n.match(g.IDENT))"_"===(a+=(e=n.token()).value).charAt(0)&&this.options.underscoreHack&&(o="_",a=a.substring(1)),i=new c(a,o,t||e.startLine,r||e.startCol),this._readWhitespace();else{var s=n.peek();s!==g.EOF&&s!==g.RBRACE&&this._unexpectedToken(n.LT(1))}return i},_ruleset:function(){var e,t=this._tokenStream;try{e=this._selectors_group()}catch(e){if(!(e instanceof i)||this.options.strict)throw e;if(this.fire({type:"error",error:e,message:e.message,line:e.line,col:e.col}),t.advance([g.RBRACE])!==g.RBRACE)throw e;return!0}return e&&(this.fire({type:"startrule",selectors:e,line:e[0].line,col:e[0].col}),this._readDeclarations(!0),this.fire({type:"endrule",selectors:e,line:e[0].line,col:e[0].col})),e},_selectors_group:function(){var e,t=this._tokenStream,r=[];if(null!==(e=this._selector()))for(r.push(e);t.match(g.COMMA);)this._readWhitespace(),null!==(e=this._selector())?r.push(e):this._unexpectedToken(t.LT(1));return r.length?r:null},_selector:function(){var e=this._tokenStream,t=[],r=null,n=null,i=null;if(null===(r=this._simple_selector_sequence()))return null;for(t.push(r);;)if(null!==(n=this._combinator()))t.push(n),null===(r=this._simple_selector_sequence())?this._unexpectedToken(e.LT(1)):t.push(r);else{if(!this._readWhitespace())break;i=new a(e.token().value,e.token().startLine,e.token().startCol),n=this._combinator(),null===(r=this._simple_selector_sequence())?null!==n&&this._unexpectedToken(e.LT(1)):(null!==n?t.push(n):t.push(i),t.push(r))}return new d(t,t[0].line,t[0].col)},_simple_selector_sequence:function(){var e,t,r=this._tokenStream,n=null,i=[],o="",a=[function(){return r.match(g.HASH)?new f(r.token().value,"id",r.token().startLine,r.token().startCol):null},this._class,this._attrib,this._pseudo,this._negation],s=0,l=a.length,c=null;for(e=r.LT(1).startLine,t=r.LT(1).startCol,(n=this._type_selector())||(n=this._universal()),null!==n&&(o+=n);r.peek()!==g.S;){for(;s1&&e.unget()),null)},_class:function(){var e,t=this._tokenStream;return t.match(g.DOT)?(t.mustMatch(g.IDENT),e=t.token(),new f("."+e.value,"class",e.startLine,e.startCol-1)):null},_element_name:function(){var e,t=this._tokenStream;return t.match(g.IDENT)?(e=t.token(),new f(e.value,"elementName",e.startLine,e.startCol)):null},_namespace_prefix:function(){var e=this._tokenStream,t="";return e.LA(1)!==g.PIPE&&e.LA(2)!==g.PIPE||(e.match([g.IDENT,g.STAR])&&(t+=e.token().value),e.mustMatch(g.PIPE),t+="|"),t.length?t:null},_universal:function(){var e,t=this._tokenStream,r="";return(e=this._namespace_prefix())&&(r+=e),t.match(g.STAR)&&(r+="*"),r.length?r:null},_attrib:function(){var e,t,r=this._tokenStream,n=null;return r.match(g.LBRACKET)?(n=(t=r.token()).value,n+=this._readWhitespace(),(e=this._namespace_prefix())&&(n+=e),r.mustMatch(g.IDENT),n+=r.token().value,n+=this._readWhitespace(),r.match([g.PREFIXMATCH,g.SUFFIXMATCH,g.SUBSTRINGMATCH,g.EQUALS,g.INCLUDES,g.DASHMATCH])&&(n+=r.token().value,n+=this._readWhitespace(),r.mustMatch([g.IDENT,g.STRING]),n+=r.token().value,n+=this._readWhitespace()),r.mustMatch(g.RBRACKET),new f(n+"]","attribute",t.startLine,t.startCol)):null},_pseudo:function(){var e,t,r=this._tokenStream,n=null,o=":";if(r.match(g.COLON)){if(r.match(g.COLON)&&(o+=":"),r.match(g.IDENT)?(n=r.token().value,e=r.token().startLine,t=r.token().startCol-o.length):r.peek()===g.FUNCTION&&(e=r.LT(1).startLine,t=r.LT(1).startCol-o.length,n=this._functional_pseudo()),!n){var a=r.LT(1).startLine,s=r.LT(0).startCol;throw new i("Expected a `FUNCTION` or `IDENT` after colon at line "+a+", col "+s+".",a,s)}n=new f(o+n,"pseudo",e,t)}return n},_functional_pseudo:function(){var e=this._tokenStream,t=null;return e.match(g.FUNCTION)&&(t=e.token().value,t+=this._readWhitespace(),t+=this._expression(),e.mustMatch(g.RPAREN),t+=")"),t},_expression:function(){for(var e=this._tokenStream,t="";e.match([g.PLUS,g.MINUS,g.DIMENSION,g.NUMBER,g.STRING,g.IDENT,g.LENGTH,g.FREQ,g.ANGLE,g.TIME,g.RESOLUTION,g.SLASH]);)t+=e.token().value,t+=this._readWhitespace();return t.length?t:null},_negation:function(){var e,t,r,n=this._tokenStream,i="",o=null;return n.match(g.NOT)&&(i=n.token().value,e=n.token().startLine,t=n.token().startCol,i+=this._readWhitespace(),i+=r=this._negation_arg(),i+=this._readWhitespace(),n.match(g.RPAREN),i+=n.token().value,(o=new f(i,"not",e,t)).args.push(r)),o},_negation_arg:function(){var e,t,r=this._tokenStream,n=[this._type_selector,this._universal,function(){return r.match(g.HASH)?new f(r.token().value,"id",r.token().startLine,r.token().startCol):null},this._class,this._attrib,this._pseudo],i=null,o=0,a=n.length;for(e=r.LT(1).startLine,t=r.LT(1).startCol;o0?new u(t,t[0].line,t[0].col):null},_term:function(e){var t,r,n,i,o=this._tokenStream,a=null,s=null,l=null;return null!==(t=this._unary_operator())&&(n=o.token().startLine,i=o.token().startCol),o.peek()===g.IE_FUNCTION&&this.options.ieFilters?(a=this._ie_function(),null===t&&(n=o.token().startLine,i=o.token().startCol)):e&&o.match([g.LPAREN,g.LBRACE,g.LBRACKET])?(s=(r=o.token()).endChar,a=r.value+this._expr(e).text,null===t&&(n=o.token().startLine,i=o.token().startCol),o.mustMatch(g.type(s)),a+=s,this._readWhitespace()):o.match([g.NUMBER,g.PERCENTAGE,g.LENGTH,g.ANGLE,g.TIME,g.FREQ,g.STRING,g.IDENT,g.URI,g.UNICODE_RANGE])?(a=o.token().value,null===t&&(n=o.token().startLine,i=o.token().startCol,l=h.fromToken(o.token())),this._readWhitespace()):null===(r=this._hexcolor())?(null===t&&(n=o.LT(1).startLine,i=o.LT(1).startCol),null===a&&(a=o.LA(3)===g.EQUALS&&this.options.ieFilters?this._ie_function():this._function())):(a=r.value,null===t&&(n=r.startLine,i=r.startCol)),null!==l?l:null!==a?new h(null!==t?t+a:a,n,i):null},_function:function(){var e,t=this._tokenStream,r=null;if(t.match(g.FUNCTION)){if(r=t.token().value,this._readWhitespace(),r+=this._expr(!0),this.options.ieFilters&&t.peek()===g.EQUALS)do{for(this._readWhitespace()&&(r+=t.token().value),t.LA(0)===g.COMMA&&(r+=t.token().value),t.match(g.IDENT),r+=t.token().value,t.match(g.EQUALS),r+=t.token().value,e=t.peek();e!==g.COMMA&&e!==g.S&&e!==g.RPAREN;)t.get(),r+=t.token().value,e=t.peek()}while(t.match([g.COMMA,g.S]));t.match(g.RPAREN),r+=")",this._readWhitespace()}return r},_ie_function:function(){var e,t=this._tokenStream,r=null;if(t.match([g.IE_FUNCTION,g.FUNCTION])){r=t.token().value;do{for(this._readWhitespace()&&(r+=t.token().value),t.LA(0)===g.COMMA&&(r+=t.token().value),t.match(g.IDENT),r+=t.token().value,t.match(g.EQUALS),r+=t.token().value,e=t.peek();e!==g.COMMA&&e!==g.S&&e!==g.RPAREN;)t.get(),r+=t.token().value,e=t.peek()}while(t.match([g.COMMA,g.S]));t.match(g.RPAREN),r+=")",this._readWhitespace()}return r},_hexcolor:function(){var e,t=this._tokenStream,r=null;if(t.match(g.HASH)){if(e=(r=t.token()).value,!/#[a-f0-9]{3,6}/i.test(e))throw new i("Expected a hex color but found '"+e+"' at line "+r.startLine+", col "+r.startCol+".",r.startLine,r.startCol);this._readWhitespace()}return r},_keyframes:function(){var e,t,r,n=this._tokenStream,i="";for(n.mustMatch(g.KEYFRAMES_SYM),e=n.token(),/^@-([^-]+)-/.test(e.value)&&(i=RegExp.$1),this._readWhitespace(),r=this._keyframe_name(),this._readWhitespace(),n.mustMatch(g.LBRACE),this.fire({type:"startkeyframes",name:r,prefix:i,line:e.startLine,col:e.startCol}),this._readWhitespace(),t=n.peek();t===g.IDENT||t===g.PERCENTAGE;)this._keyframe_rule(),this._readWhitespace(),t=n.peek();this.fire({type:"endkeyframes",name:r,prefix:i,line:e.startLine,col:e.startCol}),this._readWhitespace(),n.mustMatch(g.RBRACE),this._readWhitespace()},_keyframe_name:function(){var e=this._tokenStream;return e.mustMatch([g.IDENT,g.STRING]),o.fromToken(e.token())},_keyframe_rule:function(){var e=this._key_list();this.fire({type:"startkeyframerule",keys:e,line:e[0].line,col:e[0].col}),this._readDeclarations(!0),this.fire({type:"endkeyframerule",keys:e,line:e[0].line,col:e[0].col})},_key_list:function(){var e=this._tokenStream,t=[];for(t.push(this._key()),this._readWhitespace();e.match(g.COMMA);)this._readWhitespace(),t.push(this._key()),this._readWhitespace();return t},_key:function(){var e,t=this._tokenStream;if(t.match(g.PERCENTAGE))return o.fromToken(t.token());if(t.match(g.IDENT)){if(e=t.token(),/from|to/i.test(e.value))return o.fromToken(e);t.unget()}this._unexpectedToken(t.LT(1))},_skipCruft:function(){for(;this._tokenStream.match([g.S,g.CDO,g.CDC]););},_readDeclarations:function(e,t){var r,n=this._tokenStream;this._readWhitespace(),e&&n.mustMatch(g.LBRACE),this._readWhitespace();try{for(;;){if(n.match(g.SEMICOLON)||t&&this._margin());else{if(!this._declaration())break;if(!n.match(g.SEMICOLON))break}this._readWhitespace()}n.mustMatch(g.RBRACE),this._readWhitespace()}catch(e){if(!(e instanceof i)||this.options.strict)throw e;if(this.fire({type:"error",error:e,message:e.message,line:e.line,col:e.col}),(r=n.advance([g.SEMICOLON,g.RBRACE]))===g.SEMICOLON)this._readDeclarations(!1,t);else if(r!==g.EOF&&r!==g.RBRACE)throw e}},_readWhitespace:function(){for(var e=this._tokenStream,t="";e.match(g.S);)t+=e.token().value;return t},_unexpectedToken:function(e){throw new i("Unexpected token '"+e.value+"' at line "+e.startLine+", col "+e.startCol+".",e.startLine,e.startCol)},_verifyEnd:function(){this._tokenStream.LA(1)!==g.EOF&&this._unexpectedToken(this._tokenStream.LT(1))},_validateProperty:function(e,t){b.validate(e,t)},parse:function(e){this._tokenStream=new m(e,g),this._stylesheet()},parseStyleSheet:function(e){return this.parse(e)},parseMediaQuery:function(e){this._tokenStream=new m(e,g);var t=this._media_query();return this._verifyEnd(),t},parsePropertyValue:function(e){this._tokenStream=new m(e,g),this._readWhitespace();var t=this._expr();return this._readWhitespace(),this._verifyEnd(),t},parseRule:function(e){this._tokenStream=new m(e,g),this._readWhitespace();var t=this._ruleset();return this._readWhitespace(),this._verifyEnd(),t},parseSelector:function(e){this._tokenStream=new m(e,g),this._readWhitespace();var t=this._selector();return this._readWhitespace(),this._verifyEnd(),t},parseStyleAttribute:function(e){e+="}",this._tokenStream=new m(e,g),this._readDeclarations()}};for(e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e]);return t}()},{"../util/EventTarget":23,"../util/SyntaxError":25,"../util/SyntaxUnit":26,"./Combinator":2,"./MediaFeature":4,"./MediaQuery":5,"./PropertyName":8,"./PropertyValue":9,"./PropertyValuePart":11,"./Selector":13,"./SelectorPart":14,"./SelectorSubPart":15,"./TokenStream":17,"./Tokens":18,"./Validation":19}],7:[function(e,t,r){"use strict";t.exports={__proto__:null,"align-items":"flex-start | flex-end | center | baseline | stretch","align-content":"flex-start | flex-end | center | space-between | space-around | stretch","align-self":"auto | flex-start | flex-end | center | baseline | stretch",all:"initial | inherit | unset","-webkit-align-items":"flex-start | flex-end | center | baseline | stretch","-webkit-align-content":"flex-start | flex-end | center | space-between | space-around | stretch","-webkit-align-self":"auto | flex-start | flex-end | center | baseline | stretch","alignment-adjust":"auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | | ","alignment-baseline":"auto | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",animation:1,"animation-delay":"