mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-29 14:19:48 -04:00
Merge branch 'master' into production
This commit is contained in:
commit
6cd846a39c
80 changed files with 489 additions and 3135 deletions
app
assets/lib/ace
ace.jsext-beautify.jsext-chromevox.jsext-elastic_tabstops_lite.jsext-emmet.jsext-error_marker.jsext-keybinding_menu.jsext-language_tools.jsext-linking.jsext-modelist.jsext-old_ie.jsext-prompt.jsext-searchbox.jsext-settings_menu.jsext-spellcheck.jsext-split.jsext-static_highlight.jsext-statusbar.jsext-textarea.jsext-themelist.jsext-whitespace.jskeybinding-emacs.jskeybinding-vim.jsmode-clojure.jsmode-coffee.jsmode-javascript.jsmode-lua.jsmode-markdown.jsmode-plain_text.jsmode-python.jsmode-ruby.jsmode-text.js
snippets
theme-textmate.jsworker-coffee.jsworker-css.jsworker-html.jsworker-javascript.jsworker-json.jsworker-lua.jsworker-php.jscore
locale
schemas/models
styles
templates
views
scripts
server
analytics
commons
levels
users
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/beautify",["require","exports","module","ace/token_iterator","ace/ext/beautify/php_rules"],function(e,t,n){var r=e("ace/token_iterator").TokenIterator,i=e("./beautify/php_rules").transform;t.beautify=function(e){var t=new r(e,0,0),n=t.getCurrentToken(),s=e.$modeId.split("/").pop(),o=i(t,s);e.doc.setValue(o)},t.commands=[{name:"beautify",exec:function(e){t.beautify(e.session)},bindKey:"Ctrl-Shift-B"}]}),ace.define("ace/ext/beautify/php_rules",["require","exports","module","ace/token_iterator"],function(e,t,n){var r=e("ace/token_iterator").TokenIterator;t.newLines=[{type:"support.php_tag",value:"<?php"},{type:"support.php_tag",value:"<?"},{type:"support.php_tag",value:"?>"},{type:"paren.lparen",value:"{",indent:!0},{type:"paren.rparen",breakBefore:!0,value:"}",indent:!1},{type:"paren.rparen",breakBefore:!0,value:"})",indent:!1,dontBreak:!0},{type:"comment"},{type:"text",value:";"},{type:"text",value:":",context:"php"},{type:"keyword",value:"case",indent:!0,dontBreak:!0},{type:"keyword",value:"default",indent:!0,dontBreak:!0},{type:"keyword",value:"break",indent:!1,dontBreak:!0},{type:"punctuation.doctype.end",value:">"},{type:"meta.tag.punctuation.end",value:">"},{type:"meta.tag.punctuation.begin",value:"<",blockTag:!0,indent:!0,dontBreak:!0},{type:"meta.tag.punctuation.begin",value:"</",indent:!1,breakBefore:!0,dontBreak:!0},{type:"punctuation.operator",value:";"}],t.spaces=[{type:"xml-pe",prepend:!0},{type:"entity.other.attribute-name",prepend:!0},{type:"storage.type",value:"var",append:!0},{type:"storage.type",value:"function",append:!0},{type:"keyword.operator",value:"="},{type:"keyword",value:"as",prepend:!0,append:!0},{type:"keyword",value:"function",append:!0},{type:"support.function",next:/[^\(]/,append:!0},{type:"keyword",value:"or",append:!0,prepend:!0},{type:"keyword",value:"and",append:!0,prepend:!0},{type:"keyword",value:"case",append:!0},{type:"keyword.operator",value:"||",append:!0,prepend:!0},{type:"keyword.operator",value:"&&",append:!0,prepend:!0}],t.singleTags=["!doctype","area","base","br","hr","input","img","link","meta"],t.transform=function(e,n,r){var i=e.getCurrentToken(),s=t.newLines,o=t.spaces,u=t.singleTags,a="",f=0,l=!1,c,h,p={},d,v={},m=!1,g="";while(i!==null){console.log(i);if(!i){i=e.stepForward();continue}i.type=="support.php_tag"&&i.value!="?>"?r="php":i.type=="support.php_tag"&&i.value=="?>"?r="html":i.type=="meta.tag.name.style"&&r!="css"?r="css":i.type=="meta.tag.name.style"&&r=="css"?r="html":i.type=="meta.tag.name.script"&&r!="js"?r="js":i.type=="meta.tag.name.script"&&r=="js"&&(r="html"),v=e.stepForward(),v&&v.type.indexOf("meta.tag.name")==0&&(d=v.value),p.type=="support.php_tag"&&p.value=="<?="&&(l=!0),i.type=="meta.tag.name"&&(i.value=i.value.toLowerCase()),i.type=="text"&&(i.value=i.value.trim());if(!i.value){i=v;continue}g=i.value;for(var y in o)i.type==o[y].type&&(!o[y].value||i.value==o[y].value)&&v&&(!o[y].next||o[y].next.test(v.value))&&(o[y].prepend&&(g=" "+i.value),o[y].append&&(g+=" "));i.type.indexOf("meta.tag.name")==0&&(c=i.value),m=!1;for(y in s)if(i.type==s[y].type&&(!s[y].value||i.value==s[y].value)&&(!s[y].blockTag||u.indexOf(d)===-1)&&(!s[y].context||s[y].context===r)){s[y].indent===!1&&f--;if(s[y].breakBefore&&(!s[y].prev||s[y].prev.test(p.value))){a+="\n",m=!0;for(y=0;y<f;y++)a+=" "}break}if(l===!1)for(y in s)if(p.type==s[y].type&&(!s[y].value||p.value==s[y].value)&&(!s[y].blockTag||u.indexOf(c)===-1)&&(!s[y].context||s[y].context===r)){s[y].indent===!0&&f++;if(!s[y].dontBreak&&!m){a+="\n";for(y=0;y<f;y++)a+=" "}break}a+=g,p.type=="support.php_tag"&&p.value=="?>"&&(l=!1),h=c,p=i,i=v;if(i===null)break}return a}}),function(){ace.require(["ace/ext/beautify"],function(){})}()
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/elastic_tabstops_lite",["require","exports","module","ace/editor","ace/config"],function(e,t,n){var r=function(e){this.$editor=e;var t=this,n=[],r=!1;this.onAfterExec=function(){r=!1,t.processRows(n),n=[]},this.onExec=function(){r=!0},this.onChange=function(e){var t=e.data.range;r&&(n.indexOf(t.start.row)==-1&&n.push(t.start.row),t.end.row!=t.start.row&&n.push(t.end.row))}};(function(){this.processRows=function(e){this.$inChange=!0;var t=[];for(var n=0,r=e.length;n<r;n++){var i=e[n];if(t.indexOf(i)>-1)continue;var s=this.$findCellWidthsForBlock(i),o=this.$setBlockCellWidthsToMax(s.cellWidths),u=s.firstRow;for(var a=0,f=o.length;a<f;a++){var l=o[a];t.push(u),this.$adjustRow(u,l),u++}}this.$inChange=!1},this.$findCellWidthsForBlock=function(e){var t=[],n,r=e;while(r>=0){n=this.$cellWidthsForRow(r);if(n.length==0)break;t.unshift(n),r--}var i=r+1;r=e;var s=this.$editor.session.getLength();while(r<s-1){r++,n=this.$cellWidthsForRow(r);if(n.length==0)break;t.push(n)}return{cellWidths:t,firstRow:i}},this.$cellWidthsForRow=function(e){var t=this.$selectionColumnsForRow(e),n=[-1].concat(this.$tabsForRow(e)),r=n.map(function(e){return 0}).slice(1),i=this.$editor.session.getLine(e);for(var s=0,o=n.length-1;s<o;s++){var u=n[s]+1,a=n[s+1],f=this.$rightmostSelectionInCell(t,a),l=i.substring(u,a);r[s]=Math.max(l.replace(/\s+$/g,"").length,f-u)}return r},this.$selectionColumnsForRow=function(e){var t=[],n=this.$editor.getCursorPosition();return this.$editor.session.getSelection().isEmpty()&&e==n.row&&t.push(n.column),t},this.$setBlockCellWidthsToMax=function(e){var t=!0,n,r,i,s=this.$izip_longest(e);for(var o=0,u=s.length;o<u;o++){var a=s[o];if(!a.push){console.error(a);continue}a.push(NaN);for(var f=0,l=a.length;f<l;f++){var c=a[f];t&&(n=f,i=0,t=!1);if(isNaN(c)){r=f;for(var h=n;h<r;h++)e[h][o]=i;t=!0}i=Math.max(i,c)}}return e},this.$rightmostSelectionInCell=function(e,t){var n=0;if(e.length){var r=[];for(var i=0,s=e.length;i<s;i++)e[i]<=t?r.push(i):r.push(0);n=Math.max.apply(Math,r)}return n},this.$tabsForRow=function(e){var t=[],n=this.$editor.session.getLine(e),r=/\t/g,i;while((i=r.exec(n))!=null)t.push(i.index);return t},this.$adjustRow=function(e,t){var n=this.$tabsForRow(e);if(n.length==0)return;var r=0,i=-1,s=this.$izip(t,n);for(var o=0,u=s.length;o<u;o++){var a=s[o][0],f=s[o][1];i+=1+a,f+=r;var l=i-f;if(l==0)continue;var c=this.$editor.session.getLine(e).substr(0,f),h=c.replace(/\s*$/g,""),p=c.length-h.length;l>0&&(this.$editor.session.getDocument().insertInLine({row:e,column:f+1},Array(l+1).join(" ")+" "),this.$editor.session.getDocument().removeInLine(e,f,f+1),r+=l),l<0&&p>=-l&&(this.$editor.session.getDocument().removeInLine(e,f+l,f),r+=l)}},this.$izip_longest=function(e){if(!e[0])return[];var t=e[0].length,n=e.length;for(var r=1;r<n;r++){var i=e[r].length;i>t&&(t=i)}var s=[];for(var o=0;o<t;o++){var u=[];for(var r=0;r<n;r++)e[r][o]===""?u.push(NaN):u.push(e[r][o]);s.push(u)}return s},this.$izip=function(e,t){var n=e.length>=t.length?t.length:e.length,r=[];for(var i=0;i<n;i++){var s=[e[i],t[i]];r.push(s)}return r}}).call(r.prototype),t.ElasticTabstopsLite=r;var i=e("../editor").Editor;e("../config").defineOptions(i.prototype,"editor",{useElasticTabstops:{set:function(e){e?(this.elasticTabstops||(this.elasticTabstops=new r(this)),this.commands.on("afterExec",this.elasticTabstops.onAfterExec),this.commands.on("exec",this.elasticTabstops.onExec),this.on("change",this.elasticTabstops.onChange)):this.elasticTabstops&&(this.commands.removeListener("afterExec",this.elasticTabstops.onAfterExec),this.commands.removeListener("exec",this.elasticTabstops.onExec),this.removeListener("change",this.elasticTabstops.onChange))}}})}),function(){ace.require(["ace/ext/elastic_tabstops_lite"],function(){})}()
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
(function(){ace.require(["ace/ext/error_marker"],function(){})})()
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/keybinding_menu",["require","exports","module","ace/editor","ace/ext/menu_tools/overlay_page","ace/ext/menu_tools/get_editor_keyboard_shortcuts"],function(e,t,n){function i(t){if(!document.getElementById("kbshortcutmenu")){var n=e("./menu_tools/overlay_page").overlayPage,r=e("./menu_tools/get_editor_keyboard_shortcuts").getEditorKeybordShortcuts,i=r(t),s=document.createElement("div"),o=i.reduce(function(e,t){return e+'<div class="ace_optionsMenuEntry"><span class="ace_optionsMenuCommand">'+t.command+"</span> : "+'<span class="ace_optionsMenuKey">'+t.key+"</span></div>"},"");s.id="kbshortcutmenu",s.innerHTML="<h1>Keyboard Shortcuts</h1>"+o+"</div>",n(t,s,"0","0","0",null)}}var r=e("ace/editor").Editor;n.exports.init=function(e){r.prototype.showKeyboardShortcuts=function(){i(this)},e.commands.addCommands([{name:"showKeyboardShortcuts",bindKey:{win:"Ctrl-Alt-h",mac:"Command-Alt-h"},exec:function(e,t){e.showKeyboardShortcuts()}}])}}),ace.define("ace/ext/menu_tools/overlay_page",["require","exports","module","ace/lib/dom"],function(e,t,n){var r=e("../../lib/dom"),i="#ace_settingsmenu, #kbshortcutmenu {background-color: #F7F7F7;color: black;box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55);padding: 1em 0.5em 2em 1em;overflow: auto;position: absolute;margin: 0;bottom: 0;right: 0;top: 0;z-index: 9991;cursor: default;}.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu {box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25);background-color: rgba(255, 255, 255, 0.6);color: black;}.ace_optionsMenuEntry:hover {background-color: rgba(100, 100, 100, 0.1);-webkit-transition: all 0.5s;transition: all 0.3s}.ace_closeButton {background: rgba(245, 146, 146, 0.5);border: 1px solid #F48A8A;border-radius: 50%;padding: 7px;position: absolute;right: -8px;top: -8px;z-index: 1000;}.ace_closeButton{background: rgba(245, 146, 146, 0.9);}.ace_optionsMenuKey {color: darkslateblue;font-weight: bold;}.ace_optionsMenuCommand {color: darkcyan;font-weight: normal;}";r.importCssString(i),n.exports.overlayPage=function(t,n,i,s,o,u){function l(e){e.keyCode===27&&a.click()}i=i?"top: "+i+";":"",o=o?"bottom: "+o+";":"",s=s?"right: "+s+";":"",u=u?"left: "+u+";":"";var a=document.createElement("div"),f=document.createElement("div");a.style.cssText="margin: 0; padding: 0; position: fixed; top:0; bottom:0; left:0; right:0;z-index: 9990; background-color: rgba(0, 0, 0, 0.3);",a.addEventListener("click",function(){document.removeEventListener("keydown",l),a.parentNode.removeChild(a),t.focus(),a=null}),document.addEventListener("keydown",l),f.style.cssText=i+s+o+u,f.addEventListener("click",function(e){e.stopPropagation()});var c=r.createElement("div");c.style.position="relative";var h=r.createElement("div");h.className="ace_closeButton",h.addEventListener("click",function(){a.click()}),c.appendChild(h),f.appendChild(c),f.appendChild(n),a.appendChild(f),document.body.appendChild(a),t.blur()}}),ace.define("ace/ext/menu_tools/get_editor_keyboard_shortcuts",["require","exports","module","ace/lib/keys"],function(e,t,n){var r=e("../../lib/keys");n.exports.getEditorKeybordShortcuts=function(e){var t=r.KEY_MODS,n=[],i={};return e.keyBinding.$handlers.forEach(function(e){var r=e.commandKeyBinding;for(var s in r){var o=parseInt(s);o==-1?o="":isNaN(o)?o=s:o=""+(o&t.command?"Cmd-":"")+(o&t.ctrl?"Ctrl-":"")+(o&t.alt?"Alt-":"")+(o&t.shift?"Shift-":"");for(var u in r[s]){var a=r[s][u];typeof a!="string"&&(a=a.name),i[a]?i[a].key+="|"+o+u:(i[a]={key:o+u,command:a},n.push(i[a]))}}}),n}}),function(){ace.require(["ace/ext/keybinding_menu"],function(){})}()
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/linking",["require","exports","module","ace/editor","ace/config"],function(e,t,n){function i(e){var t=e.editor,n=e.getAccelKey();if(n){var t=e.editor,r=e.getDocumentPosition(),i=t.session,s=i.getTokenAt(r.row,r.column);t._emit("linkHover",{position:r,token:s})}}function s(e){var t=e.getAccelKey(),n=e.getButton();if(n==0&&t){var r=e.editor,i=e.getDocumentPosition(),s=r.session,o=s.getTokenAt(i.row,i.column);r._emit("linkClick",{position:i,token:o})}}var r=e("ace/editor").Editor;e("../config").defineOptions(r.prototype,"editor",{enableLinking:{set:function(e){e?(this.on("click",s),this.on("mousemove",i)):(this.off("click",s),this.off("mousemove",i))},value:!1}})}),function(){ace.require(["ace/ext/linking"],function(){})}()
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/modelist",["require","exports","module"],function(e,t,n){function i(e){var t=a.text,n=e.split(/[\/\\]/).pop();for(var i=0;i<r.length;i++)if(r[i].supportsFile(n)){t=r[i];break}return t}var r=[],s=function(e,t,n){this.name=e,this.caption=t,this.mode="ace/mode/"+e,this.extensions=n;if(/\^/.test(n))var r=n.replace(/\|(\^)?/g,function(e,t){return"$|"+(t?"^":"^.*\\.")})+"$";else var r="^.*\\.("+n+")$";this.extRe=new RegExp(r,"gi")};s.prototype.supportsFile=function(e){return e.match(this.extRe)};var o={ABAP:["abap"],ActionScript:["as"],ADA:["ada|adb"],Apache_Conf:["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"],AsciiDoc:["asciidoc"],Assembly_x86:["asm"],AutoHotKey:["ahk"],BatchFile:["bat|cmd"],C9Search:["c9search_results"],C_Cpp:["cpp|c|cc|cxx|h|hh|hpp"],Cirru:["cirru|cr"],Clojure:["clj"],Cobol:["CBL|COB"],coffee:["coffee|cf|cson|^Cakefile"],ColdFusion:["cfm"],CSharp:["cs"],CSS:["css"],Curly:["curly"],D:["d|di"],Dart:["dart"],Diff:["diff|patch"],Dockerfile:["^Dockerfile"],Dot:["dot"],Erlang:["erl|hrl"],EJS:["ejs"],Forth:["frt|fs|ldr"],FTL:["ftl"],Gherkin:["feature"],Glsl:["glsl|frag|vert"],golang:["go"],Groovy:["groovy"],HAML:["haml"],Handlebars:["hbs|handlebars|tpl|mustache"],Haskell:["hs"],haXe:["hx"],HTML:["html|htm|xhtml"],HTML_Ruby:["erb|rhtml|html.erb"],INI:["ini|conf|cfg|prefs"],Jack:["jack"],Jade:["jade"],Java:["java"],JavaScript:["js|jsm"],JSON:["json"],JSONiq:["jq"],JSP:["jsp"],JSX:["jsx"],Julia:["jl"],LaTeX:["tex|latex|ltx|bib"],LESS:["less"],Liquid:["liquid"],Lisp:["lisp"],LiveScript:["ls"],LogiQL:["logic|lql"],LSL:["lsl"],Lua:["lua"],LuaPage:["lp"],Lucene:["lucene"],Makefile:["^Makefile|^GNUmakefile|^makefile|^OCamlMakefile|make"],MATLAB:["matlab"],Markdown:["md|markdown"],MEL:["mel"],MySQL:["mysql"],MUSHCode:["mc|mush"],Nix:["nix"],ObjectiveC:["m|mm"],OCaml:["ml|mli"],Pascal:["pas|p"],Perl:["pl|pm"],pgSQL:["pgsql"],PHP:["php|phtml"],Powershell:["ps1"],Prolog:["plg|prolog"],Properties:["properties"],Protobuf:["proto"],Python:["py"],R:["r"],RDoc:["Rd"],RHTML:["Rhtml"],Ruby:["rb|ru|gemspec|rake|^Guardfile|^Rakefile|^Gemfile"],Rust:["rs"],SASS:["sass"],SCAD:["scad"],Scala:["scala"],Smarty:["smarty|tpl"],Scheme:["scm|rkt"],SCSS:["scss"],SH:["sh|bash|^.bashrc"],SJS:["sjs"],Space:["space"],snippets:["snippets"],Soy_Template:["soy"],SQL:["sql"],Stylus:["styl|stylus"],SVG:["svg"],Tcl:["tcl"],Tex:["tex"],Text:["txt"],Textile:["textile"],Toml:["toml"],Twig:["twig"],Typescript:["ts|typescript|str"],Vala:["vala"],VBScript:["vbs"],Velocity:["vm"],Verilog:["v|vh|sv|svh"],XML:["xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl"],XQuery:["xq"],YAML:["yaml|yml"]},u={ObjectiveC:"Objective-C",CSharp:"C#",golang:"Go",C_Cpp:"C/C++",coffee:"CoffeeScript",HTML_Ruby:"HTML (Ruby)",FTL:"FreeMarker"},a={};for(var f in o){var l=o[f],c=(u[f]||f).replace(/_/g," "),h=f.toLowerCase(),p=new s(h,c,l[0]);a[h]=p,r.push(p)}n.exports={getModeForPath:i,modes:r,modesByName:a}}),function(){ace.require(["ace/ext/modelist"],function(){})}()
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/prompt",["require","exports","module","ace/lib/lang","ace/lib/dom","ace/lib/event","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/editor","ace/multi_select"],function(e,t,n){function c(e,t){var n=this.pixelToScreenCoordinates(e,t);return this.session.screenToDocumentPosition(Math.min(this.session.getScreenLength()-1,Math.max(n.row,0)),Math.max(n.column,0))}var r=e("../lib/lang"),i=e("ace/lib/dom"),s=e("ace/lib/event"),o=e("ace/edit_session").EditSession,u=e("ace/undomanager").UndoManager,a=e("ace/virtual_renderer").VirtualRenderer,f=e("ace/editor").Editor,l=e("ace/multi_select").MultiSelect;t.singleLineEditor=function(e){var t=new a;t.container.style.overflow="hidden",t.screenToTextCoordinates=c,t.setStyle("ace_one-line");var n=new f(t);return n.session.setUndoManager(new u),n.setOptions({showPrintMargin:!1,showGutter:!1,highlightGutterLine:!1,focusWaitTimout:0,maxLines:4}),n}}),function(){ace.require(["ace/ext/prompt"],function(){})}()
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/spellcheck",["require","exports","module","ace/lib/event","ace/editor","ace/config"],function(e,t,n){var r=e("../lib/event");t.contextMenuHandler=function(e){var t=e.target,n=t.textInput.getElement();if(!t.selection.isEmpty())return;var i=t.getCursorPosition(),s=t.session.getWordRange(i.row,i.column),o=t.session.getTextRange(s);t.session.tokenRe.lastIndex=0;if(!t.session.tokenRe.test(o))return;var u="\x01\x01",a=o+" "+u;n.value=a,n.setSelectionRange(o.length,o.length+1),n.setSelectionRange(0,0),n.setSelectionRange(0,o.length);var f=!1;r.addListener(n,"keydown",function l(){r.removeListener(n,"keydown",l),f=!0}),t.textInput.setInputHandler(function(e){console.log(e,a,n.selectionStart,n.selectionEnd);if(e==a)return"";if(e.lastIndexOf(a,0)===0)return e.slice(a.length);if(e.substr(n.selectionEnd)==a)return e.slice(0,-a.length);if(e.slice(-2)==u){var r=e.slice(0,-2);if(r.slice(-1)==" ")return f?r.substring(0,n.selectionEnd):(r=r.slice(0,-1),t.session.replace(s,r),"")}return e})};var i=e("../editor").Editor;e("../config").defineOptions(i.prototype,"editor",{spellcheck:{set:function(e){var n=this.textInput.getElement();n.spellcheck=!!e,e?this.on("nativecontextmenu",t.contextMenuHandler):this.removeListener("nativecontextmenu",t.contextMenuHandler)},value:!0}})}),function(){ace.require(["ace/ext/spellcheck"],function(){})}()
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/split",["require","exports","module","ace/split"],function(e,t,n){n.exports=e("../split")}),ace.define("ace/split",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/editor","ace/virtual_renderer","ace/edit_session"],function(e,t,n){function l(e,t){this.$u=e,this.$doc=t}var r=e("./lib/oop"),i=e("./lib/lang"),s=e("./lib/event_emitter").EventEmitter,o=e("./editor").Editor,u=e("./virtual_renderer").VirtualRenderer,a=e("./edit_session").EditSession,f=function(e,t,n){this.BELOW=1,this.BESIDE=0,this.$container=e,this.$theme=t,this.$splits=0,this.$editorCSS="",this.$editors=[],this.$orientation=this.BESIDE,this.setSplits(n||1),this.$cEditor=this.$editors[0],this.on("focus",function(e){this.$cEditor=e}.bind(this))};(function(){r.implement(this,s),this.$createEditor=function(){var e=document.createElement("div");e.className=this.$editorCSS,e.style.cssText="position: absolute; top:0px; bottom:0px",this.$container.appendChild(e);var t=new o(new u(e,this.$theme));return t.on("focus",function(){this._emit("focus",t)}.bind(this)),this.$editors.push(t),t.setFontSize(this.$fontSize),t},this.setSplits=function(e){var t;if(e<1)throw"The number of splits have to be > 0!";if(e==this.$splits)return;if(e>this.$splits){while(this.$splits<this.$editors.length&&this.$splits<e)t=this.$editors[this.$splits],this.$container.appendChild(t.container),t.setFontSize(this.$fontSize),this.$splits++;while(this.$splits<e)this.$createEditor(),this.$splits++}else while(this.$splits>e)t=this.$editors[this.$splits-1],this.$container.removeChild(t.container),this.$splits--;this.resize()},this.getSplits=function(){return this.$splits},this.getEditor=function(e){return this.$editors[e]},this.getCurrentEditor=function(){return this.$cEditor},this.focus=function(){this.$cEditor.focus()},this.blur=function(){this.$cEditor.blur()},this.setTheme=function(e){this.$editors.forEach(function(t){t.setTheme(e)})},this.setKeyboardHandler=function(e){this.$editors.forEach(function(t){t.setKeyboardHandler(e)})},this.forEach=function(e,t){this.$editors.forEach(e,t)},this.$fontSize="",this.setFontSize=function(e){this.$fontSize=e,this.forEach(function(t){t.setFontSize(e)})},this.$cloneSession=function(e){var t=new a(e.getDocument(),e.getMode()),n=e.getUndoManager();if(n){var r=new l(n,t);t.setUndoManager(r)}return t.$informUndoManager=i.delayedCall(function(){t.$deltas=[]}),t.setTabSize(e.getTabSize()),t.setUseSoftTabs(e.getUseSoftTabs()),t.setOverwrite(e.getOverwrite()),t.setBreakpoints(e.getBreakpoints()),t.setUseWrapMode(e.getUseWrapMode()),t.setUseWorker(e.getUseWorker()),t.setWrapLimitRange(e.$wrapLimitRange.min,e.$wrapLimitRange.max),t.$foldData=e.$cloneFoldData(),t},this.setSession=function(e,t){var n;t==null?n=this.$cEditor:n=this.$editors[t];var r=this.$editors.some(function(t){return t.session===e});return r&&(e=this.$cloneSession(e)),n.setSession(e),e},this.getOrientation=function(){return this.$orientation},this.setOrientation=function(e){if(this.$orientation==e)return;this.$orientation=e,this.resize()},this.resize=function(){var e=this.$container.clientWidth,t=this.$container.clientHeight,n;if(this.$orientation==this.BESIDE){var r=e/this.$splits;for(var i=0;i<this.$splits;i++)n=this.$editors[i],n.container.style.width=r+"px",n.container.style.top="0px",n.container.style.left=i*r+"px",n.container.style.height=t+"px",n.resize()}else{var s=t/this.$splits;for(var i=0;i<this.$splits;i++)n=this.$editors[i],n.container.style.width=e+"px",n.container.style.top=i*s+"px",n.container.style.left="0px",n.container.style.height=s+"px",n.resize()}}}).call(f.prototype),function(){this.execute=function(e){this.$u.execute(e)},this.undo=function(){var e=this.$u.undo(!0);e&&this.$doc.selection.setSelectionRange(e)},this.redo=function(){var e=this.$u.redo(!0);e&&this.$doc.selection.setSelectionRange(e)},this.reset=function(){this.$u.reset()},this.hasUndo=function(){return this.$u.hasUndo()},this.hasRedo=function(){return this.$u.hasRedo()}}.call(l.prototype),t.Split=f}),function(){ace.require(["ace/ext/split"],function(){})}()
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/static_highlight",["require","exports","module","ace/edit_session","ace/layer/text","ace/config","ace/lib/dom"],function(e,t,n){var r=e("../edit_session").EditSession,i=e("../layer/text").Text,s=".ace_static_highlight {font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'Droid Sans Mono', monospace;font-size: 12px;}.ace_static_highlight .ace_gutter {width: 25px !important;display: block;float: left;text-align: right;padding: 0 3px 0 0;margin-right: 3px;position: static !important;}.ace_static_highlight .ace_line { clear: both; }.ace_static_highlight .ace_gutter-cell {-moz-user-select: -moz-none;-khtml-user-select: none;-webkit-user-select: none;user-select: none;}.ace_static_highlight .ace_gutter-cell:before {content: counter(ace_line, decimal);counter-increment: ace_line;}.ace_static_highlight {counter-reset: ace_line;}",o=e("../config"),u=e("../lib/dom"),a=function(e,t,n){var r=e.className.match(/lang-(\w+)/),i=t.mode||r&&"ace/mode/"+r[1];if(!i)return!1;var s=t.theme||"ace/theme/textmate",o="",f=[];if(e.firstElementChild){var l=0;for(var c=0;c<e.childNodes.length;c++){var h=e.childNodes[c];h.nodeType==3?(l+=h.data.length,o+=h.data):f.push(l,h)}}else o=u.getInnerText(e),t.trim&&(o=o.trim());a.render(o,i,s,t.firstLineNumber,!t.showGutter,function(t){u.importCssString(t.css,"ace_highlight"),e.innerHTML=t.html;var r=e.firstChild.firstChild;for(var i=0;i<f.length;i+=2){var s=t.session.doc.indexToPosition(f[i]),o=f[i+1],a=r.children[s.row];a&&a.appendChild(o)}n&&n()})};a.render=function(e,t,n,i,s,u){function c(){var r=a.renderSync(e,t,n,i,s);return u?u(r):r}var f=1,l=r.prototype.$modes;return typeof n=="string"&&(f++,o.loadModule(["theme",n],function(e){n=e,--f||c()})),typeof t=="string"&&(f++,o.loadModule(["mode",t],function(e){l[t]||(l[t]=new e.Mode),t=l[t],--f||c()})),--f||c()},a.renderSync=function(e,t,n,o,u){o=parseInt(o||1,10);var a=new r("");a.setUseWorker(!1),a.setMode(t);var f=new i(document.createElement("div"));f.setSession(a),f.config={characterWidth:10,lineHeight:20},a.setValue(e);var l=[],c=a.getLength();for(var h=0;h<c;h++)l.push("<div class='ace_line'>"),u||l.push("<span class='ace_gutter ace_gutter-cell' unselectable='on'></span>"),f.$renderLine(l,h,!0,!1),l.push("\n</div>");var p="<div class='"+n.cssClass+"'>"+"<div class='ace_static_highlight' style='counter-reset:ace_line "+(o-1)+"'>"+l.join("")+"</div>"+"</div>";return f.destroy(),{css:s+n.cssText,html:p,session:a}},n.exports=a,n.exports.highlight=a}),function(){ace.require(["ace/ext/static_highlight"],function(){})}()
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/statusbar",["require","exports","module","ace/lib/dom","ace/lib/lang"],function(e,t,n){var r=e("ace/lib/dom"),i=e("ace/lib/lang"),s=function(e,t){this.element=r.createElement("div"),this.element.className="ace_status-indicator",this.element.style.cssText="display: inline-block;",t.appendChild(this.element);var n=i.delayedCall(function(){this.updateStatus(e)}.bind(this));e.on("changeStatus",function(){n.schedule(100)}),e.on("changeSelection",function(){n.schedule(100)})};(function(){this.updateStatus=function(e){function n(e,n){e&&t.push(e,n||"|")}var t=[];e.$vimModeHandler?n(e.$vimModeHandler.getStatusText()):e.commands.recording&&n("REC");var r=e.selection.lead;n(r.row+":"+r.column," ");if(!e.selection.isEmpty()){var i=e.getSelectionRange();n("("+(i.end.row-i.start.row)+":"+(i.end.column-i.start.column)+")")}t.pop(),this.element.textContent=t.join("")}}).call(s.prototype),t.StatusBar=s}),function(){ace.require(["ace/ext/statusbar"],function(){})}()
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/themelist",["require","exports","module","ace/lib/fixoldbrowsers"],function(e,t,n){e("ace/lib/fixoldbrowsers");var r=[["Chrome"],["Clouds"],["Crimson Editor"],["Dawn"],["Dreamweaver"],["Eclipse"],["GitHub"],["Solarized Light"],["TextMate"],["Tomorrow"],["XCode"],["Kuroir"],["KatzenMilch"],["Ambiance","ambiance","dark"],["Chaos","chaos","dark"],["Clouds Midnight","clouds_midnight","dark"],["Cobalt","cobalt","dark"],["idle Fingers","idle_fingers","dark"],["krTheme","kr_theme","dark"],["Merbivore","merbivore","dark"],["Merbivore Soft","merbivore_soft","dark"],["Mono Industrial","mono_industrial","dark"],["Monokai","monokai","dark"],["Pastel on dark","pastel_on_dark","dark"],["Solarized Dark","solarized_dark","dark"],["Terminal","terminal","dark"],["Tomorrow Night","tomorrow_night","dark"],["Tomorrow Night Blue","tomorrow_night_blue","dark"],["Tomorrow Night Bright","tomorrow_night_bright","dark"],["Tomorrow Night 80s","tomorrow_night_eighties","dark"],["Twilight","twilight","dark"],["Vibrant Ink","vibrant_ink","dark"]];t.themesByName={},t.themes=r.map(function(e){var n=e[1]||e[0].replace(/ /g,"_").toLowerCase(),r={caption:e[0],theme:"ace/theme/"+n,isDark:e[2]=="dark",name:n};return t.themesByName[n]=r,r})}),function(){ace.require(["ace/ext/themelist"],function(){})}()
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/ext/whitespace",["require","exports","module","ace/lib/lang"],function(e,t,n){var r=e("../lib/lang");t.$detectIndentation=function(e,t){function h(e){var t=0;for(var r=e;r<n.length;r+=e)t+=n[r]||0;return t}var n=[],r=[],i=0,s=0,o=Math.min(e.length,1e3);for(var u=0;u<o;u++){var a=e[u];if(!/^\s*[^*+\-\s]/.test(a))continue;var f=a.match(/^\t*/)[0].length;a[0]==" "&&i++;var l=a.match(/^ */)[0].length;if(l&&a[l]!=" "){var c=l-s;c>0&&!(s%c)&&!(l%c)&&(r[c]=(r[c]||0)+1),n[l]=(n[l]||0)+1}s=l;while(u<o&&a[a.length-1]=="\\")a=e[u++]}if(!n.length)return;var p=r.reduce(function(e,t){return e+t},0),d={score:0,length:0},v=0;for(var u=1;u<12;u++){if(u==1){v=h(u);var m=1}else var m=h(u)/v;r[u]&&(m+=r[u]/p),m>d.score&&(d={score:m,length:u})}if(d.score&&d.score>1.4)var g=d.length;if(i>v+1)return{ch:" ",length:g};if(v+1>i)return{ch:" ",length:g}},t.detectIndentation=function(e){var n=e.getLines(0,1e3),r=t.$detectIndentation(n)||{};return r.ch&&e.setUseSoftTabs(r.ch==" "),r.length&&e.setTabSize(r.length),r},t.trimTrailingSpace=function(e,t){var n=e.getDocument(),r=n.getAllLines(),i=t?-1:0;for(var s=0,o=r.length;s<o;s++){var u=r[s],a=u.search(/\s+$/);a>i&&n.removeInLine(s,a,u.length)}},t.convertIndentation=function(e,t,n){var i=e.getTabString()[0],s=e.getTabSize();n||(n=s),t||(t=i);var o=t==" "?t:r.stringRepeat(t,n),u=e.doc,a=u.getAllLines(),f={},l={};for(var c=0,h=a.length;c<h;c++){var p=a[c],d=p.match(/^\s*/)[0];if(d){var v=e.$getStringScreenWidth(d)[0],m=Math.floor(v/s),g=v%s,y=f[m]||(f[m]=r.stringRepeat(o,m));y+=l[g]||(l[g]=r.stringRepeat(" ",g)),y!=d&&(u.removeInLine(c,0,d.length),u.insertInLine({row:c,column:0},y))}}e.setTabSize(n),e.setUseSoftTabs(t==" ")},t.$parseStringArg=function(e){var t={};/t/.test(e)?t.ch=" ":/s/.test(e)&&(t.ch=" ");var n=e.match(/\d+/);return n&&(t.length=parseInt(n[0],10)),t},t.$parseArg=function(e){return e?typeof e=="string"?t.$parseStringArg(e):typeof e.text=="string"?t.$parseStringArg(e.text):e:{}},t.commands=[{name:"detectIndentation",exec:function(e){t.detectIndentation(e.session)}},{name:"trimTrailingSpace",exec:function(e){t.trimTrailingSpace(e.session)}},{name:"convertIndentation",exec:function(e,n){var r=t.$parseArg(n);t.convertIndentation(e.session,r.ch,r.length)}},{name:"setIndentation",exec:function(e,n){var r=t.$parseArg(n);r.length&&e.session.setTabSize(r.length),r.ch&&e.session.setUseSoftTabs(r.ch==" ")}}]}),function(){ace.require(["ace/ext/whitespace"],function(){})}()
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
@ -1 +0,0 @@
|
|||
ace.define("ace/mode/plain_text",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/behaviour"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("./text_highlight_rules").TextHighlightRules,o=e("./behaviour").Behaviour,u=function(){this.HighlightRules=s,this.$behaviour=new o};r.inherits(u,i),function(){this.type="text",this.getNextLineIndent=function(e,t,n){return""},this.$id="ace/mode/plain_text"}.call(u.prototype),t.Mode=u})
|
|
@ -1 +0,0 @@
|
|||
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){var r=e("../lib/oop"),i=e("./text").Mode,s=e("./python_highlight_rules").PythonHighlightRules,o=e("./folding/pythonic").FoldMode,u=e("../range").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o("\\:")};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[\:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},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 u(n,r.length-i.length,n,r.length))},this.$id="ace/mode/python"}.call(a.prototype),t.Mode=a}),ace.define("ace/mode/python_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|loop|not|or|pass|print|raise|return|try|while|with|yield",t="True|False|None|NotImplemented|Ellipsis|__debug__",n="abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|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|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern",r=this.createKeywordMapper({"invalid.deprecated":"debugger","support.function":n,"constant.language":t,keyword:e},"identifier"),i="(?:r|u|ur|R|U|UR|Ur|uR)?",s="(?:(?:[1-9]\\d*)|(?:0))",o="(?:0[oO]?[0-7]+)",u="(?:0[xX][\\dA-Fa-f]+)",a="(?:0[bB][01]+)",f="(?:"+s+"|"+o+"|"+u+"|"+a+")",l="(?:[eE][+-]?\\d+)",c="(?:\\.\\d+)",h="(?:\\d+)",p="(?:(?:"+h+"?"+c+")|(?:"+h+"\\.))",d="(?:(?:"+p+"|"+h+")"+l+")",v="(?:"+d+"|"+p+")",m="\\\\(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:i+'"{3}',next:"qqstring3"},{token:"string",regex:i+'"(?=.)',next:"qqstring"},{token:"string",regex:i+"'{3}",next:"qstring3"},{token:"string",regex:i+"'(?=.)",next:"qstring"},{token:"constant.numeric",regex:"(?:"+v+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:v},{token:"constant.numeric",regex:f+"[lL]\\b"},{token:"constant.numeric",regex:f+"\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qqstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],qstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}]}};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){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),i=r.match(this.foldingStartMarker);if(i)return i[1]?this.openingBracketBlock(e,i[1],n,i.index):i[2]?this.indentationBlock(e,n,i.index+i[2].length):this.indentationBlock(e,n)}}.call(s.prototype)})
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
ace.define("ace/snippets/clojure",["require","exports","module"],function(e,t,n){t.snippetText='snippet comm\n (comment\n ${1}\n )\nsnippet condp\n (condp ${1:pred} ${2:expr}\n ${3})\nsnippet def\n (def ${1})\nsnippet defm\n (defmethod ${1:multifn} "${2:doc-string}" ${3:dispatch-val} [${4:args}]\n ${5})\nsnippet defmm\n (defmulti ${1:name} "${2:doc-string}" ${3:dispatch-fn})\nsnippet defma\n (defmacro ${1:name} "${2:doc-string}" ${3:dispatch-fn})\nsnippet defn\n (defn ${1:name} "${2:doc-string}" [${3:arg-list}]\n ${4})\nsnippet defp\n (defprotocol ${1:name}\n ${2})\nsnippet defr\n (defrecord ${1:name} [${2:fields}]\n ${3:protocol}\n ${4})\nsnippet deft\n (deftest ${1:name}\n (is (= ${2:assertion})))\n ${3})\nsnippet is\n (is (= ${1} ${2}))\nsnippet defty\n (deftype ${1:Name} [${2:fields}]\n ${3:Protocol}\n ${4})\nsnippet doseq\n (doseq [${1:elem} ${2:coll}]\n ${3})\nsnippet fn\n (fn [${1:arg-list}] ${2})\nsnippet if\n (if ${1:test-expr}\n ${2:then-expr}\n ${3:else-expr})\nsnippet if-let \n (if-let [${1:result} ${2:test-expr}]\n (${3:then-expr} $1)\n (${4:else-expr}))\nsnippet imp\n (:import [${1:package}])\n & {:keys [${1:keys}] :or {${2:defaults}}}\nsnippet let\n (let [${1:name} ${2:expr}]\n ${3})\nsnippet letfn\n (letfn [(${1:name) [${2:args}]\n ${3})])\nsnippet map\n (map ${1:func} ${2:coll})\nsnippet mapl\n (map #(${1:lambda}) ${2:coll})\nsnippet met\n (${1:name} [${2:this} ${3:args}]\n ${4})\nsnippet ns\n (ns ${1:name}\n ${2})\nsnippet dotimes\n (dotimes [_ 10]\n (time\n (dotimes [_ ${1:times}]\n ${2})))\nsnippet pmethod\n (${1:name} [${2:this} ${3:args}])\nsnippet refer\n (:refer-clojure :exclude [${1}])\nsnippet require\n (:require [${1:namespace} :as [${2}]])\nsnippet use\n (:use [${1:namespace} :only [${2}]])\nsnippet print\n (println ${1})\nsnippet reduce\n (reduce ${1:(fn [p n] ${3})} ${2})\nsnippet when\n (when ${1:test} ${2:body})\nsnippet when-let\n (when-let [${1:result} ${2:test}]\n ${3:body})\n',t.scope="clojure"})
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/snippets/coffee",["require","exports","module"],function(e,t,n){t.snippetText="# Closure loop\nsnippet forindo\n for ${1:name} in ${2:array}\n do ($1) ->\n ${3:// body}\n# Array comprehension\nsnippet fora\n for ${1:name} in ${2:array}\n ${3:// body...}\n# Object comprehension\nsnippet foro\n for ${1:key}, ${2:value} of ${3:object}\n ${4:// body...}\n# Range comprehension (inclusive)\nsnippet forr\n for ${1:name} in [${2:start}..${3:finish}]\n ${4:// body...}\nsnippet forrb\n for ${1:name} in [${2:start}..${3:finish}] by ${4:step}\n ${5:// body...}\n# Range comprehension (exclusive)\nsnippet forrex\n for ${1:name} in [${2:start}...${3:finish}]\n ${4:// body...}\nsnippet forrexb\n for ${1:name} in [${2:start}...${3:finish}] by ${4:step}\n ${5:// body...}\n# Function\nsnippet fun\n (${1:args}) ->\n ${2:// body...}\n# Function (bound)\nsnippet bfun\n (${1:args}) =>\n ${2:// body...}\n# Class\nsnippet cla class ..\n class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`}\n ${2}\nsnippet cla class .. constructor: ..\n class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`}\n constructor: (${2:args}) ->\n ${3}\n\n ${4}\nsnippet cla class .. extends ..\n class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`} extends ${2:ParentClass}\n ${3}\nsnippet cla class .. extends .. constructor: ..\n class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`} extends ${2:ParentClass}\n constructor: (${3:args}) ->\n ${4}\n\n ${5}\n# If\nsnippet if\n if ${1:condition}\n ${2:// body...}\n# If __ Else\nsnippet ife\n if ${1:condition}\n ${2:// body...}\n else\n ${3:// body...}\n# Else if\nsnippet elif\n else if ${1:condition}\n ${2:// body...}\n# Ternary If\nsnippet ifte\n if ${1:condition} then ${2:value} else ${3:other}\n# Unless\nsnippet unl\n ${1:action} unless ${2:condition}\n# Switch\nsnippet swi\n switch ${1:object}\n when ${2:value}\n ${3:// body...}\n\n# Log\nsnippet log\n console.log ${1}\n# Try __ Catch\nsnippet try\n try\n ${1}\n catch ${2:error}\n ${3}\n# Require\nsnippet req\n ${2:$1} = require '${1:sys}'${3}\n# Export\nsnippet exp\n ${1:root} = exports ? this\n",t.scope="coffee"})
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/snippets/javascript",["require","exports","module"],function(e,t,n){t.snippetText='# Prototype\nsnippet proto\n ${1:class_name}.prototype.${2:method_name} = function(${3:first_argument}) {\n ${4:// body...}\n };\n# Function\nsnippet fun\n function ${1?:function_name}(${2:argument}) {\n ${3:// body...}\n }\n# Anonymous Function\nregex /((=)\\s*|(:)\\s*|(\\()|\\b)/f/(\\))?/\nsnippet f\n function${M1?: ${1:functionName}}($2) {\n ${0:$TM_SELECTED_TEXT}\n }${M2?;}${M3?,}${M4?)}\n# Immediate function\ntrigger \\(?f\\(\nendTrigger \\)?\nsnippet f(\n (function(${1}) {\n ${0:${TM_SELECTED_TEXT:/* code */}}\n }(${1}));\n# if\nsnippet if\n if (${1:true}) {\n ${0}\n }\n# if ... else\nsnippet ife\n if (${1:true}) {\n ${2}\n } else {\n ${0}\n }\n# tertiary conditional\nsnippet ter\n ${1:/* condition */} ? ${2:a} : ${3:b}\n# switch\nsnippet switch\n switch (${1:expression}) {\n case \'${3:case}\':\n ${4:// code}\n break;\n ${5}\n default:\n ${2:// code}\n }\n# case\nsnippet case\n case \'${1:case}\':\n ${2:// code}\n break;\n ${3}\n\n# while (...) {...}\nsnippet wh\n while (${1:/* condition */}) {\n ${0:/* code */}\n }\n# try\nsnippet try\n try {\n ${0:/* code */}\n } catch (e) {}\n# do...while\nsnippet do\n do {\n ${2:/* code */}\n } while (${1:/* condition */});\n# Object Method\nsnippet :f\nregex /([,{[])|^\\s*/:f/\n ${1:method_name}: function(${2:attribute}) {\n ${0}\n }${3:,}\n# setTimeout function\nsnippet setTimeout\nregex /\\b/st|timeout|setTimeo?u?t?/\n setTimeout(function() {${3:$TM_SELECTED_TEXT}}, ${1:10});\n# Get Elements\nsnippet gett\n getElementsBy${1:TagName}(\'${2}\')${3}\n# Get Element\nsnippet get\n getElementBy${1:Id}(\'${2}\')${3}\n# console.log (Firebug)\nsnippet cl\n console.log(${1});\n# return\nsnippet ret\n return ${1:result}\n# for (property in object ) { ... }\nsnippet fori\n for (var ${1:prop} in ${2:Things}) {\n ${0:$2[$1]}\n }\n# hasOwnProperty\nsnippet has\n hasOwnProperty(${1})\n# docstring\nsnippet /**\n /**\n * ${1:description}\n *\n */\nsnippet @par\nregex /^\\s*\\*\\s*/@(para?m?)?/\n @param {${1:type}} ${2:name} ${3:description}\nsnippet @ret\n @return {${1:type}} ${2:description}\n# JSON.parse\nsnippet jsonp\n JSON.parse(${1:jstr});\n# JSON.stringify\nsnippet jsons\n JSON.stringify(${1:object});\n# self-defining function\nsnippet sdf\n var ${1:function_name} = function(${2:argument}) {\n ${3:// initial code ...}\n\n $1 = function($2) {\n ${4:// main code}\n };\n }\n# singleton\nsnippet sing\n function ${1:Singleton} (${2:argument}) {\n // the cached instance\n var instance;\n\n // rewrite the constructor\n $1 = function $1($2) {\n return instance;\n };\n \n // carry over the prototype properties\n $1.prototype = this;\n\n // the instance\n instance = new $1();\n\n // reset the constructor pointer\n instance.constructor = $1;\n\n ${3:// code ...}\n\n return instance;\n }\n# class\nsnippet class\nregex /^\\s*/clas{0,2}/\n var ${1:class} = function(${20}) {\n $40$0\n };\n \n (function() {\n ${60:this.prop = ""}\n }).call(${1:class}.prototype);\n \n exports.${1:class} = ${1:class};\n# \nsnippet for-\n for (var ${1:i} = ${2:Things}.length; ${1:i}--; ) {\n ${0:${2:Things}[${1:i}];}\n }\n# for (...) {...}\nsnippet for\n for (var ${1:i} = 0; $1 < ${2:Things}.length; $1++) {\n ${3:$2[$1]}$0\n }\n# for (...) {...} (Improved Native For-Loop)\nsnippet forr\n for (var ${1:i} = ${2:Things}.length - 1; $1 >= 0; $1--) {\n ${3:$2[$1]}$0\n }\n\n\n#modules\nsnippet def\n ace.define(function(require, exports, module) {\n "use strict";\n var ${1/.*\\///} = require("${1}");\n \n $TM_SELECTED_TEXT\n });\nsnippet req\nguard ^\\s*\n var ${1/.*\\///} = require("${1}");\n $0\nsnippet requ\nguard ^\\s*\n var ${1/.*\\/(.)/\\u$1/} = require("${1}").${1/.*\\/(.)/\\u$1/};\n $0\n',t.scope="javascript"})
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/snippets/lua",["require","exports","module"],function(e,t,n){t.snippetText="snippet #!\n #!/usr/bin/env lua\n $1\nsnippet local\n local ${1:x} = ${2:1}\nsnippet fun\n function ${1:fname}(${2:...})\n ${3:-- body}\n end\nsnippet for\n for ${1:i}=${2:1},${3:10} do\n ${4:print(i)}\n end\nsnippet forp\n for ${1:i},${2:v} in pairs(${3:table_name}) do\n ${4:-- body}\n end\nsnippet fori\n for ${1:i},${2:v} in ipairs(${3:table_name}) do\n ${4:-- body}\n end\n",t.scope="lua"})
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/snippets/luapage",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="luapage"})
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/snippets/plain_text",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="plain_text"})
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/snippets/python",["require","exports","module"],function(e,t,n){t.snippetText='snippet #!\n #!/usr/bin/env python\nsnippet imp\n import ${1:module}\nsnippet from\n from ${1:package} import ${2:module}\n# Module Docstring\nsnippet docs\n \'\'\'\n File: ${1:FILENAME:file_name}\n Author: ${2:author}\n Description: ${3}\n \'\'\'\nsnippet wh\n while ${1:condition}:\n ${2:# TODO: write code...}\n# dowh - does the same as do...while in other languages\nsnippet dowh\n while True:\n ${1:# TODO: write code...}\n if ${2:condition}:\n break\nsnippet with\n with ${1:expr} as ${2:var}:\n ${3:# TODO: write code...}\n# New Class\nsnippet cl\n class ${1:ClassName}(${2:object}):\n """${3:docstring for $1}"""\n def __init__(self, ${4:arg}):\n ${5:super($1, self).__init__()}\n self.$4 = $4\n ${6}\n# New Function\nsnippet def\n def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n """${3:docstring for $1}"""\n ${4:# TODO: write code...}\nsnippet deff\n def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n ${3:# TODO: write code...}\n# New Method\nsnippet defs\n def ${1:mname}(self, ${2:arg}):\n ${3:# TODO: write code...}\n# New Property\nsnippet property\n def ${1:foo}():\n doc = "${2:The $1 property.}"\n def fget(self):\n ${3:return self._$1}\n def fset(self, value):\n ${4:self._$1 = value}\n# Ifs\nsnippet if\n if ${1:condition}:\n ${2:# TODO: write code...}\nsnippet el\n else:\n ${1:# TODO: write code...}\nsnippet ei\n elif ${1:condition}:\n ${2:# TODO: write code...}\n# For\nsnippet for\n for ${1:item} in ${2:items}:\n ${3:# TODO: write code...}\n# Encodes\nsnippet cutf8\n # -*- coding: utf-8 -*-\nsnippet clatin1\n # -*- coding: latin-1 -*-\nsnippet cascii\n # -*- coding: ascii -*-\n# Lambda\nsnippet ld\n ${1:var} = lambda ${2:vars} : ${3:action}\nsnippet .\n self.\nsnippet try Try/Except\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\nsnippet try Try/Except/Else\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n else:\n ${5:# TODO: write code...}\nsnippet try Try/Except/Finally\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n finally:\n ${5:# TODO: write code...}\nsnippet try Try/Except/Else/Finally\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n else:\n ${5:# TODO: write code...}\n finally:\n ${6:# TODO: write code...}\n# if __name__ == \'__main__\':\nsnippet ifmain\n if __name__ == \'__main__\':\n ${1:main()}\n# __magic__\nsnippet _\n __${1:init}__${2}\n# python debugger (pdb)\nsnippet pdb\n import pdb; pdb.set_trace()\n# ipython debugger (ipdb)\nsnippet ipdb\n import ipdb; ipdb.set_trace()\n# ipython debugger (pdbbb)\nsnippet pdbbb\n import pdbpp; pdbpp.set_trace()\nsnippet pprint\n import pprint; pprint.pprint(${1})${2}\nsnippet "\n """\n ${1:doc}\n """\n# test function/method\nsnippet test\n def test_${1:description}(${2:self}):\n ${3:# TODO: write code...}\n# test case\nsnippet testcase\n class ${1:ExampleCase}(unittest.TestCase):\n \n def test_${2:description}(self):\n ${3:# TODO: write code...}\nsnippet fut\n from __future__ import ${1}\n#getopt\nsnippet getopt\n try:\n # Short option syntax: "hv:"\n # Long option syntax: "help" or "verbose="\n opts, args = getopt.getopt(sys.argv[1:], "${1:short_options}", [${2:long_options}])\n \n except getopt.GetoptError, err:\n # Print debug info\n print str(err)\n ${3:error_action}\n\n for option, argument in opts:\n if option in ("-h", "--help"):\n ${4}\n elif option in ("-v", "--verbose"):\n verbose = argument\n',t.scope="python"})
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
ace.define("ace/snippets/snippets",["require","exports","module"],function(e,t,n){t.snippetText="# snippets for making snippets :)\nsnippet snip\n snippet ${1:trigger}\n ${2}\nsnippet msnip\n snippet ${1:trigger} ${2:description}\n ${3}\nsnippet v\n {VISUAL}\n",t.scope="snippets"})
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/snippets/text",["require","exports","module"],function(e,t,n){t.snippetText="",t.scope="text"})
|
|
@ -1 +0,0 @@
|
|||
ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;border-radius: 2px;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -33,7 +33,7 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
'admin/clas': go('admin/CLAsView')
|
||||
'admin/employers': go('admin/EmployersListView')
|
||||
'admin/files': go('admin/FilesView')
|
||||
'admin/analytics/users': go('admin/AnalyticsUsersView')
|
||||
'admin/analytics': go('admin/AnalyticsView')
|
||||
'admin/analytics/subscriptions': go('admin/AnalyticsSubscriptionsView')
|
||||
'admin/level-sessions': go('admin/LevelSessionsView')
|
||||
'admin/users': go('admin/UsersView')
|
||||
|
|
|
@ -31,7 +31,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
contact: "Kontakt"
|
||||
twitter_follow: "Følg"
|
||||
teachers: "Lærere"
|
||||
# careers: "Careers"
|
||||
careers: "Karrierer"
|
||||
|
||||
modal:
|
||||
close: "Luk"
|
||||
|
@ -80,7 +80,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
adjust_volume: "Indstil lydstyrke"
|
||||
campaign_multiplayer: "Multiplayer Arenaer"
|
||||
campaign_multiplayer_description: "... hvor du koder ansigt-til-ansigt imod andre spillere."
|
||||
# campaign_old_multiplayer: "(Deprecated) Old Multiplayer Arenas"
|
||||
campaign_old_multiplayer: "(Forældet) Gammel version af Multiplayer Arenaer"
|
||||
# campaign_old_multiplayer_description: "Relics of a more civilized age. No simulations are run for these older, hero-less multiplayer arenas."
|
||||
|
||||
share_progress_modal:
|
||||
|
@ -159,7 +159,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
accepted: "Accepteret"
|
||||
rejected: "Afvist"
|
||||
withdrawn: "Trukket tilbage"
|
||||
# accept: "Accept"
|
||||
accept: "Accepter"
|
||||
# reject: "Reject"
|
||||
# withdraw: "Withdraw"
|
||||
submitter: "Indsender"
|
||||
|
@ -196,7 +196,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
player: "Spiller"
|
||||
player_level: "Niveau" # Like player level 5, not like level: Dungeons of Kithgard
|
||||
warrior: "Krigsherre"
|
||||
# ranger: "Ranger"
|
||||
ranger: "Bueskytte"
|
||||
wizard: "Troldmand"
|
||||
|
||||
units:
|
||||
|
@ -217,8 +217,8 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
|
||||
play_level:
|
||||
done: "Færdig"
|
||||
# next_game: "Next game"
|
||||
# show_menu: "Show game menu"
|
||||
next_game: "Næste spil"
|
||||
show_menu: "Vis spil menu"
|
||||
home: "Hjem" # Not used any more, will be removed soon.
|
||||
level: "Bane" # Like "Level: Dungeons of Kithgard"
|
||||
skip: "Spring over"
|
||||
|
@ -251,7 +251,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
victory_saving_progress: "Gemmer fremskridt"
|
||||
victory_go_home: "Gå hjem"
|
||||
victory_review: "Fortæl os mere!"
|
||||
# victory_review_placeholder: "How was the level?"
|
||||
victory_review_placeholder: "Hvordan var levelet?"
|
||||
victory_hour_of_code_done: "Er du færdig?"
|
||||
victory_hour_of_code_done_yes: "Ja, jeg er færdig med min Kodetime!"
|
||||
victory_experience_gained: "XP tjent"
|
||||
|
@ -260,7 +260,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
victory_viking_code_school: "For dælen det var en svær bane du lige slog! Hvis ikke du allerede er softwareudvikler, så burde du blive det. Du er lige kommet foran i køen til at blive accepteret hos Viking Code School, du kan tage dine evner til det næste niveau og blive en professionel webudvikler på 14 uger."
|
||||
victory_become_a_viking: "Bliv en Viking"
|
||||
# victory_bloc: "Great work! Your skills are improving, and someone's taking notice. If you've considered becoming a software developer, this may be your lucky day. Bloc is an online bootcamp that pairs you 1-on-1 with an expert mentor who will help train you into a professional developer! By beating A Mayhem of Munchkins, you're now eligible for a $500 price reduction with the code: CCRULES"
|
||||
# victory_bloc_cta: "Meet your mentor – learn about Bloc"
|
||||
victory_bloc_cta: "Mød din mentor - Hør mere om Bloc"
|
||||
guide_title: "Instruktioner"
|
||||
tome_minion_spells: "Dine Minions' besværgelser" # Only in old-style levels.
|
||||
tome_read_only_spells: "Læsebesværgelser" # Only in old-style levels.
|
||||
|
@ -298,7 +298,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
tip_scrub_shortcut: "Brug Ctrl+[ og Ctrl+] til at spole tilbage og frem."
|
||||
tip_guide_exists: "Klik på guiden i spilmenuen (i toppen af siden) for brugbar info."
|
||||
tip_open_source: "CodeCombat er 100% open source!"
|
||||
# tip_tell_friends: "Enjoying CodeCombat? Tell your friends about us!"
|
||||
tip_tell_friends: "Kan du lide CodeCombat? Fortæl dine venner om os!"
|
||||
tip_beta_launch: "CodeCombat søsatte sin beta i oktober, 2013."
|
||||
tip_think_solution: "Tænk på løsningen, ikke problemet."
|
||||
tip_theory_practice: "I teorien er der ingen forskel på teori og praksis. Men i praksis er der. - Yogi Bjørn"
|
||||
|
@ -327,23 +327,23 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..."
|
||||
# tip_superpower: "Coding is the closest thing we have to a superpower."
|
||||
# tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds"
|
||||
# tip_no_code: "No code is faster than no code."
|
||||
# tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries"
|
||||
# tip_reusable_software: "Before software can be reusable it first has to be usable."
|
||||
tip_no_code: "Ingen kode er hurtigerer end ingen kode."
|
||||
tip_code_never_lies: "Kode lyver aldrig, kommentarer gør nogle gange. - Ron Jeffries"
|
||||
tip_reusable_software: "Før software kan være genbrugeligt skal det først være brugbart."
|
||||
# tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’"
|
||||
# tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates"
|
||||
# tip_source_code: "I want to change the world but they would not give me the source code."
|
||||
# tip_javascript_java: "Java is to JavaScript what Car is to Carpet. - Chris Heilmann"
|
||||
# tip_move_forward: "Whatever you do, keep moving forward. - Martin Luther King Jr."
|
||||
tip_move_forward: "Hvad end du gør, så bliv ved med at rykke fremad. - Martin Luther King Jr."
|
||||
tip_google: "Har du et problem du ikke kan løse? Google det!"
|
||||
tip_adding_evil: "Tilføjer et strejf af ondskab.."
|
||||
# tip_hate_computers: "That's the thing about people who think they hate computers. What they really hate is lousy programmers. - Larry Niven"
|
||||
# tip_open_source_contribute: "You can help CodeCombat improve!"
|
||||
# tip_recurse: "To iterate is human, to recurse divine. - L. Peter Deutsch"
|
||||
# tip_free_your_mind: "You have to let it all go, Neo. Fear, doubt, and disbelief. Free your mind. - Morpheus"
|
||||
# tip_strong_opponents: "Even the strongest of opponents always has a weakness. - Itachi Uchiha"
|
||||
tip_strong_opponents: "Selv de stærkeste modstandere har en svaghed. - Itachi Uchiha"
|
||||
tip_paper_and_pen: "Før du starter med at programmere, kan du altid sætte dig ned med et stykke papir og blyant."
|
||||
# tip_solve_then_write: "First, solve the problem. Then, write the code. - John Johnson"
|
||||
tip_solve_then_write: "Først, løs problemet, derefter skriv koden. - John Johnson"
|
||||
|
||||
game_menu:
|
||||
inventory_tab: "Dine ting"
|
||||
|
@ -367,14 +367,14 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# view_other_solutions: "View Leaderboards"
|
||||
# scores: "Scores"
|
||||
# top_players: "Top Players by"
|
||||
# day: "Today"
|
||||
# week: "This Week"
|
||||
day: "Idag"
|
||||
week: "Denne uge"
|
||||
# all: "All-Time"
|
||||
# time: "Time"
|
||||
time: "Tid"
|
||||
# damage_taken: "Damage Taken"
|
||||
# damage_dealt: "Damage Dealt"
|
||||
difficulty: "Sværhedsgrad"
|
||||
# gold_collected: "Gold Collected"
|
||||
gold_collected: "Guld samlet"
|
||||
|
||||
# inventory:
|
||||
# choose_inventory: "Equip Items"
|
||||
|
@ -489,43 +489,43 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# subscribe_prepaid: "Click Subscribe to use prepaid code"
|
||||
# using_prepaid: "Using prepaid code for monthly subscription"
|
||||
|
||||
# choose_hero:
|
||||
# choose_hero: "Choose Your Hero"
|
||||
# programming_language: "Programming Language"
|
||||
# programming_language_description: "Which programming language do you want to use?"
|
||||
# default: "Default"
|
||||
# experimental: "Experimental"
|
||||
# python_blurb: "Simple yet powerful, great for beginners and experts."
|
||||
# javascript_blurb: "The language of the web. (Not the same as Java.)"
|
||||
# coffeescript_blurb: "Nicer JavaScript syntax."
|
||||
# clojure_blurb: "A modern Lisp."
|
||||
# lua_blurb: "Game scripting language."
|
||||
# io_blurb: "Simple but obscure."
|
||||
# status: "Status"
|
||||
# hero_type: "Type"
|
||||
# weapons: "Weapons"
|
||||
# weapons_warrior: "Swords - Short Range, No Magic"
|
||||
# weapons_ranger: "Crossbows, Guns - Long Range, No Magic"
|
||||
# weapons_wizard: "Wands, Staffs - Long Range, Magic"
|
||||
choose_hero:
|
||||
choose_hero: "Vælg din helt"
|
||||
programming_language: "Programmerings sprog"
|
||||
programming_language_description: "Hvilket programmerings sprog har du lyst til at bruge?"
|
||||
default: "Standard"
|
||||
experimental: "Experimental"
|
||||
python_blurb: "Simplet, dog stærkt, godt for begyndere og eksperter."
|
||||
javascript_blurb: "Internettets sprog. (Ikke det samme som Java.)"
|
||||
coffeescript_blurb: "Pænere JavaScript syntax."
|
||||
clojure_blurb: "En moderne version af Lisp."
|
||||
lua_blurb: " Spil scripting sprog."
|
||||
# io_blurb: "Simple but obscure."
|
||||
status: "Status"
|
||||
hero_type: "Type"
|
||||
weapons: "Våben"
|
||||
weapons_warrior: "Sværd - Kort afstand, Ingen Magi"
|
||||
weapons_ranger: "Armbryst, Skydevåben - Lang afstand, Ingen Magi"
|
||||
weapons_wizard: "Tryllestave, Stave - Lang afstand, Magi"
|
||||
# attack: "Damage" # Can also translate as "Attack"
|
||||
# health: "Health"
|
||||
# speed: "Speed"
|
||||
# regeneration: "Regeneration"
|
||||
health: "Liv"
|
||||
speed: "Fart"
|
||||
regeneration: "Regeneration"
|
||||
# range: "Range" # As in "attack or visual range"
|
||||
# blocks: "Blocks" # As in "this shield blocks this much damage"
|
||||
# backstab: "Backstab" # As in "this dagger does this much backstab damage"
|
||||
# skills: "Skills"
|
||||
skills: "Færdigheder"
|
||||
# attack_1: "Deals"
|
||||
# attack_2: "of listed"
|
||||
# attack_3: "weapon damage."
|
||||
# health_1: "Gains"
|
||||
# health_2: "of listed"
|
||||
# health_3: "armor health."
|
||||
# speed_1: "Moves at"
|
||||
# speed_2: "meters per second."
|
||||
# available_for_purchase: "Available for Purchase" # Shows up when you have unlocked, but not purchased, a hero in the hero store
|
||||
# level_to_unlock: "Level to unlock:" # Label for which level you have to beat to unlock a particular hero (click a locked hero in the store to see)
|
||||
# restricted_to_certain_heroes: "Only certain heroes can play this level."
|
||||
speed_1: "Rykker med"
|
||||
speed_2: "meter i sekundet."
|
||||
available_for_purchase: "Kan nu blive købt" # Shows up when you have unlocked, but not purchased, a hero in the hero store
|
||||
level_to_unlock: "Level for at låse op:" # Label for which level you have to beat to unlock a particular hero (click a locked hero in the store to see)
|
||||
restricted_to_certain_heroes: "Kun visse helt kan spille dette level."
|
||||
|
||||
# skill_docs:
|
||||
# writable: "writable" # Hover over "attack" in Your Skills while playing a level to see most of this
|
||||
|
|
|
@ -71,7 +71,7 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
choose_inventory: "Naudoti daiktus"
|
||||
buy_gems: "Pirkti Deimantus"
|
||||
# subscription_required: "Subscription Required"
|
||||
# anonymous: "Anonymous Player"
|
||||
anonymous: "Anoniminis Žaidėjas"
|
||||
level_difficulty: "Sudėtingumas: "
|
||||
campaign_beginner: "Naujoko kampanija"
|
||||
awaiting_levels_adventurer_prefix: "Kiekvieną savaitę sukuriame naujus lygius."
|
||||
|
@ -225,7 +225,7 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
game_menu: "Žaidimo meniu"
|
||||
guide: "Vedlys"
|
||||
restart: "Paleisti iš naujo"
|
||||
goals: "Tikslai"
|
||||
goals: "Pagalba"
|
||||
goal: "Tikslas"
|
||||
running: "Leidžiama..."
|
||||
success: "Sėkmingai!"
|
||||
|
@ -233,7 +233,7 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
timed_out: "Laikas baigėsi"
|
||||
failing: "Nesėkmingai"
|
||||
# action_timeline: "Action Timeline"
|
||||
# click_to_select: "Click on a unit to select it."
|
||||
click_to_select: "Spregtelkite ant veikėjo ar padaro, kad jį pažymėtumėte."
|
||||
control_bar_multiplayer: "Žaidimas keliese"
|
||||
control_bar_join_game: "Prisijungti prie žaidimo"
|
||||
reload: "Perkrauti"
|
||||
|
@ -241,7 +241,7 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
reload_really: "Ar tikrai norite atsukti visą lygį į pradžią?"
|
||||
reload_confirm: "Perkrauti viską"
|
||||
victory: "Pergalė"
|
||||
# victory_title_prefix: ""
|
||||
victory_title_prefix: ""
|
||||
victory_title_suffix: " baigta"
|
||||
victory_sign_up: "Užsiregistruokite, kad išsaugotumėte pažangą"
|
||||
victory_sign_up_poke: "Norite išsaugoti savo kodą? Sukurkite paskyrą nemokamai!"
|
||||
|
@ -299,12 +299,12 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
tip_guide_exists: "Pasirinkite punktą Vedlys žaidimo meniu (puslapio viršuje), jame rasite naudingos informacijos."
|
||||
tip_open_source: "CodeCombat - 100% atviro kodo!"
|
||||
tip_tell_friends: "Jums patinka CodeCombat? Papasakokite savo draugams!"
|
||||
# tip_beta_launch: "CodeCombat launched its beta in October, 2013."
|
||||
tip_beta_launch: "CodeCombat Beta versija startavo 2013 m. spalio mėnesį."
|
||||
tip_think_solution: "Galvok ne apie problemą, o apie sprendimą."
|
||||
# tip_theory_practice: "In theory, there is no difference between theory and practice. But in practice, there is. - Yogi Berra"
|
||||
tip_theory_practice: "Teoriškai nėra skirtuma tarp teorijos ir praktikos. Praktiškai - yra. - Yogi Berra"
|
||||
# tip_error_free: "There are two ways to write error-free programs; only the third one works. - Alan Perlis"
|
||||
# tip_debugging_program: "If debugging is the process of removing bugs, then programming must be the process of putting them in. - Edsger W. Dijkstra"
|
||||
# tip_forums: "Head over to the forums and tell us what you think!"
|
||||
tip_forums: "Aplankykite forumą ir parašykite mums Jūsų nuomonę!"
|
||||
# tip_baby_coders: "In the future, even babies will be Archmages."
|
||||
# tip_morale_improves: "Loading will continue until morale improves."
|
||||
# tip_all_species: "We believe in equal opportunities to learn programming for all species."
|
||||
|
@ -314,13 +314,13 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
# tip_munchkin: "If you don't eat your vegetables, a munchkin will come after you while you're asleep."
|
||||
# tip_binary: "There are only 10 types of people in the world: those who understand binary, and those who don't."
|
||||
# tip_commitment_yoda: "A programmer must have the deepest commitment, the most serious mind. ~ Yoda"
|
||||
# tip_no_try: "Do. Or do not. There is no try. - Yoda"
|
||||
# tip_patience: "Patience you must have, young Padawan. - Yoda"
|
||||
# tip_documented_bug: "A documented bug is not a bug; it is a feature."
|
||||
# tip_impossible: "It always seems impossible until it's done. - Nelson Mandela"
|
||||
tip_no_try: "Daryk. Arba ne. Jokių 'pabandysiu'. - Yoda"
|
||||
tip_patience: "Kantrybės turėti turi, jaunasis Padavane. - Yoda"
|
||||
tip_documented_bug: "Dokumentuota klaida nėra klaida; tai programos ypatybė."
|
||||
tip_impossible: "Tai visuomet atrodo neįmanoma tol, kol tai nėra padaryta. - Nelson Mandela"
|
||||
# tip_talk_is_cheap: "Talk is cheap. Show me the code. - Linus Torvalds"
|
||||
# tip_first_language: "The most disastrous thing that you can ever learn is your first programming language. - Alan Kay"
|
||||
# tip_hardware_problem: "Q: How many programmers does it take to change a light bulb? A: None, it's a hardware problem."
|
||||
tip_hardware_problem: "K: Kiek programuotojų reikia tam, kad įsuktų lemputę? A: Nei vieno, tai 'geležies' problema."
|
||||
# tip_hofstadters_law: "Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law."
|
||||
# tip_premature_optimization: "Premature optimization is the root of all evil. - Donald Knuth"
|
||||
# tip_brute_force: "When in doubt, use brute force. - Ken Thompson"
|
||||
|
@ -335,12 +335,12 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
# tip_source_code: "I want to change the world but they would not give me the source code."
|
||||
# tip_javascript_java: "Java is to JavaScript what Car is to Carpet. - Chris Heilmann"
|
||||
# tip_move_forward: "Whatever you do, keep moving forward. - Martin Luther King Jr."
|
||||
# tip_google: "Have a problem you can't solve? Google it!"
|
||||
tip_google: "Turi problemą kurios negali išspręsti? Pagooglink!"
|
||||
# tip_adding_evil: "Adding a pinch of evil."
|
||||
# tip_hate_computers: "That's the thing about people who think they hate computers. What they really hate is lousy programmers. - Larry Niven"
|
||||
# tip_open_source_contribute: "You can help CodeCombat improve!"
|
||||
tip_open_source_contribute: "Gali padėti tobulinti CodeCombat!"
|
||||
# tip_recurse: "To iterate is human, to recurse divine. - L. Peter Deutsch"
|
||||
# tip_free_your_mind: "You have to let it all go, Neo. Fear, doubt, and disbelief. Free your mind. - Morpheus"
|
||||
tip_free_your_mind: "Turi paleisti visą tai, Neo. Baimę, abejones ir netikėjimą. Išlaisvink savo mintis. - Morpheus"
|
||||
# tip_strong_opponents: "Even the strongest of opponents always has a weakness. - Itachi Uchiha"
|
||||
# tip_paper_and_pen: "Before you start coding, you can always plan with a sheet of paper and a pen."
|
||||
# tip_solve_then_write: "First, solve the problem. Then, write the code. - John Johnson"
|
||||
|
@ -349,7 +349,7 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
inventory_tab: "Inventorius"
|
||||
save_load_tab: "Įrašyti / Atkurti"
|
||||
options_tab: "Pasirinkimai"
|
||||
guide_tab: "Vedlys"
|
||||
guide_tab: "Pagalba"
|
||||
guide_video_tutorial: "Video vadovėlis"
|
||||
guide_tips: "Patarimai"
|
||||
multiplayer_tab: "Žaidimas keliese"
|
||||
|
@ -362,19 +362,19 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
multiplayer_caption: "Žaisk su draugais!"
|
||||
auth_caption: "Išsaugok savo pažangą."
|
||||
|
||||
# leaderboard:
|
||||
# leaderboard: "Leaderboard"
|
||||
# view_other_solutions: "View Leaderboards"
|
||||
# scores: "Scores"
|
||||
# top_players: "Top Players by"
|
||||
# day: "Today"
|
||||
# week: "This Week"
|
||||
# all: "All-Time"
|
||||
# time: "Time"
|
||||
# damage_taken: "Damage Taken"
|
||||
# damage_dealt: "Damage Dealt"
|
||||
# difficulty: "Difficulty"
|
||||
# gold_collected: "Gold Collected"
|
||||
leaderboard:
|
||||
leaderboard: "Rezultatai"
|
||||
view_other_solutions: "Peržiūrėti rezultatus"
|
||||
scores: "Taškai"
|
||||
top_players: "Geriausi žaidėjai pagal"
|
||||
day: "Šiandien"
|
||||
week: "Savaitė"
|
||||
all: "Visi laikotarpiai"
|
||||
time: "Laikas"
|
||||
damage_taken: "Gauta žalos"
|
||||
damage_dealt: "Padaryta žalos"
|
||||
difficulty: "Sudėtingumas"
|
||||
gold_collected: "Surinkta Aukso"
|
||||
|
||||
inventory:
|
||||
choose_inventory: "Naudoti daiktus"
|
||||
|
@ -389,18 +389,18 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
equip: "Naudoti"
|
||||
unequip: "Nenaudoti"
|
||||
|
||||
# buy_gems:
|
||||
# few_gems: "A few gems"
|
||||
# pile_gems: "Pile of gems"
|
||||
# chest_gems: "Chest of gems"
|
||||
# purchasing: "Purchasing..."
|
||||
# declined: "Your card was declined"
|
||||
# retrying: "Server error, retrying."
|
||||
# prompt_title: "Not Enough Gems"
|
||||
# prompt_body: "Do you want to get more?"
|
||||
# prompt_button: "Enter Shop"
|
||||
# recovered: "Previous gems purchase recovered. Please refresh the page."
|
||||
# price: "x3500 / mo"
|
||||
buy_gems:
|
||||
few_gems: "Sauja deimantų"
|
||||
pile_gems: "Krūvelė deimantų"
|
||||
chest_gems: "Skrynia deimantų"
|
||||
purchasing: "Perkama..."
|
||||
declined: "Jūsų kortelė atmesta"
|
||||
retrying: "Serverio klaida, kartojame."
|
||||
prompt_title: "Deimantų nepakanka"
|
||||
prompt_body: "Ar norite gauti daugiau?"
|
||||
prompt_button: "Į Parduotuvę"
|
||||
recovered: "Atstatyta deimantų pirkimo operacija. Prašome pakraukite puslapį iš naujo."
|
||||
price: "x3500 / mėn"
|
||||
|
||||
# subscribe:
|
||||
# comparison_blurb: "Sharpen your skills with a CodeCombat subscription!"
|
||||
|
@ -500,8 +500,8 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
coffeescript_blurb: "JavaScript su malonesne sintakse."
|
||||
clojure_blurb: "Šiolaikinis Lisp."
|
||||
lua_blurb: "Žaidimų skriptų kalba."
|
||||
# io_blurb: "Simple but obscure."
|
||||
# status: "Status"
|
||||
io_blurb: "Paprasta bet paini."
|
||||
status: "Būsena"
|
||||
hero_type: "Klasė"
|
||||
weapons: "Ginklai"
|
||||
weapons_warrior: "Kardai - artimas atstumas, be Kerų"
|
||||
|
@ -551,23 +551,23 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
# granularity_saved_games: "Saved"
|
||||
# granularity_change_history: "History"
|
||||
|
||||
# options:
|
||||
# general_options: "General Options" # Check out the Options tab in the Game Menu while playing a level
|
||||
# volume_label: "Volume"
|
||||
# music_label: "Music"
|
||||
# music_description: "Turn background music on/off."
|
||||
# editor_config_title: "Editor Configuration"
|
||||
# editor_config_keybindings_label: "Key Bindings"
|
||||
# editor_config_keybindings_default: "Default (Ace)"
|
||||
# editor_config_keybindings_description: "Adds additional shortcuts known from the common editors."
|
||||
# editor_config_livecompletion_label: "Live Autocompletion"
|
||||
# editor_config_livecompletion_description: "Displays autocomplete suggestions while typing."
|
||||
# editor_config_invisibles_label: "Show Invisibles"
|
||||
# editor_config_invisibles_description: "Displays invisibles such as spaces or tabs."
|
||||
# editor_config_indentguides_label: "Show Indent Guides"
|
||||
# editor_config_indentguides_description: "Displays vertical lines to see indentation better."
|
||||
# editor_config_behaviors_label: "Smart Behaviors"
|
||||
# editor_config_behaviors_description: "Autocompletes brackets, braces, and quotes."
|
||||
options:
|
||||
general_options: "Bendri nustatymai" # Check out the Options tab in the Game Menu while playing a level
|
||||
volume_label: "Garsumas"
|
||||
music_label: "Muzika"
|
||||
music_description: "Įj./išj. fono muziką."
|
||||
editor_config_title: "Redaktoriaus konfigūravimas"
|
||||
editor_config_keybindings_label: "Mygtukų funkcijos"
|
||||
editor_config_keybindings_default: "Pagal nutylėjimą (Ace)"
|
||||
editor_config_keybindings_description: "Prideda papildomas mygtukų kombinacijas iš žinomų redagavimo programų."
|
||||
editor_config_livecompletion_label: "Automatinis žodžių užpildymas "
|
||||
editor_config_livecompletion_description: "Rodyti automatinio užpildymo siūlymus rašymo metu."
|
||||
editor_config_invisibles_label: "Rodyti nematomus simbolius"
|
||||
editor_config_invisibles_description: "Rodyti nematomus simbolius, tokius kaip tarpai ar Tab."
|
||||
editor_config_indentguides_label: "Rodyti poslinkio rekomendacijas"
|
||||
editor_config_indentguides_description: "Rodomos vertikalios linijos patogesniam poslinkio matymui."
|
||||
editor_config_behaviors_label: "Išmanusis redagavimas"
|
||||
editor_config_behaviors_description: "Automatiškai uždaro skliaustus, figurinius skliaustus ir kabutes."
|
||||
|
||||
# about:
|
||||
# why_codecombat: "Why CodeCombat?"
|
||||
|
@ -770,14 +770,14 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
# scrub_playback: "Scrub back and forward through time."
|
||||
# single_scrub_playback: "Scrub back and forward through time by a single frame."
|
||||
# scrub_execution: "Scrub through current spell execution."
|
||||
# toggle_debug: "Toggle debug display."
|
||||
toggle_debug: "Įj./išj. klaidų aptikimo (debug) displejų."
|
||||
toggle_grid: "Įjungti tinklelį."
|
||||
# toggle_pathfinding: "Toggle pathfinding overlay."
|
||||
beautify: "Tvarkyti Jūsų kodą standartizuojant jo formatą."
|
||||
# maximize_editor: "Maximize/minimize code editor."
|
||||
maximize_editor: "Išdidinti/sumažinti kodo redaktorių."
|
||||
|
||||
# community:
|
||||
# main_title: "CodeCombat Community"
|
||||
community:
|
||||
main_title: "Bendruomenė CodeCombat"
|
||||
# introduction: "Check out the ways you can get involved below and decide what sounds the most fun. We look forward to working with you!"
|
||||
# level_editor_prefix: "Use the CodeCombat"
|
||||
# level_editor_suffix: "to create and edit levels. Users have created levels for their classes, friends, hackathons, students, and siblings. If create a new level sounds intimidating you can start by forking one of ours!"
|
||||
|
@ -941,24 +941,24 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
|
|||
# hours_content: "Hours of content:"
|
||||
# get_free: "Get FREE course"
|
||||
|
||||
# classes:
|
||||
# archmage_title: "Archmage"
|
||||
# archmage_title_description: "(Coder)"
|
||||
classes:
|
||||
archmage_title: "Arkimagas"
|
||||
archmage_title_description: "(Koderis)"
|
||||
# archmage_summary: "If you are a developer interested in coding educational games, become an archmage to help us build CodeCombat!"
|
||||
# artisan_title: "Artisan"
|
||||
# artisan_title_description: "(Level Builder)"
|
||||
artisan_title: "Menininkas"
|
||||
artisan_title_description: "(Lygių architektas)"
|
||||
# artisan_summary: "Build and share levels for you and your friends to play. Become an Artisan to learn the art of teaching others to program."
|
||||
# adventurer_title: "Adventurer"
|
||||
# adventurer_title_description: "(Level Playtester)"
|
||||
adventurer_title: "Nuotykių ieškotojas"
|
||||
adventurer_title_description: "(Lygių bandytojas)"
|
||||
# adventurer_summary: "Get our new levels (even our subscriber content) for free one week early and help us work out bugs before our public release."
|
||||
# scribe_title: "Scribe"
|
||||
# scribe_title_description: "(Article Editor)"
|
||||
scribe_title: "Raštininkas"
|
||||
scribe_title_description: "(Straipsnių redaktorius)"
|
||||
# scribe_summary: "Good code needs good documentation. Write, edit, and improve the docs read by millions of players across the globe."
|
||||
# diplomat_title: "Diplomat"
|
||||
# diplomat_title_description: "(Translator)"
|
||||
diplomat_title: "Diplomatas"
|
||||
diplomat_title_description: "(Vertėjas)"
|
||||
# diplomat_summary: "CodeCombat is localized in 45+ languages by our Diplomats. Help us out and contribute translations."
|
||||
# ambassador_title: "Ambassador"
|
||||
# ambassador_title_description: "(Support)"
|
||||
ambassador_title: "Ambasadorius"
|
||||
ambassador_title_description: "(Palaikymas)"
|
||||
# ambassador_summary: "Tame our forum users and provide direction for those with questions. Our ambassadors represent CodeCombat to the world."
|
||||
|
||||
# editor:
|
||||
|
|
|
@ -6,12 +6,12 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa
|
|||
play: "Mula" # The big play button that opens up the campaign view.
|
||||
old_browser: "Uh oh, browser anda terlalu lama untuk CodeCombat berfungsi. Maaf!" # Warning that shows up on really old Firefox/Chrome/Safari
|
||||
old_browser_suffix: "Anda boleh mencuba, tapi mungkin ia tidak akan berfungsi."
|
||||
# ipad_browser: "Bad news: CodeCombat doesn't run on iPad in the browser. Good news: our native iPad app is awaiting Apple approval."
|
||||
# campaign: "Campaign"
|
||||
# for_beginners: "For Beginners"
|
||||
# multiplayer: "Multiplayer" # Not currently shown on home page
|
||||
# for_developers: "For Developers" # Not currently shown on home page.
|
||||
# or_ipad: "Or download for iPad"
|
||||
ipad_browser: "Berita buruk: CodeCombat tidak boleh berfungsi pada iPad di dalam pelayar web. Berita baik: Aplikasi native iPad kami sedang menunggu pengesahan Apple."
|
||||
campaign: "Kempen"
|
||||
for_beginners: "Untuk Pemain Baru"
|
||||
multiplayer: "Ramai-Pemain" # Not currently shown on home page
|
||||
for_developers: "Untuk Pengaturcara" # Not currently shown on home page.
|
||||
or_ipad: "Atau muat turun untuk iPad"
|
||||
|
||||
nav:
|
||||
play: "Mula" # The top nav bar entry where players choose which levels to play
|
||||
|
|
|
@ -280,6 +280,7 @@ _.extend UserSchema.properties,
|
|||
pollMiscPatches: c.int()
|
||||
campaignTranslationPatches: c.int()
|
||||
campaignMiscPatches: c.int()
|
||||
concepts: {type: 'object', additionalProperties: c.int(), description: 'Number of levels completed using each programming concept.'}
|
||||
|
||||
earned: c.RewardSchema 'earned by achievements'
|
||||
purchased: c.RewardSchema 'purchased with gems or money'
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
#subscription-view
|
||||
|
||||
.invalid-email-message
|
||||
color: red
|
||||
font-size: 12px
|
||||
|
||||
.recipient-emails.invalid
|
||||
border: 1px solid red
|
||||
|
||||
.logged-out-blurb
|
||||
font-size: 18px
|
||||
|
|
12
app/styles/admin/analytics.sass
Normal file
12
app/styles/admin/analytics.sass
Normal file
|
@ -0,0 +1,12 @@
|
|||
#admin-analytics-view
|
||||
|
||||
#site-content-area
|
||||
width: 100%
|
||||
.big-stat
|
||||
width: auto
|
||||
.active-users
|
||||
color: green
|
||||
.count
|
||||
font-size: 50pt
|
||||
.description
|
||||
font-size: 8pt
|
|
@ -150,7 +150,9 @@ block content
|
|||
if view.recipientSubs.state === 'subscribing'
|
||||
.alert.alert-info(data-i18n="subscribe.subscribing")
|
||||
else
|
||||
textarea.recipient-emails(rows=3, data-i18n="[placeholder]subscribe.recipient_emails_placeholder")
|
||||
if emailValidator.state === 'invalid'
|
||||
div.invalid-email-message(aria-hidden="true") please make sure all entries are valid emails
|
||||
textarea.recipient-emails(rows=3, data-i18n="[placeholder]subscribe.recipient_emails_placeholder")=emailValidator.lastEmails
|
||||
div
|
||||
button.recipients-subscribe-button.btn.btn-lg.btn-success(data-i18n="subscribe.subscribe_users")
|
||||
if view.recipientSubs.state === 'declined'
|
||||
|
|
|
@ -48,12 +48,11 @@ block content
|
|||
li
|
||||
a(href="/admin/pending-patches", data-i18n="resources.patches") Patches
|
||||
if me.isAdmin()
|
||||
li Analytics
|
||||
li
|
||||
a(href="/admin/analytics") Analytics
|
||||
ul
|
||||
li
|
||||
a(href="/admin/analytics/subscriptions") Subscriptions
|
||||
li
|
||||
a(href="/admin/analytics/users") Users (needs updating)
|
||||
|
||||
if me.isAdmin()
|
||||
hr
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
extends /templates/base
|
||||
|
||||
block content
|
||||
|
||||
h1(data-i18n="admin.growth_title") Users
|
||||
if me.isAdmin()
|
||||
if crunchingData
|
||||
h4 Crunching Data..
|
||||
else
|
||||
h2 Registered Users
|
||||
h3 Per-Day
|
||||
h4 Totals
|
||||
svg.perDayTotal
|
||||
h4 Added
|
||||
svg.perDayAdded
|
||||
table.table.table-striped.table-bordered.table-condensed
|
||||
-for (var i = 0; i < usersPerDay.length; i++)
|
||||
tr
|
||||
td= usersPerDay[i].date
|
||||
td= usersPerDay[i].added
|
||||
td= usersPerDay[i].total
|
||||
h3 Per-Month
|
||||
h4 Totals
|
||||
svg.perMonthTotal
|
||||
h4 Added
|
||||
svg.perMonthAdded
|
||||
table.table.table-striped.table-bordered.table-condensed
|
||||
-for (var i = 0; i < usersPerMonth.length; i++)
|
||||
tr
|
||||
td= usersPerMonth[i].date
|
||||
td= usersPerMonth[i].added
|
||||
td= usersPerMonth[i].total
|
29
app/templates/admin/analytics.jade
Normal file
29
app/templates/admin/analytics.jade
Normal file
|
@ -0,0 +1,29 @@
|
|||
extends /templates/base
|
||||
|
||||
block content
|
||||
|
||||
if me.isAdmin()
|
||||
.container-fluid
|
||||
.row
|
||||
.col-md-5.big-stat.active-users
|
||||
if activeUsers.length > 0
|
||||
div.description 30-day Active Users
|
||||
div.count= activeUsers[0].monthlyCount
|
||||
|
||||
h1 Active Users
|
||||
table.table.table-striped.table-condensed
|
||||
tr
|
||||
th Day
|
||||
th Daily Actives
|
||||
th Monthly Actives
|
||||
th DAUs / MAUs
|
||||
each activeUser in activeUsers
|
||||
tr
|
||||
td= activeUser.day
|
||||
td= activeUser.dailyCount
|
||||
if activeUser.monthlyCount
|
||||
td= activeUser.monthlyCount
|
||||
td #{(activeUser.dailyCount / activeUser.monthlyCount * 100).toFixed(2)}%
|
||||
else
|
||||
td
|
||||
td
|
|
@ -120,10 +120,3 @@ block modal-footer-content
|
|||
img.pull-right(src="/file/db/level/55144b509f0c4854051769c1/viking_2.png")
|
||||
span(data-i18n="play_level.victory_viking_code_school")
|
||||
button.btn.btn-illustrated.btn-primary.btn-lg.world-map-button.continue-from-offer-button(data-i18n="play_level.victory_become_a_viking") Become a Viking
|
||||
.offer.a-mayhem-of-munchkins
|
||||
p
|
||||
img.pull-left(src="/file/db/level/55ca29439bc1892c835b0137/bloc_warrior.png")
|
||||
img.pull-right(src="/file/db/level/55ca29439bc1892c835b0137/bloc_logo.png")
|
||||
span(data-i18n="play_level.victory_bloc")
|
||||
button.btn.btn-illustrated.btn-warning.btn-lg.world-map-button.skip-offer-button(data-i18n="play_level.victory_play_continue") Continue
|
||||
button.btn.btn-illustrated.btn-primary.btn-lg.world-map-button.continue-from-offer-button(data-i18n="play_level.victory_bloc_cta")
|
||||
|
|
|
@ -49,9 +49,15 @@ module.exports = class SubscriptionView extends RootView
|
|||
prepaidCode = utils.getQueryVariable '_ppc'
|
||||
@personalSub = new PersonalSub(@supermodel, prepaidCode)
|
||||
@recipientSubs = new RecipientSubs(@supermodel)
|
||||
@emailValidator = new EmailValidator(@superModel)
|
||||
@personalSub.update => @render?()
|
||||
@recipientSubs.update => @render?()
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
c.emailValidator = @emailValidator
|
||||
c
|
||||
|
||||
# Personal Subscriptions
|
||||
|
||||
onClickStartSubscription: (e) ->
|
||||
|
@ -82,7 +88,8 @@ module.exports = class SubscriptionView extends RootView
|
|||
|
||||
onClickRecipientsSubscribe: (e) ->
|
||||
emails = @$el.find('.recipient-emails').val().split('\n')
|
||||
@recipientSubs.startSubscribe(emails)
|
||||
valid = @emailValidator.validateEmails(emails, =>@render?())
|
||||
@recipientSubs.startSubscribe(emails) if valid
|
||||
|
||||
onClickRecipientUnsubscribe: (e) ->
|
||||
$(e.target).addClass('hide')
|
||||
|
@ -97,6 +104,31 @@ module.exports = class SubscriptionView extends RootView
|
|||
|
||||
# Helper classes for managing subscription actions and updating UI state
|
||||
|
||||
class EmailValidator
|
||||
|
||||
validateEmails: (emails, render) ->
|
||||
@lastEmails = emails.join('\n')
|
||||
#taken from http://www.regular-expressions.info/email.html
|
||||
emailRegex = /[A-z0-9._%+-]+@[A-z0-9.-]+\.[A-z]{2,4}/
|
||||
@validEmails = (email for email in emails when emailRegex.test(email.trim().toLowerCase()))
|
||||
return @emailsInvalid(render) if @validEmails.length < emails.length
|
||||
return @emailsValid(render)
|
||||
|
||||
emailString: ->
|
||||
return unless @validEmails
|
||||
return @validEmails.join('\n')
|
||||
|
||||
emailsInvalid: (render) ->
|
||||
@state = "invalid"
|
||||
render()
|
||||
return false
|
||||
|
||||
emailsValid: (render) ->
|
||||
@state = "valid"
|
||||
render()
|
||||
return true
|
||||
|
||||
|
||||
class PersonalSub
|
||||
constructor: (@supermodel, @prepaidCode) ->
|
||||
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/admin/analytics-users'
|
||||
RealTimeCollection = require 'collections/RealTimeCollection'
|
||||
|
||||
require 'vendor/d3'
|
||||
|
||||
# Growth View ###################
|
||||
#
|
||||
# Display interesting growth data.
|
||||
#
|
||||
# Currently shows:
|
||||
# Registered user totals and added, per-day and per-month
|
||||
# 7-day moving average for registered users added per-day
|
||||
#
|
||||
# TODO: @padding isn't applied correctly
|
||||
# TODO: aggregate recent data if missing?
|
||||
#
|
||||
|
||||
module.exports = class AnalyticsUsersView extends RootView
|
||||
id: 'admin-analytics-users-view'
|
||||
template: template
|
||||
height: 300
|
||||
width: 1000
|
||||
xAxisGuideHeight: 80
|
||||
yAxisGuideWidth: 60
|
||||
padding: 10
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@usersPerMonth = new RealTimeCollection 'growth/users/registered/per-month'
|
||||
@usersPerMonth.on 'add', @refreshData
|
||||
@usersPerDay = new RealTimeCollection 'growth/users/registered/per-day'
|
||||
@usersPerDay.on 'add', @refreshData
|
||||
|
||||
destroy: ->
|
||||
@usersPerMonth.off 'add', @refreshData
|
||||
@usersPerDay.off 'add', @refreshData
|
||||
|
||||
refreshData: =>
|
||||
@render()
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
c.crunchingData = @usersPerMonth.length is 0 and @usersPerDay.length is 0
|
||||
c.usersPerDay = []
|
||||
# @usersPerDay.each (item) ->
|
||||
# c.usersPerDay.push date: item.get('id'), added: item.get('added'), total: item.get('total')
|
||||
c.usersPerMonth = []
|
||||
# @usersPerMonth.each (item) ->
|
||||
# c.usersPerMonth.push date: item.get('id'), added: item.get('added'), total: item.get('total')
|
||||
c
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
if me.isAdmin()
|
||||
@createPerDayChart()
|
||||
@createPerMonthChart()
|
||||
|
||||
createPerDayChart: ->
|
||||
addedData = []
|
||||
totalData = []
|
||||
@usersPerDay.each (item) ->
|
||||
addedData.push id: item.get('id'), value: item.get('added')
|
||||
totalData.push id: item.get('id'), value: item.get('total')
|
||||
@createLineChart ".perDayTotal", totalData, 1000
|
||||
@createLineChart ".perDayAdded", addedData, 10, true
|
||||
|
||||
createPerMonthChart: ->
|
||||
addedData = []
|
||||
totalData = []
|
||||
@usersPerMonth.each (item) ->
|
||||
addedData.push id: item.get('id'), value: item.get('added')
|
||||
totalData.push id: item.get('id'), value: item.get('total')
|
||||
@createLineChart ".perMonthTotal", totalData, 1000
|
||||
@createLineChart ".perMonthAdded", addedData, 1000
|
||||
|
||||
createLineChart: (selector, data, guidelineSpacing, sevenDayAverage=false) ->
|
||||
return unless data.length > 1
|
||||
|
||||
minVal = d3.min(data, (d) -> d.value)
|
||||
maxVal = d3.max(data, (d) -> d.value)
|
||||
|
||||
widthSpacing = (@width - @yAxisGuideWidth - @padding) / (data.length - 1)
|
||||
|
||||
y = d3.scale.linear()
|
||||
.domain([minVal, maxVal])
|
||||
.range([@height - @xAxisGuideHeight - 2 * @padding, 0])
|
||||
|
||||
points = []
|
||||
for i in [0...data.length]
|
||||
points.push id: data[i].id, x: i * widthSpacing + @yAxisGuideWidth, y: y(data[i].value) + @padding
|
||||
|
||||
links = []
|
||||
for i in [0...points.length - 1]
|
||||
if points[i] and points[i + 1]
|
||||
links.push start: points[i], end: points[i + 1]
|
||||
|
||||
guidelines = []
|
||||
diff = maxVal - minVal
|
||||
interval = Math.floor(diff / 5)
|
||||
for i in [0..4]
|
||||
yVal = i * interval + minVal
|
||||
yVal = Math.floor(yVal / guidelineSpacing) * guidelineSpacing
|
||||
guidelines.push start: {id: yVal, x: 0, y: y(yVal)}, end: {id: yVal, x: @width, y: y(yVal)}
|
||||
|
||||
sevenPoints = []
|
||||
sevenLinks = []
|
||||
if sevenDayAverage
|
||||
sevenTotal = 0
|
||||
for i in [0...data.length]
|
||||
sevenTotal += data[i].value
|
||||
if i > 5
|
||||
sevenAvg = sevenTotal / 7
|
||||
sevenPoints.push x: i * widthSpacing + @yAxisGuideWidth, y: y(sevenAvg) + @padding
|
||||
if i > 6
|
||||
sevenTotal -= data[i - 7].value
|
||||
for i in [0...sevenPoints.length - 1]
|
||||
if sevenPoints[i] and sevenPoints[i + 1]
|
||||
sevenLinks.push start: sevenPoints[i], end: sevenPoints[i + 1]
|
||||
|
||||
chart = d3.select(selector)
|
||||
.attr("width", @width)
|
||||
.attr("height", @height)
|
||||
|
||||
chart.selectAll(".circle")
|
||||
.data(points)
|
||||
.enter()
|
||||
.append("circle")
|
||||
.attr("cx", (d) -> d.x )
|
||||
.attr("cy", (d) -> d.y )
|
||||
.attr("r", "2px")
|
||||
.attr("fill", "black")
|
||||
|
||||
chart.selectAll(".text")
|
||||
.data(points)
|
||||
.enter()
|
||||
.append("text")
|
||||
.attr("dy", ".35em")
|
||||
.attr("transform", (d, i) => "translate(" + d.x + "," + @height + ") rotate(270)")
|
||||
.text((d) ->
|
||||
if d.id.length is 8
|
||||
return "#{parseInt(d.id[4..5])}/#{parseInt(d.id[6..7])}/#{d.id[0..3]}"
|
||||
else
|
||||
return "#{parseInt(d.id[4..5])}/#{d.id[0..3]}"
|
||||
)
|
||||
|
||||
chart.selectAll('.line')
|
||||
.data(links)
|
||||
.enter()
|
||||
.append("line")
|
||||
.attr("x1", (d) -> d.start.x )
|
||||
.attr("y1", (d) -> d.start.y )
|
||||
.attr("x2", (d) -> d.end.x )
|
||||
.attr("y2", (d) -> d.end.y )
|
||||
.style("stroke", "rgb(6,120,155)")
|
||||
|
||||
chart.selectAll(".circle")
|
||||
.data(sevenPoints)
|
||||
.enter()
|
||||
.append("circle")
|
||||
.attr("cx", (d) -> d.x )
|
||||
.attr("cy", (d) -> d.y )
|
||||
.attr("r", "2px")
|
||||
.attr("fill", "purple")
|
||||
|
||||
chart.selectAll('.line')
|
||||
.data(sevenLinks)
|
||||
.enter()
|
||||
.append("line")
|
||||
.attr("x1", (d) -> d.start.x )
|
||||
.attr("y1", (d) -> d.start.y )
|
||||
.attr("x2", (d) -> d.end.x )
|
||||
.attr("y2", (d) -> d.end.y )
|
||||
.style("stroke", "rgb(200,0,0)")
|
||||
|
||||
chart.selectAll('.line')
|
||||
.data(guidelines)
|
||||
.enter()
|
||||
.append("line")
|
||||
.attr("x1", (d) -> d.start.x )
|
||||
.attr("y1", (d) -> d.start.y )
|
||||
.attr("x2", (d) -> d.end.x )
|
||||
.attr("y2", (d) -> d.end.y )
|
||||
.style("stroke", "rgb(140,140,140)")
|
||||
|
||||
chart.selectAll(".text")
|
||||
.data(guidelines)
|
||||
.enter()
|
||||
.append("text")
|
||||
.attr("x", (d) -> d.start.x)
|
||||
.attr("y", (d) -> d.start.y - 6)
|
||||
.attr("dy", ".35em")
|
||||
.text((d) -> d.start.id)
|
27
app/views/admin/AnalyticsView.coffee
Normal file
27
app/views/admin/AnalyticsView.coffee
Normal file
|
@ -0,0 +1,27 @@
|
|||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/admin/analytics'
|
||||
utils = require 'core/utils'
|
||||
|
||||
module.exports = class AnalyticsView extends RootView
|
||||
id: 'admin-analytics-view'
|
||||
template: template
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
startDay = utils.getUTCDay(-30).replace(/-/g, '')
|
||||
endDay = utils.getUTCDay(-30).replace(/-/g, '')
|
||||
request = @supermodel.addRequestResource 'active_users', {
|
||||
url: '/db/analytics_perday/-/active_users'
|
||||
data: {startDay: startDay, endDay: endDay}
|
||||
method: 'POST'
|
||||
success: (data) =>
|
||||
@activeUsers = data
|
||||
@activeUsers.sort (a, b) -> b.day.localeCompare(a.day)
|
||||
@render?()
|
||||
}, 0
|
||||
request.load()
|
||||
|
||||
getRenderData: ->
|
||||
context = super()
|
||||
context.activeUsers = @activeUsers ? []
|
||||
context
|
|
@ -37,7 +37,7 @@ module.exports = class ThangAvatarView extends CocoView
|
|||
context = super context
|
||||
context.thang = @thang
|
||||
options = @thang?.getLankOptions() or {}
|
||||
options.async = true
|
||||
#options.async = true # sync builds fail during async builds, and we build HUD version sync
|
||||
context.avatarURL = @thangType.getPortraitSource(options) unless @thangType.loading
|
||||
context.includeName = @includeName
|
||||
context
|
||||
|
|
|
@ -476,7 +476,6 @@ module.exports = class HeroVictoryModal extends ModalView
|
|||
onClickContinueFromOffer: (e) ->
|
||||
url = {
|
||||
'lost-viking': 'http://www.vikingcodeschool.com/codecombat?utm_source=codecombat&utm_medium=viking_level&utm_campaign=affiliate&ref=Code+Combat+Elite'
|
||||
'a-mayhem-of-munchkins': 'https://www.bloc.io/web-developer-career-track?utm_campaign=affiliate&utm_source=codecombat&utm_medium=bloc_level'
|
||||
}[@level.get('slug')]
|
||||
Backbone.Mediator.publish 'router:navigate', @navigationEventUponCompletion
|
||||
window.open url, '_blank' if url
|
||||
|
|
|
@ -106,6 +106,7 @@ module.exports = class SpellView extends CocoView
|
|||
@ace.setAnimatedScroll true
|
||||
@ace.setShowFoldWidgets false
|
||||
@ace.setKeyboardHandler @keyBindings[aceConfig.keyBindings ? 'default']
|
||||
@ace.$blockScrolling = Infinity
|
||||
@toggleControls null, @writable
|
||||
@aceSession.selection.on 'changeCursor', @onCursorActivity
|
||||
$(@ace.container).find('.ace_gutter').on 'click mouseenter', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
|
||||
|
@ -459,7 +460,7 @@ module.exports = class SpellView extends CocoView
|
|||
entry.captureReturn = switch e.language
|
||||
when 'io' then varName + ' := '
|
||||
when 'javascript' then 'var ' + varName + ' = '
|
||||
when 'clojure' then '(let [' + varName + ' '
|
||||
when 'clojure' then '(let [' + varName + ' '
|
||||
else varName + ' = '
|
||||
|
||||
# TODO: Generalize this snippet replacement
|
||||
|
|
|
@ -41,7 +41,7 @@ module.exports = class LevelGuideView extends CocoView
|
|||
@docs = specific.concat(general)
|
||||
@docs = $.extend(true, [], @docs)
|
||||
@docs = [@docs[0]] if @firstOnly and @docs[0]
|
||||
doc.html = marked(utils.i18n doc, 'body') for doc in @docs
|
||||
doc.html = marked(@filterCodeLanguages(utils.i18n(doc, 'body'))) for doc in @docs
|
||||
doc.name = (utils.i18n doc, 'name') for doc in @docs
|
||||
doc.slug = _.string.slugify(doc.name) for doc in @docs
|
||||
super()
|
||||
|
@ -72,6 +72,12 @@ module.exports = class LevelGuideView extends CocoView
|
|||
@$el.find('.nav-tabs a').click(@clickTab)
|
||||
@playSound 'guide-open'
|
||||
|
||||
filterCodeLanguages: (text) ->
|
||||
currentLanguage = me.get('aceConfig')?.language or 'python'
|
||||
excludedLanguages = _.without ['javascript', 'python', 'coffeescript', 'clojure', 'lua', 'io'], currentLanguage
|
||||
exclusionRegex = new RegExp "```(#{excludedLanguages.join('|')})\n[^`]+```\n?", 'gm'
|
||||
text.replace exclusionRegex, ''
|
||||
|
||||
clickSubscribe: (e) ->
|
||||
level = @levelSlug # Save ref to level slug
|
||||
@openModalView new SubscribeModal()
|
||||
|
|
|
@ -32,13 +32,17 @@ exports.config =
|
|||
overrides:
|
||||
production:
|
||||
sourceMaps: 'absoluteUrl'
|
||||
onCompile: (files) ->
|
||||
# For some reason, production brunch produces two entries, the first of which is wrong:
|
||||
# //# sourceMappingURL=public/javascripts/app.js.map
|
||||
# //# sourceMappingURL=/javascripts/app.js.map
|
||||
# So we remove the ones that have public in them.
|
||||
exec = require('child_process').exec
|
||||
exec "perl -pi -e 's/\\/\\/# sourceMappingURL=public.*//g' public/javascripts/*.js"
|
||||
plugins:
|
||||
coffeelint:
|
||||
pattern: /\A\Z/
|
||||
afterBrunch: [
|
||||
"coffee scripts/minify.coffee",
|
||||
]
|
||||
fast:
|
||||
onCompile: (files) -> console.log "I feel the need, the need... for speed."
|
||||
plugins:
|
||||
coffeelint:
|
||||
pattern: /\A\Z/
|
||||
vagrant:
|
||||
watcher:
|
||||
usePolling: true
|
||||
|
@ -181,7 +185,6 @@ exports.config =
|
|||
plugins:
|
||||
coffeelint:
|
||||
pattern: /^app\/.*\.coffee$/
|
||||
# pattern: /^dne/ # use this pattern instead if you want to speed compilation
|
||||
options:
|
||||
line_endings:
|
||||
value: 'unix'
|
||||
|
@ -192,16 +195,14 @@ exports.config =
|
|||
level: 'ignore' # PyCharm can't just autostrip for .coffee, needed for .jade
|
||||
no_unnecessary_fat_arrows:
|
||||
level: 'ignore'
|
||||
uglify:
|
||||
mangle:
|
||||
except: ['require']
|
||||
output:
|
||||
semicolons: false
|
||||
sass:
|
||||
mode: 'native'
|
||||
allowCache: true
|
||||
bless:
|
||||
cacheBuster: false
|
||||
assetsmanager:
|
||||
copyTo:
|
||||
'lib/ace': ['node_modules/ace-builds/src-min-noconflict/*']
|
||||
|
||||
modules:
|
||||
definition: (path, data) ->
|
||||
|
|
11
package.json
11
package.json
|
@ -33,10 +33,11 @@
|
|||
"test": "./node_modules/.bin/karma start",
|
||||
"predeploy": "echo Starting deployment--hold onto your butts.; echo Skipping brunch build --production",
|
||||
"postdeploy": "echo Deployed. Unclench.",
|
||||
"postinstall": "bower install && brunch build",
|
||||
"postinstall": "bower install && brunch build --env fast",
|
||||
"brunch": "brunch",
|
||||
"bower": "bower",
|
||||
"dev": "brunch watch --server",
|
||||
"multicore": "coffee multicore.coffee",
|
||||
"nodemon": "nodemon"
|
||||
},
|
||||
"main": "index.js",
|
||||
|
@ -48,6 +49,7 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"JQDeferred": "~2.1.0",
|
||||
"ace-builds": "https://github.com/ajaxorg/ace-builds/archive/3fb55e8e374ab02ce47c1ae55ffb60a1835f3055.tar.gz",
|
||||
"aether": "~0.3.0",
|
||||
"async": "0.2.x",
|
||||
"aws-sdk": "~2.0.0",
|
||||
|
@ -80,15 +82,18 @@
|
|||
"winston": "0.6.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"after-brunch": "0.0.5",
|
||||
"assetsmanager-brunch": "^1.8.1",
|
||||
"auto-reload-brunch": "> 1.0 < 1.8",
|
||||
"bless-brunch": "https://github.com/ThomasConner/bless-brunch/tarball/master",
|
||||
"bower": "~1.6.4",
|
||||
"brunch": "^1.8.5",
|
||||
"coffee-script-brunch": "^1.8.3",
|
||||
"coffeelint-brunch": "^1.7.1",
|
||||
"compressible": "~1.0.1",
|
||||
"commonjs-require-definition": "0.2.0",
|
||||
"compressible": "~1.0.1",
|
||||
"css-brunch": "^1.7.0",
|
||||
"fs-extra": "^0.26.2",
|
||||
"jade-brunch": "1.7.5",
|
||||
"jasmine-node": "1.13.x",
|
||||
"jasmine-spec-reporter": "~0.3.0",
|
||||
|
@ -108,7 +113,7 @@
|
|||
"requirejs": "~2.1.10",
|
||||
"sass-brunch": "https://github.com/basicer/sass-brunch-bleeding/archive/1.9.1-bleeding.tar.gz",
|
||||
"telepath-brunch": "https://github.com/nwinter/telepath-brunch/tarball/master",
|
||||
"uglify-js-brunch": "^1.7.8"
|
||||
"uglify-js": "^2.5.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"webworker-threads": "~0.5.5"
|
||||
|
|
|
@ -17,8 +17,8 @@ try {
|
|||
var scriptStartTime = new Date();
|
||||
var analyticsStringCache = {};
|
||||
|
||||
// Look at last 30 days, same as Mixpanel
|
||||
var numDays = 30;
|
||||
var numDays = 32;
|
||||
var daysInMonth = 30;
|
||||
|
||||
var startDay = new Date();
|
||||
today = startDay.toISOString().substr(0, 10);
|
||||
|
@ -27,6 +27,7 @@ try {
|
|||
|
||||
var levelCompletionFunnel = ['Started Level', 'Saw Victory'];
|
||||
var levelHelpEvents = ['Problem alert help clicked', 'Spell palette help clicked', 'Start help video'];
|
||||
var activeUserEvents = ['Finished Signup', 'Started Level'];
|
||||
|
||||
log("Today is " + today);
|
||||
log("Start day is " + startDay);
|
||||
|
@ -39,7 +40,7 @@ try {
|
|||
for (day in levelCompletionData[level]) {
|
||||
if (today === day) continue; // Never save data for today because it's incomplete
|
||||
for (event in levelCompletionData[level][day]) {
|
||||
insertEventCount(event, level, day, levelCompletionData[level][day][event]);
|
||||
insertLevelEventCount(event, level, day, levelCompletionData[level][day][event]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +51,7 @@ try {
|
|||
for (level in levelDropCounts) {
|
||||
for (day in levelDropCounts[level]) {
|
||||
if (today === day) continue; // Never save data for today because it's incomplete
|
||||
insertEventCount('User Dropped', level, day, levelDropCounts[level][day]);
|
||||
insertLevelEventCount('User Dropped', level, day, levelDropCounts[level][day]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +62,7 @@ try {
|
|||
for (day in levelHelpCounts[level]) {
|
||||
if (today === day) continue; // Never save data for today because it's incomplete
|
||||
for (event in levelHelpCounts[level][day]) {
|
||||
insertEventCount(event, level, day, levelHelpCounts[level][day][event]);
|
||||
insertLevelEventCount(event, level, day, levelHelpCounts[level][day][event]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,11 +74,22 @@ try {
|
|||
for (day in levelSubscriptionCounts[level]) {
|
||||
if (today === day) continue; // Never save data for today because it's incomplete
|
||||
for (event in levelSubscriptionCounts[level][day]) {
|
||||
insertEventCount(event, level, day, levelSubscriptionCounts[level][day][event]);
|
||||
insertLevelEventCount(event, level, day, levelSubscriptionCounts[level][day][event]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log("Getting active user counts...");
|
||||
var activeUserCounts = getActiveUserCounts(startDay, activeUserEvents);
|
||||
// printjson(activeUserCounts);
|
||||
log("Inserting active user counts...");
|
||||
for (day in activeUserCounts) {
|
||||
if (today === day) continue; // Never save data for today because it's incomplete
|
||||
for (event in activeUserCounts[day]) {
|
||||
insertEventCount(event, day, activeUserCounts[day][event]);
|
||||
}
|
||||
}
|
||||
|
||||
log("Script runtime: " + (new Date() - scriptStartTime));
|
||||
}
|
||||
catch(err) {
|
||||
|
@ -383,7 +395,87 @@ function getLevelSubscriptionCounts(startDay) {
|
|||
return levelFunnelData;
|
||||
}
|
||||
|
||||
function insertEventCount(event, level, day, count) {
|
||||
function getActiveUserCounts(startDay, activeUserEvents) {
|
||||
// Counts active users per day
|
||||
if (!startDay) return {};
|
||||
|
||||
var startObj = objectIdWithTimestamp(ISODate(startDay + "T00:00:00.000Z"));
|
||||
var queryParams = {$and: [
|
||||
{_id: {$gte: startObj}},
|
||||
{'event': {$in: activeUserEvents}}
|
||||
]};
|
||||
var cursor = logDB['log'].find(queryParams);
|
||||
|
||||
var dayUserMap = {};
|
||||
while (cursor.hasNext()) {
|
||||
var doc = cursor.next();
|
||||
var created = doc._id.getTimestamp().toISOString();
|
||||
var day = created.substring(0, 10);
|
||||
var user = doc.user;
|
||||
|
||||
if (!dayUserMap[day]) dayUserMap[day] = {};
|
||||
dayUserMap[day][user] = true;
|
||||
}
|
||||
// printjson(dayUserMap['2015-11-01']);
|
||||
|
||||
var activeUsersCounts = {};
|
||||
var monthlyActives = [];
|
||||
for (day in dayUserMap) {
|
||||
activeUsersCounts[day] = {'Daily Active Users': Object.keys(dayUserMap[day]).length};
|
||||
monthlyActives.push({day: day, users: dayUserMap[day]});
|
||||
}
|
||||
|
||||
monthlyActives.sort(function (a, b) {return a.day.localeCompare(b.day);});
|
||||
|
||||
// Calculate monthly actives for each day, starting when we have enough data
|
||||
for (var i = daysInMonth - 1; i < monthlyActives.length; i++) {
|
||||
var monthUserMap = {};
|
||||
for (var j = i - daysInMonth + 1; j <= i; j++) {
|
||||
for (var user in monthlyActives[j].users) {
|
||||
monthUserMap[user] = true;
|
||||
}
|
||||
}
|
||||
activeUsersCounts[monthlyActives[i].day]['Monthly Active Users'] = Object.keys(monthUserMap).length;
|
||||
}
|
||||
return activeUsersCounts;
|
||||
}
|
||||
|
||||
function insertEventCount(event, day, count) {
|
||||
// analytics.perdays schema in server/analytics/AnalyticsPeryDay.coffee
|
||||
day = day.replace(/-/g, '');
|
||||
|
||||
var eventID = getAnalyticsString(event);
|
||||
var filterID = getAnalyticsString('all');
|
||||
|
||||
var startObj = objectIdWithTimestamp(ISODate(startDay + "T00:00:00.000Z"));
|
||||
var queryParams = {$and: [{d: day}, {e: eventID}, {f: filterID}]};
|
||||
var doc = db['analytics.perdays'].findOne(queryParams);
|
||||
if (doc && doc.c === count) return;
|
||||
|
||||
if (doc && doc.c !== count) {
|
||||
// Update existing count, assume new one is more accurate
|
||||
// log("Updating count in db for " + day + " " + event + " " + doc.c + " => " + count);
|
||||
var results = db['analytics.perdays'].update(queryParams, {$set: {c: count}});
|
||||
if (results.nMatched !== 1 && results.nModified !== 1) {
|
||||
log("ERROR: update event count failed");
|
||||
printjson(results);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var insertDoc = {d: day, e: eventID, f: filterID, c: count};
|
||||
var results = db['analytics.perdays'].insert(insertDoc);
|
||||
if (results.nInserted !== 1) {
|
||||
log("ERROR: insert event failed");
|
||||
printjson(results);
|
||||
printjson(insertDoc);
|
||||
}
|
||||
// else {
|
||||
// log("Added " + day + " " + event + " " + count);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
function insertLevelEventCount(event, level, day, count) {
|
||||
// analytics.perdays schema in server/analytics/AnalyticsPeryDay.coffee
|
||||
day = day.replace(/-/g, '');
|
||||
|
||||
|
|
61
scripts/minify.coffee
Normal file
61
scripts/minify.coffee
Normal file
|
@ -0,0 +1,61 @@
|
|||
path = require 'path'
|
||||
fs = require 'fs-extra'
|
||||
_ = require 'lodash'
|
||||
async = require 'async'
|
||||
cores = require('os').cpus().length
|
||||
child_process = require 'child_process'
|
||||
|
||||
root = path.join(__dirname, '..', 'public','javascripts');
|
||||
dest = path.join(__dirname, '..', 'public','javascripts-min');
|
||||
|
||||
console.log root
|
||||
dirStack = [path.join(root)]
|
||||
files = []
|
||||
|
||||
while dirStack.length
|
||||
dir = dirStack.pop()
|
||||
contents = fs.readdirSync(dir)
|
||||
for file in contents
|
||||
fullPath = "#{dir}/#{file}"
|
||||
stat = fs.statSync(fullPath)
|
||||
if stat.isDirectory()
|
||||
dirStack.push(fullPath)
|
||||
else if /\.js$/.test(file)
|
||||
files.push fullPath.replace root + '/', ''
|
||||
|
||||
|
||||
jobs = _.map files, (file) ->
|
||||
(cb2) ->
|
||||
fpath = path.join(root, file)
|
||||
dpath = path.join(dest, file)
|
||||
smArgs = []
|
||||
|
||||
if fs.existsSync fpath + '.map'
|
||||
smArgs = [
|
||||
'--in-source-map', fpath + '.map',
|
||||
'--source-map', dpath + '.map',
|
||||
'--source-map-include-sources',
|
||||
'--source-map-url', '/javascripts/' + file.replace('/\\/g', '/') + '.map'
|
||||
]
|
||||
|
||||
args = [fpath, '-m', '-r', 'require' , '-b', 'beautify=false,semicolons=false'].concat smArgs, ['-o', dpath]
|
||||
async.waterfall [
|
||||
_.bind(fs.mkdirs, fs, path.dirname dpath),
|
||||
(last, cb) ->
|
||||
child = child_process.spawn 'uglifyjs', args, stdio:'inherit'
|
||||
child.on 'close', (code) ->
|
||||
if code == 0 then cb null
|
||||
else cb code
|
||||
child.on 'error', (err) ->
|
||||
cb err
|
||||
], cb2
|
||||
|
||||
async.parallelLimit jobs, cores, (err, res)->
|
||||
if err
|
||||
console.log "ERROR:", err
|
||||
else
|
||||
console.log "Done, minified " + jobs.length + " files."
|
||||
fs.renameSync(root, root + "-old")
|
||||
fs.renameSync(dest, root)
|
||||
fs.removeSync(root + "-old")
|
||||
|
|
@ -14,6 +14,7 @@ class AnalyticsPerDayHandler extends Handler
|
|||
|
||||
getByRelationship: (req, res, args...) ->
|
||||
return @sendForbiddenError res unless @hasAccess req
|
||||
return @getActiveUsers(req, res) if args[1] is 'active_users'
|
||||
return @getCampaignCompletionsBySlug(req, res) if args[1] is 'campaign_completions'
|
||||
return @getLevelCompletionsBySlug(req, res) if args[1] is 'level_completions'
|
||||
return @getLevelDropsBySlugs(req, res) if args[1] is 'level_drops'
|
||||
|
@ -21,6 +22,29 @@ class AnalyticsPerDayHandler extends Handler
|
|||
return @getLevelSubscriptionsBySlugs(req, res) if args[1] is 'level_subscriptions'
|
||||
super(arguments...)
|
||||
|
||||
getActiveUsers: (req, res) ->
|
||||
AnalyticsString.find({v: {$in: ['Daily Active Users', 'Monthly Active Users']}}).exec (err, documents) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
for doc in documents
|
||||
dailyID = doc._id if doc.v is 'Daily Active Users'
|
||||
monthlyID = doc._id if doc.v is 'Monthly Active Users'
|
||||
return @sendSuccess res, [] unless dailyID? and monthlyID?
|
||||
|
||||
AnalyticsPerDay.find({e: {$in: [dailyID, monthlyID]}}).exec (err, documents) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
dayCountsMap = {}
|
||||
for doc in documents
|
||||
dayCountsMap[doc.d] ?= {}
|
||||
dayCountsMap[doc.d]['dailyCount'] = doc.c if doc.e is dailyID
|
||||
dayCountsMap[doc.d]['monthlyCount'] = doc.c if doc.e is monthlyID
|
||||
activeUsers = []
|
||||
for key, val of dayCountsMap
|
||||
data = day: key
|
||||
data.dailyCount = val.dailyCount if val.dailyCount
|
||||
data.monthlyCount = val.monthlyCount if val.monthlyCount
|
||||
activeUsers.push data
|
||||
@sendSuccess(res, activeUsers)
|
||||
|
||||
getCampaignCompletionsBySlug: (req, res) ->
|
||||
# Send back an ordered array of level per-day starts and finishes
|
||||
# Parameters:
|
||||
|
|
|
@ -166,6 +166,9 @@ module.exports = class Handler
|
|||
res.end()
|
||||
if term
|
||||
filter.filter.$text = $search: term
|
||||
else if filters.length is 1 and filters[0].filter?.index is true
|
||||
# All we are doing is an empty text search, but that doesn't hit the index, so we'll just look for the slug.
|
||||
filter.filter = slug: {$exists: true}
|
||||
args = [filter.filter]
|
||||
args.push projection if projection
|
||||
q = @modelClass.find(args...)
|
||||
|
|
|
@ -21,6 +21,7 @@ LevelSchema.index(
|
|||
'language_override': 'searchLanguage'
|
||||
'textIndexVersion': 2
|
||||
})
|
||||
|
||||
LevelSchema.index(
|
||||
{
|
||||
original: 1
|
||||
|
@ -32,6 +33,7 @@ LevelSchema.index(
|
|||
unique: true
|
||||
})
|
||||
LevelSchema.index({slug: 1}, {name: 'slug index', sparse: true, unique: true})
|
||||
LevelSchema.index({index: 1}, {name: 'index index', sparse: true}) # because we can't use the text search index with no term
|
||||
|
||||
LevelSchema.plugin(plugins.NamedPlugin)
|
||||
LevelSchema.plugin(plugins.PermissionsPlugin)
|
||||
|
|
|
@ -44,6 +44,7 @@ LevelSessionSchema.post 'init', (doc) ->
|
|||
|
||||
LevelSessionSchema.pre 'save', (next) ->
|
||||
User = require '../../users/User' # Avoid mutual inclusion cycles
|
||||
Level = require '../Level'
|
||||
@set('changed', new Date())
|
||||
|
||||
id = @get('id')
|
||||
|
@ -54,12 +55,20 @@ LevelSessionSchema.pre 'save', (next) ->
|
|||
|
||||
# Newly completed level
|
||||
if not (initd and @previousStateInfo['state.complete']) and @get('state.complete')
|
||||
User.findByIdAndUpdate userID, {$inc: 'stats.gamesCompleted': 1}, {}, (err, doc) ->
|
||||
Level.findOne({slug: levelID}).select('concepts -_id').lean().exec (err, level) ->
|
||||
log.error err if err?
|
||||
oldCopy = doc.toObject()
|
||||
oldCopy.stats = _.clone oldCopy.stats
|
||||
oldCopy.stats.gamesCompleted = oldCopy.stats.gamesCompleted - 1
|
||||
User.schema.statics.createNewEarnedAchievements doc, oldCopy
|
||||
update = $inc: {'stats.gamesCompleted': 1}
|
||||
for concept in level?.concepts ? []
|
||||
update.$inc["stats.concepts.#{concept}"] = 1
|
||||
User.findByIdAndUpdate userID, update, {}, (err, user) ->
|
||||
log.error err if err?
|
||||
oldCopy = user.toObject()
|
||||
oldCopy.stats = _.clone oldCopy.stats
|
||||
--oldCopy.stats.gamesCompleted
|
||||
oldCopy.stats.concepts ?= {}
|
||||
for concept in level?.concepts ? []
|
||||
--oldCopy.stats.concepts[concept]
|
||||
User.schema.statics.createNewEarnedAchievements user, oldCopy
|
||||
activeUserEvent = "level-completed/#{levelID}"
|
||||
|
||||
# Spent at least 30s playing this level
|
||||
|
|
|
@ -192,7 +192,14 @@ UserSchema.statics.incrementStat = (id, statName, done, inc=1) ->
|
|||
user.incrementStat statName, done, inc
|
||||
|
||||
UserSchema.methods.incrementStat = (statName, done, inc=1) ->
|
||||
@set statName, (@get(statName) or 0) + inc
|
||||
if /^concepts\./.test statName
|
||||
# Concept stats are nested a level deeper.
|
||||
concepts = @get('concepts') or {}
|
||||
concept = statName.split('.')[1]
|
||||
concepts[concept] = (concepts[concept] or 0) + inc
|
||||
@set 'concepts', concepts
|
||||
else
|
||||
@set statName, (@get(statName) or 0) + inc
|
||||
@save (err) -> done?(err)
|
||||
|
||||
UserSchema.statics.unconflictName = unconflictName = (name, done) ->
|
||||
|
|
|
@ -80,14 +80,13 @@ setupPassportMiddleware = (app) ->
|
|||
|
||||
setupCountryRedirectMiddleware = (app, country="china", countryCode="CN", languageCode="zh", serverID="tokyo") ->
|
||||
shouldRedirectToCountryServer = (req) ->
|
||||
firstLanguage = req.acceptedLanguages[0]
|
||||
speaksLanguage = firstLanguage and firstLanguage.indexOf(languageCode) isnt -1
|
||||
speaksLanguage = _.any req.acceptedLanguages, (language) -> language.indexOf languageCode isnt -1
|
||||
unless config[serverID]
|
||||
ip = req.headers['x-forwarded-for'] or req.connection.remoteAddress
|
||||
ip = ip?.split(/,? /)[0] # If there are two IP addresses, say because of CloudFlare, we just take the first.
|
||||
geo = geoip.lookup(ip)
|
||||
#if speaksLanguage or geo?.country is countryCode
|
||||
# log.info("Should we redirect to #{serverID} server? speaksLanguage: #{speaksLanguage}, firstLanguage: #{firstLanguage}, ip: #{ip}, geo: #{geo} -- so redirecting? #{geo?.country is 'CN' and speaksLanguage}")
|
||||
# log.info("Should we redirect to #{serverID} server? speaksLanguage: #{speaksLanguage}, acceptedLanguages: #{req.acceptedLanguages}, ip: #{ip}, geo: #{geo} -- so redirecting? #{geo?.country is 'CN' and speaksLanguage}")
|
||||
return geo?.country is countryCode and speaksLanguage
|
||||
else
|
||||
#log.info("We are on #{serverID} server. speaksLanguage: #{speaksLanguage}, acceptedLanguages: #{req.acceptedLanguages[0]}")
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
require('coffee-script')
|
||||
require('coffee-script/register')
|
||||
server = require('./server')
|
||||
server.startServer()
|
Loading…
Add table
Reference in a new issue