summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Faivre <jeremy.faivre@gmail.com>2012-08-04 03:17:58 +0200
committerJeremy Faivre <jeremy.faivre@gmail.com>2012-08-04 03:17:58 +0200
commit52f8447d2180dca96e02b10c60a7cef0b7038b29 (patch)
tree94fa4662ed04cf9c214f59e3314ae84f3a168659
parentbc778908ab5aa900f0b6cf842e09bdc8d8888488 (diff)
downloadyamljs-52f8447d2180dca96e02b10c60a7cef0b7038b29.tar.gz
Cleaned-up files and added compatibility with node.js
-rw-r--r--README.markdown30
-rw-r--r--bin/yaml.js2069
-rw-r--r--bin/yaml.min.js22
-rwxr-xr-xbuild41
-rw-r--r--demo/demo.html (renamed from demo.html)6
-rw-r--r--libs/demo/mootools.js5800
-rw-r--r--libs/yuicompressor.jarbin851219 -> 0 bytes
-rwxr-xr-xmake32
-rw-r--r--package.json18
-rw-r--r--src/Yaml.js (renamed from com/jeremyfa/yaml/Yaml.js)99
-rw-r--r--src/YamlDumper.js (renamed from com/jeremyfa/yaml/YamlDumper.js)0
-rw-r--r--src/YamlEscaper.js (renamed from com/jeremyfa/yaml/YamlEscaper.js)0
-rw-r--r--src/YamlInline.js (renamed from com/jeremyfa/yaml/YamlInline.js)0
-rw-r--r--src/YamlParseException.js (renamed from com/jeremyfa/yaml/YamlParseException.js)0
-rw-r--r--src/YamlParser.js (renamed from com/jeremyfa/yaml/YamlParser.js)0
-rw-r--r--src/YamlUnescaper.js (renamed from com/jeremyfa/yaml/YamlUnescaper.js)0
-rw-r--r--test/libs/jasmine-1.2.0/MIT.LICENSE (renamed from libs/jasmine-1.2.0/MIT.LICENSE)0
-rw-r--r--test/libs/jasmine-1.2.0/YamlSpec.js (renamed from libs/jasmine-1.2.0/YamlSpec.js)4
-rw-r--r--test/libs/jasmine-1.2.0/YamlTests.js (renamed from libs/jasmine-1.2.0/YamlTests.js)0
-rw-r--r--test/libs/jasmine-1.2.0/jasmine-html.js (renamed from libs/jasmine-1.2.0/jasmine-html.js)0
-rw-r--r--test/libs/jasmine-1.2.0/jasmine.css (renamed from libs/jasmine-1.2.0/jasmine.css)0
-rw-r--r--test/libs/jasmine-1.2.0/jasmine.js (renamed from libs/jasmine-1.2.0/jasmine.js)0
-rw-r--r--test/test.html (renamed from tests.html)2
-rw-r--r--test/test.js5
-rw-r--r--test/test.yml29
-rw-r--r--yaml.js22
26 files changed, 2288 insertions, 5891 deletions
diff --git a/README.markdown b/README.markdown
index 9e5fb6a..15a55cd 100644
--- a/README.markdown
+++ b/README.markdown
@@ -14,23 +14,43 @@ Import yaml.js in your html page:
Parse yaml string:
- nativeObject = YAML.decode(yamlString);
+ nativeObject = YAML.parse(yamlString);
+
+Dump native object into yaml string:
+
+ yamlString = YAML.stringify(nativeObject[, inline /* @integer depth to start using inline notation at */ ]);
Load yaml file:
nativeObject = YAML.load('file.yml');
-Load yaml file (asynchronous):
+Load yaml file:
YAML.load('file.yml', function(result)
{
- nativeObject = result;
+ nativeObject = result;
});
-Dump native object into yaml string:
+Use with node.js
+----------------
+
+Install module:
- yamlString = YAML.encode(nativeObject[, inline /* @integer depth to start using inline notation at */ ]);
+ npm install yamljs
+
+Use it:
+
+ YAML = require('yamljs');
+
+ // parse YAML string
+ nativeObject = YAML.parse(yamlString);
+ // Generate YAML
+ yamlString = YAML.stringify(nativeObject, 4);
+
+ // Load yaml file using require
+ nativeObject = require('./myfile.yml');
+
Important
---------
diff --git a/bin/yaml.js b/bin/yaml.js
new file mode 100644
index 0000000..a2dadb5
--- /dev/null
+++ b/bin/yaml.js
@@ -0,0 +1,2069 @@
+/*
+Copyright (c) 2010 Jeremy Faivre
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/**
+ * Exception class thrown when an error occurs during parsing.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+
+/**
+ * Constructor.
+ *
+ * @param string message The error message
+ * @param integer parsedLine The line where the error occurred
+ * @param integer snippet The snippet of code near the problem
+ * @param string parsedFile The file name where the error occurred
+ */
+
+var YamlParseException = function(message, parsedLine, snippet, parsedFile){
+
+ this.rawMessage = message;
+ this.parsedLine = (parsedLine !== undefined) ? parsedLine : -1;
+ this.snippet = (snippet !== undefined) ? snippet : null;
+ this.parsedFile = (parsedFile !== undefined) ? parsedFile : null;
+
+ this.updateRepr();
+
+ this.message = message;
+
+};
+YamlParseException.prototype =
+{
+
+ name: 'YamlParseException',
+ message: null,
+
+ parsedFile: null,
+ parsedLine: -1,
+ snippet: null,
+ rawMessage: null,
+
+ isDefined: function(input)
+ {
+ return input != undefined && input != null;
+ },
+
+ /**
+ * Gets the snippet of code near the error.
+ *
+ * @return string The snippet of code
+ */
+ getSnippet: function()
+ {
+ return this.snippet;
+ },
+
+ /**
+ * Sets the snippet of code near the error.
+ *
+ * @param string snippet The code snippet
+ */
+ setSnippet: function(snippet)
+ {
+ this.snippet = snippet;
+
+ this.updateRepr();
+ },
+
+ /**
+ * Gets the filename where the error occurred.
+ *
+ * This method returns null if a string is parsed.
+ *
+ * @return string The filename
+ */
+ getParsedFile: function()
+ {
+ return this.parsedFile;
+ },
+
+ /**
+ * Sets the filename where the error occurred.
+ *
+ * @param string parsedFile The filename
+ */
+ setParsedFile: function(parsedFile)
+ {
+ this.parsedFile = parsedFile;
+
+ this.updateRepr();
+ },
+
+ /**
+ * Gets the line where the error occurred.
+ *
+ * @return integer The file line
+ */
+ getParsedLine: function()
+ {
+ return this.parsedLine;
+ },
+
+ /**
+ * Sets the line where the error occurred.
+ *
+ * @param integer parsedLine The file line
+ */
+ setParsedLine: function(parsedLine)
+ {
+ this.parsedLine = parsedLine;
+
+ this.updateRepr();
+ },
+
+ updateRepr: function()
+ {
+ this.message = this.rawMessage;
+
+ dot = false;
+ if ('.' === this.message.charAt(this.message.length - 1)) {
+ this.message = this.message.substring(0, this.message.length - 1);
+ dot = true;
+ }
+
+ if (null !== this.parsedFile) {
+ this.message += ' in ' + JSON.stringify(this.parsedFile);
+ }
+
+ if (this.parsedLine >= 0) {
+ this.message += ' at line ' + this.parsedLine;
+ }
+
+ if (this.snippet) {
+ this.message += ' (near "' + this.snippet + '")';
+ }
+
+ if (dot) {
+ this.message += '.';
+ }
+ }
+}
+/**
+ * Yaml offers convenience methods to parse and dump YAML.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+
+var isNode = false;
+var Yaml = function(){};
+Yaml.prototype =
+{
+
+ /**
+ * Parses YAML into a JS representation.
+ *
+ * The parse method, when supplied with a YAML stream (file),
+ * will do its best to convert YAML in a file into a JS representation.
+ *
+ * Usage:
+ * <code>
+ * obj = yaml.parseFile('config.yml');
+ * </code>
+ *
+ * @param string input Path of YAML file
+ *
+ * @return array The YAML converted to a JS representation
+ *
+ * @throws YamlParseException If the YAML is not valid
+ */
+ parseFile: function(file /* String */, callback /* Function */)
+ {
+ if ( callback == null )
+ {
+ var input = this.getFileContents(file);
+ var ret = null;
+ try
+ {
+ ret = this.parse(input);
+ }
+ catch ( e )
+ {
+ if ( e instanceof YamlParseException ) {
+ e.setParsedFile(file);
+ }
+ throw e;
+ }
+ return ret;
+ }
+
+ this.getFileContents(file, function(data)
+ {
+ callback(new Yaml().parse(data));
+ });
+ },
+
+ /**
+ * Parses YAML into a JS representation.
+ *
+ * The parse method, when supplied with a YAML stream (string),
+ * will do its best to convert YAML into a JS representation.
+ *
+ * Usage:
+ * <code>
+ * obj = yaml.parse(...);
+ * </code>
+ *
+ * @param string input string containing YAML
+ *
+ * @return array The YAML converted to a JS representation
+ *
+ * @throws YamlParseException If the YAML is not valid
+ */
+ parse: function(input /* String */)
+ {
+ var yaml = new YamlParser();
+
+ return yaml.parse(input);
+ },
+
+ /**
+ * Dumps a JS representation to a YAML string.
+ *
+ * The dump method, when supplied with an array, will do its best
+ * to convert the array into friendly YAML.
+ *
+ * @param array array JS representation
+ * @param integer inline The level where you switch to inline YAML
+ *
+ * @return string A YAML string representing the original JS representation
+ *
+ * @api
+ */
+ dump: function(array, inline)
+ {
+ if ( inline == null ) inline = 2;
+
+ var yaml = new YamlDumper();
+
+ return yaml.dump(array, inline);
+ },
+
+ getXHR: function()
+ {
+ if ( window.XMLHttpRequest )
+ return new XMLHttpRequest();
+
+ if ( window.ActiveXObject )
+ {
+ var names = [
+ "Msxml2.XMLHTTP.6.0",
+ "Msxml2.XMLHTTP.3.0",
+ "Msxml2.XMLHTTP",
+ "Microsoft.XMLHTTP"
+ ];
+
+ for ( var i = 0; i < 4; i++ )
+ {
+ try{ return new ActiveXObject(names[i]); }
+ catch(e){}
+ }
+ }
+ return null;
+ },
+
+ getFileContents: function(file, callback)
+ {
+ if ( isNode )
+ {
+ var fs = require('fs');
+ if ( callback == null )
+ {
+ var data = fs.readFileSync(file);
+ if (data == null) return null;
+ return ''+data;
+ }
+ else
+ {
+ fs.readFile(file, function(err, data)
+ {
+ if (err)
+ callback(null);
+ else
+ callback(data);
+ });
+ }
+ }
+ else
+ {
+ var request = this.getXHR();
+
+ // Sync
+ if ( callback == null )
+ {
+ request.open('GET', file, false);
+ request.send(null);
+
+ if ( request.status == 200 || request.status == 0 )
+ return request.responseText;
+
+ return null;
+ }
+
+ // Async
+ request.onreadystatechange = function()
+ {
+ if ( request.readyState == 4 )
+ if ( request.status == 200 || request.status == 0 )
+ callback(request.responseText);
+ else
+ callback(null);
+ };
+ request.open('GET', file, true);
+ request.send(null);
+ }
+ }
+};
+
+var YAML =
+{
+ /*
+ * @param integer inline The level where you switch to inline YAML
+ */
+
+ stringify: function(input, inline)
+ {
+ return new Yaml().dump(input, inline);
+ },
+
+ parse: function(input)
+ {
+ return new Yaml().parse(input);
+ },
+
+ load: function(file, callback)
+ {
+ return new Yaml().parseFile(file, callback);
+ }
+};
+
+// Handle node.js case
+if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = YAML;
+ isNode = true;
+
+ // Add require handler
+ (function () {
+ var require_handler = function (module, filename) {
+ // fill in result
+ module.exports = YAML.load(filename);
+ };
+
+ // register require extensions only if we're on node.js
+ // hack for browserify
+ if ( undefined !== require.extensions ) {
+ require.extensions['.yml'] = require_handler;
+ require.extensions['.yaml'] = require_handler;
+ }
+ }());
+ }
+}
+
+/**
+ * YamlInline implements a YAML parser/dumper for the YAML inline syntax.
+ */
+var YamlInline = function(){};
+YamlInline.prototype =
+{
+ i: null,
+
+ /**
+ * Convert a YAML string to a JS object.
+ *
+ * @param string value A YAML string
+ *
+ * @return object A JS object representing the YAML string
+ */
+ parse: function(value)
+ {
+ var result = null;
+ value = this.trim(value);
+
+ if ( 0 == value.length )
+ {
+ return '';
+ }
+
+ switch ( value.charAt(0) )
+ {
+ case '[':
+ result = this.parseSequence(value);
+ break;
+ case '{':
+ result = this.parseMapping(value);
+ break;
+ default:
+ result = this.parseScalar(value);
+
+ // some comment can end the scalar
+ if ( value.substr(this.i).replace(/^\s+#.*$/, '') ) {
+ throw new YamlParseException('Unexpected characters near "'+value.substr(this.i)+'".');
+ }
+ }
+
+ return result;
+ },
+
+ /**
+ * Dumps a given JS variable to a YAML string.
+ *
+ * @param mixed value The JS variable to convert
+ *
+ * @return string The YAML string representing the JS object
+ */
+ dump: function(value)
+ {
+ if ( undefined == value || null == value )
+ return 'null';
+ if ( value instanceof Date)
+ return value.toISOString();
+ if ( typeof(value) == 'object')
+ return this.dumpObject(value);
+ if ( typeof(value) == 'boolean' )
+ return value ? 'true' : 'false';
+ if ( /^\d+$/.test(value) )
+ return typeof(value) == 'string' ? "'"+value+"'" : parseInt(value);
+ if ( this.isNumeric(value) )
+ return typeof(value) == 'string' ? "'"+value+"'" : parseFloat(value);
+ if ( typeof(value) == 'number' )
+ return value == Infinity ? '.Inf' : ( value == -Infinity ? '-.Inf' : ( isNaN(value) ? '.NAN' : value ) );
+ var yaml = new YamlEscaper();
+ if ( yaml.requiresDoubleQuoting(value) )
+ return yaml.escapeWithDoubleQuotes(value);
+ if ( yaml.requiresSingleQuoting(value) )
+ return yaml.escapeWithSingleQuotes(value);
+ if ( '' == value )
+ return "";
+ if ( this.getTimestampRegex().test(value) )
+ return "'"+value+"'";
+ if ( this.inArray(value.toLowerCase(), ['null','~','true','false']) )
+ return "'"+value+"'";
+ // default
+ return value;
+ },
+
+ /**
+ * Dumps a JS object to a YAML string.
+ *
+ * @param object value The JS array to dump
+ *
+ * @return string The YAML string representing the JS object
+ */
+ dumpObject: function(value)
+ {
+ var keys = this.getKeys(value);
+ var output = null;
+ var i;
+ var len = keys.length;
+
+ // array
+ if ( value instanceof Array )
+ /*( 1 == len && '0' == keys[0] )
+ ||
+ ( len > 1 && this.reduceArray(keys, function(v,w){return Math.floor(v+w);}, 0) == len * (len - 1) / 2) )*/
+ {
+ output = [];
+ for ( i = 0; i < len; i++ )
+ {
+ output.push(this.dump(value[keys[i]]));
+ }
+
+ return '['+output.join(', ')+']';
+ }
+
+ // mapping
+ output = [];
+ for ( i = 0; i < len; i++ )
+ {
+ output.push(this.dump(keys[i])+': '+this.dump(value[keys[i]]));
+ }
+
+ return '{ '+output.join(', ')+' }';
+ },
+
+ /**
+ * Parses a scalar to a YAML string.
+ *
+ * @param scalar scalar
+ * @param string delimiters
+ * @param object stringDelimiters
+ * @param integer i
+ * @param boolean evaluate
+ *
+ * @return string A YAML string
+ *
+ * @throws YamlParseException When malformed inline YAML string is parsed
+ */
+ parseScalar: function(scalar, delimiters, stringDelimiters, i, evaluate)
+ {
+ if ( delimiters == undefined ) delimiters = null;
+ if ( stringDelimiters == undefined ) stringDelimiters = ['"', "'"];
+ if ( i == undefined ) i = 0;
+ if ( evaluate == undefined ) evaluate = true;
+
+ var output = null;
+ var pos = null;
+ var matches = null;
+
+ if ( this.inArray(scalar[i], stringDelimiters) )
+ {
+ // quoted scalar
+ output = this.parseQuotedScalar(scalar, i);
+ i = this.i;
+ if (null !== delimiters) {
+ var tmp = scalar.substr(i).replace(/^\s+/, '');
+ if (!this.inArray(tmp.charAt(0), delimiters)) {
+ throw new YamlParseException('Unexpected characters ('+scalar.substr(i)+').');
+ }
+ }
+ }
+ else
+ {
+ // "normal" string
+ if ( !delimiters )
+ {
+ output = (scalar+'').substring(i);
+
+ i += output.length;
+
+ // remove comments
+ pos = output.indexOf(' #');
+ if ( pos != -1 )
+ {
+ output = output.substr(0, pos).replace(/\s+$/g,'');
+ }
+ }
+ else if ( matches = new RegExp('^(.+?)('+delimiters.join('|')+')').exec((scalar+'').substring(i)) )
+ {
+ output = matches[1];
+ i += output.length;
+ }
+ else
+ {
+ throw new YamlParseException('Malformed inline YAML string ('+scalar+').');
+ }
+ output = evaluate ? this.evaluateScalar(output) : output;
+ }
+
+ this.i = i;
+
+ return output;
+ },
+
+ /**
+ * Parses a quoted scalar to YAML.
+ *
+ * @param string scalar
+ * @param integer i
+ *
+ * @return string A YAML string
+ *
+ * @throws YamlParseException When malformed inline YAML string is parsed
+ */
+ parseQuotedScalar: function(scalar, i)
+ {
+ var matches = null;
+ //var item = /^(.*?)['"]\s*(?:[,:]|[}\]]\s*,)/.exec((scalar+'').substring(i))[1];
+
+ if ( !(matches = new RegExp('^'+YamlInline.REGEX_QUOTED_STRING).exec((scalar+'').substring(i))) )
+ {
+ throw new YamlParseException('Malformed inline YAML string ('+(scalar+'').substring(i)+').');
+ }
+
+ var output = matches[0].substr(1, matches[0].length - 2);
+
+ var unescaper = new YamlUnescaper();
+
+ if ( '"' == (scalar+'').charAt(i) )
+ {
+ output = unescaper.unescapeDoubleQuotedString(output);
+ }
+ else
+ {
+ output = unescaper.unescapeSingleQuotedString(output);
+ }
+
+ i += matches[0].length;
+
+ this.i = i;
+ return output;
+ },
+
+ /**
+ * Parses a sequence to a YAML string.
+ *
+ * @param string sequence
+ * @param integer i
+ *
+ * @return string A YAML string
+ *
+ * @throws YamlParseException When malformed inline YAML string is parsed
+ */
+ parseSequence: function(sequence, i)
+ {
+ if ( i == undefined ) i = 0;
+
+ var output = [];
+ var len = sequence.length;
+ i += 1;
+
+ // [foo, bar, ...]
+ while ( i < len )
+ {
+ switch ( sequence.charAt(i) )
+ {
+ case '[':
+ // nested sequence
+ output.push(this.parseSequence(sequence, i));
+ i = this.i;
+ break;
+ case '{':
+ // nested mapping
+ output.push(this.parseMapping(sequence, i));
+ i = this.i;
+ break;
+ case ']':
+ this.i = i;
+ return output;
+ case ',':
+ case ' ':
+ break;
+ default:
+ isQuoted = this.inArray(sequence.charAt(i), ['"', "'"]);
+ var value = this.parseScalar(sequence, [',', ']'], ['"', "'"], i);
+ i = this.i;
+
+ if ( !isQuoted && (value+'').indexOf(': ') != -1 )
+ {
+ // embedded mapping?
+ try
+ {
+ value = this.parseMapping('{'+value+'}');
+ }
+ catch ( e )
+ {
+ if ( !(e instanceof YamlParseException ) ) throw e;
+ // no, it's not
+ }
+ }
+
+ output.push(value);
+
+ i--;
+ }
+
+ i++;
+ }
+
+ throw new YamlParseException('Malformed inline YAML string "'+sequence+'"');
+ },
+
+ /**
+ * Parses a mapping to a YAML string.
+ *
+ * @param string mapping
+ * @param integer i
+ *
+ * @return string A YAML string
+ *
+ * @throws YamlParseException When malformed inline YAML string is parsed
+ */
+ parseMapping: function(mapping, i)
+ {
+ if ( i == undefined ) i = 0;
+ var output = {};
+ var len = mapping.length;
+ i += 1;
+ var done = false;
+ var doContinue = false;
+
+ // {foo: bar, bar:foo, ...}
+ while ( i < len )
+ {
+ doContinue = false;
+
+ switch ( mapping.charAt(i) )
+ {
+ case ' ':
+ case ',':
+ i++;
+ doContinue = true;
+ break;
+ case '}':
+ this.i = i;
+ return output;
+ }
+
+ if ( doContinue ) continue;
+
+ // key
+ var key = this.parseScalar(mapping, [':', ' '], ['"', "'"], i, false);
+ i = this.i;
+
+ // value
+ done = false;
+ while ( i < len )
+ {
+ switch ( mapping.charAt(i) )
+ {
+ case '[':
+ // nested sequence
+ output[key] = this.parseSequence(mapping, i);
+ i = this.i;
+ done = true;
+ break;
+ case '{':
+ // nested mapping
+ output[key] = this.parseMapping(mapping, i);
+ i = this.i;
+ done = true;
+ break;
+ case ':':
+ case ' ':
+ break;
+ default:
+ output[key] = this.parseScalar(mapping, [',', '}'], ['"', "'"], i);
+ i = this.i;
+ done = true;
+ i--;
+ }
+
+ ++i;
+
+ if ( done )
+ {
+ doContinue = true;
+ break;
+ }
+ }
+
+ if ( doContinue ) continue;
+ }
+
+ throw new YamlParseException('Malformed inline YAML string "'+mapping+'"');
+ },
+
+ /**
+ * Evaluates scalars and replaces magic values.
+ *
+ * @param string scalar
+ *
+ * @return string A YAML string
+ */
+ evaluateScalar: function(scalar)
+ {
+ scalar = this.trim(scalar);
+
+ var raw = null;
+ var cast = null;
+
+ if ( ( 'null' == scalar.toLowerCase() ) ||
+ ( '' == scalar ) ||
+ ( '~' == scalar ) )
+ return null;
+ if ( (scalar+'').indexOf('!str ') == 0 )
+ return (''+scalar).substring(5);
+ if ( (scalar+'').indexOf('! ') == 0 )
+ return parseInt(this.parseScalar((scalar+'').substr(2)));
+ if ( /^\d+$/.test(scalar) )
+ {
+ raw = scalar;
+ cast = parseInt(scalar);
+ return '0' == scalar.charAt(0) ? this.octdec(scalar) : (( ''+raw == ''+cast ) ? cast : raw);
+ }
+ if ( 'true' == (scalar+'').toLowerCase() )
+ return true;
+ if ( 'false' == (scalar+'').toLowerCase() )
+ return false;
+ if ( this.isNumeric(scalar) )
+ return '0x' == (scalar+'').substr(0, 2) ? this.hexdec(scalar) : parseFloat(scalar);
+ if ( scalar.toLowerCase() == '.inf' )
+ return Infinity;
+ if ( scalar.toLowerCase() == '.nan' )
+ return NaN;
+ if ( scalar.toLowerCase() == '-.inf' )
+ return -Infinity;
+ if ( /^(-|\+)?[0-9,]+(\.[0-9]+)?$/.test(scalar) )
+ return parseFloat(scalar.split(',').join(''));
+ if ( this.getTimestampRegex().test(scalar) )
+ return new Date(this.strtotime(scalar));
+ //else
+ return ''+scalar;
+ },
+
+ /**
+ * Gets a regex that matches an unix timestamp
+ *
+ * @return string The regular expression
+ */
+ getTimestampRegex: function()
+ {
+ return new RegExp('^'+
+ '([0-9][0-9][0-9][0-9])'+
+ '-([0-9][0-9]?)'+
+ '-([0-9][0-9]?)'+
+ '(?:(?:[Tt]|[ \t]+)'+
+ '([0-9][0-9]?)'+
+ ':([0-9][0-9])'+
+ ':([0-9][0-9])'+
+ '(?:\.([0-9]*))?'+
+ '(?:[ \t]*(Z|([-+])([0-9][0-9]?)'+
+ '(?::([0-9][0-9]))?))?)?'+
+ '$','gi');
+ },
+
+ trim: function(str /* String */)
+ {
+ return (str+'').replace(/^\s+/,'').replace(/\s+$/,'');
+ },
+
+ isNumeric: function(input)
+ {
+ return (input - 0) == input && input.length > 0 && input.replace(/\s+/g,'') != '';
+ },
+
+ inArray: function(key, tab)
+ {
+ var i;
+ var len = tab.length;
+ for ( i = 0; i < len; i++ )
+ {
+ if ( key == tab[i] ) return true;
+ }
+ return false;
+ },
+
+ getKeys: function(tab)
+ {
+ var ret = [];
+
+ for ( var name in tab )
+ {
+ if ( tab.hasOwnProperty(name) )
+ {
+ ret.push(name);
+ }
+ }
+
+ return ret;
+ },
+
+ /*reduceArray: function(tab, fun)
+ {
+ var len = tab.length;
+ if (typeof fun != "function")
+ throw new YamlParseException("fun is not a function");
+
+ // no value to return if no initial value and an empty array
+ if (len == 0 && arguments.length == 1)
+ throw new YamlParseException("empty array");
+
+ var i = 0;
+ if (arguments.length >= 2)
+ {
+ var rv = arguments[1];
+ }
+ else
+ {
+ do
+ {
+ if (i in tab)
+ {
+ rv = tab[i++];
+ break;
+ }
+
+ // if array contains no values, no initial value to return
+ if (++i >= len)
+ throw new YamlParseException("no initial value to return");
+ }
+ while (true);
+ }
+
+ for (; i < len; i++)
+ {
+ if (i in tab)
+ rv = fun.call(null, rv, tab[i], i, tab);
+ }
+
+ return rv;
+ },*/
+
+ octdec: function(input)
+ {
+ return parseInt((input+'').replace(/[^0-7]/gi, ''), 8);
+ },
+
+ hexdec: function(input)
+ {
+ input = this.trim(input);
+ if ( (input+'').substr(0, 2) == '0x' ) input = (input+'').substring(2);
+ return parseInt((input+'').replace(/[^a-f0-9]/gi, ''), 16);
+ },
+
+ /**
+ * @see http://phpjs.org/functions/strtotime
+ * @note we need timestamp with msecs so /1000 removed
+ * @note original contained binary | 0 (wtf?!) everywhere, which messes everything up
+ */
+ strtotime: function (h,b){var f,c,g,k,d="";h=(h+"").replace(/\s{2,}|^\s|\s$/g," ").replace(/[\t\r\n]/g,"");if(h==="now"){return b===null||isNaN(b)?new Date().getTime()||0:b||0}else{if(!isNaN(d=Date.parse(h))){return d||0}else{if(b){b=new Date(b)}else{b=new Date()}}}h=h.toLowerCase();var e={day:{sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6},mon:["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]};var a=function(i){var o=(i[2]&&i[2]==="ago");var n=(n=i[0]==="last"?-1:1)*(o?-1:1);switch(i[0]){case"last":case"next":switch(i[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+n);break;case"wee":b.setDate(b.getDate()+(n*7));break;case"day":b.setDate(b.getDate()+n);break;case"hou":b.setHours(b.getHours()+n);break;case"min":b.setMinutes(b.getMinutes()+n);break;case"sec":b.setSeconds(b.getSeconds()+n);break;case"mon":if(i[1]==="month"){b.setMonth(b.getMonth()+n);break}default:var l=e.day[i[1].substring(0,3)];if(typeof l!=="undefined"){var p=l-b.getDay();if(p===0){p=7*n}else{if(p>0){if(i[0]==="last"){p-=7}}else{if(i[0]==="next"){p+=7}}}b.setDate(b.getDate()+p);b.setHours(0,0,0,0)}}break;default:if(/\d+/.test(i[0])){n*=parseInt(i[0],10);switch(i[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+n);break;case"mon":b.setMonth(b.getMonth()+n);break;case"wee":b.setDate(b.getDate()+(n*7));break;case"day":b.setDate(b.getDate()+n);break;case"hou":b.setHours(b.getHours()+n);break;case"min":b.setMinutes(b.getMinutes()+n);break;case"sec":b.setSeconds(b.getSeconds()+n);break}}else{return false}break}return true};g=h.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);if(g!==null){if(!g[2]){g[2]="00:00:00"}else{if(!g[3]){g[2]+=":00"}}k=g[1].split(/-/g);k[1]=e.mon[k[1]-1]||k[1];k[0]=+k[0];k[0]=(k[0]>=0&&k[0]<=69)?"20"+(k[0]<10?"0"+k[0]:k[0]+""):(k[0]>=70&&k[0]<=99)?"19"+k[0]:k[0]+"";return parseInt(this.strtotime(k[2]+" "+k[1]+" "+k[0]+" "+g[2])+(g[4]?g[4]:""),10)}var j="([+-]?\\d+\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)|(last|next)\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))(\\sago)?";g=h.match(new RegExp(j,"gi"));if(g===null){return false}for(f=0,c=g.length;f<c;f++){if(!a(g[f].split(" "))){return false}}return b.getTime()||0}
+
+};
+
+/*
+ * @note uses only non-capturing sub-patterns (unlike PHP original)
+ */
+YamlInline.REGEX_QUOTED_STRING = '(?:"(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'(?:[^\']*(?:\'\'[^\']*)*)\')';
+
+
+/**
+ * YamlParser parses YAML strings to convert them to JS objects
+ * (port of Yaml Symfony Component)
+ */
+var YamlParser = function(offset /* Integer */)
+{
+ this.offset = (offset !== undefined) ? offset : 0;
+};
+YamlParser.prototype =
+{
+ offset: 0,
+ lines: [],
+ currentLineNb: -1,
+ currentLine: '',
+ refs: {},
+
+ /**
+ * Parses a YAML string to a JS value.
+ *
+ * @param String value A YAML string
+ *
+ * @return mixed A JS value
+ */
+ parse: function(value /* String */)
+ {
+ this.currentLineNb = -1;
+ this.currentLine = '';
+ this.lines = this.cleanup(value).split("\n");
+
+ var data = null;
+ var context = null;
+
+ while ( this.moveToNextLine() )
+ {
+ if ( this.isCurrentLineEmpty() )
+ {
+ continue;
+ }
+
+ // tab?
+ if ( this.currentLine.charAt(0) == '\t' )
+ {
+ throw new YamlParseException('A YAML file cannot contain tabs as indentation.', this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+
+ var isRef = false;
+ var isInPlace = false;
+ var isProcessed = false;
+ var values = null;
+ var matches = null;
+ var c = null;
+ var parser = null;
+ var block = null;
+ var key = null;
+ var parsed = null;
+ var len = null;
+ var reverse = null;
+
+ if ( values = /^\-((\s+)(.+?))?\s*$/.exec(this.currentLine) )
+ {
+
+ if (context && 'mapping' == context) {
+ throw new YamlParseException('You cannot define a sequence item when in a mapping', this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+ context = 'sequence';
+
+ if ( !this.isDefined(data) ) data = [];
+ //if ( !(data instanceof Array) ) throw new YamlParseException("Non array entry", this.getRealCurrentLineNb() + 1, this.currentLine);
+
+ values = {leadspaces: values[2], value: values[3]};
+
+ if ( this.isDefined(values.value) && ( matches = /^&([^ ]+) *(.*)/.exec(values.value) ) )
+ {
+ matches = {ref: matches[1], value: matches[2]};
+ isRef = matches.ref;
+ values.value = matches.value;
+ }
+
+ // array
+ if ( !this.isDefined(values.value) || '' == this.trim(values.value) || values.value.replace(/^ +/,'').charAt(0) == '#' )
+ {
+ c = this.getRealCurrentLineNb() + 1;
+ parser = new YamlParser(c);
+ parser.refs = this.refs;
+ data.push(parser.parse(this.getNextEmbedBlock()));
+ this.refs = parser.refs;
+ }
+ else
+ {
+ if ( this.isDefined(values.leadspaces) &&
+ ' ' == values.leadspaces &&
+ ( matches = new RegExp('^('+YamlInline.REGEX_QUOTED_STRING+'|[^ \'"\{\[].*?) *\:(\\s+(.+?))?\\s*$').exec(values.value) )
+ ) {
+ matches = {key: matches[1], value: matches[3]};
+ // this is a compact notation element, add to next block and parse
+ c = this.getRealCurrentLineNb();
+ parser = new YamlParser(c);
+ parser.refs = this.refs;
+ block = values.value;
+
+ if ( !this.isNextLineIndented() )
+ {
+ block += "\n"+this.getNextEmbedBlock(this.getCurrentLineIndentation() + 2);
+ }
+
+ data.push(parser.parse(block));
+ this.refs = parser.refs;
+ }
+ else
+ {
+ data.push(this.parseValue(values.value));
+ }
+ }
+ }
+ else if ( values = new RegExp('^('+YamlInline.REGEX_QUOTED_STRING+'|[^ \'"\[\{].*?) *\:(\\s+(.+?))?\\s*$').exec(this.currentLine) )
+ {
+ if ( !this.isDefined(data) ) data = {};
+ if (context && 'sequence' == context) {
+ throw new YamlParseException('You cannot define a mapping item when in a sequence', this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+ context = 'mapping';
+ //if ( data instanceof Array ) throw new YamlParseException("Non mapped entry", this.getRealCurrentLineNb() + 1, this.currentLine);
+
+ values = {key: values[1], value: values[3]};
+
+ try {
+ key = new YamlInline().parseScalar(values.key);
+ } catch (e) {
+ if ( e instanceof YamlParseException ) {
+ e.setParsedLine(this.getRealCurrentLineNb() + 1);
+ e.setSnippet(this.currentLine);
+ }
+ throw e;
+ }
+
+
+ if ( '<<' == key )
+ {
+ if ( this.isDefined(values.value) && '*' == (values.value+'').charAt(0) )
+ {
+ isInPlace = values.value.substr(1);
+ if ( this.refs[isInPlace] == undefined )
+ {
+ throw new YamlParseException('Reference "'+value+'" does not exist', this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+ }
+ else
+ {
+ if ( this.isDefined(values.value) && values.value != '' )
+ {
+ value = values.value;
+ }
+ else
+ {
+ value = this.getNextEmbedBlock();
+ }
+
+ c = this.getRealCurrentLineNb() + 1;
+ parser = new YamlParser(c);
+ parser.refs = this.refs;
+ parsed = parser.parse(value);
+ this.refs = parser.refs;
+
+ var merged = [];
+ if ( !this.isObject(parsed) )
+ {
+ throw new YamlParseException("YAML merge keys used with a scalar value instead of an array", this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+ else if ( this.isDefined(parsed[0]) )
+ {
+ // Numeric array, merge individual elements
+ reverse = this.reverseArray(parsed);
+ len = reverse.length;
+ for ( var i = 0; i < len; i++ )
+ {
+ var parsedItem = reverse[i];
+ if ( !this.isObject(reverse[i]) )
+ {
+ throw new YamlParseException("Merge items must be arrays", this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+ merged = this.mergeObject(reverse[i], merged);
+ }
+ }
+ else
+ {
+ // Associative array, merge
+ merged = this.mergeObject(merged, parsed);
+ }
+
+ isProcessed = merged;
+ }
+ }
+ else if ( this.isDefined(values.value) && (matches = /^&([^ ]+) *(.*)/.exec(values.value) ) )
+ {
+ matches = {ref: matches[1], value: matches[2]};
+ isRef = matches.ref;
+ values.value = matches.value;
+ }
+
+ if ( isProcessed )
+ {
+ // Merge keys
+ data = isProcessed;
+ }
+ // hash
+ else if ( !this.isDefined(values.value) || '' == this.trim(values.value) || this.trim(values.value).charAt(0) == '#' )
+ {
+ // if next line is less indented or equal, then it means that the current value is null
+ if ( this.isNextLineIndented() && !this.isNextLineUnIndentedCollection() )
+ {
+ data[key] = null;
+ }
+ else
+ {
+ c = this.getRealCurrentLineNb() + 1;
+ parser = new YamlParser(c);
+ parser.refs = this.refs;
+ data[key] = parser.parse(this.getNextEmbedBlock());
+ this.refs = parser.refs;
+ }
+ }
+ else
+ {
+ if ( isInPlace )
+ {
+ data = this.refs[isInPlace];
+ }
+ else
+ {
+ data[key] = this.parseValue(values.value);
+ }
+ }
+ }
+ else
+ {
+ // 1-liner followed by newline
+ if ( 2 == this.lines.length && this.isEmpty(this.lines[1]) )
+ {
+ try {
+ value = new YamlInline().parse(this.lines[0]);
+ } catch (e) {
+ if ( e instanceof YamlParseException ) {
+ e.setParsedLine(this.getRealCurrentLineNb() + 1);
+ e.setSnippet(this.currentLine);
+ }
+ throw e;
+ }
+
+ if ( this.isObject(value) )
+ {
+ first = value[0];
+ if ( typeof(value) == 'string' && '*' == first.charAt(0) )
+ {
+ data = [];
+ len = value.length;
+ for ( var i = 0; i < len; i++ )
+ {
+ data.push(this.refs[value[i].substr(1)]);
+ }
+ value = data;
+ }
+ }
+
+ return value;
+ }
+
+ throw new YamlParseException('Unable to parse.', this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+
+ if ( isRef )
+ {
+ if ( data instanceof Array )
+ this.refs[isRef] = data[data.length-1];
+ else
+ {
+ var lastKey = null;
+ for ( var k in data )
+ {
+ if ( data.hasOwnProperty(k) ) lastKey = k;
+ }
+ this.refs[isRef] = data[k];
+ }
+ }
+ }
+
+ return this.isEmpty(data) ? null : data;
+ },
+
+ /**
+ * Returns the current line number (takes the offset into account).
+ *
+ * @return integer The current line number
+ */
+ getRealCurrentLineNb: function()
+ {
+ return this.currentLineNb + this.offset;
+ },
+
+ /**
+ * Returns the current line indentation.
+ *
+ * @return integer The current line indentation
+ */
+ getCurrentLineIndentation: function()
+ {
+ return this.currentLine.length - this.currentLine.replace(/^ +/g, '').length;
+ },
+
+ /**
+ * Returns the next embed block of YAML.
+ *
+ * @param integer indentation The indent level at which the block is to be read, or null for default
+ *
+ * @return string A YAML string
+ *
+ * @throws YamlParseException When indentation problem are detected
+ */
+ getNextEmbedBlock: function(indentation)
+ {
+ this.moveToNextLine();
+ var newIndent = null;
+ var indent = null;
+
+ if ( !this.isDefined(indentation) )
+ {
+ newIndent = this.getCurrentLineIndentation();
+
+ var unindentedEmbedBlock = this.isStringUnIndentedCollectionItem(this.currentLine);
+
+ if ( !this.isCurrentLineEmpty() && 0 == newIndent && !unindentedEmbedBlock )
+ {
+ throw new YamlParseException('Indentation problem A', this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+ }
+ else
+ {
+ newIndent = indentation;
+ }
+
+ var data = [this.currentLine.substr(newIndent)];
+
+ var isItUnindentedCollection = this.isStringUnIndentedCollectionItem(this.currentLine);
+
+ while ( this.moveToNextLine() )
+ {
+
+ if (isItUnindentedCollection && !this.isStringUnIndentedCollectionItem(this.currentLine)) {
+ this.moveToPreviousLine();
+ break;
+ }
+
+ if ( this.isCurrentLineEmpty() )
+ {
+ if ( this.isCurrentLineBlank() )
+ {
+ data.push(this.currentLine.substr(newIndent));
+ }
+
+ continue;
+ }
+
+ indent = this.getCurrentLineIndentation();
+ var matches;
+ if ( matches = /^( *)$/.exec(this.currentLine) )
+ {
+ // empty line
+ data.push(matches[1]);
+ }
+ else if ( indent >= newIndent )
+ {
+ data.push(this.currentLine.substr(newIndent));
+ }
+ else if ( 0 == indent )
+ {
+ this.moveToPreviousLine();
+
+ break;
+ }
+ else
+ {
+ throw new YamlParseException('Indentation problem B', this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+ }
+
+ return data.join("\n");
+ },
+
+ /**
+ * Moves the parser to the next line.
+ *
+ * @return Boolean
+ */
+ moveToNextLine: function()
+ {
+ if ( this.currentLineNb >= this.lines.length - 1 )
+ {
+ return false;
+ }
+
+ this.currentLineNb++;
+ this.currentLine = this.lines[this.currentLineNb];
+
+ return true;
+ },
+
+ /**
+ * Moves the parser to the previous line.
+ */
+ moveToPreviousLine: function()
+ {
+ this.currentLineNb--;
+ this.currentLine = this.lines[this.currentLineNb];
+ },
+
+ /**
+ * Parses a YAML value.
+ *
+ * @param string value A YAML value
+ *
+ * @return mixed A JS value
+ *
+ * @throws YamlParseException When reference does not exist
+ */
+ parseValue: function(value)
+ {
+ if ( '*' == (value+'').charAt(0) )
+ {
+ if ( this.trim(value).charAt(0) == '#' )
+ {
+ value = (value+'').substr(1, value.indexOf('#') - 2);
+ }
+ else
+ {
+ value = (value+'').substr(1);
+ }
+
+ if ( this.refs[value] == undefined )
+ {
+ throw new YamlParseException('Reference "'+value+'" does not exist', this.getRealCurrentLineNb() + 1, this.currentLine);
+ }
+ return this.refs[value];
+ }
+
+ var matches = null;
+ if ( matches = /^(\||>)(\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?( +#.*)?$/.exec(value) )
+ {
+ matches = {separator: matches[1], modifiers: matches[2], comments: matches[3]};
+ var modifiers = this.isDefined(matches.modifiers) ? matches.modifiers : '';
+
+ return this.parseFoldedScalar(matches.separator, modifiers.replace(/\d+/g, ''), Math.abs(parseInt(modifiers)));
+ }
+ try {
+ return new YamlInline().parse(value);
+ } catch (e) {
+ if ( e instanceof YamlParseException ) {
+ e.setParsedLine(this.getRealCurrentLineNb() + 1);
+ e.setSnippet(this.currentLine);
+ }
+ throw e;
+ }
+ },
+
+ /**
+ * Parses a folded scalar.
+ *
+ * @param string separator The separator that was used to begin this folded scalar (| or >)
+ * @param string indicator The indicator that was used to begin this folded scalar (+ or -)
+ * @param integer indentation The indentation that was used to begin this folded scalar
+ *
+ * @return string The text value
+ */
+ parseFoldedScalar: function(separator, indicator, indentation)
+ {
+ if ( indicator == undefined ) indicator = '';
+ if ( indentation == undefined ) indentation = 0;
+
+ separator = '|' == separator ? "\n" : ' ';
+ var text = '';
+ var diff = null;
+
+ var notEOF = this.moveToNextLine();
+
+ while ( notEOF && this.isCurrentLineBlank() )
+ {
+ text += "\n";
+
+ notEOF = this.moveToNextLine();
+ }
+
+ if ( !notEOF )
+ {
+ return '';
+ }
+
+ var matches = null;
+ if ( !(matches = new RegExp('^('+(indentation ? this.strRepeat(' ', indentation) : ' +')+')(.*)$').exec(this.currentLine)) )
+ {
+ this.moveToPreviousLine();
+
+ return '';
+ }
+
+ matches = {indent: matches[1], text: matches[2]};
+
+ var textIndent = matches.indent;
+ var previousIndent = 0;
+
+ text += matches.text + separator;
+ while ( this.currentLineNb + 1 < this.lines.length )
+ {
+ this.moveToNextLine();
+
+ if ( matches = new RegExp('^( {'+textIndent.length+',})(.+)$').exec(this.currentLine) )
+ {
+ matches = {indent: matches[1], text: matches[2]};
+
+ if ( ' ' == separator && previousIndent != matches.indent )
+ {
+ text = text.substr(0, text.length - 1)+"\n";
+ }
+
+ previousIndent = matches.indent;
+
+ diff = matches.indent.length - textIndent.length;
+ text += this.strRepeat(' ', diff) + matches.text + (diff != 0 ? "\n" : separator);
+ }
+ else if ( matches = /^( *)$/.exec(this.currentLine) )
+ {
+ text += matches[1].replace(new RegExp('^ {1,'+textIndent.length+'}','g'), '')+"\n";
+ }
+ else
+ {
+ this.moveToPreviousLine();
+
+ break;
+ }
+ }
+
+ if ( ' ' == separator )
+ {
+ // replace last separator by a newline
+ text = text.replace(/ (\n*)$/g, "\n$1");
+ }
+
+ switch ( indicator )
+ {
+ case '':
+ text = text.replace(/\n+$/g, "\n");
+ break;
+ case '+':
+ break;
+ case '-':
+ text = text.replace(/\n+$/g, '');
+ break;
+ }
+
+ return text;
+ },
+
+ /**
+ * Returns true if the next line is indented.
+ *
+ * @return Boolean Returns true if the next line is indented, false otherwise
+ */
+ isNextLineIndented: function()
+ {
+ var currentIndentation = this.getCurrentLineIndentation();
+ var notEOF = this.moveToNextLine();
+
+ while ( notEOF && this.isCurrentLineEmpty() )
+ {
+ notEOF = this.moveToNextLine();
+ }
+
+ if ( false == notEOF )
+ {
+ return false;
+ }
+
+ var ret = false;
+ if ( this.getCurrentLineIndentation() <= currentIndentation )
+ {
+ ret = true;
+ }
+
+ this.moveToPreviousLine();
+
+ return ret;
+ },
+
+ /**
+ * Returns true if the current line is blank or if it is a comment line.
+ *
+ * @return Boolean Returns true if the current line is empty or if it is a comment line, false otherwise
+ */
+ isCurrentLineEmpty: function()
+ {
+ return this.isCurrentLineBlank() || this.isCurrentLineComment();
+ },
+
+ /**
+ * Returns true if the current line is blank.
+ *
+ * @return Boolean Returns true if the current line is blank, false otherwise
+ */
+ isCurrentLineBlank: function()
+ {
+ return '' == this.trim(this.currentLine);
+ },
+
+ /**
+ * Returns true if the current line is a comment line.
+ *
+ * @return Boolean Returns true if the current line is a comment line, false otherwise
+ */
+ isCurrentLineComment: function()
+ {
+ //checking explicitly the first char of the trim is faster than loops or strpos
+ var ltrimmedLine = this.currentLine.replace(/^ +/g, '');
+ return ltrimmedLine.charAt(0) == '#';
+ },
+
+ /**
+ * Cleanups a YAML string to be parsed.
+ *
+ * @param string value The input YAML string
+ *
+ * @return string A cleaned up YAML string
+ */
+ cleanup: function(value)
+ {
+ value = value.split("\r\n").join("\n").split("\r").join("\n");
+
+ if ( !/\n$/.test(value) )
+ {
+ value += "\n";
+ }
+
+ // strip YAML header
+ var count = 0;
+ var regex = /^\%YAML[: ][\d\.]+.*\n/;
+ while ( regex.test(value) )
+ {
+ value = value.replace(regex, '');
+ count++;
+ }
+ this.offset += count;
+
+ // remove leading comments
+ regex = /^(#.*?\n)+/;
+ if ( regex.test(value) )
+ {
+ var trimmedValue = value.replace(regex, '');
+
+ // items have been removed, update the offset
+ this.offset += this.subStrCount(value, "\n") - this.subStrCount(trimmedValue, "\n");
+ value = trimmedValue;
+ }
+
+ // remove start of the document marker (---)
+ regex = /^\-\-\-.*?\n/;
+ if ( regex.test(value) )
+ {
+ trimmedValue = value.replace(regex, '');
+
+ // items have been removed, update the offset
+ this.offset += this.subStrCount(value, "\n") - this.subStrCount(trimmedValue, "\n");
+ value = trimmedValue;
+
+ // remove end of the document marker (...)
+ value = value.replace(/\.\.\.\s*$/g, '');
+ }
+
+ return value;
+ },
+
+ /**
+ * Returns true if the next line starts unindented collection
+ *
+ * @return Boolean Returns true if the next line starts unindented collection, false otherwise
+ */
+ isNextLineUnIndentedCollection: function()
+ {
+ var currentIndentation = this.getCurrentLineIndentation();
+ var notEOF = this.moveToNextLine();
+
+ while (notEOF && this.isCurrentLineEmpty()) {
+ notEOF = this.moveToNextLine();
+ }
+
+ if (false === notEOF) {
+ return false;
+ }
+
+ var ret = false;
+ if (
+ this.getCurrentLineIndentation() == currentIndentation
+ &&
+ this.isStringUnIndentedCollectionItem(this.currentLine)
+ ) {
+ ret = true;
+ }
+
+ this.moveToPreviousLine();
+
+ return ret;
+ },
+
+ /**
+ * Returns true if the string is unindented collection item
+ *
+ * @return Boolean Returns true if the string is unindented collection item, false otherwise
+ */
+ isStringUnIndentedCollectionItem: function(string)
+ {
+ return (0 === this.currentLine.indexOf('- '));
+ },
+
+ isObject: function(input)
+ {
+ return typeof(input) == 'object' && this.isDefined(input);
+ },
+
+ isEmpty: function(input)
+ {
+ return input == undefined || input == null || input == '' || input == 0 || input == "0" || input == false;
+ },
+
+ isDefined: function(input)
+ {
+ return input != undefined && input != null;
+ },
+
+ reverseArray: function(input /* Array */)
+ {
+ var result = [];
+ var len = input.length;
+ for ( var i = len-1; i >= 0; i-- )
+ {
+ result.push(input[i]);
+ }
+
+ return result;
+ },
+
+ merge: function(a /* Object */, b /* Object */)
+ {
+ var c = {};
+ var i;
+
+ for ( i in a )
+ {
+ if ( a.hasOwnProperty(i) )
+ if ( /^\d+$/.test(i) ) c.push(a);
+ else c[i] = a[i];
+ }
+ for ( i in b )
+ {
+ if ( b.hasOwnProperty(i) )
+ if ( /^\d+$/.test(i) ) c.push(b);
+ else c[i] = b[i];
+ }
+
+ return c;
+ },
+
+ strRepeat: function(str /* String */, count /* Integer */)
+ {
+ var i;
+ var result = '';
+ for ( i = 0; i < count; i++ ) result += str;
+ return result;
+ },
+
+ subStrCount: function(string, subString, start, length)
+ {
+ var c = 0;
+
+ string = '' + string;
+ subString = '' + subString;
+
+ if ( start != undefined ) string = string.substr(start);
+ if ( length != undefined ) string = string.substr(0, length);
+
+ var len = string.length;
+ var sublen = subString.length;
+ for ( var i = 0; i < len; i++ )
+ {
+ if ( subString == string.substr(i, sublen) )
+ c++;
+ i += sublen - 1;
+ }
+
+ return c;
+ },
+
+ trim: function(str /* String */)
+ {
+ return (str+'').replace(/^ +/,'').replace(/ +$/,'');
+ }
+};
+/**
+ * YamlEscaper encapsulates escaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ */
+YamlEscaper = function(){};
+YamlEscaper.prototype =
+{
+ /**
+ * Determines if a JS value would require double quoting in YAML.
+ *
+ * @param string value A JS value
+ *
+ * @return Boolean True if the value would require double quotes.
+ */
+ requiresDoubleQuoting: function(value)
+ {
+ return new RegExp(YamlEscaper.REGEX_CHARACTER_TO_ESCAPE).test(value);
+ },
+
+ /**
+ * Escapes and surrounds a JS value with double quotes.
+ *
+ * @param string value A JS value
+ *
+ * @return string The quoted, escaped string
+ */
+ escapeWithDoubleQuotes: function(value)
+ {
+ value = value + '';
+ var len = YamlEscaper.escapees.length;
+ var maxlen = YamlEscaper.escaped.length;
+ var esc = YamlEscaper.escaped;
+ for (var i = 0; i < len; ++i)
+ if ( i >= maxlen ) esc.push('');
+
+ var ret = '';
+ ret = value.replace(new RegExp(YamlEscaper.escapees.join('|'),'g'), function(str){
+ for(var i = 0; i < len; ++i){
+ if( str == YamlEscaper.escapees[i] )
+ return esc[i];
+ }
+ });
+ return '"' + ret + '"';
+ },
+
+ /**
+ * Determines if a JS value would require single quoting in YAML.
+ *
+ * @param string value A JS value
+ *
+ * @return Boolean True if the value would require single quotes.
+ */
+ requiresSingleQuoting: function(value)
+ {
+ return /[\s'":{}[\],&*#?]|^[-?|<>=!%@`]/.test(value);
+ },
+
+ /**
+ * Escapes and surrounds a JS value with single quotes.
+ *
+ * @param string value A JS value
+ *
+ * @return string The quoted, escaped string
+ */
+ escapeWithSingleQuotes : function(value)
+ {
+ return "'" + value.replace(/'/g, "''") + "'";
+ }
+};
+
+// Characters that would cause a dumped string to require double quoting.
+YamlEscaper.REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
+
+// Mapping arrays for escaping a double quoted string. The backslash is
+// first to ensure proper escaping.
+YamlEscaper.escapees = ['\\\\', '\\"', '"',
+ "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
+ "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
+ "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
+ "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
+ "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9"];
+YamlEscaper.escaped = ['\\"', '\\\\', '\\"',
+ "\\0", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a",
+ "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "\\x0e", "\\x0f",
+ "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17",
+ "\\x18", "\\x19", "\\x1a", "\\e", "\\x1c", "\\x1d", "\\x1e", "\\x1f",
+ "\\N", "\\_", "\\L", "\\P"];
+/**
+ * YamlUnescaper encapsulates unescaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ */
+var YamlUnescaper = function(){};
+YamlUnescaper.prototype =
+{
+ /**
+ * Unescapes a single quoted string.
+ *
+ * @param string value A single quoted string.
+ *
+ * @return string The unescaped string.
+ */
+ unescapeSingleQuotedString: function(value)
+ {
+ return value.replace(/''/g, "'");
+ },
+
+ /**
+ * Unescapes a double quoted string.
+ *
+ * @param string value A double quoted string.
+ *
+ * @return string The unescaped string.
+ */
+ unescapeDoubleQuotedString: function(value)
+ {
+ var callback = function(m) {
+ return new YamlUnescaper().unescapeCharacter(m);
+ };
+
+ // evaluate the string
+ return value.replace(new RegExp(YamlUnescaper.REGEX_ESCAPED_CHARACTER, 'g'), callback);
+ },
+
+ /**
+ * Unescapes a character that was found in a double-quoted string
+ *
+ * @param string value An escaped character
+ *
+ * @return string The unescaped character
+ */
+ unescapeCharacter: function(value)
+ {
+ switch (value.charAt(1)) {
+ case '0':
+ return String.fromCharCode(0);
+ case 'a':
+ return String.fromCharCode(7);
+ case 'b':
+ return String.fromCharCode(8);
+ case 't':
+ return "\t";
+ case "\t":
+ return "\t";
+ case 'n':
+ return "\n";
+ case 'v':
+ return String.fromCharCode(11);
+ case 'f':
+ return String.fromCharCode(12);
+ case 'r':
+ return String.fromCharCode(13);
+ case 'e':
+ return "\x1b";
+ case ' ':
+ return ' ';
+ case '"':
+ return '"';
+ case '/':
+ return '/';
+ case '\\':
+ return '\\';
+ case 'N':
+ // U+0085 NEXT LINE
+ return "\x00\x85";
+ case '_':
+ // U+00A0 NO-BREAK SPACE
+ return "\x00\xA0";
+ case 'L':
+ // U+2028 LINE SEPARATOR
+ return "\x20\x28";
+ case 'P':
+ // U+2029 PARAGRAPH SEPARATOR
+ return "\x20\x29";
+ case 'x':
+ return this.pack('n', new YamlInline().hexdec(value.substr(2, 2)));
+ case 'u':
+ return this.pack('n', new YamlInline().hexdec(value.substr(2, 4)));
+ case 'U':
+ return this.pack('N', new YamlInline().hexdec(value.substr(2, 8)));
+ }
+ },
+
+ /**
+ * @see http://phpjs.org/functions/pack
+ * @warning only modes used above copied
+ */
+ pack: function(B){var g=0,o=1,m="",l="",z=0,p=[],E,s,C,I,h,c;var d,b,x,H,u,e,A,q,D,t,w,a,G,F,y,v,f;while(g<B.length){E=B.charAt(g);s="";g++;while((g<B.length)&&(B.charAt(g).match(/[\d\*]/)!==null)){s+=B.charAt(g);g++}if(s===""){s="1"}switch(E){case"n":if(s==="*"){s=arguments.length-o}if(s>(arguments.length-o)){throw new Error("Warning: pack() Type "+E+": too few arguments")}for(z=0;z<s;z++){m+=String.fromCharCode(arguments[o]>>8&255);m+=String.fromCharCode(arguments[o]&255);o++}break;case"N":if(s==="*"){s=arguments.length-o}if(s>(arguments.length-o)){throw new Error("Warning: pack() Type "+E+": too few arguments")}for(z=0;z<s;z++){m+=String.fromCharCode(arguments[o]>>24&255);m+=String.fromCharCode(arguments[o]>>16&255);m+=String.fromCharCode(arguments[o]>>8&255);m+=String.fromCharCode(arguments[o]&255);o++}break;default:throw new Error("Warning: pack() Type "+E+": unknown format code")}}if(o<arguments.length){throw new Error("Warning: pack(): "+(arguments.length-o)+" arguments unused")}return m}
+}
+
+// Regex fragment that matches an escaped character in a double quoted
+// string.
+// why escape quotes, ffs!
+YamlUnescaper.REGEX_ESCAPED_CHARACTER = '\\\\([0abt\tnvfre "\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})';
+
+/**
+ * YamlDumper dumps JS variables to YAML strings.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+var YamlDumper = function(){};
+YamlDumper.prototype =
+{
+ /**
+ * Dumps a JS value to YAML.
+ *
+ * @param mixed input The JS value
+ * @param integer inline The level where you switch to inline YAML
+ * @param integer indent The level o indentation indentation (used internally)
+ *
+ * @return string The YAML representation of the JS value
+ */
+ dump: function(input, inline, indent)
+ {
+ if ( inline == undefined ) inline = 0;
+ if ( indent == undefined ) indent = 0;
+ var output = '';
+ var prefix = indent ? this.strRepeat(' ', indent) : '';
+ var yaml;
+
+ if ( inline <= 0 || !this.isObject(input) || this.isEmpty(input) )
+ {
+ yaml = new YamlInline();
+ output += prefix + yaml.dump(input);
+ }
+ else
+ {
+ var isAHash = !this.arrayEquals(this.getKeys(input), this.range(0,input.length - 1));
+ var willBeInlined;
+
+ for ( var key in input )
+ {
+ if ( input.hasOwnProperty(key) )
+ {
+ willBeInlined = inline - 1 <= 0 || !this.isObject(input[key]) || this.isEmpty(input[key]);
+
+ if ( isAHash ) yaml = new YamlInline();
+
+ output +=
+ prefix + '' +
+ (isAHash ? yaml.dump(key)+':' : '-') + '' +
+ (willBeInlined ? ' ' : "\n") + '' +
+ this.dump(input[key], inline - 1, (willBeInlined ? 0 : indent + 2)) + '' +
+ (willBeInlined ? "\n" : '');
+ }
+ }
+ }
+
+ return output;
+ },
+
+ strRepeat: function(str /* String */, count /* Integer */)
+ {
+ var i;
+ var result = '';
+ for ( i = 0; i < count; i++ ) result += str;
+ return result;
+ },
+
+ isObject: function(input)
+ {
+ return this.isDefined(input) && typeof(input) == 'object';
+ },
+
+ isEmpty: function(input)
+ {
+ var ret = input == undefined || input == null || input == '' || input == 0 || input == "0" || input == false;
+ if ( !ret && typeof(input) == "object" && !(input instanceof Array)){
+ var propCount = 0;
+ for ( var key in input )
+ if ( input.hasOwnProperty(key) ) propCount++;
+ ret = !propCount;
+ }
+ return ret;
+ },
+
+ isDefined: function(input)
+ {
+ return input != undefined && input != null;
+ },
+
+ getKeys: function(tab)
+ {
+ var ret = [];
+
+ for ( var name in tab )
+ {
+ if ( tab.hasOwnProperty(name) )
+ {
+ ret.push(name);
+ }
+ }
+
+ return ret;
+ },
+
+ range: function(start, end)
+ {
+ if ( start > end ) return [];
+
+ var ret = [];
+
+ for ( var i = start; i <= end; i++ )
+ {
+ ret.push(i);
+ }
+
+ return ret;
+ },
+
+ arrayEquals: function(a,b)
+ {
+ if ( a.length != b.length ) return false;
+
+ var len = a.length;
+
+ for ( var i = 0; i < len; i++ )
+ {
+ if ( a[i] != b[i] ) return false;
+ }
+
+ return true;
+ }
+};
diff --git a/bin/yaml.min.js b/bin/yaml.min.js
new file mode 100644
index 0000000..a9791c2
--- /dev/null
+++ b/bin/yaml.min.js
@@ -0,0 +1,22 @@
+/*
+Copyright (c) 2010 Jeremy Faivre
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+var YamlParseException=function(e,t,n,r){this.rawMessage=e,this.parsedLine=t!==undefined?t:-1,this.snippet=n!==undefined?n:null,this.parsedFile=r!==undefined?r:null,this.updateRepr(),this.message=e};YamlParseException.prototype={name:"YamlParseException",message:null,parsedFile:null,parsedLine:-1,snippet:null,rawMessage:null,isDefined:function(e){return e!=undefined&&e!=null},getSnippet:function(){return this.snippet},setSnippet:function(e){this.snippet=e,this.updateRepr()},getParsedFile:function(){return this.parsedFile},setParsedFile:function(e){this.parsedFile=e,this.updateRepr()},getParsedLine:function(){return this.parsedLine},setParsedLine:function(e){this.parsedLine=e,this.updateRepr()},updateRepr:function(){this.message=this.rawMessage,dot=!1,"."===this.message.charAt(this.message.length-1)&&(this.message=this.message.substring(0,this.message.length-1),dot=!0),null!==this.parsedFile&&(this.message+=" in "+JSON.stringify(this.parsedFile)),this.parsedLine>=0&&(this.message+=" at line "+this.parsedLine),this.snippet&&(this.message+=' (near "'+this.snippet+'")'),dot&&(this.message+=".")}};var isNode=!1,Yaml=function(){};Yaml.prototype={parseFile:function(e,t){if(t==null){var n=this.getFileContents(e),r=null;try{r=this.parse(n)}catch(i){throw i instanceof YamlParseException&&i.setParsedFile(e),i}return r}this.getFileContents(e,function(e){t((new Yaml).parse(e))})},parse:function(e){var t=new YamlParser;return t.parse(e)},dump:function(e,t){t==null&&(t=2);var n=new YamlDumper;return n.dump(e,t)},getXHR:function(){if(window.XMLHttpRequest)return new XMLHttpRequest;if(window.ActiveXObject){var e=["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];for(var t=0;t<4;t++)try{return new ActiveXObject(e[t])}catch(n){}}return null},getFileContents:function(e,t){if(isNode){var n=require("fs");if(t==null){var r=n.readFileSync(e);return r==null?null:""+r}n.readFile(e,function(e,n){e?t(null):t(n)})}else{var i=this.getXHR();if(t==null)return i.open("GET",e,!1),i.send(null),i.status==200||i.status==0?i.responseText:null;i.onreadystatechange=function(){i.readyState==4&&(i.status==200||i.status==0?t(i.responseText):t(null))},i.open("GET",e,!0),i.send(null)}}};var YAML={stringify:function(e,t){return(new Yaml).dump(e,t)},parse:function(e){return(new Yaml).parse(e)},load:function(e,t){return(new Yaml).parseFile(e,t)}};typeof exports!="undefined"&&typeof module!="undefined"&&module.exports&&(exports=module.exports=YAML,isNode=!0,function(){var e=function(e,t){e.exports=YAML.load(t)};undefined!==require.extensions&&(require.extensions[".yml"]=e,require.extensions[".yaml"]=e)}());var YamlInline=function(){};YamlInline.prototype={i:null,parse:function(e){var t=null;e=this.trim(e);if(0==e.length)return"";switch(e.charAt(0)){case"[":t=this.parseSequence(e);break;case"{":t=this.parseMapping(e);break;default:t=this.parseScalar(e);if(e.substr(this.i).replace(/^\s+#.*$/,""))throw new YamlParseException('Unexpected characters near "'+e.substr(this.i)+'".')}return t},dump:function(e){if(undefined==e||null==e)return"null";if(e instanceof Date)return e.toISOString();if(typeof e=="object")return this.dumpObject(e);if(typeof e=="boolean")return e?"true":"false";if(/^\d+$/.test(e))return typeof e=="string"?"'"+e+"'":parseInt(e);if(this.isNumeric(e))return typeof e=="string"?"'"+e+"'":parseFloat(e);if(typeof e=="number")return e==Infinity?".Inf":e==-Infinity?"-.Inf":isNaN(e)?".NAN":e;var t=new YamlEscaper;return t.requiresDoubleQuoting(e)?t.escapeWithDoubleQuotes(e):t.requiresSingleQuoting(e)?t.escapeWithSingleQuotes(e):""==e?"":this.getTimestampRegex().test(e)?"'"+e+"'":this.inArray(e.toLowerCase(),["null","~","true","false"])?"'"+e+"'":e},dumpObject:function(e){var t=this.getKeys(e),n=null,r,i=t.length;if(e instanceof Array){n=[];for(r=0;r<i;r++)n.push(this.dump(e[t[r]]));return"["+n.join(", ")+"]"}n=[];for(r=0;r<i;r++)n.push(this.dump(t[r])+": "+this.dump(e[t[r]]));return"{ "+n.join(", ")+" }"},parseScalar:function(e,t,n,r,i){t==undefined&&(t=null),n==undefined&&(n=['"',"'"]),r==undefined&&(r=0),i==undefined&&(i=!0);var s=null,o=null,u=null;if(this.inArray(e[r],n)){s=this.parseQuotedScalar(e,r),r=this.i;if(null!==t){var a=e.substr(r).replace(/^\s+/,"");if(!this.inArray(a.charAt(0),t))throw new YamlParseException("Unexpected characters ("+e.substr(r)+").")}}else{if(!t)s=(e+"").substring(r),r+=s.length,o=s.indexOf(" #"),o!=-1&&(s=s.substr(0,o).replace(/\s+$/g,""));else{if(!(u=(new RegExp("^(.+?)("+t.join("|")+")")).exec((e+"").substring(r))))throw new YamlParseException("Malformed inline YAML string ("+e+").");s=u[1],r+=s.length}s=i?this.evaluateScalar(s):s}return this.i=r,s},parseQuotedScalar:function(e,t){var n=null;if(!(n=(new RegExp("^"+YamlInline.REGEX_QUOTED_STRING)).exec((e+"").substring(t))))throw new YamlParseException("Malformed inline YAML string ("+(e+"").substring(t)+").");var r=n[0].substr(1,n[0].length-2),i=new YamlUnescaper;return'"'==(e+"").charAt(t)?r=i.unescapeDoubleQuotedString(r):r=i.unescapeSingleQuotedString(r),t+=n[0].length,this.i=t,r},parseSequence:function(e,t){t==undefined&&(t=0);var n=[],r=e.length;t+=1;while(t<r){switch(e.charAt(t)){case"[":n.push(this.parseSequence(e,t)),t=this.i;break;case"{":n.push(this.parseMapping(e,t)),t=this.i;break;case"]":return this.i=t,n;case",":case" ":break;default:isQuoted=this.inArray(e.charAt(t),['"',"'"]);var i=this.parseScalar(e,[",","]"],['"',"'"],t);t=this.i;if(!isQuoted&&(i+"").indexOf(": ")!=-1)try{i=this.parseMapping("{"+i+"}")}catch(s){if(!(s instanceof YamlParseException))throw s}n.push(i),t--}t++}throw new YamlParseException('Malformed inline YAML string "'+e+'"')},parseMapping:function(e,t){t==undefined&&(t=0);var n={},r=e.length;t+=1;var i=!1,s=!1;while(t<r){s=!1;switch(e.charAt(t)){case" ":case",":t++,s=!0;break;case"}":return this.i=t,n}if(s)continue;var o=this.parseScalar(e,[":"," "],['"',"'"],t,!1);t=this.i,i=!1;while(t<r){switch(e.charAt(t)){case"[":n[o]=this.parseSequence(e,t),t=this.i,i=!0;break;case"{":n[o]=this.parseMapping(e,t),t=this.i,i=!0;break;case":":case" ":break;default:n[o]=this.parseScalar(e,[",","}"],['"',"'"],t),t=this.i,i=!0,t--}++t;if(i){s=!0;break}}if(s)continue}throw new YamlParseException('Malformed inline YAML string "'+e+'"')},evaluateScalar:function(e){e=this.trim(e);var t=null,n=null;return"null"==e.toLowerCase()||""==e||"~"==e?null:(e+"").indexOf("!str ")==0?(""+e).substring(5):(e+"").indexOf("! ")==0?parseInt(this.parseScalar((e+"").substr(2))):/^\d+$/.test(e)?(t=e,n=parseInt(e),"0"==e.charAt(0)?this.octdec(e):""+t==""+n?n:t):"true"==(e+"").toLowerCase()?!0:"false"==(e+"").toLowerCase()?!1:this.isNumeric(e)?"0x"==(e+"").substr(0,2)?this.hexdec(e):parseFloat(e):e.toLowerCase()==".inf"?Infinity:e.toLowerCase()==".nan"?NaN:e.toLowerCase()=="-.inf"?-Infinity:/^(-|\+)?[0-9,]+(\.[0-9]+)?$/.test(e)?parseFloat(e.split(",").join("")):this.getTimestampRegex().test(e)?new Date(this.strtotime(e)):""+e},getTimestampRegex:function(){return new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ ]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:.([0-9]*))?(?:[ ]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?)?$","gi")},trim:function(e){return(e+"").replace(/^\s+/,"").replace(/\s+$/,"")},isNumeric:function(e){return e-0==e&&e.length>0&&e.replace(/\s+/g,"")!=""},inArray:function(e,t){var n,r=t.length;for(n=0;n<r;n++)if(e==t[n])return!0;return!1},getKeys:function(e){var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(n);return t},octdec:function(e){return parseInt((e+"").replace(/[^0-7]/gi,""),8)},hexdec:function(e){return e=this.trim(e),(e+"").substr(0,2)=="0x"&&(e=(e+"").substring(2)),parseInt((e+"").replace(/[^a-f0-9]/gi,""),16)},strtotime:function(e,t){var n,r,i,s,o="";e=(e+"").replace(/\s{2,}|^\s|\s$/g," ").replace(/[\t\r\n]/g,"");if(e==="now")return t===null||isNaN(t)?(new Date).getTime()||0:t||0;if(!isNaN(o=Date.parse(e)))return o||0;t?t=new Date(t):t=new Date,e=e.toLowerCase();var u={day:{sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6},mon:["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]},a=function(e){var n=e[2]&&e[2]==="ago",r=(r=e[0]==="last"?-1:1)*(n?-1:1);switch(e[0]){case"last":case"next":switch(e[1].substring(0,3)){case"yea":t.setFullYear(t.getFullYear()+r);break;case"wee":t.setDate(t.getDate()+r*7);break;case"day":t.setDate(t.getDate()+r);break;case"hou":t.setHours(t.getHours()+r);break;case"min":t.setMinutes(t.getMinutes()+r);break;case"sec":t.setSeconds(t.getSeconds()+r);break;case"mon":if(e[1]==="month"){t.setMonth(t.getMonth()+r);break};default:var i=u.day[e[1].substring(0,3)];if(typeof i!="undefined"){var s=i-t.getDay();s===0?s=7*r:s>0?e[0]==="last"&&(s-=7):e[0]==="next"&&(s+=7),t.setDate(t.getDate()+s),t.setHours(0,0,0,0)}}break;default:if(!/\d+/.test(e[0]))return!1;r*=parseInt(e[0],10);switch(e[1].substring(0,3)){case"yea":t.setFullYear(t.getFullYear()+r);break;case"mon":t.setMonth(t.getMonth()+r);break;case"wee":t.setDate(t.getDate()+r*7);break;case"day":t.setDate(t.getDate()+r);break;case"hou":t.setHours(t.getHours()+r);break;case"min":t.setMinutes(t.getMinutes()+r);break;case"sec":t.setSeconds(t.getSeconds()+r)}}return!0};i=e.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);if(i!==null)return i[2]?i[3]||(i[2]+=":00"):i[2]="00:00:00",s=i[1].split(/-/g),s[1]=u.mon[s[1]-1]||s[1],s[0]=+s[0],s[0]=s[0]>=0&&s[0]<=69?"20"+(s[0]<10?"0"+s[0]:s[0]+""):s[0]>=70&&s[0]<=99?"19"+s[0]:s[0]+"",parseInt(this.strtotime(s[2]+" "+s[1]+" "+s[0]+" "+i[2])+(i[4]?i[4]:""),10);var f="([+-]?\\d+\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)|(last|next)\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))(\\sago)?";i=e.match(new RegExp(f,"gi"));if(i===null)return!1;for(n=0,r=i.length;n<r;n++)if(!a(i[n].split(" ")))return!1;return t.getTime()||0}},YamlInline.REGEX_QUOTED_STRING="(?:\"(?:[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|'(?:[^']*(?:''[^']*)*)')";var YamlParser=function(e){this.offset=e!==undefined?e:0};YamlParser.prototype={offset:0,lines:[],currentLineNb:-1,currentLine:"",refs:{},parse:function(e){this.currentLineNb=-1,this.currentLine="",this.lines=this.cleanup(e).split("\n");var t=null,n=null;while(this.moveToNextLine()){if(this.isCurrentLineEmpty())continue;if(this.currentLine.charAt(0)==" ")throw new YamlParseException("A YAML file cannot contain tabs as indentation.",this.getRealCurrentLineNb()+1,this.currentLine);var r=!1,i=!1,s=!1,o=null,u=null,a=null,f=null,l=null,c=null,h=null,p=null,d=null;if(o=/^\-((\s+)(.+?))?\s*$/.exec(this.currentLine)){if(n&&"mapping"==n)throw new YamlParseException("You cannot define a sequence item when in a mapping",this.getRealCurrentLineNb()+1,this.currentLine);n="sequence",this.isDefined(t)||(t=[]),o={leadspaces:o[2],value:o[3]},this.isDefined(o.value)&&(u=/^&([^ ]+) *(.*)/.exec(o.value))&&(u={ref:u[1],value:u[2]},r=u.ref,o.value=u.value),!this.isDefined(o.value)||""==this.trim(o.value)||o.value.replace(/^ +/,"").charAt(0)=="#"?(a=this.getRealCurrentLineNb()+1,f=new YamlParser(a),f.refs=this.refs,t.push(f.parse(this.getNextEmbedBlock())),this.refs=f.refs):this.isDefined(o.leadspaces)&&" "==o.leadspaces&&(u=(new RegExp("^("+YamlInline.REGEX_QUOTED_STRING+"|[^ '\"{[].*?) *:(\\s+(.+?))?\\s*$")).exec(o.value))?(u={key:u[1],value:u[3]},a=this.getRealCurrentLineNb(),f=new YamlParser(a),f.refs=this.refs,l=o.value,this.isNextLineIndented()||(l+="\n"+this.getNextEmbedBlock(this.getCurrentLineIndentation()+2)),t.push(f.parse(l)),this.refs=f.refs):t.push(this.parseValue(o.value))}else{if(!(o=(new RegExp("^("+YamlInline.REGEX_QUOTED_STRING+"|[^ '\"[{].*?) *:(\\s+(.+?))?\\s*$")).exec(this.currentLine))){if(2==this.lines.length&&this.isEmpty(this.lines[1])){try{e=(new YamlInline).parse(this.lines[0])}catch(v){throw v instanceof YamlParseException&&(v.setParsedLine(this.getRealCurrentLineNb()+1),v.setSnippet(this.currentLine)),v}if(this.isObject(e)){first=e[0];if(typeof e=="string"&&"*"==first.charAt(0)){t=[],p=e.length;for(var g=0;g<p;g++)t.push(this.refs[e[g].substr(1)]);e=t}}return e}throw new YamlParseException("Unable to parse.",this.getRealCurrentLineNb()+1,this.currentLine)}this.isDefined(t)||(t={});if(n&&"sequence"==n)throw new YamlParseException("You cannot define a mapping item when in a sequence",this.getRealCurrentLineNb()+1,this.currentLine);n="mapping",o={key:o[1],value:o[3]};try{c=(new YamlInline).parseScalar(o.key)}catch(v){throw v instanceof YamlParseException&&(v.setParsedLine(this.getRealCurrentLineNb()+1),v.setSnippet(this.currentLine)),v}if("<<"==c)if(this.isDefined(o.value)&&"*"==(o.value+"").charAt(0)){i=o.value.substr(1);if(this.refs[i]==undefined)throw new YamlParseException('Reference "'+e+'" does not exist',this.getRealCurrentLineNb()+1,this.currentLine)}else{this.isDefined(o.value)&&o.value!=""?e=o.value:e=this.getNextEmbedBlock(),a=this.getRealCurrentLineNb()+1,f=new YamlParser(a),f.refs=this.refs,h=f.parse(e),this.refs=f.refs;var m=[];if(!this.isObject(h))throw new YamlParseException("YAML merge keys used with a scalar value instead of an array",this.getRealCurrentLineNb()+1,this.currentLine);if(this.isDefined(h[0])){d=this.reverseArray(h),p=d.length;for(var g=0;g<p;g++){var y=d[g];if(!this.isObject(d[g]))throw new YamlParseException("Merge items must be arrays",this.getRealCurrentLineNb()+1,this.currentLine);m=this.mergeObject(d[g],m)}}else m=this.mergeObject(m,h);s=m}else this.isDefined(o.value)&&(u=/^&([^ ]+) *(.*)/.exec(o.value))&&(u={ref:u[1],value:u[2]},r=u.ref,o.value=u.value);s?t=s:!this.isDefined(o.value)||""==this.trim(o.value)||this.trim(o.value).charAt(0)=="#"?this.isNextLineIndented()&&!this.isNextLineUnIndentedCollection()?t[c]=null:(a=this.getRealCurrentLineNb()+1,f=new YamlParser(a),f.refs=this.refs,t[c]=f.parse(this.getNextEmbedBlock()),this.refs=f.refs):i?t=this.refs[i]:t[c]=this.parseValue(o.value)}if(r)if(t instanceof Array)this.refs[r]=t[t.length-1];else{var b=null;for(var w in t)t.hasOwnProperty(w)&&(b=w);this.refs[r]=t[w]}}return this.isEmpty(t)?null:t},getRealCurrentLineNb:function(){return this.currentLineNb+this.offset},getCurrentLineIndentation:function(){return this.currentLine.length-this.currentLine.replace(/^ +/g,"").length},getNextEmbedBlock:function(e){this.moveToNextLine();var t=null,n=null;if(!this.isDefined(e)){t=this.getCurrentLineIndentation();var r=this.isStringUnIndentedCollectionItem(this.currentLine);if(!this.isCurrentLineEmpty()&&0==t&&!r)throw new YamlParseException("Indentation problem A",this.getRealCurrentLineNb()+1,this.currentLine)}else t=e;var i=[this.currentLine.substr(t)],s=this.isStringUnIndentedCollectionItem(this.currentLine);while(this.moveToNextLine()){if(s&&!this.isStringUnIndentedCollectionItem(this.currentLine)){this.moveToPreviousLine();break}if(this.isCurrentLineEmpty()){this.isCurrentLineBlank()&&i.push(this.currentLine.substr(t));continue}n=this.getCurrentLineIndentation();var o;if(o=/^( *)$/.exec(this.currentLine))i.push(o[1]);else{if(!(n>=t)){if(0==n){this.moveToPreviousLine();break}throw new YamlParseException("Indentation problem B",this.getRealCurrentLineNb()+1,this.currentLine)}i.push(this.currentLine.substr(t))}}return i.join("\n")},moveToNextLine:function(){return this.currentLineNb>=this.lines.length-1?!1:(this.currentLineNb++,this.currentLine=this.lines[this.currentLineNb],!0)},moveToPreviousLine:function(){this.currentLineNb--,this.currentLine=this.lines[this.currentLineNb]},parseValue:function(e){if("*"==(e+"").charAt(0)){this.trim(e).charAt(0)=="#"?e=(e+"").substr(1,e.indexOf("#")-2):e=(e+"").substr(1);if(this.refs[e]==undefined)throw new YamlParseException('Reference "'+e+'" does not exist',this.getRealCurrentLineNb()+1,this.currentLine);return this.refs[e]}var t=null;if(t=/^(\||>)(\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?( +#.*)?$/.exec(e)){t={separator:t[1],modifiers:t[2],comments:t[3]};var n=this.isDefined(t.modifiers)?t.modifiers:"";return this.parseFoldedScalar(t.separator,n.replace(/\d+/g,""),Math.abs(parseInt(n)))}try{return(new YamlInline).parse(e)}catch(r){throw r instanceof YamlParseException&&(r.setParsedLine(this.getRealCurrentLineNb()+1),r.setSnippet(this.currentLine)),r}},parseFoldedScalar:function(e,t,n){t==undefined&&(t=""),n==undefined&&(n=0),e="|"==e?"\n":" ";var r="",i=null,s=this.moveToNextLine();while(s&&this.isCurrentLineBlank())r+="\n",s=this.moveToNextLine();if(!s)return"";var o=null;if(!(o=(new RegExp("^("+(n?this.strRepeat(" ",n):" +")+")(.*)$")).exec(this.currentLine)))return this.moveToPreviousLine(),"";o={indent:o[1],text:o[2]};var u=o.indent,a=0;r+=o.text+e;while(this.currentLineNb+1<this.lines.length){this.moveToNextLine();if(o=(new RegExp("^( {"+u.length+",})(.+)$")).exec(this.currentLine))o={indent:o[1],text:o[2]}," "==e&&a!=o.indent&&(r=r.substr(0,r.length-1)+"\n"),a=o.indent,i=o.indent.length-u.length,r+=this.strRepeat(" ",i)+o.text+(i!=0?"\n":e);else{if(!(o=/^( *)$/.exec(this.currentLine))){this.moveToPreviousLine();break}r+=o[1].replace(new RegExp("^ {1,"+u.length+"}","g"),"")+"\n"}}" "==e&&(r=r.replace(/ (\n*)$/g,"\n$1"));switch(t){case"":r=r.replace(/\n+$/g,"\n");break;case"+":break;case"-":r=r.replace(/\n+$/g,"")}return r},isNextLineIndented:function(){var e=this.getCurrentLineIndentation(),t=this.moveToNextLine();while(t&&this.isCurrentLineEmpty())t=this.moveToNextLine();if(0==t)return!1;var n=!1;return this.getCurrentLineIndentation()<=e&&(n=!0),this.moveToPreviousLine(),n},isCurrentLineEmpty:function(){return this.isCurrentLineBlank()||this.isCurrentLineComment()},isCurrentLineBlank:function(){return""==this.trim(this.currentLine)},isCurrentLineComment:function(){var e=this.currentLine.replace(/^ +/g,"");return e.charAt(0)=="#"},cleanup:function(e){e=e.split("\r\n").join("\n").split("\r").join("\n"),/\n$/.test(e)||(e+="\n");var t=0,n=/^\%YAML[: ][\d\.]+.*\n/;while(n.test(e))e=e.replace(n,""),t++;this.offset+=t,n=/^(#.*?\n)+/;if(n.test(e)){var r=e.replace(n,"");this.offset+=this.subStrCount(e,"\n")-this.subStrCount(r,"\n"),e=r}return n=/^\-\-\-.*?\n/,n.test(e)&&(r=e.replace(n,""),this.offset+=this.subStrCount(e,"\n")-this.subStrCount(r,"\n"),e=r,e=e.replace(/\.\.\.\s*$/g,"")),e},isNextLineUnIndentedCollection:function(){var e=this.getCurrentLineIndentation(),t=this.moveToNextLine();while(t&&this.isCurrentLineEmpty())t=this.moveToNextLine();if(!1===t)return!1;var n=!1;return this.getCurrentLineIndentation()==e&&this.isStringUnIndentedCollectionItem(this.currentLine)&&(n=!0),this.moveToPreviousLine(),n},isStringUnIndentedCollectionItem:function(e){return 0===this.currentLine.indexOf("- ")},isObject:function(e){return typeof e=="object"&&this.isDefined(e)},isEmpty:function(e){return e==undefined||e==null||e==""||e==0||e=="0"||e==0},isDefined:function(e){return e!=undefined&&e!=null},reverseArray:function(e){var t=[],n=e.length;for(var r=n-1;r>=0;r--)t.push(e[r]);return t},merge:function(e,t){var n={},r;for(r in e)e.hasOwnProperty(r)&&(/^\d+$/.test(r)?n.push(e):n[r]=e[r]);for(r in t)t.hasOwnProperty(r)&&(/^\d+$/.test(r)?n.push(t):n[r]=t[r]);return n},strRepeat:function(e,t){var n,r="";for(n=0;n<t;n++)r+=e;return r},subStrCount:function(e,t,n,r){var i=0;e=""+e,t=""+t,n!=undefined&&(e=e.substr(n)),r!=undefined&&(e=e.substr(0,r));var s=e.length,o=t.length;for(var u=0;u<s;u++)t==e.substr(u,o)&&i++,u+=o-1;return i},trim:function(e){return(e+"").replace(/^ +/,"").replace(/ +$/,"")}},YamlEscaper=function(){},YamlEscaper.prototype={requiresDoubleQuoting:function(e){return(new RegExp(YamlEscaper.REGEX_CHARACTER_TO_ESCAPE)).test(e)},escapeWithDoubleQuotes:function(e){e+="";var t=YamlEscaper.escapees.length,n=YamlEscaper.escaped.length,r=YamlEscaper.escaped;for(var i=0;i<t;++i)i>=n&&r.push("");var s="";return s=e.replace(new RegExp(YamlEscaper.escapees.join("|"),"g"),function(e){for(var n=0;n<t;++n)if(e==YamlEscaper.escapees[n])return r[n]}),'"'+s+'"'},requiresSingleQuoting:function(e){return/[\s'":{}[\],&*#?]|^[-?|<>=!%@`]/.test(e)},escapeWithSingleQuotes:function(e){return"'"+e.replace(/'/g,"''")+"'"}},YamlEscaper.REGEX_CHARACTER_TO_ESCAPE="[\\x00-\\x1f]|…| |
|
",YamlEscaper.escapees=["\\\\",'\\"','"',"\0","","","","","","","","\b"," ","\n"," ","\f","\r","","","","","","","","","","","","","","","","","","","…"," ","
","
"],YamlEscaper.escaped=['\\"',"\\\\",'\\"',"\\0","\\x01","\\x02","\\x03","\\x04","\\x05","\\x06","\\a","\\b","\\t","\\n","\\v","\\f","\\r","\\x0e","\\x0f","\\x10","\\x11","\\x12","\\x13","\\x14","\\x15","\\x16","\\x17","\\x18","\\x19","\\x1a","\\e","\\x1c","\\x1d","\\x1e","\\x1f","\\N","\\_","\\L","\\P"];var YamlUnescaper=function(){};YamlUnescaper.prototype={unescapeSingleQuotedString:function(e){return e.replace(/''/g,"'")},unescapeDoubleQuotedString:function(e){var t=function(e){return(new YamlUnescaper).unescapeCharacter(e)};return e.replace(new RegExp(YamlUnescaper.REGEX_ESCAPED_CHARACTER,"g"),t)},unescapeCharacter:function(e){switch(e.charAt(1)){case"0":return String.fromCharCode(0);case"a":return String.fromCharCode(7);case"b":return String.fromCharCode(8);case"t":return" ";case" ":return" ";case"n":return"\n";case"v":return String.fromCharCode(11);case"f":return String.fromCharCode(12);case"r":return String.fromCharCode(13);case"e":return"";case" ":return" ";case'"':return'"';case"/":return"/";case"\\":return"\\";case"N":return"\0Â…";case"_":return"\0 ";case"L":return" (";case"P":return" )";case"x":return this.pack("n",(new YamlInline).hexdec(e.substr(2,2)));case"u":return this.pack("n",(new YamlInline).hexdec(e.substr(2,4)));case"U":return this.pack("N",(new YamlInline).hexdec(e.substr(2,8)))}},pack:function(e){var t=0,n=1,r="",i="",s=0,o=[],u,a,f,l,c,h,p,d,v,m,g,y,b,w,E,S,x,T,N,C,k,L,A;while(t<e.length){u=e.charAt(t),a="",t++;while(t<e.length&&e.charAt(t).match(/[\d\*]/)!==null)a+=e.charAt(t),t++;a===""&&(a="1");switch(u){case"n":a==="*"&&(a=arguments.length-n);if(a>arguments.length-n)throw new Error("Warning: pack() Type "+u+": too few arguments");for(s=0;s<a;s++)r+=String.fromCharCode(arguments[n]>>8&255),r+=String.fromCharCode(arguments[n]&255),n++;break;case"N":a==="*"&&(a=arguments.length-n);if(a>arguments.length-n)throw new Error("Warning: pack() Type "+u+": too few arguments");for(s=0;s<a;s++)r+=String.fromCharCode(arguments[n]>>24&255),r+=String.fromCharCode(arguments[n]>>16&255),r+=String.fromCharCode(arguments[n]>>8&255),r+=String.fromCharCode(arguments[n]&255),n++;break;default:throw new Error("Warning: pack() Type "+u+": unknown format code")}}if(n<arguments.length)throw new Error("Warning: pack(): "+(arguments.length-n)+" arguments unused");return r}},YamlUnescaper.REGEX_ESCAPED_CHARACTER='\\\\([0abt nvfre "\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})';var YamlDumper=function(){};YamlDumper.prototype={dump:function(e,t,n){t==undefined&&(t=0),n==undefined&&(n=0);var r="",i=n?this.strRepeat(" ",n):"",s;if(t<=0||!this.isObject(e)||this.isEmpty(e))s=new YamlInline,r+=i+s.dump(e);else{var o=!this.arrayEquals(this.getKeys(e),this.range(0,e.length-1)),u;for(var a in e)e.hasOwnProperty(a)&&(u=t-1<=0||!this.isObject(e[a])||this.isEmpty(e[a]),o&&(s=new YamlInline),r+=i+""+(o?s.dump(a)+":":"-")+""+(u?" ":"\n")+""+this.dump(e[a],t-1,u?0:n+2)+""+(u?"\n":""))}return r},strRepeat:function(e,t){var n,r="";for(n=0;n<t;n++)r+=e;return r},isObject:function(e){return this.isDefined(e)&&typeof e=="object"},isEmpty:function(e){var t=e==undefined||e==null||e==""||e==0||e=="0"||e==0;if(!t&&typeof e=="object"&&!(e instanceof Array)){var n=0;for(var r in e)e.hasOwnProperty(r)&&n++;t=!n}return t},isDefined:function(e){return e!=undefined&&e!=null},getKeys:function(e){var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(n);return t},range:function(e,t){if(e>t)return[];var n=[];for(var r=e;r<=t;r++)n.push(r);return n},arrayEquals:function(e,t){if(e.length!=t.length)return!1;var n=e.length;for(var r=0;r<n;r++)if(e[r]!=t[r])return!1;return!0}}; \ No newline at end of file
diff --git a/build b/build
new file mode 100755
index 0000000..c85671c
--- /dev/null
+++ b/build
@@ -0,0 +1,41 @@
+#!/bin/sh
+cd `dirname $0`
+
+file="bin/yaml.js"
+
+> $file
+
+echo Compiling $file ...
+
+echo " - LICENSE"
+
+echo "/*" >> $file
+cat LICENSE >> $file
+echo "\n*/" >> $file
+
+echo " - YamlParseException.js"
+cat src/YamlParseException.js >> $file
+echo " - Yaml.js"
+cat src/Yaml.js >> $file
+echo " - YamlInline.js"
+cat src/YamlInline.js >> $file
+echo " - YamlParser.js"
+cat src/YamlParser.js >> $file
+echo " - YamlEscaper.js"
+cat src/YamlEscaper.js >> $file
+echo " - YamlUnescaper.js"
+cat src/YamlUnescaper.js >> $file
+echo " - YamlDumper.js"
+cat src/YamlDumper.js >> $file
+
+file="bin/yaml.min.js"
+
+echo "compressing..."
+echo "/*" > $file
+cat LICENSE >> $file
+echo "\n*/" >> $file
+uglifyjs -nc bin/yaml.js >> $file
+
+echo "yaml.js compiled."
+echo "yaml.min.js compiled."
+
diff --git a/demo.html b/demo/demo.html
index cbff773..87a4f10 100644
--- a/demo.html
+++ b/demo/demo.html
@@ -67,7 +67,7 @@
</style>
<!-- standalone yaml.js library -->
- <script type="text/javascript" src="yaml.js"></script>
+ <script type="text/javascript" src="../bin/yaml.js"></script>
<title>yaml.js demo</title>
</head>
@@ -104,8 +104,8 @@ comments: &gt;
Backup contact is Nancy
Billsmer @ 338-4338.
</textarea>
-<input type="button" id="parse" name="parse" value="Parse &raquo;" onclick="try{document.getElementById('result').innerHTML=JSON.stringify(YAML.decode(document.getElementById('yaml').value))}catch(e){alert(e);}" />
-<div id="tests"><span>You could also try to run some <a href="tests.html" title="Jasmine tests">javascript tests</a> based on <a href="http://www.yaml.org/YAML_for_ruby.html">YAML cookbook for Ruby</a>. All tests should pass. Those that don't are commented out; they deal with multiple YAML documents in one stream which is not supported by jaml.js (and Symfony)</span></div>
+<input type="button" id="parse" name="parse" value="Parse &raquo;" onclick="try{document.getElementById('result').innerHTML=JSON.stringify(YAML.parse(document.getElementById('yaml').value))}catch(e){alert(e);}" />
+<div id="tests"><span>You could also try to run some <a href="tests.html" title="Jasmine tests">javascript tests</a> based on <a href="http://www.yaml.org/YAML_for_ruby.html">YAML cookbook for Ruby</a>. All tests should pass. Those that don't are commented out; they deal with multiple YAML documents in one stream which is not supported by yaml.js (and Symfony)</span></div>
<div id="result"></div>
</form>
diff --git a/libs/demo/mootools.js b/libs/demo/mootools.js
deleted file mode 100644
index 88ae5b5..0000000
--- a/libs/demo/mootools.js
+++ /dev/null
@@ -1,5800 +0,0 @@
-/*
----
-MooTools: the javascript framework
-
-web build:
- - http://mootools.net/core/7c56cfef9dddcf170a5d68e3fb61cfd7
-
-packager build:
- - packager build Core/Core Core/Array Core/String Core/Number Core/Function Core/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/Cookie Core/JSON Core/DOMReady Core/Swiff
-
-/*
----
-
-name: Core
-
-description: The heart of MooTools.
-
-license: MIT-style license.
-
-copyright: Copyright (c) 2006-2010 [Valerio Proietti](http://mad4milk.net/).
-
-authors: The MooTools production team (http://mootools.net/developers/)
-
-inspiration:
- - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)
- - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)
-
-provides: [Core, MooTools, Type, typeOf, instanceOf, Native]
-
-...
-*/
-
-(function(){
-
-this.MooTools = {
- version: '1.3',
- build: 'a3eed692dd85050d80168ec2c708efe901bb7db3'
-};
-
-// typeOf, instanceOf
-
-var typeOf = this.typeOf = function(item){
- if (item == null) return 'null';
- if (item.$family) return item.$family();
-
- if (item.nodeName){
- if (item.nodeType == 1) return 'element';
- if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
- } else if (typeof item.length == 'number'){
- if (item.callee) return 'arguments';
- if ('item' in item) return 'collection';
- }
-
- return typeof item;
-};
-
-var instanceOf = this.instanceOf = function(item, object){
- if (item == null) return false;
- var constructor = item.$constructor || item.constructor;
- while (constructor){
- if (constructor === object) return true;
- constructor = constructor.parent;
- }
- return item instanceof object;
-};
-
-// Function overloading
-
-var Function = this.Function;
-
-var enumerables = true;
-for (var i in {toString: 1}) enumerables = null;
-if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];
-
-Function.prototype.overloadSetter = function(usePlural){
- var self = this;
- return function(a, b){
- if (a == null) return this;
- if (usePlural || typeof a != 'string'){
- for (var k in a) self.call(this, k, a[k]);
- if (enumerables) for (var i = enumerables.length; i--;){
- k = enumerables[i];
- if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
- }
- } else {
- self.call(this, a, b);
- }
- return this;
- };
-};
-
-Function.prototype.overloadGetter = function(usePlural){
- var self = this;
- return function(a){
- var args, result;
- if (usePlural || typeof a != 'string') args = a;
- else if (arguments.length > 1) args = arguments;
- if (args){
- result = {};
- for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]);
- } else {
- result = self.call(this, a);
- }
- return result;
- };
-};
-
-Function.prototype.extend = function(key, value){
- this[key] = value;
-}.overloadSetter();
-
-Function.prototype.implement = function(key, value){
- this.prototype[key] = value;
-}.overloadSetter();
-
-// From
-
-var slice = Array.prototype.slice;
-
-Function.from = function(item){
- return (typeOf(item) == 'function') ? item : function(){
- return item;
- };
-};
-
-Array.from = function(item){
- if (item == null) return [];
- return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item];
-};
-
-Number.from = function(item){
- var number = parseFloat(item);
- return isFinite(number) ? number : null;
-};
-
-String.from = function(item){
- return item + '';
-};
-
-// hide, protect
-
-Function.implement({
-
- hide: function(){
- this.$hidden = true;
- return this;
- },
-
- protect: function(){
- this.$protected = true;
- return this;
- }
-
-});
-
-// Type
-
-var Type = this.Type = function(name, object){
- if (name){
- var lower = name.toLowerCase();
- var typeCheck = function(item){
- return (typeOf(item) == lower);
- };
-
- Type['is' + name] = typeCheck;
- if (object != null){
- object.prototype.$family = (function(){
- return lower;
- }).hide();
- //<1.2compat>
- object.type = typeCheck;
- //</1.2compat>
- }
- }
-
- if (object == null) return null;
-
- object.extend(this);
- object.$constructor = Type;
- object.prototype.$constructor = object;
-
- return object;
-};
-
-var toString = Object.prototype.toString;
-
-Type.isEnumerable = function(item){
- return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' );
-};
-
-var hooks = {};
-
-var hooksOf = function(object){
- var type = typeOf(object.prototype);
- return hooks[type] || (hooks[type] = []);
-};
-
-var implement = function(name, method){
- if (method && method.$hidden) return this;
-
- var hooks = hooksOf(this);
-
- for (var i = 0; i < hooks.length; i++){
- var hook = hooks[i];
- if (typeOf(hook) == 'type') implement.call(hook, name, method);
- else hook.call(this, name, method);
- }
-
- var previous = this.prototype[name];
- if (previous == null || !previous.$protected) this.prototype[name] = method;
-
- if (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){
- return method.apply(item, slice.call(arguments, 1));
- });
-
- return this;
-};
-
-var extend = function(name, method){
- if (method && method.$hidden) return this;
- var previous = this[name];
- if (previous == null || !previous.$protected) this[name] = method;
- return this;
-};
-
-Type.implement({
-
- implement: implement.overloadSetter(),
-
- extend: extend.overloadSetter(),
-
- alias: function(name, existing){
- implement.call(this, name, this.prototype[existing]);
- }.overloadSetter(),
-
- mirror: function(hook){
- hooksOf(this).push(hook);
- return this;
- }
-
-});
-
-new Type('Type', Type);
-
-// Default Types
-
-var force = function(name, object, methods){
- var isType = (object != Object),
- prototype = object.prototype;
-
- if (isType) object = new Type(name, object);
-
- for (var i = 0, l = methods.length; i < l; i++){
- var key = methods[i],
- generic = object[key],
- proto = prototype[key];
-
- if (generic) generic.protect();
-
- if (isType && proto){
- delete prototype[key];
- prototype[key] = proto.protect();
- }
- }
-
- if (isType) object.implement(prototype);
-
- return force;
-};
-
-force('String', String, [
- 'charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search',
- 'slice', 'split', 'substr', 'substring', 'toLowerCase', 'toUpperCase'
-])('Array', Array, [
- 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice',
- 'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight'
-])('Number', Number, [
- 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'
-])('Function', Function, [
- 'apply', 'call', 'bind'
-])('RegExp', RegExp, [
- 'exec', 'test'
-])('Object', Object, [
- 'create', 'defineProperty', 'defineProperties', 'keys',
- 'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',
- 'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'
-])('Date', Date, ['now']);
-
-Object.extend = extend.overloadSetter();
-
-Date.extend('now', function(){
- return +(new Date);
-});
-
-new Type('Boolean', Boolean);
-
-// fixes NaN returning as Number
-
-Number.prototype.$family = function(){
- return isFinite(this) ? 'number' : 'null';
-}.hide();
-
-// Number.random
-
-Number.extend('random', function(min, max){
- return Math.floor(Math.random() * (max - min + 1) + min);
-});
-
-// forEach, each
-
-Object.extend('forEach', function(object, fn, bind){
- for (var key in object){
- if (object.hasOwnProperty(key)) fn.call(bind, object[key], key, object);
- }
-});
-
-Object.each = Object.forEach;
-
-Array.implement({
-
- forEach: function(fn, bind){
- for (var i = 0, l = this.length; i < l; i++){
- if (i in this) fn.call(bind, this[i], i, this);
- }
- },
-
- each: function(fn, bind){
- Array.forEach(this, fn, bind);
- return this;
- }
-
-});
-
-// Array & Object cloning, Object merging and appending
-
-var cloneOf = function(item){
- switch (typeOf(item)){
- case 'array': return item.clone();
- case 'object': return Object.clone(item);
- default: return item;
- }
-};
-
-Array.implement('clone', function(){
- var i = this.length, clone = new Array(i);
- while (i--) clone[i] = cloneOf(this[i]);
- return clone;
-});
-
-var mergeOne = function(source, key, current){
- switch (typeOf(current)){
- case 'object':
- if (typeOf(source[key]) == 'object') Object.merge(source[key], current);
- else source[key] = Object.clone(current);
- break;
- case 'array': source[key] = current.clone(); break;
- default: source[key] = current;
- }
- return source;
-};
-
-Object.extend({
-
- merge: function(source, k, v){
- if (typeOf(k) == 'string') return mergeOne(source, k, v);
- for (var i = 1, l = arguments.length; i < l; i++){
- var object = arguments[i];
- for (var key in object) mergeOne(source, key, object[key]);
- }
- return source;
- },
-
- clone: function(object){
- var clone = {};
- for (var key in object) clone[key] = cloneOf(object[key]);
- return clone;
- },
-
- append: function(original){
- for (var i = 1, l = arguments.length; i < l; i++){
- var extended = arguments[i] || {};
- for (var key in extended) original[key] = extended[key];
- }
- return original;
- }
-
-});
-
-// Object-less types
-
-['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(name){
- new Type(name);
-});
-
-// Unique ID
-
-var UID = Date.now();
-
-String.extend('uniqueID', function(){
- return (UID++).toString(36);
-});
-
-//<1.2compat>
-
-var Hash = this.Hash = new Type('Hash', function(object){
- if (typeOf(object) == 'hash') object = Object.clone(object.getClean());
- for (var key in object) this[key] = object[key];
- return this;
-});
-
-Hash.implement({
-
- forEach: function(fn, bind){
- Object.forEach(this, fn, bind);
- },
-
- getClean: function(){
- var clean = {};
- for (var key in this){
- if (this.hasOwnProperty(key)) clean[key] = this[key];
- }
- return clean;
- },
-
- getLength: function(){
- var length = 0;
- for (var key in this){
- if (this.hasOwnProperty(key)) length++;
- }
- return length;
- }
-
-});
-
-Hash.alias('each', 'forEach');
-
-Object.type = Type.isObject;
-
-var Native = this.Native = function(properties){
- return new Type(properties.name, properties.initialize);
-};
-
-Native.type = Type.type;
-
-Native.implement = function(objects, methods){
- for (var i = 0; i < objects.length; i++) objects[i].implement(methods);
- return Native;
-};
-
-var arrayType = Array.type;
-Array.type = function(item){
- return instanceOf(item, Array) || arrayType(item);
-};
-
-this.$A = function(item){
- return Array.from(item).slice();
-};
-
-this.$arguments = function(i){
- return function(){
- return arguments[i];
- };
-};
-
-this.$chk = function(obj){
- return !!(obj || obj === 0);
-};
-
-this.$clear = function(timer){
- clearTimeout(timer);
- clearInterval(timer);
- return null;
-};
-
-this.$defined = function(obj){
- return (obj != null);
-};
-
-this.$each = function(iterable, fn, bind){
- var type = typeOf(iterable);
- ((type == 'arguments' || type == 'collection' || type == 'array' || type == 'elements') ? Array : Object).each(iterable, fn, bind);
-};
-
-this.$empty = function(){};
-
-this.$extend = function(original, extended){
- return Object.append(original, extended);
-};
-
-this.$H = function(object){
- return new Hash(object);
-};
-
-this.$merge = function(){
- var args = Array.slice(arguments);
- args.unshift({});
- return Object.merge.apply(null, args);
-};
-
-this.$lambda = Function.from;
-this.$mixin = Object.merge;
-this.$random = Number.random;
-this.$splat = Array.from;
-this.$time = Date.now;
-
-this.$type = function(object){
- var type = typeOf(object);
- if (type == 'elements') return 'array';
- return (type == 'null') ? false : type;
-};
-
-this.$unlink = function(object){
- switch (typeOf(object)){
- case 'object': return Object.clone(object);
- case 'array': return Array.clone(object);
- case 'hash': return new Hash(object);
- default: return object;
- }
-};
-
-//</1.2compat>
-
-})();
-
-
-/*
----
-
-name: Array
-
-description: Contains Array Prototypes like each, contains, and erase.
-
-license: MIT-style license.
-
-requires: Type
-
-provides: Array
-
-...
-*/
-
-Array.implement({
-
- invoke: function(methodName){
- var args = Array.slice(arguments, 1);
- return this.map(function(item){
- return item[methodName].apply(item, args);
- });
- },
-
- every: function(fn, bind){
- for (var i = 0, l = this.length; i < l; i++){
- if ((i in this) && !fn.call(bind, this[i], i, this)) return false;
- }
- return true;
- },
-
- filter: function(fn, bind){
- var results = [];
- for (var i = 0, l = this.length; i < l; i++){
- if ((i in this) && fn.call(bind, this[i], i, this)) results.push(this[i]);
- }
- return results;
- },
-
- clean: function(){
- return this.filter(function(item){
- return item != null;
- });
- },
-
- indexOf: function(item, from){
- var len = this.length;
- for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
- if (this[i] === item) return i;
- }
- return -1;
- },
-
- map: function(fn, bind){
- var results = [];
- for (var i = 0, l = this.length; i < l; i++){
- if (i in this) results[i] = fn.call(bind, this[i], i, this);
- }
- return results;
- },
-
- some: function(fn, bind){
- for (var i = 0, l = this.length; i < l; i++){
- if ((i in this) && fn.call(bind, this[i], i, this)) return true;
- }
- return false;
- },
-
- associate: function(keys){
- var obj = {}, length = Math.min(this.length, keys.length);
- for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
- return obj;
- },
-
- link: function(object){
- var result = {};
- for (var i = 0, l = this.length; i < l; i++){
- for (var key in object){
- if (object[key](this[i])){
- result[key] = this[i];
- delete object[key];
- break;
- }
- }
- }
- return result;
- },
-
- contains: function(item, from){
- return this.indexOf(item, from) != -1;
- },
-
- append: function(array){
- this.push.apply(this, array);
- return this;
- },
-
- getLast: function(){
- return (this.length) ? this[this.length - 1] : null;
- },
-
- getRandom: function(){
- return (this.length) ? this[Number.random(0, this.length - 1)] : null;
- },
-
- include: function(item){
- if (!this.contains(item)) this.push(item);
- return this;
- },
-
- combine: function(array){
- for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
- return this;
- },
-
- erase: function(item){
- for (var i = this.length; i--;){
- if (this[i] === item) this.splice(i, 1);
- }
- return this;
- },
-
- empty: function(){
- this.length = 0;
- return this;
- },
-
- flatten: function(){
- var array = [];
- for (var i = 0, l = this.length; i < l; i++){
- var type = typeOf(this[i]);
- if (type == 'null') continue;
- array = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]);
- }
- return array;
- },
-
- pick: function(){
- for (var i = 0, l = this.length; i < l; i++){
- if (this[i] != null) return this[i];
- }
- return null;
- },
-
- hexToRgb: function(array){
- if (this.length != 3) return null;
- var rgb = this.map(function(value){
- if (value.length == 1) value += value;
- return value.toInt(16);
- });
- return (array) ? rgb : 'rgb(' + rgb + ')';
- },
-
- rgbToHex: function(array){
- if (this.length < 3) return null;
- if (this.length == 4 && this[3] == 0 && !array) 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 (array) ? hex : '#' + hex.join('');
- }
-
-});
-
-//<1.2compat>
-
-Array.alias('extend', 'append');
-
-var $pick = function(){
- return Array.from(arguments).pick();
-};
-
-//</1.2compat>
-
-
-/*
----
-
-name: String
-
-description: Contains String Prototypes like camelCase, capitalize, test, and toInt.
-
-license: MIT-style license.
-
-requires: Type
-
-provides: String
-
-...
-*/
-
-String.implement({
-
- test: function(regex, params){
- return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this);
- },
-
- contains: function(string, separator){
- return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1;
- },
-
- trim: function(){
- return this.replace(/^\s+|\s+$/g, '');
- },
-
- clean: function(){
- return this.replace(/\s+/g, ' ').trim();
- },
-
- camelCase: function(){
- return this.replace(/-\D/g, function(match){
- return match.charAt(1).toUpperCase();
- });
- },
-
- hyphenate: function(){
- return this.replace(/[A-Z]/g, function(match){
- return ('-' + match.charAt(0).toLowerCase());
- });
- },
-
- capitalize: function(){
- return this.replace(/\b[a-z]/g, function(match){
- return match.toUpperCase();
- });
- },
-
- escapeRegExp: function(){
- return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
- },
-
- toInt: function(base){
- return parseInt(this, base || 10);
- },
-
- toFloat: function(){
- return parseFloat(this);
- },
-
- hexToRgb: function(array){
- var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
- return (hex) ? hex.slice(1).hexToRgb(array) : null;
- },
-
- rgbToHex: function(array){
- var rgb = this.match(/\d{1,3}/g);
- return (rgb) ? rgb.rgbToHex(array) : null;
- },
-
- substitute: function(object, regexp){
- return this.replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){
- if (match.charAt(0) == '\\') return match.slice(1);
- return (object[name] != null) ? object[name] : '';
- });
- }
-
-});
-
-
-/*
----
-
-name: Number
-
-description: Contains Number Prototypes like limit, round, times, and ceil.
-
-license: MIT-style license.
-
-requires: Type
-
-provides: Number
-
-...
-*/
-
-Number.implement({
-
- limit: function(min, max){
- return Math.min(max, Math.max(min, this));
- },
-
- round: function(precision){
- precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);
- return Math.round(this * precision) / precision;
- },
-
- times: function(fn, bind){
- for (var i = 0; i < this; i++) fn.call(bind, i, this);
- },
-
- toFloat: function(){
- return parseFloat(this);
- },
-
- toInt: function(base){
- return parseInt(this, base || 10);
- }
-
-});
-
-Number.alias('each', 'times');
-
-(function(math){
- var methods = {};
- math.each(function(name){
- if (!Number[name]) methods[name] = function(){
- return Math[name].apply(null, [this].concat(Array.from(arguments)));
- };
- });
- Number.implement(methods);
-})(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
-
-
-/*
----
-
-name: Function
-
-description: Contains Function Prototypes like create, bind, pass, and delay.
-
-license: MIT-style license.
-
-requires: Type
-
-provides: Function
-
-...
-*/
-
-Function.extend({
-
- attempt: function(){
- for (var i = 0, l = arguments.length; i < l; i++){
- try {
- return arguments[i]();
- } catch (e){}
- }
- return null;
- }
-
-});
-
-Function.implement({
-
- attempt: function(args, bind){
- try {
- return this.apply(bind, Array.from(args));
- } catch (e){}
-
- return null;
- },
-
- bind: function(bind){
- var self = this,
- args = (arguments.length > 1) ? Array.slice(arguments, 1) : null;
-
- return function(){
- if (!args && !arguments.length) return self.call(bind);
- if (args && arguments.length) return self.apply(bind, args.concat(Array.from(arguments)));
- return self.apply(bind, args || arguments);
- };
- },
-
- pass: function(args, bind){
- var self = this;
- if (args != null) args = Array.from(args);
- return function(){
- return self.apply(bind, args || arguments);
- };
- },
-
- delay: function(delay, bind, args){
- return setTimeout(this.pass(args, bind), delay);
- },
-
- periodical: function(periodical, bind, args){
- return setInterval(this.pass(args, bind), periodical);
- }
-
-});
-
-//<1.2compat>
-
-delete Function.prototype.bind;
-
-Function.implement({
-
- create: function(options){
- var self = this;
- options = options || {};
- return function(event){
- var args = options.arguments;
- args = (args != null) ? Array.from(args) : Array.slice(arguments, (options.event) ? 1 : 0);
- if (options.event) args = [event || window.event].extend(args);
- var returns = function(){
- return self.apply(options.bind || null, args);
- };
- if (options.delay) return setTimeout(returns, options.delay);
- if (options.periodical) return setInterval(returns, options.periodical);
- if (options.attempt) return Function.attempt(returns);
- return returns();
- };
- },
-
- bind: function(bind, args){
- var self = this;
- if (args != null) args = Array.from(args);
- return function(){
- return self.apply(bind, args || arguments);
- };
- },
-
- bindWithEvent: function(bind, args){
- var self = this;
- if (args != null) args = Array.from(args);
- return function(event){
- return self.apply(bind, (args == null) ? arguments : [event].concat(args));
- };
- },
-
- run: function(args, bind){
- return this.apply(bind, Array.from(args));
- }
-
-});
-
-var $try = Function.attempt;
-
-//</1.2compat>
-
-
-/*
----
-
-name: Object
-
-description: Object generic methods
-
-license: MIT-style license.
-
-requires: Type
-
-provides: [Object, Hash]
-
-...
-*/
-
-
-Object.extend({
-
- subset: function(object, keys){
- var results = {};
- for (var i = 0, l = keys.length; i < l; i++){
- var k = keys[i];
- results[k] = object[k];
- }
- return results;
- },
-
- map: function(object, fn, bind){
- var results = {};
- for (var key in object){
- if (object.hasOwnProperty(key)) results[key] = fn.call(bind, object[key], key, object);
- }
- return results;
- },
-
- filter: function(object, fn, bind){
- var results = {};
- Object.each(object, function(value, key){
- if (fn.call(bind, value, key, object)) results[key] = value;
- });
- return results;
- },
-
- every: function(object, fn, bind){
- for (var key in object){
- if (object.hasOwnProperty(key) && !fn.call(bind, object[key], key)) return false;
- }
- return true;
- },
-
- some: function(object, fn, bind){
- for (var key in object){
- if (object.hasOwnProperty(key) && fn.call(bind, object[key], key)) return true;
- }
- return false;
- },
-
- keys: function(object){
- var keys = [];
- for (var key in object){
- if (object.hasOwnProperty(key)) keys.push(key);
- }
- return keys;
- },
-
- values: function(object){
- var values = [];
- for (var key in object){
- if (object.hasOwnProperty(key)) values.push(object[key]);
- }
- return values;
- },
-
- getLength: function(object){
- return Object.keys(object).length;
- },
-
- keyOf: function(object, value){
- for (var key in object){
- if (object.hasOwnProperty(key) && object[key] === value) return key;
- }
- return null;
- },
-
- contains: function(object, value){
- return Object.keyOf(object, value) != null;
- },
-
- toQueryString: function(object, base){
- var queryString = [];
-
- Object.each(object, function(value, key){
- if (base) key = base + '[' + key + ']';
- var result;
- switch (typeOf(value)){
- case 'object': result = Object.toQueryString(value, key); break;
- case 'array':
- var qs = {};
- value.each(function(val, i){
- qs[i] = val;
- });
- result = Object.toQueryString(qs, key);
- break;
- default: result = key + '=' + encodeURIComponent(value);
- }
- if (value != null) queryString.push(result);
- });
-
- return queryString.join('&');
- }
-
-});
-
-
-//<1.2compat>
-
-Hash.implement({
-
- has: Object.prototype.hasOwnProperty,
-
- keyOf: function(value){
- return Object.keyOf(this, value);
- },
-
- hasValue: function(value){
- return Object.contains(this, value);
- },
-
- extend: function(properties){
- Hash.each(properties || {}, function(value, key){
- Hash.set(this, key, value);
- }, this);
- return this;
- },
-
- combine: function(properties){
- Hash.each(properties || {}, function(value, key){
- Hash.include(this, key, value);
- }, this);
- return this;
- },
-
- erase: function(key){
- if (this.hasOwnProperty(key)) delete this[key];
- return this;
- },
-
- get: function(key){
- return (this.hasOwnProperty(key)) ? this[key] : null;
- },
-
- set: function(key, value){
- if (!this[key] || this.hasOwnProperty(key)) this[key] = value;
- return this;
- },
-
- empty: function(){
- Hash.each(this, function(value, key){
- delete this[key];
- }, this);
- return this;
- },
-
- include: function(key, value){
- if (this[key] == null) this[key] = value;
- return this;
- },
-
- map: function(fn, bind){
- return new Hash(Object.map(this, fn, bind));
- },
-
- filter: function(fn, bind){
- return new Hash(Object.filter(this, fn, bind));
- },
-
- every: function(fn, bind){
- return Object.every(this, fn, bind);
- },
-
- some: function(fn, bind){
- return Object.some(this, fn, bind);
- },
-
- getKeys: function(){
- return Object.keys(this);
- },
-
- getValues: function(){
- return Object.values(this);
- },
-
- toQueryString: function(base){
- return Object.toQueryString(this, base);
- }
-
-});
-
-Hash.extend = Object.append;
-
-Hash.alias({indexOf: 'keyOf', contains: 'hasValue'});
-
-//</1.2compat>
-
-
-/*
----
-
-name: Browser
-
-description: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash.
-
-license: MIT-style license.
-
-requires: [Array, Function, Number, String]
-
-provides: [Browser, Window, Document]
-
-...
-*/
-
-(function(){
-
-var document = this.document;
-var window = document.window = this;
-
-var UID = 1;
-
-this.$uid = (window.ActiveXObject) ? function(item){
- return (item.uid || (item.uid = [UID++]))[0];
-} : function(item){
- return item.uid || (item.uid = UID++);
-};
-
-$uid(window);
-$uid(document);
-
-var ua = navigator.userAgent.toLowerCase(),
- platform = navigator.platform.toLowerCase(),
- UA = ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/) || [null, 'unknown', 0],
- mode = UA[1] == 'ie' && document.documentMode;
-
-var Browser = this.Browser = {
-
- extend: Function.prototype.extend,
-
- name: (UA[1] == 'version') ? UA[3] : UA[1],
-
- version: mode || parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]),
-
- Platform: {
- name: ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0]
- },
-
- Features: {
- xpath: !!(document.evaluate),
- air: !!(window.runtime),
- query: !!(document.querySelector),
- json: !!(window.JSON)
- },
-
- Plugins: {}
-
-};
-
-Browser[Browser.name] = true;
-Browser[Browser.name + parseInt(Browser.version, 10)] = true;
-Browser.Platform[Browser.Platform.name] = true;
-
-// Request
-
-Browser.Request = (function(){
-
- var XMLHTTP = function(){
- return new XMLHttpRequest();
- };
-
- var MSXML2 = function(){
- return new ActiveXObject('MSXML2.XMLHTTP');
- };
-
- var MSXML = function(){
- return new ActiveXObject('Microsoft.XMLHTTP');
- };
-
- return Function.attempt(function(){
- XMLHTTP();
- return XMLHTTP;
- }, function(){
- MSXML2();
- return MSXML2;
- }, function(){
- MSXML();
- return MSXML;
- });
-
-})();
-
-Browser.Features.xhr = !!(Browser.Request);
-
-// Flash detection
-
-var version = (Function.attempt(function(){
- return navigator.plugins['Shockwave Flash'].description;
-}, function(){
- return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
-}) || '0 r0').match(/\d+/g);
-
-Browser.Plugins.Flash = {
- version: Number(version[0] || '0.' + version[1]) || 0,
- build: Number(version[2]) || 0
-};
-
-// String scripts
-
-Browser.exec = function(text){
- if (!text) return text;
- if (window.execScript){
- window.execScript(text);
- } else {
- var script = document.createElement('script');
- script.setAttribute('type', 'text/javascript');
- script.text = text;
- document.head.appendChild(script);
- document.head.removeChild(script);
- }
- return text;
-};
-
-String.implement('stripScripts', function(exec){
- var scripts = '';
- var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
- scripts += code + '\n';
- return '';
- });
- if (exec === true) Browser.exec(scripts);
- else if (typeOf(exec) == 'function') exec(scripts, text);
- return text;
-});
-
-// Window, Document
-
-Browser.extend({
- Document: this.Document,
- Window: this.Window,
- Element: this.Element,
- Event: this.Event
-});
-
-this.Window = this.$constructor = new Type('Window', function(){});
-
-this.$family = Function.from('window').hide();
-
-Window.mirror(function(name, method){
- window[name] = method;
-});
-
-this.Document = document.$constructor = new Type('Document', function(){});
-
-document.$family = Function.from('document').hide();
-
-Document.mirror(function(name, method){
- document[name] = method;
-});
-
-document.html = document.documentElement;
-document.head = document.getElementsByTagName('head')[0];
-
-if (document.execCommand) try {
- document.execCommand("BackgroundImageCache", false, true);
-} catch (e){}
-
-if (this.attachEvent && !this.addEventListener){
- var unloadEvent = function(){
- this.detachEvent('onunload', unloadEvent);
- document.head = document.html = document.window = null;
- };
- this.attachEvent('onunload', unloadEvent);
-}
-
-// IE fails on collections and <select>.options (refers to <select>)
-var arrayFrom = Array.from;
-try {
- arrayFrom(document.html.childNodes);
-} catch(e){
- Array.from = function(item){
- if (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'array'){
- var i = item.length, array = new Array(i);
- while (i--) array[i] = item[i];
- return array;
- }
- return arrayFrom(item);
- };
-
- var prototype = Array.prototype,
- slice = prototype.slice;
- ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice'].each(function(name){
- var method = prototype[name];
- Array[name] = function(item){
- return method.apply(Array.from(item), slice.call(arguments, 1));
- };
- });
-}
-
-//<1.2compat>
-
-if (Browser.Platform.ios) Browser.Platform.ipod = true;
-
-Browser.Engine = {};
-
-var setEngine = function(name, version){
- Browser.Engine.name = name;
- Browser.Engine[name + version] = true;
- Browser.Engine.version = version;
-};
-
-if (Browser.ie){
- Browser.Engine.trident = true;
-
- switch (Browser.version){
- case 6: setEngine('trident', 4); break;
- case 7: setEngine('trident', 5); break;
- case 8: setEngine('trident', 6);
- }
-}
-
-if (Browser.firefox){
- Browser.Engine.gecko = true;
-
- if (Browser.version >= 3) setEngine('gecko', 19);
- else setEngine('gecko', 18);
-}
-
-if (Browser.safari || Browser.chrome){
- Browser.Engine.webkit = true;
-
- switch (Browser.version){
- case 2: setEngine('webkit', 419); break;
- case 3: setEngine('webkit', 420); break;
- case 4: setEngine('webkit', 525);
- }
-}
-
-if (Browser.opera){
- Browser.Engine.presto = true;
-
- if (Browser.version >= 9.6) setEngine('presto', 960);
- else if (Browser.version >= 9.5) setEngine('presto', 950);
- else setEngine('presto', 925);
-}
-
-if (Browser.name == 'unknown'){
- switch ((ua.match(/(?:webkit|khtml|gecko)/) || [])[0]){
- case 'webkit':
- case 'khtml':
- Browser.Engine.webkit = true;
- break;
- case 'gecko':
- Browser.Engine.gecko = true;
- }
-}
-
-this.$exec = Browser.exec;
-
-//</1.2compat>
-
-})();
-
-
-/*
----
-
-name: Event
-
-description: Contains the Event Class, to make the event object cross-browser.
-
-license: MIT-style license.
-
-requires: [Window, Document, Array, Function, String, Object]
-
-provides: Event
-
-...
-*/
-
-var Event = new Type('Event', function(event, win){
- if (!win) win = window;
- var doc = win.document;
- event = event || win.event;
- if (event.$extended) return event;
- this.$extended = true;
- var type = event.type,
- target = event.target || event.srcElement,
- page = {},
- client = {};
- while (target && target.nodeType == 3) target = target.parentNode;
-
- if (type.indexOf('key') != -1){
- var code = event.which || event.keyCode;
- var key = Object.keyOf(Event.Keys, code);
- if (type == 'keydown'){
- var fKey = code - 111;
- if (fKey > 0 && fKey < 13) key = 'f' + fKey;
- }
- if (!key) key = String.fromCharCode(code).toLowerCase();
- } else if (type.test(/click|mouse|menu/i)){
- doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
- page = {
- x: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft,
- y: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop
- };
- client = {
- x: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX,
- y: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY
- };
- if (type.test(/DOMMouseScroll|mousewheel/)){
- var wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
- }
- var rightClick = (event.which == 3) || (event.button == 2),
- related = null;
- if (type.test(/over|out/)){
- related = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'];
- var testRelated = function(){
- while (related && related.nodeType == 3) related = related.parentNode;
- return true;
- };
- var hasRelated = (Browser.firefox2) ? testRelated.attempt() : testRelated();
- related = (hasRelated) ? related : null;
- }
- } else if (type.test(/gesture|touch/i)){
- this.rotation = event.rotation;
- this.scale = event.scale;
- this.targetTouches = event.targetTouches;
- this.changedTouches = event.changedTouches;
- var touches = this.touches = event.touches;
- if (touches && touches[0]){
- var touch = touches[0];
- page = {x: touch.pageX, y: touch.pageY};
- client = {x: touch.clientX, y: touch.clientY};
- }
- }
-
- return Object.append(this, {
- event: event,
- type: type,
-
- page: page,
- client: client,
- rightClick: rightClick,
-
- wheel: wheel,
-
- relatedTarget: document.id(related),
- target: document.id(target),
-
- code: code,
- key: key,
-
- shift: event.shiftKey,
- control: event.ctrlKey,
- alt: event.altKey,
- meta: event.metaKey
- });
-});
-
-Event.Keys = {
- 'enter': 13,
- 'up': 38,
- 'down': 40,
- 'left': 37,
- 'right': 39,
- 'esc': 27,
- 'space': 32,
- 'backspace': 8,
- 'tab': 9,
- 'delete': 46
-};
-
-//<1.2compat>
-
-Event.Keys = new Hash(Event.Keys);
-
-//</1.2compat>
-
-Event.implement({
-
- stop: function(){
- return this.stopPropagation().preventDefault();
- },
-
- stopPropagation: function(){
- if (this.event.stopPropagation) this.event.stopPropagation();
- else this.event.cancelBubble = true;
- return this;
- },
-
- preventDefault: function(){
- if (this.event.preventDefault) this.event.preventDefault();
- else this.event.returnValue = false;
- return this;
- }
-
-});
-
-
-/*
----
-
-name: Class
-
-description: Contains the Class Function for easily creating, extending, and implementing reusable Classes.
-
-license: MIT-style license.
-
-requires: [Array, String, Function, Number]
-
-provides: Class
-
-...
-*/
-
-(function(){
-
-var Class = this.Class = new Type('Class', function(params){
- if (instanceOf(params, Function)) params = {initialize: params};
-
- var newClass = function(){
- reset(this);
- if (newClass.$prototyping) return this;
- this.$caller = null;
- var value = (this.initialize) ? this.initialize.apply(this, arguments) : this;
- this.$caller = this.caller = null;
- return value;
- }.extend(this).implement(params);
-
- newClass.$constructor = Class;
- newClass.prototype.$constructor = newClass;
- newClass.prototype.parent = parent;
-
- return newClass;
-});
-
-var parent = function(){
- if (!this.$caller) throw new Error('The method "parent" cannot be called.');
- var name = this.$caller.$name,
- parent = this.$caller.$owner.parent,
- previous = (parent) ? parent.prototype[name] : null;
- if (!previous) throw new Error('The method "' + name + '" has no parent.');
- return previous.apply(this, arguments);
-};
-
-var reset = function(object){
- for (var key in object){
- var value = object[key];
- switch (typeOf(value)){
- case 'object':
- var F = function(){};
- F.prototype = value;
- object[key] = reset(new F);
- break;
- case 'array': object[key] = value.clone(); break;
- }
- }
- return object;
-};
-
-var wrap = function(self, key, method){
- if (method.$origin) method = method.$origin;
- var wrapper = function(){
- if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.');
- var caller = this.caller, current = this.$caller;
- this.caller = current; this.$caller = wrapper;
- var result = method.apply(this, arguments);
- this.$caller = current; this.caller = caller;
- return result;
- }.extend({$owner: self, $origin: method, $name: key});
- return wrapper;
-};
-
-var implement = function(key, value, retain){
- if (Class.Mutators.hasOwnProperty(key)){
- value = Class.Mutators[key].call(this, value);
- if (value == null) return this;
- }
-
- if (typeOf(value) == 'function'){
- if (value.$hidden) return this;
- this.prototype[key] = (retain) ? value : wrap(this, key, value);
- } else {
- Object.merge(this.prototype, key, value);
- }
-
- return this;
-};
-
-var getInstance = function(klass){
- klass.$prototyping = true;
- var proto = new klass;
- delete klass.$prototyping;
- return proto;
-};
-
-Class.implement('implement', implement.overloadSetter());
-
-Class.Mutators = {
-
- Extends: function(parent){
- this.parent = parent;
- this.prototype = getInstance(parent);
- },
-
- Implements: function(items){
- Array.from(items).each(function(item){
- var instance = new item;
- for (var key in instance) implement.call(this, key, instance[key], true);
- }, this);
- }
-};
-
-})();
-
-
-/*
----
-
-name: Class.Extras
-
-description: Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks.
-
-license: MIT-style license.
-
-requires: Class
-
-provides: [Class.Extras, Chain, Events, Options]
-
-...
-*/
-
-(function(){
-
-this.Chain = new Class({
-
- $chain: [],
-
- chain: function(){
- this.$chain.append(Array.flatten(arguments));
- return this;
- },
-
- callChain: function(){
- return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
- },
-
- clearChain: function(){
- this.$chain.empty();
- return this;
- }
-
-});
-
-var removeOn = function(string){
- return string.replace(/^on([A-Z])/, function(full, first){
- return first.toLowerCase();
- });
-};
-
-this.Events = new Class({
-
- $events: {},
-
- addEvent: function(type, fn, internal){
- type = removeOn(type);
-
- /*<1.2compat>*/
- if (fn == $empty) return this;
- /*</1.2compat>*/
-
- this.$events[type] = (this.$events[type] || []).include(fn);
- if (internal) fn.internal = true;
- return this;
- },
-
- addEvents: function(events){
- for (var type in events) this.addEvent(type, events[type]);
- return this;
- },
-
- fireEvent: function(type, args, delay){
- type = removeOn(type);
- var events = this.$events[type];
- if (!events) return this;
- args = Array.from(args);
- events.each(function(fn){
- if (delay) fn.delay(delay, this, args);
- else fn.apply(this, args);
- }, this);
- return this;
- },
-
- removeEvent: function(type, fn){
- type = removeOn(type);
- var events = this.$events[type];
- if (events && !fn.internal){
- var index = events.indexOf(fn);
- if (index != -1) delete events[index];
- }
- return this;
- },
-
- removeEvents: function(events){
- var type;
- if (typeOf(events) == 'object'){
- for (type in events) this.removeEvent(type, events[type]);
- return this;
- }
- if (events) events = removeOn(events);
- for (type in this.$events){
- if (events && events != type) continue;
- var fns = this.$events[type];
- for (var i = fns.length; i--;) this.removeEvent(type, fns[i]);
- }
- return this;
- }
-
-});
-
-this.Options = new Class({
-
- setOptions: function(){
- var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
- if (!this.addEvent) return this;
- for (var option in options){
- if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
- this.addEvent(option, options[option]);
- delete options[option];
- }
- return this;
- }
-
-});
-
-})();
-
-
-/*
----
-name: Slick.Parser
-description: Standalone CSS3 Selector parser
-provides: Slick.Parser
-...
-*/
-
-(function(){
-
-var parsed,
- separatorIndex,
- combinatorIndex,
- reversed,
- cache = {},
- reverseCache = {},
- reUnescape = /\\/g;
-
-var parse = function(expression, isReversed){
- if (expression == null) return null;
- if (expression.Slick === true) return expression;
- expression = ('' + expression).replace(/^\s+|\s+$/g, '');
- reversed = !!isReversed;
- var currentCache = (reversed) ? reverseCache : cache;
- if (currentCache[expression]) return currentCache[expression];
- parsed = {Slick: true, expressions: [], raw: expression, reverse: function(){
- return parse(this.raw, true);
- }};
- separatorIndex = -1;
- while (expression != (expression = expression.replace(regexp, parser)));
- parsed.length = parsed.expressions.length;
- return currentCache[expression] = (reversed) ? reverse(parsed) : parsed;
-};
-
-var reverseCombinator = function(combinator){
- if (combinator === '!') return ' ';
- else if (combinator === ' ') return '!';
- else if ((/^!/).test(combinator)) return combinator.replace(/^!/, '');
- else return '!' + combinator;
-};
-
-var reverse = function(expression){
- var expressions = expression.expressions;
- for (var i = 0; i < expressions.length; i++){
- var exp = expressions[i];
- var last = {parts: [], tag: '*', combinator: reverseCombinator(exp[0].combinator)};
-
- for (var j = 0; j < exp.length; j++){
- var cexp = exp[j];
- if (!cexp.reverseCombinator) cexp.reverseCombinator = ' ';
- cexp.combinator = cexp.reverseCombinator;
- delete cexp.reverseCombinator;
- }
-
- exp.reverse().push(last);
- }
- return expression;
-};
-
-var escapeRegExp = function(string){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
- return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&");
-};
-
-var regexp = new RegExp(
-/*
-#!/usr/bin/env ruby
-puts "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'')
-__END__
- "(?x)^(?:\
- \\s* ( , ) \\s* # Separator \n\
- | \\s* ( <combinator>+ ) \\s* # Combinator \n\
- | ( \\s+ ) # CombinatorChildren \n\
- | ( <unicode>+ | \\* ) # Tag \n\
- | \\# ( <unicode>+ ) # ID \n\
- | \\. ( <unicode>+ ) # ClassName \n\
- | # Attribute \n\
- \\[ \
- \\s* (<unicode1>+) (?: \
- \\s* ([*^$!~|]?=) (?: \
- \\s* (?:\
- ([\"']?)(.*?)\\9 \
- )\
- ) \
- )? \\s* \
- \\](?!\\]) \n\
- | :+ ( <unicode>+ )(?:\
- \\( (?:\
- (?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\
- ) \\)\
- )?\
- )"
-*/
- "^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|:+(<unicode>+)(?:\\((?:(?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+))\\))?)"
- .replace(/<combinator>/, '[' + escapeRegExp(">+~`!@$%^&={}\\;</") + ']')
- .replace(/<unicode>/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
- .replace(/<unicode1>/g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
-);
-
-function parser(
- rawMatch,
-
- separator,
- combinator,
- combinatorChildren,
-
- tagName,
- id,
- className,
-
- attributeKey,
- attributeOperator,
- attributeQuote,
- attributeValue,
-
- pseudoClass,
- pseudoQuote,
- pseudoClassQuotedValue,
- pseudoClassValue
-){
- if (separator || separatorIndex === -1){
- parsed.expressions[++separatorIndex] = [];
- combinatorIndex = -1;
- if (separator) return '';
- }
-
- if (combinator || combinatorChildren || combinatorIndex === -1){
- combinator = combinator || ' ';
- var currentSeparator = parsed.expressions[separatorIndex];
- if (reversed && currentSeparator[combinatorIndex])
- currentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(combinator);
- currentSeparator[++combinatorIndex] = {combinator: combinator, tag: '*'};
- }
-
- var currentParsed = parsed.expressions[separatorIndex][combinatorIndex];
-
- if (tagName){
- currentParsed.tag = tagName.replace(reUnescape, '');
-
- } else if (id){
- currentParsed.id = id.replace(reUnescape, '');
-
- } else if (className){
- className = className.replace(reUnescape, '');
-
- if (!currentParsed.classList) currentParsed.classList = [];
- if (!currentParsed.classes) currentParsed.classes = [];
- currentParsed.classList.push(className);
- currentParsed.classes.push({
- value: className,
- regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
- });
-
- } else if (pseudoClass){
- pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue;
- pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, '') : null;
-
- if (!currentParsed.pseudos) currentParsed.pseudos = [];
- currentParsed.pseudos.push({
- key: pseudoClass.replace(reUnescape, ''),
- value: pseudoClassValue
- });
-
- } else if (attributeKey){
- attributeKey = attributeKey.replace(reUnescape, '');
- attributeValue = (attributeValue || '').replace(reUnescape, '');
-
- var test, regexp;
-
- switch (attributeOperator){
- case '^=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) ); break;
- case '$=' : regexp = new RegExp( escapeRegExp(attributeValue) +'$' ); break;
- case '~=' : regexp = new RegExp( '(^|\\s)'+ escapeRegExp(attributeValue) +'(\\s|$)' ); break;
- case '|=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) +'(-|$)' ); break;
- case '=' : test = function(value){
- return attributeValue == value;
- }; break;
- case '*=' : test = function(value){
- return value && value.indexOf(attributeValue) > -1;
- }; break;
- case '!=' : test = function(value){
- return attributeValue != value;
- }; break;
- default : test = function(value){
- return !!value;
- };
- }
-
- if (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator)) test = function(){
- return false;
- };
-
- if (!test) test = function(value){
- return value && regexp.test(value);
- };
-
- if (!currentParsed.attributes) currentParsed.attributes = [];
- currentParsed.attributes.push({
- key: attributeKey,
- operator: attributeOperator,
- value: attributeValue,
- test: test
- });
-
- }
-
- return '';
-};
-
-// Slick NS
-
-var Slick = (this.Slick || {});
-
-Slick.parse = function(expression){
- return parse(expression);
-};
-
-Slick.escapeRegExp = escapeRegExp;
-
-if (!this.Slick) this.Slick = Slick;
-
-}).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS>*/this);
-
-
-/*
----
-name: Slick.Finder
-description: The new, superfast css selector engine.
-provides: Slick.Finder
-requires: Slick.Parser
-...
-*/
-
-(function(){
-
-var local = {};
-
-// Feature / Bug detection
-
-local.isNativeCode = function(fn){
- return (/\{\s*\[native code\]\s*\}/).test('' + fn);
-};
-
-local.isXML = function(document){
- return (!!document.xmlVersion) || (!!document.xml) || (Object.prototype.toString.call(document) === '[object XMLDocument]') ||
- (document.nodeType === 9 && document.documentElement.nodeName !== 'HTML');
-};
-
-local.setDocument = function(document){
-
- // convert elements / window arguments to document. if document cannot be extrapolated, the function returns.
-
- if (document.nodeType === 9); // document
- else if (document.ownerDocument) document = document.ownerDocument; // node
- else if (document.navigator) document = document.document; // window
- else return;
-
- // check if it's the old document
-
- if (this.document === document) return;
- this.document = document;
- var root = this.root = document.documentElement;
-
- this.isXMLDocument = this.isXML(document);
-
- this.brokenStarGEBTN
- = this.starSelectsClosedQSA
- = this.idGetsName
- = this.brokenMixedCaseQSA
- = this.brokenGEBCN
- = this.brokenCheckedQSA
- = this.brokenEmptyAttributeQSA
- = this.isHTMLDocument
- = false;
-
- var starSelectsClosed, starSelectsComments,
- brokenSecondClassNameGEBCN, cachedGetElementsByClassName;
-
- var selected, id;
- var testNode = document.createElement('div');
- root.appendChild(testNode);
-
- // on non-HTML documents innerHTML and getElementsById doesnt work properly
- try {
- id = 'slick_getbyid_test';
- testNode.innerHTML = '<a id="'+id+'"></a>';
- this.isHTMLDocument = !!document.getElementById(id);
- } catch(e){};
-
- if (this.isHTMLDocument){
-
- testNode.style.display = 'none';
-
- // IE returns comment nodes for getElementsByTagName('*') for some documents
- testNode.appendChild(document.createComment(''));
- starSelectsComments = (testNode.getElementsByTagName('*').length > 0);
-
- // IE returns closed nodes (EG:"</foo>") for getElementsByTagName('*') for some documents
- try {
- testNode.innerHTML = 'foo</foo>';
- selected = testNode.getElementsByTagName('*');
- starSelectsClosed = (selected && selected.length && selected[0].nodeName.charAt(0) == '/');
- } catch(e){};
-
- this.brokenStarGEBTN = starSelectsComments || starSelectsClosed;
-
- // IE 8 returns closed nodes (EG:"</foo>") for querySelectorAll('*') for some documents
- if (testNode.querySelectorAll) try {
- testNode.innerHTML = 'foo</foo>';
- selected = testNode.querySelectorAll('*');
- this.starSelectsClosedQSA = (selected && selected.length && selected[0].nodeName.charAt(0) == '/');
- } catch(e){};
-
- // IE returns elements with the name instead of just id for getElementsById for some documents
- try {
- id = 'slick_id_gets_name';
- testNode.innerHTML = '<a name="'+id+'"></a><b id="'+id+'"></b>';
- this.idGetsName = document.getElementById(id) === testNode.firstChild;
- } catch(e){};
-
- // Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode
- try {
- testNode.innerHTML = '<a class="MiXedCaSe"></a>';
- this.brokenMixedCaseQSA = !testNode.querySelectorAll('.MiXedCaSe').length;
- } catch(e){};
-
- try {
- testNode.innerHTML = '<a class="f"></a><a class="b"></a>';
- testNode.getElementsByClassName('b').length;
- testNode.firstChild.className = 'b';
- cachedGetElementsByClassName = (testNode.getElementsByClassName('b').length != 2);
- } catch(e){};
-
- // Opera 9.6 getElementsByClassName doesnt detects the class if its not the first one
- try {
- testNode.innerHTML = '<a class="a"></a><a class="f b a"></a>';
- brokenSecondClassNameGEBCN = (testNode.getElementsByClassName('a').length != 2);
- } catch(e){};
-
- this.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN;
-
- // Webkit dont return selected options on querySelectorAll
- try {
- testNode.innerHTML = '<select><option selected="selected">a</option></select>';
- this.brokenCheckedQSA = (testNode.querySelectorAll(':checked').length == 0);
- } catch(e){};
-
- // IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll
- try {
- testNode.innerHTML = '<a class=""></a>';
- this.brokenEmptyAttributeQSA = (testNode.querySelectorAll('[class*=""]').length != 0);
- } catch(e){};
-
- }
-
- root.removeChild(testNode);
- testNode = null;
-
- // hasAttribute
-
- this.hasAttribute = (root && this.isNativeCode(root.hasAttribute)) ? function(node, attribute) {
- return node.hasAttribute(attribute);
- } : function(node, attribute) {
- node = node.getAttributeNode(attribute);
- return !!(node && (node.specified || node.nodeValue));
- };
-
- // contains
- // FIXME: Add specs: local.contains should be different for xml and html documents?
- this.contains = (root && this.isNativeCode(root.contains)) ? function(context, node){
- return context.contains(node);
- } : (root && root.compareDocumentPosition) ? function(context, node){
- return context === node || !!(context.compareDocumentPosition(node) & 16);
- } : function(context, node){
- if (node) do {
- if (node === context) return true;
- } while ((node = node.parentNode));
- return false;
- };
-
- // document order sorting
- // credits to Sizzle (http://sizzlejs.com/)
-
- this.documentSorter = (root.compareDocumentPosition) ? function(a, b){
- if (!a.compareDocumentPosition || !b.compareDocumentPosition) return 0;
- return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
- } : ('sourceIndex' in root) ? function(a, b){
- if (!a.sourceIndex || !b.sourceIndex) return 0;
- return a.sourceIndex - b.sourceIndex;
- } : (document.createRange) ? function(a, b){
- if (!a.ownerDocument || !b.ownerDocument) return 0;
- var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
- aRange.setStart(a, 0);
- aRange.setEnd(a, 0);
- bRange.setStart(b, 0);
- bRange.setEnd(b, 0);
- return aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
- } : null ;
-
- this.getUID = (this.isHTMLDocument) ? this.getUIDHTML : this.getUIDXML;
-
-};
-
-// Main Method
-
-local.search = function(context, expression, append, first){
-
- var found = this.found = (first) ? null : (append || []);
-
- // context checks
-
- if (!context) return found; // No context
- if (context.navigator) context = context.document; // Convert the node from a window to a document
- else if (!context.nodeType) return found; // Reject misc junk input
-
- // setup
-
- var parsed, i;
-
- var uniques = this.uniques = {};
-
- if (this.document !== (context.ownerDocument || context)) this.setDocument(context);
-
- // should sort if there are nodes in append and if you pass multiple expressions.
- // should remove duplicates if append already has items
- var shouldUniques = !!(append && append.length);
-
- // avoid duplicating items already in the append array
- if (shouldUniques) for (i = found.length; i--;) this.uniques[this.getUID(found[i])] = true;
-
- // expression checks
-
- if (typeof expression == 'string'){ // expression is a string
-
- // Overrides
-
- for (i = this.overrides.length; i--;){
- var override = this.overrides[i];
- if (override.regexp.test(expression)){
- var result = override.method.call(context, expression, found, first);
- if (result === false) continue;
- if (result === true) return found;
- return result;
- }
- }
-
- parsed = this.Slick.parse(expression);
- if (!parsed.length) return found;
- } else if (expression == null){ // there is no expression
- return found;
- } else if (expression.Slick){ // expression is a parsed Slick object
- parsed = expression;
- } else if (this.contains(context.documentElement || context, expression)){ // expression is a node
- (found) ? found.push(expression) : found = expression;
- return found;
- } else { // other junk
- return found;
- }
-
- // cache elements for the nth selectors
-
- /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
-
- this.posNTH = {};
- this.posNTHLast = {};
- this.posNTHType = {};
- this.posNTHTypeLast = {};
-
- /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
-
- // if append is null and there is only a single selector with one expression use pushArray, else use pushUID
- this.push = (!shouldUniques && (first || (parsed.length == 1 && parsed.expressions[0].length == 1))) ? this.pushArray : this.pushUID;
-
- if (found == null) found = [];
-
- // default engine
-
- var j, m, n;
- var combinator, tag, id, classList, classes, attributes, pseudos;
- var currentItems, currentExpression, currentBit, lastBit, expressions = parsed.expressions;
-
- search: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (currentBit = currentExpression[j]); j++){
-
- combinator = 'combinator:' + currentBit.combinator;
- if (!this[combinator]) continue search;
-
- tag = (this.isXMLDocument) ? currentBit.tag : currentBit.tag.toUpperCase();
- id = currentBit.id;
- classList = currentBit.classList;
- classes = currentBit.classes;
- attributes = currentBit.attributes;
- pseudos = currentBit.pseudos;
- lastBit = (j === (currentExpression.length - 1));
-
- this.bitUniques = {};
-
- if (lastBit){
- this.uniques = uniques;
- this.found = found;
- } else {
- this.uniques = {};
- this.found = [];
- }
-
- if (j === 0){
- this[combinator](context, tag, id, classes, attributes, pseudos, classList);
- if (first && lastBit && found.length) break search;
- } else {
- if (first && lastBit) for (m = 0, n = currentItems.length; m < n; m++){
- this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
- if (found.length) break search;
- } else for (m = 0, n = currentItems.length; m < n; m++) this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
- }
-
- currentItems = this.found;
- }
-
- if (shouldUniques || (parsed.expressions.length > 1)) this.sort(found);
-
- return (first) ? (found[0] || null) : found;
-};
-
-// Utils
-
-local.uidx = 1;
-local.uidk = 'slick:uniqueid';
-
-local.getUIDXML = function(node){
- var uid = node.getAttribute(this.uidk);
- if (!uid){
- uid = this.uidx++;
- node.setAttribute(this.uidk, uid);
- }
- return uid;
-};
-
-local.getUIDHTML = function(node){
- return node.uniqueNumber || (node.uniqueNumber = this.uidx++);
-};
-
-// sort based on the setDocument documentSorter method.
-
-local.sort = function(results){
- if (!this.documentSorter) return results;
- results.sort(this.documentSorter);
- return results;
-};
-
-/*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
-
-local.cacheNTH = {};
-
-local.matchNTH = /^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;
-
-local.parseNTHArgument = function(argument){
- var parsed = argument.match(this.matchNTH);
- if (!parsed) return false;
- var special = parsed[2] || false;
- var a = parsed[1] || 1;
- if (a == '-') a = -1;
- var b = +parsed[3] || 0;
- parsed =
- (special == 'n') ? {a: a, b: b} :
- (special == 'odd') ? {a: 2, b: 1} :
- (special == 'even') ? {a: 2, b: 0} : {a: 0, b: a};
-
- return (this.cacheNTH[argument] = parsed);
-};
-
-local.createNTHPseudo = function(child, sibling, positions, ofType){
- return function(node, argument){
- var uid = this.getUID(node);
- if (!this[positions][uid]){
- var parent = node.parentNode;
- if (!parent) return false;
- var el = parent[child], count = 1;
- if (ofType){
- var nodeName = node.nodeName;
- do {
- if (el.nodeName !== nodeName) continue;
- this[positions][this.getUID(el)] = count++;
- } while ((el = el[sibling]));
- } else {
- do {
- if (el.nodeType !== 1) continue;
- this[positions][this.getUID(el)] = count++;
- } while ((el = el[sibling]));
- }
- }
- argument = argument || 'n';
- var parsed = this.cacheNTH[argument] || this.parseNTHArgument(argument);
- if (!parsed) return false;
- var a = parsed.a, b = parsed.b, pos = this[positions][uid];
- if (a == 0) return b == pos;
- if (a > 0){
- if (pos < b) return false;
- } else {
- if (b < pos) return false;
- }
- return ((pos - b) % a) == 0;
- };
-};
-
-/*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
-
-local.pushArray = function(node, tag, id, classes, attributes, pseudos){
- if (this.matchSelector(node, tag, id, classes, attributes, pseudos)) this.found.push(node);
-};
-
-local.pushUID = function(node, tag, id, classes, attributes, pseudos){
- var uid = this.getUID(node);
- if (!this.uniques[uid] && this.matchSelector(node, tag, id, classes, attributes, pseudos)){
- this.uniques[uid] = true;
- this.found.push(node);
- }
-};
-
-local.matchNode = function(node, selector){
- var parsed = this.Slick.parse(selector);
- if (!parsed) return true;
-
- // simple (single) selectors
- if(parsed.length == 1 && parsed.expressions[0].length == 1){
- var exp = parsed.expressions[0][0];
- return this.matchSelector(node, (this.isXMLDocument) ? exp.tag : exp.tag.toUpperCase(), exp.id, exp.classes, exp.attributes, exp.pseudos);
- }
-
- var nodes = this.search(this.document, parsed);
- for (var i = 0, item; item = nodes[i++];){
- if (item === node) return true;
- }
- return false;
-};
-
-local.matchPseudo = function(node, name, argument){
- var pseudoName = 'pseudo:' + name;
- if (this[pseudoName]) return this[pseudoName](node, argument);
- var attribute = this.getAttribute(node, name);
- return (argument) ? argument == attribute : !!attribute;
-};
-
-local.matchSelector = function(node, tag, id, classes, attributes, pseudos){
- if (tag){
- if (tag == '*'){
- if (node.nodeName < '@') return false; // Fix for comment nodes and closed nodes
- } else {
- if (node.nodeName != tag) return false;
- }
- }
-
- if (id && node.getAttribute('id') != id) return false;
-
- var i, part, cls;
- if (classes) for (i = classes.length; i--;){
- cls = ('className' in node) ? node.className : node.getAttribute('class');
- if (!(cls && classes[i].regexp.test(cls))) return false;
- }
- if (attributes) for (i = attributes.length; i--;){
- part = attributes[i];
- if (part.operator ? !part.test(this.getAttribute(node, part.key)) : !this.hasAttribute(node, part.key)) return false;
- }
- if (pseudos) for (i = pseudos.length; i--;){
- part = pseudos[i];
- if (!this.matchPseudo(node, part.key, part.value)) return false;
- }
- return true;
-};
-
-var combinators = {
-
- ' ': function(node, tag, id, classes, attributes, pseudos, classList){ // all child nodes, any level
-
- var i, item, children;
-
- if (this.isHTMLDocument){
- getById: if (id){
- item = this.document.getElementById(id);
- if ((!item && node.all) || (this.idGetsName && item && item.getAttributeNode('id').nodeValue != id)){
- // all[id] returns all the elements with that name or id inside node
- // if theres just one it will return the element, else it will be a collection
- children = node.all[id];
- if (!children) return;
- if (!children[0]) children = [children];
- for (i = 0; item = children[i++];) if (item.getAttributeNode('id').nodeValue == id){
- this.push(item, tag, null, classes, attributes, pseudos);
- break;
- }
- return;
- }
- if (!item){
- // if the context is in the dom we return, else we will try GEBTN, breaking the getById label
- if (this.contains(this.document.documentElement, node)) return;
- else break getById;
- } else if (this.document !== node && !this.contains(node, item)) return;
- this.push(item, tag, null, classes, attributes, pseudos);
- return;
- }
- getByClass: if (classes && node.getElementsByClassName && !this.brokenGEBCN){
- children = node.getElementsByClassName(classList.join(' '));
- if (!(children && children.length)) break getByClass;
- for (i = 0; item = children[i++];) this.push(item, tag, id, null, attributes, pseudos);
- return;
- }
- }
- getByTag: {
- children = node.getElementsByTagName(tag);
- if (!(children && children.length)) break getByTag;
- if (!this.brokenStarGEBTN) tag = null;
- for (i = 0; item = children[i++];) this.push(item, tag, id, classes, attributes, pseudos);
- }
- },
-
- '>': function(node, tag, id, classes, attributes, pseudos){ // direct children
- if ((node = node.firstChild)) do {
- if (node.nodeType === 1) this.push(node, tag, id, classes, attributes, pseudos);
- } while ((node = node.nextSibling));
- },
-
- '+': function(node, tag, id, classes, attributes, pseudos){ // next sibling
- while ((node = node.nextSibling)) if (node.nodeType === 1){
- this.push(node, tag, id, classes, attributes, pseudos);
- break;
- }
- },
-
- '^': function(node, tag, id, classes, attributes, pseudos){ // first child
- node = node.firstChild;
- if (node){
- if (node.nodeType === 1) this.push(node, tag, id, classes, attributes, pseudos);
- else this['combinator:+'](node, tag, id, classes, attributes, pseudos);
- }
- },
-
- '~': function(node, tag, id, classes, attributes, pseudos){ // next siblings
- while ((node = node.nextSibling)){
- if (node.nodeType !== 1) continue;
- var uid = this.getUID(node);
- if (this.bitUniques[uid]) break;
- this.bitUniques[uid] = true;
- this.push(node, tag, id, classes, attributes, pseudos);
- }
- },
-
- '++': function(node, tag, id, classes, attributes, pseudos){ // next sibling and previous sibling
- this['combinator:+'](node, tag, id, classes, attributes, pseudos);
- this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
- },
-
- '~~': function(node, tag, id, classes, attributes, pseudos){ // next siblings and previous siblings
- this['combinator:~'](node, tag, id, classes, attributes, pseudos);
- this['combinator:!~'](node, tag, id, classes, attributes, pseudos);
- },
-
- '!': function(node, tag, id, classes, attributes, pseudos){ // all parent nodes up to document
- while ((node = node.parentNode)) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
- },
-
- '!>': function(node, tag, id, classes, attributes, pseudos){ // direct parent (one level)
- node = node.parentNode;
- if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
- },
-
- '!+': function(node, tag, id, classes, attributes, pseudos){ // previous sibling
- while ((node = node.previousSibling)) if (node.nodeType === 1){
- this.push(node, tag, id, classes, attributes, pseudos);
- break;
- }
- },
-
- '!^': function(node, tag, id, classes, attributes, pseudos){ // last child
- node = node.lastChild;
- if (node){
- if (node.nodeType === 1) this.push(node, tag, id, classes, attributes, pseudos);
- else this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
- }
- },
-
- '!~': function(node, tag, id, classes, attributes, pseudos){ // previous siblings
- while ((node = node.previousSibling)){
- if (node.nodeType !== 1) continue;
- var uid = this.getUID(node);
- if (this.bitUniques[uid]) break;
- this.bitUniques[uid] = true;
- this.push(node, tag, id, classes, attributes, pseudos);
- }
- }
-
-};
-
-for (var c in combinators) local['combinator:' + c] = combinators[c];
-
-var pseudos = {
-
- /*<pseudo-selectors>*/
-
- 'empty': function(node){
- var child = node.firstChild;
- return !(child && child.nodeType == 1) && !(node.innerText || node.textContent || '').length;
- },
-
- 'not': function(node, expression){
- return !this.matchNode(node, expression);
- },
-
- 'contains': function(node, text){
- return (node.innerText || node.textContent || '').indexOf(text) > -1;
- },
-
- 'first-child': function(node){
- while ((node = node.previousSibling)) if (node.nodeType === 1) return false;
- return true;
- },
-
- 'last-child': function(node){
- while ((node = node.nextSibling)) if (node.nodeType === 1) return false;
- return true;
- },
-
- 'only-child': function(node){
- var prev = node;
- while ((prev = prev.previousSibling)) if (prev.nodeType === 1) return false;
- var next = node;
- while ((next = next.nextSibling)) if (next.nodeType === 1) return false;
- return true;
- },
-
- /*<nth-pseudo-selectors>*/
-
- 'nth-child': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTH'),
-
- 'nth-last-child': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHLast'),
-
- 'nth-of-type': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTHType', true),
-
- 'nth-last-of-type': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHTypeLast', true),
-
- 'index': function(node, index){
- return this['pseudo:nth-child'](node, '' + index + 1);
- },
-
- 'even': function(node, argument){
- return this['pseudo:nth-child'](node, '2n');
- },
-
- 'odd': function(node, argument){
- return this['pseudo:nth-child'](node, '2n+1');
- },
-
- /*</nth-pseudo-selectors>*/
-
- /*<of-type-pseudo-selectors>*/
-
- 'first-of-type': function(node){
- var nodeName = node.nodeName;
- while ((node = node.previousSibling)) if (node.nodeName === nodeName) return false;
- return true;
- },
-
- 'last-of-type': function(node){
- var nodeName = node.nodeName;
- while ((node = node.nextSibling)) if (node.nodeName === nodeName) return false;
- return true;
- },
-
- 'only-of-type': function(node){
- var prev = node, nodeName = node.nodeName;
- while ((prev = prev.previousSibling)) if (prev.nodeName === nodeName) return false;
- var next = node;
- while ((next = next.nextSibling)) if (next.nodeName === nodeName) return false;
- return true;
- },
-
- /*</of-type-pseudo-selectors>*/
-
- // custom pseudos
-
- 'enabled': function(node){
- return (node.disabled === false);
- },
-
- 'disabled': function(node){
- return (node.disabled === true);
- },
-
- 'checked': function(node){
- return node.checked || node.selected;
- },
-
- 'focus': function(node){
- return this.isHTMLDocument && this.document.activeElement === node && (node.href || node.type || this.hasAttribute(node, 'tabindex'));
- },
-
- 'root': function(node){
- return (node === this.root);
- },
-
- 'selected': function(node){
- return node.selected;
- }
-
- /*</pseudo-selectors>*/
-};
-
-for (var p in pseudos) local['pseudo:' + p] = pseudos[p];
-
-// attributes methods
-
-local.attributeGetters = {
-
- 'class': function(){
- return ('className' in this) ? this.className : this.getAttribute('class');
- },
-
- 'for': function(){
- return ('htmlFor' in this) ? this.htmlFor : this.getAttribute('for');
- },
-
- 'href': function(){
- return ('href' in this) ? this.getAttribute('href', 2) : this.getAttribute('href');
- },
-
- 'style': function(){
- return (this.style) ? this.style.cssText : this.getAttribute('style');
- }
-
-};
-
-local.getAttribute = function(node, name){
- // FIXME: check if getAttribute() will get input elements on a form on this browser
- // getAttribute is faster than getAttributeNode().nodeValue
- var method = this.attributeGetters[name];
- if (method) return method.call(node);
- var attributeNode = node.getAttributeNode(name);
- return attributeNode ? attributeNode.nodeValue : null;
-};
-
-// overrides
-
-local.overrides = [];
-
-local.override = function(regexp, method){
- this.overrides.push({regexp: regexp, method: method});
-};
-
-/*<overrides>*/
-
-/*<query-selector-override>*/
-
-var reEmptyAttribute = /\[.*[*$^]=(?:["']{2})?\]/;
-
-local.override(/./, function(expression, found, first){ //querySelectorAll override
-
- if (!this.querySelectorAll || this.nodeType != 9 || !local.isHTMLDocument || local.brokenMixedCaseQSA ||
- (local.brokenCheckedQSA && expression.indexOf(':checked') > -1) ||
- (local.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression)) || Slick.disableQSA) return false;
-
- var nodes, node;
- try {
- if (first) return this.querySelector(expression) || null;
- else nodes = this.querySelectorAll(expression);
- } catch(error){
- return false;
- }
-
- var i, hasOthers = !!(found.length);
-
- if (local.starSelectsClosedQSA) for (i = 0; node = nodes[i++];){
- if (node.nodeName > '@' && (!hasOthers || !local.uniques[local.getUIDHTML(node)])) found.push(node);
- } else for (i = 0; node = nodes[i++];){
- if (!hasOthers || !local.uniques[local.getUIDHTML(node)]) found.push(node);
- }
-
- if (hasOthers) local.sort(found);
-
- return true;
-
-});
-
-/*</query-selector-override>*/
-
-/*<tag-override>*/
-
-local.override(/^[\w-]+$|^\*$/, function(expression, found, first){ // tag override
- var tag = expression;
- if (tag == '*' && local.brokenStarGEBTN) return false;
-
- var nodes = this.getElementsByTagName(tag);
-
- if (first) return nodes[0] || null;
- var i, node, hasOthers = !!(found.length);
-
- for (i = 0; node = nodes[i++];){
- if (!hasOthers || !local.uniques[local.getUID(node)]) found.push(node);
- }
-
- if (hasOthers) local.sort(found);
-
- return true;
-});
-
-/*</tag-override>*/
-
-/*<class-override>*/
-
-local.override(/^\.[\w-]+$/, function(expression, found, first){ // class override
- if (!local.isHTMLDocument || (!this.getElementsByClassName && this.querySelectorAll)) return false;
-
- var nodes, node, i, hasOthers = !!(found && found.length), className = expression.substring(1);
- if (this.getElementsByClassName && !local.brokenGEBCN){
- nodes = this.getElementsByClassName(className);
- if (first) return nodes[0] || null;
- for (i = 0; node = nodes[i++];){
- if (!hasOthers || !local.uniques[local.getUIDHTML(node)]) found.push(node);
- }
- } else {
- var matchClass = new RegExp('(^|\\s)'+ Slick.escapeRegExp(className) +'(\\s|$)');
- nodes = this.getElementsByTagName('*');
- for (i = 0; node = nodes[i++];){
- className = node.className;
- if (!className || !matchClass.test(className)) continue;
- if (first) return node;
- if (!hasOthers || !local.uniques[local.getUIDHTML(node)]) found.push(node);
- }
- }
- if (hasOthers) local.sort(found);
- return (first) ? null : true;
-});
-
-/*</class-override>*/
-
-/*<id-override>*/
-
-local.override(/^#[\w-]+$/, function(expression, found, first){ // ID override
- if (!local.isHTMLDocument || this.nodeType != 9) return false;
-
- var id = expression.substring(1), el = this.getElementById(id);
- if (!el) return found;
- if (local.idGetsName && el.getAttributeNode('id').nodeValue != id) return false;
- if (first) return el || null;
- var hasOthers = !!(found.length);
- if (!hasOthers || !local.uniques[local.getUIDHTML(el)]) found.push(el);
- if (hasOthers) local.sort(found);
- return true;
-});
-
-/*</id-override>*/
-
-/*</overrides>*/
-
-if (typeof document != 'undefined') local.setDocument(document);
-
-// Slick
-
-var Slick = local.Slick = (this.Slick || {});
-
-Slick.version = '0.9dev';
-
-// Slick finder
-
-Slick.search = function(context, expression, append){
- return local.search(context, expression, append);
-};
-
-Slick.find = function(context, expression){
- return local.search(context, expression, null, true);
-};
-
-// Slick containment checker
-
-Slick.contains = function(container, node){
- local.setDocument(container);
- return local.contains(container, node);
-};
-
-// Slick attribute getter
-
-Slick.getAttribute = function(node, name){
- return local.getAttribute(node, name);
-};
-
-// Slick matcher
-
-Slick.match = function(node, selector){
- if (!(node && selector)) return false;
- if (!selector || selector === node) return true;
- if (typeof selector != 'string') return false;
- local.setDocument(node);
- return local.matchNode(node, selector);
-};
-
-// Slick attribute accessor
-
-Slick.defineAttributeGetter = function(name, fn){
- local.attributeGetters[name] = fn;
- return this;
-};
-
-Slick.lookupAttributeGetter = function(name){
- return local.attributeGetters[name];
-};
-
-// Slick pseudo accessor
-
-Slick.definePseudo = function(name, fn){
- local['pseudo:' + name] = function(node, argument){
- return fn.call(node, argument);
- };
- return this;
-};
-
-Slick.lookupPseudo = function(name){
- var pseudo = local['pseudo:' + name];
- if (pseudo) return function(argument){
- return pseudo.call(this, argument);
- };
- return null;
-};
-
-// Slick overrides accessor
-
-Slick.override = function(regexp, fn){
- local.override(regexp, fn);
- return this;
-};
-
-Slick.isXML = local.isXML;
-
-Slick.uidOf = function(node){
- return local.getUIDHTML(node);
-};
-
-if (!this.Slick) this.Slick = Slick;
-
-}).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS>*/this);
-
-
-/*
----
-
-name: Element
-
-description: One of the most important items in MooTools. Contains the dollar function, the dollars function, and an handful of cross-browser, time-saver methods to let you easily work with HTML Elements.
-
-license: MIT-style license.
-
-requires: [Window, Document, Array, String, Function, Number, Slick.Parser, Slick.Finder]
-
-provides: [Element, Elements, $, $$, Iframe, Selectors]
-
-...
-*/
-
-var Element = function(tag, props){
- var konstructor = Element.Constructors[tag];
- if (konstructor) return konstructor(props);
- if (typeof tag != 'string') return document.id(tag).set(props);
-
- if (!props) props = {};
-
- if (!tag.test(/^[\w-]+$/)){
- var parsed = Slick.parse(tag).expressions[0][0];
- tag = (parsed.tag == '*') ? 'div' : parsed.tag;
- if (parsed.id && props.id == null) props.id = parsed.id;
-
- var attributes = parsed.attributes;
- if (attributes) for (var i = 0, l = attributes.length; i < l; i++){
- var attr = attributes[i];
- if (attr.value != null && attr.operator == '=' && props[attr.key] == null)
- props[attr.key] = attr.value;
- }
-
- if (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' ');
- }
-
- return document.newElement(tag, props);
-};
-
-if (Browser.Element) Element.prototype = Browser.Element.prototype;
-
-new Type('Element', Element).mirror(function(name){
- if (Array.prototype[name]) return;
-
- var obj = {};
- obj[name] = function(){
- var results = [], args = arguments, elements = true;
- for (var i = 0, l = this.length; i < l; i++){
- var element = this[i], result = results[i] = element[name].apply(element, args);
- elements = (elements && typeOf(result) == 'element');
- }
- return (elements) ? new Elements(results) : results;
- };
-
- Elements.implement(obj);
-});
-
-if (!Browser.Element){
- Element.parent = Object;
-
- Element.Prototype = {'$family': Function.from('element').hide()};
-
- Element.mirror(function(name, method){
- Element.Prototype[name] = method;
- });
-}
-
-Element.Constructors = {};
-
-//<1.2compat>
-
-Element.Constructors = new Hash;
-
-//</1.2compat>
-
-var IFrame = new Type('IFrame', function(){
- var params = Array.link(arguments, {
- properties: Type.isObject,
- iframe: function(obj){
- return (obj != null);
- }
- });
-
- var props = params.properties || {}, iframe;
- if (params.iframe) iframe = document.id(params.iframe);
- var onload = props.onload || function(){};
- delete props.onload;
- props.id = props.name = [props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + String.uniqueID()].pick();
- iframe = new Element(iframe || 'iframe', props);
-
- var onLoad = function(){
- onload.call(iframe.contentWindow);
- };
-
- if (window.frames[props.id]) onLoad();
- else iframe.addListener('load', onLoad);
- return iframe;
-});
-
-var Elements = this.Elements = function(nodes){
- if (nodes && nodes.length){
- var uniques = {}, node;
- for (var i = 0; node = nodes[i++];){
- var uid = Slick.uidOf(node);
- if (!uniques[uid]){
- uniques[uid] = true;
- this.push(node);
- }
- }
- }
-};
-
-Elements.prototype = {length: 0};
-Elements.parent = Array;
-
-new Type('Elements', Elements).implement({
-
- filter: function(filter, bind){
- if (!filter) return this;
- return new Elements(Array.filter(this, (typeOf(filter) == 'string') ? function(item){
- return item.match(filter);
- } : filter, bind));
- }.protect(),
-
- push: function(){
- var length = this.length;
- for (var i = 0, l = arguments.length; i < l; i++){
- var item = document.id(arguments[i]);
- if (item) this[length++] = item;
- }
- return (this.length = length);
- }.protect(),
-
- concat: function(){
- var newElements = new Elements(this);
- for (var i = 0, l = arguments.length; i < l; i++){
- var item = arguments[i];
- if (Type.isEnumerable(item)) newElements.append(item);
- else newElements.push(item);
- }
- return newElements;
- }.protect(),
-
- append: function(collection){
- for (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]);
- return this;
- }.protect(),
-
- empty: function(){
- while (this.length) delete this[--this.length];
- return this;
- }.protect()
-
-});
-
-(function(){
-
-// FF, IE
-var splice = Array.prototype.splice, object = {'0': 0, '1': 1, length: 2};
-
-splice.call(object, 1, 1);
-if (object[1] == 1) Elements.implement('splice', function(){
- var length = this.length;
- splice.apply(this, arguments);
- while (length >= this.length) delete this[length--];
- return this;
-}.protect());
-
-Elements.implement(Array.prototype);
-
-Array.mirror(Elements);
-
-/*<ltIE8>*/
-var createElementAcceptsHTML;
-try {
- var x = document.createElement('<input name=x>');
- createElementAcceptsHTML = (x.name == 'x');
-} catch(e){}
-
-var escapeQuotes = function(html){
- return ('' + html).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
-};
-/*</ltIE8>*/
-
-Document.implement({
-
- newElement: function(tag, props){
- if (props && props.checked != null) props.defaultChecked = props.checked;
- /*<ltIE8>*/// Fix for readonly name and type properties in IE < 8
- if (createElementAcceptsHTML && props){
- tag = '<' + tag;
- if (props.name) tag += ' name="' + escapeQuotes(props.name) + '"';
- if (props.type) tag += ' type="' + escapeQuotes(props.type) + '"';
- tag += '>';
- delete props.name;
- delete props.type;
- }
- /*</ltIE8>*/
- return this.id(this.createElement(tag)).set(props);
- }
-
-});
-
-})();
-
-Document.implement({
-
- newTextNode: function(text){
- return this.createTextNode(text);
- },
-
- getDocument: function(){
- return this;
- },
-
- getWindow: function(){
- return this.window;
- },
-
- id: (function(){
-
- var types = {
-
- string: function(id, nocash, doc){
- id = Slick.find(doc, '#' + id.replace(/(\W)/g, '\\$1'));
- return (id) ? types.element(id, nocash) : null;
- },
-
- element: function(el, nocash){
- $uid(el);
- if (!nocash && !el.$family && !(/^object|embed$/i).test(el.tagName)){
- Object.append(el, Element.Prototype);
- }
- return el;
- },
-
- object: function(obj, nocash, doc){
- if (obj.toElement) return types.element(obj.toElement(doc), nocash);
- return null;
- }
-
- };
-
- types.textnode = types.whitespace = types.window = types.document = function(zero){
- return zero;
- };
-
- return function(el, nocash, doc){
- if (el && el.$family && el.uid) return el;
- var type = typeOf(el);
- return (types[type]) ? types[type](el, nocash, doc || document) : null;
- };
-
- })()
-
-});
-
-if (window.$ == null) Window.implement('$', function(el, nc){
- return document.id(el, nc, this.document);
-});
-
-Window.implement({
-
- getDocument: function(){
- return this.document;
- },
-
- getWindow: function(){
- return this;
- }
-
-});
-
-[Document, Element].invoke('implement', {
-
- getElements: function(expression){
- return Slick.search(this, expression, new Elements);
- },
-
- getElement: function(expression){
- return document.id(Slick.find(this, expression));
- }
-
-});
-
-//<1.2compat>
-
-(function(search, find, match){
-
- this.Selectors = {};
- var pseudos = this.Selectors.Pseudo = new Hash();
-
- var addSlickPseudos = function(){
- for (var name in pseudos) if (pseudos.hasOwnProperty(name)){
- Slick.definePseudo(name, pseudos[name]);
- delete pseudos[name];
- }
- };
-
- Slick.search = function(context, expression, append){
- addSlickPseudos();
- return search.call(this, context, expression, append);
- };
-
- Slick.find = function(context, expression){
- addSlickPseudos();
- return find.call(this, context, expression);
- };
-
- Slick.match = function(node, selector){
- addSlickPseudos();
- return match.call(this, node, selector);
- };
-
-})(Slick.search, Slick.find, Slick.match);
-
-if (window.$$ == null) Window.implement('$$', function(selector){
- var elements = new Elements;
- if (arguments.length == 1 && typeof selector == 'string') return Slick.search(this.document, selector, elements);
- var args = Array.flatten(arguments);
- for (var i = 0, l = args.length; i < l; i++){
- var item = args[i];
- switch (typeOf(item)){
- case 'element': elements.push(item); break;
- case 'string': Slick.search(this.document, item, elements);
- }
- }
- return elements;
-});
-
-//</1.2compat>
-
-if (window.$$ == null) Window.implement('$$', function(selector){
- if (arguments.length == 1){
- if (typeof selector == 'string') return Slick.search(this.document, selector, new Elements);
- else if (Type.isEnumerable(selector)) return new Elements(selector);
- }
- return new Elements(arguments);
-});
-
-(function(){
-
-var collected = {}, storage = {};
-var props = {input: 'checked', option: 'selected', textarea: 'value'};
-
-var get = function(uid){
- return (storage[uid] || (storage[uid] = {}));
-};
-
-var clean = function(item){
- if (item.removeEvents) item.removeEvents();
- if (item.clearAttributes) item.clearAttributes();
- var uid = item.uid;
- if (uid != null){
- delete collected[uid];
- delete storage[uid];
- }
- return item;
-};
-
-var camels = ['defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'frameBorder', 'maxLength', 'readOnly',
- 'rowSpan', 'tabIndex', 'useMap'
-];
-var bools = ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 'disabled', 'readOnly', 'multiple', 'selected',
- 'noresize', 'defer'
-];
- var attributes = {
- 'html': 'innerHTML',
- 'class': 'className',
- 'for': 'htmlFor',
- 'text': (function(){
- var temp = document.createElement('div');
- return (temp.innerText == null) ? 'textContent' : 'innerText';
- })()
-};
-var readOnly = ['type'];
-var expandos = ['value', 'defaultValue'];
-var uriAttrs = /^(?:href|src|usemap)$/i;
-
-bools = bools.associate(bools);
-camels = camels.associate(camels.map(String.toLowerCase));
-readOnly = readOnly.associate(readOnly);
-
-Object.append(attributes, expandos.associate(expandos));
-
-var inserters = {
-
- before: function(context, element){
- var parent = element.parentNode;
- if (parent) parent.insertBefore(context, element);
- },
-
- after: function(context, element){
- var parent = element.parentNode;
- if (parent) parent.insertBefore(context, element.nextSibling);
- },
-
- bottom: function(context, element){
- element.appendChild(context);
- },
-
- top: function(context, element){
- element.insertBefore(context, element.firstChild);
- }
-
-};
-
-inserters.inside = inserters.bottom;
-
-//<1.2compat>
-
-Object.each(inserters, function(inserter, where){
-
- where = where.capitalize();
-
- var methods = {};
-
- methods['inject' + where] = function(el){
- inserter(this, document.id(el, true));
- return this;
- };
-
- methods['grab' + where] = function(el){
- inserter(document.id(el, true), this);
- return this;
- };
-
- Element.implement(methods);
-
-});
-
-//</1.2compat>
-
-var injectCombinator = function(expression, combinator){
- if (!expression) return combinator;
-
- expression = Slick.parse(expression);
-
- var expressions = expression.expressions;
- for (var i = expressions.length; i--;)
- expressions[i][0].combinator = combinator;
-
- return expression;
-};
-
-Element.implement({
-
- set: function(prop, value){
- var property = Element.Properties[prop];
- (property && property.set) ? property.set.call(this, value) : this.setProperty(prop, value);
- }.overloadSetter(),
-
- get: function(prop){
- var property = Element.Properties[prop];
- return (property && property.get) ? property.get.apply(this) : this.getProperty(prop);
- }.overloadGetter(),
-
- erase: function(prop){
- var property = Element.Properties[prop];
- (property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop);
- return this;
- },
-
- setProperty: function(attribute, value){
- attribute = camels[attribute] || attribute;
- if (value == null) return this.removeProperty(attribute);
- var key = attributes[attribute];
- (key) ? this[key] = value :
- (bools[attribute]) ? this[attribute] = !!value : this.setAttribute(attribute, '' + value);
- return this;
- },
-
- setProperties: function(attributes){
- for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]);
- return this;
- },
-
- getProperty: function(attribute){
- attribute = camels[attribute] || attribute;
- var key = attributes[attribute] || readOnly[attribute];
- return (key) ? this[key] :
- (bools[attribute]) ? !!this[attribute] :
- (uriAttrs.test(attribute) ? this.getAttribute(attribute, 2) :
- (key = this.getAttributeNode(attribute)) ? key.nodeValue : null) || null;
- },
-
- getProperties: function(){
- var args = Array.from(arguments);
- return args.map(this.getProperty, this).associate(args);
- },
-
- removeProperty: function(attribute){
- attribute = camels[attribute] || attribute;
- var key = attributes[attribute];
- (key) ? this[key] = '' :
- (bools[attribute]) ? this[attribute] = false : this.removeAttribute(attribute);
- return this;
- },
-
- removeProperties: function(){
- Array.each(arguments, this.removeProperty, this);
- return this;
- },
-
- hasClass: function(className){
- return this.className.clean().contains(className, ' ');
- },
-
- addClass: function(className){
- if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean();
- return this;
- },
-
- removeClass: function(className){
- this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1');
- return this;
- },
-
- toggleClass: function(className, force){
- if (force == null) force = !this.hasClass(className);
- return (force) ? this.addClass(className) : this.removeClass(className);
- },
-
- adopt: function(){
- var parent = this, fragment, elements = Array.flatten(arguments), length = elements.length;
- if (length > 1) parent = fragment = document.createDocumentFragment();
-
- for (var i = 0; i < length; i++){
- var element = document.id(elements[i], true);
- if (element) parent.appendChild(element);
- }
-
- if (fragment) this.appendChild(fragment);
-
- return this;
- },
-
- appendText: function(text, where){
- return this.grab(this.getDocument().newTextNode(text), where);
- },
-
- grab: function(el, where){
- inserters[where || 'bottom'](document.id(el, true), this);
- return this;
- },
-
- inject: function(el, where){
- inserters[where || 'bottom'](this, document.id(el, true));
- return this;
- },
-
- replaces: function(el){
- el = document.id(el, true);
- el.parentNode.replaceChild(this, el);
- return this;
- },
-
- wraps: function(el, where){
- el = document.id(el, true);
- return this.replaces(el).grab(el, where);
- },
-
- getPrevious: function(expression){
- return document.id(Slick.find(this, injectCombinator(expression, '!~')));
- },
-
- getAllPrevious: function(expression){
- return Slick.search(this, injectCombinator(expression, '!~'), new Elements);
- },
-
- getNext: function(expression){
- return document.id(Slick.find(this, injectCombinator(expression, '~')));
- },
-
- getAllNext: function(expression){
- return Slick.search(this, injectCombinator(expression, '~'), new Elements);
- },
-
- getFirst: function(expression){
- return document.id(Slick.search(this, injectCombinator(expression, '>'))[0]);
- },
-
- getLast: function(expression){
- return document.id(Slick.search(this, injectCombinator(expression, '>')).getLast());
- },
-
- getParent: function(expression){
- return document.id(Slick.find(this, injectCombinator(expression, '!')));
- },
-
- getParents: function(expression){
- return Slick.search(this, injectCombinator(expression, '!'), new Elements);
- },
-
- getSiblings: function(expression){
- return Slick.search(this, injectCombinator(expression, '~~'), new Elements);
- },
-
- getChildren: function(expression){
- return Slick.search(this, injectCombinator(expression, '>'), new Elements);
- },
-
- getWindow: function(){
- return this.ownerDocument.window;
- },
-
- getDocument: function(){
- return this.ownerDocument;
- },
-
- getElementById: function(id){
- return document.id(Slick.find(this, '#' + ('' + id).replace(/(\W)/g, '\\$1')));
- },
-
- getSelected: function(){
- this.selectedIndex; // Safari 3.2.1
- return new Elements(Array.from(this.options).filter(function(option){
- return option.selected;
- }));
- },
-
- toQueryString: function(){
- var queryString = [];
- this.getElements('input, select, textarea').each(function(el){
- var type = el.type;
- if (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return;
-
- var value = (el.get('tag') == 'select') ? el.getSelected().map(function(opt){
- // IE
- return document.id(opt).get('value');
- }) : ((type == 'radio' || type == 'checkbox') && !el.checked) ? null : el.get('value');
-
- Array.from(value).each(function(val){
- if (typeof val != 'undefined') queryString.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(val));
- });
- });
- return queryString.join('&');
- },
-
- clone: function(contents, keepid){
- contents = contents !== false;
- var clone = this.cloneNode(contents);
- var clean = function(node, element){
- if (!keepid) node.removeAttribute('id');
- if (Browser.ie){
- node.clearAttributes();
- node.mergeAttributes(element);
- node.removeAttribute('uid');
- if (node.options){
- var no = node.options, eo = element.options;
- for (var j = no.length; j--;) no[j].selected = eo[j].selected;
- }
- }
- var prop = props[element.tagName.toLowerCase()];
- if (prop && element[prop]) node[prop] = element[prop];
- };
-
- var i;
- if (contents){
- var ce = clone.getElementsByTagName('*'), te = this.getElementsByTagName('*');
- for (i = ce.length; i--;) clean(ce[i], te[i]);
- }
-
- clean(clone, this);
- if (Browser.ie){
- var ts = this.getElementsByTagName('object'),
- cs = clone.getElementsByTagName('object'),
- tl = ts.length, cl = cs.length;
- for (i = 0; i < tl && i < cl; i++)
- cs[i].outerHTML = ts[i].outerHTML;
- }
- return document.id(clone);
- },
-
- destroy: function(){
- var children = clean(this).getElementsByTagName('*');
- Array.each(children, clean);
- Element.dispose(this);
- return null;
- },
-
- empty: function(){
- Array.from(this.childNodes).each(Element.dispose);
- return this;
- },
-
- dispose: function(){
- return (this.parentNode) ? this.parentNode.removeChild(this) : this;
- },
-
- match: function(expression){
- return !expression || Slick.match(this, expression);
- }
-
-});
-
-var contains = {contains: function(element){
- return Slick.contains(this, element);
-}};
-
-if (!document.contains) Document.implement(contains);
-if (!document.createElement('div').contains) Element.implement(contains);
-
-//<1.2compat>
-
-Element.implement('hasChild', function(element){
- return this !== element && this.contains(element);
-});
-
-//</1.2compat>
-
-[Element, Window, Document].invoke('implement', {
-
- addListener: function(type, fn){
- if (type == 'unload'){
- var old = fn, self = this;
- fn = function(){
- self.removeListener('unload', fn);
- old();
- };
- } else {
- collected[this.uid] = this;
- }
- if (this.addEventListener) this.addEventListener(type, fn, false);
- else this.attachEvent('on' + type, fn);
- return this;
- },
-
- removeListener: function(type, fn){
- if (this.removeEventListener) this.removeEventListener(type, fn, false);
- else this.detachEvent('on' + type, fn);
- return this;
- },
-
- retrieve: function(property, dflt){
- var storage = get(this.uid), prop = storage[property];
- if (dflt != null && prop == null) prop = storage[property] = dflt;
- return prop != null ? prop : null;
- },
-
- store: function(property, value){
- var storage = get(this.uid);
- storage[property] = value;
- return this;
- },
-
- eliminate: function(property){
- var storage = get(this.uid);
- delete storage[property];
- return this;
- }
-
-});
-
-// IE purge
-if (window.attachEvent && !window.addEventListener) window.addListener('unload', function(){
- Object.each(collected, clean);
- if (window.CollectGarbage) CollectGarbage();
-});
-
-})();
-
-Element.Properties = {};
-
-//<1.2compat>
-
-Element.Properties = new Hash;
-
-//</1.2compat>
-
-Element.Properties.style = {
-
- set: function(style){
- this.style.cssText = style;
- },
-
- get: function(){
- return this.style.cssText;
- },
-
- erase: function(){
- this.style.cssText = '';
- }
-
-};
-
-Element.Properties.tag = {
-
- get: function(){
- return this.tagName.toLowerCase();
- }
-
-};
-
-(function(maxLength){
- if (maxLength != null) Element.Properties.maxlength = Element.Properties.maxLength = {
- get: function(){
- var maxlength = this.getAttribute('maxLength');
- return maxlength == maxLength ? null : maxlength;
- }
- };
-})(document.createElement('input').getAttribute('maxLength'));
-
-Element.Properties.html = (function(){
-
- var tableTest = Function.attempt(function(){
- var table = document.createElement('table');
- table.innerHTML = '<tr><td></td></tr>';
- });
-
- var wrapper = document.createElement('div');
-
- var translations = {
- table: [1, '<table>', '</table>'],
- select: [1, '<select>', '</select>'],
- tbody: [2, '<table><tbody>', '</tbody></table>'],
- tr: [3, '<table><tbody><tr>', '</tr></tbody></table>']
- };
- translations.thead = translations.tfoot = translations.tbody;
-
- var html = {
- set: function(){
- var html = Array.flatten(arguments).join('');
- var wrap = (!tableTest && translations[this.get('tag')]);
- if (wrap){
- var first = wrapper;
- first.innerHTML = wrap[1] + html + wrap[2];
- for (var i = wrap[0]; i--;) first = first.firstChild;
- this.empty().adopt(first.childNodes);
- } else {
- this.innerHTML = html;
- }
- }
- };
-
- html.erase = html.set;
-
- return html;
-})();
-
-
-/*
----
-
-name: Element.Style
-
-description: Contains methods for interacting with the styles of Elements in a fashionable way.
-
-license: MIT-style license.
-
-requires: Element
-
-provides: Element.Style
-
-...
-*/
-
-(function(){
-
-var html = document.html;
-
-Element.Properties.styles = {set: function(styles){
- this.setStyles(styles);
-}};
-
-var hasOpacity = (html.style.opacity != null);
-var reAlpha = /alpha\(opacity=([\d.]+)\)/i;
-
-var setOpacity = function(element, opacity){
- if (!element.currentStyle || !element.currentStyle.hasLayout) element.style.zoom = 1;
- if (hasOpacity){
- element.style.opacity = opacity;
- } else {
- opacity = (opacity == 1) ? '' : 'alpha(opacity=' + opacity * 100 + ')';
- var filter = element.style.filter || element.getComputedStyle('filter') || '';
- element.style.filter = filter.test(reAlpha) ? filter.replace(reAlpha, opacity) : filter + opacity;
- }
-};
-
-Element.Properties.opacity = {
-
- set: function(opacity){
- var visibility = this.style.visibility;
- if (opacity == 0 && visibility != 'hidden') this.style.visibility = 'hidden';
- else if (opacity != 0 && visibility != 'visible') this.style.visibility = 'visible';
-
- setOpacity(this, opacity);
- },
-
- get: (hasOpacity) ? function(){
- var opacity = this.style.opacity || this.getComputedStyle('opacity');
- return (opacity == '') ? 1 : opacity;
- } : function(){
- var opacity, filter = (this.style.filter || this.getComputedStyle('filter'));
- if (filter) opacity = filter.match(reAlpha);
- return (opacity == null || filter == null) ? 1 : (opacity[1] / 100);
- }
-
-};
-
-var floatName = (html.style.cssFloat == null) ? 'styleFloat' : 'cssFloat';
-
-Element.implement({
-
- getComputedStyle: function(property){
- if (this.currentStyle) return this.currentStyle[property.camelCase()];
- var defaultView = Element.getDocument(this).defaultView,
- computed = defaultView ? defaultView.getComputedStyle(this, null) : null;
- return (computed) ? computed.getPropertyValue((property == floatName) ? 'float' : property.hyphenate()) : null;
- },
-
- setOpacity: function(value){
- setOpacity(this, value);
- return this;
- },
-
- getOpacity: function(){
- return this.get('opacity');
- },
-
- setStyle: function(property, value){
- switch (property){
- case 'opacity': return this.set('opacity', parseFloat(value));
- case 'float': property = floatName;
- }
- property = property.camelCase();
- if (typeOf(value) != 'string'){
- var map = (Element.Styles[property] || '@').split(' ');
- value = Array.from(value).map(function(val, i){
- if (!map[i]) return '';
- return (typeOf(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;
- }).join(' ');
- } else if (value == String(Number(value))){
- value = Math.round(value);
- }
- this.style[property] = value;
- return this;
- },
-
- getStyle: function(property){
- switch (property){
- case 'opacity': return this.get('opacity');
- case 'float': property = floatName;
- }
- property = property.camelCase();
- var result = this.style[property];
- if (!result || property == 'zIndex'){
- result = [];
- for (var style in Element.ShortStyles){
- if (property != style) continue;
- for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s));
- return result.join(' ');
- }
- result = this.getComputedStyle(property);
- }
- if (result){
- result = String(result);
- var color = result.match(/rgba?\([\d\s,]+\)/);
- if (color) result = result.replace(color[0], color[0].rgbToHex());
- }
- if (Browser.opera || (Browser.ie && isNaN(parseFloat(result)))){
- if (property.test(/^(height|width)$/)){
- var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
- values.each(function(value){
- size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
- }, this);
- return this['offset' + property.capitalize()] - size + 'px';
- }
- if (Browser.opera && String(result).indexOf('px') != -1) return result;
- if (property.test(/(border(.+)Width|margin|padding)/)) return '0px';
- }
- return result;
- },
-
- setStyles: function(styles){
- for (var style in styles) this.setStyle(style, styles[style]);
- return this;
- },
-
- getStyles: function(){
- var result = {};
- Array.flatten(arguments).each(function(key){
- result[key] = this.getStyle(key);
- }, this);
- return result;
- }
-
-});
-
-Element.Styles = {
- left: '@px', top: '@px', bottom: '@px', right: '@px',
- width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',
- backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
- fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
- margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
- borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
- zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'
-};
-
-//<1.2compat>
-
-Element.Styles = new Hash(Element.Styles);
-
-//</1.2compat>
-
-Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}};
-
-['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
- var Short = Element.ShortStyles;
- var All = Element.Styles;
- ['margin', 'padding'].each(function(style){
- var sd = style + direction;
- Short[style][sd] = All[sd] = '@px';
- });
- var bd = 'border' + direction;
- Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
- var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
- Short[bd] = {};
- Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
- Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
- Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
-});
-
-})();
-
-
-/*
----
-
-name: Element.Event
-
-description: Contains Element methods for dealing with events. This file also includes mouseenter and mouseleave custom Element Events.
-
-license: MIT-style license.
-
-requires: [Element, Event]
-
-provides: Element.Event
-
-...
-*/
-
-(function(){
-
-Element.Properties.events = {set: function(events){
- this.addEvents(events);
-}};
-
-[Element, Window, Document].invoke('implement', {
-
- addEvent: function(type, fn){
- var events = this.retrieve('events', {});
- if (!events[type]) events[type] = {keys: [], values: []};
- if (events[type].keys.contains(fn)) return this;
- events[type].keys.push(fn);
- var realType = type,
- custom = Element.Events[type],
- condition = fn,
- self = this;
- if (custom){
- if (custom.onAdd) custom.onAdd.call(this, fn);
- if (custom.condition){
- condition = function(event){
- if (custom.condition.call(this, event)) return fn.call(this, event);
- return true;
- };
- }
- realType = custom.base || realType;
- }
- var defn = function(){
- return fn.call(self);
- };
- var nativeEvent = Element.NativeEvents[realType];
- if (nativeEvent){
- if (nativeEvent == 2){
- defn = function(event){
- event = new Event(event, self.getWindow());
- if (condition.call(self, event) === false) event.stop();
- };
- }
- this.addListener(realType, defn);
- }
- events[type].values.push(defn);
- return this;
- },
-
- removeEvent: function(type, fn){
- var events = this.retrieve('events');
- if (!events || !events[type]) return this;
- var list = events[type];
- var index = list.keys.indexOf(fn);
- if (index == -1) return this;
- var value = list.values[index];
- delete list.keys[index];
- delete list.values[index];
- var custom = Element.Events[type];
- if (custom){
- if (custom.onRemove) custom.onRemove.call(this, fn);
- type = custom.base || type;
- }
- return (Element.NativeEvents[type]) ? this.removeListener(type, value) : this;
- },
-
- addEvents: function(events){
- for (var event in events) this.addEvent(event, events[event]);
- return this;
- },
-
- removeEvents: function(events){
- var type;
- if (typeOf(events) == 'object'){
- for (type in events) this.removeEvent(type, events[type]);
- return this;
- }
- var attached = this.retrieve('events');
- if (!attached) return this;
- if (!events){
- for (type in attached) this.removeEvents(type);
- this.eliminate('events');
- } else if (attached[events]){
- attached[events].keys.each(function(fn){
- this.removeEvent(events, fn);
- }, this);
- delete attached[events];
- }
- return this;
- },
-
- fireEvent: function(type, args, delay){
- var events = this.retrieve('events');
- if (!events || !events[type]) return this;
- args = Array.from(args);
-
- events[type].keys.each(function(fn){
- if (delay) fn.delay(delay, this, args);
- else fn.apply(this, args);
- }, this);
- return this;
- },
-
- cloneEvents: function(from, type){
- from = document.id(from);
- var events = from.retrieve('events');
- if (!events) return this;
- if (!type){
- for (var eventType in events) this.cloneEvents(from, eventType);
- } else if (events[type]){
- events[type].keys.each(function(fn){
- this.addEvent(type, fn);
- }, this);
- }
- return this;
- }
-
-});
-
-// IE9
-try {
- if (typeof HTMLElement != 'undefined')
- HTMLElement.prototype.fireEvent = Element.prototype.fireEvent;
-} catch(e){}
-
-Element.NativeEvents = {
- click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons
- mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
- mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement
- keydown: 2, keypress: 2, keyup: 2, //keyboard
- orientationchange: 2, // mobile
- touchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch
- gesturestart: 2, gesturechange: 2, gestureend: 2, // gesture
- focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, //form elements
- load: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
- error: 1, abort: 1, scroll: 1 //misc
-};
-
-var check = function(event){
- var related = event.relatedTarget;
- if (related == null) return true;
- if (!related) return false;
- return (related != this && related.prefix != 'xul' && typeOf(this) != 'document' && !this.contains(related));
-};
-
-Element.Events = {
-
- mouseenter: {
- base: 'mouseover',
- condition: check
- },
-
- mouseleave: {
- base: 'mouseout',
- condition: check
- },
-
- mousewheel: {
- base: (Browser.firefox) ? 'DOMMouseScroll' : 'mousewheel'
- }
-
-};
-
-//<1.2compat>
-
-Element.Events = new Hash(Element.Events);
-
-//</1.2compat>
-
-})();
-
-
-/*
----
-
-name: Element.Dimensions
-
-description: Contains methods to work with size, scroll, or positioning of Elements and the window object.
-
-license: MIT-style license.
-
-credits:
- - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html).
- - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [BSD License](http://developer.yahoo.com/yui/license.html).
-
-requires: [Element, Element.Style]
-
-provides: [Element.Dimensions]
-
-...
-*/
-
-(function(){
-
-Element.implement({
-
- scrollTo: function(x, y){
- if (isBody(this)){
- this.getWindow().scrollTo(x, y);
- } else {
- this.scrollLeft = x;
- this.scrollTop = y;
- }
- return this;
- },
-
- getSize: function(){
- if (isBody(this)) return this.getWindow().getSize();
- return {x: this.offsetWidth, y: this.offsetHeight};
- },
-
- getScrollSize: function(){
- if (isBody(this)) return this.getWindow().getScrollSize();
- return {x: this.scrollWidth, y: this.scrollHeight};
- },
-
- getScroll: function(){
- if (isBody(this)) return this.getWindow().getScroll();
- return {x: this.scrollLeft, y: this.scrollTop};
- },
-
- getScrolls: function(){
- var element = this.parentNode, position = {x: 0, y: 0};
- while (element && !isBody(element)){
- position.x += element.scrollLeft;
- position.y += element.scrollTop;
- element = element.parentNode;
- }
- return position;
- },
-
- getOffsetParent: function(){
- var element = this;
- if (isBody(element)) return null;
- if (!Browser.ie) return element.offsetParent;
- while ((element = element.parentNode)){
- if (styleString(element, 'position') != 'static' || isBody(element)) return element;
- }
- return null;
- },
-
- getOffsets: function(){
- if (this.getBoundingClientRect && !Browser.Platform.ios){
- var bound = this.getBoundingClientRect(),
- html = document.id(this.getDocument().documentElement),
- htmlScroll = html.getScroll(),
- elemScrolls = this.getScrolls(),
- isFixed = (styleString(this, 'position') == 'fixed');
-
- return {
- x: bound.left.toInt() + elemScrolls.x + ((isFixed) ? 0 : htmlScroll.x) - html.clientLeft,
- y: bound.top.toInt() + elemScrolls.y + ((isFixed) ? 0 : htmlScroll.y) - html.clientTop
- };
- }
-
- var element = this, position = {x: 0, y: 0};
- if (isBody(this)) return position;
-
- while (element && !isBody(element)){
- position.x += element.offsetLeft;
- position.y += element.offsetTop;
-
- if (Browser.firefox){
- if (!borderBox(element)){
- position.x += leftBorder(element);
- position.y += topBorder(element);
- }
- var parent = element.parentNode;
- if (parent && styleString(parent, 'overflow') != 'visible'){
- position.x += leftBorder(parent);
- position.y += topBorder(parent);
- }
- } else if (element != this && Browser.safari){
- position.x += leftBorder(element);
- position.y += topBorder(element);
- }
-
- element = element.offsetParent;
- }
- if (Browser.firefox && !borderBox(this)){
- position.x -= leftBorder(this);
- position.y -= topBorder(this);
- }
- return position;
- },
-
- getPosition: function(relative){
- if (isBody(this)) return {x: 0, y: 0};
- var offset = this.getOffsets(),
- scroll = this.getScrolls();
- var position = {
- x: offset.x - scroll.x,
- y: offset.y - scroll.y
- };
-
- if (relative && (relative = document.id(relative))){
- var relativePosition = relative.getPosition();
- return {x: position.x - relativePosition.x - leftBorder(relative), y: position.y - relativePosition.y - topBorder(relative)};
- }
- return position;
- },
-
- getCoordinates: function(element){
- if (isBody(this)) return this.getWindow().getCoordinates();
- var position = this.getPosition(element),
- size = this.getSize();
- var obj = {
- left: position.x,
- top: position.y,
- width: size.x,
- height: size.y
- };
- obj.right = obj.left + obj.width;
- obj.bottom = obj.top + obj.height;
- return obj;
- },
-
- computePosition: function(obj){
- return {
- left: obj.x - styleNumber(this, 'margin-left'),
- top: obj.y - styleNumber(this, 'margin-top')
- };
- },
-
- setPosition: function(obj){
- return this.setStyles(this.computePosition(obj));
- }
-
-});
-
-
-[Document, Window].invoke('implement', {
-
- getSize: function(){
- var doc = getCompatElement(this);
- return {x: doc.clientWidth, y: doc.clientHeight};
- },
-
- getScroll: function(){
- var win = this.getWindow(), doc = getCompatElement(this);
- return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
- },
-
- getScrollSize: function(){
- var doc = getCompatElement(this),
- min = this.getSize(),
- body = this.getDocument().body;
-
- return {x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y: Math.max(doc.scrollHeight, body.scrollHeight, min.y)};
- },
-
- getPosition: function(){
- return {x: 0, y: 0};
- },
-
- getCoordinates: function(){
- var size = this.getSize();
- return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x};
- }
-
-});
-
-// private methods
-
-var styleString = Element.getComputedStyle;
-
-function styleNumber(element, style){
- return styleString(element, style).toInt() || 0;
-};
-
-function borderBox(element){
- return styleString(element, '-moz-box-sizing') == 'border-box';
-};
-
-function topBorder(element){
- return styleNumber(element, 'border-top-width');
-};
-
-function leftBorder(element){
- return styleNumber(element, 'border-left-width');
-};
-
-function isBody(element){
- return (/^(?:body|html)$/i).test(element.tagName);
-};
-
-function getCompatElement(element){
- var doc = element.getDocument();
- return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
-};
-
-})();
-
-//aliases
-Element.alias({position: 'setPosition'}); //compatability
-
-[Window, Document, Element].invoke('implement', {
-
- getHeight: function(){
- return this.getSize().y;
- },
-
- getWidth: function(){
- return this.getSize().x;
- },
-
- getScrollTop: function(){
- return this.getScroll().y;
- },
-
- getScrollLeft: function(){
- return this.getScroll().x;
- },
-
- getScrollHeight: function(){
- return this.getScrollSize().y;
- },
-
- getScrollWidth: function(){
- return this.getScrollSize().x;
- },
-
- getTop: function(){
- return this.getPosition().y;
- },
-
- getLeft: function(){
- return this.getPosition().x;
- }
-
-});
-
-
-/*
----
-
-name: Fx
-
-description: Contains the basic animation logic to be extended by all other Fx Classes.
-
-license: MIT-style license.
-
-requires: [Chain, Events, Options]
-
-provides: Fx
-
-...
-*/
-
-(function(){
-
-var Fx = this.Fx = new Class({
-
- Implements: [Chain, Events, Options],
-
- options: {
- /*
- onStart: nil,
- onCancel: nil,
- onComplete: nil,
- */
- fps: 50,
- unit: false,
- duration: 500,
- link: 'ignore'
- },
-
- initialize: function(options){
- this.subject = this.subject || this;
- this.setOptions(options);
- },
-
- getTransition: function(){
- return function(p){
- return -(Math.cos(Math.PI * p) - 1) / 2;
- };
- },
-
- step: function(){
- var time = Date.now();
- if (time < this.time + this.options.duration){
- var delta = this.transition((time - this.time) / this.options.duration);
- this.set(this.compute(this.from, this.to, delta));
- } else {
- this.set(this.compute(this.from, this.to, 1));
- this.complete();
- }
- },
-
- set: function(now){
- return now;
- },
-
- compute: function(from, to, delta){
- return Fx.compute(from, to, delta);
- },
-
- check: function(){
- if (!this.timer) return true;
- switch (this.options.link){
- case 'cancel': this.cancel(); return true;
- case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
- }
- return false;
- },
-
- start: function(from, to){
- if (!this.check(from, to)) return this;
- var duration = this.options.duration;
- this.options.duration = Fx.Durations[duration] || duration.toInt();
- this.from = from;
- this.to = to;
- this.time = 0;
- this.transition = this.getTransition();
- this.startTimer();
- this.onStart();
- return this;
- },
-
- complete: function(){
- if (this.stopTimer()) this.onComplete();
- return this;
- },
-
- cancel: function(){
- if (this.stopTimer()) this.onCancel();
- return this;
- },
-
- onStart: function(){
- this.fireEvent('start', this.subject);
- },
-
- onComplete: function(){
- this.fireEvent('complete', this.subject);
- if (!this.callChain()) this.fireEvent('chainComplete', this.subject);
- },
-
- onCancel: function(){
- this.fireEvent('cancel', this.subject).clearChain();
- },
-
- pause: function(){
- this.stopTimer();
- return this;
- },
-
- resume: function(){
- this.startTimer();
- return this;
- },
-
- stopTimer: function(){
- if (!this.timer) return false;
- this.time = Date.now() - this.time;
- this.timer = removeInstance(this);
- return true;
- },
-
- startTimer: function(){
- if (this.timer) return false;
- this.time = Date.now() - this.time;
- this.timer = addInstance(this);
- return true;
- }
-
-});
-
-Fx.compute = function(from, to, delta){
- return (to - from) * delta + from;
-};
-
-Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000};
-
-// global timers
-
-var instances = {}, timers = {};
-
-var loop = function(){
- for (var i = this.length; i--;){
- if (this[i]) this[i].step();
- }
-};
-
-var addInstance = function(instance){
- var fps = instance.options.fps,
- list = instances[fps] || (instances[fps] = []);
- list.push(instance);
- if (!timers[fps]) timers[fps] = loop.periodical(Math.round(1000 / fps), list);
- return true;
-};
-
-var removeInstance = function(instance){
- var fps = instance.options.fps,
- list = instances[fps] || [];
- list.erase(instance);
- if (!list.length && timers[fps]) timers[fps] = clearInterval(timers[fps]);
- return false;
-};
-
-})();
-
-
-/*
----
-
-name: Fx.CSS
-
-description: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements.
-
-license: MIT-style license.
-
-requires: [Fx, Element.Style]
-
-provides: Fx.CSS
-
-...
-*/
-
-Fx.CSS = new Class({
-
- Extends: Fx,
-
- //prepares the base from/to object
-
- prepare: function(element, property, values){
- values = Array.from(values);
- if (values[1] == null){
- values[1] = values[0];
- values[0] = element.getStyle(property);
- }
- var parsed = values.map(this.parse);
- return {from: parsed[0], to: parsed[1]};
- },
-
- //parses a value into an array
-
- parse: function(value){
- value = Function.from(value)();
- value = (typeof value == 'string') ? value.split(' ') : Array.from(value);
- return value.map(function(val){
- val = String(val);
- var found = false;
- Object.each(Fx.CSS.Parsers, function(parser, key){
- if (found) return;
- var parsed = parser.parse(val);
- if (parsed || parsed === 0) found = {value: parsed, parser: parser};
- });
- found = found || {value: val, parser: Fx.CSS.Parsers.String};
- return found;
- });
- },
-
- //computes by a from and to prepared objects, using their parsers.
-
- compute: function(from, to, delta){
- var computed = [];
- (Math.min(from.length, to.length)).times(function(i){
- computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser});
- });
- computed.$family = Function.from('fx:css:value');
- return computed;
- },
-
- //serves the value as settable
-
- serve: function(value, unit){
- if (typeOf(value) != 'fx:css:value') value = this.parse(value);
- var returned = [];
- value.each(function(bit){
- returned = returned.concat(bit.parser.serve(bit.value, unit));
- });
- return returned;
- },
-
- //renders the change to an element
-
- render: function(element, property, value, unit){
- element.setStyle(property, this.serve(value, unit));
- },
-
- //searches inside the page css to find the values for a selector
-
- search: function(selector){
- if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];
- var to = {};
- Array.each(document.styleSheets, function(sheet, j){
- var href = sheet.href;
- if (href && href.contains('://') && !href.contains(document.domain)) return;
- var rules = sheet.rules || sheet.cssRules;
- Array.each(rules, function(rule, i){
- if (!rule.style) return;
- var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){
- return m.toLowerCase();
- }) : null;
- if (!selectorText || !selectorText.test('^' + selector + '$')) return;
- Element.Styles.each(function(value, style){
- if (!rule.style[style] || Element.ShortStyles[style]) return;
- value = String(rule.style[style]);
- to[style] = (value.test(/^rgb/)) ? value.rgbToHex() : value;
- });
- });
- });
- return Fx.CSS.Cache[selector] = to;
- }
-
-});
-
-Fx.CSS.Cache = {};
-
-Fx.CSS.Parsers = {
-
- Color: {
- parse: function(value){
- if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true);
- return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false;
- },
- compute: function(from, to, delta){
- return from.map(function(value, i){
- return Math.round(Fx.compute(from[i], to[i], delta));
- });
- },
- serve: function(value){
- return value.map(Number);
- }
- },
-
- Number: {
- parse: parseFloat,
- compute: Fx.compute,
- serve: function(value, unit){
- return (unit) ? value + unit : value;
- }
- },
-
- String: {
- parse: Function.from(false),
- compute: function(zero, one){
- return one;
- },
- serve: function(zero){
- return zero;
- }
- }
-
-};
-
-//<1.2compat>
-
-Fx.CSS.Parsers = new Hash(Fx.CSS.Parsers);
-
-//</1.2compat>
-
-
-/*
----
-
-name: Fx.Tween
-
-description: Formerly Fx.Style, effect to transition any CSS property for an element.
-
-license: MIT-style license.
-
-requires: Fx.CSS
-
-provides: [Fx.Tween, Element.fade, Element.highlight]
-
-...
-*/
-
-Fx.Tween = new Class({
-
- Extends: Fx.CSS,
-
- initialize: function(element, options){
- this.element = this.subject = document.id(element);
- this.parent(options);
- },
-
- set: function(property, now){
- if (arguments.length == 1){
- now = property;
- property = this.property || this.options.property;
- }
- this.render(this.element, property, now, this.options.unit);
- return this;
- },
-
- start: function(property, from, to){
- if (!this.check(property, from, to)) return this;
- var args = Array.flatten(arguments);
- this.property = this.options.property || args.shift();
- var parsed = this.prepare(this.element, this.property, args);
- return this.parent(parsed.from, parsed.to);
- }
-
-});
-
-Element.Properties.tween = {
-
- set: function(options){
- this.get('tween').cancel().setOptions(options);
- return this;
- },
-
- get: function(){
- var tween = this.retrieve('tween');
- if (!tween){
- tween = new Fx.Tween(this, {link: 'cancel'});
- this.store('tween', tween);
- }
- return tween;
- }
-
-};
-
-Element.implement({
-
- tween: function(property, from, to){
- this.get('tween').start(arguments);
- return this;
- },
-
- fade: function(how){
- var fade = this.get('tween'), o = 'opacity', toggle;
- how = [how, 'toggle'].pick();
- switch (how){
- case 'in': fade.start(o, 1); break;
- case 'out': fade.start(o, 0); break;
- case 'show': fade.set(o, 1); break;
- case 'hide': fade.set(o, 0); break;
- case 'toggle':
- var flag = this.retrieve('fade:flag', this.get('opacity') == 1);
- fade.start(o, (flag) ? 0 : 1);
- this.store('fade:flag', !flag);
- toggle = true;
- break;
- default: fade.start(o, arguments);
- }
- if (!toggle) this.eliminate('fade:flag');
- return this;
- },
-
- highlight: function(start, end){
- if (!end){
- end = this.retrieve('highlight:original', this.getStyle('background-color'));
- end = (end == 'transparent') ? '#fff' : end;
- }
- var tween = this.get('tween');
- tween.start('background-color', start || '#ffff88', end).chain(function(){
- this.setStyle('background-color', this.retrieve('highlight:original'));
- tween.callChain();
- }.bind(this));
- return this;
- }
-
-});
-
-
-/*
----
-
-name: Fx.Morph
-
-description: Formerly Fx.Styles, effect to transition any number of CSS properties for an element using an object of rules, or CSS based selector rules.
-
-license: MIT-style license.
-
-requires: Fx.CSS
-
-provides: Fx.Morph
-
-...
-*/
-
-Fx.Morph = new Class({
-
- Extends: Fx.CSS,
-
- initialize: function(element, options){
- this.element = this.subject = document.id(element);
- this.parent(options);
- },
-
- set: function(now){
- if (typeof now == 'string') now = this.search(now);
- for (var p in now) this.render(this.element, p, now[p], this.options.unit);
- return this;
- },
-
- compute: function(from, to, delta){
- var now = {};
- for (var p in from) now[p] = this.parent(from[p], to[p], delta);
- return now;
- },
-
- start: function(properties){
- if (!this.check(properties)) return this;
- if (typeof properties == 'string') properties = this.search(properties);
- var from = {}, to = {};
- for (var p in properties){
- var parsed = this.prepare(this.element, p, properties[p]);
- from[p] = parsed.from;
- to[p] = parsed.to;
- }
- return this.parent(from, to);
- }
-
-});
-
-Element.Properties.morph = {
-
- set: function(options){
- this.get('morph').cancel().setOptions(options);
- return this;
- },
-
- get: function(){
- var morph = this.retrieve('morph');
- if (!morph){
- morph = new Fx.Morph(this, {link: 'cancel'});
- this.store('morph', morph);
- }
- return morph;
- }
-
-};
-
-Element.implement({
-
- morph: function(props){
- this.get('morph').start(props);
- return this;
- }
-
-});
-
-
-/*
----
-
-name: Fx.Transitions
-
-description: Contains a set of advanced transitions to be used with any of the Fx Classes.
-
-license: MIT-style license.
-
-credits:
- - Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>, modified and optimized to be used with MooTools.
-
-requires: Fx
-
-provides: Fx.Transitions
-
-...
-*/
-
-Fx.implement({
-
- getTransition: function(){
- var trans = this.options.transition || Fx.Transitions.Sine.easeInOut;
- if (typeof trans == 'string'){
- var data = trans.split(':');
- trans = Fx.Transitions;
- trans = trans[data[0]] || trans[data[0].capitalize()];
- if (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')];
- }
- return trans;
- }
-
-});
-
-Fx.Transition = function(transition, params){
- params = Array.from(params);
- return Object.append(transition, {
- easeIn: function(pos){
- return transition(pos, params);
- },
- easeOut: function(pos){
- return 1 - transition(1 - pos, params);
- },
- easeInOut: function(pos){
- return (pos <= 0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2;
- }
- });
-};
-
-Fx.Transitions = {
-
- linear: function(zero){
- return zero;
- }
-
-};
-
-//<1.2compat>
-
-Fx.Transitions = new Hash(Fx.Transitions);
-
-//</1.2compat>
-
-Fx.Transitions.extend = function(transitions){
- for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
-};
-
-Fx.Transitions.extend({
-
- Pow: function(p, x){
- return Math.pow(p, x && x[0] || 6);
- },
-
- Expo: function(p){
- return Math.pow(2, 8 * (p - 1));
- },
-
- Circ: function(p){
- return 1 - Math.sin(Math.acos(p));
- },
-
- Sine: function(p){
- return 1 - Math.sin((1 - p) * Math.PI / 2);
- },
-
- Back: function(p, x){
- x = x && x[0] || 1.618;
- return Math.pow(p, 2) * ((x + 1) * p - x);
- },
-
- Bounce: function(p){
- var value;
- for (var a = 0, b = 1; 1; a += b, b /= 2){
- if (p >= (7 - 4 * a) / 11){
- value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
- break;
- }
- }
- return value;
- },
-
- Elastic: function(p, x){
- return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x && x[0] || 1) / 3);
- }
-
-});
-
-['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
- Fx.Transitions[transition] = new Fx.Transition(function(p){
- return Math.pow(p, [i + 2]);
- });
-});
-
-
-/*
----
-
-name: Request
-
-description: Powerful all purpose Request Class. Uses XMLHTTPRequest.
-
-license: MIT-style license.
-
-requires: [Object, Element, Chain, Events, Options, Browser]
-
-provides: Request
-
-...
-*/
-
-(function(){
-
-var progressSupport = ('onprogress' in new Browser.Request);
-
-var Request = this.Request = new Class({
-
- Implements: [Chain, Events, Options],
-
- options: {/*
- onRequest: function(){},
- onLoadstart: function(event, xhr){},
- onProgress: function(event, xhr){},
- onComplete: function(){},
- onCancel: function(){},
- onSuccess: function(responseText, responseXML){},
- onFailure: function(xhr){},
- onException: function(headerName, value){},
- onTimeout: function(){},
- user: '',
- password: '',*/
- url: '',
- data: '',
- headers: {
- 'X-Requested-With': 'XMLHttpRequest',
- 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
- },
- async: true,
- format: false,
- method: 'post',
- link: 'ignore',
- isSuccess: null,
- emulation: true,
- urlEncoded: true,
- encoding: 'utf-8',
- evalScripts: false,
- evalResponse: false,
- timeout: 0,
- noCache: false
- },
-
- initialize: function(options){
- this.xhr = new Browser.Request();
- this.setOptions(options);
- this.headers = this.options.headers;
- },
-
- onStateChange: function(){
- var xhr = this.xhr;
- if (xhr.readyState != 4 || !this.running) return;
- this.running = false;
- this.status = 0;
- Function.attempt(function(){
- var status = xhr.status;
- this.status = (status == 1223) ? 204 : status;
- }.bind(this));
- xhr.onreadystatechange = function(){};
- clearTimeout(this.timer);
-
- this.response = {text: this.xhr.responseText || '', xml: this.xhr.responseXML};
- if (this.options.isSuccess.call(this, this.status))
- this.success(this.response.text, this.response.xml);
- else
- this.failure();
- },
-
- isSuccess: function(){
- var status = this.status;
- return (status >= 200 && status < 300);
- },
-
- isRunning: function(){
- return !!this.running;
- },
-
- processScripts: function(text){
- if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return Browser.exec(text);
- return text.stripScripts(this.options.evalScripts);
- },
-
- success: function(text, xml){
- this.onSuccess(this.processScripts(text), xml);
- },
-
- onSuccess: function(){
- this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();
- },
-
- failure: function(){
- this.onFailure();
- },
-
- onFailure: function(){
- this.fireEvent('complete').fireEvent('failure', this.xhr);
- },
-
- loadstart: function(event){
- this.fireEvent('loadstart', [event, this.xhr]);
- },
-
- progress: function(event){
- this.fireEvent('progress', [event, this.xhr]);
- },
-
- timeout: function(){
- this.fireEvent('timeout', this.xhr);
- },
-
- setHeader: function(name, value){
- this.headers[name] = value;
- return this;
- },
-
- getHeader: function(name){
- return Function.attempt(function(){
- return this.xhr.getResponseHeader(name);
- }.bind(this));
- },
-
- check: function(){
- if (!this.running) return true;
- switch (this.options.link){
- case 'cancel': this.cancel(); return true;
- case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
- }
- return false;
- },
-
- send: function(options){
- if (!this.check(options)) return this;
-
- this.options.isSuccess = this.options.isSuccess || this.isSuccess;
- this.running = true;
-
- var type = typeOf(options);
- if (type == 'string' || type == 'element') options = {data: options};
-
- var old = this.options;
- options = Object.append({data: old.data, url: old.url, method: old.method}, options);
- var data = options.data, url = String(options.url), method = options.method.toLowerCase();
-
- switch (typeOf(data)){
- case 'element': data = document.id(data).toQueryString(); break;
- case 'object': case 'hash': data = Object.toQueryString(data);
- }
-
- if (this.options.format){
- var format = 'format=' + this.options.format;
- data = (data) ? format + '&' + data : format;
- }
-
- if (this.options.emulation && !['get', 'post'].contains(method)){
- var _method = '_method=' + method;
- data = (data) ? _method + '&' + data : _method;
- method = 'post';
- }
-
- if (this.options.urlEncoded && ['post', 'put'].contains(method)){
- var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
- this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding;
- }
-
- if (!url) url = document.location.pathname;
-
- var trimPosition = url.lastIndexOf('/');
- if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);
-
- if (this.options.noCache)
- url += (url.contains('?') ? '&' : '?') + String.uniqueID();
-
- if (data && method == 'get'){
- url += (url.contains('?') ? '&' : '?') + data;
- data = null;
- }
-
- var xhr = this.xhr;
- if (progressSupport){
- xhr.onloadstart = this.loadstart.bind(this);
- xhr.onprogress = this.progress.bind(this);
- }
-
- xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password);
- if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true;
-
- xhr.onreadystatechange = this.onStateChange.bind(this);
-
- Object.each(this.headers, function(value, key){
- try {
- xhr.setRequestHeader(key, value);
- } catch (e){
- this.fireEvent('exception', [key, value]);
- }
- }, this);
-
- this.fireEvent('request');
- xhr.send(data);
- if (!this.options.async) this.onStateChange();
- if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this);
- return this;
- },
-
- cancel: function(){
- if (!this.running) return this;
- this.running = false;
- var xhr = this.xhr;
- xhr.abort();
- clearTimeout(this.timer);
- xhr.onreadystatechange = xhr.onprogress = xhr.onloadstart = function(){};
- this.xhr = new Browser.Request();
- this.fireEvent('cancel');
- return this;
- }
-
-});
-
-var methods = {};
-['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){
- methods[method] = function(data){
- return this.send({
- data: data,
- method: method
- });
- };
-});
-
-Request.implement(methods);
-
-Element.Properties.send = {
-
- set: function(options){
- var send = this.get('send').cancel();
- send.setOptions(options);
- return this;
- },
-
- get: function(){
- var send = this.retrieve('send');
- if (!send){
- send = new Request({
- data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action')
- });
- this.store('send', send);
- }
- return send;
- }
-
-};
-
-Element.implement({
-
- send: function(url){
- var sender = this.get('send');
- sender.send({data: this, url: url || sender.options.url});
- return this;
- }
-
-});
-
-})();
-
-/*
----
-
-name: Request.HTML
-
-description: Extends the basic Request Class with additional methods for interacting with HTML responses.
-
-license: MIT-style license.
-
-requires: [Element, Request]
-
-provides: Request.HTML
-
-...
-*/
-
-Request.HTML = new Class({
-
- Extends: Request,
-
- options: {
- update: false,
- append: false,
- evalScripts: true,
- filter: false,
- headers: {
- Accept: 'text/html, application/xml, text/xml, */*'
- }
- },
-
- success: function(text){
- var options = this.options, response = this.response;
-
- response.html = text.stripScripts(function(script){
- response.javascript = script;
- });
-
- var match = response.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
- if (match) response.html = match[1];
- var temp = new Element('div').set('html', response.html);
-
- response.tree = temp.childNodes;
- response.elements = temp.getElements('*');
-
- if (options.filter) response.tree = response.elements.filter(options.filter);
- if (options.update) document.id(options.update).empty().set('html', response.html);
- else if (options.append) document.id(options.append).adopt(temp.getChildren());
- if (options.evalScripts) Browser.exec(response.javascript);
-
- this.onSuccess(response.tree, response.elements, response.html, response.javascript);
- }
-
-});
-
-Element.Properties.load = {
-
- set: function(options){
- var load = this.get('load').cancel();
- load.setOptions(options);
- return this;
- },
-
- get: function(){
- var load = this.retrieve('load');
- if (!load){
- load = new Request.HTML({data: this, link: 'cancel', update: this, method: 'get'});
- this.store('load', load);
- }
- return load;
- }
-
-};
-
-Element.implement({
-
- load: function(){
- this.get('load').send(Array.link(arguments, {data: Type.isObject, url: Type.isString}));
- return this;
- }
-
-});
-
-
-/*
----
-
-name: JSON
-
-description: JSON encoder and decoder.
-
-license: MIT-style license.
-
-See Also: <http://www.json.org/>
-
-requires: [Array, String, Number, Function]
-
-provides: JSON
-
-...
-*/
-
-if (!this.JSON) this.JSON = {};
-
-//<1.2compat>
-
-JSON = new Hash({
- stringify: JSON.stringify,
- parse: JSON.parse
-});
-
-//</1.2compat>
-
-Object.append(JSON, {
-
- $specialChars: {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'},
-
- $replaceChars: function(chr){
- return JSON.$specialChars[chr] || '\\u00' + Math.floor(chr.charCodeAt() / 16).toString(16) + (chr.charCodeAt() % 16).toString(16);
- },
-
- encode: function(obj){
- switch (typeOf(obj)){
- case 'string':
- return '"' + obj.replace(/[\x00-\x1f\\"]/g, JSON.$replaceChars) + '"';
- case 'array':
- return '[' + String(obj.map(JSON.encode).clean()) + ']';
- case 'object': case 'hash':
- var string = [];
- Object.each(obj, function(value, key){
- var json = JSON.encode(value);
- if (json) string.push(JSON.encode(key) + ':' + json);
- });
- return '{' + string + '}';
- case 'number': case 'boolean': return String(obj);
- case 'null': return 'null';
- }
- return null;
- },
-
- decode: function(string, secure){
- if (typeOf(string) != 'string' || !string.length) return null;
- if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;
- return eval('(' + string + ')');
- }
-
-});
-
-
-/*
----
-
-name: Request.JSON
-
-description: Extends the basic Request Class with additional methods for sending and receiving JSON data.
-
-license: MIT-style license.
-
-requires: [Request, JSON]
-
-provides: Request.JSON
-
-...
-*/
-
-Request.JSON = new Class({
-
- Extends: Request,
-
- options: {
- secure: true
- },
-
- initialize: function(options){
- this.parent(options);
- Object.append(this.headers, {
- 'Accept': 'application/json',
- 'X-Request': 'JSON'
- });
- },
-
- success: function(text){
- var secure = this.options.secure;
- var json = this.response.json = Function.attempt(function(){
- return JSON.decode(text, secure);
- });
-
- if (json == null) this.onFailure();
- else this.onSuccess(json, text);
- }
-
-});
-
-
-/*
----
-
-name: Cookie
-
-description: Class for creating, reading, and deleting browser Cookies.
-
-license: MIT-style license.
-
-credits:
- - Based on the functions by Peter-Paul Koch (http://quirksmode.org).
-
-requires: Options
-
-provides: Cookie
-
-...
-*/
-
-var Cookie = new Class({
-
- Implements: Options,
-
- options: {
- path: '/',
- domain: false,
- duration: false,
- secure: false,
- document: document,
- encode: true
- },
-
- initialize: function(key, options){
- this.key = key;
- this.setOptions(options);
- },
-
- write: function(value){
- if (this.options.encode) value = encodeURIComponent(value);
- if (this.options.domain) value += '; domain=' + this.options.domain;
- if (this.options.path) value += '; path=' + this.options.path;
- if (this.options.duration){
- var date = new Date();
- date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
- value += '; expires=' + date.toGMTString();
- }
- if (this.options.secure) value += '; secure';
- this.options.document.cookie = this.key + '=' + value;
- return this;
- },
-
- read: function(){
- var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.escapeRegExp() + '=([^;]*)');
- return (value) ? decodeURIComponent(value[1]) : null;
- },
-
- dispose: function(){
- new Cookie(this.key, Object.merge({}, this.options, {duration: -1})).write('');
- return this;
- }
-
-});
-
-Cookie.write = function(key, value, options){
- return new Cookie(key, options).write(value);
-};
-
-Cookie.read = function(key){
- return new Cookie(key).read();
-};
-
-Cookie.dispose = function(key, options){
- return new Cookie(key, options).dispose();
-};
-
-
-/*
----
-
-name: DOMReady
-
-description: Contains the custom event domready.
-
-license: MIT-style license.
-
-requires: [Browser, Element, Element.Event]
-
-provides: [DOMReady, DomReady]
-
-...
-*/
-
-(function(window, document){
-
-var ready,
- loaded,
- checks = [],
- shouldPoll,
- timer,
- isFramed = true;
-
-// Thanks to Rich Dougherty <http://www.richdougherty.com/>
-try {
- isFramed = window.frameElement != null;
-} catch(e){}
-
-var domready = function(){
- clearTimeout(timer);
- if (ready) return;
- Browser.loaded = ready = true;
- document.removeListener('DOMContentLoaded', domready).removeListener('readystatechange', check);
-
- document.fireEvent('domready');
- window.fireEvent('domready');
-};
-
-var check = function(){
- for (var i = checks.length; i--;) if (checks[i]()){
- domready();
- return true;
- }
-
- return false;
-};
-
-var poll = function(){
- clearTimeout(timer);
- if (!check()) timer = setTimeout(poll, 10);
-};
-
-document.addListener('DOMContentLoaded', domready);
-
-// doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/
-var testElement = document.createElement('div');
-if (testElement.doScroll && !isFramed){
- checks.push(function(){
- try {
- testElement.doScroll();
- return true;
- } catch (e){}
-
- return false;
- });
- shouldPoll = true;
-}
-
-if (document.readyState) checks.push(function(){
- var state = document.readyState;
- return (state == 'loaded' || state == 'complete');
-});
-
-if ('onreadystatechange' in document) document.addListener('readystatechange', check);
-else shouldPoll = true;
-
-if (shouldPoll) poll();
-
-Element.Events.domready = {
- onAdd: function(fn){
- if (ready) fn.call(this);
- }
-};
-
-// Make sure that domready fires before load
-Element.Events.load = {
- base: 'load',
- onAdd: function(fn){
- if (loaded && this == window) fn.call(this);
- },
- condition: function(){
- if (this == window){
- domready();
- delete Element.Events.load;
- }
-
- return true;
- }
-};
-
-// This is based on the custom load event
-window.addEvent('load', function(){
- loaded = true;
-});
-
-})(window, document);
-
-
-/*
----
-
-name: Swiff
-
-description: Wrapper for embedding SWF movies. Supports External Interface Communication.
-
-license: MIT-style license.
-
-credits:
- - Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject.
-
-requires: [Options, Object]
-
-provides: Swiff
-
-...
-*/
-
-(function(){
-
-var id = 0;
-
-var Swiff = this.Swiff = new Class({
-
- Implements: Options,
-
- options: {
- id: null,
- height: 1,
- width: 1,
- container: null,
- properties: {},
- params: {
- quality: 'high',
- allowScriptAccess: 'always',
- wMode: 'window',
- swLiveConnect: true
- },
- callBacks: {},
- vars: {}
- },
-
- toElement: function(){
- return this.object;
- },
-
- initialize: function(path, options){
- this.instance = 'Swiff_' + id++;
-
- this.setOptions(options);
- options = this.options;
- var id = this.id = options.id || this.instance;
- var container = document.id(options.container);
-
- Swiff.CallBacks[this.instance] = {};
-
- var params = options.params, vars = options.vars, callBacks = options.callBacks;
- var properties = Object.append({height: options.height, width: options.width}, options.properties);
-
- var self = this;
-
- for (var callBack in callBacks){
- Swiff.CallBacks[this.instance][callBack] = (function(option){
- return function(){
- return option.apply(self.object, arguments);
- };
- })(callBacks[callBack]);
- vars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack;
- }
-
- params.flashVars = Object.toQueryString(vars);
- if (Browser.ie){
- properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
- params.movie = path;
- } else {
- properties.type = 'application/x-shockwave-flash';
- }
- properties.data = path;
-
- var build = '<object id="' + id + '"';
- for (var property in properties) build += ' ' + property + '="' + properties[property] + '"';
- build += '>';
- for (var param in params){
- if (params[param]) build += '<param name="' + param + '" value="' + params[param] + '" />';
- }
- build += '</object>';
- this.object = ((container) ? container.empty() : new Element('div')).set('html', build).firstChild;
- },
-
- replaces: function(element){
- element = document.id(element, true);
- element.parentNode.replaceChild(this.toElement(), element);
- return this;
- },
-
- inject: function(element){
- document.id(element, true).appendChild(this.toElement());
- return this;
- },
-
- remote: function(){
- return Swiff.remote.apply(Swiff, [this.toElement()].extend(arguments));
- }
-
-});
-
-Swiff.CallBacks = {};
-
-Swiff.remote = function(obj, fn){
- var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascript">' + __flash__argumentsToXML(arguments, 2) + '</invoke>');
- return eval(rs);
-};
-
-})();
-
diff --git a/libs/yuicompressor.jar b/libs/yuicompressor.jar
deleted file mode 100644
index c29470b..0000000
--- a/libs/yuicompressor.jar
+++ /dev/null
Binary files differ
diff --git a/make b/make
deleted file mode 100755
index a619cf5..0000000
--- a/make
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-cd `dirname $0`
-
-cmd="java -jar libs/yuicompressor.jar --type js"
-file="yaml.js"
-
-> $file
-
-echo Compiling $file ...
-
-echo " - LICENSE"
-
-echo "/*" >> $file
-cat LICENSE >> $file
-echo "\n*/" >> $file
-
-echo " - YamlParseException.js"
-$cmd com/jeremyfa/yaml/YamlParseException.js >> $file
-echo " - Yaml.js"
-$cmd com/jeremyfa/yaml/Yaml.js >> $file
-echo " - YamlInline.js"
-$cmd com/jeremyfa/yaml/YamlInline.js >> $file
-echo " - YamlParser.js"
-$cmd com/jeremyfa/yaml/YamlParser.js >> $file
-echo " - YamlEscaper.js"
-$cmd com/jeremyfa/yaml/YamlEscaper.js >> $file
-echo " - YamlUnescaper.js"
-$cmd com/jeremyfa/yaml/YamlUnescaper.js >> $file
-echo " - YamlDumper.js"
-$cmd com/jeremyfa/yaml/YamlDumper.js >> $file
-
-echo $file compiled.
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..d2766ec
--- /dev/null
+++ b/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "yamljs",
+ "version": "0.1.0",
+ "description": "Standalone JavaScript YAML 1.2 Parser & Encoder. Mainly inspired from Yaml Component (part of the php framework Symfony).",
+ "keywords": [
+ "yaml"
+ ],
+ "author": "Jeremy Faivre <contact@jeremyfa.com>",
+ "main": "./bin/yaml.js",
+ "dependencies": {
+ },
+ "devDependencies": {
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/jeremyfa/yaml.js.git"
+ }
+}
diff --git a/com/jeremyfa/yaml/Yaml.js b/src/Yaml.js
index 0c5c11b..84d27d9 100644
--- a/com/jeremyfa/yaml/Yaml.js
+++ b/src/Yaml.js
@@ -5,7 +5,8 @@
*
* @api
*/
-
+
+var isNode = false;
var Yaml = function(){};
Yaml.prototype =
{
@@ -29,7 +30,7 @@ Yaml.prototype =
*/
parseFile: function(file /* String */, callback /* Function */)
{
- if ( callback == undefined )
+ if ( callback == null )
{
var input = this.getFileContents(file);
var ret = null;
@@ -92,7 +93,7 @@ Yaml.prototype =
*/
dump: function(array, inline)
{
- if ( inline == undefined ) inline = 2;
+ if ( inline == null ) inline = 2;
var yaml = new YamlDumper();
@@ -124,31 +125,54 @@ Yaml.prototype =
getFileContents: function(file, callback)
{
- var request = this.getXHR();
+ if ( isNode )
+ {
+ var fs = require('fs');
+ if ( callback == null )
+ {
+ var data = fs.readFileSync(file);
+ if (data == null) return null;
+ return ''+data;
+ }
+ else
+ {
+ fs.readFile(file, function(err, data)
+ {
+ if (err)
+ callback(null);
+ else
+ callback(data);
+ });
+ }
+ }
+ else
+ {
+ var request = this.getXHR();
- // Sync
- if ( callback == undefined )
- {
- request.open('GET', file, false);
- request.send(null);
+ // Sync
+ if ( callback == null )
+ {
+ request.open('GET', file, false);
+ request.send(null);
- if ( request.status == 200 || request.status == 0 )
- return request.responseText;
+ if ( request.status == 200 || request.status == 0 )
+ return request.responseText;
- return null;
- }
+ return null;
+ }
- // Async
- request.onreadystatechange = function()
- {
- if ( request.readyState == 4 )
- if ( request.status == 200 || request.status == 0 )
- callback(request.responseText);
- else
- callback(null);
- };
- request.open('GET', file, true);
- request.send(null);
+ // Async
+ request.onreadystatechange = function()
+ {
+ if ( request.readyState == 4 )
+ if ( request.status == 200 || request.status == 0 )
+ callback(request.responseText);
+ else
+ callback(null);
+ };
+ request.open('GET', file, true);
+ request.send(null);
+ }
}
};
@@ -158,12 +182,12 @@ var YAML =
* @param integer inline The level where you switch to inline YAML
*/
- encode: function(input, inline)
+ stringify: function(input, inline)
{
return new Yaml().dump(input, inline);
},
- decode: function(input)
+ parse: function(input)
{
return new Yaml().parse(input);
},
@@ -173,3 +197,26 @@ var YAML =
return new Yaml().parseFile(file, callback);
}
};
+
+// Handle node.js case
+if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = YAML;
+ isNode = true;
+
+ // Add require handler
+ (function () {
+ var require_handler = function (module, filename) {
+ // fill in result
+ module.exports = YAML.load(filename);
+ };
+
+ // register require extensions only if we're on node.js
+ // hack for browserify
+ if ( undefined !== require.extensions ) {
+ require.extensions['.yml'] = require_handler;
+ require.extensions['.yaml'] = require_handler;
+ }
+ }());
+ }
+}
diff --git a/com/jeremyfa/yaml/YamlDumper.js b/src/YamlDumper.js
index ffc4e7d..ffc4e7d 100644
--- a/com/jeremyfa/yaml/YamlDumper.js
+++ b/src/YamlDumper.js
diff --git a/com/jeremyfa/yaml/YamlEscaper.js b/src/YamlEscaper.js
index 8714c51..8714c51 100644
--- a/com/jeremyfa/yaml/YamlEscaper.js
+++ b/src/YamlEscaper.js
diff --git a/com/jeremyfa/yaml/YamlInline.js b/src/YamlInline.js
index a024385..a024385 100644
--- a/com/jeremyfa/yaml/YamlInline.js
+++ b/src/YamlInline.js
diff --git a/com/jeremyfa/yaml/YamlParseException.js b/src/YamlParseException.js
index 04fddf3..04fddf3 100644
--- a/com/jeremyfa/yaml/YamlParseException.js
+++ b/src/YamlParseException.js
diff --git a/com/jeremyfa/yaml/YamlParser.js b/src/YamlParser.js
index 3346b48..3346b48 100644
--- a/com/jeremyfa/yaml/YamlParser.js
+++ b/src/YamlParser.js
diff --git a/com/jeremyfa/yaml/YamlUnescaper.js b/src/YamlUnescaper.js
index ea4a2c6..ea4a2c6 100644
--- a/com/jeremyfa/yaml/YamlUnescaper.js
+++ b/src/YamlUnescaper.js
diff --git a/libs/jasmine-1.2.0/MIT.LICENSE b/test/libs/jasmine-1.2.0/MIT.LICENSE
index 7c435ba..7c435ba 100644
--- a/libs/jasmine-1.2.0/MIT.LICENSE
+++ b/test/libs/jasmine-1.2.0/MIT.LICENSE
diff --git a/libs/jasmine-1.2.0/YamlSpec.js b/test/libs/jasmine-1.2.0/YamlSpec.js
index 7f924f1..f3b9f79 100644
--- a/libs/jasmine-1.2.0/YamlSpec.js
+++ b/test/libs/jasmine-1.2.0/YamlSpec.js
@@ -5,7 +5,7 @@ describe("YAML parsing", function() {
t = YAML.parseTests[i];
it(t.title, function() {
- expect(YAML.decode(t.input)).toEqual(t.output);
+ expect(YAML.parse(t.input)).toEqual(t.output);
});
}
});
@@ -16,7 +16,7 @@ describe("YAML dumping and parsing", function() {
t = YAML.parseTests[i];
it(t.title, function() {
- expect(YAML.decode(YAML.encode(t.output))).toEqual(t.output);
+ expect(YAML.parse(YAML.stringify(t.output))).toEqual(t.output);
});
}
}); \ No newline at end of file
diff --git a/libs/jasmine-1.2.0/YamlTests.js b/test/libs/jasmine-1.2.0/YamlTests.js
index fa3aa14..fa3aa14 100644
--- a/libs/jasmine-1.2.0/YamlTests.js
+++ b/test/libs/jasmine-1.2.0/YamlTests.js
diff --git a/libs/jasmine-1.2.0/jasmine-html.js b/test/libs/jasmine-1.2.0/jasmine-html.js
index a0b0639..a0b0639 100644
--- a/libs/jasmine-1.2.0/jasmine-html.js
+++ b/test/libs/jasmine-1.2.0/jasmine-html.js
diff --git a/libs/jasmine-1.2.0/jasmine.css b/test/libs/jasmine-1.2.0/jasmine.css
index 826e575..826e575 100644
--- a/libs/jasmine-1.2.0/jasmine.css
+++ b/test/libs/jasmine-1.2.0/jasmine.css
diff --git a/libs/jasmine-1.2.0/jasmine.js b/test/libs/jasmine-1.2.0/jasmine.js
index 03bf89a..03bf89a 100644
--- a/libs/jasmine-1.2.0/jasmine.js
+++ b/test/libs/jasmine-1.2.0/jasmine.js
diff --git a/tests.html b/test/test.html
index ed59766..a0381e8 100644
--- a/tests.html
+++ b/test/test.html
@@ -10,7 +10,7 @@
<script type="text/javascript" src="libs/jasmine-1.2.0/jasmine-html.js"></script>
<!-- include source files here... -->
- <script type="text/javascript" src="yaml.js"></script>
+ <script type="text/javascript" src="../bin/yaml.js"></script>
<script type="text/javascript" src="libs/jasmine-1.2.0/YamlTests.js"></script>
<!-- include spec files here... -->
<script type="text/javascript" src="libs/jasmine-1.2.0/YamlSpec.js"></script>
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000..7b97d6c
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,5 @@
+
+require('../bin/yaml.js');
+
+// Just testing that yaml parsing is also working through node.js
+console.log(require('./test.yml'));
diff --git a/test/test.yml b/test/test.yml
new file mode 100644
index 0000000..2db4b78
--- /dev/null
+++ b/test/test.yml
@@ -0,0 +1,29 @@
+--- !clarkevans.com/^invoice
+invoice: 34843
+date : 2001-01-23
+bill-to: &id001
+ given : Chris
+ family : Dumars
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+ city : Royal Oak
+ state : MI
+ postal : 48046
+ship-to: *id001
+product:
+ - sku : "BL394D"
+ quantity : 4
+ description : Basketball
+ price : 450.00
+ - sku : BL4438H
+ quantity : 1
+ description : Super Hoop
+ price : 2392.00
+tax : 251.42
+total: 4443.52
+comments: >
+ Late afternoon is best.
+ Backup contact is Nancy
+ Billsmer @ 338-4338.
diff --git a/yaml.js b/yaml.js
deleted file mode 100644
index 924e888..0000000
--- a/yaml.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-Copyright (c) 2010 Jeremy Faivre
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is furnished
-to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-var YamlParseException=function(d,a,c,b){this.rawMessage=d;this.parsedLine=(a!==undefined)?a:-1;this.snippet=(c!==undefined)?c:null;this.parsedFile=(b!==undefined)?b:null;this.updateRepr();this.message=d};YamlParseException.prototype={name:"YamlParseException",message:null,parsedFile:null,parsedLine:-1,snippet:null,rawMessage:null,isDefined:function(a){return a!=undefined&&a!=null},getSnippet:function(){return this.snippet},setSnippet:function(a){this.snippet=a;this.updateRepr()},getParsedFile:function(){return this.parsedFile},setParsedFile:function(a){this.parsedFile=a;this.updateRepr()},getParsedLine:function(){return this.parsedLine},setParsedLine:function(a){this.parsedLine=a;this.updateRepr()},updateRepr:function(){this.message=this.rawMessage;dot=false;if("."===this.message.charAt(this.message.length-1)){this.message=this.message.substring(0,this.message.length-1);dot=true}if(null!==this.parsedFile){this.message+=" in "+JSON.stringify(this.parsedFile)}if(this.parsedLine>=0){this.message+=" at line "+this.parsedLine}if(this.snippet){this.message+=' (near "'+this.snippet+'")'}if(dot){this.message+="."}}};var Yaml=function(){};Yaml.prototype={parseFile:function(c,f){if(f==undefined){var a=this.getFileContents(c);var b=null;try{b=this.parse(a)}catch(d){if(d instanceof YamlParseException){d.setParsedFile(c)}throw d}return b}this.getFileContents(c,function(e){f(new Yaml().parse(e))})},parse:function(a){var b=new YamlParser();return b.parse(a)},dump:function(c,b){if(b==undefined){b=2}var a=new YamlDumper();return a.dump(c,b)},getXHR:function(){if(window.XMLHttpRequest){return new XMLHttpRequest()}if(window.ActiveXObject){var c=["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];for(var a=0;a<4;a++){try{return new ActiveXObject(c[a])}catch(b){}}}return null},getFileContents:function(a,c){var b=this.getXHR();if(c==undefined){b.open("GET",a,false);b.send(null);if(b.status==200||b.status==0){return b.responseText}return null}b.onreadystatechange=function(){if(b.readyState==4){if(b.status==200||b.status==0){c(b.responseText)}else{c(null)}}};b.open("GET",a,true);b.send(null)}};var YAML={encode:function(a,b){return new Yaml().dump(a,b)},decode:function(a){return new Yaml().parse(a)},load:function(a,b){return new Yaml().parseFile(a,b)}};var YamlInline=function(){};YamlInline.prototype={i:null,parse:function(b){var a=null;b=this.trim(b);if(0==b.length){return""}switch(b.charAt(0)){case"[":a=this.parseSequence(b);break;case"{":a=this.parseMapping(b);break;default:a=this.parseScalar(b);if(b.substr(this.i).replace(/^\s+#.*$/,"")){throw new YamlParseException('Unexpected characters near "'+b.substr(this.i)+'".')}}return a},dump:function(b){if(undefined==b||null==b){return"null"}if(b instanceof Date){return b.toISOString()}if(typeof(b)=="object"){return this.dumpObject(b)}if(typeof(b)=="boolean"){return b?"true":"false"}if(/^\d+$/.test(b)){return typeof(b)=="string"?"'"+b+"'":parseInt(b)}if(this.isNumeric(b)){return typeof(b)=="string"?"'"+b+"'":parseFloat(b)}if(typeof(b)=="number"){return b==Infinity?".Inf":(b==-Infinity?"-.Inf":(isNaN(b)?".NAN":b))}var a=new YamlEscaper();if(a.requiresDoubleQuoting(b)){return a.escapeWithDoubleQuotes(b)}if(a.requiresSingleQuoting(b)){return a.escapeWithSingleQuotes(b)}if(""==b){return""}if(this.getTimestampRegex().test(b)){return"'"+b+"'"}if(this.inArray(b.toLowerCase(),["null","~","true","false"])){return"'"+b+"'"}return b},dumpObject:function(e){var d=this.getKeys(e);var b=null;var c;var a=d.length;if(e instanceof Array){b=[];for(c=0;c<a;c++){b.push(this.dump(e[d[c]]))}return"["+b.join(", ")+"]"}b=[];for(c=0;c<a;c++){b.push(this.dump(d[c])+": "+this.dump(e[d[c]]))}return"{ "+b.join(", ")+" }"},parseScalar:function(a,h,j,e,b){if(h==undefined){h=null}if(j==undefined){j=['"',"'"]}if(e==undefined){e=0}if(b==undefined){b=true}var c=null;var g=null;var f=null;if(this.inArray(a[e],j)){c=this.parseQuotedScalar(a,e);e=this.i;if(null!==h){var d=a.substr(e).replace(/^\s+/,"");if(!this.inArray(d.charAt(0),h)){throw new YamlParseException("Unexpected characters ("+a.substr(e)+").")}}}else{if(!h){c=(a+"").substring(e);e+=c.length;g=c.indexOf(" #");if(g!=-1){c=c.substr(0,g).replace(/\s+$/g,"")}}else{if(f=new RegExp("^(.+?)("+h.join("|")+")").exec((a+"").substring(e))){c=f[1];e+=c.length}else{throw new YamlParseException("Malformed inline YAML string ("+a+").")}}c=b?this.evaluateScalar(c):c}this.i=e;return c},parseQuotedScalar:function(b,c){var e=null;if(!(e=new RegExp("^"+YamlInline.REGEX_QUOTED_STRING).exec((b+"").substring(c)))){throw new YamlParseException("Malformed inline YAML string ("+(b+"").substring(c)+").")}var a=e[0].substr(1,e[0].length-2);var d=new YamlUnescaper();if('"'==(b+"").charAt(c)){a=d.unescapeDoubleQuotedString(a)}else{a=d.unescapeSingleQuotedString(a)}c+=e[0].length;this.i=c;return a},parseSequence:function(g,c){if(c==undefined){c=0}var b=[];var a=g.length;c+=1;while(c<a){switch(g.charAt(c)){case"[":b.push(this.parseSequence(g,c));c=this.i;break;case"{":b.push(this.parseMapping(g,c));c=this.i;break;case"]":this.i=c;return b;case",":case" ":break;default:isQuoted=this.inArray(g.charAt(c),['"',"'"]);var d=this.parseScalar(g,[",","]"],['"',"'"],c);c=this.i;if(!isQuoted&&(d+"").indexOf(": ")!=-1){try{d=this.parseMapping("{"+d+"}")}catch(f){if(!(f instanceof YamlParseException)){throw f}}}b.push(d);c--}c++}throw new YamlParseException('Malformed inline YAML string "'+g+'"')},parseMapping:function(d,f){if(f==undefined){f=0}var c={};var a=d.length;f+=1;var b=false;var g=false;while(f<a){g=false;switch(d.charAt(f)){case" ":case",":f++;g=true;break;case"}":this.i=f;return c}if(g){continue}var e=this.parseScalar(d,[":"," "],['"',"'"],f,false);f=this.i;b=false;while(f<a){switch(d.charAt(f)){case"[":c[e]=this.parseSequence(d,f);f=this.i;b=true;break;case"{":c[e]=this.parseMapping(d,f);f=this.i;b=true;break;case":":case" ":break;default:c[e]=this.parseScalar(d,[",","}"],['"',"'"],f);f=this.i;b=true;f--}++f;if(b){g=true;break}}if(g){continue}}throw new YamlParseException('Malformed inline YAML string "'+d+'"')},evaluateScalar:function(b){b=this.trim(b);var c=null;var a=null;if(("null"==b.toLowerCase())||(""==b)||("~"==b)){return null}if((b+"").indexOf("!str ")==0){return(""+b).substring(5)}if((b+"").indexOf("! ")==0){return parseInt(this.parseScalar((b+"").substr(2)))}if(/^\d+$/.test(b)){c=b;a=parseInt(b);return"0"==b.charAt(0)?this.octdec(b):((""+c==""+a)?a:c)}if("true"==(b+"").toLowerCase()){return true}if("false"==(b+"").toLowerCase()){return false}if(this.isNumeric(b)){return"0x"==(b+"").substr(0,2)?this.hexdec(b):parseFloat(b)}if(b.toLowerCase()==".inf"){return Infinity}if(b.toLowerCase()==".nan"){return NaN}if(b.toLowerCase()=="-.inf"){return -Infinity}if(/^(-|\+)?[0-9,]+(\.[0-9]+)?$/.test(b)){return parseFloat(b.split(",").join(""))}if(this.getTimestampRegex().test(b)){return new Date(this.strtotime(b))}return""+b},getTimestampRegex:function(){return new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:.([0-9]*))?(?:[ \t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?)?$","gi")},trim:function(a){return(a+"").replace(/^\s+/,"").replace(/\s+$/,"")},isNumeric:function(a){return(a-0)==a&&a.length>0&&a.replace(/\s+/g,"")!=""},inArray:function(c,d){var b;var a=d.length;for(b=0;b<a;b++){if(c==d[b]){return true}}return false},getKeys:function(c){var b=[];for(var a in c){if(c.hasOwnProperty(a)){b.push(a)}}return b},octdec:function(a){return parseInt((a+"").replace(/[^0-7]/gi,""),8)},hexdec:function(a){a=this.trim(a);if((a+"").substr(0,2)=="0x"){a=(a+"").substring(2)}return parseInt((a+"").replace(/[^a-f0-9]/gi,""),16)},strtotime:function(m,s){var o,r,n,i,q="";m=(m+"").replace(/\s{2,}|^\s|\s$/g," ").replace(/[\t\r\n]/g,"");if(m==="now"){return s===null||isNaN(s)?new Date().getTime()||0:s||0}else{if(!isNaN(q=Date.parse(m))){return q||0}else{if(s){s=new Date(s)}else{s=new Date()}}}m=m.toLowerCase();var p={day:{sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6},mon:["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]};var t=function(b){var d=(b[2]&&b[2]==="ago");var e=(e=b[0]==="last"?-1:1)*(d?-1:1);switch(b[0]){case"last":case"next":switch(b[1].substring(0,3)){case"yea":s.setFullYear(s.getFullYear()+e);break;case"wee":s.setDate(s.getDate()+(e*7));break;case"day":s.setDate(s.getDate()+e);break;case"hou":s.setHours(s.getHours()+e);break;case"min":s.setMinutes(s.getMinutes()+e);break;case"sec":s.setSeconds(s.getSeconds()+e);break;case"mon":if(b[1]==="month"){s.setMonth(s.getMonth()+e);break}default:var a=p.day[b[1].substring(0,3)];if(typeof a!=="undefined"){var c=a-s.getDay();if(c===0){c=7*e}else{if(c>0){if(b[0]==="last"){c-=7}}else{if(b[0]==="next"){c+=7}}}s.setDate(s.getDate()+c);s.setHours(0,0,0,0)}}break;default:if(/\d+/.test(b[0])){e*=parseInt(b[0],10);switch(b[1].substring(0,3)){case"yea":s.setFullYear(s.getFullYear()+e);break;case"mon":s.setMonth(s.getMonth()+e);break;case"wee":s.setDate(s.getDate()+(e*7));break;case"day":s.setDate(s.getDate()+e);break;case"hou":s.setHours(s.getHours()+e);break;case"min":s.setMinutes(s.getMinutes()+e);break;case"sec":s.setSeconds(s.getSeconds()+e);break}}else{return false}break}return true};n=m.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);if(n!==null){if(!n[2]){n[2]="00:00:00"}else{if(!n[3]){n[2]+=":00"}}i=n[1].split(/-/g);i[1]=p.mon[i[1]-1]||i[1];i[0]=+i[0];i[0]=(i[0]>=0&&i[0]<=69)?"20"+(i[0]<10?"0"+i[0]:i[0]+""):(i[0]>=70&&i[0]<=99)?"19"+i[0]:i[0]+"";return parseInt(this.strtotime(i[2]+" "+i[1]+" "+i[0]+" "+n[2])+(n[4]?n[4]:""),10)}var l="([+-]?\\d+\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)|(last|next)\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))(\\sago)?";n=m.match(new RegExp(l,"gi"));if(n===null){return false}for(o=0,r=n.length;o<r;o++){if(!t(n[o].split(" "))){return false}}return s.getTime()||0}};YamlInline.REGEX_QUOTED_STRING="(?:\"(?:[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|'(?:[^']*(?:''[^']*)*)')";var YamlParser=function(a){this.offset=(a!==undefined)?a:0};YamlParser.prototype={offset:0,lines:[],currentLineNb:-1,currentLine:"",refs:{},parse:function(o){this.currentLineNb=-1;this.currentLine="";this.lines=this.cleanup(o).split("\n");var x=null;var d=null;while(this.moveToNextLine()){if(this.isCurrentLineEmpty()){continue}if(this.currentLine.charAt(0)=="\t"){throw new YamlParseException("A YAML file cannot contain tabs as indentation.",this.getRealCurrentLineNb()+1,this.currentLine)}var m=false;var u=false;var t=false;var b=null;var a=null;var w=null;var f=null;var g=null;var y=null;var l=null;var r=null;var h=null;if(b=/^\-((\s+)(.+?))?\s*$/.exec(this.currentLine)){if(d&&"mapping"==d){throw new YamlParseException("You cannot define a sequence item when in a mapping",this.getRealCurrentLineNb()+1,this.currentLine)}d="sequence";if(!this.isDefined(x)){x=[]}b={leadspaces:b[2],value:b[3]};if(this.isDefined(b.value)&&(a=/^&([^ ]+) *(.*)/.exec(b.value))){a={ref:a[1],value:a[2]};m=a.ref;b.value=a.value}if(!this.isDefined(b.value)||""==this.trim(b.value)||b.value.replace(/^ +/,"").charAt(0)=="#"){w=this.getRealCurrentLineNb()+1;f=new YamlParser(w);f.refs=this.refs;x.push(f.parse(this.getNextEmbedBlock()));this.refs=f.refs}else{if(this.isDefined(b.leadspaces)&&" "==b.leadspaces&&(a=new RegExp("^("+YamlInline.REGEX_QUOTED_STRING+"|[^ '\"{[].*?) *:(\\s+(.+?))?\\s*$").exec(b.value))){a={key:a[1],value:a[3]};w=this.getRealCurrentLineNb();f=new YamlParser(w);f.refs=this.refs;g=b.value;if(!this.isNextLineIndented()){g+="\n"+this.getNextEmbedBlock(this.getCurrentLineIndentation()+2)}x.push(f.parse(g));this.refs=f.refs}else{x.push(this.parseValue(b.value))}}}else{if(b=new RegExp("^("+YamlInline.REGEX_QUOTED_STRING+"|[^ '\"[{].*?) *:(\\s+(.+?))?\\s*$").exec(this.currentLine)){if(!this.isDefined(x)){x={}}if(d&&"sequence"==d){throw new YamlParseException("You cannot define a mapping item when in a sequence",this.getRealCurrentLineNb()+1,this.currentLine)}d="mapping";b={key:b[1],value:b[3]};try{y=new YamlInline().parseScalar(b.key)}catch(s){if(s instanceof YamlParseException){s.setParsedLine(this.getRealCurrentLineNb()+1);s.setSnippet(this.currentLine)}throw s}if("<<"==y){if(this.isDefined(b.value)&&"*"==(b.value+"").charAt(0)){u=b.value.substr(1);if(this.refs[u]==undefined){throw new YamlParseException('Reference "'+o+'" does not exist',this.getRealCurrentLineNb()+1,this.currentLine)}}else{if(this.isDefined(b.value)&&b.value!=""){o=b.value}else{o=this.getNextEmbedBlock()}w=this.getRealCurrentLineNb()+1;f=new YamlParser(w);f.refs=this.refs;l=f.parse(o);this.refs=f.refs;var v=[];if(!this.isObject(l)){throw new YamlParseException("YAML merge keys used with a scalar value instead of an array",this.getRealCurrentLineNb()+1,this.currentLine)}else{if(this.isDefined(l[0])){h=this.reverseArray(l);r=h.length;for(var q=0;q<r;q++){var n=h[q];if(!this.isObject(h[q])){throw new YamlParseException("Merge items must be arrays",this.getRealCurrentLineNb()+1,this.currentLine)}v=this.mergeObject(h[q],v)}}else{v=this.mergeObject(v,l)}}t=v}}else{if(this.isDefined(b.value)&&(a=/^&([^ ]+) *(.*)/.exec(b.value))){a={ref:a[1],value:a[2]};m=a.ref;b.value=a.value}}if(t){x=t}else{if(!this.isDefined(b.value)||""==this.trim(b.value)||this.trim(b.value).charAt(0)=="#"){if(this.isNextLineIndented()&&!this.isNextLineUnIndentedCollection()){x[y]=null}else{w=this.getRealCurrentLineNb()+1;f=new YamlParser(w);f.refs=this.refs;x[y]=f.parse(this.getNextEmbedBlock());this.refs=f.refs}}else{if(u){x=this.refs[u]}else{x[y]=this.parseValue(b.value)}}}}else{if(2==this.lines.length&&this.isEmpty(this.lines[1])){try{o=new YamlInline().parse(this.lines[0])}catch(s){if(s instanceof YamlParseException){s.setParsedLine(this.getRealCurrentLineNb()+1);s.setSnippet(this.currentLine)}throw s}if(this.isObject(o)){first=o[0];if(typeof(o)=="string"&&"*"==first.charAt(0)){x=[];r=o.length;for(var q=0;q<r;q++){x.push(this.refs[o[q].substr(1)])}o=x}}return o}throw new YamlParseException("Unable to parse.",this.getRealCurrentLineNb()+1,this.currentLine)}}if(m){if(x instanceof Array){this.refs[m]=x[x.length-1]}else{var j=null;for(var p in x){if(x.hasOwnProperty(p)){j=p}}this.refs[m]=x[p]}}}return this.isEmpty(x)?null:x},getRealCurrentLineNb:function(){return this.currentLineNb+this.offset},getCurrentLineIndentation:function(){return this.currentLine.length-this.currentLine.replace(/^ +/g,"").length},getNextEmbedBlock:function(c){this.moveToNextLine();var b=null;var a=null;if(!this.isDefined(c)){b=this.getCurrentLineIndentation();var g=this.isStringUnIndentedCollectionItem(this.currentLine);if(!this.isCurrentLineEmpty()&&0==b&&!g){throw new YamlParseException("Indentation problem A",this.getRealCurrentLineNb()+1,this.currentLine)}}else{b=c}var f=[this.currentLine.substr(b)];var d=this.isStringUnIndentedCollectionItem(this.currentLine);while(this.moveToNextLine()){if(d&&!this.isStringUnIndentedCollectionItem(this.currentLine)){this.moveToPreviousLine();break}if(this.isCurrentLineEmpty()){if(this.isCurrentLineBlank()){f.push(this.currentLine.substr(b))}continue}a=this.getCurrentLineIndentation();var e;if(e=/^( *)$/.exec(this.currentLine)){f.push(e[1])}else{if(a>=b){f.push(this.currentLine.substr(b))}else{if(0==a){this.moveToPreviousLine();break}else{throw new YamlParseException("Indentation problem B",this.getRealCurrentLineNb()+1,this.currentLine)}}}}return f.join("\n")},moveToNextLine:function(){if(this.currentLineNb>=this.lines.length-1){return false}this.currentLineNb++;this.currentLine=this.lines[this.currentLineNb];return true},moveToPreviousLine:function(){this.currentLineNb--;this.currentLine=this.lines[this.currentLineNb]},parseValue:function(c){if("*"==(c+"").charAt(0)){if(this.trim(c).charAt(0)=="#"){c=(c+"").substr(1,c.indexOf("#")-2)}else{c=(c+"").substr(1)}if(this.refs[c]==undefined){throw new YamlParseException('Reference "'+c+'" does not exist',this.getRealCurrentLineNb()+1,this.currentLine)}return this.refs[c]}var b=null;if(b=/^(\||>)(\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?( +#.*)?$/.exec(c)){b={separator:b[1],modifiers:b[2],comments:b[3]};var a=this.isDefined(b.modifiers)?b.modifiers:"";return this.parseFoldedScalar(b.separator,a.replace(/\d+/g,""),Math.abs(parseInt(a)))}try{return new YamlInline().parse(c)}catch(d){if(d instanceof YamlParseException){d.setParsedLine(this.getRealCurrentLineNb()+1);d.setSnippet(this.currentLine)}throw d}},parseFoldedScalar:function(c,h,f){if(h==undefined){h=""}if(f==undefined){f=0}c="|"==c?"\n":" ";var i="";var g=null;var b=this.moveToNextLine();while(b&&this.isCurrentLineBlank()){i+="\n";b=this.moveToNextLine()}if(!b){return""}var d=null;if(!(d=new RegExp("^("+(f?this.strRepeat(" ",f):" +")+")(.*)$").exec(this.currentLine))){this.moveToPreviousLine();return""}d={indent:d[1],text:d[2]};var a=d.indent;var e=0;i+=d.text+c;while(this.currentLineNb+1<this.lines.length){this.moveToNextLine();if(d=new RegExp("^( {"+a.length+",})(.+)$").exec(this.currentLine)){d={indent:d[1],text:d[2]};if(" "==c&&e!=d.indent){i=i.substr(0,i.length-1)+"\n"}e=d.indent;g=d.indent.length-a.length;i+=this.strRepeat(" ",g)+d.text+(g!=0?"\n":c)}else{if(d=/^( *)$/.exec(this.currentLine)){i+=d[1].replace(new RegExp("^ {1,"+a.length+"}","g"),"")+"\n"}else{this.moveToPreviousLine();break}}}if(" "==c){i=i.replace(/ (\n*)$/g,"\n$1")}switch(h){case"":i=i.replace(/\n+$/g,"\n");break;case"+":break;case"-":i=i.replace(/\n+$/g,"");break}return i},isNextLineIndented:function(){var b=this.getCurrentLineIndentation();var c=this.moveToNextLine();while(c&&this.isCurrentLineEmpty()){c=this.moveToNextLine()}if(false==c){return false}var a=false;if(this.getCurrentLineIndentation()<=b){a=true}this.moveToPreviousLine();return a},isCurrentLineEmpty:function(){return this.isCurrentLineBlank()||this.isCurrentLineComment()},isCurrentLineBlank:function(){return""==this.trim(this.currentLine)},isCurrentLineComment:function(){var a=this.currentLine.replace(/^ +/g,"");return a.charAt(0)=="#"},cleanup:function(d){d=d.split("\r\n").join("\n").split("\r").join("\n");if(!/\n$/.test(d)){d+="\n"}var c=0;var b=/^\%YAML[: ][\d\.]+.*\n/;while(b.test(d)){d=d.replace(b,"");c++}this.offset+=c;b=/^(#.*?\n)+/;if(b.test(d)){var a=d.replace(b,"");this.offset+=this.subStrCount(d,"\n")-this.subStrCount(a,"\n");d=a}b=/^\-\-\-.*?\n/;if(b.test(d)){a=d.replace(b,"");this.offset+=this.subStrCount(d,"\n")-this.subStrCount(a,"\n");d=a;d=d.replace(/\.\.\.\s*$/g,"")}return d},isNextLineUnIndentedCollection:function(){var b=this.getCurrentLineIndentation();var c=this.moveToNextLine();while(c&&this.isCurrentLineEmpty()){c=this.moveToNextLine()}if(false===c){return false}var a=false;if(this.getCurrentLineIndentation()==b&&this.isStringUnIndentedCollectionItem(this.currentLine)){a=true}this.moveToPreviousLine();return a},isStringUnIndentedCollectionItem:function(a){return(0===this.currentLine.indexOf("- "))},isObject:function(a){return typeof(a)=="object"&&this.isDefined(a)},isEmpty:function(a){return a==undefined||a==null||a==""||a==0||a=="0"||a==false},isDefined:function(a){return a!=undefined&&a!=null},reverseArray:function(c){var b=[];var a=c.length;for(var d=a-1;d>=0;d--){b.push(c[d])}return b},merge:function(e,d){var g={};var f;for(f in e){if(e.hasOwnProperty(f)){if(/^\d+$/.test(f)){g.push(e)}else{g[f]=e[f]}}}for(f in d){if(d.hasOwnProperty(f)){if(/^\d+$/.test(f)){g.push(d)}else{g[f]=d[f]}}}return g},strRepeat:function(d,c){var b;var a="";for(b=0;b<c;b++){a+=d}return a},subStrCount:function(d,b,j,f){var h=0;d=""+d;b=""+b;if(j!=undefined){d=d.substr(j)}if(f!=undefined){d=d.substr(0,f)}var a=d.length;var g=b.length;for(var e=0;e<a;e++){if(b==d.substr(e,g)){h++}e+=g-1}return h},trim:function(a){return(a+"").replace(/^ +/,"").replace(/ +$/,"")}};YamlEscaper=function(){};YamlEscaper.prototype={requiresDoubleQuoting:function(a){return new RegExp(YamlEscaper.REGEX_CHARACTER_TO_ESCAPE).test(a)},escapeWithDoubleQuotes:function(f){f=f+"";var a=YamlEscaper.escapees.length;var e=YamlEscaper.escaped.length;var b=YamlEscaper.escaped;for(var d=0;d<a;++d){if(d>=e){b.push("")}}var c="";c=f.replace(new RegExp(YamlEscaper.escapees.join("|"),"g"),function(h){for(var g=0;g<a;++g){if(h==YamlEscaper.escapees[g]){return b[g]}}});return'"'+c+'"'},requiresSingleQuoting:function(a){return/[\s'":{}[\],&*#?]|^[-?|<>=!%@`]/.test(a)},escapeWithSingleQuotes:function(a){return"'"+a.replace(/'/g,"''")+"'"}};YamlEscaper.REGEX_CHARACTER_TO_ESCAPE="[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";YamlEscaper.escapees=["\\\\",'\\"','"',"\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07","\x08","\x09","\x0a","\x0b","\x0c","\x0d","\x0e","\x0f","\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17","\x18","\x19","\x1a","\x1b","\x1c","\x1d","\x1e","\x1f","\xc2\x85","\xc2\xa0","\xe2\x80\xa8","\xe2\x80\xa9"];YamlEscaper.escaped=['\\"',"\\\\",'\\"',"\\0","\\x01","\\x02","\\x03","\\x04","\\x05","\\x06","\\a","\\b","\\t","\\n","\\v","\\f","\\r","\\x0e","\\x0f","\\x10","\\x11","\\x12","\\x13","\\x14","\\x15","\\x16","\\x17","\\x18","\\x19","\\x1a","\\e","\\x1c","\\x1d","\\x1e","\\x1f","\\N","\\_","\\L","\\P"];var YamlUnescaper=function(){};YamlUnescaper.prototype={unescapeSingleQuotedString:function(a){return a.replace(/''/g,"'")},unescapeDoubleQuotedString:function(a){var b=function(c){return new YamlUnescaper().unescapeCharacter(c)};return a.replace(new RegExp(YamlUnescaper.REGEX_ESCAPED_CHARACTER,"g"),b)},unescapeCharacter:function(a){switch(a.charAt(1)){case"0":return String.fromCharCode(0);case"a":return String.fromCharCode(7);case"b":return String.fromCharCode(8);case"t":return"\t";case"\t":return"\t";case"n":return"\n";case"v":return String.fromCharCode(11);case"f":return String.fromCharCode(12);case"r":return String.fromCharCode(13);case"e":return"\x1b";case" ":return" ";case'"':return'"';case"/":return"/";case"\\":return"\\";case"N":return"\x00\x85";case"_":return"\x00\xA0";case"L":return"\x20\x28";case"P":return"\x20\x29";case"x":return this.pack("n",new YamlInline().hexdec(a.substr(2,2)));case"u":return this.pack("n",new YamlInline().hexdec(a.substr(2,4)));case"U":return this.pack("N",new YamlInline().hexdec(a.substr(2,8)))}},pack:function(U){var ab=0,X=1,Y="",Z="",i=0,W=[],P,R,S,k,aa,af;var ae,ag,n,J,N,ad,V,T,Q,O,r,ah,L,M,j,K,ac;while(ab<U.length){P=U.charAt(ab);R="";ab++;while((ab<U.length)&&(U.charAt(ab).match(/[\d\*]/)!==null)){R+=U.charAt(ab);ab++}if(R===""){R="1"}switch(P){case"n":if(R==="*"){R=arguments.length-X}if(R>(arguments.length-X)){throw new Error("Warning: pack() Type "+P+": too few arguments")}for(i=0;i<R;i++){Y+=String.fromCharCode(arguments[X]>>8&255);Y+=String.fromCharCode(arguments[X]&255);X++}break;case"N":if(R==="*"){R=arguments.length-X}if(R>(arguments.length-X)){throw new Error("Warning: pack() Type "+P+": too few arguments")}for(i=0;i<R;i++){Y+=String.fromCharCode(arguments[X]>>24&255);Y+=String.fromCharCode(arguments[X]>>16&255);Y+=String.fromCharCode(arguments[X]>>8&255);Y+=String.fromCharCode(arguments[X]&255);X++}break;default:throw new Error("Warning: pack() Type "+P+": unknown format code")}}if(X<arguments.length){throw new Error("Warning: pack(): "+(arguments.length-X)+" arguments unused")}return Y}};YamlUnescaper.REGEX_ESCAPED_CHARACTER='\\\\([0abt\tnvfre "\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})';var YamlDumper=function(){};YamlDumper.prototype={dump:function(g,f,c){if(f==undefined){f=0}if(c==undefined){c=0}var b="";var e=c?this.strRepeat(" ",c):"";var i;if(f<=0||!this.isObject(g)||this.isEmpty(g)){i=new YamlInline();b+=e+i.dump(g)}else{var d=!this.arrayEquals(this.getKeys(g),this.range(0,g.length-1));var a;for(var h in g){if(g.hasOwnProperty(h)){a=f-1<=0||!this.isObject(g[h])||this.isEmpty(g[h]);if(d){i=new YamlInline()}b+=e+""+(d?i.dump(h)+":":"-")+""+(a?" ":"\n")+""+this.dump(g[h],f-1,(a?0:c+2))+""+(a?"\n":"")}}}return b},strRepeat:function(d,c){var b;var a="";for(b=0;b<c;b++){a+=d}return a},isObject:function(a){return this.isDefined(a)&&typeof(a)=="object"},isEmpty:function(a){var b=a==undefined||a==null||a==""||a==0||a=="0"||a==false;if(!b&&typeof(a)=="object"&&!(a instanceof Array)){var d=0;for(var c in a){if(a.hasOwnProperty(c)){d++}}b=!d}return b},isDefined:function(a){return a!=undefined&&a!=null},getKeys:function(c){var b=[];for(var a in c){if(c.hasOwnProperty(a)){b.push(a)}}return b},range:function(d,a){if(d>a){return[]}var b=[];for(var c=d;c<=a;c++){b.push(c)}return b},arrayEquals:function(e,d){if(e.length!=d.length){return false}var c=e.length;for(var f=0;f<c;f++){if(e[f]!=d[f]){return false}}return true}}; \ No newline at end of file