From f7a3a8dbbe3140d1f52e73fcd21bfe8dbd533219 Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Mon, 30 Jan 2017 11:40:20 -0500 Subject: [PATCH] merge --- dist.js | 19406 ++++++++++++++++++++++++++++++++++++++++++++ playground/vm.js | 19423 +++++++++++++++++++++++++++++++++++++++++++++ vm.js | 19412 ++++++++++++++++++++++++++++++++++++++++++++ vm.min.js | 13 + 4 files changed, 58254 insertions(+) create mode 100644 dist.js create mode 100644 playground/vm.js create mode 100644 vm.js create mode 100644 vm.min.js diff --git a/dist.js b/dist.js new file mode 100644 index 00000000..084738ec --- /dev/null +++ b/dist.js @@ -0,0 +1,19406 @@ +module.exports = +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + var VirtualMachine = __webpack_require__(102); + + module.exports = VirtualMachine; + + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + // Copyright Joyent, Inc. and other Node contributors. + // + // 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. + + function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; + } + module.exports = EventEmitter; + + // Backwards-compat with node 0.10.x + EventEmitter.EventEmitter = EventEmitter; + + EventEmitter.prototype._events = undefined; + EventEmitter.prototype._maxListeners = undefined; + + // By default EventEmitters will print a warning if more than 10 listeners are + // added to it. This is a useful default which helps finding memory leaks. + EventEmitter.defaultMaxListeners = 10; + + // Obviously not all Emitters should be limited to 10. This function allows + // that to be increased. Set to zero for unlimited. + EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; + }; + + EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + // At least give some kind of context to the user + var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); + err.context = er; + throw err; + } + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; + }; + + EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; + }; + + EventEmitter.prototype.on = EventEmitter.prototype.addListener; + + EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; + }; + + // emits a 'removeListener' event iff the listener was removed + EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; + }; + + EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; + }; + + EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; + }; + + EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; + }; + + EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); + }; + + function isFunction(arg) { + return typeof arg === 'function'; + } + + function isNumber(arg) { + return typeof arg === 'number'; + } + + function isObject(arg) { + return typeof arg === 'object' && arg !== null; + } + + function isUndefined(arg) { + return arg === void 0; + } + + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. + // + // 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 formatRegExp = /%[sdj%]/g; + exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; + }; + + + // Mark that a method should not be used. + // Returns a modified function which warns once by default. + // If --no-deprecation is set, then it is a no-op. + exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; + }; + + + var debugs = {}; + var debugEnviron; + exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; + }; + + + /** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ + /* legacy: obj, showHidden, depth, colors*/ + function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); + } + exports.inspect = inspect; + + + // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics + inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] + }; + + // Don't use 'blue' not visible on cmd.exe + inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' + }; + + + function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } + } + + + function stylizeNoColor(str, styleType) { + return str; + } + + + function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; + } + + + function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); + } + + + function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); + } + + + function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; + } + + + function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; + } + + + function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; + } + + + function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + } + + + // NOTE: These type checking functions intentionally don't use `instanceof` + // because it is fragile and can be easily faked with `Object.create()`. + function isArray(ar) { + return Array.isArray(ar); + } + exports.isArray = isArray; + + function isBoolean(arg) { + return typeof arg === 'boolean'; + } + exports.isBoolean = isBoolean; + + function isNull(arg) { + return arg === null; + } + exports.isNull = isNull; + + function isNullOrUndefined(arg) { + return arg == null; + } + exports.isNullOrUndefined = isNullOrUndefined; + + function isNumber(arg) { + return typeof arg === 'number'; + } + exports.isNumber = isNumber; + + function isString(arg) { + return typeof arg === 'string'; + } + exports.isString = isString; + + function isSymbol(arg) { + return typeof arg === 'symbol'; + } + exports.isSymbol = isSymbol; + + function isUndefined(arg) { + return arg === void 0; + } + exports.isUndefined = isUndefined; + + function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; + } + exports.isRegExp = isRegExp; + + function isObject(arg) { + return typeof arg === 'object' && arg !== null; + } + exports.isObject = isObject; + + function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; + } + exports.isDate = isDate; + + function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); + } + exports.isError = isError; + + function isFunction(arg) { + return typeof arg === 'function'; + } + exports.isFunction = isFunction; + + function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; + } + exports.isPrimitive = isPrimitive; + + exports.isBuffer = __webpack_require__(4); + + function objectToString(o) { + return Object.prototype.toString.call(o); + } + + + function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); + } + + + var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + + // 26 Feb 16:19:34 + function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); + } + + + // log is just a thin wrapper to console.log that prepends a timestamp + exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); + }; + + + /** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ + exports.inherits = __webpack_require__(5); + + exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; + }; + + function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(3))) + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + // shim for using process in browser + var process = module.exports = {}; + + // cached from whatever global is present so that test runners that stub it + // don't break things. But we need to wrap it in a try catch in case it is + // wrapped in strict mode code which doesn't define any globals. It's inside a + // function because try/catches deoptimize in certain engines. + + var cachedSetTimeout; + var cachedClearTimeout; + + function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); + } + function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); + } + (function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } + } ()) + function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + + } + function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + + } + var queue = []; + var draining = false; + var currentQueue; + var queueIndex = -1; + + function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } + } + + function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); + } + + process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } + }; + + // v8 likes predictible objects + function Item(fun, array) { + this.fun = fun; + this.array = array; + } + Item.prototype.run = function () { + this.fun.apply(null, this.array); + }; + process.title = 'browser'; + process.browser = true; + process.env = {}; + process.argv = []; + process.version = ''; // empty string to avoid regexp issues + process.versions = {}; + + function noop() {} + + process.on = noop; + process.addListener = noop; + process.once = noop; + process.off = noop; + process.removeListener = noop; + process.removeAllListeners = noop; + process.emit = noop; + + process.binding = function (name) { + throw new Error('process.binding is not supported'); + }; + + process.cwd = function () { return '/' }; + process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); + }; + process.umask = function() { return 0; }; + + +/***/ }, +/* 4 */ +/***/ function(module, exports) { + + module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; + } + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + + if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; + } else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + var EventEmitter = __webpack_require__(1); + var Sequencer = __webpack_require__(7); + var Blocks = __webpack_require__(24); + var Thread = __webpack_require__(9); + var util = __webpack_require__(2); + + // Virtual I/O devices. + var Clock = __webpack_require__(79); + var Keyboard = __webpack_require__(80); + var Mouse = __webpack_require__(83); + + var defaultBlockPackages = { + scratch3_control: __webpack_require__(85), + scratch3_event: __webpack_require__(86), + scratch3_looks: __webpack_require__(87), + scratch3_motion: __webpack_require__(88), + scratch3_operators: __webpack_require__(89), + scratch3_pen: __webpack_require__(103), + scratch3_sound: __webpack_require__(90), + scratch3_sensing: __webpack_require__(91), + scratch3_data: __webpack_require__(92), + scratch3_procedures: __webpack_require__(93) + }; + + /** + * Manages targets, scripts, and the sequencer. + * @constructor + */ + var Runtime = function () { + // Bind event emitter + EventEmitter.call(this); + + /** + * Target management and storage. + * @type {Array.} + */ + this.targets = []; + + /** + * A list of threads that are currently running in the VM. + * Threads are added when execution starts and pruned when execution ends. + * @type {Array.} + */ + this.threads = []; + + /** @type {!Sequencer} */ + this.sequencer = new Sequencer(this); + + /** + * Storage container for flyout blocks. + * These will execute on `_editingTarget.` + * @type {!Blocks} + */ + this.flyoutBlocks = new Blocks(); + + /** + * Currently known editing target for the VM. + * @type {?Target} + */ + this._editingTarget = null; + + /** + * Map to look up a block primitive's implementation function by its opcode. + * This is a two-step lookup: package name first, then primitive name. + * @type {Object.} + */ + this._primitives = {}; + + /** + * Map to look up hat blocks' metadata. + * Keys are opcode for hat, values are metadata objects. + * @type {Object.} + */ + this._hats = {}; + + /** + * Currently known values for edge-activated hats. + * Keys are block ID for the hat; values are the currently known values. + * @type {Object.} + */ + this._edgeActivatedHatValues = {}; + + /** + * A list of script block IDs that were glowing during the previous frame. + * @type {!Array.} + */ + this._scriptGlowsPreviousFrame = []; + + /** + * Number of threads running during the previous frame + * @type {number} + */ + this._threadCount = 0; + + /** + * Currently known number of clones, used to enforce clone limit. + * @type {number} + */ + this._cloneCounter = 0; + + /** + * Whether the project is in "turbo mode." + * @type {Boolean} + */ + this.turboMode = false; + + /** + * Whether the project is in "compatibility mode" (30 TPS). + * @type {Boolean} + */ + this.compatibilityMode = false; + + /** + * A reference to the current runtime stepping interval, set + * by a `setInterval`. + * @type {!number} + */ + this._steppingInterval = null; + + /** + * Current length of a step. + * Changes as mode switches, and used by the sequencer to calculate + * WORK_TIME. + * @type {!number} + */ + this.currentStepTime = null; + + /** + * Whether any primitive has requested a redraw. + * Affects whether `Sequencer.stepThreads` will yield + * after stepping each thread. + * Reset on every frame. + * @type {boolean} + */ + this.redrawRequested = false; + + // Register all given block packages. + this._registerBlockPackages(); + + // Register and initialize "IO devices", containers for processing + // I/O related data. + /** @type {Object.} */ + this.ioDevices = { + clock: new Clock(), + keyboard: new Keyboard(this), + mouse: new Mouse(this) + }; + }; + + /** + * Inherit from EventEmitter + */ + util.inherits(Runtime, EventEmitter); + + /** + * Width of the stage, in pixels. + * @const {number} + */ + Runtime.STAGE_WIDTH = 480; + + /** + * Height of the stage, in pixels. + * @const {number} + */ + Runtime.STAGE_HEIGHT = 360; + + /** + * Event name for glowing a script. + * @const {string} + */ + Runtime.SCRIPT_GLOW_ON = 'SCRIPT_GLOW_ON'; + + /** + * Event name for unglowing a script. + * @const {string} + */ + Runtime.SCRIPT_GLOW_OFF = 'SCRIPT_GLOW_OFF'; + + /** + * Event name for glowing a block. + * @const {string} + */ + Runtime.BLOCK_GLOW_ON = 'BLOCK_GLOW_ON'; + + /** + * Event name for unglowing a block. + * @const {string} + */ + Runtime.BLOCK_GLOW_OFF = 'BLOCK_GLOW_OFF'; + + /** + * Event name for glowing the green flag + * @const {string} + */ + Runtime.PROJECT_RUN_START = 'PROJECT_RUN_START'; + + /** + * Event name for unglowing the green flag + * @const {string} + */ + Runtime.PROJECT_RUN_STOP = 'PROJECT_RUN_STOP'; + + /** + * Event name for visual value report. + * @const {string} + */ + Runtime.VISUAL_REPORT = 'VISUAL_REPORT'; + + /** + * Event name for sprite info report. + * @const {string} + */ + Runtime.SPRITE_INFO_REPORT = 'SPRITE_INFO_REPORT'; + + /** + * How rapidly we try to step threads by default, in ms. + */ + Runtime.THREAD_STEP_INTERVAL = 1000 / 60; + + /** + * In compatibility mode, how rapidly we try to step threads, in ms. + */ + Runtime.THREAD_STEP_INTERVAL_COMPATIBILITY = 1000 / 30; + + /** + * How many clones can be created at a time. + * @const {number} + */ + Runtime.MAX_CLONES = 300; + + // ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- + + /** + * Register default block packages with this runtime. + * @todo Prefix opcodes with package name. + * @private + */ + Runtime.prototype._registerBlockPackages = function () { + for (var packageName in defaultBlockPackages) { + if (defaultBlockPackages.hasOwnProperty(packageName)) { + // @todo pass a different runtime depending on package privilege? + var packageObject = new (defaultBlockPackages[packageName])(this); + // Collect primitives from package. + if (packageObject.getPrimitives) { + var packagePrimitives = packageObject.getPrimitives(); + for (var op in packagePrimitives) { + if (packagePrimitives.hasOwnProperty(op)) { + this._primitives[op] = + packagePrimitives[op].bind(packageObject); + } + } + } + // Collect hat metadata from package. + if (packageObject.getHats) { + var packageHats = packageObject.getHats(); + for (var hatName in packageHats) { + if (packageHats.hasOwnProperty(hatName)) { + this._hats[hatName] = packageHats[hatName]; + } + } + } + } + } + }; + + /** + * Retrieve the function associated with the given opcode. + * @param {!string} opcode The opcode to look up. + * @return {Function} The function which implements the opcode. + */ + Runtime.prototype.getOpcodeFunction = function (opcode) { + return this._primitives[opcode]; + }; + + /** + * Return whether an opcode represents a hat block. + * @param {!string} opcode The opcode to look up. + * @return {Boolean} True if the op is known to be a hat. + */ + Runtime.prototype.getIsHat = function (opcode) { + return this._hats.hasOwnProperty(opcode); + }; + + /** + * Return whether an opcode represents an edge-activated hat block. + * @param {!string} opcode The opcode to look up. + * @return {Boolean} True if the op is known to be a edge-activated hat. + */ + Runtime.prototype.getIsEdgeActivatedHat = function (opcode) { + return this._hats.hasOwnProperty(opcode) && + this._hats[opcode].edgeActivated; + }; + + /** + * Update an edge-activated hat block value. + * @param {!string} blockId ID of hat to store value for. + * @param {*} newValue Value to store for edge-activated hat. + * @return {*} The old value for the edge-activated hat. + */ + Runtime.prototype.updateEdgeActivatedValue = function (blockId, newValue) { + var oldValue = this._edgeActivatedHatValues[blockId]; + this._edgeActivatedHatValues[blockId] = newValue; + return oldValue; + }; + + /** + * Clear all edge-activaed hat values. + */ + Runtime.prototype.clearEdgeActivatedValues = function () { + this._edgeActivatedHatValues = {}; + }; + + /** + * Attach the renderer + * @param {!RenderWebGL} renderer The renderer to attach + */ + Runtime.prototype.attachRenderer = function (renderer) { + this.renderer = renderer; + }; + + /** + * Attach the audio engine + * @param {!AudioEngine} audioEngine The audio engine to attach + */ + Runtime.prototype.attachAudioEngine = function (audioEngine) { + this.audioEngine = audioEngine; + }; + + // ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- + + /** + * Create a thread and push it to the list of threads. + * @param {!string} id ID of block that starts the stack. + * @param {!Target} target Target to run thread on. + * @return {!Thread} The newly created thread. + */ + Runtime.prototype._pushThread = function (id, target) { + var thread = new Thread(id); + thread.target = target; + thread.pushStack(id); + this.threads.push(thread); + return thread; + }; + + /** + * Remove a thread from the list of threads. + * @param {?Thread} thread Thread object to remove from actives + */ + Runtime.prototype._removeThread = function (thread) { + // Inform sequencer to stop executing that thread. + this.sequencer.retireThread(thread); + // Remove from the list. + var i = this.threads.indexOf(thread); + if (i > -1) { + this.threads.splice(i, 1); + } + }; + + /** + * Restart a thread in place, maintaining its position in the list of threads. + * This is used by `startHats` to and is necessary to ensure 2.0-like execution order. + * Test project: https://scratch.mit.edu/projects/130183108/ + * @param {!Thread} thread Thread object to restart. + */ + Runtime.prototype._restartThread = function (thread) { + var newThread = new Thread(thread.topBlock); + newThread.target = thread.target; + newThread.pushStack(thread.topBlock); + var i = this.threads.indexOf(thread); + if (i > -1) { + this.threads[i] = newThread; + } else { + this.threads.push(thread); + } + }; + + /** + * Return whether a thread is currently active/running. + * @param {?Thread} thread Thread object to check. + * @return {Boolean} True if the thread is active/running. + */ + Runtime.prototype.isActiveThread = function (thread) { + return this.threads.indexOf(thread) > -1; + }; + + /** + * Toggle a script. + * @param {!string} topBlockId ID of block that starts the script. + */ + Runtime.prototype.toggleScript = function (topBlockId) { + // Remove any existing thread. + for (var i = 0; i < this.threads.length; i++) { + if (this.threads[i].topBlock === topBlockId) { + this._removeThread(this.threads[i]); + return; + } + } + // Otherwise add it. + this._pushThread(topBlockId, this._editingTarget); + }; + + /** + * Run a function `f` for all scripts in a workspace. + * `f` will be called with two parameters: + * - the top block ID of the script. + * - the target that owns the script. + * @param {!Function} f Function to call for each script. + * @param {Target=} optTarget Optionally, a target to restrict to. + */ + Runtime.prototype.allScriptsDo = function (f, optTarget) { + var targets = this.targets; + if (optTarget) { + targets = [optTarget]; + } + for (var t = 0; t < targets.length; t++) { + var target = targets[t]; + var scripts = target.blocks.getScripts(); + for (var j = 0; j < scripts.length; j++) { + var topBlockId = scripts[j]; + f(topBlockId, target); + } + } + }; + + /** + * Start all relevant hats. + * @param {!string} requestedHatOpcode Opcode of hats to start. + * @param {Object=} optMatchFields Optionally, fields to match on the hat. + * @param {Target=} optTarget Optionally, a target to restrict to. + * @return {Array.} List of threads started by this function. + */ + Runtime.prototype.startHats = function (requestedHatOpcode, + optMatchFields, optTarget) { + if (!this._hats.hasOwnProperty(requestedHatOpcode)) { + // No known hat with this opcode. + return; + } + var instance = this; + var newThreads = []; + // Consider all scripts, looking for hats with opcode `requestedHatOpcode`. + this.allScriptsDo(function (topBlockId, target) { + var potentialHatOpcode = target.blocks.getBlock(topBlockId).opcode; + if (potentialHatOpcode !== requestedHatOpcode) { + // Not the right hat. + return; + } + + // Match any requested fields. + // For example: ensures that broadcasts match. + // This needs to happen before the block is evaluated + // (i.e., before the predicate can be run) because "broadcast and wait" + // needs to have a precise collection of started threads. + var hatFields = target.blocks.getFields(topBlockId); + + // If no fields are present, check inputs (horizontal blocks) + if (Object.keys(hatFields).length === 0) { + var hatInputs = target.blocks.getInputs(topBlockId); + for (var input in hatInputs) { + var id = hatInputs[input].block; + var fields = target.blocks.getFields(id); + hatFields = Object.assign(fields, hatFields); + } + } + + if (optMatchFields) { + for (var matchField in optMatchFields) { + if (hatFields[matchField].value !== + optMatchFields[matchField]) { + // Field mismatch. + return; + } + } + } + + // Look up metadata for the relevant hat. + var hatMeta = instance._hats[requestedHatOpcode]; + if (hatMeta.restartExistingThreads) { + // If `restartExistingThreads` is true, we should stop + // any existing threads starting with the top block. + for (var i = 0; i < instance.threads.length; i++) { + if (instance.threads[i].topBlock === topBlockId && + instance.threads[i].target === target) { + instance._restartThread(instance.threads[i]); + return; + } + } + } else { + // If `restartExistingThreads` is false, we should + // give up if any threads with the top block are running. + for (var j = 0; j < instance.threads.length; j++) { + if (instance.threads[j].topBlock === topBlockId && + instance.threads[j].target === target) { + // Some thread is already running. + return; + } + } + } + // Start the thread with this top block. + newThreads.push(instance._pushThread(topBlockId, target)); + }, optTarget); + return newThreads; + }; + + /** + * Dispose all targets. Return to clean state. + */ + Runtime.prototype.dispose = function () { + this.stopAll(); + this.targets.map(this.disposeTarget, this); + }; + + /** + * Dispose of a target. + * @param {!Target} disposingTarget Target to dispose of. + */ + Runtime.prototype.disposeTarget = function (disposingTarget) { + this.targets = this.targets.filter(function (target) { + if (disposingTarget !== target) return true; + // Allow target to do dispose actions. + target.dispose(); + // Remove from list of targets. + return false; + }); + }; + + /** + * Stop any threads acting on the target. + * @param {!Target} target Target to stop threads for. + * @param {Thread=} optThreadException Optional thread to skip. + */ + Runtime.prototype.stopForTarget = function (target, optThreadException) { + // Stop any threads on the target. + for (var i = 0; i < this.threads.length; i++) { + if (this.threads[i] === optThreadException) { + continue; + } + if (this.threads[i].target === target) { + this._removeThread(this.threads[i]); + } + } + }; + + /** + * Start all threads that start with the green flag. + */ + Runtime.prototype.greenFlag = function () { + this.stopAll(); + this.ioDevices.clock.resetProjectTimer(); + this.clearEdgeActivatedValues(); + // Inform all targets of the green flag. + for (var i = 0; i < this.targets.length; i++) { + this.targets[i].onGreenFlag(); + } + this.startHats('event_whenflagclicked'); + }; + + /** + * Stop "everything." + */ + Runtime.prototype.stopAll = function () { + // Dispose all clones. + var newTargets = []; + for (var i = 0; i < this.targets.length; i++) { + this.targets[i].onStopAll(); + if (this.targets[i].hasOwnProperty('isOriginal') && + !this.targets[i].isOriginal) { + this.targets[i].dispose(); + } else { + newTargets.push(this.targets[i]); + } + } + this.targets = newTargets; + // Dispose all threads. + var threadsCopy = this.threads.slice(); + while (threadsCopy.length > 0) { + var poppedThread = threadsCopy.pop(); + this._removeThread(poppedThread); + } + }; + + /** + * Repeatedly run `sequencer.stepThreads` and filter out + * inactive threads after each iteration. + */ + Runtime.prototype._step = function () { + // Find all edge-activated hats, and add them to threads to be evaluated. + for (var hatType in this._hats) { + var hat = this._hats[hatType]; + if (hat.edgeActivated) { + this.startHats(hatType); + } + } + this.redrawRequested = false; + var doneThreads = this.sequencer.stepThreads(); + this._updateGlows(doneThreads); + this._setThreadCount(this.threads.length + doneThreads.length); + if (this.renderer) { + // @todo: Only render when this.redrawRequested or clones rendered. + this.renderer.draw(); + } + }; + + /** + * Set the current editing target known by the runtime. + * @param {!Target} editingTarget New editing target. + */ + Runtime.prototype.setEditingTarget = function (editingTarget) { + this._editingTarget = editingTarget; + // Script glows must be cleared. + this._scriptGlowsPreviousFrame = []; + this._updateGlows(); + this.spriteInfoReport(editingTarget); + }; + + /** + * Set whether we are in 30 TPS compatibility mode. + * @param {boolean} compatibilityModeOn True iff in compatibility mode. + */ + Runtime.prototype.setCompatibilityMode = function (compatibilityModeOn) { + this.compatibilityMode = compatibilityModeOn; + if (this._steppingInterval) { + clearInterval(this._steppingInterval); + this.start(); + } + }; + + /** + * Emit glows/glow clears for scripts after a single tick. + * Looks at `this.threads` and notices which have turned on/off new glows. + * @param {Array.=} optExtraThreads Optional list of inactive threads. + */ + Runtime.prototype._updateGlows = function (optExtraThreads) { + var searchThreads = []; + searchThreads.push.apply(searchThreads, this.threads); + if (optExtraThreads) { + searchThreads.push.apply(searchThreads, optExtraThreads); + } + // Set of scripts that request a glow this frame. + var requestedGlowsThisFrame = []; + // Final set of scripts glowing during this frame. + var finalScriptGlows = []; + // Find all scripts that should be glowing. + for (var i = 0; i < searchThreads.length; i++) { + var thread = searchThreads[i]; + var target = thread.target; + if (target === this._editingTarget) { + var blockForThread = thread.blockGlowInFrame; + if (thread.requestScriptGlowInFrame) { + var script = target.blocks.getTopLevelScript(blockForThread); + if (!script) { + // Attempt to find in flyout blocks. + script = this.flyoutBlocks.getTopLevelScript( + blockForThread + ); + } + if (script) { + requestedGlowsThisFrame.push(script); + } + } + } + } + // Compare to previous frame. + for (var j = 0; j < this._scriptGlowsPreviousFrame.length; j++) { + var previousFrameGlow = this._scriptGlowsPreviousFrame[j]; + if (requestedGlowsThisFrame.indexOf(previousFrameGlow) < 0) { + // Glow turned off. + this.glowScript(previousFrameGlow, false); + } else { + // Still glowing. + finalScriptGlows.push(previousFrameGlow); + } + } + for (var k = 0; k < requestedGlowsThisFrame.length; k++) { + var currentFrameGlow = requestedGlowsThisFrame[k]; + if (this._scriptGlowsPreviousFrame.indexOf(currentFrameGlow) < 0) { + // Glow turned on. + this.glowScript(currentFrameGlow, true); + finalScriptGlows.push(currentFrameGlow); + } + } + this._scriptGlowsPreviousFrame = finalScriptGlows; + }; + + /** + * Emit run start/stop after each tick. Emits when `this.threads.length` goes + * between non-zero and zero + * + * @param {number} threadCount The new threadCount + */ + Runtime.prototype._setThreadCount = function (threadCount) { + if (this._threadCount === 0 && threadCount > 0) { + this.emit(Runtime.PROJECT_RUN_START); + } + if (this._threadCount > 0 && threadCount === 0) { + this.emit(Runtime.PROJECT_RUN_STOP); + } + this._threadCount = threadCount; + }; + + /** + * "Quiet" a script's glow: stop the VM from generating glow/unglow events + * about that script. Use when a script has just been deleted, but we may + * still be tracking glow data about it. + * @param {!string} scriptBlockId Id of top-level block in script to quiet. + */ + Runtime.prototype.quietGlow = function (scriptBlockId) { + var index = this._scriptGlowsPreviousFrame.indexOf(scriptBlockId); + if (index > -1) { + this._scriptGlowsPreviousFrame.splice(index, 1); + } + }; + + /** + * Emit feedback for block glowing (used in the sequencer). + * @param {?string} blockId ID for the block to update glow + * @param {boolean} isGlowing True to turn on glow; false to turn off. + */ + Runtime.prototype.glowBlock = function (blockId, isGlowing) { + if (isGlowing) { + this.emit(Runtime.BLOCK_GLOW_ON, {id: blockId}); + } else { + this.emit(Runtime.BLOCK_GLOW_OFF, {id: blockId}); + } + }; + + /** + * Emit feedback for script glowing. + * @param {?string} topBlockId ID for the top block to update glow + * @param {boolean} isGlowing True to turn on glow; false to turn off. + */ + Runtime.prototype.glowScript = function (topBlockId, isGlowing) { + if (isGlowing) { + this.emit(Runtime.SCRIPT_GLOW_ON, {id: topBlockId}); + } else { + this.emit(Runtime.SCRIPT_GLOW_OFF, {id: topBlockId}); + } + }; + + /** + * Emit value for reporter to show in the blocks. + * @param {string} blockId ID for the block. + * @param {string} value Value to show associated with the block. + */ + Runtime.prototype.visualReport = function (blockId, value) { + this.emit(Runtime.VISUAL_REPORT, {id: blockId, value: String(value)}); + }; + + /** + * Emit a sprite info report if the provided target is the original sprite + * @param {!Target} target Target to report sprite info for. + */ + Runtime.prototype.spriteInfoReport = function (target) { + if (!target.isOriginal) return; + + this.emit(Runtime.SPRITE_INFO_REPORT, target.toJSON()); + }; + + /** + * Get a target by its id. + * @param {string} targetId Id of target to find. + * @return {?Target} The target, if found. + */ + Runtime.prototype.getTargetById = function (targetId) { + for (var i = 0; i < this.targets.length; i++) { + var target = this.targets[i]; + if (target.id === targetId) { + return target; + } + } + }; + + /** + * Get the first original (non-clone-block-created) sprite given a name. + * @param {string} spriteName Name of sprite to look for. + * @return {?Target} Target representing a sprite of the given name. + */ + Runtime.prototype.getSpriteTargetByName = function (spriteName) { + for (var i = 0; i < this.targets.length; i++) { + var target = this.targets[i]; + if (target.sprite && target.sprite.name === spriteName) { + return target; + } + } + }; + + /** + * Update the clone counter to track how many clones are created. + * @param {number} changeAmount How many clones have been created/destroyed. + */ + Runtime.prototype.changeCloneCounter = function (changeAmount) { + this._cloneCounter += changeAmount; + }; + + /** + * Return whether there are clones available. + * @return {boolean} True until the number of clones hits Runtime.MAX_CLONES. + */ + Runtime.prototype.clonesAvailable = function () { + return this._cloneCounter < Runtime.MAX_CLONES; + }; + + /** + * Get a target representing the Scratch stage, if one exists. + * @return {?Target} The target, if found. + */ + Runtime.prototype.getTargetForStage = function () { + for (var i = 0; i < this.targets.length; i++) { + var target = this.targets[i]; + if (target.isStage) { + return target; + } + } + }; + + /** + * Tell the runtime to request a redraw. + * Use after a clone/sprite has completed some visible operation on the stage. + */ + Runtime.prototype.requestRedraw = function () { + this.redrawRequested = true; + }; + + /** + * Set up timers to repeatedly step in a browser. + */ + Runtime.prototype.start = function () { + var interval = Runtime.THREAD_STEP_INTERVAL; + if (this.compatibilityMode) { + interval = Runtime.THREAD_STEP_INTERVAL_COMPATIBILITY; + } + this.currentStepTime = interval; + this._steppingInterval = setInterval(function () { + this._step(); + }.bind(this), interval); + }; + + module.exports = Runtime; + + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + var Timer = __webpack_require__(8); + var Thread = __webpack_require__(9); + var execute = __webpack_require__(10); + + var Sequencer = function (runtime) { + /** + * A utility timer for timing thread sequencing. + * @type {!Timer} + */ + this.timer = new Timer(); + + /** + * Reference to the runtime owning this sequencer. + * @type {!Runtime} + */ + this.runtime = runtime; + }; + + /** + * Time to run a warp-mode thread, in ms. + * @type {number} + */ + Sequencer.WARP_TIME = 500; + + /** + * Step through all threads in `this.runtime.threads`, running them in order. + * @return {Array.} List of inactive threads after stepping. + */ + Sequencer.prototype.stepThreads = function () { + // Work time is 75% of the thread stepping interval. + var WORK_TIME = 0.75 * this.runtime.currentStepTime; + // Start counting toward WORK_TIME. + this.timer.start(); + // Count of active threads. + var numActiveThreads = Infinity; + // Whether `stepThreads` has run through a full single tick. + var ranFirstTick = false; + var doneThreads = []; + // Conditions for continuing to stepping threads: + // 1. We must have threads in the list, and some must be active. + // 2. Time elapsed must be less than WORK_TIME. + // 3. Either turbo mode, or no redraw has been requested by a primitive. + while (this.runtime.threads.length > 0 && + numActiveThreads > 0 && + this.timer.timeElapsed() < WORK_TIME && + (this.runtime.turboMode || !this.runtime.redrawRequested)) { + numActiveThreads = 0; + // Attempt to run each thread one time. + for (var i = 0; i < this.runtime.threads.length; i++) { + var activeThread = this.runtime.threads[i]; + if (activeThread.stack.length === 0 || + activeThread.status === Thread.STATUS_DONE) { + // Finished with this thread. + if (doneThreads.indexOf(activeThread) < 0) { + doneThreads.push(activeThread); + } + continue; + } + if (activeThread.status === Thread.STATUS_YIELD_TICK && + !ranFirstTick) { + // Clear single-tick yield from the last call of `stepThreads`. + activeThread.status = Thread.STATUS_RUNNING; + } + if (activeThread.status === Thread.STATUS_RUNNING || + activeThread.status === Thread.STATUS_YIELD) { + // Normal-mode thread: step. + this.stepThread(activeThread); + activeThread.warpTimer = null; + } + if (activeThread.status === Thread.STATUS_RUNNING) { + numActiveThreads++; + } + } + // We successfully ticked once. Prevents running STATUS_YIELD_TICK + // threads on the next tick. + ranFirstTick = true; + } + // Filter inactive threads from `this.runtime.threads`. + this.runtime.threads = this.runtime.threads.filter(function (thread) { + if (doneThreads.indexOf(thread) > -1) { + return false; + } + return true; + }); + return doneThreads; + }; + + /** + * Step the requested thread for as long as necessary. + * @param {!Thread} thread Thread object to step. + */ + Sequencer.prototype.stepThread = function (thread) { + var currentBlockId = thread.peekStack(); + if (!currentBlockId) { + // A "null block" - empty branch. + thread.popStack(); + } + while (thread.peekStack()) { + var isWarpMode = thread.peekStackFrame().warpMode; + if (isWarpMode && !thread.warpTimer) { + // Initialize warp-mode timer if it hasn't been already. + // This will start counting the thread toward `Sequencer.WARP_TIME`. + thread.warpTimer = new Timer(); + thread.warpTimer.start(); + } + // Execute the current block. + // Save the current block ID to notice if we did control flow. + currentBlockId = thread.peekStack(); + execute(this, thread); + thread.blockGlowInFrame = currentBlockId; + // If the thread has yielded or is waiting, yield to other threads. + if (thread.status === Thread.STATUS_YIELD) { + // Mark as running for next iteration. + thread.status = Thread.STATUS_RUNNING; + // In warp mode, yielded blocks are re-executed immediately. + if (isWarpMode && + thread.warpTimer.timeElapsed() <= Sequencer.WARP_TIME) { + continue; + } + return; + } else if (thread.status === Thread.STATUS_PROMISE_WAIT) { + // A promise was returned by the primitive. Yield the thread + // until the promise resolves. Promise resolution should reset + // thread.status to Thread.STATUS_RUNNING. + return; + } + // If no control flow has happened, switch to next block. + if (thread.peekStack() === currentBlockId) { + thread.goToNextBlock(); + } + // If no next block has been found at this point, look on the stack. + while (!thread.peekStack()) { + thread.popStack(); + + if (thread.stack.length === 0) { + // No more stack to run! + thread.status = Thread.STATUS_DONE; + return; + } + + var stackFrame = thread.peekStackFrame(); + isWarpMode = stackFrame.warpMode; + + if (stackFrame.isLoop) { + // The current level of the stack is marked as a loop. + // Return to yield for the frame/tick in general. + // Unless we're in warp mode - then only return if the + // warp timer is up. + if (!isWarpMode || + thread.warpTimer.timeElapsed() > Sequencer.WARP_TIME) { + // Don't do anything to the stack, since loops need + // to be re-executed. + return; + } else { + // Don't go to the next block for this level of the stack, + // since loops need to be re-executed. + continue; + } + } else if (stackFrame.waitingReporter) { + // This level of the stack was waiting for a value. + // This means a reporter has just returned - so don't go + // to the next block for this level of the stack. + return; + } + // Get next block of existing block on the stack. + thread.goToNextBlock(); + } + } + }; + + /** + * Step a thread into a block's branch. + * @param {!Thread} thread Thread object to step to branch. + * @param {Number} branchNum Which branch to step to (i.e., 1, 2). + * @param {Boolean} isLoop Whether this block is a loop. + */ + Sequencer.prototype.stepToBranch = function (thread, branchNum, isLoop) { + if (!branchNum) { + branchNum = 1; + } + var currentBlockId = thread.peekStack(); + var branchId = thread.target.blocks.getBranch( + currentBlockId, + branchNum + ); + thread.peekStackFrame().isLoop = isLoop; + if (branchId) { + // Push branch ID to the thread's stack. + thread.pushStack(branchId); + } else { + thread.pushStack(null); + } + }; + + /** + * Step a procedure. + * @param {!Thread} thread Thread object to step to procedure. + * @param {!string} procedureCode Procedure code of procedure to step to. + */ + Sequencer.prototype.stepToProcedure = function (thread, procedureCode) { + var definition = thread.target.blocks.getProcedureDefinition(procedureCode); + if (!definition) { + return; + } + // Check if the call is recursive. + // If so, set the thread to yield after pushing. + var isRecursive = thread.isRecursiveCall(procedureCode); + // To step to a procedure, we put its definition on the stack. + // Execution for the thread will proceed through the definition hat + // and on to the main definition of the procedure. + // When that set of blocks finishes executing, it will be popped + // from the stack by the sequencer, returning control to the caller. + thread.pushStack(definition); + // In known warp-mode threads, only yield when time is up. + if (thread.peekStackFrame().warpMode && + thread.warpTimer.timeElapsed() > Sequencer.WARP_TIME) { + thread.status = Thread.STATUS_YIELD; + } else { + // Look for warp-mode flag on definition, and set the thread + // to warp-mode if needed. + var definitionBlock = thread.target.blocks.getBlock(definition); + var doWarp = definitionBlock.mutation.warp; + if (doWarp) { + thread.peekStackFrame().warpMode = true; + } else { + // In normal-mode threads, yield any time we have a recursive call. + if (isRecursive) { + thread.status = Thread.STATUS_YIELD; + } + } + } + }; + + /** + * Retire a thread in the middle, without considering further blocks. + * @param {!Thread} thread Thread object to retire. + */ + Sequencer.prototype.retireThread = function (thread) { + thread.stack = []; + thread.stackFrame = []; + thread.requestScriptGlowInFrame = false; + thread.status = Thread.STATUS_DONE; + }; + + module.exports = Sequencer; + + +/***/ }, +/* 8 */ +/***/ function(module, exports) { + + /** + * @fileoverview + * A utility for accurately measuring time. + * To use: + * --- + * var timer = new Timer(); + * timer.start(); + * ... pass some time ... + * var timeDifference = timer.timeElapsed(); + * --- + * Or, you can use the `time` and `relativeTime` + * to do some measurement yourself. + */ + + /** + * @constructor + */ + var Timer = function () {}; + + /** + * Used to store the start time of a timer action. + * Updated when calling `timer.start`. + */ + Timer.prototype.startTime = 0; + + /** + * Return the currently known absolute time, in ms precision. + * @returns {number} ms elapsed since 1 January 1970 00:00:00 UTC. + */ + Timer.prototype.time = function () { + if (Date.now) { + return Date.now(); + } else { + return new Date().getTime(); + } + }; + + /** + * Returns a time accurate relative to other times produced by this function. + * If possible, will use sub-millisecond precision. + * If not, will use millisecond precision. + * Not guaranteed to produce the same absolute values per-system. + * @returns {number} ms-scale accurate time relative to other relative times. + */ + Timer.prototype.relativeTime = function () { + if (typeof self !== 'undefined' && + self.performance && 'now' in self.performance) { + return self.performance.now(); + } else { + return this.time(); + } + }; + + /** + * Start a timer for measuring elapsed time, + * at the most accurate precision possible. + */ + Timer.prototype.start = function () { + this.startTime = this.relativeTime(); + }; + + /** + * Check time elapsed since `timer.start` was called. + * @returns {number} Time elapsed, in ms (possibly sub-ms precision). + */ + Timer.prototype.timeElapsed = function () { + return this.relativeTime() - this.startTime; + }; + + module.exports = Timer; + + +/***/ }, +/* 9 */ +/***/ function(module, exports) { + + /** + * A thread is a running stack context and all the metadata needed. + * @param {?string} firstBlock First block to execute in the thread. + * @constructor + */ + var Thread = function (firstBlock) { + /** + * ID of top block of the thread + * @type {!string} + */ + this.topBlock = firstBlock; + + /** + * Stack for the thread. When the sequencer enters a control structure, + * the block is pushed onto the stack so we know where to exit. + * @type {Array.} + */ + this.stack = []; + + /** + * Stack frames for the thread. Store metadata for the executing blocks. + * @type {Array.} + */ + this.stackFrames = []; + + /** + * Status of the thread, one of three states (below) + * @type {number} + */ + this.status = 0; /* Thread.STATUS_RUNNING */ + + /** + * Target of this thread. + * @type {?Target} + */ + this.target = null; + + /** + * Whether the thread requests its script to glow during this frame. + * @type {boolean} + */ + this.requestScriptGlowInFrame = false; + + /** + * Which block ID should glow during this frame, if any. + * @type {?string} + */ + this.blockGlowInFrame = null; + + /** + * A timer for when the thread enters warp mode. + * Substitutes the sequencer's count toward WORK_TIME on a per-thread basis. + * @type {?Timer} + */ + this.warpTimer = null; + }; + + /** + * Thread status for initialized or running thread. + * This is the default state for a thread - execution should run normally, + * stepping from block to block. + * @const + */ + Thread.STATUS_RUNNING = 0; + + /** + * Threads are in this state when a primitive is waiting on a promise; + * execution is paused until the promise changes thread status. + * @const + */ + Thread.STATUS_PROMISE_WAIT = 1; + + /** + * Thread status for yield. + * @const + */ + Thread.STATUS_YIELD = 2; + + /** + * Thread status for a single-tick yield. This will be cleared when the + * thread is resumed. + * @const + */ + Thread.STATUS_YIELD_TICK = 3; + + /** + * Thread status for a finished/done thread. + * Thread is in this state when there are no more blocks to execute. + * @const + */ + Thread.STATUS_DONE = 4; + + /** + * Push stack and update stack frames appropriately. + * @param {string} blockId Block ID to push to stack. + */ + Thread.prototype.pushStack = function (blockId) { + this.stack.push(blockId); + // Push an empty stack frame, if we need one. + // Might not, if we just popped the stack. + if (this.stack.length > this.stackFrames.length) { + // Copy warp mode from any higher level. + var warpMode = false; + if (this.stackFrames[this.stackFrames.length - 1]) { + warpMode = this.stackFrames[this.stackFrames.length - 1].warpMode; + } + this.stackFrames.push({ + isLoop: false, // Whether this level of the stack is a loop. + warpMode: warpMode, // Whether this level is in warp mode. + reported: {}, // Collects reported input values. + waitingReporter: null, // Name of waiting reporter. + params: {}, // Procedure parameters. + executionContext: {} // A context passed to block implementations. + }); + } + }; + + /** + * Pop last block on the stack and its stack frame. + * @return {string} Block ID popped from the stack. + */ + Thread.prototype.popStack = function () { + this.stackFrames.pop(); + return this.stack.pop(); + }; + + /** + * Get top stack item. + * @return {?string} Block ID on top of stack. + */ + Thread.prototype.peekStack = function () { + return this.stack[this.stack.length - 1]; + }; + + + /** + * Get top stack frame. + * @return {?Object} Last stack frame stored on this thread. + */ + Thread.prototype.peekStackFrame = function () { + return this.stackFrames[this.stackFrames.length - 1]; + }; + + /** + * Get stack frame above the current top. + * @return {?Object} Second to last stack frame stored on this thread. + */ + Thread.prototype.peekParentStackFrame = function () { + return this.stackFrames[this.stackFrames.length - 2]; + }; + + /** + * Push a reported value to the parent of the current stack frame. + * @param {*} value Reported value to push. + */ + Thread.prototype.pushReportedValue = function (value) { + var parentStackFrame = this.peekParentStackFrame(); + if (parentStackFrame) { + var waitingReporter = parentStackFrame.waitingReporter; + parentStackFrame.reported[waitingReporter] = value; + } + }; + + /** + * Add a parameter to the stack frame. + * Use when calling a procedure with parameter values. + * @param {!string} paramName Name of parameter. + * @param {*} value Value to set for parameter. + */ + Thread.prototype.pushParam = function (paramName, value) { + var stackFrame = this.peekStackFrame(); + stackFrame.params[paramName] = value; + }; + + /** + * Get a parameter at the lowest possible level of the stack. + * @param {!string} paramName Name of parameter. + * @return {*} value Value for parameter. + */ + Thread.prototype.getParam = function (paramName) { + for (var i = this.stackFrames.length - 1; i >= 0; i--) { + var frame = this.stackFrames[i]; + if (frame.params.hasOwnProperty(paramName)) { + return frame.params[paramName]; + } + } + return null; + }; + + /** + * Whether the current execution of a thread is at the top of the stack. + * @return {Boolean} True if execution is at top of the stack. + */ + Thread.prototype.atStackTop = function () { + return this.peekStack() === this.topBlock; + }; + + + /** + * Switch the thread to the next block at the current level of the stack. + * For example, this is used in a standard sequence of blocks, + * where execution proceeds from one block to the next. + */ + Thread.prototype.goToNextBlock = function () { + var nextBlockId = this.target.blocks.getNextBlock(this.peekStack()); + // Copy warp mode to next block. + var warpMode = this.peekStackFrame().warpMode; + // The current block is on the stack - pop it and push the next. + // Note that this could push `null` - that is handled by the sequencer. + this.popStack(); + this.pushStack(nextBlockId); + if (this.peekStackFrame()) { + this.peekStackFrame().warpMode = warpMode; + } + }; + + /** + * Attempt to determine whether a procedure call is recursive, + * by examining the stack. + * @param {!string} procedureCode Procedure code of procedure being called. + * @return {boolean} True if the call appears recursive. + */ + Thread.prototype.isRecursiveCall = function (procedureCode) { + var callCount = 5; // Max number of enclosing procedure calls to examine. + var sp = this.stack.length - 1; + for (var i = sp - 1; i >= 0; i--) { + var block = this.target.blocks.getBlock(this.stack[i]); + if (block.opcode === 'procedures_callnoreturn' && + block.mutation.proccode === procedureCode) { + return true; + } + if (--callCount < 0) return false; + } + return false; + }; + + module.exports = Thread; + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + var log = __webpack_require__(11); + var Thread = __webpack_require__(9); + + /** + * Utility function to determine if a value is a Promise. + * @param {*} value Value to check for a Promise. + * @return {Boolean} True if the value appears to be a Promise. + */ + var isPromise = function (value) { + return value && value.then && typeof value.then === 'function'; + }; + + /** + * Execute a block. + * @param {!Sequencer} sequencer Which sequencer is executing. + * @param {!Thread} thread Thread which to read and execute. + */ + var execute = function (sequencer, thread) { + var runtime = sequencer.runtime; + var target = thread.target; + + // Current block to execute is the one on the top of the stack. + var currentBlockId = thread.peekStack(); + var currentStackFrame = thread.peekStackFrame(); + + // Check where the block lives: target blocks or flyout blocks. + var targetHasBlock = ( + typeof target.blocks.getBlock(currentBlockId) !== 'undefined' + ); + var flyoutHasBlock = ( + typeof runtime.flyoutBlocks.getBlock(currentBlockId) !== 'undefined' + ); + + // Stop if block or target no longer exists. + if (!target || (!targetHasBlock && !flyoutHasBlock)) { + // No block found: stop the thread; script no longer exists. + sequencer.retireThread(thread); + return; + } + + // Query info about the block. + var blockContainer = null; + if (targetHasBlock) { + blockContainer = target.blocks; + } else { + blockContainer = runtime.flyoutBlocks; + } + var opcode = blockContainer.getOpcode(currentBlockId); + var fields = blockContainer.getFields(currentBlockId); + var inputs = blockContainer.getInputs(currentBlockId); + var blockFunction = runtime.getOpcodeFunction(opcode); + var isHat = runtime.getIsHat(opcode); + + + if (!opcode) { + log.warn('Could not get opcode for block: ' + currentBlockId); + return; + } + + /** + * Handle any reported value from the primitive, either directly returned + * or after a promise resolves. + * @param {*} resolvedValue Value eventually returned from the primitive. + */ + var handleReport = function (resolvedValue) { + thread.pushReportedValue(resolvedValue); + if (isHat) { + // Hat predicate was evaluated. + if (runtime.getIsEdgeActivatedHat(opcode)) { + // If this is an edge-activated hat, only proceed if + // the value is true and used to be false. + var oldEdgeValue = runtime.updateEdgeActivatedValue( + currentBlockId, + resolvedValue + ); + var edgeWasActivated = !oldEdgeValue && resolvedValue; + if (!edgeWasActivated) { + sequencer.retireThread(thread); + } + } else { + // Not an edge-activated hat: retire the thread + // if predicate was false. + if (!resolvedValue) { + sequencer.retireThread(thread); + } + } + } else { + // In a non-hat, report the value visually if necessary if + // at the top of the thread stack. + if (typeof resolvedValue !== 'undefined' && thread.atStackTop()) { + runtime.visualReport(currentBlockId, resolvedValue); + } + // Finished any yields. + thread.status = Thread.STATUS_RUNNING; + } + }; + + // Hats and single-field shadows are implemented slightly differently + // from regular blocks. + // For hats: if they have an associated block function, + // it's treated as a predicate; if not, execution will proceed as a no-op. + // For single-field shadows: If the block has a single field, and no inputs, + // immediately return the value of the field. + if (!blockFunction) { + if (isHat) { + // Skip through the block (hat with no predicate). + return; + } else { + if (Object.keys(fields).length === 1 && + Object.keys(inputs).length === 0) { + // One field and no inputs - treat as arg. + for (var fieldKey in fields) { // One iteration. + handleReport(fields[fieldKey].value); + } + } else { + log.warn('Could not get implementation for opcode: ' + + opcode); + } + thread.requestScriptGlowInFrame = true; + return; + } + } + + // Generate values for arguments (inputs). + var argValues = {}; + + // Add all fields on this block to the argValues. + for (var fieldName in fields) { + argValues[fieldName] = fields[fieldName].value; + } + + // Recursively evaluate input blocks. + for (var inputName in inputs) { + var input = inputs[inputName]; + var inputBlockId = input.block; + // Is there no value for this input waiting in the stack frame? + if (typeof currentStackFrame.reported[inputName] === 'undefined' && + inputBlockId) { + // If there's not, we need to evaluate the block. + // Push to the stack to evaluate the reporter block. + thread.pushStack(inputBlockId); + // Save name of input for `Thread.pushReportedValue`. + currentStackFrame.waitingReporter = inputName; + // Actually execute the block. + execute(sequencer, thread); + if (thread.status === Thread.STATUS_PROMISE_WAIT) { + return; + } else { + // Execution returned immediately, + // and presumably a value was reported, so pop the stack. + currentStackFrame.waitingReporter = null; + thread.popStack(); + } + } + argValues[inputName] = currentStackFrame.reported[inputName]; + } + + // Add any mutation to args (e.g., for procedures). + var mutation = blockContainer.getMutation(currentBlockId); + if (mutation) { + argValues.mutation = mutation; + } + + // If we've gotten this far, all of the input blocks are evaluated, + // and `argValues` is fully populated. So, execute the block primitive. + // First, clear `currentStackFrame.reported`, so any subsequent execution + // (e.g., on return from a branch) gets fresh inputs. + currentStackFrame.reported = {}; + + var primitiveReportedValue = null; + primitiveReportedValue = blockFunction(argValues, { + stackFrame: currentStackFrame.executionContext, + target: target, + yield: function () { + thread.status = Thread.STATUS_YIELD; + }, + startBranch: function (branchNum, isLoop) { + sequencer.stepToBranch(thread, branchNum, isLoop); + }, + stopAll: function () { + runtime.stopAll(); + }, + stopOtherTargetThreads: function () { + runtime.stopForTarget(target, thread); + }, + stopThread: function () { + sequencer.retireThread(thread); + }, + startProcedure: function (procedureCode) { + sequencer.stepToProcedure(thread, procedureCode); + }, + getProcedureParamNames: function (procedureCode) { + return blockContainer.getProcedureParamNames(procedureCode); + }, + pushParam: function (paramName, paramValue) { + thread.pushParam(paramName, paramValue); + }, + getParam: function (paramName) { + return thread.getParam(paramName); + }, + startHats: function (requestedHat, optMatchFields, optTarget) { + return ( + runtime.startHats(requestedHat, optMatchFields, optTarget) + ); + }, + ioQuery: function (device, func, args) { + // Find the I/O device and execute the query/function call. + if (runtime.ioDevices[device] && runtime.ioDevices[device][func]) { + var devObject = runtime.ioDevices[device]; + // @todo Figure out why eslint complains about no-useless-call + // no-useless-call can't tell if the call is useless for dynamic + // expressions... or something. Not exactly sure why it + // complains here. + // eslint-disable-next-line no-useless-call + return devObject[func].call(devObject, args); + } + } + }); + + if (typeof primitiveReportedValue === 'undefined') { + // No value reported - potentially a command block. + // Edge-activated hats don't request a glow; all commands do. + thread.requestScriptGlowInFrame = true; + } + + // If it's a promise, wait until promise resolves. + if (isPromise(primitiveReportedValue)) { + if (thread.status === Thread.STATUS_RUNNING) { + // Primitive returned a promise; automatically yield thread. + thread.status = Thread.STATUS_PROMISE_WAIT; + } + // Promise handlers + primitiveReportedValue.then(function (resolvedValue) { + handleReport(resolvedValue); + if (typeof resolvedValue === 'undefined') { + var popped = thread.popStack(); + var nextBlockId = thread.target.blocks.getNextBlock(popped); + thread.pushStack(nextBlockId); + } else { + thread.popStack(); + } + }, function (rejectionReason) { + // Promise rejected: the primitive had some error. + // Log it and proceed. + log.warn('Primitive rejected promise: ', rejectionReason); + thread.status = Thread.STATUS_RUNNING; + thread.popStack(); + }); + } else if (thread.status === Thread.STATUS_RUNNING) { + handleReport(primitiveReportedValue); + } + }; + + module.exports = execute; + + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + var minilog = __webpack_require__(12); + minilog.enable(); + + module.exports = minilog('vm'); + + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + var Minilog = __webpack_require__(13); + + var oldEnable = Minilog.enable, + oldDisable = Minilog.disable, + isChrome = (typeof navigator != 'undefined' && /chrome/i.test(navigator.userAgent)), + console = __webpack_require__(17); + + // Use a more capable logging backend if on Chrome + Minilog.defaultBackend = (isChrome ? console.minilog : console); + + // apply enable inputs from localStorage and from the URL + if(typeof window != 'undefined') { + try { + Minilog.enable(JSON.parse(window.localStorage['minilogSettings'])); + } catch(e) {} + if(window.location && window.location.search) { + var match = RegExp('[?&]minilog=([^&]*)').exec(window.location.search); + match && Minilog.enable(decodeURIComponent(match[1])); + } + } + + // Make enable also add to localStorage + Minilog.enable = function() { + oldEnable.call(Minilog, true); + try { window.localStorage['minilogSettings'] = JSON.stringify(true); } catch(e) {} + return this; + }; + + Minilog.disable = function() { + oldDisable.call(Minilog); + try { delete window.localStorage.minilogSettings; } catch(e) {} + return this; + }; + + exports = module.exports = Minilog; + + exports.backends = { + array: __webpack_require__(21), + browser: Minilog.defaultBackend, + localStorage: __webpack_require__(22), + jQuery: __webpack_require__(23) + }; + + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + var Transform = __webpack_require__(14), + Filter = __webpack_require__(16); + + var log = new Transform(), + slice = Array.prototype.slice; + + exports = module.exports = function create(name) { + var o = function() { log.write(name, undefined, slice.call(arguments)); return o; }; + o.debug = function() { log.write(name, 'debug', slice.call(arguments)); return o; }; + o.info = function() { log.write(name, 'info', slice.call(arguments)); return o; }; + o.warn = function() { log.write(name, 'warn', slice.call(arguments)); return o; }; + o.error = function() { log.write(name, 'error', slice.call(arguments)); return o; }; + o.log = o.debug; // for interface compliance with Node and browser consoles + o.suggest = exports.suggest; + o.format = log.format; + return o; + }; + + // filled in separately + exports.defaultBackend = exports.defaultFormatter = null; + + exports.pipe = function(dest) { + return log.pipe(dest); + }; + + exports.end = exports.unpipe = exports.disable = function(from) { + return log.unpipe(from); + }; + + exports.Transform = Transform; + exports.Filter = Filter; + // this is the default filter that's applied when .enable() is called normally + // you can bypass it completely and set up your own pipes + exports.suggest = new Filter(); + + exports.enable = function() { + if(exports.defaultFormatter) { + return log.pipe(exports.suggest) // filter + .pipe(exports.defaultFormatter) // formatter + .pipe(exports.defaultBackend); // backend + } + return log.pipe(exports.suggest) // filter + .pipe(exports.defaultBackend); // formatter + }; + + + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + var microee = __webpack_require__(15); + + // Implements a subset of Node's stream.Transform - in a cross-platform manner. + function Transform() {} + + microee.mixin(Transform); + + // The write() signature is different from Node's + // --> makes it much easier to work with objects in logs. + // One of the lessons from v1 was that it's better to target + // a good browser rather than the lowest common denominator + // internally. + // If you want to use external streams, pipe() to ./stringify.js first. + Transform.prototype.write = function(name, level, args) { + this.emit('item', name, level, args); + }; + + Transform.prototype.end = function() { + this.emit('end'); + this.removeAllListeners(); + }; + + Transform.prototype.pipe = function(dest) { + var s = this; + // prevent double piping + s.emit('unpipe', dest); + // tell the dest that it's being piped to + dest.emit('pipe', s); + + function onItem() { + dest.write.apply(dest, Array.prototype.slice.call(arguments)); + } + function onEnd() { !dest._isStdio && dest.end(); } + + s.on('item', onItem); + s.on('end', onEnd); + + s.when('unpipe', function(from) { + var match = (from === dest) || typeof from == 'undefined'; + if(match) { + s.removeListener('item', onItem); + s.removeListener('end', onEnd); + dest.emit('unpipe'); + } + return match; + }); + + return dest; + }; + + Transform.prototype.unpipe = function(from) { + this.emit('unpipe', from); + return this; + }; + + Transform.prototype.format = function(dest) { + throw new Error([ + 'Warning: .format() is deprecated in Minilog v2! Use .pipe() instead. For example:', + 'var Minilog = require(\'minilog\');', + 'Minilog', + ' .pipe(Minilog.backends.console.formatClean)', + ' .pipe(Minilog.backends.console);'].join('\n')); + }; + + Transform.mixin = function(dest) { + var o = Transform.prototype, k; + for (k in o) { + o.hasOwnProperty(k) && (dest.prototype[k] = o[k]); + } + }; + + module.exports = Transform; + + +/***/ }, +/* 15 */ +/***/ function(module, exports) { + + function M() { this._events = {}; } + M.prototype = { + on: function(ev, cb) { + this._events || (this._events = {}); + var e = this._events; + (e[ev] || (e[ev] = [])).push(cb); + return this; + }, + removeListener: function(ev, cb) { + var e = this._events[ev] || [], i; + for(i = e.length-1; i >= 0 && e[i]; i--){ + if(e[i] === cb || e[i].cb === cb) { e.splice(i, 1); } + } + }, + removeAllListeners: function(ev) { + if(!ev) { this._events = {}; } + else { this._events[ev] && (this._events[ev] = []); } + }, + emit: function(ev) { + this._events || (this._events = {}); + var args = Array.prototype.slice.call(arguments, 1), i, e = this._events[ev] || []; + for(i = e.length-1; i >= 0 && e[i]; i--){ + e[i].apply(this, args); + } + return this; + }, + when: function(ev, cb) { + return this.once(ev, cb, true); + }, + once: function(ev, cb, when) { + if(!cb) return this; + function c() { + if(!when) this.removeListener(ev, c); + if(cb.apply(this, arguments) && when) this.removeListener(ev, c); + } + c.cb = cb; + this.on(ev, c); + return this; + } + }; + M.mixin = function(dest) { + var o = M.prototype, k; + for (k in o) { + o.hasOwnProperty(k) && (dest.prototype[k] = o[k]); + } + }; + module.exports = M; + + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + // default filter + var Transform = __webpack_require__(14); + + var levelMap = { debug: 1, info: 2, warn: 3, error: 4 }; + + function Filter() { + this.enabled = true; + this.defaultResult = true; + this.clear(); + } + + Transform.mixin(Filter); + + // allow all matching, with level >= given level + Filter.prototype.allow = function(name, level) { + this._white.push({ n: name, l: levelMap[level] }); + return this; + }; + + // deny all matching, with level <= given level + Filter.prototype.deny = function(name, level) { + this._black.push({ n: name, l: levelMap[level] }); + return this; + }; + + Filter.prototype.clear = function() { + this._white = []; + this._black = []; + return this; + }; + + function test(rule, name) { + // use .test for RegExps + return (rule.n.test ? rule.n.test(name) : rule.n == name); + }; + + Filter.prototype.test = function(name, level) { + var i, len = Math.max(this._white.length, this._black.length); + for(i = 0; i < len; i++) { + if(this._white[i] && test(this._white[i], name) && levelMap[level] >= this._white[i].l) { + return true; + } + if(this._black[i] && test(this._black[i], name) && levelMap[level] < this._black[i].l) { + return false; + } + } + return this.defaultResult; + }; + + Filter.prototype.write = function(name, level, args) { + if(!this.enabled || this.test(name, level)) { + return this.emit('item', name, level, args); + } + }; + + module.exports = Filter; + + +/***/ }, +/* 17 */ +/***/ function(module, exports, __webpack_require__) { + + var Transform = __webpack_require__(14); + + var newlines = /\n+$/, + logger = new Transform(); + + logger.write = function(name, level, args) { + var i = args.length-1; + if (typeof console === 'undefined' || !console.log) { + return; + } + if(console.log.apply) { + return console.log.apply(console, [name, level].concat(args)); + } else if(JSON && JSON.stringify) { + // console.log.apply is undefined in IE8 and IE9 + // for IE8/9: make console.log at least a bit less awful + if(args[i] && typeof args[i] == 'string') { + args[i] = args[i].replace(newlines, ''); + } + try { + for(i = 0; i < args.length; i++) { + args[i] = JSON.stringify(args[i]); + } + } catch(e) {} + console.log(args.join(' ')); + } + }; + + logger.formatters = ['color', 'minilog']; + logger.color = __webpack_require__(18); + logger.minilog = __webpack_require__(20); + + module.exports = logger; + + +/***/ }, +/* 18 */ +/***/ function(module, exports, __webpack_require__) { + + var Transform = __webpack_require__(14), + color = __webpack_require__(19); + + var colors = { debug: ['cyan'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] }, + logger = new Transform(); + + logger.write = function(name, level, args) { + var fn = console.log; + if(console[level] && console[level].apply) { + fn = console[level]; + fn.apply(console, [ '%c'+name+' %c'+level, color('gray'), color.apply(color, colors[level])].concat(args)); + } + }; + + // NOP, because piping the formatted logs can only cause trouble. + logger.pipe = function() { }; + + module.exports = logger; + + +/***/ }, +/* 19 */ +/***/ function(module, exports) { + + var hex = { + black: '#000', + red: '#c23621', + green: '#25bc26', + yellow: '#bbbb00', + blue: '#492ee1', + magenta: '#d338d3', + cyan: '#33bbc8', + gray: '#808080', + purple: '#708' + }; + function color(fg, isInverse) { + if(isInverse) { + return 'color: #fff; background: '+hex[fg]+';'; + } else { + return 'color: '+hex[fg]+';'; + } + } + + module.exports = color; + + +/***/ }, +/* 20 */ +/***/ function(module, exports, __webpack_require__) { + + var Transform = __webpack_require__(14), + color = __webpack_require__(19), + colors = { debug: ['gray'], info: ['purple' ], warn: [ 'yellow', true ], error: [ 'red', true ] }, + logger = new Transform(); + + logger.write = function(name, level, args) { + var fn = console.log; + if(level != 'debug' && console[level]) { + fn = console[level]; + } + + var subset = [], i = 0; + if(level != 'info') { + for(; i < args.length; i++) { + if(typeof args[i] != 'string') break; + } + fn.apply(console, [ '%c'+name +' '+ args.slice(0, i).join(' '), color.apply(color, colors[level]) ].concat(args.slice(i))); + } else { + fn.apply(console, [ '%c'+name, color.apply(color, colors[level]) ].concat(args)); + } + }; + + // NOP, because piping the formatted logs can only cause trouble. + logger.pipe = function() { }; + + module.exports = logger; + + +/***/ }, +/* 21 */ +/***/ function(module, exports, __webpack_require__) { + + var Transform = __webpack_require__(14), + cache = [ ]; + + var logger = new Transform(); + + logger.write = function(name, level, args) { + cache.push([ name, level, args ]); + }; + + // utility functions + logger.get = function() { return cache; }; + logger.empty = function() { cache = []; }; + + module.exports = logger; + + +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { + + var Transform = __webpack_require__(14), + cache = false; + + var logger = new Transform(); + + logger.write = function(name, level, args) { + if(typeof window == 'undefined' || typeof JSON == 'undefined' || !JSON.stringify || !JSON.parse) return; + try { + if(!cache) { cache = (window.localStorage.minilog ? JSON.parse(window.localStorage.minilog) : []); } + cache.push([ new Date().toString(), name, level, args ]); + window.localStorage.minilog = JSON.stringify(cache); + } catch(e) {} + }; + + module.exports = logger; + +/***/ }, +/* 23 */ +/***/ function(module, exports, __webpack_require__) { + + var Transform = __webpack_require__(14); + + var cid = new Date().valueOf().toString(36); + + function AjaxLogger(options) { + this.url = options.url || ''; + this.cache = []; + this.timer = null; + this.interval = options.interval || 30*1000; + this.enabled = true; + this.jQuery = window.jQuery; + this.extras = {}; + } + + Transform.mixin(AjaxLogger); + + AjaxLogger.prototype.write = function(name, level, args) { + if(!this.timer) { this.init(); } + this.cache.push([name, level].concat(args)); + }; + + AjaxLogger.prototype.init = function() { + if(!this.enabled || !this.jQuery) return; + var self = this; + this.timer = setTimeout(function() { + var i, logs = [], ajaxData, url = self.url; + if(self.cache.length == 0) return self.init(); + // Test each log line and only log the ones that are valid (e.g. don't have circular references). + // Slight performance hit but benefit is we log all valid lines. + for(i = 0; i < self.cache.length; i++) { + try { + JSON.stringify(self.cache[i]); + logs.push(self.cache[i]); + } catch(e) { } + } + if(self.jQuery.isEmptyObject(self.extras)) { + ajaxData = JSON.stringify({ logs: logs }); + url = self.url + '?client_id=' + cid; + } else { + ajaxData = JSON.stringify(self.jQuery.extend({logs: logs}, self.extras)); + } + + self.jQuery.ajax(url, { + type: 'POST', + cache: false, + processData: false, + data: ajaxData, + contentType: 'application/json', + timeout: 10000 + }).success(function(data, status, jqxhr) { + if(data.interval) { + self.interval = Math.max(1000, data.interval); + } + }).error(function() { + self.interval = 30000; + }).always(function() { + self.init(); + }); + self.cache = []; + }, this.interval); + }; + + AjaxLogger.prototype.end = function() {}; + + // wait until jQuery is defined. Useful if you don't control the load order. + AjaxLogger.jQueryWait = function(onDone) { + if(typeof window !== 'undefined' && (window.jQuery || window.$)) { + return onDone(window.jQuery || window.$); + } else if (typeof window !== 'undefined') { + setTimeout(function() { AjaxLogger.jQueryWait(onDone); }, 200); + } + }; + + module.exports = AjaxLogger; + + +/***/ }, +/* 24 */ +/***/ function(module, exports, __webpack_require__) { + + var adapter = __webpack_require__(25); + var mutationAdapter = __webpack_require__(26); + var xmlEscape = __webpack_require__(78); + + /** + * @fileoverview + * Store and mutate the VM block representation, + * and handle updates from Scratch Blocks events. + */ + + var Blocks = function () { + /** + * All blocks in the workspace. + * Keys are block IDs, values are metadata about the block. + * @type {Object.} + */ + this._blocks = {}; + + /** + * All top-level scripts in the workspace. + * A list of block IDs that represent scripts (i.e., first block in script). + * @type {Array.} + */ + this._scripts = []; + }; + + /** + * Blockly inputs that represent statements/branch. + * are prefixed with this string. + * @const{string} + */ + Blocks.BRANCH_INPUT_PREFIX = 'SUBSTACK'; + + /** + * Provide an object with metadata for the requested block ID. + * @param {!string} blockId ID of block we have stored. + * @return {?Object} Metadata about the block, if it exists. + */ + Blocks.prototype.getBlock = function (blockId) { + return this._blocks[blockId]; + }; + + /** + * Get all known top-level blocks that start scripts. + * @return {Array.} List of block IDs. + */ + Blocks.prototype.getScripts = function () { + return this._scripts; + }; + + /** + * Get the next block for a particular block + * @param {?string} id ID of block to get the next block for + * @return {?string} ID of next block in the sequence + */ + Blocks.prototype.getNextBlock = function (id) { + if (typeof this._blocks[id] === 'undefined') return null; + return this._blocks[id].next; + }; + + /** + * Get the branch for a particular C-shaped block. + * @param {?string} id ID for block to get the branch for. + * @param {?number} branchNum Which branch to select (e.g. for if-else). + * @return {?string} ID of block in the branch. + */ + Blocks.prototype.getBranch = function (id, branchNum) { + var block = this._blocks[id]; + if (typeof block === 'undefined') return null; + if (!branchNum) branchNum = 1; + + var inputName = Blocks.BRANCH_INPUT_PREFIX; + if (branchNum > 1) { + inputName += branchNum; + } + + // Empty C-block? + if (!(inputName in block.inputs)) return null; + return block.inputs[inputName].block; + }; + + /** + * Get the opcode for a particular block + * @param {?string} id ID of block to query + * @return {?string} the opcode corresponding to that block + */ + Blocks.prototype.getOpcode = function (id) { + if (typeof this._blocks[id] === 'undefined') return null; + return this._blocks[id].opcode; + }; + + /** + * Get all fields and their values for a block. + * @param {?string} id ID of block to query. + * @return {!Object} All fields and their values. + */ + Blocks.prototype.getFields = function (id) { + if (typeof this._blocks[id] === 'undefined') return null; + return this._blocks[id].fields; + }; + + /** + * Get all non-branch inputs for a block. + * @param {?string} id ID of block to query. + * @return {!Object} All non-branch inputs and their associated blocks. + */ + Blocks.prototype.getInputs = function (id) { + if (typeof this._blocks[id] === 'undefined') return null; + var inputs = {}; + for (var input in this._blocks[id].inputs) { + // Ignore blocks prefixed with branch prefix. + if (input.substring(0, Blocks.BRANCH_INPUT_PREFIX.length) !== + Blocks.BRANCH_INPUT_PREFIX) { + inputs[input] = this._blocks[id].inputs[input]; + } + } + return inputs; + }; + + /** + * Get mutation data for a block. + * @param {?string} id ID of block to query. + * @return {!Object} Mutation for the block. + */ + Blocks.prototype.getMutation = function (id) { + if (typeof this._blocks[id] === 'undefined') return null; + return this._blocks[id].mutation; + }; + + /** + * Get the top-level script for a given block. + * @param {?string} id ID of block to query. + * @return {?string} ID of top-level script block. + */ + Blocks.prototype.getTopLevelScript = function (id) { + if (typeof this._blocks[id] === 'undefined') return null; + var block = this._blocks[id]; + while (block.parent !== null) { + block = this._blocks[block.parent]; + } + return block.id; + }; + + /** + * Get the procedure definition for a given name. + * @param {?string} name Name of procedure to query. + * @return {?string} ID of procedure definition. + */ + Blocks.prototype.getProcedureDefinition = function (name) { + for (var id in this._blocks) { + var block = this._blocks[id]; + if ((block.opcode === 'procedures_defnoreturn' || + block.opcode === 'procedures_defreturn') && + block.mutation.proccode === name) { + return id; + } + } + return null; + }; + + /** + * Get the procedure definition for a given name. + * @param {?string} name Name of procedure to query. + * @return {?string} ID of procedure definition. + */ + Blocks.prototype.getProcedureParamNames = function (name) { + for (var id in this._blocks) { + var block = this._blocks[id]; + if ((block.opcode === 'procedures_defnoreturn' || + block.opcode === 'procedures_defreturn') && + block.mutation.proccode === name) { + return JSON.parse(block.mutation.argumentnames); + } + } + return null; + }; + + // --------------------------------------------------------------------- + + /** + * Create event listener for blocks. Handles validation and serves as a generic + * adapter between the blocks and the runtime interface. + * @param {Object} e Blockly "block" event + * @param {?Runtime} optRuntime Optional runtime to forward click events to. + */ + + Blocks.prototype.blocklyListen = function (e, optRuntime) { + // Validate event + if (typeof e !== 'object') return; + if (typeof e.blockId !== 'string') return; + + // UI event: clicked scripts toggle in the runtime. + if (e.element === 'stackclick') { + if (optRuntime) { + optRuntime.toggleScript(e.blockId); + } + return; + } + + // Block create/update/destroy + switch (e.type) { + case 'create': + var newBlocks = adapter(e); + // A create event can create many blocks. Add them all. + for (var i = 0; i < newBlocks.length; i++) { + this.createBlock(newBlocks[i]); + } + break; + case 'change': + this.changeBlock({ + id: e.blockId, + element: e.element, + name: e.name, + value: e.newValue + }); + break; + case 'move': + this.moveBlock({ + id: e.blockId, + oldParent: e.oldParentId, + oldInput: e.oldInputName, + newParent: e.newParentId, + newInput: e.newInputName, + newCoordinate: e.newCoordinate + }); + break; + case 'delete': + // Don't accept delete events for missing blocks, + // or shadow blocks being obscured. + if (!this._blocks.hasOwnProperty(e.blockId) || + this._blocks[e.blockId].shadow) { + return; + } + // Inform any runtime to forget about glows on this script. + if (optRuntime && this._blocks[e.blockId].topLevel) { + optRuntime.quietGlow(e.blockId); + } + this.deleteBlock({ + id: e.blockId + }); + break; + } + }; + + // --------------------------------------------------------------------- + + /** + * Block management: create blocks and scripts from a `create` event + * @param {!Object} block Blockly create event to be processed + */ + Blocks.prototype.createBlock = function (block) { + // Does the block already exist? + // Could happen, e.g., for an unobscured shadow. + if (this._blocks.hasOwnProperty(block.id)) { + return; + } + // Create new block. + this._blocks[block.id] = block; + // Push block id to scripts array. + // Blocks are added as a top-level stack if they are marked as a top-block + // (if they were top-level XML in the event). + if (block.topLevel) { + this._addScript(block.id); + } + }; + + /** + * Block management: change block field values + * @param {!Object} args Blockly change event to be processed + */ + Blocks.prototype.changeBlock = function (args) { + // Validate + if (args.element !== 'field' && args.element !== 'mutation') return; + if (typeof this._blocks[args.id] === 'undefined') return; + + if (args.element === 'field') { + // Update block value + if (!this._blocks[args.id].fields[args.name]) return; + this._blocks[args.id].fields[args.name].value = args.value; + } else if (args.element === 'mutation') { + this._blocks[args.id].mutation = mutationAdapter(args.value); + } + }; + + /** + * Block management: move blocks from parent to parent + * @param {!Object} e Blockly move event to be processed + */ + Blocks.prototype.moveBlock = function (e) { + if (!this._blocks.hasOwnProperty(e.id)) { + return; + } + + // Move coordinate changes. + if (e.newCoordinate) { + this._blocks[e.id].x = e.newCoordinate.x; + this._blocks[e.id].y = e.newCoordinate.y; + } + + // Remove from any old parent. + if (typeof e.oldParent !== 'undefined') { + var oldParent = this._blocks[e.oldParent]; + if (typeof e.oldInput !== 'undefined' && + oldParent.inputs[e.oldInput].block === e.id) { + // This block was connected to the old parent's input. + oldParent.inputs[e.oldInput].block = null; + } else if (oldParent.next === e.id) { + // This block was connected to the old parent's next connection. + oldParent.next = null; + } + this._blocks[e.id].parent = null; + } + + // Has the block become a top-level block? + if (typeof e.newParent === 'undefined') { + this._addScript(e.id); + } else { + // Remove script, if one exists. + this._deleteScript(e.id); + // Otherwise, try to connect it in its new place. + if (typeof e.newInput === 'undefined') { + // Moved to the new parent's next connection. + this._blocks[e.newParent].next = e.id; + } else { + // Moved to the new parent's input. + // Don't obscure the shadow block. + var oldShadow = null; + if (this._blocks[e.newParent].inputs.hasOwnProperty(e.newInput)) { + oldShadow = this._blocks[e.newParent].inputs[e.newInput].shadow; + } + this._blocks[e.newParent].inputs[e.newInput] = { + name: e.newInput, + block: e.id, + shadow: oldShadow + }; + } + this._blocks[e.id].parent = e.newParent; + } + }; + + /** + * Block management: delete blocks and their associated scripts. + * @param {!Object} e Blockly delete event to be processed. + */ + Blocks.prototype.deleteBlock = function (e) { + // @todo In runtime, stop threads running on this script. + + // Get block + var block = this._blocks[e.id]; + + // Delete children + if (block.next !== null) { + this.deleteBlock({id: block.next}); + } + + // Delete inputs (including branches) + for (var input in block.inputs) { + // If it's null, the block in this input moved away. + if (block.inputs[input].block !== null) { + this.deleteBlock({id: block.inputs[input].block}); + } + // Delete obscured shadow blocks. + if (block.inputs[input].shadow !== null && + block.inputs[input].shadow !== block.inputs[input].block) { + this.deleteBlock({id: block.inputs[input].shadow}); + } + } + + // Delete any script starting with this block. + this._deleteScript(e.id); + + // Delete block itself. + delete this._blocks[e.id]; + }; + + // --------------------------------------------------------------------- + + /** + * Encode all of `this._blocks` as an XML string usable + * by a Blockly/scratch-blocks workspace. + * @return {string} String of XML representing this object's blocks. + */ + Blocks.prototype.toXML = function () { + var xmlString = ''; + for (var i = 0; i < this._scripts.length; i++) { + xmlString += this.blockToXML(this._scripts[i]); + } + return xmlString + ''; + }; + + /** + * Recursively encode an individual block and its children + * into a Blockly/scratch-blocks XML string. + * @param {!string} blockId ID of block to encode. + * @return {string} String of XML representing this block and any children. + */ + Blocks.prototype.blockToXML = function (blockId) { + var block = this._blocks[blockId]; + // Encode properties of this block. + var tagName = (block.shadow) ? 'shadow' : 'block'; + var xy = (block.topLevel) ? + ' x="' + block.x + '" y="' + block.y + '"' : + ''; + var xmlString = ''; + xmlString += '<' + tagName + + ' id="' + block.id + '"' + + ' type="' + block.opcode + '"' + + xy + + '>'; + // Add any mutation. Must come before inputs. + if (block.mutation) { + xmlString += this.mutationToXML(block.mutation); + } + // Add any inputs on this block. + for (var input in block.inputs) { + var blockInput = block.inputs[input]; + // Only encode a value tag if the value input is occupied. + if (blockInput.block || blockInput.shadow) { + xmlString += ''; + if (blockInput.block) { + xmlString += this.blockToXML(blockInput.block); + } + if (blockInput.shadow && blockInput.shadow !== blockInput.block) { + // Obscured shadow. + xmlString += this.blockToXML(blockInput.shadow); + } + xmlString += ''; + } + } + // Add any fields on this block. + for (var field in block.fields) { + var blockField = block.fields[field]; + var value = blockField.value; + if (typeof value === 'string') { + value = xmlEscape(blockField.value); + } + xmlString += '' + + value + ''; + } + // Add blocks connected to the next connection. + if (block.next) { + xmlString += '' + this.blockToXML(block.next) + ''; + } + xmlString += ''; + return xmlString; + }; + + /** + * Recursively encode a mutation object to XML. + * @param {!Object} mutation Object representing a mutation. + * @return {string} XML string representing a mutation. + */ + Blocks.prototype.mutationToXML = function (mutation) { + var mutationString = '<' + mutation.tagName; + for (var prop in mutation) { + if (prop === 'children' || prop === 'tagName') continue; + var mutationValue = (typeof mutation[prop] === 'string') ? + xmlEscape(mutation[prop]) : mutation[prop]; + mutationString += ' ' + prop + '="' + mutationValue + '"'; + } + mutationString += '>'; + for (var i = 0; i < mutation.children.length; i++) { + mutationString += this.mutationToXML(mutation.children[i]); + } + mutationString += ''; + return mutationString; + }; + + // --------------------------------------------------------------------- + + /** + * Helper to add a stack to `this._scripts`. + * @param {?string} topBlockId ID of block that starts the script. + */ + Blocks.prototype._addScript = function (topBlockId) { + var i = this._scripts.indexOf(topBlockId); + if (i > -1) return; // Already in scripts. + this._scripts.push(topBlockId); + // Update `topLevel` property on the top block. + this._blocks[topBlockId].topLevel = true; + }; + + /** + * Helper to remove a script from `this._scripts`. + * @param {?string} topBlockId ID of block that starts the script. + */ + Blocks.prototype._deleteScript = function (topBlockId) { + var i = this._scripts.indexOf(topBlockId); + if (i > -1) this._scripts.splice(i, 1); + // Update `topLevel` property on the top block. + if (this._blocks[topBlockId]) this._blocks[topBlockId].topLevel = false; + }; + + module.exports = Blocks; + + +/***/ }, +/* 25 */ +/***/ function(module, exports, __webpack_require__) { + + var mutationAdapter = __webpack_require__(26); + var html = __webpack_require__(27); + + /** + * Convert outer blocks DOM from a Blockly CREATE event + * to a usable form for the Scratch runtime. + * This structure is based on Blockly xml.js:`domToWorkspace` and `domToBlock`. + * @param {Element} blocksDOM DOM tree for this event. + * @return {Array.} Usable list of blocks from this CREATE event. + */ + var domToBlocks = function (blocksDOM) { + // At this level, there could be multiple blocks adjacent in the DOM tree. + var blocks = {}; + for (var i = 0; i < blocksDOM.length; i++) { + var block = blocksDOM[i]; + if (!block.name || !block.attribs) { + continue; + } + var tagName = block.name.toLowerCase(); + if (tagName === 'block' || tagName === 'shadow') { + domToBlock(block, blocks, true, null); + } + } + // Flatten blocks object into a list. + var blocksList = []; + for (var b in blocks) { + blocksList.push(blocks[b]); + } + return blocksList; + }; + + /** + * Adapter between block creation events and block representation which can be + * used by the Scratch runtime. + * @param {Object} e `Blockly.events.create` + * @return {Array.} List of blocks from this CREATE event. + */ + var adapter = function (e) { + // Validate input + if (typeof e !== 'object') return; + if (typeof e.xml !== 'object') return; + + return domToBlocks(html.parseDOM(e.xml.outerHTML)); + }; + + /** + * Convert and an individual block DOM to the representation tree. + * Based on Blockly's `domToBlockHeadless_`. + * @param {Element} blockDOM DOM tree for an individual block. + * @param {Object} blocks Collection of blocks to add to. + * @param {Boolean} isTopBlock Whether blocks at this level are "top blocks." + * @param {?string} parent Parent block ID. + * @return {undefined} + */ + var domToBlock = function (blockDOM, blocks, isTopBlock, parent) { + // Block skeleton. + var block = { + id: blockDOM.attribs.id, // Block ID + opcode: blockDOM.attribs.type, // For execution, "event_whengreenflag". + inputs: {}, // Inputs to this block and the blocks they point to. + fields: {}, // Fields on this block and their values. + next: null, // Next block in the stack, if one exists. + topLevel: isTopBlock, // If this block starts a stack. + parent: parent, // Parent block ID, if available. + shadow: blockDOM.name === 'shadow', // If this represents a shadow/slot. + x: blockDOM.attribs.x, // X position of script, if top-level. + y: blockDOM.attribs.y // Y position of script, if top-level. + }; + + // Add the block to the representation tree. + blocks[block.id] = block; + + // Process XML children and find enclosed blocks, fields, etc. + for (var i = 0; i < blockDOM.children.length; i++) { + var xmlChild = blockDOM.children[i]; + // Enclosed blocks and shadows + var childBlockNode = null; + var childShadowNode = null; + for (var j = 0; j < xmlChild.children.length; j++) { + var grandChildNode = xmlChild.children[j]; + if (!grandChildNode.name) { + // Non-XML tag node. + continue; + } + var grandChildNodeName = grandChildNode.name.toLowerCase(); + if (grandChildNodeName === 'block') { + childBlockNode = grandChildNode; + } else if (grandChildNodeName === 'shadow') { + childShadowNode = grandChildNode; + } + } + + // Use shadow block only if there's no real block node. + if (!childBlockNode && childShadowNode) { + childBlockNode = childShadowNode; + } + + // Not all Blockly-type blocks are handled here, + // as we won't be using all of them for Scratch. + switch (xmlChild.name.toLowerCase()) { + case 'field': + // Add the field to this block. + var fieldName = xmlChild.attribs.name; + var fieldData = ''; + if (xmlChild.children.length > 0 && xmlChild.children[0].data) { + fieldData = xmlChild.children[0].data; + } else { + // If the child of the field with a data property + // doesn't exist, set the data to an empty string. + fieldData = ''; + } + block.fields[fieldName] = { + name: fieldName, + value: fieldData + }; + break; + case 'value': + case 'statement': + // Recursively generate block structure for input block. + domToBlock(childBlockNode, blocks, false, block.id); + if (childShadowNode && childBlockNode !== childShadowNode) { + // Also generate the shadow block. + domToBlock(childShadowNode, blocks, false, block.id); + } + // Link this block's input to the child block. + var inputName = xmlChild.attribs.name; + block.inputs[inputName] = { + name: inputName, + block: childBlockNode.attribs.id, + shadow: childShadowNode ? childShadowNode.attribs.id : null + }; + break; + case 'next': + if (!childBlockNode || !childBlockNode.attribs) { + // Invalid child block. + continue; + } + // Recursively generate block structure for next block. + domToBlock(childBlockNode, blocks, false, block.id); + // Link next block to this block. + block.next = childBlockNode.attribs.id; + break; + case 'mutation': + block.mutation = mutationAdapter(xmlChild); + break; + } + } + }; + + module.exports = adapter; + + +/***/ }, +/* 26 */ +/***/ function(module, exports, __webpack_require__) { + + var html = __webpack_require__(27); + + /** + * Convert a part of a mutation DOM to a mutation VM object, recursively. + * @param {Object} dom DOM object for mutation tag. + * @return {Object} Object representing useful parts of this mutation. + */ + var mutatorTagToObject = function (dom) { + var obj = Object.create(null); + obj.tagName = dom.name; + obj.children = []; + for (var prop in dom.attribs) { + if (prop === 'xmlns') continue; + obj[prop] = dom.attribs[prop]; + } + for (var i = 0; i < dom.children.length; i++) { + obj.children.push( + mutatorTagToObject(dom.children[i]) + ); + } + return obj; + }; + + /** + * Adapter between mutator XML or DOM and block representation which can be + * used by the Scratch runtime. + * @param {(Object|string)} mutation Mutation XML string or DOM. + * @return {Object} Object representing the mutation. + */ + var mutationAdpater = function (mutation) { + var mutationParsed; + // Check if the mutation is already parsed; if not, parse it. + if (typeof mutation === 'object') { + mutationParsed = mutation; + } else { + mutationParsed = html.parseDOM(mutation)[0]; + } + return mutatorTagToObject(mutationParsed); + }; + + module.exports = mutationAdpater; + + +/***/ }, +/* 27 */ +/***/ function(module, exports, __webpack_require__) { + + var Parser = __webpack_require__(28), + DomHandler = __webpack_require__(35); + + function defineProp(name, value){ + delete module.exports[name]; + module.exports[name] = value; + return value; + } + + module.exports = { + Parser: Parser, + Tokenizer: __webpack_require__(29), + ElementType: __webpack_require__(36), + DomHandler: DomHandler, + get FeedHandler(){ + return defineProp("FeedHandler", __webpack_require__(39)); + }, + get Stream(){ + return defineProp("Stream", __webpack_require__(40)); + }, + get WritableStream(){ + return defineProp("WritableStream", __webpack_require__(41)); + }, + get ProxyHandler(){ + return defineProp("ProxyHandler", __webpack_require__(64)); + }, + get DomUtils(){ + return defineProp("DomUtils", __webpack_require__(65)); + }, + get CollectingHandler(){ + return defineProp("CollectingHandler", __webpack_require__(77)); + }, + // For legacy support + DefaultHandler: DomHandler, + get RssHandler(){ + return defineProp("RssHandler", this.FeedHandler); + }, + //helper methods + parseDOM: function(data, options){ + var handler = new DomHandler(options); + new Parser(handler, options).end(data); + return handler.dom; + }, + parseFeed: function(feed, options){ + var handler = new module.exports.FeedHandler(options); + new Parser(handler, options).end(feed); + return handler.dom; + }, + createDomStream: function(cb, options, elementCb){ + var handler = new DomHandler(cb, options, elementCb); + return new Parser(handler, options); + }, + // List of all events that the parser emits + EVENTS: { /* Format: eventname: number of arguments */ + attribute: 2, + cdatastart: 0, + cdataend: 0, + text: 1, + processinginstruction: 2, + comment: 1, + commentend: 0, + closetag: 1, + opentag: 2, + opentagname: 1, + error: 1, + end: 0 + } + }; + + +/***/ }, +/* 28 */ +/***/ function(module, exports, __webpack_require__) { + + var Tokenizer = __webpack_require__(29); + + /* + Options: + + xmlMode: Disables the special behavior for script/style tags (false by default) + lowerCaseAttributeNames: call .toLowerCase for each attribute name (true if xmlMode is `false`) + lowerCaseTags: call .toLowerCase for each tag name (true if xmlMode is `false`) + */ + + /* + Callbacks: + + oncdataend, + oncdatastart, + onclosetag, + oncomment, + oncommentend, + onerror, + onopentag, + onprocessinginstruction, + onreset, + ontext + */ + + var formTags = { + input: true, + option: true, + optgroup: true, + select: true, + button: true, + datalist: true, + textarea: true + }; + + var openImpliesClose = { + tr : { tr:true, th:true, td:true }, + th : { th:true }, + td : { thead:true, th:true, td:true }, + body : { head:true, link:true, script:true }, + li : { li:true }, + p : { p:true }, + h1 : { p:true }, + h2 : { p:true }, + h3 : { p:true }, + h4 : { p:true }, + h5 : { p:true }, + h6 : { p:true }, + select : formTags, + input : formTags, + output : formTags, + button : formTags, + datalist: formTags, + textarea: formTags, + option : { option:true }, + optgroup: { optgroup:true } + }; + + var voidElements = { + __proto__: null, + area: true, + base: true, + basefont: true, + br: true, + col: true, + command: true, + embed: true, + frame: true, + hr: true, + img: true, + input: true, + isindex: true, + keygen: true, + link: true, + meta: true, + param: true, + source: true, + track: true, + wbr: true, + + //common self closing svg elements + path: true, + circle: true, + ellipse: true, + line: true, + rect: true, + use: true, + stop: true, + polyline: true, + polygon: true + }; + + var re_nameEnd = /\s|\//; + + function Parser(cbs, options){ + this._options = options || {}; + this._cbs = cbs || {}; + + this._tagname = ""; + this._attribname = ""; + this._attribvalue = ""; + this._attribs = null; + this._stack = []; + + this.startIndex = 0; + this.endIndex = null; + + this._lowerCaseTagNames = "lowerCaseTags" in this._options ? + !!this._options.lowerCaseTags : + !this._options.xmlMode; + this._lowerCaseAttributeNames = "lowerCaseAttributeNames" in this._options ? + !!this._options.lowerCaseAttributeNames : + !this._options.xmlMode; + if(!!this._options.Tokenizer) { + Tokenizer = this._options.Tokenizer; + } + this._tokenizer = new Tokenizer(this._options, this); + + if(this._cbs.onparserinit) this._cbs.onparserinit(this); + } + + __webpack_require__(2).inherits(Parser, __webpack_require__(1).EventEmitter); + + Parser.prototype._updatePosition = function(initialOffset){ + if(this.endIndex === null){ + if(this._tokenizer._sectionStart <= initialOffset){ + this.startIndex = 0; + } else { + this.startIndex = this._tokenizer._sectionStart - initialOffset; + } + } + else this.startIndex = this.endIndex + 1; + this.endIndex = this._tokenizer.getAbsoluteIndex(); + }; + + //Tokenizer event handlers + Parser.prototype.ontext = function(data){ + this._updatePosition(1); + this.endIndex--; + + if(this._cbs.ontext) this._cbs.ontext(data); + }; + + Parser.prototype.onopentagname = function(name){ + if(this._lowerCaseTagNames){ + name = name.toLowerCase(); + } + + this._tagname = name; + + if(!this._options.xmlMode && name in openImpliesClose) { + for( + var el; + (el = this._stack[this._stack.length - 1]) in openImpliesClose[name]; + this.onclosetag(el) + ); + } + + if(this._options.xmlMode || !(name in voidElements)){ + this._stack.push(name); + } + + if(this._cbs.onopentagname) this._cbs.onopentagname(name); + if(this._cbs.onopentag) this._attribs = {}; + }; + + Parser.prototype.onopentagend = function(){ + this._updatePosition(1); + + if(this._attribs){ + if(this._cbs.onopentag) this._cbs.onopentag(this._tagname, this._attribs); + this._attribs = null; + } + + if(!this._options.xmlMode && this._cbs.onclosetag && this._tagname in voidElements){ + this._cbs.onclosetag(this._tagname); + } + + this._tagname = ""; + }; + + Parser.prototype.onclosetag = function(name){ + this._updatePosition(1); + + if(this._lowerCaseTagNames){ + name = name.toLowerCase(); + } + + if(this._stack.length && (!(name in voidElements) || this._options.xmlMode)){ + var pos = this._stack.lastIndexOf(name); + if(pos !== -1){ + if(this._cbs.onclosetag){ + pos = this._stack.length - pos; + while(pos--) this._cbs.onclosetag(this._stack.pop()); + } + else this._stack.length = pos; + } else if(name === "p" && !this._options.xmlMode){ + this.onopentagname(name); + this._closeCurrentTag(); + } + } else if(!this._options.xmlMode && (name === "br" || name === "p")){ + this.onopentagname(name); + this._closeCurrentTag(); + } + }; + + Parser.prototype.onselfclosingtag = function(){ + if(this._options.xmlMode || this._options.recognizeSelfClosing){ + this._closeCurrentTag(); + } else { + this.onopentagend(); + } + }; + + Parser.prototype._closeCurrentTag = function(){ + var name = this._tagname; + + this.onopentagend(); + + //self-closing tags will be on the top of the stack + //(cheaper check than in onclosetag) + if(this._stack[this._stack.length - 1] === name){ + if(this._cbs.onclosetag){ + this._cbs.onclosetag(name); + } + this._stack.pop(); + } + }; + + Parser.prototype.onattribname = function(name){ + if(this._lowerCaseAttributeNames){ + name = name.toLowerCase(); + } + this._attribname = name; + }; + + Parser.prototype.onattribdata = function(value){ + this._attribvalue += value; + }; + + Parser.prototype.onattribend = function(){ + if(this._cbs.onattribute) this._cbs.onattribute(this._attribname, this._attribvalue); + if( + this._attribs && + !Object.prototype.hasOwnProperty.call(this._attribs, this._attribname) + ){ + this._attribs[this._attribname] = this._attribvalue; + } + this._attribname = ""; + this._attribvalue = ""; + }; + + Parser.prototype._getInstructionName = function(value){ + var idx = value.search(re_nameEnd), + name = idx < 0 ? value : value.substr(0, idx); + + if(this._lowerCaseTagNames){ + name = name.toLowerCase(); + } + + return name; + }; + + Parser.prototype.ondeclaration = function(value){ + if(this._cbs.onprocessinginstruction){ + var name = this._getInstructionName(value); + this._cbs.onprocessinginstruction("!" + name, "!" + value); + } + }; + + Parser.prototype.onprocessinginstruction = function(value){ + if(this._cbs.onprocessinginstruction){ + var name = this._getInstructionName(value); + this._cbs.onprocessinginstruction("?" + name, "?" + value); + } + }; + + Parser.prototype.oncomment = function(value){ + this._updatePosition(4); + + if(this._cbs.oncomment) this._cbs.oncomment(value); + if(this._cbs.oncommentend) this._cbs.oncommentend(); + }; + + Parser.prototype.oncdata = function(value){ + this._updatePosition(1); + + if(this._options.xmlMode || this._options.recognizeCDATA){ + if(this._cbs.oncdatastart) this._cbs.oncdatastart(); + if(this._cbs.ontext) this._cbs.ontext(value); + if(this._cbs.oncdataend) this._cbs.oncdataend(); + } else { + this.oncomment("[CDATA[" + value + "]]"); + } + }; + + Parser.prototype.onerror = function(err){ + if(this._cbs.onerror) this._cbs.onerror(err); + }; + + Parser.prototype.onend = function(){ + if(this._cbs.onclosetag){ + for( + var i = this._stack.length; + i > 0; + this._cbs.onclosetag(this._stack[--i]) + ); + } + if(this._cbs.onend) this._cbs.onend(); + }; + + + //Resets the parser to a blank state, ready to parse a new HTML document + Parser.prototype.reset = function(){ + if(this._cbs.onreset) this._cbs.onreset(); + this._tokenizer.reset(); + + this._tagname = ""; + this._attribname = ""; + this._attribs = null; + this._stack = []; + + if(this._cbs.onparserinit) this._cbs.onparserinit(this); + }; + + //Parses a complete HTML document and pushes it to the handler + Parser.prototype.parseComplete = function(data){ + this.reset(); + this.end(data); + }; + + Parser.prototype.write = function(chunk){ + this._tokenizer.write(chunk); + }; + + Parser.prototype.end = function(chunk){ + this._tokenizer.end(chunk); + }; + + Parser.prototype.pause = function(){ + this._tokenizer.pause(); + }; + + Parser.prototype.resume = function(){ + this._tokenizer.resume(); + }; + + //alias for backwards compat + Parser.prototype.parseChunk = Parser.prototype.write; + Parser.prototype.done = Parser.prototype.end; + + module.exports = Parser; + + +/***/ }, +/* 29 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = Tokenizer; + + var decodeCodePoint = __webpack_require__(30), + entityMap = __webpack_require__(32), + legacyMap = __webpack_require__(33), + xmlMap = __webpack_require__(34), + + i = 0, + + TEXT = i++, + BEFORE_TAG_NAME = i++, //after < + IN_TAG_NAME = i++, + IN_SELF_CLOSING_TAG = i++, + BEFORE_CLOSING_TAG_NAME = i++, + IN_CLOSING_TAG_NAME = i++, + AFTER_CLOSING_TAG_NAME = i++, + + //attributes + BEFORE_ATTRIBUTE_NAME = i++, + IN_ATTRIBUTE_NAME = i++, + AFTER_ATTRIBUTE_NAME = i++, + BEFORE_ATTRIBUTE_VALUE = i++, + IN_ATTRIBUTE_VALUE_DQ = i++, // " + IN_ATTRIBUTE_VALUE_SQ = i++, // ' + IN_ATTRIBUTE_VALUE_NQ = i++, + + //declarations + BEFORE_DECLARATION = i++, // ! + IN_DECLARATION = i++, + + //processing instructions + IN_PROCESSING_INSTRUCTION = i++, // ? + + //comments + BEFORE_COMMENT = i++, + IN_COMMENT = i++, + AFTER_COMMENT_1 = i++, + AFTER_COMMENT_2 = i++, + + //cdata + BEFORE_CDATA_1 = i++, // [ + BEFORE_CDATA_2 = i++, // C + BEFORE_CDATA_3 = i++, // D + BEFORE_CDATA_4 = i++, // A + BEFORE_CDATA_5 = i++, // T + BEFORE_CDATA_6 = i++, // A + IN_CDATA = i++, // [ + AFTER_CDATA_1 = i++, // ] + AFTER_CDATA_2 = i++, // ] + + //special tags + BEFORE_SPECIAL = i++, //S + BEFORE_SPECIAL_END = i++, //S + + BEFORE_SCRIPT_1 = i++, //C + BEFORE_SCRIPT_2 = i++, //R + BEFORE_SCRIPT_3 = i++, //I + BEFORE_SCRIPT_4 = i++, //P + BEFORE_SCRIPT_5 = i++, //T + AFTER_SCRIPT_1 = i++, //C + AFTER_SCRIPT_2 = i++, //R + AFTER_SCRIPT_3 = i++, //I + AFTER_SCRIPT_4 = i++, //P + AFTER_SCRIPT_5 = i++, //T + + BEFORE_STYLE_1 = i++, //T + BEFORE_STYLE_2 = i++, //Y + BEFORE_STYLE_3 = i++, //L + BEFORE_STYLE_4 = i++, //E + AFTER_STYLE_1 = i++, //T + AFTER_STYLE_2 = i++, //Y + AFTER_STYLE_3 = i++, //L + AFTER_STYLE_4 = i++, //E + + BEFORE_ENTITY = i++, //& + BEFORE_NUMERIC_ENTITY = i++, //# + IN_NAMED_ENTITY = i++, + IN_NUMERIC_ENTITY = i++, + IN_HEX_ENTITY = i++, //X + + j = 0, + + SPECIAL_NONE = j++, + SPECIAL_SCRIPT = j++, + SPECIAL_STYLE = j++; + + function whitespace(c){ + return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r"; + } + + function characterState(char, SUCCESS){ + return function(c){ + if(c === char) this._state = SUCCESS; + }; + } + + function ifElseState(upper, SUCCESS, FAILURE){ + var lower = upper.toLowerCase(); + + if(upper === lower){ + return function(c){ + if(c === lower){ + this._state = SUCCESS; + } else { + this._state = FAILURE; + this._index--; + } + }; + } else { + return function(c){ + if(c === lower || c === upper){ + this._state = SUCCESS; + } else { + this._state = FAILURE; + this._index--; + } + }; + } + } + + function consumeSpecialNameChar(upper, NEXT_STATE){ + var lower = upper.toLowerCase(); + + return function(c){ + if(c === lower || c === upper){ + this._state = NEXT_STATE; + } else { + this._state = IN_TAG_NAME; + this._index--; //consume the token again + } + }; + } + + function Tokenizer(options, cbs){ + this._state = TEXT; + this._buffer = ""; + this._sectionStart = 0; + this._index = 0; + this._bufferOffset = 0; //chars removed from _buffer + this._baseState = TEXT; + this._special = SPECIAL_NONE; + this._cbs = cbs; + this._running = true; + this._ended = false; + this._xmlMode = !!(options && options.xmlMode); + this._decodeEntities = !!(options && options.decodeEntities); + } + + Tokenizer.prototype._stateText = function(c){ + if(c === "<"){ + if(this._index > this._sectionStart){ + this._cbs.ontext(this._getSection()); + } + this._state = BEFORE_TAG_NAME; + this._sectionStart = this._index; + } else if(this._decodeEntities && this._special === SPECIAL_NONE && c === "&"){ + if(this._index > this._sectionStart){ + this._cbs.ontext(this._getSection()); + } + this._baseState = TEXT; + this._state = BEFORE_ENTITY; + this._sectionStart = this._index; + } + }; + + Tokenizer.prototype._stateBeforeTagName = function(c){ + if(c === "/"){ + this._state = BEFORE_CLOSING_TAG_NAME; + } else if(c === ">" || this._special !== SPECIAL_NONE || whitespace(c)) { + this._state = TEXT; + } else if(c === "!"){ + this._state = BEFORE_DECLARATION; + this._sectionStart = this._index + 1; + } else if(c === "?"){ + this._state = IN_PROCESSING_INSTRUCTION; + this._sectionStart = this._index + 1; + } else if(c === "<"){ + this._cbs.ontext(this._getSection()); + this._sectionStart = this._index; + } else { + this._state = (!this._xmlMode && (c === "s" || c === "S")) ? + BEFORE_SPECIAL : IN_TAG_NAME; + this._sectionStart = this._index; + } + }; + + Tokenizer.prototype._stateInTagName = function(c){ + if(c === "/" || c === ">" || whitespace(c)){ + this._emitToken("onopentagname"); + this._state = BEFORE_ATTRIBUTE_NAME; + this._index--; + } + }; + + Tokenizer.prototype._stateBeforeCloseingTagName = function(c){ + if(whitespace(c)); + else if(c === ">"){ + this._state = TEXT; + } else if(this._special !== SPECIAL_NONE){ + if(c === "s" || c === "S"){ + this._state = BEFORE_SPECIAL_END; + } else { + this._state = TEXT; + this._index--; + } + } else { + this._state = IN_CLOSING_TAG_NAME; + this._sectionStart = this._index; + } + }; + + Tokenizer.prototype._stateInCloseingTagName = function(c){ + if(c === ">" || whitespace(c)){ + this._emitToken("onclosetag"); + this._state = AFTER_CLOSING_TAG_NAME; + this._index--; + } + }; + + Tokenizer.prototype._stateAfterCloseingTagName = function(c){ + //skip everything until ">" + if(c === ">"){ + this._state = TEXT; + this._sectionStart = this._index + 1; + } + }; + + Tokenizer.prototype._stateBeforeAttributeName = function(c){ + if(c === ">"){ + this._cbs.onopentagend(); + this._state = TEXT; + this._sectionStart = this._index + 1; + } else if(c === "/"){ + this._state = IN_SELF_CLOSING_TAG; + } else if(!whitespace(c)){ + this._state = IN_ATTRIBUTE_NAME; + this._sectionStart = this._index; + } + }; + + Tokenizer.prototype._stateInSelfClosingTag = function(c){ + if(c === ">"){ + this._cbs.onselfclosingtag(); + this._state = TEXT; + this._sectionStart = this._index + 1; + } else if(!whitespace(c)){ + this._state = BEFORE_ATTRIBUTE_NAME; + this._index--; + } + }; + + Tokenizer.prototype._stateInAttributeName = function(c){ + if(c === "=" || c === "/" || c === ">" || whitespace(c)){ + this._cbs.onattribname(this._getSection()); + this._sectionStart = -1; + this._state = AFTER_ATTRIBUTE_NAME; + this._index--; + } + }; + + Tokenizer.prototype._stateAfterAttributeName = function(c){ + if(c === "="){ + this._state = BEFORE_ATTRIBUTE_VALUE; + } else if(c === "/" || c === ">"){ + this._cbs.onattribend(); + this._state = BEFORE_ATTRIBUTE_NAME; + this._index--; + } else if(!whitespace(c)){ + this._cbs.onattribend(); + this._state = IN_ATTRIBUTE_NAME; + this._sectionStart = this._index; + } + }; + + Tokenizer.prototype._stateBeforeAttributeValue = function(c){ + if(c === "\""){ + this._state = IN_ATTRIBUTE_VALUE_DQ; + this._sectionStart = this._index + 1; + } else if(c === "'"){ + this._state = IN_ATTRIBUTE_VALUE_SQ; + this._sectionStart = this._index + 1; + } else if(!whitespace(c)){ + this._state = IN_ATTRIBUTE_VALUE_NQ; + this._sectionStart = this._index; + this._index--; //reconsume token + } + }; + + Tokenizer.prototype._stateInAttributeValueDoubleQuotes = function(c){ + if(c === "\""){ + this._emitToken("onattribdata"); + this._cbs.onattribend(); + this._state = BEFORE_ATTRIBUTE_NAME; + } else if(this._decodeEntities && c === "&"){ + this._emitToken("onattribdata"); + this._baseState = this._state; + this._state = BEFORE_ENTITY; + this._sectionStart = this._index; + } + }; + + Tokenizer.prototype._stateInAttributeValueSingleQuotes = function(c){ + if(c === "'"){ + this._emitToken("onattribdata"); + this._cbs.onattribend(); + this._state = BEFORE_ATTRIBUTE_NAME; + } else if(this._decodeEntities && c === "&"){ + this._emitToken("onattribdata"); + this._baseState = this._state; + this._state = BEFORE_ENTITY; + this._sectionStart = this._index; + } + }; + + Tokenizer.prototype._stateInAttributeValueNoQuotes = function(c){ + if(whitespace(c) || c === ">"){ + this._emitToken("onattribdata"); + this._cbs.onattribend(); + this._state = BEFORE_ATTRIBUTE_NAME; + this._index--; + } else if(this._decodeEntities && c === "&"){ + this._emitToken("onattribdata"); + this._baseState = this._state; + this._state = BEFORE_ENTITY; + this._sectionStart = this._index; + } + }; + + Tokenizer.prototype._stateBeforeDeclaration = function(c){ + this._state = c === "[" ? BEFORE_CDATA_1 : + c === "-" ? BEFORE_COMMENT : + IN_DECLARATION; + }; + + Tokenizer.prototype._stateInDeclaration = function(c){ + if(c === ">"){ + this._cbs.ondeclaration(this._getSection()); + this._state = TEXT; + this._sectionStart = this._index + 1; + } + }; + + Tokenizer.prototype._stateInProcessingInstruction = function(c){ + if(c === ">"){ + this._cbs.onprocessinginstruction(this._getSection()); + this._state = TEXT; + this._sectionStart = this._index + 1; + } + }; + + Tokenizer.prototype._stateBeforeComment = function(c){ + if(c === "-"){ + this._state = IN_COMMENT; + this._sectionStart = this._index + 1; + } else { + this._state = IN_DECLARATION; + } + }; + + Tokenizer.prototype._stateInComment = function(c){ + if(c === "-") this._state = AFTER_COMMENT_1; + }; + + Tokenizer.prototype._stateAfterComment1 = function(c){ + if(c === "-"){ + this._state = AFTER_COMMENT_2; + } else { + this._state = IN_COMMENT; + } + }; + + Tokenizer.prototype._stateAfterComment2 = function(c){ + if(c === ">"){ + //remove 2 trailing chars + this._cbs.oncomment(this._buffer.substring(this._sectionStart, this._index - 2)); + this._state = TEXT; + this._sectionStart = this._index + 1; + } else if(c !== "-"){ + this._state = IN_COMMENT; + } + // else: stay in AFTER_COMMENT_2 (`--->`) + }; + + Tokenizer.prototype._stateBeforeCdata1 = ifElseState("C", BEFORE_CDATA_2, IN_DECLARATION); + Tokenizer.prototype._stateBeforeCdata2 = ifElseState("D", BEFORE_CDATA_3, IN_DECLARATION); + Tokenizer.prototype._stateBeforeCdata3 = ifElseState("A", BEFORE_CDATA_4, IN_DECLARATION); + Tokenizer.prototype._stateBeforeCdata4 = ifElseState("T", BEFORE_CDATA_5, IN_DECLARATION); + Tokenizer.prototype._stateBeforeCdata5 = ifElseState("A", BEFORE_CDATA_6, IN_DECLARATION); + + Tokenizer.prototype._stateBeforeCdata6 = function(c){ + if(c === "["){ + this._state = IN_CDATA; + this._sectionStart = this._index + 1; + } else { + this._state = IN_DECLARATION; + this._index--; + } + }; + + Tokenizer.prototype._stateInCdata = function(c){ + if(c === "]") this._state = AFTER_CDATA_1; + }; + + Tokenizer.prototype._stateAfterCdata1 = characterState("]", AFTER_CDATA_2); + + Tokenizer.prototype._stateAfterCdata2 = function(c){ + if(c === ">"){ + //remove 2 trailing chars + this._cbs.oncdata(this._buffer.substring(this._sectionStart, this._index - 2)); + this._state = TEXT; + this._sectionStart = this._index + 1; + } else if(c !== "]") { + this._state = IN_CDATA; + } + //else: stay in AFTER_CDATA_2 (`]]]>`) + }; + + Tokenizer.prototype._stateBeforeSpecial = function(c){ + if(c === "c" || c === "C"){ + this._state = BEFORE_SCRIPT_1; + } else if(c === "t" || c === "T"){ + this._state = BEFORE_STYLE_1; + } else { + this._state = IN_TAG_NAME; + this._index--; //consume the token again + } + }; + + Tokenizer.prototype._stateBeforeSpecialEnd = function(c){ + if(this._special === SPECIAL_SCRIPT && (c === "c" || c === "C")){ + this._state = AFTER_SCRIPT_1; + } else if(this._special === SPECIAL_STYLE && (c === "t" || c === "T")){ + this._state = AFTER_STYLE_1; + } + else this._state = TEXT; + }; + + Tokenizer.prototype._stateBeforeScript1 = consumeSpecialNameChar("R", BEFORE_SCRIPT_2); + Tokenizer.prototype._stateBeforeScript2 = consumeSpecialNameChar("I", BEFORE_SCRIPT_3); + Tokenizer.prototype._stateBeforeScript3 = consumeSpecialNameChar("P", BEFORE_SCRIPT_4); + Tokenizer.prototype._stateBeforeScript4 = consumeSpecialNameChar("T", BEFORE_SCRIPT_5); + + Tokenizer.prototype._stateBeforeScript5 = function(c){ + if(c === "/" || c === ">" || whitespace(c)){ + this._special = SPECIAL_SCRIPT; + } + this._state = IN_TAG_NAME; + this._index--; //consume the token again + }; + + Tokenizer.prototype._stateAfterScript1 = ifElseState("R", AFTER_SCRIPT_2, TEXT); + Tokenizer.prototype._stateAfterScript2 = ifElseState("I", AFTER_SCRIPT_3, TEXT); + Tokenizer.prototype._stateAfterScript3 = ifElseState("P", AFTER_SCRIPT_4, TEXT); + Tokenizer.prototype._stateAfterScript4 = ifElseState("T", AFTER_SCRIPT_5, TEXT); + + Tokenizer.prototype._stateAfterScript5 = function(c){ + if(c === ">" || whitespace(c)){ + this._special = SPECIAL_NONE; + this._state = IN_CLOSING_TAG_NAME; + this._sectionStart = this._index - 6; + this._index--; //reconsume the token + } + else this._state = TEXT; + }; + + Tokenizer.prototype._stateBeforeStyle1 = consumeSpecialNameChar("Y", BEFORE_STYLE_2); + Tokenizer.prototype._stateBeforeStyle2 = consumeSpecialNameChar("L", BEFORE_STYLE_3); + Tokenizer.prototype._stateBeforeStyle3 = consumeSpecialNameChar("E", BEFORE_STYLE_4); + + Tokenizer.prototype._stateBeforeStyle4 = function(c){ + if(c === "/" || c === ">" || whitespace(c)){ + this._special = SPECIAL_STYLE; + } + this._state = IN_TAG_NAME; + this._index--; //consume the token again + }; + + Tokenizer.prototype._stateAfterStyle1 = ifElseState("Y", AFTER_STYLE_2, TEXT); + Tokenizer.prototype._stateAfterStyle2 = ifElseState("L", AFTER_STYLE_3, TEXT); + Tokenizer.prototype._stateAfterStyle3 = ifElseState("E", AFTER_STYLE_4, TEXT); + + Tokenizer.prototype._stateAfterStyle4 = function(c){ + if(c === ">" || whitespace(c)){ + this._special = SPECIAL_NONE; + this._state = IN_CLOSING_TAG_NAME; + this._sectionStart = this._index - 5; + this._index--; //reconsume the token + } + else this._state = TEXT; + }; + + Tokenizer.prototype._stateBeforeEntity = ifElseState("#", BEFORE_NUMERIC_ENTITY, IN_NAMED_ENTITY); + Tokenizer.prototype._stateBeforeNumericEntity = ifElseState("X", IN_HEX_ENTITY, IN_NUMERIC_ENTITY); + + //for entities terminated with a semicolon + Tokenizer.prototype._parseNamedEntityStrict = function(){ + //offset = 1 + if(this._sectionStart + 1 < this._index){ + var entity = this._buffer.substring(this._sectionStart + 1, this._index), + map = this._xmlMode ? xmlMap : entityMap; + + if(map.hasOwnProperty(entity)){ + this._emitPartial(map[entity]); + this._sectionStart = this._index + 1; + } + } + }; + + + //parses legacy entities (without trailing semicolon) + Tokenizer.prototype._parseLegacyEntity = function(){ + var start = this._sectionStart + 1, + limit = this._index - start; + + if(limit > 6) limit = 6; //the max length of legacy entities is 6 + + while(limit >= 2){ //the min length of legacy entities is 2 + var entity = this._buffer.substr(start, limit); + + if(legacyMap.hasOwnProperty(entity)){ + this._emitPartial(legacyMap[entity]); + this._sectionStart += limit + 1; + return; + } else { + limit--; + } + } + }; + + Tokenizer.prototype._stateInNamedEntity = function(c){ + if(c === ";"){ + this._parseNamedEntityStrict(); + if(this._sectionStart + 1 < this._index && !this._xmlMode){ + this._parseLegacyEntity(); + } + this._state = this._baseState; + } else if((c < "a" || c > "z") && (c < "A" || c > "Z") && (c < "0" || c > "9")){ + if(this._xmlMode); + else if(this._sectionStart + 1 === this._index); + else if(this._baseState !== TEXT){ + if(c !== "="){ + this._parseNamedEntityStrict(); + } + } else { + this._parseLegacyEntity(); + } + + this._state = this._baseState; + this._index--; + } + }; + + Tokenizer.prototype._decodeNumericEntity = function(offset, base){ + var sectionStart = this._sectionStart + offset; + + if(sectionStart !== this._index){ + //parse entity + var entity = this._buffer.substring(sectionStart, this._index); + var parsed = parseInt(entity, base); + + this._emitPartial(decodeCodePoint(parsed)); + this._sectionStart = this._index; + } else { + this._sectionStart--; + } + + this._state = this._baseState; + }; + + Tokenizer.prototype._stateInNumericEntity = function(c){ + if(c === ";"){ + this._decodeNumericEntity(2, 10); + this._sectionStart++; + } else if(c < "0" || c > "9"){ + if(!this._xmlMode){ + this._decodeNumericEntity(2, 10); + } else { + this._state = this._baseState; + } + this._index--; + } + }; + + Tokenizer.prototype._stateInHexEntity = function(c){ + if(c === ";"){ + this._decodeNumericEntity(3, 16); + this._sectionStart++; + } else if((c < "a" || c > "f") && (c < "A" || c > "F") && (c < "0" || c > "9")){ + if(!this._xmlMode){ + this._decodeNumericEntity(3, 16); + } else { + this._state = this._baseState; + } + this._index--; + } + }; + + Tokenizer.prototype._cleanup = function (){ + if(this._sectionStart < 0){ + this._buffer = ""; + this._index = 0; + this._bufferOffset += this._index; + } else if(this._running){ + if(this._state === TEXT){ + if(this._sectionStart !== this._index){ + this._cbs.ontext(this._buffer.substr(this._sectionStart)); + } + this._buffer = ""; + this._index = 0; + this._bufferOffset += this._index; + } else if(this._sectionStart === this._index){ + //the section just started + this._buffer = ""; + this._index = 0; + this._bufferOffset += this._index; + } else { + //remove everything unnecessary + this._buffer = this._buffer.substr(this._sectionStart); + this._index -= this._sectionStart; + this._bufferOffset += this._sectionStart; + } + + this._sectionStart = 0; + } + }; + + //TODO make events conditional + Tokenizer.prototype.write = function(chunk){ + if(this._ended) this._cbs.onerror(Error(".write() after done!")); + + this._buffer += chunk; + this._parse(); + }; + + Tokenizer.prototype._parse = function(){ + while(this._index < this._buffer.length && this._running){ + var c = this._buffer.charAt(this._index); + if(this._state === TEXT) { + this._stateText(c); + } else if(this._state === BEFORE_TAG_NAME){ + this._stateBeforeTagName(c); + } else if(this._state === IN_TAG_NAME) { + this._stateInTagName(c); + } else if(this._state === BEFORE_CLOSING_TAG_NAME){ + this._stateBeforeCloseingTagName(c); + } else if(this._state === IN_CLOSING_TAG_NAME){ + this._stateInCloseingTagName(c); + } else if(this._state === AFTER_CLOSING_TAG_NAME){ + this._stateAfterCloseingTagName(c); + } else if(this._state === IN_SELF_CLOSING_TAG){ + this._stateInSelfClosingTag(c); + } + + /* + * attributes + */ + else if(this._state === BEFORE_ATTRIBUTE_NAME){ + this._stateBeforeAttributeName(c); + } else if(this._state === IN_ATTRIBUTE_NAME){ + this._stateInAttributeName(c); + } else if(this._state === AFTER_ATTRIBUTE_NAME){ + this._stateAfterAttributeName(c); + } else if(this._state === BEFORE_ATTRIBUTE_VALUE){ + this._stateBeforeAttributeValue(c); + } else if(this._state === IN_ATTRIBUTE_VALUE_DQ){ + this._stateInAttributeValueDoubleQuotes(c); + } else if(this._state === IN_ATTRIBUTE_VALUE_SQ){ + this._stateInAttributeValueSingleQuotes(c); + } else if(this._state === IN_ATTRIBUTE_VALUE_NQ){ + this._stateInAttributeValueNoQuotes(c); + } + + /* + * declarations + */ + else if(this._state === BEFORE_DECLARATION){ + this._stateBeforeDeclaration(c); + } else if(this._state === IN_DECLARATION){ + this._stateInDeclaration(c); + } + + /* + * processing instructions + */ + else if(this._state === IN_PROCESSING_INSTRUCTION){ + this._stateInProcessingInstruction(c); + } + + /* + * comments + */ + else if(this._state === BEFORE_COMMENT){ + this._stateBeforeComment(c); + } else if(this._state === IN_COMMENT){ + this._stateInComment(c); + } else if(this._state === AFTER_COMMENT_1){ + this._stateAfterComment1(c); + } else if(this._state === AFTER_COMMENT_2){ + this._stateAfterComment2(c); + } + + /* + * cdata + */ + else if(this._state === BEFORE_CDATA_1){ + this._stateBeforeCdata1(c); + } else if(this._state === BEFORE_CDATA_2){ + this._stateBeforeCdata2(c); + } else if(this._state === BEFORE_CDATA_3){ + this._stateBeforeCdata3(c); + } else if(this._state === BEFORE_CDATA_4){ + this._stateBeforeCdata4(c); + } else if(this._state === BEFORE_CDATA_5){ + this._stateBeforeCdata5(c); + } else if(this._state === BEFORE_CDATA_6){ + this._stateBeforeCdata6(c); + } else if(this._state === IN_CDATA){ + this._stateInCdata(c); + } else if(this._state === AFTER_CDATA_1){ + this._stateAfterCdata1(c); + } else if(this._state === AFTER_CDATA_2){ + this._stateAfterCdata2(c); + } + + /* + * special tags + */ + else if(this._state === BEFORE_SPECIAL){ + this._stateBeforeSpecial(c); + } else if(this._state === BEFORE_SPECIAL_END){ + this._stateBeforeSpecialEnd(c); + } + + /* + * script + */ + else if(this._state === BEFORE_SCRIPT_1){ + this._stateBeforeScript1(c); + } else if(this._state === BEFORE_SCRIPT_2){ + this._stateBeforeScript2(c); + } else if(this._state === BEFORE_SCRIPT_3){ + this._stateBeforeScript3(c); + } else if(this._state === BEFORE_SCRIPT_4){ + this._stateBeforeScript4(c); + } else if(this._state === BEFORE_SCRIPT_5){ + this._stateBeforeScript5(c); + } + + else if(this._state === AFTER_SCRIPT_1){ + this._stateAfterScript1(c); + } else if(this._state === AFTER_SCRIPT_2){ + this._stateAfterScript2(c); + } else if(this._state === AFTER_SCRIPT_3){ + this._stateAfterScript3(c); + } else if(this._state === AFTER_SCRIPT_4){ + this._stateAfterScript4(c); + } else if(this._state === AFTER_SCRIPT_5){ + this._stateAfterScript5(c); + } + + /* + * style + */ + else if(this._state === BEFORE_STYLE_1){ + this._stateBeforeStyle1(c); + } else if(this._state === BEFORE_STYLE_2){ + this._stateBeforeStyle2(c); + } else if(this._state === BEFORE_STYLE_3){ + this._stateBeforeStyle3(c); + } else if(this._state === BEFORE_STYLE_4){ + this._stateBeforeStyle4(c); + } + + else if(this._state === AFTER_STYLE_1){ + this._stateAfterStyle1(c); + } else if(this._state === AFTER_STYLE_2){ + this._stateAfterStyle2(c); + } else if(this._state === AFTER_STYLE_3){ + this._stateAfterStyle3(c); + } else if(this._state === AFTER_STYLE_4){ + this._stateAfterStyle4(c); + } + + /* + * entities + */ + else if(this._state === BEFORE_ENTITY){ + this._stateBeforeEntity(c); + } else if(this._state === BEFORE_NUMERIC_ENTITY){ + this._stateBeforeNumericEntity(c); + } else if(this._state === IN_NAMED_ENTITY){ + this._stateInNamedEntity(c); + } else if(this._state === IN_NUMERIC_ENTITY){ + this._stateInNumericEntity(c); + } else if(this._state === IN_HEX_ENTITY){ + this._stateInHexEntity(c); + } + + else { + this._cbs.onerror(Error("unknown _state"), this._state); + } + + this._index++; + } + + this._cleanup(); + }; + + Tokenizer.prototype.pause = function(){ + this._running = false; + }; + Tokenizer.prototype.resume = function(){ + this._running = true; + + if(this._index < this._buffer.length){ + this._parse(); + } + if(this._ended){ + this._finish(); + } + }; + + Tokenizer.prototype.end = function(chunk){ + if(this._ended) this._cbs.onerror(Error(".end() after done!")); + if(chunk) this.write(chunk); + + this._ended = true; + + if(this._running) this._finish(); + }; + + Tokenizer.prototype._finish = function(){ + //if there is remaining data, emit it in a reasonable way + if(this._sectionStart < this._index){ + this._handleTrailingData(); + } + + this._cbs.onend(); + }; + + Tokenizer.prototype._handleTrailingData = function(){ + var data = this._buffer.substr(this._sectionStart); + + if(this._state === IN_CDATA || this._state === AFTER_CDATA_1 || this._state === AFTER_CDATA_2){ + this._cbs.oncdata(data); + } else if(this._state === IN_COMMENT || this._state === AFTER_COMMENT_1 || this._state === AFTER_COMMENT_2){ + this._cbs.oncomment(data); + } else if(this._state === IN_NAMED_ENTITY && !this._xmlMode){ + this._parseLegacyEntity(); + if(this._sectionStart < this._index){ + this._state = this._baseState; + this._handleTrailingData(); + } + } else if(this._state === IN_NUMERIC_ENTITY && !this._xmlMode){ + this._decodeNumericEntity(2, 10); + if(this._sectionStart < this._index){ + this._state = this._baseState; + this._handleTrailingData(); + } + } else if(this._state === IN_HEX_ENTITY && !this._xmlMode){ + this._decodeNumericEntity(3, 16); + if(this._sectionStart < this._index){ + this._state = this._baseState; + this._handleTrailingData(); + } + } else if( + this._state !== IN_TAG_NAME && + this._state !== BEFORE_ATTRIBUTE_NAME && + this._state !== BEFORE_ATTRIBUTE_VALUE && + this._state !== AFTER_ATTRIBUTE_NAME && + this._state !== IN_ATTRIBUTE_NAME && + this._state !== IN_ATTRIBUTE_VALUE_SQ && + this._state !== IN_ATTRIBUTE_VALUE_DQ && + this._state !== IN_ATTRIBUTE_VALUE_NQ && + this._state !== IN_CLOSING_TAG_NAME + ){ + this._cbs.ontext(data); + } + //else, ignore remaining data + //TODO add a way to remove current tag + }; + + Tokenizer.prototype.reset = function(){ + Tokenizer.call(this, {xmlMode: this._xmlMode, decodeEntities: this._decodeEntities}, this._cbs); + }; + + Tokenizer.prototype.getAbsoluteIndex = function(){ + return this._bufferOffset + this._index; + }; + + Tokenizer.prototype._getSection = function(){ + return this._buffer.substring(this._sectionStart, this._index); + }; + + Tokenizer.prototype._emitToken = function(name){ + this._cbs[name](this._getSection()); + this._sectionStart = -1; + }; + + Tokenizer.prototype._emitPartial = function(value){ + if(this._baseState !== TEXT){ + this._cbs.onattribdata(value); //TODO implement the new event + } else { + this._cbs.ontext(value); + } + }; + + +/***/ }, +/* 30 */ +/***/ function(module, exports, __webpack_require__) { + + var decodeMap = __webpack_require__(31); + + module.exports = decodeCodePoint; + + // modified version of https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119 + function decodeCodePoint(codePoint){ + + if((codePoint >= 0xD800 && codePoint <= 0xDFFF) || codePoint > 0x10FFFF){ + return "\uFFFD"; + } + + if(codePoint in decodeMap){ + codePoint = decodeMap[codePoint]; + } + + var output = ""; + + if(codePoint > 0xFFFF){ + codePoint -= 0x10000; + output += String.fromCharCode(codePoint >>> 10 & 0x3FF | 0xD800); + codePoint = 0xDC00 | codePoint & 0x3FF; + } + + output += String.fromCharCode(codePoint); + return output; + } + + +/***/ }, +/* 31 */ +/***/ function(module, exports) { + + module.exports = { + "0": 65533, + "128": 8364, + "130": 8218, + "131": 402, + "132": 8222, + "133": 8230, + "134": 8224, + "135": 8225, + "136": 710, + "137": 8240, + "138": 352, + "139": 8249, + "140": 338, + "142": 381, + "145": 8216, + "146": 8217, + "147": 8220, + "148": 8221, + "149": 8226, + "150": 8211, + "151": 8212, + "152": 732, + "153": 8482, + "154": 353, + "155": 8250, + "156": 339, + "158": 382, + "159": 376 + }; + +/***/ }, +/* 32 */ +/***/ function(module, exports) { + + module.exports = { + "Aacute": "Á", + "aacute": "á", + "Abreve": "Ă", + "abreve": "ă", + "ac": "∾", + "acd": "∿", + "acE": "∾̳", + "Acirc": "Â", + "acirc": "â", + "acute": "´", + "Acy": "А", + "acy": "а", + "AElig": "Æ", + "aelig": "æ", + "af": "⁡", + "Afr": "𝔄", + "afr": "𝔞", + "Agrave": "À", + "agrave": "à", + "alefsym": "ℵ", + "aleph": "ℵ", + "Alpha": "Α", + "alpha": "α", + "Amacr": "Ā", + "amacr": "ā", + "amalg": "⨿", + "amp": "&", + "AMP": "&", + "andand": "⩕", + "And": "⩓", + "and": "∧", + "andd": "⩜", + "andslope": "⩘", + "andv": "⩚", + "ang": "∠", + "ange": "⦤", + "angle": "∠", + "angmsdaa": "⦨", + "angmsdab": "⦩", + "angmsdac": "⦪", + "angmsdad": "⦫", + "angmsdae": "⦬", + "angmsdaf": "⦭", + "angmsdag": "⦮", + "angmsdah": "⦯", + "angmsd": "∡", + "angrt": "∟", + "angrtvb": "⊾", + "angrtvbd": "⦝", + "angsph": "∢", + "angst": "Å", + "angzarr": "⍼", + "Aogon": "Ą", + "aogon": "ą", + "Aopf": "𝔸", + "aopf": "𝕒", + "apacir": "⩯", + "ap": "≈", + "apE": "⩰", + "ape": "≊", + "apid": "≋", + "apos": "'", + "ApplyFunction": "⁡", + "approx": "≈", + "approxeq": "≊", + "Aring": "Å", + "aring": "å", + "Ascr": "𝒜", + "ascr": "𝒶", + "Assign": "≔", + "ast": "*", + "asymp": "≈", + "asympeq": "≍", + "Atilde": "Ã", + "atilde": "ã", + "Auml": "Ä", + "auml": "ä", + "awconint": "∳", + "awint": "⨑", + "backcong": "≌", + "backepsilon": "϶", + "backprime": "‵", + "backsim": "∽", + "backsimeq": "⋍", + "Backslash": "∖", + "Barv": "⫧", + "barvee": "⊽", + "barwed": "⌅", + "Barwed": "⌆", + "barwedge": "⌅", + "bbrk": "⎵", + "bbrktbrk": "⎶", + "bcong": "≌", + "Bcy": "Б", + "bcy": "б", + "bdquo": "„", + "becaus": "∵", + "because": "∵", + "Because": "∵", + "bemptyv": "⦰", + "bepsi": "϶", + "bernou": "ℬ", + "Bernoullis": "ℬ", + "Beta": "Β", + "beta": "β", + "beth": "ℶ", + "between": "≬", + "Bfr": "𝔅", + "bfr": "𝔟", + "bigcap": "⋂", + "bigcirc": "◯", + "bigcup": "⋃", + "bigodot": "⨀", + "bigoplus": "⨁", + "bigotimes": "⨂", + "bigsqcup": "⨆", + "bigstar": "★", + "bigtriangledown": "▽", + "bigtriangleup": "△", + "biguplus": "⨄", + "bigvee": "⋁", + "bigwedge": "⋀", + "bkarow": "⤍", + "blacklozenge": "⧫", + "blacksquare": "▪", + "blacktriangle": "▴", + "blacktriangledown": "▾", + "blacktriangleleft": "◂", + "blacktriangleright": "▸", + "blank": "␣", + "blk12": "▒", + "blk14": "░", + "blk34": "▓", + "block": "█", + "bne": "=⃥", + "bnequiv": "≡⃥", + "bNot": "⫭", + "bnot": "⌐", + "Bopf": "𝔹", + "bopf": "𝕓", + "bot": "⊥", + "bottom": "⊥", + "bowtie": "⋈", + "boxbox": "⧉", + "boxdl": "┐", + "boxdL": "╕", + "boxDl": "╖", + "boxDL": "╗", + "boxdr": "┌", + "boxdR": "╒", + "boxDr": "╓", + "boxDR": "╔", + "boxh": "─", + "boxH": "═", + "boxhd": "┬", + "boxHd": "╤", + "boxhD": "╥", + "boxHD": "╦", + "boxhu": "┴", + "boxHu": "╧", + "boxhU": "╨", + "boxHU": "╩", + "boxminus": "⊟", + "boxplus": "⊞", + "boxtimes": "⊠", + "boxul": "┘", + "boxuL": "╛", + "boxUl": "╜", + "boxUL": "╝", + "boxur": "└", + "boxuR": "╘", + "boxUr": "╙", + "boxUR": "╚", + "boxv": "│", + "boxV": "║", + "boxvh": "┼", + "boxvH": "╪", + "boxVh": "╫", + "boxVH": "╬", + "boxvl": "┤", + "boxvL": "╡", + "boxVl": "╢", + "boxVL": "╣", + "boxvr": "├", + "boxvR": "╞", + "boxVr": "╟", + "boxVR": "╠", + "bprime": "‵", + "breve": "˘", + "Breve": "˘", + "brvbar": "¦", + "bscr": "𝒷", + "Bscr": "ℬ", + "bsemi": "⁏", + "bsim": "∽", + "bsime": "⋍", + "bsolb": "⧅", + "bsol": "\\", + "bsolhsub": "⟈", + "bull": "•", + "bullet": "•", + "bump": "≎", + "bumpE": "⪮", + "bumpe": "≏", + "Bumpeq": "≎", + "bumpeq": "≏", + "Cacute": "Ć", + "cacute": "ć", + "capand": "⩄", + "capbrcup": "⩉", + "capcap": "⩋", + "cap": "∩", + "Cap": "⋒", + "capcup": "⩇", + "capdot": "⩀", + "CapitalDifferentialD": "ⅅ", + "caps": "∩︀", + "caret": "⁁", + "caron": "ˇ", + "Cayleys": "ℭ", + "ccaps": "⩍", + "Ccaron": "Č", + "ccaron": "č", + "Ccedil": "Ç", + "ccedil": "ç", + "Ccirc": "Ĉ", + "ccirc": "ĉ", + "Cconint": "∰", + "ccups": "⩌", + "ccupssm": "⩐", + "Cdot": "Ċ", + "cdot": "ċ", + "cedil": "¸", + "Cedilla": "¸", + "cemptyv": "⦲", + "cent": "¢", + "centerdot": "·", + "CenterDot": "·", + "cfr": "𝔠", + "Cfr": "ℭ", + "CHcy": "Ч", + "chcy": "ч", + "check": "✓", + "checkmark": "✓", + "Chi": "Χ", + "chi": "χ", + "circ": "ˆ", + "circeq": "≗", + "circlearrowleft": "↺", + "circlearrowright": "↻", + "circledast": "⊛", + "circledcirc": "⊚", + "circleddash": "⊝", + "CircleDot": "⊙", + "circledR": "®", + "circledS": "Ⓢ", + "CircleMinus": "⊖", + "CirclePlus": "⊕", + "CircleTimes": "⊗", + "cir": "○", + "cirE": "⧃", + "cire": "≗", + "cirfnint": "⨐", + "cirmid": "⫯", + "cirscir": "⧂", + "ClockwiseContourIntegral": "∲", + "CloseCurlyDoubleQuote": "”", + "CloseCurlyQuote": "’", + "clubs": "♣", + "clubsuit": "♣", + "colon": ":", + "Colon": "∷", + "Colone": "⩴", + "colone": "≔", + "coloneq": "≔", + "comma": ",", + "commat": "@", + "comp": "∁", + "compfn": "∘", + "complement": "∁", + "complexes": "ℂ", + "cong": "≅", + "congdot": "⩭", + "Congruent": "≡", + "conint": "∮", + "Conint": "∯", + "ContourIntegral": "∮", + "copf": "𝕔", + "Copf": "ℂ", + "coprod": "∐", + "Coproduct": "∐", + "copy": "©", + "COPY": "©", + "copysr": "℗", + "CounterClockwiseContourIntegral": "∳", + "crarr": "↵", + "cross": "✗", + "Cross": "⨯", + "Cscr": "𝒞", + "cscr": "𝒸", + "csub": "⫏", + "csube": "⫑", + "csup": "⫐", + "csupe": "⫒", + "ctdot": "⋯", + "cudarrl": "⤸", + "cudarrr": "⤵", + "cuepr": "⋞", + "cuesc": "⋟", + "cularr": "↶", + "cularrp": "⤽", + "cupbrcap": "⩈", + "cupcap": "⩆", + "CupCap": "≍", + "cup": "∪", + "Cup": "⋓", + "cupcup": "⩊", + "cupdot": "⊍", + "cupor": "⩅", + "cups": "∪︀", + "curarr": "↷", + "curarrm": "⤼", + "curlyeqprec": "⋞", + "curlyeqsucc": "⋟", + "curlyvee": "⋎", + "curlywedge": "⋏", + "curren": "¤", + "curvearrowleft": "↶", + "curvearrowright": "↷", + "cuvee": "⋎", + "cuwed": "⋏", + "cwconint": "∲", + "cwint": "∱", + "cylcty": "⌭", + "dagger": "†", + "Dagger": "‡", + "daleth": "ℸ", + "darr": "↓", + "Darr": "↡", + "dArr": "⇓", + "dash": "‐", + "Dashv": "⫤", + "dashv": "⊣", + "dbkarow": "⤏", + "dblac": "˝", + "Dcaron": "Ď", + "dcaron": "ď", + "Dcy": "Д", + "dcy": "д", + "ddagger": "‡", + "ddarr": "⇊", + "DD": "ⅅ", + "dd": "ⅆ", + "DDotrahd": "⤑", + "ddotseq": "⩷", + "deg": "°", + "Del": "∇", + "Delta": "Δ", + "delta": "δ", + "demptyv": "⦱", + "dfisht": "⥿", + "Dfr": "𝔇", + "dfr": "𝔡", + "dHar": "⥥", + "dharl": "⇃", + "dharr": "⇂", + "DiacriticalAcute": "´", + "DiacriticalDot": "˙", + "DiacriticalDoubleAcute": "˝", + "DiacriticalGrave": "`", + "DiacriticalTilde": "˜", + "diam": "⋄", + "diamond": "⋄", + "Diamond": "⋄", + "diamondsuit": "♦", + "diams": "♦", + "die": "¨", + "DifferentialD": "ⅆ", + "digamma": "ϝ", + "disin": "⋲", + "div": "÷", + "divide": "÷", + "divideontimes": "⋇", + "divonx": "⋇", + "DJcy": "Ђ", + "djcy": "ђ", + "dlcorn": "⌞", + "dlcrop": "⌍", + "dollar": "$", + "Dopf": "𝔻", + "dopf": "𝕕", + "Dot": "¨", + "dot": "˙", + "DotDot": "⃜", + "doteq": "≐", + "doteqdot": "≑", + "DotEqual": "≐", + "dotminus": "∸", + "dotplus": "∔", + "dotsquare": "⊡", + "doublebarwedge": "⌆", + "DoubleContourIntegral": "∯", + "DoubleDot": "¨", + "DoubleDownArrow": "⇓", + "DoubleLeftArrow": "⇐", + "DoubleLeftRightArrow": "⇔", + "DoubleLeftTee": "⫤", + "DoubleLongLeftArrow": "⟸", + "DoubleLongLeftRightArrow": "⟺", + "DoubleLongRightArrow": "⟹", + "DoubleRightArrow": "⇒", + "DoubleRightTee": "⊨", + "DoubleUpArrow": "⇑", + "DoubleUpDownArrow": "⇕", + "DoubleVerticalBar": "∥", + "DownArrowBar": "⤓", + "downarrow": "↓", + "DownArrow": "↓", + "Downarrow": "⇓", + "DownArrowUpArrow": "⇵", + "DownBreve": "̑", + "downdownarrows": "⇊", + "downharpoonleft": "⇃", + "downharpoonright": "⇂", + "DownLeftRightVector": "⥐", + "DownLeftTeeVector": "⥞", + "DownLeftVectorBar": "⥖", + "DownLeftVector": "↽", + "DownRightTeeVector": "⥟", + "DownRightVectorBar": "⥗", + "DownRightVector": "⇁", + "DownTeeArrow": "↧", + "DownTee": "⊤", + "drbkarow": "⤐", + "drcorn": "⌟", + "drcrop": "⌌", + "Dscr": "𝒟", + "dscr": "𝒹", + "DScy": "Ѕ", + "dscy": "ѕ", + "dsol": "⧶", + "Dstrok": "Đ", + "dstrok": "đ", + "dtdot": "⋱", + "dtri": "▿", + "dtrif": "▾", + "duarr": "⇵", + "duhar": "⥯", + "dwangle": "⦦", + "DZcy": "Џ", + "dzcy": "џ", + "dzigrarr": "⟿", + "Eacute": "É", + "eacute": "é", + "easter": "⩮", + "Ecaron": "Ě", + "ecaron": "ě", + "Ecirc": "Ê", + "ecirc": "ê", + "ecir": "≖", + "ecolon": "≕", + "Ecy": "Э", + "ecy": "э", + "eDDot": "⩷", + "Edot": "Ė", + "edot": "ė", + "eDot": "≑", + "ee": "ⅇ", + "efDot": "≒", + "Efr": "𝔈", + "efr": "𝔢", + "eg": "⪚", + "Egrave": "È", + "egrave": "è", + "egs": "⪖", + "egsdot": "⪘", + "el": "⪙", + "Element": "∈", + "elinters": "⏧", + "ell": "ℓ", + "els": "⪕", + "elsdot": "⪗", + "Emacr": "Ē", + "emacr": "ē", + "empty": "∅", + "emptyset": "∅", + "EmptySmallSquare": "◻", + "emptyv": "∅", + "EmptyVerySmallSquare": "▫", + "emsp13": " ", + "emsp14": " ", + "emsp": " ", + "ENG": "Ŋ", + "eng": "ŋ", + "ensp": " ", + "Eogon": "Ę", + "eogon": "ę", + "Eopf": "𝔼", + "eopf": "𝕖", + "epar": "⋕", + "eparsl": "⧣", + "eplus": "⩱", + "epsi": "ε", + "Epsilon": "Ε", + "epsilon": "ε", + "epsiv": "ϵ", + "eqcirc": "≖", + "eqcolon": "≕", + "eqsim": "≂", + "eqslantgtr": "⪖", + "eqslantless": "⪕", + "Equal": "⩵", + "equals": "=", + "EqualTilde": "≂", + "equest": "≟", + "Equilibrium": "⇌", + "equiv": "≡", + "equivDD": "⩸", + "eqvparsl": "⧥", + "erarr": "⥱", + "erDot": "≓", + "escr": "ℯ", + "Escr": "ℰ", + "esdot": "≐", + "Esim": "⩳", + "esim": "≂", + "Eta": "Η", + "eta": "η", + "ETH": "Ð", + "eth": "ð", + "Euml": "Ë", + "euml": "ë", + "euro": "€", + "excl": "!", + "exist": "∃", + "Exists": "∃", + "expectation": "ℰ", + "exponentiale": "ⅇ", + "ExponentialE": "ⅇ", + "fallingdotseq": "≒", + "Fcy": "Ф", + "fcy": "ф", + "female": "♀", + "ffilig": "ffi", + "fflig": "ff", + "ffllig": "ffl", + "Ffr": "𝔉", + "ffr": "𝔣", + "filig": "fi", + "FilledSmallSquare": "◼", + "FilledVerySmallSquare": "▪", + "fjlig": "fj", + "flat": "♭", + "fllig": "fl", + "fltns": "▱", + "fnof": "ƒ", + "Fopf": "𝔽", + "fopf": "𝕗", + "forall": "∀", + "ForAll": "∀", + "fork": "⋔", + "forkv": "⫙", + "Fouriertrf": "ℱ", + "fpartint": "⨍", + "frac12": "½", + "frac13": "⅓", + "frac14": "¼", + "frac15": "⅕", + "frac16": "⅙", + "frac18": "⅛", + "frac23": "⅔", + "frac25": "⅖", + "frac34": "¾", + "frac35": "⅗", + "frac38": "⅜", + "frac45": "⅘", + "frac56": "⅚", + "frac58": "⅝", + "frac78": "⅞", + "frasl": "⁄", + "frown": "⌢", + "fscr": "𝒻", + "Fscr": "ℱ", + "gacute": "ǵ", + "Gamma": "Γ", + "gamma": "γ", + "Gammad": "Ϝ", + "gammad": "ϝ", + "gap": "⪆", + "Gbreve": "Ğ", + "gbreve": "ğ", + "Gcedil": "Ģ", + "Gcirc": "Ĝ", + "gcirc": "ĝ", + "Gcy": "Г", + "gcy": "г", + "Gdot": "Ġ", + "gdot": "ġ", + "ge": "≥", + "gE": "≧", + "gEl": "⪌", + "gel": "⋛", + "geq": "≥", + "geqq": "≧", + "geqslant": "⩾", + "gescc": "⪩", + "ges": "⩾", + "gesdot": "⪀", + "gesdoto": "⪂", + "gesdotol": "⪄", + "gesl": "⋛︀", + "gesles": "⪔", + "Gfr": "𝔊", + "gfr": "𝔤", + "gg": "≫", + "Gg": "⋙", + "ggg": "⋙", + "gimel": "ℷ", + "GJcy": "Ѓ", + "gjcy": "ѓ", + "gla": "⪥", + "gl": "≷", + "glE": "⪒", + "glj": "⪤", + "gnap": "⪊", + "gnapprox": "⪊", + "gne": "⪈", + "gnE": "≩", + "gneq": "⪈", + "gneqq": "≩", + "gnsim": "⋧", + "Gopf": "𝔾", + "gopf": "𝕘", + "grave": "`", + "GreaterEqual": "≥", + "GreaterEqualLess": "⋛", + "GreaterFullEqual": "≧", + "GreaterGreater": "⪢", + "GreaterLess": "≷", + "GreaterSlantEqual": "⩾", + "GreaterTilde": "≳", + "Gscr": "𝒢", + "gscr": "ℊ", + "gsim": "≳", + "gsime": "⪎", + "gsiml": "⪐", + "gtcc": "⪧", + "gtcir": "⩺", + "gt": ">", + "GT": ">", + "Gt": "≫", + "gtdot": "⋗", + "gtlPar": "⦕", + "gtquest": "⩼", + "gtrapprox": "⪆", + "gtrarr": "⥸", + "gtrdot": "⋗", + "gtreqless": "⋛", + "gtreqqless": "⪌", + "gtrless": "≷", + "gtrsim": "≳", + "gvertneqq": "≩︀", + "gvnE": "≩︀", + "Hacek": "ˇ", + "hairsp": " ", + "half": "½", + "hamilt": "ℋ", + "HARDcy": "Ъ", + "hardcy": "ъ", + "harrcir": "⥈", + "harr": "↔", + "hArr": "⇔", + "harrw": "↭", + "Hat": "^", + "hbar": "ℏ", + "Hcirc": "Ĥ", + "hcirc": "ĥ", + "hearts": "♥", + "heartsuit": "♥", + "hellip": "…", + "hercon": "⊹", + "hfr": "𝔥", + "Hfr": "ℌ", + "HilbertSpace": "ℋ", + "hksearow": "⤥", + "hkswarow": "⤦", + "hoarr": "⇿", + "homtht": "∻", + "hookleftarrow": "↩", + "hookrightarrow": "↪", + "hopf": "𝕙", + "Hopf": "ℍ", + "horbar": "―", + "HorizontalLine": "─", + "hscr": "𝒽", + "Hscr": "ℋ", + "hslash": "ℏ", + "Hstrok": "Ħ", + "hstrok": "ħ", + "HumpDownHump": "≎", + "HumpEqual": "≏", + "hybull": "⁃", + "hyphen": "‐", + "Iacute": "Í", + "iacute": "í", + "ic": "⁣", + "Icirc": "Î", + "icirc": "î", + "Icy": "И", + "icy": "и", + "Idot": "İ", + "IEcy": "Е", + "iecy": "е", + "iexcl": "¡", + "iff": "⇔", + "ifr": "𝔦", + "Ifr": "ℑ", + "Igrave": "Ì", + "igrave": "ì", + "ii": "ⅈ", + "iiiint": "⨌", + "iiint": "∭", + "iinfin": "⧜", + "iiota": "℩", + "IJlig": "IJ", + "ijlig": "ij", + "Imacr": "Ī", + "imacr": "ī", + "image": "ℑ", + "ImaginaryI": "ⅈ", + "imagline": "ℐ", + "imagpart": "ℑ", + "imath": "ı", + "Im": "ℑ", + "imof": "⊷", + "imped": "Ƶ", + "Implies": "⇒", + "incare": "℅", + "in": "∈", + "infin": "∞", + "infintie": "⧝", + "inodot": "ı", + "intcal": "⊺", + "int": "∫", + "Int": "∬", + "integers": "ℤ", + "Integral": "∫", + "intercal": "⊺", + "Intersection": "⋂", + "intlarhk": "⨗", + "intprod": "⨼", + "InvisibleComma": "⁣", + "InvisibleTimes": "⁢", + "IOcy": "Ё", + "iocy": "ё", + "Iogon": "Į", + "iogon": "į", + "Iopf": "𝕀", + "iopf": "𝕚", + "Iota": "Ι", + "iota": "ι", + "iprod": "⨼", + "iquest": "¿", + "iscr": "𝒾", + "Iscr": "ℐ", + "isin": "∈", + "isindot": "⋵", + "isinE": "⋹", + "isins": "⋴", + "isinsv": "⋳", + "isinv": "∈", + "it": "⁢", + "Itilde": "Ĩ", + "itilde": "ĩ", + "Iukcy": "І", + "iukcy": "і", + "Iuml": "Ï", + "iuml": "ï", + "Jcirc": "Ĵ", + "jcirc": "ĵ", + "Jcy": "Й", + "jcy": "й", + "Jfr": "𝔍", + "jfr": "𝔧", + "jmath": "ȷ", + "Jopf": "𝕁", + "jopf": "𝕛", + "Jscr": "𝒥", + "jscr": "𝒿", + "Jsercy": "Ј", + "jsercy": "ј", + "Jukcy": "Є", + "jukcy": "є", + "Kappa": "Κ", + "kappa": "κ", + "kappav": "ϰ", + "Kcedil": "Ķ", + "kcedil": "ķ", + "Kcy": "К", + "kcy": "к", + "Kfr": "𝔎", + "kfr": "𝔨", + "kgreen": "ĸ", + "KHcy": "Х", + "khcy": "х", + "KJcy": "Ќ", + "kjcy": "ќ", + "Kopf": "𝕂", + "kopf": "𝕜", + "Kscr": "𝒦", + "kscr": "𝓀", + "lAarr": "⇚", + "Lacute": "Ĺ", + "lacute": "ĺ", + "laemptyv": "⦴", + "lagran": "ℒ", + "Lambda": "Λ", + "lambda": "λ", + "lang": "⟨", + "Lang": "⟪", + "langd": "⦑", + "langle": "⟨", + "lap": "⪅", + "Laplacetrf": "ℒ", + "laquo": "«", + "larrb": "⇤", + "larrbfs": "⤟", + "larr": "←", + "Larr": "↞", + "lArr": "⇐", + "larrfs": "⤝", + "larrhk": "↩", + "larrlp": "↫", + "larrpl": "⤹", + "larrsim": "⥳", + "larrtl": "↢", + "latail": "⤙", + "lAtail": "⤛", + "lat": "⪫", + "late": "⪭", + "lates": "⪭︀", + "lbarr": "⤌", + "lBarr": "⤎", + "lbbrk": "❲", + "lbrace": "{", + "lbrack": "[", + "lbrke": "⦋", + "lbrksld": "⦏", + "lbrkslu": "⦍", + "Lcaron": "Ľ", + "lcaron": "ľ", + "Lcedil": "Ļ", + "lcedil": "ļ", + "lceil": "⌈", + "lcub": "{", + "Lcy": "Л", + "lcy": "л", + "ldca": "⤶", + "ldquo": "“", + "ldquor": "„", + "ldrdhar": "⥧", + "ldrushar": "⥋", + "ldsh": "↲", + "le": "≤", + "lE": "≦", + "LeftAngleBracket": "⟨", + "LeftArrowBar": "⇤", + "leftarrow": "←", + "LeftArrow": "←", + "Leftarrow": "⇐", + "LeftArrowRightArrow": "⇆", + "leftarrowtail": "↢", + "LeftCeiling": "⌈", + "LeftDoubleBracket": "⟦", + "LeftDownTeeVector": "⥡", + "LeftDownVectorBar": "⥙", + "LeftDownVector": "⇃", + "LeftFloor": "⌊", + "leftharpoondown": "↽", + "leftharpoonup": "↼", + "leftleftarrows": "⇇", + "leftrightarrow": "↔", + "LeftRightArrow": "↔", + "Leftrightarrow": "⇔", + "leftrightarrows": "⇆", + "leftrightharpoons": "⇋", + "leftrightsquigarrow": "↭", + "LeftRightVector": "⥎", + "LeftTeeArrow": "↤", + "LeftTee": "⊣", + "LeftTeeVector": "⥚", + "leftthreetimes": "⋋", + "LeftTriangleBar": "⧏", + "LeftTriangle": "⊲", + "LeftTriangleEqual": "⊴", + "LeftUpDownVector": "⥑", + "LeftUpTeeVector": "⥠", + "LeftUpVectorBar": "⥘", + "LeftUpVector": "↿", + "LeftVectorBar": "⥒", + "LeftVector": "↼", + "lEg": "⪋", + "leg": "⋚", + "leq": "≤", + "leqq": "≦", + "leqslant": "⩽", + "lescc": "⪨", + "les": "⩽", + "lesdot": "⩿", + "lesdoto": "⪁", + "lesdotor": "⪃", + "lesg": "⋚︀", + "lesges": "⪓", + "lessapprox": "⪅", + "lessdot": "⋖", + "lesseqgtr": "⋚", + "lesseqqgtr": "⪋", + "LessEqualGreater": "⋚", + "LessFullEqual": "≦", + "LessGreater": "≶", + "lessgtr": "≶", + "LessLess": "⪡", + "lesssim": "≲", + "LessSlantEqual": "⩽", + "LessTilde": "≲", + "lfisht": "⥼", + "lfloor": "⌊", + "Lfr": "𝔏", + "lfr": "𝔩", + "lg": "≶", + "lgE": "⪑", + "lHar": "⥢", + "lhard": "↽", + "lharu": "↼", + "lharul": "⥪", + "lhblk": "▄", + "LJcy": "Љ", + "ljcy": "љ", + "llarr": "⇇", + "ll": "≪", + "Ll": "⋘", + "llcorner": "⌞", + "Lleftarrow": "⇚", + "llhard": "⥫", + "lltri": "◺", + "Lmidot": "Ŀ", + "lmidot": "ŀ", + "lmoustache": "⎰", + "lmoust": "⎰", + "lnap": "⪉", + "lnapprox": "⪉", + "lne": "⪇", + "lnE": "≨", + "lneq": "⪇", + "lneqq": "≨", + "lnsim": "⋦", + "loang": "⟬", + "loarr": "⇽", + "lobrk": "⟦", + "longleftarrow": "⟵", + "LongLeftArrow": "⟵", + "Longleftarrow": "⟸", + "longleftrightarrow": "⟷", + "LongLeftRightArrow": "⟷", + "Longleftrightarrow": "⟺", + "longmapsto": "⟼", + "longrightarrow": "⟶", + "LongRightArrow": "⟶", + "Longrightarrow": "⟹", + "looparrowleft": "↫", + "looparrowright": "↬", + "lopar": "⦅", + "Lopf": "𝕃", + "lopf": "𝕝", + "loplus": "⨭", + "lotimes": "⨴", + "lowast": "∗", + "lowbar": "_", + "LowerLeftArrow": "↙", + "LowerRightArrow": "↘", + "loz": "◊", + "lozenge": "◊", + "lozf": "⧫", + "lpar": "(", + "lparlt": "⦓", + "lrarr": "⇆", + "lrcorner": "⌟", + "lrhar": "⇋", + "lrhard": "⥭", + "lrm": "‎", + "lrtri": "⊿", + "lsaquo": "‹", + "lscr": "𝓁", + "Lscr": "ℒ", + "lsh": "↰", + "Lsh": "↰", + "lsim": "≲", + "lsime": "⪍", + "lsimg": "⪏", + "lsqb": "[", + "lsquo": "‘", + "lsquor": "‚", + "Lstrok": "Ł", + "lstrok": "ł", + "ltcc": "⪦", + "ltcir": "⩹", + "lt": "<", + "LT": "<", + "Lt": "≪", + "ltdot": "⋖", + "lthree": "⋋", + "ltimes": "⋉", + "ltlarr": "⥶", + "ltquest": "⩻", + "ltri": "◃", + "ltrie": "⊴", + "ltrif": "◂", + "ltrPar": "⦖", + "lurdshar": "⥊", + "luruhar": "⥦", + "lvertneqq": "≨︀", + "lvnE": "≨︀", + "macr": "¯", + "male": "♂", + "malt": "✠", + "maltese": "✠", + "Map": "⤅", + "map": "↦", + "mapsto": "↦", + "mapstodown": "↧", + "mapstoleft": "↤", + "mapstoup": "↥", + "marker": "▮", + "mcomma": "⨩", + "Mcy": "М", + "mcy": "м", + "mdash": "—", + "mDDot": "∺", + "measuredangle": "∡", + "MediumSpace": " ", + "Mellintrf": "ℳ", + "Mfr": "𝔐", + "mfr": "𝔪", + "mho": "℧", + "micro": "µ", + "midast": "*", + "midcir": "⫰", + "mid": "∣", + "middot": "·", + "minusb": "⊟", + "minus": "−", + "minusd": "∸", + "minusdu": "⨪", + "MinusPlus": "∓", + "mlcp": "⫛", + "mldr": "…", + "mnplus": "∓", + "models": "⊧", + "Mopf": "𝕄", + "mopf": "𝕞", + "mp": "∓", + "mscr": "𝓂", + "Mscr": "ℳ", + "mstpos": "∾", + "Mu": "Μ", + "mu": "μ", + "multimap": "⊸", + "mumap": "⊸", + "nabla": "∇", + "Nacute": "Ń", + "nacute": "ń", + "nang": "∠⃒", + "nap": "≉", + "napE": "⩰̸", + "napid": "≋̸", + "napos": "ʼn", + "napprox": "≉", + "natural": "♮", + "naturals": "ℕ", + "natur": "♮", + "nbsp": " ", + "nbump": "≎̸", + "nbumpe": "≏̸", + "ncap": "⩃", + "Ncaron": "Ň", + "ncaron": "ň", + "Ncedil": "Ņ", + "ncedil": "ņ", + "ncong": "≇", + "ncongdot": "⩭̸", + "ncup": "⩂", + "Ncy": "Н", + "ncy": "н", + "ndash": "–", + "nearhk": "⤤", + "nearr": "↗", + "neArr": "⇗", + "nearrow": "↗", + "ne": "≠", + "nedot": "≐̸", + "NegativeMediumSpace": "​", + "NegativeThickSpace": "​", + "NegativeThinSpace": "​", + "NegativeVeryThinSpace": "​", + "nequiv": "≢", + "nesear": "⤨", + "nesim": "≂̸", + "NestedGreaterGreater": "≫", + "NestedLessLess": "≪", + "NewLine": "\n", + "nexist": "∄", + "nexists": "∄", + "Nfr": "𝔑", + "nfr": "𝔫", + "ngE": "≧̸", + "nge": "≱", + "ngeq": "≱", + "ngeqq": "≧̸", + "ngeqslant": "⩾̸", + "nges": "⩾̸", + "nGg": "⋙̸", + "ngsim": "≵", + "nGt": "≫⃒", + "ngt": "≯", + "ngtr": "≯", + "nGtv": "≫̸", + "nharr": "↮", + "nhArr": "⇎", + "nhpar": "⫲", + "ni": "∋", + "nis": "⋼", + "nisd": "⋺", + "niv": "∋", + "NJcy": "Њ", + "njcy": "њ", + "nlarr": "↚", + "nlArr": "⇍", + "nldr": "‥", + "nlE": "≦̸", + "nle": "≰", + "nleftarrow": "↚", + "nLeftarrow": "⇍", + "nleftrightarrow": "↮", + "nLeftrightarrow": "⇎", + "nleq": "≰", + "nleqq": "≦̸", + "nleqslant": "⩽̸", + "nles": "⩽̸", + "nless": "≮", + "nLl": "⋘̸", + "nlsim": "≴", + "nLt": "≪⃒", + "nlt": "≮", + "nltri": "⋪", + "nltrie": "⋬", + "nLtv": "≪̸", + "nmid": "∤", + "NoBreak": "⁠", + "NonBreakingSpace": " ", + "nopf": "𝕟", + "Nopf": "ℕ", + "Not": "⫬", + "not": "¬", + "NotCongruent": "≢", + "NotCupCap": "≭", + "NotDoubleVerticalBar": "∦", + "NotElement": "∉", + "NotEqual": "≠", + "NotEqualTilde": "≂̸", + "NotExists": "∄", + "NotGreater": "≯", + "NotGreaterEqual": "≱", + "NotGreaterFullEqual": "≧̸", + "NotGreaterGreater": "≫̸", + "NotGreaterLess": "≹", + "NotGreaterSlantEqual": "⩾̸", + "NotGreaterTilde": "≵", + "NotHumpDownHump": "≎̸", + "NotHumpEqual": "≏̸", + "notin": "∉", + "notindot": "⋵̸", + "notinE": "⋹̸", + "notinva": "∉", + "notinvb": "⋷", + "notinvc": "⋶", + "NotLeftTriangleBar": "⧏̸", + "NotLeftTriangle": "⋪", + "NotLeftTriangleEqual": "⋬", + "NotLess": "≮", + "NotLessEqual": "≰", + "NotLessGreater": "≸", + "NotLessLess": "≪̸", + "NotLessSlantEqual": "⩽̸", + "NotLessTilde": "≴", + "NotNestedGreaterGreater": "⪢̸", + "NotNestedLessLess": "⪡̸", + "notni": "∌", + "notniva": "∌", + "notnivb": "⋾", + "notnivc": "⋽", + "NotPrecedes": "⊀", + "NotPrecedesEqual": "⪯̸", + "NotPrecedesSlantEqual": "⋠", + "NotReverseElement": "∌", + "NotRightTriangleBar": "⧐̸", + "NotRightTriangle": "⋫", + "NotRightTriangleEqual": "⋭", + "NotSquareSubset": "⊏̸", + "NotSquareSubsetEqual": "⋢", + "NotSquareSuperset": "⊐̸", + "NotSquareSupersetEqual": "⋣", + "NotSubset": "⊂⃒", + "NotSubsetEqual": "⊈", + "NotSucceeds": "⊁", + "NotSucceedsEqual": "⪰̸", + "NotSucceedsSlantEqual": "⋡", + "NotSucceedsTilde": "≿̸", + "NotSuperset": "⊃⃒", + "NotSupersetEqual": "⊉", + "NotTilde": "≁", + "NotTildeEqual": "≄", + "NotTildeFullEqual": "≇", + "NotTildeTilde": "≉", + "NotVerticalBar": "∤", + "nparallel": "∦", + "npar": "∦", + "nparsl": "⫽⃥", + "npart": "∂̸", + "npolint": "⨔", + "npr": "⊀", + "nprcue": "⋠", + "nprec": "⊀", + "npreceq": "⪯̸", + "npre": "⪯̸", + "nrarrc": "⤳̸", + "nrarr": "↛", + "nrArr": "⇏", + "nrarrw": "↝̸", + "nrightarrow": "↛", + "nRightarrow": "⇏", + "nrtri": "⋫", + "nrtrie": "⋭", + "nsc": "⊁", + "nsccue": "⋡", + "nsce": "⪰̸", + "Nscr": "𝒩", + "nscr": "𝓃", + "nshortmid": "∤", + "nshortparallel": "∦", + "nsim": "≁", + "nsime": "≄", + "nsimeq": "≄", + "nsmid": "∤", + "nspar": "∦", + "nsqsube": "⋢", + "nsqsupe": "⋣", + "nsub": "⊄", + "nsubE": "⫅̸", + "nsube": "⊈", + "nsubset": "⊂⃒", + "nsubseteq": "⊈", + "nsubseteqq": "⫅̸", + "nsucc": "⊁", + "nsucceq": "⪰̸", + "nsup": "⊅", + "nsupE": "⫆̸", + "nsupe": "⊉", + "nsupset": "⊃⃒", + "nsupseteq": "⊉", + "nsupseteqq": "⫆̸", + "ntgl": "≹", + "Ntilde": "Ñ", + "ntilde": "ñ", + "ntlg": "≸", + "ntriangleleft": "⋪", + "ntrianglelefteq": "⋬", + "ntriangleright": "⋫", + "ntrianglerighteq": "⋭", + "Nu": "Ν", + "nu": "ν", + "num": "#", + "numero": "№", + "numsp": " ", + "nvap": "≍⃒", + "nvdash": "⊬", + "nvDash": "⊭", + "nVdash": "⊮", + "nVDash": "⊯", + "nvge": "≥⃒", + "nvgt": ">⃒", + "nvHarr": "⤄", + "nvinfin": "⧞", + "nvlArr": "⤂", + "nvle": "≤⃒", + "nvlt": "<⃒", + "nvltrie": "⊴⃒", + "nvrArr": "⤃", + "nvrtrie": "⊵⃒", + "nvsim": "∼⃒", + "nwarhk": "⤣", + "nwarr": "↖", + "nwArr": "⇖", + "nwarrow": "↖", + "nwnear": "⤧", + "Oacute": "Ó", + "oacute": "ó", + "oast": "⊛", + "Ocirc": "Ô", + "ocirc": "ô", + "ocir": "⊚", + "Ocy": "О", + "ocy": "о", + "odash": "⊝", + "Odblac": "Ő", + "odblac": "ő", + "odiv": "⨸", + "odot": "⊙", + "odsold": "⦼", + "OElig": "Œ", + "oelig": "œ", + "ofcir": "⦿", + "Ofr": "𝔒", + "ofr": "𝔬", + "ogon": "˛", + "Ograve": "Ò", + "ograve": "ò", + "ogt": "⧁", + "ohbar": "⦵", + "ohm": "Ω", + "oint": "∮", + "olarr": "↺", + "olcir": "⦾", + "olcross": "⦻", + "oline": "‾", + "olt": "⧀", + "Omacr": "Ō", + "omacr": "ō", + "Omega": "Ω", + "omega": "ω", + "Omicron": "Ο", + "omicron": "ο", + "omid": "⦶", + "ominus": "⊖", + "Oopf": "𝕆", + "oopf": "𝕠", + "opar": "⦷", + "OpenCurlyDoubleQuote": "“", + "OpenCurlyQuote": "‘", + "operp": "⦹", + "oplus": "⊕", + "orarr": "↻", + "Or": "⩔", + "or": "∨", + "ord": "⩝", + "order": "ℴ", + "orderof": "ℴ", + "ordf": "ª", + "ordm": "º", + "origof": "⊶", + "oror": "⩖", + "orslope": "⩗", + "orv": "⩛", + "oS": "Ⓢ", + "Oscr": "𝒪", + "oscr": "ℴ", + "Oslash": "Ø", + "oslash": "ø", + "osol": "⊘", + "Otilde": "Õ", + "otilde": "õ", + "otimesas": "⨶", + "Otimes": "⨷", + "otimes": "⊗", + "Ouml": "Ö", + "ouml": "ö", + "ovbar": "⌽", + "OverBar": "‾", + "OverBrace": "⏞", + "OverBracket": "⎴", + "OverParenthesis": "⏜", + "para": "¶", + "parallel": "∥", + "par": "∥", + "parsim": "⫳", + "parsl": "⫽", + "part": "∂", + "PartialD": "∂", + "Pcy": "П", + "pcy": "п", + "percnt": "%", + "period": ".", + "permil": "‰", + "perp": "⊥", + "pertenk": "‱", + "Pfr": "𝔓", + "pfr": "𝔭", + "Phi": "Φ", + "phi": "φ", + "phiv": "ϕ", + "phmmat": "ℳ", + "phone": "☎", + "Pi": "Π", + "pi": "π", + "pitchfork": "⋔", + "piv": "ϖ", + "planck": "ℏ", + "planckh": "ℎ", + "plankv": "ℏ", + "plusacir": "⨣", + "plusb": "⊞", + "pluscir": "⨢", + "plus": "+", + "plusdo": "∔", + "plusdu": "⨥", + "pluse": "⩲", + "PlusMinus": "±", + "plusmn": "±", + "plussim": "⨦", + "plustwo": "⨧", + "pm": "±", + "Poincareplane": "ℌ", + "pointint": "⨕", + "popf": "𝕡", + "Popf": "ℙ", + "pound": "£", + "prap": "⪷", + "Pr": "⪻", + "pr": "≺", + "prcue": "≼", + "precapprox": "⪷", + "prec": "≺", + "preccurlyeq": "≼", + "Precedes": "≺", + "PrecedesEqual": "⪯", + "PrecedesSlantEqual": "≼", + "PrecedesTilde": "≾", + "preceq": "⪯", + "precnapprox": "⪹", + "precneqq": "⪵", + "precnsim": "⋨", + "pre": "⪯", + "prE": "⪳", + "precsim": "≾", + "prime": "′", + "Prime": "″", + "primes": "ℙ", + "prnap": "⪹", + "prnE": "⪵", + "prnsim": "⋨", + "prod": "∏", + "Product": "∏", + "profalar": "⌮", + "profline": "⌒", + "profsurf": "⌓", + "prop": "∝", + "Proportional": "∝", + "Proportion": "∷", + "propto": "∝", + "prsim": "≾", + "prurel": "⊰", + "Pscr": "𝒫", + "pscr": "𝓅", + "Psi": "Ψ", + "psi": "ψ", + "puncsp": " ", + "Qfr": "𝔔", + "qfr": "𝔮", + "qint": "⨌", + "qopf": "𝕢", + "Qopf": "ℚ", + "qprime": "⁗", + "Qscr": "𝒬", + "qscr": "𝓆", + "quaternions": "ℍ", + "quatint": "⨖", + "quest": "?", + "questeq": "≟", + "quot": "\"", + "QUOT": "\"", + "rAarr": "⇛", + "race": "∽̱", + "Racute": "Ŕ", + "racute": "ŕ", + "radic": "√", + "raemptyv": "⦳", + "rang": "⟩", + "Rang": "⟫", + "rangd": "⦒", + "range": "⦥", + "rangle": "⟩", + "raquo": "»", + "rarrap": "⥵", + "rarrb": "⇥", + "rarrbfs": "⤠", + "rarrc": "⤳", + "rarr": "→", + "Rarr": "↠", + "rArr": "⇒", + "rarrfs": "⤞", + "rarrhk": "↪", + "rarrlp": "↬", + "rarrpl": "⥅", + "rarrsim": "⥴", + "Rarrtl": "⤖", + "rarrtl": "↣", + "rarrw": "↝", + "ratail": "⤚", + "rAtail": "⤜", + "ratio": "∶", + "rationals": "ℚ", + "rbarr": "⤍", + "rBarr": "⤏", + "RBarr": "⤐", + "rbbrk": "❳", + "rbrace": "}", + "rbrack": "]", + "rbrke": "⦌", + "rbrksld": "⦎", + "rbrkslu": "⦐", + "Rcaron": "Ř", + "rcaron": "ř", + "Rcedil": "Ŗ", + "rcedil": "ŗ", + "rceil": "⌉", + "rcub": "}", + "Rcy": "Р", + "rcy": "р", + "rdca": "⤷", + "rdldhar": "⥩", + "rdquo": "”", + "rdquor": "”", + "rdsh": "↳", + "real": "ℜ", + "realine": "ℛ", + "realpart": "ℜ", + "reals": "ℝ", + "Re": "ℜ", + "rect": "▭", + "reg": "®", + "REG": "®", + "ReverseElement": "∋", + "ReverseEquilibrium": "⇋", + "ReverseUpEquilibrium": "⥯", + "rfisht": "⥽", + "rfloor": "⌋", + "rfr": "𝔯", + "Rfr": "ℜ", + "rHar": "⥤", + "rhard": "⇁", + "rharu": "⇀", + "rharul": "⥬", + "Rho": "Ρ", + "rho": "ρ", + "rhov": "ϱ", + "RightAngleBracket": "⟩", + "RightArrowBar": "⇥", + "rightarrow": "→", + "RightArrow": "→", + "Rightarrow": "⇒", + "RightArrowLeftArrow": "⇄", + "rightarrowtail": "↣", + "RightCeiling": "⌉", + "RightDoubleBracket": "⟧", + "RightDownTeeVector": "⥝", + "RightDownVectorBar": "⥕", + "RightDownVector": "⇂", + "RightFloor": "⌋", + "rightharpoondown": "⇁", + "rightharpoonup": "⇀", + "rightleftarrows": "⇄", + "rightleftharpoons": "⇌", + "rightrightarrows": "⇉", + "rightsquigarrow": "↝", + "RightTeeArrow": "↦", + "RightTee": "⊢", + "RightTeeVector": "⥛", + "rightthreetimes": "⋌", + "RightTriangleBar": "⧐", + "RightTriangle": "⊳", + "RightTriangleEqual": "⊵", + "RightUpDownVector": "⥏", + "RightUpTeeVector": "⥜", + "RightUpVectorBar": "⥔", + "RightUpVector": "↾", + "RightVectorBar": "⥓", + "RightVector": "⇀", + "ring": "˚", + "risingdotseq": "≓", + "rlarr": "⇄", + "rlhar": "⇌", + "rlm": "‏", + "rmoustache": "⎱", + "rmoust": "⎱", + "rnmid": "⫮", + "roang": "⟭", + "roarr": "⇾", + "robrk": "⟧", + "ropar": "⦆", + "ropf": "𝕣", + "Ropf": "ℝ", + "roplus": "⨮", + "rotimes": "⨵", + "RoundImplies": "⥰", + "rpar": ")", + "rpargt": "⦔", + "rppolint": "⨒", + "rrarr": "⇉", + "Rrightarrow": "⇛", + "rsaquo": "›", + "rscr": "𝓇", + "Rscr": "ℛ", + "rsh": "↱", + "Rsh": "↱", + "rsqb": "]", + "rsquo": "’", + "rsquor": "’", + "rthree": "⋌", + "rtimes": "⋊", + "rtri": "▹", + "rtrie": "⊵", + "rtrif": "▸", + "rtriltri": "⧎", + "RuleDelayed": "⧴", + "ruluhar": "⥨", + "rx": "℞", + "Sacute": "Ś", + "sacute": "ś", + "sbquo": "‚", + "scap": "⪸", + "Scaron": "Š", + "scaron": "š", + "Sc": "⪼", + "sc": "≻", + "sccue": "≽", + "sce": "⪰", + "scE": "⪴", + "Scedil": "Ş", + "scedil": "ş", + "Scirc": "Ŝ", + "scirc": "ŝ", + "scnap": "⪺", + "scnE": "⪶", + "scnsim": "⋩", + "scpolint": "⨓", + "scsim": "≿", + "Scy": "С", + "scy": "с", + "sdotb": "⊡", + "sdot": "⋅", + "sdote": "⩦", + "searhk": "⤥", + "searr": "↘", + "seArr": "⇘", + "searrow": "↘", + "sect": "§", + "semi": ";", + "seswar": "⤩", + "setminus": "∖", + "setmn": "∖", + "sext": "✶", + "Sfr": "𝔖", + "sfr": "𝔰", + "sfrown": "⌢", + "sharp": "♯", + "SHCHcy": "Щ", + "shchcy": "щ", + "SHcy": "Ш", + "shcy": "ш", + "ShortDownArrow": "↓", + "ShortLeftArrow": "←", + "shortmid": "∣", + "shortparallel": "∥", + "ShortRightArrow": "→", + "ShortUpArrow": "↑", + "shy": "­", + "Sigma": "Σ", + "sigma": "σ", + "sigmaf": "ς", + "sigmav": "ς", + "sim": "∼", + "simdot": "⩪", + "sime": "≃", + "simeq": "≃", + "simg": "⪞", + "simgE": "⪠", + "siml": "⪝", + "simlE": "⪟", + "simne": "≆", + "simplus": "⨤", + "simrarr": "⥲", + "slarr": "←", + "SmallCircle": "∘", + "smallsetminus": "∖", + "smashp": "⨳", + "smeparsl": "⧤", + "smid": "∣", + "smile": "⌣", + "smt": "⪪", + "smte": "⪬", + "smtes": "⪬︀", + "SOFTcy": "Ь", + "softcy": "ь", + "solbar": "⌿", + "solb": "⧄", + "sol": "/", + "Sopf": "𝕊", + "sopf": "𝕤", + "spades": "♠", + "spadesuit": "♠", + "spar": "∥", + "sqcap": "⊓", + "sqcaps": "⊓︀", + "sqcup": "⊔", + "sqcups": "⊔︀", + "Sqrt": "√", + "sqsub": "⊏", + "sqsube": "⊑", + "sqsubset": "⊏", + "sqsubseteq": "⊑", + "sqsup": "⊐", + "sqsupe": "⊒", + "sqsupset": "⊐", + "sqsupseteq": "⊒", + "square": "□", + "Square": "□", + "SquareIntersection": "⊓", + "SquareSubset": "⊏", + "SquareSubsetEqual": "⊑", + "SquareSuperset": "⊐", + "SquareSupersetEqual": "⊒", + "SquareUnion": "⊔", + "squarf": "▪", + "squ": "□", + "squf": "▪", + "srarr": "→", + "Sscr": "𝒮", + "sscr": "𝓈", + "ssetmn": "∖", + "ssmile": "⌣", + "sstarf": "⋆", + "Star": "⋆", + "star": "☆", + "starf": "★", + "straightepsilon": "ϵ", + "straightphi": "ϕ", + "strns": "¯", + "sub": "⊂", + "Sub": "⋐", + "subdot": "⪽", + "subE": "⫅", + "sube": "⊆", + "subedot": "⫃", + "submult": "⫁", + "subnE": "⫋", + "subne": "⊊", + "subplus": "⪿", + "subrarr": "⥹", + "subset": "⊂", + "Subset": "⋐", + "subseteq": "⊆", + "subseteqq": "⫅", + "SubsetEqual": "⊆", + "subsetneq": "⊊", + "subsetneqq": "⫋", + "subsim": "⫇", + "subsub": "⫕", + "subsup": "⫓", + "succapprox": "⪸", + "succ": "≻", + "succcurlyeq": "≽", + "Succeeds": "≻", + "SucceedsEqual": "⪰", + "SucceedsSlantEqual": "≽", + "SucceedsTilde": "≿", + "succeq": "⪰", + "succnapprox": "⪺", + "succneqq": "⪶", + "succnsim": "⋩", + "succsim": "≿", + "SuchThat": "∋", + "sum": "∑", + "Sum": "∑", + "sung": "♪", + "sup1": "¹", + "sup2": "²", + "sup3": "³", + "sup": "⊃", + "Sup": "⋑", + "supdot": "⪾", + "supdsub": "⫘", + "supE": "⫆", + "supe": "⊇", + "supedot": "⫄", + "Superset": "⊃", + "SupersetEqual": "⊇", + "suphsol": "⟉", + "suphsub": "⫗", + "suplarr": "⥻", + "supmult": "⫂", + "supnE": "⫌", + "supne": "⊋", + "supplus": "⫀", + "supset": "⊃", + "Supset": "⋑", + "supseteq": "⊇", + "supseteqq": "⫆", + "supsetneq": "⊋", + "supsetneqq": "⫌", + "supsim": "⫈", + "supsub": "⫔", + "supsup": "⫖", + "swarhk": "⤦", + "swarr": "↙", + "swArr": "⇙", + "swarrow": "↙", + "swnwar": "⤪", + "szlig": "ß", + "Tab": "\t", + "target": "⌖", + "Tau": "Τ", + "tau": "τ", + "tbrk": "⎴", + "Tcaron": "Ť", + "tcaron": "ť", + "Tcedil": "Ţ", + "tcedil": "ţ", + "Tcy": "Т", + "tcy": "т", + "tdot": "⃛", + "telrec": "⌕", + "Tfr": "𝔗", + "tfr": "𝔱", + "there4": "∴", + "therefore": "∴", + "Therefore": "∴", + "Theta": "Θ", + "theta": "θ", + "thetasym": "ϑ", + "thetav": "ϑ", + "thickapprox": "≈", + "thicksim": "∼", + "ThickSpace": "  ", + "ThinSpace": " ", + "thinsp": " ", + "thkap": "≈", + "thksim": "∼", + "THORN": "Þ", + "thorn": "þ", + "tilde": "˜", + "Tilde": "∼", + "TildeEqual": "≃", + "TildeFullEqual": "≅", + "TildeTilde": "≈", + "timesbar": "⨱", + "timesb": "⊠", + "times": "×", + "timesd": "⨰", + "tint": "∭", + "toea": "⤨", + "topbot": "⌶", + "topcir": "⫱", + "top": "⊤", + "Topf": "𝕋", + "topf": "𝕥", + "topfork": "⫚", + "tosa": "⤩", + "tprime": "‴", + "trade": "™", + "TRADE": "™", + "triangle": "▵", + "triangledown": "▿", + "triangleleft": "◃", + "trianglelefteq": "⊴", + "triangleq": "≜", + "triangleright": "▹", + "trianglerighteq": "⊵", + "tridot": "◬", + "trie": "≜", + "triminus": "⨺", + "TripleDot": "⃛", + "triplus": "⨹", + "trisb": "⧍", + "tritime": "⨻", + "trpezium": "⏢", + "Tscr": "𝒯", + "tscr": "𝓉", + "TScy": "Ц", + "tscy": "ц", + "TSHcy": "Ћ", + "tshcy": "ћ", + "Tstrok": "Ŧ", + "tstrok": "ŧ", + "twixt": "≬", + "twoheadleftarrow": "↞", + "twoheadrightarrow": "↠", + "Uacute": "Ú", + "uacute": "ú", + "uarr": "↑", + "Uarr": "↟", + "uArr": "⇑", + "Uarrocir": "⥉", + "Ubrcy": "Ў", + "ubrcy": "ў", + "Ubreve": "Ŭ", + "ubreve": "ŭ", + "Ucirc": "Û", + "ucirc": "û", + "Ucy": "У", + "ucy": "у", + "udarr": "⇅", + "Udblac": "Ű", + "udblac": "ű", + "udhar": "⥮", + "ufisht": "⥾", + "Ufr": "𝔘", + "ufr": "𝔲", + "Ugrave": "Ù", + "ugrave": "ù", + "uHar": "⥣", + "uharl": "↿", + "uharr": "↾", + "uhblk": "▀", + "ulcorn": "⌜", + "ulcorner": "⌜", + "ulcrop": "⌏", + "ultri": "◸", + "Umacr": "Ū", + "umacr": "ū", + "uml": "¨", + "UnderBar": "_", + "UnderBrace": "⏟", + "UnderBracket": "⎵", + "UnderParenthesis": "⏝", + "Union": "⋃", + "UnionPlus": "⊎", + "Uogon": "Ų", + "uogon": "ų", + "Uopf": "𝕌", + "uopf": "𝕦", + "UpArrowBar": "⤒", + "uparrow": "↑", + "UpArrow": "↑", + "Uparrow": "⇑", + "UpArrowDownArrow": "⇅", + "updownarrow": "↕", + "UpDownArrow": "↕", + "Updownarrow": "⇕", + "UpEquilibrium": "⥮", + "upharpoonleft": "↿", + "upharpoonright": "↾", + "uplus": "⊎", + "UpperLeftArrow": "↖", + "UpperRightArrow": "↗", + "upsi": "υ", + "Upsi": "ϒ", + "upsih": "ϒ", + "Upsilon": "Υ", + "upsilon": "υ", + "UpTeeArrow": "↥", + "UpTee": "⊥", + "upuparrows": "⇈", + "urcorn": "⌝", + "urcorner": "⌝", + "urcrop": "⌎", + "Uring": "Ů", + "uring": "ů", + "urtri": "◹", + "Uscr": "𝒰", + "uscr": "𝓊", + "utdot": "⋰", + "Utilde": "Ũ", + "utilde": "ũ", + "utri": "▵", + "utrif": "▴", + "uuarr": "⇈", + "Uuml": "Ü", + "uuml": "ü", + "uwangle": "⦧", + "vangrt": "⦜", + "varepsilon": "ϵ", + "varkappa": "ϰ", + "varnothing": "∅", + "varphi": "ϕ", + "varpi": "ϖ", + "varpropto": "∝", + "varr": "↕", + "vArr": "⇕", + "varrho": "ϱ", + "varsigma": "ς", + "varsubsetneq": "⊊︀", + "varsubsetneqq": "⫋︀", + "varsupsetneq": "⊋︀", + "varsupsetneqq": "⫌︀", + "vartheta": "ϑ", + "vartriangleleft": "⊲", + "vartriangleright": "⊳", + "vBar": "⫨", + "Vbar": "⫫", + "vBarv": "⫩", + "Vcy": "В", + "vcy": "в", + "vdash": "⊢", + "vDash": "⊨", + "Vdash": "⊩", + "VDash": "⊫", + "Vdashl": "⫦", + "veebar": "⊻", + "vee": "∨", + "Vee": "⋁", + "veeeq": "≚", + "vellip": "⋮", + "verbar": "|", + "Verbar": "‖", + "vert": "|", + "Vert": "‖", + "VerticalBar": "∣", + "VerticalLine": "|", + "VerticalSeparator": "❘", + "VerticalTilde": "≀", + "VeryThinSpace": " ", + "Vfr": "𝔙", + "vfr": "𝔳", + "vltri": "⊲", + "vnsub": "⊂⃒", + "vnsup": "⊃⃒", + "Vopf": "𝕍", + "vopf": "𝕧", + "vprop": "∝", + "vrtri": "⊳", + "Vscr": "𝒱", + "vscr": "𝓋", + "vsubnE": "⫋︀", + "vsubne": "⊊︀", + "vsupnE": "⫌︀", + "vsupne": "⊋︀", + "Vvdash": "⊪", + "vzigzag": "⦚", + "Wcirc": "Ŵ", + "wcirc": "ŵ", + "wedbar": "⩟", + "wedge": "∧", + "Wedge": "⋀", + "wedgeq": "≙", + "weierp": "℘", + "Wfr": "𝔚", + "wfr": "𝔴", + "Wopf": "𝕎", + "wopf": "𝕨", + "wp": "℘", + "wr": "≀", + "wreath": "≀", + "Wscr": "𝒲", + "wscr": "𝓌", + "xcap": "⋂", + "xcirc": "◯", + "xcup": "⋃", + "xdtri": "▽", + "Xfr": "𝔛", + "xfr": "𝔵", + "xharr": "⟷", + "xhArr": "⟺", + "Xi": "Ξ", + "xi": "ξ", + "xlarr": "⟵", + "xlArr": "⟸", + "xmap": "⟼", + "xnis": "⋻", + "xodot": "⨀", + "Xopf": "𝕏", + "xopf": "𝕩", + "xoplus": "⨁", + "xotime": "⨂", + "xrarr": "⟶", + "xrArr": "⟹", + "Xscr": "𝒳", + "xscr": "𝓍", + "xsqcup": "⨆", + "xuplus": "⨄", + "xutri": "△", + "xvee": "⋁", + "xwedge": "⋀", + "Yacute": "Ý", + "yacute": "ý", + "YAcy": "Я", + "yacy": "я", + "Ycirc": "Ŷ", + "ycirc": "ŷ", + "Ycy": "Ы", + "ycy": "ы", + "yen": "¥", + "Yfr": "𝔜", + "yfr": "𝔶", + "YIcy": "Ї", + "yicy": "ї", + "Yopf": "𝕐", + "yopf": "𝕪", + "Yscr": "𝒴", + "yscr": "𝓎", + "YUcy": "Ю", + "yucy": "ю", + "yuml": "ÿ", + "Yuml": "Ÿ", + "Zacute": "Ź", + "zacute": "ź", + "Zcaron": "Ž", + "zcaron": "ž", + "Zcy": "З", + "zcy": "з", + "Zdot": "Ż", + "zdot": "ż", + "zeetrf": "ℨ", + "ZeroWidthSpace": "​", + "Zeta": "Ζ", + "zeta": "ζ", + "zfr": "𝔷", + "Zfr": "ℨ", + "ZHcy": "Ж", + "zhcy": "ж", + "zigrarr": "⇝", + "zopf": "𝕫", + "Zopf": "ℤ", + "Zscr": "𝒵", + "zscr": "𝓏", + "zwj": "‍", + "zwnj": "‌" + }; + +/***/ }, +/* 33 */ +/***/ function(module, exports) { + + module.exports = { + "Aacute": "Á", + "aacute": "á", + "Acirc": "Â", + "acirc": "â", + "acute": "´", + "AElig": "Æ", + "aelig": "æ", + "Agrave": "À", + "agrave": "à", + "amp": "&", + "AMP": "&", + "Aring": "Å", + "aring": "å", + "Atilde": "Ã", + "atilde": "ã", + "Auml": "Ä", + "auml": "ä", + "brvbar": "¦", + "Ccedil": "Ç", + "ccedil": "ç", + "cedil": "¸", + "cent": "¢", + "copy": "©", + "COPY": "©", + "curren": "¤", + "deg": "°", + "divide": "÷", + "Eacute": "É", + "eacute": "é", + "Ecirc": "Ê", + "ecirc": "ê", + "Egrave": "È", + "egrave": "è", + "ETH": "Ð", + "eth": "ð", + "Euml": "Ë", + "euml": "ë", + "frac12": "½", + "frac14": "¼", + "frac34": "¾", + "gt": ">", + "GT": ">", + "Iacute": "Í", + "iacute": "í", + "Icirc": "Î", + "icirc": "î", + "iexcl": "¡", + "Igrave": "Ì", + "igrave": "ì", + "iquest": "¿", + "Iuml": "Ï", + "iuml": "ï", + "laquo": "«", + "lt": "<", + "LT": "<", + "macr": "¯", + "micro": "µ", + "middot": "·", + "nbsp": " ", + "not": "¬", + "Ntilde": "Ñ", + "ntilde": "ñ", + "Oacute": "Ó", + "oacute": "ó", + "Ocirc": "Ô", + "ocirc": "ô", + "Ograve": "Ò", + "ograve": "ò", + "ordf": "ª", + "ordm": "º", + "Oslash": "Ø", + "oslash": "ø", + "Otilde": "Õ", + "otilde": "õ", + "Ouml": "Ö", + "ouml": "ö", + "para": "¶", + "plusmn": "±", + "pound": "£", + "quot": "\"", + "QUOT": "\"", + "raquo": "»", + "reg": "®", + "REG": "®", + "sect": "§", + "shy": "­", + "sup1": "¹", + "sup2": "²", + "sup3": "³", + "szlig": "ß", + "THORN": "Þ", + "thorn": "þ", + "times": "×", + "Uacute": "Ú", + "uacute": "ú", + "Ucirc": "Û", + "ucirc": "û", + "Ugrave": "Ù", + "ugrave": "ù", + "uml": "¨", + "Uuml": "Ü", + "uuml": "ü", + "Yacute": "Ý", + "yacute": "ý", + "yen": "¥", + "yuml": "ÿ" + }; + +/***/ }, +/* 34 */ +/***/ function(module, exports) { + + module.exports = { + "amp": "&", + "apos": "'", + "gt": ">", + "lt": "<", + "quot": "\"" + }; + +/***/ }, +/* 35 */ +/***/ function(module, exports, __webpack_require__) { + + var ElementType = __webpack_require__(36); + + var re_whitespace = /\s+/g; + var NodePrototype = __webpack_require__(37); + var ElementPrototype = __webpack_require__(38); + + function DomHandler(callback, options, elementCB){ + if(typeof callback === "object"){ + elementCB = options; + options = callback; + callback = null; + } else if(typeof options === "function"){ + elementCB = options; + options = defaultOpts; + } + this._callback = callback; + this._options = options || defaultOpts; + this._elementCB = elementCB; + this.dom = []; + this._done = false; + this._tagStack = []; + this._parser = this._parser || null; + } + + //default options + var defaultOpts = { + normalizeWhitespace: false, //Replace all whitespace with single spaces + withStartIndices: false, //Add startIndex properties to nodes + }; + + DomHandler.prototype.onparserinit = function(parser){ + this._parser = parser; + }; + + //Resets the handler back to starting state + DomHandler.prototype.onreset = function(){ + DomHandler.call(this, this._callback, this._options, this._elementCB); + }; + + //Signals the handler that parsing is done + DomHandler.prototype.onend = function(){ + if(this._done) return; + this._done = true; + this._parser = null; + this._handleCallback(null); + }; + + DomHandler.prototype._handleCallback = + DomHandler.prototype.onerror = function(error){ + if(typeof this._callback === "function"){ + this._callback(error, this.dom); + } else { + if(error) throw error; + } + }; + + DomHandler.prototype.onclosetag = function(){ + //if(this._tagStack.pop().name !== name) this._handleCallback(Error("Tagname didn't match!")); + var elem = this._tagStack.pop(); + if(this._elementCB) this._elementCB(elem); + }; + + DomHandler.prototype._addDomElement = function(element){ + var parent = this._tagStack[this._tagStack.length - 1]; + var siblings = parent ? parent.children : this.dom; + var previousSibling = siblings[siblings.length - 1]; + + element.next = null; + + if(this._options.withStartIndices){ + element.startIndex = this._parser.startIndex; + } + + if (this._options.withDomLvl1) { + element.__proto__ = element.type === "tag" ? ElementPrototype : NodePrototype; + } + + if(previousSibling){ + element.prev = previousSibling; + previousSibling.next = element; + } else { + element.prev = null; + } + + siblings.push(element); + element.parent = parent || null; + }; + + DomHandler.prototype.onopentag = function(name, attribs){ + var element = { + type: name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag, + name: name, + attribs: attribs, + children: [] + }; + + this._addDomElement(element); + + this._tagStack.push(element); + }; + + DomHandler.prototype.ontext = function(data){ + //the ignoreWhitespace is officially dropped, but for now, + //it's an alias for normalizeWhitespace + var normalize = this._options.normalizeWhitespace || this._options.ignoreWhitespace; + + var lastTag; + + if(!this._tagStack.length && this.dom.length && (lastTag = this.dom[this.dom.length-1]).type === ElementType.Text){ + if(normalize){ + lastTag.data = (lastTag.data + data).replace(re_whitespace, " "); + } else { + lastTag.data += data; + } + } else { + if( + this._tagStack.length && + (lastTag = this._tagStack[this._tagStack.length - 1]) && + (lastTag = lastTag.children[lastTag.children.length - 1]) && + lastTag.type === ElementType.Text + ){ + if(normalize){ + lastTag.data = (lastTag.data + data).replace(re_whitespace, " "); + } else { + lastTag.data += data; + } + } else { + if(normalize){ + data = data.replace(re_whitespace, " "); + } + + this._addDomElement({ + data: data, + type: ElementType.Text + }); + } + } + }; + + DomHandler.prototype.oncomment = function(data){ + var lastTag = this._tagStack[this._tagStack.length - 1]; + + if(lastTag && lastTag.type === ElementType.Comment){ + lastTag.data += data; + return; + } + + var element = { + data: data, + type: ElementType.Comment + }; + + this._addDomElement(element); + this._tagStack.push(element); + }; + + DomHandler.prototype.oncdatastart = function(){ + var element = { + children: [{ + data: "", + type: ElementType.Text + }], + type: ElementType.CDATA + }; + + this._addDomElement(element); + this._tagStack.push(element); + }; + + DomHandler.prototype.oncommentend = DomHandler.prototype.oncdataend = function(){ + this._tagStack.pop(); + }; + + DomHandler.prototype.onprocessinginstruction = function(name, data){ + this._addDomElement({ + name: name, + data: data, + type: ElementType.Directive + }); + }; + + module.exports = DomHandler; + + +/***/ }, +/* 36 */ +/***/ function(module, exports) { + + //Types of elements found in the DOM + module.exports = { + Text: "text", //Text + Directive: "directive", // + Comment: "comment", // + Script: "script", //