Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Completely reworked how the app is compiled/developed.

* no more public dir, index.html, applicaion.js, spine.js, and applicaion.css now go in the root of the project
* no more Gemfile and ruby dependencies
* no more node_modules, package.json or slugs.json, now you just install coffee-script with "npm install -g coffee-script" and then run cake in the project dir
  • Loading branch information...
commit 5ca7b604594116bbe35248b17d98c85bd2732aff 1 parent 960155e
@jonmagic jonmagic authored
View
3  .gitignore
@@ -1,3 +0,0 @@
-.rvmrc
-.sass-cache
-node_modules
View
14 Cakefile
@@ -0,0 +1,14 @@
+{print} = require 'util'
+{spawn} = require 'child_process'
+
+build = (callback) ->
+ coffee = spawn 'coffee', ['-c', '-o', './', 'scripts']
+ coffee.stderr.on 'data', (data) ->
+ process.stderr.write data.toString()
+ coffee.stdout.on 'data', (data) ->
+ print data.toString()
+ coffee.on 'exit', (code) ->
+ callback?() if code is 0
+
+task 'build', 'Build lib/ from src/', ->
+ build()
View
6 Gemfile
@@ -1,6 +0,0 @@
-source :rubygems
-
-group :development do
- gem 'guard-compass'
- gem 'foreman'
-end
View
29 Gemfile.lock
@@ -1,29 +0,0 @@
-GEM
- remote: http://rubygems.org/
- specs:
- chunky_png (1.2.5)
- compass (0.11.7)
- chunky_png (~> 1.2)
- fssm (>= 0.2.7)
- sass (~> 3.1)
- ffi (1.0.11)
- foreman (0.30.1)
- term-ansicolor (~> 1.0.5)
- thor (>= 0.13.6)
- fssm (0.2.8.1)
- guard (1.0.0)
- ffi (>= 0.5.0)
- thor (~> 0.14.6)
- guard-compass (0.0.6)
- compass (>= 0.10.5)
- guard (>= 0.2.1)
- sass (3.1.12)
- term-ansicolor (1.0.7)
- thor (0.14.6)
-
-PLATFORMS
- ruby
-
-DEPENDENCIES
- foreman
- guard-compass
View
3  Guardfile
@@ -1,3 +0,0 @@
-guard 'compass' do
- watch(%r{^styles/(.*)\.s[ac]ss})
-end
View
20 LICENSE
@@ -1,20 +0,0 @@
-Copyright (c) 2011 Jonathan Hoyt
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
2  Procfile
@@ -1,2 +0,0 @@
-web: node_modules/hem/bin/hem server
-guard: bundle exec guard
View
21 README.md
@@ -33,4 +33,23 @@ The best way to get your changes merged back into core is as follows:
## License
-See LICENSE for details.
+Copyright (c) 2011 Jonathan Hoyt
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
13 app/expression.coffee
@@ -1,13 +0,0 @@
-class Expression extends Spine.Controller
- elements:
- 'input[name=expression]': 'regexp'
- 'input[name=option]': 'option'
-
- events:
- 'keyup input': 'onKeyPress'
-
- onKeyPress: (event) ->
- @value = new RegExp(@regexp.val(), @option.val())
- @.trigger 'update'
-
-module.exports = Expression
View
14 app/index.coffee
@@ -1,14 +0,0 @@
-require('jqueryify')
-require('spine')
-
-Expression = require 'expression'
-TestStrings = require 'test_strings'
-Results = require 'results'
-
-class App
- constructor: ->
- @expression = new Expression(el: '#expression')
- @test_strings = new TestStrings(el: '#test_strings')
- @results = new Results(@expression, @test_strings)
-
-module.exports = App
View
15 app/test_strings.coffee
@@ -1,15 +0,0 @@
-class TestStrings extends Spine.Controller
- elements:
- 'textarea': 'input'
-
- events:
- 'keyup textarea': 'onKeyPress'
-
- onKeyPress: (event) ->
- @getValues(@input.val())
- @.trigger 'update'
-
- getValues: (val) ->
- @values = val.split('\n')
-
-module.exports = TestStrings
View
37 public/styles/application.css → application.css
@@ -1,4 +1,4 @@
-/* line 17, ../../../../.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* RESET */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
@@ -20,56 +20,49 @@ time, mark, audio, video {
vertical-align: baseline;
}
-/* line 20, ../../../../.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
body {
line-height: 1;
}
-/* line 22, ../../../../.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
ol, ul {
list-style: none;
}
-/* line 24, ../../../../.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
table {
border-collapse: collapse;
border-spacing: 0;
}
-/* line 26, ../../../../.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle;
}
-/* line 28, ../../../../.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
q, blockquote {
quotes: none;
}
-/* line 101, ../../../../.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none;
}
-/* line 30, ../../../../.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
a img {
border: none;
}
-/* line 114, ../../../../.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary {
display: block;
}
-/* line 12, ../../styles/application.sass */
+
+/* my styles */
body {
font-family: Helvetica;
font-size: 18px;
}
-/* line 16, ../../styles/application.sass */
h1 {
font-size: 2em;
font-weight: bold;
@@ -78,13 +71,11 @@ h1 {
width: 100%;
}
-/* line 23, ../../styles/application.sass */
h2 {
font-size: 20px;
margin-bottom: 5px;
}
-/* line 27, ../../styles/application.sass */
#main {
background-color: #eeeeee;
border: 3px solid #666666;
@@ -99,7 +90,6 @@ h2 {
width: 600px;
}
-/* line 35, ../../styles/application.sass */
input, textarea {
margin-bottom: 20px;
background-color: white;
@@ -114,33 +104,29 @@ input, textarea {
border-radius: 5px;
}
-/* line 39, ../../styles/application.sass */
#expression {
font-size: 25px;
}
-/* line 42, ../../styles/application.sass */
+
#expression input[name=expression] {
margin: 0 4px;
width: 530px;
}
-/* line 46, ../../styles/application.sass */
+
#expression input[name=option] {
margin-left: 4px;
width: 40px;
}
-/* line 51, ../../styles/application.sass */
#test_strings textarea {
height: 95px;
width: 100%;
}
-/* line 55, ../../styles/application.sass */
#output {
display: none;
}
-/* line 58, ../../styles/application.sass */
#results {
background-color: white;
border: 1px solid #666666;
@@ -154,20 +140,19 @@ input, textarea {
border-radius: 5px;
margin-bottom: 20px;
}
-/* line 61, ../../styles/application.sass */
+
#results li {
margin-bottom: 10px;
}
-/* line 63, ../../styles/application.sass */
+
#results li:last-child {
margin-bottom: 0px;
}
-/* line 65, ../../styles/application.sass */
+
#results span {
background-color: #f4ff80;
}
-/* line 68, ../../styles/application.sass */
#groups {
background-color: white;
border: 1px solid #666666;
@@ -180,13 +165,13 @@ input, textarea {
-khtml-border-radius: 5px;
border-radius: 5px;
}
-/* line 70, ../../styles/application.sass */
+
#groups h3 {
font-size: 14px;
font-weight: bold;
margin-bottom: 5px;
}
-/* line 74, ../../styles/application.sass */
+
#groups ol {
list-style-type: decimal;
margin-bottom: 10px;
View
134 application.js
@@ -0,0 +1,134 @@
+(function() {
+ var $, App, Expression, Results, TestStrings,
+ __hasProp = Object.prototype.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; },
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
+
+ $ = jQuery;
+
+ Expression = (function(_super) {
+
+ __extends(Expression, _super);
+
+ function Expression() {
+ Expression.__super__.constructor.apply(this, arguments);
+ }
+
+ Expression.prototype.elements = {
+ 'input[name=expression]': 'regexp',
+ 'input[name=option]': 'option'
+ };
+
+ Expression.prototype.events = {
+ 'keyup input': 'onKeyPress'
+ };
+
+ Expression.prototype.onKeyPress = function(event) {
+ this.value = new RegExp(this.regexp.val(), this.option.val());
+ return this.trigger('update');
+ };
+
+ return Expression;
+
+ })(Spine.Controller);
+
+ TestStrings = (function(_super) {
+
+ __extends(TestStrings, _super);
+
+ function TestStrings() {
+ TestStrings.__super__.constructor.apply(this, arguments);
+ }
+
+ TestStrings.prototype.elements = {
+ 'textarea': 'input'
+ };
+
+ TestStrings.prototype.events = {
+ 'keyup textarea': 'onKeyPress'
+ };
+
+ TestStrings.prototype.onKeyPress = function(event) {
+ this.getValues(this.input.val());
+ return this.trigger('update');
+ };
+
+ TestStrings.prototype.getValues = function(val) {
+ return this.values = val.split('\n');
+ };
+
+ return TestStrings;
+
+ })(Spine.Controller);
+
+ Results = (function() {
+
+ function Results(expression, test_strings) {
+ this.expression = expression;
+ this.test_strings = test_strings;
+ this.compile = __bind(this.compile, this);
+ this.expression.bind('update', this.compile);
+ this.test_strings.bind('update', this.compile);
+ }
+
+ Results.prototype.compile = function() {
+ var count, value, _i, _len, _ref, _results;
+ $('#output').show();
+ $('ul#results').empty();
+ $('ul#groups').empty();
+ count = 1;
+ _ref = this.test_strings.values;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ value = _ref[_i];
+ this.matchResults(value);
+ this.matchGroups(value, count);
+ _results.push(count += 1);
+ }
+ return _results;
+ };
+
+ Results.prototype.matchResults = function(value) {
+ var first, second;
+ first = value.match(this.expression.value)[0];
+ second = value.split(value.match(this.expression.value)[0]);
+ return $('ul#results').append("<li><span>" + first + "</span>" + second.slice(1) + "</li>");
+ };
+
+ Results.prototype.matchGroups = function(value, count) {
+ var match, _i, _len, _ref, _results;
+ $('ul#groups').append("<li id='match_" + count + "'><h3>Match " + count + "</h3><ol></ol></li>");
+ _ref = value.match(this.expression.value).slice(1);
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ match = _ref[_i];
+ _results.push($("ul#groups li#match_" + count + " ol").append("<li>" + match + "</li>"));
+ }
+ return _results;
+ };
+
+ return Results;
+
+ })();
+
+ App = (function() {
+
+ function App() {
+ this.expression = new Expression({
+ el: '#expression'
+ });
+ this.test_strings = new TestStrings({
+ el: '#test_strings'
+ });
+ this.results = new Results(this.expression, this.test_strings);
+ }
+
+ return App;
+
+ })();
+
+ $(function() {
+ return new App;
+ });
+
+}).call(this);
View
23 config.rb
@@ -1,23 +0,0 @@
-# Require any additional compass plugins here.
-
-# Set this to the root of your project when deployed:
-http_path = "/"
-sass_dir = "styles"
-css_dir = "public/styles"
-images_dir = "public/images"
-javascripts_dir = "public/scripts"
-
-# You can select your preferred output style here (can be overridden via the command line):
-# output_style = :expanded or :nested or :compact or :compressed
-
-# To enable relative paths to assets via compass helper functions. Uncomment:
-# relative_assets = true
-
-# To disable debugging comments that display the original location of your selectors. Uncomment:
-# line_comments = false
-
-# If you prefer the indented syntax, you might want to regenerate this
-# project again passing --syntax sass, or you can uncomment this:
-# preferred_syntax = :sass
-# and then run:
-# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
View
14 public/index.html → index.html
@@ -1,16 +1,10 @@
<html>
<head>
<title>Scriptular</title>
- <link rel="stylesheet" type="text/css" href="/styles/application.css">
- <script src="/application.js"></script>
- <script type="text/javascript" charset="utf-8">
- var $ = require("jqueryify");
- var exports = this;
- $(function() {
- var App = require("index");
- exports.app = new App();
- });
- </script>
+ <link rel="stylesheet" type="text/css" href="application.css">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
+ <script src="spine.js" type="text/javascript"></script>
+ <script src="application.js" type="text/javascript"></script>
</head>
<body>
<h1>Scriptular</h1>
View
1,493 lib/handlebars.js
@@ -1,1493 +0,0 @@
-// lib/handlebars/parser.js
-/* Jison generated parser */
-var handlebars = (function(){
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"param":27,"STRING":28,"INTEGER":29,"BOOLEAN":30,"hashSegments":31,"hashSegment":32,"ID":33,"EQUALS":34,"pathSegments":35,"SEP":36,"$accept":0,"$end":1},
-terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",29:"INTEGER",30:"BOOLEAN",33:"ID",34:"EQUALS",36:"SEP"},
-productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[27,1],[27,1],[26,1],[31,2],[31,1],[32,3],[32,3],[32,3],[32,3],[21,1],[35,3],[35,1]],
-performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 1: return $$[$0-1]
-break;
-case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0])
-break;
-case 3: this.$ = new yy.ProgramNode($$[$0])
-break;
-case 4: this.$ = new yy.ProgramNode([])
-break;
-case 5: this.$ = [$$[$0]]
-break;
-case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
-break;
-case 7: this.$ = new yy.InverseNode($$[$0-2], $$[$0-1], $$[$0])
-break;
-case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0])
-break;
-case 9: this.$ = $$[$0]
-break;
-case 10: this.$ = $$[$0]
-break;
-case 11: this.$ = new yy.ContentNode($$[$0])
-break;
-case 12: this.$ = new yy.CommentNode($$[$0])
-break;
-case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
-break;
-case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
-break;
-case 15: this.$ = $$[$0-1]
-break;
-case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
-break;
-case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true)
-break;
-case 18: this.$ = new yy.PartialNode($$[$0-1])
-break;
-case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1])
-break;
-case 20:
-break;
-case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]
-break;
-case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null]
-break;
-case 23: this.$ = [[$$[$0-1]], $$[$0]]
-break;
-case 24: this.$ = [[$$[$0]], null]
-break;
-case 25: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
-break;
-case 26: this.$ = [$$[$0]]
-break;
-case 27: this.$ = $$[$0]
-break;
-case 28: this.$ = new yy.StringNode($$[$0])
-break;
-case 29: this.$ = new yy.IntegerNode($$[$0])
-break;
-case 30: this.$ = new yy.BooleanNode($$[$0])
-break;
-case 31: this.$ = new yy.HashNode($$[$0])
-break;
-case 32: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
-break;
-case 33: this.$ = [$$[$0]]
-break;
-case 34: this.$ = [$$[$0-2], $$[$0]]
-break;
-case 35: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]
-break;
-case 36: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])]
-break;
-case 37: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])]
-break;
-case 38: this.$ = new yy.IdNode($$[$0])
-break;
-case 39: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
-break;
-case 40: this.$ = [$$[$0]]
-break;
-}
-},
-table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,33:[1,25],35:24},{17:26,21:23,33:[1,25],35:24},{17:27,21:23,33:[1,25],35:24},{17:28,21:23,33:[1,25],35:24},{21:29,33:[1,25],35:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,33:[1,25],35:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,38],28:[2,38],29:[2,38],30:[2,38],33:[2,38],36:[1,46]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],36:[2,40]},{18:[1,47]},{18:[1,48]},{18:[1,49]},{18:[1,50],21:51,33:[1,25],35:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:52,33:[1,25],35:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:53,27:54,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,23]},{18:[2,26],28:[2,26],29:[2,26],30:[2,26],33:[2,26]},{18:[2,31],32:55,33:[1,56]},{18:[2,27],28:[2,27],29:[2,27],30:[2,27],33:[2,27]},{18:[2,28],28:[2,28],29:[2,28],30:[2,28],33:[2,28]},{18:[2,29],28:[2,29],29:[2,29],30:[2,29],33:[2,29]},{18:[2,30],28:[2,30],29:[2,30],30:[2,30],33:[2,30]},{18:[2,33],33:[2,33]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],34:[1,57],36:[2,40]},{33:[1,58]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,59]},{18:[1,60]},{18:[2,21]},{18:[2,25],28:[2,25],29:[2,25],30:[2,25],33:[2,25]},{18:[2,32],33:[2,32]},{34:[1,57]},{21:61,28:[1,62],29:[1,63],30:[1,64],33:[1,25],35:24},{18:[2,39],28:[2,39],29:[2,39],30:[2,39],33:[2,39],36:[2,39]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,34],33:[2,34]},{18:[2,35],33:[2,35]},{18:[2,36],33:[2,36]},{18:[2,37],33:[2,37]}],
-defaultActions: {16:[2,1],37:[2,23],53:[2,21]},
-parseError: function parseError(str, hash) {
- throw new Error(str);
-},
-parse: function parse(input) {
- var self = this,
- stack = [0],
- vstack = [null], // semantic value stack
- lstack = [], // location stack
- table = this.table,
- yytext = '',
- yylineno = 0,
- yyleng = 0,
- recovering = 0,
- TERROR = 2,
- EOF = 1;
-
- //this.reductionCount = this.shiftCount = 0;
-
- this.lexer.setInput(input);
- this.lexer.yy = this.yy;
- this.yy.lexer = this.lexer;
- if (typeof this.lexer.yylloc == 'undefined')
- this.lexer.yylloc = {};
- var yyloc = this.lexer.yylloc;
- lstack.push(yyloc);
-
- if (typeof this.yy.parseError === 'function')
- this.parseError = this.yy.parseError;
-
- function popStack (n) {
- stack.length = stack.length - 2*n;
- vstack.length = vstack.length - n;
- lstack.length = lstack.length - n;
- }
-
- function lex() {
- var token;
- token = self.lexer.lex() || 1; // $end = 1
- // if token isn't its numeric value, convert
- if (typeof token !== 'number') {
- token = self.symbols_[token] || token;
- }
- return token;
- };
-
- var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
- while (true) {
- // retreive state number from top of stack
- state = stack[stack.length-1];
-
- // use default actions if available
- if (this.defaultActions[state]) {
- action = this.defaultActions[state];
- } else {
- if (symbol == null)
- symbol = lex();
- // read action for current state and first input
- action = table[state] && table[state][symbol];
- }
-
- // handle parse error
- if (typeof action === 'undefined' || !action.length || !action[0]) {
-
- if (!recovering) {
- // Report error
- expected = [];
- for (p in table[state]) if (this.terminals_[p] && p > 2) {
- expected.push("'"+this.terminals_[p]+"'");
- }
- var errStr = '';
- if (this.lexer.showPosition) {
- errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', ');
- } else {
- errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
- (symbol == 1 /*EOF*/ ? "end of input" :
- ("'"+(this.terminals_[symbol] || symbol)+"'"));
- }
- this.parseError(errStr,
- {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
- }
-
- // just recovered from another error
- if (recovering == 3) {
- if (symbol == EOF) {
- throw new Error(errStr || 'Parsing halted.');
- }
-
- // discard current lookahead and grab another
- yyleng = this.lexer.yyleng;
- yytext = this.lexer.yytext;
- yylineno = this.lexer.yylineno;
- yyloc = this.lexer.yylloc;
- symbol = lex();
- }
-
- // try to recover from error
- while (1) {
- // check for error recovery rule in this state
- if ((TERROR.toString()) in table[state]) {
- break;
- }
- if (state == 0) {
- throw new Error(errStr || 'Parsing halted.');
- }
- popStack(1);
- state = stack[stack.length-1];
- }
-
- preErrorSymbol = symbol; // save the lookahead token
- symbol = TERROR; // insert generic error symbol as new lookahead
- state = stack[stack.length-1];
- action = table[state] && table[state][TERROR];
- recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
- }
-
- // this shouldn't happen, unless resolve defaults are off
- if (action[0] instanceof Array && action.length > 1) {
- throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
- }
-
- switch (action[0]) {
-
- case 1: // shift
- //this.shiftCount++;
-
- stack.push(symbol);
- vstack.push(this.lexer.yytext);
- lstack.push(this.lexer.yylloc);
- stack.push(action[1]); // push state
- symbol = null;
- if (!preErrorSymbol) { // normal execution/no error
- yyleng = this.lexer.yyleng;
- yytext = this.lexer.yytext;
- yylineno = this.lexer.yylineno;
- yyloc = this.lexer.yylloc;
- if (recovering > 0)
- recovering--;
- } else { // error just occurred, resume old lookahead f/ before error
- symbol = preErrorSymbol;
- preErrorSymbol = null;
- }
- break;
-
- case 2: // reduce
- //this.reductionCount++;
-
- len = this.productions_[action[1]][1];
-
- // perform semantic action
- yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
- // default location, uses first token for firsts, last for lasts
- yyval._$ = {
- first_line: lstack[lstack.length-(len||1)].first_line,
- last_line: lstack[lstack.length-1].last_line,
- first_column: lstack[lstack.length-(len||1)].first_column,
- last_column: lstack[lstack.length-1].last_column
- };
- r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
-
- if (typeof r !== 'undefined') {
- return r;
- }
-
- // pop off stack
- if (len) {
- stack = stack.slice(0,-1*len*2);
- vstack = vstack.slice(0, -1*len);
- lstack = lstack.slice(0, -1*len);
- }
-
- stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
- vstack.push(yyval.$);
- lstack.push(yyval._$);
- // goto new state = table[STATE][NONTERMINAL]
- newState = table[stack[stack.length-2]][stack[stack.length-1]];
- stack.push(newState);
- break;
-
- case 3: // accept
- return true;
- }
-
- }
-
- return true;
-}};/* Jison generated lexer */
-var lexer = (function(){var lexer = ({EOF:1,
-parseError:function parseError(str, hash) {
- if (this.yy.parseError) {
- this.yy.parseError(str, hash);
- } else {
- throw new Error(str);
- }
- },
-setInput:function (input) {
- this._input = input;
- this._more = this._less = this.done = false;
- this.yylineno = this.yyleng = 0;
- this.yytext = this.matched = this.match = '';
- this.conditionStack = ['INITIAL'];
- this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
- return this;
- },
-input:function () {
- var ch = this._input[0];
- this.yytext+=ch;
- this.yyleng++;
- this.match+=ch;
- this.matched+=ch;
- var lines = ch.match(/\n/);
- if (lines) this.yylineno++;
- this._input = this._input.slice(1);
- return ch;
- },
-unput:function (ch) {
- this._input = ch + this._input;
- return this;
- },
-more:function () {
- this._more = true;
- return this;
- },
-pastInput:function () {
- var past = this.matched.substr(0, this.matched.length - this.match.length);
- return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
- },
-upcomingInput:function () {
- var next = this.match;
- if (next.length < 20) {
- next += this._input.substr(0, 20-next.length);
- }
- return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
- },
-showPosition:function () {
- var pre = this.pastInput();
- var c = new Array(pre.length + 1).join("-");
- return pre + this.upcomingInput() + "\n" + c+"^";
- },
-next:function () {
- if (this.done) {
- return this.EOF;
- }
- if (!this._input) this.done = true;
-
- var token,
- match,
- col,
- lines;
- if (!this._more) {
- this.yytext = '';
- this.match = '';
- }
- var rules = this._currentRules();
- for (var i=0;i < rules.length; i++) {
- match = this._input.match(this.rules[rules[i]]);
- if (match) {
- lines = match[0].match(/\n.*/g);
- if (lines) this.yylineno += lines.length;
- this.yylloc = {first_line: this.yylloc.last_line,
- last_line: this.yylineno+1,
- first_column: this.yylloc.last_column,
- last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
- this.yytext += match[0];
- this.match += match[0];
- this.matches = match;
- this.yyleng = this.yytext.length;
- this._more = false;
- this._input = this._input.slice(match[0].length);
- this.matched += match[0];
- token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
- if (token) return token;
- else return;
- }
- }
- if (this._input === "") {
- return this.EOF;
- } else {
- this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
- {text: "", token: null, line: this.yylineno});
- }
- },
-lex:function lex() {
- var r = this.next();
- if (typeof r !== 'undefined') {
- return r;
- } else {
- return this.lex();
- }
- },
-begin:function begin(condition) {
- this.conditionStack.push(condition);
- },
-popState:function popState() {
- return this.conditionStack.pop();
- },
-_currentRules:function _currentRules() {
- return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
- }});
-lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-
-var YYSTATE=YY_START
-switch($avoiding_name_collisions) {
-case 0: this.begin("mu"); if (yy_.yytext) return 14;
-break;
-case 1: return 14;
-break;
-case 2: return 24;
-break;
-case 3: return 16;
-break;
-case 4: return 20;
-break;
-case 5: return 19;
-break;
-case 6: return 19;
-break;
-case 7: return 23;
-break;
-case 8: return 23;
-break;
-case 9: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.begin("INITIAL"); return 15;
-break;
-case 10: return 22;
-break;
-case 11: return 34;
-break;
-case 12: return 33;
-break;
-case 13: return 33;
-break;
-case 14: return 36;
-break;
-case 15: /*ignore whitespace*/
-break;
-case 16: this.begin("INITIAL"); return 18;
-break;
-case 17: this.begin("INITIAL"); return 18;
-break;
-case 18: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28;
-break;
-case 19: return 30;
-break;
-case 20: return 30;
-break;
-case 21: return 29;
-break;
-case 22: return 33;
-break;
-case 23: return 'INVALID';
-break;
-case 24: return 5;
-break;
-}
-};
-lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/,/^[a-zA-Z0-9_$-]+(?=[=}\s/.])/,/^./,/^$/];
-lexer.conditions = {"mu":{"rules":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],"inclusive":false},"INITIAL":{"rules":[0,1,24],"inclusive":true}};return lexer;})()
-parser.lexer = lexer;
-return parser;
-})();
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = handlebars;
-exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }
-exports.main = function commonjsMain(args) {
- if (!args[1])
- throw new Error('Usage: '+args[0]+' FILE');
- if (typeof process !== 'undefined') {
- var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
- } else {
- var cwd = require("file").path(require("file").cwd());
- var source = cwd.join(args[1]).read({charset: "utf-8"});
- }
- return exports.parser.parse(source);
-}
-if (typeof module !== 'undefined' && require.main === module) {
- exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
-}
-};
-;
-// lib/handlebars/base.js
-var Handlebars = {};
-
-Handlebars.VERSION = "1.0.beta.2";
-
-Handlebars.Parser = handlebars;
-
-Handlebars.parse = function(string) {
- Handlebars.Parser.yy = Handlebars.AST;
- return Handlebars.Parser.parse(string);
-};
-
-Handlebars.print = function(ast) {
- return new Handlebars.PrintVisitor().accept(ast);
-};
-
-Handlebars.helpers = {};
-Handlebars.partials = {};
-
-Handlebars.registerHelper = function(name, fn, inverse) {
- if(inverse) { fn.not = inverse; }
- this.helpers[name] = fn;
-};
-
-Handlebars.registerPartial = function(name, str) {
- this.partials[name] = str;
-};
-
-Handlebars.registerHelper('helperMissing', function(arg) {
- if(arguments.length === 2) {
- return undefined;
- } else {
- throw new Error("Could not find property '" + arg + "'");
- }
-});
-
-Handlebars.registerHelper('blockHelperMissing', function(context, fn, inverse) {
- inverse = inverse || function() {};
-
- var ret = "";
- var type = Object.prototype.toString.call(context);
-
- if(type === "[object Function]") {
- context = context();
- }
-
- if(context === true) {
- return fn(this);
- } else if(context === false || context == null) {
- return inverse(this);
- } else if(type === "[object Array]") {
- if(context.length > 0) {
- for(var i=0, j=context.length; i<j; i++) {
- ret = ret + fn(context[i]);
- }
- } else {
- ret = inverse(this);
- }
- return ret;
- } else {
- return fn(context);
- }
-}, function(context, fn) {
- return fn(context);
-});
-
-Handlebars.registerHelper('each', function(context, fn, inverse) {
- var ret = "";
-
- if(context && context.length > 0) {
- for(var i=0, j=context.length; i<j; i++) {
- ret = ret + fn(context[i]);
- }
- } else {
- ret = inverse(this);
- }
- return ret;
-});
-
-Handlebars.registerHelper('if', function(context, fn, inverse) {
- if(!context || context == []) {
- return inverse(this);
- } else {
- return fn(this);
- }
-});
-
-Handlebars.registerHelper('unless', function(context, fn, inverse) {
- return Handlebars.helpers['if'].call(this, context, inverse, fn);
-});
-
-Handlebars.registerHelper('with', function(context, fn) {
- return fn(context);
-});
-
-Handlebars.logger = {
- DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
-
- // override in the host environment
- log: function(level, str) {}
-};
-
-Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
-;
-// lib/handlebars/ast.js
-(function() {
-
- Handlebars.AST = {};
-
- Handlebars.AST.ProgramNode = function(statements, inverse) {
- this.type = "program";
- this.statements = statements;
- if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
- };
-
- Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
- this.type = "mustache";
- this.id = params[0];
- this.params = params.slice(1);
- this.hash = hash;
- this.escaped = !unescaped;
- };
-
- Handlebars.AST.PartialNode = function(id, context) {
- this.type = "partial";
-
- // TODO: disallow complex IDs
-
- this.id = id;
- this.context = context;
- };
-
- var verifyMatch = function(open, close) {
- if(open.original !== close.original) {
- throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
- }
- };
-
- Handlebars.AST.BlockNode = function(mustache, program, close) {
- verifyMatch(mustache.id, close);
- this.type = "block";
- this.mustache = mustache;
- this.program = program;
- };
-
- Handlebars.AST.InverseNode = function(mustache, program, close) {
- verifyMatch(mustache.id, close);
- this.type = "inverse";
- this.mustache = mustache;
- this.program = program;
- };
-
- Handlebars.AST.ContentNode = function(string) {
- this.type = "content";
- this.string = string;
- };
-
- Handlebars.AST.HashNode = function(pairs) {
- this.type = "hash";
- this.pairs = pairs;
- };
-
- Handlebars.AST.IdNode = function(parts) {
- this.type = "ID";
- this.original = parts.join(".");
-
- var dig = [], depth = 0;
-
- for(var i=0,l=parts.length; i<l; i++) {
- var part = parts[i];
-
- if(part === "..") { depth++; }
- else if(part === "." || part === "this") { continue; }
- else { dig.push(part); }
- }
-
- this.parts = dig;
- this.string = dig.join('.');
- this.depth = depth;
- this.isSimple = (dig.length === 1) && (depth === 0);
- };
-
- Handlebars.AST.StringNode = function(string) {
- this.type = "STRING";
- this.string = string;
- };
-
- Handlebars.AST.IntegerNode = function(integer) {
- this.type = "INTEGER";
- this.integer = integer;
- };
-
- Handlebars.AST.BooleanNode = function(boolean) {
- this.type = "BOOLEAN";
- this.boolean = boolean;
- };
-
- Handlebars.AST.CommentNode = function(comment) {
- this.type = "comment";
- this.comment = comment;
- };
-
-})();;
-// lib/handlebars/visitor.js
-
-Handlebars.Visitor = function() {};
-
-Handlebars.Visitor.prototype = {
- accept: function(object) {
- return this[object.type](object);
- }
-};;
-// lib/handlebars/utils.js
-Handlebars.Exception = function(message) {
- this.message = message;
-};
-
-// Build out our basic SafeString type
-Handlebars.SafeString = function(string) {
- this.string = string;
-};
-Handlebars.SafeString.prototype.toString = function() {
- return this.string.toString();
-};
-
-(function() {
- var escape = {
- "<": "&lt;",
- ">": "&gt;",
- '"': "&quot;",
- "'": "&#x27;",
- "`": "&#x60;"
- };
-
- var badChars = /&(?!\w+;)|[<>"'`]/g;
- var possible = /[&<>"'`]/;
-
- var escapeChar = function(chr) {
- return escape[chr] || "&amp;"
- };
-
- Handlebars.Utils = {
- escapeExpression: function(string) {
- // don't escape SafeStrings, since they're already safe
- if (string instanceof Handlebars.SafeString) {
- return string.toString();
- } else if (string == null || string === false) {
- return "";
- }
-
- if(!possible.test(string)) { return string; }
- return string.replace(badChars, escapeChar);
- },
-
- isEmpty: function(value) {
- if (typeof value === "undefined") {
- return true;
- } else if (value === null) {
- return true;
- } else if (value === false) {
- return true;
- } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
- return true;
- } else {
- return false;
- }
- }
- };
-})();;
-// lib/handlebars/compiler.js
-Handlebars.Compiler = function() {};
-Handlebars.JavaScriptCompiler = function() {};
-
-(function(Compiler, JavaScriptCompiler) {
- Compiler.OPCODE_MAP = {
- appendContent: 1,
- getContext: 2,
- lookupWithHelpers: 3,
- lookup: 4,
- append: 5,
- invokeMustache: 6,
- appendEscaped: 7,
- pushString: 8,
- truthyOrFallback: 9,
- functionOrFallback: 10,
- invokeProgram: 11,
- invokePartial: 12,
- push: 13,
- invokeInverse: 14,
- assignToHash: 15,
- pushStringParam: 16
- };
-
- Compiler.MULTI_PARAM_OPCODES = {
- appendContent: 1,
- getContext: 1,
- lookupWithHelpers: 1,
- lookup: 1,
- invokeMustache: 2,
- pushString: 1,
- truthyOrFallback: 1,
- functionOrFallback: 1,
- invokeProgram: 2,
- invokePartial: 1,
- push: 1,
- invokeInverse: 1,
- assignToHash: 1,
- pushStringParam: 1
- };
-
- Compiler.DISASSEMBLE_MAP = {};
-
- for(var prop in Compiler.OPCODE_MAP) {
- var value = Compiler.OPCODE_MAP[prop];
- Compiler.DISASSEMBLE_MAP[value] = prop;
- }
-
- Compiler.multiParamSize = function(code) {
- return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
- };
-
- Compiler.prototype = {
- compiler: Compiler,
-
- disassemble: function() {
- var opcodes = this.opcodes, opcode, nextCode;
- var out = [], str, name, value;
-
- for(var i=0, l=opcodes.length; i<l; i++) {
- opcode = opcodes[i];
-
- if(opcode === 'DECLARE') {
- name = opcodes[++i];
- value = opcodes[++i];
- out.push("DECLARE " + name + " = " + value);
- } else {
- str = Compiler.DISASSEMBLE_MAP[opcode];
-
- var extraParams = Compiler.multiParamSize(opcode);
- var codes = [];
-
- for(var j=0; j<extraParams; j++) {
- nextCode = opcodes[++i];
-
- if(typeof nextCode === "string") {
- nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
- }
-
- codes.push(nextCode);
- }
-
- str = str + " " + codes.join(" ");
-
- out.push(str);
- }
- }
-
- return out.join("\n");
- },
-
- guid: 0,
-
- compile: function(program, options) {
- this.children = [];
- this.depths = {list: []};
- this.options = options || {};
- return this.program(program);
- },
-
- accept: function(node) {
- return this[node.type](node);
- },
-
- program: function(program) {
- var statements = program.statements, statement;
- this.opcodes = [];
-
- for(var i=0, l=statements.length; i<l; i++) {
- statement = statements[i];
- this[statement.type](statement);
- }
-
- this.depths.list = this.depths.list.sort(function(a, b) {
- return a - b;
- });
-
- return this;
- },
-
- compileProgram: function(program) {
- var result = new this.compiler().compile(program, this.options);
- var guid = this.guid++;
-
- this.usePartial = this.usePartial || result.usePartial;
-
- this.children[guid] = result;
-
- for(var i=0, l=result.depths.list.length; i<l; i++) {
- depth = result.depths.list[i];
-
- if(depth < 2) { continue; }
- else { this.addDepth(depth - 1); }
- }
-
- return guid;
- },
-
- block: function(block) {
- var mustache = block.mustache;
- var depth, child, inverse, inverseGuid;
-
- var params = this.setupStackForMustache(mustache);
-
- var programGuid = this.compileProgram(block.program);
-
- if(block.program.inverse) {
- inverseGuid = this.compileProgram(block.program.inverse);
- this.declare('inverse', inverseGuid);
- }
-
- this.opcode('invokeProgram', programGuid, params.length);
- this.declare('inverse', null);
- this.opcode('append');
- },
-
- inverse: function(block) {
- this.ID(block.mustache.id);
- var programGuid = this.compileProgram(block.program);
-
- this.opcode('invokeInverse', programGuid);
- this.opcode('append');
- },
-
- hash: function(hash) {
- var pairs = hash.pairs, pair, val;
-
- this.opcode('push', '{}');
-
- for(var i=0, l=pairs.length; i<l; i++) {
- pair = pairs[i];
- val = pair[1];
-
- this.accept(val);
- this.opcode('assignToHash', pair[0]);
- }
- },
-
- partial: function(partial) {
- var id = partial.id;
- this.usePartial = true;
-
- if(partial.context) {
- this.ID(partial.context);
- } else {
- this.opcode('push', 'context');
- }
-
- this.opcode('invokePartial', id.original);
- this.opcode('append');
- },
-
- content: function(content) {
- this.opcode('appendContent', content.string);
- },
-
- mustache: function(mustache) {
- var params = this.setupStackForMustache(mustache);
-
- this.opcode('invokeMustache', params.length, mustache.id.original);
-
- if(mustache.escaped) {
- this.opcode('appendEscaped');
- } else {
- this.opcode('append');
- }
- },
-
- ID: function(id) {
- this.addDepth(id.depth);
-
- this.opcode('getContext', id.depth);
-
- this.opcode('lookupWithHelpers', id.parts[0] || null);
-
- for(var i=1, l=id.parts.length; i<l; i++) {
- this.opcode('lookup', id.parts[i]);
- }
- },
-
- STRING: function(string) {
- this.opcode('pushString', string.string);
- },
-
- INTEGER: function(integer) {
- this.opcode('push', integer.integer);
- },
-
- BOOLEAN: function(boolean) {
- this.opcode('push', boolean.boolean);
- },
-
- comment: function() {},
-
- // HELPERS
- pushParams: function(params) {
- var i = params.length, param;
-
- while(i--) {
- param = params[i];
-
- if(this.options.stringParams) {
- if(param.depth) {
- this.addDepth(param.depth);
- }
-
- this.opcode('getContext', param.depth || 0);
- this.opcode('pushStringParam', param.string);
- } else {
- this[param.type](param);
- }
- }
- },
-
- opcode: function(name, val1, val2) {
- this.opcodes.push(Compiler.OPCODE_MAP[name]);
- if(val1 !== undefined) { this.opcodes.push(val1); }
- if(val2 !== undefined) { this.opcodes.push(val2); }
- },
-
- declare: function(name, value) {
- this.opcodes.push('DECLARE');
- this.opcodes.push(name);
- this.opcodes.push(value);
- },
-
- addDepth: function(depth) {
- if(depth === 0) { return; }
-
- if(!this.depths[depth]) {
- this.depths[depth] = true;
- this.depths.list.push(depth);
- }
- },
-
- setupStackForMustache: function(mustache) {
- var params = mustache.params;
-
- this.pushParams(params);
-
- if(mustache.hash) {
- this.hash(mustache.hash);
- } else {
- this.opcode('push', '{}');
- }
-
- this.ID(mustache.id);
-
- return params;
- }
- };
-
- JavaScriptCompiler.prototype = {
- // PUBLIC API: You can override these methods in a subclass to provide
- // alternative compiled forms for name lookup and buffering semantics
- nameLookup: function(parent, name, type) {
- if(JavaScriptCompiler.RESERVED_WORDS[name] || name.indexOf('-') !== -1 || !isNaN(name)) {
- return parent + "['" + name + "']";
- } else if (/^[0-9]+$/.test(name)) {
- return parent + "[" + name + "]";
- } else {
- return parent + "." + name;
- }
- },
-
- appendToBuffer: function(string) {
- return "buffer = buffer + " + string + ";";
- },
-
- initializeBuffer: function() {
- return this.quotedString("");
- },
- // END PUBLIC API
-
- compile: function(environment, options) {
- this.environment = environment;
- this.options = options || {};
-
- this.preamble();
-
- this.stackSlot = 0;
- this.stackVars = [];
- this.registers = {list: []};
-
- this.compileChildren(environment, options);
-
- Handlebars.log(Handlebars.logger.DEBUG, environment.disassemble() + "\n\n");
-
- var opcodes = environment.opcodes, opcode, name, declareName, declareVal;
-
- this.i = 0;
-
- for(l=opcodes.length; this.i<l; this.i++) {
- opcode = this.nextOpcode(0);
-
- if(opcode[0] === 'DECLARE') {
- this.i = this.i + 2;
- this[opcode[1]] = opcode[2];
- } else {
- this.i = this.i + opcode[1].length;
- this[opcode[0]].apply(this, opcode[1]);
- }
- }
-
- return this.createFunction();
- },
-
- nextOpcode: function(n) {
- var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
- var extraParams, codes;
-
- if(opcode === 'DECLARE') {
- name = opcodes[this.i + 1];
- val = opcodes[this.i + 2];
- return ['DECLARE', name, val];
- } else {
- name = Compiler.DISASSEMBLE_MAP[opcode];
-
- extraParams = Compiler.multiParamSize(opcode);
- codes = [];
-
- for(var j=0; j<extraParams; j++) {
- codes.push(opcodes[this.i + j + 1 + n]);
- }
-
- return [name, codes];
- }
- },
-
- eat: function(opcode) {
- this.i = this.i + opcode.length;
- },
-
- preamble: function() {
- var out = [];
- out.push("var buffer = " + this.initializeBuffer() + ", currentContext = context");
-
- var copies = "helpers = helpers || Handlebars.helpers;";
- if(this.environment.usePartial) { copies = copies + " partials = partials || Handlebars.partials;"; }
- out.push(copies);
-
- // track the last context pushed into place to allow skipping the
- // getContext opcode when it would be a noop
- this.lastContext = 0;
- this.source = out;
- },
-
- createFunction: function() {
- var container = {
- escapeExpression: Handlebars.Utils.escapeExpression,
- invokePartial: Handlebars.VM.invokePartial,
- programs: [],
- program: function(i, helpers, partials, data) {
- var programWrapper = this.programs[i];
- if(data) {
- return Handlebars.VM.program(this.children[i], helpers, partials, data);
- } else if(programWrapper) {
- return programWrapper;
- } else {
- programWrapper = this.programs[i] = Handlebars.VM.program(this.children[i], helpers, partials);
- return programWrapper;
- }
- },
- programWithDepth: Handlebars.VM.programWithDepth,
- noop: Handlebars.VM.noop
- };
- var locals = this.stackVars.concat(this.registers.list);
-
- if(locals.length > 0) {
- this.source[0] = this.source[0] + ", " + locals.join(", ");
- }
-
- this.source[0] = this.source[0] + ";";
-
- this.source.push("return buffer;");
-
- var params = ["Handlebars", "context", "helpers", "partials"];
-
- if(this.options.data) { params.push("data"); }
-
- for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
- params.push("depth" + this.environment.depths.list[i]);
- }
-
- if(params.length === 4 && !this.environment.usePartial) { params.pop(); }
-
- params.push(this.source.join("\n"));
-
- var fn = Function.apply(this, params);
- fn.displayName = "Handlebars.js";
-
- Handlebars.log(Handlebars.logger.DEBUG, fn.toString() + "\n\n");
-
- container.render = fn;
-
- container.children = this.environment.children;
-
- return function(context, options, $depth) {
- try {
- options = options || {};
- var args = [Handlebars, context, options.helpers, options.partials, options.data];
- var depth = Array.prototype.slice.call(arguments, 2);
- args = args.concat(depth);
- return container.render.apply(container, args);
- } catch(e) {
- throw e;
- }
- };
- },
-
- appendContent: function(content) {
- this.source.push(this.appendToBuffer(this.quotedString(content)));
- },
-
- append: function() {
- var local = this.popStack();
- this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
- },
-
- appendEscaped: function() {
- var opcode = this.nextOpcode(1), extra = "";
-
- if(opcode[0] === 'appendContent') {
- extra = " + " + this.quotedString(opcode[1][0]);
- this.eat(opcode);
- }
-
- this.source.push(this.appendToBuffer("this.escapeExpression(" + this.popStack() + ")" + extra));
- },
-
- getContext: function(depth) {
- if(this.lastContext !== depth) {
- this.lastContext = depth;
-
- if(depth === 0) {
- this.source.push("currentContext = context;");
- } else {
- this.source.push("currentContext = depth" + depth + ";");
- }
- }
- },
-
- lookupWithHelpers: function(name) {
- if(name) {
- var topStack = this.nextStack();
-
- var toPush = "if('" + name + "' in helpers) { " + topStack +
- " = " + this.nameLookup('helpers', name, 'helper') +
- "; } else { " + topStack + " = " +
- this.nameLookup('currentContext', name, 'context') +
- "; }";
-
- this.source.push(toPush);
- } else {
- this.pushStack("currentContext");
- }
- },
-
- lookup: function(name) {
- var topStack = this.topStack();
- this.source.push(topStack + " = " + this.nameLookup(topStack, name, 'context') + ";");
- },
-
- pushStringParam: function(string) {
- this.pushStack("currentContext");
- this.pushString(string);
- },
-
- pushString: function(string) {
- this.pushStack(this.quotedString(string));
- },
-
- push: function(name) {
- this.pushStack(name);
- },
-
- invokeMustache: function(paramSize, original) {
- this.populateParams(paramSize, this.quotedString(original), "{}", null, function(nextStack, helperMissingString, id) {
- this.source.push("else if(" + id + "=== undefined) { " + nextStack + " = helpers.helperMissing.call(" + helperMissingString + "); }");
- this.source.push("else { " + nextStack + " = " + id + "; }");
- });
- },
-
- invokeProgram: function(guid, paramSize) {
- var inverse = this.programExpression(this.inverse);
- var mainProgram = this.programExpression(guid);
-
- this.populateParams(paramSize, null, mainProgram, inverse, function(nextStack, helperMissingString, id) {
- this.source.push("else { " + nextStack + " = helpers.blockHelperMissing.call(" + helperMissingString + "); }");
- });
- },
-
- populateParams: function(paramSize, helperId, program, inverse, fn) {
- var id = this.popStack(), nextStack;
- var params = [], param, stringParam;
-
- var hash = this.popStack();
-
- this.register('tmp1', program);
- this.source.push('tmp1.hash = ' + hash + ';');
-
- if(this.options.stringParams) {
- this.source.push('tmp1.contexts = [];');
- }
-
- for(var i=0; i<paramSize; i++) {
- param = this.popStack();
- params.push(param);
-
- if(this.options.stringParams) {
- this.source.push('tmp1.contexts.push(' + this.popStack() + ');');
- }
- }
-
- if(inverse) {
- this.source.push('tmp1.fn = tmp1;');
- this.source.push('tmp1.inverse = ' + inverse + ';');
- }
-
- if(this.options.data) {
- this.source.push('tmp1.data = data;');
- }
-
- params.push('tmp1');
-
- // TODO: This is legacy behavior. Deprecate and remove.
- if(inverse) {
- params.push(inverse);
- }
-
- this.populateCall(params, id, helperId || id, fn);
- },
-
- populateCall: function(params, id, helperId, fn) {
- var paramString = ["context"].concat(params).join(", ");
- var helperMissingString = ["context"].concat(helperId).concat(params).join(", ");
-
- nextStack = this.nextStack();
-
- this.source.push("if(typeof " + id + " === 'function') { " + nextStack + " = " + id + ".call(" + paramString + "); }");
- fn.call(this, nextStack, helperMissingString, id);
- },
-
- invokeInverse: function(guid) {
- var program = this.programExpression(guid);
-
- var blockMissingParams = ["context", this.topStack(), "this.noop", program];
- this.pushStack("helpers.blockHelperMissing.call(" + blockMissingParams.join(", ") + ")");
- },
-
- invokePartial: function(context) {
- this.pushStack("this.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);");
- },
-
- assignToHash: function(key) {
- var value = this.popStack();
- var hash = this.topStack();
-
- this.source.push(hash + "['" + key + "'] = " + value + ";");
- },
-
- // HELPERS
-
- compiler: JavaScriptCompiler,
-
- compileChildren: function(environment, options) {
- var children = environment.children, child, compiler;
- var compiled = [];
-
- for(var i=0, l=children.length; i<l; i++) {
- child = children[i];
- compiler = new this.compiler();
-
- compiled[i] = compiler.compile(child, options);
- }
-
- environment.rawChildren = children;
- environment.children = compiled;
- },
-
- programExpression: function(guid) {
- if(guid == null) { return "this.noop"; }
-
- var programParams = [guid, "helpers", "partials"];
-
- var depths = this.environment.rawChildren[guid].depths.list;
-
- if(this.options.data) { programParams.push("data"); }
-
- for(var i=0, l = depths.length; i<l; i++) {
- depth = depths[i];
-
- if(depth === 1) { programParams.push("context"); }
- else { programParams.push("depth" + (depth - 1)); }
- }
-
- if(!this.environment.usePartial) {
- if(programParams[3]) {
- programParams[2] = "null";
- } else {
- programParams.pop();
- }
- }
-
- if(depths.length === 0) {
- return "this.program(" + programParams.join(", ") + ")";
- } else {
- programParams[0] = "this.children[" + guid + "]";
- return "this.programWithDepth(" + programParams.join(", ") + ")";
- }
- },
-
- register: function(name, val) {
- this.useRegister(name);
- this.source.push(name + " = " + val + ";");
- },
-
- useRegister: function(name) {
- if(!this.registers[name]) {
- this.registers[name] = true;
- this.registers.list.push(name);
- }
- },
-
- pushStack: function(item) {
- this.source.push(this.nextStack() + " = " + item + ";");
- return "stack" + this.stackSlot;
- },
-
- nextStack: function() {
- this.stackSlot++;
- if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
- return "stack" + this.stackSlot;
- },
-
- popStack: function() {
- return "stack" + this.stackSlot--;
- },
-
- topStack: function() {
- return "stack" + this.stackSlot;
- },
-
- quotedString: function(str) {
- return '"' + str
- .replace(/\\/g, '\\\\')
- .replace(/"/g, '\\"')
- .replace(/\n/g, '\\n')
- .replace(/\r/g, '\\r') + '"';
- }
- };
-
- var reservedWords = ("break case catch continue default delete do else finally " +
- "for function if in instanceof new return switch this throw " +
- "try typeof var void while with null true false").split(" ");
-
- compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
-
- for(var i=0, l=reservedWords.length; i<l; i++) {
- compilerWords[reservedWords[i]] = true;
- }
-
-})(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
-
-Handlebars.VM = {
- programWithDepth: function(fn, helpers, partials, data, $depth) {
- var args = Array.prototype.slice.call(arguments, 4);
-
- return function(context, options) {
- options = options || {};
-
- options = {
- helpers: options.helpers || helpers,
- partials: options.partials || partials,
- data: options.data || data
- };
-
- return fn.apply(this, [context, options].concat(args));
- };
- },
- program: function(fn, helpers, partials, data) {
- return function(context, options) {
- options = options || {};
-
- return fn(context, {
- helpers: options.helpers || helpers,
- partials: options.partials || partials,
- data: options.data || data
- });
- };
- },
- noop: function() { return ""; },
- compile: function(string, options) {
- var ast = Handlebars.parse(string);
- var environment = new Handlebars.Compiler().compile(ast, options);
- return new Handlebars.JavaScriptCompiler().compile(environment, options);
- },
- invokePartial: function(partial, name, context, helpers, partials) {
- if(partial === undefined) {
- throw new Handlebars.Exception("The partial " + name + " could not be found");
- } else if(partial instanceof Function) {
- return partial(context, {helpers: helpers, partials: partials});
- } else {
- partials[name] = Handlebars.VM.compile(partial);
- return partials[name](context, {helpers: helpers, partials: partials});
- }
- }
-};
-
-Handlebars.compile = Handlebars.VM.compile;;
View
10 package.json
@@ -1,10 +0,0 @@
-{
- "name": "scriptular",
- "version": "0.0.1",
- "dependencies": {
- "coffee-script": "1.2.0",
- "serveup": "~0.0.2",
- "hem": "~0.1.6",
- "spine": "~1.0.5"
- }
-}
View
38 app/results.coffee → scripts/application.coffee
@@ -1,7 +1,32 @@
-class Results extends Spine.Controller
+$ = jQuery
+
+class Expression extends Spine.Controller
+ elements:
+ 'input[name=expression]': 'regexp'
+ 'input[name=option]': 'option'
+
+ events:
+ 'keyup input': 'onKeyPress'
+
+ onKeyPress: (event) ->
+ @value = new RegExp(@regexp.val(), @option.val())
+ @.trigger 'update'
+
+class TestStrings extends Spine.Controller
elements:
- 'ol': 'list'
+ 'textarea': 'input'
+ events:
+ 'keyup textarea': 'onKeyPress'
+
+ onKeyPress: (event) ->
+ @getValues(@input.val())
+ @.trigger 'update'
+
+ getValues: (val) ->
+ @values = val.split('\n')
+
+class Results
constructor: (@expression, @test_strings) ->
@expression.bind 'update', @compile
@test_strings.bind 'update', @compile
@@ -28,4 +53,11 @@ class Results extends Spine.Controller
for match in value.match(@expression.value)[1..-1]
$("ul#groups li#match_#{count} ol").append("<li>#{match}</li>")
-module.exports = Results
+class App
+ constructor: ->
+ @expression = new Expression(el: '#expression')
+ @test_strings = new TestStrings(el: '#test_strings')
+ @results = new Results(@expression, @test_strings)
+
+$ ->
+ new App
View
528 scripts/spine.coffee
@@ -0,0 +1,528 @@
+Events =
+ bind: (ev, callback) ->
+ evs = ev.split(' ')
+ calls = @hasOwnProperty('_callbacks') and @_callbacks or= {}
+
+ for name in evs
+ calls[name] or= []
+ calls[name].push(callback)
+ this
+
+ one: (ev, callback) ->
+ @bind ev, ->
+ @unbind(ev, arguments.callee)
+ callback.apply(@, arguments)
+
+ trigger: (args...) ->
+ ev = args.shift()
+
+ list = @hasOwnProperty('_callbacks') and @_callbacks?[ev]
+ return unless list
+
+ for callback in list
+ if callback.apply(@, args) is false
+ break
+ true
+
+ unbind: (ev, callback) ->
+ unless ev
+ @_callbacks = {}
+ return this
+
+ list = @_callbacks?[ev]
+ return this unless list
+
+ unless callback
+ delete @_callbacks[ev]
+ return this
+
+ for cb, i in list when cb is callback
+ list = list.slice()
+ list.splice(i, 1)
+ @_callbacks[ev] = list
+ break
+ this
+
+Log =
+ trace: true
+
+ logPrefix: '(App)'
+
+ log: (args...) ->
+ return unless @trace
+ if @logPrefix then args.unshift(@logPrefix)
+ console?.log?(args...)
+ this
+
+moduleKeywords = ['included', 'extended']
+
+class Module
+ @include: (obj) ->
+ throw('include(obj) requires obj') unless obj
+ for key, value of obj when key not in moduleKeywords
+ @::[key] = value
+ obj.included?.apply(@)
+ this
+
+ @extend: (obj) ->
+ throw('extend(obj) requires obj') unless obj
+ for key, value of obj when key not in moduleKeywords
+ @[key] = value
+ obj.extended?.apply(@)
+ this
+
+ @proxy: (func) ->
+ => func.apply(@, arguments)
+
+ proxy: (func) ->
+ => func.apply(@, arguments)
+
+ constructor: ->
+ @init?(arguments...)
+
+class Model extends Module
+ @extend Events
+
+ @records: {}
+ @crecords: {}
+ @attributes: []
+
+ @configure: (name, attributes...) ->
+ @className = name
+ @records = {}
+ @crecords = {}
+ @attributes = attributes if attributes.length
+ @attributes and= makeArray(@attributes)
+ @attributes or= []
+ @unbind()
+ this
+
+ @toString: -> "#{@className}(#{@attributes.join(", ")})"
+
+ @find: (id) ->
+ record = @records[id]
+ if !record and ("#{id}").match(/c-\d+/)
+ return @findCID(id)
+ throw('Unknown record') unless record
+ record.clone()
+
+ @findCID: (cid) ->
+ record = @crecords[cid]
+ throw('Unknown record') unless record
+ record.clone()
+
+ @exists: (id) ->
+ try
+ return @find(id)
+ catch e
+ return false
+
+ @refresh: (values, options = {}) ->
+ if options.clear
+ @records = {}
+ @crecords = {}
+
+ records = @fromJSON(values)
+ records = [records] unless isArray(records)
+
+ for record in records
+ record.id or= record.cid
+ @records[record.id] = record
+ @crecords[record.cid] = record
+
+ @trigger('refresh', not options.clear and @cloneArray(records))
+ this