diff --git a/build/.gitignore b/build/.gitignore
deleted file mode 100644
index baa4f768..00000000
--- a/build/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/scriptographer.sh
-/*.tmproj
-/sync.sh
diff --git a/build/build.sh b/build/build.sh
deleted file mode 100755
index e57127be..00000000
--- a/build/build.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-# Paper.js
-#
-# This file is part of Paper.js, a JavaScript Vector Graphics Library,
-# based on Scriptographer.org and designed to be largely API compatible.
-# http://scriptographer.org/
-#
-# Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
-# http://lehni.org/ & http://jonathanpuckey.com/
-#
-# Distributed under the MIT license. See LICENSE file for details.
-#
-# All rights reserved.
-
-# Usage:
-# build.sh MODE
-#
-# MODE:
-# commented Preprocessed but still formated and commented
-# stripped Formated but without comments (default)
-# compressed Uses UglifyJS to reduce file size
-
-if [ $# -eq 0 ]
-then
- MODE="stripped"
-else
- MODE=$1
-fi
-
-# Create the dist folder if it does not exist yet.
-if [ ! -d ../dist/ ]
-then
- mkdir ../dist/
-fi
-
-./preprocess.sh $MODE ../src/paper.js ../dist/paper.js '{ "browser": true }'
-#./preprocess.sh $MODE ../src/paper.js ../dist/paper-server.js '{ "server": true }'
diff --git a/build/dist.sh b/build/dist.sh
deleted file mode 100755
index 6283502a..00000000
--- a/build/dist.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-# Paper.js
-#
-# This file is part of Paper.js, a JavaScript Vector Graphics Library,
-# based on Scriptographer.org and designed to be largely API compatible.
-# http://scriptographer.org/
-#
-# Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
-# http://lehni.org/ & http://jonathanpuckey.com/
-#
-# Distributed under the MIT license. See LICENSE file for details.
-#
-# All rights reserved.
-
-echo "Building paper.js"
-./build.sh
-echo "Building docs"
-./docs.sh
-echo "Zipping paperjs.zip"
-./zip.sh
diff --git a/build/docs.sh b/build/docs.sh
deleted file mode 100755
index b55606a0..00000000
--- a/build/docs.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-# Paper.js
-#
-# This file is part of Paper.js, a JavaScript Vector Graphics Library,
-# based on Scriptographer.org and designed to be largely API compatible.
-# http://scriptographer.org/
-#
-# Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
-# http://lehni.org/ & http://jonathanpuckey.com/
-#
-# Distributed under the MIT license. See LICENSE file for details.
-#
-# All rights reserved.
-
-# Generate documentation
-#
-# MODE:
-# docs Generates the JS API docs - Default
-# serverdocs Generates the website templates for the online JS API docs
-
-if [ $# -eq 0 ]
-then
- MODE="docs"
-else
- MODE=$1
-fi
-
-cd jsdoc-toolkit
-java -jar jsrun.jar app/run.js -c=conf/$MODE.conf -D="renderMode:$MODE"
-cd ..
-
-if [ $MODE = "docs" ]
-then
- # Build paper.js library for documentation
- ./preprocess.sh stripped ../src/paper.js ../dist/docs/resources/js/paper.js\
- '{ "browser": true }'
-fi
diff --git a/build/jsdoc-toolkit b/build/jsdoc-toolkit
deleted file mode 160000
index 55bd0b74..00000000
--- a/build/jsdoc-toolkit
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 55bd0b74e927683748aeace6e89a57e618d1f78f
diff --git a/build/load.sh b/build/load.sh
deleted file mode 100755
index 8ed8a3cc..00000000
--- a/build/load.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-# Paper.js
-#
-# This file is part of Paper.js, a JavaScript Vector Graphics Library,
-# based on Scriptographer.org and designed to be largely API compatible.
-# http://scriptographer.org/
-#
-# Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
-# http://lehni.org/ & http://jonathanpuckey.com/
-#
-# Distributed under the MIT license. See LICENSE file for details.
-#
-# All rights reserved.
-
-# Generate a paper.js file that uses load.js to directly load the library
-# through the seperate source files in the src directory. Very useful during
-# development of the library itself.
-
-echo "// Paper.js loader for development, as produced by the build/load.sh script
-document.write('');
-document.write('');" > ../dist/paper.js;
\ No newline at end of file
diff --git a/build/parse-js.sh b/build/parse-js.sh
deleted file mode 100755
index 7410b68a..00000000
--- a/build/parse-js.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-
-# Paper.js
-#
-# This file is part of Paper.js, a JavaScript Vector Graphics Library,
-# based on Scriptographer.org and designed to be largely API compatible.
-# http://scriptographer.org/
-#
-# Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
-# http://lehni.org/ & http://jonathanpuckey.com/
-#
-# Distributed under the MIT license. See LICENSE file for details.
-#
-# All rights reserved.
-
-# Generate a paper.js file that uses load.js to directly load the library
-# through the seperate source files in the src directory. Very useful during
-# development of the library itself.
-
-./preprocess.sh compressed ../lib/parse-js.js ../lib/parse-js-min.js '{}'
diff --git a/build/prepro.js b/build/prepro.js
deleted file mode 100755
index 1ba879dd..00000000
--- a/build/prepro.js
+++ /dev/null
@@ -1,174 +0,0 @@
-#! /usr/bin/env node
-/*
- * Paper.js
- *
- * This file is part of Paper.js, a JavaScript Vector Graphics Library,
- * based on Scriptographer.org and designed to be largely API compatible.
- * http://paperjs.org/
- * http://scriptographer.org/
- *
- * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
- * http://lehni.org/ & http://jonathanpuckey.com/
- *
- * Distributed under the MIT license. See LICENSE file for details.
- *
- * All rights reserved.
- */
-
-/**
- * Prepro.js - A simple preprocesssor for JavaScript that speaks JavaScript,
- * written in JavaScript, allowing preprocessing to either happen at build time
- * or compile time. Very useful for libraries that are built for distribution,
- * but can be also compiled from seperate sources directly for development,
- * supporting build time switches.
- */
-
-// Required libs
-
-var fs = require('fs'),
- path = require('path');
-
-// Parse arguments
-
-var args = process.argv.slice(2),
- options = {},
- files = [],
- strip = false;
-
-while (args.length > 0) {
- var arg = args.shift();
- switch (arg) {
- case '-d':
- // Definitions are provided as JSON and supposed to be object literals
- var def = JSON.parse(args.shift());
- // Merge new definitions into options object.
- for (var key in def)
- options[key] = def[key];
- break;
- case '-c':
- strip = true;
- break;
- default:
- files.push(arg);
- }
-}
-
-// Preprocessing
-
-var code = [],
- out = [];
-
-function include(base, file) {
- // Compose a pathname from base and file, which is specified relatively,
- // and normalize the new path, to get rid of ..
- file = path.normalize(path.join(base, file));
- var content = fs.readFileSync(file).toString();
- content.split(/\r\n|\n|\r/mg).forEach(function(line) {
- // See if our line starts with the preprocess prefix.
- var match = line.match(/^\s*\/\*#\*\/\s*(.*)$/);
- if (match) {
- // Check if the preprocessing line is an include statement, and if
- // so, handle it straight away
- line = match[1];
- if (match = line.match(/^include\(['"]([^;]*)['"]\);?$/)) {
- // Pass on the dirname of the current file as the new base
- include(path.dirname(file), match[1]);
- } else {
- // Any other preprocessing code is simply added, for later
- // evaluation.
- code.push(line);
- }
- } else {
- // Perhaps we need to replace some values? Supported formats are:
- // /*#=*/ options.NAME (outside comments)
- // *#=* options.NAME (inside comments)
- line = line.replace(/\/?\*#=\*\/?\s*options\.([\w]*)/g,
- function(all, name) {
- return options[name];
- }
- );
- // Now add a statement that when evaluated writes out this code line
- code.push('out.push(' + JSON.stringify(line) + ');');
- }
- });
-}
-
-// Include all files. Everything else happens from there, through include()
-files.forEach(function(file) {
- include(path.resolve(), file);
-});
-
-// Evaluate the resulting code: Calls puts() and writes the result to stdout.
-eval(code.join('\n'));
-
-// Convert the resulting lines to one string again.
-var out = out.join('\n');
-
-if (strip) {
- out = stripComments(out);
- // Strip empty lines that contain only white space and line breaks, as they
- // are left-overs from comment removal.
- out = out.replace(/^[ \t]+(\r\n|\n|\r)/gm, function(all) {
- return '';
- });
- // Replace a sequence of more than two line breaks with only two.
- out = out.replace(/(\r\n|\n|\r)(\r\n|\n|\r)+/g, function(all, lineBreak) {
- return lineBreak + lineBreak;
- });
-}
-
-// Write the result out
-process.stdout.write(out);
-
-/**
- * Strips comments out of JavaScript code, based on:
- * http://james.padolsey.com/javascript/removing-comments-in-javascript/
-*/
-function stripComments(str) {
- str = ('__' + str + '__').split('');
- var singleQuote = false,
- doubleQuote = false,
- blockComment = false,
- lineComment = false,
- preserveComment = false;
- for (var i = 0, l = str.length; i < l; i++) {
- if (singleQuote) {
- if (str[i] == "'" && str[i - 1] !== '\\')
- singleQuote = false;
- } else if (doubleQuote) {
- if (str[i] == '"' && str[i - 1] !== '\\')
- doubleQuote = false;
- } else if (blockComment) {
- // Is the block comment closing?
- if (str[i] == '*' && str[i + 1] == '/') {
- if (!preserveComment)
- str[i] = str[i + 1] = '';
- blockComment = preserveComment = false;
- } else if (!preserveComment) {
- str[i] = '';
- }
- } else if (lineComment) {
- // One-line comments end with the line-break
- if (str[i + 1] == '\n' || str[i + 1] == '\r')
- lineComment = false;
- str[i] = '';
- } else {
- doubleQuote = str[i] == '"';
- singleQuote = str[i] == "'";
- if (!blockComment && str[i] == '/') {
- if (str[i + 1] == '*') {
- // Do not filter out conditional comments and comments marked
- // as protected (/*! */)
- preserveComment = str[i + 2] == '@' || str[i + 2] == '!';
- if (!preserveComment)
- str[i] = '';
- blockComment = true;
- } else if (str[i + 1] == '/') {
- str[i] = '';
- lineComment = true;
- }
- }
- }
- }
- return str.join('').slice(2, -2);
-}
diff --git a/build/preprocess.sh b/build/preprocess.sh
deleted file mode 100755
index 860fdd73..00000000
--- a/build/preprocess.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-
-# Paper.js
-#
-# This file is part of Paper.js, a JavaScript Vector Graphics Library,
-# based on Scriptographer.org and designed to be largely API compatible.
-# http://scriptographer.org/
-#
-# Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
-# http://lehni.org/ & http://jonathanpuckey.com/
-#
-# Distributed under the MIT license. See LICENSE file for details.
-#
-# All rights reserved.
-
-# preprocess.sh
-#
-# A simple code preprocessing wrapper that uses a combination of cpp, jssrip.py
-# and sed to preprocess JavaScript files containing C-style preprocess macros
-# (#include, #ifdef, etc.). Three options offer control over wether comments
-# are preserved or stripped and whitespaces are compressed.
-#
-# Usage:
-# preprocess.sh MODE SOURCE DESTINATION ARGUMENTS
-#
-# ARGUMENTS:
-# e.g. "-DBROWSER"
-#
-# MODE:
-# commented Preprocessed but still formated and commented
-# stripped Formated but without comments
-# compressed Uses UglifyJS to reduce file size
-
-VERSION=0.22
-DATE=$(git log -1 --pretty=format:%ad)
-
-COMMAND="./prepro.js -d '{ \"version\": $VERSION, \"date\": \"$DATE\" }' -d '$4' $2"
-
-case $1 in
- stripped)
- eval "$COMMAND -c" > $3
- ;;
- commented)
- eval $COMMAND > $3
- ;;
- compressed)
- eval $COMMAND > temp.js
- ../../uglifyjs/bin/uglifyjs temp.js --extra --unsafe --reserved-names "$eval,$sign" > $3
- rm temp.js
- ;;
-esac
diff --git a/build/zip.sh b/build/zip.sh
deleted file mode 100755
index afc07257..00000000
--- a/build/zip.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-
-# Paper.js
-#
-# This file is part of Paper.js, a JavaScript Vector Graphics Library,
-# based on Scriptographer.org and designed to be largely API compatible.
-# http://scriptographer.org/
-#
-# Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
-# http://lehni.org/ & http://jonathanpuckey.com/
-#
-# Distributed under the MIT license. See LICENSE file for details.
-#
-# All rights reserved.
-
-if [ -f paperjs.zip ]
-then
- rm paperjs.zip
-fi
-# Create a temporary folder to copy all files in for zipping
-mkdir zip
-cd zip
-BASE=../..
-# Copy license over
-cp $BASE/LICENSE.txt .
-# Make library folder and copy paper.js there
-mkdir lib
-cp $BASE/dist/paper.js lib
-# Copy examples over
-cp -r $BASE/examples .
-# Replace ../../dist/ with ../../lib/ in each example
-find examples -type f -print0 | xargs -0 perl -i -pe 's/\.\.\/\.\.\/dist\//\.\.\/\.\.\/lib\//g'
-# Copy docs over
-cp -r $BASE/dist/docs .
-# Zip the whole thing
-zip -9 -r $BASE/dist/paperjs.zip * LICENSE.txt -x "*/.DS_Store"
-cd ..
-# Remove the temporary folder again
-rm -fr zip
diff --git a/dist/.gitignore b/dist/.gitignore
deleted file mode 100644
index 61f11ea6..00000000
--- a/dist/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/paper-server.js
-/serverdocs/
-/paperjs.zip
diff --git a/dist/docs/classes/CharacterStyle.html b/dist/docs/classes/CharacterStyle.html
deleted file mode 100644
index 359b7469..00000000
--- a/dist/docs/classes/CharacterStyle.html
+++ /dev/null
@@ -1,569 +0,0 @@
-
-
-
-
-
Paper.js
-
- Global Scope
--
-
Basic Types
-
- -
-
Items
-
- -
-
Paths
-
- -
-
Projects
-
- -
-
Colors
-
- -
-
Gradients
-
- -
-
Interface
-
- -
-
Typography
-
- -
-
JavaScript
-
-
-
-
\ No newline at end of file
diff --git a/dist/docs/index.html b/dist/docs/index.html
deleted file mode 100644
index 198c41b4..00000000
--- a/dist/docs/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-Paper.js API
-
-
-
-
diff --git a/dist/docs/resources/css/assets/bullet.gif b/dist/docs/resources/css/assets/bullet.gif
deleted file mode 100644
index 1789496d..00000000
Binary files a/dist/docs/resources/css/assets/bullet.gif and /dev/null differ
diff --git a/dist/docs/resources/css/codemirror.css b/dist/docs/resources/css/codemirror.css
deleted file mode 100644
index 98bbf7d3..00000000
--- a/dist/docs/resources/css/codemirror.css
+++ /dev/null
@@ -1,141 +0,0 @@
-.CodeMirror,
-.CodeMirror textarea,
-.CodeMirror pre {
- font-family: Menlo, Consolas, "Vera Mono", monospace;
- font-size: 12px;
-}
-
-.CodeMirror {
- overflow: auto;
- height: 100%;
-}
-
-.CodeMirror-gutter {
- position: absolute;
- left: 0;
- top: 0;
- min-width: 30px;
- height: 100%;
- background-color: #f4f4f4;
- border-right: 1px solid #999;
-}
-
-.CodeMirror-gutter-text {
- color: #aaa;
- text-align: right;
- padding: 2px 8px 2px 8px; /* 2px required for CodeMirror-selected */
-}
-
-.CodeMirror-gutter-text pre {
- font-size: 10px;
-}
-
-.CodeMirror-lines {
- background: #ffffff;
- padding: 2px 0 2px 8px; /* 2px required for CodeMirror-selected */
-}
-
-.CodeMirror-lines pre.highlight {
- background-color: #edf5fc;
-}
-
-/*
-.CodeMirror-lines pre:hover {
- background-color: #edf5fc;
-}
-
-.CodeMirror-lines pre.highlight:hover {
- background-color: #ffffff;
-}
-*/
-
-.CodeMirror pre {
- line-height: 16px;
- margin: 0;
- padding: 0;
- background: transparent;
- font-family: inherit;
-}
-
-.CodeMirror-cursor {
- z-index: 10;
- position: absolute;
- visibility: hidden;
- border-left: 1px solid #7c7c7c !important;
- height: 16px;
-}
-
-.CodeMirror-focused .CodeMirror-cursor {
- visibility: visible;
-}
-
-span.CodeMirror-selected {
- background: #ccc !important;
- color: HighlightText !important;
- padding: 2px 0 2px 0;
-}
-
-.CodeMirror-focused span.CodeMirror-selected {
- background: Highlight !important;
-}
-
-.CodeMirror-matchingbracket {
- background: #e3fc8d !important;
-}
-
-.CodeMirror-nonmatchingbracket {
- color: #d62a28 !important;
-}
-
-/* JavaScript */
-
-span.cm-keyword {
- color: #ff7800;
-}
-span.cm-atom,
-span.cm-number {
- color: #3b5bb5;
-}
-span.cm-def,
-span.cm-variable-2,
-span.cm-variable-3 {
- color: #3a4a64;
-}
-span.cm-variable {
- color: #000;
-}
-span.cm-property {
- color: #000;
-}
-span.cm-operator {
- color: #000;
-}
-span.cm-comment {
- color: #8c868f;
-}
-span.cm-string {
- color: #409b1c;
-}
-span.cm-meta {
- color: #555;
-}
-span.cm-error {
- color: #f30;
-}
-span.cm-qualifier {
- color: #555;
-}
-span.cm-builtin {
- color: #30a;
-}
-span.cm-bracket {
- color: #cc7;
-}
-span.cm-tag {
- font-weight: bold;
- color: #3b5bb5;
-}
-span.cm-attribute {
- font-style: italic;
- color: #3b5bb5;
-}
diff --git a/dist/docs/resources/css/paperscript.css b/dist/docs/resources/css/paperscript.css
deleted file mode 100644
index c296c3c1..00000000
--- a/dist/docs/resources/css/paperscript.css
+++ /dev/null
@@ -1,64 +0,0 @@
-.paperscript .button,
-.paperscript .explain {
- display: none;
- position: relative; /* position (top / right) relative to paperscriptcontainer */
- float: right; /* align right as block */
- font-size: 11px;
- line-height: 16px;
- padding: 2px 6px;
- margin-bottom: -20px; /* move canvas up by 16px (height) + 2 * 2px (padding) */
- border-radius: 4px;
- -moz-border-radius: 4px;
- -webkit-border-radius: 4px;
- z-index: 1;
- top: 8px; /* margin to top */
-}
-
-.paperscript .button {
- right: 8px; /* margin to right */
- background: #eee;
-}
-
-.paperscript .explain {
- display: block;
- right: 64px; /* margin to right */
- background: #e3f4fc;
- margin-bottom: -36px; /* (height) + 2 * 2px (padding) */
-}
-
-.paperscript:hover .button {
- display: block;
-}
-
-.paperscript .button:hover {
- background: #ddd;
- cursor: pointer;
-}
-
-.paperscript .source {
- overflow: auto;
- border: 1px solid #999;
-}
-
-.paperscript .CodeMirror {
- margin: 0 !important; /* Override any potential margins again */
-}
-
-.paperscript .CodeMirror-gutter-text,
-.paperscript .CodeMirror-lines {
- padding-top: 10px;
- padding-bottom: 10px;
-}
-
-.paperscript .canvas {
- line-height: 0; /* prevent weird 5px padding under canvas elements */
-}
-
-.paperscript .canvas.border canvas {
- border: 1px solid #999;
-}
-
-.paperscript.split .canvas {
- border: 1px solid #999;
- border-top: 0;
-}
diff --git a/dist/docs/resources/css/reference.css b/dist/docs/resources/css/reference.css
deleted file mode 100644
index d9e152c3..00000000
--- a/dist/docs/resources/css/reference.css
+++ /dev/null
@@ -1,128 +0,0 @@
-/* These styles are shared with the server version of docs */
-
-.reference h1, .reference h2, .reference h3 {
- font-size: 13px;
- font-weight: normal;
- height: 18px; /* -2px so border-bottom aligns with contained links */
- border-bottom: 1px solid;
- margin-top: 0;
- margin-bottom: 16px;
-}
-
-.reference h3 {
- margin-top: 16px;
- border-bottom-style: dotted;
-}
-
-.reference a tt {
- line-height: 18px;
-}
-
-.reference p {
- margin: 0 0 16px 0;
-}
-
-.reference ul {
- margin: 0;
- padding: 0;
- list-style: none;
-}
-
-.reference-list ul, .reference-inherited ul {
- margin-left: 16px;
-}
-
-.reference hr {
- border: none;
- border-bottom: 1px dotted;
-}
-
-.reference-packages {
- margin-left: 0px;
-}
-
-.reference-packages h2, .reference-packages h3, .reference-packages hr {
- margin: 10px 0 10px 0;
-}
-
-.reference-packages .first h2 {
- margin-top: 0;
-}
-
-* html .reference-packages img {
- margin-top: 5px;
-}
-
-.reference-packages li {
- list-style: none;
- list-style-image: none; /* needed for ie 6 */
-}
-
-.reference-members {
- margin-bottom: 16px;
-}
-
-.member-group-text {
- margin-bottom: 16px;
-}
-
-.member-description {
- border: 1px solid #999;
- /* .member-header defines border-top for operator lists */
- border-top: 0;
- margin: 16px 0 16px 0;
-}
-
-.member-header {
- border-top: 1px solid #999;
- padding: 10px;
-}
-
-.member-title {
- float: left;
- width: 400px;
-}
-
-.member-close {
- float: right;
-}
-
-.member-text {
- border-top: 1px dashed #999;
- padding: 10px 10px 0 10px;
- margin-bottom: -6px; /* Compensate margins of p and ul to end up with 10px */
-}
-
-.reference ul,
-.reference .paperscript,
-.reference .CodeMirror {
- margin-top: -8px; /* Move half way up close to previous paragraph */
- margin-bottom: 16px;
-}
-
-.reference ul {
- margin-top: 0; /* Clear the above -10px for ul again */
-}
-
-.member-link {
- text-indent: -30px;
- padding-left: 30px;
-}
-
-.reference-inherited ul li {
- text-indent: -30px;
- padding-left: 30px;
-}
-
-.package-classes {
- padding-bottom: 4px;
-}
-
-.package-classes ul {
- margin-left: 10px;
- margin-bottom: 10px;
-}
-
-.reference h2 a {
- font-weight: bold;
-}
diff --git a/dist/docs/resources/css/style.css b/dist/docs/resources/css/style.css
deleted file mode 100644
index e74a2dea..00000000
--- a/dist/docs/resources/css/style.css
+++ /dev/null
@@ -1,86 +0,0 @@
-body, select, input, textarea {
- font-family: "Lucida Grande", Geneva, Verdana, Arial, sans-serif;
-}
-
-body {
- background: #fff;
- margin: 16px;
- font-size: 13px;
- line-height: 20px;
- color: #000;
- max-width: 540px;
-}
-
-select, input, textarea {
- font-size: 11px;
- margin: 0;
- color: #000;
-}
-
-tt, pre {
- font-family: Menlo, Consolas, "Vera Mono", monospace;
- font-size: 12px;
- line-height: 20px;
-}
-
-a {
- color: #000;
- text-decoration: none;
- border-bottom: 1px solid #000;
-}
-
-img {
- border: 0;
-}
-
-a:hover {
- background: #e5e5e5;
-}
-
-p {
- margin: 0 0 20px 0;
-}
-
-ul {
- padding: 0;
- margin: 0 0 20px 16px;
- list-style: disc outside url(assets/bullet.gif);
-}
-
-ol {
- padding: 0;
- margin: 0 0 20px 0;
-}
-
-.clear {
- clear: both;
-}
-
-.hidden {
- display: none;
-}
-
-.reference-packages, .reference-packages a {
- color: #009dec;
- border-bottom: 0px;
-}
-
-/* Border-bottom color for headers and ruler */
-.reference-packages h2, .reference-packages h3, .reference-packages hr {
- border-color: #009dec;
-}
-
-.reference-packages a:hover {
- background: #e3f4fc;
-}
-
-.reference h1 {
- font-size: 18px;
- font-weight: normal;
- line-height: 24px;
- border: none;
-}
-
-.footer {
- margin-top: 20px;
-}
diff --git a/dist/docs/resources/js/bootstrap.js b/dist/docs/resources/js/bootstrap.js
deleted file mode 100644
index 59d03a88..00000000
--- a/dist/docs/resources/js/bootstrap.js
+++ /dev/null
@@ -1,4040 +0,0 @@
-new function() {
- var fix = !this.__proto__ && [Function, Number, Boolean, String, Array, Date, RegExp];
- if (fix)
- for (var i in fix)
- fix[i].prototype.__proto__ = fix[i].prototype;
-
- var has = {}.hasOwnProperty
- ? function(obj, name) {
- return (!fix || name != '__proto__') && obj.hasOwnProperty(name);
- }
- : function(obj, name) {
- return obj[name] !== (obj.__proto__ || Object.prototype)[name];
- };
-
- function inject(dest, src, enumerable, base, preserve, generics) {
-
- function field(name, dontCheck, generics) {
- var val = src[name], func = typeof val == 'function', res = val, prev = dest[name];
- if (generics && func && (!preserve || !generics[name])) generics[name] = function(bind) {
- return bind && dest[name].apply(bind,
- Array.prototype.slice.call(arguments, 1));
- }
- if ((dontCheck || val !== undefined && has(src, name)) && (!preserve || !prev)) {
- if (func) {
- if (prev && /\bthis\.base\b/.test(val)) {
- var fromBase = base && base[name] == prev;
- res = (function() {
- var tmp = this.base;
- this.base = fromBase ? base[name] : prev;
- try { return val.apply(this, arguments); }
- finally { tmp ? this.base = tmp : delete this.base; }
- }).pretend(val);
- }
- }
- dest[name] = res;
- }
- }
- if (src) {
- for (var name in src)
- if (has(src, name) && !/^(statics|generics|preserve|prototype|constructor|__proto__|toString|valueOf)$/.test(name))
- field(name, true, generics);
- field('toString');
- field('valueOf');
- }
- }
-
- function extend(obj) {
- function ctor(dont) {
- if (fix) this.__proto__ = obj;
- if (this.initialize && dont !== ctor.dont)
- return this.initialize.apply(this, arguments);
- }
- ctor.prototype = obj;
- ctor.toString = function() {
- return (this.prototype.initialize || function() {}).toString();
- }
- return ctor;
- }
-
- inject(Function.prototype, {
- inject: function(src) {
- if (src) {
- var proto = this.prototype, base = proto.__proto__ && proto.__proto__.constructor;
- inject(proto, src, false, base && base.prototype, src.preserve, src.generics && this);
- inject(this, src.statics, true, base, src.preserve);
- }
- for (var i = 1, l = arguments.length; i < l; i++)
- this.inject(arguments[i]);
- return this;
- },
-
- extend: function(src) {
- var proto = new this(this.dont), ctor = proto.constructor = extend(proto);
- ctor.dont = {};
- inject(ctor, this, true);
- return arguments.length ? this.inject.apply(ctor, arguments) : ctor;
- },
-
- pretend: function(fn) {
- this.toString = function() {
- return fn.toString();
- }
- this.valueOf = function() {
- return fn.valueOf();
- }
- return this;
- }
- });
-
- function each(obj, iter, bind) {
- return obj ? (typeof obj.length == 'number'
- ? Array : Hash).prototype.each.call(obj, iter, bind) : bind;
- }
-
- Base = Object.extend({
- has: function(name) {
- return has(this, name);
- },
-
- each: function(iter, bind) {
- return each(this, iter, bind);
- },
-
- inject: function() {
- for (var i = 0, l = arguments.length; i < l; i++)
- inject(this, arguments[i]);
- return this;
- },
-
- extend: function() {
- var res = new (extend(this));
- return res.inject.apply(res, arguments);
- },
-
- statics: {
- has: has,
- each: each,
-
- type: function(obj) {
- return (obj || obj === 0) && (
- obj._type || obj.nodeName && (
- obj.nodeType == 1 && 'element' ||
- obj.nodeType == 3 && 'textnode' ||
- obj.nodeType == 9 && 'document')
- || obj.location && obj.frames && obj.history && 'window'
- || typeof obj) || null;
- },
-
- check: function(obj) {
- return !!(obj || obj === 0);
- },
-
- pick: function() {
- for (var i = 0, l = arguments.length; i < l; i++)
- if (arguments[i] !== undefined)
- return arguments[i];
- return null;
- },
-
- iterator: function(iter) {
- return !iter
- ? function(val) { return val }
- : typeof iter != 'function'
- ? function(val) { return val == iter }
- : iter;
- },
-
- stop: {}
- }
- }, {
- generics: true,
-
- debug: function() {
- return /^(string|number|function|regexp)$/.test(Base.type(this)) ? this
- : Base.each(this, function(val, key) { this.push(key + ': ' + val); }, []).join(', ');
- },
-
- clone: function() {
- return Base.each(this, function(val, i) {
- this[i] = val;
- }, new this.constructor());
- },
-
- toQueryString: function() {
- return Base.each(this, function(val, key) {
- this.push(key + '=' + encodeURIComponent(val));
- }, []).join('&');
- }
- });
-}
-
-$each = Base.each;
-$type = Base.type;
-$check = Base.check;
-$pick = Base.pick;
-$stop = $break = Base.stop;
-
-Enumerable = {
- generics: true,
- preserve: true,
-
- findEntry: function(iter, bind) {
- var that = this, iter = Base.iterator(iter), ret = null;
- Base.each(this, function(val, key) {
- var res = iter.call(bind, val, key, that);
- if (res) {
- ret = { key: key, value: val, result: res };
- throw Base.stop;
- }
- });
- return ret;
- },
-
- find: function(iter, bind) {
- var entry = this.findEntry(iter, bind);
- return entry && entry.result;
- },
-
- contains: function(iter) {
- return !!this.findEntry(iter);
- },
-
- remove: function(iter, bind) {
- var entry = this.findEntry(iter, bind);
- if (entry) {
- delete this[entry.key];
- return entry.value;
- }
- },
-
- filter: function(iter, bind) {
- var that = this;
- return Base.each(this, function(val, i) {
- if (iter.call(bind, val, i, that))
- this[this.length] = val;
- }, []);
- },
-
- map: function(iter, bind) {
- var that = this;
- return Base.each(this, function(val, i) {
- this[this.length] = iter.call(bind, val, i, that);
- }, []);
- },
-
- every: function(iter, bind) {
- var that = this;
- return this.find(function(val, i) {
- return !iter.call(this, val, i, that);
- }, bind || null) == null;
- },
-
- some: function(iter, bind) {
- return this.find(iter, bind || null) != null;
- },
-
- collect: function(iter, bind) {
- var that = this, iter = Base.iterator(iter);
- return Base.each(this, function(val, i) {
- val = iter.call(bind, val, i, that);
- if (val != null)
- this[this.length] = val;
- }, []);
- },
-
- max: function(iter, bind) {
- var that = this, iter = Base.iterator(iter);
- return Base.each(this, function(val, i) {
- val = iter.call(bind, val, i, that);
- if (val >= (this.max || val)) this.max = val;
- }, {}).max;
- },
-
- min: function(iter, bind) {
- var that = this, iter = Base.iterator(iter);
- return Base.each(this, function(val, i) {
- val = iter.call(bind, val, i, that);
- if (val <= (this.min || val)) this.min = val;
- }, {}).min;
- },
-
- pluck: function(prop) {
- return this.map(function(val) {
- return val[prop];
- });
- },
-
- sortBy: function(iter, bind) {
- var that = this, iter = Base.iterator(iter);
- return this.map(function(val, i) {
- return { value: val, compare: iter.call(bind, val, i, that) };
- }, bind).sort(function(left, right) {
- var a = left.compare, b = right.compare;
- return a < b ? -1 : a > b ? 1 : 0;
- }).pluck('value');
- },
-
- toArray: function() {
- return this.map(function(value) {
- return value;
- });
- }
-};
-
-Hash = Base.extend(Enumerable, {
- generics: true,
-
- initialize: function(arg) {
- if (typeof arg == 'string') {
- for (var i = 0, l = arguments.length; i < l; i += 2)
- this[arguments[i]] = arguments[i + 1];
- } else {
- this.append.apply(this, arguments);
- }
- return this;
- },
-
- each: function(iter, bind) {
- var bind = bind || this, iter = Base.iterator(iter), has = Base.has;
- try {
- for (var i in this)
- if (has(this, i))
- iter.call(bind, this[i], i, this);
- } catch (e) {
- if (e !== Base.stop) throw e;
- }
- return bind;
- },
-
- append: function() {
- for (var i = 0, l = arguments.length; i < l; i++) {
- var obj = arguments[i];
- for (var key in obj)
- if (Base.has(obj, key))
- this[key] = obj[key];
- }
- return this;
- },
-
- merge: function() {
- return Array.each(arguments, function(obj) {
- Base.each(obj, function(val, key) {
- this[key] = Base.type(this[key]) == 'object'
- ? Hash.prototype.merge.call(this[key], val)
- : Base.type(val) == 'object' ? Base.clone(val) : val;
- }, this);
- }, this);
- },
-
- getKeys: function() {
- return Hash.getKeys(this);
- },
-
- getValues: Enumerable.toArray,
-
- getSize: function() {
- return this.each(function() {
- this.size++;
- }, { size: 0 }).size;
- },
-
- statics: {
- create: function(obj) {
- return arguments.length == 1 && obj.constructor == Hash
- ? obj : Hash.prototype.initialize.apply(new Hash(), arguments);
- },
-
- getKeys: Object.keys || function(obj) {
- return Hash.map(function(val, key) {
- return key;
- });
- }
- }
-});
-
-$H = Hash.create;
-
-Array.inject({
- generics: true,
- preserve: true,
- _type: 'array',
-
- forEach: function(iter, bind) {
- for (var i = 0, l = this.length; i < l; i++)
- iter.call(bind, this[i], i, this);
- },
-
- indexOf: function(obj, i) {
- i = i || 0;
- if (i < 0) i = Math.max(0, this.length + i);
- for (var l = this.length; i < l; i++)
- if (this[i] == obj) return i;
- return -1;
- },
-
- lastIndexOf: function(obj, i) {
- i = i != null ? i : this.length - 1;
- if (i < 0) i = Math.max(0, this.length + i);
- for (; i >= 0; i--)
- if (this[i] == obj) return i;
- return -1;
- },
-
- filter: function(iter, bind) {
- var res = [];
- for (var i = 0, l = this.length; i < l; i++) {
- var val = this[i];
- if (iter.call(bind, val, i, this))
- res[res.length] = val;
- }
- return res;
- },
-
- map: function(iter, bind) {
- var res = new Array(this.length);
- for (var i = 0, l = this.length; i < l; i++)
- res[i] = iter.call(bind, this[i], i, this);
- return res;
- },
-
- every: function(iter, bind) {
- for (var i = 0, l = this.length; i < l; i++)
- if (!iter.call(bind, this[i], i, this))
- return false;
- return true;
- },
-
- some: function(iter, bind) {
- for (var i = 0, l = this.length; i < l; i++)
- if (iter.call(bind, this[i], i, this))
- return true;
- return false;
- },
-
- reduce: function(fn, value) {
- var i = 0;
- if (arguments.length < 2 && this.length) value = this[i++];
- for (var l = this.length; i < l; i++)
- value = fn.call(null, value, this[i], i, this);
- return value;
- },
-
- statics: {
- isArray: function(obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
- }
- }
-}, Enumerable, {
- generics: true,
-
- each: function(iter, bind) {
- try {
- Array.prototype.forEach.call(this, Base.iterator(iter), bind = bind || this);
- } catch (e) {
- if (e !== Base.stop) throw e;
- }
- return bind;
- },
-
- collect: function(iter, bind) {
- var that = this;
- return this.each(function(val, i) {
- if ((val = iter.call(bind, val, i, that)) != null)
- this[this.length] = val;
- }, []);
- },
-
- findEntry: function(iter, bind) {
- if (typeof iter != 'function') {
- var i = this.indexOf(iter);
- return i == -1 ? null : { key: i, value: iter, result: iter };
- }
- return Enumerable.findEntry.call(this, iter, bind);
- },
-
- remove: function(iter, bind) {
- var entry = this.findEntry(iter, bind);
- if (entry) {
- this.splice(entry.key, 1);
- return entry.value;
- }
- },
-
- toArray: function() {
- return Array.prototype.slice.call(this);
- },
-
- clone: function() {
- return this.toArray();
- },
-
- clear: function() {
- this.length = 0;
- },
-
- compact: function() {
- return this.filter(function(value) {
- return value != null;
- });
- },
-
- append: function(items) {
- for (var i = 0, l = items.length; i < l; i++)
- this[this.length++] = items[i];
- return this;
- },
-
- associate: function(obj) {
- if (!obj)
- obj = this;
- else if (typeof obj == 'function')
- obj = this.map(obj);
- if (obj.length != null) {
- var that = this;
- return Base.each(obj, function(name, index) {
- this[name] = that[index];
- if (index == that.length)
- throw Base.stop;
- }, {});
- } else {
- obj = Hash.append({}, obj);
- return Array.each(this, function(val) {
- var type = Base.type(val);
- Base.each(obj, function(hint, name) {
- if (hint == 'any' || type == hint) {
- this[name] = val;
- delete obj[name];
- throw Base.stop;
- }
- }, this);
- }, {});
- }
- },
-
- flatten: function() {
- return Array.each(this, function(val) {
- if (val != null && val.flatten) this.append(val.flatten());
- else this.push(val);
- }, []);
- },
-
- swap: function(i, j) {
- var tmp = this[j];
- this[j] = this[i];
- this[i] = tmp;
- return tmp;
- },
-
- shuffle: function() {
- var res = this.clone();
- var i = this.length;
- while (i--) res.swap(i, Math.rand(i + 1));
- return res;
- },
-
- pick: function() {
- return this[Math.rand(this.length)];
- },
-
- getFirst: function() {
- return this[0];
- },
-
- getLast: function() {
- return this[this.length - 1];
- }
-}, new function() {
- function combine(subtract) {
- return function(items) {
- var res = new this.constructor();
- for (var i = this.length - 1; i >= 0; i--)
- if (subtract == !Array.find(items, this[i]))
- res.push(this[i]);
- return res;
- }
- }
-
- return {
- subtract: combine(true),
-
- intersect: combine(false)
- }
-});
-
-Array.inject(new function() {
- var proto = Array.prototype, fields = ['push','pop','shift','unshift','sort',
- 'reverse','join','slice','splice','forEach','indexOf','lastIndexOf',
- 'filter','map','every','some','reduce','concat'].each(function(name) {
- this[name] = proto[name];
- }, { generics: true, preserve: true });
-
- Array.inject(fields);
-
- Hash.append(fields, proto, {
- clear: function() {
- for (var i = 0, l = this.length; i < l; i++)
- delete this[i];
- this.length = 0;
- },
-
- concat: function(list) {
- return Browser.WEBKIT
- ? new Array(this.length + list.length).append(this).append(list)
- : Array.concat(this, list);
- },
-
- toString: proto.join,
-
- length: 0
- });
-
- return {
- statics: {
- create: function(obj) {
- if (obj == null)
- return [];
- if (obj.toArray)
- return obj.toArray();
- if (typeof obj.length == 'number')
- return Array.prototype.slice.call(obj);
- return [obj];
- },
-
- convert: function(obj) {
- return Base.type(obj) == 'array' ? obj : Array.create(obj);
- },
-
- extend: function(src) {
- var ret = Base.extend(fields, src);
- ret.extend = Function.extend;
- return ret;
- }
- }
- };
-});
-
-$A = Array.create;
-
-Function.inject(new function() {
-
- function timer(set) {
- return function(delay, bind, args) {
- var func = this.wrap(bind, args);
- if (delay === undefined)
- return func();
- var timer = set(func, delay);
- func.clear = function() {
- clearTimeout(timer);
- clearInterval(timer);
- };
- return func;
- };
- }
-
- return {
- generics: true,
- preserve: true,
-
- delay: timer(setTimeout),
- periodic: timer(setInterval),
-
- bind: function(bind) {
- var that = this, slice = Array.prototype.slice,
- args = arguments.length > 1 ? slice.call(arguments, 1) : null;
- return function() {
- return that.apply(bind, args ? arguments.length > 0
- ? args.concat(slice.call(arguments)) : args : arguments);
- }
- },
-
- wrap: function(bind, args) {
- var that = this;
- return function() {
- return that.apply(bind, args || arguments);
- }
- }
- }
-});
-
-Number.inject({
- _type: 'number',
-
- limit: function(min, max) {
- return Math.min(max, Math.max(min, this));
- },
-
- times: function(func, bind) {
- for (var i = 0; i < this; i++)
- func.call(bind, i);
- return bind || this;
- },
-
- toInt: function(base) {
- return parseInt(this, base || 10);
- },
-
- toFloat: function() {
- return parseFloat(this);
- },
-
- toPaddedString: function(length, base, prefix) {
- var str = this.toString(base || 10);
- return (prefix || '0').times(length - str.length) + str;
- }
-});
-
-String.inject({
- _type: 'string',
-
- test: function(exp, param) {
- return new RegExp(exp, param || '').test(this);
- },
-
- toArray: function() {
- return this ? this.split(/\s+/) : [];
- },
-
- toInt: Number.prototype.toInt,
-
- toFloat: Number.prototype.toFloat,
-
- camelize: function(separator) {
- return this.replace(separator ? new RegExp('[' + separator + '](\\w)', 'g') : /-(\w)/g, function(all, chr) {
- return chr.toUpperCase();
- });
- },
-
- uncamelize: function(separator) {
- separator = separator || ' ';
- return this.replace(/[a-z][A-Z0-9]|[0-9][a-zA-Z]|[A-Z]{2}[a-z]/g, function(match) {
- return match.charAt(0) + separator + match.substring(1);
- });
- },
-
- hyphenate: function(separator) {
- return this.uncamelize(separator || '-').toLowerCase();
- },
-
- capitalize: function() {
- return this.replace(/\b[a-z]/g, function(match) {
- return match.toUpperCase();
- });
- },
-
- escapeRegExp: function() {
- return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
- },
-
- trim: function(exp) {
- exp = exp ? '[' + exp + ']' : '\\s';
- return this.replace(new RegExp('^' + exp + '+|' + exp + '+$', 'g'), '');
- },
-
- clean: function() {
- return this.replace(/\s{2,}/g, ' ').trim();
- },
-
- contains: function(string, sep) {
- return (sep ? (sep + this + sep).indexOf(sep + string + sep) : this.indexOf(string)) != -1;
- },
-
- times: function(count) {
- return count < 1 ? '' : new Array(count + 1).join(this);
- },
-
- isHtml: function() {
- return /^[^<]*(<(.|\s)+>)[^>]*$/.test(this);
- }
-});
-
-RegExp.inject({
- _type: 'regexp'
-});
-
-Date.inject({
- statics: {
- SECOND: 1000,
- MINUTE: 60000,
- HOUR: 3600000,
- DAY: 86400000,
- WEEK: 604800000,
- MONTH: 2592000000,
- YEAR: 31536000000,
-
- now: Date.now || function() {
- return +new Date();
- }
- }
-});
-
-Math.rand = function(first, second) {
- return second == undefined
- ? Math.rand(0, first)
- : Math.floor(Math.random() * (second - first) + first);
-}
-
-Array.inject({
- hexToRgb: function(toArray) {
- if (this.length >= 3) {
- var rgb = [];
- for (var i = 0; i < 3; i++)
- rgb.push((this[i].length == 1 ? this[i] + this[i] : this[i]).toInt(16));
- return toArray ? rgb : 'rgb(' + rgb.join(',') + ')';
- }
- },
-
- rgbToHex: function(toArray) {
- if (this.length >= 3) {
- if (this.length == 4 && this[3] == 0 && !toArray) return 'transparent';
- var hex = [];
- for (var i = 0; i < 3; i++) {
- var bit = (this[i] - 0).toString(16);
- hex.push(bit.length == 1 ? '0' + bit : bit);
- }
- return toArray ? hex : '#' + hex.join('');
- }
- },
-
- rgbToHsb: function() {
- var r = this[0], g = this[1], b = this[2];
- var hue, saturation, brightness;
- var max = Math.max(r, g, b), min = Math.min(r, g, b);
- var delta = max - min;
- brightness = max / 255;
- saturation = (max != 0) ? delta / max : 0;
- if (saturation == 0) {
- hue = 0;
- } else {
- var rr = (max - r) / delta;
- var gr = (max - g) / delta;
- var br = (max - b) / delta;
- if (r == max) hue = br - gr;
- else if (g == max) hue = 2 + rr - br;
- else hue = 4 + gr - rr;
- hue /= 6;
- if (hue < 0) hue++;
- }
- return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
- },
-
- hsbToRgb: function() {
- var br = Math.round(this[2] / 100 * 255);
- if (this[1] == 0) {
- return [br, br, br];
- } else {
- var hue = this[0] % 360;
- var f = hue % 60;
- var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
- var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);
- var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);
- switch (Math.floor(hue / 60)) {
- case 0: return [br, t, p];
- case 1: return [q, br, p];
- case 2: return [p, br, t];
- case 3: return [p, q, br];
- case 4: return [t, p, br];
- case 5: return [br, p, q];
- }
- }
- }
-});
-
-String.inject({
- hexToRgb: function(toArray) {
- var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
- return hex && hex.slice(1).hexToRgb(toArray);
- },
-
- rgbToHex: function(toArray) {
- var rgb = this.match(/\d{1,3}/g);
- return rgb && rgb.rgbToHex(toArray);
- }
-});
-
-Json = function(JSON) {
- var special = { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', "'" : "\\'", '\\': '\\\\' };
- return {
- encode: JSON
- ? function(obj, properties) {
- return JSON.stringify(obj, properties || Browser.TRIDENT && function(key, value) {
- return key == '__proto__' ? undefined : value;
- });
- }
- : function(obj, properties) {
- if (Base.type(properties) == 'array') {
- properties = properties.each(function(val) {
- this[val] = true;
- }, {});
- }
- switch (Base.type(obj)) {
- case 'string':
- return '"' + obj.replace(/[\x00-\x1f\\"]/g, function(chr) {
- return special[chr] || '\\u' + chr.charCodeAt(0).toPaddedString(4, 16);
- }) + '"';
- case 'array':
- return '[' + obj.collect(function(val) {
- return Json.encode(val, properties);
- }) + ']';
- case 'object':
- case 'hash':
- return '{' + Hash.collect(obj, function(val, key) {
- if (!properties || properties[key]) {
- val = Json.encode(val, properties);
- if (val !== undefined)
- return Json.encode(key) + ':' + val;
- }
- }) + '}';
- case 'function':
- return undefined;
- default:
- return obj + '';
- }
- return null;
- },
-
- decode: JSON
- ? function(str, secure) {
- try {
- return JSON.parse(str);
- } catch (e) {
- return null;
- }
- }
- : function(str, secure) {
- try {
- return Base.type(str) == 'string' && (str = str.trim()) &&
- (!secure || /^[\],:{}\s]*$/.test(
- str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
- .replace(/(?:^|:|,)(?:\s*\[)+/g, "")))
- ? (new Function('return ' + str))() : null;
- } catch (e) {
- return null;
- }
- }
- };
-}(this.JSON);
-
-Browser = new function() {
- var name = window.orientation != undefined ? 'ipod'
- : (navigator.platform.match(/mac|win|linux|nix/i) || ['other'])[0].toLowerCase();
- var fields = {
- PLATFORM: name,
- XPATH: !!document.evaluate,
- QUERY: !!document.querySelector
- };
- fields[name.toUpperCase()] = true;
-
- function getVersion(prefix, min, max) {
- var ver = (new RegExp(prefix + '([\\d.]+)', 'i').exec(navigator.userAgent) || [0, '0'])[1].split('.');
- return (ver.slice(0, min).join('') + '.' + ver.slice(min, max || ver.length).join('')).toFloat();
- }
-
- var engines = {
- presto: function() {
- return !window.opera ? false : getVersion('Presto/', 2) || getVersion('Opera[/ ]', 1);
- },
-
- trident: function() {
- return !window.ActiveXObject ? false : getVersion('MSIE ', 1);
- },
-
- webkit: function() {
- return navigator.taintEnabled ? false : getVersion('WebKit/', 1, 2);
- },
-
- gecko: function() {
- return !document.getBoxObjectFor && window.mozInnerScreenX == null ? false : getVersion('rv:', 2);
- }
- };
-
- for (var engine in engines) {
- var version = engines[engine]();
- if (version) {
- fields.ENGINE = engine;
- fields.VERSION = version;
- engine = engine.toUpperCase();
- fields[engine] = true;
- fields[(engine + version).replace(/\./g, '')] = true;
- break;
- }
- }
-
- fields.log = function() {
- if (!Browser.TRIDENT && window.console && console.log)
- console.log.apply(console, arguments);
- else
- (window.console && console.log
- || window.opera && opera.postError
- || alert)(Array.join(arguments, ' '));
- }
-
- return fields;
-};
-
-DomNodes = Array.extend(new function() {
- var unique = 0;
- return {
- initialize: function(nodes) {
- this._unique = unique++;
- this.append(nodes && nodes.length != null && !nodes.nodeType
- ? nodes : arguments);
- },
-
- push: function() {
- this.append(arguments);
- return this.length;
- },
-
- append: function(items) {
- for (var i = 0, l = items.length; i < l; i++) {
- var el = items[i];
- if ((el = el && (el._wrapper || DomNode.wrap(el))) && el._unique != this._unique) {
- el._unique = this._unique;
- this[this.length++] = el;
- }
- }
- return this;
- },
-
- toNode: function() {
- return this;
- },
-
- statics: {
- inject: function(src) {
- var proto = this.prototype;
- this.base(Base.each(src || {}, function(val, key) {
- if (typeof val == 'function') {
- var func = val, prev = proto[key];
- var count = func.length, prevCount = prev && prev.length;
- val = function() {
- var args = arguments, values;
- if (prev && args.length == prevCount
- || (args.length > count && args.length <= prevCount))
- return prev.apply(this, args);
- this.each(function(obj) {
- var ret = (obj[key] || func).apply(obj, args);
- if (ret !== undefined && ret != obj) {
- values = values || (DomNode.isNode(ret)
- ? new obj._collection() : []);
- values.push(ret);
- }
- });
- return values || this;
- }
- }
- this[key] = val;
- }, {}));
- for (var i = 1, l = arguments.length; i < l; i++)
- this.inject(arguments[i]);
- return this;
- }
- }
- };
-});
-
-DomNode = Base.extend(new function() {
- var nodes = [];
- var tags = {}, classes = {}, classCheck, unique = 0;
-
- function dispose(force) {
- for (var i = nodes.length - 1; i >= 0; i--) {
- var el = nodes[i];
- if (force || (!el || el != window && el != document &&
- (!el.parentNode || !el.offsetParent))) {
- if (el) {
- var obj = el._wrapper;
- if (obj && obj.finalize) obj.finalize();
- el._wrapper = el._unique = null;
- }
- if (!force) nodes.splice(i, 1);
- }
- }
- }
-
- function inject(src) {
- src = src || {};
- (src._methods || []).each(function(name) {
- src[name] = function(arg) {
- var ret = this.$[name] && this.$[name](arg);
- return ret === undefined ? this : ret;
- }
- });
- (src._properties || []).each(function(name) {
- var part = name.capitalize(), prop = name.toLowerCase();
- src['get' + part] = function() {
- return this.getProperty(prop);
- }
- src['set' + part] = function(value) {
- return this.setProperty(prop, value);
- }
- });
- delete src._methods;
- delete src._properties;
- return Function.inject.call(this, src);
- }
-
- function getConstructor(el) {
- var match;
- return classCheck && el.className && (match = el.className.match(classCheck)) && match[2] && classes[match[2]] ||
- el.tagName && tags[el.tagName] ||
- el.className !== undefined && HtmlElement ||
- el.nodeType == 1 && DomElement ||
- el.nodeType == 3 && DomTextNode ||
- el.nodeType == 9 && (el.documentElement.nodeName.toLowerCase() == 'html' && HtmlDocument || DomDocument) ||
- el.location && el.frames && el.history && DomWindow ||
- DomNode;
- }
-
- var dont = {};
-
- return {
- _type: 'node',
- _collection: DomNodes,
- _initialize: true,
-
- initialize: function(el, props, doc) {
- if (!el) return null;
- if (this._tag && Base.type(el) == 'object') {
- props = el;
- el = this._tag;
- }
- if (typeof(el) == 'string') {
- el = DomElement.create(el, props, doc);
- } else if (el._wrapper) {
- return el._wrapper;
- }
- if (props === dont) {
- props = null;
- } else {
- var ctor = getConstructor(el);
- if (ctor != this.constructor)
- return new ctor(el, props);
- }
- this.$ = el;
- try {
- el._wrapper = this;
- nodes[nodes.length] = el;
- } catch (e) {}
- if (props) this.set(props);
- },
-
- statics: {
- inject: function(src) {
- if (src) {
- var proto = this.prototype, that = this;
- src.statics = Base.each(src, function(val, name) {
- if (typeof val == 'function' && !this[name] && !that[name]) {
- this[name] = function(el, param1, param2) {
- if (el) try {
- proto.$ = el.$ || el;
- return proto[name](param1, param2);
- } finally {
- delete proto.$;
- }
- }
- }
- }, src.statics || {});
- inject.call(this, src);
- delete src.toString;
- proto._collection.inject(src);
- }
- for (var i = 1, l = arguments.length; i < l; i++)
- this.inject(arguments[i]);
- return this;
- },
-
- extend: function(src) {
- var ret = this.base();
- var init = src.initialize;
- if (init) src.initialize = function(el, props) {
- var ret = this._initialize && this.base(el, props);
- if (ret) return ret;
- init.apply(this, arguments);
- }
- inject.call(ret, src);
- if (ret.prototype._collection == this.prototype._collection)
- ret.inject = inject;
- if (src) {
- if (src._tag)
- tags[src._tag.toLowerCase()] = tags[src._tag.toUpperCase()] = ret;
- if (src._class) {
- classes[src._class] = ret;
- classCheck = new RegExp('(^|\\s)(' + Base.each(classes, function(val, name) {
- this.push(name);
- }, []).join('|') + ')(\\s|$)');
- if (!src._lazy && src.initialize) Browser.document.addEvent('domready', function() {
- this.getElements('.' + src._class);
- });
- }
- }
- return ret;
- },
-
- wrap: function(el) {
- return el ? typeof el == 'string'
- ? DomElement.get(el)
- : el._wrapper || el._collection && el || new (getConstructor(el))(el, dont)
- : null;
- },
-
- unwrap: function(el) {
- return el && el.$ || el;
- },
-
- unique: function(el) {
- if (!el._unique) {
- nodes.push(el);
- el._unique = ++unique;
- }
- },
-
- isNode: function(obj) {
- return /^(element|node|textnode|document)$/.test(
- typeof obj == 'string' ? obj : Base.type(obj));
- },
-
- dispose: function() {
- dispose(true);
- }
- }
- }
-});
-
-DomNode.inject(new function() {
- var bools = ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked',
- 'disabled', 'readonly', 'multiple', 'selected', 'noresize', 'defer'
- ].associate();
- var properties = Hash.append({
- text: Browser.TRIDENT || Browser.WEBKIT && Browser.VERSION < 420 || Browser.PRESTO && Browser.VERSION < 9
- ? function(node) {
- return node.$.innerText !== undefined ? 'innerText' : 'nodeValue'
- } : 'textContent',
- html: 'innerHTML', 'class': 'className', className: 'className', 'for': 'htmlFor'
- }, [
- 'value', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan',
- 'frameBorder', 'maxLength', 'readOnly', 'rowSpan', 'tabIndex',
- 'selectedIndex', 'useMap', 'width', 'height'
- ].associate(function(name) {
- return name.toLowerCase();
- }), bools);
-
- var clones = { input: 'checked', option: 'selected', textarea: Browser.WEBKIT && Browser.VERSION < 420 ? 'innerHTML' : 'value' };
-
- function handle(that, prefix, name, value) {
- var ctor = that.__proto__.constructor;
- var handlers = ctor.handlers = ctor.handlers || { get: {}, set: {} };
- var list = handlers[prefix];
- var fn = name == 'events' && prefix == 'set' ? that.addEvents : list[name];
- if (fn === undefined)
- fn = list[name] = that[prefix + name.capitalize()] || null;
- return fn
- ? fn[Base.type(value) == 'array' ? 'apply' : 'call'](that, value)
- : that[prefix + 'Property'](name, value);
- }
-
- function toNodes(elements) {
- var els = Base.type(elements) == 'array' ? elements : Array.create(arguments);
- var created = els.find(function(el) {
- return !DomNode.isNode(el);
- });
- var result = els.toNode(this.getDocument());
- return {
- array: result ? (Base.type(result) == 'array' ? result : [result]) : [],
- result: created && result
- };
- }
-
- var fields = {
- _properties: ['text'],
-
- set: function(name, value) {
- switch (Base.type(name)) {
- case 'string':
- return handle(this, 'set', name, value);
- case 'object':
- return Base.each(name, function(value, key) {
- handle(this, 'set', key, value);
- }, this);
- }
- return this;
- },
-
- get: function(name) {
- return handle(this, 'get', name);
- },
-
- getDocument: function() {
- return DomNode.wrap(this.$.ownerDocument);
- },
-
- getWindow: function() {
- return this.getDocument().getWindow();
- },
-
- getPreviousNode: function() {
- return DomNode.wrap(this.$.previousSibling);
- },
-
- getNextNode: function() {
- return DomNode.wrap(this.$.nextSibling);
- },
-
- getFirstNode: function() {
- return DomNode.wrap(this.$.firstChild);
- },
-
- getLastNode: function() {
- return DomNode.wrap(this.$.lastChild);
- },
-
- getParentNode: function() {
- return DomNode.wrap(this.$.parentNode);
- },
-
- getChildNodes: function() {
- return new DomNodes(this.$.childNodes);
- },
-
- hasChildNodes: function() {
- return this.$.hasChildNodes();
- },
-
- appendChild: function(el) {
- if (el = DomNode.wrap(el)) {
- var text = Browser.TRIDENT && el.$.text;
- if (text) el.$.text = '';
- this.$.appendChild(el.$);
- if (text) el.$.text = text;
- }
- return this;
- },
-
- appendChildren: function() {
- return Array.flatten(arguments).each(function(el) {
- this.appendChild($(DomNode.wrap(el)));
- }, this);
- },
-
- appendText: function(text) {
- return this.injectBottom(this.getDocument().createTextNode(text));
- },
-
- prependText: function(text) {
- return this.injectTop(this.getDocument().createTextNode(text));
- },
-
- remove: function() {
- if (this.$.parentNode)
- this.$.parentNode.removeChild(this.$);
- return this;
- },
-
- removeChild: function(el) {
- el = DomNode.wrap(el);
- this.$.removeChild(el.$);
- return el;
- },
-
- removeChildren: function() {
- var nodes = this.getChildNodes();
- nodes.remove();
- return nodes;
- },
-
- replaceWith: function(el) {
- if (this.$.parentNode) {
- el = toNodes.apply(this, arguments);
- var els = el.array;
- if (els.length > 0)
- this.$.parentNode.replaceChild(els[0].$, this.$);
- for (var i = els.length - 1; i > 0; i--)
- els[i].insertAfter(els[0]);
- return el.result;
- }
- return null;
- },
-
- wrap: function() {
- var el = this.injectBefore.apply(this, arguments), last;
- do {
- last = el;
- el = el.getFirst();
- } while(el);
- last.appendChild(this);
- return last;
- },
-
- clone: function(contents) {
- var clone = this.$.cloneNode(!!contents);
- function clean(left, right) {
- if (Browser.TRIDENT) {
- left.clearAttributes();
- left.mergeAttributes(right);
- left.removeAttribute('_wrapper');
- left.removeAttribute('_unique');
- if (left.options)
- for (var l = left.options, r = right.options, i = l.length; i--;)
- l[i].selected = r[i].selected;
- }
- var name = clones[right.tagName.toLowerCase()];
- if (name && right[name])
- left[name] = right[name];
- if (contents)
- for (var l = left.childNodes, r = right.childNodes, i = l.length; i--;)
- clean(l[i], r[i]);
- }
- clean(clone, this.$);
- return DomNode.wrap(clone);
- },
-
- hasProperty: function(name) {
- var key = properties[name];
- key = key && typeof key == 'function' ? key(this) : key;
- return key ? this.$[key] !== undefined : this.$.hasAttribute(name);
- },
-
- getProperty: function(name) {
- var key = properties[name], value;
- key = key && typeof key == 'function' ? key(this) : key;
- var value = key ? this.$[key] : this.$.getAttribute(name);
- return bools[name] ? !!value : value;
- },
-
- setProperty: function(name, value) {
- var key = properties[name], defined = value !== undefined;
- key = key && typeof key == 'function' ? key(this) : key;
- if (key && bools[name]) value = value || !defined ? true : false;
- else if (!defined) return this.removeProperty(name);
- key ? this.$[key] = value : this.$.setAttribute(name, value);
- return this;
- },
-
- removeProperty: function(name) {
- var key = properties[name], bool = key && bools[name];
- key = key && typeof key == 'function' ? key(this) : key;
- key ? this.$[key] = bool ? false : '' : this.$.removeAttribute(name);
- return this;
- },
-
- getProperties: function() {
- var props = {};
- for (var i = 0; i < arguments.length; i++)
- props[arguments[i]] = this.getProperty(arguments[i]);
- return props;
- },
-
- setProperties: function(src) {
- return Base.each(src, function(value, name) {
- this.setProperty(name, value);
- }, this);
- },
-
- removeProperties: function() {
- return Array.each(arguments, this.removeProperty, this);
- }
- };
-
- var inserters = {
- before: function(source, dest) {
- if (source && dest && dest.$.parentNode) {
- var text = Browser.TRIDENT && dest.$.text;
- if (text) dest.$.text = '';
- dest.$.parentNode.insertBefore(source.$, dest.$);
- if (text) dest.$.text = text;
- }
- },
-
- after: function(source, dest) {
- if (source && dest && dest.$.parentNode) {
- var next = dest.$.nextSibling;
- if (next) source.insertBefore(next);
- else dest.getParent().appendChild(source);
- }
- },
-
- bottom: function(source, dest) {
- if (source && dest)
- dest.appendChild(source);
- },
-
- top: function(source, dest) {
- if (source && dest) {
- var first = dest.$.firstChild;
- if (first) source.insertBefore(first);
- else dest.appendChild(source);
- }
- }
- };
-
- inserters.inside = inserters.bottom;
-
- Base.each(inserters, function(inserter, name) {
- var part = name.capitalize();
- fields['insert' + part] = function(el) {
- el = toNodes.apply(this, arguments);
- for (var i = 0, list = el.array, l = list.length; i < l; i++)
- inserter(i == 0 ? this : this.clone(true), list[i]);
- return el.result || this;
- }
-
- fields['inject' + part] = function(el) {
- el = toNodes.apply(this, arguments);
- for (var i = 0, list = el.array, l = list.length; i < l; i++)
- inserter(list[i], this);
- return el.result || this;
- }
- });
-
- return fields;
-});
-
-DomElements = DomNodes.extend();
-
-DomElement = DomNode.extend({
- _type: 'element',
- _collection: DomElements,
-
- statics: {
- get: function(selector, root) {
- return (root && DomNode.wrap(root) || Browser.document).getElement(selector);
- },
-
- getAll: function(selector, root) {
- return (root && DomNode.wrap(root) || Browser.document).getElements(selector);
- },
-
- create: function(tag, props, doc) {
- if (Browser.TRIDENT && props) {
- ['name', 'type', 'checked'].each(function(key) {
- if (props[key]) {
- tag += ' ' + key + '="' + props[key] + '"';
- if (key != 'checked')
- delete props[key];
- }
- });
- tag = '<' + tag + '>';
- }
- return (DomElement.unwrap(doc) || document).createElement(tag);
- },
-
- isAncestor: function(el, parent) {
- return !el ? false : el.ownerDocument == parent ? true
- : Browser.WEBKIT && Browser.VERSION < 420
- ? Array.contains(parent.getElementsByTagName(el.tagName), el)
- : parent.contains
- ? parent != el && parent.contains(el)
- : !!(parent.compareDocumentPosition(el) & 16)
- }
- }
-});
-
-DomElement.inject(new function() {
- function walk(el, walk, start, match, all) {
- var elements = all && new el._collection();
- el = el.$[start || walk];
- while (el) {
- if (el.nodeType == 1 && (!match || DomElement.match(el, match))) {
- if (!all) return DomNode.wrap(el);
- elements.push(el);
- }
- el = el[walk];
- }
- return elements;
- }
-
- return {
- _properties: ['id'],
-
- getTag: function() {
- return (this.$.tagName || '').toLowerCase();
- },
-
- getPrevious: function(match) {
- return walk(this, 'previousSibling', null, match);
- },
-
- getAllPrevious: function(match) {
- return walk(this, 'previousSibling', null, match, true);
- },
-
- getNext: function(match) {
- return walk(this, 'nextSibling', null, match);
- },
-
- getAllNext: function(match) {
- return walk(this, 'nextSibling', null, match, true);
- },
-
- getFirst: function(match) {
- return walk(this, 'nextSibling', 'firstChild', match);
- },
-
- getLast: function(match) {
- return walk(this, 'previousSibling', 'lastChild', match);
- },
-
- hasChild: function(match) {
- return DomNode.isNode(match)
- ? DomElement.isAncestor(DomElement.unwrap(match), this.$)
- : !!this.getFirst(match);
- },
-
- getParent: function(match) {
- return walk(this, 'parentNode', null, match);
- },
-
- getParents: function(match) {
- return walk(this, 'parentNode', null, match, true);
- },
-
- hasParent: function(match) {
- return DomNode.isNode(match)
- ? DomElement.isAncestor(this.$, DomElement.unwrap(match))
- : !!this.getParent(match);
- },
-
- getChildren: function(match) {
- return walk(this, 'nextSibling', 'firstChild', match, true);
- },
-
- hasChildren: function(match) {
- return !!this.getChildren(match).length;
- },
-
- toString: function() {
- return (this.$.tagName || this._type).toLowerCase() +
- (this.$.id ? '#' + this.$.id : '');
- },
-
- toNode: function() {
- return this;
- }
- };
-});
-
-$ = DomElement.get;
-$$ = DomElement.getAll;
-
-DomTextNode = DomNode.extend({
- _type: 'textnode'
-});
-
-DomDocument = DomElement.extend({
- _type: 'document',
-
- initialize: function() {
- if (Browser.TRIDENT && Browser.VERSION < 7)
- try {
- this.$.execCommand('BackgroundImageCache', false, true);
- } catch (e) {}
- },
-
- createElement: function(tag, props) {
- return DomNode.wrap(DomElement.create(tag, props, this.$)).set(props);
- },
-
- createTextNode: function(text) {
- return $(this.$.createTextNode(text));
- },
-
- getDocument: function() {
- return this;
- },
-
- getWindow: function() {
- return DomNode.wrap(this.$.defaultView || this.$.parentWindow);
- },
-
- open: function() {
- this.$.open();
- },
-
- close: function() {
- this.$.close();
- },
-
- write: function(markup) {
- this.$.write(markup);
- },
-
- writeln: function(markup) {
- this.$.writeln(markup);
- }
-});
-
-Window = DomWindow = DomElement.extend({
- _type: 'window',
- _initialize: false,
- _methods: ['close', 'alert', 'prompt', 'confirm', 'blur', 'focus', 'reload'],
-
- getDocument: function() {
- return DomNode.wrap(this.$.document);
- },
-
- getWindow: function() {
- return this;
- },
-
- initialize: function(param) {
- var win;
- if (param.location && param.frames && param.history) {
- win = this.base(param) || this;
- } else {
- if (typeof param == 'string')
- param = { url: param };
- (['toolbar','menubar','location','status','resizable','scrollbars']).each(function(key) {
- param[key] = param[key] ? 1 : 0;
- });
- if (param.width && param.height) {
- if (param.left == null) param.left = Math.round(
- Math.max(0, (screen.width - param.width) / 2));
- if (param.top == null) param.top = Math.round(
- Math.max(0, (screen.height - param.height) / 2 - 40));
- }
- var str = Base.each(param, function(val, key) {
- if (!/^(focus|confirm|url|name)$/.test(key))
- this.push(key + '=' + (val + 0));
- }, []).join();
- win = this.base(window.open(param.url, param.name.replace(/\s+|\.+|-+/gi, ''), str)) || this;
- if (win && param.focus)
- win.focus();
- }
- return ['location', 'frames', 'history'].each(function(key) {
- this[key] = this.$[key];
- }, win);
- }
-});
-
-DomElement.inject(new function() {
- function cumulate(name, parent, iter) {
- var left = name + 'Left', top = name + 'Top';
- return function(that) {
- var cur, next = that, x = 0, y = 0;
- do {
- cur = next;
- x += cur.$[left] || 0;
- y += cur.$[top] || 0;
- } while((next = DomNode.wrap(cur.$[parent])) && (!iter || iter(cur, next)))
- return { x: x, y: y };
- }
- }
-
- function setBounds(fields, offset) {
- return function(values) {
- var vals = /^(object|array)$/.test(Base.type(values)) ? values : arguments;
- if (offset) {
- if (vals.x) vals.left = vals.x;
- if (vals.y) vals.top = vals.y;
- }
- var i = 0;
- return fields.each(function(name) {
- var val = vals.length ? vals[i++] : vals[name];
- if (val != null) this.setStyle(name, val);
- }, this);
- }
- }
-
- function isBody(that) {
- return that.getTag() == 'body';
- }
-
- var getAbsolute = cumulate('offset', 'offsetParent', Browser.WEBKIT ? function(cur, next) {
- return next.$ != document.body || cur.getStyle('position') != 'absolute';
- } : null, true);
-
- var getPositioned = cumulate('offset', 'offsetParent', function(cur, next) {
- return next.$ != document.body && !/^(relative|absolute)$/.test(next.getStyle('position'));
- });
-
- var getScrollOffset = cumulate('scroll', 'parentNode');
-
- var fields = {
-
- getSize: function() {
- return isBody(this)
- ? this.getWindow().getSize()
- : { width: this.$.offsetWidth, height: this.$.offsetHeight };
- },
-
- getOffset: function(relative, scroll) {
- if (isBody(this))
- return this.getWindow().getOffset();
- if (relative && !DomNode.isNode(relative))
- return getPositioned(this);
- var off = getAbsolute(this);
- if (relative) {
- var rel = getAbsolute(DomNode.wrap(relative));
- off = { x: off.x - rel.x, y: off.y - rel.y };
- }
- if (scroll) {
- scroll = this.getScrollOffset();
- off.x -= scroll.x;
- off.y -= scroll.y;
- }
- return off;
- },
-
- getScrollOffset: function() {
- return isBody(this)
- ? this.getWindow().getScrollOffset()
- : getScrollOffset(this);
- },
-
- getScrollSize: function() {
- return isBody(this)
- ? this.getWindow().getScrollSize()
- : { width: this.$.scrollWidth, height: this.$.scrollHeight };
- },
-
- getBounds: function(relative, scroll) {
- if (isBody(this))
- return this.getWindow().getBounds();
- var off = this.getOffset(relative, scroll),
- el = this.$;
- return {
- left: off.x,
- top: off.y,
- right: off.x + el.offsetWidth,
- bottom: off.y + el.offsetHeight,
- width: el.offsetWidth,
- height: el.offsetHeight
- };
- },
-
- setBounds: setBounds(['left', 'top', 'width', 'height', 'clip'], true),
-
- setOffset: setBounds(['left', 'top'], true),
-
- setSize: setBounds(['width', 'height', 'clip']),
-
- setScrollOffset: function(x, y) {
- if (isBody(this)) {
- this.getWindow().setScrollOffset(x, y);
- } else {
- var off = typeof x == 'object' ? x : { x: x, y: y };
- this.$.scrollLeft = off.x;
- this.$.scrollTop = off.y;
- }
- return this;
- },
-
- scrollTo: function(x, y) {
- return this.setScrollOffset(x, y);
- },
-
- contains: function(pos) {
- var bounds = this.getBounds();
- return pos.x >= bounds.left && pos.x < bounds.right &&
- pos.y >= bounds.top && pos.y < bounds.bottom;
- },
-
- isVisible: function(fully) {
- var win = this.getWindow(), top = win.getScrollOffset().y,
- bottom = top + win.getSize().height,
- bounds = this.getBounds(false, true);
- return (bounds.height > 0 || bounds.width > 0)
- && (bounds.top >= top && bounds.bottom <= bottom
- || (fully && bounds.top <= top && bounds.bottom >= bottom)
- || !fully && (bounds.top <= top && bounds.bottom >= top
- || bounds.top <= bottom && bounds.bottom >= bottom));
- }
- };
-
- ['left', 'top', 'right', 'bottom', 'width', 'height'].each(function(name) {
- var part = name.capitalize();
- fields['get' + part] = function() {
- return this.$['offset' + part];
- };
- fields['set' + part] = function(value) {
- this.$.style[name] = isNaN(value) ? value : value + 'px';
- };
- });
-
- return fields;
-});
-
-[DomDocument, DomWindow].each(function(ctor) {
- ctor.inject(this);
-}, {
-
- getSize: function() {
- if (Browser.PRESTO || Browser.WEBKIT) {
- var win = this.getWindow().$;
- return { width: win.innerWidth, height: win.innerHeight };
- }
- var doc = this.getCompatElement();
- return { width: doc.clientWidth, height: doc.clientHeight };
- },
-
- getScrollOffset: function() {
- var win = this.getWindow().$, doc = this.getCompatElement();
- return { x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop };
- },
-
- getScrollSize: function() {
- var doc = this.getCompatElement(), min = this.getSize();
- return { width: Math.max(doc.scrollWidth, min.width), height: Math.max(doc.scrollHeight, min.height) };
- },
-
- getOffset: function() {
- return { x: 0, y: 0 };
- },
-
- getBounds: function() {
- var size = this.getSize();
- return {
- left: 0, top: 0,
- right: size.width, bottom: size.height,
- width: size.width, height: size.height
- };
- },
-
- setScrollOffset: function(x, y) {
- var off = typeof x == 'object' ? x : { x: x, y: y };
- this.getWindow().$.scrollTo(off.x, off.y);
- return this;
- },
-
- getElementAt: function(pos, exclude) {
- var el = this.getDocument().getElement('body');
- while (true) {
- var max = -1;
- var ch = el.getFirst();
- while (ch) {
- if (ch.contains(pos) && ch != exclude) {
- var z = ch.$.style.zIndex.toInt() || 0;
- if (z >= max) {
- el = ch;
- max = z;
- }
- }
- ch = ch.getNext();
- }
- if (max < 0) break;
- }
- return el;
- },
-
- getCompatElement: function() {
- var doc = this.getDocument();
- return doc.getElement(!doc.$.compatMode
- || doc.$.compatMode == 'CSS1Compat' ? 'html' : 'body').$;
- }
-});
-
-DomEvent = Base.extend(new function() {
- var keys = {
- '8': 'backspace',
- '13': 'enter',
- '27': 'escape',
- '32': 'space',
- '37': 'left',
- '38': 'up',
- '39': 'right',
- '40': 'down',
- '46': 'delete'
- };
-
- function hover(name, type) {
- return {
- type: type,
- listener: function(event) {
- if (event.relatedTarget != this && !this.hasChild(event.relatedTarget))
- this.fireEvent(name, [event]);
- }
- }
- }
-
- return {
- initialize: function(event) {
- this.event = event = event || window.event;
- this.type = event.type;
- this.target = DomNode.wrap(event.target || event.srcElement);
- if (this.target && this.target.$.nodeType == 3)
- this.target = this.target.getParentNode();
- this.shift = event.shiftKey;
- this.control = event.ctrlKey;
- this.alt = event.altKey;
- this.meta = event.metaKey;
- if (/^(mousewheel|DOMMouseScroll)$/.test(this.type)) {
- this.wheel = event.wheelDelta ?
- event.wheelDelta / (window.opera ? -120 : 120) :
- - (event.detail || 0) / 3;
- } else if (/^key/.test(this.type)) {
- this.code = event.which || event.keyCode;
- this.key = keys[this.code] || String.fromCharCode(this.code).toLowerCase();
- } else if (/^mouse|^click$/.test(this.type)) {
- this.page = {
- x: event.pageX || event.clientX + document.documentElement.scrollLeft,
- y: event.pageY || event.clientY + document.documentElement.scrollTop
- };
- this.client = {
- x: event.pageX ? event.pageX - window.pageXOffset : event.clientX,
- y: event.pageY ? event.pageY - window.pageYOffset : event.clientY
- };
- var offset = this.target.getOffset();
- this.offset = {
- x: this.page.x - offset.x,
- y: this.page.y - offset.y
- }
- this.rightClick = event.which == 3 || event.button == 2;
- if (/^mouse(over|out)$/.test(this.type))
- this.relatedTarget = DomNode.wrap(event.relatedTarget ||
- this.type == 'mouseout' ? event.toElement : event.fromElement);
- }
- },
-
- stop: function() {
- this.stopPropagation();
- this.preventDefault();
- return this;
- },
-
- stopPropagation: function() {
- if (this.event.stopPropagation) this.event.stopPropagation();
- else this.event.cancelBubble = true;
- this.stopped = true;
- return this;
- },
-
- preventDefault: function() {
- if (this.event.preventDefault) this.event.preventDefault();
- else this.event.returnValue = false;
- return this;
- },
-
- statics: {
- events: new Hash({
- mouseenter: hover('mouseenter', 'mouseover'),
-
- mouseleave: hover('mouseleave', 'mouseout'),
-
- mousewheel: { type: Browser.GECKO ? 'DOMMouseScroll' : 'mousewheel' },
-
- domready: function(func) {
- var win = this.getWindow(), doc = this.getDocument();
- if (Browser.loaded) {
- func.call(this);
- } else if (!doc.onDomReady) {
- doc.onDomReady = function() {
- if (!Browser.loaded) {
- Browser.loaded = true;
- doc.fireEvent('domready');
- win.fireEvent('domready');
- }
- }
- if (Browser.TRIDENT) {
- var temp = doc.createElement('div');
- (function() {
- try {
- temp.$.doScroll('left');
- temp.insertBottom(DomElement.get('body')).setHtml('temp').remove();
- doc.onDomReady();
- } catch (e) {
- arguments.callee.delay(50);
- }
- }).delay(0);
- } else if (Browser.WEBKIT && Browser.VERSION < 525) {
- (function() {
- /^(loaded|complete)$/.test(doc.$.readyState)
- ? doc.onDomReady() : arguments.callee.delay(50);
- })();
- } else {
- win.addEvent('load', doc.onDomReady);
- doc.addEvent('DOMContentLoaded', doc.onDomReady);
- }
- }
- }
- }),
-
- add: function(events) {
- this.events.append(events);
- }
- }
- };
-});
-
-DomElement.inject(new function() {
- function callEvent(fire) {
- return function(type, args, delay) {
- var entries = (this.events || {})[type];
- if (entries) {
- var event = args && args[0];
- if (event)
- args[0] = event.event ? event : new DomEvent(event);
- entries.each(function(entry) {
- entry[fire ? 'func' : 'bound'].delay(delay, this, args);
- }, this);
- }
- return !!entries;
- }
- }
-
- return {
- addEvent: function(type, func) {
- this.events = this.events || {};
- var entries = this.events[type] = this.events[type] || [];
- if (func && !entries.find(function(entry) { return entry.func == func })) {
- var listener = func, name = type, pseudo = DomEvent.events[type];
- if (pseudo) {
- if (typeof pseudo == 'function') pseudo = pseudo.call(this, func);
- listener = pseudo && pseudo.listener || listener;
- name = pseudo && pseudo.type;
- }
- var that = this, bound = function(event) {
- if (event || window.event)
- event = event && event.event ? event : new DomEvent(event);
- if (listener.call(that, event) === false && event)
- event.stop();
- };
- if (name) {
- if (this.$.addEventListener) {
- this.$.addEventListener(name, bound, false);
- } else if (this.$.attachEvent) {
- this.$.attachEvent('on' + name, bound);
- }
- }
- entries.push({ func: func, name: name, bound: bound });
- }
- return this;
- },
-
- removeEvent: function(type, func) {
- var entries = (this.events || {})[type], entry;
- if (func && entries) {
- if (entry = entries.remove(function(entry) { return entry.func == func })) {
- var name = entry.name, pseudo = DomEvent.events[type];
- if (pseudo && pseudo.remove) pseudo.remove.call(this, func);
- if (name) {
- if (this.$.removeEventListener) {
- this.$.removeEventListener(name, entry.bound, false);
- } else if (this.$.detachEvent) {
- this.$.detachEvent('on' + name, entry.bound);
- }
- }
- }
- }
- return this;
- },
-
- addEvents: function(events) {
- return Base.each(events || [], function(fn, type) {
- this.addEvent(type, fn);
- }, this);
- },
-
- removeEvents: function(type) {
- if (this.events) {
- if (type) {
- (this.events[type] || []).each(function(fn) {
- this.removeEvent(type, fn);
- }, this);
- delete this.events[type];
- } else {
- Base.each(this.events, function(ev, type) {
- this.removeEvents(type);
- }, this);
- this.events = null;
- }
- }
- return this;
- },
-
- fireEvent: callEvent(true),
-
- triggerEvent: callEvent(false),
-
- finalize: function() {
- this.removeEvents();
- }
- };
-});
-
-DomEvent.add(new function() {
- var object, last;
-
- function dragStart(event) {
- if (object != this) {
- event.type = 'dragstart';
- last = event.page;
- this.fireEvent('dragstart', [event]);
- if (!event.stopped) {
- event.stop();
- var doc = this.getDocument();
- doc.addEvent('mousemove', drag);
- doc.addEvent('mouseup', dragEnd);
- object = this;
- }
- }
- }
-
- function drag(event) {
- event.type = 'drag';
- event.delta = {
- x: event.page.x - last.x,
- y: event.page.y - last.y
- }
- last = event.page;
- object.fireEvent('drag', [event]);
- event.preventDefault();
- }
-
- function dragEnd(event) {
- if (object) {
- event.type = 'dragend';
- object.fireEvent('dragend', [event]);
- event.preventDefault();
- var doc = object.getDocument();
- doc.removeEvent('mousemove', drag);
- doc.removeEvent('mouseup', dragEnd);
- object = null;
- }
- }
-
- return {
- dragstart: {
- type: 'mousedown',
- listener: dragStart
- },
-
- drag: {
- type: 'mousedown',
- listener: dragStart
- },
-
- dragend: {}
- };
-});
-
-DomElement.inject(new function() {
- var XPATH= 0, FILTER = 1;
-
- var methods = [{
- getParam: function(items, separator, context, params) {
- var str = context.namespaceURI ? 'xhtml:' + params.tag : params.tag;
- if (separator && (separator = DomElement.separators[separator]))
- str = separator[XPATH] + str;
- for (var i = params.pseudos.length; i--;) {
- var pseudo = params.pseudos[i];
- str += pseudo.handler[XPATH](pseudo.argument);
- }
- if (params.id) str += '[@id="' + params.id + '"]';
- for (var i = params.classes.length; i--;)
- str += '[contains(concat(" ", @class, " "), " ' + params.classes[i] + ' ")]';
- for (var i = params.attributes.length; i--;) {
- var attribute = params.attributes[i];
- var operator = DomElement.operators[attribute[1]];
- if (operator) str += operator[XPATH](attribute[0], attribute[2]);
- else str += '[@' + attribute[0] + ']';
- }
- items.push(str);
- return items;
- },
-
- getElements: function(items, elements, context) {
- function resolver(prefix) {
- return prefix == 'xhtml' ? 'http://www.w3.org/1999/xhtml' : false;
- }
- var res = (context.ownerDocument || context).evaluate('.//' + items.join(''), context,
- resolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
- for (var i = 0, l = res.snapshotLength; i < l; i++)
- elements.push(res.snapshotItem(i));
- }
- }, {
- getParam: function(items, separator, context, params, data) {
- var found = [];
- var tag = params.tag;
- if (separator && (separator = DomElement.separators[separator])) {
- separator = separator[FILTER];
- var uniques = {};
- function add(item) {
- if (!item._unique)
- DomNode.unique(item);
- if (!uniques[item._unique] && match(item, params, data)) {
- uniques[item._unique] = true;
- found.push(item);
- return true;
- }
- }
- for (var i = 0, l = items.length; i < l; i++)
- separator(items[i], params, add);
- if (params.clearTag)
- params.tag = params.clearTag = null;
- return found;
- }
- if (params.id) {
- var el = (context.ownerDocument || context).getElementById(params.id);
- params.id = null;
- return el && DomElement.isAncestor(el, context)
- && match(el, params, data) ? [el] : null;
- } else {
- if (!items.length) {
- items = context.getElementsByTagName(tag);
- params.tag = null;
- }
- for (var i = 0, l = items.length; i < l; i++)
- if (match(items[i], params, data))
- found.push(items[i]);
- }
- return found;
- },
-
- getElements: function(items, elements, context) {
- elements.append(items);
- }
- }];
-
- function parse(selector) {
- var params = { tag: '*', id: null, classes: [], attributes: [], pseudos: [] };
- selector.replace(/:([^:(]+)*(?:\((["']?)(.*?)\2\))?|\[([\w-]+)(?:([!*^$~|]?=)(["']?)(.*?)\6)?\]|\.[\w-]+|#[\w-]+|\w+|\*/g, function(part) {
- switch (part.charAt(0)) {
- case '.': params.classes.push(part.slice(1)); break;
- case '#': params.id = part.slice(1); break;
- case '[': params.attributes.push([arguments[4], arguments[5], arguments[7]]); break;
- case ':':
- var handler = DomElement.pseudos[arguments[1]];
- if (!handler) {
- params.attributes.push([arguments[1], arguments[3] ? '=' : '', arguments[3]]);
- break;
- }
- params.pseudos.push({
- name: arguments[1],
- argument: handler && handler.parser
- ? (handler.parser.apply ? handler.parser(arguments[3]) : handler.parser)
- : arguments[3],
- handler: handler.handler || handler
- });
- break;
- default: params.tag = part;
- }
- return '';
- });
- return params;
- }
-
- function match(el, params, data) {
- if (params.id && params.id != el.id)
- return false;
-
- if (params.tag && params.tag != '*' && params.tag != (el.tagName || '').toLowerCase())
- return false;
-
- for (var i = params.classes.length; i--;)
- if (!el.className || !el.className.contains(params.classes[i], ' '))
- return false;
-
- var proto = DomElement.prototype;
- for (var i = params.attributes.length; i--;) {
- var attribute = params.attributes[i];
- proto.$ = el;
- var val = proto.getProperty(attribute[0]);
- if (!val) return false;
- var operator = DomElement.operators[attribute[1]];
- operator = operator && operator[FILTER];
- if (operator && (!val || !operator(val, attribute[2])))
- return false;
- }
-
- for (var i = params.pseudos.length; i--;) {
- var pseudo = params.pseudos[i];
- if (!pseudo.handler[FILTER](el, pseudo.argument, data))
- return false;
- }
-
- return true;
- }
-
- function filter(items, selector, context, elements, data) {
- var method = methods[!Browser.XPATH || items.length ||
- typeof selector == 'string' && selector.contains('option[')
- ? FILTER : XPATH];
- var separators = [];
- selector = selector.trim().replace(/\s*([+>~\s])[a-zA-Z#.*\s]/g, function(match) {
- if (match.charAt(2)) match = match.trim();
- separators.push(match.charAt(0));
- return ':)' + match.charAt(1);
- }).split(':)');
- for (var i = 0, l = selector.length; i < l; i++) {
- var params = parse(selector[i]);
- if (!params) return elements;
- var next = method.getParam(items, separators[i - 1], context, params, data);
- if (!next) break;
- items = next;
- }
- method.getElements(items, elements, context);
- return elements;
- }
-
- return {
-
- getElements: function(selectors, nowrap) {
- var elements = nowrap ? [] : new this._collection();
- selectors = !selectors ? ['*'] : typeof selectors == 'string'
- ? selectors.split(',')
- : selectors.length != null ? selectors : [selectors];
- for (var i = 0, l = selectors.length; i < l; i++) {
- var selector = selectors[i];
- if (Base.type(selector) == 'element') elements.push(selector);
- else filter([], selector, this.$, elements, {});
- }
- return elements;
- },
-
- getElement: function(selector) {
- var el, type = Base.type(selector), match;
- if (type == 'window') {
- el = selector;
- } else {
- if (type == 'string' && (match = selector.match(/^#?([\w-]+)$/)))
- el = this.getDocument().$.getElementById(match[1]);
- else if (DomNode.isNode(type))
- el = DomElement.unwrap(selector);
- if (el && el != this.$ && !DomElement.isAncestor(el, this.$))
- el = null;
- if (!el)
- el = this.getElements(selector, true)[0];
- }
- return DomNode.wrap(el);
- },
-
- hasElement: function(selector) {
- return !!this.getElement(selector);
- },
-
- match: function(selector) {
- return !selector || match(this.$, parse(selector), {});
- },
-
- filter: function(elements, selector) {
- return filter(elements, selector, this.$, new this._collection(), {});
- },
-
- statics: {
- match: function(el, selector) {
- return !selector || match(DomElement.unwrap(el), parse(selector), {});
- }
- }
- };
-});
-
-DomElement.separators = {
- '~': [
- '/following-sibling::',
- function(item, params, add) {
- while (item = item.nextSibling)
- if (item.nodeType == 1 && add(item))
- break;
- }
- ],
-
- '+': [
- '/following-sibling::*[1]/self::',
- function(item, params, add) {
- while (item = item.nextSibling) {
- if (item.nodeType == 1) {
- add(item);
- break;
- }
- }
- }
- ],
-
- '>': [
- '/',
- function(item, params, add) {
- var children = item.childNodes;
- for (var i = 0, l = children.length; i < l; i++)
- if (children[i].nodeType == 1)
- add(children[i]);
- }
- ],
-
- ' ': [
- '//',
- function(item, params, add) {
- var children = item.getElementsByTagName(params.tag);
- params.clearTag = true;
- for (var i = 0, l = children.length; i < l; i++)
- add(children[i]);
- }
- ]
-};
-
-DomElement.operators = new function() {
- function contains(sep) {
- return [
- function(a, v) {
- return '[contains(' + (sep ? 'concat("' + sep + '", @' + a + ', "' + sep + '")' : '@' + a) + ', "' + sep + v + sep + '")]';
- },
- function(a, v) {
- return a.contains(v, sep);
- }
- ]
- }
-
- return {
- '=': [
- function(a, v) {
- return '[@' + a + '="' + v + '"]';
- },
- function(a, v) {
- return a == v;
- }
- ],
-
- '^=': [
- function(a, v) {
- return '[starts-with(@' + a + ', "' + v + '")]';
- },
- function(a, v) {
- return a.substring(0, v.length) == v;
- }
- ],
-
- '$=': [
- function(a, v) {
- return '[substring(@' + a + ', string-length(@' + a + ') - ' + v.length + ' + 1) = "' + v + '"]';
- },
- function(a, v) {
- return a.substring(a.length - v.length) == v;
- }
- ],
-
- '!=': [
- function(a, v) {
- return '[@' + a + '!="' + v + '"]';
- },
- function(a, v) {
- return a != v;
- }
- ],
-
- '*=': contains(''),
-
- '|=': contains('-'),
-
- '~=': contains(' ')
- };
-};
-
-DomElement.pseudos = new function() {
- var nthChild = [
- function(argument) {
- switch (argument.special) {
- case 'n': return '[count(preceding-sibling::*) mod ' + argument.a + ' = ' + argument.b + ']';
- case 'first': return '[count(preceding-sibling::*) = 0]';
- case 'last': return '[count(following-sibling::*) = 0]';
- case 'only': return '[not(preceding-sibling::* or following-sibling::*)]';
- case 'index': return '[count(preceding-sibling::*) = ' + argument.a + ']';
- }
- },
- function(el, argument, data) {
- var count = 0;
- switch (argument.special) {
- case 'n':
- data.indices = data.indices || {};
- if (!data.indices[el._unique]) {
- var children = el.parentNode.childNodes;
- for (var i = 0, l = children.length; i < l; i++) {
- var child = children[i];
- if (child.nodeType == 1) {
- if (!child._unique)
- DomNode.unique(item);
- data.indices[child._unique] = count++;
- }
- }
- }
- return data.indices[el._unique] % argument.a == argument.b;
- case 'first':
- while (el = el.previousSibling)
- if (el.nodeType == 1)
- return false;
- return true;
- case 'last':
- while (el = el.nextSibling)
- if (el.nodeType == 1)
- return false;
- return true;
- case 'only':
- var prev = el;
- while(prev = prev.previousSibling)
- if (prev.nodeType == 1)
- return false;
- var next = el;
- while (next = next.nextSibling)
- if (next.nodeType == 1)
- return false;
- return true;
- case 'index':
- while (el = el.previousSibling)
- if (el.nodeType == 1 && ++count > argument.a)
- return false;
- return true;
- }
- return false;
- }
- ];
-
- function contains(caseless) {
- var abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
- return [
- function(argument) {
- return '[contains(' + (caseless ? 'translate(text(), "' + abc
- + '", "' + abc.toLowerCase() + '")' : 'text()') + ', "'
- + (caseless && argument ? argument.toLowerCase() : argument) + '")]';
- },
- function(el, argument) {
- if (caseless && argument) argument = argument.toLowerCase();
- var nodes = el.childNodes;
- for (var i = nodes.length - 1; i >= 0; i--) {
- var child = nodes[i];
- if (child.nodeName && child.nodeType == 3 &&
- (caseless ? child.nodeValue.toLowerCase() : child.nodeValue).contains(argument))
- return true;
- }
- return false;
- }
- ];
- }
-
- return {
- 'nth-child': {
- parser: function(argument) {
- var match = argument ? argument.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/) : [null, 1, 'n', 0];
- if (!match) return null;
- var i = parseInt(match[1]),
- a = isNaN(i) ? 1 : i,
- special = match[2],
- b = parseInt(match[3]) || 0;
- if (a != 0) {
- b--;
- while (b < 1) b += a;
- while (b >= a) b -= a;
- } else {
- a = b;
- special = 'index';
- }
- switch (special) {
- case 'n': return { a: a, b: b, special: 'n' };
- case 'odd': return { a: 2, b: 0, special: 'n' };
- case 'even': return { a: 2, b: 1, special: 'n' };
- case 'first': return { special: 'first' };
- case 'last': return { special: 'last' };
- case 'only': return { special: 'only' };
- default: return { a: a - 1, special: 'index' };
- }
- },
- handler: nthChild
- },
-
- 'even': {
- parser: { a: 2, b: 1, special: 'n' },
- handler: nthChild
- },
-
- 'odd': {
- parser: { a: 2, b: 0, special: 'n' },
- handler: nthChild
- },
-
- 'first-child': {
- parser: { special: 'first' },
- handler: nthChild
- },
-
- 'last-child': {
- parser: { special: 'last' },
- handler: nthChild
- },
-
- 'only-child': {
- parser: { special: 'only' },
- handler: nthChild
- },
-
- 'enabled': [
- function() {
- return '[not(@disabled)]';
- },
- function(el) {
- return !el.disabled;
- }
- ],
-
- 'empty': [
- function() {
- return '[not(node())]';
- },
- function(el) {
- return !(el.innerText || el.textContent || '').length;
- }
- ],
-
- 'contains': contains(false),
-
- 'contains-caseless': contains(true)
- };
-};
-
-HtmlElements = DomElements.extend();
-
-HtmlElement = DomElement.extend({
- _collection: HtmlElements
-});
-
-HtmlElement.inject({
- _properties: ['html'],
-
- getClass: function() {
- return this.$.className;
- },
-
- setClass: function(cls) {
- this.$.className = cls;
- },
-
- modifyClass: function(name, add) {
- if (!this.hasClass(name) ^ !add)
- this.$.className = (add ? this.$.className + ' ' + name :
- this.$.className.replace(name, '')).clean();
- return this;
- },
-
- addClass: function(name) {
- return this.modifyClass(name, true);
- },
-
- removeClass: function(name) {
- return this.modifyClass(name, false);
- },
-
- toggleClass: function(name) {
- return this.modifyClass(name, !this.hasClass(name));
- },
-
- hasClass: function(name) {
- return this.$.className.contains(name, ' ');
- }
-});
-
-Array.inject({
- toNode: function(doc) {
- doc = DomNode.wrap(doc || document);
- var elements = new HtmlElements();
- for (var i = 0; i < this.length;) {
- var value = this[i++], element = null, type = Base.type(value);
- if (type == 'string') {
- var props = /^(object|hash)$/.test(Base.type(this[i])) && this[i++];
- element = value.isHtml()
- ? value.toNode(doc).set(props)
- : doc.createElement(value, props);
- if (Base.type(this[i]) == 'array')
- element.injectBottom(this[i++].toNode(doc));
- } else if (DomNode.isNode(type)) {
- element = value;
- } else if (value && value.toNode) {
- element = value.toNode(doc);
- }
- if (element)
- elements[Base.type(element) == 'array' ? 'append' : 'push'](element);
- }
- return elements.length == 1 ? elements[0] : elements;
- }
-});
-
-String.inject({
- toNode: function(doc) {
- var doc = doc || document, elements;
- if (this.isHtml()) {
- var str = this.trim().toLowerCase();
- var div = DomElement.unwrap(doc).createElement('div');
-
- var wrap =
- !str.indexOf('
', ''] ||
- !str.indexOf('', ''] ||
- (!str.indexOf('', ''] ||
- !str.indexOf('
', ''] ||
- (!str.indexOf(' | ', '
'] ||
- !str.indexOf('', ''] ||
- [0,'',''];
-
- div.innerHTML = wrap[1] + this + wrap[2];
- while (wrap[0]--)
- div = div.firstChild;
- if (Browser.TRIDENT) {
- var els = [];
- if (!str.indexOf('' && str.indexOf('= 0 ; --i) {
- var el = els[i];
- if (el.nodeName.toLowerCase() == 'tbody' && !el.childNodes.length)
- el.parentNode.removeChild(el);
- }
- }
- elements = new HtmlElements(div.childNodes);
- } else {
- elements = DomNode.wrap(doc).getElements(this);
- }
- return elements.length == 1 ? elements[0] : elements;
- }
-});
-
-HtmlDocument = DomDocument.extend({
- _collection: HtmlElements
-});
-
-HtmlElement.inject(new function() {
- var styles = {
- all: {
- width: '@px', height: '@px', left: '@px', top: '@px', right: '@px', bottom: '@px',
- color: 'rgb(@, @, @)', backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px',
- fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', textIndent: '@px',
- margin: '@px @px @px @px', padding: '@px @px @px @px',
- border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
- borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @',
- borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
- clip: 'rect(@px, @px, @px, @px)', opacity: '@'
- },
- part: {
- 'border': {}, 'borderWidth': {}, 'borderStyle': {}, 'borderColor': {},
- 'margin': {}, 'padding': {}
- }
- };
-
- ['Top', 'Right', 'Bottom', 'Left'].each(function(dir) {
- ['margin', 'padding'].each(function(style) {
- var sd = style + dir;
- styles.part[style][sd] = styles.all[sd] = '@px';
- });
- var bd = 'border' + dir;
- styles.part.border[bd] = styles.all[bd] = '@px @ rgb(@, @, @)';
- var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
- styles.part[bd] = {};
- styles.part.borderWidth[bdw] = styles.part[bd][bdw] = '@px';
- styles.part.borderStyle[bds] = styles.part[bd][bds] = '@';
- styles.part.borderColor[bdc] = styles.part[bd][bdc] = 'rgb(@, @, @)';
- });
-
- Base.each(styles.all, function(val, name) {
- this[name] = val.split(' ');
- });
-
- var fields = {
-
- getComputedStyle: function(name) {
- if (this.$.currentStyle) return this.$.currentStyle[name.camelize()];
- var style = this.getWindow().$.getComputedStyle(this.$, null);
- return style ? style.getPropertyValue(name.hyphenate()) : null;
- },
-
- getStyle: function(name) {
- if (name === undefined) return this.getStyles();
- if (name == 'opacity') {
- var op = this.opacity;
- return op || op == 0 ? op : this.getVisibility() ? 1 : 0;
- }
- var el = this.$;
- name = name.camelize();
- var style = el.style[name];
- if (!Base.check(style)) {
- if (styles.part[name]) {
- style = Hash.map(styles.part[name], function(val, key) {
- return this.getStyle(key);
- }, this);
- return style.every(function(val) {
- return val == style[0];
- }) ? style[0] : style.join(' ');
- }
- style = this.getComputedStyle(name);
- }
- if (name == 'visibility')
- return /^(visible|inherit(|ed))$/.test(style);
- var color = style && style.match(/rgb[a]?\([\d\s,]+\)/);
- if (color) return style.replace(color[0], color[0].rgbToHex());
- if (Browser.PRESTO || Browser.TRIDENT && isNaN(parseInt(style))) {
- if (/^(width|height)$/.test(name)) {
- var size = 0;
- (name == 'width' ? ['left', 'right'] : ['top', 'bottom']).each(function(val) {
- size += this.getStyle('border-' + val + '-width').toInt() + this.getStyle('padding-' + val).toInt();
- }, this);
- return this.$['offset' + name.capitalize()] - size + 'px';
- }
- if (Browser.PRESTO && /px/.test(style)) return style;
- if (/border(.+)[wW]idth|margin|padding/.test(name)) return '0px';
- }
- return style;
- },
-
- setStyle: function(name, value) {
- if (value === undefined) return this.setStyles(name);
- var el = this.$;
- switch (name) {
- case 'float':
- name = Browser.TRIDENT ? 'styleFloat' : 'cssFloat';
- break;
- case 'clip':
- if (value == true)
- value = [0, el.offsetWidth, el.offsetHeight, 0];
- break;
- default:
- name = name.camelize();
- }
- var type = Base.type(value);
- if (value != undefined && type != 'string') {
- var parts = styles.all[name] || ['@'], index = 0;
- value = (type == 'array' ? value.flatten() : [value]).map(function(val) {
- var part = parts[index++];
- if (!part)
- throw Base.stop;
- return Base.type(val) == 'number' ? part.replace('@', name == 'opacity' ? val : Math.round(val)) : val;
- }).join(' ');
- }
- switch (name) {
- case 'visibility':
- if (!isNaN(value)) value = !!value.toInt() + '';
- value = value == 'true' && 'visible' || value == 'false' && 'hidden' || value;
- break;
- case 'opacity':
- this.opacity = value = parseFloat(value);
- this.setStyle('visibility', !!value);
- if (!value) value = 1;
- if (!el.currentStyle || !el.currentStyle.hasLayout) el.style.zoom = 1;
- if (Browser.TRIDENT) el.style.filter = value > 0 && value < 1 ? 'alpha(opacity=' + value * 100 + ')' : '';
- el.style.opacity = value;
- return this;
- }
- el.style[name] = value;
- return this;
- },
-
- getStyles: function() {
- return arguments.length ? Array.each(arguments, function(name) {
- this[name] = that.getStyle(name);
- }, {}) : this.$.style.cssText;
- },
-
- setStyles: function(styles) {
- switch (Base.type(styles)) {
- case 'object':
- Base.each(styles, function(style, name) {
- if (style !== undefined)
- this.setStyle(name, style);
- }, this);
- break;
- case 'string':
- this.$.style.cssText = styles;
- }
- return this;
- }
- };
-
- ['opacity', 'color', 'background', 'visibility', 'clip', 'zIndex',
- 'border', 'margin', 'padding', 'display'].each(function(name) {
- var part = name.capitalize();
- fields['get' + part] = function() {
- return this.getStyle(name);
- };
- fields['set' + part] = function(value) {
- return this.setStyle(name, arguments.length > 1
- ? Array.create(arguments) : value);
- };
- });
-
- return fields;
-});
-
-HtmlElement.inject({
-
- getFormElements: function() {
- return this.getElements(['input', 'select', 'textarea']);
- },
-
- getValue: function(name) {
- var el = this.getElement(name);
- return el && el.getValue && el.getValue();
- },
-
- setValue: function(name, val) {
- var el = this.getElement(name);
- if (!el) el = this.injectTop('input', { type: 'hidden', id: name, name: name });
- return el.setValue(val);
- },
-
- getValues: function() {
- return this.getFormElements().each(function(el) {
- var name = el.getName(), value = el.getValue();
- if (name && value !== undefined && !el.getDisabled())
- this[name] = value;
- }, new Hash());
- },
-
- setValues: function(values) {
- return Base.each(values, function(val, name) {
- this.setValue(name, val);
- }, this);
- },
-
- toQueryString: function() {
- return Base.toQueryString(this.getValues());
- }
-});
-
-HtmlForm = HtmlElement.extend({
- _tag: 'form',
- _properties: ['action', 'method', 'target'],
- _methods: ['submit'],
-
- blur: function() {
- return this.getFormElements().each(function(el) {
- el.blur();
- }, this);
- },
-
- enable: function(enable) {
- return this.getFormElements().each(function(el) {
- el.enable(enable);
- }, this);
- }
-});
-
-HtmlFormElement = HtmlElement.extend({
- _properties: ['name', 'disabled'],
- _methods: ['focus', 'blur'],
-
- enable: function(enable) {
- var disabled = !enable && enable !== undefined;
- if (disabled) this.$.blur();
- this.$.disabled = disabled;
- return this;
- }
-});
-
-HtmlInput = HtmlFormElement.extend({
- _tag: 'input',
- _properties: ['type', 'checked', 'defaultChecked', 'readOnly', 'maxLength'],
- _methods: ['click'],
-
- getValue: function() {
- if (this.$.checked && /^(checkbox|radio)$/.test(this.$.type) ||
- /^(hidden|text|password|button|search)$/.test(this.$.type))
- return this.$.value;
- },
-
- setValue: function(val) {
- if (/^(checkbox|radio)$/.test(this.$.type)) this.$.checked = this.$.value == val;
- else this.$.value = val != null ? val : '';
- return this;
- }
-});
-
-HtmlTextArea = HtmlFormElement.extend({
- _tag: 'textarea',
- _properties: ['value']
-});
-
-HtmlSelect = HtmlFormElement.extend({
- _tag: 'select',
- _properties: ['type', 'selectedIndex'],
-
- getOptions: function() {
- return this.getElements('option');
- },
-
- getSelected: function() {
- return this.getElements('option[selected]');
- },
-
- setSelected: function(values) {
- this.$.selectedIndex = -1;
- if (values) {
- Array.each(values.length != null ? values : [values], function(val) {
- val = DomElement.unwrap(val);
- if (val != null)
- this.getElements('option[value="' + (val.value || val) + '"]').setProperty('selected', true);
- }, this);
- }
- return this;
- },
-
- getValue: function() {
- return this.getSelected().getProperty('value');
- },
-
- setValue: function(values) {
- return this.setSelected(values);
- }
-});
-
-HtmlOption = HtmlFormElement.extend({
- _tag: 'option',
- _properties: ['text', 'value', 'selected', 'defaultSelected', 'index']
-});
-
-HtmlFormElement.inject({
- setSelection: function(start, end) {
- var sel = end == undefined ? start : { start: start, end: end };
- this.focus();
- if (this.$.setSelectionRange) {
- this.$.setSelectionRange(sel.start, sel.end);
- } else {
- var value = this.getValue();
- var len = value.substring(sel.start, sel.end).replace(/\r/g, '').length;
- var pos = value.substring(0, sel.start).replace(/\r/g, '').length;
- var range = this.$.createTextRange();
- range.collapse(true);
- range.moveEnd('character', pos + len);
- range.moveStart('character', pos);
- range.select();
- }
- return this;
- },
-
- getSelection: function() {
- if (this.$.selectionStart !== undefined) {
- return { start: this.$.selectionStart, end: this.$.selectionEnd };
- } else {
- this.focus();
- var pos = { start: 0, end: 0 };
- var range = this.getDocument().$.selection.createRange();
- var dup = range.duplicate();
- if (this.$.type == 'text') {
- pos.start = 0 - dup.moveStart('character', -100000);
- pos.end = pos.start + range.text.length;
- } else {
- var value = this.getValue();
- dup.moveToElementText(this.$);
- dup.setEndPoint('StartToEnd', range);
- pos.end = value.length - dup.text.length;
- dup.setEndPoint('StartToStart', range);
- pos.start = value.length - dup.text.length;
- }
- return pos;
- }
- },
-
- getSelectedText: function() {
- var range = this.getSelection();
- return this.getValue().substring(range.start, range.end);
- },
-
- replaceSelectedText: function(value, select) {
- var range = this.getSelection(), current = this.getValue();
- var top = this.$.scrollTop, height = this.$.scrollHeight;
- this.setValue(current.substring(0, range.start) + value + current.substring(range.end, current.length));
- if (top != null)
- this.$.scrollTop = top + this.$.scrollHeight - height;
- return select || select == undefined
- ? this.setSelection(range.start, range.start + value.length)
- : this.setCaret(range.start + value.length);
- },
-
- getCaret: function() {
- return this.getSelection().start;
- },
-
- setCaret: function(pos) {
- return this.setSelection(pos, pos);
- }
-});
-
-HtmlImage = HtmlElement.extend({
- _tag: 'img',
- _properties: ['src', 'alt', 'title']
-});
-
-$document = Browser.document = DomNode.wrap(document);
-$window = Browser.window = DomNode.wrap(window).addEvent('unload', DomNode.dispose);
-
-Chain = {
- chain: function(fn) {
- (this._chain = this._chain || []).push(fn);
- return this;
- },
-
- callChain: function() {
- if (this._chain && this._chain.length)
- this._chain.shift().apply(this, arguments);
- return this;
- },
-
- clearChain: function() {
- this._chain = [];
- return this;
- }
-};
-
-Callback = {
- addEvent: function(type, fn) {
- var ref = this.events = this.events || {};
- ref = ref[type] = ref[type] || [];
- if (!ref.find(function(val) { return val == fn })) ref.push(fn);
- return this;
- },
-
- addEvents: function(events) {
- return Base.each((events || []), function(fn, type) {
- this.addEvent(type, fn);
- }, this);
- },
-
- fireEvent: function(type, args, delay) {
- return (this.events && this.events[type] || []).each(function(fn) {
- fn.delay(delay, this, args);
- }, this);
- },
-
- removeEvent: function(type, fn) {
- if (this.events && this.events[type])
- this.events[type].remove(function(val) { return fn == val; });
- return this;
- },
-
- setOptions: function(opts) {
- return (this.options = Hash.create(this.options, opts)).each(function(val, i) {
- if (typeof val == 'function' && (i = i.match(/^on([A-Z]\w*)/)))
- this.addEvent(i[1].toLowerCase(), val);
- }, this);
- },
-
- statics: {
- inject: function() {
- var proto = this.prototype, options = proto.options;
- this.base.apply(this, arguments);
- if (proto.options != options)
- proto.options = Hash.merge({}, options, proto.options);
- return this;
- }
- }
-};
-
-Request = Base.extend(Chain, Callback, new function() {
- var unique = 0;
-
- function createRequest(that) {
- if (!that.transport)
- that.transport = window.XMLHttpRequest && new XMLHttpRequest()
- || Browser.TRIDENT && new ActiveXObject('Microsoft.XMLHTTP');
- }
-
- function createFrame(that) {
- var id = 'request_' + unique++, load = that.onFrameLoad.bind(that);
- var div = DomElement.get('body').injectBottom('div', {
- styles: {
- position: 'absolute', width: 0, height: 0, top: 0, marginLeft: '-10000px'
- }
- }, [
- 'iframe', {
- name: id, id: id, events: { load: load, readystatechange: load }
- }
- ]
- );
- that.frame = {
- id: id, div: div,
- iframe: window.frames[id] || document.getElementById(id),
- element: DomElement.get(id)
- };
- div.offsetWidth;
- }
-
- return {
- options: {
- headers: {
- 'X-Requested-With': 'XMLHttpRequest',
- 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
- },
- method: 'post',
- async: true,
- urlEncoded: true,
- encoding: 'utf-8',
- emulation: true,
- secure: false
- },
-
- initialize: function() {
- var params = Array.associate(arguments, { url: 'string', options: 'object', handler: 'function' });
- this.setOptions(params.options);
- if (params.handler)
- this.addEvent('complete', params.handler);
- if (this.options.update)
- this.options.type = 'html';
- this.headers = new Hash(this.options.headers);
- if (this.options.type == 'json') {
- this.setHeader('Accept', 'application/json');
- this.setHeader('X-Request', 'JSON');
- }
- if (this.options.urlEncoded && /^(post|put)$/.test(this.options.method)) {
- this.setHeader('Content-Type', 'application/x-www-form-urlencoded' +
- (this.options.encoding ? '; charset=' + this.options.encoding : ''));
- }
- this.headers.append(this.options.headers);
- },
-
- onStateChange: function() {
- if (this.transport.readyState == 4 && this.running) {
- this.running = false;
- this.status = 0;
- try {
- this.status = this.transport.status;
- delete this.transport.onreadystatechange;
- } catch (e) {}
- if (!this.status || this.status >= 200 && this.status < 300) {
- this.success(this.transport.responseText, this.transport.responseXML);
- } else {
- this.fireEvent('complete').fireEvent('failure');
- }
- }
- },
-
- onFrameLoad: function() {
- var frame = this.frame && this.frame.iframe, loc = frame && frame.location,
- doc = frame && (frame.contentDocument || frame.contentWindow || frame).document;
- if (this.running && frame && loc && (!loc.href || loc.href.indexOf(this.url) != -1)
- && /^(loaded|complete|undefined)$/.test(doc.readyState)) {
- this.running = false;
- var html = this.options.type == 'html', area = !html
- && doc.getElementsByTagName('textarea')[0];
- var text = doc && (area && area.value || doc.body
- && (html && doc.body.innerHTML || doc.body.textContent
- || doc.body.innerText)) || '';
- this.frame.element.setProperty('src', '');
- this.success(text);
- if (!this.options.link) {
- var div = this.frame.div;
- div.insertBottom(DomElement.get('body'));
- div.remove.delay(5000, div);
- this.frame = null;
- }
- }
- },
-
- success: function(text, xml) {
- var args;
- switch (this.options.type) {
- case 'html':
- var match = text.match(/]*>([\u0000-\uffff]*?)<\/body>/i);
- var stripped = this.stripScripts(match ? match[1] : text);
- if (this.options.update)
- DomElement.get(this.options.update).setHtml(stripped.html);
- if (this.options.evalScripts)
- this.executeScript(stripped.script);
- args = [ stripped.html, text ];
- break;
- case 'json':
- args = [ Json.decode(text, this.options.secure), text ];
- break;
- default:
- args = [ this.processScripts(text), xml ]
- }
- this.fireEvent('complete', args)
- .fireEvent('success', args)
- .callChain();
- },
-
- stripScripts: function(html) {
- var script = '';
- html = html.replace(/');
-document.write('');
\ No newline at end of file
diff --git a/lib/bootstrap.js b/lib/bootstrap.js
deleted file mode 100644
index aaed4e9f..00000000
--- a/lib/bootstrap.js
+++ /dev/null
@@ -1,411 +0,0 @@
-/**
- * Bootstrap JavaScript Library
- * (c) 2006 - 2011 Juerg Lehni, http://lehni.org/
- *
- * Bootstrap is released under the MIT license
- * http://bootstrapjs.org/
- *
- * Inspirations:
- * http://dean.edwards.name/weblog/2006/03/base/
- * http://dev.helma.org/Wiki/JavaScript+Inheritance+Sugar/
- * http://prototypejs.org/
- */
-
-var Base = new function() { // Bootstrap scope
- // Fix __proto__ for browsers where it is not implemented (IE and Opera).
- var fix = !this.__proto__,
- hidden = /^(statics|generics|preserve|enumerable|prototype|__proto__|toString|valueOf)$/,
- proto = Object.prototype,
- /**
- * Private function that checks if an object contains a given property.
- * Naming it 'has' causes problems on Opera when defining
- * Object.prototype.has, as the local version then seems to be overriden
- * by that. Giving it a idfferent name fixes it.
- */
- has = fix
- ? function(name) {
- return name !== '__proto__' && this.hasOwnProperty(name);
- }
- : proto.hasOwnProperty,
- toString = proto.toString,
- proto = Array.prototype,
- isArray = Array.isArray = Array.isArray || function(obj) {
- return toString.call(obj) === '[object Array]';
- },
- slice = proto.slice,
- forEach = proto.forEach || function(iter, bind) {
- for (var i = 0, l = this.length; i < l; i++)
- iter.call(bind, this[i], i, this);
- },
- forIn = function(iter, bind) {
- // Do not use Object.keys for iteration as iterators might modify
- // the object we're iterating over, making the hasOwnProperty still
- // necessary.
- for (var i in this)
- if (this.hasOwnProperty(i))
- iter.call(bind, this[i], i, this);
- },
- _define = Object.defineProperty,
- _describe = Object.getOwnPropertyDescriptor;
-
- // Support a mixed environment of some ECMAScript 5 features present,
- // along with __defineGetter/Setter__ functions, as found in browsers today.
- function define(obj, name, desc) {
- // Unfortunately Safari seems to ignore configurable: true and
- // does not override existing properties, so we need to delete
- // first:
- if (_define) {
- try {
- delete obj[name];
- return _define(obj, name, desc);
- } catch (e) {}
- }
- if ((desc.get || desc.set) && obj.__defineGetter__) {
- desc.get && obj.__defineGetter__(name, desc.get);
- desc.set && obj.__defineSetter__(name, desc.set);
- } else {
- obj[name] = desc.value;
- }
- return obj;
- }
-
- function describe(obj, name) {
- if (_describe) {
- try {
- return _describe(obj, name);
- } catch (e) {}
- }
- var get = obj.__lookupGetter__ && obj.__lookupGetter__(name);
- return get
- ? { get: get, set: obj.__lookupSetter__(name), enumerable: true,
- configurable: true }
- : has.call(obj, name)
- ? { value: obj[name], enumerable: true, configurable: true,
- writable: true }
- : null;
- }
-
- /**
- * Private function that injects functions from src into dest, overriding
- * (and inherinting from) base.
- */
- function inject(dest, src, enumerable, base, preserve, generics) {
- var beans, bean;
-
- /**
- * Private function that injects one field with given name and checks if
- * the field is a function that needs to be wrapped for calls of base().
- * This is only needed if the function in base is different from the one
- * in src, and if the one in src is actually calling base through base.
- * The string of the function is parsed for this.base to detect calls.
- */
- function field(name, val, dontCheck, generics) {
- // This does even work for prop: 0, as it will just be looked up
- // again through describe.
- var val = val || (val = describe(src, name))
- && (val.get ? val : val.value),
- func = typeof val === 'function',
- res = val,
- // Only lookup previous value if we preserve or define a
- // function that might need it for this.base(). If we're
- // defining a getter, don't lookup previous value, but look if
- // the property exists (name in dest) and store result in prev
- prev = preserve || func
- ? (val && val.get ? name in dest : dest[name]) : null;
- // Make generics first, as we might jump out bellow in the
- // val !== (src.__proto__ || Object.prototype)[name] check,
- // e.g. when explicitely reinjecting Array.prototype methods
- // to produce generics of them.
- if (generics && func && (!preserve || !generics[name])) {
- generics[name] = function(bind) {
- // Do not call Array.slice generic here, as on Safari,
- // this seems to confuse scopes (calling another
- // generic from generic-producing code).
- return bind && dest[name].apply(bind,
- slice.call(arguments, 1));
- }
- }
- if ((dontCheck || val !== undefined && has.call(src, name))
- && (!preserve || !prev)) {
- if (func) {
- if (prev && /\bthis\.base\b/.test(val)) {
- var fromBase = base && base[name] == prev;
- res = function() {
- // Look up the base function each time if we can,
- // to reflect changes to the base class after
- // inheritance.
- var tmp = describe(this, 'base');
- define(this, 'base', { value: fromBase
- ? base[name] : prev, configurable: true });
- try {
- return val.apply(this, arguments);
- } finally {
- tmp ? define(this, 'base', tmp)
- : delete this.base;
- }
- };
- // Make wrapping closure pretend to be the original
- // function on inspection
- res.toString = function() {
- return val.toString();
- }
- res.valueOf = function() {
- return val.valueOf();
- }
- }
- // Produce bean properties if getters are specified. This
- // does not produce properties for setter-only properties.
- // Just collect beans for now, and look them up in dest at
- // the end of fields injection. This ensures this.base()
- // works in beans too, and inherits setters for redefined
- // getters in subclasses. Only add getter beans if they do
- // not expect arguments. Functions that should function both
- // with optional arguments and as beans should not declare
- // the parameters and use the arguments array internally
- // instead.
- if (beans && val.length == 0
- && (bean = name.match(/^(get|is)(([A-Z])(.*))$/)))
- beans.push([ bean[3].toLowerCase() + bean[4], bean[2] ]);
- }
- // No need to look up getter if this is a function already.
- if (!res || func || !res.get)
- res = { value: res, writable: true };
- // Only set/change configurable and enumerable if this field is
- // configurable
- if ((describe(dest, name)
- || { configurable: true }).configurable) {
- res.configurable = true;
- res.enumerable = enumerable;
- }
- define(dest, name, res);
- }
- }
- // Iterate through all definitions in src now and call field() for each.
- if (src) {
- beans = [];
- for (var name in src)
- if (has.call(src, name) && !hidden.test(name))
- field(name, null, true, generics);
- // IE (and some other browsers?) never enumerate these, even if
- // they are simply set on an object. Force their creation. Do not
- // create generics for these, and check them for not being defined
- // (by passing undefined for dontCheck).
- field('toString');
- field('valueOf');
- // Now finally define beans as well. Look up methods on dest, for
- // support of this.base() (See above).
- for (var i = 0, l = beans && beans.length; i < l; i++)
- try {
- var bean = beans[i], part = bean[1];
- field(bean[0], {
- get: dest['get' + part] || dest['is' + part],
- set: dest['set' + part]
- }, true);
- } catch (e) {}
- }
- return dest;
- }
-
- /**
- * Private function that creates a constructor to extend the given object.
- * When this constructor is called through new, a new object is craeted
- * that inherits all from obj.
- */
- function extend(obj) {
- // Create the constructor for the new prototype that calls initialize
- // if it is defined.
- var ctor = function(dont) {
- // Fix __proto__
- if (fix) define(this, '__proto__', { value: obj });
- // Call the constructor function, if defined and we are not
- // inheriting, in which case ctor.dont would be set, see bellow.
- if (this.initialize && dont !== ctor.dont)
- return this.initialize.apply(this, arguments);
- }
- ctor.prototype = obj;
- // Add a toString function that delegates to initialize if possible
- ctor.toString = function() {
- return (this.prototype.initialize || function() {}).toString();
- }
- return ctor;
- }
-
- /**
- * Converts the argument to an iterator function. If none is specified, the
- * identity function is returned.
- * This supports normal functions, which are returned unmodified, and values
- * to compare to. Wherever this function is used in the Enumerable
- * functions, a value, a Function or null may be passed.
- */
- function iterator(iter) {
- return !iter
- ? function(val) { return val }
- : typeof iter !== 'function'
- ? function(val) { return val == iter }
- : iter;
- }
-
- function each(obj, iter, bind, asArray) {
- try {
- if (obj)
- (asArray || asArray === undefined && isArray(obj)
- ? forEach : forIn).call(obj, iterator(iter),
- bind = bind || obj);
- } catch (e) {
- if (e !== Base.stop) throw e;
- }
- return bind;
- }
-
- function clone(obj) {
- return each(obj, function(val, i) {
- this[i] = val;
- }, new obj.constructor());
- }
-
- // Inject into new ctor object that's passed to inject(), and then returned
- return inject(function() {}, {
- inject: function(src/*, ... */) {
- if (src) {
- var proto = this.prototype,
- base = proto.__proto__ && proto.__proto__.constructor,
- // Allow the whole scope to just define statics by defining
- // statics: true.
- statics = src.statics == true ? src : src.statics;
- if (statics != src)
- inject(proto, src, src.enumerable, base && base.prototype,
- src.preserve, src.generics && this);
- // Define new static fields as enumerable, and inherit from
- // base. enumerable is necessary so they can be copied over from
- // base, and it does not harm to have enumerable properties in
- // the constructor. Use the preserve setting in src.preserve for
- // statics too, not their own.
- inject(this, statics, true, base, src.preserve);
- }
- // If there are more than one argument, loop through them and call
- // inject again. Do not simple inline the above code in one loop,
- // since each of the passed objects might override this.inject.
- for (var i = 1, l = arguments.length; i < l; i++)
- this.inject(arguments[i]);
- return this;
- },
-
- extend: function(src/* , ... */) {
- // The new prototype extends the constructor on which extend is
- // called. Fix constructor.
- // TODO: Consider using Object.create instead of using this.dont if
- // available?
- var proto = new this(this.dont),
- ctor = extend(proto);
- define(proto, 'constructor',
- { value: ctor, writable: true, configurable: true });
- // Define an object to be passed as the first parameter in
- // constructors when initialize should not be called.
- ctor.dont = {};
- // Copy over static fields, as prototype-like inheritance
- // is not possible for static fields. Mark them as enumerable
- // so they can be copied over again.
- inject(ctor, this, true);
- // Inject all the definitions in src. Use the new inject instead of
- // the one in ctor, in case it was overriden. this is needed when
- // overriding the static .inject(). But only inject if there's
- // something to actually inject.
- return arguments.length ? this.inject.apply(ctor, arguments) : ctor;
- }
- // Pass true for enumerable, so inject() and extend() can be passed on
- // to subclasses of Base through Base.inject() / extend().
- }, true).inject({
- /**
- * Returns true if the object contains a property with the given name,
- * false otherwise.
- * Just like in .each, objects only contained in the prototype(s) are
- * filtered.
- */
- has: has,
- each: each,
-
- /**
- * Injects the fields from the given object, adding this.base()
- * functionality
- */
- inject: function(/* src, ... */) {
- for (var i = 0, l = arguments.length; i < l; i++)
- inject(this, arguments[i]);
- return this;
- },
-
- /**
- * Returns a new object that inherits all properties from "this",
- * through proper JS inheritance, not copying.
- * Optionally, src and hide parameters can be passed to fill in the
- * newly created object just like in inject(), to copy the behavior
- * of Function.prototype.extend.
- */
- extend: function(/* src, ... */) {
- // Notice the "new" here: the private extend returns a constructor
- // as it's used for Function.prototype.extend as well. But when
- // extending objects, we want to return a new object that inherits
- // from "this". In that case, the constructor is never used again,
- // its just created to create a new object with the proper
- // inheritance set and is garbage collected right after.
- var res = new (extend(this));
- return res.inject.apply(res, arguments);
- },
-
- each: function(iter, bind) {
- return each(this, iter, bind);
- },
-
- /**
- * Creates a new object of the same type and copies over all
- * name / value pairs from this object.
- */
- clone: function() {
- return clone(this);
- },
-
- statics: {
- // Expose some local privates as Base generics.
- each: each,
- clone: clone,
- define: define,
- describe: describe,
- iterator: iterator,
-
- has: function(obj, name) {
- return has.call(obj, name);
- },
-
- type: function(obj) {
- return (obj || obj === 0) && (obj._type || typeof obj) || null;
- },
-
- check: function(obj) {
- return !!(obj || obj === 0);
- },
-
- /**
- * Returns the first argument that is defined.
- * Null is counted as defined too, since !== undefined is used for
- * comparisons. In this it differs from Mootools!
- */
- pick: function() {
- for (var i = 0, l = arguments.length; i < l; i++)
- if (arguments[i] !== undefined)
- return arguments[i];
- return null;
- },
-
- /**
- * A special constant, to be thrown by closures passed to each()
- *
- * $continue / Base.next is not implemented, as the same
- * functionality can achieved by using return in the closure.
- * In prototype, the implementation of $continue also leads to a
- * huge speed decrease, as the closure is wrapped in another closure
- * that does nothing else than handling $continue.
- */
- stop: {}
- }
- });
-}
diff --git a/lib/parse-js-min.js b/lib/parse-js-min.js
deleted file mode 100644
index c0bdddac..00000000
--- a/lib/parse-js-min.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * A JavaScript tokenizer / parser / generator, originally written in Lisp.
- * Copyright (c) Marijn Haverbeke
- * http://marijn.haverbeke.nl/parse-js/
- *
- * Ported by to JavaScript by Mihai Bazon
- * Copyright (c) 2010, Mihai Bazon
- * http://mihai.bazon.net/blog/
- *
- * Modifications and adaptions to browser (c) 2011, Juerg Lehni
- * http://lehni.org/
- *
- * Distributed under the BSD license.
- */var parse_js=new function(){function W(a,b,c){var d=[];for(var e=0;e0,g=j(function(){return h(a[0]?k(["case",z(a[0])+":"]):"default:")},.5)+(f?e+j(function(){return u(a[1]).join(e)}):"");!c&&f&&d0?h(a):a}).join(e)},block:w,"var":function(a){return"var "+l(W(a,x))+";"},"const":function(a){return"const "+l(W(a,x))+";"},"try":function(a,b,c){var d=["try",w(a)];b&&d.push("catch","("+b[0]+")",w(b[1])),c&&d.push("finally",w(c));return k(d)},"throw":function(a){return k(["throw",z(a)])+";"},"new":function(a,b){b=b.length>0?"("+l(W(b,z))+")":"";return k(["new",m(a,"seq","binary","conditional","assign",function(a){var b=N(),c={};try{b.with_walkers({call:function(){throw c},"function":function(){return this}},function(){b.walk(a)})}catch(d){if(d===c)return!0;throw d}})+b])},"switch":function(a,b){return k(["switch","("+z(a)+")",v(b)])},"break":function(a){var b="break";a!=null&&(b+=" "+g(a));return b+";"},"continue":function(a){var b="continue";a!=null&&(b+=" "+g(a));return b+";"},conditional:function(a,b,c){return k([m(a,"assign","seq","conditional"),"?",m(b,"seq"),":",m(c,"seq")])},assign:function(a,b,c){a&&a!==!0?a+="=":a="=";return k([z(b),a,m(c,"seq")])},dot:function(a){var b=z(a),c=1;a[0]=="num"?/\./.test(a[1])||(b+="."):o(a)&&(b="("+b+")");while(cB[b[1]])d="("+d+")";if(L(c[0],["assign","conditional","seq"])||c[0]=="binary"&&B[a]>=B[c[1]]&&(c[1]!=a||!L(a,["&&","||","*"])))e="("+e+")";return k([d,a,e])},"unary-prefix":function(a,b){var c=z(b);b[0]=="num"||b[0]=="unary-prefix"&&!M(i,a+b[1])||!o(b)||(c="("+c+")");return a+(p(a.charAt(0))?" ":"")+c},"unary-postfix":function(a,b){var c=z(b);b[0]=="num"||b[0]=="unary-postfix"&&!M(i,a+b[1])||!o(b)||(c="("+c+")");return c+a},sub:function(a,b){var c=z(a);o(a)&&(c="("+c+")");return c+"["+z(b)+"]"},object:function(a){return a.length==0?"{}":"{"+e+j(function(){return W(a,function(a){if(a.length==3)return h(t(a[0],a[1][2],a[1][3],a[2]));var d=a[0],e=z(a[1]);b.quote_keys?d=Q(d):(typeof d=="number"||!c&&+d+""==d)&&parseFloat(d)>=0?d=q(+d):V(d)||(d=Q(d));return h(k(c&&b.space_colon?[d,":",e]:[d+":",e]))}).join(","+e)})+e+h("}")},regexp:function(a,b){return"/"+a+"/"+b},array:function(a){return a.length==0?"[]":k(["[",l(W(a,function(a){return!c&&a[0]=="atom"&&a[1]=="undefined"?"":m(a,"seq")})),"]"])},stat:function(a){return z(a).replace(/;*\s*$/,";")},seq:function(){return l(W(J(arguments),z))},label:function(a,b){return k([g(a),":",z(b)])},"with":function(a,b){return k(["with","("+z(a)+")",z(b)])},atom:function(a){return g(a)}},y=[];return z(a)}function Q(a){var b=0,c=0;a=a.replace(/[\\\b\f\n\r\t\x22\x27]/g,function(a){switch(a){case"\\":return"\\\\";case"\b":return"\\b";case"\f":return"\\f";case"\n":return"\\n";case"\r":return"\\r";case"\t":return"\\t";case'"':++b;return'"';case"'":++c;return"'"}return a});return b>c?"'"+a.replace(/\x27/g,"\\'")+"'":'"'+a.replace(/\x22/g,'\\"')+'"'}function O(a){return!a||a[0]=="block"&&(!a[1]||a[1].length==0)}function N(){function g(a,b){var c={},e;for(e in a)M(a,e)&&(c[e]=d[e],d[e]=a[e]);var f=b();for(e in c)M(c,e)&&(c[e]?d[e]=c[e]:delete d[e]);return f}function f(a){if(a==null)return null;try{e.push(a);var b=a[0],f=d[b];if(f){var g=f.apply(a,a.slice(1));if(g!=null)return g}f=c[b];return f.apply(a,a.slice(1))}finally{e.pop()}}function b(a){var b=[this[0]];a!=null&&b.push(W(a,f));return b}function a(a){return[this[0],W(a,function(a){var b=[a[0]];a.length>1&&(b[1]=f(a[1]));return b})]}var c={string:function(a){return[this[0],a]},num:function(a){return[this[0],a]},name:function(a){return[this[0],a]},toplevel:function(a){return[this[0],W(a,f)]},block:b,splice:b,"var":a,"const":a,"try":function(a,b,c){return[this[0],W(a,f),b!=null?[b[0],W(b[1],f)]:null,c!=null?W(c,f):null]},"throw":function(a){return[this[0],f(a)]},"new":function(a,b){return[this[0],f(a),W(b,f)]},"switch":function(a,b){return[this[0],f(a),W(b,function(a){return[a[0]?f(a[0]):null,W(a[1],f)]})]},"break":function(a){return[this[0],a]},"continue":function(a){return[this[0],a]},conditional:function(a,b,c){return[this[0],f(a),f(b),f(c)]},assign:function(a,b,c){return[this[0],a,f(b),f(c)]},dot:function(a){return[this[0],f(a)].concat(J(arguments,1))},call:function(a,b){return[this[0],f(a),W(b,f)]},"function":function(a,b,c){return[this[0],a,b.slice(),W(c,f)]},defun:function(a,b,c){return[this[0],a,b.slice(),W(c,f)]},"if":function(a,b,c){return[this[0],f(a),f(b),f(c)]},"for":function(a,b,c,d){return[this[0],f(a),f(b),f(c),f(d)]},"for-in":function(a,b,c,d){return[this[0],f(a),f(b),f(c),f(d)]},"while":function(a,b){return[this[0],f(a),f(b)]},"do":function(a,b){return[this[0],f(a),f(b)]},"return":function(a){return[this[0],f(a)]},binary:function(a,b,c){return[this[0],a,f(b),f(c)]},"unary-prefix":function(a,b){return[this[0],a,f(b)]},"unary-postfix":function(a,b){return[this[0],a,f(b)]},sub:function(a,b){return[this[0],f(a),f(b)]},object:function(a){return[this[0],W(a,function(a){return a.length==2?[a[0],f(a[1])]:[a[0],f(a[1]),a[2]]})]},regexp:function(a,b){return[this[0],a,b]},array:function(a){return[this[0],W(a,f)]},stat:function(a){return[this[0],f(a)]},seq:function(){return[this[0]].concat(W(J(arguments),f))},label:function(a,b){return[this[0],a,f(b)]},"with":function(a,b){return[this[0],f(a),f(b)]},atom:function(a){return[this[0],a]}},d={},e=[];return{walk:f,with_walkers:g,parent:function(){return e[e.length-2]},stack:function(){return e}}}function M(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function L(a,b){for(var c=b.length;--c>=0;)if(b[c]===a)return!0;return!1}function K(a){return a.split("")}function J(a,b){return Array.prototype.slice.call(a,b||0)}function I(a){var b={};for(var c=0;c0;++b)arguments[b]();return a}function G(a){var b=J(arguments,1);return function(){return a.apply(this,b.concat(J(arguments)))}}function F(a,b,c){function bk(a){try{++d.in_loop;return a()}finally{--d.in_loop}}function bi(a){var b=bg(a),c=d.token.value;if(e("operator")&&M(A,c)){if(bh(b)){g();return p("assign",A[c],b,bi(a))}i("Invalid assignment")}return b}function bh(a){if(!b)return!0;switch(a[0]){case"dot":case"sub":case"new":case"call":return!0;case"name":return a[1]!="this"}}function bg(a){var b=bf(a);if(e("operator","?")){g();var c=bj(!1);m(":");return p("conditional",b,c,bj(!1,a))}return b}function bf(a){return be(Y(!0),0,a)}function be(a,b,c){var f=e("operator")?d.token.value:null;f&&f=="in"&&c&&(f=null);var h=f!=null?B[f]:null;if(h!=null&&h>b){g();var i=be(Y(!0),h,c);return be(p("binary",f,a,i),b,c)}return a}function bd(a,b,c){(b=="++"||b=="--")&&!bh(c)&&i("Invalid use of "+b+" operator");return p(a,b,c)}function bc(a,b){if(e("punc",".")){g();return bc(p("dot",a,bb()),b)}if(e("punc","[")){g();return bc(p("sub",a,H(bj,G(m,"]"))),b)}if(b&&e("punc","(")){g();return bc(p("call",a,Z(")")),!0)}return b&&e("operator")&&M(z,d.token.value)?H(G(bd,"unary-postfix",d.token.value,a),g):a}function bb(){switch(d.token.type){case"name":case"operator":case"keyword":case"atom":return H(d.token.value,g);default:k()}}function ba(){switch(d.token.type){case"num":case"string":return H(d.token.value,g)}return bb()}function _(){var a=!0,c=[];while(!e("punc","}")){a?a=!1:m(",");if(!b&&e("punc","}"))break;var f=d.token.type,h=ba();f!="name"||h!="get"&&h!="set"||!!e("punc",":")?(m(":"),c.push([h,bj(!1)])):c.push([bb(),P(!1),h])}g();return p("object",c)}function $(){return p("array",Z("]",!b,!0))}function Z(a,b,c){var d=!0,f=[];while(!e("punc",a)){d?d=!1:m(",");if(b&&e("punc",a))break;e("punc",",")&&c?f.push(["atom","undefined"]):f.push(bj(!1))}g();return f}function X(){var a=Y(!1),b;e("punc","(")?(g(),b=Z(")")):b=[];return bc(p("new",a,b),!0)}function W(){return p("const",U())}function V(a){return p("var",U(a))}function U(a){var b=[];for(;;){e("name")||k();var c=d.token.value;g(),e("operator","=")?(g(),b.push([c,bj(!1,a)])):b.push([c]);if(!e("punc",","))break;g()}return b}function T(){var a=R(),b,c;if(e("keyword","catch")){g(),m("("),e("name")||i("Name expected");var f=d.token.value;g(),m(")"),b=[f,R()]}e("keyword","finally")&&(g(),c=R()),!b&&!c&&i("Missing catch/finally blocks");return p("try",a,b,c)}function R(){m("{");var a=[];while(!e("punc","}"))e("eof")&&k(),a.push(t());g();return a}function Q(){var a=q(),b=t(),c;e("keyword","else")&&(g(),c=t());return p("if",a,b,c)}function O(a){var b=a[0]=="var"?p("name",a[1][0]):a;g();var c=bj();m(")");return p("for-in",a,b,c,bk(t))}function N(a){m(";");var b=e("punc",";")?null:bj();m(";");var c=e("punc",")")?null:bj();m(")");return p("for",a,b,c,bk(t))}function K(){m("(");var a=null;if(!e("punc",";")){a=e("keyword","var")?(g(),V(!0)):bj(!0,!0);if(e("operator","in"))return O(a)}return N(a)}function I(a){var b;n()||(b=e("name")?d.token.value:null),b!=null?(g(),L(b,d.labels)||i("Label "+b+" without matching loop or statement")):d.in_loop==0&&i(a+" not inside a loop or switch"),o();return p(a,b)}function F(){return p("stat",H(bj,o))}function w(a){d.labels.push(a);var c=d.token,e=t();b&&!M(C,e[0])&&k(c),d.labels.pop();return p("label",a,e)}function s(a){return c?function(){var b=d.token,c=a.apply(this,arguments);c[0]=r(c[0],b,h());return c}:a}function r(a,b,c){return a instanceof E?a:new E(a,b,c)}function q(){m("(");var a=bj();m(")");return a}function p(){return J(arguments)}function o(){e("punc",";")?g():n()||k()}function n(){return!b&&(d.token.nlb||e("eof")||e("punc","}"))}function m(a){return l("punc",a)}function l(a,b){if(e(a,b))return g();j(d.token,"Unexpected token "+d.token.type+", expected "+a)}function k(a){a==null&&(a=d.token),j(a,"Unexpected token: "+a.type+" ("+a.value+")")}function j(a,b){i(b,a.line,a.col)}function i(a,b,c,e){var f=d.input.context();u(a,b!=null?b:f.tokline,c!=null?c:f.tokcol,e!=null?e:f.tokpos)}function h(){return d.prev}function g(){d.prev=d.token,d.peeked?(d.token=d.peeked,d.peeked=null):d.token=d.input();return d.token}function f(){return d.peeked||(d.peeked=d.input())}function e(a,b){return v(d.token,a,b)}var d={input:typeof a=="string"?x(a,!0):a,token:null,prev:null,peeked:null,in_function:0,in_loop:0,labels:[]};d.token=g();var t=s(function(){e("operator","/")&&(d.peeked=null,d.token=d.input(!0));switch(d.token.type){case"num":case"string":case"regexp":case"operator":case"atom":return F();case"name":return v(f(),"punc",":")?w(H(d.token.value,g,g)):F();case"punc":switch(d.token.value){case"{":return p("block",R());case"[":case"(":return F();case";":g();return p("block");default:k()};case"keyword":switch(H(d.token.value,g)){case"break":return I("break");case"continue":return I("continue");case"debugger":o();return p("debugger");case"do":return function(a){l("keyword","while");return p("do",H(q,o),a)}(bk(t));case"for":return K();case"function":return P(!0);case"if":return Q();case"return":d.in_function==0&&i("'return' outside of function");return p("return",e("punc",";")?(g(),null):n()?null:H(bj,o));case"switch":return p("switch",q(),S());case"throw":return p("throw",H(bj,o));case"try":return T();case"var":return H(V,o);case"const":return H(W,o);case"while":return p("while",q(),bk(t));case"with":return p("with",q(),t());default:k()}}}),P=s(function(a){var b=e("name")?H(d.token.value,g):null;a&&!b&&k(),m("(");return p(a?"defun":"function",b,function(a,b){while(!e("punc",")"))a?a=!1:m(","),e("name")||k(),b.push(d.token.value),g();g();return b}(!0,[]),function(){++d.in_function;var a=d.in_loop;d.in_loop=0;var b=R();--d.in_function,d.in_loop=a;return b}())}),S=G(bk,function(){m("{");var a=[],b=null;while(!e("punc","}"))e("eof")&&k(),e("keyword","case")?(g(),b=[],a.push([bj(),b]),m(":")):e("keyword","default")?(g(),m(":"),b=[],a.push([null,b])):(b||k(),b.push(t()));g();return a}),Y=s(function(a){if(e("operator","new")){g();return X()}if(e("operator")&&M(y,d.token.value))return bd("unary-prefix",H(d.token.value,g),Y(a));if(e("punc")){switch(d.token.value){case"(":g();return bc(H(bj,G(m,")")),a);case"[":g();return bc($(),a);case"{":g();return bc(_(),a)}k()}if(e("keyword","function")){g();return bc(P(!1),a)}if(M(D,d.token.type)){var b=d.token.type=="regexp"?p("regexp",d.token.value[0],d.token.value[1]):p(d.token.type,d.token.value);return bc(H(b,g),a)}k()}),bj=s(function(a,b){arguments.length==0&&(a=!0);var c=bi(b);if(a&&e("punc",",")){g();return p("seq",c,bj(!0,b))}return c});return p("toplevel",function(a){while(!e("eof"))a.push(t());return a}([]))}function E(a,b,c){this.name=a,this.start=b,this.end=c}function x(b){function P(a){if(a)return I();y(),v();var b=g();if(!b)return x("eof");if(o(b))return C();if(b=='"'||b=="'")return F();if(M(l,b))return x("punc",h());if(b==".")return L();if(b=="/")return K();if(M(e,b))return J();if(b=="\\"||q(b))return N();B("Unexpected character '"+b+"'")}function O(a,b){try{return b()}catch(c){if(c===w)B(a);else throw c}}function N(){var b=A(r);return M(a,b)?M(i,b)?x("operator",b):M(d,b)?x("atom",b):x("keyword",b):x("name",b)}function L(){h();return o(g())?C("."):x("punc",".")}function K(){h();var a=f.regex_allowed;switch(g()){case"/":f.comments_before.push(G()),f.regex_allowed=a;return P();case"*":f.comments_before.push(H()),f.regex_allowed=a;return P()}return f.regex_allowed?I():J("/")}function J(a){function b(a){if(!g())return a;var c=a+g();if(M(i,c)){h();return b(c)}return a}return x("operator",b(a||h()))}function I(){return O("Unterminated regular expression",function(){var a=!1,b="",c,d=!1;while(c=h(!0))if(a)b+="\\"+c,a=!1;else if(c=="[")d=!0,b+=c;else if(c=="]"&&d)d=!1,b+=c;else{if(c=="/"&&!d)break;c=="\\"?a=!0:b+=c}var e=A(function(a){return M(m,a)});return x("regexp",[b,e])})}function H(){h();return O("Unterminated multiline comment",function(){var a=t("*/",!0),b=f.text.substring(f.pos,a),c=x("comment2",b,!0);f.pos=a+2,f.line+=b.split("\n").length-1,f.newline_before=b.indexOf("\n")>=0;return c})}function G(){h();var a=t("\n"),b;a==-1?(b=f.text.substr(f.pos),f.pos=f.text.length):(b=f.text.substring(f.pos,a),f.pos=a);return x("comment1",b,!0)}function F(){return O("Unterminated string constant",function(){var a=h(),b="";for(;;){var c=h(!0);if(c=="\\")c=D();else if(c==a)break;b+=c}return x("string",b)})}function E(a){var b=0;for(;a>0;--a){var c=parseInt(h(!0),16);isNaN(c)&&B("Invalid hex-character pattern in string"),b=b<<4|c}return b}function D(){var a=h(!0);switch(a){case"n":return"\n";case"r":return"\r";case"t":return"\t";case"b":return"\b";case"v":return"";case"f":return"\f";case"0":return" ";case"x":return String.fromCharCode(E(2));case"u":return String.fromCharCode(E(4));case"\n":return"";default:return a}}function C(a){var b=!1,c=!1,d=!1,e=a==".",f=A(function(f,g){if(f=="x"||f=="X")return d?!1:d=!0;if(!d&&(f=="E"||f=="e"))return b?!1:b=c=!0;if(f=="-")return c||g==0&&!a?!0:!1;if(f=="+")return c;c=!1;if(f==".")return!e&&!d?e=!0:!1;return p(f)});a&&(f=a+f);var g=s(f);if(!isNaN(g))return x("num",g);B("Invalid syntax: "+f)}function B(a){u(a,f.tokline,f.tokcol,f.tokpos)}function A(a){var b="",c=g(),d=0;while(c&&a(c,d++))b+=h(),c=g();return b}function y(){while(M(j,g()))h()}function x(a,b,d){f.regex_allowed=a=="operator"&&!M(z,b)||a=="keyword"&&M(c,b)||a=="punc"&&M(k,b);var e={type:a,value:b,line:f.tokline,col:f.tokcol,pos:f.tokpos,nlb:f.newline_before};d||(e.comments_before=f.comments_before,f.comments_before=[]),f.newline_before=!1;return e}function v(){f.tokline=f.line,f.tokcol=f.col,f.tokpos=f.pos}function t(a,b){var c=f.text.indexOf(a,f.pos);if(b&&c==-1)throw w;return c}function n(){return!f.peek()}function h(a){var b=f.text.charAt(f.pos++);if(a&&!b)throw w;b=="\n"?(f.newline_before=!0,++f.line,f.col=0):++f.col;return b}function g(){return f.text.charAt(f.pos)}var f={text:b.replace(/\r\n?|[\n\u2028\u2029]/g,"\n").replace(/^\uFEFF/,""),pos:0,tokpos:0,line:0,tokline:0,col:0,tokcol:0,newline_before:!1,regex_allowed:!1,comments_before:[]};P.context=function(a){a&&(f=a);return f};return P}function v(a,b,c){return a.type==b&&(c==null||a.value==c)}function u(a,b,c,d){throw new t(a,b,c,d)}function t(a,b,c,d){this.message=a,this.line=b,this.col=c,this.pos=d}function s(a){if(f.test(a))return parseInt(a.substr(2),16);if(g.test(a))return parseInt(a.substr(1),8);if(h.test(a))return parseFloat(a)}function r(a){return q(a)||o(a)}function q(a){return a=="$"||a=="_"||n(a)}function p(a){return o(a)||n(a)}function o(a){a=a.charCodeAt(0);return a>=48&&a<=57}function n(a){a=a.charCodeAt(0);return a>=65&&a<=90||a>=97&&a<=122}var a=I(["break","case","catch","const","continue","default","delete","do","else","finally","for","function","if","in","instanceof","new","return","switch","throw","try","typeof","var","void","while","with"]),b=I(["abstract","boolean","byte","char","class","debugger","double","enum","export","extends","final","float","goto","implements","import","int","interface","long","native","package","private","protected","public","short","static","super","synchronized","throws","transient","volatile"]),c=I(["return","new","delete","throw","else","case"]),d=I(["false","null","true","undefined"]),e=I(K("+-*&%=<>!?|~^")),f=/^0x[0-9a-f]+$/i,g=/^0[0-7]+$/,h=/^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i,i=I(["in","instanceof","typeof","new","void","delete","++","--","+","-","!","~","&","|","^","*","/","%",">>","<<",">>>","<",">","<=",">=","==","===","!=","!==","?","=","+=","-=","/=","*=","%=",">>=","<<=",">>>=","|=","^=","&=","&&","||"]),j=I(K(" \n\r\t")),k=I(K("[{}(,.;:")),l=I(K("[]{}(),;:")),m=I(K("gmsiy"));t.prototype.toString=function(){return this.message+" (line: "+this.line+", col: "+this.col+", pos: "+this.pos+")"};var w={},y=I(["typeof","void","delete","--","++","!","~","-","+"]),z=I(["--","++"]),A=function(a,b,c){while(c>=","<<=",">>>=","|=","^=","&="],{"=":!0},0),B=function(a,b){for(var c=0,d=1;c","<=",">=","in","instanceof"],[">>","<<",">>>"],["+","-"],["*","/","%"]],{}),C=I(["for","do","while","switch"]),D=I(["atom","num","string","regexp","name"]);E.prototype.toString=function(){return this.name};var P=I(["name","array","object","string","dot","sub","call","regexp"]),R=I(["if","while","do","for","for-in","with"]);return{parse:F,gen_code:S,tokenizer:x,ast_walker:N}}
\ No newline at end of file
diff --git a/lib/parse-js-unicode.js b/lib/parse-js-unicode.js
deleted file mode 100644
index 6baa67f3..00000000
--- a/lib/parse-js-unicode.js
+++ /dev/null
@@ -1,1997 +0,0 @@
-/**
- * A JavaScript tokenizer / parser / generator, originally written in Lisp.
- * Copyright (c) Marijn Haverbeke
- * http://marijn.haverbeke.nl/parse-js/
- *
- * Ported by to JavaScript by Mihai Bazon
- * Copyright (c) 2010, Mihai Bazon
- * http://mihai.bazon.net/blog/
- *
- * Modifications and adaptions to browser (c) 2011, Juerg Lehni
- * http://lehni.org/
- *
- * Distributed under the BSD license.
- */
-
-var parse_js = new function() {
-
-/* -----[ Tokenizer (constants) ]----- */
-
-var KEYWORDS = array_to_hash([
- "break",
- "case",
- "catch",
- "const",
- "continue",
- "default",
- "delete",
- "do",
- "else",
- "finally",
- "for",
- "function",
- "if",
- "in",
- "instanceof",
- "new",
- "return",
- "switch",
- "throw",
- "try",
- "typeof",
- "var",
- "void",
- "while",
- "with"
-]);
-
-var RESERVED_WORDS = array_to_hash([
- "abstract",
- "boolean",
- "byte",
- "char",
- "class",
- "debugger",
- "double",
- "enum",
- "export",
- "extends",
- "final",
- "float",
- "goto",
- "implements",
- "import",
- "int",
- "interface",
- "long",
- "native",
- "package",
- "private",
- "protected",
- "public",
- "short",
- "static",
- "super",
- "synchronized",
- "throws",
- "transient",
- "volatile"
-]);
-
-var KEYWORDS_BEFORE_EXPRESSION = array_to_hash([
- "return",
- "new",
- "delete",
- "throw",
- "else",
- "case"
-]);
-
-var KEYWORDS_ATOM = array_to_hash([
- "false",
- "null",
- "true",
- "undefined"
-]);
-
-var OPERATOR_CHARS = array_to_hash(characters("+-*&%=<>!?|~^"));
-
-var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
-var RE_OCT_NUMBER = /^0[0-7]+$/;
-var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
-
-var OPERATORS = array_to_hash([
- "in",
- "instanceof",
- "typeof",
- "new",
- "void",
- "delete",
- "++",
- "--",
- "+",
- "-",
- "!",
- "~",
- "&",
- "|",
- "^",
- "*",
- "/",
- "%",
- ">>",
- "<<",
- ">>>",
- "<",
- ">",
- "<=",
- ">=",
- "==",
- "===",
- "!=",
- "!==",
- "?",
- "=",
- "+=",
- "-=",
- "/=",
- "*=",
- "%=",
- ">>=",
- "<<=",
- ">>>=",
- "|=",
- "^=",
- "&=",
- "&&",
- "||"
-]);
-
-var WHITESPACE_CHARS = array_to_hash(characters(" \u00a0\n\r\t\f\v\u200b"));
-
-var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:"));
-
-var PUNC_CHARS = array_to_hash(characters("[]{}(),;:"));
-
-var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy"));
-
-/* -----[ Tokenizer ]----- */
-
-// regexps adapted from http://xregexp.com/plugins/#unicode
-var UNICODE = {
- letter: new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0523\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u097B-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1159\\u115F-\\u11A2\\u11A8-\\u11F9\\u1200-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u1676\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19A9\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2C6F\\u2C71-\\u2C7D\\u2C80-\\u2CE4\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FC3\\uA000-\\uA48C\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA717-\\uA71F\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA90A-\\uA925\\uA930-\\uA946\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAC00\\uD7A3\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),
- non_spacing_mark: new RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"),
- space_combining_mark: new RegExp("[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]"),
- connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]")
-};
-
-function is_letter(ch) {
- return UNICODE.letter.test(ch);
-};
-
-function is_digit(ch) {
- ch = ch.charCodeAt(0);
- return ch >= 48 && ch <= 57; //XXX: find out if "UnicodeDigit" means something else than 0..9
-};
-
-function is_alphanumeric_char(ch) {
- return is_digit(ch) || is_letter(ch);
-};
-
-function is_unicode_combining_mark(ch) {
- return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
-};
-
-function is_unicode_connector_punctuation(ch) {
- return UNICODE.connector_punctuation.test(ch);
-};
-
-function is_identifier_start(ch) {
- return ch == "$" || ch == "_" || is_letter(ch);
-};
-
-function is_identifier_char(ch) {
- return is_identifier_start(ch)
- || is_unicode_combining_mark(ch)
- || is_digit(ch)
- || is_unicode_connector_punctuation(ch)
- || ch == "\u200c" // zero-width non-joiner
- || ch == "\u200d" // zero-width joiner (in my ECMA-262 PDF, this is also 200c)
- ;
-};
-
-function parse_js_number(num) {
- if (RE_HEX_NUMBER.test(num)) {
- return parseInt(num.substr(2), 16);
- } else if (RE_OCT_NUMBER.test(num)) {
- return parseInt(num.substr(1), 8);
- } else if (RE_DEC_NUMBER.test(num)) {
- return parseFloat(num);
- }
-};
-
-function JS_Parse_Error(message, line, col, pos) {
- this.message = message;
- this.line = line;
- this.col = col;
- this.pos = pos;
-};
-
-JS_Parse_Error.prototype.toString = function() {
- return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")";
-};
-
-function js_error(message, line, col, pos) {
- throw new JS_Parse_Error(message, line, col, pos);
-};
-
-function is_token(token, type, val) {
- return token.type == type && (val == null || token.value == val);
-};
-
-var EX_EOF = {};
-
-function tokenizer($TEXT) {
-
- var S = {
- text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''),
- pos : 0,
- tokpos : 0,
- line : 0,
- tokline : 0,
- col : 0,
- tokcol : 0,
- newline_before : false,
- regex_allowed : false,
- comments_before : []
- };
-
- function peek() { return S.text.charAt(S.pos); };
-
- function next(signal_eof) {
- var ch = S.text.charAt(S.pos++);
- if (signal_eof && !ch)
- throw EX_EOF;
- if (ch == "\n") {
- S.newline_before = true;
- ++S.line;
- S.col = 0;
- } else {
- ++S.col;
- }
- return ch;
- };
-
- function eof() {
- return !S.peek();
- };
-
- function find(what, signal_eof) {
- var pos = S.text.indexOf(what, S.pos);
- if (signal_eof && pos == -1) throw EX_EOF;
- return pos;
- };
-
- function start_token() {
- S.tokline = S.line;
- S.tokcol = S.col;
- S.tokpos = S.pos;
- };
-
- function token(type, value, is_comment) {
- S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) ||
- (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) ||
- (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value)));
- var ret = {
- type : type,
- value : value,
- line : S.tokline,
- col : S.tokcol,
- pos : S.tokpos,
- nlb : S.newline_before
- };
- if (!is_comment) {
- ret.comments_before = S.comments_before;
- S.comments_before = [];
- }
- S.newline_before = false;
- return ret;
- };
-
- function skip_whitespace() {
- while (HOP(WHITESPACE_CHARS, peek()))
- next();
- };
-
- function read_while(pred) {
- var ret = "", ch = peek(), i = 0;
- while (ch && pred(ch, i++)) {
- ret += next();
- ch = peek();
- }
- return ret;
- };
-
- function parse_error(err) {
- js_error(err, S.tokline, S.tokcol, S.tokpos);
- };
-
- function read_num(prefix) {
- var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
- var num = read_while(function(ch, i){
- if (ch == "x" || ch == "X") {
- if (has_x) return false;
- return has_x = true;
- }
- if (!has_x && (ch == "E" || ch == "e")) {
- if (has_e) return false;
- return has_e = after_e = true;
- }
- if (ch == "-") {
- if (after_e || (i == 0 && !prefix)) return true;
- return false;
- }
- if (ch == "+") return after_e;
- after_e = false;
- if (ch == ".") {
- if (!has_dot && !has_x)
- return has_dot = true;
- return false;
- }
- return is_alphanumeric_char(ch);
- });
- if (prefix)
- num = prefix + num;
- var valid = parse_js_number(num);
- if (!isNaN(valid)) {
- return token("num", valid);
- } else {
- parse_error("Invalid syntax: " + num);
- }
- };
-
- function read_escaped_char() {
- var ch = next(true);
- switch (ch) {
- case "n" : return "\n";
- case "r" : return "\r";
- case "t" : return "\t";
- case "b" : return "\b";
- case "v" : return "\v";
- case "f" : return "\f";
- case "0" : return "\0";
- case "x" : return String.fromCharCode(hex_bytes(2));
- case "u" : return String.fromCharCode(hex_bytes(4));
- case "\n": return "";
- default : return ch;
- }
- };
-
- function hex_bytes(n) {
- var num = 0;
- for (; n > 0; --n) {
- var digit = parseInt(next(true), 16);
- if (isNaN(digit))
- parse_error("Invalid hex-character pattern in string");
- num = (num << 4) | digit;
- }
- return num;
- };
-
- function read_string() {
- return with_eof_error("Unterminated string constant", function(){
- var quote = next(), ret = "";
- for (;;) {
- var ch = next(true);
- if (ch == "\\") {
- // read OctalEscapeSequence (XXX: deprecated if "strict mode")
- // https://github.com/mishoo/UglifyJS/issues/178
- var octal_len = 0, first = null;
- ch = read_while(function(ch){
- if (ch >= "0" && ch <= "7") {
- if (!first) {
- first = ch;
- return ++octal_len;
- }
- else if (first <= "3" && octal_len <= 2) return ++octal_len;
- else if (first >= "4" && octal_len <= 1) return ++octal_len;
- }
- return false;
- });
- if (octal_len > 0) ch = String.fromCharCode(parseInt(ch, 8));
- else ch = read_escaped_char();
- }
- else if (ch == quote) break;
- ret += ch;
- }
- return token("string", ret);
- });
- };
-
- function read_line_comment() {
- next();
- var i = find("\n"), ret;
- if (i == -1) {
- ret = S.text.substr(S.pos);
- S.pos = S.text.length;
- } else {
- ret = S.text.substring(S.pos, i);
- S.pos = i;
- }
- return token("comment1", ret, true);
- };
-
- function read_multiline_comment() {
- next();
- return with_eof_error("Unterminated multiline comment", function(){
- var i = find("*/", true),
- text = S.text.substring(S.pos, i),
- tok = token("comment2", text, true);
- S.pos = i + 2;
- S.line += text.split("\n").length - 1;
- S.newline_before = text.indexOf("\n") >= 0;
- return tok;
- });
- };
-
- function read_name() {
- var backslash = false, name = "", ch;
- while ((ch = peek()) != null) {
- if (!backslash) {
- if (ch == "\\") backslash = true, next();
- else if (is_identifier_char(ch)) name += next();
- else break;
- }
- else {
- if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX");
- ch = read_escaped_char();
- if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier");
- name += ch;
- backslash = false;
- }
- }
- return name;
- };
-
- function read_regexp() {
- return with_eof_error("Unterminated regular expression", function(){
- var prev_backslash = false, regexp = "", ch, in_class = false;
- while ((ch = next(true))) if (prev_backslash) {
- regexp += "\\" + ch;
- prev_backslash = false;
- } else if (ch == "[") {
- in_class = true;
- regexp += ch;
- } else if (ch == "]" && in_class) {
- in_class = false;
- regexp += ch;
- } else if (ch == "/" && !in_class) {
- break;
- } else if (ch == "\\") {
- prev_backslash = true;
- } else {
- regexp += ch;
- }
- var mods = read_name();
- return token("regexp", [ regexp, mods ]);
- });
- };
-
- function read_operator(prefix) {
- function grow(op) {
- if (!peek()) return op;
- var bigger = op + peek();
- if (HOP(OPERATORS, bigger)) {
- next();
- return grow(bigger);
- } else {
- return op;
- }
- };
- return token("operator", grow(prefix || next()));
- };
-
- function handle_slash() {
- next();
- var regex_allowed = S.regex_allowed;
- switch (peek()) {
- case "/":
- S.comments_before.push(read_line_comment());
- S.regex_allowed = regex_allowed;
- return next_token();
- case "*":
- S.comments_before.push(read_multiline_comment());
- S.regex_allowed = regex_allowed;
- return next_token();
- }
- return S.regex_allowed ? read_regexp() : read_operator("/");
- };
-
- function handle_dot() {
- next();
- return is_digit(peek())
- ? read_num(".")
- : token("punc", ".");
- };
-
- function read_word() {
- var word = read_name();
- return !HOP(KEYWORDS, word)
- ? token("name", word)
- : HOP(OPERATORS, word)
- ? token("operator", word)
- : HOP(KEYWORDS_ATOM, word)
- ? token("atom", word)
- : token("keyword", word);
- };
-
- function with_eof_error(eof_error, cont) {
- try {
- return cont();
- } catch(ex) {
- if (ex === EX_EOF) parse_error(eof_error);
- else throw ex;
- }
- };
-
- function next_token(force_regexp) {
- if (force_regexp)
- return read_regexp();
- skip_whitespace();
- start_token();
- var ch = peek();
- if (!ch) return token("eof");
- if (is_digit(ch)) return read_num();
- if (ch == '"' || ch == "'") return read_string();
- if (HOP(PUNC_CHARS, ch)) return token("punc", next());
- if (ch == ".") return handle_dot();
- if (ch == "/") return handle_slash();
- if (HOP(OPERATOR_CHARS, ch)) return read_operator();
- if (ch == "\\" || is_identifier_start(ch)) return read_word();
- parse_error("Unexpected character '" + ch + "'");
- };
-
- next_token.context = function(nc) {
- if (nc) S = nc;
- return S;
- };
-
- return next_token;
-
-};
-
-/* -----[ Parser (constants) ]----- */
-
-var UNARY_PREFIX = array_to_hash([
- "typeof",
- "void",
- "delete",
- "--",
- "++",
- "!",
- "~",
- "-",
- "+"
-]);
-
-var UNARY_POSTFIX = array_to_hash([ "--", "++" ]);
-
-var ASSIGNMENT = (function(a, ret, i){
- while (i < a.length) {
- ret[a[i]] = a[i].substr(0, a[i].length - 1);
- i++;
- }
- return ret;
-})(
- ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="],
- { "=": true },
- 0
-);
-
-var PRECEDENCE = (function(a, ret){
- for (var i = 0, n = 1; i < a.length; ++i, ++n) {
- var b = a[i];
- for (var j = 0; j < b.length; ++j) {
- ret[b[j]] = n;
- }
- }
- return ret;
-})(
- [
- ["||"],
- ["&&"],
- ["|"],
- ["^"],
- ["&"],
- ["==", "===", "!=", "!=="],
- ["<", ">", "<=", ">=", "in", "instanceof"],
- [">>", "<<", ">>>"],
- ["+", "-"],
- ["*", "/", "%"]
- ],
- {}
-);
-
-var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
-
-var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
-
-/* -----[ Parser ]----- */
-
-function NodeWithToken(str, start, end) {
- this.name = str;
- this.start = start;
- this.end = end;
-};
-
-NodeWithToken.prototype.toString = function() { return this.name; };
-
-function parse($TEXT, exigent_mode, embed_tokens) {
-
- var S = {
- input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT,
- token : null,
- prev : null,
- peeked : null,
- in_function : 0,
- in_loop : 0,
- labels : []
- };
-
- S.token = next();
-
- function is(type, value) {
- return is_token(S.token, type, value);
- };
-
- function peek() { return S.peeked || (S.peeked = S.input()); };
-
- function next() {
- S.prev = S.token;
- if (S.peeked) {
- S.token = S.peeked;
- S.peeked = null;
- } else {
- S.token = S.input();
- }
- return S.token;
- };
-
- function prev() {
- return S.prev;
- };
-
- function croak(msg, line, col, pos) {
- var ctx = S.input.context();
- js_error(msg,
- line != null ? line : ctx.tokline,
- col != null ? col : ctx.tokcol,
- pos != null ? pos : ctx.tokpos);
- };
-
- function token_error(token, msg) {
- croak(msg, token.line, token.col);
- };
-
- function unexpected(token) {
- if (token == null)
- token = S.token;
- token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
- };
-
- function expect_token(type, val) {
- if (is(type, val)) {
- return next();
- }
- token_error(S.token, "Unexpected token " + S.token.type + ", expected " + type);
- };
-
- function expect(punc) { return expect_token("punc", punc); };
-
- function can_insert_semicolon() {
- return !exigent_mode && (
- S.token.nlb || is("eof") || is("punc", "}")
- );
- };
-
- function semicolon() {
- if (is("punc", ";")) next();
- else if (!can_insert_semicolon()) unexpected();
- };
-
- function as() {
- return slice(arguments);
- };
-
- function parenthesised() {
- expect("(");
- var ex = expression();
- expect(")");
- return ex;
- };
-
- function add_tokens(str, start, end) {
- return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end);
- };
-
- function maybe_embed_tokens(parser) {
- if (embed_tokens) return function() {
- var start = S.token;
- var ast = parser.apply(this, arguments);
- ast[0] = add_tokens(ast[0], start, prev());
- return ast;
- };
- else return parser;
- };
-
- var statement = maybe_embed_tokens(function() {
- if (is("operator", "/")) {
- S.peeked = null;
- S.token = S.input(true); // force regexp
- }
- switch (S.token.type) {
- case "num":
- case "string":
- case "regexp":
- case "operator":
- case "atom":
- return simple_statement();
-
- case "name":
- return is_token(peek(), "punc", ":")
- ? labeled_statement(prog1(S.token.value, next, next))
- : simple_statement();
-
- case "punc":
- switch (S.token.value) {
- case "{":
- return as("block", block_());
- case "[":
- case "(":
- return simple_statement();
- case ";":
- next();
- return as("block");
- default:
- unexpected();
- }
-
- case "keyword":
- switch (prog1(S.token.value, next)) {
- case "break":
- return break_cont("break");
-
- case "continue":
- return break_cont("continue");
-
- case "debugger":
- semicolon();
- return as("debugger");
-
- case "do":
- return (function(body){
- expect_token("keyword", "while");
- return as("do", prog1(parenthesised, semicolon), body);
- })(in_loop(statement));
-
- case "for":
- return for_();
-
- case "function":
- return function_(true);
-
- case "if":
- return if_();
-
- case "return":
- if (S.in_function == 0)
- croak("'return' outside of function");
- return as("return",
- is("punc", ";")
- ? (next(), null)
- : can_insert_semicolon()
- ? null
- : prog1(expression, semicolon));
-
- case "switch":
- return as("switch", parenthesised(), switch_block_());
-
- case "throw":
- return as("throw", prog1(expression, semicolon));
-
- case "try":
- return try_();
-
- case "var":
- return prog1(var_, semicolon);
-
- case "const":
- return prog1(const_, semicolon);
-
- case "while":
- return as("while", parenthesised(), in_loop(statement));
-
- case "with":
- return as("with", parenthesised(), statement());
-
- default:
- unexpected();
- }
- }
- });
-
- function labeled_statement(label) {
- S.labels.push(label);
- var start = S.token, stat = statement();
- if (exigent_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0]))
- unexpected(start);
- S.labels.pop();
- return as("label", label, stat);
- };
-
- function simple_statement() {
- return as("stat", prog1(expression, semicolon));
- };
-
- function break_cont(type) {
- var name;
- if (!can_insert_semicolon()) {
- name = is("name") ? S.token.value : null;
- }
- if (name != null) {
- next();
- if (!member(name, S.labels))
- croak("Label " + name + " without matching loop or statement");
- }
- else if (S.in_loop == 0)
- croak(type + " not inside a loop or switch");
- semicolon();
- return as(type, name);
- };
-
- function for_() {
- expect("(");
- var init = null;
- if (!is("punc", ";")) {
- init = is("keyword", "var")
- ? (next(), var_(true))
- : expression(true, true);
- if (is("operator", "in"))
- return for_in(init);
- }
- return regular_for(init);
- };
-
- function regular_for(init) {
- expect(";");
- var test = is("punc", ";") ? null : expression();
- expect(";");
- var step = is("punc", ")") ? null : expression();
- expect(")");
- return as("for", init, test, step, in_loop(statement));
- };
-
- function for_in(init) {
- var lhs = init[0] == "var" ? as("name", init[1][0]) : init;
- next();
- var obj = expression();
- expect(")");
- return as("for-in", init, lhs, obj, in_loop(statement));
- };
-
- var function_ = maybe_embed_tokens(function(in_statement) {
- var name = is("name") ? prog1(S.token.value, next) : null;
- if (in_statement && !name)
- unexpected();
- expect("(");
- return as(in_statement ? "defun" : "function",
- name,
- // arguments
- (function(first, a){
- while (!is("punc", ")")) {
- if (first) first = false; else expect(",");
- if (!is("name")) unexpected();
- a.push(S.token.value);
- next();
- }
- next();
- return a;
- })(true, []),
- // body
- (function(){
- ++S.in_function;
- var loop = S.in_loop;
- S.in_loop = 0;
- var a = block_();
- --S.in_function;
- S.in_loop = loop;
- return a;
- })());
- });
-
- function if_() {
- var cond = parenthesised(), body = statement(), belse;
- if (is("keyword", "else")) {
- next();
- belse = statement();
- }
- return as("if", cond, body, belse);
- };
-
- function block_() {
- expect("{");
- var a = [];
- while (!is("punc", "}")) {
- if (is("eof")) unexpected();
- a.push(statement());
- }
- next();
- return a;
- };
-
- var switch_block_ = curry(in_loop, function(){
- expect("{");
- var a = [], cur = null;
- while (!is("punc", "}")) {
- if (is("eof")) unexpected();
- if (is("keyword", "case")) {
- next();
- cur = [];
- a.push([ expression(), cur ]);
- expect(":");
- }
- else if (is("keyword", "default")) {
- next();
- expect(":");
- cur = [];
- a.push([ null, cur ]);
- }
- else {
- if (!cur) unexpected();
- cur.push(statement());
- }
- }
- next();
- return a;
- });
-
- function try_() {
- var body = block_(), bcatch, bfinally;
- if (is("keyword", "catch")) {
- next();
- expect("(");
- if (!is("name"))
- croak("Name expected");
- var name = S.token.value;
- next();
- expect(")");
- bcatch = [ name, block_() ];
- }
- if (is("keyword", "finally")) {
- next();
- bfinally = block_();
- }
- if (!bcatch && !bfinally)
- croak("Missing catch/finally blocks");
- return as("try", body, bcatch, bfinally);
- };
-
- function vardefs(no_in) {
- var a = [];
- for (;;) {
- if (!is("name"))
- unexpected();
- var name = S.token.value;
- next();
- if (is("operator", "=")) {
- next();
- a.push([ name, expression(false, no_in) ]);
- } else {
- a.push([ name ]);
- }
- if (!is("punc", ","))
- break;
- next();
- }
- return a;
- };
-
- function var_(no_in) {
- return as("var", vardefs(no_in));
- };
-
- function const_() {
- return as("const", vardefs());
- };
-
- function new_() {
- var newexp = expr_atom(false), args;
- if (is("punc", "(")) {
- next();
- args = expr_list(")");
- } else {
- args = [];
- }
- return subscripts(as("new", newexp, args), true);
- };
-
- var expr_atom = maybe_embed_tokens(function(allow_calls) {
- if (is("operator", "new")) {
- next();
- return new_();
- }
- if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
- return make_unary("unary-prefix",
- prog1(S.token.value, next),
- expr_atom(allow_calls));
- }
- if (is("punc")) {
- switch (S.token.value) {
- case "(":
- next();
- return subscripts(prog1(expression, curry(expect, ")")), allow_calls);
- case "[":
- next();
- return subscripts(array_(), allow_calls);
- case "{":
- next();
- return subscripts(object_(), allow_calls);
- }
- unexpected();
- }
- if (is("keyword", "function")) {
- next();
- return subscripts(function_(false), allow_calls);
- }
- if (HOP(ATOMIC_START_TOKEN, S.token.type)) {
- var atom = S.token.type == "regexp"
- ? as("regexp", S.token.value[0], S.token.value[1])
- : as(S.token.type, S.token.value);
- return subscripts(prog1(atom, next), allow_calls);
- }
- unexpected();
- });
-
- function expr_list(closing, allow_trailing_comma, allow_empty) {
- var first = true, a = [];
- while (!is("punc", closing)) {
- if (first) first = false; else expect(",");
- if (allow_trailing_comma && is("punc", closing)) break;
- if (is("punc", ",") && allow_empty) {
- a.push([ "atom", "undefined" ]);
- } else {
- a.push(expression(false));
- }
- }
- next();
- return a;
- };
-
- function array_() {
- return as("array", expr_list("]", !exigent_mode, true));
- };
-
- function object_() {
- var first = true, a = [];
- while (!is("punc", "}")) {
- if (first) first = false; else expect(",");
- if (!exigent_mode && is("punc", "}"))
- // allow trailing comma
- break;
- var type = S.token.type;
- var name = as_property_name();
- if (type == "name" && (name == "get" || name == "set") && !is("punc", ":")) {
- a.push([ as_name(), function_(false), name ]);
- } else {
- expect(":");
- a.push([ name, expression(false) ]);
- }
- }
- next();
- return as("object", a);
- };
-
- function as_property_name() {
- switch (S.token.type) {
- case "num":
- case "string":
- return prog1(S.token.value, next);
- }
- return as_name();
- };
-
- function as_name() {
- switch (S.token.type) {
- case "name":
- case "operator":
- case "keyword":
- case "atom":
- return prog1(S.token.value, next);
- default:
- unexpected();
- }
- };
-
- function subscripts(expr, allow_calls) {
- if (is("punc", ".")) {
- next();
- return subscripts(as("dot", expr, as_name()), allow_calls);
- }
- if (is("punc", "[")) {
- next();
- return subscripts(as("sub", expr, prog1(expression, curry(expect, "]"))), allow_calls);
- }
- if (allow_calls && is("punc", "(")) {
- next();
- return subscripts(as("call", expr, expr_list(")")), true);
- }
- if (allow_calls && is("operator") && HOP(UNARY_POSTFIX, S.token.value)) {
- return prog1(curry(make_unary, "unary-postfix", S.token.value, expr),
- next);
- }
- return expr;
- };
-
- function make_unary(tag, op, expr) {
- if ((op == "++" || op == "--") && !is_assignable(expr))
- croak("Invalid use of " + op + " operator");
- return as(tag, op, expr);
- };
-
- function expr_op(left, min_prec, no_in) {
- var op = is("operator") ? S.token.value : null;
- if (op && op == "in" && no_in) op = null;
- var prec = op != null ? PRECEDENCE[op] : null;
- if (prec != null && prec > min_prec) {
- next();
- var right = expr_op(expr_atom(true), prec, no_in);
- return expr_op(as("binary", op, left, right), min_prec, no_in);
- }
- return left;
- };
-
- function expr_ops(no_in) {
- return expr_op(expr_atom(true), 0, no_in);
- };
-
- function maybe_conditional(no_in) {
- var expr = expr_ops(no_in);
- if (is("operator", "?")) {
- next();
- var yes = expression(false);
- expect(":");
- return as("conditional", expr, yes, expression(false, no_in));
- }
- return expr;
- };
-
- function is_assignable(expr) {
- if (!exigent_mode) return true;
- switch (expr[0]) {
- case "dot":
- case "sub":
- case "new":
- case "call":
- return true;
- case "name":
- return expr[1] != "this";
- }
- };
-
- function maybe_assign(no_in) {
- var left = maybe_conditional(no_in), val = S.token.value;
- if (is("operator") && HOP(ASSIGNMENT, val)) {
- if (is_assignable(left)) {
- next();
- return as("assign", ASSIGNMENT[val], left, maybe_assign(no_in));
- }
- croak("Invalid assignment");
- }
- return left;
- };
-
- var expression = maybe_embed_tokens(function(commas, no_in) {
- if (arguments.length == 0)
- commas = true;
- var expr = maybe_assign(no_in);
- if (commas && is("punc", ",")) {
- next();
- return as("seq", expr, expression(true, no_in));
- }
- return expr;
- });
-
- function in_loop(cont) {
- try {
- ++S.in_loop;
- return cont();
- } finally {
- --S.in_loop;
- }
- };
-
- return as("toplevel", (function(a){
- while (!is("eof"))
- a.push(statement());
- return a;
- })([]));
-
-};
-
-/* -----[ Utilities ]----- */
-
-function curry(f) {
- var args = slice(arguments, 1);
- return function() { return f.apply(this, args.concat(slice(arguments))); };
-};
-
-function prog1(ret) {
- if (ret instanceof Function)
- ret = ret();
- for (var i = 1, n = arguments.length; --n > 0; ++i)
- arguments[i]();
- return ret;
-};
-
-function array_to_hash(a) {
- var ret = {};
- for (var i = 0; i < a.length; ++i)
- ret[a[i]] = true;
- return ret;
-};
-
-function slice(a, start) {
- return Array.prototype.slice.call(a, start || 0);
-};
-
-function characters(str) {
- return str.split("");
-};
-
-function member(name, array) {
- for (var i = array.length; --i >= 0;)
- if (array[i] === name)
- return true;
- return false;
-};
-
-function HOP(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
-};
-
-/* -----[ helper for AST traversal ]----- */
-
-function ast_walker() {
- function _vardefs(defs) {
- return [ this[0], MAP(defs, function(def){
- var a = [ def[0] ];
- if (def.length > 1)
- a[1] = walk(def[1]);
- return a;
- }) ];
- };
- function _block(statements) {
- var out = [ this[0] ];
- if (statements != null)
- out.push(MAP(statements, walk));
- return out;
- };
- var walkers = {
- "string": function(str) {
- return [ this[0], str ];
- },
- "num": function(num) {
- return [ this[0], num ];
- },
- "name": function(name) {
- return [ this[0], name ];
- },
- "toplevel": function(statements) {
- return [ this[0], MAP(statements, walk) ];
- },
- "block": _block,
- "splice": _block,
- "var": _vardefs,
- "const": _vardefs,
- "try": function(t, c, f) {
- return [
- this[0],
- MAP(t, walk),
- c != null ? [ c[0], MAP(c[1], walk) ] : null,
- f != null ? MAP(f, walk) : null
- ];
- },
- "throw": function(expr) {
- return [ this[0], walk(expr) ];
- },
- "new": function(ctor, args) {
- return [ this[0], walk(ctor), MAP(args, walk) ];
- },
- "switch": function(expr, body) {
- return [ this[0], walk(expr), MAP(body, function(branch){
- return [ branch[0] ? walk(branch[0]) : null,
- MAP(branch[1], walk) ];
- }) ];
- },
- "break": function(label) {
- return [ this[0], label ];
- },
- "continue": function(label) {
- return [ this[0], label ];
- },
- "conditional": function(cond, t, e) {
- return [ this[0], walk(cond), walk(t), walk(e) ];
- },
- "assign": function(op, lvalue, rvalue) {
- return [ this[0], op, walk(lvalue), walk(rvalue) ];
- },
- "dot": function(expr) {
- return [ this[0], walk(expr) ].concat(slice(arguments, 1));
- },
- "call": function(expr, args) {
- return [ this[0], walk(expr), MAP(args, walk) ];
- },
- "function": function(name, args, body) {
- return [ this[0], name, args.slice(), MAP(body, walk) ];
- },
- "defun": function(name, args, body) {
- return [ this[0], name, args.slice(), MAP(body, walk) ];
- },
- "if": function(conditional, t, e) {
- return [ this[0], walk(conditional), walk(t), walk(e) ];
- },
- "for": function(init, cond, step, block) {
- return [ this[0], walk(init), walk(cond), walk(step), walk(block) ];
- },
- "for-in": function(vvar, key, hash, block) {
- return [ this[0], walk(vvar), walk(key), walk(hash), walk(block) ];
- },
- "while": function(cond, block) {
- return [ this[0], walk(cond), walk(block) ];
- },
- "do": function(cond, block) {
- return [ this[0], walk(cond), walk(block) ];
- },
- "return": function(expr) {
- return [ this[0], walk(expr) ];
- },
- "binary": function(op, left, right) {
- return [ this[0], op, walk(left), walk(right) ];
- },
- "unary-prefix": function(op, expr) {
- return [ this[0], op, walk(expr) ];
- },
- "unary-postfix": function(op, expr) {
- return [ this[0], op, walk(expr) ];
- },
- "sub": function(expr, subscript) {
- return [ this[0], walk(expr), walk(subscript) ];
- },
- "object": function(props) {
- return [ this[0], MAP(props, function(p){
- return p.length == 2
- ? [ p[0], walk(p[1]) ]
- : [ p[0], walk(p[1]), p[2] ]; // get/set-ter
- }) ];
- },
- "regexp": function(rx, mods) {
- return [ this[0], rx, mods ];
- },
- "array": function(elements) {
- return [ this[0], MAP(elements, walk) ];
- },
- "stat": function(stat) {
- return [ this[0], walk(stat) ];
- },
- "seq": function() {
- return [ this[0] ].concat(MAP(slice(arguments), walk));
- },
- "label": function(name, block) {
- return [ this[0], name, walk(block) ];
- },
- "with": function(expr, block) {
- return [ this[0], walk(expr), walk(block) ];
- },
- "atom": function(name) {
- return [ this[0], name ];
- }
- };
-
- var user = {};
- var stack = [];
- function walk(ast) {
- if (ast == null)
- return null;
- try {
- stack.push(ast);
- var type = ast[0];
- var gen = user[type];
- if (gen) {
- var ret = gen.apply(ast, ast.slice(1));
- if (ret != null)
- return ret;
- }
- gen = walkers[type];
- return gen.apply(ast, ast.slice(1));
- } finally {
- stack.pop();
- }
- };
-
- function with_walkers(walkers, cont){
- var save = {}, i;
- for (i in walkers) if (HOP(walkers, i)) {
- save[i] = user[i];
- user[i] = walkers[i];
- }
- var ret = cont();
- for (i in save) if (HOP(save, i)) {
- if (!save[i]) delete user[i];
- else user[i] = save[i];
- }
- return ret;
- };
-
- return {
- walk: walk,
- with_walkers: with_walkers,
- parent: function() {
- return stack[stack.length - 2]; // last one is current node
- },
- stack: function() {
- return stack;
- }
- };
-};
-
-function empty(b) {
- return !b || (b[0] == "block" && (!b[1] || b[1].length == 0));
-};
-
-/* -----[ re-generate code from the AST ]----- */
-
-var DOT_CALL_NO_PARENS = array_to_hash([
- "name",
- "array",
- "object",
- "string",
- "dot",
- "sub",
- "call",
- "regexp"
-]);
-
-function make_string(str, ascii_only) {
- var dq = 0, sq = 0;
- str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029]/g, function(s){
- switch (s) {
- case "\\": return "\\\\";
- case "\b": return "\\b";
- case "\f": return "\\f";
- case "\n": return "\\n";
- case "\r": return "\\r";
- case "\t": return "\\t";
- case "\u2028": return "\\u2028";
- case "\u2029": return "\\u2029";
- case '"': ++dq; return '"';
- case "'": ++sq; return "'";
- }
- return s;
- });
- if (ascii_only) str = to_ascii(str);
- if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'";
- else return '"' + str.replace(/\x22/g, '\\"') + '"';
-};
-
-function to_ascii(str) {
- return str.replace(/[\u0080-\uffff]/g, function(ch) {
- var code = ch.charCodeAt(0).toString(16);
- while (code.length < 4) code = "0" + code;
- return "\\u" + code;
- });
-};
-
-var SPLICE_NEEDS_BRACKETS = array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]);
-
-function gen_code(ast, options) {
- options = defaults(options, {
- indent_start : 0,
- indent_level : 4,
- quote_keys : false,
- space_colon : false,
- beautify : false,
- ascii_only : false,
- inline_script: false
- });
- var beautify = !!options.beautify;
- var indentation = 0,
- newline = beautify ? "\n" : "",
- space = beautify ? " " : "";
-
- function encode_string(str) {
- var ret = make_string(str, options.ascii_only);
- if (options.inline_script)
- ret = ret.replace(/<\x2fscript([>/\t\n\f\r ])/gi, "<\\/script$1");
- return ret;
- };
-
- function make_name(name) {
- name = name.toString();
- if (options.ascii_only)
- name = to_ascii(name);
- return name;
- };
-
- function indent(line) {
- if (line == null)
- line = "";
- if (beautify)
- line = repeat_string(" ", options.indent_start + indentation * options.indent_level) + line;
- return line;
- };
-
- function with_indent(cont, incr) {
- if (incr == null) incr = 1;
- indentation += incr;
- try { return cont.apply(null, slice(arguments, 1)); }
- finally { indentation -= incr; }
- };
-
- function add_spaces(a) {
- if (beautify)
- return a.join(" ");
- var b = [];
- for (var i = 0; i < a.length; ++i) {
- var next = a[i + 1];
- b.push(a[i]);
- if (next &&
- ((/[a-z0-9_\x24]$/i.test(a[i].toString()) && /^[a-z0-9_\x24]/i.test(next.toString())) ||
- (/[\+\-]$/.test(a[i].toString()) && /^[\+\-]/.test(next.toString())))) {
- b.push(" ");
- }
- }
- return b.join("");
- };
-
- function add_commas(a) {
- return a.join("," + space);
- };
-
- function parenthesize(expr) {
- var gen = make(expr);
- for (var i = 1; i < arguments.length; ++i) {
- var el = arguments[i];
- if ((el instanceof Function && el(expr)) || expr[0] == el)
- return "(" + gen + ")";
- }
- return gen;
- };
-
- function best_of(a) {
- if (a.length == 1) {
- return a[0];
- }
- if (a.length == 2) {
- var b = a[1];
- a = a[0];
- return a.length <= b.length ? a : b;
- }
- return best_of([ a[0], best_of(a.slice(1)) ]);
- };
-
- function needs_parens(expr) {
- if (expr[0] == "function" || expr[0] == "object") {
- // dot/call on a literal function requires the
- // function literal itself to be parenthesized
- // only if it's the first "thing" in a
- // statement. This means that the parent is
- // "stat", but it could also be a "seq" and
- // we're the first in this "seq" and the
- // parent is "stat", and so on. Messy stuff,
- // but it worths the trouble.
- var a = slice($stack), self = a.pop(), p = a.pop();
- while (p) {
- if (p[0] == "stat") return true;
- if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) ||
- ((p[0] == "binary" || p[0] == "assign" || p[0] == "unary-postfix") && p[2] === self)) {
- self = p;
- p = a.pop();
- } else {
- return false;
- }
- }
- }
- return !HOP(DOT_CALL_NO_PARENS, expr[0]);
- };
-
- function make_num(num) {
- var str = num.toString(10), a = [ str.replace(/^0\./, ".") ], m;
- if (Math.floor(num) === num) {
- a.push("0x" + num.toString(16).toLowerCase(), // probably pointless
- "0" + num.toString(8)); // same.
- if ((m = /^(.*?)(0+)$/.exec(num))) {
- a.push(m[1] + "e" + m[2].length);
- }
- } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
- a.push(m[2] + "e-" + (m[1].length + m[2].length),
- str.substr(str.indexOf(".")));
- }
- return best_of(a);
- };
-
- var generators = {
- "string": encode_string,
- "num": make_num,
- "name": make_name,
- "toplevel": function(statements) {
- return make_block_statements(statements)
- .join(newline);
- },
- "splice": function(statements) {
- var parent = $stack[$stack.length - 2][0];
- if (HOP(SPLICE_NEEDS_BRACKETS, parent)) {
- // we need block brackets in this case
- return make_block.apply(this, arguments);
- } else {
- return MAP(make_block_statements(statements, true),
- function(line, i) {
- // the first line is already indented
- return i > 0 ? indent(line) : line;
- }).join(newline);
- }
- },
- "block": make_block,
- "var": function(defs) {
- return "var " + add_commas(MAP(defs, make_1vardef)) + ";";
- },
- "const": function(defs) {
- return "const " + add_commas(MAP(defs, make_1vardef)) + ";";
- },
- "try": function(tr, ca, fi) {
- var out = [ "try", make_block(tr) ];
- if (ca) out.push("catch", "(" + ca[0] + ")", make_block(ca[1]));
- if (fi) out.push("finally", make_block(fi));
- return add_spaces(out);
- },
- "throw": function(expr) {
- return add_spaces([ "throw", make(expr) ]) + ";";
- },
- "new": function(ctor, args) {
- args = args.length > 0 ? "(" + add_commas(MAP(args, make)) + ")" : "";
- return add_spaces([ "new", parenthesize(ctor, "seq", "binary", "conditional", "assign", function(expr){
- var w = ast_walker(), has_call = {};
- try {
- w.with_walkers({
- "call": function() { throw has_call },
- "function": function() { return this }
- }, function(){
- w.walk(expr);
- });
- } catch(ex) {
- if (ex === has_call)
- return true;
- throw ex;
- }
- }) + args ]);
- },
- "switch": function(expr, body) {
- return add_spaces([ "switch", "(" + make(expr) + ")", make_switch_block(body) ]);
- },
- "break": function(label) {
- var out = "break";
- if (label != null)
- out += " " + make_name(label);
- return out + ";";
- },
- "continue": function(label) {
- var out = "continue";
- if (label != null)
- out += " " + make_name(label);
- return out + ";";
- },
- "conditional": function(co, th, el) {
- return add_spaces([ parenthesize(co, "assign", "seq", "conditional"), "?",
- parenthesize(th, "seq"), ":",
- parenthesize(el, "seq") ]);
- },
- "assign": function(op, lvalue, rvalue) {
- if (op && op !== true) op += "=";
- else op = "=";
- return add_spaces([ make(lvalue), op, parenthesize(rvalue, "seq") ]);
- },
- "dot": function(expr) {
- var out = make(expr), i = 1;
- if (expr[0] == "num") {
- if (!/\./.test(expr[1]))
- out += ".";
- } else if (needs_parens(expr))
- out = "(" + out + ")";
- while (i < arguments.length)
- out += "." + make_name(arguments[i++]);
- return out;
- },
- "call": function(func, args) {
- var f = make(func);
- if (needs_parens(func))
- f = "(" + f + ")";
- return f + "(" + add_commas(MAP(args, function(expr){
- return parenthesize(expr, "seq");
- })) + ")";
- },
- "function": make_function,
- "defun": make_function,
- "if": function(co, th, el) {
- var out = [ "if", "(" + make(co) + ")", el ? make_then(th) : make(th) ];
- if (el) {
- out.push("else", make(el));
- }
- return add_spaces(out);
- },
- "for": function(init, cond, step, block) {
- var out = [ "for" ];
- init = (init != null ? make(init) : "").replace(/;*\s*$/, ";" + space);
- cond = (cond != null ? make(cond) : "").replace(/;*\s*$/, ";" + space);
- step = (step != null ? make(step) : "").replace(/;*\s*$/, "");
- var args = init + cond + step;
- if (args == "; ; ") args = ";;";
- out.push("(" + args + ")", make(block));
- return add_spaces(out);
- },
- "for-in": function(vvar, key, hash, block) {
- return add_spaces([ "for", "(" +
- (vvar ? make(vvar).replace(/;+$/, "") : make(key)),
- "in",
- make(hash) + ")", make(block) ]);
- },
- "while": function(condition, block) {
- return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]);
- },
- "do": function(condition, block) {
- return add_spaces([ "do", make(block), "while", "(" + make(condition) + ")" ]) + ";";
- },
- "return": function(expr) {
- var out = [ "return" ];
- if (expr != null) out.push(make(expr));
- return add_spaces(out) + ";";
- },
- "binary": function(operator, lvalue, rvalue) {
- var left = make(lvalue), right = make(rvalue);
- // XXX: I'm pretty sure other cases will bite here.
- // we need to be smarter.
- // adding parens all the time is the safest bet.
- if (member(lvalue[0], [ "assign", "conditional", "seq" ]) ||
- lvalue[0] == "binary" && PRECEDENCE[operator] > PRECEDENCE[lvalue[1]]) {
- left = "(" + left + ")";
- }
- if (member(rvalue[0], [ "assign", "conditional", "seq" ]) ||
- rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]] &&
- !(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) {
- right = "(" + right + ")";
- }
- else if (!beautify && options.inline_script && (operator == "<" || operator == "<<")
- && rvalue[0] == "regexp" && /^script/i.test(rvalue[1])) {
- right = " " + right;
- }
- return add_spaces([ left, operator, right ]);
- },
- "unary-prefix": function(operator, expr) {
- var val = make(expr);
- if (!(expr[0] == "num" || (expr[0] == "unary-prefix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
- val = "(" + val + ")";
- return operator + (is_alphanumeric_char(operator.charAt(0)) ? " " : "") + val;
- },
- "unary-postfix": function(operator, expr) {
- var val = make(expr);
- if (!(expr[0] == "num" || (expr[0] == "unary-postfix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
- val = "(" + val + ")";
- return val + operator;
- },
- "sub": function(expr, subscript) {
- var hash = make(expr);
- if (needs_parens(expr))
- hash = "(" + hash + ")";
- return hash + "[" + make(subscript) + "]";
- },
- "object": function(props) {
- if (props.length == 0)
- return "{}";
- return "{" + newline + with_indent(function(){
- return MAP(props, function(p){
- if (p.length == 3) {
- // getter/setter. The name is in p[0], the arg.list in p[1][2], the
- // body in p[1][3] and type ("get" / "set") in p[2].
- return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
- }
- var key = p[0], val = parenthesize(p[1], "seq");
- if (options.quote_keys) {
- key = encode_string(key);
- } else if ((typeof key == "number" || !beautify && +key + "" == key)
- && parseFloat(key) >= 0) {
- key = make_num(+key);
- } else if (!is_identifier(key)) {
- key = encode_string(key);
- }
- return indent(add_spaces(beautify && options.space_colon
- ? [ key, ":", val ]
- : [ key + ":", val ]));
- }).join("," + newline);
- }) + newline + indent("}");
- },
- "regexp": function(rx, mods) {
- return "/" + rx + "/" + mods;
- },
- "array": function(elements) {
- if (elements.length == 0) return "[]";
- return add_spaces([ "[", add_commas(MAP(elements, function(el){
- if (!beautify && el[0] == "atom" && el[1] == "undefined") return "";
- return parenthesize(el, "seq");
- })), "]" ]);
- },
- "stat": function(stmt) {
- return make(stmt).replace(/;*\s*$/, ";");
- },
- "seq": function() {
- return add_commas(MAP(slice(arguments), make));
- },
- "label": function(name, block) {
- return add_spaces([ make_name(name), ":", make(block) ]);
- },
- "with": function(expr, block) {
- return add_spaces([ "with", "(" + make(expr) + ")", make(block) ]);
- },
- "atom": function(name) {
- return make_name(name);
- }
- };
-
- // The squeezer replaces "block"-s that contain only a single
- // statement with the statement itself; technically, the AST
- // is correct, but this can create problems when we output an
- // IF having an ELSE clause where the THEN clause ends in an
- // IF *without* an ELSE block (then the outer ELSE would refer
- // to the inner IF). This function checks for this case and
- // adds the block brackets if needed.
- function make_then(th) {
- if (th[0] == "do") {
- // https://github.com/mishoo/UglifyJS/issues/#issue/57
- // IE croaks with "syntax error" on code like this:
- // if (foo) do ... while(cond); else ...
- // we need block brackets around do/while
- return make([ "block", [ th ]]);
- }
- var b = th;
- while (true) {
- var type = b[0];
- if (type == "if") {
- if (!b[3])
- // no else, we must add the block
- return make([ "block", [ th ]]);
- b = b[3];
- }
- else if (type == "while" || type == "do") b = b[2];
- else if (type == "for" || type == "for-in") b = b[4];
- else break;
- }
- return make(th);
- };
-
- function make_function(name, args, body, keyword) {
- var out = keyword || "function";
- if (name) {
- out += " " + make_name(name);
- }
- out += "(" + add_commas(MAP(args, make_name)) + ")";
- return add_spaces([ out, make_block(body) ]);
- };
-
- function make_block_statements(statements, noindent) {
- for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
- var stat = statements[i];
- var code = make(stat);
- if (code != ";") {
- if (!beautify && i == last) {
- if ((stat[0] == "while" && empty(stat[2])) ||
- (member(stat[0], [ "for", "for-in"] ) && empty(stat[4])) ||
- (stat[0] == "if" && empty(stat[2]) && !stat[3]) ||
- (stat[0] == "if" && stat[3] && empty(stat[3]))) {
- code = code.replace(/;*\s*$/, ";");
- } else {
- code = code.replace(/;+\s*$/, "");
- }
- }
- a.push(code);
- }
- }
- return noindent ? a : MAP(a, indent);
- };
-
- function make_switch_block(body) {
- var n = body.length;
- if (n == 0) return "{}";
- return "{" + newline + MAP(body, function(branch, i){
- var has_body = branch[1].length > 0, code = with_indent(function(){
- return indent(branch[0]
- ? add_spaces([ "case", make(branch[0]) + ":" ])
- : "default:");
- }, 0.5) + (has_body ? newline + with_indent(function(){
- return make_block_statements(branch[1]).join(newline);
- }) : "");
- if (!beautify && has_body && i < n - 1)
- code += ";";
- return code;
- }).join(newline) + newline + indent("}");
- };
-
- function make_block(statements) {
- if (!statements) return ";";
- if (statements.length == 0) return "{}";
- return "{" + newline + with_indent(function(){
- return make_block_statements(statements).join(newline);
- }) + newline + indent("}");
- };
-
- function make_1vardef(def) {
- var name = def[0], val = def[1];
- if (val != null)
- name = add_spaces([ make_name(name), "=", parenthesize(val, "seq") ]);
- return name;
- };
-
- var $stack = [];
-
- function make(node) {
- var type = node[0];
- var gen = generators[type];
- if (!gen)
- throw new Error("Can't find generator for \"" + type + "\"");
- $stack.push(node);
- var ret = gen.apply(type, node.slice(1));
- $stack.pop();
- return ret;
- };
-
- return make(ast);
-};
-
-/* -----[ Utilities ]----- */
-
-function repeat_string(str, i) {
- return i < 1 ? "" : new Array(i + 1).join(str);
-};
-
-function defaults(args, defs) {
- var ret = {};
- if (args === true)
- args = {};
- for (var i in defs) if (HOP(defs, i)) {
- ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
- }
- return ret;
-};
-
-function is_identifier(name) {
- return /^[a-z_$][a-z0-9_$]*$/i.test(name)
- && name != "this"
- && !HOP(KEYWORDS_ATOM, name)
- && !HOP(RESERVED_WORDS, name)
- && !HOP(KEYWORDS, name);
-};
-
-function MAP(a, f, o) {
- var ret = [];
- for (var i = 0; i < a.length; ++i) {
- ret.push(f.call(o, a[i], i));
- }
- return ret;
-};
-
-/* -----[ Exports ]----- */
-
-return {
- parse: parse,
- gen_code: gen_code,
- tokenizer: tokenizer,
- ast_walker: ast_walker
-};
-
-};
diff --git a/lib/parse-js.js b/lib/parse-js.js
deleted file mode 100644
index 749b715b..00000000
--- a/lib/parse-js.js
+++ /dev/null
@@ -1,1916 +0,0 @@
-/**
- * A JavaScript tokenizer / parser / generator, originally written in Lisp.
- * Copyright (c) Marijn Haverbeke
- * http://marijn.haverbeke.nl/parse-js/
- *
- * Ported by to JavaScript by Mihai Bazon
- * Copyright (c) 2010, Mihai Bazon
- * http://mihai.bazon.net/blog/
- *
- * Modifications and adaptions to browser (c) 2011, Juerg Lehni
- * http://lehni.org/
- *
- * Distributed under the BSD license.
- */
-
-var parse_js = new function() {
-
-/* -----[ Tokenizer (constants) ]----- */
-
-var KEYWORDS = array_to_hash([
- "break",
- "case",
- "catch",
- "const",
- "continue",
- "default",
- "delete",
- "do",
- "else",
- "finally",
- "for",
- "function",
- "if",
- "in",
- "instanceof",
- "new",
- "return",
- "switch",
- "throw",
- "try",
- "typeof",
- "var",
- "void",
- "while",
- "with"
-]);
-
-var RESERVED_WORDS = array_to_hash([
- "abstract",
- "boolean",
- "byte",
- "char",
- "class",
- "debugger",
- "double",
- "enum",
- "export",
- "extends",
- "final",
- "float",
- "goto",
- "implements",
- "import",
- "int",
- "interface",
- "long",
- "native",
- "package",
- "private",
- "protected",
- "public",
- "short",
- "static",
- "super",
- "synchronized",
- "throws",
- "transient",
- "volatile"
-]);
-
-var KEYWORDS_BEFORE_EXPRESSION = array_to_hash([
- "return",
- "new",
- "delete",
- "throw",
- "else",
- "case"
-]);
-
-var KEYWORDS_ATOM = array_to_hash([
- "false",
- "null",
- "true",
- "undefined"
-]);
-
-var OPERATOR_CHARS = array_to_hash(characters("+-*&%=<>!?|~^"));
-
-var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
-var RE_OCT_NUMBER = /^0[0-7]+$/;
-var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
-
-var OPERATORS = array_to_hash([
- "in",
- "instanceof",
- "typeof",
- "new",
- "void",
- "delete",
- "++",
- "--",
- "+",
- "-",
- "!",
- "~",
- "&",
- "|",
- "^",
- "*",
- "/",
- "%",
- ">>",
- "<<",
- ">>>",
- "<",
- ">",
- "<=",
- ">=",
- "==",
- "===",
- "!=",
- "!==",
- "?",
- "=",
- "+=",
- "-=",
- "/=",
- "*=",
- "%=",
- ">>=",
- "<<=",
- ">>>=",
- "|=",
- "^=",
- "&=",
- "&&",
- "||"
-]);
-
-var WHITESPACE_CHARS = array_to_hash(characters(" \n\r\t"));
-
-var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:"));
-
-var PUNC_CHARS = array_to_hash(characters("[]{}(),;:"));
-
-var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy"));
-
-/* -----[ Tokenizer ]----- */
-
-function is_letter(ch) {
- ch = ch.charCodeAt(0);
- return (ch >= 65 && ch <= 90) ||
- (ch >= 97 && ch <= 122);
-};
-
-function is_digit(ch) {
- ch = ch.charCodeAt(0);
- return ch >= 48 && ch <= 57;
-};
-
-function is_alphanumeric_char(ch) {
- return is_digit(ch) || is_letter(ch);
-};
-
-function is_identifier_start(ch) {
- return ch == "$" || ch == "_" || is_letter(ch);
-};
-
-function is_identifier_char(ch) {
- return is_identifier_start(ch) || is_digit(ch);
-};
-
-function parse_js_number(num) {
- if (RE_HEX_NUMBER.test(num)) {
- return parseInt(num.substr(2), 16);
- } else if (RE_OCT_NUMBER.test(num)) {
- return parseInt(num.substr(1), 8);
- } else if (RE_DEC_NUMBER.test(num)) {
- return parseFloat(num);
- }
-};
-
-function JS_Parse_Error(message, line, col, pos) {
- this.message = message;
- this.line = line;
- this.col = col;
- this.pos = pos;
-};
-
-JS_Parse_Error.prototype.toString = function() {
- return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")";
-};
-
-function js_error(message, line, col, pos) {
- throw new JS_Parse_Error(message, line, col, pos);
-};
-
-function is_token(token, type, val) {
- return token.type == type && (val == null || token.value == val);
-};
-
-var EX_EOF = {};
-
-function tokenizer($TEXT) {
-
- var S = {
- text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''),
- pos : 0,
- tokpos : 0,
- line : 0,
- tokline : 0,
- col : 0,
- tokcol : 0,
- newline_before : false,
- regex_allowed : false,
- comments_before : []
- };
-
- function peek() { return S.text.charAt(S.pos); };
-
- function next(signal_eof) {
- var ch = S.text.charAt(S.pos++);
- if (signal_eof && !ch)
- throw EX_EOF;
- if (ch == "\n") {
- S.newline_before = true;
- ++S.line;
- S.col = 0;
- } else {
- ++S.col;
- }
- return ch;
- };
-
- function eof() {
- return !S.peek();
- };
-
- function find(what, signal_eof) {
- var pos = S.text.indexOf(what, S.pos);
- if (signal_eof && pos == -1) throw EX_EOF;
- return pos;
- };
-
- function start_token() {
- S.tokline = S.line;
- S.tokcol = S.col;
- S.tokpos = S.pos;
- };
-
- function token(type, value, is_comment) {
- S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) ||
- (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) ||
- (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value)));
- var ret = {
- type : type,
- value : value,
- line : S.tokline,
- col : S.tokcol,
- pos : S.tokpos,
- nlb : S.newline_before
- };
- if (!is_comment) {
- ret.comments_before = S.comments_before;
- S.comments_before = [];
- }
- S.newline_before = false;
- return ret;
- };
-
- function skip_whitespace() {
- while (HOP(WHITESPACE_CHARS, peek()))
- next();
- };
-
- function read_while(pred) {
- var ret = "", ch = peek(), i = 0;
- while (ch && pred(ch, i++)) {
- ret += next();
- ch = peek();
- }
- return ret;
- };
-
- function parse_error(err) {
- js_error(err, S.tokline, S.tokcol, S.tokpos);
- };
-
- function read_num(prefix) {
- var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
- var num = read_while(function(ch, i){
- if (ch == "x" || ch == "X") {
- if (has_x) return false;
- return has_x = true;
- }
- if (!has_x && (ch == "E" || ch == "e")) {
- if (has_e) return false;
- return has_e = after_e = true;
- }
- if (ch == "-") {
- if (after_e || (i == 0 && !prefix)) return true;
- return false;
- }
- if (ch == "+") return after_e;
- after_e = false;
- if (ch == ".") {
- if (!has_dot && !has_x)
- return has_dot = true;
- return false;
- }
- return is_alphanumeric_char(ch);
- });
- if (prefix)
- num = prefix + num;
- var valid = parse_js_number(num);
- if (!isNaN(valid)) {
- return token("num", valid);
- } else {
- parse_error("Invalid syntax: " + num);
- }
- };
-
- function read_escaped_char() {
- var ch = next(true);
- switch (ch) {
- case "n" : return "\n";
- case "r" : return "\r";
- case "t" : return "\t";
- case "b" : return "\b";
- case "v" : return "\v";
- case "f" : return "\f";
- case "0" : return "\0";
- case "x" : return String.fromCharCode(hex_bytes(2));
- case "u" : return String.fromCharCode(hex_bytes(4));
- case "\n": return "";
- default : return ch;
- }
- };
-
- function hex_bytes(n) {
- var num = 0;
- for (; n > 0; --n) {
- var digit = parseInt(next(true), 16);
- if (isNaN(digit))
- parse_error("Invalid hex-character pattern in string");
- num = (num << 4) | digit;
- }
- return num;
- };
-
- function read_string() {
- return with_eof_error("Unterminated string constant", function(){
- var quote = next(), ret = "";
- for (;;) {
- var ch = next(true);
- if (ch == "\\") ch = read_escaped_char();
- else if (ch == quote) break;
- ret += ch;
- }
- return token("string", ret);
- });
- };
-
- function read_line_comment() {
- next();
- var i = find("\n"), ret;
- if (i == -1) {
- ret = S.text.substr(S.pos);
- S.pos = S.text.length;
- } else {
- ret = S.text.substring(S.pos, i);
- S.pos = i;
- }
- return token("comment1", ret, true);
- };
-
- function read_multiline_comment() {
- next();
- return with_eof_error("Unterminated multiline comment", function(){
- var i = find("*/", true),
- text = S.text.substring(S.pos, i),
- tok = token("comment2", text, true);
- S.pos = i + 2;
- S.line += text.split("\n").length - 1;
- S.newline_before = text.indexOf("\n") >= 0;
- return tok;
- });
- };
-
- function read_regexp() {
- return with_eof_error("Unterminated regular expression", function(){
- var prev_backslash = false, regexp = "", ch, in_class = false;
- while ((ch = next(true))) if (prev_backslash) {
- regexp += "\\" + ch;
- prev_backslash = false;
- } else if (ch == "[") {
- in_class = true;
- regexp += ch;
- } else if (ch == "]" && in_class) {
- in_class = false;
- regexp += ch;
- } else if (ch == "/" && !in_class) {
- break;
- } else if (ch == "\\") {
- prev_backslash = true;
- } else {
- regexp += ch;
- }
- var mods = read_while(function(ch){
- return HOP(REGEXP_MODIFIERS, ch);
- });
- return token("regexp", [ regexp, mods ]);
- });
- };
-
- function read_operator(prefix) {
- function grow(op) {
- if (!peek()) return op;
- var bigger = op + peek();
- if (HOP(OPERATORS, bigger)) {
- next();
- return grow(bigger);
- } else {
- return op;
- }
- };
- return token("operator", grow(prefix || next()));
- };
-
- function handle_slash() {
- next();
- var regex_allowed = S.regex_allowed;
- switch (peek()) {
- case "/":
- S.comments_before.push(read_line_comment());
- S.regex_allowed = regex_allowed;
- return next_token();
- case "*":
- S.comments_before.push(read_multiline_comment());
- S.regex_allowed = regex_allowed;
- return next_token();
- }
- return S.regex_allowed ? read_regexp() : read_operator("/");
- };
-
- function handle_dot() {
- next();
- return is_digit(peek())
- ? read_num(".")
- : token("punc", ".");
- };
-
- function read_word() {
- var word = read_while(is_identifier_char);
- return !HOP(KEYWORDS, word)
- ? token("name", word)
- : HOP(OPERATORS, word)
- ? token("operator", word)
- : HOP(KEYWORDS_ATOM, word)
- ? token("atom", word)
- : token("keyword", word);
- };
-
- function with_eof_error(eof_error, cont) {
- try {
- return cont();
- } catch(ex) {
- if (ex === EX_EOF) parse_error(eof_error);
- else throw ex;
- }
- };
-
- function next_token(force_regexp) {
- if (force_regexp)
- return read_regexp();
- skip_whitespace();
- start_token();
- var ch = peek();
- if (!ch) return token("eof");
- if (is_digit(ch)) return read_num();
- if (ch == '"' || ch == "'") return read_string();
- if (HOP(PUNC_CHARS, ch)) return token("punc", next());
- if (ch == ".") return handle_dot();
- if (ch == "/") return handle_slash();
- if (HOP(OPERATOR_CHARS, ch)) return read_operator();
- if (ch == "\\" || is_identifier_start(ch)) return read_word();
- parse_error("Unexpected character '" + ch + "'");
- };
-
- next_token.context = function(nc) {
- if (nc) S = nc;
- return S;
- };
-
- return next_token;
-
-};
-
-/* -----[ Parser (constants) ]----- */
-
-var UNARY_PREFIX = array_to_hash([
- "typeof",
- "void",
- "delete",
- "--",
- "++",
- "!",
- "~",
- "-",
- "+"
-]);
-
-var UNARY_POSTFIX = array_to_hash([ "--", "++" ]);
-
-var ASSIGNMENT = (function(a, ret, i){
- while (i < a.length) {
- ret[a[i]] = a[i].substr(0, a[i].length - 1);
- i++;
- }
- return ret;
-})(
- ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="],
- { "=": true },
- 0
-);
-
-var PRECEDENCE = (function(a, ret){
- for (var i = 0, n = 1; i < a.length; ++i, ++n) {
- var b = a[i];
- for (var j = 0; j < b.length; ++j) {
- ret[b[j]] = n;
- }
- }
- return ret;
-})(
- [
- ["||"],
- ["&&"],
- ["|"],
- ["^"],
- ["&"],
- ["==", "===", "!=", "!=="],
- ["<", ">", "<=", ">=", "in", "instanceof"],
- [">>", "<<", ">>>"],
- ["+", "-"],
- ["*", "/", "%"]
- ],
- {}
-);
-
-var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
-
-var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
-
-/* -----[ Parser ]----- */
-
-function NodeWithToken(str, start, end) {
- this.name = str;
- this.start = start;
- this.end = end;
-};
-
-NodeWithToken.prototype.toString = function() { return this.name; };
-
-function parse($TEXT, exigent_mode, embed_tokens) {
-
- var S = {
- input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT,
- token : null,
- prev : null,
- peeked : null,
- in_function : 0,
- in_loop : 0,
- labels : []
- };
-
- S.token = next();
-
- function is(type, value) {
- return is_token(S.token, type, value);
- };
-
- function peek() { return S.peeked || (S.peeked = S.input()); };
-
- function next() {
- S.prev = S.token;
- if (S.peeked) {
- S.token = S.peeked;
- S.peeked = null;
- } else {
- S.token = S.input();
- }
- return S.token;
- };
-
- function prev() {
- return S.prev;
- };
-
- function croak(msg, line, col, pos) {
- var ctx = S.input.context();
- js_error(msg,
- line != null ? line : ctx.tokline,
- col != null ? col : ctx.tokcol,
- pos != null ? pos : ctx.tokpos);
- };
-
- function token_error(token, msg) {
- croak(msg, token.line, token.col);
- };
-
- function unexpected(token) {
- if (token == null)
- token = S.token;
- token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
- };
-
- function expect_token(type, val) {
- if (is(type, val)) {
- return next();
- }
- token_error(S.token, "Unexpected token " + S.token.type + ", expected " + type);
- };
-
- function expect(punc) { return expect_token("punc", punc); };
-
- function can_insert_semicolon() {
- return !exigent_mode && (
- S.token.nlb || is("eof") || is("punc", "}")
- );
- };
-
- function semicolon() {
- if (is("punc", ";")) next();
- else if (!can_insert_semicolon()) unexpected();
- };
-
- function as() {
- return slice(arguments);
- };
-
- function parenthesised() {
- expect("(");
- var ex = expression();
- expect(")");
- return ex;
- };
-
- function add_tokens(str, start, end) {
- return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end);
- };
-
- function maybe_embed_tokens(parser) {
- if (embed_tokens) return function() {
- var start = S.token;
- var ast = parser.apply(this, arguments);
- ast[0] = add_tokens(ast[0], start, prev());
- return ast;
- };
- else return parser;
- };
-
- var statement = maybe_embed_tokens(function() {
- if (is("operator", "/")) {
- S.peeked = null;
- S.token = S.input(true); // force regexp
- }
- switch (S.token.type) {
- case "num":
- case "string":
- case "regexp":
- case "operator":
- case "atom":
- return simple_statement();
-
- case "name":
- return is_token(peek(), "punc", ":")
- ? labeled_statement(prog1(S.token.value, next, next))
- : simple_statement();
-
- case "punc":
- switch (S.token.value) {
- case "{":
- return as("block", block_());
- case "[":
- case "(":
- return simple_statement();
- case ";":
- next();
- return as("block");
- default:
- unexpected();
- }
-
- case "keyword":
- switch (prog1(S.token.value, next)) {
- case "break":
- return break_cont("break");
-
- case "continue":
- return break_cont("continue");
-
- case "debugger":
- semicolon();
- return as("debugger");
-
- case "do":
- return (function(body){
- expect_token("keyword", "while");
- return as("do", prog1(parenthesised, semicolon), body);
- })(in_loop(statement));
-
- case "for":
- return for_();
-
- case "function":
- return function_(true);
-
- case "if":
- return if_();
-
- case "return":
- if (S.in_function == 0)
- croak("'return' outside of function");
- return as("return",
- is("punc", ";")
- ? (next(), null)
- : can_insert_semicolon()
- ? null
- : prog1(expression, semicolon));
-
- case "switch":
- return as("switch", parenthesised(), switch_block_());
-
- case "throw":
- return as("throw", prog1(expression, semicolon));
-
- case "try":
- return try_();
-
- case "var":
- return prog1(var_, semicolon);
-
- case "const":
- return prog1(const_, semicolon);
-
- case "while":
- return as("while", parenthesised(), in_loop(statement));
-
- case "with":
- return as("with", parenthesised(), statement());
-
- default:
- unexpected();
- }
- }
- });
-
- function labeled_statement(label) {
- S.labels.push(label);
- var start = S.token, stat = statement();
- if (exigent_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0]))
- unexpected(start);
- S.labels.pop();
- return as("label", label, stat);
- };
-
- function simple_statement() {
- return as("stat", prog1(expression, semicolon));
- };
-
- function break_cont(type) {
- var name;
- if (!can_insert_semicolon()) {
- name = is("name") ? S.token.value : null;
- }
- if (name != null) {
- next();
- if (!member(name, S.labels))
- croak("Label " + name + " without matching loop or statement");
- }
- else if (S.in_loop == 0)
- croak(type + " not inside a loop or switch");
- semicolon();
- return as(type, name);
- };
-
- function for_() {
- expect("(");
- var init = null;
- if (!is("punc", ";")) {
- init = is("keyword", "var")
- ? (next(), var_(true))
- : expression(true, true);
- if (is("operator", "in"))
- return for_in(init);
- }
- return regular_for(init);
- };
-
- function regular_for(init) {
- expect(";");
- var test = is("punc", ";") ? null : expression();
- expect(";");
- var step = is("punc", ")") ? null : expression();
- expect(")");
- return as("for", init, test, step, in_loop(statement));
- };
-
- function for_in(init) {
- var lhs = init[0] == "var" ? as("name", init[1][0]) : init;
- next();
- var obj = expression();
- expect(")");
- return as("for-in", init, lhs, obj, in_loop(statement));
- };
-
- var function_ = maybe_embed_tokens(function(in_statement) {
- var name = is("name") ? prog1(S.token.value, next) : null;
- if (in_statement && !name)
- unexpected();
- expect("(");
- return as(in_statement ? "defun" : "function",
- name,
- // arguments
- (function(first, a){
- while (!is("punc", ")")) {
- if (first) first = false; else expect(",");
- if (!is("name")) unexpected();
- a.push(S.token.value);
- next();
- }
- next();
- return a;
- })(true, []),
- // body
- (function(){
- ++S.in_function;
- var loop = S.in_loop;
- S.in_loop = 0;
- var a = block_();
- --S.in_function;
- S.in_loop = loop;
- return a;
- })());
- });
-
- function if_() {
- var cond = parenthesised(), body = statement(), belse;
- if (is("keyword", "else")) {
- next();
- belse = statement();
- }
- return as("if", cond, body, belse);
- };
-
- function block_() {
- expect("{");
- var a = [];
- while (!is("punc", "}")) {
- if (is("eof")) unexpected();
- a.push(statement());
- }
- next();
- return a;
- };
-
- var switch_block_ = curry(in_loop, function(){
- expect("{");
- var a = [], cur = null;
- while (!is("punc", "}")) {
- if (is("eof")) unexpected();
- if (is("keyword", "case")) {
- next();
- cur = [];
- a.push([ expression(), cur ]);
- expect(":");
- }
- else if (is("keyword", "default")) {
- next();
- expect(":");
- cur = [];
- a.push([ null, cur ]);
- }
- else {
- if (!cur) unexpected();
- cur.push(statement());
- }
- }
- next();
- return a;
- });
-
- function try_() {
- var body = block_(), bcatch, bfinally;
- if (is("keyword", "catch")) {
- next();
- expect("(");
- if (!is("name"))
- croak("Name expected");
- var name = S.token.value;
- next();
- expect(")");
- bcatch = [ name, block_() ];
- }
- if (is("keyword", "finally")) {
- next();
- bfinally = block_();
- }
- if (!bcatch && !bfinally)
- croak("Missing catch/finally blocks");
- return as("try", body, bcatch, bfinally);
- };
-
- function vardefs(no_in) {
- var a = [];
- for (;;) {
- if (!is("name"))
- unexpected();
- var name = S.token.value;
- next();
- if (is("operator", "=")) {
- next();
- a.push([ name, expression(false, no_in) ]);
- } else {
- a.push([ name ]);
- }
- if (!is("punc", ","))
- break;
- next();
- }
- return a;
- };
-
- function var_(no_in) {
- return as("var", vardefs(no_in));
- };
-
- function const_() {
- return as("const", vardefs());
- };
-
- function new_() {
- var newexp = expr_atom(false), args;
- if (is("punc", "(")) {
- next();
- args = expr_list(")");
- } else {
- args = [];
- }
- return subscripts(as("new", newexp, args), true);
- };
-
- var expr_atom = maybe_embed_tokens(function(allow_calls) {
- if (is("operator", "new")) {
- next();
- return new_();
- }
- if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
- return make_unary("unary-prefix",
- prog1(S.token.value, next),
- expr_atom(allow_calls));
- }
- if (is("punc")) {
- switch (S.token.value) {
- case "(":
- next();
- return subscripts(prog1(expression, curry(expect, ")")), allow_calls);
- case "[":
- next();
- return subscripts(array_(), allow_calls);
- case "{":
- next();
- return subscripts(object_(), allow_calls);
- }
- unexpected();
- }
- if (is("keyword", "function")) {
- next();
- return subscripts(function_(false), allow_calls);
- }
- if (HOP(ATOMIC_START_TOKEN, S.token.type)) {
- var atom = S.token.type == "regexp"
- ? as("regexp", S.token.value[0], S.token.value[1])
- : as(S.token.type, S.token.value);
- return subscripts(prog1(atom, next), allow_calls);
- }
- unexpected();
- });
-
- function expr_list(closing, allow_trailing_comma, allow_empty) {
- var first = true, a = [];
- while (!is("punc", closing)) {
- if (first) first = false; else expect(",");
- if (allow_trailing_comma && is("punc", closing)) break;
- if (is("punc", ",") && allow_empty) {
- a.push([ "atom", "undefined" ]);
- } else {
- a.push(expression(false));
- }
- }
- next();
- return a;
- };
-
- function array_() {
- return as("array", expr_list("]", !exigent_mode, true));
- };
-
- function object_() {
- var first = true, a = [];
- while (!is("punc", "}")) {
- if (first) first = false; else expect(",");
- if (!exigent_mode && is("punc", "}"))
- // allow trailing comma
- break;
- var type = S.token.type;
- var name = as_property_name();
- if (type == "name" && (name == "get" || name == "set") && !is("punc", ":")) {
- a.push([ as_name(), function_(false), name ]);
- } else {
- expect(":");
- a.push([ name, expression(false) ]);
- }
- }
- next();
- return as("object", a);
- };
-
- function as_property_name() {
- switch (S.token.type) {
- case "num":
- case "string":
- return prog1(S.token.value, next);
- }
- return as_name();
- };
-
- function as_name() {
- switch (S.token.type) {
- case "name":
- case "operator":
- case "keyword":
- case "atom":
- return prog1(S.token.value, next);
- default:
- unexpected();
- }
- };
-
- function subscripts(expr, allow_calls) {
- if (is("punc", ".")) {
- next();
- return subscripts(as("dot", expr, as_name()), allow_calls);
- }
- if (is("punc", "[")) {
- next();
- return subscripts(as("sub", expr, prog1(expression, curry(expect, "]"))), allow_calls);
- }
- if (allow_calls && is("punc", "(")) {
- next();
- return subscripts(as("call", expr, expr_list(")")), true);
- }
- if (allow_calls && is("operator") && HOP(UNARY_POSTFIX, S.token.value)) {
- return prog1(curry(make_unary, "unary-postfix", S.token.value, expr),
- next);
- }
- return expr;
- };
-
- function make_unary(tag, op, expr) {
- if ((op == "++" || op == "--") && !is_assignable(expr))
- croak("Invalid use of " + op + " operator");
- return as(tag, op, expr);
- };
-
- function expr_op(left, min_prec, no_in) {
- var op = is("operator") ? S.token.value : null;
- if (op && op == "in" && no_in) op = null;
- var prec = op != null ? PRECEDENCE[op] : null;
- if (prec != null && prec > min_prec) {
- next();
- var right = expr_op(expr_atom(true), prec, no_in);
- return expr_op(as("binary", op, left, right), min_prec, no_in);
- }
- return left;
- };
-
- function expr_ops(no_in) {
- return expr_op(expr_atom(true), 0, no_in);
- };
-
- function maybe_conditional(no_in) {
- var expr = expr_ops(no_in);
- if (is("operator", "?")) {
- next();
- var yes = expression(false);
- expect(":");
- return as("conditional", expr, yes, expression(false, no_in));
- }
- return expr;
- };
-
- function is_assignable(expr) {
- if (!exigent_mode) return true;
- switch (expr[0]) {
- case "dot":
- case "sub":
- case "new":
- case "call":
- return true;
- case "name":
- return expr[1] != "this";
- }
- };
-
- function maybe_assign(no_in) {
- var left = maybe_conditional(no_in), val = S.token.value;
- if (is("operator") && HOP(ASSIGNMENT, val)) {
- if (is_assignable(left)) {
- next();
- return as("assign", ASSIGNMENT[val], left, maybe_assign(no_in));
- }
- croak("Invalid assignment");
- }
- return left;
- };
-
- var expression = maybe_embed_tokens(function(commas, no_in) {
- if (arguments.length == 0)
- commas = true;
- var expr = maybe_assign(no_in);
- if (commas && is("punc", ",")) {
- next();
- return as("seq", expr, expression(true, no_in));
- }
- return expr;
- });
-
- function in_loop(cont) {
- try {
- ++S.in_loop;
- return cont();
- } finally {
- --S.in_loop;
- }
- };
-
- return as("toplevel", (function(a){
- while (!is("eof"))
- a.push(statement());
- return a;
- })([]));
-
-};
-
-/* -----[ Utilities ]----- */
-
-function curry(f) {
- var args = slice(arguments, 1);
- return function() { return f.apply(this, args.concat(slice(arguments))); };
-};
-
-function prog1(ret) {
- if (ret instanceof Function)
- ret = ret();
- for (var i = 1, n = arguments.length; --n > 0; ++i)
- arguments[i]();
- return ret;
-};
-
-function array_to_hash(a) {
- var ret = {};
- for (var i = 0; i < a.length; ++i)
- ret[a[i]] = true;
- return ret;
-};
-
-function slice(a, start) {
- return Array.prototype.slice.call(a, start || 0);
-};
-
-function characters(str) {
- return str.split("");
-};
-
-function member(name, array) {
- for (var i = array.length; --i >= 0;)
- if (array[i] === name)
- return true;
- return false;
-};
-
-function HOP(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
-};
-
-/* -----[ helper for AST traversal ]----- */
-
-function ast_walker() {
- function _vardefs(defs) {
- return [ this[0], MAP(defs, function(def){
- var a = [ def[0] ];
- if (def.length > 1)
- a[1] = walk(def[1]);
- return a;
- }) ];
- };
- function _block(statements) {
- var out = [ this[0] ];
- if (statements != null)
- out.push(MAP(statements, walk));
- return out;
- };
- var walkers = {
- "string": function(str) {
- return [ this[0], str ];
- },
- "num": function(num) {
- return [ this[0], num ];
- },
- "name": function(name) {
- return [ this[0], name ];
- },
- "toplevel": function(statements) {
- return [ this[0], MAP(statements, walk) ];
- },
- "block": _block,
- "splice": _block,
- "var": _vardefs,
- "const": _vardefs,
- "try": function(t, c, f) {
- return [
- this[0],
- MAP(t, walk),
- c != null ? [ c[0], MAP(c[1], walk) ] : null,
- f != null ? MAP(f, walk) : null
- ];
- },
- "throw": function(expr) {
- return [ this[0], walk(expr) ];
- },
- "new": function(ctor, args) {
- return [ this[0], walk(ctor), MAP(args, walk) ];
- },
- "switch": function(expr, body) {
- return [ this[0], walk(expr), MAP(body, function(branch){
- return [ branch[0] ? walk(branch[0]) : null,
- MAP(branch[1], walk) ];
- }) ];
- },
- "break": function(label) {
- return [ this[0], label ];
- },
- "continue": function(label) {
- return [ this[0], label ];
- },
- "conditional": function(cond, t, e) {
- return [ this[0], walk(cond), walk(t), walk(e) ];
- },
- "assign": function(op, lvalue, rvalue) {
- return [ this[0], op, walk(lvalue), walk(rvalue) ];
- },
- "dot": function(expr) {
- return [ this[0], walk(expr) ].concat(slice(arguments, 1));
- },
- "call": function(expr, args) {
- return [ this[0], walk(expr), MAP(args, walk) ];
- },
- "function": function(name, args, body) {
- return [ this[0], name, args.slice(), MAP(body, walk) ];
- },
- "defun": function(name, args, body) {
- return [ this[0], name, args.slice(), MAP(body, walk) ];
- },
- "if": function(conditional, t, e) {
- return [ this[0], walk(conditional), walk(t), walk(e) ];
- },
- "for": function(init, cond, step, block) {
- return [ this[0], walk(init), walk(cond), walk(step), walk(block) ];
- },
- "for-in": function(vvar, key, hash, block) {
- return [ this[0], walk(vvar), walk(key), walk(hash), walk(block) ];
- },
- "while": function(cond, block) {
- return [ this[0], walk(cond), walk(block) ];
- },
- "do": function(cond, block) {
- return [ this[0], walk(cond), walk(block) ];
- },
- "return": function(expr) {
- return [ this[0], walk(expr) ];
- },
- "binary": function(op, left, right) {
- return [ this[0], op, walk(left), walk(right) ];
- },
- "unary-prefix": function(op, expr) {
- return [ this[0], op, walk(expr) ];
- },
- "unary-postfix": function(op, expr) {
- return [ this[0], op, walk(expr) ];
- },
- "sub": function(expr, subscript) {
- return [ this[0], walk(expr), walk(subscript) ];
- },
- "object": function(props) {
- return [ this[0], MAP(props, function(p){
- return p.length == 2
- ? [ p[0], walk(p[1]) ]
- : [ p[0], walk(p[1]), p[2] ]; // get/set-ter
- }) ];
- },
- "regexp": function(rx, mods) {
- return [ this[0], rx, mods ];
- },
- "array": function(elements) {
- return [ this[0], MAP(elements, walk) ];
- },
- "stat": function(stat) {
- return [ this[0], walk(stat) ];
- },
- "seq": function() {
- return [ this[0] ].concat(MAP(slice(arguments), walk));
- },
- "label": function(name, block) {
- return [ this[0], name, walk(block) ];
- },
- "with": function(expr, block) {
- return [ this[0], walk(expr), walk(block) ];
- },
- "atom": function(name) {
- return [ this[0], name ];
- }
- };
-
- var user = {};
- var stack = [];
- function walk(ast) {
- if (ast == null)
- return null;
- try {
- stack.push(ast);
- var type = ast[0];
- var gen = user[type];
- if (gen) {
- var ret = gen.apply(ast, ast.slice(1));
- if (ret != null)
- return ret;
- }
- gen = walkers[type];
- return gen.apply(ast, ast.slice(1));
- } finally {
- stack.pop();
- }
- };
-
- function with_walkers(walkers, cont){
- var save = {}, i;
- for (i in walkers) if (HOP(walkers, i)) {
- save[i] = user[i];
- user[i] = walkers[i];
- }
- var ret = cont();
- for (i in save) if (HOP(save, i)) {
- if (!save[i]) delete user[i];
- else user[i] = save[i];
- }
- return ret;
- };
-
- return {
- walk: walk,
- with_walkers: with_walkers,
- parent: function() {
- return stack[stack.length - 2]; // last one is current node
- },
- stack: function() {
- return stack;
- }
- };
-};
-
-function empty(b) {
- return !b || (b[0] == "block" && (!b[1] || b[1].length == 0));
-};
-
-/* -----[ re-generate code from the AST ]----- */
-
-var DOT_CALL_NO_PARENS = array_to_hash([
- "name",
- "array",
- "object",
- "string",
- "dot",
- "sub",
- "call",
- "regexp"
-]);
-
-function make_string(str) {
- var dq = 0, sq = 0;
- str = str.replace(/[\\\b\f\n\r\t\x22\x27]/g, function(s){
- switch (s) {
- case "\\": return "\\\\";
- case "\b": return "\\b";
- case "\f": return "\\f";
- case "\n": return "\\n";
- case "\r": return "\\r";
- case "\t": return "\\t";
- case '"': ++dq; return '"';
- case "'": ++sq; return "'";
- }
- return s;
- });
- if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'";
- else return '"' + str.replace(/\x22/g, '\\"') + '"';
-};
-
-var SPLICE_NEEDS_BRACKETS = array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]);
-
-function gen_code(ast, options) {
- options = defaults(options, {
- indent_start : 0,
- indent_level : 4,
- quote_keys : false,
- space_colon : false,
- beautify : false
- });
- var beautify = !!options.beautify;
- var indentation = 0,
- newline = beautify ? "\n" : "",
- space = beautify ? " " : "";
-
- function make_name(name) {
- return name.toString();
- };
-
- function indent(line) {
- if (line == null)
- line = "";
- if (beautify)
- line = repeat_string(" ", options.indent_start + indentation * options.indent_level) + line;
- return line;
- };
-
- function with_indent(cont, incr) {
- if (incr == null) incr = 1;
- indentation += incr;
- try { return cont.apply(null, slice(arguments, 1)); }
- finally { indentation -= incr; }
- };
-
- function add_spaces(a) {
- if (beautify)
- return a.join(" ");
- var b = [];
- for (var i = 0; i < a.length; ++i) {
- var next = a[i + 1];
- b.push(a[i]);
- if (next &&
- ((/[a-z0-9_\x24]$/i.test(a[i].toString()) && /^[a-z0-9_\x24]/i.test(next.toString())) ||
- (/[\+\-]$/.test(a[i].toString()) && /^[\+\-]/.test(next.toString())))) {
- b.push(" ");
- }
- }
- return b.join("");
- };
-
- function add_commas(a) {
- return a.join("," + space);
- };
-
- function parenthesize(expr) {
- var gen = make(expr);
- for (var i = 1; i < arguments.length; ++i) {
- var el = arguments[i];
- if ((el instanceof Function && el(expr)) || expr[0] == el)
- return "(" + gen + ")";
- }
- return gen;
- };
-
- function best_of(a) {
- if (a.length == 1) {
- return a[0];
- }
- if (a.length == 2) {
- var b = a[1];
- a = a[0];
- return a.length <= b.length ? a : b;
- }
- return best_of([ a[0], best_of(a.slice(1)) ]);
- };
-
- function needs_parens(expr) {
- if (expr[0] == "function" || expr[0] == "object") {
- // dot/call on a literal function requires the
- // function literal itself to be parenthesized
- // only if it's the first "thing" in a
- // statement. This means that the parent is
- // "stat", but it could also be a "seq" and
- // we're the first in this "seq" and the
- // parent is "stat", and so on. Messy stuff,
- // but it worths the trouble.
- var a = slice($stack), self = a.pop(), p = a.pop();
- while (p) {
- if (p[0] == "stat") return true;
- if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) ||
- ((p[0] == "binary" || p[0] == "assign" || p[0] == "unary-postfix") && p[2] === self)) {
- self = p;
- p = a.pop();
- } else {
- return false;
- }
- }
- }
- return !HOP(DOT_CALL_NO_PARENS, expr[0]);
- };
-
- function make_num(num) {
- var str = num.toString(10), a = [ str.replace(/^0\./, ".") ], m;
- if (Math.floor(num) === num) {
- a.push("0x" + num.toString(16).toLowerCase(), // probably pointless
- "0" + num.toString(8)); // same.
- if ((m = /^(.*?)(0+)$/.exec(num))) {
- a.push(m[1] + "e" + m[2].length);
- }
- } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
- a.push(m[2] + "e-" + (m[1].length + m[2].length),
- str.substr(str.indexOf(".")));
- }
- return best_of(a);
- };
-
- var generators = {
- "string": make_string,
- "num": make_num,
- "name": make_name,
- "toplevel": function(statements) {
- return make_block_statements(statements)
- .join(newline);
- },
- "splice": function(statements) {
- var parent = $stack[$stack.length - 2][0];
- if (HOP(SPLICE_NEEDS_BRACKETS, parent)) {
- // we need block brackets in this case
- return make_block.apply(this, arguments);
- } else {
- return MAP(make_block_statements(statements, true),
- function(line, i) {
- // the first line is already indented
- return i > 0 ? indent(line) : line;
- }).join(newline);
- }
- },
- "block": make_block,
- "var": function(defs) {
- return "var " + add_commas(MAP(defs, make_1vardef)) + ";";
- },
- "const": function(defs) {
- return "const " + add_commas(MAP(defs, make_1vardef)) + ";";
- },
- "try": function(tr, ca, fi) {
- var out = [ "try", make_block(tr) ];
- if (ca) out.push("catch", "(" + ca[0] + ")", make_block(ca[1]));
- if (fi) out.push("finally", make_block(fi));
- return add_spaces(out);
- },
- "throw": function(expr) {
- return add_spaces([ "throw", make(expr) ]) + ";";
- },
- "new": function(ctor, args) {
- args = args.length > 0 ? "(" + add_commas(MAP(args, make)) + ")" : "";
- return add_spaces([ "new", parenthesize(ctor, "seq", "binary", "conditional", "assign", function(expr){
- var w = ast_walker(), has_call = {};
- try {
- w.with_walkers({
- "call": function() { throw has_call },
- "function": function() { return this }
- }, function(){
- w.walk(expr);
- });
- } catch(ex) {
- if (ex === has_call)
- return true;
- throw ex;
- }
- }) + args ]);
- },
- "switch": function(expr, body) {
- return add_spaces([ "switch", "(" + make(expr) + ")", make_switch_block(body) ]);
- },
- "break": function(label) {
- var out = "break";
- if (label != null)
- out += " " + make_name(label);
- return out + ";";
- },
- "continue": function(label) {
- var out = "continue";
- if (label != null)
- out += " " + make_name(label);
- return out + ";";
- },
- "conditional": function(co, th, el) {
- return add_spaces([ parenthesize(co, "assign", "seq", "conditional"), "?",
- parenthesize(th, "seq"), ":",
- parenthesize(el, "seq") ]);
- },
- "assign": function(op, lvalue, rvalue) {
- if (op && op !== true) op += "=";
- else op = "=";
- return add_spaces([ make(lvalue), op, parenthesize(rvalue, "seq") ]);
- },
- "dot": function(expr) {
- var out = make(expr), i = 1;
- if (expr[0] == "num") {
- if (!/\./.test(expr[1]))
- out += ".";
- } else if (needs_parens(expr))
- out = "(" + out + ")";
- while (i < arguments.length)
- out += "." + make_name(arguments[i++]);
- return out;
- },
- "call": function(func, args) {
- var f = make(func);
- if (needs_parens(func))
- f = "(" + f + ")";
- return f + "(" + add_commas(MAP(args, function(expr){
- return parenthesize(expr, "seq");
- })) + ")";
- },
- "function": make_function,
- "defun": make_function,
- "if": function(co, th, el) {
- var out = [ "if", "(" + make(co) + ")", el ? make_then(th) : make(th) ];
- if (el) {
- out.push("else", make(el));
- }
- return add_spaces(out);
- },
- "for": function(init, cond, step, block) {
- var out = [ "for" ];
- init = (init != null ? make(init) : "").replace(/;*\s*$/, ";" + space);
- cond = (cond != null ? make(cond) : "").replace(/;*\s*$/, ";" + space);
- step = (step != null ? make(step) : "").replace(/;*\s*$/, "");
- var args = init + cond + step;
- if (args == "; ; ") args = ";;";
- out.push("(" + args + ")", make(block));
- return add_spaces(out);
- },
- "for-in": function(vvar, key, hash, block) {
- return add_spaces([ "for", "(" +
- (vvar ? make(vvar).replace(/;+$/, "") : make(key)),
- "in",
- make(hash) + ")", make(block) ]);
- },
- "while": function(condition, block) {
- return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]);
- },
- "do": function(condition, block) {
- return add_spaces([ "do", make(block), "while", "(" + make(condition) + ")" ]) + ";";
- },
- "return": function(expr) {
- var out = [ "return" ];
- if (expr != null) out.push(make(expr));
- return add_spaces(out) + ";";
- },
- "binary": function(operator, lvalue, rvalue) {
- var left = make(lvalue), right = make(rvalue);
- // XXX: I'm pretty sure other cases will bite here.
- // we need to be smarter.
- // adding parens all the time is the safest bet.
- if (member(lvalue[0], [ "assign", "conditional", "seq" ]) ||
- lvalue[0] == "binary" && PRECEDENCE[operator] > PRECEDENCE[lvalue[1]]) {
- left = "(" + left + ")";
- }
- if (member(rvalue[0], [ "assign", "conditional", "seq" ]) ||
- rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]] &&
- !(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) {
- right = "(" + right + ")";
- }
- return add_spaces([ left, operator, right ]);
- },
- "unary-prefix": function(operator, expr) {
- var val = make(expr);
- if (!(expr[0] == "num" || (expr[0] == "unary-prefix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
- val = "(" + val + ")";
- return operator + (is_alphanumeric_char(operator.charAt(0)) ? " " : "") + val;
- },
- "unary-postfix": function(operator, expr) {
- var val = make(expr);
- if (!(expr[0] == "num" || (expr[0] == "unary-postfix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
- val = "(" + val + ")";
- return val + operator;
- },
- "sub": function(expr, subscript) {
- var hash = make(expr);
- if (needs_parens(expr))
- hash = "(" + hash + ")";
- return hash + "[" + make(subscript) + "]";
- },
- "object": function(props) {
- if (props.length == 0)
- return "{}";
- return "{" + newline + with_indent(function(){
- return MAP(props, function(p){
- if (p.length == 3) {
- // getter/setter. The name is in p[0], the arg.list in p[1][2], the
- // body in p[1][3] and type ("get" / "set") in p[2].
- return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
- }
- var key = p[0], val = make(p[1]);
- if (options.quote_keys) {
- key = make_string(key);
- } else if ((typeof key == "number" || !beautify && +key + "" == key)
- && parseFloat(key) >= 0) {
- key = make_num(+key);
- } else if (!is_identifier(key)) {
- key = make_string(key);
- }
- return indent(add_spaces(beautify && options.space_colon
- ? [ key, ":", val ]
- : [ key + ":", val ]));
- }).join("," + newline);
- }) + newline + indent("}");
- },
- "regexp": function(rx, mods) {
- return "/" + rx + "/" + mods;
- },
- "array": function(elements) {
- if (elements.length == 0) return "[]";
- return add_spaces([ "[", add_commas(MAP(elements, function(el){
- if (!beautify && el[0] == "atom" && el[1] == "undefined") return "";
- return parenthesize(el, "seq");
- })), "]" ]);
- },
- "stat": function(stmt) {
- return make(stmt).replace(/;*\s*$/, ";");
- },
- "seq": function() {
- return add_commas(MAP(slice(arguments), make));
- },
- "label": function(name, block) {
- return add_spaces([ make_name(name), ":", make(block) ]);
- },
- "with": function(expr, block) {
- return add_spaces([ "with", "(" + make(expr) + ")", make(block) ]);
- },
- "atom": function(name) {
- return make_name(name);
- }
- };
-
- // The squeezer replaces "block"-s that contain only a single
- // statement with the statement itself; technically, the AST
- // is correct, but this can create problems when we output an
- // IF having an ELSE clause where the THEN clause ends in an
- // IF *without* an ELSE block (then the outer ELSE would refer
- // to the inner IF). This function checks for this case and
- // adds the block brackets if needed.
- function make_then(th) {
- if (th[0] == "do") {
- // https://github.com/mishoo/UglifyJS/issues/#issue/57
- // IE croaks with "syntax error" on code like this:
- // if (foo) do ... while(cond); else ...
- // we need block brackets around do/while
- return make([ "block", [ th ]]);
- }
- var b = th;
- while (true) {
- var type = b[0];
- if (type == "if") {
- if (!b[3])
- // no else, we must add the block
- return make([ "block", [ th ]]);
- b = b[3];
- }
- else if (type == "while" || type == "do") b = b[2];
- else if (type == "for" || type == "for-in") b = b[4];
- else break;
- }
- return make(th);
- };
-
- function make_function(name, args, body, keyword) {
- var out = keyword || "function";
- if (name) {
- out += " " + make_name(name);
- }
- out += "(" + add_commas(MAP(args, make_name)) + ")";
- return add_spaces([ out, make_block(body) ]);
- };
-
- function make_block_statements(statements, noindent) {
- for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
- var stat = statements[i];
- var code = make(stat);
- if (code != ";") {
- if (!beautify && i == last) {
- if ((stat[0] == "while" && empty(stat[2])) ||
- (member(stat[0], [ "for", "for-in"] ) && empty(stat[4])) ||
- (stat[0] == "if" && empty(stat[2]) && !stat[3]) ||
- (stat[0] == "if" && stat[3] && empty(stat[3]))) {
- code = code.replace(/;*\s*$/, ";");
- } else {
- code = code.replace(/;+\s*$/, "");
- }
- }
- a.push(code);
- }
- }
- return noindent ? a : MAP(a, indent);
- };
-
- function make_switch_block(body) {
- var n = body.length;
- if (n == 0) return "{}";
- return "{" + newline + MAP(body, function(branch, i){
- var has_body = branch[1].length > 0, code = with_indent(function(){
- return indent(branch[0]
- ? add_spaces([ "case", make(branch[0]) + ":" ])
- : "default:");
- }, 0.5) + (has_body ? newline + with_indent(function(){
- return make_block_statements(branch[1]).join(newline);
- }) : "");
- if (!beautify && has_body && i < n - 1)
- code += ";";
- return code;
- }).join(newline) + newline + indent("}");
- };
-
- function make_block(statements) {
- if (!statements) return ";";
- if (statements.length == 0) return "{}";
- return "{" + newline + with_indent(function(){
- return make_block_statements(statements).join(newline);
- }) + newline + indent("}");
- };
-
- function make_1vardef(def) {
- var name = def[0], val = def[1];
- if (val != null)
- name = add_spaces([ make_name(name), "=", parenthesize(val, "seq") ]);
- return name;
- };
-
- var $stack = [];
-
- function make(node) {
- var type = node[0];
- var gen = generators[type];
- if (!gen)
- throw new Error("Can't find generator for \"" + type + "\"");
- $stack.push(node);
- var ret = gen.apply(type, node.slice(1));
- $stack.pop();
- return ret;
- };
-
- return make(ast);
-};
-
-/* -----[ Utilities ]----- */
-
-function repeat_string(str, i) {
- return i < 1 ? "" : new Array(i + 1).join(str);
-};
-
-function defaults(args, defs) {
- var ret = {};
- if (args === true)
- args = {};
- for (var i in defs) if (HOP(defs, i)) {
- ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
- }
- return ret;
-};
-
-function is_identifier(name) {
- return /^[a-z_$][a-z0-9_$]*$/i.test(name)
- && name != "this"
- && !HOP(KEYWORDS_ATOM, name)
- && !HOP(RESERVED_WORDS, name)
- && !HOP(KEYWORDS, name);
-};
-
-function MAP(a, f, o) {
- var ret = [];
- for (var i = 0; i < a.length; ++i) {
- ret.push(f.call(o, a[i], i));
- }
- return ret;
-};
-
-/* -----[ Exports ]----- */
-
-return {
- parse: parse,
- gen_code: gen_code,
- tokenizer: tokenizer,
- ast_walker: ast_walker
-};
-
-};
diff --git a/lib/prepro.js b/lib/prepro.js
deleted file mode 100644
index c92796a7..00000000
--- a/lib/prepro.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Paper.js
- *
- * This file is part of Paper.js, a JavaScript Vector Graphics Library,
- * based on Scriptographer.org and designed to be largely API compatible.
- * http://paperjs.org/
- * http://scriptographer.org/
- *
- * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
- * http://lehni.org/ & http://jonathanpuckey.com/
- *
- * Distributed under the MIT license. See LICENSE file for details.
- *
- * All rights reserved.
- */
-
-// Since loading prepro.js is also used further down to prevent inline scripts
-// from executing right away, check that its actual code is only executed once.
-if (!window.include) {
- // Determine the source of prepro.js, so we can use it to prevent inline
- // scripts from loading straight away.
- var scripts = document.getElementsByTagName('script');
- var script = scripts[scripts.length - 1];
- var src = script.getAttribute('src');
- var root = src.match(/^(.*\/)/)[1];
-
- window.include = function(url) {
- url = root + url;
- var newRoot = url.match(/^(.*\/)/)[1];
- // Load prepro.js again, just to prevent the setting of newRoot frome
- // executing straight away, and delaying it until right before the
- // script at 'url' is loaded.
- document.write([
- '',
- // Set newRoot, so include() from 'url' load from the right place
- '',
- // Load the actual script
- '',
- // Set root back to the root before
- ''
- ].join(''));
- }
-}
diff --git a/lib/stats.js b/lib/stats.js
deleted file mode 100644
index 5d85f626..00000000
--- a/lib/stats.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// stats.js r5 - http://github.com/mrdoob/stats.js
-var Stats=function(){function w(d,K,n){var u,f,c;for(f=0;f<30;f++)for(u=0;u<73;u++){c=(u+f*74)*4;d[c]=d[c+4];d[c+1]=d[c+5];d[c+2]=d[c+6]}for(f=0;f<30;f++){c=(73+f*74)*4;if(fFPS';m.appendChild(g);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";m.appendChild(a);
-p=a.getContext("2d");p.fillStyle="rgb("+b.fps.bg.r+","+b.fps.bg.g+","+b.fps.bg.b+")";p.fillRect(0,0,a.width,a.height);C=p.getImageData(0,0,a.width,a.height);h=document.createElement("div");h.style.backgroundColor="rgb("+Math.floor(b.ms.bg.r/2)+","+Math.floor(b.ms.bg.g/2)+","+Math.floor(b.ms.bg.b/2)+")";h.style.padding="2px 0px 3px 0px";h.style.display="none";e.appendChild(h);i=document.createElement("div");i.style.fontFamily="Helvetica, Arial, sans-serif";i.style.textAlign="left";i.style.fontSize=
-"9px";i.style.color="rgb("+b.ms.fg.r+","+b.ms.fg.g+","+b.ms.fg.b+")";i.style.margin="0px 0px 1px 3px";i.innerHTML='MS';h.appendChild(i);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";h.appendChild(a);r=a.getContext("2d");r.fillStyle="rgb("+b.ms.bg.r+","+b.ms.bg.g+","+b.ms.bg.b+")";r.fillRect(0,0,a.width,a.height);F=r.getImageData(0,0,a.width,a.height);try{if(performance&&performance.memory&&performance.memory.totalJSHeapSize)x=
-3}catch(L){}j=document.createElement("div");j.style.backgroundColor="rgb("+Math.floor(b.mem.bg.r/2)+","+Math.floor(b.mem.bg.g/2)+","+Math.floor(b.mem.bg.b/2)+")";j.style.padding="2px 0px 3px 0px";j.style.display="none";e.appendChild(j);k=document.createElement("div");k.style.fontFamily="Helvetica, Arial, sans-serif";k.style.textAlign="left";k.style.fontSize="9px";k.style.color="rgb("+b.mem.fg.r+","+b.mem.fg.g+","+b.mem.fg.b+")";k.style.margin="0px 0px 1px 3px";k.innerHTML='MEM';
-j.appendChild(k);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";j.appendChild(a);t=a.getContext("2d");t.fillStyle="#301010";t.fillRect(0,0,a.width,a.height);I=t.getImageData(0,0,a.width,a.height);return{domElement:e,update:function(){y++;l=(new Date).getTime();q=l-J;D=Math.min(D,q);E=Math.max(E,q);w(F.data,Math.min(30,30-q/200*30),"ms");i.innerHTML=''+q+" MS ("+D+"-"+E+")";r.putImageData(F,0,0);J=l;if(l>
-z+1E3){o=Math.round(y*1E3/(l-z));A=Math.min(A,o);B=Math.max(B,o);w(C.data,Math.min(30,30-o/100*30),"fps");g.innerHTML=''+o+" FPS ("+A+"-"+B+")";p.putImageData(C,0,0);if(x==3){s=performance.memory.usedJSHeapSize*9.54E-7;G=Math.min(G,s);H=Math.max(H,s);w(I.data,Math.min(30,30-s/2),"mem");k.innerHTML=''+Math.round(s)+" MEM ("+Math.round(G)+"-"+Math.round(H)+")";t.putImageData(I,0,0)}z=l;y=0}}}};
-
diff --git a/node.js/index.js b/node.js/index.js
deleted file mode 100644
index 243a9d1b..00000000
--- a/node.js/index.js
+++ /dev/null
@@ -1,58 +0,0 @@
-var fs = require('fs'),
- vm = require('vm'),
- path = require('path'),
- Canvas = require('canvas');
-
-__dirname = path.resolve(__dirname, '../src/');
-
-// Create the context within which we will run the source files:
-var context = vm.createContext({
- options: {
- server: true,
- version: 'dev'
- },
- fs: fs,
- // Node Canvas library: https://github.com/learnboost/node-canvas
- Canvas: Canvas,
- HTMLCanvasElement: Canvas,
- Image: Canvas.Image,
- // Copy over global variables:
- console: console,
- require: require,
- __dirname: __dirname,
- __filename: __filename,
- // Used to load and run source files within the same context:
- include: function(uri) {
- var source = fs.readFileSync(path.resolve(__dirname, uri), 'utf8');
- // For relative includes, we save the current directory and then
- // add the uri directory to __dirname:
- var oldDirname = __dirname;
- __dirname = path.resolve(__dirname, path.dirname(uri));
- vm.runInContext(source, context, uri);
- __dirname = oldDirname;
- }
-});
-
-// Load Paper.js library files:
-context.include('paper.js');
-
-context.Base.each(context, function(val, key) {
- if (val && val.prototype instanceof context.Base) {
- val._name = key;
- // Export all classes through PaperScope:
- context.PaperScope.prototype[key] = val;
- }
-});
-context.PaperScope.prototype['Canvas'] = context.Canvas;
-
-require.extensions['.pjs'] = function(module, uri) {
- var source = context.PaperScript.compile(fs.readFileSync(uri, 'utf8'));
- var envVars = 'var __dirname = \'' + path.dirname(uri) + '\';' +
- 'var __filename = \'' + uri + '\';';
- vm.runInContext(envVars, context);
- var scope = new context.PaperScope();
- context.PaperScript.evaluate(source, scope);
- module.exports = scope;
-};
-
-module.exports = new context.PaperScope();
\ No newline at end of file