diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cf96174 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +*.DS_Store \ No newline at end of file diff --git a/.yarnrc b/.yarnrc new file mode 100644 index 0000000..fdd705c --- /dev/null +++ b/.yarnrc @@ -0,0 +1 @@ +save-prefix "" diff --git a/Cakefile b/Cakefile index 1752b49..867e95f 100644 --- a/Cakefile +++ b/Cakefile @@ -1,9 +1,11 @@ -{spawn, exec} = require 'child_process' -fs = require 'fs' -jison = require 'jison' -path = require 'path' - -task 'build', 'build the whole jam', (cb) -> +require 'iced-coffee-script/register' +{spawn, exec} = require 'child_process' +fs = require 'fs' +jison = require 'jison' +path = require 'path' +express_test = require './test/generate_express_test' + +task 'build', 'build the whole jam', (cb) -> console.log "Building" files = fs.readdirSync 'src' files = ('src/' + file for file in files when file.match(/\.coffee$/)) @@ -11,13 +13,18 @@ task 'build', 'build the whole jam', (cb) -> buildParser -> runCoffee ['-c', '-o', 'lib/'].concat(files), -> runCoffee ['-c', 'index.coffee'], -> - generateExpressTest -> - console.log "Done building." - cb() if typeof cb is 'function' + buildCommonBrowserHeaders -> + express_test.generate -> + console.log "Done building." + cb() if typeof cb is 'function' + +task 'test', 'test server and browser support', (cb) -> + run_cases = require './test/run_cases.iced' + run_cases.test -> + console.log "Done." runCoffee = (args, cb) -> - proc = spawn 'coffee', args - console.log args + proc = spawn './node_modules/.bin/coffee', args proc.stderr.on 'data', (buffer) -> console.log buffer.toString() proc.on 'exit', (status) -> process.exit(1) if status isnt 0 @@ -40,65 +47,8 @@ buildParser = (cb) -> fs.writeFileSync "./lib/#{file_name}", source cb() -generateExpressTest = (cb) -> - - # generate the JS file bundling all the tests - - proc = spawn 'coffee', ['./src/command_line.coffee', './test/cases', '-m', '-o', './test/express3/public/javascripts/test_cases.js'] - proc.stderr.on 'data', (buffer) -> console.log buffer.toString() - proc.stdout.on 'data', (buffer) -> console.log buffer.toString() - proc.on 'exit', (status) -> - process.exit(1) if status isnt 0 - cb() if typeof cb is 'function' - - # generate an index page that tests them all - - test_page = """ - - - Test Toffee in the browser - - - - - - - """ - - case_dirs = fs.readdirSync "./test/cases/" - - for dir,i in case_dirs - if dir isnt "custom_escape" # a special case since this isn't actually JSON - expected_output = fs.readFileSync "./test/cases/#{dir}/output.toffee", "utf8" - if path.existsSync "./test/cases/#{dir}/vars.js" - vars = fs.readFileSync "./test/cases/#{dir}/vars.js", "utf8" - else - vars = "{}" - rid = i - test_page += """ - \n\n\n - - - - - - - - - - - \n\n\n - """ - - test_page += """ -
FILEEXPECTED OUTPUTSERVER RENDERBROWSER RENDER
#{dir}\#{partial '../../cases/#{dir}/input.toffee', #{vars}}#{expected_output}
- - - """ - fs.writeFileSync "./test/express3/views/index.toffee", test_page, "utf8" \ No newline at end of file +buildCommonBrowserHeaders = (cb) -> + {getCommonHeadersJs} = require './lib/view' + headers = getCommonHeadersJs true, true + fs.writeFileSync "./toffee.js", headers, "utf8" + cb() diff --git a/README.md b/README.md index 8793049..fa54c1b 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,32 @@ -TOFFEE -========= -A templating language based on the simplicity and beauty of CoffeeScript. -Compatible with node (including Express 2.x, 3.x) and, very soon, the browser. In Express 3.x, the Toffee engine handles partials/includes -and smart view caching. - -status -====== -Beta! And usable! If you hit any snags, let me know and I'll act fast. - -examples -======== -Printing variables is easy. Just use CoffeeScript's #{} syntax: +# TOFFEE + +**_Toffee_ is barely maintained. Please consider another templating language.** + +_Toffee_ is a templating language, based on the simplicity and beauty of CoffeeScript. + +- it works with Node.js +- it works in the browser, too -- even the advanced features. + +Newest feature: + +- post-processing! You can let Toffee do your server-side code highighting, and other magic. + +Toffee has many cool features. Keep on reading. + +# Table of Contents + +- [1. Language Basics](#section_1) +- [2. Notes on Escaping](#section_2) +- [3. Common Questions](#section_3) +- [4. Installation & Usage (Node, Express, and the browser)](#section_4) + +## Language Basics + +Printing variables in Toffee is easy. Just use CoffeeScript's #{} syntax: + ```html
- Hey, #{user.name}. - #{flirty_welcome_msg} + Hey, #{user.name}. #{flirty_welcome_msg}
``` @@ -22,52 +34,50 @@ The `#{}` syntax is powerful, so be responsible. ```html

- You have #{(f for f in friends when f.gender is "f").length} female friends. + You have #{(sheep for sheep in flock when sheep.color is 'black').length} + black sheep in the flock.

``` -Including other files is possible thanks to the function `partial`. This works in Express 3.0, too. +Including other files is possible thanks to the function `partial`. This works in both Express and the browser. ```html

- #{partial "navigation.toffee", {username: user.name, age: 22} } + #{partial "navigation.toffee", {username: user.name, age: 22} }

``` But the greatest pleasure arises when you enter -`coffee mode`. Note the `{# ... #}` region. +`coffee mode`. Note the `{# ... #}` region, where you can write multiple lines of CoffeeScript. ```html

- {# - ten_numbers = (Math.random() for i in [0...10]) - ten_numbers.sort (a,b) -> b - a - #} - The largest number I can even think of is #{ten_numbers[0]}. + {# ten_numbers = [1,3,2,4,5,8,6,7,69, Math.random()] ten_numbers.sort (a,b) -> + b - a #} The largest number I can even think of is #{ten_numbers[0]}.

``` -Further, inside `coffee mode`, you can switch back to `toffee mode` with `{: ... :}`. It's endlessly nestable. +Against all odds, inside `coffee mode`, you can switch back to `toffee mode` with `{: ... :}`. It's endlessly nestable. ```html
-
- {# - if projects.length - for project in projects {: - - :} - #} -
+
+ {# if projects.length for project in projects {: + + :} #} +
``` This bracket and nesting syntax avoids a lot of large, ugly regions, such -as EJS's unsavory and unethical `<% } %>`. Compare: +as EJS's unethical `<% } %>`. It's been wrong for thousands of years +to have control markers surrounded by other control +markers, and it is still wrong. Witness: EJS, verbose and weak. + ``` <% for(var i=0; i
  • <%= supplies[i] %>
  • @@ -75,68 +85,188 @@ EJS, verbose and weak. ``` TOFFEE, so elegant and proud. + ```html -{# - for supply in supplies {:
  • #{supply}
  • :} -#} +{# for supply in supplies {: +
  • #{supply}
  • +:} #} ``` -Or, using the built-in `print`: +Or, using Toffee's `print`: + ```html -{# - for supply in supplies - print "
  • #{supply}
  • " -#} +{# for supply in supplies print " +
  • #{supply}
  • +" #} ``` -These are slightly different, as `print` outputs raw text, while `#{}` used in toffee mode safely escapes for HTML. This escaping -is customizable. More on that below. +These are slightly different, as `print` outputs raw text, while `#{}` used in toffee mode safely escapes HTML or JSON. This escaping +escaping is customizable. More on that below. -With nested code, indentation is inferred. +With nested code, indentation of your CoffeeScript is magically maintained. ```html -{# - for name, profile of friends when profile.is_responsible {: -

    - You know, #{name} would make a great designated driver. - And she only lives #{profile.distance}km away. - {# - profile.cars.sort (a,b) -> b.speed - a.speed - if profile.cars.length {: And wow, she drives a #{profile.cars[0].model} :} - else {: But, alas, she has no wheels. :} - #} -

    - :} -#} +{# if user.is_drunk for name, profile of friends when profile.is_responsible {: +

    + You know, #{name} would make a great designated driver. And she only lives + #{profile.distance}km away. {# if profile.car? {: And wow, she drives a + #{profile.car.model} :} else {: But, alas, she has no wheels. :} #} +

    +:} #} ``` -Switching to toffee mode without indenting ------ -By default, when you enter `{: ... :}`, the Toffee compiler assumes you're entering an indented region, -probably because of a loop or conditional. -If you ever want to cut into toffee mode without indenting, use `-{: ... :}`. For example: +### Partials (including other files), both for output and configuration + +Including other files in Toffee is easy with the `partial` function, which includes another template file. +```html +
    + #{partial '../main_navigation.toffee'} +
    ``` -{# - name = "Hans Gruber" - -{:You're a hell of a thief, #{name}:} -#} + +Shallow copies of variables are passed through from the parent document, however you can pass additional variables with a dictionary. + +```html +
    + #{partial '../main_navigation.toffee', {user: elon_musk, iq: 180} } +
    ``` -The above is identical to: +Again, toffee's `print` function allows you to use partials when in coffeescript mode: +```html +{# if user? print partial "logged_in_template.toffee" #} ``` -{# - name = "Hans Gruber" - print "You're a hell of a thief, #{name}" -#} + +For your safety and convenience, variables are shallow-copied into a template. This means if you redefine or create a variable in a +child template, it won't be available back in the parent template. However, you can relay variables by modifying the special `passback` dictionary +in a the child template. + +```html + +{# partial './config.toffee' #} +

    Our site's name is #{site_name}.

    + + +{# passback.site_name = "gittub.com" #} +``` + +For your naming convenience, you can also use the `load` function, which is identical to `partial` but withholds output. + +### Post-processing + +New in the latest version of Toffee, you can pass a `postProcess` function to Toffee. This works for individual partials or even +an entire document. The `postProcess` function performs a final transformation on your output. + +One smart use of postProcess is to find anything inside triple tick marks and perform a code higlighting. + +```html +{# print partial './something.toffee', { foo: 1000 postProcess: (s) -> +find_and_higlight_code_in s } #} +``` + +You could define `find_and_highlight_code_in` anywhere in your publishing stack. You can pass it from your webserver, define it above, whatever. If you're +doing this server-side, consider the popular Node module _highlight.js_. In that case, define a highlight function that hunts for +triple tick marks and then uses highlight's highlighter to transform it. + +Your users shouldn't have to wait for client-side JS to re-process your pages. + +### Indentation + +Since CoffeeScript is sensitive to indenting, so is Toffee. + +But...Toffee doesn't care where you start your CoffeeScript. When you want to create a coffee block, +you can indent it however you like, and all that matters is that the internal, +relative indenting is correct. For example, these are identical: + +```html +

    + {# if user.is_awesome {: YAY! :} #} +

    +

    + {# if user.is_awesome {: YAY! :} #} +

    +``` + +In other words, feel free to pick whatever indentation baseline you want when entering a region of CoffeeScript. + +Note that where you put your toffee mode tokens (`{:`) is important, as the following illustrates: + +```html +

    + {# if x is true if y is true if z is true w = true {: x is true! Dunno + anything about y or z, though. :} #} +

    +``` + +Why? Because this is roughly the same as saying: + +```html +

    + {# if x is true if y is true if z is true w = true print "\n x is true! Dunno + anything about y or z, though.\n " #} +

    +``` + +One syntactic convenience: if you start a `{:` on the same line as some preceeding CoffeeScript, it's +treated the same as putting it on a new line and indenting one level. +So the following three conditionals are the same: + +```html +{# if x is true {:yay:} #} +``` + +```html +{# if x is true {:yay:} #} +``` + +```html +{# if x is true {: yay :} #} +``` + +The third example has extra whitespace around the "yay," but otherwise the three are logically identical. + +### One gotcha with indenting + +THIS IS AN ERROR + +```html +{# if x is 0 {:Yay!:} else {:Burned:} #} +``` + +Note that the indentations before the 'if' and the 'else' are technically different, +as the `if` has only 1 space before it, and the `else` has 2. This is better style anyway: + +GOOD + +```html +{# if x is 0 {:Yay!:} else {:Burned:} #} ``` -Well, it's not exactly identical. Let's talk about escaping. +With a single line of CoffeeScript, feel free to keep it all on one line: +GOOD + +```html +
    {# foo = "bar" #}
    +``` + +## Commenting out a block of toffee + +In toffee mode, you can comment out a region with `{##` and `##}`. + +```html +
    + I don't want to output this anymore... {## +

    An ode to Ruby on Rails

    +

    #{partial 'ode.toffee'}

    + ##} +
    +``` + +## Escaping -escaping: how it works -============== In your CoffeeScript, the `print` function lets you print the raw value of a variable: ``` @@ -153,59 +283,56 @@ But in toffee mode, `#{some_expression}` output is escaped intelligently by defa

    #{danger_code}

    ``` -You can control the escaping, but here are the defaults: +You can control the escaping, but here are the defaults: - * if it's a string or scalar, it is escaped for HTML safety. - * it's an array or object, it is converted to JSON. +- if it's a string or scalar, it is escaped for HTML safety. +- it's an array or object, it is converted to JSON. -escaping overrides ----------------- +### Custom Escaping You can bypass the above rules. - * `#{json foo}`: this outputs foo as JSON. - * `#{raw foo}`: this outputs foo in raw text. - * `#{html foo}`: this outputs foo, escaped as HTML. For a scalar, it's the same as `#{foo}`, but it's available in case you -(1) override the default escaping or (2) turn off auto-escaping (both explained below). - * `#{partial "foo.toffee"}` and `#{snippet "foo.toffee"}`: unescaped, since you don't want to escape your own templates +- `#{json foo}`: this outputs foo as JSON. +- `#{raw foo}`: this outputs foo in raw text. +- `#{html foo}`: this outputs foo, escaped as HTML. For a scalar, it's the same as `#{foo}`, but it's available in case you + (1) override the default escaping or (2) turn off auto-escaping (both explained below). +- `#{partial "foo.toffee"}` and `#{snippet "foo.toffee"}`: unescaped, since you don't want to escape your own templates -When any of the functions mentioned above are leftmost in a `#{}` token in toffee mode, their output is left untouched by the +When any of the functions mentioned above are leftmost in a `#{}` token in toffee mode, their output is left untouched by the built in escape function. These functions are also available to you in coffee mode. ```html

    - Want to read some JSON, human? - {# - foo = [1,2,3, {bar: "none"}] - foo_as_json_as_html = html json foo - print foo_as_json_as_html - #} + Want to read some JSON, human? {# foo = [1,2,3, {bar: "none"}] + foo_as_json_as_html = html json foo print foo_as_json_as_html #}

    ``` -*Note!* if you pass a variable to the template called `json`, `raw`, or `html`, Toffee won't create these helper functions, which would override your vars. +_Note!_ if you pass a variable to the template called `json`, `raw`, or `html`, Toffee won't create these helper functions, which would override your vars. In this case, you can access the escape functions through their official titles, `__toffee.raw`, etc. Overriding the default `escape`: - * If you pass a variable to your template called `escape`, this will be used as the default escape. In toffee mode, everything inside `#{}` that isn't subject to an above-mentioned exception will go through your `escape` function. + +- If you pass a variable to your template called `escape`, this will be used as the default escape. In toffee mode, everything inside `#{}` that isn't subject to an above-mentioned exception will go through your `escape` function. Turning off autoescaping entirely: - * If you set `autoEscape: false` when creating the engine, the default will be raw across your project. (See more on that below under Express 3.x settings.) - * Alternatively, you could pass the var `escape: (x) -> x` to turn off escaping for a given template. -questions -======== +- If you set `autoEscape: false` when creating the engine, the default will be raw across your project. (See more on that below under Express 3.x settings.) +- Alternatively, you could pass the var `escape: (x) -> x` to turn off escaping for a given template. + +## Common Questions + +#### How does it compare to eco? -How does it compare to eco? --------------------------- Eco is another CoffeeScript templating language and inspiration for Toffee. The syntaxes are pretty different, so pick the one you prefer. One big Toffee advantage: multiple lines of CoffeeScript just look like CoffeeScript. Compare: ECO + ``` <% if @projects.length: %> <% for project in @projects: %> @@ -217,53 +344,48 @@ ECO ``` TOFFEE + ```html -{# - if @projects.length - for project in @projects - if project.is_active {: -

    #{project.name} | #{project.description}

    - :} -#} +{# if projects.length for project in projects if project.is_active {: +

    #{project.name} | #{project.description}

    +:} #} ``` -With Toffee's syntax, brackets enclose regions not directives, so your editor +With Toffee's syntax, brackets enclose regions not directives, so your editor will let you collapse and expand sections of code. And if you click on one of the brackets in most editors, it will highlight the matching bracket. -Does it cache templates? ------------------------- +#### Does it cache templates? + In Express 2.0, that's up to Express. When used in Express 3.0, Toffee asynchronously monitors known templates and recompiles them in the background when necessary. So you don't need to restart your production webserver whenever you edit a template. -Does it find line numbers in errors? ------------------------------------ -Yes, Toffee does a very good job of that. There are 3 possible places you can hit an error in Toffee: - * in the language itself, say a parse error - * in the CoffeeScript, preventing it from compiling to JS - * runtime, in the final JS +#### Does it find line numbers in errors? + +Yes, Toffee does a very good job of that. There are 3 possible places you can hit an error in Toffee: -Stack traces are converted to lines in Toffee and show you where the problem is. -By default when Toffee hits an error it replies with some pretty-printed HTML showing you the problem. +- in the language itself, say a parse error +- in the CoffeeScript, preventing it from compiling to JS +- runtime, in the final JS + +Stack traces are converted to lines in Toffee and show you where the problem is. +By default when Toffee hits an error it replies with some pretty-printed HTML showing you the problem. This can be overridden, as explained below in the Express 3.0 section. -Does it support partials? (a.k.a includes) -------------------------- -Yes. In Express 2.0, Express itself is responsible for including other files, and they call this system "partials." In Express 3.0, Toffee defines the `partial` function, and it -works as you'd expect. +### Does it support partials? (a.k.a includes) + +Yes. In Express 2.0, Express itself is responsible for including other files, and they call this system "partials." In Express 3.0 and in the browser, +Toffee defines the `partial` function, and it works as you'd expect. ```html
    #{partial '../foo/bar.toffee', name: "Chris"}
    ``` Inside a region of CoffeeScript, you can print or capture the result of a partial. + ```html
    -{# - if session - print partial 'user_menu.toffee', info: session.info - else - print partial 'guest_menu.toffee' -#} + {# if session print partial 'user_menu.toffee', info: session.info else print + partial 'guest_menu.toffee' #}
    ``` @@ -278,165 +400,31 @@ For example, in the above code, `session` would also be available in the user_me #} ``` -Does it support `layout`? -------------------------- -Yes, this works in Express 3.0, emulating the Express 2.0 way. If you publish a file `foo.toffee` and pass a `layout` filename to it as a var, `foo.toffee` is rendered, and the results are put into -a var called `body`. Then your layout is rendered, using all your vars plus the new `body` var. - - -How does the indentation work? ------ -Toffee realigns all your coffeescript inside a `{# region #}` by normalizing the indentation of that region. -So it doesn't matter how you indent things, as long as it makes local sense inside that region. - -For example, these are all identical: - -```html -

    {# if x is 0 {:Yay!:} else {:Burned:} #}

    -``` - -```html -

    {# - if x is 0 {:Yay!:} else {:Burned:} -#}

    -``` - -```html -

    -{# - if x is 0 {:Yay!:} - else {:Burned:} -#}

    -``` - -However, this would cause an error: - -ERROR -```html -

    -{# - if x is 0 {:Yay!:} - else {:Burned:} -#}

    -``` - -As would this more subtle case: - -ERROR -```html -

    -{# if x is 0 {:Yay!:} - else {:Burned:} -#}

    -``` - -In the above 2 cases, note that the leading whitespaces before the `if` and `else` are different, which is a CoffeeScript error. - - - - -Comments ------ -Inside a region of coffee, you can use coffee's `#` or `###` syntax to comment. -Inside toffee mode, you can comment with `{## ... ##}`. - -``` -{## This isn't output ##} -But this is. -``` - - -installation & usage -=========== -``` -npm install -g toffee -``` - -In Express 3.x to make it your default engine: -``` -app.set 'view engine', 'toffee' -``` - -In Express 3.x to use it just for .toffee files: -``` -toffee = require 'toffee' -app.engine 'toffee', toffee.__express -``` - -Express 2.x: -``` -toffee = require 'toffee' -app.register '.toffee', toffee -``` - -express 3.x options -=================== - -Pretty-print errors ------ - -Express's default error page is great for stack traces but not so great for pretty-printing template errors. -So by default, when Toffee hits any kind of error (in your templates, in your CoffeeScript, or even at runtime), -it fakes an okay result by returning some pretty HTML showing the error. If you don't like this - say you want to catch render errors - -you can turn it off. - -``` -toffee = require 'toffee' -toffee.expressEngine.prettyPrintErrors = false -``` - -Turning off auto-escaping for HTML ---------- -By default, Toffee escapes `#{}` output for HTML. You can turn this off in your engine with: -``` -toffee = require 'toffee' -toffee.expressEngine.autoEscape = false -``` +#### Does it support `layout`? +Yes, this works in NodeJS and Express 3.0, emulating the Express 2.0 way. The var `layout` is considered special, and should +be the path to your layout file. -known issues -=============== -1. comments in `{## ##}` cannot contain other toffee code. Hope to have this fixed soon, as these tokens should -be useful for temporarily commenting off a region of a template. +## Installation & Usage -3. There's a case where line numbers aren't right. +- [Using Toffee in NodeJS](https://github.com/malgorithms/toffee/wiki/NodeJS-Usage) +- [Using Toffee in Express 3](https://github.com/malgorithms/toffee/wiki/Express3-Usage) +- [Using Toffee in Express 2](https://github.com/malgorithms/toffee/wiki/Express2-Usage) +- [Using Toffee in the Browser](https://github.com/malgorithms/toffee/wiki/Browser-Usage) -command-line -============ -Soon I'll have browser compilation working. I'd like partials and everything to work before I release this. In the meantime, if you're -curious to see the CoffeeScript that's compiled from a template: +# contributing & asking for fixes. -``` -toffee -c foo.toffee -``` +If you have a problem with Toffee let me know, and I'll fix it ASAP. -Or to see it in JS: -``` -toffee foo.toffee -``` - -contributing -============= -I'm likely to accept good pull requests. +Also, I'm likely to accept good pull requests. If you'd like to edit code for this project, note that you should always edit the `.coffee` files, -as the `.js` files as generated automatically by building. +as the `.js` files are generated automatically by building. -To build -``` -> cake build -``` +To build and test your changes -To make sure you didn't break something ``` -> coffee tests/run_cases.coffee +# icake is iced-coffee-script's version of cake +> icake build +> icake test ``` - -I'm also very interested in someone building a Sublime/Textmate package for Toffee. - -todo -====== -- finish browser-side include and command-line compiler -- ...then add instructions on how to use it -- continue to add to unit tests -- stack trace conversion improvement diff --git a/bin/toffee b/bin/toffee old mode 100644 new mode 100755 diff --git a/index.coffee b/index.coffee index 3a6b2c5..84605af 100644 --- a/index.coffee +++ b/index.coffee @@ -1,13 +1,89 @@ # expose the render function -eclass = require('./lib/engine').engine -e = new eclass { verbose: false, prettyPrintErrors: true } -exports.expressEngine = e +{engine} = require('./lib/engine') +{view, getCommonHeaders, getCommonHeadersJs} = require('./lib/view') -# a pretty name for general usage -exports.render = e.run +exports.engine = engine +exports.view = view +exports.getCommonHeaders = getCommonHeaders +exports.getCommonHeadersJs = getCommonHeadersJs -# express 3.x support -exports.__express = e.run +exports.expressEngine = e = new engine { verbose: false, prettyPrintErrors: true } +exports.render = e.run +cacheless_engine = new engine { verbose: false, prettyPrintErrors: true, cache: false} + +# given a template string, returns a function that can be called +# on an object to render it. +# -------------------------------------------- + +exports.compileStr = (template_str, options) -> + v = new view template_str, options + return (x) -> v.run x + +# express 3.x support from a custom engine; +# this function takes a toffee engine +# and returns a function that matches the __express +# standard. +# -------------------------------------------- + +to_express = exports.toExpress = (eng) -> + return (filename, options, cb) -> + eng.run filename, options, (err, res) -> + if err + if typeof(err) is "string" + err = new Error err + cb err + else + cb null, res + +# express 3.x support using the default engine +# -------------------------------------------- + +__express = exports.__express = to_express e + +# consolidate.js support, which doesn't want caching on by default +# -------------------------------------------- + +exports.__consolidate_engine_render = (filename, options, cb) -> + eng = if options.cache then e else cacheless_engine + eng.run filename, options, (err, res) -> + cb err, res + +# consolidate.js wants this, but it might generally be useful +# -------------------------------------------- + +exports.str_render = exports.strRender = (template_str, options, cb) -> + v = new view template_str, options + [err, res] = v.run options + cb err, res # express 2.x support -exports.compile = require('./lib/view').expressCompile \ No newline at end of file +# -------------------------------------------- + +exports.compile = require('./lib/view').expressCompile + +# better support for string compiling +# -------------------------------------------- + +exports.configurable_compile = (source, opts) -> + opts = opts or {} + opts.headers = if opts.headers? then opts.headers else true + opts.filename = opts.filename or null + opts.to_coffee = opts.to_coffee or false + err = null + + # this compiles an individual template that you've read while recursing: + v = new view source, { + filename: opts.filename + bundlePath: opts.filename + browserMode: true + } + if opts.to_coffee + output = v.toCoffee() + else + output = v.toJavaScript() + if v.error then throw v.error.e + if opts.headers + header = getCommonHeadersJs true, true, true + if opts.coffee then output = "`#{header}`\n\n#{output}" + else output = "#{header}\n;\n#{output}" + return output diff --git a/index.js b/index.js index 5d397bc..ca2da7c 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,103 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.12.7 (function() { - var e, eclass; + var __express, cacheless_engine, e, engine, getCommonHeaders, getCommonHeadersJs, ref, to_express, view; - eclass = require('./lib/engine').engine; + engine = require('./lib/engine').engine; - e = new eclass({ + ref = require('./lib/view'), view = ref.view, getCommonHeaders = ref.getCommonHeaders, getCommonHeadersJs = ref.getCommonHeadersJs; + + exports.engine = engine; + + exports.view = view; + + exports.getCommonHeaders = getCommonHeaders; + + exports.getCommonHeadersJs = getCommonHeadersJs; + + exports.expressEngine = e = new engine({ verbose: false, prettyPrintErrors: true }); - exports.expressEngine = e; - exports.render = e.run; - exports.__express = e.run; + cacheless_engine = new engine({ + verbose: false, + prettyPrintErrors: true, + cache: false + }); + + exports.compileStr = function(template_str, options) { + var v; + v = new view(template_str, options); + return function(x) { + return v.run(x); + }; + }; + + to_express = exports.toExpress = function(eng) { + return function(filename, options, cb) { + return eng.run(filename, options, function(err, res) { + if (err) { + if (typeof err === "string") { + err = new Error(err); + } + return cb(err); + } else { + return cb(null, res); + } + }); + }; + }; + + __express = exports.__express = to_express(e); + + exports.__consolidate_engine_render = function(filename, options, cb) { + var eng; + eng = options.cache ? e : cacheless_engine; + return eng.run(filename, options, function(err, res) { + return cb(err, res); + }); + }; + + exports.str_render = exports.strRender = function(template_str, options, cb) { + var err, ref1, res, v; + v = new view(template_str, options); + ref1 = v.run(options), err = ref1[0], res = ref1[1]; + return cb(err, res); + }; exports.compile = require('./lib/view').expressCompile; + exports.configurable_compile = function(source, opts) { + var err, header, output, v; + opts = opts || {}; + opts.headers = opts.headers != null ? opts.headers : true; + opts.filename = opts.filename || null; + opts.to_coffee = opts.to_coffee || false; + err = null; + v = new view(source, { + filename: opts.filename, + bundlePath: opts.filename, + browserMode: true + }); + if (opts.to_coffee) { + output = v.toCoffee(); + } else { + output = v.toJavaScript(); + } + if (v.error) { + throw v.error.e; + } + if (opts.headers) { + header = getCommonHeadersJs(true, true, true); + if (opts.coffee) { + output = "`" + header + "`\n\n" + output; + } else { + output = header + "\n;\n" + output; + } + } + return output; + }; + }).call(this); diff --git a/lib/command_line.js b/lib/command_line.js index b0c21ab..dddf3ae 100644 --- a/lib/command_line.js +++ b/lib/command_line.js @@ -1,53 +1,70 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.12.7 (function() { - var compile, fs, getCommonHeadersJs, getVersionNumber, path, program, recurseRun, run, view, _ref; + var compile, fs, getCommonHeadersJs, getVersionNumber, maybeAttachHeaders, mkdirp, path, program, recurseRun, ref, run, view; fs = require('fs'); path = require('path'); - _ref = require('../lib/view'), view = _ref.view, getCommonHeadersJs = _ref.getCommonHeadersJs; + ref = require('../lib/view'), view = ref.view, getCommonHeadersJs = ref.getCommonHeadersJs; program = require('commander'); + mkdirp = require('mkdirp'); + getVersionNumber = function() { var o, p; - p = fs.readFileSync("" + __dirname + "/../package.json", "utf8"); + p = fs.readFileSync(__dirname + "/../package.json", "utf8"); o = JSON.parse(p); return o.version; }; program.on('--help', function() { - return console.log("\n Examples:\n\n toffee views # recurses through views and builds views.js\n toffee foo.toffee # builds foo.js\n toffee views -o templates # builds templates.js\n toffee -p foo.toffee # outputs JS to stdout\n\n\n Then use in your :\n\n \n \n "); + return console.log("\n Examples: \n \n toffee views # recurses through views and builds views.js \n toffee foo.toffee # builds foo.js \n toffee views -o templates # builds templates.js \n toffee -p foo.toffee # outputs JS to stdout \n \n \n Then use in your : \n \n \n \n"); }); - program.version(getVersionNumber()).option('-o, --output [path]', 'output file').option('-p, --print', 'print output to stdout').option('-m, --minimize', 'minimize output (ugly, smaller file)').option('-c, --coffee', 'output to CoffeeScript (not JS)').parse(process.argv); + program.version(getVersionNumber()).option('-o, --output [path]', 'file (bundles all output into a single .js)').option('-d, --output_dir [path]', 'compiles templates into parallel .js files').option('-p, --print', 'print to stdout').option('-c, --coffee', 'output to CoffeeScript (not JS)').option('-b, --bundle_path [path]', 'bundle_path (instead of "/") for templates').option('-n, --no_headers', 'exclude boilerplate toffee (requires toffee.js included separately)').parse(process.argv); - compile = function(start_path, path) { - /* - e.g., if start_path is /foo/bar - and path is /foo/bar/car/thing.toffee - */ + compile = function(start_path, full_path) { - var source, v; - source = fs.readFileSync(path, 'utf8'); + /* + e.g., if start_path is /foo/bar + and path is /foo/bar/car/thing.toffee + */ + var bundle_path, output, source, v; + source = fs.readFileSync(full_path, 'utf8'); + bundle_path = full_path.slice(start_path.length); + if (start_path === full_path) { + bundle_path = "/" + path.basename(full_path); + } + if (program.bundle_path) { + bundle_path = path.normalize(program.bundle_path + "/" + bundle_path); + } v = new view(source, { - fileName: path, - bundlePath: path.slice(start_path.length), - browserMode: true, - minimize: (program.minimize != null) && program.minimize + fileName: full_path, + bundlePath: bundle_path, + browserMode: true }); - return v._toJavaScript(); + if (program.coffee) { + output = v.toCoffee(); + } else { + output = v.toJavaScript(); + } + if (v.error) { + process.stderr.write(v.error.getPrettyPrintText()); + process.exit(1); + } + return [output, bundle_path]; }; recurseRun = function(start_path, curr_path, out_text) { - var file, files, stats, sub_path, sub_stats, _i, _len; + var comp, file, file_out_path, files, i, len, stats, sub_path, sub_stats; stats = fs.statSync(curr_path); if (stats.isDirectory()) { files = fs.readdirSync(curr_path); - for (_i = 0, _len = files.length; _i < _len; _i++) { - file = files[_i]; - sub_path = path.normalize("" + curr_path + "/" + file); + for (i = 0, len = files.length; i < len; i++) { + file = files[i]; + sub_path = path.normalize(curr_path + "/" + file); if (file.match(/\.toffee$/)) { out_text = recurseRun(start_path, sub_path, out_text); } else if (!(file === '.' || file === '..')) { @@ -58,13 +75,38 @@ } } } else { - out_text += "\n" + compile(start_path, curr_path); + comp = compile(start_path, curr_path); + out_text += "\n;\n" + comp[0]; + if (program.output_dir) { + file_out_path = path.normalize(program.output_dir + "/" + comp[1]); + file_out_path = (path.dirname(file_out_path)) + "/" + (path.basename(file_out_path, '.toffee')); + file_out_path += program.coffee ? '.coffee' : '.js'; + if (!program.print) { + console.log("Outputting " + file_out_path); + } + mkdirp.sync(path.dirname(file_out_path)); + fs.writeFileSync(file_out_path, maybeAttachHeaders(comp[0]), "utf8"); + } } return out_text; }; + maybeAttachHeaders = function(pre_output) { + var header_out; + if (program.no_headers) { + return pre_output; + } else { + header_out = getCommonHeadersJs(true, true, true); + if (program.coffee) { + return "`" + header_out + "`\n\n" + pre_output; + } else { + return header_out + "\n;\n" + pre_output; + } + } + }; + run = exports.run = function() { - var out_text, start_path; + var e, out_text, start_path, template_out; if (program.args.length !== 1) { console.log("Unexpected input. toffee --help for examples"); console.log(program.args); @@ -72,12 +114,23 @@ } else { try { start_path = fs.realpathSync(program.args[0]); - } catch (e) { + } catch (error) { + e = error; console.log("Input file/path not found. toffee --help for examples"); process.exit(1); } + if (program.output_dir) { + try { + mkdirp.sync(program.output_dir); + } catch (error) { + e = error; + console.log("Couldn't make/use " + program.output_dir + "; " + e); + process.exit(1); + } + } start_path = path.normalize(start_path); - out_text = "" + (getCommonHeadersJs(true, false)) + (recurseRun(start_path, start_path, '')); + template_out = recurseRun(start_path, start_path, ''); + out_text = maybeAttachHeaders(template_out); if (program.print) { console.log(out_text); } @@ -85,7 +138,8 @@ try { console.log("Writing " + program.output); return fs.writeFileSync(program.output, out_text, "utf8"); - } catch (e) { + } catch (error) { + e = error; console.log(e); return process.exit(1); } diff --git a/lib/consts.js b/lib/consts.js index cd77ed6..aed3d69 100644 --- a/lib/consts.js +++ b/lib/consts.js @@ -1,6 +1,5 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.12.7 (function() { - exports.states = { TOFFEE: 1, COFFEE: 2 @@ -8,4 +7,8 @@ exports.TAB_SPACES = 2; + exports.tweakables = { + MISSING_FILE_RECHECK: 1000 + }; + }).call(this); diff --git a/lib/engine.js b/lib/engine.js index b0ba08a..77ba860 100644 --- a/lib/engine.js +++ b/lib/engine.js @@ -1,11 +1,13 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.12.7 (function() { - var engine, fs, path, states, util, utils, view, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + var LockTable, MAX_CACHED_SANDBOXES, Pool, engine, fs, path, ref, sandboxCons, states, tweakables, util, utils, view, vm, + bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; view = require('./view').view; - states = require('./consts').states; + ref = require('./consts'), states = ref.states, tweakables = ref.tweakables; + + Pool = require('./pool').Pool; utils = require('./utils'); @@ -15,26 +17,42 @@ util = require('util'); - engine = (function() { + vm = require('vm'); - function engine(options) { - this._fn_partial = __bind(this._fn_partial, this); + LockTable = require('iced-lock').Table; - this._fn_snippet = __bind(this._fn_snippet, this); + MAX_CACHED_SANDBOXES = 100; - this._inlineInclude = __bind(this._inlineInclude, this); + sandboxCons = function() { + return vm.createContext({}); + }; - this.run = __bind(this.run, this); + engine = (function() { + function engine(options) { + this._fn_partial = bind(this._fn_partial, this); + this._fn_snippet = bind(this._fn_snippet, this); + this._fn_load = bind(this._fn_load, this); + this._inlineInclude = bind(this._inlineInclude, this); + this.run = bind(this.run, this); + this.render = bind(this.render, this); options = options || {}; this.verbose = options.verbose || false; + this.pool = new Pool(sandboxCons, options.poolSize || MAX_CACHED_SANDBOXES); this.prettyPrintErrors = options.prettyPrintErrors != null ? options.prettyPrintErrors : true; + this.prettyLogErrors = options.prettyLogErrors != null ? options.prettyLogErrors : true; + this.autoEscape = options.autoEscape != null ? options.autoEscape : true; + this.cache = options.cache != null ? options.cache : true; + this.additionalErrorHandler = options.additionalErrorHandler || null; this.viewCache = {}; + this.fsErrorCache = {}; + this.filenameCache = {}; + this.fileLockTable = new LockTable(); } engine.prototype._log = function(o) { - var _ref; + var ref1; if (this.verbose) { - if ((_ref = typeof o) === "string" || _ref === "number" || _ref === "boolean") { + if ((ref1 = typeof o) === "string" || ref1 === "number" || ref1 === "boolean") { return console.log("toffee: " + o); } else { return console.log("toffee: " + (util.inspect(o))); @@ -42,90 +60,200 @@ } }; + engine.prototype.normalizeFilename = function(dir, filename) { + var cache, normalized; + cache = this.filenameCache[dir]; + if (cache == null) { + this.filenameCache[dir] = {}; + cache = {}; + } + normalized = cache[filename]; + if (normalized == null) { + normalized = path.normalize(path.resolve(dir, filename)); + this.filenameCache[dir][filename] = normalized; + } + return normalized; + }; + + engine.prototype.render = function(filename, options, cb) { + return this.run(filename, options, cb); + }; + engine.prototype.run = function(filename, options, cb) { + /* - "options" contains the pub vars and may contain special items: - layout: path to a template expecting a body var (express 2.x style, but for use with express 3.x) - __toffee.dir: path to look relative to - __toffee.parent: parent file - __toffee.noInheritance: if true, don't pass variables through unless explicitly passed - __toffee.autoEscape: if set as false, don't escape output of #{} vars by default - */ - - var err, res, _ref, _ref1, _ref2, _ref3; - _ref = this.runSync(filename, options), err = _ref[0], res = _ref[1]; + "options" contains the pub vars and may contain special items: + layout: path to a template expecting a body var (express 2.x style, but for use with express 3.x) + postProcess: a function which takes the string of output and post processes it (returning new string) + __toffee.dir: path to look relative to + __toffee.parent: parent file + __toffee.noInheritance: if true, don't pass variables through unless explicitly passed + __toffee.repress if true, don't output anything; useful with including definition files with passback of vars + __toffee.autoEscape: if set as false, don't escape output of #{} vars by default + */ + var err, k, layout_options, post_process, ref1, ref2, ref3, ref4, ref5, res, v; + if (options.prettyPrintErrors == null) { + options.prettyPrintErrors = this.prettyPrintErrors; + } + if (options.prettyLogErrors == null) { + options.prettyLogErrors = this.prettyLogErrors; + } + if (options.additionalErrorHandler == null) { + options.additionalErrorHandler = this.additionalErrorHandler; + } + if (options.autoEscape == null) { + options.autoEscape = this.autoEscape; + } + post_process = options.postProcess; + options.postProcess = null; + if (options != null ? options.layout : void 0) { + layout_options = {}; + for (k in options) { + v = options[k]; + if (k !== "layout") { + layout_options[k] = v; + } + } + } + ref1 = this.runSync(filename, options), err = ref1[0], res = ref1[1]; if (err && this.prettyPrintErrors) { - _ref1 = [null, err], err = _ref1[0], res = _ref1[1]; + ref2 = [null, err], err = ref2[0], res = ref2[1]; } - if ((!err) && (options != null ? options.layout : void 0)) { - options.body = res; - _ref2 = this.runSync(options.layout, options), err = _ref2[0], res = _ref2[1]; + if ((!err) && (layout_options != null)) { + layout_options.body = res; + ref3 = this.runSync(options.layout, layout_options), err = ref3[0], res = ref3[1]; if (err && this.prettyPrintErrors) { - _ref3 = [null, err], err = _ref3[0], res = _ref3[1]; + ref4 = [null, err], err = ref4[0], res = ref4[1]; } } + if ((!err) && (typeof post_process === "function")) { + ref5 = this.postProcess(post_process, res), err = ref5[0], res = ref5[1]; + } return cb(err, res); }; + engine.prototype.postProcess = function(fn, res) { + var e, err; + err = null; + try { + res = fn(res); + } catch (error) { + e = error; + err = e; + } + return [err, res]; + }; + engine.prototype.runSync = function(filename, options) { - /* - "options" the same as run() above - */ - var err, pwd, realpath, res, start_time, v, _ref, _ref1, - _this = this; + /* + "options" the same as run() above + */ + var ctx, err, realpath, ref1, ref2, ref3, res, start_time, v; start_time = Date.now(); options = options || {}; options.__toffee = options.__toffee || {}; options.__toffee.dir = options.__toffee.dir || process.cwd(); - filename = filename[0] !== "/" ? "" + options.__toffee.dir + "/" + filename : filename; - realpath = path.normalize(filename); - pwd = path.dirname(realpath); - v = this.viewCache[realpath] || this._loadCacheAndMonitor(realpath, options); + realpath = this.normalizeFilename(options.__toffee.dir, filename); + if (this.cache) { + v = (this._viewCacheGet(realpath)) || (this._loadCacheAndMonitor(realpath, options)); + } else { + v = this._loadWithoutCache(realpath, options); + } if (v) { - options.__toffee.parent = realpath; - options.partial = options.partial || function(fname, lvars) { - return _this._fn_partial(fname, lvars, realpath, options); - }; - options.snippet = options.snippet || function(fname, lvars) { - return _this._fn_snippet(fname, lvars, realpath, options); - }; - options.print = options.print || function(txt) { - return _this._fn_print(txt, options); - }; - if (!(options.console != null)) { - options.console = { - log: console.log - }; + if (this.fsErrorCache[realpath]) { + ref1 = [new Error("Couldn't load " + realpath), null], err = ref1[0], res = ref1[1]; + } else { + options.__toffee.parent = realpath; + options.partial = options.partial || (function(_this) { + return function(fname, lvars) { + return _this._fn_partial(fname, lvars, realpath, options); + }; + })(this); + options.snippet = options.snippet || (function(_this) { + return function(fname, lvars) { + return _this._fn_snippet(fname, lvars, realpath, options); + }; + })(this); + options.load = options.load || (function(_this) { + return function(fname, lvars) { + return _this._fn_load(fname, lvars, realpath, options); + }; + })(this); + options.print = options.print || (function(_this) { + return function(txt) { + return _this._fn_print(txt, options); + }; + })(this); + if (options.console == null) { + options.console = { + log: console.log + }; + } + ctx = this.pool.get(); + ref2 = v.run(options, ctx), err = ref2[0], res = ref2[1]; + this.pool.release(ctx); } - _ref = v.run(options), err = _ref[0], res = _ref[1]; } else { - _ref1 = ["Couldn't load " + realpath, null], err = _ref1[0], res = _ref1[1]; + ref3 = [new Error("Couldn't load " + realpath), null], err = ref3[0], res = ref3[1]; } - this._log("" + realpath + " run in " + (Date.now() - start_time) + "ms"); + this._log(realpath + " run in " + (Date.now() - start_time) + "ms"); return [err, res]; }; + engine.prototype._viewCacheGet = function(filename) { + if (this.viewCache[filename] == null) { + return null; + } else if (this.fsErrorCache[filename] == null) { + return this.viewCache[filename]; + } else if ((Date.now() - this.fsErrorCache[filename]) < tweakables.MISSING_FILE_RECHECK) { + return this.viewCache[filename]; + } else { + return null; + } + }; + engine.prototype._inlineInclude = function(filename, local_vars, parent_realpath, parent_options) { - var err, k, options, res, v, _ref; + var err, i, k, len, noInheritance, options, ref1, ref2, ref3, repress, res, reserved, v; options = local_vars || {}; + options.passback = {}; options.__toffee = options.__toffee || {}; options.__toffee.dir = path.dirname(parent_realpath); options.__toffee.parent = parent_realpath; - if (!options.__toffee.noInheritance) { + noInheritance = options.__toffee.noInheritance; + repress = options.__toffee.repress; + reserved = {}; + ref1 = ["passback", "load", "print", "partial", "snippet", "layout", "__toffee", "postProcess"]; + for (i = 0, len = ref1.length; i < len; i++) { + k = ref1[i]; + reserved[k] = true; + } + if (!noInheritance) { for (k in parent_options) { v = parent_options[k]; - if (!((local_vars != null ? local_vars[k] : void 0) != null)) { - if (!(k === "print" || k === "partial" || k === "snippet" || k === "layout" || k === "__toffee")) { + if ((local_vars != null ? local_vars[k] : void 0) == null) { + if (reserved[k] == null) { options[k] = v; } } } } - _ref = this.runSync(filename, options), err = _ref[0], res = _ref[1]; + ref2 = this.runSync(filename, options), err = ref2[0], res = ref2[1]; + ref3 = options.passback; + for (k in ref3) { + v = ref3[k]; + parent_options[k] = v; + } return err || res; }; + engine.prototype._fn_load = function(fname, lvars, realpath, options) { + lvars = lvars != null ? lvars : {}; + lvars.__toffee = lvars.__toffee || {}; + lvars.__toffee.repress = true; + return this._inlineInclude(fname, lvars, realpath, options); + }; + engine.prototype._fn_snippet = function(fname, lvars, realpath, options) { lvars = lvars != null ? lvars : {}; lvars.__toffee = lvars.__toffee || {}; @@ -146,65 +274,137 @@ } }; + engine.prototype._loadWithoutCache = function(filename, options) { + var e, ref1, txt, v, view_options; + try { + txt = fs.readFileSync(filename, 'utf8'); + } catch (error) { + e = error; + txt = "Error: Could not read " + filename; + if (((ref1 = options.__toffee) != null ? ref1.parent : void 0) != null) { + txt += " first requested in " + options.__toffee.parent; + } + } + view_options = this._generateViewOptions(filename); + v = new view(txt, view_options); + return v; + }; + engine.prototype._loadCacheAndMonitor = function(filename, options) { - var txt, v, view_options, _ref; + var e, previous_fs_err, ref1, txt, v, view_options; + previous_fs_err = this.fsErrorCache[filename] != null; try { txt = fs.readFileSync(filename, 'utf8'); - } catch (e) { + if (this.fsErrorCache[filename] != null) { + delete this.fsErrorCache[filename]; + } + } catch (error) { + e = error; txt = "Error: Could not read " + filename; - if (((_ref = options.__toffee) != null ? _ref.parent : void 0) != null) { - txt += " requested in " + options.__toffee.parent; + if (((ref1 = options.__toffee) != null ? ref1.parent : void 0) != null) { + txt += " first requested in " + options.__toffee.parent; } + this.fsErrorCache[filename] = Date.now(); + } + if (this.fsErrorCache[filename] && previous_fs_err && this.viewCache[filename]) { + return this.viewCache[filename]; + } else { + view_options = this._generateViewOptions(filename); + v = new view(txt, view_options); + this.viewCache[filename] = v; + this._monitorForChanges(filename, options); + return v; } - view_options = { + }; + + engine.prototype._reloadFileInBkg = function(filename, options) { + this._log(filename + " acquiring lock to read"); + return this.fileLockTable.acquire2({ + name: filename + }, (function(_this) { + return function(lock) { + return fs.readFile(filename, 'utf8', function(err, txt) { + var ctx, ref1, v, view_options, waiting_for_view; + if (!err) { + _this._log((Date.now()) + " - " + filename + " changed to " + (txt != null ? txt.length : void 0) + " bytes. " + (txt != null ? typeof txt.replace === "function" ? txt.replace(/\n/g, '').slice(0, 80) : void 0 : void 0)); + } + waiting_for_view = false; + if (err || (txt !== _this.viewCache[filename].txt)) { + if (err) { + _this.fsErrorCache[filename] = Date.now(); + txt = "Error: Could not read " + filename; + if (((ref1 = options.__toffee) != null ? ref1.parent : void 0) != null) { + txt += " requested in " + options.__toffee.parent; + } + } + if (!(err && _this.viewCache[filename].fsError)) { + view_options = _this._generateViewOptions(filename); + ctx = _this.pool.get(); + view_options.ctx = ctx; + view_options.cb = function(v) { + _this._log(filename + " updated and ready"); + _this.viewCache[filename] = v; + _this.pool.release(ctx); + _this._log(filename + " lock releasing (view_options.cb)"); + return lock.release(); + }; + waiting_for_view = true; + if (err) { + view_options.fsError = true; + } + v = new view(txt, view_options); + } + } + if (!waiting_for_view) { + _this._log(filename + " lock releasing (not waiting for view)"); + return lock.release(); + } + }); + }; + })(this)); + }; + + engine.prototype._generateViewOptions = function(filename) { + return { fileName: filename, verbose: this.verbose, - prettyPrintErrors: this.prettyPrintErrors + prettyPrintErrors: this.prettyPrintErrors, + prettyLogErrors: this.prettyLogErrors, + autoEscape: this.autoEscape, + additionalErrorHandler: this.additionalErrorHandler }; - v = new view(txt, view_options); - this.viewCache[filename] = v; - this._monitorForChanges(filename, options); - return v; }; engine.prototype._monitorForChanges = function(filename, options) { + /* - we must continuously unwatch/rewatch because some editors/systems invoke a "rename" - event and we'll end up following the wrong, old 'file' as a new one - is dropped in its place. - */ - - var fsw, - _this = this; - fsw = null; - return fsw = fs.watch(filename, { - persistent: true - }, function(change) { - fsw.close(); - _this._log("Got an fs.watch hit on " + filename); - return fs.readFile(filename, 'utf8', function(err, txt) { - var v, view_options, _ref; - _this._monitorForChanges(filename, options); - if (txt !== _this.viewCache[filename].txt) { - if (err) { - txt = "Error: Could not read " + filename + " after fs.watch() hit."; - if (((_ref = options.__toffee) != null ? _ref.parent : void 0) != null) { - txt += " requested in " + options.__toffee.parent; - } - } - view_options = { - fileName: filename, - verbose: _this.verbose, - prettyPrintErrors: _this.prettyPrintErrors, - cb: function(v) { - _this._log("" + filename + " updated and ready"); - return _this.viewCache[filename] = v; - } + we must continuously unwatch/rewatch because some editors/systems invoke a "rename" + event and we'll end up following the wrong, old 'file' as a new one + is dropped in its place. + + Files that are missing are ignored here because they get picked up by new calls to _loadCacheAndMonitor + */ + var e, fsw; + if (this.fsErrorCache[filename] == null) { + fsw = null; + try { + this._log(filename + " starting fs.watch()"); + return fsw = fs.watch(filename, { + persistent: true + }, (function(_this) { + return function(change) { + _this._log(filename + " closing fs.watch()"); + fsw.close(); + _this._monitorForChanges(filename, options); + return _this._reloadFileInBkg(filename, options); }; - return v = new view(txt, view_options); - } - }); - }); + })(this)); + } catch (error) { + e = error; + this._log("fs.watch() failed for " + filename + "; settings fsErrorCache = true"); + return this.fsErrorCache[filename] = Date.now(); + } + } }; return engine; diff --git a/lib/errorHandler.js b/lib/errorHandler.js index 24a7947..a575eba 100644 --- a/lib/errorHandler.js +++ b/lib/errorHandler.js @@ -1,6 +1,8 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.12.7 (function() { - var eh, errorTypes, path, toffeeError, util, _ppEscape; + var _ppEscape, errorTypes, path, toffeeError, util, + extend = 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; }, + hasProp = {}.hasOwnProperty; path = require("path"); @@ -13,7 +15,8 @@ RUNTIME: 3 }; - toffeeError = (function() { + toffeeError = (function(superClass) { + extend(toffeeError, superClass); function toffeeError(view, err_type, e) { this.errType = err_type; @@ -38,6 +41,7 @@ } toffeeError.prototype.getConvertedError = function() { + /* -------------------------------------- returns a JS style error, but with some extras { @@ -48,9 +52,8 @@ ...etc... } ------------------------------------------ - */ - - var line, res, _ref; + */ + var line, ref, ref1, ref2, res; res = { stack: [], message: "", @@ -58,15 +61,20 @@ full_path: this.view.fileName, dir_name: path.dirname(this.view.fileName), file: path.basename(this.view.fileName), - line_range: [0, 0] + line_range: null }; - if (((_ref = this.e) != null ? _ref.message : void 0) != null) { + if (((ref = this.e) != null ? ref.message : void 0) != null) { res.message = this.e.message; } + if (((ref1 = this.e) != null ? (ref2 = ref1.location) != null ? ref2.first_line : void 0 : void 0) != null) { + res.line_range = this._convertJsErrorRangeToToffeeRange(this.e.location); + } switch (this.errType) { case errorTypes.PARSER: - line = this._extractOffensiveLineNo(this.e.message, /on line ([0-9]+)/); - res.line_range = [line, line + 1]; + if (res.line_range == null) { + line = this._extractOffensiveLineNo(this.e.message, /on line ([0-9]+)/); + res.line_range = [line, line + 1]; + } break; case errorTypes.STR_INTERPOLATE: res.line_range = [this.e.relayed_line_range[0], this.e.relayed_line_range[1]]; @@ -74,11 +82,20 @@ res.message = res.message.replace('missing }', 'unclosed `\#{}`'); break; case errorTypes.COFFEE_COMPILE: - line = this._extractOffensiveLineNo(this.e.message, /on line ([0-9]+)/); - res.line_range = this._convertOffensiveLineToToffeeRange(line); - res.message = res.message.replace(/on line [0-9]+/, this._lineRangeToPhrase(res.line_range)); + if (res.line_range == null) { + line = this._extractOffensiveLineNo(this.e.message, /on line ([0-9]+)/); + res.line_range = this._convertOffensiveLineToToffeeRange(line); + } + if (res.message.indexOf('on line') !== -1) { + res.message = res.message.replace(/on line [0-9]+/, this._lineRangeToPhrase(res.line_range)); + } else { + res.message += " " + this._lineRangeToPhrase(res.line_range); + } break; case errorTypes.RUNTIME: + if (res.line_range == null) { + res.line_range = [0, 0]; + } if (this.e.stack) { res.stack = this.e.stack.split("\n"); this._convertRuntimeStackLines(res); @@ -88,18 +105,18 @@ }; toffeeError.prototype._convertRuntimeStackLines = function(converted_err) { - /* - a little more complicated, so extracted. Returns an array - of dictionaries where there's extra info on each line in the stack. - */ - var at_pub_call, hit_pub_yet, i, in_src_file, line, lineno, lrange, m, rxx_inline, rxx_pub, stack, _i, _len, _results; + /* + a little more complicated, so extracted. Returns an array + of dictionaries where there's extra info on each line in the stack. + */ + var at_pub_call, hit_pub_yet, i, in_src_file, k, len, line, lineno, lrange, m, results, rxx_inline, rxx_pub, stack; hit_pub_yet = false; stack = converted_err.stack; - _results = []; - for (i = _i = 0, _len = stack.length; _i < _len; i = ++_i) { + results = []; + for (i = k = 0, len = stack.length; k < len; i = ++k) { line = stack[i]; - rxx_pub = /Object[\.]pub[\s]\(undefined\:([0-9]+)\:[0-9]+/; + rxx_pub = /Object[\.].*?pub[\s]\(undefined\:([0-9]+)\:[0-9]+|tmpl[\.]render[\.]tmpl[\.]pub.*\(.*\:([0-9]+)\:[0-9]+/; m = line.match(rxx_pub); in_src_file = false; lrange = [null, null]; @@ -130,37 +147,33 @@ line_range: lrange }; if (stack[i].line_range[0] && !converted_err.line_range[0]) { - _results.push(converted_err.line_range = stack[i].line_range); + results.push(converted_err.line_range = stack[i].line_range); } else { - _results.push(void 0); + results.push(void 0); } } - return _results; + return results; }; toffeeError.prototype.getPrettyPrintText = function() { - /* - returns a TEXT only blob explaining the error - */ - var cerr, count, header, i, item, res, _i, _len, _ref, _ref1; + /* + returns a TEXT only blob explaining the error + */ + var cerr, count, header, i, item, k, len, ref, ref1, res; cerr = this.getConvertedError(); - if (cerr.type === errorTypes.RUNTIME) { - header = cerr.message; - } else { - header = "" + cerr.dir_name + "/" + cerr.file + ": " + cerr.message; - } + header = cerr.dir_name + "/" + cerr.file + ": " + cerr.message; res = "ERROR\n=====\n" + header; - if ((_ref = cerr.stack) != null ? _ref.length : void 0) { + if ((ref = cerr.stack) != null ? ref.length : void 0) { res += "\n\nSTACK\n=====\n"; count = 0; - _ref1 = cerr.stack; - for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) { - item = _ref1[i]; + ref1 = cerr.stack; + for (i = k = 0, len = ref1.length; k < len; i = ++k) { + item = ref1[i]; if (i === 0) { - res += "" + (count++) + " " + item.line; + res += (count++) + " " + item.line; } else if (item.in_src_file && (item.above_pub_call || item.at_pub_call)) { - res += "" + (count++) + " [" + (this._lineRangeToPhrase(item.line_range)) + "] " + cerr.dir_name + "/" + cerr.file; + res += (count++) + " [" + (this._lineRangeToPhrase(item.line_range)) + "] " + cerr.dir_name + "/" + cerr.file; } else if (item.in_src_file) { continue; } else { @@ -176,68 +189,64 @@ }; toffeeError.prototype.getPrettyPrint = function() { - /* - returns an HTML blob explaining the error - with lines highlighted - */ - var cerr, count, extra, header, i, item, j, line, padding, padding_len, res, _i, _j, _len, _ref, _ref1, _ref2, _ref3, _ref4; + /* + returns an HTML blob explaining the error + with lines highlighted + */ + var cerr, count, extra, header, i, item, j, k, l, len, line, padding, padding_len, ref, ref1, ref2, ref3, ref4, res; cerr = this.getConvertedError(); res = ""; - if (cerr.type === 234432) { - header = cerr.message; - } else { - header = "" + cerr.dir_name + "/" + cerr.file + ": " + cerr.message + ""; - } - res += "
    \n \n
    " + header + "
    \n \n
    \n \n
    "; - if ((_ref = cerr.stack) != null ? _ref.length : void 0) { - res += "
    "; + header = cerr.dir_name + "/" + cerr.file + ": " + (_ppEscape(cerr.message)) + ""; + res += "
    \n \n
    " + header + "
    \n \n
    \n \n
    "; + if ((ref = cerr.stack) != null ? ref.length : void 0) { + res += "
    "; count = 0; - _ref1 = cerr.stack; - for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) { - item = _ref1[i]; + ref1 = cerr.stack; + for (i = k = 0, len = ref1.length; k < len; i = ++k) { + item = ref1[i]; if (i === 0) { - res += "
    " + (count++) + " " + item.line + "
    "; + res += "
    " + (count++) + " " + item.line + "
    "; } else if (item.in_src_file && (item.above_pub_call || item.at_pub_call)) { - res += "
    " + (count++) + " [" + (this._lineRangeToPhrase(item.line_range)) + "] " + cerr.dir_name + "/" + cerr.file + "
    "; + res += "
    " + (count++) + " [" + (this._lineRangeToPhrase(item.line_range)) + "] " + cerr.dir_name + "/" + cerr.file + "
    "; } else if (item.in_src_file) { continue; } else { - res += "
    " + (count++) + item.line + "
    "; + res += "
    " + (count++) + item.line + "
    "; } } res += "
    "; } - for (i = _j = _ref2 = cerr.line_range[0] - 3, _ref3 = cerr.line_range[1] + 1; _ref2 <= _ref3 ? _j < _ref3 : _j > _ref3; i = _ref2 <= _ref3 ? ++_j : --_j) { + for (i = l = ref2 = cerr.line_range[0] - 3, ref3 = cerr.line_range[1] + 1; ref2 <= ref3 ? l < ref3 : l > ref3; i = ref2 <= ref3 ? ++l : --l) { if ((i < 0) || i > this.toffeeSrcLines.length - 1) { continue; } line = _ppEscape(this.toffeeSrcLines[i]); padding_len = 5 - ("" + (i + 1)).length; padding = ((function() { - var _k, _results; - _results = []; - for (j = _k = 0; 0 <= padding_len ? _k < padding_len : _k > padding_len; j = 0 <= padding_len ? ++_k : --_k) { - _results.push(" "); + var n, ref4, results; + results = []; + for (j = n = 0, ref4 = padding_len; 0 <= ref4 ? n < ref4 : n > ref4; j = 0 <= ref4 ? ++n : --n) { + results.push(" "); } - return _results; + return results; })()).join(""); - if ((cerr.line_range[0] <= (_ref4 = i + 1) && _ref4 < cerr.line_range[1])) { + if (((cerr.line_range[0] - 1) <= (ref4 = i) && ref4 < cerr.line_range[1])) { extra = ""; } else { extra = ""; } - res += "" + extra + "\n" + (i + 1) + ": " + padding + " " + line + "
    "; + res += extra + "\n" + (i + 1) + ": " + padding + " " + line + "

    "; } res += " \n
    \n\n
    "; return res; }; toffeeError.prototype._lineRangeToPhrase = function(lrange) { - if (lrange[0] >= lrange[1] - 1) { + if (lrange[0] === lrange[1]) { return "on line " + lrange[0]; } else { - return "between lines " + lrange[0] + " and " + (lrange[1] - 1); + return "between lines " + lrange[0] + " and " + lrange[1]; } }; @@ -250,23 +259,33 @@ return parseInt(m[1]); }; + toffeeError.prototype._convertJsErrorRangeToToffeeRange = function(loc) { + var range, range2; + range = this._convertOffensiveLineToToffeeRange(loc.first_line); + if (loc.last_line != null) { + range2 = this._convertOffensiveLineToToffeeRange(loc.last_line); + range[1] = range2[1]; + } + return range; + }; + toffeeError.prototype._convertOffensiveLineToToffeeRange = function(lineno) { - /* - Given the error line in a converted file, hunts for surrounding - __toffee.lineno calls and returns a pair array with the error position - range in the original toffee file. - */ + /* + Given the error line in a converted file, hunts for surrounding + __toffee.lineno calls and returns a pair array with the error position + range in the original toffee file. + */ var next, next_matches, ol, prev, prev_matches, res, tl; ol = this.offensiveSrcLines; tl = this.toffeeSrcLines; - if ((!(lineno != null)) || isNaN(lineno)) { + if ((lineno == null) || isNaN(lineno)) { return [1, tl.length]; } prev = ol.slice(0, lineno).join("\n"); next = ol.slice(lineno).join("\n"); - prev_matches = prev.match(/_ln[ ]*([0-9]+)/g); - next_matches = next.match(/_ln[ ]*([0-9]+)/g); + prev_matches = prev.match(/_ln[ ]*\(?[ ]*([0-9]+)/g); + next_matches = next.match(/_ln[ ]*\(?[ ]*([0-9]+)/g); res = [1, tl.length]; if (prev_matches != null ? prev_matches.length : void 0) { res[0] = parseInt(prev_matches[prev_matches.length - 1].match(/[0-9]+/)[0]); @@ -279,135 +298,21 @@ return toffeeError; - })(); + })(Error); exports.toffeeError = toffeeError; - eh = exports.errorHandler = { - generateRuntimeError: function(view, e) { - /* - e: the error caught when running - */ - - var after, after_matches, before, msg, new_msg, prev_matches, res, search, src, src_lines, stack, txt_lines; - src = view.javaScript; - msg = e.message; - stack = e.stack; - res = { - src_line: 0, - toffee_line_range: [0, 1], - original_msg: msg, - converted_msg: msg - }; - search = stack.match(/pub\ \(undefined\:([0-9]+):[0-9]+/); - if (!((search != null ? search.length : void 0) >= 2)) { - return res; - } - res.src_line = search[1]; - src_lines = src.split('\n'); - txt_lines = view.txt.split('\n'); - before = src_lines.slice(0, res.src_line).join("\n"); - after = src_lines.slice(res.src_line).join("\n"); - prev_matches = before.match(/__toffee.lineno[ ]*=[ ]*([0-9]+)/g); - after_matches = after.match(/__toffee.lineno[ ]*=[ ]*([0-9]+)/g); - if (prev_matches != null ? prev_matches.length : void 0) { - res.toffee_line_range[0] = parseInt(prev_matches[prev_matches.length - 1].match(/[0-9]+/)[0]); - } else { - res.toffee_line_range[0] = 1; - } - if (after_matches != null ? after_matches.length : void 0) { - res.toffee_line_range[1] = parseInt(after_matches[0].match(/[0-9]+/)[0]); - } else { - res.toffee_line_range[1] = txt_lines.length; - } - res.offensive_lines = txt_lines.slice(res.toffee_line_range[0] - 1, res.toffee_line_range[1] - 1); - if (res.toffee_line_range[0] === res.toffee_line_range[1] - 1) { - new_msg = "on line " + res.toffee_line_range[0]; - } else { - new_msg = "between lines " + res.toffee_line_range[0] + " and " + res.toffee_line_range[1]; - } - res.converted_msg = res.original_msg + " " + new_msg; - if (view.fileName) { - res.converted_msg = "" + view.fileName + ": " + res.converted_msg; - } - return res; - }, - generateCompileToJsError: function(view, e) { - /* - e: the error caught when compiling - */ - - var msg, new_msg, res, search, src; - src = view.coffeeScript; - msg = e.message; - res = { - src_line: 0, - toffee_line_range: [0, 1], - original_msg: msg, - converted_msg: msg - }; - search = msg.match(/on line ([0-9]+)/); - if ((search != null ? search.length : void 0) >= 2) { - res.src_line = search[1]; - res.toffee_line_range = this._convertSrcLineToToffeeRange(view.coffeeScript, res.src_line); - res.offensive_lines = txt_lines.slice(res.toffee_line_range[0] - 1, res.toffee_line_range[1] - 1); - if (res.toffee_line_range[0] === res.toffee_line_range[1] - 1) { - new_msg = "on line " + res.toffee_line_range[0]; - } else { - new_msg = "between lines " + res.toffee_line_range[0] + " and " + res.toffee_line_range[1]; - } - res.converted_msg = res.original_msg.replace("on line " + res.src_line, new_msg); - if (view.fileName) { - res.converted_msg = "" + view.fileName + ": " + res.converted_msg; - } - } - return res; - }, - prettyPrintError: function(view) { - var i, line, lineno, padding, padding_len, res, txt_lines, _i, _ref, _ref1; - if (!view.error) { - return ""; - } else { - res = "
    "; - res += "" + (eh._ppEscape(view.error.converted_msg)) + ""; - res += "\n
    --------
    "; - res += "\n
    "; - txt_lines = view.txt.split('\n'); - for (i = _i = _ref = view.error.toffee_line_range[0] - 3, _ref1 = view.error.toffee_line_range[1] + 1; _ref <= _ref1 ? _i < _ref1 : _i > _ref1; i = _ref <= _ref1 ? ++_i : --_i) { - if ((i < 0) || i > txt_lines.length - 1) { - continue; - } - line = eh._ppEscape(txt_lines[i]); - lineno = i + 1; - padding_len = 5 - ("" + lineno).length; - padding = ((function() { - var _j, _results; - _results = []; - for (i = _j = 0; 0 <= padding_len ? _j < padding_len : _j > padding_len; i = 0 <= padding_len ? ++_j : --_j) { - _results.push(" "); - } - return _results; - })()).join(""); - res += "\n" + lineno + ": " + padding + " " + line + "
    "; - } - res += "\n
    "; - res += "\n
    "; - return res; - } - } - }; - _ppEscape = function(txt) { var i, m; txt = txt.replace(/&/g, '&').replace(/ _ref; i = 0 <= _ref ? ++_i : --_i) { - _results.push(" "); + var k, ref, results; + results = []; + for (i = k = 0, ref = m[0].length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { + results.push(" "); } - return _results; + return results; })()).join("")); return txt; }; diff --git a/lib/pool.js b/lib/pool.js new file mode 100644 index 0000000..d61bdf7 --- /dev/null +++ b/lib/pool.js @@ -0,0 +1,32 @@ +// Generated by CoffeeScript 1.12.7 +(function() { + var Pool; + + Pool = (function() { + function Pool(cons, size) { + this._consfn = cons; + this._size = size; + this._pool = []; + } + + Pool.prototype.get = function() { + if (this._pool.length > 0) { + return this._pool.pop(); + } else { + return this._consfn(); + } + }; + + Pool.prototype.release = function(x) { + if (this._pool.length < this._size) { + return this._pool.push(x); + } + }; + + return Pool; + + })(); + + exports.Pool = Pool; + +}).call(this); diff --git a/lib/toffee_lang.js b/lib/toffee_lang.js index cc2c8f8..b3f17e5 100644 --- a/lib/toffee_lang.js +++ b/lib/toffee_lang.js @@ -1,422 +1,655 @@ -/* Jison generated parser */ +/* parser generated by jison 0.4.18 */ +/* + Returns a Parser object of the following structure: + + Parser: { + yy: {} + } + + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, + } + } + + + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } + + + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ var toffee_lang = (function(){ -var parser = {trace: function trace() { }, +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[2,7],$V1=[1,8],$V2=[1,7],$V3=[1,9],$V4=[5,15],$V5=[1,15],$V6=[2,19],$V7=[1,20],$V8=[11,12,13,14,15,16],$V9=[5,9,12,13,14,15,16],$Va=[5,9,12,15,16]; +var parser = {trace: function trace () { }, yy: {}, -symbols_: {"error":2,"starter":3,"toffee_zone":4,"EOF":5,"toffee_code":6,"flip_to_coffee":7,"flip_to_toffeecomment":8,"START_TOFFEE_COMMENT":9,"code":10,"END_TOFFEE_COMMENT":11,"START_COFFEE":12,"coffee_zone":13,"END_COFFEE":14,"coffee_code":15,"flip_to_toffee":16,"START_TOFFEE":17,"END_TOFFEE":18,"START_INDENTED_TOFFEE":19,"CODE":20,"$accept":0,"$end":1}, -terminals_: {2:"error",5:"EOF",9:"START_TOFFEE_COMMENT",11:"END_TOFFEE_COMMENT",12:"START_COFFEE",14:"END_COFFEE",17:"START_TOFFEE",18:"END_TOFFEE",19:"START_INDENTED_TOFFEE",20:"CODE"}, -productions_: [0,[3,2],[4,1],[4,3],[4,2],[4,3],[4,2],[4,0],[8,3],[7,3],[13,1],[13,3],[13,2],[13,0],[16,3],[16,3],[6,1],[15,1],[10,1],[10,2]], -performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { +symbols_: {"error":2,"starter":3,"toffee_zone":4,"EOF":5,"toffee_code":6,"flip_to_coffee":7,"flip_to_toffee_comment":8,"START_TOFFEE_COMMENT":9,"toffee_commented_region":10,"END_TOFFEE_COMMENT":11,"START_COFFEE":12,"END_COFFEE":13,"START_TOFFEE":14,"END_TOFFEE":15,"CODE":16,"coffee_zone":17,"coffee_code":18,"flip_to_toffee":19,"code":20,"$accept":0,"$end":1}, +terminals_: {2:"error",5:"EOF",9:"START_TOFFEE_COMMENT",11:"END_TOFFEE_COMMENT",12:"START_COFFEE",13:"END_COFFEE",14:"START_TOFFEE",15:"END_TOFFEE",16:"CODE"}, +productions_: [0,[3,2],[4,1],[4,3],[4,2],[4,3],[4,2],[4,0],[8,3],[10,2],[10,2],[10,2],[10,2],[10,2],[10,0],[7,3],[17,1],[17,3],[17,2],[17,0],[19,3],[6,1],[18,1],[20,1],[20,2]], +performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { +/* this == yyval */ var $0 = $$.length - 1; switch (yystate) { -case 1: this.$ = ["TOFFEE_ZONE", $$[$0-1]]; return this.$; -break; -case 2: this.$ = [$$[$0]]; -break; -case 3: this.$ = $$[$0]; $$[$0].splice(0,0,$$[$0-2],$$[$0-1]); -break; -case 4: this.$ = $$[$0]; $$[$0].splice(0,0,$$[$0-1]); +case 1: + this.$ = ["TOFFEE_ZONE", $$[$0-1]]; return this.$; break; -case 5: this.$ = $$[$0]; $$[$0].splice(0,0,$$[$0-2]); +case 2: case 16: + this.$ = [$$[$0]]; break; -case 6: this.$ = $$[$0]; +case 3: case 17: + this.$ = $$[$0]; $$[$0].splice(0,0,$$[$0-2],$$[$0-1]); break; -case 7: this.$ = []; +case 4: case 18: + this.$ = $$[$0]; $$[$0].splice(0,0,$$[$0-1]); break; -case 9: this.$ = ["COFFEE_ZONE", $$[$0-1]]; +case 5: + this.$ = $$[$0]; $$[$0].splice(0,0,$$[$0-2]); break; -case 10: this.$ = [$$[$0]]; +case 6: + this.$ = $$[$0]; break; -case 11: this.$ = $$[$0]; $$[$0].splice(0,0,$$[$0-2],$$[$0-1]); +case 7: case 19: + this.$ = []; break; -case 12: this.$ = $$[$0]; $$[$0].splice(0,0,$$[$0-1]); +case 15: + this.$ = ["COFFEE_ZONE", $$[$0-1]]; break; -case 13: this.$ = []; +case 20: + this.$ = ["TOFFEE_ZONE", $$[$0-1]]; break; -case 14: this.$ = ["TOFFEE_ZONE", $$[$0-1]]; +case 21: + this.$ = ["TOFFEE", $$[$0][0], $$[$0][1] ]; break; -case 15: this.$ = ["INDENTED_TOFFEE_ZONE", $$[$0-1]]; +case 22: + this.$ = ["COFFEE", $$[$0][0], $$[$0][1] ]; break; -case 16: this.$ = ["TOFFEE", $$[$0][0], $$[$0][1] ]; -break; -case 17: this.$ = ["COFFEE", $$[$0][0], $$[$0][1] ]; -break; -case 18: var ln = yylineno + 1 - $$[$0].split("\n").length + 1; +case 23: + var ln = yylineno + 1 - $$[$0].split("\n").length + 1; this.$ = [$$[$0], ln]; break; -case 19: var c = $$[$0-1][0] + $$[$0]; +case 24: + var c = $$[$0-1][0] + $$[$0]; var ln = yylineno + 1 - c.split("\n").length + 1; this.$ = [c, ln]; break; } }, -table: [{3:1,4:2,5:[2,7],6:3,7:4,8:5,9:[1,8],10:6,12:[1,7],20:[1,9]},{1:[3]},{5:[1,10]},{5:[2,2],7:11,8:12,9:[1,8],12:[1,7],18:[2,2]},{4:13,5:[2,7],6:3,7:4,8:5,9:[1,8],10:6,12:[1,7],18:[2,7],20:[1,9]},{4:14,5:[2,7],6:3,7:4,8:5,9:[1,8],10:6,12:[1,7],18:[2,7],20:[1,9]},{5:[2,16],9:[2,16],12:[2,16],18:[2,16],20:[1,15]},{10:19,13:16,14:[2,13],15:17,16:18,17:[1,20],19:[1,21],20:[1,9]},{10:22,20:[1,9]},{5:[2,18],9:[2,18],11:[2,18],12:[2,18],14:[2,18],17:[2,18],18:[2,18],19:[2,18],20:[2,18]},{1:[2,1]},{4:23,5:[2,7],6:3,7:4,8:5,9:[1,8],10:6,12:[1,7],18:[2,7],20:[1,9]},{4:24,5:[2,7],6:3,7:4,8:5,9:[1,8],10:6,12:[1,7],18:[2,7],20:[1,9]},{5:[2,4],18:[2,4]},{5:[2,6],18:[2,6]},{5:[2,19],9:[2,19],11:[2,19],12:[2,19],14:[2,19],17:[2,19],18:[2,19],19:[2,19],20:[2,19]},{14:[1,25]},{14:[2,10],16:26,17:[1,20],19:[1,21]},{10:19,13:27,14:[2,13],15:17,16:18,17:[1,20],19:[1,21],20:[1,9]},{14:[2,17],17:[2,17],19:[2,17],20:[1,15]},{4:28,6:3,7:4,8:5,9:[1,8],10:6,12:[1,7],18:[2,7],20:[1,9]},{4:29,6:3,7:4,8:5,9:[1,8],10:6,12:[1,7],18:[2,7],20:[1,9]},{11:[1,30],20:[1,15]},{5:[2,3],18:[2,3]},{5:[2,5],18:[2,5]},{5:[2,9],9:[2,9],12:[2,9],18:[2,9],20:[2,9]},{10:19,13:31,14:[2,13],15:17,16:18,17:[1,20],19:[1,21],20:[1,9]},{14:[2,12]},{18:[1,32]},{18:[1,33]},{5:[2,8],9:[2,8],12:[2,8],18:[2,8],20:[2,8]},{14:[2,11]},{14:[2,14],17:[2,14],19:[2,14],20:[2,14]},{14:[2,15],17:[2,15],19:[2,15],20:[2,15]}], -defaultActions: {10:[2,1],27:[2,12],31:[2,11]}, -parseError: function parseError(str, hash) { - throw new Error(str); +table: [{3:1,4:2,5:$V0,6:3,7:4,8:5,9:$V1,12:$V2,16:$V3,20:6},{1:[3]},{5:[1,10]},o($V4,[2,2],{7:11,8:12,9:$V1,12:$V2}),o($V4,$V0,{6:3,7:4,8:5,20:6,4:13,9:$V1,12:$V2,16:$V3}),o($V4,$V0,{6:3,7:4,8:5,20:6,4:14,9:$V1,12:$V2,16:$V3}),o([5,9,12,15],[2,21],{16:$V5}),{13:$V6,14:$V7,16:$V3,17:16,18:17,19:18,20:19},o($V8,[2,14],{10:21}),o($V9,[2,23]),{1:[2,1]},o($V4,$V0,{6:3,7:4,8:5,20:6,4:22,9:$V1,12:$V2,16:$V3}),o($V4,$V0,{6:3,7:4,8:5,20:6,4:23,9:$V1,12:$V2,16:$V3}),o($V4,[2,4]),o($V4,[2,6]),o($V9,[2,24]),{13:[1,24]},{13:[2,16],14:$V7,19:25},{13:$V6,14:$V7,16:$V3,17:26,18:17,19:18,20:19},o([13,14],[2,22],{16:$V5}),{4:27,6:3,7:4,8:5,9:$V1,12:$V2,15:$V0,16:$V3,20:6},{11:[1,28],12:[1,29],13:[1,30],14:[1,31],15:[1,32],16:[1,33]},o($V4,[2,3]),o($V4,[2,5]),o($Va,[2,15]),{13:$V6,14:$V7,16:$V3,17:34,18:17,19:18,20:19},{13:[2,18]},{15:[1,35]},o($Va,[2,8]),o($V8,[2,9]),o($V8,[2,10]),o($V8,[2,11]),o($V8,[2,12]),o($V8,[2,13]),{13:[2,17]},o([13,14,16],[2,20])], +defaultActions: {10:[2,1],26:[2,18],34:[2,17]}, +parseError: function parseError (str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } }, 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; + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer; + sharedState.yy.parser = this; + if (typeof lexer.yylloc == 'undefined') { + lexer.yylloc = {}; + } + var yyloc = 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; + var ranges = lexer.options && lexer.options.ranges; + if (typeof sharedState.yy.parseError === 'function') { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).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; + _token_stack: + var lex = function () { + var token; + token = lexer.lex() || EOF; + 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 + state = stack[stack.length - 1]; if (this.defaultActions[state]) { action = this.defaultActions[state]; } else { - if (symbol == null) + if (symbol === null || typeof symbol == 'undefined') { symbol = lex(); - // read action for current state and first input + } action = table[state] && table[state][symbol]; } - - // handle parse error - _handle_error: - if (typeof action === 'undefined' || !action.length || !action[0]) { - - if (!recovering) { - // Report error + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; expected = []; - for (p in table[state]) if (this.terminals_[p] && p > 2) { - expected.push("'"+this.terminals_[p]+"'"); + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + 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(', ') + ", got '" + this.terminals_[symbol]+ "'"; + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; } 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.'); + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); } - popStack(1); - state = stack[stack.length-1]; + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); } - - 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); + 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); + case 1: + stack.push(symbol); + vstack.push(lexer.yytext); + lstack.push(lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = lexer.yyleng; + yytext = lexer.yytext; + yylineno = lexer.yylineno; + yyloc = lexer.yylloc; + if (recovering > 0) { + recovering--; } - - 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; + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + 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 + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== 'undefined') { + return r; + } + 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]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; } - } - return true; }}; -/* Jison generated lexer */ +/* generated by jison-lex 0.3.4 */ var lexer = (function(){ -var lexer = ({EOF:1, +var lexer = ({ + +EOF:1, + parseError:function parseError(str, hash) { - if (this.yy.parseError) { - this.yy.parseError(str, hash); + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); } else { throw new Error(str); } }, -setInput:function (input) { + +// resets the lexer, sets new input +setInput:function (input, yy) { + this.yy = yy || this.yy || {}; this._input = input; - this._more = this._less = this.done = false; + this._more = this._backtrack = 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}; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0,0]; + } + this.offset = 0; return this; }, + +// consumes and returns one char from the input input:function () { var ch = this._input[0]; - this.yytext+=ch; + this.yytext += ch; this.yyleng++; - this.match+=ch; - this.matched+=ch; - var lines = ch.match(/\n/); - if (lines) this.yylineno++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); return ch; }, + +// unshifts one char (or a string) into the input unput:function (ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? + (lines.length === oldLines.length ? this.yylloc.first_column : 0) + + oldLines[oldLines.length - lines.length].length - lines[0].length : + this.yylloc.first_column - len + }; + + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; return this; }, + +// When called from action, caches matched text and appends it on next action more:function () { this._more = true; return this; }, + +// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. +reject:function () { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + + } + return this; + }, + +// retain first n characters of the match less:function (n) { - this._input = this.match.slice(n) + this._input; + this.unput(this.match.slice(n)); }, + +// displays already matched input, i.e. for error messages pastInput:function () { var past = this.matched.substr(0, this.matched.length - this.match.length); return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); }, + +// displays upcoming input, i.e. for error messages 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, ""); + return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); }, + +// displays the character position where the lexing error occurred, i.e. for error messages showPosition:function () { var pre = this.pastInput(); var c = new Array(pre.length + 1).join("-"); - return pre + this.upcomingInput() + "\n" + c+"^"; + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + +// test the lexed token: return FALSE when not a match, otherwise return token +test_match:function(match, indexed_rule) { + var token, + lines, + backup; + + if (this.options.backtrack_lexer) { + // save context + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + + lines = match[0].match(/(?:\r\n?|\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 - lines[lines.length - 1].match(/\r?\n?/)[0].length : + this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + // recover context + for (var k in backup) { + this[k] = backup[k]; + } + return false; // rule action called reject() implying the next rule should be tested instead. + } + return false; }, + +// return next match in input next:function () { if (this.done) { return this.EOF; } - if (!this._input) this.done = true; + if (!this._input) { + this.done = true; + } var token, match, tempMatch, - index, - col, - lines; + index; if (!this._more) { this.yytext = ''; this.match = ''; } var rules = this._currentRules(); - for (var i=0;i < rules.length; i++) { + for (var i = 0; i < rules.length; i++) { tempMatch = this._input.match(this.rules[rules[i]]); if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { match = tempMatch; index = i; - if (!this.options.flex) break; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; // rule action called reject() implying a rule MISmatch. + } else { + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + } else if (!this.options.flex) { + break; + } } } 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.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[index],this.conditionStack[this.conditionStack.length-1]); - if (this.done && this._input) this.done = false; - if (token) return token; - else return; + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; } 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}); + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); } }, -lex:function lex() { + +// return next match that has a token +lex:function lex () { var r = this.next(); - if (typeof r !== 'undefined') { + if (r) { return r; } else { return this.lex(); } }, -begin:function begin(condition) { + +// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) +begin:function begin (condition) { this.conditionStack.push(condition); }, -popState:function popState() { - return this.conditionStack.pop(); + +// pop the previously active lexer condition state off the condition stack +popState:function popState () { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } }, -_currentRules:function _currentRules() { - return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules; + +// produce the lexer rule set which is active for the currently active lexer condition state +_currentRules:function _currentRules () { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } }, -topState:function () { - return this.conditionStack[this.conditionStack.length-2]; + +// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available +topState:function topState (n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } }, -pushState:function begin(condition) { + +// alias for begin(condition) +pushState:function pushState (condition) { this.begin(condition); - }}); -lexer.options = {}; -lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { + }, -var YYSTATE=YY_START +// return the number of states currently on the stack +stateStackSize:function stateStackSize() { + return this.conditionStack.length; + }, +options: {}, +performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { +var YYSTATE=YY_START; switch($avoiding_name_collisions) { case 0:return 9; break; case 1:return 11; break; -case 2:return 18; +case 2:return 15; break; -case 3:return 19; +case 3:return 14; break; case 4:return 12; break; -case 5:return 14; +case 5:return 13; break; -case 6:return 17; +case 6:return 16; break; -case 7:return 20; -break; -case 8:return 5; +case 7:return 5; break; } -}; -lexer.rules = [/^\{##/,/^##\}/,/^:\}/,/^\{:/,/^\{#/,/^#\}/,/^[\-][\t\r\n ]*\{:/,/^[^{}#\\:\-]+|[\\{}#:\-]/,/^$/]; -lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8],"inclusive":true}}; -return lexer;})() +}, +rules: [/^(?:\{##)/,/^(?:##\})/,/^(?::\})/,/^(?:\{:)/,/^(?:\{#)/,/^(?:#\})/,/^(?:[^{}#\\:\-]+|[\\{}#:\-])/,/^(?:$)/], +conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7],"inclusive":true}} +}); +return lexer; +})(); parser.lexer = lexer; -return parser; +function Parser () { + this.yy = {}; +} +Parser.prototype = parser;parser.Parser = Parser; +return new Parser; })(); + + if (typeof require !== 'undefined' && typeof exports !== 'undefined') { exports.parser = toffee_lang; -exports.parse = function () { return toffee_lang.parse.apply(toffee_lang, 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"}); +exports.Parser = toffee_lang.Parser; +exports.parse = function () { return toffee_lang.parse.apply(toffee_lang, arguments); }; +exports.main = function commonjsMain (args) { + if (!args[1]) { + console.log('Usage: '+args[0]+' FILE'); + process.exit(1); } + var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8"); return exports.parser.parse(source); -} +}; if (typeof module !== 'undefined' && require.main === module) { - exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args); + exports.main(process.argv.slice(1)); } } \ No newline at end of file diff --git a/lib/utils.js b/lib/utils.js index 28733ef..7417318 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.12.7 (function() { var lex, lexer; @@ -7,13 +7,13 @@ lex = new lexer.Lexer(); exports.interpolateString = function(str) { - /* - Similar to the interpolateString function in CoffeeScript, - except that it doesn't actually work on anything inside an outer #{}; - we're just looking to recognize them. - */ - var expr, i, inner, interpolated, letter, pi, res, tag, tokens, value, _i, _len, _ref; + /* + Similar to the interpolateString function in CoffeeScript, + except that it doesn't actually work on anything inside an outer #{}; + we're just looking to recognize them. + */ + var expr, i, inner, interpolated, j, len, letter, pi, ref, res, tag, tokens, value; tokens = []; res = []; pi = 0; @@ -48,8 +48,8 @@ if (interpolated = tokens.length > 1) { res.push('(', '('); } - for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) { - _ref = tokens[i], tag = _ref[0], value = _ref[1]; + for (i = j = 0, len = tokens.length; j < len; i = ++j) { + ref = tokens[i], tag = ref[0], value = ref[1]; if (i) { res.push('+', '+'); } diff --git a/lib/view.js b/lib/view.js index 16c606a..db150aa 100644 --- a/lib/view.js +++ b/lib/view.js @@ -1,103 +1,133 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.12.7 (function() { - var TAB_SPACES, coffee, errorHandler, errorTypes, getBundleHeaders, getCommonHeaders, getCommonHeadersJs, minimizeJs, parser, states, toffeeError, utils, view, vm, _ref, _ref1; + var TAB_SPACES, coffee, e, errorHandler, errorTypes, getBundleHeaders, getCommonHeaders, getCommonHeadersJs, parser, ref, ref1, spaces, states, tabs, toffeeError, util, utils, view, vm; parser = require('./toffee_lang').parser; - _ref = require('./errorHandler'), errorHandler = _ref.errorHandler, toffeeError = _ref.toffeeError, errorTypes = _ref.errorTypes; + ref = require('./errorHandler'), errorHandler = ref.errorHandler, toffeeError = ref.toffeeError, errorTypes = ref.errorTypes; - _ref1 = require('./consts'), states = _ref1.states, TAB_SPACES = _ref1.TAB_SPACES; + ref1 = require('./consts'), states = ref1.states, TAB_SPACES = ref1.TAB_SPACES; utils = require('./utils'); vm = require('vm'); + util = require('util'); + try { coffee = require("iced-coffee-script"); - } catch (e) { + } catch (error) { + e = error; coffee = require("coffee-script"); } - minimizeJs = function(js) { - return js; + spaces = function(n) { + var i; + return ((function() { + var j, ref2, results; + results = []; + for (i = j = 0, ref2 = n; 0 <= ref2 ? j < ref2 : j > ref2; i = 0 <= ref2 ? ++j : --j) { + results.push(" "); + } + return results; + })()).join(""); + }; + + tabs = function(n) { + var i; + return ((function() { + var j, ref2, results; + results = []; + for (i = j = 0, ref2 = n; 0 <= ref2 ? j < ref2 : j > ref2; i = 0 <= ref2 ? ++j : --j) { + results.push(spaces(TAB_SPACES)); + } + return results; + })()).join(""); }; - getCommonHeaders = function(include_bundle_headers) { + getCommonHeaders = function(tab_level, include_bundle_headers, auto_escape) { + /* - each view will use this, or if they're bundled together, - it'll only be used once. + each view will use this, or if they're bundled together, + it'll only be used once. - include_bundle_headers: includes some functions needed for browser use - */ - return "if not toffee? then toffee = {}\nif not toffee.templates then toffee.templates = {}\n\ntoffee.states = " + (JSON.stringify(states)) + "\n\ntoffee.__json = (locals, o) ->\n try\n json = JSON.stringify(o).replace(//g,'\\\\u003E').replace(/&/g,'\\\\u0026')\n catch e\n throw {stack:[], message: \"JSONify error (\#{e.message}) on line \#{locals.__toffee.lineno}\", toffee_line_base: locals.__toffee.lineno }\n \"\" + json\n\ntoffee.__raw = (locals, o) -> o\n\ntoffee.__html = (locals, o) ->\n (\"\"+o).replace(/&/g, '&').replace(//g, '>').replace(/\"/g, '"')\n\ntoffee.__escape = (locals, o) ->\n if (not locals.__toffee.autoEscape?) or locals.__toffee.autoEscape\n if o is undefined then return ''\n if o? and (typeof o) is \"object\" then return locals.json o\n return locals.html o\n return o\n\n" + (include_bundle_headers ? getBundleHeaders() : ""); + include_bundle_headers: includes some functions needed for browser use + */ + var __; + __ = tabs(tab_level); + return "\n\n" + __ + "if not toffee? then toffee = {}\n" + __ + "if not toffee.templates then toffee.templates = {}\n\n" + __ + "toffee.states = " + (JSON.stringify(states)) + "\n\n" + __ + "toffee.__json = (locals, o, opts) ->\n" + __ + " opts or= {}\n" + __ + " opts.indent or= \"\"\n" + __ + " if not o?\n" + __ + " return \"null\"\n" + __ + " else\n" + __ + " return \"\" + JSON.stringify(o,null,opts.indent)\n" + __ + " .replace(//g,'\\\\u003E')\n" + __ + " .replace(/&/g,'\\\\u0026').replace(/\\u2028/g, '\\\\u2028')\n" + __ + " .replace(/\\u2029/g, '\\\\u2029')\n" + __ + " .replace(/\\u200e/g, '\\\\u200e') # LEFT-TO-RIGHT MARK\n" + __ + " .replace(/\\u200f/g, '\\\\u200f') # RIGHT-TO-LEFT MARK\n" + __ + " .replace(/\\u202a/g, '\\\\u202a') # LEFT-TO-RIGHT EMBEDDING\n" + __ + " .replace(/\\u202b/g, '\\\\u202b') # RIGHT-TO-LEFT EMBEDDING\n" + __ + " .replace(/\\u202c/g, '\\\\u202c') # POP DIRECTIONAL FORMATTING\n" + __ + " .replace(/\\u202d/g, '\\\\u202d') # LEFT-TO-RIGHT OVERRIDE\n" + __ + " .replace(/\\u202e/g, '\\\\u202e') # RIGHT-TO-LEFT OVERRIDE\n" + __ + " .replace(/\\u206a/g, '\\\\u206a') # INHIBIT SYMMETRIC SWAPPING\n" + __ + " .replace(/\\u206b/g, '\\\\u206b') # ACTIVATE SYMMETRIC SWAPPING\n" + __ + " .replace(/\\u206c/g, '\\\\u206c') # INHIBIT ARABIC FORM SHAPING\n" + __ + " .replace(/\\u206d/g, '\\\\u206d') # ACTIVATE ARABIC FORM SHAPING\n" + __ + " .replace(/\\u206e/g, '\\\\u206e') # NATIONAL DIGIT SHAPES\n" + __ + " .replace(/\\u206f/g, '\\\\u206f') # NOMINAL DIGIT SHAPES\n" + __ + " .replace(/\\u2066/g, '\\\\u2066') # LEFT-TO-RIGHT ISOLATE (LRI)\n" + __ + " .replace(/\\u2067/g, '\\\\u2067') # RIGHT-TO-LEFT ISOLATE (RLI)\n" + __ + " .replace(/\\u2068/g, '\\\\u2068') # FIRST STRONG ISOLATE (FSI)\n" + __ + " .replace(/\\u2069/g, '\\\\u2069') # POP DIRECTIONAL ISOLATE (PDI)\n\n\n" + __ + "toffee.__raw = (locals, o) -> o\n\n" + __ + "toffee.__html = (locals, o) ->\n" + __ + " (\"\"+o).replace(/&/g, '&')\n" + __ + " .replace(//g, '>')\n" + __ + " .replace(/\"/g, '"')\n" + __ + " .replace(/\\u200e/g, '') # LEFT-TO-RIGHT MARK\n" + __ + " .replace(/\\u200f/g, '') # RIGHT-TO-LEFT MARK\n" + __ + " .replace(/\\u202a/g, '') # LEFT-TO-RIGHT EMBEDDING\n" + __ + " .replace(/\\u202b/g, '') # RIGHT-TO-LEFT EMBEDDING\n" + __ + " .replace(/\\u202c/g, '') # POP DIRECTIONAL FORMATTING\n" + __ + " .replace(/\\u202d/g, '') # LEFT-TO-RIGHT OVERRIDE\n" + __ + " .replace(/\\u202e/g, '') # RIGHT-TO-LEFT OVERRIDE\n" + __ + " .replace(/\\u206a/g, '') # INHIBIT SYMMETRIC SWAPPING\n" + __ + " .replace(/\\u206b/g, '') # ACTIVATE SYMMETRIC SWAPPING\n" + __ + " .replace(/\\u206c/g, '') # INHIBIT ARABIC FORM SHAPING\n" + __ + " .replace(/\\u206d/g, '') # ACTIVATE ARABIC FORM SHAPING\n" + __ + " .replace(/\\u206e/g, '') # NATIONAL DIGIT SHAPES\n" + __ + " .replace(/\\u206f/g, '') # NOMINAL DIGIT SHAPES\n" + __ + " .replace(/\\u2066/g, '') # LEFT-TO-RIGHT ISOLATE (LRI)\n" + __ + " .replace(/\\u2067/g, '') # RIGHT-TO-LEFT ISOLATE (RLI)\n" + __ + " .replace(/\\u2068/g, '') # FIRST STRONG ISOLATE (FSI)\n" + __ + " .replace(/\\u2069/g, '') # POP DIRECTIONAL ISOLATE (PDI)\n\n\n" + __ + "toffee.__escape = (locals, o) ->\n" + __ + " if locals.__toffee.autoEscape? then ae = locals.__toffee.autoEscape\n" + __ + " else if " + (auto_escape != null) + " then ae = " + auto_escape + "\n" + __ + " else ae = true\n" + __ + " if ae\n" + __ + " if o is undefined then return ''\n" + __ + " if o? and (typeof o) is \"object\" then return locals.json o\n" + __ + " return locals.html o\n" + __ + " return o\n\n" + __ + "toffee.__augmentLocals = (locals, bundle_path) ->\n" + __ + " _l = locals\n" + __ + " _t = _l.__toffee = {out: []}\n" + __ + " if not _l.print? then _l.print = (o) -> toffee.__print _l, o\n" + __ + " if not _l.json? then _l.json = (o, opts) -> toffee.__json _l, o, opts\n" + __ + " if not _l.raw? then _l.raw = (o) -> toffee.__raw _l, o\n" + __ + " if not _l.html? then _l.html = (o) -> toffee.__html _l, o\n" + __ + " if not _l.escape? then _l.escape = (o) -> toffee.__escape _l, o\n" + __ + " if not _l.partial? then _l.partial = (path, vars) -> toffee.__partial toffee.templates[\"\#{bundle_path}\"], _l, path, vars\n" + __ + " if not _l.snippet? then _l.snippet = (path, vars) -> toffee.__snippet toffee.templates[\"\#{bundle_path}\"], _l, path, vars\n" + __ + " if not _l.load? then _l.load = (path, vars) -> toffee.__load toffee.templates[\"\#{bundle_path}\"], _l, path, vars\n" + __ + " _t.print = _l.print\n" + __ + " _t.json = _l.json\n" + __ + " _t.raw = _l.raw\n" + __ + " _t.html = _l.html\n" + __ + " _t.escape = _l.escape\n" + __ + " _t.partial = _l.partial\n" + __ + " _t.snippet = _l.snippet\n" + __ + " _t.load = _l.load\n\n" + (include_bundle_headers ? getBundleHeaders(tab_level) : ""); }; - getBundleHeaders = function() { + getBundleHeaders = function(tab_level) { + /* - header stuff - only needed when compiling to a JS file - */ - return "\ntoffee.__print = (locals, o) ->\n if locals.__toffee.state is toffee.states.COFFEE\n locals.__toffee.out.push o\n return ''\n else\n return \"\#{o}\"\n\ntoffee.__normalize = (path) ->\n if (not path?) or path is \"/\"\n return path\n else \n parts = path.split \"/\"\n np = []\n # make sure path always starts with '/'\n if parts[0]\n np.push ''\n for part in parts\n if part is \"..\"\n if np.length > 1\n np.pop()\n else\n np.push part\n else\n if part isnt \".\"\n np.push part\n path = np.join \"/\"\n if not path then path = \"/\"\n return path\n\ntoffee.__partial = (parent_tmpl, parent_locals, path, vars) ->\n path = toffee.__normalize parent_tmpl.bundlePath + \"/../\" + path\n return toffee.__inlineInclude path, vars, parent_locals\n\ntoffee.__snippet = (parent_tmpl, parent_locals, path, vars) ->\n path = toffee.__normalize parent_tmpl.bundlePath + \"/../\" + path\n vars = if vars? then vars else {}\n vars.__toffee = vars.__toffee or {}\n vars.__toffee.noInheritance = true\n return toffee.__inlineInclude path, vars, parent_locals\n\ntoffee.__inlineInclude = (path, locals, parent_locals) ->\n options = locals or {}\n options.__toffee = options.__toffee or {}\n\n # we need to make a shallow copy of parent variables\n if not options.__toffee.noInheritance\n for k,v of parent_locals when not locals?[k]?\n if not (k in [\"print\", \"partial\", \"snippet\", \"layout\", \"__toffee\"])\n options[k] = v\n\n if not toffee.templates[path]\n return \"Inline toffee include: Could not find \#{path}\"\n else\n return toffee.templates[path].pub options\n"; + header stuff + only needed when compiling to a JS file + */ + var __; + __ = tabs(tab_level); + return "\n\n" + __ + "toffee.__print = (locals, o) ->\n" + __ + " if locals.__toffee.state is toffee.states.COFFEE\n" + __ + " locals.__toffee.out.push o\n" + __ + " return ''\n" + __ + " else\n" + __ + " return \"\#{o}\"\n\n" + __ + "toffee.__normalize = (path) ->\n" + __ + " if (not path?) or path is \"/\"\n" + __ + " return path\n" + __ + " else\n" + __ + " parts = path.split \"/\"\n" + __ + " np = []\n" + __ + " # make sure path always starts with '/'\n" + __ + " if parts[0]\n" + __ + " np.push ''\n" + __ + " for part in parts\n" + __ + " if part is \"..\"\n" + __ + " if np.length > 1\n" + __ + " np.pop()\n" + __ + " else\n" + __ + " np.push part\n" + __ + " else\n" + __ + " if part isnt \".\"\n" + __ + " np.push part\n" + __ + " path = np.join \"/\"\n" + __ + " if not path then path = \"/\"\n" + __ + " return path\n\n" + __ + "toffee.__partial = (parent_tmpl, parent_locals, path, vars) ->\n" + __ + " path = toffee.__normalize parent_tmpl.bundlePath + \"/../\" + path\n" + __ + " return toffee.__inlineInclude path, vars, parent_locals\n\n" + __ + "toffee.__snippet = (parent_tmpl, parent_locals, path, vars) ->\n" + __ + " path = toffee.__normalize parent_tmpl.bundlePath + \"/../\" + path\n" + __ + " vars = if vars? then vars else {}\n" + __ + " vars.__toffee = vars.__toffee or {}\n" + __ + " vars.__toffee.noInheritance = true\n" + __ + " return toffee.__inlineInclude path, vars, parent_locals\n\n" + __ + "toffee.__load = (parent_tmpl, parent_locals, path, vars) ->\n" + __ + " path = toffee.__normalize parent_tmpl.bundlePath + \"/../\" + path\n" + __ + " vars = if vars? then vars else {}\n" + __ + " vars.__toffee = vars.__toffee or {}\n" + __ + " vars.__toffee.repress = true\n" + __ + " return toffee.__inlineInclude path, vars, parent_locals\n\n" + __ + "toffee.__inlineInclude = (path, locals, parent_locals) ->\n" + __ + " options = locals or {}\n" + __ + " options.passback = {}\n" + __ + " options.__toffee = options.__toffee or {}\n" + __ + "\n" + __ + " # we need to make a shallow copy of parent variables\n" + __ + " reserved = {}\n" + __ + " reserved[k] = true for k in [\"passback\", \"load\", \"print\", \"partial\", \"snippet\", \"layout\", \"__toffee\", \"postProcess\"]\n" + __ + " if not options.__toffee.noInheritance\n" + __ + " for k,v of parent_locals when not locals?[k]?\n" + __ + " if not reserved[k]?\n" + __ + " options[k] = v\n" + __ + "\n" + __ + " if not toffee.templates[path]\n" + __ + " return \"Inline toffee include: Could not find \#{path}\"\n" + __ + " else\n" + __ + " res = toffee.templates[path].pub options\n" + __ + " for k,v of options.passback\n" + __ + " parent_locals[k] = v\n" + __ + " return res"; }; - getCommonHeadersJs = function(include_bundle_headers, minimize) { + getCommonHeadersJs = function(include_bundle_headers, auto_escape) { var ch, js; - ch = getCommonHeaders(include_bundle_headers); + ch = getCommonHeaders(0, include_bundle_headers, auto_escape); js = coffee.compile(ch, { bare: true }); - if (minimize) { - js = minimizeJs(js); - } return js; }; view = (function() { - function view(txt, options) { - /* - important options: - cb: if this is set, compilation will happen async and cb will be executed when it's ready - */ - var _this = this; + /* + important options: + cb: if this is set, compilation will happen async and cb will be executed when it's ready + */ options = options || {}; this.fileName = options.fileName || options.filename || null; this.bundlePath = options.bundlePath || "/"; this.browserMode = options.browserMode || false; - this.minimize = options.minimize || false; this.verbose = options.verbose || false; + this.fsError = options.fsError || false; this.prettyPrintErrors = options.prettyPrintErrors != null ? options.prettyPrintErrors : true; + this.prettyLogErrors = options.prettyLogErrors != null ? options.prettyLogErrors : false; + this.autoEscape = options.autoEscape != null ? options.autoEscape : false; + this.additionalErrorHandler = options.additionalErrorHandler || null; this.txt = txt; this.tokenObj = null; this.coffeeScript = null; this.javaScript = null; - this.scriptObj = null; + this.fun = null; this.error = null; if (options.cb) { - this._prepAsync(txt, function() { - return options.cb(_this); - }); + this._prepAsync(txt, options.ctx, ((function(_this) { + return function() { + return options.cb(_this); + }; + })(this))); } } - view.prototype._prepAsync = function(txt, cb) { - /* - Only once it's fully compiled does it callback. - Defers via setTimeouts in each stage in the compile process - for CPU friendliness. This is a lot prettier with iced-coffee-script. - */ + view.prototype._prepAsync = function(txt, ctx, cb) { + /* + Only once it's fully compiled does it callback. + Defers via setTimeouts in each stage in the compile process + for CPU friendliness. This is a lot prettier with iced-coffee-script. + */ var v; + ctx = ctx || vm.createContext({}); this._log("Prepping " + (this.fileName != null ? this.fileName : 'unknown') + " async."); this._toTokenObj(); v = this; return setTimeout(function() { - v._toCoffee(); + v.toCoffee(); return setTimeout(function() { - v._toJavaScript(); + v.toJavaScript(); return setTimeout(function() { - v._toScriptObj(); + v._toFun(ctx); v._log("Done async prep of " + (v.fileName != null ? v.fileName : 'unknown') + ". Calling back."); return cb(); }, 0); @@ -106,9 +136,9 @@ }; view.prototype._log = function(o) { - var _ref2; + var ref2; if (this.verbose) { - if ((_ref2 = typeof o) === "string" || _ref2 === "number" || _ref2 === "boolean") { + if ((ref2 = typeof o) === "string" || ref2 === "number" || ref2 === "boolean") { return console.log("toffee: " + o); } else { return console.log("toffee: " + (util.inspect(o))); @@ -117,49 +147,57 @@ }; view.prototype._cleanTabs = function(obj) { + /* - replaces tabs with spaces in their coffee regions - */ - - var item, _i, _len, _ref2, _ref3, _results; - if ((_ref2 = obj[0]) === "INDENTED_TOFFEE_ZONE" || _ref2 === "TOFFEE_ZONE" || _ref2 === "COFFEE_ZONE") { - _ref3 = obj[1]; - _results = []; - for (_i = 0, _len = _ref3.length; _i < _len; _i++) { - item = _ref3[_i]; - _results.push(this._cleanTabs(item)); + replaces tabs with spaces in their coffee regions + */ + var item, j, len, ref2, ref3, results; + if ((ref2 = obj[0]) === "TOFFEE_ZONE" || ref2 === "COFFEE_ZONE") { + ref3 = obj[1]; + results = []; + for (j = 0, len = ref3.length; j < len; j++) { + item = ref3[j]; + results.push(this._cleanTabs(item)); } - return _results; + return results; } else if (obj[0] === "COFFEE") { - return obj[1] = obj[1].replace(/\t/g, this._tabAsSpaces()); + return obj[1] = obj[1].replace(/\t/g, tabs(1)); } }; - view.prototype.run = function(options) { - /* - returns [err, str] - */ + view.prototype.run = function(options, ctx) { - var pair, res, sandbox, script; - script = this._toScriptObj(); + /* + returns [err, str] + */ + var fun, j, len, line, pair, ref2, res, txt; + ctx = ctx || vm.createContext({}); + fun = this._toFun(ctx); res = null; if (!this.error) { try { - sandbox = { - __toffee_run_input: options - }; - script.runInNewContext(sandbox); - res = sandbox.__toffee_run_input.__toffee.res; - delete sandbox.__toffee_run_input.__toffee; - } catch (e) { + res = fun(options); + } catch (error) { + e = error; this.error = new toffeeError(this, errorTypes.RUNTIME, e); } } if (this.error) { + if (this.prettyLogErrors) { + txt = this.error.getPrettyPrintText(); + ref2 = txt.split("\n"); + for (j = 0, len = ref2.length; j < len; j++) { + line = ref2[j]; + console.log("toffee err: " + line); + } + } + if (this.additionalErrorHandler) { + this.additionalErrorHandler(this.error.getPrettyPrintText(), this.error.getPrettyPrint(), this.fileName, options); + } if (this.prettyPrintErrors) { pair = [null, this.error.getPrettyPrint()]; } else { - pair = [null, this.error.getPrettyPrintText()]; + pair = [this.error.e, null]; } if (this.error.errType === errorTypes.RUNTIME) { this.error = null; @@ -171,94 +209,100 @@ }; view.prototype._toTokenObj = function() { + /* - compiles Toffee to token array - */ - if (!(this.tokenObj != null)) { + compiles Toffee to token array + */ + if (this.tokenObj == null) { try { this.tokenObj = parser.parse(this.txt); - } catch (e) { + } catch (error) { + e = error; this.error = new toffeeError(this, errorTypes.PARSER, e); } - if (!(this.error != null)) { + if (this.error == null) { this._cleanTabs(this.tokenObj); } } return this.tokenObj; }; - view.prototype._toScriptObj = function() { + view.prototype._toFun = function(ctx) { var d, txt; - if (!(this.scriptObj != null)) { - txt = this._toJavaScript(); + if (this.fun == null) { + txt = this.toJavaScript(); if (!this.error) { d = Date.now(); - this.scriptObj = vm.createScript(txt); - this._log("" + this.fileName + " compiled to scriptObj in " + (Date.now() - d) + "ms"); + vm.runInContext(txt, ctx); + this.fun = ctx['_TMPL_']; + this._log(this.fileName + " compiled to scriptObj in " + (Date.now() - d) + "ms"); } } - return this.scriptObj; + return this.fun; }; - view.prototype._toJavaScript = function() { - var c, d, d2; - if (!(this.javaScript != null)) { - c = this._toCoffee(); + view.prototype.toJavaScript = function() { + var c, d, opts; + if (this.javaScript == null) { + c = this.toCoffee(); if (!this.error) { d = Date.now(); try { - this.javaScript = coffee.compile(c, { - bare: false - }); - } catch (e) { + opts = { + bare: true + }; + if (this.browserMode) { + opts.bare = false; + } + this.javaScript = coffee.compile(c, opts); + } catch (error) { + e = error; this.error = new toffeeError(this, errorTypes.COFFEE_COMPILE, e); } - if (this.minimize && !this.error) { - d2 = Date.now(); - this.javaScript = minimizeJs(this.javaScript); - } - this._log("" + this.fileName + " compiled to JavaScript in " + (Date.now() - d) + "ms"); + this._log(this.fileName + " compiled to JavaScript in " + (Date.now() - d) + "ms"); } } return this.javaScript; }; - view.prototype._toCoffee = function() { + view.prototype.toCoffee = function() { var d, res, tobj; - if (!(this.coffeeScript != null)) { + if (this.coffeeScript == null) { tobj = this._toTokenObj(); if (!this.error) { d = Date.now(); res = this._coffeeHeaders(); try { - res += this._toCoffeeRecurse(tobj, TAB_SPACES, 0)[0]; + res += this._toCoffeeRecurse(tobj, TAB_SPACES * (1 + this._globalTabLevel()), 0, {})[0]; res += this._coffeeFooters(); this.coffeeScript = res; - } catch (e) { + } catch (error) { + e = error; + console.log(e); this.error; } - this._log("" + this.fileName + " compiled to CoffeeScript in " + (Date.now() - d) + "ms"); + this._log(this.fileName + " compiled to CoffeeScript in " + (Date.now() - d) + "ms"); } } return this.coffeeScript; }; view.prototype._printLineNo = function(n, ind) { - if (this.minimize || ((this.lastLineNo != null) && (n === this.lastLineNo))) { + if ((this.lastLineNo != null) && (n === this.lastLineNo)) { return ""; } else { this.lastLineNo = n; - return "\n" + (this._space(ind)) + "_ln " + n; + return "\n" + (spaces(ind)) + "_ln " + n; } }; view.prototype._snippetHasEscapeOverride = function(str) { - var token, _i, _len, _ref2, _ref3; - _ref2 = ['print', ' snippet', 'partial', 'raw', 'html', 'json', '__toffee.raw', '__toffee.html', '__toffee.json', 'JSON.stringify']; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - token = _ref2[_i]; + var j, len, ref2, ref3, token; + ref2 = ['print', ' snippet', 'load', 'partial', 'raw', 'html', 'json', '__toffee.raw', '__toffee.html', '__toffee.json']; + for (j = 0, len = ref2.length; j < len; j++) { + token = ref2[j]; if (str.slice(0, token.length) === token) { - if ((str.length > token.length) && ((_ref3 = str[token.length]) === ' ' || _ref3 === '\t' || _ref3 === '\n' || _ref3 === '(')) { + if ((str.length > token.length) && ((ref3 = str[token.length]) === ' ' || ref3 === '\t' || ref3 === '\n' || ref3 === '(')) { return true; } } @@ -267,66 +311,63 @@ }; view.prototype._snippetIsSoloToken = function(str) { + /* - if the inside is something like #{ foo } not #{ foo.bar } or other complex thing. - */ + if the inside is something like #{ foo } not #{ foo.bar } or other complex thing. + */ if (str.match(/^[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*$/)) { return true; } return false; }; - view.prototype._toCoffeeRecurse = function(obj, indent_level, indent_baseline) { - var c, chunk, delta, i, i_delta, ind, interp, item, lbreak, line, lineno, lines, part, res, s, t_int, temp_indent_level, zone_baseline, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; + view.prototype._toCoffeeRecurse = function(obj, indent_level, indent_baseline, state_carry) { + var c, chunk, delta, i, i_delta, ind, interp, item, j, k, l, lbreak, len, len1, len2, len3, line, lineno, lines, m, part, ref2, ref3, ref4, ref5, res, s, t_int, temp_indent_level, zone_baseline; res = ""; i_delta = 0; switch (obj[0]) { - case "INDENTED_TOFFEE_ZONE": - indent_level += TAB_SPACES; - _ref2 = obj[1]; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - item = _ref2[_i]; - _ref3 = this._toCoffeeRecurse(item, indent_level, indent_baseline), s = _ref3[0], delta = _ref3[1]; - res += s; - } - break; case "TOFFEE_ZONE": - res += "\n" + (this._space(indent_level)) + "_ts " + states.TOFFEE; - _ref4 = obj[1]; - for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) { - item = _ref4[_j]; - _ref5 = this._toCoffeeRecurse(item, indent_level, indent_baseline), s = _ref5[0], delta = _ref5[1]; + if (state_carry.last_coffee_ends_with_newline === false) { + indent_level += TAB_SPACES; + } + res += "\n" + (spaces(indent_level)) + "_ts " + states.TOFFEE; + ref2 = obj[1]; + for (j = 0, len = ref2.length; j < len; j++) { + item = ref2[j]; + ref3 = this._toCoffeeRecurse(item, indent_level, indent_baseline, state_carry), s = ref3[0], delta = ref3[1]; res += s; } break; case "COFFEE_ZONE": - res += "\n" + (this._space(indent_level)) + "_ts " + states.COFFEE; + res += "\n" + (spaces(indent_level)) + "_ts " + states.COFFEE; zone_baseline = this._getZoneBaseline(obj[1]); temp_indent_level = indent_level; - _ref6 = obj[1]; - for (_k = 0, _len2 = _ref6.length; _k < _len2; _k++) { - item = _ref6[_k]; - _ref7 = this._toCoffeeRecurse(item, temp_indent_level, zone_baseline), s = _ref7[0], delta = _ref7[1]; + ref4 = obj[1]; + for (k = 0, len1 = ref4.length; k < len1; k++) { + item = ref4[k]; + ref5 = this._toCoffeeRecurse(item, temp_indent_level, zone_baseline, state_carry), s = ref5[0], delta = ref5[1]; res += s; temp_indent_level = indent_level + delta; } break; case "TOFFEE": ind = indent_level; - res += "\n" + (this._space(ind)) + "_ts " + states.TOFFEE; + res += "\n" + (spaces(ind)) + "_ts " + states.TOFFEE; lineno = obj[2]; try { t_int = utils.interpolateString(obj[1]); - } catch (e) { + } catch (error) { + e = error; e.relayed_line_range = [lineno, lineno + obj[1].split("\n").length]; this.error = new toffeeError(this, errorTypes.STR_INTERPOLATE, e); throw e; } - for (_l = 0, _len3 = t_int.length; _l < _len3; _l++) { - part = t_int[_l]; + for (l = 0, len2 = t_int.length; l < len2; l++) { + part = t_int[l]; if (part[0] === "TOKENS") { res += this._printLineNo(lineno, ind); interp = part[1].replace(/(^[\n \t]+)|([\n \t]+)$/g, ''); + interp = interp.replace(/[\u2028\u2029]/g, '\n'); if (this._snippetIsSoloToken(interp)) { chunk = "\#{if " + interp + "? then escape " + interp + " else ''}"; } else if (this._snippetHasEscapeOverride(interp)) { @@ -334,17 +375,17 @@ } else { chunk = "\#{escape(" + interp + ")}"; } - res += "\n" + (this._space(ind)) + "_to " + (this._quoteStr(chunk)); + res += "\n" + (spaces(ind)) + "_to " + (this._quoteStr(chunk)); lineno += part[1].split("\n").length - 1; } else { - lines = part[1].split("\n"); - for (i = _m = 0, _len4 = lines.length; _m < _len4; i = ++_m) { + lines = part[1].split(/[\n\u2028\u2029]/); + for (i = m = 0, len3 = lines.length; m < len3; i = ++m) { line = lines[i]; res += this._printLineNo(lineno, ind); lbreak = i !== lines.length - 1 ? "\n" : ""; chunk = this._escapeForStr("" + line + lbreak); if (chunk.length) { - res += "\n" + (this._space(ind)) + "_to " + (this._quoteStr(chunk + lbreak)); + res += "\n" + (spaces(ind)) + "_to " + (this._quoteStr(chunk + lbreak)); } if (i < lines.length - 1) { lineno++; @@ -353,12 +394,14 @@ } } res += this._printLineNo(obj[2] + (obj[1].split('\n').length - 1), ind); - res += "\n" + (this._space(ind)) + "_ts " + states.COFFEE; + res += "\n" + (spaces(ind)) + "_ts " + states.COFFEE; break; case "COFFEE": c = obj[1]; + c = c.replace(/[\u2028\u2029]/g, '\n'); res += "\n" + (this._reindent(c, indent_level, indent_baseline)); i_delta = this._getIndentationDelta(c, indent_baseline); + state_carry.last_coffee_ends_with_newline = this._doesEndWithNewline(c); break; default: throw "Bad parsing. " + obj + " not handled."; @@ -368,12 +411,12 @@ }; view.prototype._quoteStr = function(s) { - /* - returns a triple-quoted string, dividing into single quoted - start and stops, if the string begins with double quotes, since - coffee doesn't want to let us escape those. - */ + /* + returns a triple-quoted string, dividing into single quoted + start and stops, if the string begins with double quotes, since + coffee doesn't want to let us escape those. + */ var follow, lead, res; lead = ""; follow = ""; @@ -396,11 +439,22 @@ return res; }; + view.prototype._doesEndWithNewline = function(s) { + var parts; + parts = s.split("\n"); + if ((parts.length > 1) && parts[parts.length - 1].match(/^[\t ]*$/)) { + return true; + } else { + return false; + } + }; + view.prototype._escapeForStr = function(s) { + /* - escapes a string so it can make it into coffeescript - triple quotes without losing whitespace, etc. - */ + escapes a string so it can make it into coffeescript + triple quotes without losing whitespace, etc. + */ s = s.replace(/\\/g, '\\\\'); s = s.replace(/\n/g, '\\n'); s = s.replace(/\t/g, '\\t'); @@ -408,9 +462,9 @@ }; view.prototype._getZoneBaseline = function(obj_arr) { - var ib, obj, _i, _len; - for (_i = 0, _len = obj_arr.length; _i < _len; _i++) { - obj = obj_arr[_i]; + var ib, j, len, obj; + for (j = 0, len = obj_arr.length; j < len; j++) { + obj = obj_arr[j]; if (obj[0] === "COFFEE") { ib = this._getIndentationBaseline(obj[1]); if (ib != null) { @@ -422,11 +476,11 @@ }; view.prototype._getIndentationBaseline = function(coffee) { - var i, line, lines, res, _i, _len; + var i, j, len, line, lines, res; res = null; lines = coffee.split("\n"); if (lines.length) { - for (i = _i = 0, _len = lines.length; _i < _len; i = ++_i) { + for (i = j = 0, len = lines.length; j < len; i = ++j) { line = lines[i]; if ((!line.match(/^[ ]*$/)) || i === (lines.length - 1)) { res = line.match(/[ ]*/)[0].length; @@ -434,25 +488,25 @@ } } } - if (!(res != null)) { + if (res == null) { res = coffee.length; } return res; }; view.prototype._getIndentationDelta = function(coffee, baseline) { - /* - given an arbitrarily indented set of coffeescript, returns the delta - between the first and last lines, in chars. - Ignores leading/trailing whitespace lines - If passed a baseline, uses that instead of own. - */ + /* + given an arbitrarily indented set of coffeescript, returns the delta + between the first and last lines, in chars. + Ignores leading/trailing whitespace lines + If passed a baseline, uses that instead of own. + */ var lines, res, y, y_l; - if (!(baseline != null)) { + if (baseline == null) { baseline = this._getIndentationBaseline(coffee); } - if (!(baseline != null)) { + if (baseline == null) { res = 0; } else { lines = coffee.split("\n"); @@ -478,53 +532,43 @@ } rxx = /^[ ]*/; strip = indent_baseline; - indent = this._space(indent_level); + indent = spaces(indent_level); res = ((function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = lines.length; _i < _len; _i++) { - line = lines[_i]; - _results.push("" + indent + line.slice(strip)); + var j, len, results; + results = []; + for (j = 0, len = lines.length; j < len; j++) { + line = lines[j]; + results.push("" + indent + line.slice(strip)); } - return _results; + return results; })()).join("\n"); return res; }; - view.prototype._space = function(indent) { - var i; - return ((function() { - var _i, _results; - _results = []; - for (i = _i = 0; 0 <= indent ? _i < indent : _i > indent; i = 0 <= indent ? ++_i : --_i) { - _results.push(" "); - } - return _results; - })()).join(""); + view.prototype._globalTabLevel = function() { + if (this.browserMode) { + return 0; + } else { + return 1; + } }; - view.prototype._tabAsSpaces = function() { - var i; - return ((function() { - var _i, _results; - _results = []; - for (i = _i = 0; 0 <= TAB_SPACES ? _i < TAB_SPACES : _i > TAB_SPACES; i = 0 <= TAB_SPACES ? ++_i : --_i) { - _results.push(" "); - } - return _results; - })()).join(""); + view.prototype._globalTabs = function() { + return tabs(this._globalTabLevel()); }; view.prototype._coffeeHeaders = function() { - var ___; - ___ = this._tabAsSpaces(); - return "" + (this.browserMode ? '' : getCommonHeaders(false)) + "\ntmpl = toffee.templates[\"" + this.bundlePath + "\"] =\n bundlePath: \"" + this.bundlePath + "\"\ntmpl.pub = (locals) ->\n" + ___ + "_l = locals\n" + ___ + "_t = _l.__toffee = { out: []}\n" + ___ + "_to = (x) -> locals.__toffee.out.push x\n" + ___ + "_ln = (x) -> locals.__toffee.lineno = x\n" + ___ + "_ts = (x) -> locals.__toffee.state = x\n\n" + ___ + "if not _l.print? then _l.print = (o) -> toffee.__print _l, o\n" + ___ + "if not _l.json? then _l.json = (o) -> toffee.__json _l, o\n" + ___ + "if not _l.raw? then _l.raw = (o) -> toffee.__raw _l, o\n" + ___ + "if not _l.html? then _l.html = (o) -> toffee.__html _l, o\n" + ___ + "if not _l.escape? then _l.escape = (o) -> toffee.__escape _l, o\n" + ___ + "if not _l.partial? then _l.partial = (path, vars) -> toffee.__partial toffee.templates[\"" + this.bundlePath + "\"], _l, path, vars\n" + ___ + "if not _l.snippet? then _l.snippet = (path, vars) -> toffee.__snippet toffee.templates[\"" + this.bundlePath + "\"], _l, path, vars\n\n" + ___ + "_t.print = _l.print\n" + ___ + "_t.json = _l.json\n" + ___ + "_t.raw = _l.raw\n" + ___ + "_t.html = _l.html\n" + ___ + "_t.escape = _l.escape\n" + ___ + "_t.partial = _l.partial\n" + ___ + "_t.snippet = _l.snippet\n\n" + ___ + "`with (locals) {`\n" + ___ + "__toffee.out = []"; + var __, ___; + __ = this._globalTabs(); + ___ = tabs(1); + return (this.browserMode ? '' : '_TMPL_ = (__toffee_run_input) ->' + (getCommonHeaders(1, false, this.autoEscape))) + "\n" + __ + "# browser mode = " + this.browserMode + "\n" + __ + "tmpl = toffee.templates[\"" + this.bundlePath + "\"] =\n" + __ + " bundlePath: \"" + this.bundlePath + "\"\n" + __ + "tmpl.render = tmpl.pub = (__locals) ->\n" + __ + ___ + "__locals = __locals or {}\n" + __ + ___ + "__repress = __locals.__toffee?.repress\n" + __ + ___ + "_to = (x) -> __locals.__toffee.out.push x\n" + __ + ___ + "_ln = (x) -> __locals.__toffee.lineno = x\n" + __ + ___ + "_ts = (x) -> __locals.__toffee.state = x\n" + __ + ___ + "toffee.__augmentLocals __locals, \"" + this.bundlePath + "\"\n\n" + __ + ___ + "`with (__locals) {`\n" + __ + ___ + "__toffee.out = []"; }; view.prototype._coffeeFooters = function() { - var ___; - ___ = this._tabAsSpaces(); - return "\n\n" + ___ + "__toffee.res = __toffee.out.join \"\"\n" + ___ + "return __toffee.res\n" + ___ + "`} /* closing JS 'with' */ `\n# sometimes we want to execute the whole thing in a sandbox\n# and just output results\nif __toffee_run_input?\n" + ___ + "return tmpl.pub __toffee_run_input"; + var __, ___; + __ = this._globalTabs(); + ___ = tabs(1); + return "\n\n" + __ + ___ + "__toffee.res = __toffee.out.join \"\"\n" + __ + ___ + "if postProcess?\n" + __ + ___ + ___ + "__toffee.res = postProcess __toffee.res\n" + __ + ___ + "if (not __repress) then return __toffee.res else return \"\"\n" + __ + "`true; } /* closing JS 'with' */ `\n" + __ + "# sometimes we want to execute the whole thing in a sandbox\n" + __ + "# and just output results\n" + __ + "if __toffee_run_input?\n" + __ + ___ + "return tmpl.pub __toffee_run_input"; }; return view; diff --git a/package.json b/package.json index 6719b52..ea46ba3 100644 --- a/package.json +++ b/package.json @@ -1,25 +1,43 @@ { - "name": "toffee", - "description": "An Express 3.x and 2.x templating language based on CoffeeScript with slicker tokens and syntax. Built with love at OkCupid.", - "version": "0.0.30", - "directories": { - "lib": "./lib" - }, - "main": "index.js", - "author": "Chris Coyne ", - "bin": "./bin/toffee", - "dependencies": { - "coffee-script": "*", - "commander": "*" - }, - "repository": { - "type": "git", - "url": "http://github.com/malgorithms/toffee" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/malgorithms/toffee/raw/master/LICENSE" - } - ] -} \ No newline at end of file + "name": "toffee", + "description": "A NodeJs and browser-side templating language based on CoffeeScript with slicker tokens and syntax.", + "version": "0.3.7", + "directories": { + "lib": "./lib" + }, + "main": "index.js", + "author": "Chris Coyne ", + "bin": "./bin/toffee", + "dependencies": { + "coffee-script": "1.12.7", + "commander": "10.0.0", + "highlight.js": "11.7.0", + "iced-lock": "2.0.1", + "mkdirp": "2.1.3" + }, + "devDependencies": { + "assert": "2.0.0", + "colors": "1.4.0", + "diff": "5.1.0", + "express": "4.18.2", + "iced-coffee-script": "108.0.14", + "jison": "0.4.18", + "tablify": "0.1.5", + "zombie": "6.1.4" + }, + "files": [ + "index.js", + "lib/*", + "bin/*" + ], + "repository": { + "type": "git", + "url": "http://github.com/malgorithms/toffee" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/malgorithms/toffee/raw/master/LICENSE" + } + ] +} diff --git a/src/command_line.coffee b/src/command_line.coffee index dfad949..da54047 100644 --- a/src/command_line.coffee +++ b/src/command_line.coffee @@ -2,6 +2,7 @@ fs = require 'fs' path = require 'path' {view, getCommonHeadersJs} = require '../lib/view' program = require 'commander' +mkdirp = require 'mkdirp' # ----------------------------------------------------------------------------- @@ -29,30 +30,47 @@ program.on '--help', -> \n var pubvars = { name: \"Hans Gruber\", criminal: true }; \n var some_html = toffee.render (\"views/layout.toffee\", pubvars); \n -\n +\n " program.version(getVersionNumber()) - .option('-o, --output [path]', 'output file') - .option('-p, --print', 'print output to stdout') - .option('-m, --minimize', 'minimize output (ugly, smaller file)') - .option('-c, --coffee', 'output to CoffeeScript (not JS)') + .option('-o, --output [path]', 'file (bundles all output into a single .js)') + .option('-d, --output_dir [path]', 'compiles templates into parallel .js files') + .option('-p, --print', 'print to stdout') + .option('-c, --coffee', 'output to CoffeeScript (not JS)') + .option('-b, --bundle_path [path]', 'bundle_path (instead of "/") for templates') + .option('-n, --no_headers', 'exclude boilerplate toffee (requires toffee.js included separately)') .parse process.argv # ----------------------------------------------------------------------------- -compile = (start_path, path) -> +compile = (start_path, full_path) -> ### e.g., if start_path is /foo/bar and path is /foo/bar/car/thing.toffee ### - source = fs.readFileSync path, 'utf8' + source = fs.readFileSync full_path, 'utf8' + bundle_path = full_path[start_path.length...] + + if start_path is full_path + bundle_path = "/" + path.basename full_path + + if program.bundle_path + bundle_path = path.normalize "#{program.bundle_path}/#{bundle_path}" + v = new view source, - fileName: path - bundlePath: path[start_path.length...] + fileName: full_path + bundlePath: bundle_path browserMode: true - minimize: program.minimize? and program.minimize - return v._toJavaScript() + if program.coffee + output = v.toCoffee() + else + output = v.toJavaScript() + if v.error + process.stderr.write v.error.getPrettyPrintText() + process.exit 1 + + [output, bundle_path] # ----------------------------------------------------------------------------- @@ -69,10 +87,33 @@ recurseRun = (start_path, curr_path, out_text) -> if sub_stats.isDirectory() out_text = recurseRun start_path, sub_path, out_text else - out_text += "\n" + compile start_path, curr_path + comp = compile start_path, curr_path + out_text += "\n;\n" + comp[0] + if program.output_dir + file_out_path = path.normalize "#{program.output_dir}/#{comp[1]}" + file_out_path = "#{path.dirname file_out_path}/#{path.basename file_out_path, '.toffee'}" + file_out_path += if program.coffee then '.coffee' else '.js' + if not program.print + console.log "Outputting #{file_out_path}" + mkdirp.sync path.dirname file_out_path + fs.writeFileSync file_out_path, maybeAttachHeaders(comp[0]), "utf8" return out_text +# ----------------------------------------------------------------------------- + +maybeAttachHeaders = (pre_output) -> + if program.no_headers + return pre_output + else + header_out = getCommonHeadersJs true, true, true + if program.coffee + return "`#{header_out}`\n\n#{pre_output}" + else + return "#{header_out}\n;\n#{pre_output}" + +# ----------------------------------------------------------------------------- + run = exports.run = -> if program.args.length isnt 1 @@ -85,10 +126,21 @@ run = exports.run = -> catch e console.log "Input file/path not found. toffee --help for examples" process.exit 1 + + if program.output_dir + try + mkdirp.sync program.output_dir + catch e + console.log "Couldn't make/use #{program.output_dir}; #{e}" + process.exit 1 + start_path = path.normalize start_path - out_text = """#{getCommonHeadersJs true, false}#{recurseRun start_path, start_path, ''}""" + template_out = recurseRun start_path, start_path, '' + out_text = maybeAttachHeaders template_out + if program.print console.log out_text + if program.output try console.log "Writing #{program.output}" diff --git a/src/consts.coffee b/src/consts.coffee index 98f8ee4..e26da34 100644 --- a/src/consts.coffee +++ b/src/consts.coffee @@ -1,5 +1,8 @@ exports.states = - TOFFEE: 1 + TOFFEE: 1 COFFEE: 2 -exports.TAB_SPACES = 2 \ No newline at end of file +exports.TAB_SPACES = 2 + +exports.tweakables = + MISSING_FILE_RECHECK: 1000 # ms before checking if a file has been introduced/changed if fs.watch() fails diff --git a/src/engine.coffee b/src/engine.coffee index 424c759..337697f 100644 --- a/src/engine.coffee +++ b/src/engine.coffee @@ -1,17 +1,34 @@ -{view} = require './view' -{states} = require './consts' -utils = require './utils' -fs = require 'fs' -path = require 'path' -util = require 'util' +{view} = require './view' +{states, tweakables} = require './consts' +{Pool} = require './pool' +utils = require './utils' +fs = require 'fs' +path = require 'path' +util = require 'util' +vm = require 'vm' +LockTable = require('iced-lock').Table +MAX_CACHED_SANDBOXES = 100 + +sandboxCons = () -> + vm.createContext({}) class engine constructor: (options) -> - options = options or {} - @verbose = options.verbose or false - @prettyPrintErrors = if options.prettyPrintErrors? then options.prettyPrintErrors else true - @viewCache = {} # filename + options = options or {} + @verbose = options.verbose or false + @pool = new Pool(sandboxCons, options.poolSize or MAX_CACHED_SANDBOXES) + @prettyPrintErrors = if options.prettyPrintErrors? then options.prettyPrintErrors else true + @prettyLogErrors = if options.prettyLogErrors? then options.prettyLogErrors else true + @autoEscape = if options.autoEscape? then options.autoEscape else true + @cache = if options.cache? then options.cache else true + @additionalErrorHandler = options.additionalErrorHandler or null + + @viewCache = {} # filename -> view + @fsErrorCache = {} # filename -> timestamp last failed + + @filenameCache = {} # caches dir -> filename -> path.normalize path.resolve dir, filename + @fileLockTable = new LockTable() _log: (o) -> if @verbose @@ -20,31 +37,73 @@ class engine else console.log "toffee: #{util.inspect o}" + # basically returns `path.normalize path.resolve dir, filename`, but caches it to speed up multiple inclusions + normalizeFilename: (dir, filename) -> + cache = @filenameCache[dir] + if not cache? + @filenameCache[dir] = {} + cache = {} + normalized = cache[filename] + if not normalized? + normalized = path.normalize path.resolve dir, filename + @filenameCache[dir][filename] = normalized + return normalized + + + render: (filename, options, cb) => @run filename, options, cb + run: (filename, options, cb) => ### "options" contains the pub vars and may contain special items: layout: path to a template expecting a body var (express 2.x style, but for use with express 3.x) + postProcess: a function which takes the string of output and post processes it (returning new string) __toffee.dir: path to look relative to __toffee.parent: parent file __toffee.noInheritance: if true, don't pass variables through unless explicitly passed + __toffee.repress if true, don't output anything; useful with including definition files with passback of vars __toffee.autoEscape: if set as false, don't escape output of #{} vars by default ### + if not options.prettyPrintErrors? then options.prettyPrintErrors = @prettyPrintErrors + if not options.prettyLogErrors? then options.prettyLogErrors = @prettyLogErrors + if not options.additionalErrorHandler? then options.additionalErrorHandler = @additionalErrorHandler + if not options.autoEscape? then options.autoEscape = @autoEscape + + # we only want to pass post_process into the layout + post_process = options.postProcess + options.postProcess = null + + if options?.layout + layout_options = {} + layout_options[k] = v for k,v of options when k isnt "layout" + [err, res] = @runSync filename, options # if we got an error but want to pretty-print by faking ok result - if err and @prettyPrintErrors + if err and @prettyPrintErrors [err, res] = [null, err] # if we're using a layout, pub into that - if (not err) and options?.layout - options.body = res - [err, res] = @runSync options.layout, options + if (not err) and layout_options? + layout_options.body = res + [err, res] = @runSync options.layout, layout_options if err and @prettyPrintErrors [err, res] = [null, err] + # post processing + if (not err) and (typeof(post_process) is "function") + [err, res] = @postProcess post_process, res + cb err, res + postProcess: (fn, res) -> + err = null + try + res = fn res + catch e + err = e + return [err, res] + runSync: (filename, options) -> ### "options" the same as run() above @@ -55,39 +114,72 @@ class engine options = options or {} options.__toffee = options.__toffee or {} options.__toffee.dir = options.__toffee.dir or process.cwd() - filename = if filename[0] isnt "/" then "#{options.__toffee.dir}/#{filename}" else filename - realpath = path.normalize filename - pwd = path.dirname realpath + realpath = @normalizeFilename options.__toffee.dir, filename + + if @cache + v = (@_viewCacheGet realpath) or (@_loadCacheAndMonitor realpath, options) + else + v = @_loadWithoutCache realpath, options - v = @viewCache[realpath] or @_loadCacheAndMonitor realpath, options if v - options.__toffee.parent = realpath - options.partial = options.partial or (fname, lvars) => @_fn_partial fname, lvars, realpath, options - options.snippet = options.snippet or (fname, lvars) => @_fn_snippet fname, lvars, realpath, options - options.print = options.print or (txt) => @_fn_print txt, options - if not options.console? then options.console = log: console.log - [err, res] = v.run options + if @fsErrorCache[realpath] + [err, res] = [new Error("Couldn't load #{realpath}"), null] + else + options.__toffee.parent = realpath + options.partial = options.partial or (fname, lvars) => @_fn_partial fname, lvars, realpath, options + options.snippet = options.snippet or (fname, lvars) => @_fn_snippet fname, lvars, realpath, options + options.load = options.load or (fname, lvars) => @_fn_load fname, lvars, realpath, options + options.print = options.print or (txt) => @_fn_print txt, options + if not options.console? then options.console = log: console.log + ctx = @pool.get() + [err, res] = v.run options, ctx + @pool.release(ctx) else - [err, res] = ["Couldn't load #{realpath}", null] + [err, res] = [new Error("Couldn't load #{realpath}"), null] @_log "#{realpath} run in #{Date.now() - start_time}ms" return [err, res] + _viewCacheGet: (filename) -> + if not @viewCache[filename]? + return null + else if not @fsErrorCache[filename]? + return @viewCache[filename] + else if (Date.now() - @fsErrorCache[filename]) < tweakables.MISSING_FILE_RECHECK + return @viewCache[filename] + else + return null + _inlineInclude: (filename, local_vars, parent_realpath, parent_options) => options = local_vars or {} + options.passback = {} options.__toffee = options.__toffee or {} options.__toffee.dir = path.dirname parent_realpath options.__toffee.parent = parent_realpath + noInheritance = options.__toffee.noInheritance + repress = options.__toffee.repress # we need to make a shallow copy of parent variables - if not options.__toffee.noInheritance + reserved = {} + reserved[k] = true for k in ["passback", "load", "print", "partial", "snippet", "layout", "__toffee", "postProcess"] + if not noInheritance for k,v of parent_options when not local_vars?[k]? - if not (k in ["print", "partial", "snippet", "layout", "__toffee"]) + if not reserved[k]? options[k] = v [err, res] = @runSync filename, options + + for k,v of options.passback + parent_options[k] = v + return err or res + _fn_load: (fname, lvars, realpath, options) => + lvars = if lvars? then lvars else {} + lvars.__toffee = lvars.__toffee or {} + lvars.__toffee.repress = true + @_inlineInclude fname, lvars, realpath, options + _fn_snippet: (fname, lvars, realpath, options) => lvars = if lvars? then lvars else {} lvars.__toffee = lvars.__toffee or {} @@ -104,44 +196,95 @@ class engine else return txt + _loadWithoutCache: (filename, options) -> + try + txt = fs.readFileSync filename, 'utf8' + catch e + txt = "Error: Could not read #{filename}" + if options.__toffee?.parent? then txt += " first requested in #{options.__toffee.parent}" + + view_options = @_generateViewOptions filename + v = new view txt, view_options + return v + _loadCacheAndMonitor: (filename, options) -> + previous_fs_err = @fsErrorCache[filename]? try txt = fs.readFileSync filename, 'utf8' + if @fsErrorCache[filename]? then delete @fsErrorCache[filename] catch e txt = "Error: Could not read #{filename}" - if options.__toffee?.parent? then txt += " requested in #{options.__toffee.parent}" - view_options = - fileName: filename - verbose: @verbose - prettyPrintErrors: @prettyPrintErrors - v = new view txt, view_options - @viewCache[filename] = v - @_monitorForChanges filename, options - v + if options.__toffee?.parent? then txt += " first requested in #{options.__toffee.parent}" + @fsErrorCache[filename] = Date.now() + + # if we hit an fs error and it already happened, just return that + if (@fsErrorCache[filename] and previous_fs_err and @viewCache[filename]) + return @viewCache[filename] + else + view_options = @_generateViewOptions filename + v = new view txt, view_options + @viewCache[filename] = v + @_monitorForChanges filename, options + return v + + _reloadFileInBkg: (filename, options) -> + @_log "#{filename} acquiring lock to read" + @fileLockTable.acquire2 {name: filename}, (lock) => + fs.readFile filename, 'utf8', (err, txt) => + @_log "#{Date.now()} - #{filename} changed to #{txt?.length} bytes. #{txt?.replace?(/\n/g , '')[...80]}" if not err + waiting_for_view = false + if err or (txt isnt @viewCache[filename].txt) + if err + @fsErrorCache[filename] = Date.now() + txt = "Error: Could not read #{filename}" + if options.__toffee?.parent? then txt += " requested in #{options.__toffee.parent}" + if not (err and @viewCache[filename].fsError) # i.e., don't just create a new error view + view_options = @_generateViewOptions filename + ctx = @pool.get() + view_options.ctx = ctx + view_options.cb = (v) => + @_log "#{filename} updated and ready" + @viewCache[filename] = v + @pool.release(ctx) + @_log "#{filename} lock releasing (view_options.cb)" + lock.release() + waiting_for_view = true # do not release lock instantly + if err + view_options.fsError = true + v = new view txt, view_options + if not waiting_for_view + @_log "#{filename} lock releasing (not waiting for view)" + lock.release() + + _generateViewOptions: (filename) -> + return { + fileName: filename + verbose: @verbose + prettyPrintErrors: @prettyPrintErrors + prettyLogErrors: @prettyLogErrors + autoEscape: @autoEscape + additionalErrorHandler: @additionalErrorHandler + } _monitorForChanges: (filename, options) -> ### we must continuously unwatch/rewatch because some editors/systems invoke a "rename" event and we'll end up following the wrong, old 'file' as a new one is dropped in its place. + + Files that are missing are ignored here because they get picked up by new calls to _loadCacheAndMonitor ### - fsw = null - fsw = fs.watch filename, {persistent: true}, (change) => - fsw.close() - @_log "Got an fs.watch hit on #{filename}" - fs.readFile filename, 'utf8', (err, txt) => - @_monitorForChanges filename, options - if txt isnt @viewCache[filename].txt - if err - txt = "Error: Could not read #{filename} after fs.watch() hit." - if options.__toffee?.parent? then txt += " requested in #{options.__toffee.parent}" - view_options = - fileName: filename - verbose: @verbose - prettyPrintErrors: @prettyPrintErrors - cb: (v) => - @_log "#{filename} updated and ready" - @viewCache[filename] = v - v = new view txt, view_options + if not @fsErrorCache[filename]? # if there's an fsError, this will get rechecked on-demand occasionally + fsw = null + try + @_log "#{filename} starting fs.watch()" + fsw = fs.watch filename, {persistent: true}, (change) => + @_log "#{filename} closing fs.watch()" + fsw.close() + @_monitorForChanges filename, options + @_reloadFileInBkg filename, options + catch e + @_log "fs.watch() failed for #{filename}; settings fsErrorCache = true" + @fsErrorCache[filename] = Date.now() -exports.engine = engine \ No newline at end of file +exports.engine = engine diff --git a/src/errorHandler.coffee b/src/errorHandler.coffee index 32351e3..c56e277 100644 --- a/src/errorHandler.coffee +++ b/src/errorHandler.coffee @@ -7,7 +7,7 @@ errorTypes = exports.errorTypes = COFFEE_COMPILE: 2 RUNTIME: 3 -class toffeeError +class toffeeError extends Error constructor: (view, err_type, e) -> @errType = err_type @@ -43,15 +43,21 @@ class toffeeError full_path: @view.fileName dir_name: path.dirname @view.fileName file: path.basename @view.fileName - line_range: [0,0] + line_range: null # will be a pair } if @e?.message? then res.message = @e.message + + # Error objects now support line numbers in certain cases. + if @e?.location?.first_line? + res.line_range = @_convertJsErrorRangeToToffeeRange @e.location + switch @errType when errorTypes.PARSER - line = @_extractOffensiveLineNo @e.message, /on line ([0-9]+)/ - res.line_range = [line, line + 1] + if not res.line_range? + line = @_extractOffensiveLineNo @e.message, /on line ([0-9]+)/ + res.line_range = [line, line + 1] when errorTypes.STR_INTERPOLATE res.line_range = [@e.relayed_line_range[0], @e.relayed_line_range[1]] @@ -59,11 +65,18 @@ class toffeeError res.message = res.message.replace 'missing }', 'unclosed `\#{}`' when errorTypes.COFFEE_COMPILE - line = @_extractOffensiveLineNo @e.message, /on line ([0-9]+)/ - res.line_range = @_convertOffensiveLineToToffeeRange line - res.message = res.message.replace /on line [0-9]+/, @_lineRangeToPhrase res.line_range + if not res.line_range? + line = @_extractOffensiveLineNo @e.message, /on line ([0-9]+)/ + res.line_range = @_convertOffensiveLineToToffeeRange line + if res.message.indexOf('on line') isnt -1 + res.message = res.message.replace /on line [0-9]+/, @_lineRangeToPhrase res.line_range + else + res.message += " " + @_lineRangeToPhrase res.line_range + when errorTypes.RUNTIME + if not res.line_range? + res.line_range = [0,0] if @e.stack res.stack = @e.stack.split "\n" @_convertRuntimeStackLines res @@ -78,7 +91,11 @@ class toffeeError stack = converted_err.stack for line, i in stack - rxx_pub = /// Object[\.]pub[\s]\(undefined\:([0-9]+)\:[0-9]+ /// + rxx_pub = /// + Object[\.].*?pub[\s]\(undefined\:([0-9]+)\:[0-9]+ + | + tmpl[\.]render[\.]tmpl[\.]pub.*\(.*\:([0-9]+)\:[0-9]+ + /// m = line.match rxx_pub in_src_file = false lrange = [null, null] @@ -116,10 +133,7 @@ class toffeeError returns a TEXT only blob explaining the error ### cerr = @getConvertedError() - if cerr.type is errorTypes.RUNTIME - header = cerr.message - else - header = "#{cerr.dir_name}/#{cerr.file}: #{cerr.message}" + header = "#{cerr.dir_name}/#{cerr.file}: #{cerr.message}" res = """ ERROR ===== @@ -147,42 +161,39 @@ class toffeeError getPrettyPrint: -> ### - returns an HTML blob explaining the error + returns an HTML blob explaining the error with lines highlighted ### cerr = @getConvertedError() res = "" - if cerr.type is 234432#errorTypes.RUNTIME - header = cerr.message - else - header = "#{cerr.dir_name}/#{cerr.file}: #{cerr.message}" + header = "#{cerr.dir_name}/#{cerr.file}: #{_ppEscape cerr.message}" res += """ -
    +
    \n
    #{header}
    \n
    - \n
    + \n
    """ if cerr.stack?.length - res += "
    " + res += "
    " count = 0 for item,i in cerr.stack if i is 0 - res += "
    #{count++} #{item.line}
    " + res += "
    #{count++} #{item.line}
    " else if item.in_src_file and (item.above_pub_call or item.at_pub_call) - res += "
    #{count++} [#{@_lineRangeToPhrase item.line_range}] #{cerr.dir_name}/#{cerr.file}
    " + res += "
    #{count++} [#{@_lineRangeToPhrase item.line_range}] #{cerr.dir_name}/#{cerr.file}
    " else if item.in_src_file continue else - res += "
    #{count++}#{item.line}
    " + res += "
    #{count++}#{item.line}
    " res += "
    " for i in [(cerr.line_range[0]-3)...(cerr.line_range[1]+1)] if (i < 0) or i > @toffeeSrcLines.length - 1 continue - line = _ppEscape @toffeeSrcLines[i] + line = _ppEscape @toffeeSrcLines[i] padding_len = 5 - ("#{i+1}").length padding = (" " for j in [0...padding_len]).join "" - if cerr.line_range[0] <= (i+1) < cerr.line_range[1] + if (cerr.line_range[0] - 1) <= (i) < cerr.line_range[1] extra = "" else extra = "" @@ -194,16 +205,23 @@ class toffeeError res _lineRangeToPhrase: (lrange) -> - if lrange[0] >= lrange[1] - 1 + if lrange[0] is lrange[1] "on line #{lrange[0]}" else - "between lines #{lrange[0]} and #{lrange[1] - 1}" + "between lines #{lrange[0]} and #{lrange[1]}" _extractOffensiveLineNo: (msg, rxx) -> m = msg.match rxx if not (m?.length >= 2) then return null return parseInt m[1] + _convertJsErrorRangeToToffeeRange: (loc) -> + range = @_convertOffensiveLineToToffeeRange loc.first_line + if loc.last_line? + range2 = @_convertOffensiveLineToToffeeRange loc.last_line + range[1] = range2[1] + return range + _convertOffensiveLineToToffeeRange: (lineno) -> ### Given the error line in a converted file, hunts for surrounding @@ -218,8 +236,8 @@ class toffeeError prev = ol[0...lineno].join "\n" next = ol[lineno...].join "\n" - prev_matches = prev.match /_ln[ ]*([0-9]+)/g - next_matches = next.match /_ln[ ]*([0-9]+)/g + prev_matches = prev.match /_ln[ ]*\(?[ ]*([0-9]+)/g + next_matches = next.match /_ln[ ]*\(?[ ]*([0-9]+)/g res = [1,tl.length] if prev_matches?.length @@ -231,102 +249,9 @@ class toffeeError exports.toffeeError = toffeeError - -# ----------------------------------------------------------------------------- - - - -eh = exports.errorHandler = - - generateRuntimeError: (view, e) -> - ### - e: the error caught when running - ### - src = view.javaScript - msg = e.message - stack = e.stack - - res = - src_line: 0 - toffee_line_range: [0,1] - original_msg: msg - converted_msg: msg - - search = stack.match /pub\ \(undefined\:([0-9]+):[0-9]+/ - if not (search?.length >= 2) then return res - res.src_line = search[1] - src_lines = src.split '\n' - txt_lines = view.txt.split '\n' - before = src_lines[0...res.src_line].join "\n" - after = src_lines[res.src_line...].join "\n" - prev_matches = before.match /__toffee.lineno[ ]*=[ ]*([0-9]+)/g - after_matches = after.match /__toffee.lineno[ ]*=[ ]*([0-9]+)/g - if prev_matches?.length - res.toffee_line_range[0] = parseInt prev_matches[prev_matches.length-1].match(/[0-9]+/)[0] - else - res.toffee_line_range[0] = 1 - if after_matches?.length - res.toffee_line_range[1] = parseInt after_matches[0].match(/[0-9]+/)[0] - else - res.toffee_line_range[1] = txt_lines.length - res.offensive_lines = txt_lines[(res.toffee_line_range[0]-1)...(res.toffee_line_range[1]-1)] - if res.toffee_line_range[0] is res.toffee_line_range[1] - 1 - new_msg = "on line #{res.toffee_line_range[0]}" - else - new_msg = "between lines #{res.toffee_line_range[0]} and #{res.toffee_line_range[1]}" - res.converted_msg = res.original_msg + " " + new_msg - if view.fileName then res.converted_msg = "#{view.fileName}: #{res.converted_msg}" - res - - - generateCompileToJsError: (view, e) -> - ### - e: the error caught when compiling - ### - src = view.coffeeScript - msg = e.message - res = - src_line: 0 - toffee_line_range: [0,1] - original_msg: msg - converted_msg: msg - search = msg.match /on line ([0-9]+)/ - if search?.length >= 2 - res.src_line = search[1] - res.toffee_line_range = @_convertSrcLineToToffeeRange view.coffeeScript, res.src_line - res.offensive_lines = txt_lines[(res.toffee_line_range[0]-1)...(res.toffee_line_range[1]-1)] - if res.toffee_line_range[0] is res.toffee_line_range[1] - 1 - new_msg = "on line #{res.toffee_line_range[0]}" - else - new_msg = "between lines #{res.toffee_line_range[0]} and #{res.toffee_line_range[1]}" - res.converted_msg = res.original_msg.replace "on line #{res.src_line}", new_msg - if view.fileName then res.converted_msg = "#{view.fileName}: #{res.converted_msg}" - res - - prettyPrintError: (view) -> - if not view.error - "" - else - res = """
    """ - res += "#{eh._ppEscape view.error.converted_msg}" - res += "\n
    --------
    " - res += "\n
    " - txt_lines = view.txt.split '\n' - for i in [(view.error.toffee_line_range[0]-3)...(view.error.toffee_line_range[1]+1)] - if (i < 0) or i > txt_lines.length - 1 - continue - line = eh._ppEscape txt_lines[i] - lineno = i+1 - padding_len = 5 - ("#{lineno}").length - padding = (" " for i in [0...padding_len]).join "" - res+= "\n#{lineno}: #{padding} #{line}
    " - res += "\n
    " - res += "\n
    " - res - _ppEscape = (txt) -> txt = txt.replace(/&/g, '&').replace(/ + @_consfn = cons + @_size = size + @_pool = [] + + get: () -> + if @_pool.length > 0 + @_pool.pop() + else + @_consfn() + + release: (x) -> + if @_pool.length < @_size + @_pool.push x + +exports.Pool = Pool diff --git a/src/toffee.jison b/src/toffee.jison index d6f106a..e9d0f86 100644 --- a/src/toffee.jison +++ b/src/toffee.jison @@ -10,10 +10,9 @@ "{##" return 'START_TOFFEE_COMMENT'; "##}" return 'END_TOFFEE_COMMENT'; ":}" return 'END_TOFFEE'; -"{:" return 'START_INDENTED_TOFFEE'; +"{:" return 'START_TOFFEE'; "{#" return 'START_COFFEE'; "#}" return 'END_COFFEE'; -[\-][\t\r\n ]*"{:" return 'START_TOFFEE'; [^{}#\\:\-]+|[\\{}#:\-] return 'CODE'; <> return 'EOF'; @@ -28,24 +27,39 @@ starter toffee_zone EOF { $$ = ["TOFFEE_ZONE", $1]; return $$;} ; + toffee_zone : - toffee_code { $$ = [$1]; } + toffee_code { $$ = [$1]; } | - toffee_code flip_to_coffee toffee_zone { $$ = $3; $3.splice(0,0,$1,$2); } + toffee_code flip_to_coffee toffee_zone { $$ = $3; $3.splice(0,0,$1,$2); } | - flip_to_coffee toffee_zone { $$ = $2; $2.splice(0,0,$1); } + flip_to_coffee toffee_zone { $$ = $2; $2.splice(0,0,$1); } | - toffee_code flip_to_toffeecomment toffee_zone { $$ = $3; $3.splice(0,0,$1); } + toffee_code flip_to_toffee_comment toffee_zone { $$ = $3; $3.splice(0,0,$1); } | - flip_to_toffeecomment toffee_zone { $$ = $2; } + flip_to_toffee_comment toffee_zone { $$ = $2; } | - { $$ = []; } + { $$ = []; } ; -flip_to_toffeecomment +flip_to_toffee_comment : - START_TOFFEE_COMMENT code END_TOFFEE_COMMENT {} + START_TOFFEE_COMMENT toffee_commented_region END_TOFFEE_COMMENT {} + ; + +toffee_commented_region + : + toffee_commented_region START_COFFEE + | + toffee_commented_region END_COFFEE + | + toffee_commented_region START_TOFFEE + | + toffee_commented_region END_TOFFEE + | + toffee_commented_region CODE + | ; flip_to_coffee @@ -67,8 +81,6 @@ coffee_zone flip_to_toffee : START_TOFFEE toffee_zone END_TOFFEE { $$ = ["TOFFEE_ZONE", $2]; } - | - START_INDENTED_TOFFEE toffee_zone END_TOFFEE { $$ = ["INDENTED_TOFFEE_ZONE", $2]; } ; diff --git a/src/view.coffee b/src/view.coffee index f7ff125..0f1ea2f 100644 --- a/src/view.coffee +++ b/src/view.coffee @@ -3,118 +3,199 @@ {states, TAB_SPACES} = require './consts' utils = require './utils' vm = require 'vm' -try +util = require 'util' +try coffee = require "iced-coffee-script" catch e coffee = require "coffee-script" -minimizeJs = (js) -> - # uglify doesn't seem to be working right; #TODO: This - js -getCommonHeaders = (include_bundle_headers) -> +spaces = (n) -> (" " for i in [0...n]).join "" +tabs = (n) -> (spaces(TAB_SPACES) for i in [0...n]).join "" + +getCommonHeaders = (tab_level, include_bundle_headers, auto_escape) -> ### each view will use this, or if they're bundled together, it'll only be used once. include_bundle_headers: includes some functions needed for browser use ### - """ -if not toffee? then toffee = {} -if not toffee.templates then toffee.templates = {} - -toffee.states = #{JSON.stringify states} - -toffee.__json = (locals, o) -> - try - json = JSON.stringify(o).replace(//g,'\\\\u003E').replace(/&/g,'\\\\u0026') - catch e - throw {stack:[], message: "JSONify error (\#{e.message}) on line \#{locals.__toffee.lineno}", toffee_line_base: locals.__toffee.lineno } - "" + json - -toffee.__raw = (locals, o) -> o - -toffee.__html = (locals, o) -> - (""+o).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"') + __ = tabs tab_level -toffee.__escape = (locals, o) -> - if (not locals.__toffee.autoEscape?) or locals.__toffee.autoEscape - if o is undefined then return '' - if o? and (typeof o) is "object" then return locals.json o - return locals.html o - return o - -#{if include_bundle_headers then getBundleHeaders() else ""} + """ +\n +#{__}if not toffee? then toffee = {} +#{__}if not toffee.templates then toffee.templates = {} + +#{__}toffee.states = #{JSON.stringify states} + +#{__}toffee.__json = (locals, o, opts) -> +#{__} opts or= {} +#{__} opts.indent or= "" +#{__} if not o? +#{__} return "null" +#{__} else +#{__} return "" + JSON.stringify(o,null,opts.indent) +#{__} .replace(//g,'\\\\u003E') +#{__} .replace(/&/g,'\\\\u0026').replace(/\\u2028/g, '\\\\u2028') +#{__} .replace(/\\u2029/g, '\\\\u2029') +#{__} .replace(/\\u200e/g, '\\\\u200e') # LEFT-TO-RIGHT MARK +#{__} .replace(/\\u200f/g, '\\\\u200f') # RIGHT-TO-LEFT MARK +#{__} .replace(/\\u202a/g, '\\\\u202a') # LEFT-TO-RIGHT EMBEDDING +#{__} .replace(/\\u202b/g, '\\\\u202b') # RIGHT-TO-LEFT EMBEDDING +#{__} .replace(/\\u202c/g, '\\\\u202c') # POP DIRECTIONAL FORMATTING +#{__} .replace(/\\u202d/g, '\\\\u202d') # LEFT-TO-RIGHT OVERRIDE +#{__} .replace(/\\u202e/g, '\\\\u202e') # RIGHT-TO-LEFT OVERRIDE +#{__} .replace(/\\u206a/g, '\\\\u206a') # INHIBIT SYMMETRIC SWAPPING +#{__} .replace(/\\u206b/g, '\\\\u206b') # ACTIVATE SYMMETRIC SWAPPING +#{__} .replace(/\\u206c/g, '\\\\u206c') # INHIBIT ARABIC FORM SHAPING +#{__} .replace(/\\u206d/g, '\\\\u206d') # ACTIVATE ARABIC FORM SHAPING +#{__} .replace(/\\u206e/g, '\\\\u206e') # NATIONAL DIGIT SHAPES +#{__} .replace(/\\u206f/g, '\\\\u206f') # NOMINAL DIGIT SHAPES +#{__} .replace(/\\u2066/g, '\\\\u2066') # LEFT-TO-RIGHT ISOLATE (LRI) +#{__} .replace(/\\u2067/g, '\\\\u2067') # RIGHT-TO-LEFT ISOLATE (RLI) +#{__} .replace(/\\u2068/g, '\\\\u2068') # FIRST STRONG ISOLATE (FSI) +#{__} .replace(/\\u2069/g, '\\\\u2069') # POP DIRECTIONAL ISOLATE (PDI) + + +#{__}toffee.__raw = (locals, o) -> o + +#{__}toffee.__html = (locals, o) -> +#{__} (""+o).replace(/&/g, '&') +#{__} .replace(//g, '>') +#{__} .replace(/\"/g, '"') +#{__} .replace(/\\u200e/g, '') # LEFT-TO-RIGHT MARK +#{__} .replace(/\\u200f/g, '') # RIGHT-TO-LEFT MARK +#{__} .replace(/\\u202a/g, '') # LEFT-TO-RIGHT EMBEDDING +#{__} .replace(/\\u202b/g, '') # RIGHT-TO-LEFT EMBEDDING +#{__} .replace(/\\u202c/g, '') # POP DIRECTIONAL FORMATTING +#{__} .replace(/\\u202d/g, '') # LEFT-TO-RIGHT OVERRIDE +#{__} .replace(/\\u202e/g, '') # RIGHT-TO-LEFT OVERRIDE +#{__} .replace(/\\u206a/g, '') # INHIBIT SYMMETRIC SWAPPING +#{__} .replace(/\\u206b/g, '') # ACTIVATE SYMMETRIC SWAPPING +#{__} .replace(/\\u206c/g, '') # INHIBIT ARABIC FORM SHAPING +#{__} .replace(/\\u206d/g, '') # ACTIVATE ARABIC FORM SHAPING +#{__} .replace(/\\u206e/g, '') # NATIONAL DIGIT SHAPES +#{__} .replace(/\\u206f/g, '') # NOMINAL DIGIT SHAPES +#{__} .replace(/\\u2066/g, '') # LEFT-TO-RIGHT ISOLATE (LRI) +#{__} .replace(/\\u2067/g, '') # RIGHT-TO-LEFT ISOLATE (RLI) +#{__} .replace(/\\u2068/g, '') # FIRST STRONG ISOLATE (FSI) +#{__} .replace(/\\u2069/g, '') # POP DIRECTIONAL ISOLATE (PDI) + + +#{__}toffee.__escape = (locals, o) -> +#{__} if locals.__toffee.autoEscape? then ae = locals.__toffee.autoEscape +#{__} else if #{auto_escape?} then ae = #{auto_escape} +#{__} else ae = true +#{__} if ae +#{__} if o is undefined then return '' +#{__} if o? and (typeof o) is "object" then return locals.json o +#{__} return locals.html o +#{__} return o + +#{__}toffee.__augmentLocals = (locals, bundle_path) -> +#{__} _l = locals +#{__} _t = _l.__toffee = {out: []} +#{__} if not _l.print? then _l.print = (o) -> toffee.__print _l, o +#{__} if not _l.json? then _l.json = (o, opts) -> toffee.__json _l, o, opts +#{__} if not _l.raw? then _l.raw = (o) -> toffee.__raw _l, o +#{__} if not _l.html? then _l.html = (o) -> toffee.__html _l, o +#{__} if not _l.escape? then _l.escape = (o) -> toffee.__escape _l, o +#{__} if not _l.partial? then _l.partial = (path, vars) -> toffee.__partial toffee.templates["\#{bundle_path}"], _l, path, vars +#{__} if not _l.snippet? then _l.snippet = (path, vars) -> toffee.__snippet toffee.templates["\#{bundle_path}"], _l, path, vars +#{__} if not _l.load? then _l.load = (path, vars) -> toffee.__load toffee.templates["\#{bundle_path}"], _l, path, vars +#{__} _t.print = _l.print +#{__} _t.json = _l.json +#{__} _t.raw = _l.raw +#{__} _t.html = _l.html +#{__} _t.escape = _l.escape +#{__} _t.partial = _l.partial +#{__} _t.snippet = _l.snippet +#{__} _t.load = _l.load + +#{if include_bundle_headers then getBundleHeaders(tab_level) else ""} """ -getBundleHeaders = -> +getBundleHeaders = (tab_level) -> ### - header stuff + header stuff only needed when compiling to a JS file ### + __ = tabs tab_level """ - -toffee.__print = (locals, o) -> - if locals.__toffee.state is toffee.states.COFFEE - locals.__toffee.out.push o - return '' - else - return "\#{o}" - -toffee.__normalize = (path) -> - if (not path?) or path is "/" - return path - else - parts = path.split "/" - np = [] - # make sure path always starts with '/' - if parts[0] - np.push '' - for part in parts - if part is ".." - if np.length > 1 - np.pop() - else - np.push part - else - if part isnt "." - np.push part - path = np.join "/" - if not path then path = "/" - return path - -toffee.__partial = (parent_tmpl, parent_locals, path, vars) -> - path = toffee.__normalize parent_tmpl.bundlePath + "/../" + path - return toffee.__inlineInclude path, vars, parent_locals - -toffee.__snippet = (parent_tmpl, parent_locals, path, vars) -> - path = toffee.__normalize parent_tmpl.bundlePath + "/../" + path - vars = if vars? then vars else {} - vars.__toffee = vars.__toffee or {} - vars.__toffee.noInheritance = true - return toffee.__inlineInclude path, vars, parent_locals - -toffee.__inlineInclude = (path, locals, parent_locals) -> - options = locals or {} - options.__toffee = options.__toffee or {} - - # we need to make a shallow copy of parent variables - if not options.__toffee.noInheritance - for k,v of parent_locals when not locals?[k]? - if not (k in ["print", "partial", "snippet", "layout", "__toffee"]) - options[k] = v - - if not toffee.templates[path] - return "Inline toffee include: Could not find \#{path}" - else - return toffee.templates[path].pub options - +\n +#{__}toffee.__print = (locals, o) -> +#{__} if locals.__toffee.state is toffee.states.COFFEE +#{__} locals.__toffee.out.push o +#{__} return '' +#{__} else +#{__} return "\#{o}" + +#{__}toffee.__normalize = (path) -> +#{__} if (not path?) or path is "/" +#{__} return path +#{__} else +#{__} parts = path.split "/" +#{__} np = [] +#{__} # make sure path always starts with '/' +#{__} if parts[0] +#{__} np.push '' +#{__} for part in parts +#{__} if part is ".." +#{__} if np.length > 1 +#{__} np.pop() +#{__} else +#{__} np.push part +#{__} else +#{__} if part isnt "." +#{__} np.push part +#{__} path = np.join "/" +#{__} if not path then path = "/" +#{__} return path + +#{__}toffee.__partial = (parent_tmpl, parent_locals, path, vars) -> +#{__} path = toffee.__normalize parent_tmpl.bundlePath + "/../" + path +#{__} return toffee.__inlineInclude path, vars, parent_locals + +#{__}toffee.__snippet = (parent_tmpl, parent_locals, path, vars) -> +#{__} path = toffee.__normalize parent_tmpl.bundlePath + "/../" + path +#{__} vars = if vars? then vars else {} +#{__} vars.__toffee = vars.__toffee or {} +#{__} vars.__toffee.noInheritance = true +#{__} return toffee.__inlineInclude path, vars, parent_locals + +#{__}toffee.__load = (parent_tmpl, parent_locals, path, vars) -> +#{__} path = toffee.__normalize parent_tmpl.bundlePath + "/../" + path +#{__} vars = if vars? then vars else {} +#{__} vars.__toffee = vars.__toffee or {} +#{__} vars.__toffee.repress = true +#{__} return toffee.__inlineInclude path, vars, parent_locals + +#{__}toffee.__inlineInclude = (path, locals, parent_locals) -> +#{__} options = locals or {} +#{__} options.passback = {} +#{__} options.__toffee = options.__toffee or {} +#{__} +#{__} # we need to make a shallow copy of parent variables +#{__} reserved = {} +#{__} reserved[k] = true for k in ["passback", "load", "print", "partial", "snippet", "layout", "__toffee", "postProcess"] +#{__} if not options.__toffee.noInheritance +#{__} for k,v of parent_locals when not locals?[k]? +#{__} if not reserved[k]? +#{__} options[k] = v +#{__} +#{__} if not toffee.templates[path] +#{__} return "Inline toffee include: Could not find \#{path}" +#{__} else +#{__} res = toffee.templates[path].pub options +#{__} for k,v of options.passback +#{__} parent_locals[k] = v +#{__} return res """ -getCommonHeadersJs = (include_bundle_headers, minimize)-> - ch = getCommonHeaders include_bundle_headers +getCommonHeadersJs = (include_bundle_headers, auto_escape)-> + ch = getCommonHeaders 0, include_bundle_headers, auto_escape js = coffee.compile ch, {bare: true} - if minimize then js = minimizeJs js js class view @@ -125,37 +206,41 @@ class view cb: if this is set, compilation will happen async and cb will be executed when it's ready ### options = options or {} - @fileName = options.fileName or options.filename or null - @bundlePath = options.bundlePath or "/" # if to be included inside a bundle, this is the path inside it. - @browserMode = options.browserMode or false - @minimize = options.minimize or false # excludes line numbers from coffee ; uses uglify.JS - @verbose = options.verbose or false - @prettyPrintErrors = if options.prettyPrintErrors? then options.prettyPrintErrors else true - @txt = txt - @tokenObj = null # constructed as needed - @coffeeScript = null # constructed as needed - @javaScript = null # constructed as needed - @scriptObj = null # constructed as needed - @error = null # if err, instance of toffeeError class + @fileName = options.fileName or options.filename or null + @bundlePath = options.bundlePath or "/" # if to be included inside a bundle, this is the path inside it. + @browserMode = options.browserMode or false + @verbose = options.verbose or false + @fsError = options.fsError or false # pass true if you could not load the view template and passed in error text + @prettyPrintErrors = if options.prettyPrintErrors? then options.prettyPrintErrors else true + @prettyLogErrors = if options.prettyLogErrors? then options.prettyLogErrors else false + @autoEscape = if options.autoEscape? then options.autoEscape else false + @additionalErrorHandler = options.additionalErrorHandler or null + @txt = txt + @tokenObj = null # constructed as needed + @coffeeScript = null # constructed as needed + @javaScript = null # constructed as needed + @fun = null # constructed as needed + @error = null # if err, instance of toffeeError class if options.cb - @_prepAsync txt, => - options.cb @ + @_prepAsync txt, options.ctx, (=> options.cb @) + - _prepAsync: (txt, cb) -> + _prepAsync: (txt, ctx, cb) -> ### Only once it's fully compiled does it callback. Defers via setTimeouts in each stage in the compile process for CPU friendliness. This is a lot prettier with iced-coffee-script. ### + ctx = ctx or vm.createContext({}) @_log "Prepping #{if @fileName? then @fileName else 'unknown'} async." @_toTokenObj() v = @ setTimeout -> - v._toCoffee() + v.toCoffee() setTimeout -> - v._toJavaScript() + v.toJavaScript() setTimeout -> - v._toScriptObj() + v._toFun(ctx) v._log "Done async prep of #{if v.fileName? then v.fileName else 'unknown'}. Calling back." cb() , 0 @@ -173,36 +258,42 @@ class view ### replaces tabs with spaces in their coffee regions ### - if obj[0] in ["INDENTED_TOFFEE_ZONE", "TOFFEE_ZONE", "COFFEE_ZONE"] + if obj[0] in ["TOFFEE_ZONE", "COFFEE_ZONE"] @_cleanTabs item for item in obj[1] else if obj[0] is "COFFEE" - obj[1] = obj[1].replace /\t/g, @_tabAsSpaces() + obj[1] = obj[1].replace /\t/g, tabs 1 - run: (options) -> + run: (options, ctx) -> ### returns [err, str] ### - script = @_toScriptObj() + ctx = ctx or vm.createContext({}) + fun = @_toFun(ctx) res = null if not @error try - sandbox = { __toffee_run_input: options } - script.runInNewContext sandbox - res = sandbox.__toffee_run_input.__toffee.res - delete sandbox.__toffee_run_input.__toffee + res = fun options catch e @error = new toffeeError @, errorTypes.RUNTIME, e if @error + if @prettyLogErrors + txt = @error.getPrettyPrintText() + for line in txt.split "\n" + console.log "toffee err: #{line}" + if @additionalErrorHandler + @additionalErrorHandler @error.getPrettyPrintText(), @error.getPrettyPrint(), @fileName, options + if @prettyPrintErrors pair = [null, @error.getPrettyPrint()] else - pair = [null, @error.getPrettyPrintText()] + pair = [@error.e, null] if @error.errType is errorTypes.RUNTIME # don't hold onto runtime errors after value returned. @error = null else pair = [null, res] + return pair _toTokenObj: -> @@ -219,54 +310,56 @@ class view @tokenObj - _toScriptObj: -> - if not @scriptObj? - txt = @_toJavaScript() + _toFun: (ctx) -> + if not @fun? + txt = @toJavaScript() if not @error d = Date.now() - @scriptObj = vm.createScript txt + vm.runInContext(txt, ctx) + @fun = ctx['_TMPL_'] @_log "#{@fileName} compiled to scriptObj in #{Date.now()-d}ms" - @scriptObj + @fun - _toJavaScript: -> + toJavaScript: -> if not @javaScript? - c = @_toCoffee() + c = @toCoffee() if not @error d = Date.now() try - @javaScript = coffee.compile c, {bare: false} + opts = { bare: true } + if @browserMode + opts.bare = false + @javaScript = coffee.compile c, opts catch e @error = new toffeeError @, errorTypes.COFFEE_COMPILE, e - if @minimize and not @error - d2 = Date.now() - @javaScript = minimizeJs @javaScript @_log "#{@fileName} compiled to JavaScript in #{Date.now()-d}ms" @javaScript - _toCoffee: -> + toCoffee: -> if not @coffeeScript? tobj = @_toTokenObj() if not @error d = Date.now() res = @_coffeeHeaders() try - res += @_toCoffeeRecurse(tobj, TAB_SPACES, 0)[0] + res += @_toCoffeeRecurse(tobj, TAB_SPACES * (1 + @_globalTabLevel()), 0, {})[0] res += @_coffeeFooters() @coffeeScript = res - catch e + catch e + console.log e @error # already assigned inside _toCoffeeRecurse @_log "#{@fileName} compiled to CoffeeScript in #{Date.now()-d}ms" @coffeeScript _printLineNo: (n, ind) -> - if @minimize or (@lastLineNo? and (n is @lastLineNo)) + if (@lastLineNo? and (n is @lastLineNo)) return "" else @lastLineNo = n - return "\n#{@_space ind}_ln #{n}" + return "\n#{spaces ind}_ln #{n}" _snippetHasEscapeOverride: (str) -> - for token in ['print',' snippet', 'partial', 'raw', 'html', 'json', '__toffee.raw', '__toffee.html', '__toffee.json', 'JSON.stringify'] + for token in ['print',' snippet', 'load', 'partial', 'raw', 'html', 'json', '__toffee.raw', '__toffee.html', '__toffee.json'] if str[0...token.length] is token if (str.length > token.length) and (str[token.length] in [' ','\t','\n','(']) return true @@ -286,35 +379,32 @@ class view return false - _toCoffeeRecurse: (obj, indent_level, indent_baseline) -> + _toCoffeeRecurse: (obj, indent_level, indent_baseline, state_carry) -> # returns [res, indent_baseline_delta] # indent_level = # of spaces to add to each coffeescript section - # indent_baseline = # of chars to strip from each line inside {# #} + # indent_baseline = # of chars to strip from each line inside {# #} res = "" i_delta = 0 switch obj[0] - when "INDENTED_TOFFEE_ZONE" - indent_level += TAB_SPACES - for item in obj[1] - [s, delta] = @_toCoffeeRecurse item, indent_level, indent_baseline - res += s when "TOFFEE_ZONE" - res += "\n#{@_space indent_level}_ts #{states.TOFFEE}" + if state_carry.last_coffee_ends_with_newline is false + indent_level += TAB_SPACES + res += "\n#{spaces indent_level}_ts #{states.TOFFEE}" for item in obj[1] - [s, delta] = @_toCoffeeRecurse item, indent_level, indent_baseline + [s, delta] = @_toCoffeeRecurse item, indent_level, indent_baseline, state_carry res += s when "COFFEE_ZONE" - res += "\n#{@_space indent_level}_ts #{states.COFFEE}" + res += "\n#{spaces indent_level}_ts #{states.COFFEE}" zone_baseline = @_getZoneBaseline obj[1] temp_indent_level = indent_level for item in obj[1] - [s, delta] = @_toCoffeeRecurse item, temp_indent_level, zone_baseline + [s, delta] = @_toCoffeeRecurse item, temp_indent_level, zone_baseline, state_carry res += s temp_indent_level = indent_level + delta when "TOFFEE" ind = indent_level - res += "\n#{@_space ind}_ts #{states.TOFFEE}" + res += "\n#{spaces ind}_ts #{states.TOFFEE}" lineno = obj[2] try t_int = utils.interpolateString obj[1] @@ -326,30 +416,33 @@ class view if part[0] is "TOKENS" res += @_printLineNo lineno, ind interp = part[1].replace /(^[\n \t]+)|([\n \t]+)$/g, '' + interp = interp.replace /[\u2028\u2029]/g , '\n' if @_snippetIsSoloToken interp chunk = "\#{if #{interp}? then escape #{interp} else ''}" else if @_snippetHasEscapeOverride interp chunk = "\#{#{interp}}" else chunk = "\#{escape(#{interp})}" - res += "\n#{@_space ind}_to #{@_quoteStr chunk}" + res += "\n#{spaces ind}_to #{@_quoteStr chunk}" lineno += part[1].split("\n").length - 1 else - lines = part[1].split "\n" + lines = part[1].split /[\n\u2028\u2029]/ for line,i in lines res += @_printLineNo lineno, ind lbreak = if i isnt lines.length - 1 then "\n" else "" chunk = @_escapeForStr "#{line}#{lbreak}" if chunk.length - res += "\n#{@_space ind}_to #{@_quoteStr(chunk + lbreak)}" + res += "\n#{spaces ind}_to #{@_quoteStr(chunk + lbreak)}" if i < lines.length - 1 then lineno++ res += @_printLineNo obj[2] + (obj[1].split('\n').length-1), ind - res += "\n#{@_space ind}_ts #{states.COFFEE}" + res += "\n#{spaces ind}_ts #{states.COFFEE}" when "COFFEE" c = obj[1] + c = c.replace /[\u2028\u2029]/g , '\n' res += "\n#{@_reindent c, indent_level, indent_baseline}" i_delta = @_getIndentationDelta c, indent_baseline - else + state_carry.last_coffee_ends_with_newline = @_doesEndWithNewline c + else throw "Bad parsing. #{obj} not handled." return ["",0] @@ -375,6 +468,13 @@ class view if follow.length then res += "+ \'#{follow}\'" res + _doesEndWithNewline: (s) -> + parts = s.split "\n" + if (parts.length > 1) and parts[parts.length - 1].match /^[\t ]*$/ + return true + else + return false + _escapeForStr: (s) -> ### escapes a string so it can make it into coffeescript @@ -417,17 +517,17 @@ class view if not baseline? then baseline = @_getIndentationBaseline coffee if not baseline? res = 0 - else + else lines = coffee.split "\n" if lines.length < 1 res = 0 - else + else y = lines[lines.length - 1] y_l = y.match(/[ ]*/)[0].length res = y_l - baseline return res - _reindent: (coffee, indent_level, indent_baseline) -> + _reindent: (coffee, indent_level, indent_baseline) -> lines = coffee.split '\n' # strip out any leading whitespace lines while lines.length and lines[0].match /^[ ]*$/ @@ -435,58 +535,48 @@ class view return '' unless lines.length rxx = /^[ ]*/ strip = indent_baseline - indent = @_space indent_level + indent = spaces indent_level res = ("#{indent}#{line[strip...]}" for line in lines).join "\n" res - _space: (indent) -> (" " for i in [0...indent]).join "" - - _tabAsSpaces: -> (" " for i in [0...TAB_SPACES]).join "" + _globalTabLevel: -> + if @browserMode then 0 else 1 - _coffeeHeaders: -> - ___ = @_tabAsSpaces() + _globalTabs: -> tabs @_globalTabLevel() + _coffeeHeaders: -> + __ = @_globalTabs() + ___ = tabs 1 # guaranteed tabs """ -#{if @browserMode then '' else getCommonHeaders(false)} -tmpl = toffee.templates["#{@bundlePath}"] = - bundlePath: "#{@bundlePath}" -tmpl.pub = (locals) -> -#{___}_l = locals -#{___}_t = _l.__toffee = { out: []} -#{___}_to = (x) -> locals.__toffee.out.push x -#{___}_ln = (x) -> locals.__toffee.lineno = x -#{___}_ts = (x) -> locals.__toffee.state = x - -#{___}if not _l.print? then _l.print = (o) -> toffee.__print _l, o -#{___}if not _l.json? then _l.json = (o) -> toffee.__json _l, o -#{___}if not _l.raw? then _l.raw = (o) -> toffee.__raw _l, o -#{___}if not _l.html? then _l.html = (o) -> toffee.__html _l, o -#{___}if not _l.escape? then _l.escape = (o) -> toffee.__escape _l, o -#{___}if not _l.partial? then _l.partial = (path, vars) -> toffee.__partial toffee.templates["#{@bundlePath}"], _l, path, vars -#{___}if not _l.snippet? then _l.snippet = (path, vars) -> toffee.__snippet toffee.templates["#{@bundlePath}"], _l, path, vars - -#{___}_t.print = _l.print -#{___}_t.json = _l.json -#{___}_t.raw = _l.raw -#{___}_t.html = _l.html -#{___}_t.escape = _l.escape -#{___}_t.partial = _l.partial -#{___}_t.snippet = _l.snippet - -#{___}`with (locals) {` -#{___}__toffee.out = [] +#{if @browserMode then '' else ('_TMPL_ = (__toffee_run_input) ->' + (getCommonHeaders 1, false, @autoEscape)) } +#{__}# browser mode = #{@browserMode} +#{__}tmpl = toffee.templates["#{@bundlePath}"] = +#{__} bundlePath: "#{@bundlePath}" +#{__}tmpl.render = tmpl.pub = (__locals) -> +#{__}#{___}__locals = __locals or {} +#{__}#{___}__repress = __locals.__toffee?.repress +#{__}#{___}_to = (x) -> __locals.__toffee.out.push x +#{__}#{___}_ln = (x) -> __locals.__toffee.lineno = x +#{__}#{___}_ts = (x) -> __locals.__toffee.state = x +#{__}#{___}toffee.__augmentLocals __locals, "#{@bundlePath}" + +#{__}#{___}`with (__locals) {` +#{__}#{___}__toffee.out = [] """ _coffeeFooters: -> - ___ = @_tabAsSpaces() + __ = @_globalTabs() + ___ = tabs 1 # guaranteed tabs """\n -#{___}__toffee.res = __toffee.out.join "" -#{___}return __toffee.res -#{___}`} /* closing JS 'with' */ ` -# sometimes we want to execute the whole thing in a sandbox -# and just output results -if __toffee_run_input? -#{___}return tmpl.pub __toffee_run_input +#{__}#{___}__toffee.res = __toffee.out.join "" +#{__}#{___}if postProcess? +#{__}#{___}#{___}__toffee.res = postProcess __toffee.res +#{__}#{___}if (not __repress) then return __toffee.res else return "" +#{__}`true; } /* closing JS 'with' */ ` +#{__}# sometimes we want to execute the whole thing in a sandbox +#{__}# and just output results +#{__}if __toffee_run_input? +#{__}#{___}return tmpl.pub __toffee_run_input """ exports.view = view diff --git a/test/cases/bad_unicode/input.toffee b/test/cases/bad_unicode/input.toffee new file mode 100644 index 0000000..f184e18 --- /dev/null +++ b/test/cases/bad_unicode/input.toffee @@ -0,0 +1,8 @@ +\u2028:
 +\u2029:
 +{# + u2028 = "
" + u2029 = "
" +#} +

    HI 2028: #{"
"}

    +

    HI 2028: #{"
"}

    diff --git a/test/cases/bad_unicode/output.toffee b/test/cases/bad_unicode/output.toffee new file mode 100644 index 0000000..e7f9c21 --- /dev/null +++ b/test/cases/bad_unicode/output.toffee @@ -0,0 +1,7 @@ +\u2028: + +\u2029: + + +

    HI 2028:

    +

    HI 2028:

    diff --git a/test/cases/comments/input.toffee b/test/cases/comments/input.toffee index 89cc52b..54655cf 100644 --- a/test/cases/comments/input.toffee +++ b/test/cases/comments/input.toffee @@ -17,5 +17,16 @@ Pass 2 ### #} -Pass 3 -{## Fail ##}{## Fail ##} \ No newline at end of file +Pass 3{## Fail ##}{## Fail ##} +{## + Fail + #{"Fail"} + {# + for x in [1...100] {: + #{"Fail"} + {# + print "Fail" + #} + :} + #} +##} \ No newline at end of file diff --git a/test/cases/custom_escape/input.toffee b/test/cases/custom_escape/input.toffee index d308ca6..6f45042 100644 --- a/test/cases/custom_escape/input.toffee +++ b/test/cases/custom_escape/input.toffee @@ -1,31 +1,11 @@ {# - x = '"Hello world"' + x = '"Hello world"' y = '' z = 'click&clack' w = [1, 2, {"place": "The Dreadfort"}] #}

    - default x = #{x} - default y = #{y} - default z = #{z} - default w = #{w} -

    -

    - raw x = #{raw x} - raw y = #{raw y} - raw z = #{raw z} - raw w = #{raw w} -

    - -

    -{# - print " raw printed x = #{x}\n" - print " raw printed y = #{y}\n" - print " raw printed z = #{z}\n" - print " raw printed w = #{w}" -#} + custom x = #{x} + custom y = #{y} + custom z = #{z} + custom w = #{w}

    \ No newline at end of file diff --git a/test/cases/custom_escape/output.toffee b/test/cases/custom_escape/output.toffee index 73b29fb..008e9a4 100644 --- a/test/cases/custom_escape/output.toffee +++ b/test/cases/custom_escape/output.toffee @@ -1,24 +1,6 @@

    - default x = ["Hello world"] - default y = [] - default z = [click&clack] - default w = [1,2,[object Object]] -

    -

    - raw x = "Hello world" - raw y = - raw z = click&clack - raw w = 1,2,[object Object] -

    - -

    - raw printed x = "Hello world" - raw printed y = - raw printed z = click&clack - raw printed w = 1,2,[object Object] + custom x = Helloworldscriptvarx100script + custom y = td + custom z = clickclack + custom w = 12objectObject

    \ No newline at end of file diff --git a/test/cases/custom_escape/vars.coffee b/test/cases/custom_escape/vars.coffee new file mode 100644 index 0000000..643dc53 --- /dev/null +++ b/test/cases/custom_escape/vars.coffee @@ -0,0 +1,3 @@ +{ + escape: (s) -> "#{s}".replace /[^a-z0-9]/gi, '' +} \ No newline at end of file diff --git a/test/cases/custom_escape/vars.js b/test/cases/custom_escape/vars.js deleted file mode 100644 index 61d8a4d..0000000 --- a/test/cases/custom_escape/vars.js +++ /dev/null @@ -1,3 +0,0 @@ -{ - "escape": function(str) { return "[" + str + "]"; } -} \ No newline at end of file diff --git a/test/cases/escape/input.toffee b/test/cases/escape/input.toffee index 9d77017..697235e 100644 --- a/test/cases/escape/input.toffee +++ b/test/cases/escape/input.toffee @@ -2,14 +2,19 @@ x = '"Hello world"' y = '
    ' z = 'click&clack' - w = [1, 2, {"place": "The Dreadfort"}] + w = [1, 2, {"place": "The Dreadfort", "evil \"code\"": "italic"}] + v = ["\u2028", "\u2029"] + dir = ["hi\u{202e}there"] # ltr type things #}

    default x = #{x} default y = #{y} default z = #{z} default w = #{w} - default r = #{r} - default w.foo = #{w.foo} + default r = #{r}eol + default w.foo = #{w.foo}eol + default v = #{v} + default dir = #{dir} + default dir0 = #{dir[0]}

    raw x = #{raw x} @@ -17,11 +22,16 @@ raw z = #{raw z} raw w = #{raw w}

    +
    +  w_as_json_stringify=#{JSON.stringify w}
    +  w_as_json_stringify_raw=#{raw JSON.stringify w}
    +

    {# @@ -36,7 +46,8 @@ print " json printed x = #{ raw raw raw raw json x }\n" print " json printed y = #{ raw raw raw raw json y }\n" print " json printed z = #{ raw raw raw raw json z }\n" - print " json printed w = #{ raw raw raw raw json w }" + print " json printed w = #{ raw raw raw raw json w }\n" + print " json printed v = #{ raw raw raw raw json v }" #}

    @@ -46,4 +57,4 @@ print " html printed longhand z = #{ __toffee.html z }\n" print " html printed longhand w = #{ __toffee.html w }" #} -

    \ No newline at end of file +

    diff --git a/test/cases/escape/output.toffee b/test/cases/escape/output.toffee index 6fdefe5..7624efa 100644 --- a/test/cases/escape/output.toffee +++ b/test/cases/escape/output.toffee @@ -2,9 +2,12 @@ default x = "Hello world" default y = <hr /> default z = click&clack - default w = [1,2,{"place":"The Dreadfort"}] - default r = - default w.foo = + default w = [1,2,{"place":"The Dreadfort","evil \u003Cb\u003E\"code\"\u003C/b\u003E":"\u003Ci\u003Eitalic\u003C/i\u003E"}] + default r = eol + default w.foo = eol + default v = ["\u2028","\u2029"] + default dir = ["hi\u202ethere"] + default dir0 = hithere

    raw x = "Hello world" @@ -12,11 +15,16 @@ raw z = click&clack raw w = 1,2,[object Object]

    +
    +  w_as_json_stringify=[1,2,{"place":"The Dreadfort","evil <b>\"code\"</b>":"<i>italic</i>"}]
    +  w_as_json_stringify_raw=[1,2,{"place":"The Dreadfort","evil \"code\"":"italic"}]
    +

    raw printed x = "Hello world" @@ -28,11 +36,12 @@ json printed x = "\"Hello world\"" json printed y = "\u003Chr /\u003E" json printed z = "click\u0026clack" - json printed w = [1,2,{"place":"The Dreadfort"}] + json printed w = [1,2,{"place":"The Dreadfort","evil \u003Cb\u003E\"code\"\u003C/b\u003E":"\u003Ci\u003Eitalic\u003C/i\u003E"}] + json printed v = ["\u2028","\u2029"]

    html printed longhand x = "Hello world" html printed longhand y = <hr /> html printed longhand z = click&clack html printed longhand w = 1,2,[object Object] -

    \ No newline at end of file +

    diff --git a/test/cases/include_order/input.toffee b/test/cases/include_order/input.toffee index 663c0be..76d5abf 100644 --- a/test/cases/include_order/input.toffee +++ b/test/cases/include_order/input.toffee @@ -1,6 +1,6 @@ {# say_hi = -> - -{:hi:} + {:hi:} #}1 2 #{partial "child.toffee", say_hi: say_hi} diff --git a/test/cases/include_techniques/input.toffee b/test/cases/include_techniques/input.toffee index 61cb308..63b1a9b 100644 --- a/test/cases/include_techniques/input.toffee +++ b/test/cases/include_techniques/input.toffee @@ -2,6 +2,6 @@ #{partial "message.toffee", from: "Max & Sam"} {# print partial "message.toffee", from: "Christian" - -{:#{partial "message.toffee", from: "Jennie"}:} - print partial "message.toffee", sender: "The enemy" + {:#{ partial "message.toffee", from: "Jennie"}:} + print partial "message.toffee", sender: "The enemy" #} \ No newline at end of file diff --git a/test/cases/indent_attack/input.toffee b/test/cases/indent_attack/input.toffee index f63c1bc..d552e88 100644 --- a/test/cases/indent_attack/input.toffee +++ b/test/cases/indent_attack/input.toffee @@ -51,21 +51,52 @@ print 'Pass7' else print 'Fail' - {:Fail8:} - -{:Pass8:} + {:Fail8:} + {:Pass8:} #} {# - -{:...passed with flying colors.:} + {:...passed with flying colors.:} +#}{## +{# + if true and 10 is 10 + {: + Pass9 + :} + print "Pass10" + if 11 is 12 + print "Fail" + if 12 is 13 {: + Fail + :} + else + {: + Pass11 + :} + else if 11 is 12 + {: + Fail + :} #} +##}

    {# - x = 10 + x = 20 if x > 1 - for i in [0...x] - {:
    #{i}{# - if i is 3 {: (my favorite number) :} + for i in [12...x] + square = 16 + {:Pass#{i}{# + if i is square {:(a perfect square):} #}:} #} + {# + x = 20 + if x > 1 + for i in [12...x] + square = 16 + {:Pass#{i}{# + if i is square {:(a perfect square):} + #}:} + #}

    \ No newline at end of file diff --git a/test/cases/indent_attack/output.toffee b/test/cases/indent_attack/output.toffee index eb0dc63..5da2813 100644 --- a/test/cases/indent_attack/output.toffee +++ b/test/cases/indent_attack/output.toffee @@ -11,5 +11,6 @@ Pass7Pass8 ...passed with flying colors.

    -
    0
    1
    2
    3 (my favorite number)
    4
    5
    6
    7
    8
    9 + Pass12Pass13Pass14Pass15Pass16(a perfect square)Pass17Pass18Pass19 + Pass20

    \ No newline at end of file diff --git a/test/cases/json_formatting/input.toffee b/test/cases/json_formatting/input.toffee new file mode 100644 index 0000000..673bead --- /dev/null +++ b/test/cases/json_formatting/input.toffee @@ -0,0 +1,12 @@ +{# + x = + foo: [1,2,3] + bar: + car: [4,5,"<\/html",{zar: [6,7,null]}] + y = [1,2,"<\/script>\""] +#} +#{x} +#{json x, {indent: ' '}} +#{json x, {indent: 2}} +#{json x, {indent: '\t'}} +#{__toffee.json y, {indent:3}} diff --git a/test/cases/json_formatting/output.toffee b/test/cases/json_formatting/output.toffee new file mode 100644 index 0000000..f9e8db4 --- /dev/null +++ b/test/cases/json_formatting/output.toffee @@ -0,0 +1,70 @@ + +{"foo":[1,2,3],"bar":{"car":[4,5,"\u003C/html",{"zar":[6,7,null]}]}} +{ + "foo": [ + 1, + 2, + 3 + ], + "bar": { + "car": [ + 4, + 5, + "\u003C/html", + { + "zar": [ + 6, + 7, + null + ] + } + ] + } +} +{ + "foo": [ + 1, + 2, + 3 + ], + "bar": { + "car": [ + 4, + 5, + "\u003C/html", + { + "zar": [ + 6, + 7, + null + ] + } + ] + } +} +{ + "foo": [ + 1, + 2, + 3 + ], + "bar": { + "car": [ + 4, + 5, + "\u003C/html", + { + "zar": [ + 6, + 7, + null + ] + } + ] + } +} +[ + 1, + 2, + "\u003C/script\u003E\"" +] diff --git a/test/cases/junk/input.toffee b/test/cases/junk/input.toffee index 7d402e3..c0420b0 100644 --- a/test/cases/junk/input.toffee +++ b/test/cases/junk/input.toffee @@ -2,4 +2,4 @@ supplies = ["broom", "mop", "vacuum"] #}
      {# for supply in supplies {:
    • #{supply}
    • :} #} -
    \ No newline at end of file + diff --git a/test/cases/junk/output.toffee b/test/cases/junk/output.toffee index 5e50d3c..f60f38f 100644 --- a/test/cases/junk/output.toffee +++ b/test/cases/junk/output.toffee @@ -1,3 +1,3 @@
    • broom
    • mop
    • vacuum
    • -
    \ No newline at end of file + diff --git a/test/cases/lambda_fns/input.toffee b/test/cases/lambda_fns/input.toffee index a3b4087..d827176 100644 --- a/test/cases/lambda_fns/input.toffee +++ b/test/cases/lambda_fns/input.toffee @@ -2,9 +2,9 @@ print_it = (msg) -> {:#{msg}:} print_it_twice = (msg) -> - -{:#{msg}:} + {:#{msg}:} m = msg - -{:#{m}:} + {:#{m}:} echo_it = (msg) -> v = msg diff --git a/test/cases/passback/const1.toffee b/test/cases/passback/const1.toffee new file mode 100644 index 0000000..9ade052 --- /dev/null +++ b/test/cases/passback/const1.toffee @@ -0,0 +1,7 @@ +{# + passback.vx = "vx1" + passback.vy = "vy1" + passback.x = "oh shit" + passback.y = "oh noze" +#} +This should output (1). \ No newline at end of file diff --git a/test/cases/passback/const2.toffee b/test/cases/passback/const2.toffee new file mode 100644 index 0000000..d626b3a --- /dev/null +++ b/test/cases/passback/const2.toffee @@ -0,0 +1,6 @@ +{# + passback.vz = "vz2" + vx = "Should not set." + vy = "Should not set." +#} +This should not output (2). \ No newline at end of file diff --git a/test/cases/passback/const3.toffee b/test/cases/passback/const3.toffee new file mode 100644 index 0000000..2f9d296 --- /dev/null +++ b/test/cases/passback/const3.toffee @@ -0,0 +1,5 @@ +{# + passback["vx"] = "vx3" + passback["vy"] = "vy3" +#} +This should not output (3). \ No newline at end of file diff --git a/test/cases/passback/const4.toffee b/test/cases/passback/const4.toffee new file mode 100644 index 0000000..fe80dcb --- /dev/null +++ b/test/cases/passback/const4.toffee @@ -0,0 +1,6 @@ +{# + passback.vx = "vx4" + passback.vy = "vy4" + partial "./const4_sub.toffee" +#} +This should not output (4). \ No newline at end of file diff --git a/test/cases/passback/const4_sub.toffee b/test/cases/passback/const4_sub.toffee new file mode 100644 index 0000000..515a618 --- /dev/null +++ b/test/cases/passback/const4_sub.toffee @@ -0,0 +1,5 @@ +{# + passback.vx = "vx4_sub" + passback.vy = "vy4_sub" +#} +This should not output (4_sub). \ No newline at end of file diff --git a/test/cases/passback/const5.toffee b/test/cases/passback/const5.toffee new file mode 100644 index 0000000..549fc16 --- /dev/null +++ b/test/cases/passback/const5.toffee @@ -0,0 +1,8 @@ +{# + passback.vx = "vx5" + passback.vy = "vy5" + print load "./const5_sub.toffee" + passback.vx = vx + passback.vy = vy +#} +This should not output (5). \ No newline at end of file diff --git a/test/cases/passback/const5_sub.toffee b/test/cases/passback/const5_sub.toffee new file mode 100644 index 0000000..b3453f2 --- /dev/null +++ b/test/cases/passback/const5_sub.toffee @@ -0,0 +1,5 @@ +{# + passback.vx = "vx5_sub" + passback.vy = "vy5_sub" +#} +This should not output (5_sub). \ No newline at end of file diff --git a/test/cases/passback/input.toffee b/test/cases/passback/input.toffee new file mode 100644 index 0000000..03104e0 --- /dev/null +++ b/test/cases/passback/input.toffee @@ -0,0 +1,11 @@ +vx,vy,vz = #{vx},#{vy},#{vz} +#{partial "./const1.toffee"} +vx,vy,vz = #{vx},#{vy},#{vz} +#{load "./const2.toffee"} +vx,vy,vz = #{vx},#{vy},#{vz} +#{load "./const3.toffee"} +vx,vy,vz = #{vx},#{vy},#{vz} +#{load "./const4.toffee"} +vx,vy,vz = #{vx},#{vy},#{vz} +#{load "./const5.toffee"} +vx,vy,vz = #{vx},#{vy},#{vz} \ No newline at end of file diff --git a/test/cases/passback/output.toffee b/test/cases/passback/output.toffee new file mode 100644 index 0000000..72bfdc2 --- /dev/null +++ b/test/cases/passback/output.toffee @@ -0,0 +1,12 @@ +vx,vy,vz = vx0,, + +This should output (1). +vx,vy,vz = vx1,vy1, + +vx,vy,vz = vx1,vy1,vz2 + +vx,vy,vz = vx3,vy3,vz2 + +vx,vy,vz = vx4,vy4,vz2 + +vx,vy,vz = vx5_sub,vy5_sub,vz2 \ No newline at end of file diff --git a/test/cases/passback/vars.js b/test/cases/passback/vars.js new file mode 100644 index 0000000..254c8e7 --- /dev/null +++ b/test/cases/passback/vars.js @@ -0,0 +1,4 @@ +{ + "vx": "vx0", + "x" : "hi" +} \ No newline at end of file diff --git a/test/cases/post_process/buncha_junk.toffee b/test/cases/post_process/buncha_junk.toffee new file mode 100644 index 0000000..e1bf4dc --- /dev/null +++ b/test/cases/post_process/buncha_junk.toffee @@ -0,0 +1 @@ +T3246h354is345-i3245s345-534a534-h534i543d534d534e534n543-m534e543s543s543ag5e534.543 \ No newline at end of file diff --git a/test/cases/post_process/input.toffee b/test/cases/post_process/input.toffee new file mode 100644 index 0000000..4e0f3e0 --- /dev/null +++ b/test/cases/post_process/input.toffee @@ -0,0 +1,7 @@ +#{greeting}, world. +#{partial './signature.toffee'} +{# + reverse = (s) -> (c for c in s by -1).join "" + clean = (s) -> (c for c in s when c.match /[a-z\-]/gi).join "" +#} +#{partial './buncha_junk.toffee', {postProcess: (s) -> reverse(clean(s))}} \ No newline at end of file diff --git a/test/cases/post_process/output.toffee b/test/cases/post_process/output.toffee new file mode 100644 index 0000000..7549b0b --- /dev/null +++ b/test/cases/post_process/output.toffee @@ -0,0 +1,4 @@ +This-is-a-hidden-message + +.dlrow leurc ,eybdooG + .dlrow ,olleH \ No newline at end of file diff --git a/test/cases/post_process/signature.toffee b/test/cases/post_process/signature.toffee new file mode 100644 index 0000000..89c169c --- /dev/null +++ b/test/cases/post_process/signature.toffee @@ -0,0 +1 @@ +Goodbye, cruel world. \ No newline at end of file diff --git a/test/cases/post_process/vars.coffee b/test/cases/post_process/vars.coffee new file mode 100644 index 0000000..d572995 --- /dev/null +++ b/test/cases/post_process/vars.coffee @@ -0,0 +1,4 @@ +{ + greeting: 'Hello' + postProcess: (s) -> (c for c in s by -1).join '' +} \ No newline at end of file diff --git a/test/cases/render_no_args/input.toffee b/test/cases/render_no_args/input.toffee new file mode 100644 index 0000000..951084a --- /dev/null +++ b/test/cases/render_no_args/input.toffee @@ -0,0 +1 @@ +No arguments passed. \ No newline at end of file diff --git a/test/cases/render_no_args/output.toffee b/test/cases/render_no_args/output.toffee new file mode 100644 index 0000000..951084a --- /dev/null +++ b/test/cases/render_no_args/output.toffee @@ -0,0 +1 @@ +No arguments passed. \ No newline at end of file diff --git a/test/cases/special_cases/input.toffee b/test/cases/special_cases/input.toffee index 429d51c..563d8a2 100644 --- a/test/cases/special_cases/input.toffee +++ b/test/cases/special_cases/input.toffee @@ -4,7 +4,7 @@ ##} {# - -{:"PASSED":} + {:"PASSED":} #} {## diff --git a/test/express3/app.coffee b/test/express3/app.coffee deleted file mode 100644 index c78a41d..0000000 --- a/test/express3/app.coffee +++ /dev/null @@ -1,31 +0,0 @@ - -express = require 'express' -routes = require './routes' -http = require 'http' -toffee = require 'toffee' - -app = express() - - -app.configure -> - - toffee.expressEngine.verbose = true - #toffee.expressEngine.prettyPrintErrors = false - - app.set 'port', process.env.PORT or 3033 - app.set 'views', __dirname + '/views' - app.set 'view engine', 'toffee' - app.use express.favicon() - app.use express.logger 'dev' - app.use express.bodyParser() - app.use express.methodOverride() - app.use app.router - app.use express.static __dirname + '/public' - -app.configure 'development', -> - app.use express.errorHandler() - -app.get '/', routes.index - -http.createServer(app).listen app.get('port'), -> - console.log "Express server listening on port #{app.get('port')}" \ No newline at end of file diff --git a/test/express3/public/javascripts/test_cases.js b/test/express3/public/javascripts/test_cases.js deleted file mode 100644 index 082406f..0000000 --- a/test/express3/public/javascripts/test_cases.js +++ /dev/null @@ -1,4203 +0,0 @@ -var toffee; - -if (!(typeof toffee !== "undefined" && toffee !== null)) toffee = {}; - -if (!toffee.templates) toffee.templates = {}; - -toffee.states = { - "TOFFEE": 1, - "COFFEE": 2 -}; - -toffee.__json = function(locals, o) { - var json; - try { - json = JSON.stringify(o).replace(//g, '\\u003E').replace(/&/g, '\\u0026'); - } catch (e) { - throw { - stack: [], - message: "JSONify error (" + e.message + ") on line " + locals.__toffee.lineno, - toffee_line_base: locals.__toffee.lineno - }; - } - return "" + json; -}; - -toffee.__raw = function(locals, o) { - return o; -}; - -toffee.__html = function(locals, o) { - return ("" + o).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); -}; - -toffee.__escape = function(locals, o) { - if ((!(locals.__toffee.autoEscape != null)) || locals.__toffee.autoEscape) { - if (o === void 0) return ''; - if ((o != null) && (typeof o) === "object") return locals.json(o); - return locals.html(o); - } - return o; -}; - -toffee.__print = function(locals, o) { - if (locals.__toffee.state === toffee.states.COFFEE) { - locals.__toffee.out.push(o); - return ''; - } else { - return "" + o; - } -}; - -toffee.__normalize = function(path) { - var np, part, parts, _i, _len; - if ((!(path != null)) || path === "/") { - return path; - } else { - parts = path.split("/"); - np = []; - if (parts[0]) np.push(''); - for (_i = 0, _len = parts.length; _i < _len; _i++) { - part = parts[_i]; - if (part === "..") { - if (np.length > 1) { - np.pop(); - } else { - np.push(part); - } - } else { - if (part !== ".") np.push(part); - } - } - path = np.join("/"); - if (!path) path = "/"; - return path; - } -}; - -toffee.__partial = function(parent_tmpl, parent_locals, path, vars) { - path = toffee.__normalize(parent_tmpl.bundlePath + "/../" + path); - return toffee.__inlineInclude(path, vars, parent_locals); -}; - -toffee.__snippet = function(parent_tmpl, parent_locals, path, vars) { - path = toffee.__normalize(parent_tmpl.bundlePath + "/../" + path); - vars = vars != null ? vars : {}; - vars.__toffee = vars.__toffee || {}; - vars.__toffee.noInheritance = true; - return toffee.__inlineInclude(path, vars, parent_locals); -}; - -toffee.__inlineInclude = function(path, locals, parent_locals) { - var k, options, v; - options = locals || {}; - options.__toffee = options.__toffee || {}; - if (!options.__toffee.noInheritance) { - for (k in parent_locals) { - v = parent_locals[k]; - if (!((locals != null ? locals[k] : void 0) != null)) { - if (!(k === "print" || k === "partial" || k === "snippet" || k === "layout" || k === "__toffee")) { - options[k] = v; - } - } - } - } - if (!toffee.templates[path]) { - return "Inline toffee include: Could not find " + path; - } else { - return toffee.templates[path].pub(options); - } -}; - -(function() { - var tmpl; - - tmpl = toffee.templates["/big_file/input.toffee"] = { - bundlePath: "/big_file/input.toffee" - }; - - tmpl.pub = function(locals) { - var count, i, _i, _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/big_file/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/big_file/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - count = 0; - for (i = _i = 0; _i < 2; i = ++_i) { - _ts(1); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("..."); - _ts(2); - _ts(2); - count += 1; - print(" " + count + "..."); - _ts(1); - _to(" "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("... "); - _to("" + (escape(count++))); - _to("..."); - _ts(2); - _ts(2); - count += 1; - print(" " + count + "..."); - } - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/big_file/output.toffee"] = { - bundlePath: "/big_file/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/big_file/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/big_file/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("0... 1... 2... 3... 4... 5... 6... 7... 8... 9... 10... 11... 12... 13... 14... 15... 16... 17... 18... 19... 20... 21... 22... 23... 24... 25... 26... 27... 28... 29... 30... 31... 32... 33... 34... 35... 36... 37... 38... 39... 40... 41... 42... 43... 44... 45... 46... 47... 48... 49... 50... 51... 52... 53... 54... 55... 56... 57... 58... 59... 60... 61... 62... 63... 64... 65... 66... 67... 68... 70... 70... 71... 72... 73... 74... 75... 76... 77... 78... 79... 80... 81... 82... 83... 84... 85... 86... 87... 88... 89... 90... 91... 92... 93... 94... 95... 96... 97... 98... 99... 100... 101... 102... 103... 104... 105... 106... 107... 108... 109... 110... 111... 112... 113... 114... 115... 116... 117... 118... 119... 120... 121... 122... 123... 124... 125... 126... 127... 128... 129... 130... 131... 132... 133... 134... 135... 136... 137... 138... 139... 140... 141... 142... 143... 144... 145... 146... 147... 148... 149... 150... 151... 152... 153... 154... 155... 156... 157... 158... 159... 160... 162...162... 163... 164... 165... 166... 167... 168... 169... 170... 171... 172... 173... 174... 175... 176... 177... 178... 179... 180... 181... 182... 183... 184... 185... 186... 187... 188... 189... 190... 191... 192... 193... 194... 195... 196... 197... 198... 199... 200... 201... 202... 203... 204... 205... 206... 207... 208... 209... 210... 211... 212... 213... 214... 215... 216... 217... 218... 219... 220... 221... 222... 223... 224... 225... 226... 227... 228... 229... 230... 232... 232... 233... 234... 235... 236... 237... 238... 239... 240... 241... 242... 243... 244... 245... 246... 247... 248... 249... 250... 251... 252... 253... 254... 255... 256... 257... 258... 259... 260... 261... 262... 263... 264... 265... 266... 267... 268... 269... 270... 271... 272... 273... 274... 275... 276... 277... 278... 279... 280... 281... 282... 283... 284... 285... 286... 287... 288... 289... 290... 291... 292... 293... 294... 295... 296... 297... 298... 299... 300... 301... 302... 303... 304... 305... 306... 307... 308... 309... 310... 311... 312... 313... 314... 315... 316... 317... 318... 319... 320... 321... 322... 324..."); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/comments/input.toffee"] = { - bundlePath: "/comments/input.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/comments/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/comments/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("\n"); - _to("Pass 1\n"); - _ts(2); - _ts(1); - _to("\n"); - _to("Pass 2\n"); - _ts(2); - _ts(2); - /* - print "FAIL FAIL FAIL" - #{ foo } - */ - - _ts(1); - _to("\n"); - _to("Pass 3\n"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/comments/output.toffee"] = { - bundlePath: "/comments/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/comments/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/comments/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("\n"); - _to("Pass 1\n"); - _to("\n"); - _to("Pass 2\n"); - _to("\n"); - _to("Pass 3\n"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/custom_escape/input.toffee"] = { - bundlePath: "/custom_escape/input.toffee" - }; - - tmpl.pub = function(locals) { - var w, x, y, z, _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/custom_escape/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/custom_escape/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - x = '"Hello world"'; - y = ''; - z = 'click&clack'; - w = [ - 1, 2, { - "place": "The Dreadfort" - } - ]; - _ts(1); - _to("

    \n"); - _to(" default x = "); - _to("" + (x != null ? escape(x) : '')); - _to("\n"); - _to(" default y = "); - _to("" + (y != null ? escape(y) : '')); - _to("\n"); - _to(" default z = "); - _to("" + (z != null ? escape(z) : '')); - _to("\n"); - _to(" default w = "); - _to("" + (w != null ? escape(w) : '')); - _to("\n"); - _to("

    \n"); - _to("

    \n"); - _to(" raw x = "); - _to("" + (raw(x))); - _to("\n"); - _to(" raw y = "); - _to("" + (raw(y))); - _to("\n"); - _to(" raw z = "); - _to("" + (raw(z))); - _to("\n"); - _to(" raw w = "); - _to("" + (raw(w))); - _to("\n"); - _to("

    \n"); - _to("\n"); - _to("

    \n"); - _ts(2); - _ts(2); - print(" raw printed x = " + x + "\n"); - print(" raw printed y = " + y + "\n"); - print(" raw printed z = " + z + "\n"); - print(" raw printed w = " + w); - _ts(1); - _to("\n"); - _to("

    "); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/custom_escape/output.toffee"] = { - bundlePath: "/custom_escape/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/custom_escape/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/custom_escape/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("

    \n"); - _to(" default x = [\"Hello world\"]\n"); - _to(" default y = []\n"); - _to(" default z = [click&clack]\n"); - _to(" default w = [1,2,[object Object]]\n"); - _to("

    \n"); - _to("

    \n"); - _to(" raw x = \"Hello world\"\n"); - _to(" raw y = \n"); - _to(" raw z = click&clack\n"); - _to(" raw w = 1,2,[object Object]\n"); - _to("

    \n"); - _to("\n"); - _to("

    \n"); - _to(" raw printed x = \"Hello world\"\n"); - _to(" raw printed y = \n"); - _to(" raw printed z = click&clack\n"); - _to(" raw printed w = 1,2,[object Object]\n"); - _to("

    "); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/eco_compare/input.toffee"] = { - bundlePath: "/eco_compare/input.toffee" - }; - - tmpl.pub = function(locals) { - var f, friends, project, _i, _l, _len, _ln, _ref, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/eco_compare/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/eco_compare/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - this.projects = [ - { - url: "http://localhost:3000", - name: "okcupid", - description: "A site for singles" - }, { - url: "http://localhost:3001", - name: "tallygram", - description: "A site for anyone" - } - ]; - if (this.projects.length) { - _ref = this.projects; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - project = _ref[_i]; - _ts(1); - _to("\n"); - _to(" "); - _to("" + (escape(project.name))); - _to("\n"); - _to("

    "); - _to("" + (escape(project.description))); - _to("

    \n"); - _to(" "); - _ts(2); - } - } else { - _ts(1); - _to(" No projects "); - _ts(2); - } - friends = [ - { - gender: "f", - name: "Jennie" - }, { - gender: "f", - name: "Rachel" - }, { - gender: "m", - name: "Petar" - }, { - gender: "f", - name: "Marissa" - } - ]; - _ts(1); - _to("\n"); - _to("\n"); - _to("You have "); - _to("" + (escape(((function() { - var _j, _len1, _results; - _results = []; - for (_j = 0, _len1 = friends.length; _j < _len1; _j++) { - f = friends[_j]; - if (f.gender === "f") _results.push(f); - } - return _results; - })()).length))); - _to(" female friends."); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/eco_compare/output.toffee"] = { - bundlePath: "/eco_compare/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/eco_compare/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/eco_compare/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("\n"); - _to(" okcupid\n"); - _to("

    A site for singles

    \n"); - _to(" \n"); - _to(" tallygram\n"); - _to("

    A site for anyone

    \n"); - _to(" \n"); - _to("\n"); - _to("You have 3 female friends."); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/escape/input.toffee"] = { - bundlePath: "/escape/input.toffee" - }; - - tmpl.pub = function(locals) { - var w, x, y, z, _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/escape/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/escape/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - x = '"Hello world"'; - y = '
    '; - z = 'click&clack'; - w = [ - 1, 2, { - "place": "The Dreadfort" - } - ]; - _ts(1); - _to("

    \n"); - _to(" default x = "); - _to("" + (x != null ? escape(x) : '')); - _to("\n"); - _to(" default y = "); - _to("" + (y != null ? escape(y) : '')); - _to("\n"); - _to(" default z = "); - _to("" + (z != null ? escape(z) : '')); - _to("\n"); - _to(" default w = "); - _to("" + (w != null ? escape(w) : '')); - _to("\n"); - _to(" default r = "); - _to("" + (typeof r !== "undefined" && r !== null ? escape(r) : '')); - _to("\n"); - _to(" default w.foo = "); - _to("" + (escape(w.foo))); - _to("\n"); - _to("

    \n"); - _to("

    \n"); - _to(" raw x = "); - _to("" + (raw(x))); - _to("\n"); - _to(" raw y = "); - _to("" + (raw(y))); - _to("\n"); - _to(" raw z = "); - _to("" + (raw(z))); - _to("\n"); - _to(" raw w = "); - _to("" + (raw(w))); - _to("\n"); - _to("

    \n"); - _to("\n"); - _to("

    \n"); - _ts(2); - _ts(2); - print(" raw printed x = " + x + "\n"); - print(" raw printed y = " + y + "\n"); - print(" raw printed z = " + z + "\n"); - print(" raw printed w = " + w); - _ts(1); - _to("\n"); - _to("

    \n"); - _to("

    \n"); - _ts(2); - _ts(2); - print(" json printed x = " + (raw(raw(raw(raw(json(x)))))) + "\n"); - print(" json printed y = " + (raw(raw(raw(raw(json(y)))))) + "\n"); - print(" json printed z = " + (raw(raw(raw(raw(json(z)))))) + "\n"); - print(" json printed w = " + (raw(raw(raw(raw(json(w))))))); - _ts(1); - _to("\n"); - _to("

    \n"); - _to("

    \n"); - _ts(2); - _ts(2); - print(" html printed longhand x = " + (__toffee.html(x)) + "\n"); - print(" html printed longhand y = " + (__toffee.html(y)) + "\n"); - print(" html printed longhand z = " + (__toffee.html(z)) + "\n"); - print(" html printed longhand w = " + (__toffee.html(w))); - _ts(1); - _to("\n"); - _to("

    "); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/escape/output.toffee"] = { - bundlePath: "/escape/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/escape/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/escape/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("

    \n"); - _to(" default x = "Hello world"\n"); - _to(" default y = <hr />\n"); - _to(" default z = click&clack\n"); - _to(" default w = [1,2,{\"place\":\"The Dreadfort\"}]\n"); - _to(" default r = \n"); - _to(" default w.foo = \n"); - _to("

    \n"); - _to("

    \n"); - _to(" raw x = \"Hello world\"\n"); - _to(" raw y =


    \n"); - _to(" raw z = click&clack\n"); - _to(" raw w = 1,2,[object Object]\n"); - _to("

    \n"); - _to("\n"); - _to("

    \n"); - _to(" raw printed x = \"Hello world\"\n"); - _to(" raw printed y =


    \n"); - _to(" raw printed z = click&clack\n"); - _to(" raw printed w = 1,2,[object Object]\n"); - _to("

    \n"); - _to("

    \n"); - _to(" json printed x = \"\\\"Hello world\\\"\"\n"); - _to(" json printed y = \"\\u003Chr /\\u003E\"\n"); - _to(" json printed z = \"click\\u0026clack\"\n"); - _to(" json printed w = [1,2,{\"place\":\"The Dreadfort\"}]\n"); - _to("

    \n"); - _to("

    \n"); - _to(" html printed longhand x = "Hello world"\n"); - _to(" html printed longhand y = <hr />\n"); - _to(" html printed longhand z = click&clack\n"); - _to(" html printed longhand w = 1,2,[object Object]\n"); - _to("

    "); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/hello_world/input.toffee"] = { - bundlePath: "/hello_world/input.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/hello_world/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/hello_world/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("" + (typeof greeting !== "undefined" && greeting !== null ? escape(greeting) : '')); - _to(", world."); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/hello_world/output.toffee"] = { - bundlePath: "/hello_world/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/hello_world/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/hello_world/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("Hello, world."); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/hello_world/temp.toffee"] = { - bundlePath: "/hello_world/temp.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/hello_world/temp.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/hello_world/temp.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("a\n"); - _to("b\n"); - _to("c\n"); - _to("" + (escape(passed_fn(100)))); - _to("\n"); - _to("d\n"); - _to("e\n"); - _to("f"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/include_order/child.toffee"] = { - bundlePath: "/include_order/child.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/include_order/child.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/include_order/child.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("a\n"); - _ts(2); - _ts(2); - say_hi(); - _ts(1); - _to("\n"); - _to("b"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/include_order/input.toffee"] = { - bundlePath: "/include_order/input.toffee" - }; - - tmpl.pub = function(locals) { - var say_hi, _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/include_order/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/include_order/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - say_hi = function() { - _ts(1); - _ts(1); - _to("hi"); - return _ts(2); - }; - _ts(1); - _to("1\n"); - _to("2\n"); - _to("" + (partial("child.toffee", { - say_hi: say_hi - }))); - _to("\n"); - _to("3\n"); - _to("4"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/include_order/output.toffee"] = { - bundlePath: "/include_order/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/include_order/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/include_order/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("1\n"); - _to("2\n"); - _to("hia\n"); - _to("\n"); - _to("b\n"); - _to("3\n"); - _to("4"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/include_recursion/input.toffee"] = { - bundlePath: "/include_recursion/input.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/include_recursion/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/include_recursion/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - if (countdown === 0) { - _ts(1); - _to("blastoff!"); - _ts(2); - } else { - print("" + countdown + "..." + (partial('input.toffee', { - countdown: countdown - 1 - }))); - } - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/include_recursion/output.toffee"] = { - bundlePath: "/include_recursion/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/include_recursion/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/include_recursion/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("10...9...8...7...6...5...4...3...2...1...blastoff!"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/include_techniques/input.toffee"] = { - bundlePath: "/include_techniques/input.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/include_techniques/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/include_techniques/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("" + (partial("message.toffee", { - from: "Chris " - }))); - _to("\n"); - _to("" + (partial("message.toffee", { - from: "Max & Sam" - }))); - _to("\n"); - _ts(2); - _ts(2); - print(partial("message.toffee", { - from: "Christian" - })); - _ts(1); - _ts(1); - _to("" + (partial("message.toffee", { - from: "Jennie" - }))); - _ts(2); - print(partial("message.toffee", { - sender: "The enemy" - })); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/include_techniques/message.toffee"] = { - bundlePath: "/include_techniques/message.toffee" - }; - - tmpl.pub = function(locals) { - var from, _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/include_techniques/message.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/include_techniques/message.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - from = from || "Unknown"; - _ts(1); - _to("From: "); - _to("" + (from != null ? escape(from) : '')); - _to(" \n"); - _to("Msg: Hello, world\n"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/include_techniques/output.toffee"] = { - bundlePath: "/include_techniques/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/include_techniques/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/include_techniques/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("From: Chris <ccoyne77@gmail> \n"); - _to("Msg: Hello, world\n"); - _to("\n"); - _to("From: Max & Sam \n"); - _to("Msg: Hello, world\n"); - _to("\n"); - _to("From: Christian \n"); - _to("Msg: Hello, world\n"); - _to("From: Jennie \n"); - _to("Msg: Hello, world\n"); - _to("From: Unknown \n"); - _to("Msg: Hello, world\n"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/indent_attack/input.toffee"] = { - bundlePath: "/indent_attack/input.toffee" - }; - - tmpl.pub = function(locals) { - var i, x, _i, _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/indent_attack/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/indent_attack/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("
    \n"); - _to(" "); - _ts(2); - _ts(2); - if (1 === 1) { - if (2 === 2) { - if (3 === 3) { - _ts(1); - _to("Pass1"); - _ts(2); - } - } - } - if (1 === 1) { - if (2 === 3) { - if (3 === 3) { - _ts(1); - _to("Fail"); - _ts(2); - } else { - _ts(1); - _to("Fail"); - _ts(2); - } - } else { - if (2 === 2) { - if (3 === 3) { - _ts(1); - _to("Pass2"); - _ts(2); - } - } - } - } - _ts(1); - _to("\n"); - _to("
    \n"); - _to("\n"); - _ts(2); - _ts(2); - if (1 === 1) { - if (2 === 2) { - if (3 === 3) { - _ts(1); - _to("Pass3"); - _ts(2); - } - } - } - if (1 === 1) { - if (2 === 3) { - if (3 === 3) { - _ts(1); - _to("Fail"); - _ts(2); - } else { - _ts(1); - _to("Fail"); - _ts(2); - } - } else { - if (2 === 2) { - if (3 === 3) { - _ts(1); - _to("Pass4"); - _ts(2); - } - } - } - } - _ts(1); - _to("\n"); - _to("
    \n"); - _to("\n"); - _ts(2); - _ts(2); - if (10 === 10) { - if (20 === 20) { - if (30 === 30) { - _ts(1); - _to("Pass5"); - _ts(2); - } - } - } - if (10 === 10) { - if (20 === 30) { - if (30 === 30) { - _ts(1); - _to("Fail"); - _ts(2); - } else { - _ts(1); - _to("Fail"); - _ts(2); - } - } else { - if (20 === 20) { - if (30 === 30) { - _ts(1); - _to("Pass6"); - _ts(2); - } - } - } - } - _ts(1); - _to("\n"); - _to("\n"); - _ts(2); - _ts(2); - if (99 === 99) { - print('Pass7'); - } else { - print('Fail'); - _ts(1); - _to("Fail8"); - _ts(2); - } - _ts(1); - _ts(1); - _to("Pass8"); - _ts(2); - _ts(1); - _to("\n"); - _to("\n"); - _ts(2); - _ts(2); - _ts(1); - _ts(1); - _to("...passed with flying colors."); - _ts(2); - _ts(1); - _to("\n"); - _to("

    \n"); - _to(" "); - _ts(2); - _ts(2); - x = 10; - if (x > 1) { - for (i = _i = 0; 0 <= x ? _i < x : _i > x; i = 0 <= x ? ++_i : --_i) { - _ts(1); - _to("
    "); - _to("" + (i != null ? escape(i) : '')); - _ts(2); - _ts(2); - if (i === 3) { - _ts(1); - _to(" (my favorite number) "); - _ts(2); - } - } - } - _ts(1); - _to("\n"); - _to("

    "); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/indent_attack/output.toffee"] = { - bundlePath: "/indent_attack/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/indent_attack/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/indent_attack/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("
    \n"); - _to(" Pass1Pass2\n"); - _to("
    \n"); - _to("\n"); - _to("Pass3Pass4\n"); - _to("
    \n"); - _to("\n"); - _to("Pass5Pass6\n"); - _to("\n"); - _to("Pass7Pass8\n"); - _to("\n"); - _to("...passed with flying colors.\n"); - _to("

    \n"); - _to("
    0
    1
    2
    3 (my favorite number)
    4
    5
    6
    7
    8
    9\n"); - _to("

    "); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/junk/input.toffee"] = { - bundlePath: "/junk/input.toffee" - }; - - tmpl.pub = function(locals) { - var supplies, supply, _i, _l, _len, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/junk/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/junk/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - supplies = ["broom", "mop", "vacuum"]; - _ts(1); - _to("
      \n"); - _to(" "); - _ts(2); - _ts(2); - for (_i = 0, _len = supplies.length; _i < _len; _i++) { - supply = supplies[_i]; - _ts(1); - _to("
    • "); - _to("" + (supply != null ? escape(supply) : '')); - _to("
    • "); - _ts(2); - } - _ts(1); - _to("\n"); - _to("
    "); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/junk/output.toffee"] = { - bundlePath: "/junk/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/junk/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/junk/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("
      \n"); - _to("
    • broom
    • mop
    • vacuum
    • \n"); - _to("
    "); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/lambda_fns/input.toffee"] = { - bundlePath: "/lambda_fns/input.toffee" - }; - - tmpl.pub = function(locals) { - var echo_it, print_it, print_it_twice, _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/lambda_fns/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/lambda_fns/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - print_it = function(msg) { - _ts(1); - _to("" + (msg != null ? escape(msg) : '')); - return _ts(2); - }; - print_it_twice = function(msg) { - var m; - _ts(1); - _ts(1); - _to("" + (msg != null ? escape(msg) : '')); - _ts(2); - m = msg; - _ts(1); - _ts(1); - _to("" + (m != null ? escape(m) : '')); - return _ts(2); - }; - echo_it = function(msg) { - var v; - v = msg; - return v; - }; - print_it("Pass"); - print_it_twice("Pass"); - print(echo_it("Pass")); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/lambda_fns/output.toffee"] = { - bundlePath: "/lambda_fns/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/lambda_fns/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/lambda_fns/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("PassPassPassPass"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/multiline_interpolation/foo.toffee"] = { - bundlePath: "/multiline_interpolation/foo.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/multiline_interpolation/foo.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/multiline_interpolation/foo.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("" + (typeof a !== "undefined" && a !== null ? escape(a) : '')); - _to(" "); - _to("" + (typeof b !== "undefined" && b !== null ? escape(b) : '')); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/multiline_interpolation/input.toffee"] = { - bundlePath: "/multiline_interpolation/input.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/multiline_interpolation/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/multiline_interpolation/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("" + (escape("Hello, " + "world"))); - _to("\n"); - _to("
    \n"); - _to("" + (partial("foo.toffee", { - a: "Goodbye" + ',', - b: "world" - }))); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/multiline_interpolation/output.toffee"] = { - bundlePath: "/multiline_interpolation/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/multiline_interpolation/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/multiline_interpolation/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("Hello, world\n"); - _to("
    \n"); - _to("Goodbye, world"); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/plaintext/input.toffee"] = { - bundlePath: "/plaintext/input.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/plaintext/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/plaintext/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("Hi there."); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/plaintext/output.toffee"] = { - bundlePath: "/plaintext/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/plaintext/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/plaintext/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("Hi there."); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/snippets/foo/bar/body.toffee"] = { - bundlePath: "/snippets/foo/bar/body.toffee" - }; - - tmpl.pub = function(locals) { - var msg, _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/snippets/foo/bar/body.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/snippets/foo/bar/body.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - msg = msg || "Unknown message"; - print(msg); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/snippets/foo/message.toffee"] = { - bundlePath: "/snippets/foo/message.toffee" - }; - - tmpl.pub = function(locals) { - var from, msg, _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/snippets/foo/message.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/snippets/foo/message.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(2); - from = from || "Unknown sender"; - msg = msg || "Unknown message."; - print("From: " + from + "\n" + (snippet('./bar/body.toffee', { - msg: msg - }))); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/snippets/input.toffee"] = { - bundlePath: "/snippets/input.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/snippets/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/snippets/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("" + (partial("./foo/message.toffee"))); - _to("\n"); - _to("" + (escape(snippet("./foo/message.toffee")))); - _to("\n"); - _to("" + (partial("./foo/message.toffee", { - from: "Sam" - }))); - _to("\n"); - _to("" + (escape(snippet("./foo/message.toffee", { - from: "Max" - })))); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/snippets/output.toffee"] = { - bundlePath: "/snippets/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/snippets/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/snippets/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("From: Preloaded sender\n"); - _to("Preloaded message.\n"); - _to("From: Unknown sender\n"); - _to("Unknown message.\n"); - _to("From: Sam\n"); - _to("Preloaded message.\n"); - _to("From: Max\n"); - _to("Unknown message."); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/special_cases/input.toffee"] = { - bundlePath: "/special_cases/input.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/special_cases/input.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/special_cases/input.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("\n"); - _ts(2); - _ts(2); - _ts(1); - _ts(1); - _to('"' + "PASSED" + '"'); - _ts(2); - _ts(1); - _to("\n"); - _ts(2); - _ts(1); - _to("\n"); - _to("

    \n"); - _to(" "); - _to("" + (print("" + 'click & clack' + ""))); - _to("\n"); - _to("

    \n"); - _ts(2); - _ts(1); - _to("\n"); - _to("A backslash is a \\\n"); - _to(""); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); - -(function() { - var tmpl; - - tmpl = toffee.templates["/special_cases/output.toffee"] = { - bundlePath: "/special_cases/output.toffee" - }; - - tmpl.pub = function(locals) { - var _l, _ln, _t, _to, _ts; - _l = locals; - _t = _l.__toffee = { - out: [] - }; - _to = function(x) { - return locals.__toffee.out.push(x); - }; - _ln = function(x) { - return locals.__toffee.lineno = x; - }; - _ts = function(x) { - return locals.__toffee.state = x; - }; - if (!(_l.print != null)) { - _l.print = function(o) { - return toffee.__print(_l, o); - }; - } - if (!(_l.json != null)) { - _l.json = function(o) { - return toffee.__json(_l, o); - }; - } - if (!(_l.raw != null)) { - _l.raw = function(o) { - return toffee.__raw(_l, o); - }; - } - if (!(_l.html != null)) { - _l.html = function(o) { - return toffee.__html(_l, o); - }; - } - if (!(_l.escape != null)) { - _l.escape = function(o) { - return toffee.__escape(_l, o); - }; - } - if (!(_l.partial != null)) { - _l.partial = function(path, vars) { - return toffee.__partial(toffee.templates["/special_cases/output.toffee"], _l, path, vars); - }; - } - if (!(_l.snippet != null)) { - _l.snippet = function(path, vars) { - return toffee.__snippet(toffee.templates["/special_cases/output.toffee"], _l, path, vars); - }; - } - _t.print = _l.print; - _t.json = _l.json; - _t.raw = _l.raw; - _t.html = _l.html; - _t.escape = _l.escape; - _t.partial = _l.partial; - _t.snippet = _l.snippet; - with (locals) {; - - __toffee.out = []; - _ts(1); - _ts(1); - _to("\n"); - _to('"' + "PASSED\"\n"); - _to("\n"); - _to("

    \n"); - _to(" click & clack\n"); - _to("

    \n"); - _to("\n"); - _to("A backslash is a \\\n"); - _to(""); - _ts(2); - __toffee.res = __toffee.out.join(""); - return __toffee.res; - return } /* closing JS 'with' */ ; - }; - - if (typeof __toffee_run_input !== "undefined" && __toffee_run_input !== null) { - return tmpl.pub(__toffee_run_input); - } - -}).call(this); diff --git a/test/express3/routes/index.js b/test/express3/routes/index.js deleted file mode 100644 index 29fed96..0000000 --- a/test/express3/routes/index.js +++ /dev/null @@ -1,14 +0,0 @@ - -/* - * GET home page. - */ - -exports.index = function(req, res){ - var circular_obj = [1,2,3]; - circular_obj.push(circular_obj); - var vars = { - title: 'Express', - a_bad_test_function: function() {return JSON.stringify(circular_obj);} - } - res.render('index', vars); -}; \ No newline at end of file diff --git a/test/express3/views/index.toffee b/test/express3/views/index.toffee deleted file mode 100644 index a68d0a1..0000000 --- a/test/express3/views/index.toffee +++ /dev/null @@ -1,444 +0,0 @@ - - - Test Toffee in the browser - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FILEEXPECTED OUTPUTSERVER RENDERBROWSER RENDER
    big_file#{partial '../../cases/big_file/input.toffee', {}}0... 1... 2... 3... 4... 5... 6... 7... 8... 9... 10... 11... 12... 13... 14... 15... 16... 17... 18... 19... 20... 21... 22... 23... 24... 25... 26... 27... 28... 29... 30... 31... 32... 33... 34... 35... 36... 37... 38... 39... 40... 41... 42... 43... 44... 45... 46... 47... 48... 49... 50... 51... 52... 53... 54... 55... 56... 57... 58... 59... 60... 61... 62... 63... 64... 65... 66... 67... 68... 70... 70... 71... 72... 73... 74... 75... 76... 77... 78... 79... 80... 81... 82... 83... 84... 85... 86... 87... 88... 89... 90... 91... 92... 93... 94... 95... 96... 97... 98... 99... 100... 101... 102... 103... 104... 105... 106... 107... 108... 109... 110... 111... 112... 113... 114... 115... 116... 117... 118... 119... 120... 121... 122... 123... 124... 125... 126... 127... 128... 129... 130... 131... 132... 133... 134... 135... 136... 137... 138... 139... 140... 141... 142... 143... 144... 145... 146... 147... 148... 149... 150... 151... 152... 153... 154... 155... 156... 157... 158... 159... 160... 162...162... 163... 164... 165... 166... 167... 168... 169... 170... 171... 172... 173... 174... 175... 176... 177... 178... 179... 180... 181... 182... 183... 184... 185... 186... 187... 188... 189... 190... 191... 192... 193... 194... 195... 196... 197... 198... 199... 200... 201... 202... 203... 204... 205... 206... 207... 208... 209... 210... 211... 212... 213... 214... 215... 216... 217... 218... 219... 220... 221... 222... 223... 224... 225... 226... 227... 228... 229... 230... 232... 232... 233... 234... 235... 236... 237... 238... 239... 240... 241... 242... 243... 244... 245... 246... 247... 248... 249... 250... 251... 252... 253... 254... 255... 256... 257... 258... 259... 260... 261... 262... 263... 264... 265... 266... 267... 268... 269... 270... 271... 272... 273... 274... 275... 276... 277... 278... 279... 280... 281... 282... 283... 284... 285... 286... 287... 288... 289... 290... 291... 292... 293... 294... 295... 296... 297... 298... 299... 300... 301... 302... 303... 304... 305... 306... 307... 308... 309... 310... 311... 312... 313... 314... 315... 316... 317... 318... 319... 320... 321... 322... 324...
    comments#{partial '../../cases/comments/input.toffee', { - "greeting": "Hello" -}} -Pass 1 - -Pass 2 - -Pass 3 -
    eco_compare#{partial '../../cases/eco_compare/input.toffee', {}} - okcupid -

    A site for singles

    - - tallygram -

    A site for anyone

    - - -You have 3 female friends.
    escape#{partial '../../cases/escape/input.toffee', {}}

    - default x = "Hello world" - default y = <hr /> - default z = click&clack - default w = [1,2,{"place":"The Dreadfort"}] - default r = - default w.foo = -

    -

    - raw x = "Hello world" - raw y =


    - raw z = click&clack - raw w = 1,2,[object Object] -

    - -

    - raw printed x = "Hello world" - raw printed y =


    - raw printed z = click&clack - raw printed w = 1,2,[object Object] -

    -

    - json printed x = "\"Hello world\"" - json printed y = "\u003Chr /\u003E" - json printed z = "click\u0026clack" - json printed w = [1,2,{"place":"The Dreadfort"}] -

    -

    - html printed longhand x = "Hello world" - html printed longhand y = <hr /> - html printed longhand z = click&clack - html printed longhand w = 1,2,[object Object] -

    hello_world#{partial '../../cases/hello_world/input.toffee', { - "greeting": "Hello" -}}Hello, world.
    include_order#{partial '../../cases/include_order/input.toffee', { - "greeting": "Hello" -}}1 -2 -hia - -b -3 -4
    include_recursion#{partial '../../cases/include_recursion/input.toffee', { - "countdown" : 10 -}}10...9...8...7...6...5...4...3...2...1...blastoff!
    include_techniques#{partial '../../cases/include_techniques/input.toffee', { -}}From: Chris <ccoyne77@gmail> -Msg: Hello, world - -From: Max & Sam -Msg: Hello, world - -From: Christian -Msg: Hello, world -From: Jennie -Msg: Hello, world -From: Unknown -Msg: Hello, world -
    indent_attack#{partial '../../cases/indent_attack/input.toffee', { -}}
    - Pass1Pass2 -
    - -Pass3Pass4 -
    - -Pass5Pass6 - -Pass7Pass8 - -...passed with flying colors. -

    -
    0
    1
    2
    3 (my favorite number)
    4
    5
    6
    7
    8
    9 -

    junk#{partial '../../cases/junk/input.toffee', {}}
      -
    • broom
    • mop
    • vacuum
    • -
    lambda_fns#{partial '../../cases/lambda_fns/input.toffee', {}}PassPassPassPass
    multiline_interpolation#{partial '../../cases/multiline_interpolation/input.toffee', {}}Hello, world -
    -Goodbye, world
    plaintext#{partial '../../cases/plaintext/input.toffee', {}}Hi there.
    snippets#{partial '../../cases/snippets/input.toffee', { - "from": "Preloaded sender", - "msg" : "Preloaded message." -}}From: Preloaded sender -Preloaded message. -From: Unknown sender -Unknown message. -From: Sam -Preloaded message. -From: Max -Unknown message.
    special_cases#{partial '../../cases/special_cases/input.toffee', {}} -"PASSED" - -

    - click & clack -

    - -A backslash is a \ -
    - - \ No newline at end of file diff --git a/test/express4/app.coffee b/test/express4/app.coffee new file mode 100644 index 0000000..6dc78ea --- /dev/null +++ b/test/express4/app.coffee @@ -0,0 +1,37 @@ + +run = (cb) -> + toffee = require '../../index.js' + express = require 'express' + http = require 'http' + + app = express() + + + app_configure = -> + + toffee.expressEngine.verbose = not module.parent + toffee.expressEngine.prettyPrintErrors = false + + app.set 'port', process.env.PORT or 3033 + app.set 'views', __dirname + '/views' + app.engine 'toffee', toffee.__express + app.use express.static __dirname + '/public' + app.route('/').get (req, res) => + circular_obj = [1,2,3] + circular_obj.push circular_obj + title = 'Express' + a_bad_test_function = -> return JSON.stringify circular_obj + vars = {title, a_bad_test_function} + res.render 'index.toffee', vars + + http.createServer(app).listen app.get('port'), -> + console.log "Express server listening on port #{app.get('port')}" + if cb? then cb() + + app_configure() + +if not module.parent + run() + +else + exports.run = (cb) -> run cb diff --git a/test/express4/public/javascripts/jquery-1.9.0.min.js b/test/express4/public/javascripts/jquery-1.9.0.min.js new file mode 100644 index 0000000..50d1b22 --- /dev/null +++ b/test/express4/public/javascripts/jquery-1.9.0.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.9.0 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license */(function(e,t){"use strict";function n(e){var t=e.length,n=st.type(e);return st.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e){var t=Tt[e]={};return st.each(e.match(lt)||[],function(e,n){t[n]=!0}),t}function i(e,n,r,i){if(st.acceptData(e)){var o,a,s=st.expando,u="string"==typeof n,l=e.nodeType,c=l?st.cache:e,f=l?e[s]:e[s]&&s;if(f&&c[f]&&(i||c[f].data)||!u||r!==t)return f||(l?e[s]=f=K.pop()||st.guid++:f=s),c[f]||(c[f]={},l||(c[f].toJSON=st.noop)),("object"==typeof n||"function"==typeof n)&&(i?c[f]=st.extend(c[f],n):c[f].data=st.extend(c[f].data,n)),o=c[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[st.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[st.camelCase(n)])):a=o,a}}function o(e,t,n){if(st.acceptData(e)){var r,i,o,a=e.nodeType,u=a?st.cache:e,l=a?e[st.expando]:st.expando;if(u[l]){if(t&&(r=n?u[l]:u[l].data)){st.isArray(t)?t=t.concat(st.map(t,st.camelCase)):t in r?t=[t]:(t=st.camelCase(t),t=t in r?[t]:t.split(" "));for(i=0,o=t.length;o>i;i++)delete r[t[i]];if(!(n?s:st.isEmptyObject)(r))return}(n||(delete u[l].data,s(u[l])))&&(a?st.cleanData([e],!0):st.support.deleteExpando||u!=u.window?delete u[l]:u[l]=null)}}}function a(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(Nt,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:wt.test(r)?st.parseJSON(r):r}catch(o){}st.data(e,n,r)}else r=t}return r}function s(e){var t;for(t in e)if(("data"!==t||!st.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function u(){return!0}function l(){return!1}function c(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function f(e,t,n){if(t=t||0,st.isFunction(t))return st.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return st.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=st.grep(e,function(e){return 1===e.nodeType});if(Wt.test(t))return st.filter(t,r,!n);t=st.filter(t,r)}return st.grep(e,function(e){return st.inArray(e,t)>=0===n})}function p(e){var t=zt.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function d(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function h(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function g(e){var t=nn.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function m(e,t){for(var n,r=0;null!=(n=e[r]);r++)st._data(n,"globalEval",!t||st._data(t[r],"globalEval"))}function y(e,t){if(1===t.nodeType&&st.hasData(e)){var n,r,i,o=st._data(e),a=st._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)st.event.add(t,n,s[n][r])}a.data&&(a.data=st.extend({},a.data))}}function v(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!st.support.noCloneEvent&&t[st.expando]){r=st._data(t);for(i in r.events)st.removeEvent(t,i,r.handle);t.removeAttribute(st.expando)}"script"===n&&t.text!==e.text?(h(t).text=e.text,g(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),st.support.html5Clone&&e.innerHTML&&!st.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Zt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function b(e,n){var r,i,o=0,a=e.getElementsByTagName!==t?e.getElementsByTagName(n||"*"):e.querySelectorAll!==t?e.querySelectorAll(n||"*"):t;if(!a)for(a=[],r=e.childNodes||e;null!=(i=r[o]);o++)!n||st.nodeName(i,n)?a.push(i):st.merge(a,b(i,n));return n===t||n&&st.nodeName(e,n)?st.merge([e],a):a}function x(e){Zt.test(e.type)&&(e.defaultChecked=e.checked)}function T(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Nn.length;i--;)if(t=Nn[i]+n,t in e)return t;return r}function w(e,t){return e=t||e,"none"===st.css(e,"display")||!st.contains(e.ownerDocument,e)}function N(e,t){for(var n,r=[],i=0,o=e.length;o>i;i++)n=e[i],n.style&&(r[i]=st._data(n,"olddisplay"),t?(r[i]||"none"!==n.style.display||(n.style.display=""),""===n.style.display&&w(n)&&(r[i]=st._data(n,"olddisplay",S(n.nodeName)))):r[i]||w(n)||st._data(n,"olddisplay",st.css(n,"display")));for(i=0;o>i;i++)n=e[i],n.style&&(t&&"none"!==n.style.display&&""!==n.style.display||(n.style.display=t?r[i]||"":"none"));return e}function C(e,t,n){var r=mn.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function k(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;4>o;o+=2)"margin"===n&&(a+=st.css(e,n+wn[o],!0,i)),r?("content"===n&&(a-=st.css(e,"padding"+wn[o],!0,i)),"margin"!==n&&(a-=st.css(e,"border"+wn[o]+"Width",!0,i))):(a+=st.css(e,"padding"+wn[o],!0,i),"padding"!==n&&(a+=st.css(e,"border"+wn[o]+"Width",!0,i)));return a}function E(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=ln(e),a=st.support.boxSizing&&"border-box"===st.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=un(e,t,o),(0>i||null==i)&&(i=e.style[t]),yn.test(i))return i;r=a&&(st.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+k(e,t,n||(a?"border":"content"),r,o)+"px"}function S(e){var t=V,n=bn[e];return n||(n=A(e,t),"none"!==n&&n||(cn=(cn||st(" + + :} + {::} + #} + + + \ No newline at end of file diff --git a/test/express4_error_handling/views/test_bad_coffee_syntax.toffee b/test/express4_error_handling/views/test_bad_coffee_syntax.toffee new file mode 100644 index 0000000..1df5dd2 --- /dev/null +++ b/test/express4_error_handling/views/test_bad_coffee_syntax.toffee @@ -0,0 +1,15 @@ + +{# + x = "Foo" +#} + +{# + y = "Bar" + {: + Hello there + {# + var x = 100 + #} + :} +#} +Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah Bleah bleah bleah Bleah \ No newline at end of file diff --git a/test/express4_error_handling/views/test_bad_runtime.toffee b/test/express4_error_handling/views/test_bad_runtime.toffee new file mode 100644 index 0000000..0a8d912 --- /dev/null +++ b/test/express4_error_handling/views/test_bad_runtime.toffee @@ -0,0 +1,13 @@ + +About to convert a circular JSON structure + +{# + x = [1,2,3] + x.push x + {: +

    x as JSON

    + {# + print JSON.stringify x + #} + :} +#} diff --git a/test/express4_error_handling/views/test_bad_str_interpolate.toffee b/test/express4_error_handling/views/test_bad_str_interpolate.toffee new file mode 100644 index 0000000..d0e946d --- /dev/null +++ b/test/express4_error_handling/views/test_bad_str_interpolate.toffee @@ -0,0 +1,6 @@ + +This is a bad variable. + +foo.bar = #{foo.bar} + +Hah. \ No newline at end of file diff --git a/test/express4_error_handling/views/test_bad_toffee_syntax.toffee b/test/express4_error_handling/views/test_bad_toffee_syntax.toffee new file mode 100644 index 0000000..d5dff31 --- /dev/null +++ b/test/express4_error_handling/views/test_bad_toffee_syntax.toffee @@ -0,0 +1,10 @@ + +{# + x = "Foo" +#} + +{# + {: :} + y = "Bar" + {: +#} diff --git a/test/generate_express_test.coffee b/test/generate_express_test.coffee new file mode 100644 index 0000000..d62dbae --- /dev/null +++ b/test/generate_express_test.coffee @@ -0,0 +1,96 @@ +{spawn, exec} = require 'child_process' +fs = require 'fs' +path = require 'path' +coffee = require 'coffee-script' + + +generateExpressTest = (cb) -> + + proc = spawn path.join(__dirname,"../node_modules/.bin/coffee"), ['./src/command_line.coffee', '-n', './test/cases', '-o', './test/express4/public/javascripts/test_cases.js'] + proc.stderr.on 'data', (buffer) -> console.log buffer.toString() + proc.stdout.on 'data', (buffer) -> console.log buffer.toString() + proc.on 'exit', (status) -> + if status isnt 0 + console.log "Error running command line. #{status}" + process.exit 1 + cb() if typeof cb is 'function' + + {getCommonHeadersJs} = require '../lib/view' + headers = getCommonHeadersJs true, true + fs.writeFileSync "./test/express4/public/javascripts/toffee.js", headers, "utf8" + + # generate an index page that tests them all + + test_page = """ + + + Testing Toffee in the Browser + + + + + + + + + + """ + + case_dirs = fs.readdirSync "./test/cases/" + + for dir,i in case_dirs + expected_output = fs.readFileSync "./test/cases/#{dir}/output.toffee", "utf8" + if fs.existsSync "./test/cases/#{dir}/vars.coffee" + coffee_vars = fs.readFileSync "./test/cases/#{dir}/vars.coffee", "utf8" + js_vars = coffee.compile(coffee_vars, {bare: true}).replace(/;[ \n]*$/,'') + else if fs.existsSync "./test/cases/#{dir}/vars.js" + coffee_vars = fs.readFileSync "./test/cases/#{dir}/vars.js", "utf8" + js_vars = coffee_vars; + else + if dir == "render_no_args" + coffee_vars = "" + js_vars = "" + else + coffee_vars = "{}" + js_vars = "{}" + rid = i + test_page += """ + \n\n\n + + + + + + + + \n\n\n + """ + + test_page += """ +
    FILEEXPECTED OUTPUTSERVER RENDERBROWSER RENDER
    #{dir}#{expected_output}\#{partial '../../cases/#{dir}/input.toffee', #{coffee_vars}}
    + + + """ + fs.writeFileSync "./test/express4/views/index.toffee", test_page, "utf8" + +exports.generate = generateExpressTest + diff --git a/test/run_cases.coffee b/test/run_cases.coffee deleted file mode 100644 index 9b6a520..0000000 --- a/test/run_cases.coffee +++ /dev/null @@ -1,60 +0,0 @@ -{engine} = require '../lib/engine' -fs = require 'fs' -path = require 'path' - -e = new engine({ - verbose: false - prettyPrintErrors: false -}) - -run_case_dir = (dir, cb) -> - expected = fs.readFileSync "#{dir}/output.toffee", "utf8" - if path.existsSync "#{dir}/vars.js" - vars = fs.readFileSync "#{dir}/vars.js", "utf8" - vars = eval "(#{vars})" - else - vars = {} - d = Date.now() - e.run "#{dir}/input.toffee", vars, (err, res) -> - time_ms = Date.now() - d - if err - cb err, time_ms - else - if res isnt expected - cb "Failure in case #{dir}." + - "\n\nExpected\n=====\n#{expected}\n=====" + - "\nGot\n=====\n#{res}\n=====\n", time_ms - else - cb null, time_ms - -run_all_case_dirs = (cb) -> - time_ms = 0 - case_dirs = fs.readdirSync "#{__dirname}/cases/" - countdown = case_dirs.length - for dir in case_dirs - run_case_dir "#{__dirname}/cases/#{dir}", (err, ms) -> - countdown-- - time_ms += ms - if err - console.log err - process.exit 1 - if countdown is 0 - cb null, time_ms, case_dirs.length - -run_all_case_dirs (err, time, tests_run) -> - - console.log "SUCCESS for #{tests_run} cold tests in #{time}ms" - - times = [] - speed_runs = 20 - countdown = speed_runs - total_time = 0 - total_tests = 0 - for i in [0...speed_runs] - run_all_case_dirs (err, time, tests_run) -> - countdown-- - total_time += time - total_tests += tests_run - if countdown is 0 - console.log "SUCCESS for #{total_tests} hot tests in #{total_time}ms. #{total_time / total_tests}ms/test" - process.exit 0 \ No newline at end of file diff --git a/test/run_cases.iced b/test/run_cases.iced new file mode 100644 index 0000000..a64ec0e --- /dev/null +++ b/test/run_cases.iced @@ -0,0 +1,106 @@ +{engine} = require '../lib/engine' +fs = require 'fs' +path = require 'path' +Browser = require 'zombie' +coffee = require 'coffee-script' +tablify = require 'tablify' +colors = require 'colors' +jsdiff = require 'diff' + +regular_engine = new engine({ + verbose: false + prettyPrintErrors: false +}) + +# --------------------------------------------------------------- + +MULTI_RUNS = 50 + +file_cache = {} + +# --------------------------------------------------------------- + +read_file_sync = (fname) -> + if not file_cache[fname]? + file_cache[fname] = fs.readFileSync fname, "utf8" + return file_cache[fname] + +# --------------------------------------------------------------- + +run_case_dir = (eng, dir, cb) -> + start = Date.now() + expected = read_file_sync "#{dir}/output.toffee" + existsSync = if path.existsSync? then path.existsSync else fs.existsSync + if existsSync "#{dir}/vars.coffee" + txt = read_file_sync "#{dir}/vars.coffee" + vars = coffee.compile(txt, {bare: true}) + vars = eval "#{vars}" + else if existsSync "#{dir}/vars.js" + vars = read_file_sync "#{dir}/vars.js" + vars = eval "(#{vars})" + else + vars = {} + vars["rand_#{Math.random()}"] = ("foo" for i in [0...(~~(20000*Math.random()))]).join "" + await eng.run "#{dir}/input.toffee", vars, defer err, res + time_ms = Date.now() - start + if err + cb err, time_ms + else + if res isnt expected + diff = jsdiff.diffLines res, expected + delta = "" + diff.forEach (part) -> + c = if part.added then 'green' else if part.removed then 'red' else 'grey' + v = part.value + delta += v[c] + cb "Failure in case #{dir}." + + "#{delta}", time_ms + else + cb null, time_ms + +run_all_case_dirs = (eng, cb) -> + start = Date.now() + case_dirs = fs.readdirSync "#{__dirname}/cases/" + for dir in case_dirs + await run_case_dir eng, "#{__dirname}/cases/#{dir}", defer err, ms + if err + console.log err + process.exit 1 + cb null, (Date.now() - start), case_dirs.length + +run_multiple_runs = (eng, num_runs, cb) -> + total_tests = 0 + start = Date.now() + for i in [0...num_runs] + await setTimeout defer(), 1 + await run_all_case_dirs regular_engine, defer err, time, tests_run + total_tests += tests_run + cb null, (Date.now() - start), total_tests + +run_express_test = (cb) -> + require('./express4/app').run -> + browser = new Browser() + browser.visit 'http://127.0.0.1:3033', (e) -> + if e + console.log e + $ = browser.window.$ + successes = $('.success').length + fails = $('.fail').length + if (fails is 0) and (successes > 0) + console.log "Express SUCCESS: #{successes} succeeded, #{fails} failed" + return cb() + console.log "BROWSER ERROR! Server left running at http://localhost:3033 for your convenience" + +# ---------------------------------------------------------------- +go = -> + await run_all_case_dirs regular_engine, defer err, time, tests_run + console.log "Regular Engine: SUCCESS for #{tests_run} cold tests in #{time}ms (#{(time/tests_run).toFixed 2}ms/test)" + await run_multiple_runs regular_engine, MULTI_RUNS, defer err, time, tests_run + console.log "Regular Engine: SUCCESS for #{tests_run} hot tests in #{time}ms (#{(time/tests_run).toFixed 2}ms/test)" + await run_express_test defer() + process.exit 0 + +if not module.parent? + go() + +else exports.test = go diff --git a/toffee.js b/toffee.js new file mode 100644 index 0000000..5d6b01c --- /dev/null +++ b/toffee.js @@ -0,0 +1,205 @@ +var toffee; + +if (typeof toffee === "undefined" || toffee === null) { + toffee = {}; +} + +if (!toffee.templates) { + toffee.templates = {}; +} + +toffee.states = { + "TOFFEE": 1, + "COFFEE": 2 +}; + +toffee.__json = function(locals, o, opts) { + opts || (opts = {}); + opts.indent || (opts.indent = ""); + if (o == null) { + return "null"; + } else { + return "" + JSON.stringify(o, null, opts.indent).replace(//g, '\\u003E').replace(/&/g, '\\u0026').replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029').replace(/\u200e/g, '\\u200e').replace(/\u200f/g, '\\u200f').replace(/\u202a/g, '\\u202a').replace(/\u202b/g, '\\u202b').replace(/\u202c/g, '\\u202c').replace(/\u202d/g, '\\u202d').replace(/\u202e/g, '\\u202e').replace(/\u206a/g, '\\u206a').replace(/\u206b/g, '\\u206b').replace(/\u206c/g, '\\u206c').replace(/\u206d/g, '\\u206d').replace(/\u206e/g, '\\u206e').replace(/\u206f/g, '\\u206f').replace(/\u2066/g, '\\u2066').replace(/\u2067/g, '\\u2067').replace(/\u2068/g, '\\u2068').replace(/\u2069/g, '\\u2069'); + } +}; + +toffee.__raw = function(locals, o) { + return o; +}; + +toffee.__html = function(locals, o) { + return ("" + o).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/\u200e/g, '').replace(/\u200f/g, '').replace(/\u202a/g, '').replace(/\u202b/g, '').replace(/\u202c/g, '').replace(/\u202d/g, '').replace(/\u202e/g, '').replace(/\u206a/g, '').replace(/\u206b/g, '').replace(/\u206c/g, '').replace(/\u206d/g, '').replace(/\u206e/g, '').replace(/\u206f/g, '').replace(/\u2066/g, '').replace(/\u2067/g, '').replace(/\u2068/g, '').replace(/\u2069/g, ''); +}; + +toffee.__escape = function(locals, o) { + var ae; + if (locals.__toffee.autoEscape != null) { + ae = locals.__toffee.autoEscape; + } else if (true) { + ae = true; + } else { + ae = true; + } + if (ae) { + if (o === void 0) { + return ''; + } + if ((o != null) && (typeof o) === "object") { + return locals.json(o); + } + return locals.html(o); + } + return o; +}; + +toffee.__augmentLocals = function(locals, bundle_path) { + var _l, _t; + _l = locals; + _t = _l.__toffee = { + out: [] + }; + if (_l.print == null) { + _l.print = function(o) { + return toffee.__print(_l, o); + }; + } + if (_l.json == null) { + _l.json = function(o, opts) { + return toffee.__json(_l, o, opts); + }; + } + if (_l.raw == null) { + _l.raw = function(o) { + return toffee.__raw(_l, o); + }; + } + if (_l.html == null) { + _l.html = function(o) { + return toffee.__html(_l, o); + }; + } + if (_l.escape == null) { + _l.escape = function(o) { + return toffee.__escape(_l, o); + }; + } + if (_l.partial == null) { + _l.partial = function(path, vars) { + return toffee.__partial(toffee.templates["" + bundle_path], _l, path, vars); + }; + } + if (_l.snippet == null) { + _l.snippet = function(path, vars) { + return toffee.__snippet(toffee.templates["" + bundle_path], _l, path, vars); + }; + } + if (_l.load == null) { + _l.load = function(path, vars) { + return toffee.__load(toffee.templates["" + bundle_path], _l, path, vars); + }; + } + _t.print = _l.print; + _t.json = _l.json; + _t.raw = _l.raw; + _t.html = _l.html; + _t.escape = _l.escape; + _t.partial = _l.partial; + _t.snippet = _l.snippet; + return _t.load = _l.load; +}; + +toffee.__print = function(locals, o) { + if (locals.__toffee.state === toffee.states.COFFEE) { + locals.__toffee.out.push(o); + return ''; + } else { + return "" + o; + } +}; + +toffee.__normalize = function(path) { + var np, part, parts, _i, _len; + if ((path == null) || path === "/") { + return path; + } else { + parts = path.split("/"); + np = []; + if (parts[0]) { + np.push(''); + } + for (_i = 0, _len = parts.length; _i < _len; _i++) { + part = parts[_i]; + if (part === "..") { + if (np.length > 1) { + np.pop(); + } else { + np.push(part); + } + } else { + if (part !== ".") { + np.push(part); + } + } + } + path = np.join("/"); + if (!path) { + path = "/"; + } + return path; + } +}; + +toffee.__partial = function(parent_tmpl, parent_locals, path, vars) { + path = toffee.__normalize(parent_tmpl.bundlePath + "/../" + path); + return toffee.__inlineInclude(path, vars, parent_locals); +}; + +toffee.__snippet = function(parent_tmpl, parent_locals, path, vars) { + path = toffee.__normalize(parent_tmpl.bundlePath + "/../" + path); + vars = vars != null ? vars : {}; + vars.__toffee = vars.__toffee || {}; + vars.__toffee.noInheritance = true; + return toffee.__inlineInclude(path, vars, parent_locals); +}; + +toffee.__load = function(parent_tmpl, parent_locals, path, vars) { + path = toffee.__normalize(parent_tmpl.bundlePath + "/../" + path); + vars = vars != null ? vars : {}; + vars.__toffee = vars.__toffee || {}; + vars.__toffee.repress = true; + return toffee.__inlineInclude(path, vars, parent_locals); +}; + +toffee.__inlineInclude = function(path, locals, parent_locals) { + var k, options, res, reserved, v, _i, _len, _ref, _ref1; + options = locals || {}; + options.passback = {}; + options.__toffee = options.__toffee || {}; + reserved = {}; + _ref = ["passback", "load", "print", "partial", "snippet", "layout", "__toffee", "postProcess"]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + k = _ref[_i]; + reserved[k] = true; + } + if (!options.__toffee.noInheritance) { + for (k in parent_locals) { + v = parent_locals[k]; + if ((locals != null ? locals[k] : void 0) == null) { + if (reserved[k] == null) { + options[k] = v; + } + } + } + } + if (!toffee.templates[path]) { + return "Inline toffee include: Could not find " + path; + } else { + res = toffee.templates[path].pub(options); + _ref1 = options.passback; + for (k in _ref1) { + v = _ref1[k]; + parent_locals[k] = v; + } + return res; + } +}; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..2829e32 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,1423 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +JSONSelect@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/JSONSelect/-/JSONSelect-0.4.0.tgz#a08edcc67eb3fcbe99ed630855344a0cf282bb8d" + integrity sha512-VRLR3Su35MH+XV2lrvh9O7qWoug/TUyj9tLDjn9rtpUCNnILLrHjgd/tB0KrhugCxUpj3UqoLqfYb3fLJdIQQQ== + +"JSV@>= 4.0.x": + version "4.0.2" + resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" + integrity sha512-ZJ6wx9xaKJ3yFUhq5/sk82PJMuUyLk277I8mQeyDgCTjGdjWJIvPfaU5LIXaMuaN2UO1X3kZH4+lgphublZUHw== + +abab@^2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-globals@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-walk@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" + integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== + +acorn@^5.5.3: + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== + +acorn@^6.0.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== + +ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + integrity sha512-3iF4FIKdxaVYT3JqQuY3Wat/T2t7TRbbQ94Fu50ZUCbLy4TFbTzr90NOHQodQkNqmeEGCw8WbeP78WNi6SKYUA== + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +assert@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" + integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== + dependencies: + es6-object-assign "^1.1.0" + is-nan "^1.2.1" + object-is "^1.0.1" + util "^0.12.0" + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" + integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== + +babel-runtime@6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g== + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + +bluebird@^3.5.1: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + +chalk@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + integrity sha512-sQfYDlfv2DGVtjdoQqxS0cEZDroyG8h6TamA6rvxwlrU5BaSLDx9xhatBYl2pxZ7gmpNaPFVwBtdGdu5rQ+tYQ== + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +cjson@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/cjson/-/cjson-0.3.0.tgz#e6439b90703d312ff6e2224097bea92ce3d02a14" + integrity sha512-bBRQcCIHzI1IVH59fR0bwGrFmi3Btb/JNwM/n401i1DnYgWndpsUBiQRAddLflkZage20A2d25OAWZZk0vBRlA== + dependencies: + jsonlint "1.6.0" + +coffee-script@1.12.7: + version "1.12.7" + resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53" + integrity sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw== + +colors@0.5.x: + version "0.5.1" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774" + integrity sha512-XjsuUwpDeY98+yz959OlUK6m7mLBM+1MEG5oaenfuQnNnrQk1WvtcvFgN3FNDP3f2NmZ211t0mNEfSEN1h0eIg== + +colors@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.0.tgz#71797971162cd3cf65f0b9d24eb28f8d303acdf1" + integrity sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +core-js@^2.4.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" + integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== + dependencies: + cssom "0.3.x" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +define-properties@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +diff@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + +ebnf-parser@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/ebnf-parser/-/ebnf-parser-0.1.10.tgz#cd1f6ba477c5638c40c97ed9b572db5bab5d8331" + integrity sha512-urvSxVQ6XJcoTpc+/x2pWhhuOX4aljCNQpwzw+ifZvV1andZkAmiJc3Rq1oGEAQmcjiLceyMXOy1l8ms8qs2fQ== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +es6-object-assign@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" + integrity sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escodegen@1.3.x: + version "1.3.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.3.3.tgz#f024016f5a88e046fd12005055e939802e6c5f23" + integrity sha512-z9FWgKc48wjMlpzF5ymKS1AF8OIgnKLp9VyN7KbdtyrP/9lndwUFqCtMm+TAJmJf7KJFFYc4cFJfVTTGkKEwsA== + dependencies: + esprima "~1.1.1" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.33" + +escodegen@^1.9.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esprima@1.1.x, esprima@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549" + integrity sha512-qxxB994/7NtERxgXdFgLHIs9M6bhLXc6qtUmWZ3L8+gTQ9qaoyki2887P2IqAYsoENyr8SUbTutStDniOHSDHg== + +esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + integrity sha512-FpCjJDfmo3vsc/1zKSeqR5k42tcIhxFIlvq+h9j0fO2q/h2uLKyweq7rYJ+0CoVvrGQOxIS5wyBrW/+vF58BUQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + integrity sha512-x/iYH53X3quDwfHRz4y8rn4XcEwwCJeWsul9pF1zldMbGtgOtMNBEOuYWwB1EQlK2LRa1fev3YAgym/RElp5Cg== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventsource@^1.0.5: + version "1.1.2" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.2.tgz#bc75ae1c60209e7cb1541231980460343eaea7c2" + integrity sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA== + +express@4.18.2: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + integrity sha512-kaNz5OTAYYmt646Hkqw50/qyxP2vFnTVu5AQ1Zmk22Kk5+4Qx6BpO8+u7IKsML5fOsFk0ZT0AcCJNYwcvaLBvw== + +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +highlight.js@11.7.0: + version "11.7.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.7.0.tgz#3ff0165bc843f8c9bce1fd89e2fda9143d24b11e" + integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ== + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +iced-coffee-script@108.0.14: + version "108.0.14" + resolved "https://registry.yarnpkg.com/iced-coffee-script/-/iced-coffee-script-108.0.14.tgz#9ca5b258decf4a5eafb16f5663ff7683227c4f1a" + integrity sha512-e0CNmz51UGWRa2glPnUMnJM7oKQE81cxeC0WAgCjJDRImv3FDHldZr/Ngkbrgdbf1drGGzYWp+PWeJwXIfHwDw== + dependencies: + iced-runtime ">=0.0.1" + uglify-js "^3.5.9" + +iced-lock@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/iced-lock/-/iced-lock-2.0.1.tgz#92fe46ffe01b872bf88f963c2a319fa8ad80d13b" + integrity sha512-J6dnGMpAoHNyACUYJYhiJkLY7YFRTa7NMZ8ZygpYB3HNDOGWtzv55+kT2u1zItRi4Y1EXruG9d1VDsx8R5faTw== + dependencies: + iced-runtime "^1.0.0" + +iced-runtime@>=0.0.1, iced-runtime@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/iced-runtime/-/iced-runtime-1.0.4.tgz#e9de26dfe98cd8621201f7f3dfb9f7f09c550990" + integrity sha512-rgiJXNF6ZgF2Clh/TKUlBDW3q51YPDJUXmxGQXx1b8tbZpVpTn+1RX9q1sjNkujXIIaVxZByQzPHHORg7KV51g== + +iconv-lite@0.4.24, iconv-lite@^0.4.21: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inherits@2.0.4, inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.3: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-nan@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + +is-typed-array@^1.1.10, is-typed-array@^1.1.3: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + +jison-lex@0.3.x: + version "0.3.4" + resolved "https://registry.yarnpkg.com/jison-lex/-/jison-lex-0.3.4.tgz#81ca28d84f84499dfa8c594dcde3d8a3f26ec7a5" + integrity sha512-EBh5wrXhls1cUwROd5DcDHR1sG7CdsCFSqY1027+YA1RGxz+BX2TDLAhdsQf40YEtFDGoiO0Qm8PpnBl2EzDJw== + dependencies: + lex-parser "0.1.x" + nomnom "1.5.2" + +jison@0.4.18: + version "0.4.18" + resolved "https://registry.yarnpkg.com/jison/-/jison-0.4.18.tgz#c68a6a54bfe7028fa40bcfc6cc8bbd9ed291f502" + integrity sha512-FKkCiJvozgC7VTHhMJ00a0/IApSxhlGsFIshLW6trWJ8ONX2TQJBBz6DlcO1Gffy4w9LT+uL+PA+CVnUSJMF7w== + dependencies: + JSONSelect "0.4.0" + cjson "0.3.0" + ebnf-parser "0.1.10" + escodegen "1.3.x" + esprima "1.1.x" + jison-lex "0.3.x" + lex-parser "~0.1.3" + nomnom "1.5.2" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +jsdom@11.12.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +jsonlint@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/jsonlint/-/jsonlint-1.6.0.tgz#88aa46bc289a7ac93bb46cae2d58a187a9bb494a" + integrity sha512-x6YLBe6NjdpmIeiklwQOxsZuYj/SOWkT33GlTpaG1UdFGjdWjPcxJ1CWZAX3wA7tarz8E2YHF6KiW5HTapPlXw== + dependencies: + JSV ">= 4.0.x" + nomnom ">= 1.5.x" + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lex-parser@0.1.x, lex-parser@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/lex-parser/-/lex-parser-0.1.4.tgz#64c4f025f17fd53bfb45763faeb16f015a747550" + integrity sha512-DuAEISsr1H4LOpmFLkyMc8YStiRWZCO8hMsoXAXSbgyfvs2WQhSt0+/FBv3ZU/JBFZMGcE+FWzEBSzwUU7U27w== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + +lodash@^4.17.10, lodash@^4.17.19: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.3.1: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mkdirp@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.3.tgz#b083ff37be046fd3d6552468c1f0ff44c1545d1f" + integrity sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +nomnom@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.5.2.tgz#f4345448a853cfbd5c0d26320f2477ab0526fe2f" + integrity sha512-fiVbT7BqxiQqjlR9U3FDGOSERFCKoXVCdxV2FwZuNN7/cmJ42iQx35nUFOAFDcyvemu9Adp+IlsCGlKQYLmBKw== + dependencies: + colors "0.5.x" + underscore "1.1.x" + +"nomnom@>= 1.5.x": + version "1.8.1" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" + integrity sha512-5s0JxqhDx9/rksG2BTMVN1enjWSvPidpoSgViZU4ZXULyTe+7jxcCRLB6f42Z0l1xYJpleCBtSyY6Lwg3uu5CQ== + dependencies: + chalk "~0.4.0" + underscore "~1.6.0" + +nwsapi@^2.0.7: + version "2.2.2" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" + integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +psl@^1.1.28: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== + dependencies: + lodash "^4.17.19" + +request-promise-native@^1.0.5: + version "1.0.9" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== + dependencies: + request-promise-core "1.1.4" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.85.0, request@^2.87.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +source-map@~0.1.33: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + integrity sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ== + dependencies: + amdefine ">=0.0.4" + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + integrity sha512-behete+3uqxecWlDAm5lmskaSaISA+ThQ4oNNBDTBJt0x2ppR6IPqfZNuj6BLaLJ/Sji4TPZlcRyOis8wXQTLg== + +symbol-tree@^3.2.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +tablify@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/tablify/-/tablify-0.1.5.tgz#47160ce2918be291d63cecceddb5254dd72982c7" + integrity sha512-puOS3ef9p20DqujVs5JBCAYp5EeQke7B7+5g0SUdQKUNWkX6oM3jSzW8OD42HXowB7NTLisFGLsbYms3x+q9HA== + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== + dependencies: + prelude-ls "~1.1.2" + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +uglify-js@^3.5.9: + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + +underscore@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.1.7.tgz#40bab84bad19d230096e8d6ef628bff055d83db0" + integrity sha512-w4QtCHoLBXw1mjofIDoMyexaEdWGMedWNDhlWTtT1V1lCRqi65Pnoygkh6+WRdr+Bm8ldkBNkNeCsXGMlQS9HQ== + +underscore@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" + integrity sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util@^0.12.0: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +w3c-hr-time@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-typed-array@^1.1.2: + version "1.1.9" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +ws@^5.2.0: + version "5.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" + integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== + dependencies: + async-limiter "~1.0.0" + +ws@^6.1.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" + integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== + dependencies: + async-limiter "~1.0.0" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +zombie@6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/zombie/-/zombie-6.1.4.tgz#9f0f53f3d9a032beb7f3fe5b382146a3475a4d47" + integrity sha512-yxNvKtyz3PP8lkr31AYh7vdbBD4is9hYXiOQKPp+k/7GiDiFQXX1Ex+peCl4ttodu/bHZcIluJ8lxMla5XefBQ== + dependencies: + babel-runtime "6.26.0" + bluebird "^3.5.1" + debug "^4.1.0" + eventsource "^1.0.5" + iconv-lite "^0.4.21" + jsdom "11.12.0" + lodash "^4.17.10" + mime "^2.3.1" + ms "^2.1.1" + request "^2.85.0" + tough-cookie "^2.3.4" + ws "^6.1.2"