diff --git a/README.md b/README.md index 234e07629..86cff25c5 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,44 @@ make build ``` +## Abstract Syntax Tree + +#### Overview + +#### Anatomy of a Block +```json +{ + "id": "^1r~63Gdl7;Dh?I*OP3_", + "opcode": "wedo_motorclockwise", + "next": null, + "fields": { + "DURATION": { + "name": "DURATION", + "value": null, + "blocks": { + "1?P=eV(OiDY3vMk!24Ip": { + "id": "1?P=eV(OiDY3vMk!24Ip", + "opcode": "math_number", + "next": null, + "fields": { + "NUM": { + "name": "NUM", + "value": "10", + "blocks": null + } + } + } + } + }, + "SUBSTACK": { + "name": "SUBSTACK", + "value": "@1ln(HsUO4!]*2*%BrE|", + "blocks": null + } + } +} +``` + ## Testing ```bash make test diff --git a/package.json b/package.json index 90f5105db..3fd3d7539 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,14 @@ "scripts": { "test": "make test" }, - "dependencies": {}, + "dependencies": { + "htmlparser2": "3.9.0", + "memoizee": "0.3.10" + }, "devDependencies": { "benchmark": "2.1.0", "eslint": "2.7.0", + "json-loader": "0.5.4", "tap": "5.7.1", "webpack": "1.13.0" } diff --git a/src/engine/adapter.js b/src/engine/adapter.js new file mode 100644 index 000000000..50240ca4e --- /dev/null +++ b/src/engine/adapter.js @@ -0,0 +1,87 @@ +var html = require('htmlparser2'); +var memoize = require('memoizee'); +var parseDOM = memoize(html.parseDOM, { + length: 1, + resolvers: [String], + max: 200 +}); + +/** + * Adapter between block creation events and block representation which can be + * used by the Scratch runtime. + * + * @param {Object} `Blockly.events.create` + * + * @return {Object} + */ +module.exports = function (e) { + // Validate input + if (typeof e !== 'object') return; + if (typeof e.blockId !== 'string') return; + if (typeof e.xml !== 'object') return; + + // Storage object + var obj = { + id: e.blockId, + opcode: null, + next: null, + fields: {} + }; + + // Set opcode + if (typeof e.xml.attributes === 'object') { + obj.opcode = e.xml.attributes.type.value; + } + + // Extract fields from event's `innerHTML` + if (typeof e.xml.innerHTML !== 'string') return obj; + if (e.xml.innerHTML === '') return obj; + obj.fields = extract(parseDOM(e.xml.innerHTML)); + + return obj; +} + +/** + * Extracts fields from a block's innerHTML. + * @todo Extend this to support vertical grammar / nested blocks. + * + * @param {Object} DOM representation of block's innerHTML + * + * @return {Object} + */ +function extract (dom) { + // Storage object + var fields = {}; + + // Field + var field = dom[0]; + var fieldName = field.attribs.name; + fields[fieldName] = { + name: fieldName, + value: null, + blocks: {} + }; + + // Shadow block + var shadow = field.children[0]; + var shadowId = shadow.attribs.id; + var shadowOpcode = shadow.attribs.type; + fields[fieldName].blocks[shadowId] = { + id: shadowId, + opcode: shadowOpcode, + next: null, + fields: {} + }; + + // Primitive + var primitive = shadow.children[0]; + var primitiveName = primitive.attribs.name; + var primitiveValue = primitive.children[0].data; + fields[fieldName].blocks[shadowId].fields[primitiveName] = { + name: primitiveName, + value: primitiveValue, + blocks: null + }; + + return fields; +} diff --git a/src/engine/primatives.js b/src/engine/primatives.js index c8ee6c193..3e8fb2dae 100644 --- a/src/engine/primatives.js +++ b/src/engine/primatives.js @@ -1,41 +1,5 @@ function Primitives () { - + // @todo } -Primitives.prototype.event_whenflagclicked = function (thread, runtime) { - // No-op: flags are started by the interpreter but don't do any action - // Take 1/3 second to show running state - if (Date.now() - thread.blockFirstTime < 300) { - thread.yield = true; - return; - } -}; - -Primitives.prototype.control_repeat = function (thread, runtime) { - // Take 1/3 second to show running state - if (Date.now() - thread.blockFirstTime < 300) { - thread.yield = true; - return; - } - if (thread.repeatCounter == -1) { - thread.repeatCounter = 10; // @todo from the arg - } - if (thread.repeatCounter > 0) { - thread.repeatCounter -= 1; - runtime.interpreter.startSubstack(thread); - } else { - thread.repeatCounter = -1; - thread.nextBlock = runtime.getNextBlock(thread.blockPointer); - } -}; - -Primitives.prototype.control_forever = function (thread, runtime) { - // Take 1/3 second to show running state - if (Date.now() - thread.blockFirstTime < 300) { - thread.yield = true; - return; - } - runtime.interpreter.startSubstack(thread); -}; - module.exports = Primitives; diff --git a/src/engine/runtime.js b/src/engine/runtime.js index 6625fa465..4c81faab6 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -1,26 +1,19 @@ var EventEmitter = require('events'); var util = require('util'); -var Primitives = require('./primatives'); -var Sequencer = require('./sequencer'); -var Thread = require('./thread'); - -var STEP_THREADS_INTERVAL = 1000 / 30; - /** * A simple runtime for blocks. */ function Runtime () { // Bind event emitter - EventEmitter.call(instance); - - // Instantiate sequencer and primitives - this.sequencer = new Sequencer(this); - this.primitives = new Primitives(); + EventEmitter.call(this); // State this.blocks = {}; this.stacks = []; + + window._BLOCKS = this.blocks; + window._STACKS = this.stacks; } /** @@ -28,19 +21,34 @@ function Runtime () { */ util.inherits(Runtime, EventEmitter); -Runtime.prototype.createBlock = function (e) { +Runtime.prototype.createBlock = function (block) { // Create new block - this.blocks[e.id] = { - id: e.id, - opcode: e.opcode, - next: null, - inputs: {} - }; + this.blocks[block.id] = block; + + // Walk each field and add any shadow blocks + // @todo Expand this to cover vertical / nested blocks + for (var i in block.fields) { + var shadows = block.fields[i].blocks; + for (var y in shadows) { + var shadow = shadows[y]; + this.blocks[shadow.id] = shadow; + }; + } // Push block id to stacks array. New blocks are always a stack even if only // momentary. If the new block is added to an existing stack this stack will // be removed by the `moveBlock` method below. - this.stacks.push(e.id); + this.stacks.push(block.id); +}; + +Runtime.prototype.changeBlock = function (args) { + // Validate + if (args.element !== 'field') return; + if (typeof this.blocks[args.id] === 'undefined') return; + if (typeof this.blocks[args.id].fields[args.name] === 'undefined') return; + + // Update block value + this.blocks[args.id].fields[args.name].value = args.value; }; Runtime.prototype.moveBlock = function (e) { @@ -52,10 +60,14 @@ Runtime.prototype.moveBlock = function (e) { _this._deleteStack(e.id); // Update new parent - if (e.newInput === undefined) { + if (e.newField === undefined) { _this.blocks[e.newParent].next = e.id; } else { - _this.blocks[e.newParent].inputs[e.newInput] = e.id; + _this.blocks[e.newParent].fields[e.newField] = { + name: e.newField, + value: e.id, + blocks: {} + }; } } @@ -65,30 +77,34 @@ Runtime.prototype.moveBlock = function (e) { _this.stacks.push(e.id); // Update old parent - if (e.oldInput === undefined) { + if (e.oldField === undefined) { _this.blocks[e.oldParent].next = null; } else { - delete _this.blocks[e.oldParent].inputs[e.oldInput]; + delete _this.blocks[e.oldParent].fields[e.oldField]; } } }; -Runtime.prototype.changeBlock = function (e) { - // @todo -}; - Runtime.prototype.deleteBlock = function (e) { // @todo Stop threads running on this stack - // Delete children + // Get block var block = this.blocks[e.id]; + + // Delete children if (block.next !== null) { this.deleteBlock({id: block.next}); } - // Delete inputs - for (var i in block.inputs) { - this.deleteBlock({id: block.inputs[i]}); + // Delete substacks and fields + for (var field in block.fields) { + if (field === 'SUBSTACK') { + this.deleteBlock({id: block.fields[field].value}); + } else { + for (var shadow in block.fields[field].blocks) { + this.deleteBlock({id: shadow}); + } + } } // Delete stack @@ -98,19 +114,6 @@ Runtime.prototype.deleteBlock = function (e) { delete this.blocks[e.id]; }; -Runtime.prototype.runAllStacks = function () { - // @todo -}; - -Runtime.prototype.runStack = function (e) { - // @todo - console.dir(e); -}; - -Runtime.prototype.stopAllStacks = function () { - // @todo -}; - // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- @@ -126,7 +129,7 @@ Runtime.prototype._getNextBlock = function (id) { Runtime.prototype._getSubstack = function (id) { if (typeof this.blocks[id] === 'undefined') return null; - return this.blocks[id].inputs['SUBSTACK']; + return this.blocks[id].fields['SUBSTACK']; }; module.exports = Runtime; diff --git a/src/engine/sequencer.js b/src/engine/sequencer.js index 09723614f..919f105fa 100644 --- a/src/engine/sequencer.js +++ b/src/engine/sequencer.js @@ -1,29 +1,5 @@ -var Timer = require('../util/timer'); - -/** - * Constructor - */ -function Sequencer (runtime) { - // Bi-directional binding for runtime - this.runtime = runtime; - - // State - this.runningThreads = []; - this.workTime = 30; - this.timer = new Timer(); - this.currentTime = 0; +function Sequencer () { + // @todo } -Sequencer.prototype.stepAllThreads = function () { - -}; - -Sequencer.prototype.stepThread = function (thread) { - -}; - -Sequencer.prototype.startSubstack = function (thread) { - -}; - module.exports = Sequencer; diff --git a/src/engine/thread.js b/src/engine/thread.js index a3ce684ab..42dd09587 100644 --- a/src/engine/thread.js +++ b/src/engine/thread.js @@ -1,19 +1,5 @@ -/** - * Thread is an internal data structure used by the interpreter. It holds the - * state of a thread so it can continue from where it left off, and it has - * a stack to support nested control structures and procedure calls. - * - * @param {String} Unique block identifier - */ -function Thread (id) { - this.topBlockId = id; - this.blockPointer = id; - this.blockFirstTime = -1; - this.nextBlock = null; - this.waiting = null; - this.runningDeviceBlock = false; - this.stack = []; - this.repeatCounter = -1; +function Thread () { + // @todo } module.exports = Thread; diff --git a/src/index.js b/src/index.js index 148155b51..d88033341 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,7 @@ var EventEmitter = require('events'); var util = require('util'); var Runtime = require('./engine/runtime'); +var adapter = require('./engine/adapter'); /** * Handles connections between blocks, stage, and extensions. @@ -30,23 +31,23 @@ function VirtualMachine () { // Blocks switch (e.type) { case 'create': - instance.runtime.createBlock({ + instance.runtime.createBlock(adapter(e)); + break; + case 'change': + instance.runtime.changeBlock({ id: e.blockId, - opcode: e.xml.attributes.type.value + element: e.element, + name: e.name, + value: e.newValue }); break; case 'move': instance.runtime.moveBlock({ id: e.blockId, oldParent: e.oldParentId, - oldInput: e.oldInputName, + oldField: e.oldInputName, newParent: e.newParentId, - newInput: e.newInputName - }); - break; - case 'change': - instance.runtime.changeBlock({ - id: e.blockId + newField: e.newInputName }); break; case 'delete': @@ -55,19 +56,7 @@ function VirtualMachine () { }); break; } - - // UI - if (typeof e.element === 'undefined') return; - switch (e.element) { - case 'click': - instance.runtime.runStack({ - id: e.blockId - }); - break; - } }; - - // @todo Forward runtime events } /** @@ -75,22 +64,6 @@ function VirtualMachine () { */ util.inherits(VirtualMachine, EventEmitter); -VirtualMachine.prototype.start = function () { - // @todo Run all green flags -}; - -VirtualMachine.prototype.stop = function () { - // @todo Stop all threads -}; - -VirtualMachine.prototype.save = function () { - // @todo Serialize runtime state -}; - -VirtualMachine.prototype.load = function () { - // @todo Deserialize and apply runtime state -}; - /** * Export and bind to `window` */ diff --git a/src/util/timer.js b/src/util/timer.js index f093c3e53..b16585205 100644 --- a/src/util/timer.js +++ b/src/util/timer.js @@ -1,6 +1,5 @@ /** * Constructor - * @todo Swap out Date.now() with microtime module that works in node & browsers */ function Timer () { this.startTime = 0; diff --git a/test/benchmark/ast.js b/test/benchmark/ast.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/blocks.js b/test/fixtures/blocks.js deleted file mode 100644 index 0b5c396b0..000000000 --- a/test/fixtures/blocks.js +++ /dev/null @@ -1,26 +0,0 @@ -var events = require('events'); -var util = require('util'); - -/** - * Simulates event emitter / listener patterns from Scratch Blocks. - * - * @author Andrew Sliwinski - */ -function Blocks () { - -} - -/** - * Inherit from EventEmitter to enable messaging. - */ -util.inherits(VirtualMachine, events.EventEmitter); - -Blocks.prototype.spaghetti = function () { - this.emit(''); -}; - -Blocks.prototype.spam = function () { - this.emit(''); -}; - -module.exports = Blocks; diff --git a/test/fixtures/events.json b/test/fixtures/events.json new file mode 100644 index 000000000..fca8693ff --- /dev/null +++ b/test/fixtures/events.json @@ -0,0 +1,20 @@ +{ + "create": { + "blockId": "z!+#Nqr,_(V=xz0y7a@d", + "workspaceId": "7Luws3lyb*Z98~Kk+IG|", + "group": ";OswyM#@%`%,xOrhOXC=", + "recordUndo": true, + "xml": { + "attributes": { + "type": { + "value": "wedo_motorclockwise" + } + }, + "innerHTML": "10" + }, + "ids": [ + "z!+#Nqr,_(V=xz0y7a@d", + "!6Ahqg4f}Ljl}X5Hws?Z" + ] + } +} diff --git a/test/integration/index.js b/test/integration/index.js new file mode 100644 index 000000000..c91a852f8 --- /dev/null +++ b/test/integration/index.js @@ -0,0 +1,22 @@ +var test = require('tap').test; +var VirtualMachine = require('../../src/index'); + +test('spec', function (t) { + t.end(); +}); + +test('create', function (t) { + t.end(); +}); + +test('move', function (t) { + t.end(); +}); + +test('change', function (t) { + t.end(); +}); + +test('delete', function (t) { + t.end(); +}); diff --git a/test/unit/adapter.js b/test/unit/adapter.js new file mode 100644 index 000000000..547e0b9b0 --- /dev/null +++ b/test/unit/adapter.js @@ -0,0 +1,20 @@ +var test = require('tap').test; +var adapter = require('../../src/engine/adapter'); +var events = require('../fixtures/events.json'); + +test('spec', function (t) { + t.type(adapter, 'function'); + t.end(); +}); + +test('create event', function (t) { + var result = adapter(events.create); + + t.type(result, 'object'); + t.type(result.id, 'string'); + t.type(result.opcode, 'string'); + t.type(result.fields, 'object'); + t.type(result.fields['DURATION'], 'object'); + + t.end(); +}); diff --git a/test/unit/primatives.js b/test/unit/primatives.js new file mode 100644 index 000000000..c028dc2f5 --- /dev/null +++ b/test/unit/primatives.js @@ -0,0 +1,8 @@ +var test = require('tap').test; +var Primatives = require('../../src/engine/primatives'); + +test('spec', function (t) { + t.type(Primatives, 'function'); + // @todo + t.end(); +}); diff --git a/test/unit/runtime.js b/test/unit/runtime.js index ac58d4e6b..0e41ed5be 100644 --- a/test/unit/runtime.js +++ b/test/unit/runtime.js @@ -24,7 +24,9 @@ test('create', function (t) { var r = new Runtime(); r.createBlock({ id: 'foo', - opcode: 'TEST_BLOCK' + opcode: 'TEST_BLOCK', + next: null, + fields: {} }); t.type(r.blocks['foo'], 'object'); @@ -37,11 +39,15 @@ test('move', function (t) { var r = new Runtime(); r.createBlock({ id: 'foo', - opcode: 'TEST_BLOCK' + opcode: 'TEST_BLOCK', + next: null, + fields: {} }); r.createBlock({ id: 'bar', - opcode: 'TEST_BLOCK' + opcode: 'TEST_BLOCK', + next: null, + fields: {} }); // Attach 'bar' to the end of 'foo' @@ -69,7 +75,9 @@ test('delete', function (t) { var r = new Runtime(); r.createBlock({ id: 'foo', - opcode: 'TEST_BLOCK' + opcode: 'TEST_BLOCK', + next: null, + fields: {} }); r.deleteBlock({ id: 'foo' diff --git a/test/unit/sequencer.js b/test/unit/sequencer.js new file mode 100644 index 000000000..23ec4c13d --- /dev/null +++ b/test/unit/sequencer.js @@ -0,0 +1,8 @@ +var test = require('tap').test; +var Sequencer = require('../../src/engine/sequencer'); + +test('spec', function (t) { + t.type(Sequencer, 'function'); + // @todo + t.end(); +}); diff --git a/test/unit/spec.js b/test/unit/spec.js index 796c165fe..22519faa7 100644 --- a/test/unit/spec.js +++ b/test/unit/spec.js @@ -2,17 +2,10 @@ var test = require('tap').test; var VirtualMachine = require('../../src/index'); test('spec', function (t) { - var vm = new VirtualMachine('foo'); + var vm = new VirtualMachine(); t.type(VirtualMachine, 'function'); t.type(vm, 'object'); - t.type(vm.blockListener, 'function'); - // t.type(vm.uiListener, 'function'); - // t.type(vm.start, 'function'); - // t.type(vm.stop, 'function'); - // t.type(vm.save, 'function'); - // t.type(vm.load, 'function'); - t.end(); }); diff --git a/test/unit/thread.js b/test/unit/thread.js index 3e5cede60..3bda4fc69 100644 --- a/test/unit/thread.js +++ b/test/unit/thread.js @@ -2,9 +2,7 @@ var test = require('tap').test; var Thread = require('../../src/engine/thread'); test('spec', function (t) { - var thread = new Thread('foo'); - t.type(Thread, 'function'); - t.type(thread, 'object'); + // @todo t.end(); }); diff --git a/vm.js b/vm.js index c91db8ad5..5358a9e4c 100644 --- a/vm.js +++ b/vm.js @@ -48,6 +48,7 @@ var util = __webpack_require__(2); var Runtime = __webpack_require__(6); + var adapter = __webpack_require__(7); /** * Handles connections between blocks, stage, and extensions. @@ -76,23 +77,23 @@ // Blocks switch (e.type) { case 'create': - instance.runtime.createBlock({ + instance.runtime.createBlock(adapter(e)); + break; + case 'change': + instance.runtime.changeBlock({ id: e.blockId, - opcode: e.xml.attributes.type.value + element: e.element, + name: e.name, + value: e.newValue }); break; case 'move': instance.runtime.moveBlock({ id: e.blockId, oldParent: e.oldParentId, - oldInput: e.oldInputName, + oldField: e.oldInputName, newParent: e.newParentId, - newInput: e.newInputName - }); - break; - case 'change': - instance.runtime.changeBlock({ - id: e.blockId + newField: e.newInputName }); break; case 'delete': @@ -101,19 +102,7 @@ }); break; } - - // UI - if (typeof e.element === 'undefined') return; - switch (e.element) { - case 'click': - instance.runtime.runStack({ - id: e.blockId - }); - break; - } }; - - // @todo Forward runtime events } /** @@ -121,22 +110,6 @@ */ util.inherits(VirtualMachine, EventEmitter); - VirtualMachine.prototype.start = function () { - // @todo Run all green flags - }; - - VirtualMachine.prototype.stop = function () { - // @todo Stop all threads - }; - - VirtualMachine.prototype.save = function () { - // @todo Serialize runtime state - }; - - VirtualMachine.prototype.load = function () { - // @todo Deserialize and apply runtime state - }; - /** * Export and bind to `window` */ @@ -1185,26 +1158,19 @@ var EventEmitter = __webpack_require__(1); var util = __webpack_require__(2); - var Primitives = __webpack_require__(7); - var Sequencer = __webpack_require__(8); - var Thread = __webpack_require__(10); - - var STEP_THREADS_INTERVAL = 1000 / 30; - /** * A simple runtime for blocks. */ function Runtime () { // Bind event emitter - EventEmitter.call(instance); - - // Instantiate sequencer and primitives - this.sequencer = new Sequencer(this); - this.primitives = new Primitives(); + EventEmitter.call(this); // State this.blocks = {}; this.stacks = []; + + window._BLOCKS = this.blocks; + window._STACKS = this.stacks; } /** @@ -1212,19 +1178,34 @@ */ util.inherits(Runtime, EventEmitter); - Runtime.prototype.createBlock = function (e) { + Runtime.prototype.createBlock = function (block) { // Create new block - this.blocks[e.id] = { - id: e.id, - opcode: e.opcode, - next: null, - inputs: {} - }; + this.blocks[block.id] = block; + + // Walk each field and add any shadow blocks + // @todo Expand this to cover vertical / nested blocks + for (var i in block.fields) { + var shadows = block.fields[i].blocks; + for (var y in shadows) { + var shadow = shadows[y]; + this.blocks[shadow.id] = shadow; + }; + } // Push block id to stacks array. New blocks are always a stack even if only // momentary. If the new block is added to an existing stack this stack will // be removed by the `moveBlock` method below. - this.stacks.push(e.id); + this.stacks.push(block.id); + }; + + Runtime.prototype.changeBlock = function (args) { + // Validate + if (args.element !== 'field') return; + if (typeof this.blocks[args.id] === 'undefined') return; + if (typeof this.blocks[args.id].fields[args.name] === 'undefined') return; + + // Update block value + this.blocks[args.id].fields[args.name].value = args.value; }; Runtime.prototype.moveBlock = function (e) { @@ -1236,10 +1217,14 @@ _this._deleteStack(e.id); // Update new parent - if (e.newInput === undefined) { + if (e.newField === undefined) { _this.blocks[e.newParent].next = e.id; } else { - _this.blocks[e.newParent].inputs[e.newInput] = e.id; + _this.blocks[e.newParent].fields[e.newField] = { + name: e.newField, + value: e.id, + blocks: {} + }; } } @@ -1249,30 +1234,34 @@ _this.stacks.push(e.id); // Update old parent - if (e.oldInput === undefined) { + if (e.oldField === undefined) { _this.blocks[e.oldParent].next = null; } else { - delete _this.blocks[e.oldParent].inputs[e.oldInput]; + delete _this.blocks[e.oldParent].fields[e.oldField]; } } }; - Runtime.prototype.changeBlock = function (e) { - // @todo - }; - Runtime.prototype.deleteBlock = function (e) { // @todo Stop threads running on this stack - // Delete children + // Get block var block = this.blocks[e.id]; + + // Delete children if (block.next !== null) { this.deleteBlock({id: block.next}); } - // Delete inputs - for (var i in block.inputs) { - this.deleteBlock({id: block.inputs[i]}); + // Delete substacks and fields + for (var field in block.fields) { + if (field === 'SUBSTACK') { + this.deleteBlock({id: block.fields[field].value}); + } else { + for (var shadow in block.fields[field].blocks) { + this.deleteBlock({id: shadow}); + } + } } // Delete stack @@ -1282,19 +1271,6 @@ delete this.blocks[e.id]; }; - Runtime.prototype.runAllStacks = function () { - // @todo - }; - - Runtime.prototype.runStack = function (e) { - // @todo - console.dir(e); - }; - - Runtime.prototype.stopAllStacks = function () { - // @todo - }; - // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- @@ -1310,7 +1286,7 @@ Runtime.prototype._getSubstack = function (id) { if (typeof this.blocks[id] === 'undefined') return null; - return this.blocks[id].inputs['SUBSTACK']; + return this.blocks[id].fields['SUBSTACK']; }; module.exports = Runtime; @@ -1318,136 +1294,11535 @@ /***/ }, /* 7 */ -/***/ function(module, exports) { +/***/ function(module, exports, __webpack_require__) { - function Primitives () { + var html = __webpack_require__(8); + var memoize = __webpack_require__(59); + var parseDOM = memoize(html.parseDOM, { + length: 1, + resolvers: [String], + max: 200 + }); + /** + * Adapter between block creation events and block representation which can be + * used by the Scratch runtime. + * + * @param {Object} `Blockly.events.create` + * + * @return {Object} + */ + module.exports = function (e) { + // Validate input + if (typeof e !== 'object') return; + if (typeof e.blockId !== 'string') return; + if (typeof e.xml !== 'object') return; + + // Storage object + var obj = { + id: e.blockId, + opcode: null, + next: null, + fields: {} + }; + + // Set opcode + if (typeof e.xml.attributes === 'object') { + obj.opcode = e.xml.attributes.type.value; + } + + // Extract fields from event's `innerHTML` + if (typeof e.xml.innerHTML !== 'string') return obj; + if (e.xml.innerHTML === '') return obj; + obj.fields = extract(parseDOM(e.xml.innerHTML)); + + return obj; } - Primitives.prototype.event_whenflagclicked = function (thread, runtime) { - // No-op: flags are started by the interpreter but don't do any action - // Take 1/3 second to show running state - if (Date.now() - thread.blockFirstTime < 300) { - thread.yield = true; - return; - } - }; + /** + * Extracts fields from a block's innerHTML. + * @todo Extend this to support vertical grammar / nested blocks. + * + * @param {Object} DOM representation of block's innerHTML + * + * @return {Object} + */ + function extract (dom) { + // Storage object + var fields = {}; - Primitives.prototype.control_repeat = function (thread, runtime) { - // Take 1/3 second to show running state - if (Date.now() - thread.blockFirstTime < 300) { - thread.yield = true; - return; - } - if (thread.repeatCounter == -1) { - thread.repeatCounter = 10; // @todo from the arg - } - if (thread.repeatCounter > 0) { - thread.repeatCounter -= 1; - runtime.interpreter.startSubstack(thread); - } else { - thread.repeatCounter = -1; - thread.nextBlock = runtime.getNextBlock(thread.blockPointer); - } - }; + // Field + var field = dom[0]; + var fieldName = field.attribs.name; + fields[fieldName] = { + name: fieldName, + value: null, + blocks: {} + }; - Primitives.prototype.control_forever = function (thread, runtime) { - // Take 1/3 second to show running state - if (Date.now() - thread.blockFirstTime < 300) { - thread.yield = true; - return; - } - runtime.interpreter.startSubstack(thread); - }; + // Shadow block + var shadow = field.children[0]; + var shadowId = shadow.attribs.id; + var shadowOpcode = shadow.attribs.type; + fields[fieldName].blocks[shadowId] = { + id: shadowId, + opcode: shadowOpcode, + next: null, + fields: {} + }; - module.exports = Primitives; + // Primitive + var primitive = shadow.children[0]; + var primitiveName = primitive.attribs.name; + var primitiveValue = primitive.children[0].data; + fields[fieldName].blocks[shadowId].fields[primitiveName] = { + name: primitiveName, + value: primitiveValue, + blocks: null + }; + + return fields; + } /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { - var Timer = __webpack_require__(9); + var Parser = __webpack_require__(9), + DomHandler = __webpack_require__(16); - /** - * Constructor - */ - function Sequencer (runtime) { - // Bi-directional binding for runtime - this.runtime = runtime; - - // State - this.runningThreads = []; - this.workTime = 30; - this.timer = new Timer(); - this.currentTime = 0; + function defineProp(name, value){ + delete module.exports[name]; + module.exports[name] = value; + return value; } - Sequencer.prototype.stepAllThreads = function () { - + module.exports = { + Parser: Parser, + Tokenizer: __webpack_require__(10), + ElementType: __webpack_require__(17), + DomHandler: DomHandler, + get FeedHandler(){ + return defineProp("FeedHandler", __webpack_require__(20)); + }, + get Stream(){ + return defineProp("Stream", __webpack_require__(21)); + }, + get WritableStream(){ + return defineProp("WritableStream", __webpack_require__(22)); + }, + get ProxyHandler(){ + return defineProp("ProxyHandler", __webpack_require__(45)); + }, + get DomUtils(){ + return defineProp("DomUtils", __webpack_require__(46)); + }, + get CollectingHandler(){ + return defineProp("CollectingHandler", __webpack_require__(58)); + }, + // 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 + } }; - Sequencer.prototype.stepThread = function (thread) { - - }; - - Sequencer.prototype.startSubstack = function (thread) { - - }; - - module.exports = Sequencer; - /***/ }, /* 9 */ -/***/ function(module, exports) { +/***/ function(module, exports, __webpack_require__) { - /** - * Constructor - * @todo Swap out Date.now() with microtime module that works in node & browsers - */ - function Timer () { - this.startTime = 0; + var Tokenizer = __webpack_require__(10); + + /* + 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); } - Timer.prototype.time = function () { - return Date.now(); + __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(); }; - Timer.prototype.start = function () { - this.startTime = this.time(); + //Tokenizer event handlers + Parser.prototype.ontext = function(data){ + this._updatePosition(1); + this.endIndex--; + + if(this._cbs.ontext) this._cbs.ontext(data); }; - Timer.prototype.stop = function () { - return this.startTime - this.time(); + 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 = {}; }; - module.exports = Timer; + 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; /***/ }, /* 10 */ -/***/ function(module, exports) { +/***/ function(module, exports, __webpack_require__) { - /** - * Thread is an internal data structure used by the interpreter. It holds the - * state of a thread so it can continue from where it left off, and it has - * a stack to support nested control structures and procedure calls. - * - * @param {String} Unique block identifier - */ - function Thread (id) { - this.topBlockId = id; - this.blockPointer = id; - this.blockFirstTime = -1; - this.nextBlock = null; - this.waiting = null; - this.runningDeviceBlock = false; - this.stack = []; - this.repeatCounter = -1; + module.exports = Tokenizer; + + var decodeCodePoint = __webpack_require__(11), + entityMap = __webpack_require__(13), + legacyMap = __webpack_require__(14), + xmlMap = __webpack_require__(15), + + 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"; } - module.exports = Thread; + 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); + } + }; + + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + var decodeMap = __webpack_require__(12); + + 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; + } + + +/***/ }, +/* 12 */ +/***/ 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 + }; + +/***/ }, +/* 13 */ +/***/ 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": "‌" + }; + +/***/ }, +/* 14 */ +/***/ 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": "ÿ" + }; + +/***/ }, +/* 15 */ +/***/ function(module, exports) { + + module.exports = { + "amp": "&", + "apos": "'", + "gt": ">", + "lt": "<", + "quot": "\"" + }; + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + var ElementType = __webpack_require__(17); + + var re_whitespace = /\s+/g; + var NodePrototype = __webpack_require__(18); + var ElementPrototype = __webpack_require__(19); + + 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; + + +/***/ }, +/* 17 */ +/***/ function(module, exports) { + + //Types of elements found in the DOM + module.exports = { + Text: "text", //Text + Directive: "directive", // + Comment: "comment", // + Script: "script", //