├── .gitignore
├── .istanbul.yml
├── .travis.yml
├── LICENSE
├── README.markdown
├── favicon.ico
├── index.html
├── package.json
├── tests.js
├── thermite.js
└── thermite.min.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | bundle.js
4 | .zuulrc
5 |
--------------------------------------------------------------------------------
/.istanbul.yml:
--------------------------------------------------------------------------------
1 | instrumentation:
2 | excludes: [tests.js]
3 | check:
4 | global:
5 | statements: 100
6 | lines: 100
7 | branches: 100
8 | functions: 100
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - stable
4 | after_script:
5 | - npm run-script cover
6 | - npm run-script coveralls
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 omphalos
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | Thermite
2 | ========
3 |
4 | [
5 | ](http://travis-ci.org/omphalos/thermite)
6 | [
7 | ](https://coveralls.io/github/omphalos/thermite)
8 |
9 | Thermite gives you an API for programmatically live reloading code.
10 |
11 | Its main purpose is to act like a library used by
12 | development and (experimentally) deployment tools.
13 |
14 | Comparison with native browser live code reloading
15 | --------------------------------------------------
16 |
17 | I love native browser live code reloading and use it in normal development.
18 | Nevertheless there are advantages to doing live code reloading with a library.
19 |
20 | * Most runtimes currently do not support live code reloading,
21 | so on many browsers,
22 | if you want this feature,
23 | you're out of luck.
24 | * Browsers that do support this
25 | don't offer direct access to this feature
26 | from inside your program.
27 |
28 | Thermite doesn't have these restrictions.
29 |
30 | I'm not complaining about native browser reloading - I think it's great.
31 | But I think there's utility
32 | in having a library that gives you
33 | direct programmatic access to hot code swapping cross browser.
34 |
35 | Demo
36 | ----
37 |
38 | The demo is [here](https://omphalos.github.io/thermite).
39 |
40 | Check it out!
41 |
42 | Set Up
43 | ------
44 |
45 | If you are using Node, first, `npm install thermite`,
46 | then `var thermite = require('thermite')`
47 |
48 | If you are using the browser, use thermite.min.js.
49 | `thermite` is exposed as a global variable.
50 | Or just use browserify.
51 |
52 | Basic usage
53 | -----------
54 |
55 | var hotSwappableCode = thermite.eval('(' + function() {
56 | document.addEventListener("mousemove", function(evt) {
57 | console.log(evt.clientX * evt.clientY)
58 | })
59 | } + ')()')
60 |
61 | hotSwappableCode.hotSwap('(' + function() {
62 | document.addEventListener("mousemove", function(evt) {
63 | console.log(evt.clientX + evt.clientY)
64 | })
65 | } + ')()')
66 |
67 | Calling `hotSwap` here doesn't add a second event listener to the DOM.
68 | It effectively replaces the reference to the event listener stored in the DOM
69 | with a new one.
70 |
71 | How it works
72 | ------------
73 |
74 | Thermite works by rewriting code
75 | and proxying each function.
76 |
77 | Additionally it stores the initial version of your code in a map.
78 |
79 | When you call `hotSwap`,
80 | thermite runs a diff to identify how functions change.
81 | It uses this diff to update the map.
82 |
83 | Whenever a function runs, it checks its version.
84 | When a function finds that its version is lower than the one in the map,
85 | it `evals` the new function (creating it in the proper scope).
86 |
87 | License
88 | -------
89 |
90 | MIT
91 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/omphalos/thermite/b1d7a4f100c6b2122adb8211a18c049e7af5d116/favicon.ico
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
43 |
44 |
45 |
46 |
69 |
Hot Swap
70 | GitHub
72 |
73 |
83 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "thermite",
3 | "version": "0.0.8",
4 | "description": "JavaScript live code reloading utility for Node and browsers",
5 | "main": "thermite.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/omphalos/thermite"
9 | },
10 | "keywords": [
11 | "JavaScript",
12 | "hot-swap",
13 | "hot-load",
14 | "hot-reload",
15 | "live-reload",
16 | "live-edit",
17 | "instrumentation",
18 | "ast",
19 | "abstract-syntax-tree",
20 | "swap",
21 | "swapping",
22 | "hot-swapping",
23 | "livereload",
24 | "reload",
25 | "live"
26 | ],
27 | "author": "omphalos",
28 | "license": "MIT",
29 | "bugs": {
30 | "url": "https://github.com/omphalos/thermite/issues"
31 | },
32 | "homepage": "https://github.com/omphalos/thermite",
33 | "dependencies": {
34 | "falafel": "1.2.0",
35 | "googlediff": "0.1.0",
36 | "survivor": "^0.0.3"
37 | },
38 | "devDependencies": {
39 | "browserify": "13.1.1",
40 | "bumpt": "0.0.4",
41 | "coveralls": "2.11.4",
42 | "istanbul": "0.3.19",
43 | "minilint": "0.0.12",
44 | "mocha": "3.1.2",
45 | "nodemon": "1.4.1",
46 | "uglifyjs": "2.4.10"
47 | },
48 | "scripts": {
49 | "test": "npm run lint && npm run mocha && npm run cover-and-check",
50 | "mocha": "mocha ./tests.js",
51 | "watch": "nodemon -x 'mocha ./tests.js'",
52 | "check-coverage": "istanbul check-coverage coverage/coverage.json",
53 | "cover-and-check": "npm run cover && npm run check-coverage",
54 | "cover": "istanbul cover _mocha -- ./tests.js",
55 | "coveralls": "cat ./coverage/lcov.info | coveralls",
56 | "lint": "minilint",
57 | "bundle": "browserify thermite.js -s thermite > bundle.js",
58 | "minify": "cat bundle.js | uglifyjs > thermite.min.js",
59 | "count": "gzip -c thermite.min.js | wc -c",
60 | "build": "npm run bundle; npm run minify; npm run count; rm bundle.js",
61 | "release": "npm run build; npm run test; bumpt"
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/tests.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | 'use strict'
4 |
5 | var assert = require('assert')
6 | var thermite = require('./thermite.js')
7 |
8 | it('should should eval raw JavaScript', function() {
9 | assert.equal(thermite.eval('123').result, 123)
10 | })
11 |
12 | it('should eval an anonymous function', function() {
13 | var fn = thermite.eval('(function() { return 123 })').result
14 | assert.equal(fn(), 123)
15 | })
16 |
17 | it('should eval a named function', function() {
18 | var fn = thermite.eval('(function x() { return 123 })').result
19 | assert.equal(fn(), 123)
20 | assert.equal(fn.name, 'x')
21 | })
22 |
23 | it('should eval in scope', function() {
24 | var x = 123
25 | thermite.eval('x = 5', {
26 | eval: function(code) { return eval(code) }
27 | })
28 | assert.equal(x, 5)
29 | })
30 |
31 | it('should replace functions', function() {
32 | var target = thermite.eval('(function noop() {})')
33 | target.hotSwap('(function add(x, y) { return x + y })')
34 | assert.equal(target.result(2, 3), 5)
35 | })
36 |
37 | it('should replace multiline functions', function() {
38 | var target = thermite.eval('(function noop() {})')
39 | target.hotSwap('(function add(x, y) { return x + y })')
40 | assert.equal(target.result(2, 3), 5)
41 | })
42 |
43 | it('should hotSwap function references', function() {
44 | var target = thermite.eval('(function() {})')
45 | var savedReference = target.result
46 | target.hotSwap('(function add(x, y) { return x + y })')
47 | assert.equal(savedReference(2, 3), 5)
48 | })
49 |
50 | it('should hotSwap recursive-style function references', function() {
51 | var target = thermite.eval('(function length(x) {\n'
52 | + ' return x ? rec(x.tail) + 1 : 0\n'
53 | + '})')
54 | var savedReference = target.result
55 | target.hotSwap('(function length(x) {\n'
56 | + ' return x ? length(x.tail) + 1 : 100\n'
57 | + '})')
58 | assert.equal(savedReference({ tail: { tail: {} } }), 103)
59 | })
60 |
61 | it('should hot swap nested functions', function() {
62 | var target = thermite.eval('(function outer() {\n'
63 | + ' return "outer-" + inner()\n'
64 | + ' function inner() { return "inner" }\n'
65 | + '})')
66 | var savedReference = target.result
67 | target.hotSwap('(function outer() {\n'
68 | + ' return "outerChanged-" + inner()\n'
69 | + ' function inner() { return "innerChanged" }\n'
70 | + '})')
71 | assert.equal(savedReference(), 'outerChanged-innerChanged')
72 | })
73 |
74 | it('should hot swap nested function twice', function() {
75 | var target = thermite.eval('(' + function outer() {
76 | return function inner() {}
77 | } + ')')
78 |
79 | target.hotSwap('(' + function outer() {
80 | return function inner() { return 'a' }
81 | } + ')')
82 | var callback = target.result()
83 |
84 | target.hotSwap('(' + function outer() {
85 | return function inner() { return 'b' }
86 | } + ')')
87 |
88 | assert.equal(callback(), 'b')
89 | })
90 |
91 | it('should hot swap callbacks twice', function() {
92 | var state = {}
93 | var callback = null
94 | function setCallback(f) { callback = f }
95 |
96 | var target = thermite.eval('(' + function outer(state) {
97 | return 0
98 | } + ')')
99 |
100 | target.hotSwap('(' + function outer(state, setCallback) {
101 | setCallback(function inner() {
102 | state.value = 1
103 | })
104 | } + ')')
105 | target.result(state, setCallback)
106 | callback()
107 |
108 | target.hotSwap('(' + function outer(state, setCallback) {
109 | setCallback(function inner() {
110 | state.value = 2
111 | })
112 | } + ')')
113 | callback()
114 |
115 | assert.equal(state.value, 2)
116 | })
117 |
118 | it('should add functions', function() {
119 | var target = thermite.eval('(function outer() {\n'
120 | + ' return function inner() {}\n'
121 | + '})')
122 | var outer = target.result
123 | target.hotSwap('(function outer() {\n'
124 | + ' return function inner1() {\n'
125 | + ' return function inner2() { return "inner2Result" }\n'
126 | + ' }\n'
127 | + '})')
128 | var inner1 = outer()
129 | var inner2 = inner1()
130 | var inner2Result = inner2()
131 | assert.equal(inner2Result, 'inner2Result')
132 | })
133 |
134 | it('should hotSwap added functions', function() {
135 | var target = thermite.eval('(function outer() {\n'
136 | + ' return function inner() {}\n'
137 | + '})')
138 | var outer = target.result
139 | target.hotSwap('(function outer() {\n'
140 | + ' return function inner1() {\n'
141 | + ' return function inner2() { return "inner2Result" }\n'
142 | + ' }\n'
143 | + '})')
144 | target.hotSwap('(function outer() {\n'
145 | + ' return function inner1() {\n'
146 | + ' return function inner2() { return "inner2ResultChanged" }\n'
147 | + ' }\n'
148 | + '})')
149 | var inner1 = outer()
150 | var inner2 = inner1()
151 | var inner2Result = inner2()
152 | assert.equal(inner2Result, 'inner2ResultChanged')
153 | })
154 |
155 | it('should hotSwap added functions 10 times', function() {
156 | var target = thermite.eval('(function outer() {\n'
157 | + ' return function inner() {}\n'
158 | + '})')
159 | var outer = target.result
160 | for(var i = 0; i < 10; i++)
161 | target.hotSwap('(function outer() {\n'
162 | + ' return function inner1() {\n'
163 | + ' return function inner2() { return ' + i + ' }\n'
164 | + ' }\n'
165 | + '})')
166 | var inner1 = outer()
167 | var inner2 = inner1()
168 | var inner2Result = inner2()
169 | assert.equal(inner2Result, 9)
170 | })
171 |
172 | it('should hotSwap function twice', function() {
173 | var target = thermite.eval('(function outer() {\n'
174 | + ' return function inner() {}\n'
175 | + '})')
176 | var outer = target.result
177 | target.hotSwap('(function outer() {\n'
178 | + ' return function inner() { return 1 }\n'
179 | + '})')
180 | target.hotSwap('(function outer() {\n'
181 | + ' return function inner() { return 2 }\n'
182 | + '})')
183 | var inner = outer()
184 | assert.equal(inner(), 2)
185 | })
186 |
187 | it('should hotSwap 10 times', function() {
188 | var target = thermite.eval('(function outer() {\n'
189 | + ' return function inner() {}\n'
190 | + '})')
191 | var outer = target.result
192 | for(var i = 0; i < 10; i++)
193 | target.hotSwap('(function outer() {\n'
194 | + ' return function inner() { return ' + i + ' }\n'
195 | + '})')
196 | var inner = outer()
197 | assert.equal(inner(), 9) // The last value of `i` is 9.
198 | })
199 |
200 | it('should hotSwap member functions', function() {
201 | var target = thermite.eval('(function() {\n'
202 | + ' return { fn: function() {} }\n'
203 | + '})')
204 | var fn = target.result().fn
205 | target.hotSwap('(function() {\n'
206 | + ' return { fn: function() { return "hotSwapped" } }\n'
207 | + '})')
208 | assert.equal(fn(), 'hotSwapped')
209 | })
210 |
211 | it('should hotSwap all copies of a function', function() {
212 | var target = thermite.eval('(function() {\n'
213 | + ' return function() {}\n'
214 | + '})')
215 | var fn1 = target.result()
216 | var fn2 = target.result()
217 | target.hotSwap('(function() {\n'
218 | + ' return function() { return "hotSwapped" }\n'
219 | + '})')
220 | assert.equal(fn1(), 'hotSwapped')
221 | assert.equal(fn2(), 'hotSwapped')
222 | })
223 |
224 | it('should hotSwap recursive function references', function() {
225 | var recursiveReference
226 |
227 | var target = thermite.eval('(function rec(x) {\n'
228 | + ' return x ? rec(x.tail) + 1 : 0\n'
229 | + '})')
230 |
231 | // Call the function so that recursiveReference gets set
232 | var recursiveReference = target.result
233 |
234 | // Replace this with a new calculation
235 | target.hotSwap('(function rec(x) {\n'
236 | + ' return x ? rec(x.tail) + 1 : 100\n'
237 | + '})')
238 |
239 | assert.equal(recursiveReference({ tail: { tail: {} } }), 103)
240 | })
241 |
242 | it('should propagate parse error', function() {
243 | var originalLog = console.log
244 | var logs = []
245 | console.log = logs.push.bind(logs)
246 | try {
247 | try {
248 | thermite.eval('1.1.1')
249 | } finally {
250 | console.log = originalLog
251 | }
252 | } catch(err) {
253 | assert.equal(logs[0], 'Error parsing source:')
254 | assert.equal(logs[1], '1.1.1')
255 | return
256 | }
257 | assert.fail('failed to propagate error')
258 | })
259 |
260 | it('should propagate parse error during hotSwap', function() {
261 | var target = thermite.eval('1.1')
262 | var originalLog = console.log
263 | var logs = []
264 | console.log = logs.push.bind(logs)
265 | try {
266 | try {
267 | target.hotSwap('1.1.1')
268 | } finally {
269 | console.log = originalLog
270 | }
271 | } catch(err) {
272 | assert.equal(logs[0], 'Error parsing source:')
273 | assert.equal(logs[1], '1.1.1')
274 | return
275 | }
276 | assert.fail('failed to propagate error')
277 | })
278 |
279 | it('should propagate runtime error', function() {
280 | var originalLog = console.log
281 | var logs = []
282 | console.log = logs.push.bind(logs)
283 | try {
284 | try {
285 | thermite.eval('a.b.c')
286 | } finally {
287 | console.log = originalLog
288 | }
289 | } catch(err) {
290 | assert.equal(logs[0], 'Error evaling code:')
291 | assert.equal(logs[1], 'a.b.c')
292 | return
293 | }
294 | assert.fail('failed to propagate error')
295 | })
296 |
297 | it('should handle changing declaration to expression', function() {
298 | var target = thermite.eval('(function() {\n'
299 | + ' function fn(a, b) {\n'
300 | + ' return a + b\n'
301 | + ' }\n'
302 | + ' return fn\n'
303 | + '})()')
304 | var fn = target.result
305 | target.hotSwap('(function() {\n'
306 | + ' var fn = function(a, b) {\n'
307 | + ' return a * b\n'
308 | + ' }\n'
309 | + ' return fn\n'
310 | + '})()')
311 | assert.equal(fn(2, 3), 6)
312 | })
313 |
314 | it('should handle changing expression to declaration', function() {
315 | var target = thermite.eval('(function() {\n'
316 | + ' var fn = function(a, b) {\n'
317 | + ' return a * b\n'
318 | + ' }\n'
319 | + ' return fn\n'
320 | + '})()')
321 | var fn = target.result
322 | target.hotSwap('(function() {\n'
323 | + ' function fn(a, b) {\n'
324 | + ' return a + b\n'
325 | + ' }\n'
326 | + ' return fn\n'
327 | + '})()')
328 | assert.equal(fn(2, 3), 5)
329 | })
330 |
331 | it('should preserve deleted functions', function() {
332 | var target = thermite.eval('(function() {\n'
333 | + ' return function() { return "hello" }\n'
334 | + '})()')
335 | var fn = target.result
336 | target.hotSwap('(function() {\n'
337 | + ' return\n'
338 | + '})()')
339 | assert.equal(fn(), 'hello')
340 | })
341 |
342 | it('should update multiple expressions', function() {
343 | var target = thermite.eval('(function() {\n'
344 | + ' var a = function() { return "a" }\n'
345 | + ' var b = function() { return "b" }\n'
346 | + ' return { a: a, b: b }\n'
347 | + '})()')
348 | var fns = target.result
349 | target.hotSwap('(function() {\n'
350 | + ' var a = function() { return "a1" }\n'
351 | + ' var b = function() { return "b1" }\n'
352 | + ' return { a: a, b: b }\n'
353 | + '})()')
354 | assert.equal(fns.a(), 'a1')
355 | assert.equal(fns.b(), 'b1')
356 | })
357 |
358 | it('should update multiple declarations', function() {
359 | var target = thermite.eval('(function() {\n'
360 | + ' return { a: a, b: b }\n'
361 | + ' function a() { return "a" }\n'
362 | + ' function b() { return "b" }\n'
363 | + '})()')
364 | var fns = target.result
365 | target.hotSwap('(function() {\n'
366 | + ' return { a: a, b: b }\n'
367 | + ' function a() { return "a1" }\n'
368 | + ' function b() { return "b1" }\n'
369 | + '})()')
370 | assert.equal(fns.a(), 'a1')
371 | assert.equal(fns.b(), 'b1')
372 | })
373 |
374 | it('should cache function expressions', function() {
375 | var target = thermite.eval('(function() { return 1 })')
376 | shouldCache(assert, target, null, 1)
377 | })
378 |
379 | it('should cache function declarations', function() {
380 | var target = thermite.eval('(function() {\n'
381 | + ' return x\n'
382 | + ' function x() { return 1 }\n'
383 | + '})()')
384 | shouldCache(assert, target, null, 1)
385 | })
386 |
387 | it('should cache recursive function expressions', function() {
388 | var target = thermite.eval('(function factorial(n) {\n'
389 | + ' return n <= 1 ? 1 : factorial(n - 1) * n\n'
390 | + '})')
391 | shouldCache(assert, target, 3, 6)
392 | })
393 |
394 | it('should cache recursive function declarations', function() {
395 | var target = thermite.eval('(function() {\n'
396 | + ' return factorial\n'
397 | + ' function factorial(n) {\n'
398 | + ' return n <= 1 ? 1 : factorial(n - 1) * n\n'
399 | + ' }\n'
400 | + '})()')
401 | shouldCache(assert, target, 3, 6)
402 | })
403 |
404 | it('should not swap deleted functions', function() {
405 | var target = thermite.eval('(function() {\n'
406 | + ' return function() { return 1 }\n'
407 | + '})')
408 | var fn1 = target.result()
409 | target.hotSwap('(function() {\n'
410 | + ' return\n'
411 | + '})')
412 | target.hotSwap('(function() {\n'
413 | + ' return function() { return 2 }\n'
414 | + '})')
415 | var fn2 = target.result()
416 | assert.equal(fn1(), 1)
417 | assert.equal(fn2(), 2)
418 | })
419 |
420 | it('should swap classes', function() {
421 | var target = thermite.eval('(function() {\n'
422 | + ' function X() { this.a = 1 }\n'
423 | + ' X.prototype.b = function() { return 3 }\n'
424 | + ' return X\n'
425 | + '})()')
426 | var X = target.result
427 | target.hotSwap('(function() {\n'
428 | + ' function X() { this.a = 2 }\n'
429 | + ' X.prototype.b = function() { return 4 }\n'
430 | + ' return X\n'
431 | + '})()')
432 | var instance = new X
433 | assert.equal(instance.a, 2)
434 | assert.equal(instance.b(), 4)
435 | })
436 |
437 | it('should swap base classes', function() {
438 | var target = thermite.eval('(function() {\n'
439 | + ' function Parent() { this.x = 1 }\n'
440 | + ' Parent.prototype.a = function() { return 2 }\n'
441 | + ' function Child() {\n'
442 | + ' Parent.call(this)\n'
443 | + ' this.y = 3\n'
444 | + ' }\n'
445 | + ' Child.prototype = Object.create(Parent.prototype)\n'
446 | + ' return Child\n'
447 | + '})()')
448 | var Child = target.result
449 | target.hotSwap('(function() {\n'
450 | + ' function Parent() { this.x = 10 }\n'
451 | + ' Parent.prototype.a = function() { return 20 }\n'
452 | + ' function Child() {\n'
453 | + ' Parent.call(this)\n'
454 | + ' this.y = 30\n'
455 | + ' }\n'
456 | + ' Child.prototype = Object.create(Parent.prototype)\n'
457 | + ' return Child\n'
458 | + '})()')
459 | var instance = new Child
460 | assert.equal(instance.x, 10)
461 | assert.equal(instance.a(), 20)
462 | assert.equal(instance.y, 30)
463 | })
464 |
465 | it('should preserve bizarre constructor semantics of JavaScript', function() {
466 | var target1 = thermite.eval('(function X() {\n'
467 | + ' this.a = 1\n'
468 | + ' return "string"\n'
469 | + '})')
470 | var X = target1.result
471 | assert.equal(new X() instanceof X, true)
472 | var target2 = thermite.eval('(function Y() {\n'
473 | + ' this.a = 1\n'
474 | + ' return { b: 2 }\n'
475 | + '})')
476 | var Y = target2.result
477 | assert.equal(new Y() instanceof Y, false)
478 | })
479 |
480 | function shouldCache(assert, target, arg, expected) {
481 | assert.equal(target.result(arg), expected)
482 | var originalEval = global.eval
483 | try {
484 | global.eval = assert.fail
485 | assert.equal(target.result(arg), expected)
486 | } finally {
487 | global.eval = originalEval
488 | }
489 | }
490 |
--------------------------------------------------------------------------------
/thermite.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | var falafel = require('falafel')
4 | var DiffMatchPatch = require('googlediff')
5 | var survivor = require('survivor')
6 | var functionNodeTypes = ['FunctionExpression', 'FunctionDeclaration']
7 | var blockIDCounter = new Counter('f')
8 | var contextIDCounter = new Counter('c')
9 |
10 | var template = ['function $thermiteTemplate() {',
11 | '',
12 | 'if(__thermiteMap.$thermiteContextID.$thermiteBlockID.codeVersion >',
13 | ' (__thermiteFunctionVersion_$thermiteBlockID || -1)) {',
14 | '',
15 | ' __thermiteFunction_$thermiteBlockID =',
16 | ' eval(__thermiteMap.$thermiteContextID.$thermiteBlockID.code)',
17 | '',
18 | ' __thermiteFunctionVersion_$thermiteBlockID =',
19 | ' __thermiteMap.$thermiteContextID.$thermiteBlockID.codeVersion',
20 | '}',
21 | '',
22 | 'return __thermiteFunction_$thermiteBlockID.apply(this, arguments)',
23 | '',
24 | '}'].join('\n')
25 |
26 | global.__thermiteMap = {}
27 |
28 | function Counter(label) {
29 | this.label = label
30 | this.value = 0
31 | }
32 |
33 | Counter.prototype.getNextID = function() {
34 | return this.label + (this.value++)
35 | }
36 |
37 | function thermiteEval(source, options) {
38 |
39 | options = options || {}
40 | var fnTree = {}
41 | var state = {
42 | contextID: contextIDCounter.getNextID(),
43 | lastSource: source,
44 | doLineDiff: options.lineDiff || false,
45 | version: 1
46 | }
47 |
48 | var rewritten = forEachNode(source, function(node) {
49 | if(functionNodeTypes.indexOf(node.type) < 0) return
50 | var blockID = blockIDCounter.getNextID()
51 | rewriteNode(state.contextID, blockID, state.version, node)
52 | }).toString()
53 |
54 | return {
55 | hotSwap: function(source) { return hotSwap(state, source) },
56 | result: invokeEval(options.eval || eval, rewritten)
57 | }
58 | }
59 |
60 | function hotSwap(state, source) {
61 |
62 | state.version++
63 |
64 | var version = state.version
65 | var contextID = state.contextID
66 | var dmp = new DiffMatchPatch()
67 | var diffs = dmp.diff_main(state.lastSource, source, state.doLineDiff)
68 | var lookup = survivor(diffs, true)
69 | var entries = getEntriesForContext(contextID)
70 | var entriesByRangeString = {}
71 | var persistedBlockIDs = {}
72 |
73 | for(var blockID in entries) {
74 | var entry = entries[blockID]
75 | if(entry.deleted) continue
76 | var rangeString = rangeToString(entry.node.range)
77 | entriesByRangeString[rangeString] = entry
78 | }
79 |
80 | forEachNode(source, function(node) {
81 | if(functionNodeTypes.indexOf(node.type) < 0) return
82 | var startSurvived = lookup(node.range[0])
83 | var endSurvived = lookup(node.range[1])
84 | var existingEntry = startSurvived
85 | && endSurvived
86 | && entriesByRangeString[rangeToString([startSurvived, endSurvived])]
87 | var blockID = existingEntry
88 | ? existingEntry.blockID
89 | : blockIDCounter.getNextID()
90 | rewriteNode(contextID, blockID, version, node)
91 | persistedBlockIDs[blockID] = true
92 | })
93 |
94 | for(var blockID in entries)
95 | if(!(blockID in persistedBlockIDs))
96 | entries[blockID].deleted = true
97 |
98 | state.lastSource = source
99 | }
100 |
101 | function getEntriesForContext(contextID) {
102 | return __thermiteMap[contextID] = __thermiteMap[contextID] || {}
103 | }
104 |
105 | function invokeEval(evaler, code) {
106 | try {
107 | return evaler(code)
108 | } catch(err) {
109 | console.log('Error evaling code:')
110 | console.log(code)
111 | throw err
112 | }
113 | }
114 |
115 | function forEachNode(source, visitor) {
116 | try {
117 | return falafel(source, { ranges: true }, visitor)
118 | } catch(err) {
119 | console.log('Error parsing source:')
120 | console.log(source)
121 | throw err
122 | }
123 | }
124 |
125 | function rewriteNode(contextID, blockID, version, node) {
126 | var code = node.source()
127 | var name = ''
128 | // Strip out the name (to handle recursive references)
129 | if(node.id && node.id.name) {
130 | name = node.id.name
131 | code = code.replace(name, '')
132 | node.update(code)
133 | }
134 | var addVersionTo = {
135 | FunctionDeclaration: addVersionToDeclaration,
136 | FunctionExpression: addVersionToExpression
137 | }
138 | var boundTemplate = addVersionTo[node.type](template, name)
139 | .replace(/\$thermiteTemplate/g, name)
140 | .replace(/\$thermiteBlockID/g, blockID)
141 | .replace(/\$thermiteContextID/g, contextID)
142 | node.update(boundTemplate)
143 | var rewritten = '(' + code + ')'
144 | var entries = getEntriesForContext(contextID)
145 | entries[blockID] = {
146 | blockID: blockID,
147 | node: node,
148 | codeVersion: version,
149 | code: rewritten
150 | }
151 | }
152 |
153 | function addVersionToDeclaration(template, name) {
154 | return '; '
155 | + 'var __thermiteFunctionVersion_$thermiteBlockID; '
156 | + 'var __thermiteFunction_$thermiteBlockID; '
157 | + template
158 | }
159 |
160 | function addVersionToExpression(template, name) {
161 | return '(function ' + name + '() { '
162 | + 'var __thermiteFunctionVersion_$thermiteBlockID; '
163 | + 'var __thermiteFunction_$thermiteBlockID; '
164 | + 'return (' + template + ');'
165 | + '})()'
166 | }
167 |
168 | function rangeToString(range) {
169 | return 'from' + range[0] + 'to' + range[1]
170 | }
171 |
172 | exports.eval = thermiteEval
173 |
174 |
--------------------------------------------------------------------------------
/thermite.min.js:
--------------------------------------------------------------------------------
1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.thermite=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o=len)return x;switch(x){case"%s":return String(args[i++]);case"%d":return Number(args[i++]);case"%j":try{return JSON.stringify(args[i++])}catch(_){return"[Circular]"}default:return x}});for(var x=args[i];i=3)ctx.depth=arguments[2];if(arguments.length>=4)ctx.colors=arguments[3];if(isBoolean(opts)){ctx.showHidden=opts}else if(opts){exports._extend(ctx,opts)}if(isUndefined(ctx.showHidden))ctx.showHidden=false;if(isUndefined(ctx.depth))ctx.depth=2;if(isUndefined(ctx.colors))ctx.colors=false;if(isUndefined(ctx.customInspect))ctx.customInspect=true;if(ctx.colors)ctx.stylize=stylizeWithColor;return formatValue(ctx,obj,ctx.depth)}exports.inspect=inspect;inspect.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]};inspect.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"};function stylizeWithColor(str,styleType){var style=inspect.styles[styleType];if(style){return"["+inspect.colors[style][0]+"m"+str+"["+inspect.colors[style][1]+"m"}else{return str}}function stylizeNoColor(str,styleType){return str}function arrayToHash(array){var hash={};array.forEach(function(val,idx){hash[val]=true});return hash}function formatValue(ctx,value,recurseTimes){if(ctx.customInspect&&value&&isFunction(value.inspect)&&value.inspect!==exports.inspect&&!(value.constructor&&value.constructor.prototype===value)){var ret=value.inspect(recurseTimes,ctx);if(!isString(ret)){ret=formatValue(ctx,ret,recurseTimes)}return ret}var primitive=formatPrimitive(ctx,value);if(primitive){return primitive}var keys=Object.keys(value);var visibleKeys=arrayToHash(keys);if(ctx.showHidden){keys=Object.getOwnPropertyNames(value)}if(isError(value)&&(keys.indexOf("message")>=0||keys.indexOf("description")>=0)){return formatError(value)}if(keys.length===0){if(isFunction(value)){var name=value.name?": "+value.name:"";return ctx.stylize("[Function"+name+"]","special")}if(isRegExp(value)){return ctx.stylize(RegExp.prototype.toString.call(value),"regexp")}if(isDate(value)){return ctx.stylize(Date.prototype.toString.call(value),"date")}if(isError(value)){return formatError(value)}}var base="",array=false,braces=["{","}"];if(isArray(value)){array=true;braces=["[","]"]}if(isFunction(value)){var n=value.name?": "+value.name:"";base=" [Function"+n+"]"}if(isRegExp(value)){base=" "+RegExp.prototype.toString.call(value)}if(isDate(value)){base=" "+Date.prototype.toUTCString.call(value)}if(isError(value)){base=" "+formatError(value)}if(keys.length===0&&(!array||value.length==0)){return braces[0]+base+braces[1]}if(recurseTimes<0){if(isRegExp(value)){return ctx.stylize(RegExp.prototype.toString.call(value),"regexp")}else{return ctx.stylize("[Object]","special")}}ctx.seen.push(value);var output;if(array){output=formatArray(ctx,value,recurseTimes,visibleKeys,keys)}else{output=keys.map(function(key){return formatProperty(ctx,value,recurseTimes,visibleKeys,key,array)})}ctx.seen.pop();return reduceToSingleString(output,base,braces)}function formatPrimitive(ctx,value){if(isUndefined(value))return ctx.stylize("undefined","undefined");if(isString(value)){var simple="'"+JSON.stringify(value).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return ctx.stylize(simple,"string")}if(isNumber(value))return ctx.stylize(""+value,"number");if(isBoolean(value))return ctx.stylize(""+value,"boolean");if(isNull(value))return ctx.stylize("null","null")}function formatError(value){return"["+Error.prototype.toString.call(value)+"]"}function formatArray(ctx,value,recurseTimes,visibleKeys,keys){var output=[];for(var i=0,l=value.length;i-1){if(array){str=str.split("\n").map(function(line){return" "+line}).join("\n").substr(2)}else{str="\n"+str.split("\n").map(function(line){return" "+line}).join("\n")}}}else{str=ctx.stylize("[Circular]","special")}}if(isUndefined(name)){if(array&&key.match(/^\d+$/)){return str}name=JSON.stringify(""+key);if(name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)){name=name.substr(1,name.length-2);name=ctx.stylize(name,"name")}else{name=name.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'");name=ctx.stylize(name,"string")}}return name+": "+str}function reduceToSingleString(output,base,braces){var numLinesEst=0;var length=output.reduce(function(prev,cur){numLinesEst++;if(cur.indexOf("\n")>=0)numLinesEst++;return prev+cur.replace(/\u001b\[\d\d?m/g,"").length+1},0);if(length>60){return braces[0]+(base===""?"":base+"\n ")+" "+output.join(",\n ")+" "+braces[1]}return braces[0]+base+" "+output.join(", ")+" "+braces[1]}function isArray(ar){return Array.isArray(ar)}exports.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports.isBoolean=isBoolean;function isNull(arg){return arg===null}exports.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports.isUndefined=isUndefined;function isRegExp(re){return isObject(re)&&objectToString(re)==="[object RegExp]"}exports.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports.isObject=isObject;function isDate(d){return isObject(d)&&objectToString(d)==="[object Date]"}exports.isDate=isDate;function isError(e){return isObject(e)&&(objectToString(e)==="[object Error]"||e instanceof Error)}exports.isError=isError;function isFunction(arg){return typeof arg==="function"}exports.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports.isPrimitive=isPrimitive;exports.isBuffer=_dereq_("./support/isBuffer");function objectToString(o){return Object.prototype.toString.call(o)}function pad(n){return n<10?"0"+n.toString(10):n.toString(10)}var months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function timestamp(){var d=new Date;var time=[pad(d.getHours()),pad(d.getMinutes()),pad(d.getSeconds())].join(":");return[d.getDate(),months[d.getMonth()],time].join(" ")}exports.log=function(){console.log("%s - %s",timestamp(),exports.format.apply(exports,arguments))};exports.inherits=_dereq_("inherits");exports._extend=function(origin,add){if(!add||!isObject(add))return origin;var keys=Object.keys(add);var i=keys.length;while(i--){origin[keys[i]]=add[keys[i]]}return origin};function hasOwnProperty(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)}}).call(this,_dereq_("_process"),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./support/isBuffer":4,_process:3,inherits:2}],6:[function(_dereq_,module,exports){"use strict";var tt=_dereq_("./tokentype").types;var Parser=_dereq_("./state").Parser;var reservedWords=_dereq_("./identifier").reservedWords;var has=_dereq_("./util").has;var pp=Parser.prototype;pp.checkPropClash=function(prop,propHash){if(this.options.ecmaVersion>=6)return;var key=prop.key,name=undefined;switch(key.type){case"Identifier":name=key.name;break;case"Literal":name=String(key.value);break;default:return}var kind=prop.kind||"init",other=undefined;if(has(propHash,name)){other=propHash[name];var isGetSet=kind!=="init";if((this.strict||isGetSet)&&other[kind]||!(isGetSet^other.init))this.raise(key.start,"Redefinition of property")}else{other=propHash[name]={init:false,get:false,set:false}}other[kind]=true};pp.parseExpression=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseMaybeAssign(noIn,refShorthandDefaultPos);if(this.type===tt.comma){var node=this.startNodeAt(startPos,startLoc);node.expressions=[expr];while(this.eat(tt.comma))node.expressions.push(this.parseMaybeAssign(noIn,refShorthandDefaultPos));return this.finishNode(node,"SequenceExpression")}return expr};pp.parseMaybeAssign=function(noIn,refShorthandDefaultPos,afterLeftParse){if(this.type==tt._yield&&this.inGenerator)return this.parseYield();var failOnShorthandAssign=undefined;if(!refShorthandDefaultPos){refShorthandDefaultPos={start:0};failOnShorthandAssign=true}else{failOnShorthandAssign=false}var startPos=this.start,startLoc=this.startLoc;if(this.type==tt.parenL||this.type==tt.name)this.potentialArrowAt=this.start;var left=this.parseMaybeConditional(noIn,refShorthandDefaultPos);if(afterLeftParse)left=afterLeftParse.call(this,left,startPos,startLoc);if(this.type.isAssign){var node=this.startNodeAt(startPos,startLoc);node.operator=this.value;node.left=this.type===tt.eq?this.toAssignable(left):left;refShorthandDefaultPos.start=0;this.checkLVal(left);this.next();node.right=this.parseMaybeAssign(noIn);return this.finishNode(node,"AssignmentExpression")}else if(failOnShorthandAssign&&refShorthandDefaultPos.start){this.unexpected(refShorthandDefaultPos.start)}return left};pp.parseMaybeConditional=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprOps(noIn,refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;if(this.eat(tt.question)){var node=this.startNodeAt(startPos,startLoc);node.test=expr;node.consequent=this.parseMaybeAssign();this.expect(tt.colon);node.alternate=this.parseMaybeAssign(noIn);return this.finishNode(node,"ConditionalExpression")}return expr};pp.parseExprOps=function(noIn,refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseMaybeUnary(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;return this.parseExprOp(expr,startPos,startLoc,-1,noIn)};pp.parseExprOp=function(left,leftStartPos,leftStartLoc,minPrec,noIn){var prec=this.type.binop;if(Array.isArray(leftStartPos)){if(this.options.locations&&noIn===undefined){noIn=minPrec;minPrec=leftStartLoc;leftStartLoc=leftStartPos[1];leftStartPos=leftStartPos[0]}}if(prec!=null&&(!noIn||this.type!==tt._in)){if(prec>minPrec){var node=this.startNodeAt(leftStartPos,leftStartLoc);node.left=left;node.operator=this.value;var op=this.type;this.next();var startPos=this.start,startLoc=this.startLoc;node.right=this.parseExprOp(this.parseMaybeUnary(),startPos,startLoc,prec,noIn);this.finishNode(node,op===tt.logicalOR||op===tt.logicalAND?"LogicalExpression":"BinaryExpression");return this.parseExprOp(node,leftStartPos,leftStartLoc,minPrec,noIn)}}return left};pp.parseMaybeUnary=function(refShorthandDefaultPos){if(this.type.prefix){var node=this.startNode(),update=this.type===tt.incDec;node.operator=this.value;node.prefix=true;this.next();node.argument=this.parseMaybeUnary();if(refShorthandDefaultPos&&refShorthandDefaultPos.start)this.unexpected(refShorthandDefaultPos.start);if(update)this.checkLVal(node.argument);else if(this.strict&&node.operator==="delete"&&node.argument.type==="Identifier")this.raise(node.start,"Deleting local variable in strict mode");return this.finishNode(node,update?"UpdateExpression":"UnaryExpression")}var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprSubscripts(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;while(this.type.postfix&&!this.canInsertSemicolon()){var node=this.startNodeAt(startPos,startLoc);node.operator=this.value;node.prefix=false;node.argument=expr;this.checkLVal(expr);this.next();expr=this.finishNode(node,"UpdateExpression")}return expr};pp.parseExprSubscripts=function(refShorthandDefaultPos){var startPos=this.start,startLoc=this.startLoc;var expr=this.parseExprAtom(refShorthandDefaultPos);if(refShorthandDefaultPos&&refShorthandDefaultPos.start)return expr;return this.parseSubscripts(expr,startPos,startLoc)};pp.parseSubscripts=function(base,startPos,startLoc,noCalls){if(Array.isArray(startPos)){if(this.options.locations&&noCalls===undefined){noCalls=startLoc;startLoc=startPos[1];startPos=startPos[0]}}for(;;){if(this.eat(tt.dot)){var node=this.startNodeAt(startPos,startLoc);node.object=base;node.property=this.parseIdent(true);node.computed=false;base=this.finishNode(node,"MemberExpression")}else if(this.eat(tt.bracketL)){var node=this.startNodeAt(startPos,startLoc);node.object=base;node.property=this.parseExpression();node.computed=true;this.expect(tt.bracketR);base=this.finishNode(node,"MemberExpression")}else if(!noCalls&&this.eat(tt.parenL)){var node=this.startNodeAt(startPos,startLoc);node.callee=base;node.arguments=this.parseExprList(tt.parenR,false);base=this.finishNode(node,"CallExpression")}else if(this.type===tt.backQuote){var node=this.startNodeAt(startPos,startLoc);node.tag=base;node.quasi=this.parseTemplate();base=this.finishNode(node,"TaggedTemplateExpression")}else{return base}}};pp.parseExprAtom=function(refShorthandDefaultPos){var node=undefined,canBeArrow=this.potentialArrowAt==this.start;switch(this.type){case tt._this:case tt._super:var type=this.type===tt._this?"ThisExpression":"Super";node=this.startNode();this.next();return this.finishNode(node,type);case tt._yield:if(this.inGenerator)this.unexpected();case tt.name:var startPos=this.start,startLoc=this.startLoc;var id=this.parseIdent(this.type!==tt.name);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(tt.arrow))return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),[id]);return id;case tt.regexp:var value=this.value;node=this.parseLiteral(value.value);node.regex={pattern:value.pattern,flags:value.flags};return node;case tt.num:case tt.string:return this.parseLiteral(this.value);case tt._null:case tt._true:case tt._false:node=this.startNode();node.value=this.type===tt._null?null:this.type===tt._true;node.raw=this.type.keyword;this.next();return this.finishNode(node,"Literal");case tt.parenL:return this.parseParenAndDistinguishExpression(canBeArrow);case tt.bracketL:node=this.startNode();this.next();if(this.options.ecmaVersion>=7&&this.type===tt._for){return this.parseComprehension(node,false)}node.elements=this.parseExprList(tt.bracketR,true,true,refShorthandDefaultPos);return this.finishNode(node,"ArrayExpression");case tt.braceL:return this.parseObj(false,refShorthandDefaultPos);case tt._function:node=this.startNode();this.next();return this.parseFunction(node,false);case tt._class:return this.parseClass(this.startNode(),false);case tt._new:return this.parseNew();case tt.backQuote:return this.parseTemplate();default:this.unexpected()}};pp.parseLiteral=function(value){var node=this.startNode();node.value=value;node.raw=this.input.slice(this.start,this.end);this.next();return this.finishNode(node,"Literal")};pp.parseParenExpression=function(){this.expect(tt.parenL);var val=this.parseExpression();this.expect(tt.parenR);return val};pp.parseParenAndDistinguishExpression=function(canBeArrow){var startPos=this.start,startLoc=this.startLoc,val=undefined;if(this.options.ecmaVersion>=6){this.next();if(this.options.ecmaVersion>=7&&this.type===tt._for){return this.parseComprehension(this.startNodeAt(startPos,startLoc),true)}var innerStartPos=this.start,innerStartLoc=this.startLoc;var exprList=[],first=true;var refShorthandDefaultPos={start:0},spreadStart=undefined,innerParenStart=undefined;while(this.type!==tt.parenR){first?first=false:this.expect(tt.comma);if(this.type===tt.ellipsis){spreadStart=this.start;exprList.push(this.parseParenItem(this.parseRest()));break}else{if(this.type===tt.parenL&&!innerParenStart){innerParenStart=this.start}exprList.push(this.parseMaybeAssign(false,refShorthandDefaultPos,this.parseParenItem))}}var innerEndPos=this.start,innerEndLoc=this.startLoc;this.expect(tt.parenR);if(canBeArrow&&!this.canInsertSemicolon()&&this.eat(tt.arrow)){if(innerParenStart)this.unexpected(innerParenStart);return this.parseParenArrowList(startPos,startLoc,exprList)}if(!exprList.length)this.unexpected(this.lastTokStart);if(spreadStart)this.unexpected(spreadStart);if(refShorthandDefaultPos.start)this.unexpected(refShorthandDefaultPos.start);if(exprList.length>1){val=this.startNodeAt(innerStartPos,innerStartLoc);val.expressions=exprList;this.finishNodeAt(val,"SequenceExpression",innerEndPos,innerEndLoc)}else{val=exprList[0]}}else{val=this.parseParenExpression()}if(this.options.preserveParens){var par=this.startNodeAt(startPos,startLoc);par.expression=val;return this.finishNode(par,"ParenthesizedExpression")}else{return val}};pp.parseParenItem=function(item){return item};pp.parseParenArrowList=function(startPos,startLoc,exprList){return this.parseArrowExpression(this.startNodeAt(startPos,startLoc),exprList)};var empty=[];pp.parseNew=function(){var node=this.startNode();var meta=this.parseIdent(true);if(this.options.ecmaVersion>=6&&this.eat(tt.dot)){node.meta=meta;node.property=this.parseIdent(true);if(node.property.name!=="target")this.raise(node.property.start,"The only valid meta property for new is new.target");return this.finishNode(node,"MetaProperty")}var startPos=this.start,startLoc=this.startLoc;node.callee=this.parseSubscripts(this.parseExprAtom(),startPos,startLoc,true);if(this.eat(tt.parenL))node.arguments=this.parseExprList(tt.parenR,false);else node.arguments=empty;return this.finishNode(node,"NewExpression")};pp.parseTemplateElement=function(){var elem=this.startNode();elem.value={raw:this.input.slice(this.start,this.end),cooked:this.value};this.next();elem.tail=this.type===tt.backQuote;return this.finishNode(elem,"TemplateElement")};pp.parseTemplate=function(){var node=this.startNode();this.next();node.expressions=[];var curElt=this.parseTemplateElement();node.quasis=[curElt];while(!curElt.tail){this.expect(tt.dollarBraceL);node.expressions.push(this.parseExpression());this.expect(tt.braceR);node.quasis.push(curElt=this.parseTemplateElement())}this.next();return this.finishNode(node,"TemplateLiteral")};pp.parseObj=function(isPattern,refShorthandDefaultPos){var node=this.startNode(),first=true,propHash={};node.properties=[];this.next();while(!this.eat(tt.braceR)){if(!first){this.expect(tt.comma);if(this.afterTrailingComma(tt.braceR))break}else first=false;var prop=this.startNode(),isGenerator=undefined,startPos=undefined,startLoc=undefined;if(this.options.ecmaVersion>=6){prop.method=false;prop.shorthand=false;if(isPattern||refShorthandDefaultPos){startPos=this.start;startLoc=this.startLoc}if(!isPattern)isGenerator=this.eat(tt.star)}this.parsePropertyName(prop);this.parsePropertyValue(prop,isPattern,isGenerator,startPos,startLoc,refShorthandDefaultPos);this.checkPropClash(prop,propHash);node.properties.push(this.finishNode(prop,"Property"))}return this.finishNode(node,isPattern?"ObjectPattern":"ObjectExpression")};pp.parsePropertyValue=function(prop,isPattern,isGenerator,startPos,startLoc,refShorthandDefaultPos){if(this.eat(tt.colon)){prop.value=isPattern?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(false,refShorthandDefaultPos);prop.kind="init"}else if(this.options.ecmaVersion>=6&&this.type===tt.parenL){if(isPattern)this.unexpected();prop.kind="init";prop.method=true;prop.value=this.parseMethod(isGenerator)}else if(this.options.ecmaVersion>=5&&!prop.computed&&prop.key.type==="Identifier"&&(prop.key.name==="get"||prop.key.name==="set")&&(this.type!=tt.comma&&this.type!=tt.braceR)){if(isGenerator||isPattern)this.unexpected();prop.kind=prop.key.name;this.parsePropertyName(prop);prop.value=this.parseMethod(false)}else if(this.options.ecmaVersion>=6&&!prop.computed&&prop.key.type==="Identifier"){prop.kind="init";if(isPattern){if(this.isKeyword(prop.key.name)||this.strict&&(reservedWords.strictBind(prop.key.name)||reservedWords.strict(prop.key.name))||!this.options.allowReserved&&this.isReservedWord(prop.key.name))this.raise(prop.key.start,"Binding "+prop.key.name);prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key)}else if(this.type===tt.eq&&refShorthandDefaultPos){if(!refShorthandDefaultPos.start)refShorthandDefaultPos.start=this.start;prop.value=this.parseMaybeDefault(startPos,startLoc,prop.key)}else{prop.value=prop.key}prop.shorthand=true}else this.unexpected()};pp.parsePropertyName=function(prop){if(this.options.ecmaVersion>=6){if(this.eat(tt.bracketL)){prop.computed=true;prop.key=this.parseMaybeAssign();this.expect(tt.bracketR);return prop.key}else{prop.computed=false}}return prop.key=this.type===tt.num||this.type===tt.string?this.parseExprAtom():this.parseIdent(true)};pp.initFunction=function(node){node.id=null;if(this.options.ecmaVersion>=6){node.generator=false;node.expression=false}};pp.parseMethod=function(isGenerator){var node=this.startNode();this.initFunction(node);this.expect(tt.parenL);node.params=this.parseBindingList(tt.parenR,false,false);var allowExpressionBody=undefined;if(this.options.ecmaVersion>=6){node.generator=isGenerator;allowExpressionBody=true}else{allowExpressionBody=false}this.parseFunctionBody(node,allowExpressionBody);return this.finishNode(node,"FunctionExpression")};pp.parseArrowExpression=function(node,params){this.initFunction(node);node.params=this.toAssignableList(params,true);this.parseFunctionBody(node,true);return this.finishNode(node,"ArrowFunctionExpression")};pp.parseFunctionBody=function(node,allowExpression){var isExpression=allowExpression&&this.type!==tt.braceL;if(isExpression){node.body=this.parseMaybeAssign();node.expression=true}else{var oldInFunc=this.inFunction,oldInGen=this.inGenerator,oldLabels=this.labels;this.inFunction=true;this.inGenerator=node.generator;this.labels=[];node.body=this.parseBlock(true);node.expression=false;this.inFunction=oldInFunc;this.inGenerator=oldInGen;this.labels=oldLabels}if(this.strict||!isExpression&&node.body.body.length&&this.isUseStrict(node.body.body[0])){var nameHash={},oldStrict=this.strict;this.strict=true;if(node.id)this.checkLVal(node.id,true);for(var i=0;i=6||this.input.slice(this.start,this.end).indexOf("\\")==-1)))this.raise(this.start,"The keyword '"+this.value+"' is reserved");node.name=this.value}else if(liberal&&this.type.keyword){node.name=this.type.keyword}else{this.unexpected()}this.next();
2 |
3 | return this.finishNode(node,"Identifier")};pp.parseYield=function(){var node=this.startNode();this.next();if(this.type==tt.semi||this.canInsertSemicolon()||this.type!=tt.star&&!this.type.startsExpr){node.delegate=false;node.argument=null}else{node.delegate=this.eat(tt.star);node.argument=this.parseMaybeAssign()}return this.finishNode(node,"YieldExpression")};pp.parseComprehension=function(node,isGenerator){node.blocks=[];while(this.type===tt._for){var block=this.startNode();this.next();this.expect(tt.parenL);block.left=this.parseBindingAtom();this.checkLVal(block.left,true);this.expectContextual("of");block.right=this.parseExpression();this.expect(tt.parenR);node.blocks.push(this.finishNode(block,"ComprehensionBlock"))}node.filter=this.eat(tt._if)?this.parseParenExpression():null;node.body=this.parseExpression();this.expect(isGenerator?tt.parenR:tt.bracketR);node.generator=isGenerator;return this.finishNode(node,"ComprehensionExpression")}},{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],7:[function(_dereq_,module,exports){"use strict";exports.isIdentifierStart=isIdentifierStart;exports.isIdentifierChar=isIdentifierChar;exports.__esModule=true;function makePredicate(words){words=words.split(" ");var f="",cats=[];out:for(var i=0;i3){cats.sort(function(a,b){return b.length-a.length});f+="switch(str.length){";for(var i=0;icode){return false}pos+=set[i+1];if(pos>=code){return true}}}function isIdentifierStart(code,astral){if(code<65){return code===36}if(code<91){return true}if(code<97){return code===95}if(code<123){return true}if(code<=65535){return code>=170&&nonASCIIidentifierStart.test(String.fromCharCode(code))}if(astral===false){return false}return isInAstralSet(code,astralIdentifierStartCodes)}function isIdentifierChar(code,astral){if(code<48){return code===36}if(code<58){return true}if(code<65){return false}if(code<91){return true}if(code<97){return code===95}if(code<123){return true}if(code<=65535){return code>=170&&nonASCIIidentifier.test(String.fromCharCode(code))}if(astral===false){return false}return isInAstralSet(code,astralIdentifierStartCodes)||isInAstralSet(code,astralIdentifierCodes)}},{}],8:[function(_dereq_,module,exports){"use strict";var _classCallCheck=function(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}};exports.getLineInfo=getLineInfo;exports.__esModule=true;var Parser=_dereq_("./state").Parser;var lineBreakG=_dereq_("./whitespace").lineBreakG;var deprecate=_dereq_("util").deprecate;var Position=exports.Position=function(){function Position(line,col){_classCallCheck(this,Position);this.line=line;this.column=col}Position.prototype.offset=function offset(n){return new Position(this.line,this.column+n)};return Position}();var SourceLocation=exports.SourceLocation=function SourceLocation(p,start,end){_classCallCheck(this,SourceLocation);this.start=start;this.end=end;if(p.sourceFile!==null)this.source=p.sourceFile};function getLineInfo(input,offset){for(var line=1,cur=0;;){lineBreakG.lastIndex=cur;var match=lineBreakG.exec(input);if(match&&match.index=6&&node){switch(node.type){case"Identifier":case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":break;case"ObjectExpression":node.type="ObjectPattern";for(var i=0;i=5&&stmt.type==="ExpressionStatement"&&stmt.expression.type==="Literal"&&stmt.expression.value==="use strict"};pp.eat=function(type){if(this.type===type){this.next();return true}else{return false}};pp.isContextual=function(name){return this.type===tt.name&&this.value===name};pp.eatContextual=function(name){return this.value===name&&this.eat(tt.name)};pp.expectContextual=function(name){if(!this.eatContextual(name))this.unexpected()};pp.canInsertSemicolon=function(){return this.type===tt.eof||this.type===tt.braceR||lineBreak.test(this.input.slice(this.lastTokEnd,this.start))};pp.insertSemicolon=function(){if(this.canInsertSemicolon()){if(this.options.onInsertedSemicolon)this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc);return true}};pp.semicolon=function(){if(!this.eat(tt.semi)&&!this.insertSemicolon())this.unexpected()};pp.afterTrailingComma=function(tokType){if(this.type==tokType){if(this.options.onTrailingComma)this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc);this.next();return true}};pp.expect=function(type){this.eat(type)||this.unexpected()};pp.unexpected=function(pos){this.raise(pos!=null?pos:this.start,"Unexpected token")}},{"./state":13,"./tokentype":17,"./whitespace":19}],13:[function(_dereq_,module,exports){"use strict";exports.Parser=Parser;exports.__esModule=true;var _identifier=_dereq_("./identifier");var reservedWords=_identifier.reservedWords;var keywords=_identifier.keywords;var tt=_dereq_("./tokentype").types;var lineBreak=_dereq_("./whitespace").lineBreak;function Parser(options,input,startPos){this.options=options;this.sourceFile=this.options.sourceFile||null;this.isKeyword=keywords[this.options.ecmaVersion>=6?6:5];this.isReservedWord=reservedWords[this.options.ecmaVersion];this.input=input;this.loadPlugins(this.options.plugins);if(startPos){this.pos=startPos;this.lineStart=Math.max(0,this.input.lastIndexOf("\n",startPos));this.curLine=this.input.slice(0,this.lineStart).split(lineBreak).length}else{this.pos=this.lineStart=0;this.curLine=1}this.type=tt.eof;this.value=null;this.start=this.end=this.pos;this.startLoc=this.endLoc=null;this.lastTokEndLoc=this.lastTokStartLoc=null;this.lastTokStart=this.lastTokEnd=this.pos;this.context=this.initialContext();this.exprAllowed=true;this.strict=this.inModule=this.options.sourceType==="module";this.potentialArrowAt=-1;this.inFunction=this.inGenerator=false;this.labels=[];if(this.pos===0&&this.options.allowHashBang&&this.input.slice(0,2)==="#!")this.skipLineComment(2)}Parser.prototype.extend=function(name,f){this[name]=f(this[name])};var plugins={};exports.plugins=plugins;Parser.prototype.loadPlugins=function(plugins){for(var _name in plugins){var plugin=exports.plugins[_name];if(!plugin)throw new Error("Plugin '"+_name+"' not found");plugin(this,plugins[_name])}}},{"./identifier":7,"./tokentype":17,"./whitespace":19}],14:[function(_dereq_,module,exports){"use strict";var tt=_dereq_("./tokentype").types;var Parser=_dereq_("./state").Parser;var lineBreak=_dereq_("./whitespace").lineBreak;var pp=Parser.prototype;pp.parseTopLevel=function(node){var first=true;if(!node.body)node.body=[];while(this.type!==tt.eof){var stmt=this.parseStatement(true,true);node.body.push(stmt);if(first&&this.isUseStrict(stmt))this.setStrict(true);first=false}this.next();if(this.options.ecmaVersion>=6){node.sourceType=this.options.sourceType}return this.finishNode(node,"Program")};var loopLabel={kind:"loop"},switchLabel={kind:"switch"};pp.parseStatement=function(declaration,topLevel){var starttype=this.type,node=this.startNode();switch(starttype){case tt._break:case tt._continue:return this.parseBreakContinueStatement(node,starttype.keyword);case tt._debugger:return this.parseDebuggerStatement(node);case tt._do:return this.parseDoStatement(node);case tt._for:return this.parseForStatement(node);case tt._function:if(!declaration&&this.options.ecmaVersion>=6)this.unexpected();return this.parseFunctionStatement(node);case tt._class:if(!declaration)this.unexpected();return this.parseClass(node,true);case tt._if:return this.parseIfStatement(node);case tt._return:return this.parseReturnStatement(node);case tt._switch:return this.parseSwitchStatement(node);case tt._throw:return this.parseThrowStatement(node);case tt._try:return this.parseTryStatement(node);case tt._let:case tt._const:if(!declaration)this.unexpected();case tt._var:return this.parseVarStatement(node,starttype);case tt._while:return this.parseWhileStatement(node);case tt._with:return this.parseWithStatement(node);case tt.braceL:return this.parseBlock();case tt.semi:return this.parseEmptyStatement(node);case tt._export:case tt._import:if(!this.options.allowImportExportEverywhere){if(!topLevel)this.raise(this.start,"'import' and 'export' may only appear at the top level");if(!this.inModule)this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")}return starttype===tt._import?this.parseImport(node):this.parseExport(node);default:var maybeName=this.value,expr=this.parseExpression();if(starttype===tt.name&&expr.type==="Identifier"&&this.eat(tt.colon))return this.parseLabeledStatement(node,maybeName,expr);else return this.parseExpressionStatement(node,expr)}};pp.parseBreakContinueStatement=function(node,keyword){var isBreak=keyword=="break";this.next();if(this.eat(tt.semi)||this.insertSemicolon())node.label=null;else if(this.type!==tt.name)this.unexpected();else{node.label=this.parseIdent();this.semicolon()}for(var i=0;i=6)this.eat(tt.semi);else this.semicolon();return this.finishNode(node,"DoWhileStatement")};pp.parseForStatement=function(node){this.next();this.labels.push(loopLabel);this.expect(tt.parenL);if(this.type===tt.semi)return this.parseFor(node,null);if(this.type===tt._var||this.type===tt._let||this.type===tt._const){var _init=this.startNode(),varKind=this.type;this.next();this.parseVar(_init,true,varKind);this.finishNode(_init,"VariableDeclaration");if((this.type===tt._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&_init.declarations.length===1&&!(varKind!==tt._var&&_init.declarations[0].init))return this.parseForIn(node,_init);return this.parseFor(node,_init)}var refShorthandDefaultPos={start:0};var init=this.parseExpression(true,refShorthandDefaultPos);if(this.type===tt._in||this.options.ecmaVersion>=6&&this.isContextual("of")){this.toAssignable(init);this.checkLVal(init);return this.parseForIn(node,init)}else if(refShorthandDefaultPos.start){this.unexpected(refShorthandDefaultPos.start)}return this.parseFor(node,init)};pp.parseFunctionStatement=function(node){this.next();return this.parseFunction(node,true)};pp.parseIfStatement=function(node){this.next();node.test=this.parseParenExpression();node.consequent=this.parseStatement(false);node.alternate=this.eat(tt._else)?this.parseStatement(false):null;return this.finishNode(node,"IfStatement")};pp.parseReturnStatement=function(node){if(!this.inFunction&&!this.options.allowReturnOutsideFunction)this.raise(this.start,"'return' outside of function");this.next();if(this.eat(tt.semi)||this.insertSemicolon())node.argument=null;else{node.argument=this.parseExpression();this.semicolon()}return this.finishNode(node,"ReturnStatement")};pp.parseSwitchStatement=function(node){this.next();node.discriminant=this.parseParenExpression();node.cases=[];this.expect(tt.braceL);this.labels.push(switchLabel);for(var cur,sawDefault;this.type!=tt.braceR;){if(this.type===tt._case||this.type===tt._default){var isCase=this.type===tt._case;if(cur)this.finishNode(cur,"SwitchCase");node.cases.push(cur=this.startNode());cur.consequent=[];this.next();if(isCase){cur.test=this.parseExpression()}else{if(sawDefault)this.raise(this.lastTokStart,"Multiple default clauses");sawDefault=true;cur.test=null}this.expect(tt.colon)}else{if(!cur)this.unexpected();cur.consequent.push(this.parseStatement(true))}}if(cur)this.finishNode(cur,"SwitchCase");this.next();this.labels.pop();return this.finishNode(node,"SwitchStatement")};pp.parseThrowStatement=function(node){this.next();if(lineBreak.test(this.input.slice(this.lastTokEnd,this.start)))this.raise(this.lastTokEnd,"Illegal newline after throw");node.argument=this.parseExpression();this.semicolon();return this.finishNode(node,"ThrowStatement")};var empty=[];pp.parseTryStatement=function(node){this.next();node.block=this.parseBlock();node.handler=null;if(this.type===tt._catch){var clause=this.startNode();this.next();this.expect(tt.parenL);clause.param=this.parseBindingAtom();this.checkLVal(clause.param,true);this.expect(tt.parenR);clause.guard=null;clause.body=this.parseBlock();node.handler=this.finishNode(clause,"CatchClause")}node.guardedHandlers=empty;node.finalizer=this.eat(tt._finally)?this.parseBlock():null;if(!node.handler&&!node.finalizer)this.raise(node.start,"Missing catch or finally clause");return this.finishNode(node,"TryStatement")};pp.parseVarStatement=function(node,kind){this.next();this.parseVar(node,false,kind);this.semicolon();return this.finishNode(node,"VariableDeclaration")};pp.parseWhileStatement=function(node){this.next();node.test=this.parseParenExpression();this.labels.push(loopLabel);node.body=this.parseStatement(false);this.labels.pop();return this.finishNode(node,"WhileStatement")};pp.parseWithStatement=function(node){if(this.strict)this.raise(this.start,"'with' in strict mode");this.next();node.object=this.parseParenExpression();node.body=this.parseStatement(false);return this.finishNode(node,"WithStatement")};pp.parseEmptyStatement=function(node){this.next();return this.finishNode(node,"EmptyStatement")};pp.parseLabeledStatement=function(node,maybeName,expr){for(var i=0;i=6&&this.isContextual("of"))){this.unexpected()}else if(decl.id.type!="Identifier"&&!(isFor&&(this.type===tt._in||this.isContextual("of")))){this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value")}else{decl.init=null}node.declarations.push(this.finishNode(decl,"VariableDeclarator"));if(!this.eat(tt.comma))break}return node};pp.parseVarId=function(decl){decl.id=this.parseBindingAtom();this.checkLVal(decl.id,true)};pp.parseFunction=function(node,isStatement,allowExpressionBody){this.initFunction(node);if(this.options.ecmaVersion>=6)node.generator=this.eat(tt.star);if(isStatement||this.type===tt.name)node.id=this.parseIdent();this.parseFunctionParams(node);this.parseFunctionBody(node,allowExpressionBody);return this.finishNode(node,isStatement?"FunctionDeclaration":"FunctionExpression")};pp.parseFunctionParams=function(node){this.expect(tt.parenL);node.params=this.parseBindingList(tt.parenR,false,false)};pp.parseClass=function(node,isStatement){this.next();this.parseClassId(node,isStatement);this.parseClassSuper(node);var classBody=this.startNode();var hadConstructor=false;classBody.body=[];this.expect(tt.braceL);while(!this.eat(tt.braceR)){if(this.eat(tt.semi))continue;var method=this.startNode();var isGenerator=this.eat(tt.star);var isMaybeStatic=this.type===tt.name&&this.value==="static";this.parsePropertyName(method);method["static"]=isMaybeStatic&&this.type!==tt.parenL;if(method["static"]){if(isGenerator)this.unexpected();isGenerator=this.eat(tt.star);this.parsePropertyName(method)}method.kind="method";if(!method.computed){var key=method.key;var isGetSet=false;if(!isGenerator&&key.type==="Identifier"&&this.type!==tt.parenL&&(key.name==="get"||key.name==="set")){isGetSet=true;method.kind=key.name;key=this.parsePropertyName(method)}if(!method["static"]&&(key.type==="Identifier"&&key.name==="constructor"||key.type==="Literal"&&key.value==="constructor")){if(hadConstructor)this.raise(key.start,"Duplicate constructor in the same class");if(isGetSet)this.raise(key.start,"Constructor can't have get/set modifier");if(isGenerator)this.raise(key.start,"Constructor can't be a generator");method.kind="constructor";hadConstructor=true}}this.parseClassMethod(classBody,method,isGenerator)}node.body=this.finishNode(classBody,"ClassBody");return this.finishNode(node,isStatement?"ClassDeclaration":"ClassExpression")};pp.parseClassMethod=function(classBody,method,isGenerator){method.value=this.parseMethod(isGenerator);classBody.body.push(this.finishNode(method,"MethodDefinition"))};pp.parseClassId=function(node,isStatement){node.id=this.type===tt.name?this.parseIdent():isStatement?this.unexpected():null};pp.parseClassSuper=function(node){node.superClass=this.eat(tt._extends)?this.parseExprSubscripts():null};pp.parseExport=function(node){this.next();if(this.eat(tt.star)){this.expectContextual("from");node.source=this.type===tt.string?this.parseExprAtom():this.unexpected();this.semicolon();return this.finishNode(node,"ExportAllDeclaration")}if(this.eat(tt._default)){var expr=this.parseMaybeAssign();var needsSemi=true;if(expr.type=="FunctionExpression"||expr.type=="ClassExpression"){needsSemi=false;if(expr.id){expr.type=expr.type=="FunctionExpression"?"FunctionDeclaration":"ClassDeclaration"}}node.declaration=expr;if(needsSemi)this.semicolon();return this.finishNode(node,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement()){node.declaration=this.parseStatement(true);node.specifiers=[];node.source=null}else{node.declaration=null;node.specifiers=this.parseExportSpecifiers();if(this.eatContextual("from")){node.source=this.type===tt.string?this.parseExprAtom():this.unexpected()}else{node.source=null}this.semicolon()}return this.finishNode(node,"ExportNamedDeclaration")};pp.shouldParseExportStatement=function(){return this.type.keyword};pp.parseExportSpecifiers=function(){var nodes=[],first=true;this.expect(tt.braceL);while(!this.eat(tt.braceR)){if(!first){this.expect(tt.comma);if(this.afterTrailingComma(tt.braceR))break}else first=false;var node=this.startNode();
4 |
5 | node.local=this.parseIdent(this.type===tt._default);node.exported=this.eatContextual("as")?this.parseIdent(true):node.local;nodes.push(this.finishNode(node,"ExportSpecifier"))}return nodes};pp.parseImport=function(node){this.next();if(this.type===tt.string){node.specifiers=empty;node.source=this.parseExprAtom();node.kind=""}else{node.specifiers=this.parseImportSpecifiers();this.expectContextual("from");node.source=this.type===tt.string?this.parseExprAtom():this.unexpected()}this.semicolon();return this.finishNode(node,"ImportDeclaration")};pp.parseImportSpecifiers=function(){var nodes=[],first=true;if(this.type===tt.name){var node=this.startNode();node.local=this.parseIdent();this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportDefaultSpecifier"));if(!this.eat(tt.comma))return nodes}if(this.type===tt.star){var node=this.startNode();this.next();this.expectContextual("as");node.local=this.parseIdent();this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportNamespaceSpecifier"));return nodes}this.expect(tt.braceL);while(!this.eat(tt.braceR)){if(!first){this.expect(tt.comma);if(this.afterTrailingComma(tt.braceR))break}else first=false;var node=this.startNode();node.imported=this.parseIdent(true);node.local=this.eatContextual("as")?this.parseIdent():node.imported;this.checkLVal(node.local,true);nodes.push(this.finishNode(node,"ImportSpecifier"))}return nodes}},{"./state":13,"./tokentype":17,"./whitespace":19}],15:[function(_dereq_,module,exports){"use strict";var _classCallCheck=function(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}};exports.__esModule=true;var Parser=_dereq_("./state").Parser;var tt=_dereq_("./tokentype").types;var lineBreak=_dereq_("./whitespace").lineBreak;var TokContext=exports.TokContext=function TokContext(token,isExpr,preserveSpace,override){_classCallCheck(this,TokContext);this.token=token;this.isExpr=isExpr;this.preserveSpace=preserveSpace;this.override=override};var types={b_stat:new TokContext("{",false),b_expr:new TokContext("{",true),b_tmpl:new TokContext("${",true),p_stat:new TokContext("(",false),p_expr:new TokContext("(",true),q_tmpl:new TokContext("`",true,true,function(p){return p.readTmplToken()}),f_expr:new TokContext("function",true)};exports.types=types;var pp=Parser.prototype;pp.initialContext=function(){return[types.b_stat]};pp.braceIsBlock=function(prevType){var parent=undefined;if(prevType===tt.colon&&(parent=this.curContext()).token=="{")return!parent.isExpr;if(prevType===tt._return)return lineBreak.test(this.input.slice(this.lastTokEnd,this.start));if(prevType===tt._else||prevType===tt.semi||prevType===tt.eof)return true;if(prevType==tt.braceL)return this.curContext()===types.b_stat;return!this.exprAllowed};pp.updateContext=function(prevType){var update=undefined,type=this.type;if(type.keyword&&prevType==tt.dot)this.exprAllowed=false;else if(update=type.updateContext)update.call(this,prevType);else this.exprAllowed=type.beforeExpr};tt.parenR.updateContext=tt.braceR.updateContext=function(){if(this.context.length==1){this.exprAllowed=true;return}var out=this.context.pop();if(out===types.b_stat&&this.curContext()===types.f_expr){this.context.pop();this.exprAllowed=false}else if(out===types.b_tmpl){this.exprAllowed=true}else{this.exprAllowed=!out.isExpr}};tt.braceL.updateContext=function(prevType){this.context.push(this.braceIsBlock(prevType)?types.b_stat:types.b_expr);this.exprAllowed=true};tt.dollarBraceL.updateContext=function(){this.context.push(types.b_tmpl);this.exprAllowed=true};tt.parenL.updateContext=function(prevType){var statementParens=prevType===tt._if||prevType===tt._for||prevType===tt._with||prevType===tt._while;this.context.push(statementParens?types.p_stat:types.p_expr);this.exprAllowed=true};tt.incDec.updateContext=function(){};tt._function.updateContext=function(){if(this.curContext()!==types.b_stat)this.context.push(types.f_expr);this.exprAllowed=false};tt.backQuote.updateContext=function(){if(this.curContext()===types.q_tmpl)this.context.pop();else this.context.push(types.q_tmpl);this.exprAllowed=false}},{"./state":13,"./tokentype":17,"./whitespace":19}],16:[function(_dereq_,module,exports){"use strict";var _classCallCheck=function(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}};exports.__esModule=true;var _identifier=_dereq_("./identifier");var isIdentifierStart=_identifier.isIdentifierStart;var isIdentifierChar=_identifier.isIdentifierChar;var _tokentype=_dereq_("./tokentype");var tt=_tokentype.types;var keywordTypes=_tokentype.keywords;var Parser=_dereq_("./state").Parser;var SourceLocation=_dereq_("./location").SourceLocation;var _whitespace=_dereq_("./whitespace");var lineBreak=_whitespace.lineBreak;var lineBreakG=_whitespace.lineBreakG;var isNewLine=_whitespace.isNewLine;var nonASCIIwhitespace=_whitespace.nonASCIIwhitespace;var Token=exports.Token=function Token(p){_classCallCheck(this,Token);this.type=p.type;this.value=p.value;this.start=p.start;this.end=p.end;if(p.options.locations)this.loc=new SourceLocation(p,p.startLoc,p.endLoc);if(p.options.ranges)this.range=[p.start,p.end]};var pp=Parser.prototype;var isRhino=typeof Packages!=="undefined";pp.next=function(){if(this.options.onToken)this.options.onToken(new Token(this));this.lastTokEnd=this.end;this.lastTokStart=this.start;this.lastTokEndLoc=this.endLoc;this.lastTokStartLoc=this.startLoc;this.nextToken()};pp.getToken=function(){this.next();return new Token(this)};if(typeof Symbol!=="undefined")pp[Symbol.iterator]=function(){var self=this;return{next:function next(){var token=self.getToken();return{done:token.type===tt.eof,value:token}}}};pp.setStrict=function(strict){this.strict=strict;if(this.type!==tt.num&&this.type!==tt.string)return;this.pos=this.start;if(this.options.locations){while(this.pos=this.input.length)return this.finishToken(tt.eof);if(curContext.override)return curContext.override(this);else this.readToken(this.fullCharCodeAtPos())};pp.readToken=function(code){if(isIdentifierStart(code,this.options.ecmaVersion>=6)||code===92)return this.readWord();return this.getTokenFromCode(code)};pp.fullCharCodeAtPos=function(){var code=this.input.charCodeAt(this.pos);if(code<=55295||code>=57344)return code;var next=this.input.charCodeAt(this.pos+1);return(code<<10)+next-56613888};pp.skipBlockComment=function(){var startLoc=this.options.onComment&&this.options.locations&&this.curPosition();var start=this.pos,end=this.input.indexOf("*/",this.pos+=2);if(end===-1)this.raise(this.pos-2,"Unterminated comment");this.pos=end+2;if(this.options.locations){lineBreakG.lastIndex=start;var match=undefined;while((match=lineBreakG.exec(this.input))&&match.index8&&ch<14){++this.pos}else if(ch===47){var next=this.input.charCodeAt(this.pos+1);if(next===42){this.skipBlockComment()}else if(next===47){this.skipLineComment(2)}else break}else if(ch===160){++this.pos}else if(ch>=5760&&nonASCIIwhitespace.test(String.fromCharCode(ch))){++this.pos}else{break}}};pp.finishToken=function(type,val){this.end=this.pos;if(this.options.locations)this.endLoc=this.curPosition();var prevType=this.type;this.type=type;this.value=val;this.updateContext(prevType)};pp.readToken_dot=function(){var next=this.input.charCodeAt(this.pos+1);if(next>=48&&next<=57)return this.readNumber(true);var next2=this.input.charCodeAt(this.pos+2);if(this.options.ecmaVersion>=6&&next===46&&next2===46){this.pos+=3;return this.finishToken(tt.ellipsis)}else{++this.pos;return this.finishToken(tt.dot)}};pp.readToken_slash=function(){var next=this.input.charCodeAt(this.pos+1);if(this.exprAllowed){++this.pos;return this.readRegexp()}if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(tt.slash,1)};pp.readToken_mult_modulo=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(code===42?tt.star:tt.modulo,1)};pp.readToken_pipe_amp=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code)return this.finishOp(code===124?tt.logicalOR:tt.logicalAND,2);if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(code===124?tt.bitwiseOR:tt.bitwiseAND,1)};pp.readToken_caret=function(){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(tt.bitwiseXOR,1)};pp.readToken_plus_min=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===code){if(next==45&&this.input.charCodeAt(this.pos+2)==62&&lineBreak.test(this.input.slice(this.lastTokEnd,this.pos))){this.skipLineComment(3);this.skipSpace();return this.nextToken()}return this.finishOp(tt.incDec,2)}if(next===61)return this.finishOp(tt.assign,2);return this.finishOp(tt.plusMin,1)};pp.readToken_lt_gt=function(code){var next=this.input.charCodeAt(this.pos+1);var size=1;if(next===code){size=code===62&&this.input.charCodeAt(this.pos+2)===62?3:2;if(this.input.charCodeAt(this.pos+size)===61)return this.finishOp(tt.assign,size+1);return this.finishOp(tt.bitShift,size)}if(next==33&&code==60&&this.input.charCodeAt(this.pos+2)==45&&this.input.charCodeAt(this.pos+3)==45){if(this.inModule)this.unexpected();this.skipLineComment(4);this.skipSpace();return this.nextToken()}if(next===61)size=this.input.charCodeAt(this.pos+2)===61?3:2;return this.finishOp(tt.relational,size)};pp.readToken_eq_excl=function(code){var next=this.input.charCodeAt(this.pos+1);if(next===61)return this.finishOp(tt.equality,this.input.charCodeAt(this.pos+2)===61?3:2);if(code===61&&next===62&&this.options.ecmaVersion>=6){this.pos+=2;return this.finishToken(tt.arrow)}return this.finishOp(code===61?tt.eq:tt.prefix,1)};pp.getTokenFromCode=function(code){switch(code){case 46:return this.readToken_dot();case 40:++this.pos;return this.finishToken(tt.parenL);case 41:++this.pos;return this.finishToken(tt.parenR);case 59:++this.pos;return this.finishToken(tt.semi);case 44:++this.pos;return this.finishToken(tt.comma);case 91:++this.pos;return this.finishToken(tt.bracketL);case 93:++this.pos;return this.finishToken(tt.bracketR);case 123:++this.pos;return this.finishToken(tt.braceL);case 125:++this.pos;return this.finishToken(tt.braceR);case 58:++this.pos;return this.finishToken(tt.colon);case 63:++this.pos;return this.finishToken(tt.question);case 96:if(this.options.ecmaVersion<6)break;++this.pos;return this.finishToken(tt.backQuote);case 48:var next=this.input.charCodeAt(this.pos+1);if(next===120||next===88)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(next===111||next===79)return this.readRadixNumber(8);if(next===98||next===66)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(false);case 34:case 39:return this.readString(code);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo(code);case 124:case 38:return this.readToken_pipe_amp(code);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(code);case 60:case 62:return this.readToken_lt_gt(code);case 61:case 33:return this.readToken_eq_excl(code);case 126:return this.finishOp(tt.prefix,1)}this.raise(this.pos,"Unexpected character '"+codePointToString(code)+"'")};pp.finishOp=function(type,size){var str=this.input.slice(this.pos,this.pos+size);this.pos+=size;return this.finishToken(type,str)};var regexpUnicodeSupport=false;try{new RegExp("","u");regexpUnicodeSupport=true}catch(e){}pp.readRegexp=function(){var escaped=undefined,inClass=undefined,start=this.pos;for(;;){if(this.pos>=this.input.length)this.raise(start,"Unterminated regular expression");var ch=this.input.charAt(this.pos);if(lineBreak.test(ch))this.raise(start,"Unterminated regular expression");if(!escaped){if(ch==="[")inClass=true;else if(ch==="]"&&inClass)inClass=false;else if(ch==="/"&&!inClass)break;escaped=ch==="\\"}else escaped=false;++this.pos}var content=this.input.slice(start,this.pos);++this.pos;var mods=this.readWord1();var tmp=content;if(mods){var validFlags=/^[gmsiy]*$/;if(this.options.ecmaVersion>=6)validFlags=/^[gmsiyu]*$/;if(!validFlags.test(mods))this.raise(start,"Invalid regular expression flag");if(mods.indexOf("u")>=0&&!regexpUnicodeSupport){tmp=tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x")}}var value=null;if(!isRhino){try{new RegExp(tmp)}catch(e){if(e instanceof SyntaxError)this.raise(start,"Error parsing regular expression: "+e.message);this.raise(e)}try{value=new RegExp(content,mods)}catch(err){}}return this.finishToken(tt.regexp,{pattern:content,flags:mods,value:value})};pp.readInt=function(radix,len){var start=this.pos,total=0;for(var i=0,e=len==null?Infinity:len;i=97)val=code-97+10;else if(code>=65)val=code-65+10;else if(code>=48&&code<=57)val=code-48;else val=Infinity;if(val>=radix)break;++this.pos;total=total*radix+val}if(this.pos===start||len!=null&&this.pos-start!==len)return null;return total};pp.readRadixNumber=function(radix){this.pos+=2;var val=this.readInt(radix);if(val==null)this.raise(this.start+2,"Expected number in radix "+radix);if(isIdentifierStart(this.fullCharCodeAtPos()))this.raise(this.pos,"Identifier directly after number");return this.finishToken(tt.num,val)};pp.readNumber=function(startsWithDot){var start=this.pos,isFloat=false,octal=this.input.charCodeAt(this.pos)===48;if(!startsWithDot&&this.readInt(10)===null)this.raise(start,"Invalid number");if(this.input.charCodeAt(this.pos)===46){++this.pos;this.readInt(10);isFloat=true}var next=this.input.charCodeAt(this.pos);if(next===69||next===101){next=this.input.charCodeAt(++this.pos);if(next===43||next===45)++this.pos;if(this.readInt(10)===null)this.raise(start,"Invalid number");isFloat=true}if(isIdentifierStart(this.fullCharCodeAtPos()))this.raise(this.pos,"Identifier directly after number");var str=this.input.slice(start,this.pos),val=undefined;if(isFloat)val=parseFloat(str);else if(!octal||str.length===1)val=parseInt(str,10);else if(/[89]/.test(str)||this.strict)this.raise(start,"Invalid number");else val=parseInt(str,8);return this.finishToken(tt.num,val)};pp.readCodePoint=function(){var ch=this.input.charCodeAt(this.pos),code=undefined;if(ch===123){if(this.options.ecmaVersion<6)this.unexpected();++this.pos;code=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos);++this.pos;if(code>1114111)this.unexpected()}else{code=this.readHexChar(4)}return code};function codePointToString(code){if(code<=65535){return String.fromCharCode(code)}return String.fromCharCode((code-65536>>10)+55296,(code-65536&1023)+56320)}pp.readString=function(quote){var out="",chunkStart=++this.pos;for(;;){if(this.pos>=this.input.length)this.raise(this.start,"Unterminated string constant");var ch=this.input.charCodeAt(this.pos);if(ch===quote)break;if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar();chunkStart=this.pos}else{if(isNewLine(ch))this.raise(this.start,"Unterminated string constant");++this.pos}}out+=this.input.slice(chunkStart,this.pos++);return this.finishToken(tt.string,out)};pp.readTmplToken=function(){var out="",chunkStart=this.pos;for(;;){if(this.pos>=this.input.length)this.raise(this.start,"Unterminated template");var ch=this.input.charCodeAt(this.pos);if(ch===96||ch===36&&this.input.charCodeAt(this.pos+1)===123){if(this.pos===this.start&&this.type===tt.template){if(ch===36){this.pos+=2;return this.finishToken(tt.dollarBraceL)}else{++this.pos;return this.finishToken(tt.backQuote)}}out+=this.input.slice(chunkStart,this.pos);return this.finishToken(tt.template,out)}if(ch===92){out+=this.input.slice(chunkStart,this.pos);out+=this.readEscapedChar();chunkStart=this.pos}else if(isNewLine(ch)){out+=this.input.slice(chunkStart,this.pos);++this.pos;if(ch===13&&this.input.charCodeAt(this.pos)===10){++this.pos;out+="\n"}else{out+=String.fromCharCode(ch)}if(this.options.locations){++this.curLine;this.lineStart=this.pos}chunkStart=this.pos}else{++this.pos}}};pp.readEscapedChar=function(){var ch=this.input.charCodeAt(++this.pos);var octal=/^[0-7]+/.exec(this.input.slice(this.pos,this.pos+3));if(octal)octal=octal[0];while(octal&&parseInt(octal,8)>255)octal=octal.slice(0,-1);if(octal==="0")octal=null;++this.pos;if(octal){if(this.strict)this.raise(this.pos-2,"Octal literal in strict mode");this.pos+=octal.length-1;return String.fromCharCode(parseInt(octal,8))}else{switch(ch){case 110:return"\n";case 114:return"\r";case 120:return String.fromCharCode(this.readHexChar(2));case 117:return codePointToString(this.readCodePoint());case 116:return" ";case 98:return"\b";case 118:return"";case 102:return"\f";case 48:return"\x00";case 13:if(this.input.charCodeAt(this.pos)===10)++this.pos;case 10:if(this.options.locations){this.lineStart=this.pos;++this.curLine}return"";default:return String.fromCharCode(ch)}}};pp.readHexChar=function(len){var n=this.readInt(16,len);if(n===null)this.raise(this.start,"Bad character escape sequence");return n};var containsEsc;pp.readWord1=function(){containsEsc=false;var word="",first=true,chunkStart=this.pos;var astral=this.options.ecmaVersion>=6;while(this.pos=6||!containsEsc)&&this.isKeyword(word))type=keywordTypes[word];return this.finishToken(type,word)}},{"./identifier":7,"./location":8,"./state":13,"./tokentype":17,"./whitespace":19}],17:[function(_dereq_,module,exports){"use strict";var _classCallCheck=function(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}};exports.__esModule=true;var TokenType=exports.TokenType=function TokenType(label){var conf=arguments[1]===undefined?{}:arguments[1];_classCallCheck(this,TokenType);this.label=label;this.keyword=conf.keyword;this.beforeExpr=!!conf.beforeExpr;this.startsExpr=!!conf.startsExpr;this.isLoop=!!conf.isLoop;this.isAssign=!!conf.isAssign;this.prefix=!!conf.prefix;this.postfix=!!conf.postfix;this.binop=conf.binop||null;this.updateContext=null};function binop(name,prec){return new TokenType(name,{beforeExpr:true,binop:prec})}var beforeExpr={beforeExpr:true},startsExpr={startsExpr:true};var types={num:new TokenType("num",startsExpr),regexp:new TokenType("regexp",startsExpr),string:new TokenType("string",startsExpr),name:new TokenType("name",startsExpr),eof:new TokenType("eof"),bracketL:new TokenType("[",{beforeExpr:true,startsExpr:true}),bracketR:new TokenType("]"),braceL:new TokenType("{",{beforeExpr:true,startsExpr:true}),braceR:new TokenType("}"),parenL:new TokenType("(",{beforeExpr:true,startsExpr:true}),parenR:new TokenType(")"),comma:new TokenType(",",beforeExpr),semi:new TokenType(";",beforeExpr),colon:new TokenType(":",beforeExpr),dot:new TokenType("."),question:new TokenType("?",beforeExpr),arrow:new TokenType("=>",beforeExpr),template:new TokenType("template"),ellipsis:new TokenType("...",beforeExpr),backQuote:new TokenType("`",startsExpr),dollarBraceL:new TokenType("${",{beforeExpr:true,startsExpr:true}),eq:new TokenType("=",{beforeExpr:true,isAssign:true}),assign:new TokenType("_=",{beforeExpr:true,isAssign:true}),incDec:new TokenType("++/--",{prefix:true,postfix:true,startsExpr:true}),prefix:new TokenType("prefix",{beforeExpr:true,prefix:true,startsExpr:true}),logicalOR:binop("||",1),logicalAND:binop("&&",2),bitwiseOR:binop("|",3),bitwiseXOR:binop("^",4),bitwiseAND:binop("&",5),equality:binop("==/!=",6),relational:binop(">",7),bitShift:binop("<>>",8),plusMin:new TokenType("+/-",{beforeExpr:true,binop:9,prefix:true,startsExpr:true}),modulo:binop("%",10),star:binop("*",10),slash:binop("/",10)};exports.types=types;var keywords={};exports.keywords=keywords;function kw(name){var options=arguments[1]===undefined?{}:arguments[1];options.keyword=name;keywords[name]=types["_"+name]=new TokenType(name,options)}kw("break");kw("case",beforeExpr);kw("catch");kw("continue");kw("debugger");kw("default");kw("do",{isLoop:true});kw("else",beforeExpr);kw("finally");kw("for",{isLoop:true});kw("function",startsExpr);kw("if");kw("return",beforeExpr);kw("switch");kw("throw",beforeExpr);kw("try");kw("var");kw("let");kw("const");kw("while",{isLoop:true});kw("with");kw("new",{beforeExpr:true,startsExpr:true});kw("this",startsExpr);kw("super",startsExpr);kw("class");kw("extends",beforeExpr);kw("export");kw("import");kw("yield",{beforeExpr:true,startsExpr:true});kw("null",startsExpr);kw("true",startsExpr);kw("false",startsExpr);kw("in",{beforeExpr:true,binop:7});kw("instanceof",{beforeExpr:true,binop:7});kw("typeof",{beforeExpr:true,prefix:true,startsExpr:true});kw("void",{beforeExpr:true,prefix:true,startsExpr:true});kw("delete",{beforeExpr:true,prefix:true,startsExpr:true})},{}],18:[function(_dereq_,module,exports){"use strict";exports.isArray=isArray;exports.has=has;exports.__esModule=true;function isArray(obj){return Object.prototype.toString.call(obj)==="[object Array]"}function has(obj,propName){return Object.prototype.hasOwnProperty.call(obj,propName)}},{}],19:[function(_dereq_,module,exports){"use strict";exports.isNewLine=isNewLine;exports.__esModule=true;var lineBreak=/\r\n?|\n|\u2028|\u2029/;exports.lineBreak=lineBreak;var lineBreakG=new RegExp(lineBreak.source,"g");exports.lineBreakG=lineBreakG;function isNewLine(code){return code===10||code===13||code===8232||code==8233}var nonASCIIwhitespace=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;exports.nonASCIIwhitespace=nonASCIIwhitespace},{}]},{},[1])(1)})}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],3:[function(require,module,exports){var hasOwn=Object.prototype.hasOwnProperty;var toString=Object.prototype.toString;module.exports=function forEach(obj,fn,ctx){if(toString.call(fn)!=="[object Function]"){throw new TypeError("iterator must be a function")}var l=obj.length;if(l===+l){for(var i=0;i0&&!has.call(object,0)){for(var i=0;i0){for(var j=0;j=0&&toStr.call(value.callee)==="[object Function]"}return isArgs}},{}],7:[function(require,module,exports){module.exports=require("./javascript/diff_match_patch_uncompressed.js").diff_match_patch},{"./javascript/diff_match_patch_uncompressed.js":8}],8:[function(require,module,exports){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=.5;this.Match_Distance=1e3;this.Patch_DeleteThreshold=.5;this.Patch_Margin=4;this.Match_MaxBits=32}var DIFF_DELETE=-1;var DIFF_INSERT=1;var DIFF_EQUAL=0;diff_match_patch.Diff;diff_match_patch.prototype.diff_main=function(text1,text2,opt_checklines,opt_deadline){if(typeof opt_deadline=="undefined"){if(this.Diff_Timeout<=0){opt_deadline=Number.MAX_VALUE}else{opt_deadline=(new Date).getTime()+this.Diff_Timeout*1e3}}var deadline=opt_deadline;if(text1==null||text2==null){throw new Error("Null input. (diff_main)")}if(text1==text2){if(text1){return[[DIFF_EQUAL,text1]]}return[]}if(typeof opt_checklines=="undefined"){opt_checklines=true}var checklines=opt_checklines;var commonlength=this.diff_commonPrefix(text1,text2);var commonprefix=text1.substring(0,commonlength);text1=text1.substring(commonlength);text2=text2.substring(commonlength);commonlength=this.diff_commonSuffix(text1,text2);var commonsuffix=text1.substring(text1.length-commonlength);text1=text1.substring(0,text1.length-commonlength);text2=text2.substring(0,text2.length-commonlength);var diffs=this.diff_compute_(text1,text2,checklines,deadline);if(commonprefix){diffs.unshift([DIFF_EQUAL,commonprefix])}if(commonsuffix){diffs.push([DIFF_EQUAL,commonsuffix])}this.diff_cleanupMerge(diffs);return diffs};diff_match_patch.prototype.diff_compute_=function(text1,text2,checklines,deadline){var diffs;if(!text1){return[[DIFF_INSERT,text2]]}if(!text2){return[[DIFF_DELETE,text1]]}var longtext=text1.length>text2.length?text1:text2;var shorttext=text1.length>text2.length?text2:text1;var i=longtext.indexOf(shorttext);if(i!=-1){diffs=[[DIFF_INSERT,longtext.substring(0,i)],[DIFF_EQUAL,shorttext],[DIFF_INSERT,longtext.substring(i+shorttext.length)]];if(text1.length>text2.length){diffs[0][0]=diffs[2][0]=DIFF_DELETE}return diffs}if(shorttext.length==1){return[[DIFF_DELETE,text1],[DIFF_INSERT,text2]]}var hm=this.diff_halfMatch_(text1,text2);if(hm){var text1_a=hm[0];var text1_b=hm[1];var text2_a=hm[2];var text2_b=hm[3];var mid_common=hm[4];var diffs_a=this.diff_main(text1_a,text2_a,checklines,deadline);var diffs_b=this.diff_main(text1_b,text2_b,checklines,deadline);return diffs_a.concat([[DIFF_EQUAL,mid_common]],diffs_b)}if(checklines&&text1.length>100&&text2.length>100){return this.diff_lineMode_(text1,text2,deadline)}return this.diff_bisect_(text1,text2,deadline)};diff_match_patch.prototype.diff_lineMode_=function(text1,text2,deadline){var a=this.diff_linesToChars_(text1,text2);text1=a.chars1;text2=a.chars2;var linearray=a.lineArray;var diffs=this.diff_main(text1,text2,false,deadline);this.diff_charsToLines_(diffs,linearray);this.diff_cleanupSemantic(diffs);diffs.push([DIFF_EQUAL,""]);var pointer=0;var count_delete=0;var count_insert=0;var text_delete="";var text_insert="";while(pointer=1&&count_insert>=1){diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert);pointer=pointer-count_delete-count_insert;var a=this.diff_main(text_delete,text_insert,false,deadline);for(var j=a.length-1;j>=0;j--){diffs.splice(pointer,0,a[j])}pointer=pointer+a.length}count_insert=0;count_delete=0;text_delete="";text_insert="";break}pointer++}diffs.pop();return diffs};diff_match_patch.prototype.diff_bisect_=function(text1,text2,deadline){var text1_length=text1.length;var text2_length=text2.length;var max_d=Math.ceil((text1_length+text2_length)/2);var v_offset=max_d;var v_length=2*max_d;var v1=new Array(v_length);var v2=new Array(v_length);for(var x=0;xdeadline){break}for(var k1=-d+k1start;k1<=d-k1end;k1+=2){var k1_offset=v_offset+k1;var x1;if(k1==-d||k1!=d&&v1[k1_offset-1]text1_length){k1end+=2}else if(y1>text2_length){k1start+=2}else if(front){var k2_offset=v_offset+delta-k1;if(k2_offset>=0&&k2_offset=x2){return this.diff_bisectSplit_(text1,text2,x1,y1,deadline);
6 |
7 | }}}}for(var k2=-d+k2start;k2<=d-k2end;k2+=2){var k2_offset=v_offset+k2;var x2;if(k2==-d||k2!=d&&v2[k2_offset-1]text1_length){k2end+=2}else if(y2>text2_length){k2start+=2}else if(!front){var k1_offset=v_offset+delta-k2;if(k1_offset>=0&&k1_offset=x2){return this.diff_bisectSplit_(text1,text2,x1,y1,deadline)}}}}}return[[DIFF_DELETE,text1],[DIFF_INSERT,text2]]};diff_match_patch.prototype.diff_bisectSplit_=function(text1,text2,x,y,deadline){var text1a=text1.substring(0,x);var text2a=text2.substring(0,y);var text1b=text1.substring(x);var text2b=text2.substring(y);var diffs=this.diff_main(text1a,text2a,false,deadline);var diffsb=this.diff_main(text1b,text2b,false,deadline);return diffs.concat(diffsb)};diff_match_patch.prototype.diff_linesToChars_=function(text1,text2){var lineArray=[];var lineHash={};lineArray[0]="";function diff_linesToCharsMunge_(text){var chars="";var lineStart=0;var lineEnd=-1;var lineArrayLength=lineArray.length;while(lineEndtext2_length){text1=text1.substring(text1_length-text2_length)}else if(text1_lengthtext2.length?text1:text2;var shorttext=text1.length>text2.length?text2:text1;if(longtext.length<4||shorttext.length*2=longtext.length){return[best_longtext_a,best_longtext_b,best_shorttext_a,best_shorttext_b,best_common]}else{return null}}var hm1=diff_halfMatchI_(longtext,shorttext,Math.ceil(longtext.length/4));var hm2=diff_halfMatchI_(longtext,shorttext,Math.ceil(longtext.length/2));var hm;if(!hm1&&!hm2){return null}else if(!hm2){hm=hm1}else if(!hm1){hm=hm2}else{hm=hm1[4].length>hm2[4].length?hm1:hm2}var text1_a,text1_b,text2_a,text2_b;if(text1.length>text2.length){text1_a=hm[0];text1_b=hm[1];text2_a=hm[2];text2_b=hm[3]}else{text2_a=hm[0];text2_b=hm[1];text1_a=hm[2];text1_b=hm[3]}var mid_common=hm[4];return[text1_a,text1_b,text2_a,text2_b,mid_common]};diff_match_patch.prototype.diff_cleanupSemantic=function(diffs){var changes=false;var equalities=[];var equalitiesLength=0;var lastequality=null;var pointer=0;var length_insertions1=0;var length_deletions1=0;var length_insertions2=0;var length_deletions2=0;while(pointer0?equalities[equalitiesLength-1]:-1;length_insertions1=0;length_deletions1=0;length_insertions2=0;length_deletions2=0;lastequality=null;changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}this.diff_cleanupSemanticLossless(diffs);pointer=1;while(pointer=overlap_length2){if(overlap_length1>=deletion.length/2||overlap_length1>=insertion.length/2){diffs.splice(pointer,0,[DIFF_EQUAL,insertion.substring(0,overlap_length1)]);diffs[pointer-1][1]=deletion.substring(0,deletion.length-overlap_length1);diffs[pointer+1][1]=insertion.substring(overlap_length1);pointer++}}else{if(overlap_length2>=deletion.length/2||overlap_length2>=insertion.length/2){diffs.splice(pointer,0,[DIFF_EQUAL,deletion.substring(0,overlap_length2)]);diffs[pointer-1][0]=DIFF_INSERT;diffs[pointer-1][1]=insertion.substring(0,insertion.length-overlap_length2);diffs[pointer+1][0]=DIFF_DELETE;diffs[pointer+1][1]=deletion.substring(overlap_length2);pointer++}}pointer++}pointer++}};diff_match_patch.prototype.diff_cleanupSemanticLossless=function(diffs){function diff_cleanupSemanticScore_(one,two){if(!one||!two){return 6}var char1=one.charAt(one.length-1);var char2=two.charAt(0);var nonAlphaNumeric1=char1.match(diff_match_patch.nonAlphaNumericRegex_);var nonAlphaNumeric2=char2.match(diff_match_patch.nonAlphaNumericRegex_);var whitespace1=nonAlphaNumeric1&&char1.match(diff_match_patch.whitespaceRegex_);var whitespace2=nonAlphaNumeric2&&char2.match(diff_match_patch.whitespaceRegex_);var lineBreak1=whitespace1&&char1.match(diff_match_patch.linebreakRegex_);var lineBreak2=whitespace2&&char2.match(diff_match_patch.linebreakRegex_);var blankLine1=lineBreak1&&one.match(diff_match_patch.blanklineEndRegex_);var blankLine2=lineBreak2&&two.match(diff_match_patch.blanklineStartRegex_);if(blankLine1||blankLine2){return 5}else if(lineBreak1||lineBreak2){return 4}else if(nonAlphaNumeric1&&!whitespace1&&whitespace2){return 3}else if(whitespace1||whitespace2){return 2}else if(nonAlphaNumeric1||nonAlphaNumeric2){return 1}return 0}var pointer=1;while(pointer=bestScore){bestScore=score;bestEquality1=equality1;bestEdit=edit;bestEquality2=equality2}}if(diffs[pointer-1][1]!=bestEquality1){if(bestEquality1){diffs[pointer-1][1]=bestEquality1}else{diffs.splice(pointer-1,1);pointer--}diffs[pointer][1]=bestEdit;if(bestEquality2){diffs[pointer+1][1]=bestEquality2}else{diffs.splice(pointer+1,1);pointer--}}}pointer++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;diff_match_patch.prototype.diff_cleanupEfficiency=function(diffs){var changes=false;var equalities=[];var equalitiesLength=0;var lastequality=null;var pointer=0;var pre_ins=false;var pre_del=false;var post_ins=false;var post_del=false;while(pointer0?equalities[equalitiesLength-1]:-1;post_ins=post_del=false}changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}};diff_match_patch.prototype.diff_cleanupMerge=function(diffs){diffs.push([DIFF_EQUAL,""]);var pointer=0;var count_delete=0;var count_insert=0;var text_delete="";var text_insert="";var commonlength;while(pointer1){if(count_delete!==0&&count_insert!==0){commonlength=this.diff_commonPrefix(text_insert,text_delete);if(commonlength!==0){if(pointer-count_delete-count_insert>0&&diffs[pointer-count_delete-count_insert-1][0]==DIFF_EQUAL){diffs[pointer-count_delete-count_insert-1][1]+=text_insert.substring(0,commonlength)}else{diffs.splice(0,0,[DIFF_EQUAL,text_insert.substring(0,commonlength)]);pointer++}text_insert=text_insert.substring(commonlength);text_delete=text_delete.substring(commonlength)}commonlength=this.diff_commonSuffix(text_insert,text_delete);if(commonlength!==0){diffs[pointer][1]=text_insert.substring(text_insert.length-commonlength)+diffs[pointer][1];text_insert=text_insert.substring(0,text_insert.length-commonlength);text_delete=text_delete.substring(0,text_delete.length-commonlength)}}if(count_delete===0){diffs.splice(pointer-count_insert,count_delete+count_insert,[DIFF_INSERT,text_insert])}else if(count_insert===0){diffs.splice(pointer-count_delete,count_delete+count_insert,[DIFF_DELETE,text_delete])}else{diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert,[DIFF_DELETE,text_delete],[DIFF_INSERT,text_insert])}pointer=pointer-count_delete-count_insert+(count_delete?1:0)+(count_insert?1:0)+1}else if(pointer!==0&&diffs[pointer-1][0]==DIFF_EQUAL){diffs[pointer-1][1]+=diffs[pointer][1];diffs.splice(pointer,1)}else{pointer++}count_insert=0;count_delete=0;text_delete="";text_insert="";break}}if(diffs[diffs.length-1][1]===""){diffs.pop()}var changes=false;pointer=1;while(pointerloc){break}last_chars1=chars1;last_chars2=chars2}if(diffs.length!=x&&diffs[x][0]===DIFF_DELETE){return last_chars2}return last_chars2+(loc-last_chars1)};diff_match_patch.prototype.diff_prettyHtml=function(diffs){var html=[];var pattern_amp=/&/g;var pattern_lt=//g;var pattern_para=/\n/g;for(var x=0;x");switch(op){case DIFF_INSERT:html[x]=''+text+" ";break;case DIFF_DELETE:html[x]=''+text+"";break;case DIFF_EQUAL:html[x]=""+text+" ";break}}return html.join("")};diff_match_patch.prototype.diff_text1=function(diffs){var text=[];for(var x=0;xthis.Match_MaxBits){throw new Error("Pattern too long for this browser.")}var s=this.match_alphabet_(pattern);var dmp=this;function match_bitapScore_(e,x){var accuracy=e/pattern.length;var proximity=Math.abs(loc-x);if(!dmp.Match_Distance){return proximity?1:accuracy}return accuracy+proximity/dmp.Match_Distance}var score_threshold=this.Match_Threshold;var best_loc=text.indexOf(pattern,loc);if(best_loc!=-1){score_threshold=Math.min(match_bitapScore_(0,best_loc),score_threshold);best_loc=text.lastIndexOf(pattern,loc+pattern.length);if(best_loc!=-1){score_threshold=Math.min(match_bitapScore_(0,best_loc),score_threshold)}}var matchmask=1<=start;j--){var charMatch=s[text.charAt(j-1)];if(d===0){rd[j]=(rd[j+1]<<1|1)&charMatch}else{rd[j]=(rd[j+1]<<1|1)&charMatch|((last_rd[j+1]|last_rd[j])<<1|1)|last_rd[j+1]}if(rd[j]&matchmask){var score=match_bitapScore_(d,j-1);if(score<=score_threshold){score_threshold=score;best_loc=j-1;if(best_loc>loc){start=Math.max(1,2*loc-best_loc)}else{break}}}}if(match_bitapScore_(d+1,loc)>score_threshold){break}last_rd=rd}return best_loc};diff_match_patch.prototype.match_alphabet_=function(pattern){var s={};for(var i=0;i2){this.diff_cleanupSemantic(diffs);this.diff_cleanupEfficiency(diffs)}}else if(a&&typeof a=="object"&&typeof opt_b=="undefined"&&typeof opt_c=="undefined"){diffs=a;text1=this.diff_text1(diffs)}else if(typeof a=="string"&&opt_b&&typeof opt_b=="object"&&typeof opt_c=="undefined"){text1=a;diffs=opt_b}else if(typeof a=="string"&&typeof opt_b=="string"&&opt_c&&typeof opt_c=="object"){text1=a;diffs=opt_c}else{throw new Error("Unknown call format to patch_make.")}if(diffs.length===0){return[]}var patches=[];var patch=new diff_match_patch.patch_obj;var patchDiffLength=0;var char_count1=0;var char_count2=0;var prepatch_text=text1;var postpatch_text=text1;for(var x=0;x=2*this.Patch_Margin){if(patchDiffLength){this.patch_addContext_(patch,prepatch_text);patches.push(patch);patch=new diff_match_patch.patch_obj;patchDiffLength=0;prepatch_text=postpatch_text;char_count1=char_count2}}break}if(diff_type!==DIFF_INSERT){char_count1+=diff_text.length}if(diff_type!==DIFF_DELETE){char_count2+=diff_text.length}}if(patchDiffLength){this.patch_addContext_(patch,prepatch_text);patches.push(patch)}return patches};diff_match_patch.prototype.patch_deepCopy=function(patches){var patchesCopy=[];for(var x=0;xthis.Match_MaxBits){start_loc=this.match_main(text,text1.substring(0,this.Match_MaxBits),expected_loc);if(start_loc!=-1){end_loc=this.match_main(text,text1.substring(text1.length-this.Match_MaxBits),expected_loc+text1.length-this.Match_MaxBits);if(end_loc==-1||start_loc>=end_loc){start_loc=-1}}}else{start_loc=this.match_main(text,text1,expected_loc)}if(start_loc==-1){results[x]=false;delta-=patches[x].length2-patches[x].length1}else{results[x]=true;delta=start_loc-expected_loc;var text2;if(end_loc==-1){text2=text.substring(start_loc,start_loc+text1.length)}else{text2=text.substring(start_loc,end_loc+this.Match_MaxBits)}if(text1==text2){text=text.substring(0,start_loc)+this.diff_text2(patches[x].diffs)+text.substring(start_loc+text1.length)}else{var diffs=this.diff_main(text1,text2,false);if(text1.length>this.Match_MaxBits&&this.diff_levenshtein(diffs)/text1.length>this.Patch_DeleteThreshold){results[x]=false}else{this.diff_cleanupSemanticLossless(diffs);var index1=0;var index2;for(var y=0;ydiffs[0][1].length){var extraLength=paddingLength-diffs[0][1].length;diffs[0][1]=nullPadding.substring(diffs[0][1].length)+diffs[0][1];patch.start1-=extraLength;patch.start2-=extraLength;patch.length1+=extraLength;patch.length2+=extraLength}patch=patches[patches.length-1];diffs=patch.diffs;if(diffs.length==0||diffs[diffs.length-1][0]!=DIFF_EQUAL){diffs.push([DIFF_EQUAL,nullPadding]);patch.length1+=paddingLength;patch.length2+=paddingLength}else if(paddingLength>diffs[diffs.length-1][1].length){var extraLength=paddingLength-diffs[diffs.length-1][1].length;diffs[diffs.length-1][1]+=nullPadding.substring(0,extraLength);patch.length1+=extraLength;patch.length2+=extraLength}return nullPadding};diff_match_patch.prototype.patch_splitMax=function(patches){var patch_size=this.Match_MaxBits;for(var x=0;x2*patch_size){patch.length1+=diff_text.length;start1+=diff_text.length;empty=false;patch.diffs.push([diff_type,diff_text]);bigpatch.diffs.shift()}else{diff_text=diff_text.substring(0,patch_size-patch.length1-this.Patch_Margin);patch.length1+=diff_text.length;start1+=diff_text.length;if(diff_type===DIFF_EQUAL){patch.length2+=diff_text.length;start2+=diff_text.length}else{empty=false}patch.diffs.push([diff_type,diff_text]);if(diff_text==bigpatch.diffs[0][1]){bigpatch.diffs.shift()}else{bigpatch.diffs[0][1]=bigpatch.diffs[0][1].substring(diff_text.length)}}}precontext=this.diff_text2(patch.diffs);precontext=precontext.substring(precontext.length-this.Patch_Margin);var postcontext=this.diff_text1(bigpatch.diffs).substring(0,this.Patch_Margin);if(postcontext!==""){patch.length1+=postcontext.length;patch.length2+=postcontext.length;if(patch.diffs.length!==0&&patch.diffs[patch.diffs.length-1][0]===DIFF_EQUAL){patch.diffs[patch.diffs.length-1][1]+=postcontext}else{patch.diffs.push([DIFF_EQUAL,postcontext])}}if(!empty){patches.splice(++x,0,patch)}}}};diff_match_patch.prototype.patch_toText=function(patches){var text=[];for(var x=0;x"," (__thermiteFunctionVersion_$thermiteBlockID || -1)) {",""," __thermiteFunction_$thermiteBlockID ="," eval(__thermiteMap.$thermiteContextID.$thermiteBlockID.code)",""," __thermiteFunctionVersion_$thermiteBlockID ="," __thermiteMap.$thermiteContextID.$thermiteBlockID.codeVersion","}","","return __thermiteFunction_$thermiteBlockID.apply(this, arguments)","","}"].join("\n");
8 |
9 | global.__thermiteMap={};function Counter(label){this.label=label;this.value=0}Counter.prototype.getNextID=function(){return this.label+this.value++};function thermiteEval(source,options){options=options||{};var fnTree={};var state={contextID:contextIDCounter.getNextID(),lastSource:source,doLineDiff:options.lineDiff||false,version:1};var rewritten=forEachNode(source,function(node){if(functionNodeTypes.indexOf(node.type)<0)return;var blockID=blockIDCounter.getNextID();rewriteNode(state.contextID,blockID,state.version,node)}).toString();return{hotSwap:function(source){return hotSwap(state,source)},result:invokeEval(options.eval||eval,rewritten)}}function hotSwap(state,source){state.version++;var version=state.version;var contextID=state.contextID;var dmp=new DiffMatchPatch;var diffs=dmp.diff_main(state.lastSource,source,state.doLineDiff);var lookup=survivor(diffs,true);var entries=getEntriesForContext(contextID);var entriesByRangeString={};var persistedBlockIDs={};for(var blockID in entries){var entry=entries[blockID];if(entry.deleted)continue;var rangeString=rangeToString(entry.node.range);entriesByRangeString[rangeString]=entry}forEachNode(source,function(node){if(functionNodeTypes.indexOf(node.type)<0)return;var startSurvived=lookup(node.range[0]);var endSurvived=lookup(node.range[1]);var existingEntry=startSurvived&&endSurvived&&entriesByRangeString[rangeToString([startSurvived,endSurvived])];var blockID=existingEntry?existingEntry.blockID:blockIDCounter.getNextID();rewriteNode(contextID,blockID,version,node);persistedBlockIDs[blockID]=true});for(var blockID in entries)if(!(blockID in persistedBlockIDs))entries[blockID].deleted=true;state.lastSource=source}function getEntriesForContext(contextID){return __thermiteMap[contextID]=__thermiteMap[contextID]||{}}function invokeEval(evaler,code){try{return evaler(code)}catch(err){console.log("Error evaling code:");console.log(code);throw err}}function forEachNode(source,visitor){try{return falafel(source,{ranges:true},visitor)}catch(err){console.log("Error parsing source:");console.log(source);throw err}}function rewriteNode(contextID,blockID,version,node){var code=node.source();var name="";if(node.id&&node.id.name){name=node.id.name;code=code.replace(name,"");node.update(code)}var addVersionTo={FunctionDeclaration:addVersionToDeclaration,FunctionExpression:addVersionToExpression};var boundTemplate=addVersionTo[node.type](template,name).replace(/\$thermiteTemplate/g,name).replace(/\$thermiteBlockID/g,blockID).replace(/\$thermiteContextID/g,contextID);node.update(boundTemplate);var rewritten="("+code+")";var entries=getEntriesForContext(contextID);entries[blockID]={blockID:blockID,node:node,codeVersion:version,code:rewritten}}function addVersionToDeclaration(template,name){return"; "+"var __thermiteFunctionVersion_$thermiteBlockID; "+"var __thermiteFunction_$thermiteBlockID; "+template}function addVersionToExpression(template,name){return"(function "+name+"() { "+"var __thermiteFunctionVersion_$thermiteBlockID; "+"var __thermiteFunction_$thermiteBlockID; "+"return ("+template+");"+"})()"}function rangeToString(range){return"from"+range[0]+"to"+range[1]}exports.eval=thermiteEval}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{falafel:1,googlediff:7,survivor:9}]},{},[10])(10)});
--------------------------------------------------------------------------------