packages feed

forml (empty) → 0.1.1

raw patch · 41 files changed

+6407/−0 lines, 41 filesdep +HTTPdep +MissingHdep +ansi-terminalsetup-changed

Dependencies added: HTTP, MissingH, ansi-terminal, base, bytestring, containers, directory, file-embed, indents, interpolatedstring-perl6, jmacro, mtl, network, pandoc, parsec, process, text, transformers, urlencoded, utf8-string, wl-pprint-text

Files

+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ forml.cabal view
@@ -0,0 +1,87 @@+Name:                forml+Version:             0.1.1+Synopsis:            A statically typed, functional programming language +License:             MIT+Author:              Andrew Stein+Maintainer:          steinlink@gmail.com+Stability:           Experimental+Category:            Compiler+Build-type:          Simple+Cabal-version:       >=1.4+data-files:          +                     lib/js/jasmine-1.0.1/jasmine-html.js, +                     lib/js/jasmine-1.0.1/jasmine.css, +                     lib/js/jasmine-1.0.1/jasmine.js, +                     lib/js/coda.css, +                     lib/js/jquery.js, +                     lib/js/lang-hs.js, +                     lib/js/prettify.css, +                     lib/js/prettify.js, +                     src/forml/parsec.forml, +                     src/forml/prelude.forml, +                     src/forml/tests.forml, +                     src/forml/readme.forml, +                     src/html/footer.html, +                     src/html/header.html, +                     src/js/FormlReporter.js+homepage:            http://texodus.github.com/forml+++Executable forml+  hs-source-dirs: src/hs+  main-is: Main.hs++  Build-depends:+    base >= 4 && <= 5, +    bytestring >= 0.9.1 && <0.10,+    parsec,+    indents,+    containers,+    pandoc,+    jmacro,+    MissingH,+    interpolatedstring-perl6,+    transformers,+    mtl,+    text,+    wl-pprint-text,+    ansi-terminal,+    HTTP,+    network,+    urlencoded,+    file-embed,+    process,+    directory,+    utf8-string == 0.3.7+ +  if impl(ghc >= 6.12.0)+    ghc-options: -Wall -fwarn-tabs -funbox-strict-fields+                 -fno-warn-unused-do-bind -threaded+                 -funfolding-use-threshold=16 -fexcess-precision+                 -optc-O3 -optc-ffast-math+  else+    ghc-options: -Wall -fwarn-tabs -funbox-strict-fields+  other-modules:  +                  Forml.Javascript,+                  Forml.Javascript.Backend,+                  Forml.Javascript.Utils,+                  Forml.Optimize,+                  Forml.Parser,+                  Forml.Parser.Utils,+                  Forml.TypeCheck,+                  Forml.TypeCheck.Types,+                  Forml.Types.Axiom,+                  Forml.Types.Definition,+                  Forml.Types.Expression,+                  Forml.Types.Literal,+                  Forml.Types.Namespace,+                  Forml.Types.Pattern,+                  Forml.Types.Statement,+                  Forml.Types.Symbol,+                  Forml.Types.Type,+                  Forml.Types.TypeDefinition,+                  Forml.Closure,+                  Forml.CLI,+                  Forml.Doc,+                  Forml.Static,+                  Forml.Javascript.Test
+ lib/js/coda.css view
@@ -0,0 +1,25 @@+/* Coda scheme ported from TextMate to google prettify */++pre.prettyprint { padding: 5px; border-left: 5px solid #939393; +border-width: 0 0 0 5px !important;}+pre .nocode { background-color: none; color: #000 }+pre .str { color: #731318; } /* string */+pre .kwd { color: #8C1751;} /* keyword */+pre .com { color: #256D24; } /* comment */+pre .typ { color: #000; } /* type */+pre .lit { color: #000;} /* literal */+pre .pun { color: #000 }    /* punctuation */+pre .pln { color: #000 }    /* plaintext */+pre .tag { color: #861681;} /* html/xml tag */+pre .atn { color: #C5680C;} /* attribute name */+pre .atv { color: #221AA6;} /* attribute value */+pre .dec { color: #1F00FF; } /* decimal */++/* Specify class=linenums on a pre to get line numbering */+ol.linenums { margin-top: 0; margin-bottom: 0; +color: #333; } +/* IE indents via margin-left */+li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 {+ list-style-type: none }+/* Alternate shading for lines */+li.L1,li.L3,li.L5,li.L7,li.L9 {background: #eee;}
+ lib/js/jasmine-1.0.1/jasmine-html.js view
@@ -0,0 +1,10 @@+jasmine.TrivialReporter=function(a){this.document=a||document;this.suiteDivs={};this.logRunningSpecs=!1};jasmine.TrivialReporter.prototype.createDom=function(a,b,c){for(var d=document.createElement(a),e=2;e<arguments.length;e++){var f=arguments[e];"string"===typeof f?d.appendChild(document.createTextNode(f)):f&&d.appendChild(f)}for(var g in b)"className"==g?d[g]=b[g]:d.setAttribute(g,b[g]);return d};+jasmine.TrivialReporter.prototype.reportRunnerStarting=function(a){var b,c;this.outerDiv=this.createDom("div",{className:"jasmine_reporter"},this.createDom("div",{className:"banner"},this.createDom("div",{className:"logo"},this.createDom("a",{href:"http://pivotal.github.com/jasmine/",target:"_blank"},"Jasmine"),this.createDom("span",{className:"version"},a.env.versionString())),this.createDom("div",{className:"options"},"Show ",b=this.createDom("input",{id:"__jasmine_TrivialReporter_showPassed__",+type:"checkbox"}),this.createDom("label",{"for":"__jasmine_TrivialReporter_showPassed__"}," passed "),c=this.createDom("input",{id:"__jasmine_TrivialReporter_showSkipped__",type:"checkbox"}),this.createDom("label",{"for":"__jasmine_TrivialReporter_showSkipped__"}," skipped"))),this.runnerDiv=this.createDom("div",{className:"runner running"},this.createDom("a",{className:"run_spec",href:"?"},"run all"),this.runnerMessageSpan=this.createDom("span",{},"Running..."),this.finishedAtSpan=this.createDom("span",+{className:"finished-at"},"")));this.document.body.appendChild(this.outerDiv);for(var a=a.suites(),d=0;d<a.length;d++){var e=a[d],f=this.createDom("div",{className:"suite"},this.createDom("a",{className:"run_spec",href:"?spec="+encodeURIComponent(e.getFullName())},"run"),this.createDom("a",{className:"description",href:"?spec="+encodeURIComponent(e.getFullName())},e.description));this.suiteDivs[e.id]=f;var g=this.outerDiv;e.parentSuite&&(g=this.suiteDivs[e.parentSuite.id]);g.appendChild(f)}this.startedAt=+new Date;var h=this;b.onclick=function(){h.outerDiv.className=b.checked?h.outerDiv.className+" show-passed":h.outerDiv.className.replace(/ show-passed/,"")};c.onclick=function(){h.outerDiv.className=c.checked?h.outerDiv.className+" show-skipped":h.outerDiv.className.replace(/ show-skipped/,"")}};+jasmine.TrivialReporter.prototype.reportRunnerResults=function(a){var b=a.results(),c=0<b.failedCount?"runner failed":"runner passed";this.runnerDiv.setAttribute("class",c);this.runnerDiv.setAttribute("className",c);for(var a=a.specs(),d=c=0;d<a.length;d++)this.specFilter(a[d])&&c++;b=""+c+" spec"+(1==c?"":"s")+", "+b.failedCount+" failure"+(1==b.failedCount?"":"s");b+=" in "+((new Date).getTime()-this.startedAt.getTime())/1E3+"s";this.runnerMessageSpan.replaceChild(this.createDom("a",{className:"description",+href:"?"},b),this.runnerMessageSpan.firstChild);this.finishedAtSpan.appendChild(document.createTextNode("Finished at "+(new Date).toString()))};jasmine.TrivialReporter.prototype.reportSuiteResults=function(a){var b=a.results(),c=b.passed()?"passed":"failed";0==b.totalCount&&(c="skipped");this.suiteDivs[a.id].className+=" "+c};jasmine.TrivialReporter.prototype.reportSpecStarting=function(a){this.logRunningSpecs&&this.log(">> Jasmine Running "+a.suite.description+" "+a.description+"...")};+jasmine.TrivialReporter.prototype.reportSpecResults=function(a){var b=a.results(),c=b.passed()?"passed":"failed";b.skipped&&(c="skipped");for(var c=this.createDom("div",{className:"spec "+c},this.createDom("a",{className:"run_spec",href:"?spec="+encodeURIComponent(a.getFullName())},"run"),this.createDom("a",{className:"description",href:"?spec="+encodeURIComponent(a.getFullName()),title:a.getFullName()},a.description.split("__::__")[1])),b=b.getItems(),d=this.createDom("div",{className:"messages"}),+e=0;e<b.length;e++){var f=b[e];"log"==f.type?d.appendChild(this.createDom("div",{className:"resultMessage log"},f.toString())):"expect"==f.type&&f.passed&&!f.passed()&&(d.appendChild(this.createDom("div",{className:"resultMessage fail"},f.message)),f.trace.stack&&d.appendChild(this.createDom("div",{className:"stackTrace"},f.trace.stack)))}0<d.childNodes.length&&c.appendChild(d);this.suiteDivs[a.suite.id].appendChild(c)};+jasmine.TrivialReporter.prototype.log=function(){var a=jasmine.getGlobal().console;a&&a.log&&(a.log.apply?a.log.apply(a,arguments):a.log(arguments))};jasmine.TrivialReporter.prototype.getLocation=function(){return this.document.location};jasmine.TrivialReporter.prototype.specFilter=function(a){for(var b={},c=this.getLocation().search.substring(1).split("&"),d=0;d<c.length;d++){var e=c[d].split("=");b[decodeURIComponent(e[0])]=decodeURIComponent(e[1])}return!b.spec?!0:0==a.getFullName().indexOf(b.spec)};
+ lib/js/jasmine-1.0.1/jasmine.css view
@@ -0,0 +1,171 @@++.jasmine_reporter a:visited, .jasmine_reporter a {+  color: #303; +}++.jasmine_reporter a:hover, .jasmine_reporter a:active {+  color: blue; +}++.run_spec {+  float:right;+  padding-right: 5px;+  font-size: .8em;+  text-decoration: none;+}++.jasmine_reporter {+  margin: 0px 0px 40px 0px;+}++.banner {+  color: #303;+  padding: 5px;+}++.runner.failed {+  background-color: #fdd;+}++.runner.passed {+    background-color: #dfd;+}+++.logo {+  float: left;+  font-size: 1.1em;+  padding-left: 5px;+}++.logo .version {+  font-size: .6em;+  padding-left: 1em;+}++.runner.running {+  background-color: yellow;+}+++.options {+  text-align: right;+  font-size: .8em;+}+++++.suite {+  margin: 5px 0px 5px 5px;+  padding-left: 1em;+  padding-top: 2px;+  padding-bottom: 2px;+}++.suite .suite {+  margin: 5px 0px 5px 5px; +}++.suite.passed {+  background-color: #dfd;+}++.suite.failed {+  background-color: #fdd;+}++.spec {+  margin: 5px 0px 5px 5px;+  padding-left: 1em;+  clear: both;+}++.spec.failed, .spec.passed, .spec.skipped {+  padding-bottom: 5px;+}++.spec.failed {+  background-color: #fbb;+  border-color: red;+}++.spec.passed {+  background-color: #bfb;+  border-color: green;+}++.spec.skipped {+  background-color: #bbb;+}++.messages {+  border-left: 1px dashed gray;+  padding-left: 1em;+  padding-right: 1em;+}++.passed {+ /* background-color: #cfc; */+  display: none;+}++/*+.failed {+  background-color: #fbb;+}+*/+.skipped {+  color: #777;+  background-color: #eee;+  display: none;+}+++/*.resultMessage {*/+  /*white-space: pre;*/+/*}*/++.resultMessage span.result {+  display: block;+  line-height: 2em;+  color: black;+}++.resultMessage .mismatch {+  color: black;+}++.stackTrace {+  white-space: pre;+  font-size: .8em;+  margin-left: 10px;+  max-height: 5em;+  overflow: auto;+  border: 1px inset red;+  padding: 1em;+  background: #eef;+}++.finished-at {+  padding-left: 1em;+  font-size: .6em;+}++.show-passed .passed,+.show-skipped .skipped {+  display: block;+}+++#jasmine_content {+  position:fixed;+  right: 100%;+}++.runner {+  display: block;+  margin: 5px 0px -5px 5px;+  padding: 2px 0 2px 10px;+}+
+ lib/js/jasmine-1.0.1/jasmine.js view
@@ -0,0 +1,77 @@+var jasmine={unimplementedMethod_:function(){throw Error("unimplemented method");}};jasmine.undefined=jasmine.___undefined___;jasmine.DEFAULT_UPDATE_INTERVAL=250;jasmine.DEFAULT_TIMEOUT_INTERVAL=5E3;jasmine.getGlobal=function(){return function(){return this}()};jasmine.bindOriginal_=function(a,b){var c=a[b];return c.apply?function(){return c.apply(a,arguments)}:jasmine.getGlobal()[b]};jasmine.setTimeout=jasmine.bindOriginal_(jasmine.getGlobal(),"setTimeout");+jasmine.clearTimeout=jasmine.bindOriginal_(jasmine.getGlobal(),"clearTimeout");jasmine.setInterval=jasmine.bindOriginal_(jasmine.getGlobal(),"setInterval");jasmine.clearInterval=jasmine.bindOriginal_(jasmine.getGlobal(),"clearInterval");jasmine.MessageResult=function(a){this.type="log";this.values=a;this.trace=Error()};+jasmine.MessageResult.prototype.toString=function(){for(var a="",b=0;b<this.values.length;b++)0<b&&(a+=" "),a=jasmine.isString_(this.values[b])?a+this.values[b]:a+jasmine.pp(this.values[b]);return a};jasmine.ExpectationResult=function(a){this.type="expect";this.matcherName=a.matcherName;this.passed_=a.passed;this.expected=a.expected;this.actual=a.actual;this.message=this.passed_?"Passed.":a.message;this.trace=this.passed_?"":Error(this.message)};jasmine.ExpectationResult.prototype.toString=function(){return this.message};+jasmine.ExpectationResult.prototype.passed=function(){return this.passed_};jasmine.getEnv=function(){return jasmine.currentEnv_=jasmine.currentEnv_||new jasmine.Env};jasmine.isArray_=function(a){return jasmine.isA_("Array",a)};jasmine.isString_=function(a){return jasmine.isA_("String",a)};jasmine.isNumber_=function(a){return jasmine.isA_("Number",a)};jasmine.isA_=function(a,b){return Object.prototype.toString.apply(b)==="[object "+a+"]"};+jasmine.pp=function(a){var b=new jasmine.StringPrettyPrinter;b.format(a);return b.string};jasmine.isDomNode=function(a){return 0<a.nodeType};jasmine.any=function(a){return new jasmine.Matchers.Any(a)};jasmine.Spy=function(a){this.identity=a||"unknown";this.isSpy=!0;this.plan=function(){};this.mostRecentCall={};this.argsForCall=[];this.calls=[]};jasmine.Spy.prototype.andCallThrough=function(){this.plan=this.originalValue;return this};+jasmine.Spy.prototype.andReturn=function(a){this.plan=function(){return a};return this};jasmine.Spy.prototype.andThrow=function(a){this.plan=function(){throw a;};return this};jasmine.Spy.prototype.andCallFake=function(a){this.plan=a;return this};jasmine.Spy.prototype.reset=function(){this.wasCalled=!1;this.callCount=0;this.argsForCall=[];this.calls=[];this.mostRecentCall={}};+jasmine.createSpy=function(a){var b=function(){b.wasCalled=!0;b.callCount++;var a=jasmine.util.argsToArray(arguments);b.mostRecentCall.object=this;b.mostRecentCall.args=a;b.argsForCall.push(a);b.calls.push({object:this,args:a});return b.plan.apply(this,arguments)},a=new jasmine.Spy(a),c;for(c in a)b[c]=a[c];b.reset();return b};jasmine.isSpy=function(a){return a&&a.isSpy};+jasmine.createSpyObj=function(a,b){if(!jasmine.isArray_(b)||0==b.length)throw Error("createSpyObj requires a non-empty array of method names to create spies for");for(var c={},d=0;d<b.length;d++)c[b[d]]=jasmine.createSpy(a+"."+b[d]);return c};jasmine.log=function(){var a=jasmine.getEnv().currentSpec;a.log.apply(a,arguments)};+var spyOn=function(a,b){return jasmine.getEnv().currentSpec.spyOn(a,b)},it=function(a,b){return jasmine.getEnv().it(a,b)},xit=function(a,b){return jasmine.getEnv().xit(a,b)},expect=function(a){return jasmine.getEnv().currentSpec.expect(a)},runs=function(a){jasmine.getEnv().currentSpec.runs(a)},waits=function(a){jasmine.getEnv().currentSpec.waits(a)},waitsFor=function(a,b,c){jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec,arguments)},beforeEach=function(a){jasmine.getEnv().beforeEach(a)},+afterEach=function(a){jasmine.getEnv().afterEach(a)},describe=function(a,b){return jasmine.getEnv().describe(a,b)},xdescribe=function(a,b){return jasmine.getEnv().xdescribe(a,b)};+jasmine.XmlHttpRequest="undefined"==typeof XMLHttpRequest?function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(b){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(c){}try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(d){}throw Error("This browser does not support XMLHttpRequest.");}:XMLHttpRequest;jasmine.util={};jasmine.util.inherit=function(a,b){var c=function(){};c.prototype=b.prototype;a.prototype=new c};+jasmine.util.formatException=function(a){var b;a.line?b=a.line:a.lineNumber&&(b=a.lineNumber);var c;a.sourceURL?c=a.sourceURL:a.fileName&&(c=a.fileName);a=a.name&&a.message?a.name+": "+a.message:a.toString();c&&b&&(a+=" in "+c+" (line "+b+")");return a};jasmine.util.htmlEscape=function(a){return!a?a:a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};jasmine.util.argsToArray=function(a){for(var b=[],c=0;c<a.length;c++)b.push(a[c]);return b};+jasmine.util.extend=function(a,b){for(var c in b)a[c]=b[c];return a};+jasmine.Env=function(){this.currentSuite=this.currentSpec=null;this.currentRunner_=new jasmine.Runner(this);this.reporter=new jasmine.MultiReporter;this.updateInterval=jasmine.DEFAULT_UPDATE_INTERVAL;this.defaultTimeoutInterval=jasmine.DEFAULT_TIMEOUT_INTERVAL;this.lastUpdate=0;this.specFilter=function(){return!0};this.nextSuiteId_=this.nextSpecId_=0;this.equalityTesters_=[];this.matchersClass=function(){jasmine.Matchers.apply(this,arguments)};jasmine.util.inherit(this.matchersClass,jasmine.Matchers);+jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype,this.matchersClass)};jasmine.Env.prototype.setTimeout=jasmine.setTimeout;jasmine.Env.prototype.clearTimeout=jasmine.clearTimeout;jasmine.Env.prototype.setInterval=jasmine.setInterval;jasmine.Env.prototype.clearInterval=jasmine.clearInterval;jasmine.Env.prototype.version=function(){if(jasmine.version_)return jasmine.version_;throw Error("Version not set");};+jasmine.Env.prototype.versionString=function(){if(jasmine.version_){var a=this.version();return a.major+"."+a.minor+"."+a.build+" revision "+a.revision}return"version unknown"};jasmine.Env.prototype.nextSpecId=function(){return this.nextSpecId_++};jasmine.Env.prototype.nextSuiteId=function(){return this.nextSuiteId_++};jasmine.Env.prototype.addReporter=function(a){this.reporter.addReporter(a)};jasmine.Env.prototype.execute=function(){this.currentRunner_.execute()};+jasmine.Env.prototype.describe=function(a,b){var c=new jasmine.Suite(this,a,b,this.currentSuite),d=this.currentSuite;d?d.add(c):this.currentRunner_.add(c);this.currentSuite=c;var e=null;try{b.call(c)}catch(f){e=f}this.currentSuite=d;e&&this.it("encountered a declaration exception",function(){throw e;});return c};jasmine.Env.prototype.beforeEach=function(a){this.currentSuite?this.currentSuite.beforeEach(a):this.currentRunner_.beforeEach(a)};jasmine.Env.prototype.currentRunner=function(){return this.currentRunner_};+jasmine.Env.prototype.afterEach=function(a){this.currentSuite?this.currentSuite.afterEach(a):this.currentRunner_.afterEach(a)};jasmine.Env.prototype.xdescribe=function(){return{execute:function(){}}};jasmine.Env.prototype.it=function(a,b){var c=new jasmine.Spec(this,this.currentSuite,a);this.currentSuite.add(c);this.currentSpec=c;b&&c.runs(b);return c};jasmine.Env.prototype.xit=function(){return{id:this.nextSpecId(),runs:function(){}}};+jasmine.Env.prototype.compareObjects_=function(a,b,c,d){if(a.__Jasmine_been_here_before__===b&&b.__Jasmine_been_here_before__===a)return!0;a.__Jasmine_been_here_before__=b;b.__Jasmine_been_here_before__=a;var e=function(a,b){return null!=a&&a[b]!==jasmine.undefined},f;for(f in b)!e(a,f)&&e(b,f)&&c.push("expected has key '"+f+"', but missing from actual.");for(f in a)!e(b,f)&&e(a,f)&&c.push("expected missing key '"+f+"', but present in actual.");for(f in b)"__Jasmine_been_here_before__"!=f&&(this.equals_(a[f],+b[f],c,d)||d.push("'"+f+"' was '"+(b[f]?jasmine.util.htmlEscape(b[f].toString()):b[f])+"' in expected, but was '"+(a[f]?jasmine.util.htmlEscape(a[f].toString()):a[f])+"' in actual."));jasmine.isArray_(a)&&(jasmine.isArray_(b)&&a.length!=b.length)&&d.push("arrays were not the same length");delete a.__Jasmine_been_here_before__;delete b.__Jasmine_been_here_before__;return 0==c.length&&0==d.length};+jasmine.Env.prototype.equals_=function(a,b,c,d){for(var c=c||[],d=d||[],e=0;e<this.equalityTesters_.length;e++){var f=(0,this.equalityTesters_[e])(a,b,this,c,d);if(f!==jasmine.undefined)return f}return a===b?!0:a===jasmine.undefined||null===a||b===jasmine.undefined||null===b?a==jasmine.undefined&&b==jasmine.undefined:jasmine.isDomNode(a)&&jasmine.isDomNode(b)?a===b:a instanceof Date&&b instanceof Date?a.getTime()==b.getTime():a instanceof jasmine.Matchers.Any?a.matches(b):b instanceof jasmine.Matchers.Any?+b.matches(a):jasmine.isString_(a)&&jasmine.isString_(b)||jasmine.isNumber_(a)&&jasmine.isNumber_(b)?a==b:"object"===typeof a&&"object"===typeof b?this.compareObjects_(a,b,c,d):a===b};jasmine.Env.prototype.contains_=function(a,b){if(jasmine.isArray_(a)){for(var c=0;c<a.length;c++)if(this.equals_(a[c],b))return!0;return!1}return 0<=a.indexOf(b)};jasmine.Env.prototype.addEqualityTester=function(a){this.equalityTesters_.push(a)};jasmine.Reporter=function(){};+jasmine.Reporter.prototype.reportRunnerStarting=function(){};jasmine.Reporter.prototype.reportRunnerResults=function(){};jasmine.Reporter.prototype.reportSuiteResults=function(){};jasmine.Reporter.prototype.reportSpecStarting=function(){};jasmine.Reporter.prototype.reportSpecResults=function(){};jasmine.Reporter.prototype.log=function(){};jasmine.Block=function(a,b,c){this.env=a;this.func=b;this.spec=c};jasmine.Block.prototype.execute=function(a){try{this.func.apply(this.spec)}catch(b){this.spec.fail(b)}a()};+jasmine.JsApiReporter=function(){this.finished=this.started=!1;this.suites_=[];this.results_={}};jasmine.JsApiReporter.prototype.reportRunnerStarting=function(a){this.started=!0;for(var a=a.topLevelSuites(),b=0;b<a.length;b++)this.suites_.push(this.summarize_(a[b]))};jasmine.JsApiReporter.prototype.suites=function(){return this.suites_};+jasmine.JsApiReporter.prototype.summarize_=function(a){var b=a instanceof jasmine.Suite,c={id:a.id,name:a.description,type:b?"suite":"spec",children:[]};if(b){a=a.children();for(b=0;b<a.length;b++)c.children.push(this.summarize_(a[b]))}return c};jasmine.JsApiReporter.prototype.results=function(){return this.results_};jasmine.JsApiReporter.prototype.resultsForSpec=function(a){return this.results_[a]};jasmine.JsApiReporter.prototype.reportRunnerResults=function(){this.finished=!0};+jasmine.JsApiReporter.prototype.reportSuiteResults=function(){};jasmine.JsApiReporter.prototype.reportSpecResults=function(a){this.results_[a.id]={messages:a.results().getItems(),result:0<a.results().failedCount?"failed":"passed"}};jasmine.JsApiReporter.prototype.log=function(){};jasmine.JsApiReporter.prototype.resultsForSpecs=function(a){for(var b={},c=0;c<a.length;c++){var d=a[c];b[d]=this.summarizeResult_(this.results_[d])}return b};+jasmine.JsApiReporter.prototype.summarizeResult_=function(a){for(var b=[],c=a.messages.length,d=0;d<c;d++){var e=a.messages[d];b.push({text:"log"==e.type?e.toString():jasmine.undefined,passed:e.passed?e.passed():!0,type:e.type,message:e.message,trace:{stack:e.passed&&!e.passed()?e.trace.stack:jasmine.undefined}})}return{result:a.result,messages:b}};jasmine.Matchers=function(a,b,c,d){this.env=a;this.actual=b;this.spec=c;this.isNot=d||!1;this.reportWasCalled_=!1};+jasmine.Matchers.pp=function(){throw Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");};jasmine.Matchers.prototype.report=function(){throw Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");};jasmine.Matchers.wrapInto_=function(a,b){for(var c in a)"report"!=c&&(b.prototype[c]=jasmine.Matchers.matcherFn_(c,a[c]))};+jasmine.Matchers.matcherFn_=function(a,b){return function(){var c=jasmine.util.argsToArray(arguments),d=b.apply(this,arguments);this.isNot&&(d=!d);if(this.reportWasCalled_)return d;var e;if(!d)if(this.message)e=this.message.apply(this,arguments),jasmine.isArray_(e)&&(e=e[this.isNot?1:0]);else{e=a.replace(/[A-Z]/g,function(a){return" "+a.toLowerCase()});e="Expected "+jasmine.pp(this.actual)+(this.isNot?" not ":" ")+e;if(0<c.length)for(var f=0;f<c.length;f++)0<f&&(e+=","),e+=" "+jasmine.pp(c[f]);e+=+"."}this.spec.addMatcherResult(new jasmine.ExpectationResult({matcherName:a,passed:d,expected:1<c.length?c:c[0],actual:this.actual,message:e}));return jasmine.undefined}};jasmine.Matchers.prototype.toBe=function(a){return this.actual===a};jasmine.Matchers.prototype.toNotBe=function(a){return this.actual!==a};jasmine.Matchers.prototype.toEqual=function(a){return this.env.equals_(this.actual,a)};jasmine.Matchers.prototype.toNotEqual=function(a){return!this.env.equals_(this.actual,a)};+jasmine.Matchers.prototype.toMatch=function(a){return RegExp(a).test(this.actual)};jasmine.Matchers.prototype.toNotMatch=function(a){return!RegExp(a).test(this.actual)};jasmine.Matchers.prototype.toBeDefined=function(){return this.actual!==jasmine.undefined};jasmine.Matchers.prototype.toBeUndefined=function(){return this.actual===jasmine.undefined};jasmine.Matchers.prototype.toBeNull=function(){return null===this.actual};jasmine.Matchers.prototype.toBeTruthy=function(){return!!this.actual};+jasmine.Matchers.prototype.toBeFalsy=function(){return!this.actual};jasmine.Matchers.prototype.toHaveBeenCalled=function(){if(0<arguments.length)throw Error("toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith");if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return["Expected spy "+this.actual.identity+" to have been called.","Expected spy "+this.actual.identity+" not to have been called."]};return this.actual.wasCalled};+jasmine.Matchers.prototype.wasCalled=jasmine.Matchers.prototype.toHaveBeenCalled;jasmine.Matchers.prototype.wasNotCalled=function(){if(0<arguments.length)throw Error("wasNotCalled does not take arguments");if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return["Expected spy "+this.actual.identity+" to not have been called.","Expected spy "+this.actual.identity+" to have been called."]};return!this.actual.wasCalled};+jasmine.Matchers.prototype.toHaveBeenCalledWith=function(){var a=jasmine.util.argsToArray(arguments);if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return 0==this.actual.callCount?["Expected spy to have been called with "+jasmine.pp(a)+" but it was never called.","Expected spy not to have been called with "+jasmine.pp(a)+" but it was."]:["Expected spy to have been called with "+jasmine.pp(a)+" but was called with "+jasmine.pp(this.actual.argsForCall),+"Expected spy not to have been called with "+jasmine.pp(a)+" but was called with "+jasmine.pp(this.actual.argsForCall)]};return this.env.contains_(this.actual.argsForCall,a)};jasmine.Matchers.prototype.wasCalledWith=jasmine.Matchers.prototype.toHaveBeenCalledWith;+jasmine.Matchers.prototype.wasNotCalledWith=function(){var a=jasmine.util.argsToArray(arguments);if(!jasmine.isSpy(this.actual))throw Error("Expected a spy, but got "+jasmine.pp(this.actual)+".");this.message=function(){return["Expected spy not to have been called with "+jasmine.pp(a)+" but it was","Expected spy to have been called with "+jasmine.pp(a)+" but it was"]};return!this.env.contains_(this.actual.argsForCall,a)};+jasmine.Matchers.prototype.toContain=function(a){return this.env.contains_(this.actual,a)};jasmine.Matchers.prototype.toNotContain=function(a){return!this.env.contains_(this.actual,a)};jasmine.Matchers.prototype.toBeLessThan=function(a){return this.actual<a};jasmine.Matchers.prototype.toBeGreaterThan=function(a){return this.actual>a};+jasmine.Matchers.prototype.toThrow=function(a){var b=!1,c;if("function"!=typeof this.actual)throw Error("Actual is not a function");try{this.actual()}catch(d){c=d}c&&(b=a===jasmine.undefined||this.env.equals_(c.message||c,a.message||a));var e=this.isNot?"not ":"";this.message=function(){return c&&(a===jasmine.undefined||!this.env.equals_(c.message||c,a.message||a))?["Expected function "+e+"to throw",a?a.message||a:" an exception",", but it threw",c.message||c].join(" "):"Expected function to throw an exception."};+return b};jasmine.Matchers.Any=function(a){this.expectedClass=a};jasmine.Matchers.Any.prototype.matches=function(a){return this.expectedClass==String?"string"==typeof a||a instanceof String:this.expectedClass==Number?"number"==typeof a||a instanceof Number:this.expectedClass==Function?"function"==typeof a||a instanceof Function:this.expectedClass==Object?"object"==typeof a:a instanceof this.expectedClass};+jasmine.Matchers.Any.prototype.toString=function(){return"<jasmine.any("+this.expectedClass+")>"};jasmine.MultiReporter=function(){this.subReporters_=[]};jasmine.util.inherit(jasmine.MultiReporter,jasmine.Reporter);jasmine.MultiReporter.prototype.addReporter=function(a){this.subReporters_.push(a)};+(function(){for(var a="reportRunnerStarting reportRunnerResults reportSuiteResults reportSpecStarting reportSpecResults log".split(" "),b=0;b<a.length;b++){var c=a[b];jasmine.MultiReporter.prototype[c]=function(a){return function(){for(var b=0;b<this.subReporters_.length;b++){var c=this.subReporters_[b];c[a]&&c[a].apply(c,arguments)}}}(c)}})();jasmine.NestedResults=function(){this.failedCount=this.passedCount=this.totalCount=0;this.skipped=!1;this.items_=[]};+jasmine.NestedResults.prototype.rollupCounts=function(a){this.totalCount+=a.totalCount;this.passedCount+=a.passedCount;this.failedCount+=a.failedCount};jasmine.NestedResults.prototype.log=function(a){this.items_.push(new jasmine.MessageResult(a))};jasmine.NestedResults.prototype.getItems=function(){return this.items_};jasmine.NestedResults.prototype.addResult=function(a){"log"!=a.type&&(a.items_?this.rollupCounts(a):(this.totalCount++,a.passed()?this.passedCount++:this.failedCount++));this.items_.push(a)};+jasmine.NestedResults.prototype.passed=function(){return this.passedCount===this.totalCount};jasmine.PrettyPrinter=function(){this.ppNestLevel_=0};+jasmine.PrettyPrinter.prototype.format=function(a){if(40<this.ppNestLevel_)throw Error("jasmine.PrettyPrinter: format() nested too deeply!");this.ppNestLevel_++;try{a===jasmine.undefined?this.emitScalar("undefined"):null===a?this.emitScalar("null"):a===jasmine.getGlobal()?this.emitScalar("<global>"):a instanceof jasmine.Matchers.Any?this.emitScalar(a.toString()):"string"===typeof a?this.emitString(a):jasmine.isSpy(a)?this.emitScalar("spy on "+a.identity):a instanceof RegExp?this.emitScalar(a.toString()):+"function"===typeof a?this.emitScalar("Function"):"number"===typeof a.nodeType?this.emitScalar("HTMLNode"):a instanceof Date?this.emitScalar("Date("+a+")"):a.__Jasmine_been_here_before__?this.emitScalar("<circular reference: "+(jasmine.isArray_(a)?"Array":"Object")+">"):jasmine.isArray_(a)||"object"==typeof a?(a.__Jasmine_been_here_before__=!0,jasmine.isArray_(a)?this.emitArray(a):this.emitObject(a),delete a.__Jasmine_been_here_before__):this.emitScalar(a.toString())}finally{this.ppNestLevel_--}};+jasmine.PrettyPrinter.prototype.iterateObject=function(a,b){for(var c in a)"__Jasmine_been_here_before__"!=c&&b(c,a.__lookupGetter__?null!=a.__lookupGetter__(c):!1)};jasmine.PrettyPrinter.prototype.emitArray=jasmine.unimplementedMethod_;jasmine.PrettyPrinter.prototype.emitObject=jasmine.unimplementedMethod_;jasmine.PrettyPrinter.prototype.emitScalar=jasmine.unimplementedMethod_;jasmine.PrettyPrinter.prototype.emitString=jasmine.unimplementedMethod_;+jasmine.StringPrettyPrinter=function(){jasmine.PrettyPrinter.call(this);this.string=""};jasmine.util.inherit(jasmine.StringPrettyPrinter,jasmine.PrettyPrinter);jasmine.StringPrettyPrinter.prototype.emitScalar=function(a){this.append(a)};jasmine.StringPrettyPrinter.prototype.emitString=function(a){this.append("'"+a+"'")};jasmine.StringPrettyPrinter.prototype.emitArray=function(a){this.append("[ ");for(var b=0;b<a.length;b++)0<b&&this.append(", "),this.format(a[b]);this.append(" ]")};+jasmine.StringPrettyPrinter.prototype.emitObject=function(a){var b=this;this.append("{ ");var c=!0;this.iterateObject(a,function(d,e){c?c=!1:b.append(", ");b.append(d);b.append(" : ");e?b.append("<getter>"):b.format(a[d])});this.append(" }")};jasmine.StringPrettyPrinter.prototype.append=function(a){this.string+=a};jasmine.Queue=function(a){this.env=a;this.blocks=[];this.running=!1;this.offset=this.index=0;this.abort=!1};jasmine.Queue.prototype.addBefore=function(a){this.blocks.unshift(a)};+jasmine.Queue.prototype.add=function(a){this.blocks.push(a)};jasmine.Queue.prototype.insertNext=function(a){this.blocks.splice(this.index+this.offset+1,0,a);this.offset++};jasmine.Queue.prototype.start=function(a){this.running=!0;this.onComplete=a;this.next_()};jasmine.Queue.prototype.isRunning=function(){return this.running};jasmine.Queue.LOOP_DONT_RECURSE=!0;+jasmine.Queue.prototype.next_=function(){for(var a=this,b=!0;b;)if(b=!1,a.index<a.blocks.length&&!this.abort){var c=!0,d=!1,e=function(){if(jasmine.Queue.LOOP_DONT_RECURSE&&c)d=!0;else{a.blocks[a.index].abort&&(a.abort=!0);a.offset=0;a.index++;var e=(new Date).getTime();a.env.updateInterval&&e-a.env.lastUpdate>a.env.updateInterval?(a.env.lastUpdate=e,a.env.setTimeout(function(){a.next_()},0)):jasmine.Queue.LOOP_DONT_RECURSE&&d?b=!0:a.next_()}};a.blocks[a.index].execute(e);c=!1;d&&e()}else if(a.running=+!1,a.onComplete)a.onComplete()};jasmine.Queue.prototype.results=function(){for(var a=new jasmine.NestedResults,b=0;b<this.blocks.length;b++)this.blocks[b].results&&a.addResult(this.blocks[b].results());return a};jasmine.Runner=function(a){this.env=a;this.queue=new jasmine.Queue(a);this.before_=[];this.after_=[];this.suites_=[]};jasmine.Runner.prototype.execute=function(){var a=this;a.env.reporter.reportRunnerStarting&&a.env.reporter.reportRunnerStarting(this);a.queue.start(function(){a.finishCallback()})};+jasmine.Runner.prototype.beforeEach=function(a){a.typeName="beforeEach";this.before_.splice(0,0,a)};jasmine.Runner.prototype.afterEach=function(a){a.typeName="afterEach";this.after_.splice(0,0,a)};jasmine.Runner.prototype.finishCallback=function(){this.env.reporter.reportRunnerResults(this)};jasmine.Runner.prototype.addSuite=function(a){this.suites_.push(a)};jasmine.Runner.prototype.add=function(a){a instanceof jasmine.Suite&&this.addSuite(a);this.queue.add(a)};+jasmine.Runner.prototype.specs=function(){for(var a=this.suites(),b=[],c=0;c<a.length;c++)b=b.concat(a[c].specs());return b};jasmine.Runner.prototype.suites=function(){return this.suites_};jasmine.Runner.prototype.topLevelSuites=function(){for(var a=[],b=0;b<this.suites_.length;b++)this.suites_[b].parentSuite||a.push(this.suites_[b]);return a};jasmine.Runner.prototype.results=function(){return this.queue.results()};+jasmine.Spec=function(a,b,c){if(!a)throw Error("jasmine.Env() required");if(!b)throw Error("jasmine.Suite() required");this.id=a.nextSpecId?a.nextSpecId():null;this.env=a;this.suite=b;this.description=c;this.queue=new jasmine.Queue(a);this.afterCallbacks=[];this.spies_=[];this.results_=new jasmine.NestedResults;this.results_.description=c;this.matchersClass=null};jasmine.Spec.prototype.getFullName=function(){return this.suite.getFullName()+" "+this.description+"."};+jasmine.Spec.prototype.results=function(){return this.results_};jasmine.Spec.prototype.log=function(){return this.results_.log(arguments)};jasmine.Spec.prototype.runs=function(a){this.addToQueue(new jasmine.Block(this.env,a,this));return this};jasmine.Spec.prototype.addToQueue=function(a){this.queue.isRunning()?this.queue.insertNext(a):this.queue.add(a)};jasmine.Spec.prototype.addMatcherResult=function(a){this.results_.addResult(a)};+jasmine.Spec.prototype.expect=function(a){var b=new (this.getMatchersClass_())(this.env,a,this);b.not=new (this.getMatchersClass_())(this.env,a,this,!0);return b};jasmine.Spec.prototype.waits=function(a){this.addToQueue(new jasmine.WaitsBlock(this.env,a,this));return this};+jasmine.Spec.prototype.waitsFor=function(a,b,c){for(var d=null,e=null,f=null,g=0;g<arguments.length;g++){var h=arguments[g];switch(typeof h){case "function":d=h;break;case "string":e=h;break;case "number":f=h}}this.addToQueue(new jasmine.WaitsForBlock(this.env,f,d,e,this));return this};jasmine.Spec.prototype.fail=function(a){this.results_.addResult(new jasmine.ExpectationResult({passed:!1,message:a?jasmine.util.formatException(a):"Exception"}))};+jasmine.Spec.prototype.getMatchersClass_=function(){return this.matchersClass||this.env.matchersClass};jasmine.Spec.prototype.addMatchers=function(a){var b=this.getMatchersClass_(),c=function(){b.apply(this,arguments)};jasmine.util.inherit(c,b);jasmine.Matchers.wrapInto_(a,c);this.matchersClass=c};jasmine.Spec.prototype.finishCallback=function(){this.env.reporter.reportSpecResults(this)};jasmine.Spec.prototype.finish=function(a){this.removeAllSpies();this.finishCallback();a&&a()};+jasmine.Spec.prototype.after=function(a){this.queue.isRunning()?this.queue.add(new jasmine.Block(this.env,a,this)):this.afterCallbacks.unshift(a)};jasmine.Spec.prototype.execute=function(a){var b=this;b.env.specFilter(b)?(this.env.reporter.reportSpecStarting(this),b.env.currentSpec=b,b.addBeforesAndAftersToQueue(),b.queue.start(function(){b.finish(a)})):(b.results_.skipped=!0,b.finish(a))};+jasmine.Spec.prototype.addBeforesAndAftersToQueue=function(){for(var a=this.env.currentRunner(),b,c=this.suite;c;c=c.parentSuite)for(b=0;b<c.before_.length;b++)this.queue.addBefore(new jasmine.Block(this.env,c.before_[b],this));for(b=0;b<a.before_.length;b++)this.queue.addBefore(new jasmine.Block(this.env,a.before_[b],this));for(b=0;b<this.afterCallbacks.length;b++)this.queue.add(new jasmine.Block(this.env,this.afterCallbacks[b],this));for(c=this.suite;c;c=c.parentSuite)for(b=0;b<c.after_.length;b++)this.queue.add(new jasmine.Block(this.env,+c.after_[b],this));for(b=0;b<a.after_.length;b++)this.queue.add(new jasmine.Block(this.env,a.after_[b],this))};jasmine.Spec.prototype.explodes=function(){throw"explodes function should not have been called";};+jasmine.Spec.prototype.spyOn=function(a,b,c){if(a==jasmine.undefined)throw"spyOn could not find an object to spy upon for "+b+"()";if(!c&&a[b]===jasmine.undefined)throw b+"() method does not exist";if(!c&&a[b]&&a[b].isSpy)throw Error(b+" has already been spied upon");c=jasmine.createSpy(b);this.spies_.push(c);c.baseObj=a;c.methodName=b;c.originalValue=a[b];return a[b]=c};+jasmine.Spec.prototype.removeAllSpies=function(){for(var a=0;a<this.spies_.length;a++){var b=this.spies_[a];b.baseObj[b.methodName]=b.originalValue}this.spies_=[]};jasmine.Suite=function(a,b,c,d){this.id=a.nextSuiteId?a.nextSuiteId():null;this.description=b;this.queue=new jasmine.Queue(a);this.parentSuite=d;this.env=a;this.before_=[];this.after_=[];this.children_=[];this.suites_=[];this.specs_=[]};+jasmine.Suite.prototype.getFullName=function(){for(var a=this.description,b=this.parentSuite;b;b=b.parentSuite)a=b.description+" "+a;return a};jasmine.Suite.prototype.finish=function(a){this.env.reporter.reportSuiteResults(this);this.finished=!0;"function"==typeof a&&a()};jasmine.Suite.prototype.beforeEach=function(a){a.typeName="beforeEach";this.before_.unshift(a)};jasmine.Suite.prototype.afterEach=function(a){a.typeName="afterEach";this.after_.unshift(a)};jasmine.Suite.prototype.results=function(){return this.queue.results()};+jasmine.Suite.prototype.add=function(a){this.children_.push(a);a instanceof jasmine.Suite?(this.suites_.push(a),this.env.currentRunner().addSuite(a)):this.specs_.push(a);this.queue.add(a)};jasmine.Suite.prototype.specs=function(){return this.specs_};jasmine.Suite.prototype.suites=function(){return this.suites_};jasmine.Suite.prototype.children=function(){return this.children_};jasmine.Suite.prototype.execute=function(a){var b=this;this.queue.start(function(){b.finish(a)})};+jasmine.WaitsBlock=function(a,b,c){this.timeout=b;jasmine.Block.call(this,a,null,c)};jasmine.util.inherit(jasmine.WaitsBlock,jasmine.Block);jasmine.WaitsBlock.prototype.execute=function(a){this.env.reporter.log(">> Jasmine waiting for "+this.timeout+" ms...");this.env.setTimeout(function(){a()},this.timeout)};jasmine.WaitsForBlock=function(a,b,c,d,e){this.timeout=b||a.defaultTimeoutInterval;this.latchFunction=c;this.message=d;this.totalTimeSpentWaitingForLatch=0;jasmine.Block.call(this,a,null,e)};+jasmine.util.inherit(jasmine.WaitsForBlock,jasmine.Block);jasmine.WaitsForBlock.TIMEOUT_INCREMENT=10;+jasmine.WaitsForBlock.prototype.execute=function(a){this.env.reporter.log(">> Jasmine waiting for "+(this.message||"something to happen"));var b;try{b=this.latchFunction.apply(this.spec)}catch(c){this.spec.fail(c);a();return}if(b)a();else if(this.totalTimeSpentWaitingForLatch>=this.timeout)this.spec.fail({name:"timeout",message:"timed out after "+this.timeout+" msec waiting for "+(this.message||"something to happen")}),this.abort=!0,a();else{this.totalTimeSpentWaitingForLatch+=jasmine.WaitsForBlock.TIMEOUT_INCREMENT;+var d=this;this.env.setTimeout(function(){d.execute(a)},jasmine.WaitsForBlock.TIMEOUT_INCREMENT)}};jasmine.FakeTimer=function(){this.reset();var a=this;a.setTimeout=function(b,c){a.timeoutsMade++;a.scheduleFunction(a.timeoutsMade,b,c,!1);return a.timeoutsMade};a.setInterval=function(b,c){a.timeoutsMade++;a.scheduleFunction(a.timeoutsMade,b,c,!0);return a.timeoutsMade};a.clearTimeout=function(b){a.scheduledFunctions[b]=jasmine.undefined};a.clearInterval=function(b){a.scheduledFunctions[b]=jasmine.undefined}};+jasmine.FakeTimer.prototype.reset=function(){this.timeoutsMade=0;this.scheduledFunctions={};this.nowMillis=0};jasmine.FakeTimer.prototype.tick=function(a){var b=this.nowMillis,a=b+a;this.runFunctionsWithinRange(b,a);this.nowMillis=a};+jasmine.FakeTimer.prototype.runFunctionsWithinRange=function(a,b){var c,d=[],e;for(e in this.scheduledFunctions)c=this.scheduledFunctions[e],c!=jasmine.undefined&&(c.runAtMillis>=a&&c.runAtMillis<=b)&&(d.push(c),this.scheduledFunctions[e]=jasmine.undefined);if(0<d.length){d.sort(function(a,b){return a.runAtMillis-b.runAtMillis});for(c=0;c<d.length;++c)try{var f=d[c];this.nowMillis=f.runAtMillis;f.funcToCall();f.recurring&&this.scheduleFunction(f.timeoutKey,f.funcToCall,f.millis,!0)}catch(g){}this.runFunctionsWithinRange(a,+b)}};jasmine.FakeTimer.prototype.scheduleFunction=function(a,b,c,d){this.scheduledFunctions[a]={runAtMillis:this.nowMillis+c,funcToCall:b,recurring:d,timeoutKey:a,millis:c}};+jasmine.Clock={defaultFakeTimer:new jasmine.FakeTimer,reset:function(){jasmine.Clock.assertInstalled();jasmine.Clock.defaultFakeTimer.reset()},tick:function(a){jasmine.Clock.assertInstalled();jasmine.Clock.defaultFakeTimer.tick(a)},runFunctionsWithinRange:function(a,b){jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(a,b)},scheduleFunction:function(a,b,c,d){jasmine.Clock.defaultFakeTimer.scheduleFunction(a,b,c,d)},useMock:function(){jasmine.Clock.isInstalled()||(jasmine.getEnv().currentSpec.after(jasmine.Clock.uninstallMock),+jasmine.Clock.installMock())},installMock:function(){jasmine.Clock.installed=jasmine.Clock.defaultFakeTimer},uninstallMock:function(){jasmine.Clock.assertInstalled();jasmine.Clock.installed=jasmine.Clock.real},real:{setTimeout:jasmine.getGlobal().setTimeout,clearTimeout:jasmine.getGlobal().clearTimeout,setInterval:jasmine.getGlobal().setInterval,clearInterval:jasmine.getGlobal().clearInterval},assertInstalled:function(){if(!jasmine.Clock.isInstalled())throw Error("Mock clock is not installed, use jasmine.Clock.useMock()");+},isInstalled:function(){return jasmine.Clock.installed==jasmine.Clock.defaultFakeTimer},installed:null};jasmine.Clock.installed=jasmine.Clock.real;jasmine.getGlobal().setTimeout=function(a,b){return jasmine.Clock.installed.setTimeout.apply?jasmine.Clock.installed.setTimeout.apply(this,arguments):jasmine.Clock.installed.setTimeout(a,b)};+jasmine.getGlobal().setInterval=function(a,b){return jasmine.Clock.installed.setInterval.apply?jasmine.Clock.installed.setInterval.apply(this,arguments):jasmine.Clock.installed.setInterval(a,b)};jasmine.getGlobal().clearTimeout=function(a){return jasmine.Clock.installed.clearTimeout.apply?jasmine.Clock.installed.clearTimeout.apply(this,arguments):jasmine.Clock.installed.clearTimeout(a)};+jasmine.getGlobal().clearInterval=function(a){return jasmine.Clock.installed.clearTimeout.apply?jasmine.Clock.installed.clearInterval.apply(this,arguments):jasmine.Clock.installed.clearInterval(a)};jasmine.version_={major:1,minor:0,build:1,revision:1286311016};
+ lib/js/jquery.js view
@@ -0,0 +1,16 @@+/*!+ * jQuery JavaScript Library v1.5.2+ * http://jquery.com/+ *+ * Copyright 2011, John Resig+ * Dual licensed under the MIT or GPL Version 2 licenses.+ * http://jquery.org/license+ *+ * Includes Sizzle.js+ * http://sizzlejs.com/+ * Copyright 2011, The Dojo Foundation+ * Released under the MIT, BSD, and GPL Licenses.+ *+ * Date: Thu Mar 31 15:28:23 2011 -0400+ */+(function(a,b){function ci(a){return d.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cf(a){if(!b_[a]){var b=d("<"+a+">").appendTo("body"),c=b.css("display");b.remove();if(c==="none"||c==="")c="block";b_[a]=c}return b_[a]}function ce(a,b){var c={};d.each(cd.concat.apply([],cd.slice(0,b)),function(){c[this]=a});return c}function b$(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function bZ(){try{return new a.XMLHttpRequest}catch(b){}}function bY(){d(a).unload(function(){for(var a in bW)bW[a](0,1)})}function bS(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var e=a.dataTypes,f={},g,h,i=e.length,j,k=e[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h==="string"&&(f[h.toLowerCase()]=a.converters[h]);l=k,k=e[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=f[m]||f["* "+k];if(!n){p=b;for(o in f){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=f[j[1]+" "+k];if(p){o=f[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&d.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function bR(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bQ(a,b,c,e){if(d.isArray(b)&&b.length)d.each(b,function(b,f){c||bs.test(a)?e(a,f):bQ(a+"["+(typeof f==="object"||d.isArray(f)?b:"")+"]",f,c,e)});else if(c||b==null||typeof b!=="object")e(a,b);else if(d.isArray(b)||d.isEmptyObject(b))e(a,"");else for(var f in b)bQ(a+"["+f+"]",b[f],c,e)}function bP(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bJ,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l==="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bP(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bP(a,c,d,e,"*",g));return l}function bO(a){return function(b,c){typeof b!=="string"&&(c=b,b="*");if(d.isFunction(c)){var e=b.toLowerCase().split(bD),f=0,g=e.length,h,i,j;for(;f<g;f++)h=e[f],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bq(a,b,c){var e=b==="width"?bk:bl,f=b==="width"?a.offsetWidth:a.offsetHeight;if(c==="border")return f;d.each(e,function(){c||(f-=parseFloat(d.css(a,"padding"+this))||0),c==="margin"?f+=parseFloat(d.css(a,"margin"+this))||0:f-=parseFloat(d.css(a,"border"+this+"Width"))||0});return f}function bc(a,b){b.src?d.ajax({url:b.src,async:!1,dataType:"script"}):d.globalEval(b.text||b.textContent||b.innerHTML||""),b.parentNode&&b.parentNode.removeChild(b)}function bb(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function ba(a,b){if(b.nodeType===1){var c=b.nodeName.toLowerCase();b.clearAttributes(),b.mergeAttributes(a);if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(d.expando)}}function _(a,b){if(b.nodeType===1&&d.hasData(a)){var c=d.expando,e=d.data(a),f=d.data(b,e);if(e=e[c]){var g=e.events;f=f[c]=d.extend({},e);if(g){delete f.handle,f.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)d.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function $(a,b){return d.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Q(a,b,c){if(d.isFunction(b))return d.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return d.grep(a,function(a,d){return a===b===c});if(typeof b==="string"){var e=d.grep(a,function(a){return a.nodeType===1});if(L.test(b))return d.filter(b,e,!c);b=d.filter(b,e)}return d.grep(a,function(a,e){return d.inArray(a,b)>=0===c})}function P(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function H(a,b){return(a&&a!=="*"?a+".":"")+b.replace(t,"`").replace(u,"&")}function G(a){var b,c,e,f,g,h,i,j,k,l,m,n,o,p=[],q=[],s=d._data(this,"events");if(a.liveFired!==this&&s&&s.live&&!a.target.disabled&&(!a.button||a.type!=="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var t=s.live.slice(0);for(i=0;i<t.length;i++)g=t[i],g.origType.replace(r,"")===a.type?q.push(g.selector):t.splice(i--,1);f=d(a.target).closest(q,a.currentTarget);for(j=0,k=f.length;j<k;j++){m=f[j];for(i=0;i<t.length;i++){g=t[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,e=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,e=d(a.relatedTarget).closest(g.selector)[0];(!e||e!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){f=p[j];if(c&&f.level>c)break;a.currentTarget=f.elem,a.data=f.handleObj.data,a.handleObj=f.handleObj,o=f.handleObj.origHandler.apply(f.elem,arguments);if(o===!1||a.isPropagationStopped()){c=f.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function E(a,c,e){var f=d.extend({},e[0]);f.type=a,f.originalEvent={},f.liveFired=b,d.event.handle.call(c,f),f.isDefaultPrevented()&&e[0].preventDefault()}function y(){return!0}function x(){return!1}function i(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function h(a,c,e){if(e===b&&a.nodeType===1){e=a.getAttribute("data-"+c);if(typeof e==="string"){try{e=e==="true"?!0:e==="false"?!1:e==="null"?null:d.isNaN(e)?g.test(e)?d.parseJSON(e):e:parseFloat(e)}catch(f){}d.data(a,c,e)}else e=b}return e}var c=a.document,d=function(){function G(){if(!d.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(G,1);return}d.ready()}}var d=function(a,b){return new d.fn.init(a,b,g)},e=a.jQuery,f=a.$,g,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,i=/\S/,j=/^\s+/,k=/\s+$/,l=/\d/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=navigator.userAgent,w,x,y,z=Object.prototype.toString,A=Object.prototype.hasOwnProperty,B=Array.prototype.push,C=Array.prototype.slice,D=String.prototype.trim,E=Array.prototype.indexOf,F={};d.fn=d.prototype={constructor:d,init:function(a,e,f){var g,i,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!e&&c.body){this.context=c,this[0]=c.body,this.selector="body",this.length=1;return this}if(typeof a==="string"){g=h.exec(a);if(!g||!g[1]&&e)return!e||e.jquery?(e||f).find(a):this.constructor(e).find(a);if(g[1]){e=e instanceof d?e[0]:e,k=e?e.ownerDocument||e:c,j=m.exec(a),j?d.isPlainObject(e)?(a=[c.createElement(j[1])],d.fn.attr.call(a,e,!0)):a=[k.createElement(j[1])]:(j=d.buildFragment([g[1]],[k]),a=(j.cacheable?d.clone(j.fragment):j.fragment).childNodes);return d.merge(this,a)}i=c.getElementById(g[2]);if(i&&i.parentNode){if(i.id!==g[2])return f.find(a);this.length=1,this[0]=i}this.context=c,this.selector=a;return this}if(d.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return d.makeArray(a,this)},selector:"",jquery:"1.5.2",length:0,size:function(){return this.length},toArray:function(){return C.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var e=this.constructor();d.isArray(a)?B.apply(e,a):d.merge(e,a),e.prevObject=this,e.context=this.context,b==="find"?e.selector=this.selector+(this.selector?" ":"")+c:b&&(e.selector=this.selector+"."+b+"("+c+")");return e},each:function(a,b){return d.each(this,a,b)},ready:function(a){d.bindReady(),x.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(C.apply(this,arguments),"slice",C.call(arguments).join(","))},map:function(a){return this.pushStack(d.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:B,sort:[].sort,splice:[].splice},d.fn.init.prototype=d.fn,d.extend=d.fn.extend=function(){var a,c,e,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i==="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!=="object"&&!d.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){e=i[c],f=a[c];if(i===f)continue;l&&f&&(d.isPlainObject(f)||(g=d.isArray(f)))?(g?(g=!1,h=e&&d.isArray(e)?e:[]):h=e&&d.isPlainObject(e)?e:{},i[c]=d.extend(l,h,f)):f!==b&&(i[c]=f)}return i},d.extend({noConflict:function(b){a.$=f,b&&(a.jQuery=e);return d},isReady:!1,readyWait:1,ready:function(a){a===!0&&d.readyWait--;if(!d.readyWait||a!==!0&&!d.isReady){if(!c.body)return setTimeout(d.ready,1);d.isReady=!0;if(a!==!0&&--d.readyWait>0)return;x.resolveWith(c,[d]),d.fn.trigger&&d(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!x){x=d._Deferred();if(c.readyState==="complete")return setTimeout(d.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",y,!1),a.addEventListener("load",d.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",y),a.attachEvent("onload",d.ready);var b=!1;try{b=a.frameElement==null}catch(e){}c.documentElement.doScroll&&b&&G()}}},isFunction:function(a){return d.type(a)==="function"},isArray:Array.isArray||function(a){return d.type(a)==="array"},isWindow:function(a){return a&&typeof a==="object"&&"setInterval"in a},isNaN:function(a){return a==null||!l.test(a)||isNaN(a)},type:function(a){return a==null?String(a):F[z.call(a)]||"object"},isPlainObject:function(a){if(!a||d.type(a)!=="object"||a.nodeType||d.isWindow(a))return!1;if(a.constructor&&!A.call(a,"constructor")&&!A.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a){}return c===b||A.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!=="string"||!b)return null;b=d.trim(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return a.JSON&&a.JSON.parse?a.JSON.parse(b):(new Function("return "+b))();d.error("Invalid JSON: "+b)},parseXML:function(b,c,e){a.DOMParser?(e=new DOMParser,c=e.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),e=c.documentElement,(!e||!e.nodeName||e.nodeName==="parsererror")&&d.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(a){if(a&&i.test(a)){var b=c.head||c.getElementsByTagName("head")[0]||c.documentElement,e=c.createElement("script");d.support.scriptEval()?e.appendChild(c.createTextNode(a)):e.text=a,b.insertBefore(e,b.firstChild),b.removeChild(e)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,e){var f,g=0,h=a.length,i=h===b||d.isFunction(a);if(e){if(i){for(f in a)if(c.apply(a[f],e)===!1)break}else for(;g<h;)if(c.apply(a[g++],e)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(var j=a[0];g<h&&c.call(j,g,j)!==!1;j=a[++g]){}return a},trim:D?function(a){return a==null?"":D.call(a)}:function(a){return a==null?"":(a+"").replace(j,"").replace(k,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var e=d.type(a);a.length==null||e==="string"||e==="function"||e==="regexp"||d.isWindow(a)?B.call(c,a):d.merge(c,a)}return c},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length==="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,b,c){var d=[],e;for(var f=0,g=a.length;f<g;f++)e=b(a[f],f,c),e!=null&&(d[d.length]=e);return d.concat.apply([],d)},guid:1,proxy:function(a,c,e){arguments.length===2&&(typeof c==="string"?(e=a,a=e[c],c=b):c&&!d.isFunction(c)&&(e=c,c=b)),!c&&a&&(c=function(){return a.apply(e||this,arguments)}),a&&(c.guid=a.guid=a.guid||c.guid||d.guid++);return c},access:function(a,c,e,f,g,h){var i=a.length;if(typeof c==="object"){for(var j in c)d.access(a,j,c[j],f,g,e);return a}if(e!==b){f=!h&&f&&d.isFunction(e);for(var k=0;k<i;k++)g(a[k],c,f?e.call(a[k],k,g(a[k],c)):e,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}d.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.subclass=this.subclass,a.fn.init=function b(b,c){c&&c instanceof d&&!(c instanceof a)&&(c=a(c));return d.fn.init.call(this,b,c,e)},a.fn.init.prototype=a.fn;var e=a(c);return a},browser:{}}),d.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){F["[object "+b+"]"]=b.toLowerCase()}),w=d.uaMatch(v),w.browser&&(d.browser[w.browser]=!0,d.browser.version=w.version),d.browser.webkit&&(d.browser.safari=!0),E&&(d.inArray=function(a,b){return E.call(b,a)}),i.test(" ")&&(j=/^[\s\xA0]+/,k=/[\s\xA0]+$/),g=d(c),c.addEventListener?y=function(){c.removeEventListener("DOMContentLoaded",y,!1),d.ready()}:c.attachEvent&&(y=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",y),d.ready())});return d}(),e="then done fail isResolved isRejected promise".split(" "),f=[].slice;d.extend({_Deferred:function(){var a=[],b,c,e,f={done:function(){if(!e){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=d.type(i),j==="array"?f.done.apply(f,i):j==="function"&&a.push(i);k&&f.resolveWith(k[0],k[1])}return this},resolveWith:function(d,f){if(!e&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(d,f)}finally{b=[d,f],c=0}}return this},resolve:function(){f.resolveWith(this,arguments);return this},isResolved:function(){return c||b},cancel:function(){e=1,a=[];return this}};return f},Deferred:function(a){var b=d._Deferred(),c=d._Deferred(),f;d.extend(b,{then:function(a,c){b.done(a).fail(c);return this},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,promise:function(a){if(a==null){if(f)return f;f=a={}}var c=e.length;while(c--)a[e[c]]=b[e[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?f.call(arguments,0):c,--g||h.resolveWith(h,f.call(b,0))}}var b=arguments,c=0,e=b.length,g=e,h=e<=1&&a&&d.isFunction(a.promise)?a:d.Deferred();if(e>1){for(;c<e;c++)b[c]&&d.isFunction(b[c].promise)?b[c].promise().then(i(c),h.reject):--g;g||h.resolveWith(h,b)}else h!==a&&h.resolveWith(h,e?[a]:[]);return h.promise()}}),function(){d.support={};var b=c.createElement("div");b.style.display="none",b.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=b.getElementsByTagName("*"),f=b.getElementsByTagName("a")[0],g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=b.getElementsByTagName("input")[0];if(e&&e.length&&f){d.support={leadingWhitespace:b.firstChild.nodeType===3,tbody:!b.getElementsByTagName("tbody").length,htmlSerialize:!!b.getElementsByTagName("link").length,style:/red/.test(f.getAttribute("style")),hrefNormalized:f.getAttribute("href")==="/a",opacity:/^0.55$/.test(f.style.opacity),cssFloat:!!f.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,deleteExpando:!0,optDisabled:!1,checkClone:!1,noCloneEvent:!0,noCloneChecked:!0,boxModel:null,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableHiddenOffsets:!0,reliableMarginRight:!0},i.checked=!0,d.support.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,d.support.optDisabled=!h.disabled;var j=null;d.support.scriptEval=function(){if(j===null){var b=c.documentElement,e=c.createElement("script"),f="script"+d.now();try{e.appendChild(c.createTextNode("window."+f+"=1;"))}catch(g){}b.insertBefore(e,b.firstChild),a[f]?(j=!0,delete a[f]):j=!1,b.removeChild(e)}return j};try{delete b.test}catch(k){d.support.deleteExpando=!1}!b.addEventListener&&b.attachEvent&&b.fireEvent&&(b.attachEvent("onclick",function l(){d.support.noCloneEvent=!1,b.detachEvent("onclick",l)}),b.cloneNode(!0).fireEvent("onclick")),b=c.createElement("div"),b.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";var m=c.createDocumentFragment();m.appendChild(b.firstChild),d.support.checkClone=m.cloneNode(!0).cloneNode(!0).lastChild.checked,d(function(){var a=c.createElement("div"),b=c.getElementsByTagName("body")[0];if(b){a.style.width=a.style.paddingLeft="1px",b.appendChild(a),d.boxModel=d.support.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,d.support.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",d.support.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";var e=a.getElementsByTagName("td");d.support.reliableHiddenOffsets=e[0].offsetHeight===0,e[0].style.display="",e[1].style.display="none",d.support.reliableHiddenOffsets=d.support.reliableHiddenOffsets&&e[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(a.style.width="1px",a.style.marginRight="0",d.support.reliableMarginRight=(parseInt(c.defaultView.getComputedStyle(a,null).marginRight,10)||0)===0),b.removeChild(a).style.display="none",a=e=null}});var n=function(a){var b=c.createElement("div");a="on"+a;if(!b.attachEvent)return!0;var d=a in b;d||(b.setAttribute(a,"return;"),d=typeof b[a]==="function");return d};d.support.submitBubbles=n("submit"),d.support.changeBubbles=n("change"),b=e=f=null}}();var g=/^(?:\{.*\}|\[.*\])$/;d.extend({cache:{},uuid:0,expando:"jQuery"+(d.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?d.cache[a[d.expando]]:a[d.expando];return!!a&&!i(a)},data:function(a,c,e,f){if(d.acceptData(a)){var g=d.expando,h=typeof c==="string",i,j=a.nodeType,k=j?d.cache:a,l=j?a[d.expando]:a[d.expando]&&d.expando;if((!l||f&&l&&!k[l][g])&&h&&e===b)return;l||(j?a[d.expando]=l=++d.uuid:l=d.expando),k[l]||(k[l]={},j||(k[l].toJSON=d.noop));if(typeof c==="object"||typeof c==="function")f?k[l][g]=d.extend(k[l][g],c):k[l]=d.extend(k[l],c);i=k[l],f&&(i[g]||(i[g]={}),i=i[g]),e!==b&&(i[c]=e);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[c]:i}},removeData:function(b,c,e){if(d.acceptData(b)){var f=d.expando,g=b.nodeType,h=g?d.cache:b,j=g?b[d.expando]:d.expando;if(!h[j])return;if(c){var k=e?h[j][f]:h[j];if(k){delete k[c];if(!i(k))return}}if(e){delete h[j][f];if(!i(h[j]))return}var l=h[j][f];d.support.deleteExpando||h!=a?delete h[j]:h[j]=null,l?(h[j]={},g||(h[j].toJSON=d.noop),h[j][f]=l):g&&(d.support.deleteExpando?delete b[d.expando]:b.removeAttribute?b.removeAttribute(d.expando):b[d.expando]=null)}},_data:function(a,b,c){return d.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=d.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),d.fn.extend({data:function(a,c){var e=null;if(typeof a==="undefined"){if(this.length){e=d.data(this[0]);if(this[0].nodeType===1){var f=this[0].attributes,g;for(var i=0,j=f.length;i<j;i++)g=f[i].name,g.indexOf("data-")===0&&(g=g.substr(5),h(this[0],g,e[g]))}}return e}if(typeof a==="object")return this.each(function(){d.data(this,a)});var k=a.split(".");k[1]=k[1]?"."+k[1]:"";if(c===b){e=this.triggerHandler("getData"+k[1]+"!",[k[0]]),e===b&&this.length&&(e=d.data(this[0],a),e=h(this[0],a,e));return e===b&&k[1]?this.data(k[0]):e}return this.each(function(){var b=d(this),e=[k[0],c];b.triggerHandler("setData"+k[1]+"!",e),d.data(this,a,c),b.triggerHandler("changeData"+k[1]+"!",e)})},removeData:function(a){return this.each(function(){d.removeData(this,a)})}}),d.extend({queue:function(a,b,c){if(a){b=(b||"fx")+"queue";var e=d._data(a,b);if(!c)return e||[];!e||d.isArray(c)?e=d._data(a,b,d.makeArray(c)):e.push(c);return e}},dequeue:function(a,b){b=b||"fx";var c=d.queue(a,b),e=c.shift();e==="inprogress"&&(e=c.shift()),e&&(b==="fx"&&c.unshift("inprogress"),e.call(a,function(){d.dequeue(a,b)})),c.length||d.removeData(a,b+"queue",!0)}}),d.fn.extend({queue:function(a,c){typeof a!=="string"&&(c=a,a="fx");if(c===b)return d.queue(this[0],a);return this.each(function(b){var e=d.queue(this,a,c);a==="fx"&&e[0]!=="inprogress"&&d.dequeue(this,a)})},dequeue:function(a){return this.each(function(){d.dequeue(this,a)})},delay:function(a,b){a=d.fx?d.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){d.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var j=/[\n\t\r]/g,k=/\s+/,l=/\r/g,m=/^(?:href|src|style)$/,n=/^(?:button|input)$/i,o=/^(?:button|input|object|select|textarea)$/i,p=/^a(?:rea)?$/i,q=/^(?:radio|checkbox)$/i;d.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"},d.fn.extend({attr:function(a,b){return d.access(this,a,b,!0,d.attr)},removeAttr:function(a,b){return this.each(function(){d.attr(this,a,""),this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.addClass(a.call(this,b,c.attr("class")))});if(a&&typeof a==="string"){var b=(a||"").split(k);for(var c=0,e=this.length;c<e;c++){var f=this[c];if(f.nodeType===1)if(f.className){var g=" "+f.className+" ",h=f.className;for(var i=0,j=b.length;i<j;i++)g.indexOf(" "+b[i]+" ")<0&&(h+=" "+b[i]);f.className=d.trim(h)}else f.className=a}}return this},removeClass:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.removeClass(a.call(this,b,c.attr("class")))});if(a&&typeof a==="string"||a===b){var c=(a||"").split(k);for(var e=0,f=this.length;e<f;e++){var g=this[e];if(g.nodeType===1&&g.className)if(a){var h=(" "+g.className+" ").replace(j," ");for(var i=0,l=c.length;i<l;i++)h=h.replace(" "+c[i]+" "," ");g.className=d.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,e=typeof b==="boolean";if(d.isFunction(a))return this.each(function(c){var e=d(this);e.toggleClass(a.call(this,c,e.attr("class"),b),b)});return this.each(function(){if(c==="string"){var f,g=0,h=d(this),i=b,j=a.split(k);while(f=j[g++])i=e?i:!h.hasClass(f),h[i?"addClass":"removeClass"](f)}else if(c==="undefined"||c==="boolean")this.className&&d._data(this,"__className__",this.className),this.className=this.className||a===!1?"":d._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if((" "+this[c].className+" ").replace(j," ").indexOf(b)>-1)return!0;return!1},val:function(a){if(!arguments.length){var c=this[0];if(c){if(d.nodeName(c,"option")){var e=c.attributes.value;return!e||e.specified?c.value:c.text}if(d.nodeName(c,"select")){var f=c.selectedIndex,g=[],h=c.options,i=c.type==="select-one";if(f<0)return null;for(var j=i?f:0,k=i?f+1:h.length;j<k;j++){var m=h[j];if(m.selected&&(d.support.optDisabled?!m.disabled:m.getAttribute("disabled")===null)&&(!m.parentNode.disabled||!d.nodeName(m.parentNode,"optgroup"))){a=d(m).val();if(i)return a;g.push(a)}}if(i&&!g.length&&h.length)return d(h[f]).val();return g}if(q.test(c.type)&&!d.support.checkOn)return c.getAttribute("value")===null?"on":c.value;return(c.value||"").replace(l,"")}return b}var n=d.isFunction(a);return this.each(function(b){var c=d(this),e=a;if(this.nodeType===1){n&&(e=a.call(this,b,c.val())),e==null?e="":typeof e==="number"?e+="":d.isArray(e)&&(e=d.map(e,function(a){return a==null?"":a+""}));if(d.isArray(e)&&q.test(this.type))this.checked=d.inArray(c.val(),e)>=0;else if(d.nodeName(this,"select")){var f=d.makeArray(e);d("option",this).each(function(){this.selected=d.inArray(d(this).val(),f)>=0}),f.length||(this.selectedIndex=-1)}else this.value=e}})}}),d.extend({attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,e,f){if(!a||a.nodeType===3||a.nodeType===8||a.nodeType===2)return b;if(f&&c in d.attrFn)return d(a)[c](e);var g=a.nodeType!==1||!d.isXMLDoc(a),h=e!==b;c=g&&d.props[c]||c;if(a.nodeType===1){var i=m.test(c);if(c==="selected"&&!d.support.optSelected){var j=a.parentNode;j&&(j.selectedIndex,j.parentNode&&j.parentNode.selectedIndex)}if((c in a||a[c]!==b)&&g&&!i){h&&(c==="type"&&n.test(a.nodeName)&&a.parentNode&&d.error("type property can't be changed"),e===null?a.nodeType===1&&a.removeAttribute(c):a[c]=e);if(d.nodeName(a,"form")&&a.getAttributeNode(c))return a.getAttributeNode(c).nodeValue;if(c==="tabIndex"){var k=a.getAttributeNode("tabIndex");return k&&k.specified?k.value:o.test(a.nodeName)||p.test(a.nodeName)&&a.href?0:b}return a[c]}if(!d.support.style&&g&&c==="style"){h&&(a.style.cssText=""+e);return a.style.cssText}h&&a.setAttribute(c,""+e);if(!a.attributes[c]&&(a.hasAttribute&&!a.hasAttribute(c)))return b;var l=!d.support.hrefNormalized&&g&&i?a.getAttribute(c,2):a.getAttribute(c);return l===null?b:l}h&&(a[c]=e);return a[c]}});var r=/\.(.*)$/,s=/^(?:textarea|input|select)$/i,t=/\./g,u=/ /g,v=/[^\w\s.|`]/g,w=function(a){return a.replace(v,"\\$&")};d.event={add:function(c,e,f,g){if(c.nodeType!==3&&c.nodeType!==8){try{d.isWindow(c)&&(c!==a&&!c.frameElement)&&(c=a)}catch(h){}if(f===!1)f=x;else if(!f)return;var i,j;f.handler&&(i=f,f=i.handler),f.guid||(f.guid=d.guid++);var k=d._data(c);if(!k)return;var l=k.events,m=k.handle;l||(k.events=l={}),m||(k.handle=m=function(a){return typeof d!=="undefined"&&d.event.triggered!==a.type?d.event.handle.apply(m.elem,arguments):b}),m.elem=c,e=e.split(" ");var n,o=0,p;while(n=e[o++]){j=i?d.extend({},i):{handler:f,data:g},n.indexOf(".")>-1?(p=n.split("."),n=p.shift(),j.namespace=p.slice(0).sort().join(".")):(p=[],j.namespace=""),j.type=n,j.guid||(j.guid=f.guid);var q=l[n],r=d.event.special[n]||{};if(!q){q=l[n]=[];if(!r.setup||r.setup.call(c,g,p,m)===!1)c.addEventListener?c.addEventListener(n,m,!1):c.attachEvent&&c.attachEvent("on"+n,m)}r.add&&(r.add.call(c,j),j.handler.guid||(j.handler.guid=f.guid)),q.push(j),d.event.global[n]=!0}c=null}},global:{},remove:function(a,c,e,f){if(a.nodeType!==3&&a.nodeType!==8){e===!1&&(e=x);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=d.hasData(a)&&d._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(e=c.handler,c=c.type);if(!c||typeof c==="string"&&c.charAt(0)==="."){c=c||"";for(h in t)d.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+d.map(m.slice(0).sort(),w).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!e){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))d.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=d.event.special[h]||{};for(j=f||0;j<p.length;j++){q=p[j];if(e.guid===q.guid){if(l||n.test(q.namespace))f==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(f!=null)break}}if(p.length===0||f!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&d.removeEvent(a,h,s.handle),g=null,delete t[h]}if(d.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,d.isEmptyObject(s)&&d.removeData(a,b,!0)}}},trigger:function(a,c,e){var f=a.type||a,g=arguments[3];if(!g){a=typeof a==="object"?a[d.expando]?a:d.extend(d.Event(f),a):d.Event(f),f.indexOf("!")>=0&&(a.type=f=f.slice(0,-1),a.exclusive=!0),e||(a.stopPropagation(),d.event.global[f]&&d.each(d.cache,function(){var b=d.expando,e=this[b];e&&e.events&&e.events[f]&&d.event.trigger(a,c,e.handle.elem)}));if(!e||e.nodeType===3||e.nodeType===8)return b;a.result=b,a.target=e,c=d.makeArray(c),c.unshift(a)}a.currentTarget=e;var h=d._data(e,"handle");h&&h.apply(e,c);var i=e.parentNode||e.ownerDocument;try{e&&e.nodeName&&d.noData[e.nodeName.toLowerCase()]||e["on"+f]&&e["on"+f].apply(e,c)===!1&&(a.result=!1,a.preventDefault())}catch(j){}if(!a.isPropagationStopped()&&i)d.event.trigger(a,c,i,!0);else if(!a.isDefaultPrevented()){var k,l=a.target,m=f.replace(r,""),n=d.nodeName(l,"a")&&m==="click",o=d.event.special[m]||{};if((!o._default||o._default.call(e,a)===!1)&&!n&&!(l&&l.nodeName&&d.noData[l.nodeName.toLowerCase()])){try{l[m]&&(k=l["on"+m],k&&(l["on"+m]=null),d.event.triggered=a.type,l[m]())}catch(p){}k&&(l["on"+m]=k),d.event.triggered=b}}},handle:function(c){var e,f,g,h,i,j=[],k=d.makeArray(arguments);c=k[0]=d.event.fix(c||a.event),c.currentTarget=this,e=c.type.indexOf(".")<0&&!c.exclusive,e||(g=c.type.split("."),c.type=g.shift(),j=g.slice(0).sort(),h=new RegExp("(^|\\.)"+j.join("\\.(?:.*\\.)?")+"(\\.|$)")),c.namespace=c.namespace||j.join("."),i=d._data(this,"events"),f=(i||{})[c.type];if(i&&f){f=f.slice(0);for(var l=0,m=f.length;l<m;l++){var n=f[l];if(e||h.test(n.namespace)){c.handler=n.handler,c.data=n.data,c.handleObj=n;var o=n.handler.apply(this,k);o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[d.expando])return a;var e=a;a=d.Event(e);for(var f=this.props.length,g;f;)g=this.props[--f],a[g]=e[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=c.documentElement,i=c.body;a.pageX=a.clientX+(h&&h.scrollLeft||i&&i.scrollLeft||0)-(h&&h.clientLeft||i&&i.clientLeft||0),a.pageY=a.clientY+(h&&h.scrollTop||i&&i.scrollTop||0)-(h&&h.clientTop||i&&i.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:d.proxy,special:{ready:{setup:d.bindReady,teardown:d.noop},live:{add:function(a){d.event.add(this,H(a.origType,a.selector),d.extend({},a,{handler:G,guid:a.handler.guid}))},remove:function(a){d.event.remove(this,H(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){d.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},d.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},d.Event=function(a){if(!this.preventDefault)return new d.Event(a);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?y:x):this.type=a,this.timeStamp=d.now(),this[d.expando]=!0},d.Event.prototype={preventDefault:function(){this.isDefaultPrevented=y;var a=this.originalEvent;a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=y;var a=this.originalEvent;a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=y,this.stopPropagation()},isDefaultPrevented:x,isPropagationStopped:x,isImmediatePropagationStopped:x};var z=function(a){var b=a.relatedTarget;try{if(b&&b!==c&&!b.parentNode)return;while(b&&b!==this)b=b.parentNode;b!==this&&(a.type=a.data,d.event.handle.apply(this,arguments))}catch(e){}},A=function(a){a.type=a.data,d.event.handle.apply(this,arguments)};d.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){d.event.special[a]={setup:function(c){d.event.add(this,b,c&&c.selector?A:z,a)},teardown:function(a){d.event.remove(this,b,a&&a.selector?A:z)}}}),d.support.submitBubbles||(d.event.special.submit={setup:function(a,b){if(this.nodeName&&this.nodeName.toLowerCase()!=="form")d.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=b.type;(c==="submit"||c==="image")&&d(b).closest("form").length&&E("submit",this,arguments)}),d.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=b.type;(c==="text"||c==="password")&&d(b).closest("form").length&&a.keyCode===13&&E("submit",this,arguments)});else return!1},teardown:function(a){d.event.remove(this,".specialSubmit")}});if(!d.support.changeBubbles){var B,C=function(a){var b=a.type,c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?d.map(a.options,function(a){return a.selected}).join("-"):"":a.nodeName.toLowerCase()==="select"&&(c=a.selectedIndex);return c},D=function D(a){var c=a.target,e,f;if(s.test(c.nodeName)&&!c.readOnly){e=d._data(c,"_change_data"),f=C(c),(a.type!=="focusout"||c.type!=="radio")&&d._data(c,"_change_data",f);if(e===b||f===e)return;if(e!=null||f)a.type="change",a.liveFired=b,d.event.trigger(a,arguments[1],c)}};d.event.special.change={filters:{focusout:D,beforedeactivate:D,click:function(a){var b=a.target,c=b.type;(c==="radio"||c==="checkbox"||b.nodeName.toLowerCase()==="select")&&D.call(this,a)},keydown:function(a){var b=a.target,c=b.type;(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&D.call(this,a)},beforeactivate:function(a){var b=a.target;d._data(b,"_change_data",C(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in B)d.event.add(this,c+".specialChange",B[c]);return s.test(this.nodeName)},teardown:function(a){d.event.remove(this,".specialChange");return s.test(this.nodeName)}},B=d.event.special.change.filters,B.focus=B.beforeactivate}c.addEventListener&&d.each({focus:"focusin",blur:"focusout"},function(a,b){function f(a){var c=d.event.fix(a);c.type=b,c.originalEvent={},d.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var e=0;d.event.special[b]={setup:function(){e++===0&&c.addEventListener(a,f,!0)},teardown:function(){--e===0&&c.removeEventListener(a,f,!0)}}}),d.each(["bind","one"],function(a,c){d.fn[c]=function(a,e,f){if(typeof a==="object"){for(var g in a)this[c](g,e,a[g],f);return this}if(d.isFunction(e)||e===!1)f=e,e=b;var h=c==="one"?d.proxy(f,function(a){d(this).unbind(a,h);return f.apply(this,arguments)}):f;if(a==="unload"&&c!=="one")this.one(a,e,f);else for(var i=0,j=this.length;i<j;i++)d.event.add(this[i],a,h,e);return this}}),d.fn.extend({unbind:function(a,b){if(typeof a!=="object"||a.preventDefault)for(var e=0,f=this.length;e<f;e++)d.event.remove(this[e],a,b);else for(var c in a)this.unbind(c,a[c]);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){d.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){var c=d.Event(a);c.preventDefault(),c.stopPropagation(),d.event.trigger(c,b,this[0]);return c.result}},toggle:function(a){var b=arguments,c=1;while(c<b.length)d.proxy(a,b[c++]);return this.click(d.proxy(a,function(e){var f=(d._data(this,"lastToggle"+a.guid)||0)%c;d._data(this,"lastToggle"+a.guid,f+1),e.preventDefault();return b[f].apply(this,arguments)||!1}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var F={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};d.each(["live","die"],function(a,c){d.fn[c]=function(a,e,f,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:d(this.context);if(typeof a==="object"&&!a.preventDefault){for(var o in a)n[c](o,e,a[o],m);return this}d.isFunction(e)&&(f=e,e=b),a=(a||"").split(" ");while((h=a[i++])!=null){j=r.exec(h),k="",j&&(k=j[0],h=h.replace(r,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,h==="focus"||h==="blur"?(a.push(F[h]+k),h=h+k):h=(F[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)d.event.add(n[p],"live."+H(h,m),{data:e,selector:m,handler:f,origType:h,origHandler:f,preType:l});else n.unbind("live."+H(h,m),f)}return this}}),d.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){d.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},d.attrFn&&(d.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!=="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,e,g){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!=="string")return e;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(f.call(n)==="[object Array]")if(u)if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&e.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&e.push(j[t]);else e.push.apply(e,n);else p(n,e);o&&(k(o,h,e,g),k.uniqueSort(e));return e};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!=="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(f){if(f===!0)continue}else g=o=!0}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b==="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1){}a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b==="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=u;typeof b==="string"&&!j.test(b)&&(b=b.toLowerCase(),d=b,g=t),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=u;typeof b==="string"&&!j.test(b)&&(b=b.toLowerCase(),d=b,g=t),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!=="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!=="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!=="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return"text"===c&&(b===c||b===null)},radio:function(a){return"radio"===a.type},checkbox:function(a){return"checkbox"===a.type},file:function(a){return"file"===a.type},password:function(a){return"password"===a.type},submit:function(a){return"submit"===a.type},image:function(a){return"image"===a.type},reset:function(a){return"reset"===a.type},button:function(a){return"button"===a.type||a.nodeName.toLowerCase()==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(f.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length==="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(a===b){g=!0;return 0}if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!=="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!=="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!=="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!=="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!=="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};d.find=k,d.expr=k.selectors,d.expr[":"]=d.expr.filters,d.unique=k.uniqueSort,d.text=k.getText,d.isXMLDoc=k.isXML,d.contains=k.contains}();var I=/Until$/,J=/^(?:parents|prevUntil|prevAll)/,K=/,/,L=/^.[^:#\[\.,]*$/,M=Array.prototype.slice,N=d.expr.match.POS,O={children:!0,contents:!0,next:!0,prev:!0};d.fn.extend({find:function(a){var b=this.pushStack("","find",a),c=0;for(var e=0,f=this.length;e<f;e++){c=b.length,d.find(a,this[e],b);if(e>0)for(var g=c;g<b.length;g++)for(var h=0;h<c;h++)if(b[h]===b[g]){b.splice(g--,1);break}}return b},has:function(a){var b=d(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(d.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(Q(this,a,!1),"not",a)},filter:function(a){return this.pushStack(Q(this,a,!0),"filter",a)},is:function(a){return!!a&&d.filter(a,this).length>0},closest:function(a,b){var c=[],e,f,g=this[0];if(d.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(e=0,f=a.length;e<f;e++)i=a[e],j[i]||(j[i]=d.expr.match.POS.test(i)?d(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:d(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=N.test(a)?d(a,b||this.context):null;for(e=0,f=this.length;e<f;e++){g=this[e];while(g){if(l?l.index(g)>-1:d.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b)break}}c=c.length>1?d.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a==="string")return d.inArray(this[0],a?d(a):this.parent().children());return d.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a==="string"?d(a,b):d.makeArray(a),e=d.merge(this.get(),c);return this.pushStack(P(c[0])||P(e[0])?e:d.unique(e))},andSelf:function(){return this.add(this.prevObject)}}),d.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return d.dir(a,"parentNode")},parentsUntil:function(a,b,c){return d.dir(a,"parentNode",c)},next:function(a){return d.nth(a,2,"nextSibling")},prev:function(a){return d.nth(a,2,"previousSibling")},nextAll:function(a){return d.dir(a,"nextSibling")},prevAll:function(a){return d.dir(a,"previousSibling")},nextUntil:function(a,b,c){return d.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return d.dir(a,"previousSibling",c)},siblings:function(a){return d.sibling(a.parentNode.firstChild,a)},children:function(a){return d.sibling(a.firstChild)},contents:function(a){return d.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:d.makeArray(a.childNodes)}},function(a,b){d.fn[a]=function(c,e){var f=d.map(this,b,c),g=M.call(arguments);I.test(a)||(e=c),e&&typeof e==="string"&&(f=d.filter(e,f)),f=this.length>1&&!O[a]?d.unique(f):f,(this.length>1||K.test(e))&&J.test(a)&&(f=f.reverse());return this.pushStack(f,a,g.join(","))}}),d.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?d.find.matchesSelector(b[0],a)?[b[0]]:[]:d.find.matches(a,b)},dir:function(a,c,e){var f=[],g=a[c];while(g&&g.nodeType!==9&&(e===b||g.nodeType!==1||!d(g).is(e)))g.nodeType===1&&f.push(g),g=g[c];return f},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var R=/ jQuery\d+="(?:\d+|null)"/g,S=/^\s+/,T=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,U=/<([\w:]+)/,V=/<tbody/i,W=/<|&#?\w+;/,X=/<(?:script|object|embed|option|style)/i,Y=/checked\s*(?:[^=]|=\s*.checked.)/i,Z={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};Z.optgroup=Z.option,Z.tbody=Z.tfoot=Z.colgroup=Z.caption=Z.thead,Z.th=Z.td,d.support.htmlSerialize||(Z._default=[1,"div<div>","</div>"]),d.fn.extend({text:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.text(a.call(this,b,c.text()))});if(typeof a!=="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return d.text(this)},wrapAll:function(a){if(d.isFunction(a))return this.each(function(b){d(this).wrapAll(a.call(this,b))});if(this[0]){var b=d(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(d.isFunction(a))return this.each(function(b){d(this).wrapInner(a.call(this,b))});return this.each(function(){var b=d(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){d(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){d.nodeName(this,"body")||d(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=d(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,d(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,e;(e=this[c])!=null;c++)if(!a||d.filter(a,[e]).length)!b&&e.nodeType===1&&(d.cleanData(e.getElementsByTagName("*")),d.cleanData([e])),e.parentNode&&e.parentNode.removeChild(e);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&d.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return d.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(R,""):null;if(typeof a!=="string"||X.test(a)||!d.support.leadingWhitespace&&S.test(a)||Z[(U.exec(a)||["",""])[1].toLowerCase()])d.isFunction(a)?this.each(function(b){var c=d(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);else{a=a.replace(T,"<$1></$2>");try{for(var c=0,e=this.length;c<e;c++)this[c].nodeType===1&&(d.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(f){this.empty().append(a)}}return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(d.isFunction(a))return this.each(function(b){var c=d(this),e=c.html();c.replaceWith(a.call(this,b,e))});typeof a!=="string"&&(a=d(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;d(this).remove(),b?d(b).before(a):d(c).append(a)})}return this.length?this.pushStack(d(d.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,e){var f,g,h,i,j=a[0],k=[];if(!d.support.checkClone&&arguments.length===3&&typeof j==="string"&&Y.test(j))return this.each(function(){d(this).domManip(a,c,e,!0)});if(d.isFunction(j))return this.each(function(f){var g=d(this);a[0]=j.call(this,f,c?g.html():b),g.domManip(a,c,e)});if(this[0]){i=j&&j.parentNode,d.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?f={fragment:i}:f=d.buildFragment(a,this,k),h=f.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&d.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)e.call(c?$(this[l],g):this[l],f.cacheable||m>1&&l<n?d.clone(h,!0,!0):h)}k.length&&d.each(k,bc)}return this}}),d.buildFragment=function(a,b,e){var f,g,h,i=b&&b[0]?b[0].ownerDocument||b[0]:c;a.length===1&&typeof a[0]==="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!X.test(a[0])&&(d.support.checkClone||!Y.test(a[0]))&&(g=!0,h=d.fragments[a[0]],h&&(h!==1&&(f=h))),f||(f=i.createDocumentFragment(),d.clean(a,i,f,e)),g&&(d.fragments[a[0]]=h?f:1);return{fragment:f,cacheable:g}},d.fragments={},d.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){d.fn[a]=function(c){var e=[],f=d(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&f.length===1){f[b](this[0]);return this}for(var h=0,i=f.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();d(f[h])[b](j),e=e.concat(j)}return this.pushStack(e,a,f.selector)}}),d.extend({clone:function(a,b,c){var e=a.cloneNode(!0),f,g,h;if((!d.support.noCloneEvent||!d.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!d.isXMLDoc(a)){ba(a,e),f=bb(a),g=bb(e);for(h=0;f[h];++h)ba(f[h],g[h])}if(b){_(a,e);if(c){f=bb(a),g=bb(e);for(h=0;f[h];++h)_(f[h],g[h])}}return e},clean:function(a,b,e,f){b=b||c,typeof b.createElement==="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var g=[];for(var h=0,i;(i=a[h])!=null;h++){typeof i==="number"&&(i+="");if(!i)continue;if(typeof i!=="string"||W.test(i)){if(typeof i==="string"){i=i.replace(T,"<$1></$2>");var j=(U.exec(i)||["",""])[1].toLowerCase(),k=Z[j]||Z._default,l=k[0],m=b.createElement("div");m.innerHTML=k[1]+i+k[2];while(l--)m=m.lastChild;if(!d.support.tbody){var n=V.test(i),o=j==="table"&&!n?m.firstChild&&m.firstChild.childNodes:k[1]==="<table>"&&!n?m.childNodes:[];for(var p=o.length-1;p>=0;--p)d.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!d.support.leadingWhitespace&&S.test(i)&&m.insertBefore(b.createTextNode(S.exec(i)[0]),m.firstChild),i=m.childNodes}}else i=b.createTextNode(i);i.nodeType?g.push(i):g=d.merge(g,i)}if(e)for(h=0;g[h];h++)!f||!d.nodeName(g[h],"script")||g[h].type&&g[h].type.toLowerCase()!=="text/javascript"?(g[h].nodeType===1&&g.splice.apply(g,[h+1,0].concat(d.makeArray(g[h].getElementsByTagName("script")))),e.appendChild(g[h])):f.push(g[h].parentNode?g[h].parentNode.removeChild(g[h]):g[h]);return g},cleanData:function(a){var b,c,e=d.cache,f=d.expando,g=d.event.special,h=d.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&d.noData[j.nodeName.toLowerCase()])continue;c=j[d.expando];if(c){b=e[c]&&e[c][f];if(b&&b.events){for(var k in b.events)g[k]?d.event.remove(j,k):d.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[d.expando]:j.removeAttribute&&j.removeAttribute(d.expando),delete e[c]}}}});var bd=/alpha\([^)]*\)/i,be=/opacity=([^)]*)/,bf=/-([a-z])/ig,bg=/([A-Z]|^ms)/g,bh=/^-?\d+(?:px)?$/i,bi=/^-?\d/,bj={position:"absolute",visibility:"hidden",display:"block"},bk=["Left","Right"],bl=["Top","Bottom"],bm,bn,bo,bp=function(a,b){return b.toUpperCase()};d.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return d.access(this,a,c,!0,function(a,c,e){return e!==b?d.style(a,c,e):d.css(a,c)})},d.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bm(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0},cssProps:{"float":d.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,e,f){if(a&&a.nodeType!==3&&a.nodeType!==8&&a.style){var g,h=d.camelCase(c),i=a.style,j=d.cssHooks[h];c=d.cssProps[h]||h;if(e===b){if(j&&"get"in j&&(g=j.get(a,!1,f))!==b)return g;return i[c]}if(typeof e==="number"&&isNaN(e)||e==null)return;typeof e==="number"&&!d.cssNumber[h]&&(e+="px");if(!j||!("set"in j)||(e=j.set(a,e))!==b)try{i[c]=e}catch(k){}}},css:function(a,c,e){var f,g=d.camelCase(c),h=d.cssHooks[g];c=d.cssProps[g]||g;if(h&&"get"in h&&(f=h.get(a,!0,e))!==b)return f;if(bm)return bm(a,c,g)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bf,bp)}}),d.curCSS=d.css,d.each(["height","width"],function(a,b){d.cssHooks[b]={get:function(a,c,e){var f;if(c){a.offsetWidth!==0?f=bq(a,b,e):d.swap(a,bj,function(){f=bq(a,b,e)});if(f<=0){f=bm(a,b,b),f==="0px"&&bo&&(f=bo(a,b,b));if(f!=null)return f===""||f==="auto"?"0px":f}if(f<0||f==null){f=a.style[b];return f===""||f==="auto"?"0px":f}return typeof f==="string"?f:f+"px"}},set:function(a,b){if(!bh.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),d.support.opacity||(d.cssHooks.opacity={get:function(a,b){return be.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style;c.zoom=1;var e=d.isNaN(b)?"":"alpha(opacity="+b*100+")",f=c.filter||"";c.filter=bd.test(f)?f.replace(bd,e):c.filter+" "+e}}),d(function(){d.support.reliableMarginRight||(d.cssHooks.marginRight={get:function(a,b){var c;d.swap(a,{display:"inline-block"},function(){b?c=bm(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bn=function(a,c,e){var f,g,h;e=e.replace(bg,"-$1").toLowerCase();if(!(g=a.ownerDocument.defaultView))return b;if(h=g.getComputedStyle(a,null))f=h.getPropertyValue(e),f===""&&!d.contains(a.ownerDocument.documentElement,a)&&(f=d.style(a,e));return f}),c.documentElement.currentStyle&&(bo=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bh.test(d)&&bi.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bm=bn||bo,d.expr&&d.expr.filters&&(d.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!d.support.reliableHiddenOffsets&&(a.style.display||d.css(a,"display"))==="none"},d.expr.filters.visible=function(a){return!d.expr.filters.hidden(a)});var br=/%20/g,bs=/\[\]$/,bt=/\r?\n/g,bu=/#.*$/,bv=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bw=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bx=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,by=/^(?:GET|HEAD)$/,bz=/^\/\//,bA=/\?/,bB=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bC=/^(?:select|textarea)/i,bD=/\s+/,bE=/([?&])_=[^&]*/,bF=/(^|\-)([a-z])/g,bG=function(a,b,c){return b+c.toUpperCase()},bH=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bI=d.fn.load,bJ={},bK={},bL,bM;try{bL=c.location.href}catch(bN){bL=c.createElement("a"),bL.href="",bL=bL.href}bM=bH.exec(bL.toLowerCase())||[],d.fn.extend({load:function(a,c,e){if(typeof a!=="string"&&bI)return bI.apply(this,arguments);if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var g=a.slice(f,a.length);a=a.slice(0,f)}var h="GET";c&&(d.isFunction(c)?(e=c,c=b):typeof c==="object"&&(c=d.param(c,d.ajaxSettings.traditional),h="POST"));var i=this;d.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?d("<div>").append(c.replace(bB,"")).find(g):c)),e&&i.each(e,[c,b,a])}});return this},serialize:function(){return d.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?d.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bC.test(this.nodeName)||bw.test(this.type))}).map(function(a,b){var c=d(this).val();return c==null?null:d.isArray(c)?d.map(c,function(a,c){return{name:b.name,value:a.replace(bt,"\r\n")}}):{name:b.name,value:c.replace(bt,"\r\n")}}).get()}}),d.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){d.fn[b]=function(a){return this.bind(b,a)}}),d.each(["get","post"],function(a,c){d[c]=function(a,e,f,g){d.isFunction(e)&&(g=g||f,f=e,e=b);return d.ajax({type:c,url:a,data:e,success:f,dataType:g})}}),d.extend({getScript:function(a,c){return d.get(a,b,c,"script")},getJSON:function(a,b,c){return d.get(a,b,c,"json")},ajaxSetup:function(a,b){b?d.extend(!0,a,d.ajaxSettings,b):(b=a,a=d.extend(!0,d.ajaxSettings,b));for(var c in {context:1,url:1})c in b?a[c]=b[c]:c in d.ajaxSettings&&(a[c]=d.ajaxSettings[c]);return a},ajaxSettings:{url:bL,isLocal:bx.test(bM[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":d.parseJSON,"text xml":d.parseXML}},ajaxPrefilter:bO(bJ),ajaxTransport:bO(bK),ajax:function(a,c){function v(a,c,l,n){if(r!==2){r=2,p&&clearTimeout(p),o=b,m=n||"",u.readyState=a?4:0;var q,t,v,w=l?bR(e,u,l):b,x,y;if(a>=200&&a<300||a===304){if(e.ifModified){if(x=u.getResponseHeader("Last-Modified"))d.lastModified[k]=x;if(y=u.getResponseHeader("Etag"))d.etag[k]=y}if(a===304)c="notmodified",q=!0;else try{t=bS(e,w),c="success",q=!0}catch(z){c="parsererror",v=z}}else{v=c;if(!c||a)c="error",a<0&&(a=0)}u.status=a,u.statusText=c,q?h.resolveWith(f,[t,c,u]):h.rejectWith(f,[u,c,v]),u.statusCode(j),j=b,s&&g.trigger("ajax"+(q?"Success":"Error"),[u,e,q?t:v]),i.resolveWith(f,[u,c]),s&&(g.trigger("ajaxComplete",[u,e]),--d.active||d.event.trigger("ajaxStop"))}}typeof a==="object"&&(c=a,a=b),c=c||{};var e=d.ajaxSetup({},c),f=e.context||e,g=f!==e&&(f.nodeType||f instanceof d)?d(f):d.event,h=d.Deferred(),i=d._Deferred(),j=e.statusCode||{},k,l={},m,n,o,p,q,r=0,s,t,u={readyState:0,setRequestHeader:function(a,b){r||(l[a.toLowerCase().replace(bF,bG)]=b);return this},getAllResponseHeaders:function(){return r===2?m:null},getResponseHeader:function(a){var c;if(r===2){if(!n){n={};while(c=bv.exec(m))n[c[1].toLowerCase()]=c[2]}c=n[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){r||(e.mimeType=a);return this},abort:function(a){a=a||"abort",o&&o.abort(a),v(0,a);return this}};h.promise(u),u.success=u.done,u.error=u.fail,u.complete=i.done,u.statusCode=function(a){if(a){var b;if(r<2)for(b in a)j[b]=[j[b],a[b]];else b=a[u.status],u.then(b,b)}return this},e.url=((a||e.url)+"").replace(bu,"").replace(bz,bM[1]+"//"),e.dataTypes=d.trim(e.dataType||"*").toLowerCase().split(bD),e.crossDomain==null&&(q=bH.exec(e.url.toLowerCase()),e.crossDomain=q&&(q[1]!=bM[1]||q[2]!=bM[2]||(q[3]||(q[1]==="http:"?80:443))!=(bM[3]||(bM[1]==="http:"?80:443)))),e.data&&e.processData&&typeof e.data!=="string"&&(e.data=d.param(e.data,e.traditional)),bP(bJ,e,c,u);if(r===2)return!1;s=e.global,e.type=e.type.toUpperCase(),e.hasContent=!by.test(e.type),s&&d.active++===0&&d.event.trigger("ajaxStart");if(!e.hasContent){e.data&&(e.url+=(bA.test(e.url)?"&":"?")+e.data),k=e.url;if(e.cache===!1){var w=d.now(),x=e.url.replace(bE,"$1_="+w);e.url=x+(x===e.url?(bA.test(e.url)?"&":"?")+"_="+w:"")}}if(e.data&&e.hasContent&&e.contentType!==!1||c.contentType)l["Content-Type"]=e.contentType;e.ifModified&&(k=k||e.url,d.lastModified[k]&&(l["If-Modified-Since"]=d.lastModified[k]),d.etag[k]&&(l["If-None-Match"]=d.etag[k])),l.Accept=e.dataTypes[0]&&e.accepts[e.dataTypes[0]]?e.accepts[e.dataTypes[0]]+(e.dataTypes[0]!=="*"?", */*; q=0.01":""):e.accepts["*"];for(t in e.headers)u.setRequestHeader(t,e.headers[t]);if(e.beforeSend&&(e.beforeSend.call(f,u,e)===!1||r===2)){u.abort();return!1}for(t in {success:1,error:1,complete:1})u[t](e[t]);o=bP(bK,e,c,u);if(o){u.readyState=1,s&&g.trigger("ajaxSend",[u,e]),e.async&&e.timeout>0&&(p=setTimeout(function(){u.abort("timeout")},e.timeout));try{r=1,o.send(l,v)}catch(y){status<2?v(-1,y):d.error(y)}}else v(-1,"No Transport");return u},param:function(a,c){var e=[],f=function(a,b){b=d.isFunction(b)?b():b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=d.ajaxSettings.traditional);if(d.isArray(a)||a.jquery&&!d.isPlainObject(a))d.each(a,function(){f(this.name,this.value)});else for(var g in a)bQ(g,a[g],c,f);return e.join("&").replace(br,"+")}}),d.extend({active:0,lastModified:{},etag:{}});var bT=d.now(),bU=/(\=)\?(&|$)|\?\?/i;d.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return d.expando+"_"+bT++}}),d.ajaxPrefilter("json jsonp",function(b,c,e){var f=typeof b.data==="string";if(b.dataTypes[0]==="jsonp"||c.jsonpCallback||c.jsonp!=null||b.jsonp!==!1&&(bU.test(b.url)||f&&bU.test(b.data))){var g,h=b.jsonpCallback=d.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2",m=function(){a[h]=i,g&&d.isFunction(i)&&a[h](g[0])};b.jsonp!==!1&&(j=j.replace(bU,l),b.url===j&&(f&&(k=k.replace(bU,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},e.then(m,m),b.converters["script json"]=function(){g||d.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),d.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){d.globalEval(a);return a}}}),d.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),d.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var bV=d.now(),bW,bX;d.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&bZ()||b$()}:bZ,bX=d.ajaxSettings.xhr(),d.support.ajax=!!bX,d.support.cors=bX&&"withCredentials"in bX,bX=b,d.support.ajax&&d.ajaxTransport(function(a){if(!a.crossDomain||d.support.cors){var c;return{send:function(e,f){var g=a.xhr(),h,i;a.username?g.open(a.type,a.url,a.async,a.username,a.password):g.open(a.type,a.url,a.async);if(a.xhrFields)for(i in a.xhrFields)g[i]=a.xhrFields[i];a.mimeType&&g.overrideMimeType&&g.overrideMimeType(a.mimeType),!a.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(i in e)g.setRequestHeader(i,e[i])}catch(j){}g.send(a.hasContent&&a.data||null),c=function(e,i){var j,k,l,m,n;try{if(c&&(i||g.readyState===4)){c=b,h&&(g.onreadystatechange=d.noop,delete bW[h]);if(i)g.readyState!==4&&g.abort();else{j=g.status,l=g.getAllResponseHeaders(),m={},n=g.responseXML,n&&n.documentElement&&(m.xml=n),m.text=g.responseText;try{k=g.statusText}catch(o){k=""}j||!a.isLocal||a.crossDomain?j===1223&&(j=204):j=m.text?200:404}}}catch(p){i||f(-1,p)}m&&f(j,k,m,l)},a.async&&g.readyState!==4?(bW||(bW={},bY()),h=bV++,g.onreadystatechange=bW[h]=c):c()},abort:function(){c&&c(0,1)}}}});var b_={},ca=/^(?:toggle|show|hide)$/,cb=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cc,cd=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];d.fn.extend({show:function(a,b,c){var e,f;if(a||a===0)return this.animate(ce("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)e=this[g],f=e.style.display,!d._data(e,"olddisplay")&&f==="none"&&(f=e.style.display=""),f===""&&d.css(e,"display")==="none"&&d._data(e,"olddisplay",cf(e.nodeName));for(g=0;g<h;g++){e=this[g],f=e.style.display;if(f===""||f==="none")e.style.display=d._data(e,"olddisplay")||""}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ce("hide",3),a,b,c);for(var e=0,f=this.length;e<f;e++){var g=d.css(this[e],"display");g!=="none"&&!d._data(this[e],"olddisplay")&&d._data(this[e],"olddisplay",g)}for(e=0;e<f;e++)this[e].style.display="none";return this},_toggle:d.fn.toggle,toggle:function(a,b,c){var e=typeof a==="boolean";d.isFunction(a)&&d.isFunction(b)?this._toggle.apply(this,arguments):a==null||e?this.each(function(){var b=e?a:d(this).is(":hidden");d(this)[b?"show":"hide"]()}):this.animate(ce("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,e){var f=d.speed(b,c,e);if(d.isEmptyObject(a))return this.each(f.complete);return this[f.queue===!1?"each":"queue"](function(){var b=d.extend({},f),c,e=this.nodeType===1,g=e&&d(this).is(":hidden"),h=this;for(c in a){var i=d.camelCase(c);c!==i&&(a[i]=a[c],delete a[c],c=i);if(a[c]==="hide"&&g||a[c]==="show"&&!g)return b.complete.call(this);if(e&&(c==="height"||c==="width")){b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(d.css(this,"display")==="inline"&&d.css(this,"float")==="none")if(d.support.inlineBlockNeedsLayout){var j=cf(this.nodeName);j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)}else this.style.display="inline-block"}d.isArray(a[c])&&((b.specialEasing=b.specialEasing||{})[c]=a[c][1],a[c]=a[c][0])}b.overflow!=null&&(this.style.overflow="hidden"),b.curAnim=d.extend({},a),d.each(a,function(c,e){var f=new d.fx(h,b,c);if(ca.test(e))f[e==="toggle"?g?"show":"hide":e](a);else{var i=cb.exec(e),j=f.cur();if(i){var k=parseFloat(i[2]),l=i[3]||(d.cssNumber[c]?"":"px");l!=="px"&&(d.style(h,c,(k||1)+l),j=(k||1)/f.cur()*j,d.style(h,c,j+l)),i[1]&&(k=(i[1]==="-="?-1:1)*k+j),f.custom(j,k,l)}else f.custom(j,e,"")}});return!0})},stop:function(a,b){var c=d.timers;a&&this.queue([]),this.each(function(){for(var a=c.length-1;a>=0;a--)c[a].elem===this&&(b&&c[a](!0),c.splice(a,1))}),b||this.dequeue();return this}}),d.each({slideDown:ce("show",1),slideUp:ce("hide",1),slideToggle:ce("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){d.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),d.extend({speed:function(a,b,c){var e=a&&typeof a==="object"?d.extend({},a):{complete:c||!c&&b||d.isFunction(a)&&a,duration:a,easing:c&&b||b&&!d.isFunction(b)&&b};e.duration=d.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in d.fx.speeds?d.fx.speeds[e.duration]:d.fx.speeds._default,e.old=e.complete,e.complete=function(){e.queue!==!1&&d(this).dequeue(),d.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig||(b.orig={})}}),d.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(d.fx.step[this.prop]||d.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=d.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function g(a){return e.step(a)}var e=this,f=d.fx;this.startTime=d.now(),this.start=a,this.end=b,this.unit=c||this.unit||(d.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,g.elem=this.elem,g()&&d.timers.push(g)&&!cc&&(cc=setInterval(f.tick,f.interval))},show:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),d(this.elem).show()},hide:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=d.now(),c=!0;if(a||b>=this.options.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),this.options.curAnim[this.prop]=!0;for(var e in this.options.curAnim)this.options.curAnim[e]!==!0&&(c=!1);if(c){if(this.options.overflow!=null&&!d.support.shrinkWrapBlocks){var f=this.elem,g=this.options;d.each(["","X","Y"],function(a,b){f.style["overflow"+b]=g.overflow[a]})}this.options.hide&&d(this.elem).hide();if(this.options.hide||this.options.show)for(var h in this.options.curAnim)d.style(this.elem,h,this.options.orig[h]);this.options.complete.call(this.elem)}return!1}var i=b-this.startTime;this.state=i/this.options.duration;var j=this.options.specialEasing&&this.options.specialEasing[this.prop],k=this.options.easing||(d.easing.swing?"swing":"linear");this.pos=d.easing[j||k](this.state,i,0,1,this.options.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update();return!0}},d.extend(d.fx,{tick:function(){var a=d.timers;for(var b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||d.fx.stop()},interval:13,stop:function(){clearInterval(cc),cc=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){d.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),d.expr&&d.expr.filters&&(d.expr.filters.animated=function(a){return d.grep(d.timers,function(b){return a===b.elem}).length});var cg=/^t(?:able|d|h)$/i,ch=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?d.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){d.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return d.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(e){}var f=b.ownerDocument,g=f.documentElement;if(!c||!d.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=f.body,i=ci(f),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||d.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||d.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:d.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){d.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return d.offset.bodyOffset(b);d.offset.initialize();var c,e=b.offsetParent,f=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(d.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===e&&(l+=b.offsetTop,m+=b.offsetLeft,d.offset.doesNotAddBorder&&(!d.offset.doesAddBorderForTableAndCells||!cg.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),f=e,e=b.offsetParent),d.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;d.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},d.offset={initialize:function(){var a=c.body,b=c.createElement("div"),e,f,g,h,i=parseFloat(d.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";d.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),e=b.firstChild,f=e.firstChild,h=e.nextSibling.firstChild.firstChild,this.doesNotAddBorder=f.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,f.style.position="fixed",f.style.top="20px",this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15,f.style.position=f.style.top="",e.style.overflow="hidden",e.style.position="relative",this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),d.offset.initialize=d.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;d.offset.initialize(),d.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(d.css(a,"marginTop"))||0,c+=parseFloat(d.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var e=d.css(a,"position");e==="static"&&(a.style.position="relative");var f=d(a),g=f.offset(),h=d.css(a,"top"),i=d.css(a,"left"),j=(e==="absolute"||e==="fixed")&&d.inArray("auto",[h,i])>-1,k={},l={},m,n;j&&(l=f.position()),m=j?l.top:parseInt(h,10)||0,n=j?l.left:parseInt(i,10)||0,d.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):f.css(k)}},d.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),e=ch.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(d.css(a,"marginTop"))||0,c.left-=parseFloat(d.css(a,"marginLeft"))||0,e.top+=parseFloat(d.css(b[0],"borderTopWidth"))||0,e.left+=parseFloat(d.css(b[0],"borderLeftWidth"))||0;return{top:c.top-e.top,left:c.left-e.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&(!ch.test(a.nodeName)&&d.css(a,"position")==="static"))a=a.offsetParent;return a})}}),d.each(["Left","Top"],function(a,c){var e="scroll"+c;d.fn[e]=function(c){var f=this[0],g;if(!f)return null;if(c!==b)return this.each(function(){g=ci(this),g?g.scrollTo(a?d(g).scrollLeft():c,a?c:d(g).scrollTop()):this[e]=c});g=ci(f);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:d.support.boxModel&&g.document.documentElement[e]||g.document.body[e]:f[e]}}),d.each(["Height","Width"],function(a,c){var e=c.toLowerCase();d.fn["inner"+c]=function(){return this[0]?parseFloat(d.css(this[0],e,"padding")):null},d.fn["outer"+c]=function(a){return this[0]?parseFloat(d.css(this[0],e,a?"margin":"border")):null},d.fn[e]=function(a){var f=this[0];if(!f)return a==null?null:this;if(d.isFunction(a))return this.each(function(b){var c=d(this);c[e](a.call(this,b,c[e]()))});if(d.isWindow(f)){var g=f.document.documentElement["client"+c];return f.document.compatMode==="CSS1Compat"&&g||f.document.body["client"+c]||g}if(f.nodeType===9)return Math.max(f.documentElement["client"+c],f.body["scroll"+c],f.documentElement["scroll"+c],f.body["offset"+c],f.documentElement["offset"+c]);if(a===b){var h=d.css(f,e),i=parseFloat(h);return d.isNaN(i)?h:i}return this.css(e,typeof a==="string"?a:a+"px")}}),a.jQuery=a.$=d})(window);
+ lib/js/lang-hs.js view
@@ -0,0 +1,102 @@+// Copyright (C) 2009 Google Inc.+//+// Licensed under the Apache License, Version 2.0 (the "License");+// you may not use this file except in compliance with the License.+// You may obtain a copy of the License at+//+//      http://www.apache.org/licenses/LICENSE-2.0+//+// Unless required by applicable law or agreed to in writing, software+// distributed under the License is distributed on an "AS IS" BASIS,+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+// See the License for the specific language governing permissions and+// limitations under the License.++++/**+ * @fileoverview+ * Registers a language handler for Haskell.+ *+ *+ * To use, include prettify.js and this file in your HTML page.+ * Then put your code in an HTML tag like+ *      <pre class="prettyprint lang-hs">(my lisp code)</pre>+ * The lang-cl class identifies the language as common lisp.+ * This file supports the following language extensions:+ *     lang-cl - Common Lisp+ *     lang-el - Emacs Lisp+ *     lang-lisp - Lisp+ *     lang-scm - Scheme+ *+ *+ * I used http://www.informatik.uni-freiburg.de/~thiemann/haskell/haskell98-report-html/syntax-iso.html+ * as the basis, but ignore the way the ncomment production nests since this+ * makes the lexical grammar irregular.  It might be possible to support+ * ncomments using the lookbehind filter.+ *+ *+ * @author mikesamuel@gmail.com+ */++PR['registerLangHandler'](+    PR['createSimpleLexer'](+        [+         // Whitespace+         // whitechar    ->    newline | vertab | space | tab | uniWhite+         // newline      ->    return linefeed | return | linefeed | formfeed+         [PR['PR_PLAIN'],       /^[\t\n\x0B\x0C\r ]+/, null, '\t\n\x0B\x0C\r '],+         // Single line double and single-quoted strings.+         // char         ->    ' (graphic<' | \> | space | escape<\&>) '+         // string       ->    " {graphic<" | \> | space | escape | gap}"+         // escape       ->    \ ( charesc | ascii | decimal | o octal+         //                        | x hexadecimal )+         // charesc      ->    a | b | f | n | r | t | v | \ | " | ' | &+         [PR['PR_STRING'],      /^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,+          null, '"'],+         [PR['PR_STRING'],      /^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/,+          null, "'"],+         // decimal      ->    digit{digit}+         // octal        ->    octit{octit}+         // hexadecimal  ->    hexit{hexit}+         // integer      ->    decimal+         //               |    0o octal | 0O octal+         //               |    0x hexadecimal | 0X hexadecimal+         // float        ->    decimal . decimal [exponent]+         //               |    decimal exponent+         // exponent     ->    (e | E) [+ | -] decimal+         [PR['PR_LITERAL'],+          /^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,+          null, '0123456789']+        ],+        [+         // Haskell does not have a regular lexical grammar due to the nested+         // ncomment.+         // comment      ->    dashes [ any<symbol> {any}] newline+         // ncomment     ->    opencom ANYseq {ncomment ANYseq}closecom+         // dashes       ->    '--' {'-'}+         // opencom      ->    '{-'+         // closecom     ->    '-}'+//	 [PR['PR_LITERAL'],     /^(?:[a-zA-Z]+?\:)/, null],+         [PR['PR_COMMENT'],     /^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/],+         // reservedid   ->    case | class | data | default | deriving | do+         //               |    else | if | import | in | infix | infixl | infixr+         //               |    instance | let | module | newtype | of | then+         //               |    type | where | _+         [PR['PR_KEYWORD'],     /^(?:yield|lazy|inline|private|open|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|when|with|type|where|_)(?=[^a-zA-Z0-9\']|$)/, null],+         // qvarid       ->    [ modid . ] varid+         // qconid       ->    [ modid . ] conid+         // varid        ->    (small {small | large | digit | ' })<reservedid>+         // conid        ->    large {small | large | digit | ' }+         // modid        ->    conid+         // small        ->    ascSmall | uniSmall | _+         // ascSmall     ->    a | b | ... | z+         // uniSmall     ->    any Unicode lowercase letter+         // large        ->    ascLarge | uniLarge+         // ascLarge     ->    A | B | ... | Z+         // uniLarge     ->    any uppercase or titlecase Unicode letter+         [PR['PR_PLAIN'],  /^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/],+         // matches the symbol production+         [PR['PR_PUNCTUATION'], /^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/]+        ]),+    ['hs']);
+ lib/js/prettify.css view
@@ -0,0 +1,1 @@+.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
+ lib/js/prettify.js view
@@ -0,0 +1,28 @@+var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;+(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=+[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<+f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&+(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=+{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,+t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===+"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),+l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,+q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,+q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,+"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),+a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}+for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",+m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=+a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=+j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],+"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],+H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],+J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"++I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),+["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",+/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),+["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",+hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=+!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,+250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",+PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
+ src/forml/parsec.forml view
@@ -0,0 +1,180 @@+-- Parsec+-- ------++module parsec++    open prelude+    open prelude.option+    open prelude.string+    open prelude.html+    open prelude.array++++    Parser a = {parser: String -> {rest: String, parsed: Option a}}++++    --  Runs a parser over a text argument and throws away the leftover text.++    inline run_parser:+    +          Parser p  -> String -> Option p	                    +        | {parser = p} x = p x |> λ {parsed = {some = y}, _} = {some = y} +                                  | _  = {none}+++                                       +    --  Applies a function to the parse result, only if the parse was+    --  successful.                    +    +    inline (<$>):+    +        (a -> b) -> Parser a    -> Parser b+        f       <$> {parser = z} =++            { parser s =+                  z s |>  λ {parsed = {some: x}, rest = ss} =+                               {parsed = {some = f x}, rest = ss}+                          | {parsed = {none}, rest = x} =+                               {parsed = {none}, rest = x} }++++    --  Allows functions that take multiple arguments to be applied+    --  sequentially to a sequence of parsed values.+    +    inline (<*>):++        Parser (a -> b) -> Parser a    -> Parser b+        {parser = fp}  <*> {parser = p} =++            { parser s = +                  fp s |> λ {parsed = {some: f}, rest = rr} =+                                p rr |> λ {parsed = {some = x}, rest = z} =+                                              {parsed = {some = f x}, rest = z}+                                        | {parsed = {none}, rest = x} =+                                              {parsed = {none}, rest = x}+                          | {parsed: {none}, rest: x} =+                               {parsed: {none}, rest: x} }++++++    --  Applies two parsers in sequence, throwing out the result+    --  of the first.++    inline (*>):+        +        Parser a -> Parser b -> Parser b+        {parser = f} *> {parser = g} =++            { parser s =+                  f s |> λ {parsed = {some = x}, rest = zz} = g zz+                         | {parsed = {none}, rest = x} =+                               {parsed = {none}, rest = x} }++    private inline lift(g, {parser: f}) =+        { parser text =+             let f' = f text+             in  g { text: text+                     f: f+                     parsed: f'.parsed+                     rest: f'.rest+                     f': f' }}++++       +    --  Alternative will try the first parser, and applies the second only if+    --  the first fails *and* consumes no input from the text.++    inline (<|>):+    +        Parser a      -> Parser a    -> Parser a+        {parser = f} <|> {parser = g} =++            let h text {parsed = {none}, rest = textt} when text == textt =+                    g text+                | _ x = x++            in {parser text = h text (f text)}++++    --  Tries to apply a parser, but restores the parser state in the case+    --  of a failure.  This is useful with combinators that check the+    --  state of the consumed text, like `<|>`++    inline try':++          Parser a    -> Parser a+        = lift λ (x & {_, parsed: {none}}) =+                     {parsed: {none}, rest: x.text}+               | x = x.f'++++    --  A parser that matches a string.  Unlike Haskell's Parsec library,+    --  parsec.forml will not consume any input if the entire string+    --  doesn't match.  This is for efficiency reasons currently, but+    --  may change in the future.++    inline string:+	+	  String -> Parser String              +        | x = { parser y = +                    let sub = do! `y.substring(0, x.length)`+                    if (sub == x)    +                        { rest   = do! `y.substring(x.length)`+                          parsed = {some = x} }+                    else {rest = y, parsed = {none}} }+                      +                      +    +    --  Applies a parser repeatedly, until parsing fails. ++    many:++          Parser a -> Parser (Array a)+        = lift λ (x & {_, parsed: {none}}) =+                     {parsed: {some: []}, rest = x.rest}+               | (y & {_, parsed: {some: x}}) =+                     (push! x <$> many {parser: y.f}).parser y.rest+                                  +              ++    module "Testing"++        {some = "ten"} == run_parser (string "ten") "tens"+        {some = "tenten"} == run_parser ((λx = x +++ x) <$> string "ten") "tenfingers"++        {parsed = {some = "tenten"}, rest = "fingers"} +            == ((λx = x +++ x) <$> string "ten").parser "tenfingers"++        var result = run_parser ((λx y = y +++ x) <$> string "ten" <*> string "fingers") "tenfingers"+        result == {some: "fingersten"}+        +        var result = run_parser (string "ten" <|> string "eleven") "eleven"+        result == {some: "eleven"}++        var result = run_parser (string "ten" *> string "fingers") "tenfingers"+        result == {some: "fingers"}++        var parser = (string "ten" *> string "fingers") <|> string "tentoes"+            result = run_parser parser "tentoes"+        result == {none}++        var parser = try' (string "ten" *> string "fingers") <|> string "tentoes"+            result = run_parser parser "tentoes"+        result == {some: "tentoes"}+                            +        var parser = many (string "ten")+            result = run_parser parser "tententententen"+        result == {some: ["ten", "ten", "ten", "ten", "ten"]}++        +    	                +    	                    	         +        
+ src/forml/prelude.forml view
@@ -0,0 +1,811 @@+-- Prelude+-- -------++-- If you are familiar with Haskell or ML, the prelude may serve as a +-- good introduction to forml.+-- Forml's syntax is quite liberal;  to illustrate, the prelude will +-- maintain an intentionally inconsistent style throughout.++-- First, we need to create a namespace with the `module` keyword.++module prelude+++    JS a = {} -> a++    inline object? x = do! `typeof x === "object"`+    inline array?    = do! `is_array`+    inline string? x = do! `typeof x === "string"`++    inline+    num? x = do! `typeof x == "number"`+++    inline type? x   = do! `typeof x`++    inline+    not: Bool -> Bool +    not x = do! `!x`+    not false+    ++    object? {}+    array? []+    not (array? {})+    not (object? 0)++++    -- Side effects can only happen in Javascript, so we use a monadic container to+    -- compose these bits.++    inline +    (>>=): JS a -> (a -> JS b) -> JS b+    (>>=)  x       y            = y (run x)++    inline +    (>>): JS a -> JS b -> JS b+    (>>)  x       y     = `run x; return (run y)`++    inline return:++             a -> JS a+      return x  = `x`++    +    do! x   <- `1 + 4`+        y   <- `2 + 3`+        ans <- `x + y`+        return (10 == ans)++    5  == do! return 5+    10 == do! `5 + 5`++++    inline log: a -> JS {} +              | x  = `console.log(x)`++    -- Testing to verify that escaping Javascript & utilizing escaped+    -- Javascript with `do` sugar and composition in general works as+    -- expected.++    var x = 0+        y = do z <- `x = 1`+               return z+    x == 0+++    -- Numbers+    -- -------+    -- Some basic aliases to native javascript infix functions.  These are type+    -- annotated to constrain inferrence - otherwise, these functions would all be+    -- inferred as `a -> b -> c`.++    inline (&&): Bool -> Bool -> Bool | x y = do! `x && y`+    inline (||): Bool -> Bool -> Bool | x y = do! `x || y`+    inline (*):  Num -> Num -> Num    | x y = do! `x * y`+    inline (/):  Num -> Num -> Num    | x y = do! `x / y`+    inline (%):  Num -> Num -> Num    | x y = do! `x % y`+    inline (+):  Num -> Num -> Num    | x y = do! `x + y`+    inline (-):  Num -> Num -> Num    | x y = do! `x - y`+    inline (<=): Num -> Num -> Bool   | x y = do! `x <= y`+    inline (>=): Num -> Num -> Bool   | x y = do! `x >= y`+    inline (<):  Num -> Num -> Bool   | x y = do! `x < y`+    inline (>):  Num -> Num -> Bool   | x y = do! `x > y`++    -- Equality is overloaded to match records and arrays. By constraining the type of+    -- this operator, we need only dispatch on the type of the first element,+    -- constraining ++    inline x != y = not (x is y)++    inline x /= y = not (x == y)++    (==): a -> a -> Bool+        | x y when do! `x === y` = true+        | x y when object? x =+            do! `var result = true;+                 for (key in x) {+                    result = result && y.hasOwnProperty(key) && _eq_eq(x[key])(y[key]);+                 };++                 var z = Object.keys(x).length +                             === Object.keys(y).length;++                 result && z`+                 +        | x y when array? x =+            do! `var result = true;+                 for (z in x) {+                     result = result && _eq_eq(x[z])(y[z]);+                 };++                 result && x.length == y.length`++        | x y = false++    -- And a few simple tests to verify the correctness of these+    -- implementations.  This is not meant to be exhaustive, only a smoke+    -- test against regressions.++    (3 * 4) + 5 * 4 == 64 / 2+    4 - 1 != 5 - 10+    (10 >= 5 + 5) != (4 + 5 <= 10 - 2)+    ({test: 1} == {test: 1}) == true+    ({test: 1} != {test: 1}) == false++    -- Fibonacci function++    fib 0 = 0 | 1 = 1 | n = fib(n - 1) + fib(n - 2)++    -- Speed+    -- -----++    -- Due to the nested recursion, `fib` is an excellent function for testing the+    -- runtime speed versus raw javascript.  `fast_fib` is a trivial javascript+    -- implementation of the same function, recursed itself to remove any potential+    -- overhead from forml's dispatch mechanism.++    module speedtest++        private inline get_time = `new Date().getTime()`++        time js =++            do start <- get_time+               js+               stop  <- get_time+               return (stop - start)++        private inline+        fast_fib =++            do! `var f = function(n) {+                     return 0 === n ? 0 : 1 === n ? 1 : f(n - 1) + f(n - 2)+                 }; f`+                +        fast_fib 7 == fib 7+        +        -- With this, we can set up a simple canary to let us know if the prelude is+        -- suddenly dramatically slower than it previously was; in this case, we fail a test+        -- if the forml version isn't at least 90% as fast as the native javascript+        -- version.++        floor: Num -> Num = do! `Math.floor`++        do! fast_time <- time yield fast_fib 30+            slow_time <- time yield fib 30+            return (floor (fast_time / slow_time * 100) >= 80)++    -- Function Combinators+    -- --------------------+    -- Simple left & right pipes, ala F#.  ++    inline x <| y = x y+    inline x |> y = y x+    +    3 |> (λy = y + 1) |> λy = y + 1 == 5+    (λy x z = x + y + z + 1) 1 <| 3 <| 4 == 9+    +    -- Alternatively, there is a right associative version of `<|`, ala+    -- haskell.  All operators which end with a `:` are right associative.++    inline x <: y = x y+    +    (λx = x - 3) <: (λx = x - 3) <: 5 + 5 == 4+    +    -- Function composition++    inline x .: y = λz = x y(z)+    inline id x = x+    inline flip(f) x y = f(y, x)++    inline x ' y = y x++     +    ((λx = x + 1) .: (λx = x * 2) .: λx = x - 3) 4 == 3+    id [1, 2, 3] == [1, 2, 3]+    flip (λx y = x - y) 3 5 == 2++++    -- Strings+    -- -------++    module string+        +        inline +        lstrip: String -> String+        lstrip x = do! `x.replace(/^\s+/, '')` + +        inline rstrip: String -> String | x = do! `x.replace(/\s+$/, '')` +        inline strip:  String -> String | = lstrip .: rstrip++        length: String -> Num | n = do! `n.length`++        inline +        (+++): a -> b -> String+        x +++ y = do! `"" + x + y`++        strip "    test    " is "test"++        -- interpolated strings++        let x = "test"+        in "hello `x`" is "hello test"++    open string++    -- Tests+    -- -----+    -- By invoking javascript, we can listen for exceptions.+             +    err x = do! `try {+                     x();+                     return false;+                 } catch (e) {+                     return e;+                 }`++    -- Option+    -- ------++    module option+        +        Option a = {some: a} | {none}+        +        option b {none} = b+             | _ {some: x} = x+             +        option 3 {some: 2} == 2++    module html++        HTML = { element:   a+                 inner:     JS String+                 on_click:  JS {} -> JS {}+                 set:       b -> JS {}+                 add_class: String -> JS {}+                 add_style: String -> String -> JS {} }++        get:+              String -> JS HTML+            | x = do el <- `$(x).get(0)`++                     return { element    = el+                              inner      = `el.innerHTML`+                              on_click y = `el.onclick = y`+                              set y      = `el.innerHTML = y`++                              add_class y =+                                  `el.setAttribute("class", el.getAttribute("class") + " " + y)`++                              add_style y z = `el.style[y] = z` }++        inline ($=):++           String -> a -> JS {}+           x      $= y  =++             `if (typeof $ != "undefined") {+                  var xx = $(x).get(0);+                  if (typeof xx != "undefined") {+                      xx.innerHTML = y;+                  }+              }`++        inline ($|): ++             String   -> String -> String -> JS {}+             selector $| rule      value   = `$(selector).css(rule, value)`++        inline +        ($.): String -> String -> JS {}+        ($.) x y = `$(x).addClass(y)`++        inline ($+): String -> String -> JS {}+            | x y = `$(x).append(y)`++        div: String -> JS String+            | x = yield "<div id='`x`'/>"++        move: HTML -> HTML -> JS a+            | x y = `$(y.element).append($(x.element).detach())`+                       +        on_load: JS {} -> JS {}+            | x = `window.addEventListener("load", x, false)`++        inline stringify: a -> String | x = do! `JSON.stringify(x)`++        inline (!!): Array a -> Num -> a | x y = do! `x[y]`++        with_page: JS<a> -> JS<a>+            | x = do old <- `$("body").clone()`+                     xx <- x+                     `$("body").replaceWith(old)`+                     return xx++        -- do! with_page do "body" $= "Test"+        --                  text <- get "body"+        --                  text <- text.inner+        --                  return (text == "Test")++        do! d <- div "test1"++            "body"   $+ d+            "#test1" $= "I am a test!"++            text <- get "#test1"+            text <- text.inner++            "#test1" $= ""++            return (text == "I am a test!")++        inline split: String -> String -> Array String | y x = do! `x.split(y)`+++        -- This is the initializer for prelude's console test suite. ++        console_runner: JS {} =++            var is_error = 0++            var get_line x =  x |> split "__::__"+                                |> \x = x !! 0+                                |> split "_" +                                |> \x = x !! 0+                                |> \x = do! `parseInt x`+                                |> \x = x + 1+                                |> stringify++            var report_failed spec results =++                    let items = spec.results_.items_+                        desc  = spec.description.split "__::__" !! 1+                        exp   = stringify (items !! 0).expected+                        act   = stringify (items !! 0).actual+                        line  = get_line spec.description+                    +                    do  if is_error == 0+                            then log "\r                        " +                            else return {}++                        `is_error = 1`++                        log "Test failed at line `line`++                             `desc`+                             +                                 Expected `exp`+                                 Actual   `act`"++                        log ""++            var report spec = ++                    do! results <- `spec.results()`+                        passed  <- `results.passed()`++                        if   passed +                        then return {}+                        else report_failed spec results++            var reporter = { reportSpecResults:   report +                             reportRunnerResults: `phantom.exit(is_error)` }++            do env <- `jasmine.getEnv()`++               `env.addReporter(reporter)`+               `env.execute()`+++        push : a -> Array a -> JS (Array a)+        push xs x = `xs.push(x)` ++        private console_reporter = {++            total    = 0+            failed   = 0++            messages = []++            reportSpecResults spec =++                do! results <- `spec.results()`+                    passed  <- `results.passed()`+                    `console_reporter.total++`++                    if not passed then do+                        `console_reporter.failed++`+                        push console_reporter.messages spec.description+                        return {}+                    else return {}++            reportRunnerResults =++                do if console_reporter.failed > 0+                       log console_reporter.messages+                   else +                       return {}+                         +                   log "`console_reporter.total - console_reporter.failed`/`console_reporter.total` tests passed"+        }++        -- This is the initializer for prelude's HTML test suite. ++        table_of_contents =++            do "code"  $. "prettyprint"+               "code"  $. "lang-hs"++               ".test" $| "position" <| "relative"+               ".test" $| "left"     <| "50px"++               `prettyPrint()`++               trivial <- `new jasmine.TrivialReporter()`+               forml  <- `new jasmine.FormlReporter()`+               env     <- `jasmine.getEnv()`++               `env.addReporter trivial`+               `env.addReporter forml`+               `env.addReporter console_reporter`++               `env.execute()`++               reporter <- get ".jasmine_reporter"+               body     <- get "#test_suite"++               move reporter body++    module array+    +        inline push! : x -> Array x -> Array x+        | x xs = do! `xs.unshift(x); xs`++++        +                       +    -- Lists+    -- -----+    -- A simple implementation of a library for manipulating linked lists.++    module list+    +        List a = { head: a, tail: List a } +               | { nil }+                 +        -- This complex type can be hidden behind a constructor function which+        -- works more like a traditional cons.++        inline +        x :: y = { head = x, tail = y }++        -- The compiler itself also supports the list sugar `[: 1, 2, 3 ]` (or+        -- `[: 1, 2, 3 :]`, if you prefer symmetry).  All of these lists are+        -- synonyms.++        var xs = [:++            [:1,2,3]++            [:1,2,3:]++            (1::2::3::{nil})++            { head = 1+              tail = { head = 2+                       tail = { head = 3+                                tail = {nil} }}}+        ]++        all? (λy = [:1,2,3] == y) xs +                           ++        -- Simple implementations of list accessors, which illustrate+        -- incomplete definition.++        empty? { nil } = true | _ = false++        head { head: x, tail: _ } = x+           | { nil } = error "Head called on empty list"+           +        tail { head: _, tail: x } = x +           | { nil } = error "Tail called on empty list"++        last { head: x, tail: { nil } } = x+        last { head: _, tail: x } = last x+        last { nil } = error "Last called on empty list"++        take 0 x = { nil } | n x = head x :: take (n - 1) (tail x)+        drop 0 x = x | n x = drop (n - 1) (tail x)++        x .. y = +            let f xx z when xx >= x = f (xx - 1) (xx :: z)+                f _ z = z ++            f y {nil}+           +        1 .. 5 == [:1,2,3,4,5]++        -- Project Euler problem 1, modified to protect the innocent:++        288045 == 1 .. 1111 |> filter (λx = x % 3 == 0 || x % 5 == 0) |> sum+++        take_while f { nil } = { nil }+                 | f x when f (head x) = head x :: filter f (tail x)+                 | _ _ = { nil }++        drop_while f { nil } = { nil }+                 | f x when f (head x) = drop_while f (tail x)+                 | _ x = x++        not (empty? (1 :: {nil}))+        empty? [:]+   +        head [: 1, 2 ] is 1+        tail [: 1, 2 ] is [:2]+        last [: 1, 2 ] is 2++        err (lazy head {nil}) is "Head called on empty list"+        err (lazy tail {nil}) is "Tail called on empty list"+        err (lazy last {nil}) is "Last called on empty list"++        take(2, [: 1, 2, 3 ]) == [: 1, 2 ]+        drop(2, [: 1, 2, 3 ]) == [: 3 ]++        take_while (λx = x < 0) [:] == [:]+        take_while (λx = x > 0) [: 2, 1, 0 ] == [: 2, 1 ]++        drop_while (λx = x < 0) {nil} == {nil}+        drop_while (λx = x > 0) [: 2, 1, 0 ] == [: 0 ]++        -- Cardinality+        +        length ++             | {nil}              = 0+             | {head: _, tail: x} = 1 + length x+             +        length [: 1, 2, 3, 4 ] == 4++        -- Generators++        init 0 _ = {nil}+           | n x = x :: init (n - 1) x+           +        length (init 30 0) == 30+        tail (init 3 0)    == init 2 0++        -- List concatenation++        (++)++           | {nil} y                = y+           | {head: y, tail: ys} xs = y :: (ys ++ xs)++        {nil} ++ (1 :: 2 :: {nil}) == 1 :: 2 :: {nil}+        [: 1, 2 ] ++ [: 3, 4 ] == [: 1, 2, 3, 4 ]+                  +        -- Filter.++        filter: (a -> Bool) -> List a -> List a+              | f {nil} = {nil}+              | f x when f (head x) = head x :: filter f (tail x)+              | f x = filter f <| tail x+        +        [: 1, 2, 3, 4 ] 'filter (λx = x > 2) == [: 3, 4 ]++        -- Map+       +        map(f, {nil}) = {nil}+        map(f, x)     = f(head(x)) :: map(f, tail(x))+          +        [: 2, 3, 4 ] == [: 1, 2, 3 ] |> map λx = x + 1+            +        -- Reverse++        reverse y = +            let r rest [:] = rest+                r rest { head: x, tail: xs } = +                    r (x :: rest) xs++            in  r {nil} y++        reverse [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]++        var test_x = [: 1, 2, 3, 4 ]+        test_x == reverse <| reverse test_x++        take' x y =+            let t(0, _, acc) = acc+                t(n, x, acc) = t(n - 1, tail x, head x :: acc)++            in  reverse t(x, y, {nil})++        var x = [: 1, 2, 3, 4, 5, 6, 7, 8 ]+        take 5 x == take' 5 x++        -- Folds++        foldl f x xs =+            var g y {nil} = y+                | y { head: z, tail: zs } = g (f y z) zs+            g x xs++        foldl1 _ {nil} = error "Foldl1 called on empty list"+             | f x = foldl f (head x) (tail x)+     +        foldr f x =+            var g {nil} = x+                g { head: y, tail: ys } = f y (g ys)+            g++        foldr1 _ {nil} = error "Foldr1 called on empty list"+             | f x = foldr f (head x) (tail x)+        +        all? f = foldl1 (λx y = x && y) .: map f+        any? f = foldl1 (λx y = x || y) .: map f++        sum     = foldl1 λ(x, y) = x + y+        product = foldl1 λ(x, y) = x * y+        +        concat = foldl1 λx y = x ++ y+        concat_map f xs = concat (map f xs)+        +        maximum = foldl1 λ(x, y) when x > y = x+                         |(_, y) = y++        minimum = foldl1 λx y = if x > y then y else x++        foldl (λx y = x + y) 0 [: 1, 2, 3, 4 ] == 10+        foldr (λx y = x + y) 0 [: 1, 2, 3, 4 ] == 10+        all? id [:true,true]+        not (all? id [:true,false])+        any? id [:true,false]+        not (any? id [:false,false])+        sum [:1,2,3] == 6+        product [:1,2,4] == 8++        let x = [:1,2], y = [:3,4]+        concat [:x,y] == [:1,2,3,4]++        concat_map (λx = [:x,x+1]) [:1,2] == [:1,2,2,3]+             +        minimum [: 1, 2, 3 ] == 1+        maximum [: 1, 2, 3 ] == 3+        ++    -- Sequences+    -- ---------+    -- Sequences are an abstract data type which resembles a list, except that elements+    -- Sequences may be infinite, as long as you never try to read every element.+    -- However, the current implementation is stack-consuming and thus limited by the+    -- underlying javascript runtime [TODO].  ++    module seq++        open list+        open speedtest+        open html+    +        Seq a = { seq: JS { elem: a, next: Seq a}}+              | { end }++        inline seq x = {seq: x}+                   +        iterate f x = seq yield { elem: x, next: iterate f (f x) }++        from_list {nil} = {end}+                | { head: x, tail: xs } =+                    { seq: yield { elem: x, next: from_list xs }}+                    +        to_list { end }    = {nil}+              | { seq: x } = do! { elem: y, next: ys } <- x+                                 return (y :: to_list ys)++        take _ {end} = {end}+           | 0 _ = {end}+           | x { seq: y } = seq do { elem: z, next: zs } <- y+                                   return { elem: z, next: take (x - 1) zs }++        to_list (from_list [:1,2]) == [:1,2]+        iterate (λx = x + 1) 0 |> take 100 |> to_list |> length == 100++        zip_with:+        +              (a -> b -> c) -> Seq a -> Seq b -> Seq c+            | _ {end}    _____    = {end}+            | _ _____    {end}    = {end}+            | f {seq: a} {seq: b} = seq do++                { elem: xx, next: xs } <- a+                { elem: yy, next: ys } <- b++                return { elem: f xx yy, next: zip_with f xs ys }+                                        +        inline x ::: y = seq yield { elem: x, next: do! y }+        +        tail:+              Seq a   -> Seq a+            | {end}    = error "tail called on empty seq"+            | {seq: t} = do! t >>= λx = return x.next+ +        to_lazy+              | {end} = {end}+              | {seq: y} = seq lazy do!+                    {elem: x, next: xs} <- y+                    return {elem: x, next: to_lazy xs}+ +        -- Infinite sequence example+ +        fibs = to_lazy <: 1 ::: return <: 1 ::: yield zip_with (λx y = x + y) fibs <: tail fibs+    +        -- Since the `lazy` keyword memoizes it's argument, this fibonacci implementation+        -- is ridiculously faster than the recursive version.  For example, the runtime+        -- speed of this fib implementation compared to the native recursive one is <span+        -- id="speedtest">__________</span>%.++        do! fast_time <- time yield fast_fib 30+            slow_time <- time yield fibs |> take 30 |> to_list |> last+            let ratio = floor (fast_time / slow_time * 100)+            "#speedtest" $= ratio+            return (ratio >= 2)++        fibs |> take 5 |> to_list == [:1,1,2,3,5]++        fast_fib 15 == fibs |> take 15+                            |> to_list+                            |> last+++    -- FormlZ+    -- -------+    -- Demonstration of some classic FP data structures.  This form of polymorphism can+    -- be simulated in Forml the same way they are implemented in Haskell - as a function+    -- dictionary, the only difference being that you must explicitly bind the dictionary+    -- instance to a symbol (as opposed to it being referenced by the type variable's+    -- instantiation).++    module "Forml Z"++        open list++        Functor f =++            { map: (a -> b) -> f a -> f b }++        Monad m =++            { (>>=): m a -> (a -> m b) -> m b+              ret: a -> m a }++        map z x f = z.map f x++        bind { ret: f, _ } x = f x++        list_functor =++            { map _ {nil} = {nil} +                | f { head: x, tail: xs } =+                      { head: f x+                        tail: list_functor.map f xs }}++        list_monad =++            { (>>=) x g = concat_map g x+              return x = [:x] }++        js_monad =++            { (>>=) x f = x >>= f+              return x = return x }++        let (>>>=) x g = concat_map g x+            z = 1 .. 3 >>>= λx = [:x, x + 1, x + 2]++        z == [:1,2,3,2,3,4,3,4,5]
+ src/forml/readme.forml view
@@ -0,0 +1,312 @@+-- Forml+-- -----++-- <script type="text/javascript">+-- $("header ul").prepend('<li><a href="https://github.com/texodus/forml/zipball/master">Download <strong>ZIP File</strong></a></li><li><a href="https://github.com/texodus/forml/tarball/master">Download <strong>TAR Ball</strong></a></li><li><a href="https://github.com/texodus/forml">View On <strong>GitHub</strong></a></li>').css("width", "360");+-- $("header h1").after('<p></p><p class="view"><a href="https://github.com/texodus/forml">View the Project on GitHub <small>texodus/forml</small></a></p><br style="clear: both;"/>');+-- </script>++-- Forml is an modern programming language for the discriminating+-- programmer.  More importantly, forml is my vanity project, an+-- attempt to learn ML by writing one.  ++-- Philosophy+-- ----------++--     1) Writing software is unnecessarily hard, because the language's+--        syntax treats the programmer like a machine.  A modern programming+--        language should be read and written for programmers - a philosophy+--        lifted unapologetically from [Ruby](http://www.artima.com/intv/ruby4.html).++--     2) Writing software is unnecessarily hard, because the language+--        lets the programmer make mistakes.  A modern programming language+--        should prevent the programmer from writing incorrect code, in so far+--        as it never conflicts with #1.++-- Features+-- --------++--   * Buzzwords:  functional, strict, expressive, pure(ish), static(y), inferred, fast, fun.+--     Strong like a gorilla, yet soft and yielding like a Nerf ball.++--   * Targets Javascript, but please regard this as an implementation detail -+--     forml is not intended as an answer to "the Javascript problem."  Simple+--     foreign function interface, which allows the+--     introduction of untyped values for quick & dirty+--     code integration, which can later be restricted via explicit typing.++--   * Type system which is designed to be simple and catch obvious errors,+--     not entirely exhaustive, dictatorial and somewhat combative (I'm looking+--     at you, Haskell).   Strucural types, partials records, arbitrary unions, +--     ability to introduce unrestricted types via FFI.++--   * Sugary, flexible syntax.++--   * Inline testing, compiles to a separate suite.++--   * Fast.  Automatic tail call optimization,+--     inline functions, designed for use with [Google Closure Compiler](https://developers.google.com/closure/)+--     advanced optimizations mode.++--   * Heavily inspired by +--          [Haskell](http://www.haskell.org/haskellwiki/Haskell)+--        , [F#](http://msdn.microsoft.com/en-us/vstudio/hh388569.aspx)+--        , [Coffeescript](http://coffeescript.org/).+--        , ([_](http://en.wikipedia.org/wiki/Category:ML_programming_language_family))([S](http://www.smlnj.org/))([OCA](http://caml.inria.fr/))ML+--        , [Clojure](http://clojure.org/)+--        , [JMacro](http://www.haskell.org/haskellwiki/Jmacro)+--        , [Ruby](http://www.ruby-lang.org/en/)++-- Installation+-- ------------++-- Mac OSX (tested on Snow Leopard & Lion).  Note that Forml also requires+-- [Closure](https://developers.google.com/closure/)for optimizations and+-- either [Phantom.js](http://phantomjs.org) or [Node.js](http://nodejs.org)++-- Install the+-- [Haskell Platform](http://hackage.haskell.org/platform/index.html), then++--        <pre><code>--$ cabal install forml</pre></code>++-- To compile some forml files:+   +--        <pre><code>--$ forml -o app test.forml test2.forml</pre></code>++-- will create an app.js and app.spec.js with the compiled code and+-- test suite respectively.++-- Forml will by default try to minify/optimize your code with Closure, via the+-- $CLOSURE environment variable, which should point to the closure jar.  Failing this,+-- forml will attempt to post your code to the Closure web service.++-- Additionally, forml will attempt to run the test suite with the phantomjs binary,+-- which it expects to find on your PATH.  You may optionally specifiy to run your suite+-- via node.js with++--        <pre><code>--$ forml -node-test test.forml</pre></code>++-- To compile literate+-- forml (eg, Forml code embedded in Markdown):+   +--        <pre><code>--$ forml test.lforml</pre></code>+   +-- To see the inferred types:+   +--        <pre><code>--$ forml -t test.forml</pre></code>+   +-- To turn off optimizing (eg, Closure) or testing:+   +--        <pre><code>--$ forml -no-test -no-opt test.forml</pre></code>++-- To watch a file for changes and incrementally compile:+   +--        <pre><code>--$ forml -w test.forml</pre></code>++-- To generate an HTML (like this one!) and test suite:+   +--        <pre><code>--$ forml -docs test.forml</pre></code>+++-- Tutorial+-- --------+-- This is unfortunately not comprehensive, and presumes some working knowledge of +-- ML or Haskell.  For more examples, see the annotated +-- [prelude](http://texodus.github.com/forml/Prelude)+-- and [parsec](http://texodus.github.com/forml.Parsec.html).  ++-- Forml supports a flexible, forgiving syntax that supports many synonymous forms.+-- This will be illustrated by adherring to an entirely random, arbitrary style throughout.++-- All forml programs must reside in a module.+-- Within a module, the compiler recognizes logical sections divided by +-- `open` statements and sub modules.  Within a section, declarations+-- can be in any order.++module readme++    open prelude+    open prelude.string++    -- Simple function.  Forml allows functions to be written in ML style, or+    -- in more traditional java style.++    square x = x * x++    add(x, y) = x + y++    -- With pattern matching++    fib 0 = 0 | 1 = 1 | n = fib (n - 1) + fib (n - 2)++    -- Patterns can be separated with `|`, or by repeating the definition's+    -- name ala Haskell.  Definitions can have optional type annotations and+    -- assertions (which are compiled separately from your application code).++    private++    fib' : Num -> Num++    fib' 0 = 0+    fib' 1 = 1+    fib' n = fib' (n - 1) + fib' (n - 2)++    fib' 7 == 13+    fib' 0 == 0++    -- Forml has the basic primative types from Javascript:  Num, String, Bool;  plus+    -- a record, which is structurally typed and implemented as a simple Javascript object.+    +    person name address = { +        name    = name+        address = address+        message = "`name` lives at `address`"+    }++    person("Andrew", "123 Fake St.").message is "Andrew lives at 123 Fake St."++    point = {x: 10, y: 10}+    +    20 == point.x + point.y+   +    -- Also supports partial records.++    magnitude {x: x, y: y, _} = sqrt (square x + square y)++    magnitude {x: 3, y: 4, other: "test"} == 5+    magnitude {x: 4, y: 3, test: "other"} == 5++    -- Operators can be defined much like in Haskell.  Precedence is currently fixed,+    -- though you can declare right associative operators by ending them with a `:`.+    -- For performance, you can declare functions to be `inline`.  This example+    -- will compile to a loop, as it is tail recursive.++    inline (**): ++         String -> Num -> String+         text   ** n    =++             var f(_, 0, acc) = acc       -- `let` and `var` are synonyms+                 f(text, n, acc) =+                     f(text, n - 1, acc +++ text)+             +             in f(text, n, "")            -- `in` is optional+++    "hello" ** 3 == "hellohellohello"+    length ("a" ** 10000) == 10000++    -- Anonymous functions also follow Haskell, can be written with `\` or `λ`, and+    -- allows pattern seperation via `|`++    -- Note this function mutates its argument, so we name it with an exclamation.++    map!: (a -> b) -> Array a -> Array b+    map! f xs = do! `xs.map(f)`++    let fil = λ x when x > 5 = x+              | x            = 5++    map! fil [2, 6, 3, 7] is [5, 6, 5, 7]++    -- Interop / Side Effects+    -- ----------------------+    -- Forml technically allows unrestricted side effects, but by default+    -- wraps them in a `JS a` type, which can be composed with the+    -- `>>=` and `>>` operators, or a variation of Haskell's `do` notation.++    hello_world = do++        `console.log("Hello World")` -- Calls to Javascript always return type `JS a`+        x <- `Math.sqrt(9)`          -- `x` is inferred to be the unrestricted type `a`+        let z = x + 1                -- `x` is now restricted to type `Num`+        return (z + 1)               -- type of `hello_world` is inferred to be `JS Num`++    8 == do! hello_world >>= λx = `x + 3`++    -- Though this function is inferred to be `a -> b`, you can restrict it with+    -- a signature.  ++    inline+    sqrt: Num -> Num                 +    sqrt x = do! `Math.sqrt(x)`      -- `do!` realizes its argument immediately++    -- Forml also supports additional keywords `lazy` and `yield`.  Both take+    -- expressions as arguments (as opposed to `do` syntax), but return an+    -- unrealized type `JS a`, the difference being that `lazy` will only+    -- evaluate it's arguments once, then cache the result.++    let x = 0+        test = lazy do! `x = x + 1; x`++    in  1 == do! test >> test >> test >> test++    -- Types, Aliases & Unions+    -- -----------------------++    -- Forml lacks algebraic data types in the ML sense, instead opting for+    -- only structural typing of records.  However, you can add explicit type+    -- signatures to tell the Forml compiler it is OK to overload the types+    -- of specific symbols.++    num_or_string:++          (Num | String) -> String+        | x when num? x   = "Num"+        | _               = "String"++    -- You can also gives union types such as these an alias, effectively allowing+    -- algebraic data types to be declared in a local scope, for all+    -- records which are structurally equivalent to those declared.  For instance,+    -- we could declare a `Maybe a` ADT in forml via+  +    Maybe a = {just: a} | {nothing}++    -- ... where `{nothing}` is shorthand for the strucural type `{nothing: {}}`.+    -- Any scope which imports the alias `Maybe a` will now allow values which+    -- can be typed both a `{just: a}` or `{nothing}` record++    maybe x {just: y} = y+    maybe x {nothing} = x++    maybe 3 {just: 4} == 4+    maybe 3 {nothing} == 3++    -- In case this sort of things floats your boat, you can also declare+    -- polymorphic types in "java" style, with `< >`.++    has_value: Maybe<a> -> Bool+    has_value {just: _} = true+    has_value _ = false++    has_value {just: 4}+    not (has_value {nothing})+    +    -- Changes+    -- -------+    +    -- 0.1.1++    -- * Documentation generation has been greatly improved.  Better styling, generates individual pages for each file.+    -- * The prelude is now embedded in the compiler.  Simply import it via `open prelude` - the compiler will include+    --   the code automatically.  Currently weighs in at ~11k, if you care about that sort of thing.+    -- * Command line interface is more pleasant to work with ++++    ++    ++++    +++++    ++    ++    
+ src/forml/tests.forml view
@@ -0,0 +1,145 @@++-- Tests+-- -----+-- A collection of tests for compiler bugs, benchmarking, etc.++-- Benchmarks+-- ----------+-- A collection of simple benchmarks.  You can view the results+-- by opening your browser's terminal.++module "Benchmarks for the prelude"+    +    title x = +        do log "\r                                  "+           log x+           return true++    open prelude+    open prelude.speedtest+    open prelude.list+    open prelude.string++    -- Here we have 5 implementations of +    -- (Project Euler problem #1)[http://projecteuler.net/problem=1].+    -- The first is simply a native JS implementation.++    euler_1 x = `var sum = 0;+                 for (var i = 1; i < x; i++) {+                     if (i % 3 == 0 || i % 5 == 0) sum += i;+                 };+                 return sum;`++    -- The second is a tail recursive.  The forml compiler will +    -- optimize simple functions which are tail recursive into +    -- javascript `for` loops automatically, making them+    -- much faster.++    euler_2 x y when x < 3 = y+          | x y when x % 3 == 0 || x % 5 == 0 =+                euler_2 (x - 1) (y + 1)+          | x y = euler_2 (x - 1) y++    euler_3 x when x < 3 = 0+    euler_3 x = if x % 3 == 0 || x % 5 == 0+                then 1 + euler_3 (x - 1)+                else euler_3 (x - 1)++    euler_4 z = yield 1 .. z +                      |> filter (λx = x % 3 == 0 || x % 5 == 0)+                      |> sum++    euler_5 x y when x < 3 = y+          | x y when do! `x % 3 == 0 || x % 5 == 0` =+                euler_5 (x - 1) (y + 1)+          | x y = euler_5 (x - 1) y++    do! title "Relative Speeds (10k)"++        w <- time (euler_1 10000)+        x <- time yield euler_2 10000 0+        y <- time yield euler_3 10000+        z <- time (euler_4 10000)+        q <- time yield euler_5 10000 0++        log "  Native JS:          `w / 1000`s"+        log "  Forml TCO Unboxed: `q / 1000`s"+        log "  Forml TCO:         `x / 1000`s"+        log "  Forml Recursive:   `y / 1000`s"+        log "  Forml list:        `z / 1000`s"+        +        return <| (x <= y && y < z)++    string? (err yield euler_3(250000)).message++    do! title "Relative Speeds (2.5M)"++        w <- time (euler_1 2500000)+        x <- time yield euler_2 2500000 0+        y <- time yield euler_5 2500000 0+        +        log "  Native JS:          `w / 1000`s"+        log "  Forml TCO Unboxed: `y / 1000`s"+        log "  Forml TCO:         `x / 1000`s"+        log "  Forml Recursive:   `err yield euler_3(250000)`"+        log "  Forml list:        `err (euler_4 250000)`"++        log ""+        +        return <| (w < x)+++module "Tests for partial records"++    open prelude++    var f {a: x, b: y, _ } = x + y+    f { a: 5, b: 5, c: 5 } == f { a: 5, b: 5, d: 5 }++    var f {a: 1, b: 1, _ } = 2+        f {b: 2, c: 2, _ } = 2+    f {a:1,b:1,c:3,d:5} + f {a:1,b:2,c:2,e:5} == 4+      +    var f { a = 1, b = 2, _ } = 1+        g { b = 2, c = 3, _ } = 2+        x = { a = 1, b = 2, c = 3, d = 4 }+    f x + 1 == g x++module "Tests for TCO bugs"+    +    open prelude+    open prelude.list++    rev_1 y = +        var r rest [:] = rest+            | rest { head: x, tail: xs } = +                r (x :: rest) xs++        r {nil} y++    rev_2 = +        var rrr rest [:] = rest+            rrr rest { head: x, tail: xs } = +                rrr (x :: rest) xs++        rrr {nil}+     +    rev_2 [: 1, 2, 3, 4 ] == [: 4, 3, 2, 1 ]++    test_x = [: 1, 2, 3, 4, 5, 6, 7 ]++    rev_2 test_x == rev_1 test_x+    rev_1 test_x == reverse test_x+    length (rev_2 test_x) == length (rev_1 test_x)+    length (rev_2 test_x) == length test_x+    length (rev_1 test_x) == length (reverse test_x)+++module "Tests for parser bugs"++    open prelude+    open prelude.string+    open prelude.html++    var x = do! `[ {x: 1}, {x: 2}, {x: 3} ]`+    stringify (x !! 0).x == "1"
+ src/hs/Forml/CLI.hs view
@@ -0,0 +1,111 @@++module Forml.CLI where+++import Control.Monad.State hiding (lift)++import System.Console.ANSI+import System.Exit+import System.IO+import System.Process++import Data.String.Utils++++data TestMode  = NoTest | Node | Phantom++data RunConfig = RunConfig { inputs :: [String]+                           , output :: String+                           , show_types :: Bool+                           , optimize :: Bool+                           , run_tests :: TestMode+                           , write_docs :: Bool+                           , watch :: Bool }+++parseArgs :: [String] -> RunConfig+parseArgs = fst . runState argsParser++  where argsParser = do args <- get+                        case args of+                          []     -> return $ RunConfig [] "default" False True Phantom False False+                          (x':xs) -> do put xs+                                        case x' of+                                         "-w"    -> do x <- argsParser+                                                       return $ x { watch = True }+                                         "-docs"    -> do x <- argsParser+                                                          return $ x { write_docs = True }+                                         "-t"    -> do x <- argsParser+                                                       return $ x { show_types = True }+                                         "-no-opt" -> do x <- argsParser+                                                         return $ x { optimize = False }+                                         "-no-test" -> do x <- argsParser+                                                          return $ x { run_tests = NoTest }+                                         "-node-test" -> do x <- argsParser+                                                            return $ x { run_tests = Node }+                                         "-o"    -> do (name:ys) <- get+                                                       put ys+                                                       RunConfig a _ c d e f g <- argsParser+                                                       return $ RunConfig (x':a) name c d e f g+                                         ('-':_) -> error "Could not parse options"+                                         z       -> do RunConfig a _ c d e f g <- argsParser+                                                       let b = last $ split "/" $ head $ split "." z++                                                       return $ RunConfig (x':a) b c d e f g++++warn :: String -> a -> IO a+warn x js = colors ((putStr $ "[-] " ++ x) >> return js) $+            do putStr "\r["+               setSGR [SetColor Foreground Dull Yellow]+               putStr "-"+               setSGR []+               putStrLn$ "] " ++ x+               return js++colors :: IO a -> IO a -> IO a+colors failure success =++          do (_, Just std_out', _, p) <-+                 createProcess (shell "tput colors 2> /dev/null") { std_out = CreatePipe }+             waitForProcess p+             c <- hGetContents std_out'+             case reads (strip c) of+                [(x, "")] | x > (2 :: Integer) -> success+                _ -> failure++++monitor :: String -> IO (Either [String] a) -> IO a+monitor x d = do colors (return ()) $ putStr $ "[ ] " ++ x+                 hFlush stdout+                 d' <- d+                 case d' of+                   Right y -> colors ((putStrLn $ "[*] " ++ x) >> return y) $+                              do putStr "\r["+                                 setSGR [SetColor Foreground Dull Green]+                                 putStr "*"+                                 setSGR []+                                 putStrLn$ "] " ++ x+                                 return y+                   Left y  -> colors (errors y) $+                              do putStr "\r["+                                 setSGR [SetColor Foreground Dull Red]+                                 putStr "X"+                                 setSGR []+                                 putStrLn$ "] " ++ x+                                 putStrLn ""+                                 if length y <= 5+                                    then mapM putStrLn y >> return ()+                                    else mapM putStrLn (take 5 y) >> putStrLn ("\n" ++ show (length y - 5) ++ " additional errors")+                                 exitFailure++     where errors y =+                  do putStrLn ("[X] " ++ x)+                     if length y <= 5+                        then mapM putStrLn y >> return ()+                        else mapM putStrLn (take 5 y) >> putStrLn ("\n" ++ show (length y - 5) ++ " additional errors")+                     exitFailure+
+ src/hs/Forml/Closure.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TupleSections #-}++module Forml.Closure where++import Control.Applicative++import System.IO+import System.Environment+import System.Directory+import System.Process++import Network.HTTP+import Network.URI++import Data.List as L+import Data.URLEncoded+import Data.Maybe (fromMaybe)++++closure_local :: String -> String -> IO (Either a String)+closure_local x y =++        do env' <- L.lookup "CLOSURE" <$> getEnvironment+           case env' of+             Just env ->+                 do exists' <- doesFileExist env+                    if exists' +                        then do putStr "[local]"+                                hFlush stdout+                                writeFile "temp.js" x+                                system$ "java -jar $CLOSURE --compilation_level "+                                          ++ y +                                       --   ++ " --formatting=pretty_print --formatting=print_input_delimiter "+                                          ++ " --js temp.js --warning_level QUIET > temp.compiled.js"+                                js <- readFile "temp.compiled.js"+                                system "rm temp.js"+                                system "rm temp.compiled.js"+                                return $ Right js+                        else putStr " remote]" >> hFlush stdout >> closure x y+             Nothing -> putStr " remote]" >> hFlush stdout >> closure x y++++closure :: String -> String -> IO (Either a String)+closure x z = do let uri = fromMaybe undefined $ parseURI "http://closure-compiler.appspot.com/compile" ++                     y = export$ importList [ ("output_format",     "text")+                                            , ("output_info",       "compiled_code")+                                            , ("compilation_level", z)+                                            , ("js_code",           x) ]++                     args = [ mkHeader HdrContentLength (show$ length y)+                            , mkHeader HdrContentType "application/x-www-form-urlencoded" ]++                 rsp <- simpleHTTP (Request uri POST args y)+                 txt <- getResponseBody rsp++                 putStr "[remote]"+                 hFlush stdout++                 return$ Right txt
+ src/hs/Forml/Doc.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE NamedFieldPuns       #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes          #-}+{-# LANGUAGE RankNTypes           #-}+{-# LANGUAGE RecordWildCards      #-}+{-# LANGUAGE TemplateHaskell      #-}+{-# LANGUAGE TupleSections        #-}+{-# LANGUAGE ViewPatterns         #-}+++module Forml.Doc where++import Text.InterpolatedString.Perl6+import Text.Pandoc++import Data.Char         (isAscii, ord)+import Data.String.Utils++import Forml.Parser+import Forml.Static+import Forml.CLI++type Source   = String+type Title    = String+type Error    = String+type Filename = String++toEntities :: String -> String+toEntities [] = ""+toEntities (c:cs) | isAscii c = c : toEntities cs+                  | otherwise = [qq|&#{ord c};{toEntities cs}|]++toHTML :: String -> String+toHTML = toEntities . writeHtmlString defaultWriterOptions . readMarkdown defaultParserState+++to_literate :: String -> String -> String+to_literate "(Prelude)" = id+to_literate filename+    | (head . tail . split "." $ filename) == "forml" = unlines . map l . lines+    | otherwise = id++    where l (lstrip -> '-':'-':xs) = lstrip xs+          l x = "    " ++ x+++get_title :: String -> String -> (String, String)+get_title d x = case lines x of+                  z @ ((strip -> ('-':'-':_:x')):('-':'-':_:'-':_):_) ->+                      (x', unlines $ drop 2 z)+                  _ -> (d, x)+++docs :: String -> [String] -> [Title] -> [Program] -> [Source] -> IO ()+docs _ [] [] [] [] = return ()+docs js (tests:testses) (title:titles) (program @ (Program xs):programs) (source:sources) =++  let html     = highlight (get_tests xs) $ toHTML (annotate_tests source program)++      filename = [qq|$title.html|]+      compiled = [qq|<script>$js $tests</script>|]+      hook     = [qq|<script>$htmljs;window.document.title='{title}';$('h1').html('{title}')</script>|]++  in  do monitor [qq|Docs {title}.html|] $+            do writeFile filename $ concat [header, css', scripts, compiled, html, hook, footer]+               return $ Right ()+         +         docs js testses titles programs sources++docs _ _ _ _ _ = error "Paradox: `docs` called with non equivalent arguments"
+ src/hs/Forml/Javascript.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE FlexibleContexts, FlexibleInstances, FunctionalDependencies,+             MultiParamTypeClasses, NamedFieldPuns, OverlappingInstances,+             QuasiQuotes, RankNTypes, RecordWildCards, TypeSynonymInstances,+             UndecidableInstances #-}++module Forml.Javascript (render, render_spec) where++import Language.Javascript.JMacro+import Prelude                    hiding (curry, (++))++import Forml.Types.Statement++import qualified Data.Map as M++import Forml.Javascript.Backend+import Forml.Parser++++class Compress a where+    comp :: a -> a++instance (Compress a, Compress b) => Compress (a, b) where+    comp (a, b) = (comp a, comp b)++instance (Compress a) => Compress [a] where+    comp x = map comp x++instance (Functor m, Compress a) => Compress (m a) where+    comp x = fmap comp x++instance Compress JStat where+    comp (ReturnStat x)      = ReturnStat (comp x)+    comp (IfStat a b c)      = IfStat (comp a) (comp b) (comp c)+    comp (WhileStat a b)     = WhileStat (comp a) (comp b)+    comp (ForInStat a b c d) = ForInStat a b (comp c) (comp d)+    comp (SwitchStat a b c)  = SwitchStat (comp a) (comp b) (comp c)+    comp (TryStat a b c d)   = TryStat (comp a) b (comp c) (comp d)+    comp (BlockStat xs)      = BlockStat (comp xs)+    comp (ApplStat a b)      = ApplStat (comp a) (comp b)+    comp (PPostStat a b c)   = PPostStat a b (comp c)+    comp (AssignStat a b)    = AssignStat (comp a) (comp b)+    comp (UnsatBlock a)      = UnsatBlock (comp a)++    comp x = x++    -- comp (DeclStat    Ident (Maybe JLocalType)+    -- comp (UnsatBlock (IdentSupply JStat)+    -- comp (AntiStat   String+    -- comp (ForeignStat Ident JLocalType+    -- comp (BreakStat++instance Compress JVal where+    comp (JList xs)   = JList (comp xs)+    comp (JHash m)    = JHash (M.map comp m)+    comp (JFunc xs x) = JFunc xs (comp x)+    comp (UnsatVal x) = UnsatVal (comp x)++    comp x = x++    -- comp x@(JVar _) = x+    -- comp x@(JDouble _) = x+    -- comp x@(JInt _) = x+    -- comp x@(JStr _) = x+    -- comp x@(JRegEx _) = x++instance Compress JExpr where+    comp (SelExpr e (StrI i))  = IdxExpr (comp e) (ValExpr (JStr i))  -- Closure fix - advanced mode nukes these+    comp (IdxExpr a b)         = IdxExpr (comp a) (comp b)+    comp (InfixExpr a b c)     = InfixExpr a (comp b) (comp c)+    comp (PPostExpr a b c)     = PPostExpr a b (comp c)+    comp (IfExpr a b c)        = IfExpr (comp a) (comp b) (comp c)+    comp (NewExpr a)           = NewExpr (comp a)++   -- comp (ApplExpr (ValExpr (UnsatVal (JFunc [z] y))) [x])++    comp (ApplExpr a b)        = ApplExpr (comp a) (map comp b)+    comp (TypeExpr a b c)      = TypeExpr a (comp b) c+    comp (ValExpr a)           = ValExpr (comp a)+    comp (UnsatExpr a)         = UnsatExpr (comp a)+    comp _ = error "Compression"++render :: Program -> String -> Program -> String+render (Program ys) src (Program xs) = show . renderJs $ (comp . runJS src . toJS . map (empty_meta Library ys) $ xs)++render_spec :: Program -> String -> Program -> String+render_spec (Program ys) src (Program xs) = show . renderJs . wrap . runJS src . toJS . map (empty_meta Test ys) $ xs+    where wrap x = [jmacro| describe("", function() { `(x)`; }); |]+++
+ src/hs/Forml/Javascript/Backend.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances, KindSignatures #-}++module Forml.Javascript.Backend where+        +        import Forml.Types.Namespace+        import Forml.TypeCheck.Types+        import Forml.Parser.Utils +        +        import Data.Monoid      +        import Data.String.Utils+        import Text.Parsec (sourceLine)+            +        type TypeSystem = [(Namespace, [Assumption])]+        +        data JSState = JSState { src :: String+                               , assumptions :: TypeSystem }+        +        newtype JS a = JS (JSState -> (JSState, a))+        +        instance Monad JS where+          fail x     = JS (\_ -> error$ x) +          return x   = JS (\y -> (y, x))+          JS f >>= g = JS (\x -> case f x of+                                  (y, x') -> let JS gx = g x'+                                             in  gx y)+         +        instance Functor JS where+            fmap f y = y >>= (\x -> JS (\x' -> (x', f x)))+        +        class Javascript e t | e -> t where toJS :: e -> JS t+        +        runJS :: String -> JS t -> t+        runJS src (JS f) = snd . f $ JSState src []+        +        instance (Javascript a b, Monoid b) => Javascript [a] b where+        +                toJS []     = return mempty+                toJS (x:xs) = do x'  <- toJS x+                                 xs' <- toJS xs+                                 return $ mappend x' xs'+                                 +        get_error :: Addr a -> String -> String+        get_error (Addr (sourceLine -> x) (sourceLine -> y) _) =+        +             rstrip . unlines . lines . rstrip . unlines . take ((y - x) + 1) . drop (x - 1) . lines+     
+ src/hs/Forml/Javascript/Test.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE NamedFieldPuns       #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes          #-}+{-# LANGUAGE RankNTypes           #-}+{-# LANGUAGE RecordWildCards      #-}+{-# LANGUAGE TemplateHaskell      #-}+{-# LANGUAGE TupleSections        #-}++module Forml.Javascript.Test where++import Text.InterpolatedString.Perl6++import Control.Concurrent++import System.Exit+import System.IO+import System.Process++import Forml.CLI+import Forml.Static++test :: RunConfig -> String -> String -> String -> IO ()+test RunConfig { run_tests = Node } js title tests =++      monitor [qq|Testing {title}.js [Node.js]|] $+      do (Just std_in, Just std_out, _, p) <-+             createProcess (proc "node" []) { std_in = CreatePipe, std_out = CreatePipe }++         forkIO $ do errors <- hGetContents std_out+                     putStr errors+                     hFlush stdout++         hPutStrLn std_in$ jasmine+         hPutStrLn std_in$ js ++ "\n\n"+         hPutStrLn std_in$ tests+         hPutStrLn std_in$ console++         z <- waitForProcess p+    +         case z of+           ExitFailure _ -> return$ Left []+           ExitSuccess   -> return$ Right ()++test rc @ RunConfig { run_tests = Phantom } js title tests =++      monitor [qq|Testing {title}.js [Phantom.js]|] $+      do writeFile (output rc ++ ".phantom.js")+               (jquery ++ jasmine ++ js ++ tests ++ console)++         (Just std_in, Just std_out, _, p) <-+             createProcess (proc "phantomjs" [output rc ++ ".phantom.js"]) { std_in = CreatePipe, std_out = CreatePipe }++         forkIO $ do errors <- hGetContents std_out+                     putStr errors+                     hFlush stdout++         z <- waitForProcess p++         system$ "rm " ++ output rc ++ ".phantom.js"++         case z of+             ExitFailure _ -> return$ Left []+             ExitSuccess   -> return$ Right ()+             +test _ _ _ _ = warn "Testing" ()
+ src/hs/Forml/Javascript/Utils.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE OverlappingInstances #-}++{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}++module Forml.Javascript.Utils where+++import Text.InterpolatedString.Perl6+import Language.Javascript.JMacro+import Data.Monoid+import Data.String.Utils++import Prelude hiding (curry, (++), error)+++prelude :: String+prelude = show $ renderJs +          [jmacro| function !is_array(x) { +                       return `(InfixExpr "instanceof" x (ref "Array"))`;+                   }++                   var !__undefined__ = "undefined";++                   function !run(x) { return x(); }++                   function !error(x) { throw x; }++                   function !exhaust() { error("Pattern Match Exhausted"); }++                   function !__check(x, y) {+                       return x.hasOwnProperty(y);+                   } |]++instance (ToStat a) => ToStat [a] where+    toStat [] = mempty+    toStat x = foldl1 mappend . map toStat $ x++--------------------------------------------------------------------------------+----+---- Metadata+++--------------------------------------------------------------------------------+----+---- Utilities++(++) :: Monoid a => a -> a -> a+(++) = mappend++end :: forall a. [a] -> [a]+end (reverse -> x : xs) = x : reverse xs+end _ = fail "End is not defined for empty lists"++ref :: String -> JExpr+ref name    = ValExpr (JVar (StrI name))++func :: String -> JStat -> JStat+func var ex = ReturnStat (ValExpr (JFunc [StrI var] (BlockStat [ex])))++declare_this :: forall a. ToJExpr a => [Char] -> a -> JStat+declare_this name expr =++    [jmacro| `(declare (replace " " "_" name) expr)`;+             this[`(replace " " "_" name)`] = `(ref (replace " " "_" name))`; |]++declare_window :: forall a. ToJExpr a => [Char] -> a -> JStat+declare_window name expr =++    [jmacro| `(declare (replace " " "_" name) expr)`;+             (typeof global == "undefined" ? window : global)[`((replace " " "_" name))`] = `(ref (replace " " "_" name))`; |]+declare :: forall a. ToJExpr a => [Char] -> a -> JStat++declare name expr = +     [jmacro| `(DeclStat (StrI (replace " " "_" name)) Nothing)`;+              `(ref (replace " " "_" name))` = `(expr)`; |]+             +declare_scope :: String -> JExpr -> JStat -> JStat+declare_scope name expr stat =++    BlockStat [ReturnStat (ApplExpr (ValExpr (JFunc [StrI name] stat)) [expr])]++curry :: Int -> (String -> String) -> JStat -> JStat+curry 0 _ jexpr = jexpr+curry n f jexpr = func (f $ local_pool $ n - 1) (curry (n - 1) f jexpr)++local_pool :: Int -> String+local_pool n = [qq|__{ "abcdefghijklmnopqrstuvqxyz" !! n }__|]++scope :: forall a. ToStat a => a -> JExpr+scope x = [jmacroE| (function() { `(x)`; })() |]
+ src/hs/Forml/Optimize.hs view
@@ -0,0 +1,330 @@++{-# LANGUAGE FlexibleContexts       #-}+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs                  #-}+{-# LANGUAGE MultiParamTypeClasses  #-}+{-# LANGUAGE NamedFieldPuns         #-}+{-# LANGUAGE OverlappingInstances   #-}+{-# LANGUAGE QuasiQuotes            #-}+{-# LANGUAGE RankNTypes             #-}+{-# LANGUAGE RecordWildCards        #-}+{-# LANGUAGE ScopedTypeVariables    #-}+{-# LANGUAGE TemplateHaskell        #-}+{-# LANGUAGE TypeSynonymInstances   #-}+{-# LANGUAGE UndecidableInstances   #-}+{-# LANGUAGE ViewPatterns           #-}++module Forml.Optimize where+import System.IO.Unsafe ()++import Language.Javascript.JMacro++import qualified Data.Map as M++import Control.Applicative+import Control.Monad+import Data.Char+import Data.Monoid++import Forml.Types.Axiom+import Forml.Types.Definition+import Forml.Types.Expression+import Forml.Types.Namespace  hiding (Module)+import Forml.Types.Pattern+import Forml.Types.Statement  hiding (Test, find, modules, namespace)+import Forml.Types.Symbol++import Forml.TypeCheck.Types hiding (get_namespace)++import Forml.Parser+import Forml.Parser.Utils++import qualified Forml.Javascript.Utils as J++import Prelude hiding (curry)+++++type Inlines = [((Namespace, Symbol), (Match (Expression Definition), Expression Definition))]+type Inline  = [(Symbol, (Match (Expression Definition), Expression Definition))]++data OptimizeState = OptimizeState { ns :: Namespace+                                   , assumptions :: [(Namespace, [Assumption])]+                                   , inlines :: Inlines+                                   , tco :: [String]+                                   , env :: Inline }++data Optimizer a = Optimizer (OptimizeState -> (OptimizeState, a))++instance Monad Optimizer where++    fail   x = Optimizer (\y -> error x)+    return x = Optimizer (\y -> (y, x))++    Optimizer f >>= g =+        Optimizer (\x -> case f x of (y, x) -> let Optimizer gx = g x in gx y)++instance Functor Optimizer where++    fmap f (Optimizer g) = Optimizer (\x -> case g x of (y, x) -> (y, f x))++instance Applicative Optimizer where++    pure = return+    x <*> y = do f <- x+                 f <$> y++class Optimize a where++    optimize :: a -> Optimizer a++set_namespace :: Namespace -> Optimizer ()+set_namespace ns' = Optimizer (\x -> (x { ns = ns' }, ()))++get_namespace :: Optimizer Namespace+get_namespace  = Optimizer (\x -> (x, ns x))++set_inline :: Inlines -> Optimizer ()+set_inline ns' = Optimizer (\x -> (x { inlines = ns' }, ()))++get_inline :: Optimizer Inlines+get_inline  = Optimizer (\x -> (x, inlines x))++set_env :: Inline -> Optimizer ()+set_env ns' = Optimizer (\x -> (x { env = ns' }, ()))++get_env :: Optimizer Inline+get_env  = Optimizer (\x -> (x, env x))++add_tco :: String -> Optimizer ()+add_tco x = Optimizer (\y -> (y { tco = x : tco y }, ()))++with_env :: forall b. Optimizer b -> Optimizer b+with_env xs =++    do e <- get_env+       xs' <- xs+       set_env e+       return xs'++get_addr :: Addr a -> a+get_addr (Addr _ _ x) = x++instance (Optimize a) => Optimize (Addr a) where++    optimize (Addr s e a) = Addr s e <$> optimize a++instance Optimize (Expression Definition) where++    optimize (ApplyExpression f' @ (SymbolExpression f) args) =++        do is <- get_env+           case f `lookup` is of+             Just (m @ (Match pss _), ex) | length pss == length args ->++                 do args' <- mapM optimize args+                    ex'   <- optimize ex+                    m'    <- optimize m+                    return $ ApplyExpression (FunctionExpression [EqualityAxiom m' (Addr undefined undefined ex')]) args'++             _ -> ApplyExpression <$> optimize f' <*> mapM optimize args++++    optimize (ApplyExpression f args) = ApplyExpression <$> optimize f <*> mapM optimize args+    optimize (IfExpression a b c) = IfExpression <$> optimize a <*> optimize b <*> optimize c+    optimize (LazyExpression x l) = flip LazyExpression l <$> optimize x+    optimize (FunctionExpression xs) = FunctionExpression <$> mapM optimize xs+    optimize (AccessorExpression x xs) = flip AccessorExpression xs <$> optimize x+    optimize (ListExpression ex) = ListExpression <$> mapM optimize ex++    optimize (LetExpression ds ex) =++        do ds' <- mapM optimize ds+           LetExpression ds' <$> optimize ex++    optimize (RecordExpression (M.toList -> xs)) =++        let (keys, vals) = unzip xs+        in  RecordExpression . M.fromList . zip keys <$> mapM optimize vals++    optimize x = return x+++-- TODO wrong+instance Optimize (Match (Expression Definition)) where++    optimize (Match ms (Just ex)) = Match ms . Just <$> optimize ex+    optimize x = return x++instance Optimize (Axiom (Expression Definition)) where++    optimize t @ (TypeAxiom _) = return t+    optimize (EqualityAxiom m ex) =++        do m' <- optimize m+           ex' <- optimize ex+           return (EqualityAxiom m' ex')++instance Optimize Definition where++    optimize (Definition a True name [eq @ (EqualityAxiom _ _)]) =++        do (EqualityAxiom m ex) <- optimize eq+           is  <- get_inline+           e   <- get_env+           ns  <- get_namespace+           set_inline (((ns, name), (m, get_addr ex)) : is)+           set_env    ((name, (m, get_addr ex)) : e)+           return (Definition a True name [EqualityAxiom m ex])++    optimize (Definition a True c (TypeAxiom _ : x)) = optimize (Definition a True c x)+    optimize (Definition _ True name _) = fail$ "Illegal inline definition '" ++ show name ++ "'"++    optimize (Definition a b name xs) | is_recursive xs =++       do xs' <- mapM optimize xs+          add_tco $ show name+          return $ Definition a b name (axioms xs')++       where is_recursive (TypeAxiom _: xs') = is_recursive xs'+             is_recursive (EqualityAxiom _ x: xs') = is_recursive' (get_addr x) || is_recursive xs'+             is_recursive [] = False++             is_recursive' (ApplyExpression (SymbolExpression x) _) | name == x = True+             is_recursive' (LetExpression _ e) = is_recursive' e+             is_recursive' (IfExpression _ a b) = is_recursive' a || is_recursive' b+             is_recursive' _ = False++             axioms (t @ (TypeAxiom _): xs) = t : axioms xs+             axioms xs' =+                  [EqualityAxiom (Match [] Nothing) (Addr undefined undefined (JSExpression (to_trampoline xs')))]++             to_trampoline xs @ (EqualityAxiom (Match ps _) _ : _) =+                 J.scope . J.curry (length ps) ("_V"++) . to_trampoline' ps $ xs++             to_trampoline' ps xs =++                 [jmacro| var __result = undefined;+                          `(def_local (reverse . take (length ps) . map J.local_pool $ [0 .. 26]) local_var_names)`;+                          while (typeof __result == "undefined") {+                              (function() {+                                 `(to_trampoline'' xs __result)`;+                              })();+                          }+                          return __result; |]++                 where to_trampoline'' [] _ = [jmacro| exhaust(); |]+                       to_trampoline'' (EqualityAxiom (Match pss cond) (Addr _ _ ex) : xss) result =++                           [jmacro| `(declare_bindings var_names pss)`;+                                    if (`(pss)` && `(cond)`) {+                                        `(result)` = `(replace pss ex)`;+                                    } else `(to_trampoline'' xss result)`; |]++                       var_names = map J.ref . reverse . take (length ps) . map J.local_pool $ [0 .. 26]++                       --to_expr ps = toJExpr$ zipWith PM (reverse . take (length ps) . map ("r"++) . map J.local_pool $ [0 .. 26]) ps++                       local_var_names = map J.ref . map ("_V"++) . reverse . take (length ps) . map J.local_pool $ [0 .. 26]++                       declare_bindings (name : names) (VarPattern x : zs) =++                           [jmacro| `(J.declare x name)`; |] `mappend` declare_bindings names zs++                       declare_bindings (name : names) (RecordPattern x _: zs) =+                           let (ns, z) = unzip . M.toList $ x+                           in  declare_bindings (map (acc name) ns) z `mappend` declare_bindings names zs++                       declare_bindings (_ : names) (_ : zs) = declare_bindings names zs+                       declare_bindings _ _ = mempty++                       acc n ns = [jmacroE| `(n)`[`(ns)`] |]++                       replace _ (ApplyExpression (SymbolExpression x) args) | name == x =++                           JSExpression [jmacroE| (function() {+                                                     `(bind_local (reverse . take (length ps) . map J.local_pool $ [0 .. 26]) args)`;+                                                     return undefined;+                                                  })() |]++                       replace pss (LetExpression x e) = LetExpression x (replace pss e)+                       replace pss (IfExpression x a b) = IfExpression x (replace pss a) (replace pss b)+                       replace _ x = x++                       bind_local :: ToJExpr a => [String] -> [a] -> JStat+                       bind_local (x:xs) (y:ys) = [jmacro|  `(J.ref x)` = `(y)`; |] `mappend` bind_local xs ys+                       bind_local _ _ = mempty++                       def_local :: [String] -> [JExpr] -> JStat+                       def_local (x:xs) (y:ys) = [jmacro| `(J.declare x y)`; |] `mappend` def_local xs ys+                       def_local _ _ = mempty+++    optimize (Definition a b c xs) = Definition a b c <$> mapM optimize xs++instance Optimize Statement where++    optimize (DefinitionStatement d) = DefinitionStatement <$> optimize d+    optimize (ExpressionStatement (Addr s e x)) = ExpressionStatement . Addr s e <$> optimize x+    optimize (ModuleStatement x xs) =++        do ns <- get_namespace+           set_namespace$ ns `mappend` x+           xs' <- with_env$ optimize xs+           set_namespace ns+           return$ ModuleStatement x xs'++    optimize ss @ (ImportStatement (Namespace x)) =++        do is <- get_inline+           e  <- get_env+           n  <- get_namespace+           rfind n is e++        where rfind (Namespace n) is e =++                     case lookup' (Namespace x) is of+                       [] ->++                           if length n > 0 && head n /= head x+                           then do optimize (ImportStatement (Namespace (head n : x)))+                                   return ss+                           else return ss++                       zs ->++                           do set_env $ cc zs ++ e+                              return ss++              cc (((_, s), ex): zs) = (s, ex) : cc zs+              cc [] = []++              lookup' x (((y, z), w):ys) | x == y = (((y, z), w) : lookup' x ys)+                                         | otherwise = lookup' x ys+              lookup' _ [] = []++    optimize x = return x++instance Optimize [Statement] where++    optimize [] = return []+    optimize (x:xs) =++        do x <- optimize x+           xs <- optimize xs+           return (x:xs)++instance Optimize Program where++    optimize (Program xs) = Program <$> optimize xs++run_optimizer :: [Program] -> [(Namespace, [Assumption])] -> [Program]+run_optimizer ps as = g ps as gen_state++    where g ps @ (optimize . head -> Optimizer f) as st = case f st of (st', p) -> p : g (tail ps) as st'++          gen_state = OptimizeState (Namespace []) as [] [] []+
+ src/hs/Forml/Parser.hs view
@@ -0,0 +1,114 @@+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE NamedFieldPuns       #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes          #-}+{-# LANGUAGE RankNTypes           #-}+{-# LANGUAGE RecordWildCards      #-}+{-# LANGUAGE TemplateHaskell      #-}++module Forml.Parser where++import Control.Applicative+import Data.String.Utils+import Forml.Parser.Utils hiding (spaces)+import Text.Parsec         hiding (State, label, many, parse, (<|>))++import Forml.Types.Statement++-- Parsing+-- -----------------------------------------------------------------------------+-- A Sonnet program is represented by a set of statements++parseForml :: String -> String -> Either ParseError Program+parseForml name src = case parse ((comment <|> return "\n") `manyTill` eof) "Cleaning comments" src of+                          Right x -> parse syntax name (concat x)+                          Left y -> error $ show y+++compress :: String -> String+compress = run var . run nul . run fun++    where run x src' = case parse ((try x <|> ((:[]) <$> anyChar)) `manyTill` eof) "Compressing" src' of+                         Right z -> concat z+                         Left z  -> error $ show z++          var = do string "var"+                   spaces+                   name <- many1 (alphaNum <|> char '_')+                   string ";"+                   spaces+                   string name+                   return $ "var " ++ name++          nul = do string "var"+                   spaces+                   name <- many1 (alphaNum <|> char '_')+                   string ";"+                   spaces+                   string name+                   spaces+                   string "="+                   spaces+                   string "null"+                   return $ "var " ++ name++          pairs = do string "{"+                     inner <- (try pairs <|> try fun <|> try var <|> try nul <|> ((:[]) <$> anyChar)) `manyTill` string "}"+                     return $ "{" ++ concat inner ++ "}"++          fun = do string "(function()"+                   spaces+                   string "{"+                   spaces+                   string "return"+                   spaces++                   string "(function("+                   name <- many1 (alphaNum <|> char '_')+                   string ")"+                   spaces+                   content <- pairs+                   spaces+                   string ");"+                   spaces+                   string "})()"+                   return $ "(function(" ++ name ++ ")" ++ content ++ ")"++get_tests :: [Statement] -> [(SourcePos, SourcePos)]+get_tests [] = []+get_tests (ExpressionStatement (Addr x y _): xs) = (x,y) : get_tests xs+get_tests (ModuleStatement _ x: xs) = get_tests x ++ get_tests xs+get_tests (_: xs) = get_tests xs++annotate_tests :: String -> Program -> String+annotate_tests zz (Program xs) = annotate_tests' zz (get_tests xs)+    where annotate_tests' x [] = x+          annotate_tests' x' ((a, b):ys) =+              annotate_tests' marked ys+                  where marked = mark (mark x' (serial a b ++ "--") row' col') ("--" ++ serial a b) row col++                        mark str tk x y =+                            let str' = lines str+                            in  unlines $ take x str'+                                    ++ [take y (str' !! x) ++ tk ++ drop y (str' !! x)]+                                    ++ drop (x + 1) str'++                        row = sourceLine a - 1+                        col = sourceColumn a - 1++                        row' = sourceLine b - 1+                        col' = sourceColumn b +1+++highlight :: [(SourcePos, SourcePos)] -> String -> String+highlight [] x = x+highlight ((a, b):xs) y = highlight xs (replace ("--" ++ serial a b) ("<span class='test' id='test_" ++ serial a b ++ "'>") (replace (serial a b ++ "--") "</span>" y))+++newtype Program = Program [Statement]++instance Show Program where+     show (Program ss) = sep_with "\n\n" ss++instance Syntax Program where+    syntax = Program <$> many (many (string "\n") >> syntax) <* eof
+ src/hs/Forml/Parser/Utils.hs view
@@ -0,0 +1,210 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE TypeSynonymInstances #-}+++module Forml.Parser.Utils where++import Control.Applicative+import Control.Monad.Identity+import Control.Monad.State hiding (lift)++import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import qualified Text.Parsec as P+import Text.Parsec.Indent  hiding (same)++import qualified Data.Map as M+import qualified Data.List as L++import Data.String.Utils+++import Text.Parsec.Prim hiding ((<|>), State, many, parse, label)+import qualified Data.Text as T+import System.IO.Unsafe (unsafePerformIO)+++++data Addr a = Addr SourcePos SourcePos a++instance Functor Addr where++    fmap f (Addr s e a) = Addr s e $ f a++addr :: Parser a -> Parser (Addr a)+addr p = do x <- getPosition+            y <- p+            z <- getPosition+            return$ Addr x z y+++instance (Show a) => Show (Addr a) where+    show (Addr _ _ x) = show x++instance (Monad m) => Stream T.Text m Char where+    uncons = return . T.uncons++type Parser a = ParsecT T.Text () (StateT SourcePos Identity) a++class Syntax a where+    syntax :: Parser a++instance Syntax Double where+    syntax = read <$> do x <- many1 digit+                         string "."+                         y <- many1 digit+                         return $ x ++ "." ++ y++instance Syntax Int where+    syntax = read <$> many1 digit++instance Syntax String where+    syntax = do char '"'+                (escaped_char <|> anyChar) `manyTill` char '"'++        where escaped_char = do char '\\'+                                x <- oneOf "tnr"+                                case x of+                                  'r' -> return '\r'+                                  'n' -> return '\n'+                                  't' -> return '\t'+                                  _   -> error "Unimplemented"+++parse :: Parser a -> SourceName -> String -> Either ParseError a+parse parser sname input = runIndent sname $ runParserT parser () sname (T.pack input)++whitespace :: Parser String+whitespace = many $ oneOf "\t "++whitespace1 :: Parser String+whitespace1 = space >> whitespace++same :: Parser ()+same = spaces >> do pos <- getPosition+                    s <- get+                    if (sourceColumn pos) /= (sourceColumn s)+                       then parserFail $ "not indented to exactly " ++ show (sourceColumn s)+                       else do put $ setSourceLine s (sourceLine pos)+                               return ()++set_indentation :: (Int -> Int) -> Parser ()+set_indentation f = do s <- get+                       put$ setSourceColumn s (f (sourceColumn s))++spaces :: Parser ()+spaces = try emptyline `manyTill` try line_start >> return ()++    where emptyline  = whitespace >> newline+          line_start = whitespace >> notFollowedBy newline >> in_block++          in_block = do pos <- getPosition+                        s <- get+                        if (sourceColumn pos) < (sourceColumn s)+                           then parserFail $ "not indented to at least " ++ show (sourceColumn s)+                           else do put $ setSourceLine s (sourceLine pos)+                                   return ()+++comment :: Parser String+comment = try empty_line <|> try commented_code <|> try code <|> markdown_comment++    where markdown_comment = anyChar `manyTill` newline *> return "\n"+          empty_line = whitespace *> newline *> return "\n"+          code = (\x y -> x ++ rstrip y ++ "\n") <$> string "    " <*> (anyChar `manyTill` newline)+          commented_code = do string "    "+                              x <- noneOf "\n" `manyTill` try (string "--")+                              anyChar `manyTill` newline+                              return $ if length (strip x) > 0+                                           then "    " ++ rstrip x ++ "\n"+                                           else "\n"++sep_with :: Show a => String -> [a] -> String+sep_with x = concat . L.intersperse x . fmap show++unsep_with :: forall a b. (Show a, Show b) => String -> (M.Map b a) -> String+unsep_with z = concat . L.intersperse ", " . fmap (\(x, y) -> concat [show x, z, show y]) . M.toAscList++(<:>) :: Parser a -> Parser [a] -> Parser [a]+(<:>) x y = (:) <$> x <*> y++operator_dict :: M.Map Char String+operator_dict = M.fromList [ ('!', "_bang"),+                             ('@', "_at"),+                             ('#', "_hash"),+                             ('$', "$"),+                             ('%', "_perc"),+                             ('^', "_exp"),+                             ('&', "_and"),+                             ('|', "_or"),+                             ('<', "_less"),+                             ('>', "_grea"),+                             ('?', "_ques"),+                             ('/', "_forw"),+                             ('=', "_eq"),+                             (':', "_col"),+                             ('\\', "_back"),+                             ('~', "_tild"),+                             ('+', "_plus"),+                             ('-', "_minu"),+                             ('\'', "_tick"),+                             ('*', "_star"),+                             (',', "_comm"),+                             ('\'', "_apos"),+                             ('.', "_comp") ]++operator :: Parser Char+operator = oneOf (fst . unzip . M.toList $ operator_dict)++not_reserved :: Parser String -> Parser String+not_reserved x = do y <- x+                    if y `elem` reserved_words+                       then parserFail "non-reserved word"+                       else return y++    where reserved_words = [ "if", "then", "else", "let", "when", "with", "and", "or", "do", "var",+                             "module", "open", "yield", "lazy", "inline", "in", "is", "isnt",+                             "|", "\\", "=", ":", ",", "->", "<-" ]++not_system :: Parser String -> Parser String+not_system x = not_reserved$ do y <- x+                                if y `elem` reserved_words+                                    then parserFail "non-reserved word"+                                    else return y++    where reserved_words = [ "==", "<=", ">=", "!=", "<", ">", "||", "&&", ".", ","  ]+++type_sep    :: Parser Char+indentPairs :: String -> Parser a -> String -> Parser a+not_comma   :: Parser ()+comma       :: Parser ()++type_sep          = try (spaces *> char '|' <* whitespace)+not_comma         = whitespace >> newline >> spaces >> notFollowedBy (string "}")+comma             = spaces *> string "," *> spaces+optional_sep      = try (try comma <|> not_comma)++indentPairs a p b = string a *> P.spaces *> withPosTemp (withPos p) <* P.spaces <* string b++indentAsymmetricPairs :: String -> Parser a -> Parser b -> Parser a+indentAsymmetricPairs a p b = string a *> P.spaces *> withPos p <* P.spaces <* b++withPosTemp p = do x <- get+                   try p <|> (put x >> parserFail ("expression continuation indented to " ++ show x))+++db :: Show a => a -> a+db x = unsafePerformIO $ do putStrLn$ "-- " ++ (show x)+                            return x+
+ src/hs/Forml/Static.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE NamedFieldPuns       #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes          #-}+{-# LANGUAGE RankNTypes           #-}+{-# LANGUAGE RecordWildCards      #-}+{-# LANGUAGE TemplateHaskell      #-}+{-# LANGUAGE TupleSections        #-}+{-# LANGUAGE ViewPatterns         #-}++module Forml.Static where++import Text.InterpolatedString.Perl6++import qualified Data.ByteString.UTF8 as B+import           Data.FileEmbed+import           Data.Monoid+++jasmine  :: String+header   :: String+css      :: String+prelude' :: String+jquery   :: String+footer   :: String+report   :: String+prettify :: String+htmljs   :: String+console  :: String+scripts  :: String+css'     :: String++htmljs   = "$('code').addClass('prettyprint lang-hs');prettyPrint();$('#run_tests').bind('click', prelude.html.table_of_contents)"+console  = "prelude.html.console_runner()"++prelude' = B.toString $(embedFile "src/forml/prelude.forml")+jquery   = B.toString $(embedFile "lib/js/jquery.js")+header   = B.toString $(embedFile "src/html/header.html")+footer   = B.toString $(embedFile "src/html/footer.html")+report   = B.toString $(embedFile "src/js/FormlReporter.js")++scripts  = [qq|<script>$jquery $jasmine $report $prettify</script>|]+css'     = [qq|<style type=\"text/css\">$css</style>|]+++jasmine  = B.toString $(embedFile "lib/js/jasmine-1.0.1/jasmine.js") +               `mappend` B.toString $(embedFile "lib/js/jasmine-1.0.1/jasmine-html.js")++prettify = B.toString $(embedFile "lib/js/prettify.js") +               `mappend` B.toString $(embedFile "lib/js/lang-hs.js")++css      = B.toString $(embedFile "lib/js/jasmine-1.0.1/jasmine.css") +               `mappend` B.toString $(embedFile "src/html/styles.css") +               `mappend` B.toString $(embedFile "lib/js/prettify.css")
+ src/hs/Forml/TypeCheck.hs view
@@ -0,0 +1,570 @@++{-# LANGUAGE FlexibleContexts       #-}+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs                  #-}+{-# LANGUAGE KindSignatures         #-}+{-# LANGUAGE MultiParamTypeClasses  #-}+{-# LANGUAGE NamedFieldPuns         #-}+{-# LANGUAGE OverlappingInstances   #-}+{-# LANGUAGE QuasiQuotes            #-}+{-# LANGUAGE RankNTypes             #-}+{-# LANGUAGE RecordWildCards        #-}+{-# LANGUAGE ScopedTypeVariables    #-}+{-# LANGUAGE TemplateHaskell        #-}+{-# LANGUAGE TypeSynonymInstances   #-}+{-# LANGUAGE UndecidableInstances   #-}+{-# LANGUAGE ViewPatterns           #-}++module Forml.TypeCheck where++import           Data.List                     (intersect, partition,+                                                union, (\\))++import qualified Data.List                     as L+import qualified Data.Map                      as M+import qualified Data.Set                      as S++import           Text.ParserCombinators.Parsec++import           Forml.Types.Axiom+import           Forml.Types.Definition+import           Forml.Types.Expression+import           Forml.Types.Namespace        hiding (Module)+import           Forml.Types.Pattern+import           Forml.Types.Statement        hiding (Test, find, modules,+                                                namespace)+import           Forml.Types.Symbol++import           Forml.Types.Type+import           Forml.Types.TypeDefinition++import           Forml.Parser+import           Forml.Parser.Utils++import           Forml.TypeCheck.Types+++-- Type Inference+-- --------------------------------------------------------------------------------+++instance Infer (Expression Definition) Type where+    infer (ApplyExpression _ []) = fail "This should not be"+    infer (ApplyExpression e (x:[])) =++        do te <- infer e+           tx <- infer x+           t  <- newTVar Star+           unify (tx `fn` t) te+           return t++    infer (ApplyExpression e (x:xs)) = infer (ApplyExpression (ApplyExpression e (x:[])) xs)++    infer (IfExpression a b c) =++        do ta <- infer a+           tb <- infer b+           tc <- infer c+           t  <- newTVar Star+           unify ta bool_type+           unify t tb+           unify t tc+           return t++    infer (LiteralExpression s) = infer s++    infer (SymbolExpression i) =++        do sc <- find (show i)+           (ps :=> t) <- freshInst sc+           predicate ps+           return t++    infer (JSExpression _) =++        do t <- newTVar Star+           return (TypeApplication (Type (TypeConst "JS" (KindFunction Star Star))) t)++    infer (LazyExpression x _) =++        do t <- newTVar Star+           t' <- infer x+           unify t t'+           return (TypeApplication (Type (TypeConst "JS" (KindFunction Star Star))) t)+++    -- TODO this may be removeable at no perf cost?+    infer (FunctionExpression rs) =++        do t <- newTVar Star+           as <- get_assumptions+           [_ :>: q] <- with_scope$ ims as+           (_ :=> t') <- freshInst q+           unify t t'+           return t++        where ims as =++                  do infer [Definition Public False (Symbol "") rs]+                     as'' <- get_assumptions+                     return$ as'' \\ as++    infer (AccessorExpression (Addr s f x) y) = infer (acc y)++        where acc :: [Symbol] -> Expression Definition+              acc [] = x+              acc (y:ys) = --Addr undefined undefined $+                  ApplyExpression+                  (FunctionExpression+                   [ EqualityAxiom+                     (Match [RecordPattern (M.fromList [(y, VarPattern "__x__")]) Partial] Nothing)+                     (Addr s f (SymbolExpression (Symbol "__x__"))) ] )+                  [acc ys]++    infer (RecordExpression (unzip . M.toList -> (names, xs))) =++        do ts <- mapM infer xs+           let r = TypeRecord (TRecord (M.fromList (zip (map f names) ts)) TComplete Star)+           t' <- newTVar Star+           sc <- find $ quantify (tv r) ([] :=> r)+           case sc of+             Nothing ->+                 do unify t' r+                    return t'+             Just (Forall _ scr, sct) ->+                 do (_ :=> t'') <- freshInst sct+                    (qs :=> t''') <- return$ inst (map TypeVar$ tv t'') (scr)+                    (_ :=> t) <- freshInst (quantify (tv t''' \\ tv t'') (qs :=> t'''))+                    unify t r+                    unify t' t''+                    s <- get_substitution+                    let t''' = apply s t+                        r''' = apply s r+                        qt   = quantify (tv t''') $ [] :=> t'''+                        rt   = quantify (tv r''') $ [] :=> r'''+                        sct' = apply s t''+                    if qt /= rt+                        then do add_error$ "Record does not match expected signature for " ++ show sct' ++ "\n"+                                             ++ "  Expected: " ++ show qt ++ "\n"+                                             ++ "  Actual:   " ++ show rt+                                return t'+                        else return t'++        where f (Symbol x) = x+              f (Operator x) = x++    infer (LetExpression xs x) =++        with_scope$ do infer' defs+                       infer x++        where defs = to_group (map DefinitionStatement xs)++              infer' [] = return []+              infer' (x:xs) =++                 do a <- infer x+                    assume a+                    as <- infer' xs+                    return$ a ++ as++    infer (ListExpression x) =++        do t <- newTVar Star+           ts <- mapM infer x+           mapM (unify t) ts+           t' <- newTVar Star+           unify t' (TypeApplication (Type (TypeConst "Array" (KindFunction Star Star))) t)+           return t'+           +    infer x = error $ "Unimplemented: " ++ show x++-- Axioms++instance (Infer a t) => Infer (Addr a) t where++    infer (Addr s _ x) = do m <- get_msg+                            set_msg new_msg+                            z <- infer x+                            set_msg m+                            return z++        where new_msg = "  at line " ++ show (sourceLine s) ++ ", column " ++ show (sourceColumn s) ++ "\n"++instance Infer (Axiom (Expression Definition)) Type where++    infer (EqualityAxiom (Match y z) x) =++        do ts <- mapM infer y+           case z of+             (Just q) -> infer q >>= (flip unify) bool_type+             _ -> return ()+           t  <- infer x+           return (foldr fn t ts)++    infer _ = newTVar Star++++++-- Generalization++split :: Monad m => ClassEnv -> [TypeVar] -> [TypeVar] -> [Pred] -> m ([Pred], [Pred])+split ce fs _ ps =++    do ps' <- reduce ce ps+       let (ds, rs) = partition (all (`elem` fs) . tv) ps'+       return (ds, rs) -- \\ rs')++instance Infer [Definition] () where+    infer bs =++        do def_types <- mapM (\_ -> newTVar Star) bs++           let is    = map get_name bs+               scs   = map toScheme def_types+               altss = map get_axioms bs++           axiom_types <- with_scope$+                do assume $ zipWith (:>:) is scs+                   mapM (mapM (with_scope . infer)) altss++           let f _ []     = return ()+               f g (x:xs) = do s <- get_substitution+                               g x+                               g (apply s x)+                               f g xs++           mapM (\(t, as) -> f (unify t) as) (zip def_types axiom_types)++           ps  <- get_predicates+           as  <- get_assumptions+           ps' <- substitute ps+           ss  <- get_substitution+           fs' <- substitute as++           let ts' = apply ss def_types+               fs  = tv fs'+               vss = map tv ts'+               gs  = foldr1 union vss \\ fs++           ce <- get_classenv+           (ds, rs) <- split ce fs (foldr1 intersect vss) ps'++           if restricted then+               let gs'  = gs \\ tv rs+                   scs' = map (quantify gs' . ([]:=>)) ts'+               in do predicate (ds ++ rs)+                     assume (zipWith (:>:) is scs')+                     return ()+             else+               let scs' = map (quantify gs . (rs:=>)) ts'+               in do predicate ds+                     assume (zipWith (:>:) is scs')+                     return ()++        where get_name (Definition _ _ (Symbol x) _) = x+              get_name (Definition _ _ (Operator x) _) = x+              get_axioms (Definition _ _ _ x) = x++              restricted = any simple bs+              simple (Definition _ _ _ axs) = any (null . f) axs++              f (EqualityAxiom (Match p _) _) = p+              f _ = error "Fatal error occurred while reticulating splines"+++data BindGroup = Scope [Namespace] [Statement] [Definition] [[Definition]] [Addr (Expression Definition)]+               | Module String [BindGroup]+               deriving (Show)++instance Infer Definition () where++    infer (Definition _ _ name axs) =++        do sc <- find$ f name+           (qs :=> t)  <- freshInst sc+           axiom_types <- with_scope$ mapM (with_scope . infer) axs++           s <- get_substitution+           mapM (flip unify t) axiom_types  -- TODO apply sub to axiom_types?++           as <- get_assumptions+           ce <- get_classenv+           ps <- get_predicates++           let qs' = apply s qs+               t'  = apply s t+               fs  = tv (apply s as)+               gs  = tv t' \\ fs+               sc' = quantify gs (qs' :=> t')+               ps' = filter (not . entail ce qs') (apply s ps)++           (_, rs) <- split ce fs gs ps'++           if sc /= sc' then+               add_error$ "Signature too general\n\n    Expected: " ++ show sc ++ "\n    Actual: " ++ show sc'+             else if not (null rs) then+               add_error$ "Context too weak\n\n    Expected: " ++ show sc ++ "\n    Actual: " ++ show sc'+             else+               assume (f name :>: sc)++           return ()++        where f (Symbol x) = x+              f (Operator x) = x++instance Infer Test () where++    infer (Test ex) = do t <- newTVar Star+                         x <- infer ex+                         unify t x+                         unify t bool_type++newtype Test = Test (Addr (Expression Definition))++instance Infer BindGroup [Assumption] where+    infer (Scope imps tts es iss ts) =++        do --as <- get_assumptions+           mapM import' imps+           as' <- get_assumptions+           infer tts+           mapM assume$ sigs es+           mapM infer iss+           with_scope$ mapM infer es+           mapM infer (map Test ts)+           as'' <- get_assumptions+           set_assumptions as'+           return (as'' \\ as')++        where f (TypeAxiom t) = True+              f _ = False++              g name (TypeAxiom t) = [ name :>: to_scheme' t' | t' <- enumerate_types t ]++              to_scheme' :: Type -> Scheme+              to_scheme' t = quantify (tv t) ([] :=> t)++              sigs :: [Definition] -> [Assumption]+              sigs [] = []+              sigs (Definition _ _ name as:xs) =+                  case L.find f as of+                    Nothing -> sigs xs+                    Just x -> g (h name) x ++ sigs xs++              import' (Namespace ns) =++                  do z <- get_modules+                     a <- get_assumptions+                     (Namespace ns') <- get_namespace+                     case Namespace ns `lookup` z of+                       Just z' -> assume$ a ++ z'+                       Nothing -> if length ns' > 0 && head ns' /= head ns+                                  then import' (Namespace (head ns' : ns))+                                  else add_error$ "Unknown namespace " ++ show (Namespace ns)++              h (Symbol x) = x+              h (Operator x) = x++    infer (Module name bgs) =++        do as <- get_assumptions+           with_module name$ infer' bgs+           set_assumptions as+           return []++         where infer' [] = return []+               infer' (x:xs) =++                  do a <- infer x+                     assume a+                     as' <- infer' xs+                     return$ a ++ as'++++to_scheme :: TypeDefinition -> UnionType -> [Assumption]+to_scheme (TypeDefinition n vs) t = [ quantify (vars y) ([]:=> y) :>>: def_type y+                                          | y <- enumerate_types t ]++    where vars y = map (\x -> TVar x (infer_kind x y)) vs++          def_type y = quantify (vars y) ([] :=> foldl app poly_type (map TypeVar (vars y)))++          poly_type = Type (TypeConst n (to_kind (length vs)))++          to_kind 0 = Star+          to_kind n = KindFunction Star (to_kind$ n - 1)++          app :: Type -> Type -> Type+          app y x = TypeApplication y x++          -- TODO this is still wrong - have to check for all enumerated types++          infer_kind x y = let ks = infer_kinds x y+                           in if ks == []+                              then Star+                              else if all (\x -> x == head ks) ks+                                   then head ks+                                   else error "Kind mismatch in scheme"++          infer_kinds x (TypeApplication a b) = infer_kinds x a ++ infer_kinds x b+          infer_kinds x (TypeVar (TVar y k)) | x == y = [k]+          infer_kinds x (TypeRecord (TRecord m _ _)) = concat$ map (infer_kinds x) (M.elems m)+          infer_kinds _ _ = []++-- | Computes all possible types from a type signature AST.++enumerate_types :: UnionType -> [Type]+enumerate_types (UnionType types) = to_unit . concat . map enumerate_type . S.toList $ types++    where term_type (VariableType x)      = [ TypeVar (TVar x Star) ]+          term_type (SymbolType x)        = [ Type (TypeConst (show x) Star) ]+          term_type (PolymorphicType a b) = [ foldl TypeApplication a' b'+                                                  | b' <- map enumerate_types b+                                                  , a' <- to_kind' (length b')$ term_type a ]++          to_kind 0 = Star+          to_kind n = KindFunction Star (to_kind$ n - 1)++          to_unit [] = [TypeRecord (TRecord M.empty TComplete Star)]+          to_unit x = x++          to_kind' _ [] = []+          to_kind' n (TypeVar (TVar x _) : xs) = TypeVar (TVar x (to_kind n)) : to_kind' n xs+          to_kind' n (Type (TypeConst x _) : xs) = Type (TypeConst x (to_kind n)) : to_kind' n xs++          enumerate_type (SimpleType x) = term_type x++          enumerate_type (FunctionType a b) =+              [ a' `fn` b' | a' <- enumerate_types a, b' <- enumerate_types b ]++          enumerate_type (RecordType (unzip . M.toList -> (names, types'))) =++              map f permutations++              where f = TypeRecord . (\x -> TRecord x TComplete Star) . M.fromList . zip (map show names)+                    permutations = permutations' . map enumerate_types $ types'++                        where permutations' [] = []+                              permutations' (x:[]) = [ x ]+                              permutations' (x:xs) = [ x' : xs' | x' <- x, xs' <- permutations' xs ]++++++instance Infer [Statement] () where++    infer [] = return ()+    infer (TypeStatement t c : xs) =++        do assume     $ to_scheme t c+           infer xs++    infer (_ : xs) = infer xs++sort_dep :: [[Definition]] -> [[Definition]]+sort_dep [] = []+sort_dep xs = case map (:[])$ concat$ map snd$ filter fst free of+                [] -> error$ "Unresolvable dependency ordering in " ++ show (get_names xs)+                xs -> xs ++ sort_dep (map snd$ filter (not . fst) free)+++    where as = get_needed (get_names xs) (zip (get_names xs) (get_expressions xs))++          free = get_free as `zip` xs++          get_free [] = []+          get_free ([]:xs) = True : get_free xs+          get_free (_:xs) = False : get_free xs++          get_names [] = []+          get_names ([Definition _ _ n _]:xs) = show n : get_names xs++          get_needed _ [] = []+          get_needed names ((n,x):xs) =+              ((names \\ [n]) `L.intersect` (concat$ map get_symbols x)) : get_needed names xs++          get_expressions :: [[Definition]] -> [[Expression Definition]]+          get_expressions [] = []+          get_expressions ([Definition _ _ _ as]:xs) = get_expressions' as : get_expressions xs++          get_expressions' [] = []+          get_expressions' (TypeAxiom _: xs) = get_expressions' xs+          get_expressions' (EqualityAxiom (Match _ (Just y)) (Addr _ _ x): xs) = y : x : get_expressions' xs+          get_expressions' (EqualityAxiom _ (Addr _ _ x): xs) = x : get_expressions' xs++          get_symbols (RecordExpression (unzip . M.toList -> (_, xs))) = concat (map get_symbols xs)+          get_symbols (AccessorExpression (Addr _ _ x) _) = get_symbols x+          get_symbols (ApplyExpression a b)   = get_symbols a ++ concat (map get_symbols b)+          get_symbols (IfExpression a b c)    = get_symbols a ++ get_symbols b ++ get_symbols c+          get_symbols (LiteralExpression _)   = []+          get_symbols (SymbolExpression x)    = [show x]+          get_symbols (JSExpression _)        = []+          get_symbols (LazyExpression (Addr _ _ x) _)      = get_symbols x+          get_symbols (FunctionExpression as) = concat$ map get_symbols$ get_expressions' as+          get_symbols (LetExpression _ x)     = get_symbols x+          get_symbols (ListExpression x)      = concat (map get_symbols x)+js_type :: Type++js_type = Type (TypeConst "JS" (KindFunction Star Star))++tiProgram :: Program -> [(Namespace, [Assumption])] -> ([(Namespace, [Assumption])], [String])+tiProgram (Program bgs) env =++    runTI $ do TI (\x -> (x { modules = env }, ()))+               assume$ "true"  :>: (Forall [] ([] :=> Type (TypeConst "Bool" Star)))+               assume$ "false" :>: (Forall [] ([] :=> Type (TypeConst "Bool" Star)))+               assume$ "error" :>: (Forall [Star] ([] :=> TypeGen 0))+               assume$ "run"   :>: (Forall [Star] ([] :=> (TypeApplication js_type (TypeGen 0) -:> TypeGen 0)))+               infer'$ to_group bgs+               s  <- get_substitution+               ce <- get_classenv+               ps <- get_predicates+               ms <- TI (\y -> (y, modules y))+               rs <- reduce ce (apply s ps)+               e  <- get_errors+               return ((apply s ms), S.toList . S.fromList $ e)++    where infer' [] = return ()+          infer' (x:xs) =++              do a <- infer x+                 assume a+                 infer' xs+++++to_group :: [Statement] -> [BindGroup]+to_group [] = []+to_group xs = case takeWhile not_module xs of+                [] -> to_group' xs+                yx -> sort_deps (foldl f (Scope [] [] [] [] []) yx)+                      : to_group' (dropWhile not_module xs)++    where to_group' [] = []+          to_group' (ModuleStatement x y:xs) = Module (show x) (to_group y) : to_group xs+          to_group' _ = error "Unexpected"++          sort_deps (Scope i t a b c) = Scope i t a (sort_dep b) c++          not_module (ModuleStatement _ _) = False+          not_module _ = True++          f (Scope i t a b c) (DefinitionStatement x @ (Definition _ _ _ (EqualityAxiom _ _:_))) =+              Scope i t a (b ++ [[x]]) c+          f (Scope i t a b c) (DefinitionStatement x @ (Definition _ _ _ (TypeAxiom _:_))) =+              Scope i t (a ++ [x]) b c+          f (Scope i t a b c) (ExpressionStatement x) =+              Scope i t a b (c ++ [x])+          f (Scope i t a b c) (ImportStatement ns) =+              Scope (i ++ [ns]) t a b c+          f (Scope i t a b c) x @ (TypeStatement _ _) =+              Scope i (t ++ [x]) a b c+          f x _ = x+
+ src/hs/Forml/TypeCheck/Types.hs view
@@ -0,0 +1,671 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances, KindSignatures #-}++module Forml.TypeCheck.Types where++import Data.List (nub, intersect, union)+import System.IO.Unsafe++import Text.InterpolatedString.Perl6++import Data.List (nub, (\\), intersect, union, partition)++import qualified Data.Map as M+import qualified Data.List as L+import qualified Data.Set as S++import Control.Monad+import Data.Monoid++import Forml.Types.Namespace hiding (Module)++type Id = String++enumId :: Int -> Id+enumId n = "v" ++ show n++data Kind = Star | KindFunction Kind Kind deriving (Show, Eq, Ord)++type Key = String++data Type = TypeVar TypeVar+          | Type TypeConst+          | TypeApplication Type Type+          | TypeRecord TypeRecord+          | TypeGen Int+            deriving Eq++data TPartial = TComplete | TPartial Type deriving (Eq, Show)++data TypeRecord = TRecord (M.Map Key Type) TPartial Kind+                deriving (Show, Eq)++data TypeVar = TVar Id Kind+               deriving (Show, Eq, Ord)++data TypeConst = TypeConst Id Kind -- (?)+                 deriving (Show, Eq, Ord)++instance Show Type where+    show (TypeVar (TVar i _)) = i+    show (Type (TypeConst i _)) = i+    show (TypeApplication (TypeApplication (Type (TypeConst "->" _)) +                          u @ (TypeApplication (TypeApplication (Type (TypeConst "->" _)) _) _)) v) = +        "(" ++ show u ++ ") → " ++ show v+    show (TypeApplication (TypeApplication (Type (TypeConst "->" _)) u) v) = +        show u ++ " → " ++ show v+    show (TypeApplication t u) = show t ++ " " ++ show u+    show (TypeGen x) = (map (:[])$ concat$ repeat "abcdefghijklmnopqrstuvwxyz") !! x+    show (TypeRecord (TRecord m TComplete _)) =+        "{" ++ (concat$ L.intersperse ", "$ map (\(x, y) -> x ++ " = " ++ show y) . M.toList $ m) ++ "}"+    show (TypeRecord (TRecord m (TPartial _) _)) =+        "{" ++ (concat$ L.intersperse ", "$ map (\(x, y) -> x ++ " = " ++ show y) . M.toList $ m) ++ ", _ }"+++num_type :: Type+fun_type :: Type+num_type  = Type (TypeConst "Num" Star)+fun_type  = Type (TypeConst "->" (KindFunction Star (KindFunction Star Star)))++infixr 4 -:>+(-:>) :: Type -> Type -> Type+a -:> b = TypeApplication (TypeApplication fun_type a) b++class HasKind t where kind :: t -> Kind++instance HasKind TypeVar where   kind (TVar _ k) = k+instance HasKind TypeConst where kind (TypeConst _ k) = k+instance HasKind TypeRecord where kind (TRecord _ _ k) = k+instance HasKind Type where+    kind (Type x) = kind x+    kind (TypeVar x) = kind x+    kind (TypeRecord x) = kind x+    kind (TypeApplication (kind -> KindFunction _ k)  _) = k+    kind t = error$ "Could not determine kind of " ++ show t++type Substitution = [(TypeVar, Type)]++(+->) :: TypeVar -> Type -> Substitution+x +-> y = [(x, y)]++class Types t where+    apply :: Substitution -> t -> t+    tv :: t -> [TypeVar]++instance Types Type where+    apply s (TypeVar u) = case lookup u s of +                            Just x -> x+                            Nothing -> TypeVar u+    apply s (TypeApplication l r) = TypeApplication (apply s l) (apply s r)+    apply s (TypeRecord (TRecord xs TComplete k)) = TypeRecord (TRecord (fmap (apply s) xs) TComplete k)+    apply s (TypeRecord (TRecord xs (TPartial p) k)) =+        case apply s p of+          p' | p' == p   -> TypeRecord (TRecord (fmap (apply s) xs) (TPartial p) k)+          TypeRecord (TRecord ys p' _) -> TypeRecord (TRecord (fmap (apply s) (xs `M.union` ys)) p' k)+          x -> TypeRecord (TRecord (fmap (apply s) xs) (TPartial x) k)+    apply _ t = t++    tv (TypeVar u) = [u]+    tv (TypeApplication l r) = tv l `union` tv r+    tv (TypeRecord (TRecord xs TComplete _)) = nub $ M.elems xs >>= tv+    tv (TypeRecord (TRecord xs (TPartial t) _)) = (nub $ M.elems xs >>= tv) ++ tv t+    tv _ = []++instance Types a => Types [a] where+    apply s = map (apply s)+    tv = nub . concat . map tv++infixr 4 @@+(@@) :: Substitution -> Substitution -> Substitution+s1 @@ s2 = ([(u, apply s1 t) | (u, t) <- s2] ++ s1)++merge :: Monad m => Substitution -> Substitution -> m Substitution+merge s1 s2 = if agree then return (s1 ++ s2) else fail $ "merge fails " ++ show s1 ++ show s2+    where agree = all f (map fst s1 `intersect` map fst s2)+          f (TypeVar -> v) = apply s1 v == apply s2 v++++++++-- Unification+-- --------------------------------------------------------------------------------++instance Monoid TypeVar where+    mappend (TVar x k) (TVar y k') | k == k' = TVar (x ++ y) k+    mempty = TVar "" Star++var_bind :: Monad m => TypeVar -> Type -> m Substitution+match    :: Monad m => Type -> Type -> m Substitution++class Unify a where+    (|=|) :: Monad m => a -> a -> m Substitution++instance Unify TypeRecord where++    TRecord t TComplete _ |=| TRecord u TComplete _+       | M.keysSet t == M.keysSet u = ++            f (M.elems t) (M.elems u) []++        where f [] _ s = return s+              f (x:xs) (y:ys) s = do s' <- apply s x |=| apply s y+                                     f xs ys (s @@ s')++    TRecord t (TPartial (TypeVar p)) k |=| TRecord u (TPartial (TypeVar p')) k' =++        do a <- TRecord t' TComplete k |=| TRecord u' TComplete k'+           b <- f (u M.\\ t) p  (p `mappend` p') k+           c <- f (t M.\\ u) p' (p `mappend` p') k+           return$ a @@ b @@ c++        where t' = u M.\\ (u M.\\ t)+              u' = t M.\\ (t M.\\ u)+              +              f x p p' k | M.size x > 0 = var_bind p (TypeRecord (TRecord x (TPartial (TypeVar p')) k))+                         | otherwise    = return []++    t' @ (TRecord t (TPartial (TypeVar p)) k) |=| u' @ (TRecord u TComplete k')+        | M.keysSet t `S.intersection` M.keysSet u == M.keysSet t =++            do a <- TRecord t TComplete k |=| TRecord (u M.\\ (u M.\\ t)) TComplete k'+               b <- if M.size u >= M.size t+                    then var_bind p$ TypeRecord$ TRecord (u M.\\ t) TComplete Star+                    else return []+               return$ a @@ b++        | otherwise = fail [qq|Records do not unify: found {TypeRecord t'}, expecting {TypeRecord u'}|]+                    +    t |=| u @ (TRecord _ (TPartial _) _) = u |=| t++    t |=| u = fail [qq|Illegal record unification: {TypeRecord t} and {TypeRecord u}|]++instance Unify Type where++    TypeApplication l1 r1 |=| TypeApplication l2 r2 =++        do s1 <- l1 |=| l2+           s2 <- apply s1 r1 |=| apply s1 r2+           return$ s1 @@ s2++    TypeVar u |=| t = var_bind u t+    t |=| TypeVar u = var_bind u t+    TypeRecord a |=| TypeRecord b = a |=| b+    Type t |=| Type u | t == u = return []+    t |=| u = fail$ "Types do not unify: found " ++ show t ++ ", expecting " ++ show u++data Z a = Z a | Error String++instance Monad Z where+    return x = Z x+    (Z x) >>= f = f x+    (Error x) >>= _ = Error x+    fail x = Error x++mgu :: Type -> Type -> TI Substitution+mgu x y = do z <- mgu' x y+             case z of+               Left e  -> add_error e >> return []+               Right e -> return e++mgu' :: Type -> Type -> TI (Either String Substitution)+mgu' x y = case x |=| y of+             Z z -> return $ Right z+             Error e -> second_chance e x y++    where second_chance e x@ (TypeRecord (TRecord _ (TPartial _) _)) y =+              +              do as <- get_assumptions+                 g  <- find''' as x++                 case g of+                   Nothing -> return $ Left e --add_error e >> return []+                   Just (x, sct) ->+                       do (qs' :=> t'') <- freshInst sct+                          return $ Right x++          second_chance e y x @ (TypeRecord (TRecord _ (TPartial _) _)) = second_chance e x y+          second_chance e (TypeApplication a b) (TypeApplication c d) =+              do xss <- second_chance e a c+                 yss <- second_chance e b d+                 case (xss, yss) of+                   (Right xss', Right yss') -> return$ Right$ xss' @@ yss'+                   (Left e', _) -> return $ Left e'+                   (_, Left e') -> return $ Left e'+                   ++          second_chance e x y = case x |=| y of+                                  Error _ -> return $ Left e --add_error e >> return []+                                  Z x -> return $ Right x+ +          find''' [] _ = return Nothing+          find''' (_:>:_:xs) t = find''' xs t+          find''' ((Forall _ x :>>: y):xs) t =++              do (_ :=> t') <- return$ inst (map TypeVar$ tv t) x+                 case t' |=| t of+                   Error _ -> find''' xs t++                   -- TODO Only allow this shorthand if the match is unique - true?+                   Z x  -> do zz' <- find''' xs t+                              case zz' of+                                Nothing -> return$ Just (x, y)+                                Just _ -> return$ Nothing++var_bind u t | t == TypeVar u   = return []+             | u `elem` tv t    = fail $ "occurs check fails: " ++ show u ++ show t+             | kind u /= kind t = fail "kinds do not match"+             | otherwise        = return (u +-> t)++match (TypeApplication l1 r1) (TypeApplication l2 r2) =+    do s1 <- match l1 l2+       s2 <- match r1 r2+       merge s1 s2++match (TypeVar u) t +    | kind u == kind t = return (u +-> t)+match (TypeRecord t) (TypeRecord u) +    | t == u = return []+match (Type t) (Type u)+    | t == u = return []+match _ _ = fail "Types do not match"++++-- Type Classes+-- --------------------------------------------------------------------------------++data Qual t = [Pred] :=> t deriving Eq+data Pred = IsIn Id Type deriving (Show, Eq)++instance (Show t) => Show (Qual t) where+    show (_ :=> t) = show t++instance Types t => Types (Qual t) where+  apply s (ps :=> t) = apply s ps :=> apply s t+  tv (ps :=> t)      = tv ps `union` tv t++instance Types Pred where+  apply s (IsIn i t) = IsIn i (apply s t)+  tv (IsIn _ t)      = tv t++mguPred, matchPred :: Pred -> Pred -> Maybe Substitution+mguPred   = lift (|=|)+lift :: forall (m :: * -> *) a.+                       Monad m =>+                       (Type -> Type -> m a) -> Pred -> Pred -> m a+matchPred = lift match++lift m (IsIn i t) (IsIn i' t')+         | i == i'   = m t t'+         | otherwise = fail "classes differ"++type Class    = ([Id], [Inst])+type Inst     = Qual Pred++++-- Class Environments+-- --------------------------------------------------------------------------------++data ClassEnv = ClassEnv { classes  :: Id -> Maybe Class,+                           defaults :: [Type] }++super :: ClassEnv -> Id -> [Id]+super ce i = case classes ce i of Just (is, _) -> is++insts :: ClassEnv -> Id -> [Inst]+insts ce i = case classes ce i of Just (_, its) -> its++defined :: Maybe a -> Bool+defined (Just x) = True+defined Nothing  = False++modify :: ClassEnv -> Id -> Class -> ClassEnv+modify ce i c = ce{classes = \j -> if i==j then Just c+                                           else classes ce j}++initialEnv :: ClassEnv+initialEnv  = ClassEnv { classes  = \_ -> fail "class not defined",+                         defaults = [num_type] }++type EnvTransformer = ClassEnv -> Maybe ClassEnv++infixr 5 <::>+(<::>)       :: EnvTransformer -> EnvTransformer -> EnvTransformer+(f <::> g) ce = do ce' <- f ce+                   g ce'++addClass                              :: Id -> [Id] -> EnvTransformer+addClass i is ce+ | defined (classes ce i)              = fail "class already defined"+ | any (not . defined . classes ce) is = fail "superclass not defined"+ | otherwise                           = return (modify ce i (is, []))++addPreludeClasses :: EnvTransformer+addPreludeClasses  = addCoreClasses <::> addNumClasses++addCoreClasses ::   EnvTransformer+addCoreClasses  =   addClass "Eq" []+                <::> addClass "Ord" ["Eq"]+                <::> addClass "Show" []+                <::> addClass "Read" []+                <::> addClass "Bounded" []+                <::> addClass "Enum" []+                <::> addClass "Functor" []+                <::> addClass "Monad" []++addNumClasses  ::   EnvTransformer+addNumClasses   =   addClass "Num" ["Eq", "Show"]+                <::> addClass "Real" ["Num", "Ord"]+                <::> addClass "Fractional" ["Num"]+                <::> addClass "Integral" ["Real", "Enum"]+                <::> addClass "RealFrac" ["Real", "Fractional"]+                <::> addClass "Floating" ["Fractional"]+                <::> addClass "RealFloat" ["RealFrac", "Floating"]++++-- Entailment+-- --------------------------------------------------------------------------------++bySuper :: ClassEnv -> Pred -> [Pred]+bySuper ce p@(IsIn i t) =+    p : concat [ bySuper ce (IsIn i' t) | i' <- super ce i ]++byInst :: ClassEnv -> Pred -> Maybe [Pred]+byInst ce p@(IsIn i t)    = msum [ tryInst it | it <- insts ce i ]+ where tryInst (ps :=> h) = do u <- matchPred h p+                               Just (map (apply u) ps)++entail        :: ClassEnv -> [Pred] -> Pred -> Bool+entail ce ps p = any (p `elem`) (map (bySuper ce) ps) ||+                 case byInst ce p of+                   Nothing -> False+                   Just qs -> all (entail ce ps) qs++inHnf       :: Pred -> Bool+inHnf (IsIn _ t) = hnf t+   where hnf (TypeVar v)  = True+         hnf (Type tc) = False+         hnf (TypeApplication t _) = hnf t++toHnfs      :: Monad m => ClassEnv -> [Pred] -> m [Pred]+toHnfs ce ps = do pss <- mapM (toHnf ce) ps+                  return (concat pss)++toHnf                 :: Monad m => ClassEnv -> Pred -> m [Pred]+toHnf ce p | inHnf p   = return [p]+           | otherwise = case byInst ce p of+                           Nothing -> fail "context reduction"+                           Just ps -> toHnfs ce ps++simplify   :: ClassEnv -> [Pred] -> [Pred]+simplify ce = loop []+ where loop rs []                            = rs+       loop rs (p:ps) | entail ce (rs++ps) p = loop rs ps+                      | otherwise            = loop (p:rs) ps++reduce      :: Monad m => ClassEnv -> [Pred] -> m [Pred]+reduce ce ps = do qs <- toHnfs ce ps+                  return (simplify ce qs)++scEntail        :: ClassEnv -> [Pred] -> Pred -> Bool+scEntail ce ps p = any (p `elem`) (map (bySuper ce) ps)++++-- Type Schemes+-- --------------------------------------------------------------------------------++data Scheme = Forall [Kind] (Qual Type) deriving Eq++instance Show Scheme where+    show (Forall [] t) = show t+    show (Forall xs t) = show t --"∀" ++ vars ++ " ⇒ " ++ show t+        where vars = concat . L.intersperse " " . map (\x -> (map (:[]) "abcdefghijklmnopqrstuvwxyz") !! x) . take (length xs) $ [0..]++instance Types Scheme where+  apply s (Forall ks qt) = Forall ks (apply s qt)+  tv (Forall _ qt)      = tv qt++quantify      :: [TypeVar] -> Qual Type -> Scheme+quantify vs qt = Forall ks (apply s qt)+ where vs' = [ v | v <- tv qt, v `elem` vs ]+       ks  = map kind vs'+       s   = zip vs' (map TypeGen [0..])++toScheme      :: Type -> Scheme+toScheme t     = Forall [] ([] :=> t)++++-- Assumptions+-- --------------------------------------------------------------------------------++data Assumption = Id :>: Scheme | Scheme :>>: Scheme deriving (Eq)++newtype A = A [Assumption]++instance Show Assumption where+    show (i :>: s)  = i ++ ": " ++ show s+    show (i :>>: s) = show i ++ ": " ++ show s++instance Types Assumption where+    apply s (i :>: sc)  = i :>: (apply s sc)+    apply s (sc :>>: sd) = apply s sc :>>: apply s sd++    tv (_ :>: sc)       = tv sc+    tv (sc :>>: _) = tv sc++class Find a b | a -> b where+    find :: a -> TI b++instance Find Id Scheme where++    find i = do (reverse -> x) <- get_assumptions+                find' x ++        where find' ((i':>:sc):as) = if i == i' then return sc else find' as+              find' (_:as)         = find' as+              find' []             = do add_error ("Unbound identifier " ++ show i)+                                        return$ toScheme$ TypeVar (TVar "a" Star)+              ++instance Find Scheme (Maybe (Scheme, Scheme)) where++    find i = do (reverse -> x) <- get_assumptions+                find' x ++        where find' []              = return Nothing+              find' ((i':>>:sc):as) = do (_ :=> i'') <- freshInst i+                                         (_ :=> i''') <- freshInst i'+                                         x <- i'' `can_unify` i'''+                                         if x then return $ Just (i', sc) else find' as+              find' (_:as)          = find' as++++-- Type Inference Monad+-- --------------------------------------------------------------------------------++data TIState = TIState { substitution :: Substitution+                       , seed :: Int+                       , class_env :: ClassEnv+                       , msg :: String+                       , warnings :: [String]+                       , errors :: [String]+                       , modules :: [(Namespace, [Assumption])]+                       , namespace :: Namespace+                       , assumptions :: [Assumption]+                       , predicates :: [Pred] }++newtype TI a = TI (TIState -> (TIState, a))++instance Monad TI where+  fail x     = TI (\y -> error$ x ++ "\n" ++ msg y) +  return x   = TI (\y -> (y, x))+  TI f >>= g = TI (\x -> case f x of+                          (y, x) -> let TI gx = g x+                                   in  gx y)++instance Functor TI where+    fmap f y = y >>= (\x -> TI (\x' -> (x', f x)))++instance Types [(Namespace, [Assumption])] where+    apply s v = map (\(x, y) -> (x, apply s y)) v+    tv = concat . map (\(_, y) -> tv y)+++runTI :: TI a -> a+runTI (TI f) = x where (t,x) = f (TIState [] 0 initialEnv "" [] [] [] (Namespace []) [] [])++get_assumptions  :: TI [Assumption]+get_msg          :: TI String+set_msg          :: String -> TI ()+get_predicates   :: TI [Pred]+set_predicates   :: [Pred] -> TI ()+get_substitution :: TI Substitution+get_classenv     :: TI ClassEnv+add_error        :: String -> TI ()++get_assumptions  = TI (\x -> (x, assumptions x))+get_msg          = TI (\x -> (x, msg x))+set_msg x        = TI (\y -> (y { msg = x }, ()))+get_predicates   = TI (\x -> (x, predicates x))+set_predicates x = TI (\y -> (y { predicates = x }, ()))+get_substitution = TI (\x -> (x, substitution x))+get_classenv     = TI (\x -> (x, class_env x))+add_error y      = TI (\x -> (x { errors = errors x ++ [y ++ "\n" ++ msg x] }, ()))+set_assumptions :: [Assumption] -> TI ()+get_errors :: TI [String]+get_errors       = TI (\x -> (x, errors x))+get_modules :: TI [(Namespace, [Assumption])]+get_modules      = TI (\x -> (x, modules x))+set_assumptions x = TI (\y -> (y { assumptions = x }, ()))+get_namespace :: TI Namespace+get_namespace = TI (\y -> (y, namespace y))+          +class Assume a where+    assume :: a -> TI ()++instance Assume Assumption where+    assume x = TI (\y -> (y { assumptions = assumptions y ++ (x:[]) }, ()))++instance Assume [Assumption] where+    assume x = TI (\y -> (y { assumptions = assumptions y ++ x}, ()))++class Predicated a where+    predicate :: a -> TI ()++instance Predicated Pred where+    predicate x = TI (\y -> (y { predicates = predicates y ++ (x:[]) }, ()))++instance Predicated [Pred] where+    predicate x = TI (\y -> (y { predicates = predicates y ++ x}, ()))+++with_scope :: TI a -> TI a+with_scope x = do as <- get_assumptions+                  ps <- get_predicates+                  y <- x+                  set_assumptions as+                  set_predicates ps+                  return y++with_module :: String -> TI [Assumption] -> TI ()+with_module name x = do --as <- get_assumptions+                        ns <- get_namespace+                        set_namespace (ns `mappend` Namespace [name])+                        as' <- x+                        --as' <- get_assumptions+                        --set_assumptions as+                        add_module (ns `mappend` Namespace [name], as')+                        set_namespace ns++    where add_module x = TI (\y -> (y { modules = modules y ++ [x] }, ()))++          set_namespace x = TI (\y -> (y { namespace = x }, ()))+++substitute :: Types a => a -> TI a+substitute x = do y <- get_substitution+                  return $ apply y x++unify :: Type -> Type -> TI ()+unify t1 t2 = do s <- get_substitution+                 u <- apply s t1 `mgu` apply s t2+                 extSubst $ u @@ s++    where extSubst   :: Substitution -> TI ()+          extSubst s' = TI (\x -> (x { substitution = s' }, ()))++can_unify :: Type -> Type -> TI Bool+can_unify t1 t2 = with_scope $ +              do s <- get_substitution+                 u <- apply s t1 `mgu'` apply s t2+                 case u of+                   Left x  -> return False+                   Right x -> return True++newTVar :: Kind -> TI Type+newTVar k   = TI (\x -> let v = TVar (enumId (seed x)) k+                       in  (x { seed = seed x + 1}, TypeVar v))++freshInst :: Scheme -> TI (Qual Type)+freshInst (Forall ks qt) = do ts <- mapM newTVar ks+                              return (inst ts qt)++class Instantiate t where+  inst  :: [Type] -> t -> t++instance Instantiate Type where+  inst ts (TypeApplication l r) = TypeApplication (inst ts l) (inst ts r)+  inst ts (TypeGen n)  = ts !! n+  inst ts (TypeRecord (TRecord m TComplete k)) =+      TypeRecord (TRecord (M.map (inst ts) m) TComplete k)+  inst ts (TypeRecord (TRecord m (TPartial p) k)) =+      TypeRecord (TRecord (M.map (inst ts) m) (TPartial (inst ts p)) k)+  inst _ t   = t++instance Instantiate a => Instantiate [a] where+  inst ts = map (inst ts)++instance Instantiate t => Instantiate (Qual t) where+  inst ts (ps :=> t) = inst ts ps :=> inst ts t++instance Instantiate Pred where+  inst ts (IsIn c t) = IsIn c (inst ts t)++class Infer e t | e -> t where infer :: e -> TI t+++list_scheme :: Scheme+list_scheme = Forall [Star] qual_list+    where qual_list = [] :=> TypeApplication (Type (TypeConst "List" (KindFunction Star Star))) (TypeGen 0)++bool_type :: Type+bool_type = Type (TypeConst "Bool" Star)++-- Expressions+++infixr      4 `fn`+fn         :: Type -> Type -> Type+a `fn` b    = TypeApplication (TypeApplication fun_type a) b
+ src/hs/Forml/Types/Axiom.hs view
@@ -0,0 +1,98 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Forml.Types.Axiom where++import Text.InterpolatedString.Perl6+import Language.Javascript.JMacro++import qualified Data.Map as M++import Forml.Parser.Utils+import Forml.Javascript.Utils++import Forml.Types.Type+import Forml.Types.Pattern+++import Data.Monoid++import Prelude hiding (curry, (++))+++-- Axiom+-- --------------------------------------------------------------------------------++data Axiom a = TypeAxiom UnionType+             | EqualityAxiom (Match a) (Addr a)++instance (Show a) => Show (Axiom a) where+    show (TypeAxiom x) = ": " ++ show x+    show (EqualityAxiom ps ex) = [qq|$ps = $ex|]++instance (Show a, ToJExpr a) => ToJExpr [Axiom a] where+    toJExpr [] = toJExpr . scope $ (Curried [] :: Curried a)+    toJExpr (TypeAxiom _:xs) = toJExpr xs+    toJExpr xs @ (EqualityAxiom (Match ps _) _ : _) = scope . curry (length ps) id . toStat . Curried $ xs++newtype Curried a = Curried [Axiom a]++instance (Show a, ToJExpr a) => ToStat (Curried a) where++    toStat (Curried []) = [jmacro| exhaust(); |]++    toStat (Curried (EqualityAxiom (Match [] Nothing) (Addr _ _ ex) : xss)) = ++        [jmacro|    return `(ex)`; |]++    toStat (Curried (EqualityAxiom (Match pss Nothing) (Addr _ _ ex) : xss)) = ++        [jmacro|    `(declare_bindings (var_names pss) pss)`;+                    if (`(pss)`) return `(ex)`;+                    `(Curried xss)`; |]+                    +    toStat (Curried (EqualityAxiom (Match [] cond) (Addr _ _ ex) : xss)) = ++        [jmacro|    if (`(cond)`) return `(ex)`; |]+                    ++    toStat (Curried (EqualityAxiom (Match pss cond) (Addr _ _ ex) : xss)) = ++        [jmacro|    `(declare_bindings (var_names pss) pss)`;+                    if (`(pss)` && `(cond)`) return `(ex)`;+                    `(Curried xss)`; |]+++declare_bindings (name : names) (AliasPattern x : zs) =++    declare_bindings (take (length x) (repeat name)) x ++ declare_bindings names zs++declare_bindings (name : names) (VarPattern x : zs) =+    +    [jmacro| `(declare x name)`; |] ++ declare_bindings names zs++declare_bindings (name : names) (RecordPattern x _: zs) = +    let (ns, z) = unzip . M.toList $ x+    in  declare_bindings (map (acc name) ns) z ++ declare_bindings names zs++declare_bindings (_ : names) (_ : zs) = declare_bindings names zs+declare_bindings [] [] = mempty++var_names :: forall a. [a] -> [JExpr]+var_names pss = map ref . reverse . take (length pss) . map local_pool $ [0 .. 26]++acc n ns = [jmacroE| `(n)`[`(ns)`] |]+++instance (ToJExpr a) => ToJExpr (Maybe a) where+    toJExpr = maybe (toJExpr True) toJExpr
+ src/hs/Forml/Types/Definition.hs view
@@ -0,0 +1,153 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses #-}++module Forml.Types.Definition where++import Text.InterpolatedString.Perl6+import Language.Javascript.JMacro++import Control.Applicative+import Control.Monad+import Data.Monoid++import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import qualified Text.Parsec as P+import Text.Parsec.Indent  hiding (same)++import Forml.Parser.Utils+import Forml.Javascript.Utils+import Forml.Javascript.Backend++import Forml.Types.Type+import Forml.Types.Symbol+import Forml.Types.Pattern+import Forml.Types.Axiom+import Forml.Types.Expression++import Prelude hiding (curry, (++))++++-- Definition+-- --------------------------------------------------------------------------------++data Visibility = Public | Private+++data Definition = Definition Visibility Bool Symbol [Axiom (Expression Definition)]++instance Show Definition where+    show (Definition Public _ name ax) =[qq|$name {sep_with "\\n" ax}|]+    show (Definition Private _ name ax) =[qq|private $name {sep_with "\\n" ax}|]++instance Syntax Definition where++    syntax = do whitespace+                vis <- option Public (try (string "private" >> spaces >> return Private))+                inl <- option False (try (string "inline" >> spaces >> return True))+                (x, y) <- try prefix <|> try infix''+                return $ Definition vis inl x y++        where infix'' =++                  do whitespace+                     first_arg <- try syntax+                     whitespace+                     op <- not_reserved $ many1 operator+                     whitespace+                     Match pss cond <- syntax+                     ax <- no_args_eq_axiom $ Match (first_arg:pss) cond+                     axs <- try (prefix' $ Operator op) <|> return []+                     return (Operator op, ax:axs)++                  where no_args_eq_axiom patterns =++                          do whitespace *> string "=" *> spaces *> indented+                             ex <- withPos (addr syntax)+                             return $ EqualityAxiom patterns ex++              prefix = ++                  do name <- try syntax <|> (Symbol <$> many1 (char '_'))+                     y <- prefix' name+                     return (name, y)+          +              prefix' name =++                       do sig <- first+                          eqs <- (try $ spaces *> (withPos . many . try $ try infix_axiom <|> eq_axiom)) <|> return []+                          whitespace+                          if length sig == 0 && length eqs == 0 +                              then parserFail "Definition Axioms"+                              else return (sig ++ eqs)++                where first = try type_or_first+                              <|> ((:[]) <$> try naked_eq_axiom)+                              <|> ((:[]) <$> (whitespace *> infix_axiom))+                              <|> return []++                      type_or_first = (:) <$> type_axiom <*> second++                      second = option [] ((:[]) <$> try (no_args_eq_axiom (Match [] Nothing)))++                      eq_axiom =++                          do try (spaces >> same) <|> (whitespace >> return ())+                             string "|" <|> try (string name' <* notFollowedBy (digit <|> letter)) +                             naked_eq_axiom++                          where name' = case name of+                                         (Symbol name'')   -> name''+                                         (Operator name'') -> "(" ++ name'' ++ ")"++                      naked_eq_axiom =++                          do whitespace+                             patterns <- syntax+                             no_args_eq_axiom patterns++                      no_args_eq_axiom patterns =++                          do P.spaces *> string "=" *> spaces *> indented+                             ex <- withPos (addr syntax)+                             return $ EqualityAxiom patterns ex++                      infix_axiom =+                          +                          case name of+                             (Symbol _)   -> parserFail "Infix Definition"+                             (Operator name'') -> do first_arg <- syntax+                                                     whitespace+                                                     string name''+                                                     whitespace+                                                     Match pss cond <- syntax+                                                     no_args_eq_axiom $ Match (first_arg:pss) cond ++                      type_axiom =++                          do spaces+                             indented+                             string ":"+                             spaces+                             indented+                             TypeAxiom <$> withPos type_axiom_signature++-- TODO Visibility should be more than skin deep?++instance Javascript Definition JStat where+    toJS (Definition _ _ _ (TypeAxiom _: [])) = return mempty+    toJS (Definition _ _ name as) = return [jmacro| `(declare_this (to_name name) $ toJExpr as)`; |]++instance ToLocalStat Definition where+    toLocal (Definition _ _ _ (TypeAxiom _: [])) = mempty+    toLocal (Definition _ _ name as) = [jmacro| `(declare (to_name name) $ toJExpr as)`; |]
+ src/hs/Forml/Types/Expression.hs view
@@ -0,0 +1,529 @@+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE FlexibleInstances    #-}+{-# LANGUAGE GADTs                #-}+{-# LANGUAGE NamedFieldPuns       #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes          #-}+{-# LANGUAGE RankNTypes           #-}+{-# LANGUAGE RecordWildCards      #-}+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE TemplateHaskell      #-}+{-# LANGUAGE ViewPatterns         #-}++module Forml.Types.Expression where++import Language.Javascript.JMacro++import Control.Applicative+import Control.Monad+import Control.Monad.State hiding (lift)++import           Text.InterpolatedString.Perl6+import           Text.Parsec                   hiding (State, label, many, parse, spaces, (<|>))+import qualified Text.Parsec                   as P+import           Text.Parsec.Expr+import           Text.Parsec.Indent            hiding (same)++import qualified Data.List         as L+import qualified Data.Map          as M+import           Data.Monoid+import           Data.String.Utils hiding (join)+++import Forml.Javascript.Utils+import Forml.Parser.Utils+import Forml.Types.Axiom+import Forml.Types.Literal+import Forml.Types.Pattern+import Forml.Types.Symbol+import Forml.Types.Type++import Prelude hiding (curry, (++))++++-- Expression+-- --------------------------------------------------------------------------------++class ToLocalStat a where+    toLocal :: a -> JStat++data Lazy = Once | Every++data Expression d = ApplyExpression (Expression d) [Expression d]+                  | IfExpression (Expression d) (Expression d) (Expression d)+                  | LiteralExpression Literal+                  | SymbolExpression Symbol+                  | JSExpression JExpr+                  | LazyExpression (Addr (Expression d)) Lazy+                  | FunctionExpression [Axiom (Expression d)]+                  | RecordExpression (M.Map Symbol (Expression d))+                  | InheritExpression (Expression d) (M.Map Symbol (Expression d))+                  | LetExpression [d] (Expression d)+                  | ListExpression [Expression d]+                  | AccessorExpression (Addr (Expression d)) [Symbol]++instance (Show d) => Show (Expression d) where++    show (ApplyExpression x @ (SymbolExpression (show -> f : _)) y)+        | f `elem` "abcdefghijklmnopqrstuvwxyz" = [qq|$x {sep_with " " y}|]+        | length y == 2                         = [qq|{y !! 0} $x {y !! 1}|]++    show (ApplyExpression x y)   = [qq|$x {sep_with " " y}|]+    show (IfExpression a b c)    = [qq|if $a then $b else $c|]+    show (LiteralExpression x)   = show x+    show (SymbolExpression x)    = show x+    show (ListExpression x)      = [qq|[ {sep_with ", " x} ]|]+    show (FunctionExpression as) = replace "\n |" "\n     |" $ [qq|(λ{sep_with "| " as})|]+    show (JSExpression x)        = "`" ++ show (renderJs x) ++ "`"+    show (LazyExpression x Once)      = "lazy " ++ show x+    show (LazyExpression x Every)      = "do " ++ show x+    show (LetExpression ax e)    = replace "\n |" "\n     |" $ [qq|let {sep_with "\\n| " ax} in ($e)|]+    show (RecordExpression m)    = [qq|\{ {unsep_with " = " m} \}|]+    show (InheritExpression x m) = [qq|\{ $x with {unsep_with " = " m} \}|]+    show (AccessorExpression x m) = [qq|$x.{sep_with "." m}|]+++instance (Syntax d, Show d) => Syntax (Expression d) where++    syntax = try if' <|> try infix' <|> other++        where other = try let'+                      <|> try do'+                      <|> try yield+                      <|> try lazy+                      <|> other_next++              other_next =++                      try apply+                      <|> function+                      <|> try accessor+                      <|> inner++              inner = try accessor <|> inner_no_accessor++              inner_no_accessor =+                      indentPairs "(" syntax ")"+                      <|> js+                      <|> try record+                      <|> named_key+                      <|> literal+                      <|> symbol+                      <|> try array+                      <|> list++              let' = withPosTemp $ do string "var" <|> string "let"+                                      whitespace1+                                      defs <- withPos def+                                      spaces+                                      try (do string "in"+                                              spaces+                                              LetExpression <$> return defs <*> syntax)+                                         <|> do same+                                                LetExpression <$> return defs <*> syntax++                  where def = try syntax `sepBy1` (try comma <|> try (spaces *> same))++              do'  = do s <- getPosition+                        string "do"+                        i <- try (string "!") <|> return ""+                        P.spaces+                        l <- withPos line+                        if i == "!"+                           then return$ ApplyExpression (SymbolExpression (Symbol "run")) [wrap s l]+                           else return$ wrap s l++                  where line = try bind <|> try let_bind <|> try return'++                        wrap s x = LazyExpression (Addr s s (ApplyExpression (SymbolExpression (Symbol "run")) [x])) Every++                        bind = do p <- syntax+                                  whitespace <* (string "<-" <|> string "←") <* whitespace+                                  ex <- withPos syntax+                                  spaces *> same+                                  f ex p <$> addr line++                        let_bind = withPosTemp $ do string "let"+                                                    whitespace1+                                                    defs <- withPos def+                                                    spaces+                                                    same+                                                    LetExpression <$> return defs <*> line++                            where def = try syntax `sepBy1` try (spaces *> same)++                        return' = do v <- syntax+                                     option v $ try $ unit_bind v++                        unit_bind v = do spaces *> same+                                         f v AnyPattern <$> addr line++                        f ex pat zx = ApplyExpression+                                         (SymbolExpression (Operator ">>="))+                                         [ ex, (FunctionExpression+                                                    [ EqualityAxiom+                                                      (Match [pat] Nothing)+                                                      zx ]) ]++              lazy  = do string "lazy"+                         whitespace1+                         LazyExpression <$> withPos (addr$ try syntax) <*> return Once++              yield = do string "yield"+                         whitespace1+                         LazyExpression <$> withPos (addr$ try syntax) <*> return Every++              if' = withPos $ do string "if"+                                 whitespace1+                                 e <- withPos$ try infix' <|> other+                                 spaces+                                 try (jStyle e) <|> hStyle e++                    where jStyle e = do indented+                                        cont e++                          hStyle e = do string "then"+                                        whitespace1+                                        cont e++                          cont e   = do t <- withPos$ try infix' <|> other+                                        P.spaces+                                        string "else"+                                        whitespace1+                                        IfExpression e t <$> withPos (try infix' <|> other)++              infix' = buildExpressionParser table term++                  where table  = [ [ix "^"]+                                 , [ix "*", ix "/"]+                                 , [px "-", px "!" ]+                                 , [ix "+", ix "-"]+                                 , [ Infix user_op_right AssocRight, Infix user_op_left AssocLeft ]+                                 , [ix "<", ix "<=", ix ">=", ix ">", ix "==", ix "!=", ix "is", ix "isnt"]+                                 , [ix "&&", ix "||", ix "and", ix "or" ] ]++                        ix s   = Infix (try . op $ (unwind <$> string s) <* notFollowedBy operator) AssocLeft++                        unwind "and" = Operator "&&"+                        unwind "or" = Operator "||"+                        unwind "is" = Operator "=="+                        unwind "isnt" = Operator "!="+                        unwind x = Operator x++                        px s   = Prefix (try neg)+                                 where neg = do spaces+                                                op <- SymbolExpression . Operator <$> string s+                                                spaces+                                                return (\x -> ApplyExpression op [x])++                        term   = try other++                        user_op_left = try $ do spaces+                                                op' <- not_system (many1 operator)+                                                spaces+                                                return $ f op'++                        user_op_right = try $ do spaces+                                                 op' @ (end -> x : _) <- g operator+                                                 spaces+                                                 if x == ':'+                                                     then return $ f op'+                                                     else parserFail "Operator"++                        f op' x y = ApplyExpression (SymbolExpression (Operator op')) [x, y]++                        g = not_system . many1++                        op p   = do spaces+                                    op' <- SymbolExpression <$> p+                                    spaces++                                    return (\x y -> ApplyExpression op' [x, y])++              named_key = do x <- indentPairs "{" syntax "}"+                             return $ RecordExpression (M.fromList [(x, SymbolExpression (Symbol "true"))])++              accessor = do s <- getPosition+                            x <- indentPairs "(" syntax ")"+                                 <|> js+                                 <|> record+                                 <|> literal+                                 <|> try java_apply+                                 <|> try symbol+                                 <|> list++                            f <- getPosition+                            string "."+                            z <- syntax `sepBy1` string "."+                            return $ acc_exp (Addr s f) x z++              acc_exp f x z = AccessorExpression (f x) z++              java_apply = ApplyExpression <$> inner_no_accessor <*> try java++                  where java = indentPairs "(" java_args ")"+                            where  java_args = do x <- syntax `sepEndBy1` comma+                                                  option x ((x ++) <$> try java)++              apply = ApplyExpression <$> inner <*> arguments++                  where arguments = try java <|> try cont <|> halt++                            where cont = do x <- whitespace *> (try (ApplyExpression <$> inner <*> java) <|> inner)+                                            option [x] ((x:) <$> try (whitespace *> (try cont <|> halt)))++                                  halt = (:[]) <$> (whitespace *> (try let'+                                                    <|> try do'+                                                    <|> try lazy+                                                    <|> try yield+                                                    <|> function))++                        java = indentPairs "(" java_args ")"+                            where  java_args = do x <- syntax `sepEndBy1` comma+                                                  option x ((x ++) <$> try arguments)++              -- No idea why this is necessary?+              withPosTemp :: Parser a -> Parser a+              withPosTemp p = do x <- get+                                 z <- try (Just <$> p) <|> return Nothing+                                 put x+                                 case z of+                                   Just z -> return z+                                   Nothing -> parserFail ("expression continuation indented to " ++ show x)++              function = withPosTemp$ withPos $ do try (char '\\') <|> char 'λ'+                                                   whitespace+                                                   pat_fun++                  where pat_fun    = do t <- option [] ( ((:[]) <$> type_axiom <* spaces))+                                        eqs <- try eq_axiom `sepBy1` try (spaces *> string "|" <* whitespace)+                                        return $ FunctionExpression (t ++ eqs)++                        type_axiom = do string ":"+                                        spaces+                                        indented+                                        TypeAxiom <$> withPos type_axiom_signature++                        eq_axiom   = do patterns <- syntax+                                        string "="+                                        spaces+                                        indented+                                        ex <- withPosTemp $ withPos (addr syntax)+                                        return $ EqualityAxiom patterns ex++              js = g <$> indentPairs "`" (many $ noneOf "`") "`"+                  where p (parseJM . wrap -> Right (BlockStat [AssignStat _ x])) =+                            [jmacroE| (function() { return `(x)`; }) |]+                        p (parseJM . (++";") -> Right z) = [jmacroE| (function() { `(z)`; }) |]+                        p (parseJM . concat . L.intersperse ";" . h . split ";" -> Right x) =+                            [jmacroE| (function() { `(x)`; }) |]+                        p _ = error "\n\nJavascript parsing failed"++                        g x | last x == '!' = ApplyExpression (SymbolExpression (Symbol "run"))+                                              [JSExpression (p (take (length x - 1) x))]+                            | otherwise = JSExpression$ p x++                        h [] = []+                        h (x:[]) = ["return " ++ x]+                        h (x:xs) = x : h xs++                        wrap x = "__ans__ = " ++ x ++ ";"++              record = indentPairs "{" (try inherit <|> (RecordExpression . M.fromList <$>  pairs')) "}"++                  where pairs' = withPos $ (try key_eq_val <|> try function')+                                         `sepBy` optional_sep++                        function' = do n <- syntax+                                       whitespace+                                       eqs <- try eq_axiom `sepBy1` try (spaces *> string "|" <* whitespace)+                                       return $ (n, FunctionExpression eqs)++                        eq_axiom   = do patterns <- syntax+                                        string "="+                                        spaces+                                        indented+                                        ex <- withPos (addr syntax)+                                        return $ EqualityAxiom patterns ex++                        inherit = do ex <- syntax+                                     spaces *> indented+                                     string "with"+                                     spaces *> indented+                                     ps <- pairs'+                                     return $ InheritExpression ex (M.fromList ps)++                        key_eq_val = do key <- syntax+                                        whitespace+                                        string "=" <|> string ":"+                                        spaces+                                        value <- withPos syntax+                                        return (key, value)++              literal = do (sourceColumn -> x) <- getPosition+                           undo x <$> syntax++              strip_indent x y = let splitted = split "\n" y+                                     r x' | strip (take x x') == "" = drop x x'+                                          | otherwise = error$ "Badly formatted string \"" ++ show splitted ++ "\""+                                 in  if length splitted > 1+                                     then head splitted ++ "\n" ++ (concat . L.intersperse "\n" . fmap r . tail $ splitted)+                                     else y++              undo z (StringLiteral x) = to_escaped . split "`" . strip_indent z $ x+              undo _ l = LiteralExpression l++              to_escaped (x:s:xs) =+                  ApplyExpression (SymbolExpression$ Operator "+++")+                                      [ ApplyExpression (SymbolExpression$ Operator "+++")+                                        [LiteralExpression $ StringLiteral x+                                          , p s ]+                                      , to_escaped xs ]+              to_escaped (l:[]) = LiteralExpression $ StringLiteral l+              to_escaped [] =  LiteralExpression $ StringLiteral ""++              p s = case parse syntax "Escaped String" s of+                      Left x -> error$ show x+                      Right x -> x++              symbol  = SymbolExpression <$> syntax++              list    = ListExpression <$> indentPairs "[" v "]"+                  where v = do whitespace+                               withPos (syntax `sepBy` optional_sep)++              array   = f <$> indentAsymmetricPairs "[:" v (try (string ":]") <|> string "]")++                  where v = do whitespace+                               withPos (syntax `sepBy` optional_sep)++                        f [] = RecordExpression (M.fromList [(Symbol "nil", SymbolExpression (Symbol "true"))])+                        f (x:xs) = RecordExpression (M.fromList [(Symbol "head", x), (Symbol "tail", f xs)])++class Opt a where+    opt :: a -> a++instance (Opt a, Opt b) => Opt (a, b) where+    opt (a, b) = (opt a, opt b)++instance (Opt a) => Opt [a] where+    opt x = map opt x++instance (Functor m, Opt a) => Opt (m a) where+    opt x = fmap opt x++instance Opt JStat where+    opt (ReturnStat x)      = ReturnStat (opt x)+    opt (IfStat a b c)      = IfStat (opt a) (opt b) (opt c)+    opt (WhileStat a b)     = WhileStat (opt a) (opt b)+    opt (ForInStat a b c d) = ForInStat a b (opt c) (opt d)+    opt (SwitchStat a b c)  = SwitchStat (opt a) (opt b) (opt c)+    opt (TryStat a b c d)   = TryStat (opt a) b (opt c) (opt d)+    opt (BlockStat xs)      = BlockStat (opt xs)+    opt (ApplStat a b)      = ApplStat (opt a) (opt b)+    opt (PPostStat a b c)   = PPostStat a b (opt c)+    opt (AssignStat a b)    = AssignStat (opt a) (opt b)+    opt (UnsatBlock a)      = UnsatBlock (opt a)++    opt x = x++    -- opt (DeclStat    Ident (Maybe JLocalType)+    -- opt (UnsatBlock (IdentSupply JStat)+    -- opt (AntiStat   String+    -- opt (ForeignStat Ident JLocalType+    -- opt (BreakStat+++instance Opt JVal where+    opt (JList xs)   = JList (opt xs)+    opt (JHash m)    = JHash (M.map opt m)+    opt (JFunc xs x) = JFunc xs (opt x)+    opt (UnsatVal x) = UnsatVal (opt x)++    opt x = x++    -- opt x@(JVar _) = x+    -- opt x@(JDouble _) = x+    -- opt x@(JInt _) = x+    -- opt x@(JStr _) = x+    -- opt x@(JRegEx _) = x++instance Opt JExpr where+    opt (SelExpr e (StrI i))  = IdxExpr (opt e) (ValExpr (JStr i))  -- Closure fix - advanced mode nukes these+    opt (IdxExpr a b)         = IdxExpr (opt a) (opt b)+    opt (InfixExpr a b c)     = InfixExpr a (opt b) (opt c)+    opt (PPostExpr a b c)     = PPostExpr a b (opt c)+    opt (IfExpr a b c)        = IfExpr (opt a) (opt b) (opt c)+    opt (NewExpr a)           = NewExpr (opt a)+    opt (ApplExpr a b)        = ApplExpr (opt a) (map opt b)+    opt (TypeExpr a b c)      = TypeExpr a (opt b) c+    opt (ValExpr a)           = ValExpr (opt a)+    opt (UnsatExpr a)         = UnsatExpr (opt a)++instance (Show d, ToLocalStat d) => ToJExpr (Expression d) where++--    toJExpr (ApplyExpression (SymbolExpression (Symbol "run")) [x]) = [jmacroE| `(x)`() |]++    toJExpr (ApplyExpression (SymbolExpression f @ (Operator _)) [x, y]) =+        toJExpr (ApplyExpression (SymbolExpression (Symbol (to_name f))) [x,y])++    toJExpr (ApplyExpression (SymbolExpression (Operator _)) x) =+        error $ "Operator with " ++ show (length x) ++ " params"++    toJExpr (ApplyExpression (SymbolExpression f) []) = ref (to_name f)+    toJExpr (ApplyExpression f []) = [jmacroE| `(f)` |]+    toJExpr (ApplyExpression f (end -> x : xs)) = [jmacroE| `(ApplyExpression f xs)`(`(x)`) |]++    toJExpr (AccessorExpression (Addr _ _ x) []) =++        toJExpr x++    toJExpr (AccessorExpression x (reverse -> y:ys)) =++        [jmacroE| `(AccessorExpression x (reverse ys))`[`(to_name y)`] |]++    toJExpr (ListExpression x)      = toJExpr x+    toJExpr (LiteralExpression l)   = toJExpr l+    toJExpr (SymbolExpression x)    = ref (to_name x)+    toJExpr (FunctionExpression x)  = toJExpr x+    toJExpr (LazyExpression x Every) =++        toJExpr (FunctionExpression+                 [ EqualityAxiom+                   (Match [AnyPattern] Nothing)+                   x ])++    toJExpr (LazyExpression (Addr _ _ x) Once) =++        [jmacroE| (function() {+                      var y = undefined;+                      return function() {+                          if (y) {+                              return y;+                          } else {+                              y = `(x)`;+                              return y;+                          }+                      }+                  })() |]++    toJExpr (RecordExpression m)    = toJExpr (M.mapKeys to_name m)+    toJExpr (JSExpression s)        = opt s+    toJExpr (LetExpression bs ex) =++        [jmacroE| (function() { `(foldl1 mappend $ map toLocal bs)`; return `(ex)` })() |]++    toJExpr (IfExpression x y z) =++        [jmacroE| (function(){+                     if (`(x)`) {+                        return `(y)`;+                     } else {+                        return `(z)`+                     }+                   })() |]++    toJExpr x = error $ "Unimplemented " ++ show x++
+ src/hs/Forml/Types/Literal.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE MultiParamTypeClasses #-}++module Forml.Types.Literal where++import Language.Javascript.JMacro++import Control.Applicative+import Text.Parsec         hiding ((<|>), State, many, spaces, parse, label)++import Forml.Parser.Utils+import Forml.TypeCheck.Types++data Literal = StringLiteral String | IntLiteral Int | DoubleLiteral Double++instance Show Literal where+   show (StringLiteral x) = show x+   show (IntLiteral x)    = show x+   show (DoubleLiteral x) = show x++instance Syntax Literal where++    syntax = try flt <|> try num <|> try str++        where flt = DoubleLiteral <$> syntax +              num = IntLiteral    <$> syntax+              str = StringLiteral <$> syntax++instance ToJExpr Literal where+    toJExpr (StringLiteral s) = toJExpr s+    toJExpr (IntLiteral s)    = toJExpr s+    toJExpr (DoubleLiteral s) = toJExpr s++instance Infer Literal Type where+    infer (StringLiteral _) = return (Type (TypeConst "String" Star))+    infer (IntLiteral _)    = return (Type (TypeConst "Num" Star))+    infer (DoubleLiteral _)    = return (Type (TypeConst "Double" Star))+    
+ src/hs/Forml/Types/Namespace.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}++module Forml.Types.Namespace where++import Language.Javascript.JMacro++import Control.Applicative++import Text.Parsec hiding ((<|>), State, many, spaces, parse, label)+import Data.Monoid+import qualified Data.List as L++import Forml.Parser.Utils+import Forml.Javascript.Utils++import Prelude hiding (curry, (++))++newtype Namespace = Namespace [String] deriving (Eq)++instance Monoid Namespace where+    mempty = Namespace []+    mappend (Namespace x) (Namespace y) = Namespace (x ++ y)++instance Show Namespace where+    show (Namespace []) = "global"+    show (Namespace x) = concat $ L.intersperse "." x++instance Syntax Namespace where+    syntax = Namespace <$> (many1 lower `sepBy1` char '.')++instance ToJExpr Namespace where+    toJExpr (Namespace []) = ref "this"+    toJExpr (Namespace (end -> x : xs)) = [jmacroE| `(Namespace xs)`[`(x)`] |]+++++data Module = Module Namespace [Module]+            | Var String++instance Show Module where+    show (Module (Namespace (reverse -> (x:_))) _) = x+    show (Var s) = s+
+ src/hs/Forml/Types/Pattern.hs view
@@ -0,0 +1,256 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses #-}++module Forml.Types.Pattern where++import Text.InterpolatedString.Perl6+import Data.Maybe+import Language.Javascript.JMacro++import Control.Applicative+import Control.Monad++import Text.Parsec         hiding ((<|>), State, many, spaces, parse, label)+import qualified Text.Parsec as P+import qualified Data.List as L+import Text.Parsec.Indent  hiding (same)++import qualified Data.Map as M++import Forml.Parser.Utils+import Forml.Javascript.Utils++import Forml.Types.Literal+import Forml.Types.Type+import Forml.Types.Symbol+import Forml.TypeCheck.Types++import Prelude hiding (curry, (++))+import System.IO.Unsafe (unsafePerformIO)+import Data.Monoid (mappend)++++++-- Pattern+-- --------------------------------------------------------------------------------++data Match a = Match [Pattern a] (Maybe a)+data Pattern a = VarPattern String+               | AnyPattern+               | LiteralPattern Literal+               | RecordPattern (M.Map Symbol (Pattern a)) Partial+               | ListPattern [Pattern a]+               | ViewPattern a (Pattern a)+               | AliasPattern [Pattern a]+++instance (Show a) => Show (Match a) where+    show (Match p Nothing)  = sep_with " " p+    show (Match p (Just x)) = [qq|{sep_with " " p} when $x|]++instance (Syntax a, Show a) => Syntax (Match a) where++    syntax = try conditional <|> ((\x -> Match x Nothing) <$> (try jStyle <|> hStyle))++        where ++          jStyle = do x <- indentPairs "(" (syntax `sepBy1` comma) ")"+                      spaces+                      if length x > 1 then return x else fail "Java-style arguments"++          hStyle = syntax `sepEndBy` whitespace1++          conditional = do x <- try jStyle <|> try hStyle+                           string "when"+                           spaces+                           indented+                           ex <- withPos syntax+                           spaces+                           indented+                           return $ Match x (Just ex)++newtype Condition = Condition JExpr++instance ToJExpr [Condition] where+    toJExpr [] = toJExpr True+    toJExpr (Condition x : []) = [jmacroE| `(x)` |]+    toJExpr (Condition x : xs) = [jmacroE| `(x)` && `(xs)` |]++data PatternMatch a = PM String (Pattern a)++instance (Show a) => ToJExpr [PatternMatch a] where+    toJExpr []     = toJExpr True+    toJExpr (x:[]) = [jmacroE| `(x)` |]+    toJExpr (x:xs) = [jmacroE| `(x)` && `(xs)` |]++instance (Show a) => ToJExpr (PatternMatch a) where++    toJExpr (PM n (AliasPattern xs)) = toJExpr $ filter fil $ map (PM n) xs++    toJExpr (PM n (LiteralPattern x)) =++        [jmacroE| `(ref n)` === `(x)` |]++    toJExpr (PM n (RecordPattern (M.toList -> xs) _)) =++        [jmacroE| `(map g xs)` && `(filter fil $ map f xs)` |]+            where f (key, val) = PM (n ++ "[\"" ++ to_name key ++ "\"]") val+                  g (key, _) = Condition [jmacroE| __check(`(ref n)`, `(to_name key)`) |]++    toJExpr (PM n (ListPattern [])) =+        [jmacroE| equals(`(n)`)([]) |]+    toJExpr (PM n (ListPattern xs)) = +        let x = toJExpr (map f (zip [(0 :: Int) ..] xs))+            f (index, val) = toJExpr (PM (n ++ "[" ++ show index ++ "]") val)+        in   [jmacroE| `(x)` && `(ref n)`.length == `(length xs)` |]+    toJExpr (PM _ x) = error $ "Unimplemented " ++ show x++data Partial = Partial | Complete deriving (Eq, Show)++instance (Show a) => Show (Pattern a) where+    show (VarPattern x)     = x+    show AnyPattern         = "_"+    show (LiteralPattern x) = show x+    show (ListPattern x)    = [qq|[ {sep_with ", " x} ]|]+    show (ViewPattern x y)  = [qq|($x -> $y)|]+    show (RecordPattern m Complete)  = [qq|\{ {unsep_with " = " m} \}|] +    show (RecordPattern m Partial)   = [qq|\{ {unsep_with " = " m}, _ \}|]+    show (AliasPattern a) = sep_with " & " a++instance (Show a, ToJExpr a) => ToJExpr [Pattern a] where++    toJExpr ps = toJExpr$ filter fil $ zipWith PM (reverse . take (length ps) . map local_pool $ [0 .. 26]) ps+    +fil (PM _ (VarPattern _)) = False+fil (PM _ AnyPattern) = False+fil (PM _ (RecordPattern (M.toList -> []) Complete)) = False+fil _ = True++instance (Syntax a, Show a) => Syntax (Pattern a) where+    +    syntax = try literal+             <|> try var+             <|> any'+             <|> try record+             <|> naked_apply+             <|> array+             <|> list+             <|> indentPairs "(" (try alias <|> syntax) ")"+                     +        where alias = let sep = P.spaces <* string "&" <* P.spaces+                      in  AliasPattern <$> ((:) <$> syntax <* sep <*> sepBy1 syntax sep) ++              var         = VarPattern <$> type_var+              literal     = LiteralPattern <$> syntax+              any'        = many1 (string "_") *> return AnyPattern+              naked_apply =++                  do x <- indentPairs "{" (many1 letter) "}"+                     return $ RecordPattern (M.fromList [(Symbol x, AnyPattern )]) Complete++              record  = indentPairs "{" any_record "}"+                                                   ++                  where pairs = (try key_eq_val <|> (many1 (char '_') >> return Nothing)) `sepEndBy` optional_sep++                        any_record =+                        +                              do ps <- pairs+                                 let ps' = catMaybes ps+                                 return $+                                   case (length ps, (not . isJust) `filter` ps) of+                                     (0, _)           -> RecordPattern M.empty Complete+                                     (_, (Nothing:_)) -> RecordPattern (M.fromList ps') Partial+                                     _                -> RecordPattern (M.fromList ps') Complete++                        key_eq_val = do key <- syntax+                                        spaces+                                        string "=" <|> string ":"+                                        spaces+                                        value <- syntax+                                        return$ Just (key, value)++              list = ListPattern <$> indentPairs "[" (syntax `sepBy` optional_sep) "]"++              array = f <$> indentAsymmetricPairs "[:" v (try (string ":]") <|> string "]")++                  where v = do whitespace+                               withPos (syntax `sepBy` optional_sep)++                        f []     = RecordPattern (M.fromList [(Symbol "nil", AnyPattern)]) Complete+                        f (x:xs) = RecordPattern (M.fromList [(Symbol "head", x), (Symbol "tail", f xs)]) Complete++++instance (Show b) => Infer (Pattern b) Type where++    infer (AliasPattern (x:[])) = infer x+           +    infer (AliasPattern (x:xs)) = +        do z <- infer x+           z' <- infer (AliasPattern xs)+           unify z z'+           return z'++    infer (VarPattern i) = do v <- newTVar Star+                              assume (i :>: toScheme v)+                              return v++    infer AnyPattern = newTVar Star++    infer (LiteralPattern x) = infer x++    infer (ListPattern xs) = do ts <- mapM infer xs+                                t' <- newTVar Star+                                (qs :=> t) <- freshInst list_scheme+                                mapM_ (unify t') ts+                                predicate qs+                                return t++    infer (RecordPattern (unzip . M.toList -> (names, patterns)) p) =+        +        do ts <- mapM infer patterns+           p' <- case p of+                   Complete -> return TComplete+                   Partial  -> do t <-  newTVar Star+                                  return$ TPartial t++           let r = TypeRecord (TRecord (M.fromList (zip (map f names) ts)) p' Star)+           t' <- newTVar Star+           sc <- find $ quantify (tv r) ([] :=> r)+           case sc of+             Nothing ->+                 do unify t' r+                    return t'+             Just (Forall _ scr, sct) ->+                 do (_ :=> t'') <- freshInst sct+                    (qs :=> t''') <- return$ inst (map TypeVar$ tv t'') scr+                    (_ :=> t) <- freshInst (quantify (tv t''' L.\\ tv t'') (qs :=> t'''))+                    unify t r+                    unify t' t''+                    s <- get_substitution+                    let t''' = apply s t+                        r''' = apply s r+                        qt = quantify (tv t''') $ [] :=> t'''+                        rt = quantify (tv r''') $ [] :=> r'''+                    if qt /= rt+                        then do add_error$ "Object constructor does not match signature\n" +                                             ++ "  Expected: " ++ show qt ++ "\n" +                                             ++ "  Actual:   " ++ show rt+                                return t'+                        else return t'++        where f (Symbol x) = x+              f (Operator x) = x
+ src/hs/Forml/Types/Statement.hs view
@@ -0,0 +1,301 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances, KindSignatures #-}++module Forml.Types.Statement where++import Text.InterpolatedString.Perl6++import Language.Javascript.JMacro++import Control.Applicative++import Text.Parsec         hiding ((<|>), State, many, spaces, parse, label)+import Text.Parsec.Indent  hiding (same)++import Data.String.Utils+import Data.Monoid+import qualified Data.List as L++import Forml.Parser.Utils++import Forml.Types.Type+import Forml.Types.Axiom+import Forml.Types.TypeDefinition+import Forml.Types.Symbol+import Forml.Types.Definition+import Forml.Types.Expression+import Forml.Types.Namespace++import Forml.Javascript.Utils+import Forml.Javascript.Backend++import Prelude hiding (curry, (++))+import System.IO.Unsafe (unsafePerformIO)++++--------------------------------------------------------------------------------+----+---- Statement++data Statement = TypeStatement TypeDefinition UnionType+               | DefinitionStatement Definition+               | ExpressionStatement (Addr (Expression Definition))+               | ImportStatement Namespace+               | ModuleStatement Namespace [Statement]++instance Show Statement where+    show (TypeStatement t c)     = [qq|type $t = $c|]+    show (DefinitionStatement d) = show d+    show (ExpressionStatement (Addr _ _ x)) = show x+    show (ImportStatement x) = [qq|import $x|]+    show (ModuleStatement x xs) = replace "\n |" "\n     |" +                                  $ replace "\n\n" "\n\n    " +                                  $ "module " +                                  ++ show x ++ "\n\n" ++ sep_with "\n\n" xs++instance Syntax Statement where++    syntax = whitespace >> withPos statement_types <* many newline++        where statement_types =++                  (type_statement <?> "Type Definition")+                  <|> (try import_statement <?> "Import Statement")+                  <|> (module_statement <?> "Module Declaration")+                  <|> (try def_statement <?> "Symbol Definition")+                  <|> (expression_statement <?> "Assertion")++              def_statement = DefinitionStatement <$> syntax++              import_statement = do string "open"+                                    whitespace+                                    ImportStatement <$> syntax++              module_statement = do try (string "module")+                                    whitespace1+                                    name <- try syntax <|> (char '"' *> (Namespace . (:[]) <$> (anyChar `manyTill` char '"')))+                                    whitespace *> newline+                                    spaces *> (indented <|> same)+                                    ModuleStatement name <$> withPos (many1 ((spaces >> same >> syntax)))++              type_statement  = do try (string "type" >> spaces) <|> return ()+                                   def <- syntax+                                   set_indentation (+1)+                                   whitespace+                                   sig <- try (string "=" >> spaces >> (string "|" >> type_definition_signature))+                                          <|> (string "=" >> spaces >> type_definition_signature)+                                   whitespace+                                   set_indentation (+(-1))+                                   return $ TypeStatement def sig++              expression_statement = do try (string "test" >> spaces) <|> return ()+                                        whitespace+                                        x <- getPosition +                                        y <- withPos$ addr syntax+                                        z <- getPosition+                                        return $ ExpressionStatement y+                                                                   ++++--------------------------------------------------------------------------------+----+---- Meta++data Meta = Meta { target    :: Target,+                   namespace :: Namespace,+                   modules   :: [Module],+                   expr      :: Statement } deriving (Show)++data Target = Test | Library+            deriving (Show)++serial :: SourcePos -> SourcePos -> String+serial a b = show (sourceLine a - 1) ++ "_" ++ show (sourceLine b - 1) ++ (if sourceLine a /= sourceLine b then "multi" else "")++get_code :: forall a. Addr a -> JS String+get_code a = do src <- JS (\s @ JSState {src = src} -> (s, src))+                return $ get_error a src++instance Javascript Meta JStat where++    -- Expressions are ignored for Libraries, and rendered as tests for Test+    toJS (Meta { target = Library, expr = ExpressionStatement _ }) = return mempty+    toJS (Meta { target = Test,    expr = ExpressionStatement a' @ (Addr a b e) }) = ++        do message <- get_code a'+           return [jmacro| it(`(serial a b ++ "__::__" ++ message)`, function() {+                               `(Jasmine e)`;+                           }); |]++    -- Imports work identically for both targets+    toJS (Meta { modules, +                 namespace = Namespace [], +                 expr      = ImportStatement target_namespace @ (find modules -> Nothing) }) = ++        fail [qq| Could not resolve namespace $target_namespace |]  ++    toJS (Meta { modules, +                 expr      = ImportStatement target_namespace, +                 namespace = (find modules . (++ target_namespace) -> Just y) }) =++        return $ open target_namespace y++    toJS meta @ (Meta { expr = ImportStatement _, .. }) = ++        let slice (Namespace ns) = Namespace . take (length ns - 1) $ ns+        in  toJS (meta { namespace = slice namespace })++++    -- Modules in test mode must open the contents of the Library++    toJS meta @ (Meta { target = Library, namespace = Namespace [], expr = ModuleStatement ns xs, .. }) =+        +        do xs' <- toJS $ fmap (\z -> meta { namespace =  ns, expr = z }) xs+           return $ declare_window (show ns)+                 [jmacroE| new (function() { +                               `(xs')`;+                           }) |]++    toJS meta @ (Meta { target = Library, expr = ModuleStatement ns xs, .. }) =+        +        do xs' <- toJS $ fmap (\z -> meta { namespace = namespace ++ ns, expr = z }) xs+           return $ declare_this (show ns)+                 [jmacroE| new (function() { +                               `(xs')`;+                           }) |]+++    toJS meta @ (Meta { target = Test, expr = ModuleStatement ns xs, .. }) =++        let (imports, rest) = L.partition f xs+            f (ImportStatement _) = True+            f _ = False in++        do imports' <- toJS $ map (\z -> meta { namespace = namespace ++ ns, expr = z }) imports+           rest'    <- toJS $ map (\z -> meta { namespace = namespace ++ ns, expr = z }) rest++           return [jmacro| describe(`(show ns)`, function() {+                             `(open (namespace ++ ns) xs)`;+                             `(imports')`; +                             `(open (namespace ++ ns) xs)`;+        +                             var x = new (function {+                                 `(rest')`; +                             }());+                         }); |]++++    -- Definitions are ignored for the Test target++    toJS (Meta { target = Library, expr = DefinitionStatement d }) = toJS d+    toJS (Meta { target = Test,    expr = DefinitionStatement _ }) = return mempty++    toJS (Meta { expr = TypeStatement _ _ }) = return mempty+  --  toJS x = fail $ "Unimplemented " ++ show x++++empty_meta :: Target -> [Statement] -> Statement -> Meta+empty_meta x = Meta x (Namespace []) . build_modules++    where build_modules (ModuleStatement n ns : xs) = Module n (build_modules ns) : build_modules xs+          build_modules (DefinitionStatement (Definition _ _ n _): xs) = Var (to_name n) : build_modules xs+          build_modules (_ : xs) = build_modules xs+          build_modules [] = []++find :: [Module] -> Namespace -> Maybe [String]+find (Var s : ss) n @ (Namespace []) = Just [s] ++ find ss n+find (Var _: xs) ns                  = find xs ns+find [] (Namespace [])               = Just []+find [] _                            = Nothing++find (Module _ xs : ms) n @ (Namespace []) = Just (map show xs) ++ find ms n+find (Module (Namespace ys) x : zs) n @ (Namespace xs)+     | length xs >= length ys && take (length ys) xs == ys = +         find x (Namespace $ drop (length ys) xs)+     | otherwise = find zs n++++--------------------------------------------------------------------------------+----+---- Open++class Open a where open :: Namespace -> [a] -> JStat++instance Open Statement where+    open _ [] = mempty+    open ns (DefinitionStatement (Definition _ _ _ (TypeAxiom _: [])) : xs) = open ns xs+    open ns (DefinitionStatement (Definition _ _ n _) : xs) =++        let f = ref . replace " " "_" . show+            x = [jmacroE| `(f ns)`[`(n)`] |] in++        [jmacro| `(declare (replace " " "_" $ to_name n) x)`;+                 `(open ns xs)`; |]++    open nss (ModuleStatement ns @ (Namespace (n:_)) _:xs) =++        [jmacro| `(declare n (ref . replace " " "_" . show $ nss ++ ns))`;+                 `(open nss xs)`; |]++    open ns (_ : xs) = open ns xs++instance Open String where+    open _ [] = mempty+    open (Namespace (map (replace " " "_") -> ns)) (x:xs) =++        let print' []     = error "Empty Namespace"+            print' (y:[]) = [jmacroE| `(ref y)` |]+            print' (y:ys) = [jmacroE| `(print' ys)`[`(y)`] |]++        in  declare x [jmacroE| `(print' $ reverse ns)`[`(x)`] || window[`(x)`] |] ++ open (Namespace ns) xs+++++--------------------------------------------------------------------------------+----+---- Jasmine++newtype Jasmine = Jasmine (Expression Definition)++instance ToStat Jasmine where++    toStat (Jasmine (ApplyExpression (SymbolExpression (Operator "==")) [x, y])) =++        [jmacro| expect(`(x)`).toEqual(`(y)`); |]++    toStat (Jasmine (ApplyExpression (SymbolExpression (Operator "!=")) [x, y])) =++        [jmacro| expect(`(x)`).toNotEqual(`(y)`); |]+        +    toStat (Jasmine e) = ++        [jmacro| expect((function() {+                     try {+                         return `(e)`;+                     } catch (ex) {+                         return { error: ex };+                     }+                 })()).toEqual(true); |]++
+ src/hs/Forml/Types/Symbol.hs view
@@ -0,0 +1,35 @@++module Forml.Types.Symbol where++import Language.Javascript.JMacro++import Control.Applicative+import Text.Parsec         hiding ((<|>), State, many, spaces, parse, label)+import qualified Data.Map as M+import Forml.Parser.Utils+import Data.String.Utils++data Symbol = Symbol String+            | Operator String+            deriving (Ord, Eq)++instance Show Symbol where+    show (Symbol s)   = s+    show (Operator x) = x++instance Syntax Symbol where+    syntax =  (Symbol <$> not_reserved (oneOf "abscdefghijklmnopqrstuvwxyz" <:> many (alphaNum <|> oneOf "_'!$" <|> (string "?" >> return '_'))))+              <|> (Operator <$> not_reserved imp_infix)+        where imp_infix = string "(" *> many1 operator <* option "" (try (string ":")) <* string ")"++instance ToJExpr Symbol where+    toJExpr = toJExpr . to_name++to_name :: Symbol -> String+to_name (Symbol "return") = "_return_"+to_name (Symbol "new") = "_new_"+++to_name (Symbol x) = replace "!" "_excl" $ replace " " "_" $ replace "'" "_apos" x+to_name (Operator op) = concat . map (\x -> M.findWithDefault "_" x operator_dict) $ op+
+ src/hs/Forml/Types/Type.hs view
@@ -0,0 +1,171 @@+{-# LANGUAGE FlexibleContexts, NamedFieldPuns, OverlappingInstances,+             QuasiQuotes, RankNTypes, RecordWildCards, TemplateHaskell,+             ViewPatterns #-}++module Forml.Types.Type where++import Control.Applicative+import Text.InterpolatedString.Perl6++import Text.Parsec        hiding (State, label, many, parse, spaces, (<|>))+import Text.Parsec.Indent hiding (same)++import qualified Data.Map as M+import qualified Data.Set as S++import Forml.Parser.Utils++import Forml.Types.Symbol+++data UnionType = UnionType (S.Set ComplexType)+               deriving (Ord, Eq)++data ComplexType = RecordType (M.Map Symbol UnionType)+                 | InheritType SimpleType (M.Map Symbol UnionType)+                 | FunctionType UnionType UnionType+                 | SimpleType SimpleType+                 deriving (Eq, Ord)++data SimpleType = PolymorphicType SimpleType [UnionType]+                | SymbolType Symbol+                | VariableType String+                deriving (Ord, Eq)++instance Show UnionType where+    show (UnionType xs)         = [qq|{sep_with " | " $ S.toList xs}|]++instance Show ComplexType where+    show (SimpleType y)         = [qq|$y|]+    show (InheritType n m)      = [qq|\{ $n with {unsep_with ": " m} \}|]+    show (RecordType m)         = [qq|\{ {unsep_with ": " m} \}|]++    show (FunctionType g @ (UnionType (S.toList -> ((FunctionType _ _):[]))) h) =+        [qq|($g -> $h)|]++    show (FunctionType g h)     = [qq|$g -> $h|]++instance Show SimpleType where+    show (PolymorphicType x y)  = [qq|($x {sep_with " " y})|]+    show (SymbolType x)   = show x+    show (VariableType x) = x++++-- Type Signatures+-- -----------------------------------------------------------------------------+-- TODO ! (IO type)+-- TODO type axioms need nominative types?+-- ? TODO List, Map, Set shorthand?++-- The type algebra of Sonnet is broken into 3 types to preserve the+-- associativity of UnionTypes: (x | y) | z == x | y | z++++-- Where a type signature may be used in Sonnet had two slightly different parsers+-- in order to allow for somewhat overloaded surrounding characters (eg "|" - when+-- declaring the type of an axiom, one must be careful to disambiguate UnionTypes+-- and sets of EqualityAxioms).  However, these types are otherwise equivalent,+-- and any type that may be declared in a TypeDefinition may also be the explicit+-- type of a Definition (Note, however, that in the case of NamedTypes, the+-- names introduced into scope will be inaccessible in the case of a Definition).+++type_axiom_signature      :: Parser UnionType+type_definition_signature :: Parser UnionType++type_axiom_signature = do option "" (string "|" <* whitespace)+                          t <- (u $ try function_type) <|> try nested_union_type <|> u inner_type+                          whitespace+                          return t++    where u = (<$>) $ UnionType . S.fromList . (:[])++type_definition_signature = UnionType . S.fromList <$> types <* whitespace+    where types = (try function_type <|> inner_type) `sepBy1` type_sep+++-- Through various complexities of the recursive structure of these types, we will+-- need a few mutually recursive parsers to express these slightly different+-- signature parsers.++inner_type        :: Parser ComplexType+nested_function   :: Parser ComplexType+nested_union_type :: Parser UnionType++inner_type  = nested_function+              <|> try record_type+              <|> try named_type+              <|> try poly_type+              <|> var_type+              <|> symbol_type++nested_function   = indentPairs "(" (try function_type <|> inner_type) ")"+nested_union_type = indentPairs "(" type_definition_signature ")"+++-- Now that we've expressed the possible parses of a UnionType, we can move on to+-- parsing the ComplexType and SimpleType layers.  While these are also mutually+-- recursive, the recursion is uniform, as the various allowable combinations+-- have already been defined above.++function_type :: Parser ComplexType+poly_type     :: Parser ComplexType+record_type   :: Parser ComplexType+named_type    :: Parser ComplexType+symbol_type   :: Parser ComplexType+var_type      :: Parser ComplexType++function_type = do x <- try nested_union_type <|> unionize inner_type+                   spaces+                   string "->" <|> string "→"+                   spaces+                   y <- (unionize $ try function_type) <|> try nested_union_type <|> unionize inner_type+                   return $ FunctionType x y++poly_type = do name <- (SymbolType <$> type_name) <|> (VariableType <$> try type_var)+               whitespace+               SimpleType . PolymorphicType name <$> (j_style <|> h_style)++     where rvs = record_type <|> var_type <|> symbol_type+           h_style = (try nested_union_type <|> unionize (try rvs)) `sepEndBy1` whitespace+           j_style = indentPairs "<" ((try nested_union_type <|> unionize (try rvs)) `sepBy1` optional_sep) ">"++record_type   = let key_value = (,) <$> syntax <* div' <*> type_definition_signature+                    div'      = spaces <* string ":" <* spaces+                    pairs     = key_value `sepEndBy` optional_sep+                    inner     = RecordType . M.fromList <$> pairs+                    inherit   = do SimpleType n <- try poly_type <|> try symbol_type <|> var_type+                                   spaces+                                   indented+                                   string "with"+                                   spaces *> indented+                                   InheritType n . M.fromList <$> pairs++                in indentPairs "{" (try inherit <|> inner) "}"++named_type = do x <- indentPairs "{" name "}"++-- named_type = do x <- name+--                 y <- option bool (try nested_union_type <|> unionize inner_type)++                return $ RecordType (M.fromList [(Symbol x, bool)])++    where name = type_var+          bool = UnionType (S.fromList [(SimpleType (SymbolType (Symbol "Bool")))])++symbol_type   = SimpleType . SymbolType <$> type_name+var_type      = SimpleType . VariableType <$> type_var++unionize :: Parser ComplexType -> Parser UnionType+unionize = fmap $ UnionType . S.fromList . (:[])+++type_name   :: Parser Symbol+type_var    :: Parser String++type_name   = Symbol <$> not_reserved (upper <:> many (alphaNum <|> oneOf "_'"))+type_var    = not_reserved (oneOf "abscdefghijklmnopqrstuvwxyz" <:> many (alphaNum <|> oneOf "_'"))++
+ src/hs/Forml/Types/TypeDefinition.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE NamedFieldPuns       #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes          #-}+{-# LANGUAGE RankNTypes           #-}+{-# LANGUAGE RecordWildCards      #-}+{-# LANGUAGE TemplateHaskell      #-}++module Forml.Types.TypeDefinition where++++import           Control.Applicative++import qualified Data.List           as L+import           Text.Parsec         hiding (State, label, many, parse, spaces,+                                      (<|>))++import           Forml.Parser.Utils+++data TypeDefinition = TypeDefinition String [String]+++instance Show TypeDefinition where+    show (TypeDefinition name vars) = concat . L.intersperse " " $ name : vars+++instance Syntax TypeDefinition where++    syntax = do name <- (:) <$> upper <*> many alphaNum+                vars <- try vars' <|> return []+                return $ TypeDefinition name vars++        where vars' = do many1 $ oneOf "\t "+                         let var = (:) <$> lower <*> many alphaNum+                         var `sepEndBy` whitespace
+ src/hs/Main.hs view
@@ -0,0 +1,137 @@+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE NamedFieldPuns       #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE QuasiQuotes          #-}+{-# LANGUAGE RankNTypes           #-}+{-# LANGUAGE RecordWildCards      #-}+{-# LANGUAGE TemplateHaskell      #-}+{-# LANGUAGE TupleSections        #-}+{-# LANGUAGE ViewPatterns         #-}++module Main(main) where++import Text.InterpolatedString.Perl6++import Control.Concurrent+import Control.Monad.State hiding (lift)++import System.Directory+import System.Environment+import System.IO++import Data.List as L++import           Forml.CLI+import           Forml.Closure+import           Forml.Doc+import           Forml.Javascript+import           Forml.Javascript.Backend+import           Forml.Javascript.Test+import           Forml.Javascript.Utils   (prelude)+import qualified Forml.Optimize           as O+import           Forml.Parser+import           Forml.Static+import           Forml.TypeCheck          hiding (split)+import Data.String.Utils (split)++to_parsed :: Title -> Source -> TypeSystem -> Either [Error] (TypeSystem, Program)+to_parsed name src env = case parseForml name src of+                              Left x  -> Left [show x]+                              Right x -> case tiProgram x env of+                                           (as, []) -> Right (as, x)+                                           (_, y)   -> Left y++parse_forml :: [Filename] -> IO ([Filename], TypeSystem, [(Program, Source)], [Title])+parse_forml filenames =++    do sources <- mapM get_source filenames+       foldM parse' ("prelude.forml" : filenames, [], [], []) (prelude' : sources)++    where parse' :: ([Filename], TypeSystem, [(Program, Source)], [Title]) -> String -> IO ([Filename], TypeSystem, [(Program, Source)], [Title])+          parse' (zs, ts, as, titles) src'' =++             do let (title, src) = get_title (head . split "." . last . split "/" . head $ zs) src''+                let src' = to_literate (head zs) . (++ "\n") $ src+                (ts', as') <- monitor [qq|Loading {head zs}|] $ return$ to_parsed (head zs) src' ts+                return (tail zs, ts ++ ts', as ++ [(as', src')], titles ++ [title])++          get_source filename =+             do hFile <- openFile filename ReadMode+                hGetContents hFile++gen_js :: [Source] -> [Program] -> (String, [String])+gen_js src p = (g, h)++    where g = unserialize $ zipWith (render whole_program) src p+          h = map (unserialize . (:[])) $ zipWith (render_spec whole_program) src p++          unserialize x = compress $ read' prelude ++ "\n" ++ (unlines $ map read' x)++          read' xs @ ('"':_) = read xs+          read' x = x+          +          whole_program = Program $ get_program p+          +          get_program (Program ss: ps) = ss ++ get_program ps+          get_program [] = []++main :: IO ()+main  = do args <- getArgs+           main' args++main' :: [String] -> IO ()+main' (parseArgs -> rc') =+         if watch rc'+                 then watch' rc'+                 else compile rc'++    where f (x, y) = show x ++ "\n    " ++ concat (L.intersperse "\n    " (map show y)) ++ "\n\n  "++          watch' rc =++              do x <- mapM getModificationTime . inputs $ rc+                 compile rc+                 putStr "Waiting ..."+                 hFlush stdout+                 wait rc x++          wait rc x =++              do threadDelay 1000+                 x' <- mapM getModificationTime . inputs $ rc+                 if x /= x' then do putStr "\r"+                                    watch' rc+                            else wait rc x++          compile rc =++              do (_, types, src', titles) <- parse_forml$ inputs rc+                 let src'' = O.run_optimizer (fmap fst src') types+                 let (js', tests') = gen_js (fmap snd src') src''++               --  writeFile "prelude.types" (B.toString $ S.encode as)++                 js <- if optimize rc+                       then monitor [qq|Closure {output rc}.js |]$ closure_local js' "ADVANCED_OPTIMIZATIONS"+                       else do warn "Closure [libs]" js'++                 tests <- case rc of+                              RunConfig { optimize = True, run_tests = Phantom } ->+                                  zipWithM (\title t -> monitor [qq|Closure {title}.spec.js |]$ closure_local t "SIMPLE_OPTIMIZATIONS") titles tests'+                              _ -> warn "Closure [tests]" tests'++                 writeFile (output rc ++ ".js") js+                 zipWithM writeFile (map (++ ".spec.js") titles) tests++                 if write_docs rc+                     then let programs = map fst src'+                              sources  = map snd src'+                          in  do docs js tests titles programs sources+                     else monitor "Docs" $ return $ Right ()++                 sequence (zipWith (test rc js) titles tests)++                 if (show_types rc)+                      then putStrLn ("\nTypes\n\n  " ++ concat (map f types))+                      else return ()+ 
+ src/html/footer.html view
@@ -0,0 +1,8 @@++      </section>+      <footer>+        <div id="test_suite"></div>+      </footer>+    </div>+  </body>+</html>
+ src/html/header.html view
@@ -0,0 +1,24 @@+<!doctype html>+<html>+  <head>+    <meta charset="utf-8">+    <meta http-equiv="X-UA-Compatible" content="chrome=1">+    <title>Forml</title>+    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">+    <!--[if lt IE 9]>+    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>+    <![endif]-->+  </head>+  <body>+    <div class="wrapper">+      <header>+        <h1></h1>+        <span id="test_button_container">+        <ul>+          <li id="test_button"><a id="run_tests">Run<strong>Tests</strong></a></li>+        </ul>+        </span>+      </header>+      <section>++    <div class="container">
+ src/js/FormlReporter.js view
@@ -0,0 +1,81 @@++(function() {+jasmine.FormlReporter = function(doc) {+   this.document = doc || document;+   this.suiteDivs = {};+   this.logRunningSpecs = false;+ };+ + jasmine.FormlReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {+ };+ + jasmine.FormlReporter.prototype.reportRunnerStarting = function(runner) {+   var showPassed, showSkipped;+ +   var suites = runner.suites();+   for (var i = 0; i < suites.length; i++) {+     var suite = suites[i];+   }+ +   this.startedAt = new Date();+ +   var self = this;+ };+ + jasmine.FormlReporter.prototype.reportRunnerResults = function(runner) {+     $("#run_tests").unbind();+     $("header #test_button").css({"background-color":"lightgreen"})+ };+ + jasmine.FormlReporter.prototype.reportSuiteResults = function(suite) {+ };+ + jasmine.FormlReporter.prototype.reportSpecStarting = function(spec) {+ };+ + jasmine.FormlReporter.prototype.reportSpecResults = function(spec) {+   var results = spec.results();+   var status = results.passed() ? 'passed' : 'failed';+ +     var k = "#test_" + spec.description.split("__::__")[0]+     var el = $(k)++     spec.description = spec.description.split("__::__")[1]++     if (status == "passed") {+         if (k.indexOf("multi") >= 0) {+             $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(32,186,24,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual) + "'> <span style='color:rgb(255,255,255);font-weight:bold'>PASS</span> </span> ")+         } else {+             $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(32,186,24,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual) + "'> <span style='color:rgb(255,255,255);font-weight:bold'>PASS</span> </span> ")+         }+     } else {+         if (k.indexOf("multi") >= 0) {+             $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(182,24,32,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual) + "'> <span style='color:rgb(255,255,255);font-weight:bold'>FAIL</span> </span> ")+         } else {+             $(k).before("<span style='border-radius:3;margin-right:-50px;background-color:rgba(182,24,32,0.5)' title='" + JSON.stringify(spec.results_.items_[0].actual) + "'> <span style='color:rgb(255,255,255);font-weight:bold'>FAIL</span> </span> ")+         }+     }+ };+ + jasmine.FormlReporter.prototype.log = function() {+ };+ + jasmine.FormlReporter.prototype.getLocation = function() {+   return this.document.location;+ };+ + jasmine.FormlReporter.prototype.specFilter = function(spec) {+   var paramMap = {};+   var params = this.getLocation().search.substring(1).split('&');+   for (var i = 0; i < params.length; i++) {+     var p = params[i].split('=');+     paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);+   }+ +   if (!paramMap.spec) {+     return true;+   }+   return spec.getFullName().indexOf(paramMap.spec) === 0;+ };+ +})();