UNPKG

394 kBJavaScriptView Raw
1!function(){/**
2* @name AttributeList
3* @class
4* @extends Array
5* @classdesc Return a new list of {@link Element} attributes.
6* @param {...Array|AttributeList|Object} attrs - An array or object of attributes.
7* @returns {AttributeList}
8* @example
9* new AttributeList([{ name: 'class', value: 'foo' }, { name: 'id', value: 'bar' }])
10* @example
11* new AttributeList({ class: 'foo', id: 'bar' })
12*/
13class AttributeList extends Array {
14 constructor(attrs) {
15 super();
16
17 if (attrs === Object(attrs)) {
18 this.push(...getAttributeListArray(attrs));
19 }
20 }
21 /**
22 * Add an attribute or attributes to the current {@link AttributeList}.
23 * @param {Array|Object|RegExp|String} name - The attribute to remove.
24 * @param {String} [value] - The value of the attribute being added.
25 * @returns {Boolean} - Whether the attribute or attributes were added to the current {@link AttributeList}.
26 * @example <caption>Add an empty "id" attribute.</caption>
27 * attrs.add('id')
28 * @example <caption>Add an "id" attribute with a value of "bar".</caption>
29 * attrs.add({ id: 'bar' })
30 * @example
31 * attrs.add([{ name: 'id', value: 'bar' }])
32 */
33
34
35 add(name) {
36 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
37 args[_key - 1] = arguments[_key];
38 }
39
40 return toggle(this, getAttributeListArray(name, ...args), true).attributeAdded;
41 }
42 /**
43 * Return a new clone of the current {@link AttributeList} while conditionally applying additional attributes.
44 * @param {...Array|AttributeList|Object} attrs - Additional attributes to be added to the new {@link AttributeList}.
45 * @returns {Element} - The cloned Element.
46 * @example
47 * attrs.clone()
48 * @example <caption>Clone the current attribute and add an "id" attribute with a value of "bar".</caption>
49 * attrs.clone({ name: 'id', value: 'bar' })
50 */
51
52
53 clone() {
54 for (var _len2 = arguments.length, attrs = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
55 attrs[_key2] = arguments[_key2];
56 }
57
58 return new AttributeList(Array.from(this).concat(getAttributeListArray(attrs)));
59 }
60 /**
61 * Return whether an attribute or attributes exists in the current {@link AttributeList}.
62 * @param {String} name - The name or attribute object being accessed.
63 * @returns {Boolean} - Whether the attribute exists.
64 * @example <caption>Return whether there is an "id" attribute.</caption>
65 * attrs.contains('id')
66 * @example
67 * attrs.contains({ id: 'bar' })
68 * @example <caption>Return whether there is an "id" attribute with a value of "bar".</caption>
69 * attrs.contains([{ name: 'id': value: 'bar' }])
70 */
71
72
73 contains(name) {
74 return this.indexOf(name) !== -1;
75 }
76 /**
77 * Return an attribute value by name from the current {@link AttributeList}.
78 * @description If the attribute exists with a value then a String is returned. If the attribute exists with no value then `null` is returned. If the attribute does not exist then `false` is returned.
79 * @param {RegExp|String} name - The name of the attribute being accessed.
80 * @returns {Boolean|Null|String} - The value of the attribute (a string or null) or false (if the attribute does not exist).
81 * @example <caption>Return the value of "id" or `false`.</caption>
82 * // <div>this element has no "id" attribute</div>
83 * attrs.get('id') // returns false
84 * // <div id>this element has an "id" attribute with no value</div>
85 * attrs.get('id') // returns null
86 * // <div id="">this element has an "id" attribute with a value</div>
87 * attrs.get('id') // returns ''
88 */
89
90
91 get(name) {
92 const index = this.indexOf(name);
93 return index === -1 ? false : this[index].value;
94 }
95 /**
96 * Return the position of an attribute by name or attribute object in the current {@link AttributeList}.
97 * @param {Array|Object|RegExp|String} name - The attribute to locate.
98 * @returns {Number} - The index of the attribute or -1.
99 * @example <caption>Return the index of "id".</caption>
100 * attrs.indexOf('id')
101 * @example <caption>Return the index of /d$/.</caption>
102 * attrs.indexOf(/d$/i)
103 * @example <caption>Return the index of "foo" with a value of "bar".</caption>
104 * attrs.indexOf({ foo: 'bar' })
105 * @example <caption>Return the index of "ariaLabel" or "aria-label" matching /^open/.</caption>
106 * attrs.indexOf({ ariaLabel: /^open/ })
107 * @example <caption>Return the index of an attribute whose name matches `/^foo/`.</caption>
108 * attrs.indexOf([{ name: /^foo/ })
109 */
110
111
112 indexOf(name) {
113 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
114 args[_key3 - 1] = arguments[_key3];
115 }
116
117 return this.findIndex(Array.isArray(name) ? findIndexByArray : isRegExp(name) ? findIndexByRegExp : name === Object(name) ? findIndexByObject : findIndexByString);
118
119 function findIndexByArray(attr) {
120 return name.some(innerAttr => ('name' in Object(innerAttr) ? isRegExp(innerAttr.name) ? innerAttr.name.test(attr.name) : String(innerAttr.name) === attr.name : true) && ('value' in Object(innerAttr) ? isRegExp(innerAttr.value) ? innerAttr.value.test(attr.value) : getAttributeValue(innerAttr.value) === attr.value : true));
121 }
122
123 function findIndexByObject(attr) {
124 const innerAttr = name[attr.name] || name[toCamelCaseString(attr.name)];
125 return innerAttr ? isRegExp(innerAttr) ? innerAttr.test(attr.value) : attr.value === innerAttr : false;
126 }
127
128 function findIndexByRegExp(attr) {
129 return name.test(attr.name) && (args.length ? isRegExp(args[0]) ? args[0].test(attr.value) : attr.value === getAttributeValue(args[0]) : true);
130 }
131
132 function findIndexByString(attr) {
133 return (attr.name === String(name) || attr.name === toKebabCaseString(name)) && (args.length ? isRegExp(args[0]) ? args[0].test(attr.value) : attr.value === getAttributeValue(args[0]) : true);
134 }
135 }
136 /**
137 * Remove an attribute or attributes from the current {@link AttributeList}.
138 * @param {Array|Object|RegExp|String} name - The attribute to remove.
139 * @param {String} [value] - The value of the attribute being removed.
140 * @returns {Boolean} - Whether the attribute or attributes were removed from the {@link AttributeList}.
141 * @example <caption>Remove the "id" attribute.</caption>
142 * attrs.remove('id')
143 * @example <caption>Remove the "id" attribute when it has a value of "bar".</caption>
144 * attrs.remove('id', 'bar')
145 * @example
146 * attrs.remove({ id: 'bar' })
147 * @example
148 * attrs.remove([{ name: 'id', value: 'bar' }])
149 * @example <caption>Remove the "id" and "class" attributes.</caption>
150 * attrs.remove(['id', 'class'])
151 */
152
153
154 remove(name) {
155 for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
156 args[_key4 - 1] = arguments[_key4];
157 }
158
159 return toggle(this, getAttributeListArray(name, ...args), false).attributeRemoved;
160 }
161 /**
162 * Toggle an attribute or attributes from the current {@link AttributeList}.
163 * @param {String|Object} name_or_attrs - The name of the attribute being toggled, or an object of attributes being toggled.
164 * @param {String|Boolean} [value_or_force] - The value of the attribute being toggled when the first argument is not an object, or attributes should be exclusively added (true) or removed (false).
165 * @param {Boolean} [force] - Whether attributes should be exclusively added (true) or removed (false).
166 * @returns {Boolean} - Whether any attribute was added to the current {@link AttributeList}.
167 * @example <caption>Toggle the "id" attribute.</caption>
168 * attrs.toggle('id')
169 * @example <caption>Toggle the "id" attribute with a value of "bar".</caption>
170 * attrs.toggle('id', 'bar')
171 * @example
172 * attrs.toggle({ id: 'bar' })
173 * @example
174 * attrs.toggle([{ name: 'id', value: 'bar' }])
175 */
176
177
178 toggle(name) {
179 for (var _len5 = arguments.length, args = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
180 args[_key5 - 1] = arguments[_key5];
181 }
182
183 const attrs = getAttributeListArray(name, ...args);
184 const force = name === Object(name) ? args[0] == null ? null : Boolean(args[0]) : args[1] == null ? null : Boolean(args[1]);
185 const result = toggle(this, attrs, force);
186 return result.attributeAdded || result.atttributeModified;
187 }
188 /**
189 * Return the current {@link AttributeList} as a String.
190 * @returns {String} A string version of the current {@link AttributeList}
191 * @example
192 * attrs.toString() // returns 'class="foo" data-foo="bar"'
193 */
194
195
196 toString() {
197 return this.length ? "" + this.map(attr => "" + (Object(attr.source).before || ' ') + attr.name + (attr.value === null ? '' : "=" + (Object(attr.source).quote || '"') + attr.value + (Object(attr.source).quote || '"'))).join('') : '';
198 }
199 /**
200 * Return the current {@link AttributeList} as an Object.
201 * @returns {Object} point - An object version of the current {@link AttributeList}
202 * @example
203 * attrs.toJSON() // returns { class: 'foo', dataFoo: 'bar' } when <x class="foo" data-foo: "bar" />
204 */
205
206
207 toJSON() {
208 return this.reduce((object, attr) => Object.assign(object, {
209 [toCamelCaseString(attr.name)]: attr.value
210 }), {});
211 }
212 /**
213 * Return a new {@link AttributeList} from an array or object.
214 * @param {Array|AttributeList|Object} nodes - An array or object of attributes.
215 * @returns {AttributeList} A new {@link AttributeList}
216 * @example <caption>Return an array of attributes from a regular object.</caption>
217 * AttributeList.from({ dataFoo: 'bar' }) // returns AttributeList [{ name: 'data-foo', value: 'bar' }]
218 * @example <caption>Return a normalized array of attributes from an impure array of attributes.</caption>
219 * AttributeList.from([{ name: 'data-foo', value: true, foo: 'bar' }]) // returns AttributeList [{ name: 'data-foo', value: 'true' }]
220 */
221
222
223 static from(attrs) {
224 return new AttributeList(getAttributeListArray(attrs));
225 }
226
227}
228/**
229* Toggle an attribute or attributes from an {@link AttributeList}.
230* @param {AttributeList} attrs - The {@link AttributeList} being modified.
231* @param {String|Object} toggles - The attributes being toggled.
232* @param {Boolean} [force] - Whether attributes should be exclusively added (true) or removed (false)
233* @returns {Object} An object specifying whether any attributes were added, removed, and/or modified.
234* @private
235*/
236
237
238function toggle(attrs, toggles, force) {
239 let attributeAdded = false;
240 let attributeRemoved = false;
241 let atttributeModified = false;
242 toggles.forEach(toggleAttr => {
243 const index = attrs.indexOf(toggleAttr.name);
244
245 if (index === -1) {
246 if (force !== false) {
247 // add the attribute (if not exclusively removing attributes)
248 attrs.push(toggleAttr);
249 attributeAdded = true;
250 }
251 } else if (force !== true) {
252 // remove the attribute (if not exclusively adding attributes)
253 attrs.splice(index, 1);
254 attributeRemoved = true;
255 } else if (toggleAttr.value !== undefined && attrs[index].value !== toggleAttr.value) {
256 // change the value of the attribute (if exclusively adding attributes)
257 attrs[index].value = toggleAttr.value;
258 atttributeModified = true;
259 }
260 });
261 return {
262 attributeAdded,
263 attributeRemoved,
264 atttributeModified
265 };
266}
267/**
268* Return an AttributeList-compatible array from an array or object.
269* @private
270*/
271
272
273function getAttributeListArray(attrs, value) {
274 return attrs === null || attrs === undefined // void values are omitted
275 ? [] : Array.isArray(attrs) // arrays are sanitized as a name or value, and then optionally a source
276 ? attrs.reduce((attrs, rawattr) => {
277 const attr = {};
278
279 if ('name' in Object(rawattr)) {
280 attr.name = String(rawattr.name);
281 }
282
283 if ('value' in Object(rawattr)) {
284 attr.value = getAttributeValue(rawattr.value);
285 }
286
287 if ('source' in Object(rawattr)) {
288 attr.source = rawattr.source;
289 }
290
291 if ('name' in attr || 'value' in attr) {
292 attrs.push(attr);
293 }
294
295 return attrs;
296 }, []) : attrs === Object(attrs) // objects are sanitized as a name and value
297 ? Object.keys(attrs).map(name => ({
298 name: toKebabCaseString(name),
299 value: getAttributeValue(attrs[name])
300 })) : 1 in arguments // both name and value arguments are sanitized as a name and value
301 ? [{
302 name: attrs,
303 value: getAttributeValue(value)
304 }] // one name argument is sanitized as a name
305 : [{
306 name: attrs
307 }];
308}
309/**
310* Return a value transformed into an attribute value.
311* @description Expected values are strings. Unexpected values are null, objects, and undefined. Nulls returns null, Objects with the default toString return their JSON.stringify’d value otherwise toString’d, and Undefineds return an empty string.
312* @example <caption>Expected values.</caption>
313* getAttributeValue('foo') // returns 'foo'
314* getAttributeValue('') // returns ''
315* @example <caption>Unexpected values.</caption>
316* getAttributeValue(null) // returns null
317* getAttributeValue(undefined) // returns ''
318* getAttributeValue(['foo']) // returns '["foo"]'
319* getAttributeValue({ toString() { return 'bar' }}) // returns 'bar'
320* getAttributeValue({ toString: 'bar' }) // returns '{"toString":"bar"}'
321* @private
322*/
323
324
325function getAttributeValue(value) {
326 return value === null ? null : value === undefined ? '' : value === Object(value) ? value.toString === Object.prototype.toString ? JSON.stringify(value) : String(value) : String(value);
327}
328/**
329* Return a string formatted using camelCasing.
330* @param {String} value - The value being formatted.
331* @example
332* toCamelCaseString('hello-world') // returns 'helloWorld'
333* @private
334*/
335
336
337function toCamelCaseString(value) {
338 return isKebabCase(value) ? String(value).replace(/-[a-z]/g, $0 => $0.slice(1).toUpperCase()) : String(value);
339}
340/**
341* Return a string formatted using kebab-casing.
342* @param {String} value - The value being formatted.
343* @description Expected values do not already contain dashes.
344* @example <caption>Expected values.</caption>
345* toKebabCaseString('helloWorld') // returns 'hello-world'
346* toKebabCaseString('helloworld') // returns 'helloworld'
347* @example <caption>Unexpected values.</caption>
348* toKebabCaseString('hello-World') // returns 'hello-World'
349* @private
350*/
351
352
353function toKebabCaseString(value) {
354 return isCamelCase(value) ? String(value).replace(/[A-Z]/g, $0 => "-" + $0.toLowerCase()) : String(value);
355}
356/**
357* Return whether a value is formatted camelCase.
358* @example
359* isCamelCase('helloWorld') // returns true
360* isCamelCase('hello-world') // returns false
361* isCamelCase('helloworld') // returns false
362* @private
363*/
364
365
366function isCamelCase(value) {
367 return /^\w+[A-Z]\w*$/.test(value);
368}
369/**
370* Return whether a value is formatted kebab-case.
371* @example
372* isKebabCase('hello-world') // returns true
373* isKebabCase('helloworld') // returns false
374* isKebabCase('helloWorld') // returns false
375* @private
376*/
377
378
379function isKebabCase(value) {
380 return /^\w+[-]\w+$/.test(value);
381}
382/**
383* Return whether a value is a Regular Expression.
384* @example
385* isRegExp(/hello-world/) // returns true
386* isRegExp('/hello-world/') // returns false
387* isRegExp(new RegExp('hello-world')) // returns true
388* @private
389*/
390
391
392function isRegExp(value) {
393 return Object.prototype.toString.call(value) === '[object RegExp]';
394}
395
396/**
397* Transform a {@link Node} and any descendants using visitors.
398* @param {Node} node - The {@link Node} to be visited.
399* @param {Result} result - The {@link Result} to be used by visitors.
400* @param {Object} [overrideVisitors] - Alternative visitors to be used in place of {@link Result} visitors.
401* @returns {ResultPromise}
402* @private
403*/
404function visit(node, result, overrideVisitors) {
405 // get visitors as an object
406 const visitors = Object(overrideVisitors || Object(result).visitors); // get node types
407
408 const beforeType = getTypeFromNode(node);
409 const beforeSubType = getSubTypeFromNode(node);
410 const beforeNodeType = 'Node';
411 const beforeRootType = 'Root';
412 const afterType = "after" + beforeType;
413 const afterSubType = "after" + beforeSubType;
414 const afterNodeType = 'afterNode';
415 const afterRootType = 'afterRoot';
416 let promise = Promise.resolve(); // fire "before" visitors
417
418 if (visitors[beforeNodeType]) {
419 promise = promise.then(() => runAll(visitors[beforeNodeType], node, result));
420 }
421
422 if (visitors[beforeType]) {
423 promise = promise.then(() => runAll(visitors[beforeType], node, result));
424 }
425
426 if (beforeSubType !== beforeType && visitors[beforeSubType]) {
427 promise = promise.then(() => runAll(visitors[beforeSubType], node, result));
428 } // dispatch before root event
429
430
431 if (visitors[beforeRootType] && node === result.root) {
432 promise = promise.then(() => runAll(visitors[beforeRootType], node, result));
433 } // walk children
434
435
436 if (Array.isArray(node.nodes)) {
437 node.nodes.slice(0).forEach(childNode => {
438 promise = promise.then(() => childNode.parent === node && visit(childNode, result, overrideVisitors));
439 });
440 } // fire "after" visitors
441
442
443 if (visitors[afterNodeType]) {
444 promise = promise.then(() => runAll(visitors[afterNodeType], node, result));
445 }
446
447 if (visitors[afterType]) {
448 promise = promise.then(() => runAll(visitors[afterType], node, result));
449 }
450
451 if (afterType !== afterSubType && visitors[afterSubType]) {
452 promise = promise.then(() => runAll(visitors[afterSubType], node, result));
453 } // dispatch root event
454
455
456 if (visitors[afterRootType] && node === result.root) {
457 promise = promise.then(() => runAll(visitors[afterRootType], node, result));
458 }
459
460 return promise.then(() => result);
461}
462
463function runAll(plugins, node, result) {
464 let promise = Promise.resolve();
465 [].concat(plugins || []).forEach(plugin => {
466 // run the current plugin
467 promise = promise.then(() => {
468 // update the current plugin
469 result.currentPlugin = plugin;
470 return plugin(node, result);
471 }).then(() => {
472 // clear the current plugin
473 result.currentPlugin = null;
474 });
475 });
476 return promise;
477} // return normalized plugins and visitors
478
479function getVisitors(rawplugins) {
480 const visitors = {}; // initialize plugins and visitors
481
482 [].concat(rawplugins || []).forEach(plugin => {
483 const initializedPlugin = Object(plugin).type === 'plugin' ? plugin() : plugin;
484
485 if (initializedPlugin instanceof Function) {
486 if (!visitors.afterRoot) {
487 visitors.afterRoot = [];
488 }
489
490 visitors.afterRoot.push(initializedPlugin);
491 } else if (Object(initializedPlugin) === initializedPlugin && Object.keys(initializedPlugin).length) {
492 Object.keys(initializedPlugin).forEach(key => {
493 const fn = initializedPlugin[key];
494
495 if (fn instanceof Function) {
496 if (!visitors[key]) {
497 visitors[key] = [];
498 }
499
500 visitors[key].push(initializedPlugin[key]);
501 }
502 });
503 }
504 });
505 return visitors;
506}
507
508function getTypeFromNode(node) {
509 return {
510 'comment': 'Comment',
511 'text': 'Text',
512 'doctype': 'Doctype',
513 'fragment': 'Fragment'
514 }[node.type] || 'Element';
515}
516
517function getSubTypeFromNode(node) {
518 return {
519 'comment': 'Comment',
520 'text': 'Text',
521 'doctype': 'Doctype',
522 'fragment': 'Fragment'
523 }[node.type] || (!node.name ? 'FragmentElement' : "" + node.name[0].toUpperCase() + node.name.slice(1) + "Element");
524}
525
526/**
527* @name Node
528* @class
529* @extends Node
530* @classdesc Create a new {@link Node}.
531* @returns {Node}
532*/
533
534class Node {
535 /**
536 * The position of the current {@link Node} from its parent.
537 * @returns {Number}
538 * @example
539 * node.index // returns the index of the node or -1
540 */
541 get index() {
542 if (this.parent === Object(this.parent) && this.parent.nodes && this.parent.nodes.length) {
543 return this.parent.nodes.indexOf(this);
544 }
545
546 return -1;
547 }
548 /**
549 * The next {@link Node} after the current {@link Node}, or `null` if there is none.
550 * @returns {Node|Null} - The next Node or null.
551 * @example
552 * node.next // returns null
553 */
554
555
556 get next() {
557 const index = this.index;
558
559 if (index !== -1) {
560 return this.parent.nodes[index + 1] || null;
561 }
562
563 return null;
564 }
565 /**
566 * The next {@link Element} after the current {@link Node}, or `null` if there is none.
567 * @returns {Element|Null}
568 * @example
569 * node.nextElement // returns an element or null
570 */
571
572
573 get nextElement() {
574 const index = this.index;
575
576 if (index !== -1) {
577 return this.parent.nodes.slice(index).find(hasNodes);
578 }
579
580 return null;
581 }
582 /**
583 * The previous {@link Node} before the current {@link Node}, or `null` if there is none.
584 * @returns {Node|Null}
585 * @example
586 * node.previous // returns a node or null
587 */
588
589
590 get previous() {
591 const index = this.index;
592
593 if (index !== -1) {
594 return this.parent.nodes[index - 1] || null;
595 }
596
597 return null;
598 }
599 /**
600 * The previous {@link Element} before the current {@link Node}, or `null` if there is none.
601 * @returns {Element|Null}
602 * @example
603 * node.previousElement // returns an element or null
604 */
605
606
607 get previousElement() {
608 const index = this.index;
609
610 if (index !== -1) {
611 return this.parent.nodes.slice(0, index).reverse().find(hasNodes);
612 }
613
614 return null;
615 }
616 /**
617 * The top-most ancestor from the current {@link Node}.
618 * @returns {Node}
619 * @example
620 * node.root // returns the top-most node or the current node itself
621 */
622
623
624 get root() {
625 let parent = this;
626
627 while (parent.parent) {
628 parent = parent.parent;
629 }
630
631 return parent;
632 }
633 /**
634 * Insert one ore more {@link Node}s after the current {@link Node}.
635 * @param {...Node|String} nodes - Any nodes to be inserted after the current {@link Node}.
636 * @returns {Node} - The current {@link Node}.
637 * @example
638 * node.after(new Text({ data: 'Hello World' }))
639 */
640
641
642 after() {
643 for (var _len = arguments.length, nodes = new Array(_len), _key = 0; _key < _len; _key++) {
644 nodes[_key] = arguments[_key];
645 }
646
647 if (nodes.length) {
648 const index = this.index;
649
650 if (index !== -1) {
651 this.parent.nodes.splice(index + 1, 0, ...nodes);
652 }
653 }
654
655 return this;
656 }
657 /**
658 * Append Nodes or new Text Nodes to the current {@link Node}.
659 * @param {...Node|String} nodes - Any nodes to be inserted after the last child of the current {@link Node}.
660 * @returns {Node} - The current {@link Node}.
661 * @example
662 * node.append(someOtherNode)
663 */
664
665
666 append() {
667 if (this.nodes) {
668 for (var _len2 = arguments.length, nodes = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
669 nodes[_key2] = arguments[_key2];
670 }
671
672 this.nodes.splice(this.nodes.length, 0, ...nodes);
673 }
674
675 return this;
676 }
677 /**
678 * Append the current {@link Node} to another Node.
679 * @param {Container} parent - The {@link Container} for the current {@link Node}.
680 * @returns {Node} - The current {@link Node}.
681 */
682
683
684 appendTo(parent) {
685 if (parent && parent.nodes) {
686 parent.nodes.splice(parent.nodes.length, 0, this);
687 }
688
689 return this;
690 }
691 /**
692 * Insert Nodes or new Text Nodes before the Node if it has a parent.
693 * @param {...Node|String} nodes - Any nodes to be inserted before the current {@link Node}.
694 * @returns {Node}
695 * @example
696 * node.before(new Text({ data: 'Hello World' })) // returns the current node
697 */
698
699
700 before() {
701 for (var _len3 = arguments.length, nodes = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
702 nodes[_key3] = arguments[_key3];
703 }
704
705 if (nodes.length) {
706 const index = this.index;
707
708 if (index !== -1) {
709 this.parent.nodes.splice(index, 0, ...nodes);
710 }
711 }
712
713 return this;
714 }
715 /**
716 * Prepend Nodes or new Text Nodes to the current {@link Node}.
717 * @param {...Node|String} nodes - Any nodes inserted before the first child of the current {@link Node}.
718 * @returns {Node} - The current {@link Node}.
719 * @example
720 * node.prepend(someOtherNode)
721 */
722
723
724 prepend() {
725 if (this.nodes) {
726 for (var _len4 = arguments.length, nodes = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
727 nodes[_key4] = arguments[_key4];
728 }
729
730 this.nodes.splice(0, 0, ...nodes);
731 }
732
733 return this;
734 }
735 /**
736 * Remove the current {@link Node} from its parent.
737 * @returns {Node}
738 * @example
739 * node.remove() // returns the current node
740 */
741
742
743 remove() {
744 const index = this.index;
745
746 if (index !== -1) {
747 this.parent.nodes.splice(index, 1);
748 }
749
750 return this;
751 }
752 /**
753 * Replace the current {@link Node} with another Node or Nodes.
754 * @param {...Node} nodes - Any nodes replacing the current {@link Node}.
755 * @returns {Node} - The current {@link Node}
756 * @example
757 * node.replaceWith(someOtherNode) // returns the current node
758 */
759
760
761 replaceWith() {
762 const index = this.index;
763
764 if (index !== -1) {
765 for (var _len5 = arguments.length, nodes = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
766 nodes[_key5] = arguments[_key5];
767 }
768
769 this.parent.nodes.splice(index, 1, ...nodes);
770 }
771
772 return this;
773 }
774 /**
775 * Transform the current {@link Node} and any descendants using visitors.
776 * @param {Result} result - The {@link Result} to be used by visitors.
777 * @param {Object} [overrideVisitors] - Alternative visitors to be used in place of {@link Result} visitors.
778 * @returns {ResultPromise}
779 * @example
780 * await node.visit(result)
781 * @example
782 * await node.visit() // visit using the result of the current node
783 * @example
784 * await node.visit(result, {
785 * Element () {
786 * // do something to an element
787 * }
788 * })
789 */
790
791
792 visit(result, overrideVisitors) {
793 const resultToUse = 0 in arguments ? result : this.result;
794 return visit(this, resultToUse, overrideVisitors);
795 }
796 /**
797 * Add a warning from the current {@link Node}.
798 * @param {Result} result - The {@link Result} the warning is being added to.
799 * @param {String} text - The message being sent as the warning.
800 * @param {Object} [opts] - Additional information about the warning.
801 * @example
802 * node.warn(result, 'Something went wrong')
803 * @example
804 * node.warn(result, 'Something went wrong', {
805 * node: someOtherNode,
806 * plugin: someOtherPlugin
807 * })
808 */
809
810
811 warn(result, text, opts) {
812 const data = Object.assign({
813 node: this
814 }, opts);
815 return result.warn(text, data);
816 }
817
818}
819
820function hasNodes(node) {
821 return node.nodes;
822}
823
824/**
825* @name Comment
826* @class
827* @extends Node
828* @classdesc Return a new {@link Comment} {@link Node}.
829* @param {Object|String} settings - Custom settings applied to the Comment, or the content of the {@link Comment}.
830* @param {String} settings.comment - Content of the Comment.
831* @param {Object} settings.source - Source mapping of the Comment.
832* @returns {Comment}
833* @example
834* new Comment({ comment: ' Hello World ' })
835*/
836
837class Comment extends Node {
838 constructor(settings) {
839 super();
840
841 if (typeof settings === 'string') {
842 settings = {
843 comment: settings
844 };
845 }
846
847 Object.assign(this, {
848 type: 'comment',
849 name: '#comment',
850 comment: String(Object(settings).comment || ''),
851 source: Object(Object(settings).source)
852 });
853 }
854 /**
855 * Return the stringified innerHTML of the current {@link Comment}.
856 * @returns {String}
857 * @example
858 * attrs.innerHTML // returns ' Hello World '
859 */
860
861
862 get innerHTML() {
863 return String(this.comment);
864 }
865 /**
866 * Return the stringified outerHTML of the current {@link Comment}.
867 * @returns {String}
868 * @example
869 * attrs.outerHTML // returns '<!-- Hello World -->'
870 */
871
872
873 get outerHTML() {
874 return String(this);
875 }
876 /**
877 * Return the stringified innerHTML from the source input.
878 * @returns {String}
879 * @example
880 * attrs.sourceInnerHTML // returns ' Hello World '
881 */
882
883
884 get sourceInnerHTML() {
885 return typeof Object(this.source.input).html !== 'string' ? '' : this.source.input.html.slice(this.source.startOffset + 4, this.source.endOffset - 3);
886 }
887 /**
888 * Return the stringified outerHTML from the source input.
889 * @returns {String}
890 * @example
891 * attrs.sourceOuterHTML // returns '<!-- Hello World -->'
892 */
893
894
895 get sourceOuterHTML() {
896 return typeof Object(this.source.input).html !== 'string' ? '' : this.source.input.html.slice(this.source.startOffset, this.source.endOffset);
897 }
898 /**
899 * Return a clone of the current {@link Comment}.
900 * @param {Object} settings - Custom settings applied to the cloned {@link Comment}.
901 * @returns {Comment} - The cloned {@link Comment}
902 * @example
903 * comment.clone()
904 * @example <caption>Clone the current text with new source.</caption>
905 * comment.clone({ source: { input: 'modified source' } })
906 */
907
908
909 clone(settings) {
910 return new this.constructor(Object.assign({}, this, settings, {
911 source: Object.assign({}, this.source, Object(settings).source)
912 }));
913 }
914 /**
915 * Return the current {@link Comment} as a String.
916 * @returns {String} A string version of the current {@link Comment}
917 * @example
918 * attrs.toJSON() // returns '<!-- Hello World -->'
919 */
920
921
922 toString() {
923 return "<!--" + this.comment + "-->";
924 }
925 /**
926 * Return the current {@link Comment} as a Object.
927 * @returns {Object} An object version of the current {@link Comment}
928 * @example
929 * attrs.toJSON() // returns { comment: ' Hello World ' }
930 */
931
932
933 toJSON() {
934 return {
935 comment: this.comment
936 };
937 }
938
939}
940
941/**
942* @name Container
943* @class
944* @extends Node
945* @classdesc Return a new {@link Container} {@link Node}.
946* @returns {Container}
947*/
948
949class Container extends Node {
950 /**
951 * Return the first child {@link Node} of the current {@link Container}, or `null` if there is none.
952 * @returns {Node|Null}
953 * @example
954 * container.first // returns a Node or null
955 */
956 get first() {
957 return this.nodes[0] || null;
958 }
959 /**
960 * Return the first child {@link Element} of the current {@link Container}, or `null` if there is none.
961 * @returns {Node|Null}
962 * @example
963 * container.firstElement // returns an Element or null
964 */
965
966
967 get firstElement() {
968 return this.nodes.find(hasNodes$1) || null;
969 }
970 /**
971 * Return the last child {@link Node} of the current {@link Container}, or `null` if there is none.
972 * @returns {Node|Null}
973 * @example
974 * container.last // returns a Node or null
975 */
976
977
978 get last() {
979 return this.nodes[this.nodes.length - 1] || null;
980 }
981 /**
982 * Return the last child {@link Element} of the current {@link Container}, or `null` if there is none.
983 * @returns {Node|Null}
984 * @example
985 * container.lastElement // returns an Element or null
986 */
987
988
989 get lastElement() {
990 return this.nodes.slice().reverse().find(hasNodes$1) || null;
991 }
992 /**
993 * Return a child {@link Element} {@link NodeList} of the current {@link Container}.
994 * @returns {Array}
995 * @example
996 * container.elements // returns an array of Elements
997 */
998
999
1000 get elements() {
1001 return this.nodes.filter(hasNodes$1) || [];
1002 }
1003 /**
1004 * Return the innerHTML of the current {@link Container} as a String.
1005 * @returns {String}
1006 * @example
1007 * container.innerHTML // returns a string of innerHTML
1008 */
1009
1010
1011 get innerHTML() {
1012 return this.nodes.innerHTML;
1013 }
1014 /**
1015 * Define the nodes of the current {@link Container} from a String.
1016 * @param {String} innerHTML - Source being processed.
1017 * @returns {Void}
1018 * @example
1019 * container.innerHTML = 'Hello <strong>world</strong>';
1020 * container.nodes.length; // 2
1021 */
1022
1023
1024 set innerHTML(innerHTML) {
1025 this.nodes.innerHTML = innerHTML;
1026 }
1027 /**
1028 * Return the outerHTML of the current {@link Container} as a String.
1029 * @returns {String}
1030 * @example
1031 * container.outerHTML // returns a string of outerHTML
1032 */
1033
1034
1035 get outerHTML() {
1036 return this.nodes.innerHTML;
1037 }
1038 /**
1039 * Replace the current {@link Container} from a String.
1040 * @param {String} input - Source being processed.
1041 * @returns {Void}
1042 * @example
1043 * container.outerHTML = 'Hello <strong>world</strong>';
1044 */
1045
1046
1047 set outerHTML(outerHTML) {
1048 const Result = Object(this.result).constructor;
1049
1050 if (Result) {
1051 const childNodes = new Result(outerHTML).root.nodes;
1052 this.replaceWith(...childNodes);
1053 }
1054 }
1055 /**
1056 * Return the stringified innerHTML from the source input.
1057 * @returns {String}
1058 */
1059
1060
1061 get sourceInnerHTML() {
1062 return this.isSelfClosing || this.isVoid || typeof Object(this.source.input).html !== 'string' ? '' : 'startInnerOffset' in this.source && 'endInnerOffset' in this.source ? this.source.input.html.slice(this.source.startInnerOffset, this.source.endInnerOffset) : this.sourceOuterHTML;
1063 }
1064 /**
1065 * Return the stringified outerHTML from the source input.
1066 * @returns {String}
1067 */
1068
1069
1070 get sourceOuterHTML() {
1071 return typeof Object(this.source.input).html !== 'string' ? '' : this.source.input.html.slice(this.source.startOffset, this.source.endOffset);
1072 }
1073 /**
1074 * Return the text content of the current {@link Container} as a String.
1075 * @returns {String}
1076 */
1077
1078
1079 get textContent() {
1080 return this.nodes.textContent;
1081 }
1082 /**
1083 * Define the content of the current {@link Container} as a new {@link Text} {@link Node}.
1084 * @returns {String}
1085 */
1086
1087
1088 set textContent(textContent) {
1089 this.nodes.textContent = textContent;
1090 }
1091 /**
1092 * Return a child {@link Node} of the current {@link Container} by last index, or `null` if there is none.
1093 * @returns {Node|Null}
1094 * @example
1095 * container.lastNth(0) // returns a Node or null
1096 */
1097
1098
1099 lastNth(index) {
1100 return this.nodes.slice().reverse()[index] || null;
1101 }
1102 /**
1103 * Return a child {@link Element} of the current {@link Container} by last index, or `null` if there is none.
1104 * @returns {Element|Null}
1105 * @example
1106 * container.lastNthElement(0) // returns an Element or null
1107 */
1108
1109
1110 lastNthElement(index) {
1111 return this.elements.reverse()[index] || null;
1112 }
1113 /**
1114 * Return a child {@link Node} of the current {@link Container} by index, or `null` if there is none.
1115 * @returns {Node|Null}
1116 * @example
1117 * container.nth(0) // returns a Node or null
1118 */
1119
1120
1121 nth(index) {
1122 return this.nodes[index] || null;
1123 }
1124 /**
1125 * Return an {@link Element} child of the current Container by index, or `null` if there is none.
1126 * @returns {Element|Null}
1127 * @example
1128 * container.nthElement(0) // returns an Element or null
1129 */
1130
1131
1132 nthElement(index) {
1133 return this.elements[index] || null;
1134 }
1135 /**
1136 * Replace all of the children of the current {@link Container}.
1137 * @param {...Node} nodes - Any nodes replacing the current children of the {@link Container}.
1138 * @returns {Container} - The current {@link Container}.
1139 * @example
1140 * container.replaceAll(new Text({ data: 'Hello World' }))
1141 */
1142
1143
1144 replaceAll() {
1145 if (this.nodes) {
1146 for (var _len = arguments.length, nodes = new Array(_len), _key = 0; _key < _len; _key++) {
1147 nodes[_key] = arguments[_key];
1148 }
1149
1150 this.nodes.splice(0, this.nodes.length, ...nodes);
1151 }
1152
1153 return this;
1154 }
1155 /**
1156 * Traverse the descendant {@link Node}s of the current {@link Container} with a callback function.
1157 * @param {Function|String|RegExp} callback_or_filter - A callback function, or a filter to reduce {@link Node}s the callback is applied to.
1158 * @param {Function|String|RegExp} callback - A callback function when a filter is also specified.
1159 * @returns {Container} - The current {@link Container}.
1160 * @example
1161 * container.walk(node => {
1162 * console.log(node);
1163 * })
1164 * @example
1165 * container.walk('*', node => {
1166 * console.log(node);
1167 * })
1168 * @example <caption>Walk only "section" {@link Element}s.</caption>
1169 * container.walk('section', node => {
1170 * console.log(node); // logs only Section Elements
1171 * })
1172 * @example
1173 * container.walk(/^section$/, node => {
1174 * console.log(node); // logs only Section Elements
1175 * })
1176 * @example
1177 * container.walk(
1178 * node => node.name.toLowerCase() === 'section',
1179 * node => {
1180 * console.log(node); // logs only Section Elements
1181 * })
1182 * @example <caption>Walk only {@link Text}.</caption>
1183 * container.walk('#text', node => {
1184 * console.log(node); // logs only Text Nodes
1185 * })
1186 */
1187
1188
1189 walk() {
1190 const _getCbAndFilterFromAr = getCbAndFilterFromArgs(arguments),
1191 cb = _getCbAndFilterFromAr[0],
1192 filter = _getCbAndFilterFromAr[1];
1193
1194 walk(this, cb, filter);
1195 return this;
1196 }
1197
1198}
1199
1200function walk(node, cb, filter) {
1201 if (typeof cb === 'function' && node.nodes) {
1202 node.nodes.slice(0).forEach(child => {
1203 if (Object(child).parent === node) {
1204 if (testWithFilter(child, filter)) {
1205 cb(child); // eslint-disable-line callback-return
1206 }
1207
1208 if (child.nodes) {
1209 walk(child, cb, filter);
1210 }
1211 }
1212 });
1213 }
1214}
1215
1216function getCbAndFilterFromArgs(args) {
1217 const cbOrFilter = args[0],
1218 onlyCb = args[1];
1219 const cb = onlyCb || cbOrFilter;
1220 const filter = onlyCb ? cbOrFilter : undefined;
1221 return [cb, filter];
1222}
1223
1224function testWithFilter(node, filter) {
1225 if (!filter) {
1226 return true;
1227 } else if (filter === '*') {
1228 return Object(node).constructor.name === 'Element';
1229 } else if (typeof filter === 'string') {
1230 return node.name === filter;
1231 } else if (filter instanceof RegExp) {
1232 return filter.test(node.name);
1233 } else if (filter instanceof Function) {
1234 return filter(node);
1235 } else {
1236 return false;
1237 }
1238}
1239
1240function hasNodes$1(node) {
1241 return node.nodes;
1242}
1243
1244/**
1245* @name Doctype
1246* @class
1247* @extends Node
1248* @classdesc Create a new {@link Doctype} {@link Node}.
1249* @param {Object|String} settings - Custom settings applied to the {@link Doctype}, or the name of the {@link Doctype}.
1250* @param {String} settings.name - Name of the {@link Doctype}.
1251* @param {String} settings.publicId - Public identifier portion of the {@link Doctype}.
1252* @param {String} settings.systemId - System identifier portion of the {@link Doctype}.
1253* @param {Object} settings.source - Source mapping of the {@link Doctype}.
1254* @returns {Doctype}
1255* @example
1256* new Doctype({ name: 'html' }) // <!doctype html>
1257*/
1258
1259class Doctype extends Node {
1260 constructor(settings) {
1261 super();
1262
1263 if (typeof settings === 'string') {
1264 settings = {
1265 name: settings
1266 };
1267 }
1268
1269 Object.assign(this, {
1270 type: 'doctype',
1271 doctype: String(Object(settings).doctype || 'doctype'),
1272 name: String(Object(settings).name || 'html'),
1273 publicId: Object(settings).publicId || null,
1274 systemId: Object(settings).systemId || null,
1275 source: Object.assign({
1276 before: Object(Object(settings).source).before || ' ',
1277 after: Object(Object(settings).source).after || '',
1278 beforePublicId: Object(Object(settings).source).beforePublicId || null,
1279 beforeSystemId: Object(Object(settings).source).beforeSystemId || null
1280 }, Object(settings).source)
1281 });
1282 }
1283 /**
1284 * Return a clone of the current {@link Doctype}.
1285 * @param {Object} settings - Custom settings applied to the cloned {@link Doctype}.
1286 * @returns {Doctype} - The cloned {@link Doctype}
1287 * @example
1288 * doctype.clone()
1289 * @example <caption>Clone the current text with new source.</caption>
1290 * doctype.clone({ source: { input: 'modified source' } })
1291 */
1292
1293
1294 clone(settings) {
1295 return new this.constructor(Object.assign({}, this, settings, {
1296 source: Object.assign({}, this.source, Object(settings).source)
1297 }));
1298 }
1299 /**
1300 * Return the current {@link Doctype} as a String.
1301 * @returns {String}
1302 */
1303
1304
1305 toString() {
1306 const publicId = this.publicId ? "" + (this.source.beforePublicId || ' ') + this.publicId : '';
1307 const systemId = this.systemId ? "" + (this.source.beforeSystemId || ' ') + this.systemId : '';
1308 return "<!" + this.doctype + this.source.before + this.name + this.source.after + publicId + systemId + ">";
1309 }
1310 /**
1311 * Return the current {@link Doctype} as an Object.
1312 * @returns {Object}
1313 */
1314
1315
1316 toJSON() {
1317 return {
1318 name: this.name,
1319 publicId: this.publicId,
1320 systemId: this.systemId
1321 };
1322 }
1323
1324}
1325
1326/**
1327* @name Fragment
1328* @class
1329* @extends Container
1330* @classdesc Create a new {@link Fragment} {@Link Node}.
1331* @param {Object} settings - Custom settings applied to the {@link Fragment}.
1332* @param {Array|NodeList} settings.nodes - Nodes appended to the {@link Fragment}.
1333* @param {Object} settings.source - Source mapping of the {@link Fragment}.
1334* @returns {Fragment}
1335* @example
1336* new Fragment() // returns an empty fragment
1337*
1338* new Fragment({ nodes: [ new Element('span') ] }) // returns a fragment with a <span>
1339*/
1340
1341class Fragment extends Container {
1342 constructor(settings) {
1343 super();
1344 Object.assign(this, settings, {
1345 type: 'fragment',
1346 name: '#document-fragment',
1347 nodes: Array.isArray(Object(settings).nodes) ? new NodeList(this, ...Array.from(settings.nodes)) : Object(settings).nodes !== null && Object(settings).nodes !== undefined ? new NodeList(this, settings.nodes) : new NodeList(this),
1348 source: Object(Object(settings).source)
1349 });
1350 }
1351 /**
1352 * Return a clone of the current {@link Fragment}.
1353 * @param {Boolean} isDeep - Whether the descendants of the current Fragment should also be cloned.
1354 * @returns {Fragment} - The cloned Fragment
1355 */
1356
1357
1358 clone(isDeep) {
1359 const clone = new Fragment(Object.assign({}, this, {
1360 nodes: []
1361 }));
1362
1363 if (isDeep) {
1364 clone.nodes = this.nodes.clone(clone);
1365 }
1366
1367 return clone;
1368 }
1369 /**
1370 * Return the current {@link Fragment} as an Array.
1371 * @returns {Array}
1372 * @example
1373 * fragment.toJSON() // returns []
1374 */
1375
1376
1377 toJSON() {
1378 return this.nodes.toJSON();
1379 }
1380 /**
1381 * Return the current {@link Fragment} as a String.
1382 * @returns {String}
1383 * @example
1384 * fragment.toJSON() // returns ''
1385 */
1386
1387
1388 toString() {
1389 return String(this.nodes);
1390 }
1391
1392}
1393
1394/**
1395* @name Text
1396* @class
1397* @extends Node
1398* @classdesc Create a new {@link Text} {@link Node}.
1399* @param {Object|String} settings - Custom settings applied to the {@link Text}, or the content of the {@link Text}.
1400* @param {String} settings.data - Content of the {@link Text}.
1401* @param {Object} settings.source - Source mapping of the {@link Text}.
1402* @returns {Text}
1403* @example
1404* new Text({ data: 'Hello World' })
1405*/
1406
1407class Text extends Node {
1408 constructor(settings) {
1409 super();
1410
1411 if (typeof settings === 'string') {
1412 settings = {
1413 data: settings
1414 };
1415 }
1416
1417 Object.assign(this, {
1418 type: 'text',
1419 name: '#text',
1420 data: String(Object(settings).data || ''),
1421 source: Object(Object(settings).source)
1422 });
1423 }
1424 /**
1425 * Return the stringified innerHTML from the source input.
1426 * @returns {String}
1427 */
1428
1429
1430 get sourceInnerHTML() {
1431 return typeof Object(this.source.input).html !== 'string' ? '' : this.source.input.html.slice(this.source.startOffset, this.source.endOffset);
1432 }
1433 /**
1434 * Return the stringified outerHTML from the source input.
1435 * @returns {String}
1436 */
1437
1438
1439 get sourceOuterHTML() {
1440 return typeof Object(this.source.input).html !== 'string' ? '' : this.source.input.html.slice(this.source.startOffset, this.source.endOffset);
1441 }
1442 /**
1443 * Return the current {@link Text} as a String.
1444 * @returns {String}
1445 * @example
1446 * text.textContent // returns ''
1447 */
1448
1449
1450 get textContent() {
1451 return String(this.data);
1452 }
1453 /**
1454 * Define the current {@link Text} from a String.
1455 * @returns {Void}
1456 * @example
1457 * text.textContent = 'Hello World'
1458 * text.textContent // 'Hello World'
1459 */
1460
1461
1462 set textContent(textContent) {
1463 this.data = String(textContent);
1464 }
1465 /**
1466 * Return a clone of the current {@link Text}.
1467 * @param {Object} settings - Custom settings applied to the cloned {@link Text}.
1468 * @returns {Text} - The cloned {@link Text}
1469 * @example
1470 * text.clone()
1471 * @example <caption>Clone the current text with new source.</caption>
1472 * text.clone({ source: { input: 'modified source' } })
1473 */
1474
1475
1476 clone(settings) {
1477 return new Text(Object.assign({}, this, settings, {
1478 source: Object.assign({}, this.source, Object(settings).source)
1479 }));
1480 }
1481 /**
1482 * Return the current {@link Text} as a String.
1483 * @returns {String}
1484 * @example
1485 * text.toString() // returns ''
1486 */
1487
1488
1489 toString() {
1490 return String(this.data);
1491 }
1492 /**
1493 * Return the current {@link Text} as a String.
1494 * @returns {String}
1495 * @example
1496 * text.toJSON() // returns ''
1497 */
1498
1499
1500 toJSON() {
1501 return String(this.data);
1502 }
1503
1504}
1505
1506function normalize(node) {
1507 const nodeTypes = {
1508 comment: Comment,
1509 doctype: Doctype,
1510 element: Element,
1511 fragment: Fragment,
1512 text: Text
1513 };
1514 return node instanceof Node // Nodes are unchanged
1515 ? node : node.type in nodeTypes // Strings are converted into Text nodes
1516 ? new nodeTypes[node.type](node) // Node-like Objects with recognized types are normalized
1517 : new Text({
1518 data: String(node)
1519 });
1520}
1521
1522const parents = new WeakMap();
1523/**
1524* @name NodeList
1525* @class
1526* @extends Array
1527* @classdesc Create a new {@link NodeList}.
1528* @param {Container} parent - Parent containing the current {@link NodeList}.
1529* @param {...Node} nodes - {@link Node}s belonging to the current {@link NodeList}.
1530* @returns {NodeList}
1531*/
1532
1533class NodeList extends Array {
1534 constructor(parent) {
1535 super();
1536 parents.set(this, parent);
1537
1538 for (var _len = arguments.length, nodes = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1539 nodes[_key - 1] = arguments[_key];
1540 }
1541
1542 if (nodes.length) {
1543 this.push(...nodes);
1544 }
1545 }
1546 /**
1547 * Return the innerHTML of the current {@link Container} as a String.
1548 * @returns {String}
1549 * @example
1550 * container.innerHTML // returns a string of innerHTML
1551 */
1552
1553
1554 get innerHTML() {
1555 return this.map(node => node.type === 'text' ? getInnerHtmlEncodedString(node.data) : 'outerHTML' in node ? node.outerHTML : String(node)).join('');
1556 }
1557 /**
1558 * Define the nodes of the current {@link NodeList} from a String.
1559 * @param {String} innerHTML - Source being processed.
1560 * @returns {Void}
1561 * @example
1562 * nodeList.innerHTML = 'Hello <strong>world</strong>';
1563 * nodeList.length; // 2
1564 */
1565
1566
1567 set innerHTML(innerHTML) {
1568 const parent = this.parent;
1569 const Result = Object(parent.result).constructor;
1570
1571 if (Result) {
1572 const nodes = new Result(innerHTML).root.nodes;
1573 this.splice(0, this.length, ...nodes);
1574 }
1575 }
1576 /**
1577 * Return the parent of the current {@link NodeList}.
1578 * @returns {Container}
1579 */
1580
1581
1582 get parent() {
1583 return parents.get(this);
1584 }
1585 /**
1586 * Return the text content of the current {@link NodeList} as a String.
1587 * @returns {String}
1588 */
1589
1590
1591 get textContent() {
1592 return this.map(node => Object(node).textContent || '').join('');
1593 }
1594 /**
1595 * Define the content of the current {@link NodeList} as a new {@link Text} {@link Node}.
1596 * @returns {String}
1597 */
1598
1599
1600 set textContent(textContent) {
1601 this.splice(0, this.length, new Text({
1602 data: textContent
1603 }));
1604 }
1605 /**
1606 * Return a clone of the current {@link NodeList}.
1607 * @param {Object} parent - New parent containing the cloned {@link NodeList}.
1608 * @returns {NodeList} - The cloned NodeList
1609 */
1610
1611
1612 clone(parent) {
1613 return new NodeList(parent, ...this.map(node => node.clone({}, true)));
1614 }
1615 /**
1616 * Remove and return the last {@link Node} in the {@link NodeList}.
1617 * @returns {Node}
1618 */
1619
1620
1621 pop() {
1622 const _this$splice = this.splice(this.length - 1, 1),
1623 remove = _this$splice[0];
1624
1625 return remove;
1626 }
1627 /**
1628 * Add {@link Node}s to the end of the {@link NodeList} and return the new length of the {@link NodeList}.
1629 * @returns {Number}
1630 */
1631
1632
1633 push() {
1634 const parent = this.parent;
1635
1636 for (var _len2 = arguments.length, nodes = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1637 nodes[_key2] = arguments[_key2];
1638 }
1639
1640 const inserts = nodes.filter(node => node !== parent);
1641 this.splice(this.length, 0, ...inserts);
1642 return this.length;
1643 }
1644 /**
1645 * Remove and return the first {@link Node} in the {@link NodeList}.
1646 * @returns {Node}
1647 */
1648
1649
1650 shift() {
1651 const _this$splice2 = this.splice(0, 1),
1652 remove = _this$splice2[0];
1653
1654 return remove;
1655 }
1656 /**
1657 * Add and remove {@link Node}s to and from the {@link NodeList}.
1658 * @returns {Array}
1659 */
1660
1661
1662 splice(start) {
1663 const length = this.length,
1664 parent = this.parent;
1665 const startIndex = start > length ? length : start < 0 ? Math.max(length + start, 0) : Number(start) || 0;
1666
1667 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
1668 args[_key3 - 1] = arguments[_key3];
1669 }
1670
1671 const deleteCount = 0 in args ? Number(args[0]) || 0 : length;
1672 const inserts = getNodeListArray(args.slice(1).filter(node => node !== parent));
1673
1674 for (let _i = 0, _length = inserts == null ? 0 : inserts.length; _i < _length; _i++) {
1675 let insert = inserts[_i];
1676 insert.remove();
1677 insert.parent = parent;
1678 }
1679
1680 const removes = Array.prototype.splice.call(this, startIndex, deleteCount, ...inserts);
1681
1682 for (let _i2 = 0, _length2 = removes == null ? 0 : removes.length; _i2 < _length2; _i2++) {
1683 let remove = removes[_i2];
1684 delete remove.parent;
1685 }
1686
1687 return removes;
1688 }
1689 /**
1690 * Add {@link Node}s to the beginning of the {@link NodeList} and return the new length of the {@link NodeList}.
1691 * @returns {Number}
1692 */
1693
1694
1695 unshift() {
1696 const parent = this.parent;
1697
1698 for (var _len4 = arguments.length, nodes = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
1699 nodes[_key4] = arguments[_key4];
1700 }
1701
1702 const inserts = nodes.filter(node => node !== parent);
1703 this.splice(0, 0, ...inserts);
1704 return this.length;
1705 }
1706 /**
1707 * Return the current {@link NodeList} as a String.
1708 * @returns {String}
1709 * @example
1710 * nodeList.toString() // returns ''
1711 */
1712
1713
1714 toString() {
1715 return this.join('');
1716 }
1717 /**
1718 * Return the current {@link NodeList} as an Array.
1719 * @returns {Array}
1720 * @example
1721 * nodeList.toJSON() // returns []
1722 */
1723
1724
1725 toJSON() {
1726 return Array.from(this).map(node => node.toJSON());
1727 }
1728 /**
1729 * Return a new {@link NodeList} from an object.
1730 * @param {Array|Node} nodes - An array or object of nodes.
1731 * @returns {NodeList} A new {@link NodeList}
1732 * @example <caption>Return a NodeList from an array of text.</caption>
1733 * NodeList.from([ 'test' ]) // returns NodeList [ Text { data: 'test' } ]
1734 */
1735
1736
1737 static from(nodes) {
1738 return new NodeList(new Fragment(), ...getNodeListArray(nodes));
1739 }
1740
1741}
1742/**
1743* Return an NodeList-compatible array from an array.
1744* @private
1745*/
1746
1747function getNodeListArray(nodes) {
1748 // coerce nodes into an array
1749 return Object(nodes).length ? Array.from(nodes).filter(node => node != null).map(normalize) : [];
1750}
1751/**
1752* Return an innerHTML-encoded string.
1753* @private
1754*/
1755
1756
1757function getInnerHtmlEncodedString(string) {
1758 return string.replace(/&|<|>/g, match => match === '&' ? '&amp;' : match === '<' ? '&lt;' : '&gt;');
1759}
1760
1761const UNDEFINED_CODE_POINTS = [0xfffe, 0xffff, 0x1fffe, 0x1ffff, 0x2fffe, 0x2ffff, 0x3fffe, 0x3ffff, 0x4fffe, 0x4ffff, 0x5fffe, 0x5ffff, 0x6fffe, 0x6ffff, 0x7fffe, 0x7ffff, 0x8fffe, 0x8ffff, 0x9fffe, 0x9ffff, 0xafffe, 0xaffff, 0xbfffe, 0xbffff, 0xcfffe, 0xcffff, 0xdfffe, 0xdffff, 0xefffe, 0xeffff, 0xffffe, 0xfffff, 0x10fffe, 0x10ffff];
1762var REPLACEMENT_CHARACTER = '\uFFFD';
1763var CODE_POINTS = {
1764 EOF: -1,
1765 NULL: 0x00,
1766 TABULATION: 0x09,
1767 CARRIAGE_RETURN: 0x0d,
1768 LINE_FEED: 0x0a,
1769 FORM_FEED: 0x0c,
1770 SPACE: 0x20,
1771 EXCLAMATION_MARK: 0x21,
1772 QUOTATION_MARK: 0x22,
1773 NUMBER_SIGN: 0x23,
1774 AMPERSAND: 0x26,
1775 APOSTROPHE: 0x27,
1776 HYPHEN_MINUS: 0x2d,
1777 SOLIDUS: 0x2f,
1778 DIGIT_0: 0x30,
1779 DIGIT_9: 0x39,
1780 SEMICOLON: 0x3b,
1781 LESS_THAN_SIGN: 0x3c,
1782 EQUALS_SIGN: 0x3d,
1783 GREATER_THAN_SIGN: 0x3e,
1784 QUESTION_MARK: 0x3f,
1785 LATIN_CAPITAL_A: 0x41,
1786 LATIN_CAPITAL_F: 0x46,
1787 LATIN_CAPITAL_X: 0x58,
1788 LATIN_CAPITAL_Z: 0x5a,
1789 RIGHT_SQUARE_BRACKET: 0x5d,
1790 GRAVE_ACCENT: 0x60,
1791 LATIN_SMALL_A: 0x61,
1792 LATIN_SMALL_F: 0x66,
1793 LATIN_SMALL_X: 0x78,
1794 LATIN_SMALL_Z: 0x7a,
1795 REPLACEMENT_CHARACTER: 0xfffd
1796};
1797var CODE_POINT_SEQUENCES = {
1798 DASH_DASH_STRING: [0x2d, 0x2d],
1799 //--
1800 DOCTYPE_STRING: [0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45],
1801 //DOCTYPE
1802 CDATA_START_STRING: [0x5b, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5b],
1803 //[CDATA[
1804 SCRIPT_STRING: [0x73, 0x63, 0x72, 0x69, 0x70, 0x74],
1805 //script
1806 PUBLIC_STRING: [0x50, 0x55, 0x42, 0x4c, 0x49, 0x43],
1807 //PUBLIC
1808 SYSTEM_STRING: [0x53, 0x59, 0x53, 0x54, 0x45, 0x4d] //SYSTEM
1809
1810}; //Surrogates
1811
1812var isSurrogate = function isSurrogate(cp) {
1813 return cp >= 0xd800 && cp <= 0xdfff;
1814};
1815
1816var isSurrogatePair = function isSurrogatePair(cp) {
1817 return cp >= 0xdc00 && cp <= 0xdfff;
1818};
1819
1820var getSurrogatePairCodePoint = function getSurrogatePairCodePoint(cp1, cp2) {
1821 return (cp1 - 0xd800) * 0x400 + 0x2400 + cp2;
1822}; //NOTE: excluding NULL and ASCII whitespace
1823
1824
1825var isControlCodePoint = function isControlCodePoint(cp) {
1826 return cp !== 0x20 && cp !== 0x0a && cp !== 0x0d && cp !== 0x09 && cp !== 0x0c && cp >= 0x01 && cp <= 0x1f || cp >= 0x7f && cp <= 0x9f;
1827};
1828
1829var isUndefinedCodePoint = function isUndefinedCodePoint(cp) {
1830 return cp >= 0xfdd0 && cp <= 0xfdef || UNDEFINED_CODE_POINTS.indexOf(cp) > -1;
1831};
1832
1833var unicode = {
1834 REPLACEMENT_CHARACTER: REPLACEMENT_CHARACTER,
1835 CODE_POINTS: CODE_POINTS,
1836 CODE_POINT_SEQUENCES: CODE_POINT_SEQUENCES,
1837 isSurrogate: isSurrogate,
1838 isSurrogatePair: isSurrogatePair,
1839 getSurrogatePairCodePoint: getSurrogatePairCodePoint,
1840 isControlCodePoint: isControlCodePoint,
1841 isUndefinedCodePoint: isUndefinedCodePoint
1842};
1843
1844var errorCodes = {
1845 controlCharacterInInputStream: 'control-character-in-input-stream',
1846 noncharacterInInputStream: 'noncharacter-in-input-stream',
1847 surrogateInInputStream: 'surrogate-in-input-stream',
1848 nonVoidHtmlElementStartTagWithTrailingSolidus: 'non-void-html-element-start-tag-with-trailing-solidus',
1849 endTagWithAttributes: 'end-tag-with-attributes',
1850 endTagWithTrailingSolidus: 'end-tag-with-trailing-solidus',
1851 unexpectedSolidusInTag: 'unexpected-solidus-in-tag',
1852 unexpectedNullCharacter: 'unexpected-null-character',
1853 unexpectedQuestionMarkInsteadOfTagName: 'unexpected-question-mark-instead-of-tag-name',
1854 invalidFirstCharacterOfTagName: 'invalid-first-character-of-tag-name',
1855 unexpectedEqualsSignBeforeAttributeName: 'unexpected-equals-sign-before-attribute-name',
1856 missingEndTagName: 'missing-end-tag-name',
1857 unexpectedCharacterInAttributeName: 'unexpected-character-in-attribute-name',
1858 unknownNamedCharacterReference: 'unknown-named-character-reference',
1859 missingSemicolonAfterCharacterReference: 'missing-semicolon-after-character-reference',
1860 unexpectedCharacterAfterDoctypeSystemIdentifier: 'unexpected-character-after-doctype-system-identifier',
1861 unexpectedCharacterInUnquotedAttributeValue: 'unexpected-character-in-unquoted-attribute-value',
1862 eofBeforeTagName: 'eof-before-tag-name',
1863 eofInTag: 'eof-in-tag',
1864 missingAttributeValue: 'missing-attribute-value',
1865 missingWhitespaceBetweenAttributes: 'missing-whitespace-between-attributes',
1866 missingWhitespaceAfterDoctypePublicKeyword: 'missing-whitespace-after-doctype-public-keyword',
1867 missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers: 'missing-whitespace-between-doctype-public-and-system-identifiers',
1868 missingWhitespaceAfterDoctypeSystemKeyword: 'missing-whitespace-after-doctype-system-keyword',
1869 missingQuoteBeforeDoctypePublicIdentifier: 'missing-quote-before-doctype-public-identifier',
1870 missingQuoteBeforeDoctypeSystemIdentifier: 'missing-quote-before-doctype-system-identifier',
1871 missingDoctypePublicIdentifier: 'missing-doctype-public-identifier',
1872 missingDoctypeSystemIdentifier: 'missing-doctype-system-identifier',
1873 abruptDoctypePublicIdentifier: 'abrupt-doctype-public-identifier',
1874 abruptDoctypeSystemIdentifier: 'abrupt-doctype-system-identifier',
1875 cdataInHtmlContent: 'cdata-in-html-content',
1876 incorrectlyOpenedComment: 'incorrectly-opened-comment',
1877 eofInScriptHtmlCommentLikeText: 'eof-in-script-html-comment-like-text',
1878 eofInDoctype: 'eof-in-doctype',
1879 nestedComment: 'nested-comment',
1880 abruptClosingOfEmptyComment: 'abrupt-closing-of-empty-comment',
1881 eofInComment: 'eof-in-comment',
1882 incorrectlyClosedComment: 'incorrectly-closed-comment',
1883 eofInCdata: 'eof-in-cdata',
1884 absenceOfDigitsInNumericCharacterReference: 'absence-of-digits-in-numeric-character-reference',
1885 nullCharacterReference: 'null-character-reference',
1886 surrogateCharacterReference: 'surrogate-character-reference',
1887 characterReferenceOutsideUnicodeRange: 'character-reference-outside-unicode-range',
1888 controlCharacterReference: 'control-character-reference',
1889 noncharacterCharacterReference: 'noncharacter-character-reference',
1890 missingWhitespaceBeforeDoctypeName: 'missing-whitespace-before-doctype-name',
1891 missingDoctypeName: 'missing-doctype-name',
1892 invalidCharacterSequenceAfterDoctypeName: 'invalid-character-sequence-after-doctype-name',
1893 duplicateAttribute: 'duplicate-attribute',
1894 nonConformingDoctype: 'non-conforming-doctype',
1895 missingDoctype: 'missing-doctype',
1896 misplacedDoctype: 'misplaced-doctype',
1897 endTagWithoutMatchingOpenElement: 'end-tag-without-matching-open-element',
1898 closingOfElementWithOpenChildElements: 'closing-of-element-with-open-child-elements',
1899 disallowedContentInNoscriptInHead: 'disallowed-content-in-noscript-in-head',
1900 openElementsLeftAfterEof: 'open-elements-left-after-eof',
1901 abandonedHeadElementChild: 'abandoned-head-element-child',
1902 misplacedStartTagForHeadElement: 'misplaced-start-tag-for-head-element',
1903 nestedNoscriptInHead: 'nested-noscript-in-head',
1904 eofInElementThatCanContainOnlyText: 'eof-in-element-that-can-contain-only-text'
1905};
1906
1907const $ = unicode.CODE_POINTS; //Const
1908
1909const DEFAULT_BUFFER_WATERLINE = 1 << 16; //Preprocessor
1910//NOTE: HTML input preprocessing
1911//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#preprocessing-the-input-stream)
1912
1913class Preprocessor {
1914 constructor() {
1915 this.html = null;
1916 this.pos = -1;
1917 this.lastGapPos = -1;
1918 this.lastCharPos = -1;
1919 this.gapStack = [];
1920 this.skipNextNewLine = false;
1921 this.lastChunkWritten = false;
1922 this.endOfChunkHit = false;
1923 this.bufferWaterline = DEFAULT_BUFFER_WATERLINE;
1924 }
1925
1926 _err() {// NOTE: err reporting is noop by default. Enabled by mixin.
1927 }
1928
1929 _addGap() {
1930 this.gapStack.push(this.lastGapPos);
1931 this.lastGapPos = this.pos;
1932 }
1933
1934 _processSurrogate(cp) {
1935 //NOTE: try to peek a surrogate pair
1936 if (this.pos !== this.lastCharPos) {
1937 const nextCp = this.html.charCodeAt(this.pos + 1);
1938
1939 if (unicode.isSurrogatePair(nextCp)) {
1940 //NOTE: we have a surrogate pair. Peek pair character and recalculate code point.
1941 this.pos++; //NOTE: add gap that should be avoided during retreat
1942
1943 this._addGap();
1944
1945 return unicode.getSurrogatePairCodePoint(cp, nextCp);
1946 }
1947 } //NOTE: we are at the end of a chunk, therefore we can't infer surrogate pair yet.
1948 else if (!this.lastChunkWritten) {
1949 this.endOfChunkHit = true;
1950 return $.EOF;
1951 } //NOTE: isolated surrogate
1952
1953
1954 this._err(errorCodes.surrogateInInputStream);
1955
1956 return cp;
1957 }
1958
1959 dropParsedChunk() {
1960 if (this.pos > this.bufferWaterline) {
1961 this.lastCharPos -= this.pos;
1962 this.html = this.html.substring(this.pos);
1963 this.pos = 0;
1964 this.lastGapPos = -1;
1965 this.gapStack = [];
1966 }
1967 }
1968
1969 write(chunk, isLastChunk) {
1970 if (this.html) {
1971 this.html += chunk;
1972 } else {
1973 this.html = chunk;
1974 }
1975
1976 this.lastCharPos = this.html.length - 1;
1977 this.endOfChunkHit = false;
1978 this.lastChunkWritten = isLastChunk;
1979 }
1980
1981 insertHtmlAtCurrentPos(chunk) {
1982 this.html = this.html.substring(0, this.pos + 1) + chunk + this.html.substring(this.pos + 1, this.html.length);
1983 this.lastCharPos = this.html.length - 1;
1984 this.endOfChunkHit = false;
1985 }
1986
1987 advance() {
1988 this.pos++;
1989
1990 if (this.pos > this.lastCharPos) {
1991 this.endOfChunkHit = !this.lastChunkWritten;
1992 return $.EOF;
1993 }
1994
1995 let cp = this.html.charCodeAt(this.pos); //NOTE: any U+000A LINE FEED (LF) characters that immediately follow a U+000D CARRIAGE RETURN (CR) character
1996 //must be ignored.
1997
1998 if (this.skipNextNewLine && cp === $.LINE_FEED) {
1999 this.skipNextNewLine = false;
2000
2001 this._addGap();
2002
2003 return this.advance();
2004 } //NOTE: all U+000D CARRIAGE RETURN (CR) characters must be converted to U+000A LINE FEED (LF) characters
2005
2006
2007 if (cp === $.CARRIAGE_RETURN) {
2008 this.skipNextNewLine = true;
2009 return $.LINE_FEED;
2010 }
2011
2012 this.skipNextNewLine = false;
2013
2014 if (unicode.isSurrogate(cp)) {
2015 cp = this._processSurrogate(cp);
2016 } //OPTIMIZATION: first check if code point is in the common allowed
2017 //range (ASCII alphanumeric, whitespaces, big chunk of BMP)
2018 //before going into detailed performance cost validation.
2019
2020
2021 const isCommonValidRange = cp > 0x1f && cp < 0x7f || cp === $.LINE_FEED || cp === $.CARRIAGE_RETURN || cp > 0x9f && cp < 0xfdd0;
2022
2023 if (!isCommonValidRange) {
2024 this._checkForProblematicCharacters(cp);
2025 }
2026
2027 return cp;
2028 }
2029
2030 _checkForProblematicCharacters(cp) {
2031 if (unicode.isControlCodePoint(cp)) {
2032 this._err(errorCodes.controlCharacterInInputStream);
2033 } else if (unicode.isUndefinedCodePoint(cp)) {
2034 this._err(errorCodes.noncharacterInInputStream);
2035 }
2036 }
2037
2038 retreat() {
2039 if (this.pos === this.lastGapPos) {
2040 this.lastGapPos = this.gapStack.pop();
2041 this.pos--;
2042 }
2043
2044 this.pos--;
2045 }
2046
2047}
2048
2049var preprocessor = Preprocessor;
2050
2051//(details: https://github.com/inikulin/parse5/tree/master/scripts/generate-named-entity-data/README.md)
2052
2053var namedEntityData = new Uint16Array([4, 52, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 106, 303, 412, 810, 1432, 1701, 1796, 1987, 2114, 2360, 2420, 2484, 3170, 3251, 4140, 4393, 4575, 4610, 5106, 5512, 5728, 6117, 6274, 6315, 6345, 6427, 6516, 7002, 7910, 8733, 9323, 9870, 10170, 10631, 10893, 11318, 11386, 11467, 12773, 13092, 14474, 14922, 15448, 15542, 16419, 17666, 18166, 18611, 19004, 19095, 19298, 19397, 4, 16, 69, 77, 97, 98, 99, 102, 103, 108, 109, 110, 111, 112, 114, 115, 116, 117, 140, 150, 158, 169, 176, 194, 199, 210, 216, 222, 226, 242, 256, 266, 283, 294, 108, 105, 103, 5, 198, 1, 59, 148, 1, 198, 80, 5, 38, 1, 59, 156, 1, 38, 99, 117, 116, 101, 5, 193, 1, 59, 167, 1, 193, 114, 101, 118, 101, 59, 1, 258, 4, 2, 105, 121, 182, 191, 114, 99, 5, 194, 1, 59, 189, 1, 194, 59, 1, 1040, 114, 59, 3, 55349, 56580, 114, 97, 118, 101, 5, 192, 1, 59, 208, 1, 192, 112, 104, 97, 59, 1, 913, 97, 99, 114, 59, 1, 256, 100, 59, 1, 10835, 4, 2, 103, 112, 232, 237, 111, 110, 59, 1, 260, 102, 59, 3, 55349, 56632, 112, 108, 121, 70, 117, 110, 99, 116, 105, 111, 110, 59, 1, 8289, 105, 110, 103, 5, 197, 1, 59, 264, 1, 197, 4, 2, 99, 115, 272, 277, 114, 59, 3, 55349, 56476, 105, 103, 110, 59, 1, 8788, 105, 108, 100, 101, 5, 195, 1, 59, 292, 1, 195, 109, 108, 5, 196, 1, 59, 301, 1, 196, 4, 8, 97, 99, 101, 102, 111, 114, 115, 117, 321, 350, 354, 383, 388, 394, 400, 405, 4, 2, 99, 114, 327, 336, 107, 115, 108, 97, 115, 104, 59, 1, 8726, 4, 2, 118, 119, 342, 345, 59, 1, 10983, 101, 100, 59, 1, 8966, 121, 59, 1, 1041, 4, 3, 99, 114, 116, 362, 369, 379, 97, 117, 115, 101, 59, 1, 8757, 110, 111, 117, 108, 108, 105, 115, 59, 1, 8492, 97, 59, 1, 914, 114, 59, 3, 55349, 56581, 112, 102, 59, 3, 55349, 56633, 101, 118, 101, 59, 1, 728, 99, 114, 59, 1, 8492, 109, 112, 101, 113, 59, 1, 8782, 4, 14, 72, 79, 97, 99, 100, 101, 102, 104, 105, 108, 111, 114, 115, 117, 442, 447, 456, 504, 542, 547, 569, 573, 577, 616, 678, 784, 790, 796, 99, 121, 59, 1, 1063, 80, 89, 5, 169, 1, 59, 454, 1, 169, 4, 3, 99, 112, 121, 464, 470, 497, 117, 116, 101, 59, 1, 262, 4, 2, 59, 105, 476, 478, 1, 8914, 116, 97, 108, 68, 105, 102, 102, 101, 114, 101, 110, 116, 105, 97, 108, 68, 59, 1, 8517, 108, 101, 121, 115, 59, 1, 8493, 4, 4, 97, 101, 105, 111, 514, 520, 530, 535, 114, 111, 110, 59, 1, 268, 100, 105, 108, 5, 199, 1, 59, 528, 1, 199, 114, 99, 59, 1, 264, 110, 105, 110, 116, 59, 1, 8752, 111, 116, 59, 1, 266, 4, 2, 100, 110, 553, 560, 105, 108, 108, 97, 59, 1, 184, 116, 101, 114, 68, 111, 116, 59, 1, 183, 114, 59, 1, 8493, 105, 59, 1, 935, 114, 99, 108, 101, 4, 4, 68, 77, 80, 84, 591, 596, 603, 609, 111, 116, 59, 1, 8857, 105, 110, 117, 115, 59, 1, 8854, 108, 117, 115, 59, 1, 8853, 105, 109, 101, 115, 59, 1, 8855, 111, 4, 2, 99, 115, 623, 646, 107, 119, 105, 115, 101, 67, 111, 110, 116, 111, 117, 114, 73, 110, 116, 101, 103, 114, 97, 108, 59, 1, 8754, 101, 67, 117, 114, 108, 121, 4, 2, 68, 81, 658, 671, 111, 117, 98, 108, 101, 81, 117, 111, 116, 101, 59, 1, 8221, 117, 111, 116, 101, 59, 1, 8217, 4, 4, 108, 110, 112, 117, 688, 701, 736, 753, 111, 110, 4, 2, 59, 101, 696, 698, 1, 8759, 59, 1, 10868, 4, 3, 103, 105, 116, 709, 717, 722, 114, 117, 101, 110, 116, 59, 1, 8801, 110, 116, 59, 1, 8751, 111, 117, 114, 73, 110, 116, 101, 103, 114, 97, 108, 59, 1, 8750, 4, 2, 102, 114, 742, 745, 59, 1, 8450, 111, 100, 117, 99, 116, 59, 1, 8720, 110, 116, 101, 114, 67, 108, 111, 99, 107, 119, 105, 115, 101, 67, 111, 110, 116, 111, 117, 114, 73, 110, 116, 101, 103, 114, 97, 108, 59, 1, 8755, 111, 115, 115, 59, 1, 10799, 99, 114, 59, 3, 55349, 56478, 112, 4, 2, 59, 67, 803, 805, 1, 8915, 97, 112, 59, 1, 8781, 4, 11, 68, 74, 83, 90, 97, 99, 101, 102, 105, 111, 115, 834, 850, 855, 860, 865, 888, 903, 916, 921, 1011, 1415, 4, 2, 59, 111, 840, 842, 1, 8517, 116, 114, 97, 104, 100, 59, 1, 10513, 99, 121, 59, 1, 1026, 99, 121, 59, 1, 1029, 99, 121, 59, 1, 1039, 4, 3, 103, 114, 115, 873, 879, 883, 103, 101, 114, 59, 1, 8225, 114, 59, 1, 8609, 104, 118, 59, 1, 10980, 4, 2, 97, 121, 894, 900, 114, 111, 110, 59, 1, 270, 59, 1, 1044, 108, 4, 2, 59, 116, 910, 912, 1, 8711, 97, 59, 1, 916, 114, 59, 3, 55349, 56583, 4, 2, 97, 102, 927, 998, 4, 2, 99, 109, 933, 992, 114, 105, 116, 105, 99, 97, 108, 4, 4, 65, 68, 71, 84, 950, 957, 978, 985, 99, 117, 116, 101, 59, 1, 180, 111, 4, 2, 116, 117, 964, 967, 59, 1, 729, 98, 108, 101, 65, 99, 117, 116, 101, 59, 1, 733, 114, 97, 118, 101, 59, 1, 96, 105, 108, 100, 101, 59, 1, 732, 111, 110, 100, 59, 1, 8900, 102, 101, 114, 101, 110, 116, 105, 97, 108, 68, 59, 1, 8518, 4, 4, 112, 116, 117, 119, 1021, 1026, 1048, 1249, 102, 59, 3, 55349, 56635, 4, 3, 59, 68, 69, 1034, 1036, 1041, 1, 168, 111, 116, 59, 1, 8412, 113, 117, 97, 108, 59, 1, 8784, 98, 108, 101, 4, 6, 67, 68, 76, 82, 85, 86, 1065, 1082, 1101, 1189, 1211, 1236, 111, 110, 116, 111, 117, 114, 73, 110, 116, 101, 103, 114, 97, 108, 59, 1, 8751, 111, 4, 2, 116, 119, 1089, 1092, 59, 1, 168, 110, 65, 114, 114, 111, 119, 59, 1, 8659, 4, 2, 101, 111, 1107, 1141, 102, 116, 4, 3, 65, 82, 84, 1117, 1124, 1136, 114, 114, 111, 119, 59, 1, 8656, 105, 103, 104, 116, 65, 114, 114, 111, 119, 59, 1, 8660, 101, 101, 59, 1, 10980, 110, 103, 4, 2, 76, 82, 1149, 1177, 101, 102, 116, 4, 2, 65, 82, 1158, 1165, 114, 114, 111, 119, 59, 1, 10232, 105, 103, 104, 116, 65, 114, 114, 111, 119, 59, 1, 10234, 105, 103, 104, 116, 65, 114, 114, 111, 119, 59, 1, 10233, 105, 103, 104, 116, 4, 2, 65, 84, 1199, 1206, 114, 114, 111, 119, 59, 1, 8658, 101, 101, 59, 1, 8872, 112, 4, 2, 65, 68, 1218, 1225, 114, 114, 111, 119, 59, 1, 8657, 111, 119, 110, 65, 114, 114, 111, 119, 59, 1, 8661, 101, 114, 116, 105, 99, 97, 108, 66, 97, 114, 59, 1, 8741, 110, 4, 6, 65, 66, 76, 82, 84, 97, 1264, 1292, 1299, 1352, 1391, 1408, 114, 114, 111, 119, 4, 3, 59, 66, 85, 1276, 1278, 1283, 1, 8595, 97, 114, 59, 1, 10515, 112, 65, 114, 114, 111, 119, 59, 1, 8693, 114, 101, 118, 101, 59, 1, 785, 101, 102, 116, 4, 3, 82, 84, 86, 1310, 1323, 1334, 105, 103, 104, 116, 86, 101, 99, 116, 111, 114, 59, 1, 10576, 101, 101, 86, 101, 99, 116, 111, 114, 59, 1, 10590, 101, 99, 116, 111, 114, 4, 2, 59, 66, 1345, 1347, 1, 8637, 97, 114, 59, 1, 10582, 105, 103, 104, 116, 4, 2, 84, 86, 1362, 1373, 101, 101, 86, 101, 99, 116, 111, 114, 59, 1, 10591, 101, 99, 116, 111, 114, 4, 2, 59, 66, 1384, 1386, 1, 8641, 97, 114, 59, 1, 10583, 101, 101, 4, 2, 59, 65, 1399, 1401, 1, 8868, 114, 114, 111, 119, 59, 1, 8615, 114, 114, 111, 119, 59, 1, 8659, 4, 2, 99, 116, 1421, 1426, 114, 59, 3, 55349, 56479, 114, 111, 107, 59, 1, 272, 4, 16, 78, 84, 97, 99, 100, 102, 103, 108, 109, 111, 112, 113, 115, 116, 117, 120, 1466, 1470, 1478, 1489, 1515, 1520, 1525, 1536, 1544, 1593, 1609, 1617, 1650, 1664, 1668, 1677, 71, 59, 1, 330, 72, 5, 208, 1, 59, 1476, 1, 208, 99, 117, 116, 101, 5, 201, 1, 59, 1487, 1, 201, 4, 3, 97, 105, 121, 1497, 1503, 1512, 114, 111, 110, 59, 1, 282, 114, 99, 5, 202, 1, 59, 1510, 1, 202, 59, 1, 1069, 111, 116, 59, 1, 278, 114, 59, 3, 55349, 56584, 114, 97, 118, 101, 5, 200, 1, 59, 1534, 1, 200, 101, 109, 101, 110, 116, 59, 1, 8712, 4, 2, 97, 112, 1550, 1555, 99, 114, 59, 1, 274, 116, 121, 4, 2, 83, 86, 1563, 1576, 109, 97, 108, 108, 83, 113, 117, 97, 114, 101, 59, 1, 9723, 101, 114, 121, 83, 109, 97, 108, 108, 83, 113, 117, 97, 114, 101, 59, 1, 9643, 4, 2, 103, 112, 1599, 1604, 111, 110, 59, 1, 280, 102, 59, 3, 55349, 56636, 115, 105, 108, 111, 110, 59, 1, 917, 117, 4, 2, 97, 105, 1624, 1640, 108, 4, 2, 59, 84, 1631, 1633, 1, 10869, 105, 108, 100, 101, 59, 1, 8770, 108, 105, 98, 114, 105, 117, 109, 59, 1, 8652, 4, 2, 99, 105, 1656, 1660, 114, 59, 1, 8496, 109, 59, 1, 10867, 97, 59, 1, 919, 109, 108, 5, 203, 1, 59, 1675, 1, 203, 4, 2, 105, 112, 1683, 1689, 115, 116, 115, 59, 1, 8707, 111, 110, 101, 110, 116, 105, 97, 108, 69, 59, 1, 8519, 4, 5, 99, 102, 105, 111, 115, 1713, 1717, 1722, 1762, 1791, 121, 59, 1, 1060, 114, 59, 3, 55349, 56585, 108, 108, 101, 100, 4, 2, 83, 86, 1732, 1745, 109, 97, 108, 108, 83, 113, 117, 97, 114, 101, 59, 1, 9724, 101, 114, 121, 83, 109, 97, 108, 108, 83, 113, 117, 97, 114, 101, 59, 1, 9642, 4, 3, 112, 114, 117, 1770, 1775, 1781, 102, 59, 3, 55349, 56637, 65, 108, 108, 59, 1, 8704, 114, 105, 101, 114, 116, 114, 102, 59, 1, 8497, 99, 114, 59, 1, 8497, 4, 12, 74, 84, 97, 98, 99, 100, 102, 103, 111, 114, 115, 116, 1822, 1827, 1834, 1848, 1855, 1877, 1882, 1887, 1890, 1896, 1978, 1984, 99, 121, 59, 1, 1027, 5, 62, 1, 59, 1832, 1, 62, 109, 109, 97, 4, 2, 59, 100, 1843, 1845, 1, 915, 59, 1, 988, 114, 101, 118, 101, 59, 1, 286, 4, 3, 101, 105, 121, 1863, 1869, 1874, 100, 105, 108, 59, 1, 290, 114, 99, 59, 1, 284, 59, 1, 1043, 111, 116, 59, 1, 288, 114, 59, 3, 55349, 56586, 59, 1, 8921, 112, 102, 59, 3, 55349, 56638, 101, 97, 116, 101, 114, 4, 6, 69, 70, 71, 76, 83, 84, 1915, 1933, 1944, 1953, 1959, 1971, 113, 117, 97, 108, 4, 2, 59, 76, 1925, 1927, 1, 8805, 101, 115, 115, 59, 1, 8923, 117, 108, 108, 69, 113, 117, 97, 108, 59, 1, 8807, 114, 101, 97, 116, 101, 114, 59, 1, 10914, 101, 115, 115, 59, 1, 8823, 108, 97, 110, 116, 69, 113, 117, 97, 108, 59, 1, 10878, 105, 108, 100, 101, 59, 1, 8819, 99, 114, 59, 3, 55349, 56482, 59, 1, 8811, 4, 8, 65, 97, 99, 102, 105, 111, 115, 117, 2005, 2012, 2026, 2032, 2036, 2049, 2073, 2089, 82, 68, 99, 121, 59, 1, 1066, 4, 2, 99, 116, 2018, 2023, 101, 107, 59, 1, 711, 59, 1, 94, 105, 114, 99, 59, 1, 292, 114, 59, 1, 8460, 108, 98, 101, 114, 116, 83, 112, 97, 99, 101, 59, 1, 8459, 4, 2, 112, 114, 2055, 2059, 102, 59, 1, 8461, 105, 122, 111, 110, 116, 97, 108, 76, 105, 110, 101, 59, 1, 9472, 4, 2, 99, 116, 2079, 2083, 114, 59, 1, 8459, 114, 111, 107, 59, 1, 294, 109, 112, 4, 2, 68, 69, 2097, 2107, 111, 119, 110, 72, 117, 109, 112, 59, 1, 8782, 113, 117, 97, 108, 59, 1, 8783, 4, 14, 69, 74, 79, 97, 99, 100, 102, 103, 109, 110, 111, 115, 116, 117, 2144, 2149, 2155, 2160, 2171, 2189, 2194, 2198, 2209, 2245, 2307, 2329, 2334, 2341, 99, 121, 59, 1, 1045, 108, 105, 103, 59, 1, 306, 99, 121, 59, 1, 1025, 99, 117, 116, 101, 5, 205, 1, 59, 2169, 1, 205, 4, 2, 105, 121, 2177, 2186, 114, 99, 5, 206, 1, 59, 2184, 1, 206, 59, 1, 1048, 111, 116, 59, 1, 304, 114, 59, 1, 8465, 114, 97, 118, 101, 5, 204, 1, 59, 2207, 1, 204, 4, 3, 59, 97, 112, 2217, 2219, 2238, 1, 8465, 4, 2, 99, 103, 2225, 2229, 114, 59, 1, 298, 105, 110, 97, 114, 121, 73, 59, 1, 8520, 108, 105, 101, 115, 59, 1, 8658, 4, 2, 116, 118, 2251, 2281, 4, 2, 59, 101, 2257, 2259, 1, 8748, 4, 2, 103, 114, 2265, 2271, 114, 97, 108, 59, 1, 8747, 115, 101, 99, 116, 105, 111, 110, 59, 1, 8898, 105, 115, 105, 98, 108, 101, 4, 2, 67, 84, 2293, 2300, 111, 109, 109, 97, 59, 1, 8291, 105, 109, 101, 115, 59, 1, 8290, 4, 3, 103, 112, 116, 2315, 2320, 2325, 111, 110, 59, 1, 302, 102, 59, 3, 55349, 56640, 97, 59, 1, 921, 99, 114, 59, 1, 8464, 105, 108, 100, 101, 59, 1, 296, 4, 2, 107, 109, 2347, 2352, 99, 121, 59, 1, 1030, 108, 5, 207, 1, 59, 2358, 1, 207, 4, 5, 99, 102, 111, 115, 117, 2372, 2386, 2391, 2397, 2414, 4, 2, 105, 121, 2378, 2383, 114, 99, 59, 1, 308, 59, 1, 1049, 114, 59, 3, 55349, 56589, 112, 102, 59, 3, 55349, 56641, 4, 2, 99, 101, 2403, 2408, 114, 59, 3, 55349, 56485, 114, 99, 121, 59, 1, 1032, 107, 99, 121, 59, 1, 1028, 4, 7, 72, 74, 97, 99, 102, 111, 115, 2436, 2441, 2446, 2452, 2467, 2472, 2478, 99, 121, 59, 1, 1061, 99, 121, 59, 1, 1036, 112, 112, 97, 59, 1, 922, 4, 2, 101, 121, 2458, 2464, 100, 105, 108, 59, 1, 310, 59, 1, 1050, 114, 59, 3, 55349, 56590, 112, 102, 59, 3, 55349, 56642, 99, 114, 59, 3, 55349, 56486, 4, 11, 74, 84, 97, 99, 101, 102, 108, 109, 111, 115, 116, 2508, 2513, 2520, 2562, 2585, 2981, 2986, 3004, 3011, 3146, 3167, 99, 121, 59, 1, 1033, 5, 60, 1, 59, 2518, 1, 60, 4, 5, 99, 109, 110, 112, 114, 2532, 2538, 2544, 2548, 2558, 117, 116, 101, 59, 1, 313, 98, 100, 97, 59, 1, 923, 103, 59, 1, 10218, 108, 97, 99, 101, 116, 114, 102, 59, 1, 8466, 114, 59, 1, 8606, 4, 3, 97, 101, 121, 2570, 2576, 2582, 114, 111, 110, 59, 1, 317, 100, 105, 108, 59, 1, 315, 59, 1, 1051, 4, 2, 102, 115, 2591, 2907, 116, 4, 10, 65, 67, 68, 70, 82, 84, 85, 86, 97, 114, 2614, 2663, 2672, 2728, 2735, 2760, 2820, 2870, 2888, 2895, 4, 2, 110, 114, 2620, 2633, 103, 108, 101, 66, 114, 97, 99, 107, 101, 116, 59, 1, 10216, 114, 111, 119, 4, 3, 59, 66, 82, 2644, 2646, 2651, 1, 8592, 97, 114, 59, 1, 8676, 105, 103, 104, 116, 65, 114, 114, 111, 119, 59, 1, 8646, 101, 105, 108, 105, 110, 103, 59, 1, 8968, 111, 4, 2, 117, 119, 2679, 2692, 98, 108, 101, 66, 114, 97, 99, 107, 101, 116, 59, 1, 10214, 110, 4, 2, 84, 86, 2699, 2710, 101, 101, 86, 101, 99, 116, 111, 114, 59, 1, 10593, 101, 99, 116, 111, 114, 4, 2, 59, 66, 2721, 2723, 1, 8643, 97, 114, 59, 1, 10585, 108, 111, 111, 114, 59, 1, 8970, 105, 103, 104, 116, 4, 2, 65, 86, 2745, 2752, 114, 114, 111, 119, 59, 1, 8596, 101, 99, 116, 111, 114, 59, 1, 10574, 4, 2, 101, 114, 2766, 2792, 101, 4, 3, 59, 65, 86, 2775, 2777, 2784, 1, 8867, 114, 114, 111, 119, 59, 1, 8612, 101, 99, 116, 111, 114, 59, 1, 10586, 105, 97, 110, 103, 108, 101, 4, 3, 59, 66, 69, 2806, 2808, 2813, 1, 8882, 97, 114, 59, 1, 10703, 113, 117, 97, 108, 59, 1, 8884, 112, 4, 3, 68, 84, 86, 2829, 2841, 2852, 111, 119, 110, 86, 101, 99, 116, 111, 114, 59, 1, 10577, 101, 101, 86, 101, 99, 116, 111, 114, 59, 1, 10592, 101, 99, 116, 111, 114, 4, 2, 59, 66, 2863, 2865, 1, 8639, 97, 114, 59, 1, 10584, 101, 99, 116, 111, 114, 4, 2, 59, 66, 2881, 2883, 1, 8636, 97, 114, 59, 1, 10578, 114, 114, 111, 119, 59, 1, 8656, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 8660, 115, 4, 6, 69, 70, 71, 76, 83, 84, 2922, 2936, 2947, 2956, 2962, 2974, 113, 117, 97, 108, 71, 114, 101, 97, 116, 101, 114, 59, 1, 8922, 117, 108, 108, 69, 113, 117, 97, 108, 59, 1, 8806, 114, 101, 97, 116, 101, 114, 59, 1, 8822, 101, 115, 115, 59, 1, 10913, 108, 97, 110, 116, 69, 113, 117, 97, 108, 59, 1, 10877, 105, 108, 100, 101, 59, 1, 8818, 114, 59, 3, 55349, 56591, 4, 2, 59, 101, 2992, 2994, 1, 8920, 102, 116, 97, 114, 114, 111, 119, 59, 1, 8666, 105, 100, 111, 116, 59, 1, 319, 4, 3, 110, 112, 119, 3019, 3110, 3115, 103, 4, 4, 76, 82, 108, 114, 3030, 3058, 3070, 3098, 101, 102, 116, 4, 2, 65, 82, 3039, 3046, 114, 114, 111, 119, 59, 1, 10229, 105, 103, 104, 116, 65, 114, 114, 111, 119, 59, 1, 10231, 105, 103, 104, 116, 65, 114, 114, 111, 119, 59, 1, 10230, 101, 102, 116, 4, 2, 97, 114, 3079, 3086, 114, 114, 111, 119, 59, 1, 10232, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 10234, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 10233, 102, 59, 3, 55349, 56643, 101, 114, 4, 2, 76, 82, 3123, 3134, 101, 102, 116, 65, 114, 114, 111, 119, 59, 1, 8601, 105, 103, 104, 116, 65, 114, 114, 111, 119, 59, 1, 8600, 4, 3, 99, 104, 116, 3154, 3158, 3161, 114, 59, 1, 8466, 59, 1, 8624, 114, 111, 107, 59, 1, 321, 59, 1, 8810, 4, 8, 97, 99, 101, 102, 105, 111, 115, 117, 3188, 3192, 3196, 3222, 3227, 3237, 3243, 3248, 112, 59, 1, 10501, 121, 59, 1, 1052, 4, 2, 100, 108, 3202, 3213, 105, 117, 109, 83, 112, 97, 99, 101, 59, 1, 8287, 108, 105, 110, 116, 114, 102, 59, 1, 8499, 114, 59, 3, 55349, 56592, 110, 117, 115, 80, 108, 117, 115, 59, 1, 8723, 112, 102, 59, 3, 55349, 56644, 99, 114, 59, 1, 8499, 59, 1, 924, 4, 9, 74, 97, 99, 101, 102, 111, 115, 116, 117, 3271, 3276, 3283, 3306, 3422, 3427, 4120, 4126, 4137, 99, 121, 59, 1, 1034, 99, 117, 116, 101, 59, 1, 323, 4, 3, 97, 101, 121, 3291, 3297, 3303, 114, 111, 110, 59, 1, 327, 100, 105, 108, 59, 1, 325, 59, 1, 1053, 4, 3, 103, 115, 119, 3314, 3380, 3415, 97, 116, 105, 118, 101, 4, 3, 77, 84, 86, 3327, 3340, 3365, 101, 100, 105, 117, 109, 83, 112, 97, 99, 101, 59, 1, 8203, 104, 105, 4, 2, 99, 110, 3348, 3357, 107, 83, 112, 97, 99, 101, 59, 1, 8203, 83, 112, 97, 99, 101, 59, 1, 8203, 101, 114, 121, 84, 104, 105, 110, 83, 112, 97, 99, 101, 59, 1, 8203, 116, 101, 100, 4, 2, 71, 76, 3389, 3405, 114, 101, 97, 116, 101, 114, 71, 114, 101, 97, 116, 101, 114, 59, 1, 8811, 101, 115, 115, 76, 101, 115, 115, 59, 1, 8810, 76, 105, 110, 101, 59, 1, 10, 114, 59, 3, 55349, 56593, 4, 4, 66, 110, 112, 116, 3437, 3444, 3460, 3464, 114, 101, 97, 107, 59, 1, 8288, 66, 114, 101, 97, 107, 105, 110, 103, 83, 112, 97, 99, 101, 59, 1, 160, 102, 59, 1, 8469, 4, 13, 59, 67, 68, 69, 71, 72, 76, 78, 80, 82, 83, 84, 86, 3492, 3494, 3517, 3536, 3578, 3657, 3685, 3784, 3823, 3860, 3915, 4066, 4107, 1, 10988, 4, 2, 111, 117, 3500, 3510, 110, 103, 114, 117, 101, 110, 116, 59, 1, 8802, 112, 67, 97, 112, 59, 1, 8813, 111, 117, 98, 108, 101, 86, 101, 114, 116, 105, 99, 97, 108, 66, 97, 114, 59, 1, 8742, 4, 3, 108, 113, 120, 3544, 3552, 3571, 101, 109, 101, 110, 116, 59, 1, 8713, 117, 97, 108, 4, 2, 59, 84, 3561, 3563, 1, 8800, 105, 108, 100, 101, 59, 3, 8770, 824, 105, 115, 116, 115, 59, 1, 8708, 114, 101, 97, 116, 101, 114, 4, 7, 59, 69, 70, 71, 76, 83, 84, 3600, 3602, 3609, 3621, 3631, 3637, 3650, 1, 8815, 113, 117, 97, 108, 59, 1, 8817, 117, 108, 108, 69, 113, 117, 97, 108, 59, 3, 8807, 824, 114, 101, 97, 116, 101, 114, 59, 3, 8811, 824, 101, 115, 115, 59, 1, 8825, 108, 97, 110, 116, 69, 113, 117, 97, 108, 59, 3, 10878, 824, 105, 108, 100, 101, 59, 1, 8821, 117, 109, 112, 4, 2, 68, 69, 3666, 3677, 111, 119, 110, 72, 117, 109, 112, 59, 3, 8782, 824, 113, 117, 97, 108, 59, 3, 8783, 824, 101, 4, 2, 102, 115, 3692, 3724, 116, 84, 114, 105, 97, 110, 103, 108, 101, 4, 3, 59, 66, 69, 3709, 3711, 3717, 1, 8938, 97, 114, 59, 3, 10703, 824, 113, 117, 97, 108, 59, 1, 8940, 115, 4, 6, 59, 69, 71, 76, 83, 84, 3739, 3741, 3748, 3757, 3764, 3777, 1, 8814, 113, 117, 97, 108, 59, 1, 8816, 114, 101, 97, 116, 101, 114, 59, 1, 8824, 101, 115, 115, 59, 3, 8810, 824, 108, 97, 110, 116, 69, 113, 117, 97, 108, 59, 3, 10877, 824, 105, 108, 100, 101, 59, 1, 8820, 101, 115, 116, 101, 100, 4, 2, 71, 76, 3795, 3812, 114, 101, 97, 116, 101, 114, 71, 114, 101, 97, 116, 101, 114, 59, 3, 10914, 824, 101, 115, 115, 76, 101, 115, 115, 59, 3, 10913, 824, 114, 101, 99, 101, 100, 101, 115, 4, 3, 59, 69, 83, 3838, 3840, 3848, 1, 8832, 113, 117, 97, 108, 59, 3, 10927, 824, 108, 97, 110, 116, 69, 113, 117, 97, 108, 59, 1, 8928, 4, 2, 101, 105, 3866, 3881, 118, 101, 114, 115, 101, 69, 108, 101, 109, 101, 110, 116, 59, 1, 8716, 103, 104, 116, 84, 114, 105, 97, 110, 103, 108, 101, 4, 3, 59, 66, 69, 3900, 3902, 3908, 1, 8939, 97, 114, 59, 3, 10704, 824, 113, 117, 97, 108, 59, 1, 8941, 4, 2, 113, 117, 3921, 3973, 117, 97, 114, 101, 83, 117, 4, 2, 98, 112, 3933, 3952, 115, 101, 116, 4, 2, 59, 69, 3942, 3945, 3, 8847, 824, 113, 117, 97, 108, 59, 1, 8930, 101, 114, 115, 101, 116, 4, 2, 59, 69, 3963, 3966, 3, 8848, 824, 113, 117, 97, 108, 59, 1, 8931, 4, 3, 98, 99, 112, 3981, 4000, 4045, 115, 101, 116, 4, 2, 59, 69, 3990, 3993, 3, 8834, 8402, 113, 117, 97, 108, 59, 1, 8840, 99, 101, 101, 100, 115, 4, 4, 59, 69, 83, 84, 4015, 4017, 4025, 4037, 1, 8833, 113, 117, 97, 108, 59, 3, 10928, 824, 108, 97, 110, 116, 69, 113, 117, 97, 108, 59, 1, 8929, 105, 108, 100, 101, 59, 3, 8831, 824, 101, 114, 115, 101, 116, 4, 2, 59, 69, 4056, 4059, 3, 8835, 8402, 113, 117, 97, 108, 59, 1, 8841, 105, 108, 100, 101, 4, 4, 59, 69, 70, 84, 4080, 4082, 4089, 4100, 1, 8769, 113, 117, 97, 108, 59, 1, 8772, 117, 108, 108, 69, 113, 117, 97, 108, 59, 1, 8775, 105, 108, 100, 101, 59, 1, 8777, 101, 114, 116, 105, 99, 97, 108, 66, 97, 114, 59, 1, 8740, 99, 114, 59, 3, 55349, 56489, 105, 108, 100, 101, 5, 209, 1, 59, 4135, 1, 209, 59, 1, 925, 4, 14, 69, 97, 99, 100, 102, 103, 109, 111, 112, 114, 115, 116, 117, 118, 4170, 4176, 4187, 4205, 4212, 4217, 4228, 4253, 4259, 4292, 4295, 4316, 4337, 4346, 108, 105, 103, 59, 1, 338, 99, 117, 116, 101, 5, 211, 1, 59, 4185, 1, 211, 4, 2, 105, 121, 4193, 4202, 114, 99, 5, 212, 1, 59, 4200, 1, 212, 59, 1, 1054, 98, 108, 97, 99, 59, 1, 336, 114, 59, 3, 55349, 56594, 114, 97, 118, 101, 5, 210, 1, 59, 4226, 1, 210, 4, 3, 97, 101, 105, 4236, 4241, 4246, 99, 114, 59, 1, 332, 103, 97, 59, 1, 937, 99, 114, 111, 110, 59, 1, 927, 112, 102, 59, 3, 55349, 56646, 101, 110, 67, 117, 114, 108, 121, 4, 2, 68, 81, 4272, 4285, 111, 117, 98, 108, 101, 81, 117, 111, 116, 101, 59, 1, 8220, 117, 111, 116, 101, 59, 1, 8216, 59, 1, 10836, 4, 2, 99, 108, 4301, 4306, 114, 59, 3, 55349, 56490, 97, 115, 104, 5, 216, 1, 59, 4314, 1, 216, 105, 4, 2, 108, 109, 4323, 4332, 100, 101, 5, 213, 1, 59, 4330, 1, 213, 101, 115, 59, 1, 10807, 109, 108, 5, 214, 1, 59, 4344, 1, 214, 101, 114, 4, 2, 66, 80, 4354, 4380, 4, 2, 97, 114, 4360, 4364, 114, 59, 1, 8254, 97, 99, 4, 2, 101, 107, 4372, 4375, 59, 1, 9182, 101, 116, 59, 1, 9140, 97, 114, 101, 110, 116, 104, 101, 115, 105, 115, 59, 1, 9180, 4, 9, 97, 99, 102, 104, 105, 108, 111, 114, 115, 4413, 4422, 4426, 4431, 4435, 4438, 4448, 4471, 4561, 114, 116, 105, 97, 108, 68, 59, 1, 8706, 121, 59, 1, 1055, 114, 59, 3, 55349, 56595, 105, 59, 1, 934, 59, 1, 928, 117, 115, 77, 105, 110, 117, 115, 59, 1, 177, 4, 2, 105, 112, 4454, 4467, 110, 99, 97, 114, 101, 112, 108, 97, 110, 101, 59, 1, 8460, 102, 59, 1, 8473, 4, 4, 59, 101, 105, 111, 4481, 4483, 4526, 4531, 1, 10939, 99, 101, 100, 101, 115, 4, 4, 59, 69, 83, 84, 4498, 4500, 4507, 4519, 1, 8826, 113, 117, 97, 108, 59, 1, 10927, 108, 97, 110, 116, 69, 113, 117, 97, 108, 59, 1, 8828, 105, 108, 100, 101, 59, 1, 8830, 109, 101, 59, 1, 8243, 4, 2, 100, 112, 4537, 4543, 117, 99, 116, 59, 1, 8719, 111, 114, 116, 105, 111, 110, 4, 2, 59, 97, 4555, 4557, 1, 8759, 108, 59, 1, 8733, 4, 2, 99, 105, 4567, 4572, 114, 59, 3, 55349, 56491, 59, 1, 936, 4, 4, 85, 102, 111, 115, 4585, 4594, 4599, 4604, 79, 84, 5, 34, 1, 59, 4592, 1, 34, 114, 59, 3, 55349, 56596, 112, 102, 59, 1, 8474, 99, 114, 59, 3, 55349, 56492, 4, 12, 66, 69, 97, 99, 101, 102, 104, 105, 111, 114, 115, 117, 4636, 4642, 4650, 4681, 4704, 4763, 4767, 4771, 5047, 5069, 5081, 5094, 97, 114, 114, 59, 1, 10512, 71, 5, 174, 1, 59, 4648, 1, 174, 4, 3, 99, 110, 114, 4658, 4664, 4668, 117, 116, 101, 59, 1, 340, 103, 59, 1, 10219, 114, 4, 2, 59, 116, 4675, 4677, 1, 8608, 108, 59, 1, 10518, 4, 3, 97, 101, 121, 4689, 4695, 4701, 114, 111, 110, 59, 1, 344, 100, 105, 108, 59, 1, 342, 59, 1, 1056, 4, 2, 59, 118, 4710, 4712, 1, 8476, 101, 114, 115, 101, 4, 2, 69, 85, 4722, 4748, 4, 2, 108, 113, 4728, 4736, 101, 109, 101, 110, 116, 59, 1, 8715, 117, 105, 108, 105, 98, 114, 105, 117, 109, 59, 1, 8651, 112, 69, 113, 117, 105, 108, 105, 98, 114, 105, 117, 109, 59, 1, 10607, 114, 59, 1, 8476, 111, 59, 1, 929, 103, 104, 116, 4, 8, 65, 67, 68, 70, 84, 85, 86, 97, 4792, 4840, 4849, 4905, 4912, 4972, 5022, 5040, 4, 2, 110, 114, 4798, 4811, 103, 108, 101, 66, 114, 97, 99, 107, 101, 116, 59, 1, 10217, 114, 111, 119, 4, 3, 59, 66, 76, 4822, 4824, 4829, 1, 8594, 97, 114, 59, 1, 8677, 101, 102, 116, 65, 114, 114, 111, 119, 59, 1, 8644, 101, 105, 108, 105, 110, 103, 59, 1, 8969, 111, 4, 2, 117, 119, 4856, 4869, 98, 108, 101, 66, 114, 97, 99, 107, 101, 116, 59, 1, 10215, 110, 4, 2, 84, 86, 4876, 4887, 101, 101, 86, 101, 99, 116, 111, 114, 59, 1, 10589, 101, 99, 116, 111, 114, 4, 2, 59, 66, 4898, 4900, 1, 8642, 97, 114, 59, 1, 10581, 108, 111, 111, 114, 59, 1, 8971, 4, 2, 101, 114, 4918, 4944, 101, 4, 3, 59, 65, 86, 4927, 4929, 4936, 1, 8866, 114, 114, 111, 119, 59, 1, 8614, 101, 99, 116, 111, 114, 59, 1, 10587, 105, 97, 110, 103, 108, 101, 4, 3, 59, 66, 69, 4958, 4960, 4965, 1, 8883, 97, 114, 59, 1, 10704, 113, 117, 97, 108, 59, 1, 8885, 112, 4, 3, 68, 84, 86, 4981, 4993, 5004, 111, 119, 110, 86, 101, 99, 116, 111, 114, 59, 1, 10575, 101, 101, 86, 101, 99, 116, 111, 114, 59, 1, 10588, 101, 99, 116, 111, 114, 4, 2, 59, 66, 5015, 5017, 1, 8638, 97, 114, 59, 1, 10580, 101, 99, 116, 111, 114, 4, 2, 59, 66, 5033, 5035, 1, 8640, 97, 114, 59, 1, 10579, 114, 114, 111, 119, 59, 1, 8658, 4, 2, 112, 117, 5053, 5057, 102, 59, 1, 8477, 110, 100, 73, 109, 112, 108, 105, 101, 115, 59, 1, 10608, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 8667, 4, 2, 99, 104, 5087, 5091, 114, 59, 1, 8475, 59, 1, 8625, 108, 101, 68, 101, 108, 97, 121, 101, 100, 59, 1, 10740, 4, 13, 72, 79, 97, 99, 102, 104, 105, 109, 111, 113, 115, 116, 117, 5134, 5150, 5157, 5164, 5198, 5203, 5259, 5265, 5277, 5283, 5374, 5380, 5385, 4, 2, 67, 99, 5140, 5146, 72, 99, 121, 59, 1, 1065, 121, 59, 1, 1064, 70, 84, 99, 121, 59, 1, 1068, 99, 117, 116, 101, 59, 1, 346, 4, 5, 59, 97, 101, 105, 121, 5176, 5178, 5184, 5190, 5195, 1, 10940, 114, 111, 110, 59, 1, 352, 100, 105, 108, 59, 1, 350, 114, 99, 59, 1, 348, 59, 1, 1057, 114, 59, 3, 55349, 56598, 111, 114, 116, 4, 4, 68, 76, 82, 85, 5216, 5227, 5238, 5250, 111, 119, 110, 65, 114, 114, 111, 119, 59, 1, 8595, 101, 102, 116, 65, 114, 114, 111, 119, 59, 1, 8592, 105, 103, 104, 116, 65, 114, 114, 111, 119, 59, 1, 8594, 112, 65, 114, 114, 111, 119, 59, 1, 8593, 103, 109, 97, 59, 1, 931, 97, 108, 108, 67, 105, 114, 99, 108, 101, 59, 1, 8728, 112, 102, 59, 3, 55349, 56650, 4, 2, 114, 117, 5289, 5293, 116, 59, 1, 8730, 97, 114, 101, 4, 4, 59, 73, 83, 85, 5306, 5308, 5322, 5367, 1, 9633, 110, 116, 101, 114, 115, 101, 99, 116, 105, 111, 110, 59, 1, 8851, 117, 4, 2, 98, 112, 5329, 5347, 115, 101, 116, 4, 2, 59, 69, 5338, 5340, 1, 8847, 113, 117, 97, 108, 59, 1, 8849, 101, 114, 115, 101, 116, 4, 2, 59, 69, 5358, 5360, 1, 8848, 113, 117, 97, 108, 59, 1, 8850, 110, 105, 111, 110, 59, 1, 8852, 99, 114, 59, 3, 55349, 56494, 97, 114, 59, 1, 8902, 4, 4, 98, 99, 109, 112, 5395, 5420, 5475, 5478, 4, 2, 59, 115, 5401, 5403, 1, 8912, 101, 116, 4, 2, 59, 69, 5411, 5413, 1, 8912, 113, 117, 97, 108, 59, 1, 8838, 4, 2, 99, 104, 5426, 5468, 101, 101, 100, 115, 4, 4, 59, 69, 83, 84, 5440, 5442, 5449, 5461, 1, 8827, 113, 117, 97, 108, 59, 1, 10928, 108, 97, 110, 116, 69, 113, 117, 97, 108, 59, 1, 8829, 105, 108, 100, 101, 59, 1, 8831, 84, 104, 97, 116, 59, 1, 8715, 59, 1, 8721, 4, 3, 59, 101, 115, 5486, 5488, 5507, 1, 8913, 114, 115, 101, 116, 4, 2, 59, 69, 5498, 5500, 1, 8835, 113, 117, 97, 108, 59, 1, 8839, 101, 116, 59, 1, 8913, 4, 11, 72, 82, 83, 97, 99, 102, 104, 105, 111, 114, 115, 5536, 5546, 5552, 5567, 5579, 5602, 5607, 5655, 5695, 5701, 5711, 79, 82, 78, 5, 222, 1, 59, 5544, 1, 222, 65, 68, 69, 59, 1, 8482, 4, 2, 72, 99, 5558, 5563, 99, 121, 59, 1, 1035, 121, 59, 1, 1062, 4, 2, 98, 117, 5573, 5576, 59, 1, 9, 59, 1, 932, 4, 3, 97, 101, 121, 5587, 5593, 5599, 114, 111, 110, 59, 1, 356, 100, 105, 108, 59, 1, 354, 59, 1, 1058, 114, 59, 3, 55349, 56599, 4, 2, 101, 105, 5613, 5631, 4, 2, 114, 116, 5619, 5627, 101, 102, 111, 114, 101, 59, 1, 8756, 97, 59, 1, 920, 4, 2, 99, 110, 5637, 5647, 107, 83, 112, 97, 99, 101, 59, 3, 8287, 8202, 83, 112, 97, 99, 101, 59, 1, 8201, 108, 100, 101, 4, 4, 59, 69, 70, 84, 5668, 5670, 5677, 5688, 1, 8764, 113, 117, 97, 108, 59, 1, 8771, 117, 108, 108, 69, 113, 117, 97, 108, 59, 1, 8773, 105, 108, 100, 101, 59, 1, 8776, 112, 102, 59, 3, 55349, 56651, 105, 112, 108, 101, 68, 111, 116, 59, 1, 8411, 4, 2, 99, 116, 5717, 5722, 114, 59, 3, 55349, 56495, 114, 111, 107, 59, 1, 358, 4, 14, 97, 98, 99, 100, 102, 103, 109, 110, 111, 112, 114, 115, 116, 117, 5758, 5789, 5805, 5823, 5830, 5835, 5846, 5852, 5921, 5937, 6089, 6095, 6101, 6108, 4, 2, 99, 114, 5764, 5774, 117, 116, 101, 5, 218, 1, 59, 5772, 1, 218, 114, 4, 2, 59, 111, 5781, 5783, 1, 8607, 99, 105, 114, 59, 1, 10569, 114, 4, 2, 99, 101, 5796, 5800, 121, 59, 1, 1038, 118, 101, 59, 1, 364, 4, 2, 105, 121, 5811, 5820, 114, 99, 5, 219, 1, 59, 5818, 1, 219, 59, 1, 1059, 98, 108, 97, 99, 59, 1, 368, 114, 59, 3, 55349, 56600, 114, 97, 118, 101, 5, 217, 1, 59, 5844, 1, 217, 97, 99, 114, 59, 1, 362, 4, 2, 100, 105, 5858, 5905, 101, 114, 4, 2, 66, 80, 5866, 5892, 4, 2, 97, 114, 5872, 5876, 114, 59, 1, 95, 97, 99, 4, 2, 101, 107, 5884, 5887, 59, 1, 9183, 101, 116, 59, 1, 9141, 97, 114, 101, 110, 116, 104, 101, 115, 105, 115, 59, 1, 9181, 111, 110, 4, 2, 59, 80, 5913, 5915, 1, 8899, 108, 117, 115, 59, 1, 8846, 4, 2, 103, 112, 5927, 5932, 111, 110, 59, 1, 370, 102, 59, 3, 55349, 56652, 4, 8, 65, 68, 69, 84, 97, 100, 112, 115, 5955, 5985, 5996, 6009, 6026, 6033, 6044, 6075, 114, 114, 111, 119, 4, 3, 59, 66, 68, 5967, 5969, 5974, 1, 8593, 97, 114, 59, 1, 10514, 111, 119, 110, 65, 114, 114, 111, 119, 59, 1, 8645, 111, 119, 110, 65, 114, 114, 111, 119, 59, 1, 8597, 113, 117, 105, 108, 105, 98, 114, 105, 117, 109, 59, 1, 10606, 101, 101, 4, 2, 59, 65, 6017, 6019, 1, 8869, 114, 114, 111, 119, 59, 1, 8613, 114, 114, 111, 119, 59, 1, 8657, 111, 119, 110, 97, 114, 114, 111, 119, 59, 1, 8661, 101, 114, 4, 2, 76, 82, 6052, 6063, 101, 102, 116, 65, 114, 114, 111, 119, 59, 1, 8598, 105, 103, 104, 116, 65, 114, 114, 111, 119, 59, 1, 8599, 105, 4, 2, 59, 108, 6082, 6084, 1, 978, 111, 110, 59, 1, 933, 105, 110, 103, 59, 1, 366, 99, 114, 59, 3, 55349, 56496, 105, 108, 100, 101, 59, 1, 360, 109, 108, 5, 220, 1, 59, 6115, 1, 220, 4, 9, 68, 98, 99, 100, 101, 102, 111, 115, 118, 6137, 6143, 6148, 6152, 6166, 6250, 6255, 6261, 6267, 97, 115, 104, 59, 1, 8875, 97, 114, 59, 1, 10987, 121, 59, 1, 1042, 97, 115, 104, 4, 2, 59, 108, 6161, 6163, 1, 8873, 59, 1, 10982, 4, 2, 101, 114, 6172, 6175, 59, 1, 8897, 4, 3, 98, 116, 121, 6183, 6188, 6238, 97, 114, 59, 1, 8214, 4, 2, 59, 105, 6194, 6196, 1, 8214, 99, 97, 108, 4, 4, 66, 76, 83, 84, 6209, 6214, 6220, 6231, 97, 114, 59, 1, 8739, 105, 110, 101, 59, 1, 124, 101, 112, 97, 114, 97, 116, 111, 114, 59, 1, 10072, 105, 108, 100, 101, 59, 1, 8768, 84, 104, 105, 110, 83, 112, 97, 99, 101, 59, 1, 8202, 114, 59, 3, 55349, 56601, 112, 102, 59, 3, 55349, 56653, 99, 114, 59, 3, 55349, 56497, 100, 97, 115, 104, 59, 1, 8874, 4, 5, 99, 101, 102, 111, 115, 6286, 6292, 6298, 6303, 6309, 105, 114, 99, 59, 1, 372, 100, 103, 101, 59, 1, 8896, 114, 59, 3, 55349, 56602, 112, 102, 59, 3, 55349, 56654, 99, 114, 59, 3, 55349, 56498, 4, 4, 102, 105, 111, 115, 6325, 6330, 6333, 6339, 114, 59, 3, 55349, 56603, 59, 1, 926, 112, 102, 59, 3, 55349, 56655, 99, 114, 59, 3, 55349, 56499, 4, 9, 65, 73, 85, 97, 99, 102, 111, 115, 117, 6365, 6370, 6375, 6380, 6391, 6405, 6410, 6416, 6422, 99, 121, 59, 1, 1071, 99, 121, 59, 1, 1031, 99, 121, 59, 1, 1070, 99, 117, 116, 101, 5, 221, 1, 59, 6389, 1, 221, 4, 2, 105, 121, 6397, 6402, 114, 99, 59, 1, 374, 59, 1, 1067, 114, 59, 3, 55349, 56604, 112, 102, 59, 3, 55349, 56656, 99, 114, 59, 3, 55349, 56500, 109, 108, 59, 1, 376, 4, 8, 72, 97, 99, 100, 101, 102, 111, 115, 6445, 6450, 6457, 6472, 6477, 6501, 6505, 6510, 99, 121, 59, 1, 1046, 99, 117, 116, 101, 59, 1, 377, 4, 2, 97, 121, 6463, 6469, 114, 111, 110, 59, 1, 381, 59, 1, 1047, 111, 116, 59, 1, 379, 4, 2, 114, 116, 6483, 6497, 111, 87, 105, 100, 116, 104, 83, 112, 97, 99, 101, 59, 1, 8203, 97, 59, 1, 918, 114, 59, 1, 8488, 112, 102, 59, 1, 8484, 99, 114, 59, 3, 55349, 56501, 4, 16, 97, 98, 99, 101, 102, 103, 108, 109, 110, 111, 112, 114, 115, 116, 117, 119, 6550, 6561, 6568, 6612, 6622, 6634, 6645, 6672, 6699, 6854, 6870, 6923, 6933, 6963, 6974, 6983, 99, 117, 116, 101, 5, 225, 1, 59, 6559, 1, 225, 114, 101, 118, 101, 59, 1, 259, 4, 6, 59, 69, 100, 105, 117, 121, 6582, 6584, 6588, 6591, 6600, 6609, 1, 8766, 59, 3, 8766, 819, 59, 1, 8767, 114, 99, 5, 226, 1, 59, 6598, 1, 226, 116, 101, 5, 180, 1, 59, 6607, 1, 180, 59, 1, 1072, 108, 105, 103, 5, 230, 1, 59, 6620, 1, 230, 4, 2, 59, 114, 6628, 6630, 1, 8289, 59, 3, 55349, 56606, 114, 97, 118, 101, 5, 224, 1, 59, 6643, 1, 224, 4, 2, 101, 112, 6651, 6667, 4, 2, 102, 112, 6657, 6663, 115, 121, 109, 59, 1, 8501, 104, 59, 1, 8501, 104, 97, 59, 1, 945, 4, 2, 97, 112, 6678, 6692, 4, 2, 99, 108, 6684, 6688, 114, 59, 1, 257, 103, 59, 1, 10815, 5, 38, 1, 59, 6697, 1, 38, 4, 2, 100, 103, 6705, 6737, 4, 5, 59, 97, 100, 115, 118, 6717, 6719, 6724, 6727, 6734, 1, 8743, 110, 100, 59, 1, 10837, 59, 1, 10844, 108, 111, 112, 101, 59, 1, 10840, 59, 1, 10842, 4, 7, 59, 101, 108, 109, 114, 115, 122, 6753, 6755, 6758, 6762, 6814, 6835, 6848, 1, 8736, 59, 1, 10660, 101, 59, 1, 8736, 115, 100, 4, 2, 59, 97, 6770, 6772, 1, 8737, 4, 8, 97, 98, 99, 100, 101, 102, 103, 104, 6790, 6793, 6796, 6799, 6802, 6805, 6808, 6811, 59, 1, 10664, 59, 1, 10665, 59, 1, 10666, 59, 1, 10667, 59, 1, 10668, 59, 1, 10669, 59, 1, 10670, 59, 1, 10671, 116, 4, 2, 59, 118, 6821, 6823, 1, 8735, 98, 4, 2, 59, 100, 6830, 6832, 1, 8894, 59, 1, 10653, 4, 2, 112, 116, 6841, 6845, 104, 59, 1, 8738, 59, 1, 197, 97, 114, 114, 59, 1, 9084, 4, 2, 103, 112, 6860, 6865, 111, 110, 59, 1, 261, 102, 59, 3, 55349, 56658, 4, 7, 59, 69, 97, 101, 105, 111, 112, 6886, 6888, 6891, 6897, 6900, 6904, 6908, 1, 8776, 59, 1, 10864, 99, 105, 114, 59, 1, 10863, 59, 1, 8778, 100, 59, 1, 8779, 115, 59, 1, 39, 114, 111, 120, 4, 2, 59, 101, 6917, 6919, 1, 8776, 113, 59, 1, 8778, 105, 110, 103, 5, 229, 1, 59, 6931, 1, 229, 4, 3, 99, 116, 121, 6941, 6946, 6949, 114, 59, 3, 55349, 56502, 59, 1, 42, 109, 112, 4, 2, 59, 101, 6957, 6959, 1, 8776, 113, 59, 1, 8781, 105, 108, 100, 101, 5, 227, 1, 59, 6972, 1, 227, 109, 108, 5, 228, 1, 59, 6981, 1, 228, 4, 2, 99, 105, 6989, 6997, 111, 110, 105, 110, 116, 59, 1, 8755, 110, 116, 59, 1, 10769, 4, 16, 78, 97, 98, 99, 100, 101, 102, 105, 107, 108, 110, 111, 112, 114, 115, 117, 7036, 7041, 7119, 7135, 7149, 7155, 7219, 7224, 7347, 7354, 7463, 7489, 7786, 7793, 7814, 7866, 111, 116, 59, 1, 10989, 4, 2, 99, 114, 7047, 7094, 107, 4, 4, 99, 101, 112, 115, 7058, 7064, 7073, 7080, 111, 110, 103, 59, 1, 8780, 112, 115, 105, 108, 111, 110, 59, 1, 1014, 114, 105, 109, 101, 59, 1, 8245, 105, 109, 4, 2, 59, 101, 7088, 7090, 1, 8765, 113, 59, 1, 8909, 4, 2, 118, 119, 7100, 7105, 101, 101, 59, 1, 8893, 101, 100, 4, 2, 59, 103, 7113, 7115, 1, 8965, 101, 59, 1, 8965, 114, 107, 4, 2, 59, 116, 7127, 7129, 1, 9141, 98, 114, 107, 59, 1, 9142, 4, 2, 111, 121, 7141, 7146, 110, 103, 59, 1, 8780, 59, 1, 1073, 113, 117, 111, 59, 1, 8222, 4, 5, 99, 109, 112, 114, 116, 7167, 7181, 7188, 7193, 7199, 97, 117, 115, 4, 2, 59, 101, 7176, 7178, 1, 8757, 59, 1, 8757, 112, 116, 121, 118, 59, 1, 10672, 115, 105, 59, 1, 1014, 110, 111, 117, 59, 1, 8492, 4, 3, 97, 104, 119, 7207, 7210, 7213, 59, 1, 946, 59, 1, 8502, 101, 101, 110, 59, 1, 8812, 114, 59, 3, 55349, 56607, 103, 4, 7, 99, 111, 115, 116, 117, 118, 119, 7241, 7262, 7288, 7305, 7328, 7335, 7340, 4, 3, 97, 105, 117, 7249, 7253, 7258, 112, 59, 1, 8898, 114, 99, 59, 1, 9711, 112, 59, 1, 8899, 4, 3, 100, 112, 116, 7270, 7275, 7281, 111, 116, 59, 1, 10752, 108, 117, 115, 59, 1, 10753, 105, 109, 101, 115, 59, 1, 10754, 4, 2, 113, 116, 7294, 7300, 99, 117, 112, 59, 1, 10758, 97, 114, 59, 1, 9733, 114, 105, 97, 110, 103, 108, 101, 4, 2, 100, 117, 7318, 7324, 111, 119, 110, 59, 1, 9661, 112, 59, 1, 9651, 112, 108, 117, 115, 59, 1, 10756, 101, 101, 59, 1, 8897, 101, 100, 103, 101, 59, 1, 8896, 97, 114, 111, 119, 59, 1, 10509, 4, 3, 97, 107, 111, 7362, 7436, 7458, 4, 2, 99, 110, 7368, 7432, 107, 4, 3, 108, 115, 116, 7377, 7386, 7394, 111, 122, 101, 110, 103, 101, 59, 1, 10731, 113, 117, 97, 114, 101, 59, 1, 9642, 114, 105, 97, 110, 103, 108, 101, 4, 4, 59, 100, 108, 114, 7411, 7413, 7419, 7425, 1, 9652, 111, 119, 110, 59, 1, 9662, 101, 102, 116, 59, 1, 9666, 105, 103, 104, 116, 59, 1, 9656, 107, 59, 1, 9251, 4, 2, 49, 51, 7442, 7454, 4, 2, 50, 52, 7448, 7451, 59, 1, 9618, 59, 1, 9617, 52, 59, 1, 9619, 99, 107, 59, 1, 9608, 4, 2, 101, 111, 7469, 7485, 4, 2, 59, 113, 7475, 7478, 3, 61, 8421, 117, 105, 118, 59, 3, 8801, 8421, 116, 59, 1, 8976, 4, 4, 112, 116, 119, 120, 7499, 7504, 7517, 7523, 102, 59, 3, 55349, 56659, 4, 2, 59, 116, 7510, 7512, 1, 8869, 111, 109, 59, 1, 8869, 116, 105, 101, 59, 1, 8904, 4, 12, 68, 72, 85, 86, 98, 100, 104, 109, 112, 116, 117, 118, 7549, 7571, 7597, 7619, 7655, 7660, 7682, 7708, 7715, 7721, 7728, 7750, 4, 4, 76, 82, 108, 114, 7559, 7562, 7565, 7568, 59, 1, 9559, 59, 1, 9556, 59, 1, 9558, 59, 1, 9555, 4, 5, 59, 68, 85, 100, 117, 7583, 7585, 7588, 7591, 7594, 1, 9552, 59, 1, 9574, 59, 1, 9577, 59, 1, 9572, 59, 1, 9575, 4, 4, 76, 82, 108, 114, 7607, 7610, 7613, 7616, 59, 1, 9565, 59, 1, 9562, 59, 1, 9564, 59, 1, 9561, 4, 7, 59, 72, 76, 82, 104, 108, 114, 7635, 7637, 7640, 7643, 7646, 7649, 7652, 1, 9553, 59, 1, 9580, 59, 1, 9571, 59, 1, 9568, 59, 1, 9579, 59, 1, 9570, 59, 1, 9567, 111, 120, 59, 1, 10697, 4, 4, 76, 82, 108, 114, 7670, 7673, 7676, 7679, 59, 1, 9557, 59, 1, 9554, 59, 1, 9488, 59, 1, 9484, 4, 5, 59, 68, 85, 100, 117, 7694, 7696, 7699, 7702, 7705, 1, 9472, 59, 1, 9573, 59, 1, 9576, 59, 1, 9516, 59, 1, 9524, 105, 110, 117, 115, 59, 1, 8863, 108, 117, 115, 59, 1, 8862, 105, 109, 101, 115, 59, 1, 8864, 4, 4, 76, 82, 108, 114, 7738, 7741, 7744, 7747, 59, 1, 9563, 59, 1, 9560, 59, 1, 9496, 59, 1, 9492, 4, 7, 59, 72, 76, 82, 104, 108, 114, 7766, 7768, 7771, 7774, 7777, 7780, 7783, 1, 9474, 59, 1, 9578, 59, 1, 9569, 59, 1, 9566, 59, 1, 9532, 59, 1, 9508, 59, 1, 9500, 114, 105, 109, 101, 59, 1, 8245, 4, 2, 101, 118, 7799, 7804, 118, 101, 59, 1, 728, 98, 97, 114, 5, 166, 1, 59, 7812, 1, 166, 4, 4, 99, 101, 105, 111, 7824, 7829, 7834, 7846, 114, 59, 3, 55349, 56503, 109, 105, 59, 1, 8271, 109, 4, 2, 59, 101, 7841, 7843, 1, 8765, 59, 1, 8909, 108, 4, 3, 59, 98, 104, 7855, 7857, 7860, 1, 92, 59, 1, 10693, 115, 117, 98, 59, 1, 10184, 4, 2, 108, 109, 7872, 7885, 108, 4, 2, 59, 101, 7879, 7881, 1, 8226, 116, 59, 1, 8226, 112, 4, 3, 59, 69, 101, 7894, 7896, 7899, 1, 8782, 59, 1, 10926, 4, 2, 59, 113, 7905, 7907, 1, 8783, 59, 1, 8783, 4, 15, 97, 99, 100, 101, 102, 104, 105, 108, 111, 114, 115, 116, 117, 119, 121, 7942, 8021, 8075, 8080, 8121, 8126, 8157, 8279, 8295, 8430, 8446, 8485, 8491, 8707, 8726, 4, 3, 99, 112, 114, 7950, 7956, 8007, 117, 116, 101, 59, 1, 263, 4, 6, 59, 97, 98, 99, 100, 115, 7970, 7972, 7977, 7984, 7998, 8003, 1, 8745, 110, 100, 59, 1, 10820, 114, 99, 117, 112, 59, 1, 10825, 4, 2, 97, 117, 7990, 7994, 112, 59, 1, 10827, 112, 59, 1, 10823, 111, 116, 59, 1, 10816, 59, 3, 8745, 65024, 4, 2, 101, 111, 8013, 8017, 116, 59, 1, 8257, 110, 59, 1, 711, 4, 4, 97, 101, 105, 117, 8031, 8046, 8056, 8061, 4, 2, 112, 114, 8037, 8041, 115, 59, 1, 10829, 111, 110, 59, 1, 269, 100, 105, 108, 5, 231, 1, 59, 8054, 1, 231, 114, 99, 59, 1, 265, 112, 115, 4, 2, 59, 115, 8069, 8071, 1, 10828, 109, 59, 1, 10832, 111, 116, 59, 1, 267, 4, 3, 100, 109, 110, 8088, 8097, 8104, 105, 108, 5, 184, 1, 59, 8095, 1, 184, 112, 116, 121, 118, 59, 1, 10674, 116, 5, 162, 2, 59, 101, 8112, 8114, 1, 162, 114, 100, 111, 116, 59, 1, 183, 114, 59, 3, 55349, 56608, 4, 3, 99, 101, 105, 8134, 8138, 8154, 121, 59, 1, 1095, 99, 107, 4, 2, 59, 109, 8146, 8148, 1, 10003, 97, 114, 107, 59, 1, 10003, 59, 1, 967, 114, 4, 7, 59, 69, 99, 101, 102, 109, 115, 8174, 8176, 8179, 8258, 8261, 8268, 8273, 1, 9675, 59, 1, 10691, 4, 3, 59, 101, 108, 8187, 8189, 8193, 1, 710, 113, 59, 1, 8791, 101, 4, 2, 97, 100, 8200, 8223, 114, 114, 111, 119, 4, 2, 108, 114, 8210, 8216, 101, 102, 116, 59, 1, 8634, 105, 103, 104, 116, 59, 1, 8635, 4, 5, 82, 83, 97, 99, 100, 8235, 8238, 8241, 8246, 8252, 59, 1, 174, 59, 1, 9416, 115, 116, 59, 1, 8859, 105, 114, 99, 59, 1, 8858, 97, 115, 104, 59, 1, 8861, 59, 1, 8791, 110, 105, 110, 116, 59, 1, 10768, 105, 100, 59, 1, 10991, 99, 105, 114, 59, 1, 10690, 117, 98, 115, 4, 2, 59, 117, 8288, 8290, 1, 9827, 105, 116, 59, 1, 9827, 4, 4, 108, 109, 110, 112, 8305, 8326, 8376, 8400, 111, 110, 4, 2, 59, 101, 8313, 8315, 1, 58, 4, 2, 59, 113, 8321, 8323, 1, 8788, 59, 1, 8788, 4, 2, 109, 112, 8332, 8344, 97, 4, 2, 59, 116, 8339, 8341, 1, 44, 59, 1, 64, 4, 3, 59, 102, 108, 8352, 8354, 8358, 1, 8705, 110, 59, 1, 8728, 101, 4, 2, 109, 120, 8365, 8371, 101, 110, 116, 59, 1, 8705, 101, 115, 59, 1, 8450, 4, 2, 103, 105, 8382, 8395, 4, 2, 59, 100, 8388, 8390, 1, 8773, 111, 116, 59, 1, 10861, 110, 116, 59, 1, 8750, 4, 3, 102, 114, 121, 8408, 8412, 8417, 59, 3, 55349, 56660, 111, 100, 59, 1, 8720, 5, 169, 2, 59, 115, 8424, 8426, 1, 169, 114, 59, 1, 8471, 4, 2, 97, 111, 8436, 8441, 114, 114, 59, 1, 8629, 115, 115, 59, 1, 10007, 4, 2, 99, 117, 8452, 8457, 114, 59, 3, 55349, 56504, 4, 2, 98, 112, 8463, 8474, 4, 2, 59, 101, 8469, 8471, 1, 10959, 59, 1, 10961, 4, 2, 59, 101, 8480, 8482, 1, 10960, 59, 1, 10962, 100, 111, 116, 59, 1, 8943, 4, 7, 100, 101, 108, 112, 114, 118, 119, 8507, 8522, 8536, 8550, 8600, 8697, 8702, 97, 114, 114, 4, 2, 108, 114, 8516, 8519, 59, 1, 10552, 59, 1, 10549, 4, 2, 112, 115, 8528, 8532, 114, 59, 1, 8926, 99, 59, 1, 8927, 97, 114, 114, 4, 2, 59, 112, 8545, 8547, 1, 8630, 59, 1, 10557, 4, 6, 59, 98, 99, 100, 111, 115, 8564, 8566, 8573, 8587, 8592, 8596, 1, 8746, 114, 99, 97, 112, 59, 1, 10824, 4, 2, 97, 117, 8579, 8583, 112, 59, 1, 10822, 112, 59, 1, 10826, 111, 116, 59, 1, 8845, 114, 59, 1, 10821, 59, 3, 8746, 65024, 4, 4, 97, 108, 114, 118, 8610, 8623, 8663, 8672, 114, 114, 4, 2, 59, 109, 8618, 8620, 1, 8631, 59, 1, 10556, 121, 4, 3, 101, 118, 119, 8632, 8651, 8656, 113, 4, 2, 112, 115, 8639, 8645, 114, 101, 99, 59, 1, 8926, 117, 99, 99, 59, 1, 8927, 101, 101, 59, 1, 8910, 101, 100, 103, 101, 59, 1, 8911, 101, 110, 5, 164, 1, 59, 8670, 1, 164, 101, 97, 114, 114, 111, 119, 4, 2, 108, 114, 8684, 8690, 101, 102, 116, 59, 1, 8630, 105, 103, 104, 116, 59, 1, 8631, 101, 101, 59, 1, 8910, 101, 100, 59, 1, 8911, 4, 2, 99, 105, 8713, 8721, 111, 110, 105, 110, 116, 59, 1, 8754, 110, 116, 59, 1, 8753, 108, 99, 116, 121, 59, 1, 9005, 4, 19, 65, 72, 97, 98, 99, 100, 101, 102, 104, 105, 106, 108, 111, 114, 115, 116, 117, 119, 122, 8773, 8778, 8783, 8821, 8839, 8854, 8887, 8914, 8930, 8944, 9036, 9041, 9058, 9197, 9227, 9258, 9281, 9297, 9305, 114, 114, 59, 1, 8659, 97, 114, 59, 1, 10597, 4, 4, 103, 108, 114, 115, 8793, 8799, 8805, 8809, 103, 101, 114, 59, 1, 8224, 101, 116, 104, 59, 1, 8504, 114, 59, 1, 8595, 104, 4, 2, 59, 118, 8816, 8818, 1, 8208, 59, 1, 8867, 4, 2, 107, 108, 8827, 8834, 97, 114, 111, 119, 59, 1, 10511, 97, 99, 59, 1, 733, 4, 2, 97, 121, 8845, 8851, 114, 111, 110, 59, 1, 271, 59, 1, 1076, 4, 3, 59, 97, 111, 8862, 8864, 8880, 1, 8518, 4, 2, 103, 114, 8870, 8876, 103, 101, 114, 59, 1, 8225, 114, 59, 1, 8650, 116, 115, 101, 113, 59, 1, 10871, 4, 3, 103, 108, 109, 8895, 8902, 8907, 5, 176, 1, 59, 8900, 1, 176, 116, 97, 59, 1, 948, 112, 116, 121, 118, 59, 1, 10673, 4, 2, 105, 114, 8920, 8926, 115, 104, 116, 59, 1, 10623, 59, 3, 55349, 56609, 97, 114, 4, 2, 108, 114, 8938, 8941, 59, 1, 8643, 59, 1, 8642, 4, 5, 97, 101, 103, 115, 118, 8956, 8986, 8989, 8996, 9001, 109, 4, 3, 59, 111, 115, 8965, 8967, 8983, 1, 8900, 110, 100, 4, 2, 59, 115, 8975, 8977, 1, 8900, 117, 105, 116, 59, 1, 9830, 59, 1, 9830, 59, 1, 168, 97, 109, 109, 97, 59, 1, 989, 105, 110, 59, 1, 8946, 4, 3, 59, 105, 111, 9009, 9011, 9031, 1, 247, 100, 101, 5, 247, 2, 59, 111, 9020, 9022, 1, 247, 110, 116, 105, 109, 101, 115, 59, 1, 8903, 110, 120, 59, 1, 8903, 99, 121, 59, 1, 1106, 99, 4, 2, 111, 114, 9048, 9053, 114, 110, 59, 1, 8990, 111, 112, 59, 1, 8973, 4, 5, 108, 112, 116, 117, 119, 9070, 9076, 9081, 9130, 9144, 108, 97, 114, 59, 1, 36, 102, 59, 3, 55349, 56661, 4, 5, 59, 101, 109, 112, 115, 9093, 9095, 9109, 9116, 9122, 1, 729, 113, 4, 2, 59, 100, 9102, 9104, 1, 8784, 111, 116, 59, 1, 8785, 105, 110, 117, 115, 59, 1, 8760, 108, 117, 115, 59, 1, 8724, 113, 117, 97, 114, 101, 59, 1, 8865, 98, 108, 101, 98, 97, 114, 119, 101, 100, 103, 101, 59, 1, 8966, 110, 4, 3, 97, 100, 104, 9153, 9160, 9172, 114, 114, 111, 119, 59, 1, 8595, 111, 119, 110, 97, 114, 114, 111, 119, 115, 59, 1, 8650, 97, 114, 112, 111, 111, 110, 4, 2, 108, 114, 9184, 9190, 101, 102, 116, 59, 1, 8643, 105, 103, 104, 116, 59, 1, 8642, 4, 2, 98, 99, 9203, 9211, 107, 97, 114, 111, 119, 59, 1, 10512, 4, 2, 111, 114, 9217, 9222, 114, 110, 59, 1, 8991, 111, 112, 59, 1, 8972, 4, 3, 99, 111, 116, 9235, 9248, 9252, 4, 2, 114, 121, 9241, 9245, 59, 3, 55349, 56505, 59, 1, 1109, 108, 59, 1, 10742, 114, 111, 107, 59, 1, 273, 4, 2, 100, 114, 9264, 9269, 111, 116, 59, 1, 8945, 105, 4, 2, 59, 102, 9276, 9278, 1, 9663, 59, 1, 9662, 4, 2, 97, 104, 9287, 9292, 114, 114, 59, 1, 8693, 97, 114, 59, 1, 10607, 97, 110, 103, 108, 101, 59, 1, 10662, 4, 2, 99, 105, 9311, 9315, 121, 59, 1, 1119, 103, 114, 97, 114, 114, 59, 1, 10239, 4, 18, 68, 97, 99, 100, 101, 102, 103, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 120, 9361, 9376, 9398, 9439, 9444, 9447, 9462, 9495, 9531, 9585, 9598, 9614, 9659, 9755, 9771, 9792, 9808, 9826, 4, 2, 68, 111, 9367, 9372, 111, 116, 59, 1, 10871, 116, 59, 1, 8785, 4, 2, 99, 115, 9382, 9392, 117, 116, 101, 5, 233, 1, 59, 9390, 1, 233, 116, 101, 114, 59, 1, 10862, 4, 4, 97, 105, 111, 121, 9408, 9414, 9430, 9436, 114, 111, 110, 59, 1, 283, 114, 4, 2, 59, 99, 9421, 9423, 1, 8790, 5, 234, 1, 59, 9428, 1, 234, 108, 111, 110, 59, 1, 8789, 59, 1, 1101, 111, 116, 59, 1, 279, 59, 1, 8519, 4, 2, 68, 114, 9453, 9458, 111, 116, 59, 1, 8786, 59, 3, 55349, 56610, 4, 3, 59, 114, 115, 9470, 9472, 9482, 1, 10906, 97, 118, 101, 5, 232, 1, 59, 9480, 1, 232, 4, 2, 59, 100, 9488, 9490, 1, 10902, 111, 116, 59, 1, 10904, 4, 4, 59, 105, 108, 115, 9505, 9507, 9515, 9518, 1, 10905, 110, 116, 101, 114, 115, 59, 1, 9191, 59, 1, 8467, 4, 2, 59, 100, 9524, 9526, 1, 10901, 111, 116, 59, 1, 10903, 4, 3, 97, 112, 115, 9539, 9544, 9564, 99, 114, 59, 1, 275, 116, 121, 4, 3, 59, 115, 118, 9554, 9556, 9561, 1, 8709, 101, 116, 59, 1, 8709, 59, 1, 8709, 112, 4, 2, 49, 59, 9571, 9583, 4, 2, 51, 52, 9577, 9580, 59, 1, 8196, 59, 1, 8197, 1, 8195, 4, 2, 103, 115, 9591, 9594, 59, 1, 331, 112, 59, 1, 8194, 4, 2, 103, 112, 9604, 9609, 111, 110, 59, 1, 281, 102, 59, 3, 55349, 56662, 4, 3, 97, 108, 115, 9622, 9635, 9640, 114, 4, 2, 59, 115, 9629, 9631, 1, 8917, 108, 59, 1, 10723, 117, 115, 59, 1, 10865, 105, 4, 3, 59, 108, 118, 9649, 9651, 9656, 1, 949, 111, 110, 59, 1, 949, 59, 1, 1013, 4, 4, 99, 115, 117, 118, 9669, 9686, 9716, 9747, 4, 2, 105, 111, 9675, 9680, 114, 99, 59, 1, 8790, 108, 111, 110, 59, 1, 8789, 4, 2, 105, 108, 9692, 9696, 109, 59, 1, 8770, 97, 110, 116, 4, 2, 103, 108, 9705, 9710, 116, 114, 59, 1, 10902, 101, 115, 115, 59, 1, 10901, 4, 3, 97, 101, 105, 9724, 9729, 9734, 108, 115, 59, 1, 61, 115, 116, 59, 1, 8799, 118, 4, 2, 59, 68, 9741, 9743, 1, 8801, 68, 59, 1, 10872, 112, 97, 114, 115, 108, 59, 1, 10725, 4, 2, 68, 97, 9761, 9766, 111, 116, 59, 1, 8787, 114, 114, 59, 1, 10609, 4, 3, 99, 100, 105, 9779, 9783, 9788, 114, 59, 1, 8495, 111, 116, 59, 1, 8784, 109, 59, 1, 8770, 4, 2, 97, 104, 9798, 9801, 59, 1, 951, 5, 240, 1, 59, 9806, 1, 240, 4, 2, 109, 114, 9814, 9822, 108, 5, 235, 1, 59, 9820, 1, 235, 111, 59, 1, 8364, 4, 3, 99, 105, 112, 9834, 9838, 9843, 108, 59, 1, 33, 115, 116, 59, 1, 8707, 4, 2, 101, 111, 9849, 9859, 99, 116, 97, 116, 105, 111, 110, 59, 1, 8496, 110, 101, 110, 116, 105, 97, 108, 101, 59, 1, 8519, 4, 12, 97, 99, 101, 102, 105, 106, 108, 110, 111, 112, 114, 115, 9896, 9910, 9914, 9921, 9954, 9960, 9967, 9989, 9994, 10027, 10036, 10164, 108, 108, 105, 110, 103, 100, 111, 116, 115, 101, 113, 59, 1, 8786, 121, 59, 1, 1092, 109, 97, 108, 101, 59, 1, 9792, 4, 3, 105, 108, 114, 9929, 9935, 9950, 108, 105, 103, 59, 1, 64259, 4, 2, 105, 108, 9941, 9945, 103, 59, 1, 64256, 105, 103, 59, 1, 64260, 59, 3, 55349, 56611, 108, 105, 103, 59, 1, 64257, 108, 105, 103, 59, 3, 102, 106, 4, 3, 97, 108, 116, 9975, 9979, 9984, 116, 59, 1, 9837, 105, 103, 59, 1, 64258, 110, 115, 59, 1, 9649, 111, 102, 59, 1, 402, 4, 2, 112, 114, 10000, 10005, 102, 59, 3, 55349, 56663, 4, 2, 97, 107, 10011, 10016, 108, 108, 59, 1, 8704, 4, 2, 59, 118, 10022, 10024, 1, 8916, 59, 1, 10969, 97, 114, 116, 105, 110, 116, 59, 1, 10765, 4, 2, 97, 111, 10042, 10159, 4, 2, 99, 115, 10048, 10155, 4, 6, 49, 50, 51, 52, 53, 55, 10062, 10102, 10114, 10135, 10139, 10151, 4, 6, 50, 51, 52, 53, 54, 56, 10076, 10083, 10086, 10093, 10096, 10099, 5, 189, 1, 59, 10081, 1, 189, 59, 1, 8531, 5, 188, 1, 59, 10091, 1, 188, 59, 1, 8533, 59, 1, 8537, 59, 1, 8539, 4, 2, 51, 53, 10108, 10111, 59, 1, 8532, 59, 1, 8534, 4, 3, 52, 53, 56, 10122, 10129, 10132, 5, 190, 1, 59, 10127, 1, 190, 59, 1, 8535, 59, 1, 8540, 53, 59, 1, 8536, 4, 2, 54, 56, 10145, 10148, 59, 1, 8538, 59, 1, 8541, 56, 59, 1, 8542, 108, 59, 1, 8260, 119, 110, 59, 1, 8994, 99, 114, 59, 3, 55349, 56507, 4, 17, 69, 97, 98, 99, 100, 101, 102, 103, 105, 106, 108, 110, 111, 114, 115, 116, 118, 10206, 10217, 10247, 10254, 10268, 10273, 10358, 10363, 10374, 10380, 10385, 10406, 10458, 10464, 10470, 10497, 10610, 4, 2, 59, 108, 10212, 10214, 1, 8807, 59, 1, 10892, 4, 3, 99, 109, 112, 10225, 10231, 10244, 117, 116, 101, 59, 1, 501, 109, 97, 4, 2, 59, 100, 10239, 10241, 1, 947, 59, 1, 989, 59, 1, 10886, 114, 101, 118, 101, 59, 1, 287, 4, 2, 105, 121, 10260, 10265, 114, 99, 59, 1, 285, 59, 1, 1075, 111, 116, 59, 1, 289, 4, 4, 59, 108, 113, 115, 10283, 10285, 10288, 10308, 1, 8805, 59, 1, 8923, 4, 3, 59, 113, 115, 10296, 10298, 10301, 1, 8805, 59, 1, 8807, 108, 97, 110, 116, 59, 1, 10878, 4, 4, 59, 99, 100, 108, 10318, 10320, 10324, 10345, 1, 10878, 99, 59, 1, 10921, 111, 116, 4, 2, 59, 111, 10332, 10334, 1, 10880, 4, 2, 59, 108, 10340, 10342, 1, 10882, 59, 1, 10884, 4, 2, 59, 101, 10351, 10354, 3, 8923, 65024, 115, 59, 1, 10900, 114, 59, 3, 55349, 56612, 4, 2, 59, 103, 10369, 10371, 1, 8811, 59, 1, 8921, 109, 101, 108, 59, 1, 8503, 99, 121, 59, 1, 1107, 4, 4, 59, 69, 97, 106, 10395, 10397, 10400, 10403, 1, 8823, 59, 1, 10898, 59, 1, 10917, 59, 1, 10916, 4, 4, 69, 97, 101, 115, 10416, 10419, 10434, 10453, 59, 1, 8809, 112, 4, 2, 59, 112, 10426, 10428, 1, 10890, 114, 111, 120, 59, 1, 10890, 4, 2, 59, 113, 10440, 10442, 1, 10888, 4, 2, 59, 113, 10448, 10450, 1, 10888, 59, 1, 8809, 105, 109, 59, 1, 8935, 112, 102, 59, 3, 55349, 56664, 97, 118, 101, 59, 1, 96, 4, 2, 99, 105, 10476, 10480, 114, 59, 1, 8458, 109, 4, 3, 59, 101, 108, 10489, 10491, 10494, 1, 8819, 59, 1, 10894, 59, 1, 10896, 5, 62, 6, 59, 99, 100, 108, 113, 114, 10512, 10514, 10527, 10532, 10538, 10545, 1, 62, 4, 2, 99, 105, 10520, 10523, 59, 1, 10919, 114, 59, 1, 10874, 111, 116, 59, 1, 8919, 80, 97, 114, 59, 1, 10645, 117, 101, 115, 116, 59, 1, 10876, 4, 5, 97, 100, 101, 108, 115, 10557, 10574, 10579, 10599, 10605, 4, 2, 112, 114, 10563, 10570, 112, 114, 111, 120, 59, 1, 10886, 114, 59, 1, 10616, 111, 116, 59, 1, 8919, 113, 4, 2, 108, 113, 10586, 10592, 101, 115, 115, 59, 1, 8923, 108, 101, 115, 115, 59, 1, 10892, 101, 115, 115, 59, 1, 8823, 105, 109, 59, 1, 8819, 4, 2, 101, 110, 10616, 10626, 114, 116, 110, 101, 113, 113, 59, 3, 8809, 65024, 69, 59, 3, 8809, 65024, 4, 10, 65, 97, 98, 99, 101, 102, 107, 111, 115, 121, 10653, 10658, 10713, 10718, 10724, 10760, 10765, 10786, 10850, 10875, 114, 114, 59, 1, 8660, 4, 4, 105, 108, 109, 114, 10668, 10674, 10678, 10684, 114, 115, 112, 59, 1, 8202, 102, 59, 1, 189, 105, 108, 116, 59, 1, 8459, 4, 2, 100, 114, 10690, 10695, 99, 121, 59, 1, 1098, 4, 3, 59, 99, 119, 10703, 10705, 10710, 1, 8596, 105, 114, 59, 1, 10568, 59, 1, 8621, 97, 114, 59, 1, 8463, 105, 114, 99, 59, 1, 293, 4, 3, 97, 108, 114, 10732, 10748, 10754, 114, 116, 115, 4, 2, 59, 117, 10741, 10743, 1, 9829, 105, 116, 59, 1, 9829, 108, 105, 112, 59, 1, 8230, 99, 111, 110, 59, 1, 8889, 114, 59, 3, 55349, 56613, 115, 4, 2, 101, 119, 10772, 10779, 97, 114, 111, 119, 59, 1, 10533, 97, 114, 111, 119, 59, 1, 10534, 4, 5, 97, 109, 111, 112, 114, 10798, 10803, 10809, 10839, 10844, 114, 114, 59, 1, 8703, 116, 104, 116, 59, 1, 8763, 107, 4, 2, 108, 114, 10816, 10827, 101, 102, 116, 97, 114, 114, 111, 119, 59, 1, 8617, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 8618, 102, 59, 3, 55349, 56665, 98, 97, 114, 59, 1, 8213, 4, 3, 99, 108, 116, 10858, 10863, 10869, 114, 59, 3, 55349, 56509, 97, 115, 104, 59, 1, 8463, 114, 111, 107, 59, 1, 295, 4, 2, 98, 112, 10881, 10887, 117, 108, 108, 59, 1, 8259, 104, 101, 110, 59, 1, 8208, 4, 15, 97, 99, 101, 102, 103, 105, 106, 109, 110, 111, 112, 113, 115, 116, 117, 10925, 10936, 10958, 10977, 10990, 11001, 11039, 11045, 11101, 11192, 11220, 11226, 11237, 11285, 11299, 99, 117, 116, 101, 5, 237, 1, 59, 10934, 1, 237, 4, 3, 59, 105, 121, 10944, 10946, 10955, 1, 8291, 114, 99, 5, 238, 1, 59, 10953, 1, 238, 59, 1, 1080, 4, 2, 99, 120, 10964, 10968, 121, 59, 1, 1077, 99, 108, 5, 161, 1, 59, 10975, 1, 161, 4, 2, 102, 114, 10983, 10986, 59, 1, 8660, 59, 3, 55349, 56614, 114, 97, 118, 101, 5, 236, 1, 59, 10999, 1, 236, 4, 4, 59, 105, 110, 111, 11011, 11013, 11028, 11034, 1, 8520, 4, 2, 105, 110, 11019, 11024, 110, 116, 59, 1, 10764, 116, 59, 1, 8749, 102, 105, 110, 59, 1, 10716, 116, 97, 59, 1, 8489, 108, 105, 103, 59, 1, 307, 4, 3, 97, 111, 112, 11053, 11092, 11096, 4, 3, 99, 103, 116, 11061, 11065, 11088, 114, 59, 1, 299, 4, 3, 101, 108, 112, 11073, 11076, 11082, 59, 1, 8465, 105, 110, 101, 59, 1, 8464, 97, 114, 116, 59, 1, 8465, 104, 59, 1, 305, 102, 59, 1, 8887, 101, 100, 59, 1, 437, 4, 5, 59, 99, 102, 111, 116, 11113, 11115, 11121, 11136, 11142, 1, 8712, 97, 114, 101, 59, 1, 8453, 105, 110, 4, 2, 59, 116, 11129, 11131, 1, 8734, 105, 101, 59, 1, 10717, 100, 111, 116, 59, 1, 305, 4, 5, 59, 99, 101, 108, 112, 11154, 11156, 11161, 11179, 11186, 1, 8747, 97, 108, 59, 1, 8890, 4, 2, 103, 114, 11167, 11173, 101, 114, 115, 59, 1, 8484, 99, 97, 108, 59, 1, 8890, 97, 114, 104, 107, 59, 1, 10775, 114, 111, 100, 59, 1, 10812, 4, 4, 99, 103, 112, 116, 11202, 11206, 11211, 11216, 121, 59, 1, 1105, 111, 110, 59, 1, 303, 102, 59, 3, 55349, 56666, 97, 59, 1, 953, 114, 111, 100, 59, 1, 10812, 117, 101, 115, 116, 5, 191, 1, 59, 11235, 1, 191, 4, 2, 99, 105, 11243, 11248, 114, 59, 3, 55349, 56510, 110, 4, 5, 59, 69, 100, 115, 118, 11261, 11263, 11266, 11271, 11282, 1, 8712, 59, 1, 8953, 111, 116, 59, 1, 8949, 4, 2, 59, 118, 11277, 11279, 1, 8948, 59, 1, 8947, 59, 1, 8712, 4, 2, 59, 105, 11291, 11293, 1, 8290, 108, 100, 101, 59, 1, 297, 4, 2, 107, 109, 11305, 11310, 99, 121, 59, 1, 1110, 108, 5, 239, 1, 59, 11316, 1, 239, 4, 6, 99, 102, 109, 111, 115, 117, 11332, 11346, 11351, 11357, 11363, 11380, 4, 2, 105, 121, 11338, 11343, 114, 99, 59, 1, 309, 59, 1, 1081, 114, 59, 3, 55349, 56615, 97, 116, 104, 59, 1, 567, 112, 102, 59, 3, 55349, 56667, 4, 2, 99, 101, 11369, 11374, 114, 59, 3, 55349, 56511, 114, 99, 121, 59, 1, 1112, 107, 99, 121, 59, 1, 1108, 4, 8, 97, 99, 102, 103, 104, 106, 111, 115, 11404, 11418, 11433, 11438, 11445, 11450, 11455, 11461, 112, 112, 97, 4, 2, 59, 118, 11413, 11415, 1, 954, 59, 1, 1008, 4, 2, 101, 121, 11424, 11430, 100, 105, 108, 59, 1, 311, 59, 1, 1082, 114, 59, 3, 55349, 56616, 114, 101, 101, 110, 59, 1, 312, 99, 121, 59, 1, 1093, 99, 121, 59, 1, 1116, 112, 102, 59, 3, 55349, 56668, 99, 114, 59, 3, 55349, 56512, 4, 23, 65, 66, 69, 72, 97, 98, 99, 100, 101, 102, 103, 104, 106, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 11515, 11538, 11544, 11555, 11560, 11721, 11780, 11818, 11868, 12136, 12160, 12171, 12203, 12208, 12246, 12275, 12327, 12509, 12523, 12569, 12641, 12732, 12752, 4, 3, 97, 114, 116, 11523, 11528, 11532, 114, 114, 59, 1, 8666, 114, 59, 1, 8656, 97, 105, 108, 59, 1, 10523, 97, 114, 114, 59, 1, 10510, 4, 2, 59, 103, 11550, 11552, 1, 8806, 59, 1, 10891, 97, 114, 59, 1, 10594, 4, 9, 99, 101, 103, 109, 110, 112, 113, 114, 116, 11580, 11586, 11594, 11600, 11606, 11624, 11627, 11636, 11694, 117, 116, 101, 59, 1, 314, 109, 112, 116, 121, 118, 59, 1, 10676, 114, 97, 110, 59, 1, 8466, 98, 100, 97, 59, 1, 955, 103, 4, 3, 59, 100, 108, 11615, 11617, 11620, 1, 10216, 59, 1, 10641, 101, 59, 1, 10216, 59, 1, 10885, 117, 111, 5, 171, 1, 59, 11634, 1, 171, 114, 4, 8, 59, 98, 102, 104, 108, 112, 115, 116, 11655, 11657, 11669, 11673, 11677, 11681, 11685, 11690, 1, 8592, 4, 2, 59, 102, 11663, 11665, 1, 8676, 115, 59, 1, 10527, 115, 59, 1, 10525, 107, 59, 1, 8617, 112, 59, 1, 8619, 108, 59, 1, 10553, 105, 109, 59, 1, 10611, 108, 59, 1, 8610, 4, 3, 59, 97, 101, 11702, 11704, 11709, 1, 10923, 105, 108, 59, 1, 10521, 4, 2, 59, 115, 11715, 11717, 1, 10925, 59, 3, 10925, 65024, 4, 3, 97, 98, 114, 11729, 11734, 11739, 114, 114, 59, 1, 10508, 114, 107, 59, 1, 10098, 4, 2, 97, 107, 11745, 11758, 99, 4, 2, 101, 107, 11752, 11755, 59, 1, 123, 59, 1, 91, 4, 2, 101, 115, 11764, 11767, 59, 1, 10635, 108, 4, 2, 100, 117, 11774, 11777, 59, 1, 10639, 59, 1, 10637, 4, 4, 97, 101, 117, 121, 11790, 11796, 11811, 11815, 114, 111, 110, 59, 1, 318, 4, 2, 100, 105, 11802, 11807, 105, 108, 59, 1, 316, 108, 59, 1, 8968, 98, 59, 1, 123, 59, 1, 1083, 4, 4, 99, 113, 114, 115, 11828, 11832, 11845, 11864, 97, 59, 1, 10550, 117, 111, 4, 2, 59, 114, 11840, 11842, 1, 8220, 59, 1, 8222, 4, 2, 100, 117, 11851, 11857, 104, 97, 114, 59, 1, 10599, 115, 104, 97, 114, 59, 1, 10571, 104, 59, 1, 8626, 4, 5, 59, 102, 103, 113, 115, 11880, 11882, 12008, 12011, 12031, 1, 8804, 116, 4, 5, 97, 104, 108, 114, 116, 11895, 11913, 11935, 11947, 11996, 114, 114, 111, 119, 4, 2, 59, 116, 11905, 11907, 1, 8592, 97, 105, 108, 59, 1, 8610, 97, 114, 112, 111, 111, 110, 4, 2, 100, 117, 11925, 11931, 111, 119, 110, 59, 1, 8637, 112, 59, 1, 8636, 101, 102, 116, 97, 114, 114, 111, 119, 115, 59, 1, 8647, 105, 103, 104, 116, 4, 3, 97, 104, 115, 11959, 11974, 11984, 114, 114, 111, 119, 4, 2, 59, 115, 11969, 11971, 1, 8596, 59, 1, 8646, 97, 114, 112, 111, 111, 110, 115, 59, 1, 8651, 113, 117, 105, 103, 97, 114, 114, 111, 119, 59, 1, 8621, 104, 114, 101, 101, 116, 105, 109, 101, 115, 59, 1, 8907, 59, 1, 8922, 4, 3, 59, 113, 115, 12019, 12021, 12024, 1, 8804, 59, 1, 8806, 108, 97, 110, 116, 59, 1, 10877, 4, 5, 59, 99, 100, 103, 115, 12043, 12045, 12049, 12070, 12083, 1, 10877, 99, 59, 1, 10920, 111, 116, 4, 2, 59, 111, 12057, 12059, 1, 10879, 4, 2, 59, 114, 12065, 12067, 1, 10881, 59, 1, 10883, 4, 2, 59, 101, 12076, 12079, 3, 8922, 65024, 115, 59, 1, 10899, 4, 5, 97, 100, 101, 103, 115, 12095, 12103, 12108, 12126, 12131, 112, 112, 114, 111, 120, 59, 1, 10885, 111, 116, 59, 1, 8918, 113, 4, 2, 103, 113, 12115, 12120, 116, 114, 59, 1, 8922, 103, 116, 114, 59, 1, 10891, 116, 114, 59, 1, 8822, 105, 109, 59, 1, 8818, 4, 3, 105, 108, 114, 12144, 12150, 12156, 115, 104, 116, 59, 1, 10620, 111, 111, 114, 59, 1, 8970, 59, 3, 55349, 56617, 4, 2, 59, 69, 12166, 12168, 1, 8822, 59, 1, 10897, 4, 2, 97, 98, 12177, 12198, 114, 4, 2, 100, 117, 12184, 12187, 59, 1, 8637, 4, 2, 59, 108, 12193, 12195, 1, 8636, 59, 1, 10602, 108, 107, 59, 1, 9604, 99, 121, 59, 1, 1113, 4, 5, 59, 97, 99, 104, 116, 12220, 12222, 12227, 12235, 12241, 1, 8810, 114, 114, 59, 1, 8647, 111, 114, 110, 101, 114, 59, 1, 8990, 97, 114, 100, 59, 1, 10603, 114, 105, 59, 1, 9722, 4, 2, 105, 111, 12252, 12258, 100, 111, 116, 59, 1, 320, 117, 115, 116, 4, 2, 59, 97, 12267, 12269, 1, 9136, 99, 104, 101, 59, 1, 9136, 4, 4, 69, 97, 101, 115, 12285, 12288, 12303, 12322, 59, 1, 8808, 112, 4, 2, 59, 112, 12295, 12297, 1, 10889, 114, 111, 120, 59, 1, 10889, 4, 2, 59, 113, 12309, 12311, 1, 10887, 4, 2, 59, 113, 12317, 12319, 1, 10887, 59, 1, 8808, 105, 109, 59, 1, 8934, 4, 8, 97, 98, 110, 111, 112, 116, 119, 122, 12345, 12359, 12364, 12421, 12446, 12467, 12474, 12490, 4, 2, 110, 114, 12351, 12355, 103, 59, 1, 10220, 114, 59, 1, 8701, 114, 107, 59, 1, 10214, 103, 4, 3, 108, 109, 114, 12373, 12401, 12409, 101, 102, 116, 4, 2, 97, 114, 12382, 12389, 114, 114, 111, 119, 59, 1, 10229, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 10231, 97, 112, 115, 116, 111, 59, 1, 10236, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 10230, 112, 97, 114, 114, 111, 119, 4, 2, 108, 114, 12433, 12439, 101, 102, 116, 59, 1, 8619, 105, 103, 104, 116, 59, 1, 8620, 4, 3, 97, 102, 108, 12454, 12458, 12462, 114, 59, 1, 10629, 59, 3, 55349, 56669, 117, 115, 59, 1, 10797, 105, 109, 101, 115, 59, 1, 10804, 4, 2, 97, 98, 12480, 12485, 115, 116, 59, 1, 8727, 97, 114, 59, 1, 95, 4, 3, 59, 101, 102, 12498, 12500, 12506, 1, 9674, 110, 103, 101, 59, 1, 9674, 59, 1, 10731, 97, 114, 4, 2, 59, 108, 12517, 12519, 1, 40, 116, 59, 1, 10643, 4, 5, 97, 99, 104, 109, 116, 12535, 12540, 12548, 12561, 12564, 114, 114, 59, 1, 8646, 111, 114, 110, 101, 114, 59, 1, 8991, 97, 114, 4, 2, 59, 100, 12556, 12558, 1, 8651, 59, 1, 10605, 59, 1, 8206, 114, 105, 59, 1, 8895, 4, 6, 97, 99, 104, 105, 113, 116, 12583, 12589, 12594, 12597, 12614, 12635, 113, 117, 111, 59, 1, 8249, 114, 59, 3, 55349, 56513, 59, 1, 8624, 109, 4, 3, 59, 101, 103, 12606, 12608, 12611, 1, 8818, 59, 1, 10893, 59, 1, 10895, 4, 2, 98, 117, 12620, 12623, 59, 1, 91, 111, 4, 2, 59, 114, 12630, 12632, 1, 8216, 59, 1, 8218, 114, 111, 107, 59, 1, 322, 5, 60, 8, 59, 99, 100, 104, 105, 108, 113, 114, 12660, 12662, 12675, 12680, 12686, 12692, 12698, 12705, 1, 60, 4, 2, 99, 105, 12668, 12671, 59, 1, 10918, 114, 59, 1, 10873, 111, 116, 59, 1, 8918, 114, 101, 101, 59, 1, 8907, 109, 101, 115, 59, 1, 8905, 97, 114, 114, 59, 1, 10614, 117, 101, 115, 116, 59, 1, 10875, 4, 2, 80, 105, 12711, 12716, 97, 114, 59, 1, 10646, 4, 3, 59, 101, 102, 12724, 12726, 12729, 1, 9667, 59, 1, 8884, 59, 1, 9666, 114, 4, 2, 100, 117, 12739, 12746, 115, 104, 97, 114, 59, 1, 10570, 104, 97, 114, 59, 1, 10598, 4, 2, 101, 110, 12758, 12768, 114, 116, 110, 101, 113, 113, 59, 3, 8808, 65024, 69, 59, 3, 8808, 65024, 4, 14, 68, 97, 99, 100, 101, 102, 104, 105, 108, 110, 111, 112, 115, 117, 12803, 12809, 12893, 12908, 12914, 12928, 12933, 12937, 13011, 13025, 13032, 13049, 13052, 13069, 68, 111, 116, 59, 1, 8762, 4, 4, 99, 108, 112, 114, 12819, 12827, 12849, 12887, 114, 5, 175, 1, 59, 12825, 1, 175, 4, 2, 101, 116, 12833, 12836, 59, 1, 9794, 4, 2, 59, 101, 12842, 12844, 1, 10016, 115, 101, 59, 1, 10016, 4, 2, 59, 115, 12855, 12857, 1, 8614, 116, 111, 4, 4, 59, 100, 108, 117, 12869, 12871, 12877, 12883, 1, 8614, 111, 119, 110, 59, 1, 8615, 101, 102, 116, 59, 1, 8612, 112, 59, 1, 8613, 107, 101, 114, 59, 1, 9646, 4, 2, 111, 121, 12899, 12905, 109, 109, 97, 59, 1, 10793, 59, 1, 1084, 97, 115, 104, 59, 1, 8212, 97, 115, 117, 114, 101, 100, 97, 110, 103, 108, 101, 59, 1, 8737, 114, 59, 3, 55349, 56618, 111, 59, 1, 8487, 4, 3, 99, 100, 110, 12945, 12954, 12985, 114, 111, 5, 181, 1, 59, 12952, 1, 181, 4, 4, 59, 97, 99, 100, 12964, 12966, 12971, 12976, 1, 8739, 115, 116, 59, 1, 42, 105, 114, 59, 1, 10992, 111, 116, 5, 183, 1, 59, 12983, 1, 183, 117, 115, 4, 3, 59, 98, 100, 12995, 12997, 13000, 1, 8722, 59, 1, 8863, 4, 2, 59, 117, 13006, 13008, 1, 8760, 59, 1, 10794, 4, 2, 99, 100, 13017, 13021, 112, 59, 1, 10971, 114, 59, 1, 8230, 112, 108, 117, 115, 59, 1, 8723, 4, 2, 100, 112, 13038, 13044, 101, 108, 115, 59, 1, 8871, 102, 59, 3, 55349, 56670, 59, 1, 8723, 4, 2, 99, 116, 13058, 13063, 114, 59, 3, 55349, 56514, 112, 111, 115, 59, 1, 8766, 4, 3, 59, 108, 109, 13077, 13079, 13087, 1, 956, 116, 105, 109, 97, 112, 59, 1, 8888, 97, 112, 59, 1, 8888, 4, 24, 71, 76, 82, 86, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 108, 109, 111, 112, 114, 115, 116, 117, 118, 119, 13142, 13165, 13217, 13229, 13247, 13330, 13359, 13414, 13420, 13508, 13513, 13579, 13602, 13626, 13631, 13762, 13767, 13855, 13936, 13995, 14214, 14285, 14312, 14432, 4, 2, 103, 116, 13148, 13152, 59, 3, 8921, 824, 4, 2, 59, 118, 13158, 13161, 3, 8811, 8402, 59, 3, 8811, 824, 4, 3, 101, 108, 116, 13173, 13200, 13204, 102, 116, 4, 2, 97, 114, 13181, 13188, 114, 114, 111, 119, 59, 1, 8653, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 8654, 59, 3, 8920, 824, 4, 2, 59, 118, 13210, 13213, 3, 8810, 8402, 59, 3, 8810, 824, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 8655, 4, 2, 68, 100, 13235, 13241, 97, 115, 104, 59, 1, 8879, 97, 115, 104, 59, 1, 8878, 4, 5, 98, 99, 110, 112, 116, 13259, 13264, 13270, 13275, 13308, 108, 97, 59, 1, 8711, 117, 116, 101, 59, 1, 324, 103, 59, 3, 8736, 8402, 4, 5, 59, 69, 105, 111, 112, 13287, 13289, 13293, 13298, 13302, 1, 8777, 59, 3, 10864, 824, 100, 59, 3, 8779, 824, 115, 59, 1, 329, 114, 111, 120, 59, 1, 8777, 117, 114, 4, 2, 59, 97, 13316, 13318, 1, 9838, 108, 4, 2, 59, 115, 13325, 13327, 1, 9838, 59, 1, 8469, 4, 2, 115, 117, 13336, 13344, 112, 5, 160, 1, 59, 13342, 1, 160, 109, 112, 4, 2, 59, 101, 13352, 13355, 3, 8782, 824, 59, 3, 8783, 824, 4, 5, 97, 101, 111, 117, 121, 13371, 13385, 13391, 13407, 13411, 4, 2, 112, 114, 13377, 13380, 59, 1, 10819, 111, 110, 59, 1, 328, 100, 105, 108, 59, 1, 326, 110, 103, 4, 2, 59, 100, 13399, 13401, 1, 8775, 111, 116, 59, 3, 10861, 824, 112, 59, 1, 10818, 59, 1, 1085, 97, 115, 104, 59, 1, 8211, 4, 7, 59, 65, 97, 100, 113, 115, 120, 13436, 13438, 13443, 13466, 13472, 13478, 13494, 1, 8800, 114, 114, 59, 1, 8663, 114, 4, 2, 104, 114, 13450, 13454, 107, 59, 1, 10532, 4, 2, 59, 111, 13460, 13462, 1, 8599, 119, 59, 1, 8599, 111, 116, 59, 3, 8784, 824, 117, 105, 118, 59, 1, 8802, 4, 2, 101, 105, 13484, 13489, 97, 114, 59, 1, 10536, 109, 59, 3, 8770, 824, 105, 115, 116, 4, 2, 59, 115, 13503, 13505, 1, 8708, 59, 1, 8708, 114, 59, 3, 55349, 56619, 4, 4, 69, 101, 115, 116, 13523, 13527, 13563, 13568, 59, 3, 8807, 824, 4, 3, 59, 113, 115, 13535, 13537, 13559, 1, 8817, 4, 3, 59, 113, 115, 13545, 13547, 13551, 1, 8817, 59, 3, 8807, 824, 108, 97, 110, 116, 59, 3, 10878, 824, 59, 3, 10878, 824, 105, 109, 59, 1, 8821, 4, 2, 59, 114, 13574, 13576, 1, 8815, 59, 1, 8815, 4, 3, 65, 97, 112, 13587, 13592, 13597, 114, 114, 59, 1, 8654, 114, 114, 59, 1, 8622, 97, 114, 59, 1, 10994, 4, 3, 59, 115, 118, 13610, 13612, 13623, 1, 8715, 4, 2, 59, 100, 13618, 13620, 1, 8956, 59, 1, 8954, 59, 1, 8715, 99, 121, 59, 1, 1114, 4, 7, 65, 69, 97, 100, 101, 115, 116, 13647, 13652, 13656, 13661, 13665, 13737, 13742, 114, 114, 59, 1, 8653, 59, 3, 8806, 824, 114, 114, 59, 1, 8602, 114, 59, 1, 8229, 4, 4, 59, 102, 113, 115, 13675, 13677, 13703, 13725, 1, 8816, 116, 4, 2, 97, 114, 13684, 13691, 114, 114, 111, 119, 59, 1, 8602, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 8622, 4, 3, 59, 113, 115, 13711, 13713, 13717, 1, 8816, 59, 3, 8806, 824, 108, 97, 110, 116, 59, 3, 10877, 824, 4, 2, 59, 115, 13731, 13734, 3, 10877, 824, 59, 1, 8814, 105, 109, 59, 1, 8820, 4, 2, 59, 114, 13748, 13750, 1, 8814, 105, 4, 2, 59, 101, 13757, 13759, 1, 8938, 59, 1, 8940, 105, 100, 59, 1, 8740, 4, 2, 112, 116, 13773, 13778, 102, 59, 3, 55349, 56671, 5, 172, 3, 59, 105, 110, 13787, 13789, 13829, 1, 172, 110, 4, 4, 59, 69, 100, 118, 13800, 13802, 13806, 13812, 1, 8713, 59, 3, 8953, 824, 111, 116, 59, 3, 8949, 824, 4, 3, 97, 98, 99, 13820, 13823, 13826, 59, 1, 8713, 59, 1, 8951, 59, 1, 8950, 105, 4, 2, 59, 118, 13836, 13838, 1, 8716, 4, 3, 97, 98, 99, 13846, 13849, 13852, 59, 1, 8716, 59, 1, 8958, 59, 1, 8957, 4, 3, 97, 111, 114, 13863, 13892, 13899, 114, 4, 4, 59, 97, 115, 116, 13874, 13876, 13883, 13888, 1, 8742, 108, 108, 101, 108, 59, 1, 8742, 108, 59, 3, 11005, 8421, 59, 3, 8706, 824, 108, 105, 110, 116, 59, 1, 10772, 4, 3, 59, 99, 101, 13907, 13909, 13914, 1, 8832, 117, 101, 59, 1, 8928, 4, 2, 59, 99, 13920, 13923, 3, 10927, 824, 4, 2, 59, 101, 13929, 13931, 1, 8832, 113, 59, 3, 10927, 824, 4, 4, 65, 97, 105, 116, 13946, 13951, 13971, 13982, 114, 114, 59, 1, 8655, 114, 114, 4, 3, 59, 99, 119, 13961, 13963, 13967, 1, 8603, 59, 3, 10547, 824, 59, 3, 8605, 824, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 8603, 114, 105, 4, 2, 59, 101, 13990, 13992, 1, 8939, 59, 1, 8941, 4, 7, 99, 104, 105, 109, 112, 113, 117, 14011, 14036, 14060, 14080, 14085, 14090, 14106, 4, 4, 59, 99, 101, 114, 14021, 14023, 14028, 14032, 1, 8833, 117, 101, 59, 1, 8929, 59, 3, 10928, 824, 59, 3, 55349, 56515, 111, 114, 116, 4, 2, 109, 112, 14045, 14050, 105, 100, 59, 1, 8740, 97, 114, 97, 108, 108, 101, 108, 59, 1, 8742, 109, 4, 2, 59, 101, 14067, 14069, 1, 8769, 4, 2, 59, 113, 14075, 14077, 1, 8772, 59, 1, 8772, 105, 100, 59, 1, 8740, 97, 114, 59, 1, 8742, 115, 117, 4, 2, 98, 112, 14098, 14102, 101, 59, 1, 8930, 101, 59, 1, 8931, 4, 3, 98, 99, 112, 14114, 14157, 14171, 4, 4, 59, 69, 101, 115, 14124, 14126, 14130, 14133, 1, 8836, 59, 3, 10949, 824, 59, 1, 8840, 101, 116, 4, 2, 59, 101, 14141, 14144, 3, 8834, 8402, 113, 4, 2, 59, 113, 14151, 14153, 1, 8840, 59, 3, 10949, 824, 99, 4, 2, 59, 101, 14164, 14166, 1, 8833, 113, 59, 3, 10928, 824, 4, 4, 59, 69, 101, 115, 14181, 14183, 14187, 14190, 1, 8837, 59, 3, 10950, 824, 59, 1, 8841, 101, 116, 4, 2, 59, 101, 14198, 14201, 3, 8835, 8402, 113, 4, 2, 59, 113, 14208, 14210, 1, 8841, 59, 3, 10950, 824, 4, 4, 103, 105, 108, 114, 14224, 14228, 14238, 14242, 108, 59, 1, 8825, 108, 100, 101, 5, 241, 1, 59, 14236, 1, 241, 103, 59, 1, 8824, 105, 97, 110, 103, 108, 101, 4, 2, 108, 114, 14254, 14269, 101, 102, 116, 4, 2, 59, 101, 14263, 14265, 1, 8938, 113, 59, 1, 8940, 105, 103, 104, 116, 4, 2, 59, 101, 14279, 14281, 1, 8939, 113, 59, 1, 8941, 4, 2, 59, 109, 14291, 14293, 1, 957, 4, 3, 59, 101, 115, 14301, 14303, 14308, 1, 35, 114, 111, 59, 1, 8470, 112, 59, 1, 8199, 4, 9, 68, 72, 97, 100, 103, 105, 108, 114, 115, 14332, 14338, 14344, 14349, 14355, 14369, 14376, 14408, 14426, 97, 115, 104, 59, 1, 8877, 97, 114, 114, 59, 1, 10500, 112, 59, 3, 8781, 8402, 97, 115, 104, 59, 1, 8876, 4, 2, 101, 116, 14361, 14365, 59, 3, 8805, 8402, 59, 3, 62, 8402, 110, 102, 105, 110, 59, 1, 10718, 4, 3, 65, 101, 116, 14384, 14389, 14393, 114, 114, 59, 1, 10498, 59, 3, 8804, 8402, 4, 2, 59, 114, 14399, 14402, 3, 60, 8402, 105, 101, 59, 3, 8884, 8402, 4, 2, 65, 116, 14414, 14419, 114, 114, 59, 1, 10499, 114, 105, 101, 59, 3, 8885, 8402, 105, 109, 59, 3, 8764, 8402, 4, 3, 65, 97, 110, 14440, 14445, 14468, 114, 114, 59, 1, 8662, 114, 4, 2, 104, 114, 14452, 14456, 107, 59, 1, 10531, 4, 2, 59, 111, 14462, 14464, 1, 8598, 119, 59, 1, 8598, 101, 97, 114, 59, 1, 10535, 4, 18, 83, 97, 99, 100, 101, 102, 103, 104, 105, 108, 109, 111, 112, 114, 115, 116, 117, 118, 14512, 14515, 14535, 14560, 14597, 14603, 14618, 14643, 14657, 14662, 14701, 14741, 14747, 14769, 14851, 14877, 14907, 14916, 59, 1, 9416, 4, 2, 99, 115, 14521, 14531, 117, 116, 101, 5, 243, 1, 59, 14529, 1, 243, 116, 59, 1, 8859, 4, 2, 105, 121, 14541, 14557, 114, 4, 2, 59, 99, 14548, 14550, 1, 8858, 5, 244, 1, 59, 14555, 1, 244, 59, 1, 1086, 4, 5, 97, 98, 105, 111, 115, 14572, 14577, 14583, 14587, 14591, 115, 104, 59, 1, 8861, 108, 97, 99, 59, 1, 337, 118, 59, 1, 10808, 116, 59, 1, 8857, 111, 108, 100, 59, 1, 10684, 108, 105, 103, 59, 1, 339, 4, 2, 99, 114, 14609, 14614, 105, 114, 59, 1, 10687, 59, 3, 55349, 56620, 4, 3, 111, 114, 116, 14626, 14630, 14640, 110, 59, 1, 731, 97, 118, 101, 5, 242, 1, 59, 14638, 1, 242, 59, 1, 10689, 4, 2, 98, 109, 14649, 14654, 97, 114, 59, 1, 10677, 59, 1, 937, 110, 116, 59, 1, 8750, 4, 4, 97, 99, 105, 116, 14672, 14677, 14693, 14698, 114, 114, 59, 1, 8634, 4, 2, 105, 114, 14683, 14687, 114, 59, 1, 10686, 111, 115, 115, 59, 1, 10683, 110, 101, 59, 1, 8254, 59, 1, 10688, 4, 3, 97, 101, 105, 14709, 14714, 14719, 99, 114, 59, 1, 333, 103, 97, 59, 1, 969, 4, 3, 99, 100, 110, 14727, 14733, 14736, 114, 111, 110, 59, 1, 959, 59, 1, 10678, 117, 115, 59, 1, 8854, 112, 102, 59, 3, 55349, 56672, 4, 3, 97, 101, 108, 14755, 14759, 14764, 114, 59, 1, 10679, 114, 112, 59, 1, 10681, 117, 115, 59, 1, 8853, 4, 7, 59, 97, 100, 105, 111, 115, 118, 14785, 14787, 14792, 14831, 14837, 14841, 14848, 1, 8744, 114, 114, 59, 1, 8635, 4, 4, 59, 101, 102, 109, 14802, 14804, 14817, 14824, 1, 10845, 114, 4, 2, 59, 111, 14811, 14813, 1, 8500, 102, 59, 1, 8500, 5, 170, 1, 59, 14822, 1, 170, 5, 186, 1, 59, 14829, 1, 186, 103, 111, 102, 59, 1, 8886, 114, 59, 1, 10838, 108, 111, 112, 101, 59, 1, 10839, 59, 1, 10843, 4, 3, 99, 108, 111, 14859, 14863, 14873, 114, 59, 1, 8500, 97, 115, 104, 5, 248, 1, 59, 14871, 1, 248, 108, 59, 1, 8856, 105, 4, 2, 108, 109, 14884, 14893, 100, 101, 5, 245, 1, 59, 14891, 1, 245, 101, 115, 4, 2, 59, 97, 14901, 14903, 1, 8855, 115, 59, 1, 10806, 109, 108, 5, 246, 1, 59, 14914, 1, 246, 98, 97, 114, 59, 1, 9021, 4, 12, 97, 99, 101, 102, 104, 105, 108, 109, 111, 114, 115, 117, 14948, 14992, 14996, 15033, 15038, 15068, 15090, 15189, 15192, 15222, 15427, 15441, 114, 4, 4, 59, 97, 115, 116, 14959, 14961, 14976, 14989, 1, 8741, 5, 182, 2, 59, 108, 14968, 14970, 1, 182, 108, 101, 108, 59, 1, 8741, 4, 2, 105, 108, 14982, 14986, 109, 59, 1, 10995, 59, 1, 11005, 59, 1, 8706, 121, 59, 1, 1087, 114, 4, 5, 99, 105, 109, 112, 116, 15009, 15014, 15019, 15024, 15027, 110, 116, 59, 1, 37, 111, 100, 59, 1, 46, 105, 108, 59, 1, 8240, 59, 1, 8869, 101, 110, 107, 59, 1, 8241, 114, 59, 3, 55349, 56621, 4, 3, 105, 109, 111, 15046, 15057, 15063, 4, 2, 59, 118, 15052, 15054, 1, 966, 59, 1, 981, 109, 97, 116, 59, 1, 8499, 110, 101, 59, 1, 9742, 4, 3, 59, 116, 118, 15076, 15078, 15087, 1, 960, 99, 104, 102, 111, 114, 107, 59, 1, 8916, 59, 1, 982, 4, 2, 97, 117, 15096, 15119, 110, 4, 2, 99, 107, 15103, 15115, 107, 4, 2, 59, 104, 15110, 15112, 1, 8463, 59, 1, 8462, 118, 59, 1, 8463, 115, 4, 9, 59, 97, 98, 99, 100, 101, 109, 115, 116, 15140, 15142, 15148, 15151, 15156, 15168, 15171, 15179, 15184, 1, 43, 99, 105, 114, 59, 1, 10787, 59, 1, 8862, 105, 114, 59, 1, 10786, 4, 2, 111, 117, 15162, 15165, 59, 1, 8724, 59, 1, 10789, 59, 1, 10866, 110, 5, 177, 1, 59, 15177, 1, 177, 105, 109, 59, 1, 10790, 119, 111, 59, 1, 10791, 59, 1, 177, 4, 3, 105, 112, 117, 15200, 15208, 15213, 110, 116, 105, 110, 116, 59, 1, 10773, 102, 59, 3, 55349, 56673, 110, 100, 5, 163, 1, 59, 15220, 1, 163, 4, 10, 59, 69, 97, 99, 101, 105, 110, 111, 115, 117, 15244, 15246, 15249, 15253, 15258, 15334, 15347, 15367, 15416, 15421, 1, 8826, 59, 1, 10931, 112, 59, 1, 10935, 117, 101, 59, 1, 8828, 4, 2, 59, 99, 15264, 15266, 1, 10927, 4, 6, 59, 97, 99, 101, 110, 115, 15280, 15282, 15290, 15299, 15303, 15329, 1, 8826, 112, 112, 114, 111, 120, 59, 1, 10935, 117, 114, 108, 121, 101, 113, 59, 1, 8828, 113, 59, 1, 10927, 4, 3, 97, 101, 115, 15311, 15319, 15324, 112, 112, 114, 111, 120, 59, 1, 10937, 113, 113, 59, 1, 10933, 105, 109, 59, 1, 8936, 105, 109, 59, 1, 8830, 109, 101, 4, 2, 59, 115, 15342, 15344, 1, 8242, 59, 1, 8473, 4, 3, 69, 97, 115, 15355, 15358, 15362, 59, 1, 10933, 112, 59, 1, 10937, 105, 109, 59, 1, 8936, 4, 3, 100, 102, 112, 15375, 15378, 15404, 59, 1, 8719, 4, 3, 97, 108, 115, 15386, 15392, 15398, 108, 97, 114, 59, 1, 9006, 105, 110, 101, 59, 1, 8978, 117, 114, 102, 59, 1, 8979, 4, 2, 59, 116, 15410, 15412, 1, 8733, 111, 59, 1, 8733, 105, 109, 59, 1, 8830, 114, 101, 108, 59, 1, 8880, 4, 2, 99, 105, 15433, 15438, 114, 59, 3, 55349, 56517, 59, 1, 968, 110, 99, 115, 112, 59, 1, 8200, 4, 6, 102, 105, 111, 112, 115, 117, 15462, 15467, 15472, 15478, 15485, 15491, 114, 59, 3, 55349, 56622, 110, 116, 59, 1, 10764, 112, 102, 59, 3, 55349, 56674, 114, 105, 109, 101, 59, 1, 8279, 99, 114, 59, 3, 55349, 56518, 4, 3, 97, 101, 111, 15499, 15520, 15534, 116, 4, 2, 101, 105, 15506, 15515, 114, 110, 105, 111, 110, 115, 59, 1, 8461, 110, 116, 59, 1, 10774, 115, 116, 4, 2, 59, 101, 15528, 15530, 1, 63, 113, 59, 1, 8799, 116, 5, 34, 1, 59, 15540, 1, 34, 4, 21, 65, 66, 72, 97, 98, 99, 100, 101, 102, 104, 105, 108, 109, 110, 111, 112, 114, 115, 116, 117, 120, 15586, 15609, 15615, 15620, 15796, 15855, 15893, 15931, 15977, 16001, 16039, 16183, 16204, 16222, 16228, 16285, 16312, 16318, 16363, 16408, 16416, 4, 3, 97, 114, 116, 15594, 15599, 15603, 114, 114, 59, 1, 8667, 114, 59, 1, 8658, 97, 105, 108, 59, 1, 10524, 97, 114, 114, 59, 1, 10511, 97, 114, 59, 1, 10596, 4, 7, 99, 100, 101, 110, 113, 114, 116, 15636, 15651, 15656, 15664, 15687, 15696, 15770, 4, 2, 101, 117, 15642, 15646, 59, 3, 8765, 817, 116, 101, 59, 1, 341, 105, 99, 59, 1, 8730, 109, 112, 116, 121, 118, 59, 1, 10675, 103, 4, 4, 59, 100, 101, 108, 15675, 15677, 15680, 15683, 1, 10217, 59, 1, 10642, 59, 1, 10661, 101, 59, 1, 10217, 117, 111, 5, 187, 1, 59, 15694, 1, 187, 114, 4, 11, 59, 97, 98, 99, 102, 104, 108, 112, 115, 116, 119, 15721, 15723, 15727, 15739, 15742, 15746, 15750, 15754, 15758, 15763, 15767, 1, 8594, 112, 59, 1, 10613, 4, 2, 59, 102, 15733, 15735, 1, 8677, 115, 59, 1, 10528, 59, 1, 10547, 115, 59, 1, 10526, 107, 59, 1, 8618, 112, 59, 1, 8620, 108, 59, 1, 10565, 105, 109, 59, 1, 10612, 108, 59, 1, 8611, 59, 1, 8605, 4, 2, 97, 105, 15776, 15781, 105, 108, 59, 1, 10522, 111, 4, 2, 59, 110, 15788, 15790, 1, 8758, 97, 108, 115, 59, 1, 8474, 4, 3, 97, 98, 114, 15804, 15809, 15814, 114, 114, 59, 1, 10509, 114, 107, 59, 1, 10099, 4, 2, 97, 107, 15820, 15833, 99, 4, 2, 101, 107, 15827, 15830, 59, 1, 125, 59, 1, 93, 4, 2, 101, 115, 15839, 15842, 59, 1, 10636, 108, 4, 2, 100, 117, 15849, 15852, 59, 1, 10638, 59, 1, 10640, 4, 4, 97, 101, 117, 121, 15865, 15871, 15886, 15890, 114, 111, 110, 59, 1, 345, 4, 2, 100, 105, 15877, 15882, 105, 108, 59, 1, 343, 108, 59, 1, 8969, 98, 59, 1, 125, 59, 1, 1088, 4, 4, 99, 108, 113, 115, 15903, 15907, 15914, 15927, 97, 59, 1, 10551, 100, 104, 97, 114, 59, 1, 10601, 117, 111, 4, 2, 59, 114, 15922, 15924, 1, 8221, 59, 1, 8221, 104, 59, 1, 8627, 4, 3, 97, 99, 103, 15939, 15966, 15970, 108, 4, 4, 59, 105, 112, 115, 15950, 15952, 15957, 15963, 1, 8476, 110, 101, 59, 1, 8475, 97, 114, 116, 59, 1, 8476, 59, 1, 8477, 116, 59, 1, 9645, 5, 174, 1, 59, 15975, 1, 174, 4, 3, 105, 108, 114, 15985, 15991, 15997, 115, 104, 116, 59, 1, 10621, 111, 111, 114, 59, 1, 8971, 59, 3, 55349, 56623, 4, 2, 97, 111, 16007, 16028, 114, 4, 2, 100, 117, 16014, 16017, 59, 1, 8641, 4, 2, 59, 108, 16023, 16025, 1, 8640, 59, 1, 10604, 4, 2, 59, 118, 16034, 16036, 1, 961, 59, 1, 1009, 4, 3, 103, 110, 115, 16047, 16167, 16171, 104, 116, 4, 6, 97, 104, 108, 114, 115, 116, 16063, 16081, 16103, 16130, 16143, 16155, 114, 114, 111, 119, 4, 2, 59, 116, 16073, 16075, 1, 8594, 97, 105, 108, 59, 1, 8611, 97, 114, 112, 111, 111, 110, 4, 2, 100, 117, 16093, 16099, 111, 119, 110, 59, 1, 8641, 112, 59, 1, 8640, 101, 102, 116, 4, 2, 97, 104, 16112, 16120, 114, 114, 111, 119, 115, 59, 1, 8644, 97, 114, 112, 111, 111, 110, 115, 59, 1, 8652, 105, 103, 104, 116, 97, 114, 114, 111, 119, 115, 59, 1, 8649, 113, 117, 105, 103, 97, 114, 114, 111, 119, 59, 1, 8605, 104, 114, 101, 101, 116, 105, 109, 101, 115, 59, 1, 8908, 103, 59, 1, 730, 105, 110, 103, 100, 111, 116, 115, 101, 113, 59, 1, 8787, 4, 3, 97, 104, 109, 16191, 16196, 16201, 114, 114, 59, 1, 8644, 97, 114, 59, 1, 8652, 59, 1, 8207, 111, 117, 115, 116, 4, 2, 59, 97, 16214, 16216, 1, 9137, 99, 104, 101, 59, 1, 9137, 109, 105, 100, 59, 1, 10990, 4, 4, 97, 98, 112, 116, 16238, 16252, 16257, 16278, 4, 2, 110, 114, 16244, 16248, 103, 59, 1, 10221, 114, 59, 1, 8702, 114, 107, 59, 1, 10215, 4, 3, 97, 102, 108, 16265, 16269, 16273, 114, 59, 1, 10630, 59, 3, 55349, 56675, 117, 115, 59, 1, 10798, 105, 109, 101, 115, 59, 1, 10805, 4, 2, 97, 112, 16291, 16304, 114, 4, 2, 59, 103, 16298, 16300, 1, 41, 116, 59, 1, 10644, 111, 108, 105, 110, 116, 59, 1, 10770, 97, 114, 114, 59, 1, 8649, 4, 4, 97, 99, 104, 113, 16328, 16334, 16339, 16342, 113, 117, 111, 59, 1, 8250, 114, 59, 3, 55349, 56519, 59, 1, 8625, 4, 2, 98, 117, 16348, 16351, 59, 1, 93, 111, 4, 2, 59, 114, 16358, 16360, 1, 8217, 59, 1, 8217, 4, 3, 104, 105, 114, 16371, 16377, 16383, 114, 101, 101, 59, 1, 8908, 109, 101, 115, 59, 1, 8906, 105, 4, 4, 59, 101, 102, 108, 16394, 16396, 16399, 16402, 1, 9657, 59, 1, 8885, 59, 1, 9656, 116, 114, 105, 59, 1, 10702, 108, 117, 104, 97, 114, 59, 1, 10600, 59, 1, 8478, 4, 19, 97, 98, 99, 100, 101, 102, 104, 105, 108, 109, 111, 112, 113, 114, 115, 116, 117, 119, 122, 16459, 16466, 16472, 16572, 16590, 16672, 16687, 16746, 16844, 16850, 16924, 16963, 16988, 17115, 17121, 17154, 17206, 17614, 17656, 99, 117, 116, 101, 59, 1, 347, 113, 117, 111, 59, 1, 8218, 4, 10, 59, 69, 97, 99, 101, 105, 110, 112, 115, 121, 16494, 16496, 16499, 16513, 16518, 16531, 16536, 16556, 16564, 16569, 1, 8827, 59, 1, 10932, 4, 2, 112, 114, 16505, 16508, 59, 1, 10936, 111, 110, 59, 1, 353, 117, 101, 59, 1, 8829, 4, 2, 59, 100, 16524, 16526, 1, 10928, 105, 108, 59, 1, 351, 114, 99, 59, 1, 349, 4, 3, 69, 97, 115, 16544, 16547, 16551, 59, 1, 10934, 112, 59, 1, 10938, 105, 109, 59, 1, 8937, 111, 108, 105, 110, 116, 59, 1, 10771, 105, 109, 59, 1, 8831, 59, 1, 1089, 111, 116, 4, 3, 59, 98, 101, 16582, 16584, 16587, 1, 8901, 59, 1, 8865, 59, 1, 10854, 4, 7, 65, 97, 99, 109, 115, 116, 120, 16606, 16611, 16634, 16642, 16646, 16652, 16668, 114, 114, 59, 1, 8664, 114, 4, 2, 104, 114, 16618, 16622, 107, 59, 1, 10533, 4, 2, 59, 111, 16628, 16630, 1, 8600, 119, 59, 1, 8600, 116, 5, 167, 1, 59, 16640, 1, 167, 105, 59, 1, 59, 119, 97, 114, 59, 1, 10537, 109, 4, 2, 105, 110, 16659, 16665, 110, 117, 115, 59, 1, 8726, 59, 1, 8726, 116, 59, 1, 10038, 114, 4, 2, 59, 111, 16679, 16682, 3, 55349, 56624, 119, 110, 59, 1, 8994, 4, 4, 97, 99, 111, 121, 16697, 16702, 16716, 16739, 114, 112, 59, 1, 9839, 4, 2, 104, 121, 16708, 16713, 99, 121, 59, 1, 1097, 59, 1, 1096, 114, 116, 4, 2, 109, 112, 16724, 16729, 105, 100, 59, 1, 8739, 97, 114, 97, 108, 108, 101, 108, 59, 1, 8741, 5, 173, 1, 59, 16744, 1, 173, 4, 2, 103, 109, 16752, 16770, 109, 97, 4, 3, 59, 102, 118, 16762, 16764, 16767, 1, 963, 59, 1, 962, 59, 1, 962, 4, 8, 59, 100, 101, 103, 108, 110, 112, 114, 16788, 16790, 16795, 16806, 16817, 16828, 16832, 16838, 1, 8764, 111, 116, 59, 1, 10858, 4, 2, 59, 113, 16801, 16803, 1, 8771, 59, 1, 8771, 4, 2, 59, 69, 16812, 16814, 1, 10910, 59, 1, 10912, 4, 2, 59, 69, 16823, 16825, 1, 10909, 59, 1, 10911, 101, 59, 1, 8774, 108, 117, 115, 59, 1, 10788, 97, 114, 114, 59, 1, 10610, 97, 114, 114, 59, 1, 8592, 4, 4, 97, 101, 105, 116, 16860, 16883, 16891, 16904, 4, 2, 108, 115, 16866, 16878, 108, 115, 101, 116, 109, 105, 110, 117, 115, 59, 1, 8726, 104, 112, 59, 1, 10803, 112, 97, 114, 115, 108, 59, 1, 10724, 4, 2, 100, 108, 16897, 16900, 59, 1, 8739, 101, 59, 1, 8995, 4, 2, 59, 101, 16910, 16912, 1, 10922, 4, 2, 59, 115, 16918, 16920, 1, 10924, 59, 3, 10924, 65024, 4, 3, 102, 108, 112, 16932, 16938, 16958, 116, 99, 121, 59, 1, 1100, 4, 2, 59, 98, 16944, 16946, 1, 47, 4, 2, 59, 97, 16952, 16954, 1, 10692, 114, 59, 1, 9023, 102, 59, 3, 55349, 56676, 97, 4, 2, 100, 114, 16970, 16985, 101, 115, 4, 2, 59, 117, 16978, 16980, 1, 9824, 105, 116, 59, 1, 9824, 59, 1, 8741, 4, 3, 99, 115, 117, 16996, 17028, 17089, 4, 2, 97, 117, 17002, 17015, 112, 4, 2, 59, 115, 17009, 17011, 1, 8851, 59, 3, 8851, 65024, 112, 4, 2, 59, 115, 17022, 17024, 1, 8852, 59, 3, 8852, 65024, 117, 4, 2, 98, 112, 17035, 17062, 4, 3, 59, 101, 115, 17043, 17045, 17048, 1, 8847, 59, 1, 8849, 101, 116, 4, 2, 59, 101, 17056, 17058, 1, 8847, 113, 59, 1, 8849, 4, 3, 59, 101, 115, 17070, 17072, 17075, 1, 8848, 59, 1, 8850, 101, 116, 4, 2, 59, 101, 17083, 17085, 1, 8848, 113, 59, 1, 8850, 4, 3, 59, 97, 102, 17097, 17099, 17112, 1, 9633, 114, 4, 2, 101, 102, 17106, 17109, 59, 1, 9633, 59, 1, 9642, 59, 1, 9642, 97, 114, 114, 59, 1, 8594, 4, 4, 99, 101, 109, 116, 17131, 17136, 17142, 17148, 114, 59, 3, 55349, 56520, 116, 109, 110, 59, 1, 8726, 105, 108, 101, 59, 1, 8995, 97, 114, 102, 59, 1, 8902, 4, 2, 97, 114, 17160, 17172, 114, 4, 2, 59, 102, 17167, 17169, 1, 9734, 59, 1, 9733, 4, 2, 97, 110, 17178, 17202, 105, 103, 104, 116, 4, 2, 101, 112, 17188, 17197, 112, 115, 105, 108, 111, 110, 59, 1, 1013, 104, 105, 59, 1, 981, 115, 59, 1, 175, 4, 5, 98, 99, 109, 110, 112, 17218, 17351, 17420, 17423, 17427, 4, 9, 59, 69, 100, 101, 109, 110, 112, 114, 115, 17238, 17240, 17243, 17248, 17261, 17267, 17279, 17285, 17291, 1, 8834, 59, 1, 10949, 111, 116, 59, 1, 10941, 4, 2, 59, 100, 17254, 17256, 1, 8838, 111, 116, 59, 1, 10947, 117, 108, 116, 59, 1, 10945, 4, 2, 69, 101, 17273, 17276, 59, 1, 10955, 59, 1, 8842, 108, 117, 115, 59, 1, 10943, 97, 114, 114, 59, 1, 10617, 4, 3, 101, 105, 117, 17299, 17335, 17339, 116, 4, 3, 59, 101, 110, 17308, 17310, 17322, 1, 8834, 113, 4, 2, 59, 113, 17317, 17319, 1, 8838, 59, 1, 10949, 101, 113, 4, 2, 59, 113, 17330, 17332, 1, 8842, 59, 1, 10955, 109, 59, 1, 10951, 4, 2, 98, 112, 17345, 17348, 59, 1, 10965, 59, 1, 10963, 99, 4, 6, 59, 97, 99, 101, 110, 115, 17366, 17368, 17376, 17385, 17389, 17415, 1, 8827, 112, 112, 114, 111, 120, 59, 1, 10936, 117, 114, 108, 121, 101, 113, 59, 1, 8829, 113, 59, 1, 10928, 4, 3, 97, 101, 115, 17397, 17405, 17410, 112, 112, 114, 111, 120, 59, 1, 10938, 113, 113, 59, 1, 10934, 105, 109, 59, 1, 8937, 105, 109, 59, 1, 8831, 59, 1, 8721, 103, 59, 1, 9834, 4, 13, 49, 50, 51, 59, 69, 100, 101, 104, 108, 109, 110, 112, 115, 17455, 17462, 17469, 17476, 17478, 17481, 17496, 17509, 17524, 17530, 17536, 17548, 17554, 5, 185, 1, 59, 17460, 1, 185, 5, 178, 1, 59, 17467, 1, 178, 5, 179, 1, 59, 17474, 1, 179, 1, 8835, 59, 1, 10950, 4, 2, 111, 115, 17487, 17491, 116, 59, 1, 10942, 117, 98, 59, 1, 10968, 4, 2, 59, 100, 17502, 17504, 1, 8839, 111, 116, 59, 1, 10948, 115, 4, 2, 111, 117, 17516, 17520, 108, 59, 1, 10185, 98, 59, 1, 10967, 97, 114, 114, 59, 1, 10619, 117, 108, 116, 59, 1, 10946, 4, 2, 69, 101, 17542, 17545, 59, 1, 10956, 59, 1, 8843, 108, 117, 115, 59, 1, 10944, 4, 3, 101, 105, 117, 17562, 17598, 17602, 116, 4, 3, 59, 101, 110, 17571, 17573, 17585, 1, 8835, 113, 4, 2, 59, 113, 17580, 17582, 1, 8839, 59, 1, 10950, 101, 113, 4, 2, 59, 113, 17593, 17595, 1, 8843, 59, 1, 10956, 109, 59, 1, 10952, 4, 2, 98, 112, 17608, 17611, 59, 1, 10964, 59, 1, 10966, 4, 3, 65, 97, 110, 17622, 17627, 17650, 114, 114, 59, 1, 8665, 114, 4, 2, 104, 114, 17634, 17638, 107, 59, 1, 10534, 4, 2, 59, 111, 17644, 17646, 1, 8601, 119, 59, 1, 8601, 119, 97, 114, 59, 1, 10538, 108, 105, 103, 5, 223, 1, 59, 17664, 1, 223, 4, 13, 97, 98, 99, 100, 101, 102, 104, 105, 111, 112, 114, 115, 119, 17694, 17709, 17714, 17737, 17742, 17749, 17754, 17860, 17905, 17957, 17964, 18090, 18122, 4, 2, 114, 117, 17700, 17706, 103, 101, 116, 59, 1, 8982, 59, 1, 964, 114, 107, 59, 1, 9140, 4, 3, 97, 101, 121, 17722, 17728, 17734, 114, 111, 110, 59, 1, 357, 100, 105, 108, 59, 1, 355, 59, 1, 1090, 111, 116, 59, 1, 8411, 108, 114, 101, 99, 59, 1, 8981, 114, 59, 3, 55349, 56625, 4, 4, 101, 105, 107, 111, 17764, 17805, 17836, 17851, 4, 2, 114, 116, 17770, 17786, 101, 4, 2, 52, 102, 17777, 17780, 59, 1, 8756, 111, 114, 101, 59, 1, 8756, 97, 4, 3, 59, 115, 118, 17795, 17797, 17802, 1, 952, 121, 109, 59, 1, 977, 59, 1, 977, 4, 2, 99, 110, 17811, 17831, 107, 4, 2, 97, 115, 17818, 17826, 112, 112, 114, 111, 120, 59, 1, 8776, 105, 109, 59, 1, 8764, 115, 112, 59, 1, 8201, 4, 2, 97, 115, 17842, 17846, 112, 59, 1, 8776, 105, 109, 59, 1, 8764, 114, 110, 5, 254, 1, 59, 17858, 1, 254, 4, 3, 108, 109, 110, 17868, 17873, 17901, 100, 101, 59, 1, 732, 101, 115, 5, 215, 3, 59, 98, 100, 17884, 17886, 17898, 1, 215, 4, 2, 59, 97, 17892, 17894, 1, 8864, 114, 59, 1, 10801, 59, 1, 10800, 116, 59, 1, 8749, 4, 3, 101, 112, 115, 17913, 17917, 17953, 97, 59, 1, 10536, 4, 4, 59, 98, 99, 102, 17927, 17929, 17934, 17939, 1, 8868, 111, 116, 59, 1, 9014, 105, 114, 59, 1, 10993, 4, 2, 59, 111, 17945, 17948, 3, 55349, 56677, 114, 107, 59, 1, 10970, 97, 59, 1, 10537, 114, 105, 109, 101, 59, 1, 8244, 4, 3, 97, 105, 112, 17972, 17977, 18082, 100, 101, 59, 1, 8482, 4, 7, 97, 100, 101, 109, 112, 115, 116, 17993, 18051, 18056, 18059, 18066, 18072, 18076, 110, 103, 108, 101, 4, 5, 59, 100, 108, 113, 114, 18009, 18011, 18017, 18032, 18035, 1, 9653, 111, 119, 110, 59, 1, 9663, 101, 102, 116, 4, 2, 59, 101, 18026, 18028, 1, 9667, 113, 59, 1, 8884, 59, 1, 8796, 105, 103, 104, 116, 4, 2, 59, 101, 18045, 18047, 1, 9657, 113, 59, 1, 8885, 111, 116, 59, 1, 9708, 59, 1, 8796, 105, 110, 117, 115, 59, 1, 10810, 108, 117, 115, 59, 1, 10809, 98, 59, 1, 10701, 105, 109, 101, 59, 1, 10811, 101, 122, 105, 117, 109, 59, 1, 9186, 4, 3, 99, 104, 116, 18098, 18111, 18116, 4, 2, 114, 121, 18104, 18108, 59, 3, 55349, 56521, 59, 1, 1094, 99, 121, 59, 1, 1115, 114, 111, 107, 59, 1, 359, 4, 2, 105, 111, 18128, 18133, 120, 116, 59, 1, 8812, 104, 101, 97, 100, 4, 2, 108, 114, 18143, 18154, 101, 102, 116, 97, 114, 114, 111, 119, 59, 1, 8606, 105, 103, 104, 116, 97, 114, 114, 111, 119, 59, 1, 8608, 4, 18, 65, 72, 97, 98, 99, 100, 102, 103, 104, 108, 109, 111, 112, 114, 115, 116, 117, 119, 18204, 18209, 18214, 18234, 18250, 18268, 18292, 18308, 18319, 18343, 18379, 18397, 18413, 18504, 18547, 18553, 18584, 18603, 114, 114, 59, 1, 8657, 97, 114, 59, 1, 10595, 4, 2, 99, 114, 18220, 18230, 117, 116, 101, 5, 250, 1, 59, 18228, 1, 250, 114, 59, 1, 8593, 114, 4, 2, 99, 101, 18241, 18245, 121, 59, 1, 1118, 118, 101, 59, 1, 365, 4, 2, 105, 121, 18256, 18265, 114, 99, 5, 251, 1, 59, 18263, 1, 251, 59, 1, 1091, 4, 3, 97, 98, 104, 18276, 18281, 18287, 114, 114, 59, 1, 8645, 108, 97, 99, 59, 1, 369, 97, 114, 59, 1, 10606, 4, 2, 105, 114, 18298, 18304, 115, 104, 116, 59, 1, 10622, 59, 3, 55349, 56626, 114, 97, 118, 101, 5, 249, 1, 59, 18317, 1, 249, 4, 2, 97, 98, 18325, 18338, 114, 4, 2, 108, 114, 18332, 18335, 59, 1, 8639, 59, 1, 8638, 108, 107, 59, 1, 9600, 4, 2, 99, 116, 18349, 18374, 4, 2, 111, 114, 18355, 18369, 114, 110, 4, 2, 59, 101, 18363, 18365, 1, 8988, 114, 59, 1, 8988, 111, 112, 59, 1, 8975, 114, 105, 59, 1, 9720, 4, 2, 97, 108, 18385, 18390, 99, 114, 59, 1, 363, 5, 168, 1, 59, 18395, 1, 168, 4, 2, 103, 112, 18403, 18408, 111, 110, 59, 1, 371, 102, 59, 3, 55349, 56678, 4, 6, 97, 100, 104, 108, 115, 117, 18427, 18434, 18445, 18470, 18475, 18494, 114, 114, 111, 119, 59, 1, 8593, 111, 119, 110, 97, 114, 114, 111, 119, 59, 1, 8597, 97, 114, 112, 111, 111, 110, 4, 2, 108, 114, 18457, 18463, 101, 102, 116, 59, 1, 8639, 105, 103, 104, 116, 59, 1, 8638, 117, 115, 59, 1, 8846, 105, 4, 3, 59, 104, 108, 18484, 18486, 18489, 1, 965, 59, 1, 978, 111, 110, 59, 1, 965, 112, 97, 114, 114, 111, 119, 115, 59, 1, 8648, 4, 3, 99, 105, 116, 18512, 18537, 18542, 4, 2, 111, 114, 18518, 18532, 114, 110, 4, 2, 59, 101, 18526, 18528, 1, 8989, 114, 59, 1, 8989, 111, 112, 59, 1, 8974, 110, 103, 59, 1, 367, 114, 105, 59, 1, 9721, 99, 114, 59, 3, 55349, 56522, 4, 3, 100, 105, 114, 18561, 18566, 18572, 111, 116, 59, 1, 8944, 108, 100, 101, 59, 1, 361, 105, 4, 2, 59, 102, 18579, 18581, 1, 9653, 59, 1, 9652, 4, 2, 97, 109, 18590, 18595, 114, 114, 59, 1, 8648, 108, 5, 252, 1, 59, 18601, 1, 252, 97, 110, 103, 108, 101, 59, 1, 10663, 4, 15, 65, 66, 68, 97, 99, 100, 101, 102, 108, 110, 111, 112, 114, 115, 122, 18643, 18648, 18661, 18667, 18847, 18851, 18857, 18904, 18909, 18915, 18931, 18937, 18943, 18949, 18996, 114, 114, 59, 1, 8661, 97, 114, 4, 2, 59, 118, 18656, 18658, 1, 10984, 59, 1, 10985, 97, 115, 104, 59, 1, 8872, 4, 2, 110, 114, 18673, 18679, 103, 114, 116, 59, 1, 10652, 4, 7, 101, 107, 110, 112, 114, 115, 116, 18695, 18704, 18711, 18720, 18742, 18754, 18810, 112, 115, 105, 108, 111, 110, 59, 1, 1013, 97, 112, 112, 97, 59, 1, 1008, 111, 116, 104, 105, 110, 103, 59, 1, 8709, 4, 3, 104, 105, 114, 18728, 18732, 18735, 105, 59, 1, 981, 59, 1, 982, 111, 112, 116, 111, 59, 1, 8733, 4, 2, 59, 104, 18748, 18750, 1, 8597, 111, 59, 1, 1009, 4, 2, 105, 117, 18760, 18766, 103, 109, 97, 59, 1, 962, 4, 2, 98, 112, 18772, 18791, 115, 101, 116, 110, 101, 113, 4, 2, 59, 113, 18784, 18787, 3, 8842, 65024, 59, 3, 10955, 65024, 115, 101, 116, 110, 101, 113, 4, 2, 59, 113, 18803, 18806, 3, 8843, 65024, 59, 3, 10956, 65024, 4, 2, 104, 114, 18816, 18822, 101, 116, 97, 59, 1, 977, 105, 97, 110, 103, 108, 101, 4, 2, 108, 114, 18834, 18840, 101, 102, 116, 59, 1, 8882, 105, 103, 104, 116, 59, 1, 8883, 121, 59, 1, 1074, 97, 115, 104, 59, 1, 8866, 4, 3, 101, 108, 114, 18865, 18884, 18890, 4, 3, 59, 98, 101, 18873, 18875, 18880, 1, 8744, 97, 114, 59, 1, 8891, 113, 59, 1, 8794, 108, 105, 112, 59, 1, 8942, 4, 2, 98, 116, 18896, 18901, 97, 114, 59, 1, 124, 59, 1, 124, 114, 59, 3, 55349, 56627, 116, 114, 105, 59, 1, 8882, 115, 117, 4, 2, 98, 112, 18923, 18927, 59, 3, 8834, 8402, 59, 3, 8835, 8402, 112, 102, 59, 3, 55349, 56679, 114, 111, 112, 59, 1, 8733, 116, 114, 105, 59, 1, 8883, 4, 2, 99, 117, 18955, 18960, 114, 59, 3, 55349, 56523, 4, 2, 98, 112, 18966, 18981, 110, 4, 2, 69, 101, 18973, 18977, 59, 3, 10955, 65024, 59, 3, 8842, 65024, 110, 4, 2, 69, 101, 18988, 18992, 59, 3, 10956, 65024, 59, 3, 8843, 65024, 105, 103, 122, 97, 103, 59, 1, 10650, 4, 7, 99, 101, 102, 111, 112, 114, 115, 19020, 19026, 19061, 19066, 19072, 19075, 19089, 105, 114, 99, 59, 1, 373, 4, 2, 100, 105, 19032, 19055, 4, 2, 98, 103, 19038, 19043, 97, 114, 59, 1, 10847, 101, 4, 2, 59, 113, 19050, 19052, 1, 8743, 59, 1, 8793, 101, 114, 112, 59, 1, 8472, 114, 59, 3, 55349, 56628, 112, 102, 59, 3, 55349, 56680, 59, 1, 8472, 4, 2, 59, 101, 19081, 19083, 1, 8768, 97, 116, 104, 59, 1, 8768, 99, 114, 59, 3, 55349, 56524, 4, 14, 99, 100, 102, 104, 105, 108, 109, 110, 111, 114, 115, 117, 118, 119, 19125, 19146, 19152, 19157, 19173, 19176, 19192, 19197, 19202, 19236, 19252, 19269, 19286, 19291, 4, 3, 97, 105, 117, 19133, 19137, 19142, 112, 59, 1, 8898, 114, 99, 59, 1, 9711, 112, 59, 1, 8899, 116, 114, 105, 59, 1, 9661, 114, 59, 3, 55349, 56629, 4, 2, 65, 97, 19163, 19168, 114, 114, 59, 1, 10234, 114, 114, 59, 1, 10231, 59, 1, 958, 4, 2, 65, 97, 19182, 19187, 114, 114, 59, 1, 10232, 114, 114, 59, 1, 10229, 97, 112, 59, 1, 10236, 105, 115, 59, 1, 8955, 4, 3, 100, 112, 116, 19210, 19215, 19230, 111, 116, 59, 1, 10752, 4, 2, 102, 108, 19221, 19225, 59, 3, 55349, 56681, 117, 115, 59, 1, 10753, 105, 109, 101, 59, 1, 10754, 4, 2, 65, 97, 19242, 19247, 114, 114, 59, 1, 10233, 114, 114, 59, 1, 10230, 4, 2, 99, 113, 19258, 19263, 114, 59, 3, 55349, 56525, 99, 117, 112, 59, 1, 10758, 4, 2, 112, 116, 19275, 19281, 108, 117, 115, 59, 1, 10756, 114, 105, 59, 1, 9651, 101, 101, 59, 1, 8897, 101, 100, 103, 101, 59, 1, 8896, 4, 8, 97, 99, 101, 102, 105, 111, 115, 117, 19316, 19335, 19349, 19357, 19362, 19367, 19373, 19379, 99, 4, 2, 117, 121, 19323, 19332, 116, 101, 5, 253, 1, 59, 19330, 1, 253, 59, 1, 1103, 4, 2, 105, 121, 19341, 19346, 114, 99, 59, 1, 375, 59, 1, 1099, 110, 5, 165, 1, 59, 19355, 1, 165, 114, 59, 3, 55349, 56630, 99, 121, 59, 1, 1111, 112, 102, 59, 3, 55349, 56682, 99, 114, 59, 3, 55349, 56526, 4, 2, 99, 109, 19385, 19389, 121, 59, 1, 1102, 108, 5, 255, 1, 59, 19395, 1, 255, 4, 10, 97, 99, 100, 101, 102, 104, 105, 111, 115, 119, 19419, 19426, 19441, 19446, 19462, 19467, 19472, 19480, 19486, 19492, 99, 117, 116, 101, 59, 1, 378, 4, 2, 97, 121, 19432, 19438, 114, 111, 110, 59, 1, 382, 59, 1, 1079, 111, 116, 59, 1, 380, 4, 2, 101, 116, 19452, 19458, 116, 114, 102, 59, 1, 8488, 97, 59, 1, 950, 114, 59, 3, 55349, 56631, 99, 121, 59, 1, 1078, 103, 114, 97, 114, 114, 59, 1, 8669, 112, 102, 59, 3, 55349, 56683, 99, 114, 59, 3, 55349, 56527, 4, 2, 106, 110, 19498, 19501, 59, 1, 8205, 106, 59, 1, 8204]);
2054
2055const $$1 = unicode.CODE_POINTS;
2056const $$ = unicode.CODE_POINT_SEQUENCES; //C1 Unicode control character reference replacements
2057
2058const C1_CONTROLS_REFERENCE_REPLACEMENTS = {
2059 0x80: 0x20ac,
2060 0x82: 0x201a,
2061 0x83: 0x0192,
2062 0x84: 0x201e,
2063 0x85: 0x2026,
2064 0x86: 0x2020,
2065 0x87: 0x2021,
2066 0x88: 0x02c6,
2067 0x89: 0x2030,
2068 0x8a: 0x0160,
2069 0x8b: 0x2039,
2070 0x8c: 0x0152,
2071 0x8e: 0x017d,
2072 0x91: 0x2018,
2073 0x92: 0x2019,
2074 0x93: 0x201c,
2075 0x94: 0x201d,
2076 0x95: 0x2022,
2077 0x96: 0x2013,
2078 0x97: 0x2014,
2079 0x98: 0x02dc,
2080 0x99: 0x2122,
2081 0x9a: 0x0161,
2082 0x9b: 0x203a,
2083 0x9c: 0x0153,
2084 0x9e: 0x017e,
2085 0x9f: 0x0178
2086}; // Named entity tree flags
2087
2088const HAS_DATA_FLAG = 1 << 0;
2089const DATA_DUPLET_FLAG = 1 << 1;
2090const HAS_BRANCHES_FLAG = 1 << 2;
2091const MAX_BRANCH_MARKER_VALUE = HAS_DATA_FLAG | DATA_DUPLET_FLAG | HAS_BRANCHES_FLAG; //States
2092
2093const DATA_STATE = 'DATA_STATE';
2094const RCDATA_STATE = 'RCDATA_STATE';
2095const RAWTEXT_STATE = 'RAWTEXT_STATE';
2096const SCRIPT_DATA_STATE = 'SCRIPT_DATA_STATE';
2097const PLAINTEXT_STATE = 'PLAINTEXT_STATE';
2098const TAG_OPEN_STATE = 'TAG_OPEN_STATE';
2099const END_TAG_OPEN_STATE = 'END_TAG_OPEN_STATE';
2100const TAG_NAME_STATE = 'TAG_NAME_STATE';
2101const RCDATA_LESS_THAN_SIGN_STATE = 'RCDATA_LESS_THAN_SIGN_STATE';
2102const RCDATA_END_TAG_OPEN_STATE = 'RCDATA_END_TAG_OPEN_STATE';
2103const RCDATA_END_TAG_NAME_STATE = 'RCDATA_END_TAG_NAME_STATE';
2104const RAWTEXT_LESS_THAN_SIGN_STATE = 'RAWTEXT_LESS_THAN_SIGN_STATE';
2105const RAWTEXT_END_TAG_OPEN_STATE = 'RAWTEXT_END_TAG_OPEN_STATE';
2106const RAWTEXT_END_TAG_NAME_STATE = 'RAWTEXT_END_TAG_NAME_STATE';
2107const SCRIPT_DATA_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_LESS_THAN_SIGN_STATE';
2108const SCRIPT_DATA_END_TAG_OPEN_STATE = 'SCRIPT_DATA_END_TAG_OPEN_STATE';
2109const SCRIPT_DATA_END_TAG_NAME_STATE = 'SCRIPT_DATA_END_TAG_NAME_STATE';
2110const SCRIPT_DATA_ESCAPE_START_STATE = 'SCRIPT_DATA_ESCAPE_START_STATE';
2111const SCRIPT_DATA_ESCAPE_START_DASH_STATE = 'SCRIPT_DATA_ESCAPE_START_DASH_STATE';
2112const SCRIPT_DATA_ESCAPED_STATE = 'SCRIPT_DATA_ESCAPED_STATE';
2113const SCRIPT_DATA_ESCAPED_DASH_STATE = 'SCRIPT_DATA_ESCAPED_DASH_STATE';
2114const SCRIPT_DATA_ESCAPED_DASH_DASH_STATE = 'SCRIPT_DATA_ESCAPED_DASH_DASH_STATE';
2115const SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE';
2116const SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE = 'SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE';
2117const SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE = 'SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE';
2118const SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE';
2119const SCRIPT_DATA_DOUBLE_ESCAPED_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_STATE';
2120const SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE';
2121const SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE';
2122const SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE';
2123const SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE';
2124const BEFORE_ATTRIBUTE_NAME_STATE = 'BEFORE_ATTRIBUTE_NAME_STATE';
2125const ATTRIBUTE_NAME_STATE = 'ATTRIBUTE_NAME_STATE';
2126const AFTER_ATTRIBUTE_NAME_STATE = 'AFTER_ATTRIBUTE_NAME_STATE';
2127const BEFORE_ATTRIBUTE_VALUE_STATE = 'BEFORE_ATTRIBUTE_VALUE_STATE';
2128const ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE = 'ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE';
2129const ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE = 'ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE';
2130const ATTRIBUTE_VALUE_UNQUOTED_STATE = 'ATTRIBUTE_VALUE_UNQUOTED_STATE';
2131const AFTER_ATTRIBUTE_VALUE_QUOTED_STATE = 'AFTER_ATTRIBUTE_VALUE_QUOTED_STATE';
2132const SELF_CLOSING_START_TAG_STATE = 'SELF_CLOSING_START_TAG_STATE';
2133const BOGUS_COMMENT_STATE = 'BOGUS_COMMENT_STATE';
2134const MARKUP_DECLARATION_OPEN_STATE = 'MARKUP_DECLARATION_OPEN_STATE';
2135const COMMENT_START_STATE = 'COMMENT_START_STATE';
2136const COMMENT_START_DASH_STATE = 'COMMENT_START_DASH_STATE';
2137const COMMENT_STATE = 'COMMENT_STATE';
2138const COMMENT_LESS_THAN_SIGN_STATE = 'COMMENT_LESS_THAN_SIGN_STATE';
2139const COMMENT_LESS_THAN_SIGN_BANG_STATE = 'COMMENT_LESS_THAN_SIGN_BANG_STATE';
2140const COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE = 'COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE';
2141const COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE = 'COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE';
2142const COMMENT_END_DASH_STATE = 'COMMENT_END_DASH_STATE';
2143const COMMENT_END_STATE = 'COMMENT_END_STATE';
2144const COMMENT_END_BANG_STATE = 'COMMENT_END_BANG_STATE';
2145const DOCTYPE_STATE = 'DOCTYPE_STATE';
2146const BEFORE_DOCTYPE_NAME_STATE = 'BEFORE_DOCTYPE_NAME_STATE';
2147const DOCTYPE_NAME_STATE = 'DOCTYPE_NAME_STATE';
2148const AFTER_DOCTYPE_NAME_STATE = 'AFTER_DOCTYPE_NAME_STATE';
2149const AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE = 'AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE';
2150const BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE = 'BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE';
2151const DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE = 'DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE';
2152const DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE = 'DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE';
2153const AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE = 'AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE';
2154const BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE = 'BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE';
2155const AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE = 'AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE';
2156const BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE = 'BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE';
2157const DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE = 'DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE';
2158const DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE = 'DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE';
2159const AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE = 'AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE';
2160const BOGUS_DOCTYPE_STATE = 'BOGUS_DOCTYPE_STATE';
2161const CDATA_SECTION_STATE = 'CDATA_SECTION_STATE';
2162const CDATA_SECTION_BRACKET_STATE = 'CDATA_SECTION_BRACKET_STATE';
2163const CDATA_SECTION_END_STATE = 'CDATA_SECTION_END_STATE';
2164const CHARACTER_REFERENCE_STATE = 'CHARACTER_REFERENCE_STATE';
2165const NAMED_CHARACTER_REFERENCE_STATE = 'NAMED_CHARACTER_REFERENCE_STATE';
2166const AMBIGUOUS_AMPERSAND_STATE = 'AMBIGUOS_AMPERSAND_STATE';
2167const NUMERIC_CHARACTER_REFERENCE_STATE = 'NUMERIC_CHARACTER_REFERENCE_STATE';
2168const HEXADEMICAL_CHARACTER_REFERENCE_START_STATE = 'HEXADEMICAL_CHARACTER_REFERENCE_START_STATE';
2169const DECIMAL_CHARACTER_REFERENCE_START_STATE = 'DECIMAL_CHARACTER_REFERENCE_START_STATE';
2170const HEXADEMICAL_CHARACTER_REFERENCE_STATE = 'HEXADEMICAL_CHARACTER_REFERENCE_STATE';
2171const DECIMAL_CHARACTER_REFERENCE_STATE = 'DECIMAL_CHARACTER_REFERENCE_STATE';
2172const NUMERIC_CHARACTER_REFERENCE_END_STATE = 'NUMERIC_CHARACTER_REFERENCE_END_STATE'; //Utils
2173//OPTIMIZATION: these utility functions should not be moved out of this module. V8 Crankshaft will not inline
2174//this functions if they will be situated in another module due to context switch.
2175//Always perform inlining check before modifying this functions ('node --trace-inlining').
2176
2177function isWhitespace(cp) {
2178 return cp === $$1.SPACE || cp === $$1.LINE_FEED || cp === $$1.TABULATION || cp === $$1.FORM_FEED;
2179}
2180
2181function isAsciiDigit(cp) {
2182 return cp >= $$1.DIGIT_0 && cp <= $$1.DIGIT_9;
2183}
2184
2185function isAsciiUpper(cp) {
2186 return cp >= $$1.LATIN_CAPITAL_A && cp <= $$1.LATIN_CAPITAL_Z;
2187}
2188
2189function isAsciiLower(cp) {
2190 return cp >= $$1.LATIN_SMALL_A && cp <= $$1.LATIN_SMALL_Z;
2191}
2192
2193function isAsciiLetter(cp) {
2194 return isAsciiLower(cp) || isAsciiUpper(cp);
2195}
2196
2197function isAsciiAlphaNumeric(cp) {
2198 return isAsciiLetter(cp) || isAsciiDigit(cp);
2199}
2200
2201function isAsciiUpperHexDigit(cp) {
2202 return cp >= $$1.LATIN_CAPITAL_A && cp <= $$1.LATIN_CAPITAL_F;
2203}
2204
2205function isAsciiLowerHexDigit(cp) {
2206 return cp >= $$1.LATIN_SMALL_A && cp <= $$1.LATIN_SMALL_F;
2207}
2208
2209function isAsciiHexDigit(cp) {
2210 return isAsciiDigit(cp) || isAsciiUpperHexDigit(cp) || isAsciiLowerHexDigit(cp);
2211}
2212
2213function toAsciiLowerCodePoint(cp) {
2214 return cp + 0x0020;
2215} //NOTE: String.fromCharCode() function can handle only characters from BMP subset.
2216//So, we need to workaround this manually.
2217//(see: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode#Getting_it_to_work_with_higher_values)
2218
2219
2220function toChar(cp) {
2221 if (cp <= 0xffff) {
2222 return String.fromCharCode(cp);
2223 }
2224
2225 cp -= 0x10000;
2226 return String.fromCharCode(cp >>> 10 & 0x3ff | 0xd800) + String.fromCharCode(0xdc00 | cp & 0x3ff);
2227}
2228
2229function toAsciiLowerChar(cp) {
2230 return String.fromCharCode(toAsciiLowerCodePoint(cp));
2231}
2232
2233function findNamedEntityTreeBranch(nodeIx, cp) {
2234 const branchCount = namedEntityData[++nodeIx];
2235 let lo = ++nodeIx;
2236 let hi = lo + branchCount - 1;
2237
2238 while (lo <= hi) {
2239 const mid = lo + hi >>> 1;
2240 const midCp = namedEntityData[mid];
2241
2242 if (midCp < cp) {
2243 lo = mid + 1;
2244 } else if (midCp > cp) {
2245 hi = mid - 1;
2246 } else {
2247 return namedEntityData[mid + branchCount];
2248 }
2249 }
2250
2251 return -1;
2252} //Tokenizer
2253
2254
2255class Tokenizer {
2256 constructor() {
2257 this.preprocessor = new preprocessor();
2258 this.tokenQueue = [];
2259 this.allowCDATA = false;
2260 this.state = DATA_STATE;
2261 this.returnState = '';
2262 this.charRefCode = -1;
2263 this.tempBuff = [];
2264 this.lastStartTagName = '';
2265 this.consumedAfterSnapshot = -1;
2266 this.active = false;
2267 this.currentCharacterToken = null;
2268 this.currentToken = null;
2269 this.currentAttr = null;
2270 } //Errors
2271
2272
2273 _err() {// NOTE: err reporting is noop by default. Enabled by mixin.
2274 }
2275
2276 _errOnNextCodePoint(err) {
2277 this._consume();
2278
2279 this._err(err);
2280
2281 this._unconsume();
2282 } //API
2283
2284
2285 getNextToken() {
2286 while (!this.tokenQueue.length && this.active) {
2287 this.consumedAfterSnapshot = 0;
2288
2289 const cp = this._consume();
2290
2291 if (!this._ensureHibernation()) {
2292 this[this.state](cp);
2293 }
2294 }
2295
2296 return this.tokenQueue.shift();
2297 }
2298
2299 write(chunk, isLastChunk) {
2300 this.active = true;
2301 this.preprocessor.write(chunk, isLastChunk);
2302 }
2303
2304 insertHtmlAtCurrentPos(chunk) {
2305 this.active = true;
2306 this.preprocessor.insertHtmlAtCurrentPos(chunk);
2307 } //Hibernation
2308
2309
2310 _ensureHibernation() {
2311 if (this.preprocessor.endOfChunkHit) {
2312 for (; this.consumedAfterSnapshot > 0; this.consumedAfterSnapshot--) {
2313 this.preprocessor.retreat();
2314 }
2315
2316 this.active = false;
2317 this.tokenQueue.push({
2318 type: Tokenizer.HIBERNATION_TOKEN
2319 });
2320 return true;
2321 }
2322
2323 return false;
2324 } //Consumption
2325
2326
2327 _consume() {
2328 this.consumedAfterSnapshot++;
2329 return this.preprocessor.advance();
2330 }
2331
2332 _unconsume() {
2333 this.consumedAfterSnapshot--;
2334 this.preprocessor.retreat();
2335 }
2336
2337 _reconsumeInState(state) {
2338 this.state = state;
2339
2340 this._unconsume();
2341 }
2342
2343 _consumeSequenceIfMatch(pattern, startCp, caseSensitive) {
2344 let consumedCount = 0;
2345 let isMatch = true;
2346 const patternLength = pattern.length;
2347 let patternPos = 0;
2348 let cp = startCp;
2349 let patternCp = void 0;
2350
2351 for (; patternPos < patternLength; patternPos++) {
2352 if (patternPos > 0) {
2353 cp = this._consume();
2354 consumedCount++;
2355 }
2356
2357 if (cp === $$1.EOF) {
2358 isMatch = false;
2359 break;
2360 }
2361
2362 patternCp = pattern[patternPos];
2363
2364 if (cp !== patternCp && (caseSensitive || cp !== toAsciiLowerCodePoint(patternCp))) {
2365 isMatch = false;
2366 break;
2367 }
2368 }
2369
2370 if (!isMatch) {
2371 while (consumedCount--) {
2372 this._unconsume();
2373 }
2374 }
2375
2376 return isMatch;
2377 } //Temp buffer
2378
2379
2380 _isTempBufferEqualToScriptString() {
2381 if (this.tempBuff.length !== $$.SCRIPT_STRING.length) {
2382 return false;
2383 }
2384
2385 for (let i = 0; i < this.tempBuff.length; i++) {
2386 if (this.tempBuff[i] !== $$.SCRIPT_STRING[i]) {
2387 return false;
2388 }
2389 }
2390
2391 return true;
2392 } //Token creation
2393
2394
2395 _createStartTagToken() {
2396 this.currentToken = {
2397 type: Tokenizer.START_TAG_TOKEN,
2398 tagName: '',
2399 selfClosing: false,
2400 ackSelfClosing: false,
2401 attrs: []
2402 };
2403 }
2404
2405 _createEndTagToken() {
2406 this.currentToken = {
2407 type: Tokenizer.END_TAG_TOKEN,
2408 tagName: '',
2409 selfClosing: false,
2410 attrs: []
2411 };
2412 }
2413
2414 _createCommentToken() {
2415 this.currentToken = {
2416 type: Tokenizer.COMMENT_TOKEN,
2417 data: ''
2418 };
2419 }
2420
2421 _createDoctypeToken(initialName) {
2422 this.currentToken = {
2423 type: Tokenizer.DOCTYPE_TOKEN,
2424 name: initialName,
2425 forceQuirks: false,
2426 publicId: null,
2427 systemId: null
2428 };
2429 }
2430
2431 _createCharacterToken(type, ch) {
2432 this.currentCharacterToken = {
2433 type: type,
2434 chars: ch
2435 };
2436 }
2437
2438 _createEOFToken() {
2439 this.currentToken = {
2440 type: Tokenizer.EOF_TOKEN
2441 };
2442 } //Tag attributes
2443
2444
2445 _createAttr(attrNameFirstCh) {
2446 this.currentAttr = {
2447 name: attrNameFirstCh,
2448 value: ''
2449 };
2450 }
2451
2452 _leaveAttrName(toState) {
2453 if (Tokenizer.getTokenAttr(this.currentToken, this.currentAttr.name) === null) {
2454 this.currentToken.attrs.push(this.currentAttr);
2455 } else {
2456 this._err(errorCodes.duplicateAttribute);
2457 }
2458
2459 this.state = toState;
2460 }
2461
2462 _leaveAttrValue(toState) {
2463 this.state = toState;
2464 } //Token emission
2465
2466
2467 _emitCurrentToken() {
2468 this._emitCurrentCharacterToken();
2469
2470 const ct = this.currentToken;
2471 this.currentToken = null; //NOTE: store emited start tag's tagName to determine is the following end tag token is appropriate.
2472
2473 if (ct.type === Tokenizer.START_TAG_TOKEN) {
2474 this.lastStartTagName = ct.tagName;
2475 } else if (ct.type === Tokenizer.END_TAG_TOKEN) {
2476 if (ct.attrs.length > 0) {
2477 this._err(errorCodes.endTagWithAttributes);
2478 }
2479
2480 if (ct.selfClosing) {
2481 this._err(errorCodes.endTagWithTrailingSolidus);
2482 }
2483 }
2484
2485 this.tokenQueue.push(ct);
2486 }
2487
2488 _emitCurrentCharacterToken() {
2489 if (this.currentCharacterToken) {
2490 this.tokenQueue.push(this.currentCharacterToken);
2491 this.currentCharacterToken = null;
2492 }
2493 }
2494
2495 _emitEOFToken() {
2496 this._createEOFToken();
2497
2498 this._emitCurrentToken();
2499 } //Characters emission
2500 //OPTIMIZATION: specification uses only one type of character tokens (one token per character).
2501 //This causes a huge memory overhead and a lot of unnecessary parser loops. parse5 uses 3 groups of characters.
2502 //If we have a sequence of characters that belong to the same group, parser can process it
2503 //as a single solid character token.
2504 //So, there are 3 types of character tokens in parse5:
2505 //1)NULL_CHARACTER_TOKEN - \u0000-character sequences (e.g. '\u0000\u0000\u0000')
2506 //2)WHITESPACE_CHARACTER_TOKEN - any whitespace/new-line character sequences (e.g. '\n \r\t \f')
2507 //3)CHARACTER_TOKEN - any character sequence which don't belong to groups 1 and 2 (e.g. 'abcdef1234@@#$%^')
2508
2509
2510 _appendCharToCurrentCharacterToken(type, ch) {
2511 if (this.currentCharacterToken && this.currentCharacterToken.type !== type) {
2512 this._emitCurrentCharacterToken();
2513 }
2514
2515 if (this.currentCharacterToken) {
2516 this.currentCharacterToken.chars += ch;
2517 } else {
2518 this._createCharacterToken(type, ch);
2519 }
2520 }
2521
2522 _emitCodePoint(cp) {
2523 let type = Tokenizer.CHARACTER_TOKEN;
2524
2525 if (isWhitespace(cp)) {
2526 type = Tokenizer.WHITESPACE_CHARACTER_TOKEN;
2527 } else if (cp === $$1.NULL) {
2528 type = Tokenizer.NULL_CHARACTER_TOKEN;
2529 }
2530
2531 this._appendCharToCurrentCharacterToken(type, toChar(cp));
2532 }
2533
2534 _emitSeveralCodePoints(codePoints) {
2535 for (let i = 0; i < codePoints.length; i++) {
2536 this._emitCodePoint(codePoints[i]);
2537 }
2538 } //NOTE: used then we emit character explicitly. This is always a non-whitespace and a non-null character.
2539 //So we can avoid additional checks here.
2540
2541
2542 _emitChars(ch) {
2543 this._appendCharToCurrentCharacterToken(Tokenizer.CHARACTER_TOKEN, ch);
2544 } // Character reference helpers
2545
2546
2547 _matchNamedCharacterReference(startCp) {
2548 let result = null;
2549 let excess = 1;
2550 let i = findNamedEntityTreeBranch(0, startCp);
2551 this.tempBuff.push(startCp);
2552
2553 while (i > -1) {
2554 const current = namedEntityData[i];
2555 const inNode = current < MAX_BRANCH_MARKER_VALUE;
2556 const nodeWithData = inNode && current & HAS_DATA_FLAG;
2557
2558 if (nodeWithData) {
2559 //NOTE: we use greedy search, so we continue lookup at this point
2560 result = current & DATA_DUPLET_FLAG ? [namedEntityData[++i], namedEntityData[++i]] : [namedEntityData[++i]];
2561 excess = 0;
2562 }
2563
2564 const cp = this._consume();
2565
2566 this.tempBuff.push(cp);
2567 excess++;
2568
2569 if (cp === $$1.EOF) {
2570 break;
2571 }
2572
2573 if (inNode) {
2574 i = current & HAS_BRANCHES_FLAG ? findNamedEntityTreeBranch(i, cp) : -1;
2575 } else {
2576 i = cp === current ? ++i : -1;
2577 }
2578 }
2579
2580 while (excess--) {
2581 this.tempBuff.pop();
2582
2583 this._unconsume();
2584 }
2585
2586 return result;
2587 }
2588
2589 _isCharacterReferenceInAttribute() {
2590 return this.returnState === ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE || this.returnState === ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE || this.returnState === ATTRIBUTE_VALUE_UNQUOTED_STATE;
2591 }
2592
2593 _isCharacterReferenceAttributeQuirk(withSemicolon) {
2594 if (!withSemicolon && this._isCharacterReferenceInAttribute()) {
2595 const nextCp = this._consume();
2596
2597 this._unconsume();
2598
2599 return nextCp === $$1.EQUALS_SIGN || isAsciiAlphaNumeric(nextCp);
2600 }
2601
2602 return false;
2603 }
2604
2605 _flushCodePointsConsumedAsCharacterReference() {
2606 if (this._isCharacterReferenceInAttribute()) {
2607 for (let i = 0; i < this.tempBuff.length; i++) {
2608 this.currentAttr.value += toChar(this.tempBuff[i]);
2609 }
2610 } else {
2611 this._emitSeveralCodePoints(this.tempBuff);
2612 }
2613
2614 this.tempBuff = [];
2615 } // State machine
2616 // Data state
2617 //------------------------------------------------------------------
2618
2619
2620 [DATA_STATE](cp) {
2621 this.preprocessor.dropParsedChunk();
2622
2623 if (cp === $$1.LESS_THAN_SIGN) {
2624 this.state = TAG_OPEN_STATE;
2625 } else if (cp === $$1.AMPERSAND) {
2626 this.returnState = DATA_STATE;
2627 this.state = CHARACTER_REFERENCE_STATE;
2628 } else if (cp === $$1.NULL) {
2629 this._err(errorCodes.unexpectedNullCharacter);
2630
2631 this._emitCodePoint(cp);
2632 } else if (cp === $$1.EOF) {
2633 this._emitEOFToken();
2634 } else {
2635 this._emitCodePoint(cp);
2636 }
2637 } // RCDATA state
2638 //------------------------------------------------------------------
2639
2640
2641 [RCDATA_STATE](cp) {
2642 this.preprocessor.dropParsedChunk();
2643
2644 if (cp === $$1.AMPERSAND) {
2645 this.returnState = RCDATA_STATE;
2646 this.state = CHARACTER_REFERENCE_STATE;
2647 } else if (cp === $$1.LESS_THAN_SIGN) {
2648 this.state = RCDATA_LESS_THAN_SIGN_STATE;
2649 } else if (cp === $$1.NULL) {
2650 this._err(errorCodes.unexpectedNullCharacter);
2651
2652 this._emitChars(unicode.REPLACEMENT_CHARACTER);
2653 } else if (cp === $$1.EOF) {
2654 this._emitEOFToken();
2655 } else {
2656 this._emitCodePoint(cp);
2657 }
2658 } // RAWTEXT state
2659 //------------------------------------------------------------------
2660
2661
2662 [RAWTEXT_STATE](cp) {
2663 this.preprocessor.dropParsedChunk();
2664
2665 if (cp === $$1.LESS_THAN_SIGN) {
2666 this.state = RAWTEXT_LESS_THAN_SIGN_STATE;
2667 } else if (cp === $$1.NULL) {
2668 this._err(errorCodes.unexpectedNullCharacter);
2669
2670 this._emitChars(unicode.REPLACEMENT_CHARACTER);
2671 } else if (cp === $$1.EOF) {
2672 this._emitEOFToken();
2673 } else {
2674 this._emitCodePoint(cp);
2675 }
2676 } // Script data state
2677 //------------------------------------------------------------------
2678
2679
2680 [SCRIPT_DATA_STATE](cp) {
2681 this.preprocessor.dropParsedChunk();
2682
2683 if (cp === $$1.LESS_THAN_SIGN) {
2684 this.state = SCRIPT_DATA_LESS_THAN_SIGN_STATE;
2685 } else if (cp === $$1.NULL) {
2686 this._err(errorCodes.unexpectedNullCharacter);
2687
2688 this._emitChars(unicode.REPLACEMENT_CHARACTER);
2689 } else if (cp === $$1.EOF) {
2690 this._emitEOFToken();
2691 } else {
2692 this._emitCodePoint(cp);
2693 }
2694 } // PLAINTEXT state
2695 //------------------------------------------------------------------
2696
2697
2698 [PLAINTEXT_STATE](cp) {
2699 this.preprocessor.dropParsedChunk();
2700
2701 if (cp === $$1.NULL) {
2702 this._err(errorCodes.unexpectedNullCharacter);
2703
2704 this._emitChars(unicode.REPLACEMENT_CHARACTER);
2705 } else if (cp === $$1.EOF) {
2706 this._emitEOFToken();
2707 } else {
2708 this._emitCodePoint(cp);
2709 }
2710 } // Tag open state
2711 //------------------------------------------------------------------
2712
2713
2714 [TAG_OPEN_STATE](cp) {
2715 if (cp === $$1.EXCLAMATION_MARK) {
2716 this.state = MARKUP_DECLARATION_OPEN_STATE;
2717 } else if (cp === $$1.SOLIDUS) {
2718 this.state = END_TAG_OPEN_STATE;
2719 } else if (isAsciiLetter(cp)) {
2720 this._createStartTagToken();
2721
2722 this._reconsumeInState(TAG_NAME_STATE);
2723 } else if (cp === $$1.QUESTION_MARK) {
2724 this._err(errorCodes.unexpectedQuestionMarkInsteadOfTagName);
2725
2726 this._createCommentToken();
2727
2728 this._reconsumeInState(BOGUS_COMMENT_STATE);
2729 } else if (cp === $$1.EOF) {
2730 this._err(errorCodes.eofBeforeTagName);
2731
2732 this._emitChars('<');
2733
2734 this._emitEOFToken();
2735 } else {
2736 this._err(errorCodes.invalidFirstCharacterOfTagName);
2737
2738 this._emitChars('<');
2739
2740 this._reconsumeInState(DATA_STATE);
2741 }
2742 } // End tag open state
2743 //------------------------------------------------------------------
2744
2745
2746 [END_TAG_OPEN_STATE](cp) {
2747 if (isAsciiLetter(cp)) {
2748 this._createEndTagToken();
2749
2750 this._reconsumeInState(TAG_NAME_STATE);
2751 } else if (cp === $$1.GREATER_THAN_SIGN) {
2752 this._err(errorCodes.missingEndTagName);
2753
2754 this.state = DATA_STATE;
2755 } else if (cp === $$1.EOF) {
2756 this._err(errorCodes.eofBeforeTagName);
2757
2758 this._emitChars('</');
2759
2760 this._emitEOFToken();
2761 } else {
2762 this._err(errorCodes.invalidFirstCharacterOfTagName);
2763
2764 this._createCommentToken();
2765
2766 this._reconsumeInState(BOGUS_COMMENT_STATE);
2767 }
2768 } // Tag name state
2769 //------------------------------------------------------------------
2770
2771
2772 [TAG_NAME_STATE](cp) {
2773 if (isWhitespace(cp)) {
2774 this.state = BEFORE_ATTRIBUTE_NAME_STATE;
2775 } else if (cp === $$1.SOLIDUS) {
2776 this.state = SELF_CLOSING_START_TAG_STATE;
2777 } else if (cp === $$1.GREATER_THAN_SIGN) {
2778 this.state = DATA_STATE;
2779
2780 this._emitCurrentToken();
2781 } else if (isAsciiUpper(cp)) {
2782 this.currentToken.tagName += toAsciiLowerChar(cp);
2783 } else if (cp === $$1.NULL) {
2784 this._err(errorCodes.unexpectedNullCharacter);
2785
2786 this.currentToken.tagName += unicode.REPLACEMENT_CHARACTER;
2787 } else if (cp === $$1.EOF) {
2788 this._err(errorCodes.eofInTag);
2789
2790 this._emitEOFToken();
2791 } else {
2792 this.currentToken.tagName += toChar(cp);
2793 }
2794 } // RCDATA less-than sign state
2795 //------------------------------------------------------------------
2796
2797
2798 [RCDATA_LESS_THAN_SIGN_STATE](cp) {
2799 if (cp === $$1.SOLIDUS) {
2800 this.tempBuff = [];
2801 this.state = RCDATA_END_TAG_OPEN_STATE;
2802 } else {
2803 this._emitChars('<');
2804
2805 this._reconsumeInState(RCDATA_STATE);
2806 }
2807 } // RCDATA end tag open state
2808 //------------------------------------------------------------------
2809
2810
2811 [RCDATA_END_TAG_OPEN_STATE](cp) {
2812 if (isAsciiLetter(cp)) {
2813 this._createEndTagToken();
2814
2815 this._reconsumeInState(RCDATA_END_TAG_NAME_STATE);
2816 } else {
2817 this._emitChars('</');
2818
2819 this._reconsumeInState(RCDATA_STATE);
2820 }
2821 } // RCDATA end tag name state
2822 //------------------------------------------------------------------
2823
2824
2825 [RCDATA_END_TAG_NAME_STATE](cp) {
2826 if (isAsciiUpper(cp)) {
2827 this.currentToken.tagName += toAsciiLowerChar(cp);
2828 this.tempBuff.push(cp);
2829 } else if (isAsciiLower(cp)) {
2830 this.currentToken.tagName += toChar(cp);
2831 this.tempBuff.push(cp);
2832 } else {
2833 if (this.lastStartTagName === this.currentToken.tagName) {
2834 if (isWhitespace(cp)) {
2835 this.state = BEFORE_ATTRIBUTE_NAME_STATE;
2836 return;
2837 }
2838
2839 if (cp === $$1.SOLIDUS) {
2840 this.state = SELF_CLOSING_START_TAG_STATE;
2841 return;
2842 }
2843
2844 if (cp === $$1.GREATER_THAN_SIGN) {
2845 this.state = DATA_STATE;
2846
2847 this._emitCurrentToken();
2848
2849 return;
2850 }
2851 }
2852
2853 this._emitChars('</');
2854
2855 this._emitSeveralCodePoints(this.tempBuff);
2856
2857 this._reconsumeInState(RCDATA_STATE);
2858 }
2859 } // RAWTEXT less-than sign state
2860 //------------------------------------------------------------------
2861
2862
2863 [RAWTEXT_LESS_THAN_SIGN_STATE](cp) {
2864 if (cp === $$1.SOLIDUS) {
2865 this.tempBuff = [];
2866 this.state = RAWTEXT_END_TAG_OPEN_STATE;
2867 } else {
2868 this._emitChars('<');
2869
2870 this._reconsumeInState(RAWTEXT_STATE);
2871 }
2872 } // RAWTEXT end tag open state
2873 //------------------------------------------------------------------
2874
2875
2876 [RAWTEXT_END_TAG_OPEN_STATE](cp) {
2877 if (isAsciiLetter(cp)) {
2878 this._createEndTagToken();
2879
2880 this._reconsumeInState(RAWTEXT_END_TAG_NAME_STATE);
2881 } else {
2882 this._emitChars('</');
2883
2884 this._reconsumeInState(RAWTEXT_STATE);
2885 }
2886 } // RAWTEXT end tag name state
2887 //------------------------------------------------------------------
2888
2889
2890 [RAWTEXT_END_TAG_NAME_STATE](cp) {
2891 if (isAsciiUpper(cp)) {
2892 this.currentToken.tagName += toAsciiLowerChar(cp);
2893 this.tempBuff.push(cp);
2894 } else if (isAsciiLower(cp)) {
2895 this.currentToken.tagName += toChar(cp);
2896 this.tempBuff.push(cp);
2897 } else {
2898 if (this.lastStartTagName === this.currentToken.tagName) {
2899 if (isWhitespace(cp)) {
2900 this.state = BEFORE_ATTRIBUTE_NAME_STATE;
2901 return;
2902 }
2903
2904 if (cp === $$1.SOLIDUS) {
2905 this.state = SELF_CLOSING_START_TAG_STATE;
2906 return;
2907 }
2908
2909 if (cp === $$1.GREATER_THAN_SIGN) {
2910 this._emitCurrentToken();
2911
2912 this.state = DATA_STATE;
2913 return;
2914 }
2915 }
2916
2917 this._emitChars('</');
2918
2919 this._emitSeveralCodePoints(this.tempBuff);
2920
2921 this._reconsumeInState(RAWTEXT_STATE);
2922 }
2923 } // Script data less-than sign state
2924 //------------------------------------------------------------------
2925
2926
2927 [SCRIPT_DATA_LESS_THAN_SIGN_STATE](cp) {
2928 if (cp === $$1.SOLIDUS) {
2929 this.tempBuff = [];
2930 this.state = SCRIPT_DATA_END_TAG_OPEN_STATE;
2931 } else if (cp === $$1.EXCLAMATION_MARK) {
2932 this.state = SCRIPT_DATA_ESCAPE_START_STATE;
2933
2934 this._emitChars('<!');
2935 } else {
2936 this._emitChars('<');
2937
2938 this._reconsumeInState(SCRIPT_DATA_STATE);
2939 }
2940 } // Script data end tag open state
2941 //------------------------------------------------------------------
2942
2943
2944 [SCRIPT_DATA_END_TAG_OPEN_STATE](cp) {
2945 if (isAsciiLetter(cp)) {
2946 this._createEndTagToken();
2947
2948 this._reconsumeInState(SCRIPT_DATA_END_TAG_NAME_STATE);
2949 } else {
2950 this._emitChars('</');
2951
2952 this._reconsumeInState(SCRIPT_DATA_STATE);
2953 }
2954 } // Script data end tag name state
2955 //------------------------------------------------------------------
2956
2957
2958 [SCRIPT_DATA_END_TAG_NAME_STATE](cp) {
2959 if (isAsciiUpper(cp)) {
2960 this.currentToken.tagName += toAsciiLowerChar(cp);
2961 this.tempBuff.push(cp);
2962 } else if (isAsciiLower(cp)) {
2963 this.currentToken.tagName += toChar(cp);
2964 this.tempBuff.push(cp);
2965 } else {
2966 if (this.lastStartTagName === this.currentToken.tagName) {
2967 if (isWhitespace(cp)) {
2968 this.state = BEFORE_ATTRIBUTE_NAME_STATE;
2969 return;
2970 } else if (cp === $$1.SOLIDUS) {
2971 this.state = SELF_CLOSING_START_TAG_STATE;
2972 return;
2973 } else if (cp === $$1.GREATER_THAN_SIGN) {
2974 this._emitCurrentToken();
2975
2976 this.state = DATA_STATE;
2977 return;
2978 }
2979 }
2980
2981 this._emitChars('</');
2982
2983 this._emitSeveralCodePoints(this.tempBuff);
2984
2985 this._reconsumeInState(SCRIPT_DATA_STATE);
2986 }
2987 } // Script data escape start state
2988 //------------------------------------------------------------------
2989
2990
2991 [SCRIPT_DATA_ESCAPE_START_STATE](cp) {
2992 if (cp === $$1.HYPHEN_MINUS) {
2993 this.state = SCRIPT_DATA_ESCAPE_START_DASH_STATE;
2994
2995 this._emitChars('-');
2996 } else {
2997 this._reconsumeInState(SCRIPT_DATA_STATE);
2998 }
2999 } // Script data escape start dash state
3000 //------------------------------------------------------------------
3001
3002
3003 [SCRIPT_DATA_ESCAPE_START_DASH_STATE](cp) {
3004 if (cp === $$1.HYPHEN_MINUS) {
3005 this.state = SCRIPT_DATA_ESCAPED_DASH_DASH_STATE;
3006
3007 this._emitChars('-');
3008 } else {
3009 this._reconsumeInState(SCRIPT_DATA_STATE);
3010 }
3011 } // Script data escaped state
3012 //------------------------------------------------------------------
3013
3014
3015 [SCRIPT_DATA_ESCAPED_STATE](cp) {
3016 if (cp === $$1.HYPHEN_MINUS) {
3017 this.state = SCRIPT_DATA_ESCAPED_DASH_STATE;
3018
3019 this._emitChars('-');
3020 } else if (cp === $$1.LESS_THAN_SIGN) {
3021 this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
3022 } else if (cp === $$1.NULL) {
3023 this._err(errorCodes.unexpectedNullCharacter);
3024
3025 this._emitChars(unicode.REPLACEMENT_CHARACTER);
3026 } else if (cp === $$1.EOF) {
3027 this._err(errorCodes.eofInScriptHtmlCommentLikeText);
3028
3029 this._emitEOFToken();
3030 } else {
3031 this._emitCodePoint(cp);
3032 }
3033 } // Script data escaped dash state
3034 //------------------------------------------------------------------
3035
3036
3037 [SCRIPT_DATA_ESCAPED_DASH_STATE](cp) {
3038 if (cp === $$1.HYPHEN_MINUS) {
3039 this.state = SCRIPT_DATA_ESCAPED_DASH_DASH_STATE;
3040
3041 this._emitChars('-');
3042 } else if (cp === $$1.LESS_THAN_SIGN) {
3043 this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
3044 } else if (cp === $$1.NULL) {
3045 this._err(errorCodes.unexpectedNullCharacter);
3046
3047 this.state = SCRIPT_DATA_ESCAPED_STATE;
3048
3049 this._emitChars(unicode.REPLACEMENT_CHARACTER);
3050 } else if (cp === $$1.EOF) {
3051 this._err(errorCodes.eofInScriptHtmlCommentLikeText);
3052
3053 this._emitEOFToken();
3054 } else {
3055 this.state = SCRIPT_DATA_ESCAPED_STATE;
3056
3057 this._emitCodePoint(cp);
3058 }
3059 } // Script data escaped dash dash state
3060 //------------------------------------------------------------------
3061
3062
3063 [SCRIPT_DATA_ESCAPED_DASH_DASH_STATE](cp) {
3064 if (cp === $$1.HYPHEN_MINUS) {
3065 this._emitChars('-');
3066 } else if (cp === $$1.LESS_THAN_SIGN) {
3067 this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
3068 } else if (cp === $$1.GREATER_THAN_SIGN) {
3069 this.state = SCRIPT_DATA_STATE;
3070
3071 this._emitChars('>');
3072 } else if (cp === $$1.NULL) {
3073 this._err(errorCodes.unexpectedNullCharacter);
3074
3075 this.state = SCRIPT_DATA_ESCAPED_STATE;
3076
3077 this._emitChars(unicode.REPLACEMENT_CHARACTER);
3078 } else if (cp === $$1.EOF) {
3079 this._err(errorCodes.eofInScriptHtmlCommentLikeText);
3080
3081 this._emitEOFToken();
3082 } else {
3083 this.state = SCRIPT_DATA_ESCAPED_STATE;
3084
3085 this._emitCodePoint(cp);
3086 }
3087 } // Script data escaped less-than sign state
3088 //------------------------------------------------------------------
3089
3090
3091 [SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE](cp) {
3092 if (cp === $$1.SOLIDUS) {
3093 this.tempBuff = [];
3094 this.state = SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE;
3095 } else if (isAsciiLetter(cp)) {
3096 this.tempBuff = [];
3097
3098 this._emitChars('<');
3099
3100 this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE);
3101 } else {
3102 this._emitChars('<');
3103
3104 this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
3105 }
3106 } // Script data escaped end tag open state
3107 //------------------------------------------------------------------
3108
3109
3110 [SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE](cp) {
3111 if (isAsciiLetter(cp)) {
3112 this._createEndTagToken();
3113
3114 this._reconsumeInState(SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE);
3115 } else {
3116 this._emitChars('</');
3117
3118 this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
3119 }
3120 } // Script data escaped end tag name state
3121 //------------------------------------------------------------------
3122
3123
3124 [SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE](cp) {
3125 if (isAsciiUpper(cp)) {
3126 this.currentToken.tagName += toAsciiLowerChar(cp);
3127 this.tempBuff.push(cp);
3128 } else if (isAsciiLower(cp)) {
3129 this.currentToken.tagName += toChar(cp);
3130 this.tempBuff.push(cp);
3131 } else {
3132 if (this.lastStartTagName === this.currentToken.tagName) {
3133 if (isWhitespace(cp)) {
3134 this.state = BEFORE_ATTRIBUTE_NAME_STATE;
3135 return;
3136 }
3137
3138 if (cp === $$1.SOLIDUS) {
3139 this.state = SELF_CLOSING_START_TAG_STATE;
3140 return;
3141 }
3142
3143 if (cp === $$1.GREATER_THAN_SIGN) {
3144 this._emitCurrentToken();
3145
3146 this.state = DATA_STATE;
3147 return;
3148 }
3149 }
3150
3151 this._emitChars('</');
3152
3153 this._emitSeveralCodePoints(this.tempBuff);
3154
3155 this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
3156 }
3157 } // Script data double escape start state
3158 //------------------------------------------------------------------
3159
3160
3161 [SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE](cp) {
3162 if (isWhitespace(cp) || cp === $$1.SOLIDUS || cp === $$1.GREATER_THAN_SIGN) {
3163 this.state = this._isTempBufferEqualToScriptString() ? SCRIPT_DATA_DOUBLE_ESCAPED_STATE : SCRIPT_DATA_ESCAPED_STATE;
3164
3165 this._emitCodePoint(cp);
3166 } else if (isAsciiUpper(cp)) {
3167 this.tempBuff.push(toAsciiLowerCodePoint(cp));
3168
3169 this._emitCodePoint(cp);
3170 } else if (isAsciiLower(cp)) {
3171 this.tempBuff.push(cp);
3172
3173 this._emitCodePoint(cp);
3174 } else {
3175 this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
3176 }
3177 } // Script data double escaped state
3178 //------------------------------------------------------------------
3179
3180
3181 [SCRIPT_DATA_DOUBLE_ESCAPED_STATE](cp) {
3182 if (cp === $$1.HYPHEN_MINUS) {
3183 this.state = SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE;
3184
3185 this._emitChars('-');
3186 } else if (cp === $$1.LESS_THAN_SIGN) {
3187 this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
3188
3189 this._emitChars('<');
3190 } else if (cp === $$1.NULL) {
3191 this._err(errorCodes.unexpectedNullCharacter);
3192
3193 this._emitChars(unicode.REPLACEMENT_CHARACTER);
3194 } else if (cp === $$1.EOF) {
3195 this._err(errorCodes.eofInScriptHtmlCommentLikeText);
3196
3197 this._emitEOFToken();
3198 } else {
3199 this._emitCodePoint(cp);
3200 }
3201 } // Script data double escaped dash state
3202 //------------------------------------------------------------------
3203
3204
3205 [SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE](cp) {
3206 if (cp === $$1.HYPHEN_MINUS) {
3207 this.state = SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE;
3208
3209 this._emitChars('-');
3210 } else if (cp === $$1.LESS_THAN_SIGN) {
3211 this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
3212
3213 this._emitChars('<');
3214 } else if (cp === $$1.NULL) {
3215 this._err(errorCodes.unexpectedNullCharacter);
3216
3217 this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
3218
3219 this._emitChars(unicode.REPLACEMENT_CHARACTER);
3220 } else if (cp === $$1.EOF) {
3221 this._err(errorCodes.eofInScriptHtmlCommentLikeText);
3222
3223 this._emitEOFToken();
3224 } else {
3225 this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
3226
3227 this._emitCodePoint(cp);
3228 }
3229 } // Script data double escaped dash dash state
3230 //------------------------------------------------------------------
3231
3232
3233 [SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE](cp) {
3234 if (cp === $$1.HYPHEN_MINUS) {
3235 this._emitChars('-');
3236 } else if (cp === $$1.LESS_THAN_SIGN) {
3237 this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
3238
3239 this._emitChars('<');
3240 } else if (cp === $$1.GREATER_THAN_SIGN) {
3241 this.state = SCRIPT_DATA_STATE;
3242
3243 this._emitChars('>');
3244 } else if (cp === $$1.NULL) {
3245 this._err(errorCodes.unexpectedNullCharacter);
3246
3247 this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
3248
3249 this._emitChars(unicode.REPLACEMENT_CHARACTER);
3250 } else if (cp === $$1.EOF) {
3251 this._err(errorCodes.eofInScriptHtmlCommentLikeText);
3252
3253 this._emitEOFToken();
3254 } else {
3255 this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
3256
3257 this._emitCodePoint(cp);
3258 }
3259 } // Script data double escaped less-than sign state
3260 //------------------------------------------------------------------
3261
3262
3263 [SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE](cp) {
3264 if (cp === $$1.SOLIDUS) {
3265 this.tempBuff = [];
3266 this.state = SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE;
3267
3268 this._emitChars('/');
3269 } else {
3270 this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPED_STATE);
3271 }
3272 } // Script data double escape end state
3273 //------------------------------------------------------------------
3274
3275
3276 [SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE](cp) {
3277 if (isWhitespace(cp) || cp === $$1.SOLIDUS || cp === $$1.GREATER_THAN_SIGN) {
3278 this.state = this._isTempBufferEqualToScriptString() ? SCRIPT_DATA_ESCAPED_STATE : SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
3279
3280 this._emitCodePoint(cp);
3281 } else if (isAsciiUpper(cp)) {
3282 this.tempBuff.push(toAsciiLowerCodePoint(cp));
3283
3284 this._emitCodePoint(cp);
3285 } else if (isAsciiLower(cp)) {
3286 this.tempBuff.push(cp);
3287
3288 this._emitCodePoint(cp);
3289 } else {
3290 this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPED_STATE);
3291 }
3292 } // Before attribute name state
3293 //------------------------------------------------------------------
3294
3295
3296 [BEFORE_ATTRIBUTE_NAME_STATE](cp) {
3297 if (isWhitespace(cp)) {
3298 return;
3299 }
3300
3301 if (cp === $$1.SOLIDUS || cp === $$1.GREATER_THAN_SIGN || cp === $$1.EOF) {
3302 this._reconsumeInState(AFTER_ATTRIBUTE_NAME_STATE);
3303 } else if (cp === $$1.EQUALS_SIGN) {
3304 this._err(errorCodes.unexpectedEqualsSignBeforeAttributeName);
3305
3306 this._createAttr('=');
3307
3308 this.state = ATTRIBUTE_NAME_STATE;
3309 } else {
3310 this._createAttr('');
3311
3312 this._reconsumeInState(ATTRIBUTE_NAME_STATE);
3313 }
3314 } // Attribute name state
3315 //------------------------------------------------------------------
3316
3317
3318 [ATTRIBUTE_NAME_STATE](cp) {
3319 if (isWhitespace(cp) || cp === $$1.SOLIDUS || cp === $$1.GREATER_THAN_SIGN || cp === $$1.EOF) {
3320 this._leaveAttrName(AFTER_ATTRIBUTE_NAME_STATE);
3321
3322 this._unconsume();
3323 } else if (cp === $$1.EQUALS_SIGN) {
3324 this._leaveAttrName(BEFORE_ATTRIBUTE_VALUE_STATE);
3325 } else if (isAsciiUpper(cp)) {
3326 this.currentAttr.name += toAsciiLowerChar(cp);
3327 } else if (cp === $$1.QUOTATION_MARK || cp === $$1.APOSTROPHE || cp === $$1.LESS_THAN_SIGN) {
3328 this._err(errorCodes.unexpectedCharacterInAttributeName);
3329
3330 this.currentAttr.name += toChar(cp);
3331 } else if (cp === $$1.NULL) {
3332 this._err(errorCodes.unexpectedNullCharacter);
3333
3334 this.currentAttr.name += unicode.REPLACEMENT_CHARACTER;
3335 } else {
3336 this.currentAttr.name += toChar(cp);
3337 }
3338 } // After attribute name state
3339 //------------------------------------------------------------------
3340
3341
3342 [AFTER_ATTRIBUTE_NAME_STATE](cp) {
3343 if (isWhitespace(cp)) {
3344 return;
3345 }
3346
3347 if (cp === $$1.SOLIDUS) {
3348 this.state = SELF_CLOSING_START_TAG_STATE;
3349 } else if (cp === $$1.EQUALS_SIGN) {
3350 this.state = BEFORE_ATTRIBUTE_VALUE_STATE;
3351 } else if (cp === $$1.GREATER_THAN_SIGN) {
3352 this.state = DATA_STATE;
3353
3354 this._emitCurrentToken();
3355 } else if (cp === $$1.EOF) {
3356 this._err(errorCodes.eofInTag);
3357
3358 this._emitEOFToken();
3359 } else {
3360 this._createAttr('');
3361
3362 this._reconsumeInState(ATTRIBUTE_NAME_STATE);
3363 }
3364 } // Before attribute value state
3365 //------------------------------------------------------------------
3366
3367
3368 [BEFORE_ATTRIBUTE_VALUE_STATE](cp) {
3369 if (isWhitespace(cp)) {
3370 return;
3371 }
3372
3373 if (cp === $$1.QUOTATION_MARK) {
3374 this.state = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
3375 } else if (cp === $$1.APOSTROPHE) {
3376 this.state = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
3377 } else if (cp === $$1.GREATER_THAN_SIGN) {
3378 this._err(errorCodes.missingAttributeValue);
3379
3380 this.state = DATA_STATE;
3381
3382 this._emitCurrentToken();
3383 } else {
3384 this._reconsumeInState(ATTRIBUTE_VALUE_UNQUOTED_STATE);
3385 }
3386 } // Attribute value (double-quoted) state
3387 //------------------------------------------------------------------
3388
3389
3390 [ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE](cp) {
3391 if (cp === $$1.QUOTATION_MARK) {
3392 this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
3393 } else if (cp === $$1.AMPERSAND) {
3394 this.returnState = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
3395 this.state = CHARACTER_REFERENCE_STATE;
3396 } else if (cp === $$1.NULL) {
3397 this._err(errorCodes.unexpectedNullCharacter);
3398
3399 this.currentAttr.value += unicode.REPLACEMENT_CHARACTER;
3400 } else if (cp === $$1.EOF) {
3401 this._err(errorCodes.eofInTag);
3402
3403 this._emitEOFToken();
3404 } else {
3405 this.currentAttr.value += toChar(cp);
3406 }
3407 } // Attribute value (single-quoted) state
3408 //------------------------------------------------------------------
3409
3410
3411 [ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE](cp) {
3412 if (cp === $$1.APOSTROPHE) {
3413 this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
3414 } else if (cp === $$1.AMPERSAND) {
3415 this.returnState = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
3416 this.state = CHARACTER_REFERENCE_STATE;
3417 } else if (cp === $$1.NULL) {
3418 this._err(errorCodes.unexpectedNullCharacter);
3419
3420 this.currentAttr.value += unicode.REPLACEMENT_CHARACTER;
3421 } else if (cp === $$1.EOF) {
3422 this._err(errorCodes.eofInTag);
3423
3424 this._emitEOFToken();
3425 } else {
3426 this.currentAttr.value += toChar(cp);
3427 }
3428 } // Attribute value (unquoted) state
3429 //------------------------------------------------------------------
3430
3431
3432 [ATTRIBUTE_VALUE_UNQUOTED_STATE](cp) {
3433 if (isWhitespace(cp)) {
3434 this._leaveAttrValue(BEFORE_ATTRIBUTE_NAME_STATE);
3435 } else if (cp === $$1.AMPERSAND) {
3436 this.returnState = ATTRIBUTE_VALUE_UNQUOTED_STATE;
3437 this.state = CHARACTER_REFERENCE_STATE;
3438 } else if (cp === $$1.GREATER_THAN_SIGN) {
3439 this._leaveAttrValue(DATA_STATE);
3440
3441 this._emitCurrentToken();
3442 } else if (cp === $$1.NULL) {
3443 this._err(errorCodes.unexpectedNullCharacter);
3444
3445 this.currentAttr.value += unicode.REPLACEMENT_CHARACTER;
3446 } else if (cp === $$1.QUOTATION_MARK || cp === $$1.APOSTROPHE || cp === $$1.LESS_THAN_SIGN || cp === $$1.EQUALS_SIGN || cp === $$1.GRAVE_ACCENT) {
3447 this._err(errorCodes.unexpectedCharacterInUnquotedAttributeValue);
3448
3449 this.currentAttr.value += toChar(cp);
3450 } else if (cp === $$1.EOF) {
3451 this._err(errorCodes.eofInTag);
3452
3453 this._emitEOFToken();
3454 } else {
3455 this.currentAttr.value += toChar(cp);
3456 }
3457 } // After attribute value (quoted) state
3458 //------------------------------------------------------------------
3459
3460
3461 [AFTER_ATTRIBUTE_VALUE_QUOTED_STATE](cp) {
3462 if (isWhitespace(cp)) {
3463 this._leaveAttrValue(BEFORE_ATTRIBUTE_NAME_STATE);
3464 } else if (cp === $$1.SOLIDUS) {
3465 this._leaveAttrValue(SELF_CLOSING_START_TAG_STATE);
3466 } else if (cp === $$1.GREATER_THAN_SIGN) {
3467 this._leaveAttrValue(DATA_STATE);
3468
3469 this._emitCurrentToken();
3470 } else if (cp === $$1.EOF) {
3471 this._err(errorCodes.eofInTag);
3472
3473 this._emitEOFToken();
3474 } else {
3475 this._err(errorCodes.missingWhitespaceBetweenAttributes);
3476
3477 this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
3478 }
3479 } // Self-closing start tag state
3480 //------------------------------------------------------------------
3481
3482
3483 [SELF_CLOSING_START_TAG_STATE](cp) {
3484 if (cp === $$1.GREATER_THAN_SIGN) {
3485 this.currentToken.selfClosing = true;
3486 this.state = DATA_STATE;
3487
3488 this._emitCurrentToken();
3489 } else if (cp === $$1.EOF) {
3490 this._err(errorCodes.eofInTag);
3491
3492 this._emitEOFToken();
3493 } else {
3494 this._err(errorCodes.unexpectedSolidusInTag);
3495
3496 this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
3497 }
3498 } // Bogus comment state
3499 //------------------------------------------------------------------
3500
3501
3502 [BOGUS_COMMENT_STATE](cp) {
3503 if (cp === $$1.GREATER_THAN_SIGN) {
3504 this.state = DATA_STATE;
3505
3506 this._emitCurrentToken();
3507 } else if (cp === $$1.EOF) {
3508 this._emitCurrentToken();
3509
3510 this._emitEOFToken();
3511 } else if (cp === $$1.NULL) {
3512 this._err(errorCodes.unexpectedNullCharacter);
3513
3514 this.currentToken.data += unicode.REPLACEMENT_CHARACTER;
3515 } else {
3516 this.currentToken.data += toChar(cp);
3517 }
3518 } // Markup declaration open state
3519 //------------------------------------------------------------------
3520
3521
3522 [MARKUP_DECLARATION_OPEN_STATE](cp) {
3523 if (this._consumeSequenceIfMatch($$.DASH_DASH_STRING, cp, true)) {
3524 this._createCommentToken();
3525
3526 this.state = COMMENT_START_STATE;
3527 } else if (this._consumeSequenceIfMatch($$.DOCTYPE_STRING, cp, false)) {
3528 this.state = DOCTYPE_STATE;
3529 } else if (this._consumeSequenceIfMatch($$.CDATA_START_STRING, cp, true)) {
3530 if (this.allowCDATA) {
3531 this.state = CDATA_SECTION_STATE;
3532 } else {
3533 this._err(errorCodes.cdataInHtmlContent);
3534
3535 this._createCommentToken();
3536
3537 this.currentToken.data = '[CDATA[';
3538 this.state = BOGUS_COMMENT_STATE;
3539 }
3540 } //NOTE: sequence lookup can be abrupted by hibernation. In that case lookup
3541 //results are no longer valid and we will need to start over.
3542 else if (!this._ensureHibernation()) {
3543 this._err(errorCodes.incorrectlyOpenedComment);
3544
3545 this._createCommentToken();
3546
3547 this._reconsumeInState(BOGUS_COMMENT_STATE);
3548 }
3549 } // Comment start state
3550 //------------------------------------------------------------------
3551
3552
3553 [COMMENT_START_STATE](cp) {
3554 if (cp === $$1.HYPHEN_MINUS) {
3555 this.state = COMMENT_START_DASH_STATE;
3556 } else if (cp === $$1.GREATER_THAN_SIGN) {
3557 this._err(errorCodes.abruptClosingOfEmptyComment);
3558
3559 this.state = DATA_STATE;
3560
3561 this._emitCurrentToken();
3562 } else {
3563 this._reconsumeInState(COMMENT_STATE);
3564 }
3565 } // Comment start dash state
3566 //------------------------------------------------------------------
3567
3568
3569 [COMMENT_START_DASH_STATE](cp) {
3570 if (cp === $$1.HYPHEN_MINUS) {
3571 this.state = COMMENT_END_STATE;
3572 } else if (cp === $$1.GREATER_THAN_SIGN) {
3573 this._err(errorCodes.abruptClosingOfEmptyComment);
3574
3575 this.state = DATA_STATE;
3576
3577 this._emitCurrentToken();
3578 } else if (cp === $$1.EOF) {
3579 this._err(errorCodes.eofInComment);
3580
3581 this._emitCurrentToken();
3582
3583 this._emitEOFToken();
3584 } else {
3585 this.currentToken.data += '-';
3586
3587 this._reconsumeInState(COMMENT_STATE);
3588 }
3589 } // Comment state
3590 //------------------------------------------------------------------
3591
3592
3593 [COMMENT_STATE](cp) {
3594 if (cp === $$1.HYPHEN_MINUS) {
3595 this.state = COMMENT_END_DASH_STATE;
3596 } else if (cp === $$1.LESS_THAN_SIGN) {
3597 this.currentToken.data += '<';
3598 this.state = COMMENT_LESS_THAN_SIGN_STATE;
3599 } else if (cp === $$1.NULL) {
3600 this._err(errorCodes.unexpectedNullCharacter);
3601
3602 this.currentToken.data += unicode.REPLACEMENT_CHARACTER;
3603 } else if (cp === $$1.EOF) {
3604 this._err(errorCodes.eofInComment);
3605
3606 this._emitCurrentToken();
3607
3608 this._emitEOFToken();
3609 } else {
3610 this.currentToken.data += toChar(cp);
3611 }
3612 } // Comment less-than sign state
3613 //------------------------------------------------------------------
3614
3615
3616 [COMMENT_LESS_THAN_SIGN_STATE](cp) {
3617 if (cp === $$1.EXCLAMATION_MARK) {
3618 this.currentToken.data += '!';
3619 this.state = COMMENT_LESS_THAN_SIGN_BANG_STATE;
3620 } else if (cp === $$1.LESS_THAN_SIGN) {
3621 this.currentToken.data += '!';
3622 } else {
3623 this._reconsumeInState(COMMENT_STATE);
3624 }
3625 } // Comment less-than sign bang state
3626 //------------------------------------------------------------------
3627
3628
3629 [COMMENT_LESS_THAN_SIGN_BANG_STATE](cp) {
3630 if (cp === $$1.HYPHEN_MINUS) {
3631 this.state = COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE;
3632 } else {
3633 this._reconsumeInState(COMMENT_STATE);
3634 }
3635 } // Comment less-than sign bang dash state
3636 //------------------------------------------------------------------
3637
3638
3639 [COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE](cp) {
3640 if (cp === $$1.HYPHEN_MINUS) {
3641 this.state = COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE;
3642 } else {
3643 this._reconsumeInState(COMMENT_END_DASH_STATE);
3644 }
3645 } // Comment less-than sign bang dash dash state
3646 //------------------------------------------------------------------
3647
3648
3649 [COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE](cp) {
3650 if (cp !== $$1.GREATER_THAN_SIGN && cp !== $$1.EOF) {
3651 this._err(errorCodes.nestedComment);
3652 }
3653
3654 this._reconsumeInState(COMMENT_END_STATE);
3655 } // Comment end dash state
3656 //------------------------------------------------------------------
3657
3658
3659 [COMMENT_END_DASH_STATE](cp) {
3660 if (cp === $$1.HYPHEN_MINUS) {
3661 this.state = COMMENT_END_STATE;
3662 } else if (cp === $$1.EOF) {
3663 this._err(errorCodes.eofInComment);
3664
3665 this._emitCurrentToken();
3666
3667 this._emitEOFToken();
3668 } else {
3669 this.currentToken.data += '-';
3670
3671 this._reconsumeInState(COMMENT_STATE);
3672 }
3673 } // Comment end state
3674 //------------------------------------------------------------------
3675
3676
3677 [COMMENT_END_STATE](cp) {
3678 if (cp === $$1.GREATER_THAN_SIGN) {
3679 this.state = DATA_STATE;
3680
3681 this._emitCurrentToken();
3682 } else if (cp === $$1.EXCLAMATION_MARK) {
3683 this.state = COMMENT_END_BANG_STATE;
3684 } else if (cp === $$1.HYPHEN_MINUS) {
3685 this.currentToken.data += '-';
3686 } else if (cp === $$1.EOF) {
3687 this._err(errorCodes.eofInComment);
3688
3689 this._emitCurrentToken();
3690
3691 this._emitEOFToken();
3692 } else {
3693 this.currentToken.data += '--';
3694
3695 this._reconsumeInState(COMMENT_STATE);
3696 }
3697 } // Comment end bang state
3698 //------------------------------------------------------------------
3699
3700
3701 [COMMENT_END_BANG_STATE](cp) {
3702 if (cp === $$1.HYPHEN_MINUS) {
3703 this.currentToken.data += '--!';
3704 this.state = COMMENT_END_DASH_STATE;
3705 } else if (cp === $$1.GREATER_THAN_SIGN) {
3706 this._err(errorCodes.incorrectlyClosedComment);
3707
3708 this.state = DATA_STATE;
3709
3710 this._emitCurrentToken();
3711 } else if (cp === $$1.EOF) {
3712 this._err(errorCodes.eofInComment);
3713
3714 this._emitCurrentToken();
3715
3716 this._emitEOFToken();
3717 } else {
3718 this.currentToken.data += '--!';
3719
3720 this._reconsumeInState(COMMENT_STATE);
3721 }
3722 } // DOCTYPE state
3723 //------------------------------------------------------------------
3724
3725
3726 [DOCTYPE_STATE](cp) {
3727 if (isWhitespace(cp)) {
3728 this.state = BEFORE_DOCTYPE_NAME_STATE;
3729 } else if (cp === $$1.GREATER_THAN_SIGN) {
3730 this._reconsumeInState(BEFORE_DOCTYPE_NAME_STATE);
3731 } else if (cp === $$1.EOF) {
3732 this._err(errorCodes.eofInDoctype);
3733
3734 this._createDoctypeToken(null);
3735
3736 this.currentToken.forceQuirks = true;
3737
3738 this._emitCurrentToken();
3739
3740 this._emitEOFToken();
3741 } else {
3742 this._err(errorCodes.missingWhitespaceBeforeDoctypeName);
3743
3744 this._reconsumeInState(BEFORE_DOCTYPE_NAME_STATE);
3745 }
3746 } // Before DOCTYPE name state
3747 //------------------------------------------------------------------
3748
3749
3750 [BEFORE_DOCTYPE_NAME_STATE](cp) {
3751 if (isWhitespace(cp)) {
3752 return;
3753 }
3754
3755 if (isAsciiUpper(cp)) {
3756 this._createDoctypeToken(toAsciiLowerChar(cp));
3757
3758 this.state = DOCTYPE_NAME_STATE;
3759 } else if (cp === $$1.NULL) {
3760 this._err(errorCodes.unexpectedNullCharacter);
3761
3762 this._createDoctypeToken(unicode.REPLACEMENT_CHARACTER);
3763
3764 this.state = DOCTYPE_NAME_STATE;
3765 } else if (cp === $$1.GREATER_THAN_SIGN) {
3766 this._err(errorCodes.missingDoctypeName);
3767
3768 this._createDoctypeToken(null);
3769
3770 this.currentToken.forceQuirks = true;
3771
3772 this._emitCurrentToken();
3773
3774 this.state = DATA_STATE;
3775 } else if (cp === $$1.EOF) {
3776 this._err(errorCodes.eofInDoctype);
3777
3778 this._createDoctypeToken(null);
3779
3780 this.currentToken.forceQuirks = true;
3781
3782 this._emitCurrentToken();
3783
3784 this._emitEOFToken();
3785 } else {
3786 this._createDoctypeToken(toChar(cp));
3787
3788 this.state = DOCTYPE_NAME_STATE;
3789 }
3790 } // DOCTYPE name state
3791 //------------------------------------------------------------------
3792
3793
3794 [DOCTYPE_NAME_STATE](cp) {
3795 if (isWhitespace(cp)) {
3796 this.state = AFTER_DOCTYPE_NAME_STATE;
3797 } else if (cp === $$1.GREATER_THAN_SIGN) {
3798 this.state = DATA_STATE;
3799
3800 this._emitCurrentToken();
3801 } else if (isAsciiUpper(cp)) {
3802 this.currentToken.name += toAsciiLowerChar(cp);
3803 } else if (cp === $$1.NULL) {
3804 this._err(errorCodes.unexpectedNullCharacter);
3805
3806 this.currentToken.name += unicode.REPLACEMENT_CHARACTER;
3807 } else if (cp === $$1.EOF) {
3808 this._err(errorCodes.eofInDoctype);
3809
3810 this.currentToken.forceQuirks = true;
3811
3812 this._emitCurrentToken();
3813
3814 this._emitEOFToken();
3815 } else {
3816 this.currentToken.name += toChar(cp);
3817 }
3818 } // After DOCTYPE name state
3819 //------------------------------------------------------------------
3820
3821
3822 [AFTER_DOCTYPE_NAME_STATE](cp) {
3823 if (isWhitespace(cp)) {
3824 return;
3825 }
3826
3827 if (cp === $$1.GREATER_THAN_SIGN) {
3828 this.state = DATA_STATE;
3829
3830 this._emitCurrentToken();
3831 } else if (cp === $$1.EOF) {
3832 this._err(errorCodes.eofInDoctype);
3833
3834 this.currentToken.forceQuirks = true;
3835
3836 this._emitCurrentToken();
3837
3838 this._emitEOFToken();
3839 } else if (this._consumeSequenceIfMatch($$.PUBLIC_STRING, cp, false)) {
3840 this.state = AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE;
3841 } else if (this._consumeSequenceIfMatch($$.SYSTEM_STRING, cp, false)) {
3842 this.state = AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE;
3843 } //NOTE: sequence lookup can be abrupted by hibernation. In that case lookup
3844 //results are no longer valid and we will need to start over.
3845 else if (!this._ensureHibernation()) {
3846 this._err(errorCodes.invalidCharacterSequenceAfterDoctypeName);
3847
3848 this.currentToken.forceQuirks = true;
3849
3850 this._reconsumeInState(BOGUS_DOCTYPE_STATE);
3851 }
3852 } // After DOCTYPE public keyword state
3853 //------------------------------------------------------------------
3854
3855
3856 [AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE](cp) {
3857 if (isWhitespace(cp)) {
3858 this.state = BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
3859 } else if (cp === $$1.QUOTATION_MARK) {
3860 this._err(errorCodes.missingWhitespaceAfterDoctypePublicKeyword);
3861
3862 this.currentToken.publicId = '';
3863 this.state = DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE;
3864 } else if (cp === $$1.APOSTROPHE) {
3865 this._err(errorCodes.missingWhitespaceAfterDoctypePublicKeyword);
3866
3867 this.currentToken.publicId = '';
3868 this.state = DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE;
3869 } else if (cp === $$1.GREATER_THAN_SIGN) {
3870 this._err(errorCodes.missingDoctypePublicIdentifier);
3871
3872 this.currentToken.forceQuirks = true;
3873 this.state = DATA_STATE;
3874
3875 this._emitCurrentToken();
3876 } else if (cp === $$1.EOF) {
3877 this._err(errorCodes.eofInDoctype);
3878
3879 this.currentToken.forceQuirks = true;
3880
3881 this._emitCurrentToken();
3882
3883 this._emitEOFToken();
3884 } else {
3885 this._err(errorCodes.missingQuoteBeforeDoctypePublicIdentifier);
3886
3887 this.currentToken.forceQuirks = true;
3888
3889 this._reconsumeInState(BOGUS_DOCTYPE_STATE);
3890 }
3891 } // Before DOCTYPE public identifier state
3892 //------------------------------------------------------------------
3893
3894
3895 [BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE](cp) {
3896 if (isWhitespace(cp)) {
3897 return;
3898 }
3899
3900 if (cp === $$1.QUOTATION_MARK) {
3901 this.currentToken.publicId = '';
3902 this.state = DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE;
3903 } else if (cp === $$1.APOSTROPHE) {
3904 this.currentToken.publicId = '';
3905 this.state = DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE;
3906 } else if (cp === $$1.GREATER_THAN_SIGN) {
3907 this._err(errorCodes.missingDoctypePublicIdentifier);
3908
3909 this.currentToken.forceQuirks = true;
3910 this.state = DATA_STATE;
3911
3912 this._emitCurrentToken();
3913 } else if (cp === $$1.EOF) {
3914 this._err(errorCodes.eofInDoctype);
3915
3916 this.currentToken.forceQuirks = true;
3917
3918 this._emitCurrentToken();
3919
3920 this._emitEOFToken();
3921 } else {
3922 this._err(errorCodes.missingQuoteBeforeDoctypePublicIdentifier);
3923
3924 this.currentToken.forceQuirks = true;
3925
3926 this._reconsumeInState(BOGUS_DOCTYPE_STATE);
3927 }
3928 } // DOCTYPE public identifier (double-quoted) state
3929 //------------------------------------------------------------------
3930
3931
3932 [DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE](cp) {
3933 if (cp === $$1.QUOTATION_MARK) {
3934 this.state = AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
3935 } else if (cp === $$1.NULL) {
3936 this._err(errorCodes.unexpectedNullCharacter);
3937
3938 this.currentToken.publicId += unicode.REPLACEMENT_CHARACTER;
3939 } else if (cp === $$1.GREATER_THAN_SIGN) {
3940 this._err(errorCodes.abruptDoctypePublicIdentifier);
3941
3942 this.currentToken.forceQuirks = true;
3943
3944 this._emitCurrentToken();
3945
3946 this.state = DATA_STATE;
3947 } else if (cp === $$1.EOF) {
3948 this._err(errorCodes.eofInDoctype);
3949
3950 this.currentToken.forceQuirks = true;
3951
3952 this._emitCurrentToken();
3953
3954 this._emitEOFToken();
3955 } else {
3956 this.currentToken.publicId += toChar(cp);
3957 }
3958 } // DOCTYPE public identifier (single-quoted) state
3959 //------------------------------------------------------------------
3960
3961
3962 [DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE](cp) {
3963 if (cp === $$1.APOSTROPHE) {
3964 this.state = AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
3965 } else if (cp === $$1.NULL) {
3966 this._err(errorCodes.unexpectedNullCharacter);
3967
3968 this.currentToken.publicId += unicode.REPLACEMENT_CHARACTER;
3969 } else if (cp === $$1.GREATER_THAN_SIGN) {
3970 this._err(errorCodes.abruptDoctypePublicIdentifier);
3971
3972 this.currentToken.forceQuirks = true;
3973
3974 this._emitCurrentToken();
3975
3976 this.state = DATA_STATE;
3977 } else if (cp === $$1.EOF) {
3978 this._err(errorCodes.eofInDoctype);
3979
3980 this.currentToken.forceQuirks = true;
3981
3982 this._emitCurrentToken();
3983
3984 this._emitEOFToken();
3985 } else {
3986 this.currentToken.publicId += toChar(cp);
3987 }
3988 } // After DOCTYPE public identifier state
3989 //------------------------------------------------------------------
3990
3991
3992 [AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE](cp) {
3993 if (isWhitespace(cp)) {
3994 this.state = BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE;
3995 } else if (cp === $$1.GREATER_THAN_SIGN) {
3996 this.state = DATA_STATE;
3997
3998 this._emitCurrentToken();
3999 } else if (cp === $$1.QUOTATION_MARK) {
4000 this._err(errorCodes.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
4001
4002 this.currentToken.systemId = '';
4003 this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
4004 } else if (cp === $$1.APOSTROPHE) {
4005 this._err(errorCodes.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
4006
4007 this.currentToken.systemId = '';
4008 this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
4009 } else if (cp === $$1.EOF) {
4010 this._err(errorCodes.eofInDoctype);
4011
4012 this.currentToken.forceQuirks = true;
4013
4014 this._emitCurrentToken();
4015
4016 this._emitEOFToken();
4017 } else {
4018 this._err(errorCodes.missingQuoteBeforeDoctypeSystemIdentifier);
4019
4020 this.currentToken.forceQuirks = true;
4021
4022 this._reconsumeInState(BOGUS_DOCTYPE_STATE);
4023 }
4024 } // Between DOCTYPE public and system identifiers state
4025 //------------------------------------------------------------------
4026
4027
4028 [BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE](cp) {
4029 if (isWhitespace(cp)) {
4030 return;
4031 }
4032
4033 if (cp === $$1.GREATER_THAN_SIGN) {
4034 this._emitCurrentToken();
4035
4036 this.state = DATA_STATE;
4037 } else if (cp === $$1.QUOTATION_MARK) {
4038 this.currentToken.systemId = '';
4039 this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
4040 } else if (cp === $$1.APOSTROPHE) {
4041 this.currentToken.systemId = '';
4042 this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
4043 } else if (cp === $$1.EOF) {
4044 this._err(errorCodes.eofInDoctype);
4045
4046 this.currentToken.forceQuirks = true;
4047
4048 this._emitCurrentToken();
4049
4050 this._emitEOFToken();
4051 } else {
4052 this._err(errorCodes.missingQuoteBeforeDoctypeSystemIdentifier);
4053
4054 this.currentToken.forceQuirks = true;
4055
4056 this._reconsumeInState(BOGUS_DOCTYPE_STATE);
4057 }
4058 } // After DOCTYPE system keyword state
4059 //------------------------------------------------------------------
4060
4061
4062 [AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE](cp) {
4063 if (isWhitespace(cp)) {
4064 this.state = BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
4065 } else if (cp === $$1.QUOTATION_MARK) {
4066 this._err(errorCodes.missingWhitespaceAfterDoctypeSystemKeyword);
4067
4068 this.currentToken.systemId = '';
4069 this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
4070 } else if (cp === $$1.APOSTROPHE) {
4071 this._err(errorCodes.missingWhitespaceAfterDoctypeSystemKeyword);
4072
4073 this.currentToken.systemId = '';
4074 this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
4075 } else if (cp === $$1.GREATER_THAN_SIGN) {
4076 this._err(errorCodes.missingDoctypeSystemIdentifier);
4077
4078 this.currentToken.forceQuirks = true;
4079 this.state = DATA_STATE;
4080
4081 this._emitCurrentToken();
4082 } else if (cp === $$1.EOF) {
4083 this._err(errorCodes.eofInDoctype);
4084
4085 this.currentToken.forceQuirks = true;
4086
4087 this._emitCurrentToken();
4088
4089 this._emitEOFToken();
4090 } else {
4091 this._err(errorCodes.missingQuoteBeforeDoctypeSystemIdentifier);
4092
4093 this.currentToken.forceQuirks = true;
4094
4095 this._reconsumeInState(BOGUS_DOCTYPE_STATE);
4096 }
4097 } // Before DOCTYPE system identifier state
4098 //------------------------------------------------------------------
4099
4100
4101 [BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE](cp) {
4102 if (isWhitespace(cp)) {
4103 return;
4104 }
4105
4106 if (cp === $$1.QUOTATION_MARK) {
4107 this.currentToken.systemId = '';
4108 this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
4109 } else if (cp === $$1.APOSTROPHE) {
4110 this.currentToken.systemId = '';
4111 this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
4112 } else if (cp === $$1.GREATER_THAN_SIGN) {
4113 this._err(errorCodes.missingDoctypeSystemIdentifier);
4114
4115 this.currentToken.forceQuirks = true;
4116 this.state = DATA_STATE;
4117
4118 this._emitCurrentToken();
4119 } else if (cp === $$1.EOF) {
4120 this._err(errorCodes.eofInDoctype);
4121
4122 this.currentToken.forceQuirks = true;
4123
4124 this._emitCurrentToken();
4125
4126 this._emitEOFToken();
4127 } else {
4128 this._err(errorCodes.missingQuoteBeforeDoctypeSystemIdentifier);
4129
4130 this.currentToken.forceQuirks = true;
4131
4132 this._reconsumeInState(BOGUS_DOCTYPE_STATE);
4133 }
4134 } // DOCTYPE system identifier (double-quoted) state
4135 //------------------------------------------------------------------
4136
4137
4138 [DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE](cp) {
4139 if (cp === $$1.QUOTATION_MARK) {
4140 this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
4141 } else if (cp === $$1.NULL) {
4142 this._err(errorCodes.unexpectedNullCharacter);
4143
4144 this.currentToken.systemId += unicode.REPLACEMENT_CHARACTER;
4145 } else if (cp === $$1.GREATER_THAN_SIGN) {
4146 this._err(errorCodes.abruptDoctypeSystemIdentifier);
4147
4148 this.currentToken.forceQuirks = true;
4149
4150 this._emitCurrentToken();
4151
4152 this.state = DATA_STATE;
4153 } else if (cp === $$1.EOF) {
4154 this._err(errorCodes.eofInDoctype);
4155
4156 this.currentToken.forceQuirks = true;
4157
4158 this._emitCurrentToken();
4159
4160 this._emitEOFToken();
4161 } else {
4162 this.currentToken.systemId += toChar(cp);
4163 }
4164 } // DOCTYPE system identifier (single-quoted) state
4165 //------------------------------------------------------------------
4166
4167
4168 [DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE](cp) {
4169 if (cp === $$1.APOSTROPHE) {
4170 this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
4171 } else if (cp === $$1.NULL) {
4172 this._err(errorCodes.unexpectedNullCharacter);
4173
4174 this.currentToken.systemId += unicode.REPLACEMENT_CHARACTER;
4175 } else if (cp === $$1.GREATER_THAN_SIGN) {
4176 this._err(errorCodes.abruptDoctypeSystemIdentifier);
4177
4178 this.currentToken.forceQuirks = true;
4179
4180 this._emitCurrentToken();
4181
4182 this.state = DATA_STATE;
4183 } else if (cp === $$1.EOF) {
4184 this._err(errorCodes.eofInDoctype);
4185
4186 this.currentToken.forceQuirks = true;
4187
4188 this._emitCurrentToken();
4189
4190 this._emitEOFToken();
4191 } else {
4192 this.currentToken.systemId += toChar(cp);
4193 }
4194 } // After DOCTYPE system identifier state
4195 //------------------------------------------------------------------
4196
4197
4198 [AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE](cp) {
4199 if (isWhitespace(cp)) {
4200 return;
4201 }
4202
4203 if (cp === $$1.GREATER_THAN_SIGN) {
4204 this._emitCurrentToken();
4205
4206 this.state = DATA_STATE;
4207 } else if (cp === $$1.EOF) {
4208 this._err(errorCodes.eofInDoctype);
4209
4210 this.currentToken.forceQuirks = true;
4211
4212 this._emitCurrentToken();
4213
4214 this._emitEOFToken();
4215 } else {
4216 this._err(errorCodes.unexpectedCharacterAfterDoctypeSystemIdentifier);
4217
4218 this._reconsumeInState(BOGUS_DOCTYPE_STATE);
4219 }
4220 } // Bogus DOCTYPE state
4221 //------------------------------------------------------------------
4222
4223
4224 [BOGUS_DOCTYPE_STATE](cp) {
4225 if (cp === $$1.GREATER_THAN_SIGN) {
4226 this._emitCurrentToken();
4227
4228 this.state = DATA_STATE;
4229 } else if (cp === $$1.NULL) {
4230 this._err(errorCodes.unexpectedNullCharacter);
4231 } else if (cp === $$1.EOF) {
4232 this._emitCurrentToken();
4233
4234 this._emitEOFToken();
4235 }
4236 } // CDATA section state
4237 //------------------------------------------------------------------
4238
4239
4240 [CDATA_SECTION_STATE](cp) {
4241 if (cp === $$1.RIGHT_SQUARE_BRACKET) {
4242 this.state = CDATA_SECTION_BRACKET_STATE;
4243 } else if (cp === $$1.EOF) {
4244 this._err(errorCodes.eofInCdata);
4245
4246 this._emitEOFToken();
4247 } else {
4248 this._emitCodePoint(cp);
4249 }
4250 } // CDATA section bracket state
4251 //------------------------------------------------------------------
4252
4253
4254 [CDATA_SECTION_BRACKET_STATE](cp) {
4255 if (cp === $$1.RIGHT_SQUARE_BRACKET) {
4256 this.state = CDATA_SECTION_END_STATE;
4257 } else {
4258 this._emitChars(']');
4259
4260 this._reconsumeInState(CDATA_SECTION_STATE);
4261 }
4262 } // CDATA section end state
4263 //------------------------------------------------------------------
4264
4265
4266 [CDATA_SECTION_END_STATE](cp) {
4267 if (cp === $$1.GREATER_THAN_SIGN) {
4268 this.state = DATA_STATE;
4269 } else if (cp === $$1.RIGHT_SQUARE_BRACKET) {
4270 this._emitChars(']');
4271 } else {
4272 this._emitChars(']]');
4273
4274 this._reconsumeInState(CDATA_SECTION_STATE);
4275 }
4276 } // Character reference state
4277 //------------------------------------------------------------------
4278
4279
4280 [CHARACTER_REFERENCE_STATE](cp) {
4281 this.tempBuff = [$$1.AMPERSAND];
4282
4283 if (cp === $$1.NUMBER_SIGN) {
4284 this.tempBuff.push(cp);
4285 this.state = NUMERIC_CHARACTER_REFERENCE_STATE;
4286 } else if (isAsciiAlphaNumeric(cp)) {
4287 this._reconsumeInState(NAMED_CHARACTER_REFERENCE_STATE);
4288 } else {
4289 this._flushCodePointsConsumedAsCharacterReference();
4290
4291 this._reconsumeInState(this.returnState);
4292 }
4293 } // Named character reference state
4294 //------------------------------------------------------------------
4295
4296
4297 [NAMED_CHARACTER_REFERENCE_STATE](cp) {
4298 const matchResult = this._matchNamedCharacterReference(cp); //NOTE: matching can be abrupted by hibernation. In that case match
4299 //results are no longer valid and we will need to start over.
4300
4301
4302 if (this._ensureHibernation()) {
4303 this.tempBuff = [$$1.AMPERSAND];
4304 } else if (matchResult) {
4305 const withSemicolon = this.tempBuff[this.tempBuff.length - 1] === $$1.SEMICOLON;
4306
4307 if (!this._isCharacterReferenceAttributeQuirk(withSemicolon)) {
4308 if (!withSemicolon) {
4309 this._errOnNextCodePoint(errorCodes.missingSemicolonAfterCharacterReference);
4310 }
4311
4312 this.tempBuff = matchResult;
4313 }
4314
4315 this._flushCodePointsConsumedAsCharacterReference();
4316
4317 this.state = this.returnState;
4318 } else {
4319 this._flushCodePointsConsumedAsCharacterReference();
4320
4321 this.state = AMBIGUOUS_AMPERSAND_STATE;
4322 }
4323 } // Ambiguos ampersand state
4324 //------------------------------------------------------------------
4325
4326
4327 [AMBIGUOUS_AMPERSAND_STATE](cp) {
4328 if (isAsciiAlphaNumeric(cp)) {
4329 if (this._isCharacterReferenceInAttribute()) {
4330 this.currentAttr.value += toChar(cp);
4331 } else {
4332 this._emitCodePoint(cp);
4333 }
4334 } else {
4335 if (cp === $$1.SEMICOLON) {
4336 this._err(errorCodes.unknownNamedCharacterReference);
4337 }
4338
4339 this._reconsumeInState(this.returnState);
4340 }
4341 } // Numeric character reference state
4342 //------------------------------------------------------------------
4343
4344
4345 [NUMERIC_CHARACTER_REFERENCE_STATE](cp) {
4346 this.charRefCode = 0;
4347
4348 if (cp === $$1.LATIN_SMALL_X || cp === $$1.LATIN_CAPITAL_X) {
4349 this.tempBuff.push(cp);
4350 this.state = HEXADEMICAL_CHARACTER_REFERENCE_START_STATE;
4351 } else {
4352 this._reconsumeInState(DECIMAL_CHARACTER_REFERENCE_START_STATE);
4353 }
4354 } // Hexademical character reference start state
4355 //------------------------------------------------------------------
4356
4357
4358 [HEXADEMICAL_CHARACTER_REFERENCE_START_STATE](cp) {
4359 if (isAsciiHexDigit(cp)) {
4360 this._reconsumeInState(HEXADEMICAL_CHARACTER_REFERENCE_STATE);
4361 } else {
4362 this._err(errorCodes.absenceOfDigitsInNumericCharacterReference);
4363
4364 this._flushCodePointsConsumedAsCharacterReference();
4365
4366 this._reconsumeInState(this.returnState);
4367 }
4368 } // Decimal character reference start state
4369 //------------------------------------------------------------------
4370
4371
4372 [DECIMAL_CHARACTER_REFERENCE_START_STATE](cp) {
4373 if (isAsciiDigit(cp)) {
4374 this._reconsumeInState(DECIMAL_CHARACTER_REFERENCE_STATE);
4375 } else {
4376 this._err(errorCodes.absenceOfDigitsInNumericCharacterReference);
4377
4378 this._flushCodePointsConsumedAsCharacterReference();
4379
4380 this._reconsumeInState(this.returnState);
4381 }
4382 } // Hexademical character reference state
4383 //------------------------------------------------------------------
4384
4385
4386 [HEXADEMICAL_CHARACTER_REFERENCE_STATE](cp) {
4387 if (isAsciiUpperHexDigit(cp)) {
4388 this.charRefCode = this.charRefCode * 16 + cp - 0x37;
4389 } else if (isAsciiLowerHexDigit(cp)) {
4390 this.charRefCode = this.charRefCode * 16 + cp - 0x57;
4391 } else if (isAsciiDigit(cp)) {
4392 this.charRefCode = this.charRefCode * 16 + cp - 0x30;
4393 } else if (cp === $$1.SEMICOLON) {
4394 this.state = NUMERIC_CHARACTER_REFERENCE_END_STATE;
4395 } else {
4396 this._err(errorCodes.missingSemicolonAfterCharacterReference);
4397
4398 this._reconsumeInState(NUMERIC_CHARACTER_REFERENCE_END_STATE);
4399 }
4400 } // Decimal character reference state
4401 //------------------------------------------------------------------
4402
4403
4404 [DECIMAL_CHARACTER_REFERENCE_STATE](cp) {
4405 if (isAsciiDigit(cp)) {
4406 this.charRefCode = this.charRefCode * 10 + cp - 0x30;
4407 } else if (cp === $$1.SEMICOLON) {
4408 this.state = NUMERIC_CHARACTER_REFERENCE_END_STATE;
4409 } else {
4410 this._err(errorCodes.missingSemicolonAfterCharacterReference);
4411
4412 this._reconsumeInState(NUMERIC_CHARACTER_REFERENCE_END_STATE);
4413 }
4414 } // Numeric character reference end state
4415 //------------------------------------------------------------------
4416
4417
4418 [NUMERIC_CHARACTER_REFERENCE_END_STATE]() {
4419 if (this.charRefCode === $$1.NULL) {
4420 this._err(errorCodes.nullCharacterReference);
4421
4422 this.charRefCode = $$1.REPLACEMENT_CHARACTER;
4423 } else if (this.charRefCode > 0x10ffff) {
4424 this._err(errorCodes.characterReferenceOutsideUnicodeRange);
4425
4426 this.charRefCode = $$1.REPLACEMENT_CHARACTER;
4427 } else if (unicode.isSurrogate(this.charRefCode)) {
4428 this._err(errorCodes.surrogateCharacterReference);
4429
4430 this.charRefCode = $$1.REPLACEMENT_CHARACTER;
4431 } else if (unicode.isUndefinedCodePoint(this.charRefCode)) {
4432 this._err(errorCodes.noncharacterCharacterReference);
4433 } else if (unicode.isControlCodePoint(this.charRefCode) || this.charRefCode === $$1.CARRIAGE_RETURN) {
4434 this._err(errorCodes.controlCharacterReference);
4435
4436 const replacement = C1_CONTROLS_REFERENCE_REPLACEMENTS[this.charRefCode];
4437
4438 if (replacement) {
4439 this.charRefCode = replacement;
4440 }
4441 }
4442
4443 this.tempBuff = [this.charRefCode];
4444
4445 this._flushCodePointsConsumedAsCharacterReference();
4446
4447 this._reconsumeInState(this.returnState);
4448 }
4449
4450} //Token types
4451
4452
4453Tokenizer.CHARACTER_TOKEN = 'CHARACTER_TOKEN';
4454Tokenizer.NULL_CHARACTER_TOKEN = 'NULL_CHARACTER_TOKEN';
4455Tokenizer.WHITESPACE_CHARACTER_TOKEN = 'WHITESPACE_CHARACTER_TOKEN';
4456Tokenizer.START_TAG_TOKEN = 'START_TAG_TOKEN';
4457Tokenizer.END_TAG_TOKEN = 'END_TAG_TOKEN';
4458Tokenizer.COMMENT_TOKEN = 'COMMENT_TOKEN';
4459Tokenizer.DOCTYPE_TOKEN = 'DOCTYPE_TOKEN';
4460Tokenizer.EOF_TOKEN = 'EOF_TOKEN';
4461Tokenizer.HIBERNATION_TOKEN = 'HIBERNATION_TOKEN'; //Tokenizer initial states for different modes
4462
4463Tokenizer.MODE = {
4464 DATA: DATA_STATE,
4465 RCDATA: RCDATA_STATE,
4466 RAWTEXT: RAWTEXT_STATE,
4467 SCRIPT_DATA: SCRIPT_DATA_STATE,
4468 PLAINTEXT: PLAINTEXT_STATE
4469}; //Static
4470
4471Tokenizer.getTokenAttr = function (token, attrName) {
4472 for (let i = token.attrs.length - 1; i >= 0; i--) {
4473 if (token.attrs[i].name === attrName) {
4474 return token.attrs[i].value;
4475 }
4476 }
4477
4478 return null;
4479};
4480
4481var tokenizer = Tokenizer;
4482
4483function createCommonjsModule(fn, module) {
4484 return module = { exports: {} }, fn(module, module.exports), module.exports;
4485}
4486
4487var html = createCommonjsModule(function (module, exports) {
4488
4489 const NS = exports.NAMESPACES = {
4490 HTML: 'http://www.w3.org/1999/xhtml',
4491 MATHML: 'http://www.w3.org/1998/Math/MathML',
4492 SVG: 'http://www.w3.org/2000/svg',
4493 XLINK: 'http://www.w3.org/1999/xlink',
4494 XML: 'http://www.w3.org/XML/1998/namespace',
4495 XMLNS: 'http://www.w3.org/2000/xmlns/'
4496 };
4497 exports.ATTRS = {
4498 TYPE: 'type',
4499 ACTION: 'action',
4500 ENCODING: 'encoding',
4501 PROMPT: 'prompt',
4502 NAME: 'name',
4503 COLOR: 'color',
4504 FACE: 'face',
4505 SIZE: 'size'
4506 };
4507 exports.DOCUMENT_MODE = {
4508 NO_QUIRKS: 'no-quirks',
4509 QUIRKS: 'quirks',
4510 LIMITED_QUIRKS: 'limited-quirks'
4511 };
4512 const $ = exports.TAG_NAMES = {
4513 A: 'a',
4514 ADDRESS: 'address',
4515 ANNOTATION_XML: 'annotation-xml',
4516 APPLET: 'applet',
4517 AREA: 'area',
4518 ARTICLE: 'article',
4519 ASIDE: 'aside',
4520 B: 'b',
4521 BASE: 'base',
4522 BASEFONT: 'basefont',
4523 BGSOUND: 'bgsound',
4524 BIG: 'big',
4525 BLOCKQUOTE: 'blockquote',
4526 BODY: 'body',
4527 BR: 'br',
4528 BUTTON: 'button',
4529 CAPTION: 'caption',
4530 CENTER: 'center',
4531 CODE: 'code',
4532 COL: 'col',
4533 COLGROUP: 'colgroup',
4534 DD: 'dd',
4535 DESC: 'desc',
4536 DETAILS: 'details',
4537 DIALOG: 'dialog',
4538 DIR: 'dir',
4539 DIV: 'div',
4540 DL: 'dl',
4541 DT: 'dt',
4542 EM: 'em',
4543 EMBED: 'embed',
4544 FIELDSET: 'fieldset',
4545 FIGCAPTION: 'figcaption',
4546 FIGURE: 'figure',
4547 FONT: 'font',
4548 FOOTER: 'footer',
4549 FOREIGN_OBJECT: 'foreignObject',
4550 FORM: 'form',
4551 FRAME: 'frame',
4552 FRAMESET: 'frameset',
4553 H1: 'h1',
4554 H2: 'h2',
4555 H3: 'h3',
4556 H4: 'h4',
4557 H5: 'h5',
4558 H6: 'h6',
4559 HEAD: 'head',
4560 HEADER: 'header',
4561 HGROUP: 'hgroup',
4562 HR: 'hr',
4563 HTML: 'html',
4564 I: 'i',
4565 IMG: 'img',
4566 IMAGE: 'image',
4567 INPUT: 'input',
4568 IFRAME: 'iframe',
4569 KEYGEN: 'keygen',
4570 LABEL: 'label',
4571 LI: 'li',
4572 LINK: 'link',
4573 LISTING: 'listing',
4574 MAIN: 'main',
4575 MALIGNMARK: 'malignmark',
4576 MARQUEE: 'marquee',
4577 MATH: 'math',
4578 MENU: 'menu',
4579 META: 'meta',
4580 MGLYPH: 'mglyph',
4581 MI: 'mi',
4582 MO: 'mo',
4583 MN: 'mn',
4584 MS: 'ms',
4585 MTEXT: 'mtext',
4586 NAV: 'nav',
4587 NOBR: 'nobr',
4588 NOFRAMES: 'noframes',
4589 NOEMBED: 'noembed',
4590 NOSCRIPT: 'noscript',
4591 OBJECT: 'object',
4592 OL: 'ol',
4593 OPTGROUP: 'optgroup',
4594 OPTION: 'option',
4595 P: 'p',
4596 PARAM: 'param',
4597 PLAINTEXT: 'plaintext',
4598 PRE: 'pre',
4599 RB: 'rb',
4600 RP: 'rp',
4601 RT: 'rt',
4602 RTC: 'rtc',
4603 RUBY: 'ruby',
4604 S: 's',
4605 SCRIPT: 'script',
4606 SECTION: 'section',
4607 SELECT: 'select',
4608 SOURCE: 'source',
4609 SMALL: 'small',
4610 SPAN: 'span',
4611 STRIKE: 'strike',
4612 STRONG: 'strong',
4613 STYLE: 'style',
4614 SUB: 'sub',
4615 SUMMARY: 'summary',
4616 SUP: 'sup',
4617 TABLE: 'table',
4618 TBODY: 'tbody',
4619 TEMPLATE: 'template',
4620 TEXTAREA: 'textarea',
4621 TFOOT: 'tfoot',
4622 TD: 'td',
4623 TH: 'th',
4624 THEAD: 'thead',
4625 TITLE: 'title',
4626 TR: 'tr',
4627 TRACK: 'track',
4628 TT: 'tt',
4629 U: 'u',
4630 UL: 'ul',
4631 SVG: 'svg',
4632 VAR: 'var',
4633 WBR: 'wbr',
4634 XMP: 'xmp'
4635 };
4636 exports.SPECIAL_ELEMENTS = {
4637 [NS.HTML]: {
4638 [$.ADDRESS]: true,
4639 [$.APPLET]: true,
4640 [$.AREA]: true,
4641 [$.ARTICLE]: true,
4642 [$.ASIDE]: true,
4643 [$.BASE]: true,
4644 [$.BASEFONT]: true,
4645 [$.BGSOUND]: true,
4646 [$.BLOCKQUOTE]: true,
4647 [$.BODY]: true,
4648 [$.BR]: true,
4649 [$.BUTTON]: true,
4650 [$.CAPTION]: true,
4651 [$.CENTER]: true,
4652 [$.COL]: true,
4653 [$.COLGROUP]: true,
4654 [$.DD]: true,
4655 [$.DETAILS]: true,
4656 [$.DIR]: true,
4657 [$.DIV]: true,
4658 [$.DL]: true,
4659 [$.DT]: true,
4660 [$.EMBED]: true,
4661 [$.FIELDSET]: true,
4662 [$.FIGCAPTION]: true,
4663 [$.FIGURE]: true,
4664 [$.FOOTER]: true,
4665 [$.FORM]: true,
4666 [$.FRAME]: true,
4667 [$.FRAMESET]: true,
4668 [$.H1]: true,
4669 [$.H2]: true,
4670 [$.H3]: true,
4671 [$.H4]: true,
4672 [$.H5]: true,
4673 [$.H6]: true,
4674 [$.HEAD]: true,
4675 [$.HEADER]: true,
4676 [$.HGROUP]: true,
4677 [$.HR]: true,
4678 [$.HTML]: true,
4679 [$.IFRAME]: true,
4680 [$.IMG]: true,
4681 [$.INPUT]: true,
4682 [$.LI]: true,
4683 [$.LINK]: true,
4684 [$.LISTING]: true,
4685 [$.MAIN]: true,
4686 [$.MARQUEE]: true,
4687 [$.MENU]: true,
4688 [$.META]: true,
4689 [$.NAV]: true,
4690 [$.NOEMBED]: true,
4691 [$.NOFRAMES]: true,
4692 [$.NOSCRIPT]: true,
4693 [$.OBJECT]: true,
4694 [$.OL]: true,
4695 [$.P]: true,
4696 [$.PARAM]: true,
4697 [$.PLAINTEXT]: true,
4698 [$.PRE]: true,
4699 [$.SCRIPT]: true,
4700 [$.SECTION]: true,
4701 [$.SELECT]: true,
4702 [$.SOURCE]: true,
4703 [$.STYLE]: true,
4704 [$.SUMMARY]: true,
4705 [$.TABLE]: true,
4706 [$.TBODY]: true,
4707 [$.TD]: true,
4708 [$.TEMPLATE]: true,
4709 [$.TEXTAREA]: true,
4710 [$.TFOOT]: true,
4711 [$.TH]: true,
4712 [$.THEAD]: true,
4713 [$.TITLE]: true,
4714 [$.TR]: true,
4715 [$.TRACK]: true,
4716 [$.UL]: true,
4717 [$.WBR]: true,
4718 [$.XMP]: true
4719 },
4720 [NS.MATHML]: {
4721 [$.MI]: true,
4722 [$.MO]: true,
4723 [$.MN]: true,
4724 [$.MS]: true,
4725 [$.MTEXT]: true,
4726 [$.ANNOTATION_XML]: true
4727 },
4728 [NS.SVG]: {
4729 [$.TITLE]: true,
4730 [$.FOREIGN_OBJECT]: true,
4731 [$.DESC]: true
4732 }
4733 };
4734});
4735var html_1 = html.NAMESPACES;
4736var html_2 = html.ATTRS;
4737var html_3 = html.DOCUMENT_MODE;
4738var html_4 = html.TAG_NAMES;
4739var html_5 = html.SPECIAL_ELEMENTS;
4740
4741const $$2 = html.TAG_NAMES;
4742const NS = html.NAMESPACES; //Element utils
4743//OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
4744//It's faster than using dictionary.
4745
4746function isImpliedEndTagRequired(tn) {
4747 switch (tn.length) {
4748 case 1:
4749 return tn === $$2.P;
4750
4751 case 2:
4752 return tn === $$2.RB || tn === $$2.RP || tn === $$2.RT || tn === $$2.DD || tn === $$2.DT || tn === $$2.LI;
4753
4754 case 3:
4755 return tn === $$2.RTC;
4756
4757 case 6:
4758 return tn === $$2.OPTION;
4759
4760 case 8:
4761 return tn === $$2.OPTGROUP;
4762 }
4763
4764 return false;
4765}
4766
4767function isImpliedEndTagRequiredThoroughly(tn) {
4768 switch (tn.length) {
4769 case 1:
4770 return tn === $$2.P;
4771
4772 case 2:
4773 return tn === $$2.RB || tn === $$2.RP || tn === $$2.RT || tn === $$2.DD || tn === $$2.DT || tn === $$2.LI || tn === $$2.TD || tn === $$2.TH || tn === $$2.TR;
4774
4775 case 3:
4776 return tn === $$2.RTC;
4777
4778 case 5:
4779 return tn === $$2.TBODY || tn === $$2.TFOOT || tn === $$2.THEAD;
4780
4781 case 6:
4782 return tn === $$2.OPTION;
4783
4784 case 7:
4785 return tn === $$2.CAPTION;
4786
4787 case 8:
4788 return tn === $$2.OPTGROUP || tn === $$2.COLGROUP;
4789 }
4790
4791 return false;
4792}
4793
4794function isScopingElement(tn, ns) {
4795 switch (tn.length) {
4796 case 2:
4797 if (tn === $$2.TD || tn === $$2.TH) {
4798 return ns === NS.HTML;
4799 } else if (tn === $$2.MI || tn === $$2.MO || tn === $$2.MN || tn === $$2.MS) {
4800 return ns === NS.MATHML;
4801 }
4802
4803 break;
4804
4805 case 4:
4806 if (tn === $$2.HTML) {
4807 return ns === NS.HTML;
4808 } else if (tn === $$2.DESC) {
4809 return ns === NS.SVG;
4810 }
4811
4812 break;
4813
4814 case 5:
4815 if (tn === $$2.TABLE) {
4816 return ns === NS.HTML;
4817 } else if (tn === $$2.MTEXT) {
4818 return ns === NS.MATHML;
4819 } else if (tn === $$2.TITLE) {
4820 return ns === NS.SVG;
4821 }
4822
4823 break;
4824
4825 case 6:
4826 return (tn === $$2.APPLET || tn === $$2.OBJECT) && ns === NS.HTML;
4827
4828 case 7:
4829 return (tn === $$2.CAPTION || tn === $$2.MARQUEE) && ns === NS.HTML;
4830
4831 case 8:
4832 return tn === $$2.TEMPLATE && ns === NS.HTML;
4833
4834 case 13:
4835 return tn === $$2.FOREIGN_OBJECT && ns === NS.SVG;
4836
4837 case 14:
4838 return tn === $$2.ANNOTATION_XML && ns === NS.MATHML;
4839 }
4840
4841 return false;
4842} //Stack of open elements
4843
4844
4845class OpenElementStack {
4846 constructor(document, treeAdapter) {
4847 this.stackTop = -1;
4848 this.items = [];
4849 this.current = document;
4850 this.currentTagName = null;
4851 this.currentTmplContent = null;
4852 this.tmplCount = 0;
4853 this.treeAdapter = treeAdapter;
4854 } //Index of element
4855
4856
4857 _indexOf(element) {
4858 let idx = -1;
4859
4860 for (let i = this.stackTop; i >= 0; i--) {
4861 if (this.items[i] === element) {
4862 idx = i;
4863 break;
4864 }
4865 }
4866
4867 return idx;
4868 } //Update current element
4869
4870
4871 _isInTemplate() {
4872 return this.currentTagName === $$2.TEMPLATE && this.treeAdapter.getNamespaceURI(this.current) === NS.HTML;
4873 }
4874
4875 _updateCurrentElement() {
4876 this.current = this.items[this.stackTop];
4877 this.currentTagName = this.current && this.treeAdapter.getTagName(this.current);
4878 this.currentTmplContent = this._isInTemplate() ? this.treeAdapter.getTemplateContent(this.current) : null;
4879 } //Mutations
4880
4881
4882 push(element) {
4883 this.items[++this.stackTop] = element;
4884
4885 this._updateCurrentElement();
4886
4887 if (this._isInTemplate()) {
4888 this.tmplCount++;
4889 }
4890 }
4891
4892 pop() {
4893 this.stackTop--;
4894
4895 if (this.tmplCount > 0 && this._isInTemplate()) {
4896 this.tmplCount--;
4897 }
4898
4899 this._updateCurrentElement();
4900 }
4901
4902 replace(oldElement, newElement) {
4903 const idx = this._indexOf(oldElement);
4904
4905 this.items[idx] = newElement;
4906
4907 if (idx === this.stackTop) {
4908 this._updateCurrentElement();
4909 }
4910 }
4911
4912 insertAfter(referenceElement, newElement) {
4913 const insertionIdx = this._indexOf(referenceElement) + 1;
4914 this.items.splice(insertionIdx, 0, newElement);
4915
4916 if (insertionIdx === ++this.stackTop) {
4917 this._updateCurrentElement();
4918 }
4919 }
4920
4921 popUntilTagNamePopped(tagName) {
4922 while (this.stackTop > -1) {
4923 const tn = this.currentTagName;
4924 const ns = this.treeAdapter.getNamespaceURI(this.current);
4925 this.pop();
4926
4927 if (tn === tagName && ns === NS.HTML) {
4928 break;
4929 }
4930 }
4931 }
4932
4933 popUntilElementPopped(element) {
4934 while (this.stackTop > -1) {
4935 const poppedElement = this.current;
4936 this.pop();
4937
4938 if (poppedElement === element) {
4939 break;
4940 }
4941 }
4942 }
4943
4944 popUntilNumberedHeaderPopped() {
4945 while (this.stackTop > -1) {
4946 const tn = this.currentTagName;
4947 const ns = this.treeAdapter.getNamespaceURI(this.current);
4948 this.pop();
4949
4950 if (tn === $$2.H1 || tn === $$2.H2 || tn === $$2.H3 || tn === $$2.H4 || tn === $$2.H5 || tn === $$2.H6 && ns === NS.HTML) {
4951 break;
4952 }
4953 }
4954 }
4955
4956 popUntilTableCellPopped() {
4957 while (this.stackTop > -1) {
4958 const tn = this.currentTagName;
4959 const ns = this.treeAdapter.getNamespaceURI(this.current);
4960 this.pop();
4961
4962 if (tn === $$2.TD || tn === $$2.TH && ns === NS.HTML) {
4963 break;
4964 }
4965 }
4966 }
4967
4968 popAllUpToHtmlElement() {
4969 //NOTE: here we assume that root <html> element is always first in the open element stack, so
4970 //we perform this fast stack clean up.
4971 this.stackTop = 0;
4972
4973 this._updateCurrentElement();
4974 }
4975
4976 clearBackToTableContext() {
4977 while (this.currentTagName !== $$2.TABLE && this.currentTagName !== $$2.TEMPLATE && this.currentTagName !== $$2.HTML || this.treeAdapter.getNamespaceURI(this.current) !== NS.HTML) {
4978 this.pop();
4979 }
4980 }
4981
4982 clearBackToTableBodyContext() {
4983 while (this.currentTagName !== $$2.TBODY && this.currentTagName !== $$2.TFOOT && this.currentTagName !== $$2.THEAD && this.currentTagName !== $$2.TEMPLATE && this.currentTagName !== $$2.HTML || this.treeAdapter.getNamespaceURI(this.current) !== NS.HTML) {
4984 this.pop();
4985 }
4986 }
4987
4988 clearBackToTableRowContext() {
4989 while (this.currentTagName !== $$2.TR && this.currentTagName !== $$2.TEMPLATE && this.currentTagName !== $$2.HTML || this.treeAdapter.getNamespaceURI(this.current) !== NS.HTML) {
4990 this.pop();
4991 }
4992 }
4993
4994 remove(element) {
4995 for (let i = this.stackTop; i >= 0; i--) {
4996 if (this.items[i] === element) {
4997 this.items.splice(i, 1);
4998 this.stackTop--;
4999
5000 this._updateCurrentElement();
5001
5002 break;
5003 }
5004 }
5005 } //Search
5006
5007
5008 tryPeekProperlyNestedBodyElement() {
5009 //Properly nested <body> element (should be second element in stack).
5010 const element = this.items[1];
5011 return element && this.treeAdapter.getTagName(element) === $$2.BODY ? element : null;
5012 }
5013
5014 contains(element) {
5015 return this._indexOf(element) > -1;
5016 }
5017
5018 getCommonAncestor(element) {
5019 let elementIdx = this._indexOf(element);
5020
5021 return --elementIdx >= 0 ? this.items[elementIdx] : null;
5022 }
5023
5024 isRootHtmlElementCurrent() {
5025 return this.stackTop === 0 && this.currentTagName === $$2.HTML;
5026 } //Element in scope
5027
5028
5029 hasInScope(tagName) {
5030 for (let i = this.stackTop; i >= 0; i--) {
5031 const tn = this.treeAdapter.getTagName(this.items[i]);
5032 const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
5033
5034 if (tn === tagName && ns === NS.HTML) {
5035 return true;
5036 }
5037
5038 if (isScopingElement(tn, ns)) {
5039 return false;
5040 }
5041 }
5042
5043 return true;
5044 }
5045
5046 hasNumberedHeaderInScope() {
5047 for (let i = this.stackTop; i >= 0; i--) {
5048 const tn = this.treeAdapter.getTagName(this.items[i]);
5049 const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
5050
5051 if ((tn === $$2.H1 || tn === $$2.H2 || tn === $$2.H3 || tn === $$2.H4 || tn === $$2.H5 || tn === $$2.H6) && ns === NS.HTML) {
5052 return true;
5053 }
5054
5055 if (isScopingElement(tn, ns)) {
5056 return false;
5057 }
5058 }
5059
5060 return true;
5061 }
5062
5063 hasInListItemScope(tagName) {
5064 for (let i = this.stackTop; i >= 0; i--) {
5065 const tn = this.treeAdapter.getTagName(this.items[i]);
5066 const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
5067
5068 if (tn === tagName && ns === NS.HTML) {
5069 return true;
5070 }
5071
5072 if ((tn === $$2.UL || tn === $$2.OL) && ns === NS.HTML || isScopingElement(tn, ns)) {
5073 return false;
5074 }
5075 }
5076
5077 return true;
5078 }
5079
5080 hasInButtonScope(tagName) {
5081 for (let i = this.stackTop; i >= 0; i--) {
5082 const tn = this.treeAdapter.getTagName(this.items[i]);
5083 const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
5084
5085 if (tn === tagName && ns === NS.HTML) {
5086 return true;
5087 }
5088
5089 if (tn === $$2.BUTTON && ns === NS.HTML || isScopingElement(tn, ns)) {
5090 return false;
5091 }
5092 }
5093
5094 return true;
5095 }
5096
5097 hasInTableScope(tagName) {
5098 for (let i = this.stackTop; i >= 0; i--) {
5099 const tn = this.treeAdapter.getTagName(this.items[i]);
5100 const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
5101
5102 if (ns !== NS.HTML) {
5103 continue;
5104 }
5105
5106 if (tn === tagName) {
5107 return true;
5108 }
5109
5110 if (tn === $$2.TABLE || tn === $$2.TEMPLATE || tn === $$2.HTML) {
5111 return false;
5112 }
5113 }
5114
5115 return true;
5116 }
5117
5118 hasTableBodyContextInTableScope() {
5119 for (let i = this.stackTop; i >= 0; i--) {
5120 const tn = this.treeAdapter.getTagName(this.items[i]);
5121 const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
5122
5123 if (ns !== NS.HTML) {
5124 continue;
5125 }
5126
5127 if (tn === $$2.TBODY || tn === $$2.THEAD || tn === $$2.TFOOT) {
5128 return true;
5129 }
5130
5131 if (tn === $$2.TABLE || tn === $$2.HTML) {
5132 return false;
5133 }
5134 }
5135
5136 return true;
5137 }
5138
5139 hasInSelectScope(tagName) {
5140 for (let i = this.stackTop; i >= 0; i--) {
5141 const tn = this.treeAdapter.getTagName(this.items[i]);
5142 const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
5143
5144 if (ns !== NS.HTML) {
5145 continue;
5146 }
5147
5148 if (tn === tagName) {
5149 return true;
5150 }
5151
5152 if (tn !== $$2.OPTION && tn !== $$2.OPTGROUP) {
5153 return false;
5154 }
5155 }
5156
5157 return true;
5158 } //Implied end tags
5159
5160
5161 generateImpliedEndTags() {
5162 while (isImpliedEndTagRequired(this.currentTagName)) {
5163 this.pop();
5164 }
5165 }
5166
5167 generateImpliedEndTagsThoroughly() {
5168 while (isImpliedEndTagRequiredThoroughly(this.currentTagName)) {
5169 this.pop();
5170 }
5171 }
5172
5173 generateImpliedEndTagsWithExclusion(exclusionTagName) {
5174 while (isImpliedEndTagRequired(this.currentTagName) && this.currentTagName !== exclusionTagName) {
5175 this.pop();
5176 }
5177 }
5178
5179}
5180
5181var openElementStack = OpenElementStack;
5182
5183const NOAH_ARK_CAPACITY = 3; //List of formatting elements
5184
5185class FormattingElementList {
5186 constructor(treeAdapter) {
5187 this.length = 0;
5188 this.entries = [];
5189 this.treeAdapter = treeAdapter;
5190 this.bookmark = null;
5191 } //Noah Ark's condition
5192 //OPTIMIZATION: at first we try to find possible candidates for exclusion using
5193 //lightweight heuristics without thorough attributes check.
5194
5195
5196 _getNoahArkConditionCandidates(newElement) {
5197 const candidates = [];
5198
5199 if (this.length >= NOAH_ARK_CAPACITY) {
5200 const neAttrsLength = this.treeAdapter.getAttrList(newElement).length;
5201 const neTagName = this.treeAdapter.getTagName(newElement);
5202 const neNamespaceURI = this.treeAdapter.getNamespaceURI(newElement);
5203
5204 for (let i = this.length - 1; i >= 0; i--) {
5205 const entry = this.entries[i];
5206
5207 if (entry.type === FormattingElementList.MARKER_ENTRY) {
5208 break;
5209 }
5210
5211 const element = entry.element;
5212 const elementAttrs = this.treeAdapter.getAttrList(element);
5213 const isCandidate = this.treeAdapter.getTagName(element) === neTagName && this.treeAdapter.getNamespaceURI(element) === neNamespaceURI && elementAttrs.length === neAttrsLength;
5214
5215 if (isCandidate) {
5216 candidates.push({
5217 idx: i,
5218 attrs: elementAttrs
5219 });
5220 }
5221 }
5222 }
5223
5224 return candidates.length < NOAH_ARK_CAPACITY ? [] : candidates;
5225 }
5226
5227 _ensureNoahArkCondition(newElement) {
5228 const candidates = this._getNoahArkConditionCandidates(newElement);
5229
5230 let cLength = candidates.length;
5231
5232 if (cLength) {
5233 const neAttrs = this.treeAdapter.getAttrList(newElement);
5234 const neAttrsLength = neAttrs.length;
5235 const neAttrsMap = Object.create(null); //NOTE: build attrs map for the new element so we can perform fast lookups
5236
5237 for (let i = 0; i < neAttrsLength; i++) {
5238 const neAttr = neAttrs[i];
5239 neAttrsMap[neAttr.name] = neAttr.value;
5240 }
5241
5242 for (let i = 0; i < neAttrsLength; i++) {
5243 for (let j = 0; j < cLength; j++) {
5244 const cAttr = candidates[j].attrs[i];
5245
5246 if (neAttrsMap[cAttr.name] !== cAttr.value) {
5247 candidates.splice(j, 1);
5248 cLength--;
5249 }
5250
5251 if (candidates.length < NOAH_ARK_CAPACITY) {
5252 return;
5253 }
5254 }
5255 } //NOTE: remove bottommost candidates until Noah's Ark condition will not be met
5256
5257
5258 for (let i = cLength - 1; i >= NOAH_ARK_CAPACITY - 1; i--) {
5259 this.entries.splice(candidates[i].idx, 1);
5260 this.length--;
5261 }
5262 }
5263 } //Mutations
5264
5265
5266 insertMarker() {
5267 this.entries.push({
5268 type: FormattingElementList.MARKER_ENTRY
5269 });
5270 this.length++;
5271 }
5272
5273 pushElement(element, token) {
5274 this._ensureNoahArkCondition(element);
5275
5276 this.entries.push({
5277 type: FormattingElementList.ELEMENT_ENTRY,
5278 element: element,
5279 token: token
5280 });
5281 this.length++;
5282 }
5283
5284 insertElementAfterBookmark(element, token) {
5285 let bookmarkIdx = this.length - 1;
5286
5287 for (; bookmarkIdx >= 0; bookmarkIdx--) {
5288 if (this.entries[bookmarkIdx] === this.bookmark) {
5289 break;
5290 }
5291 }
5292
5293 this.entries.splice(bookmarkIdx + 1, 0, {
5294 type: FormattingElementList.ELEMENT_ENTRY,
5295 element: element,
5296 token: token
5297 });
5298 this.length++;
5299 }
5300
5301 removeEntry(entry) {
5302 for (let i = this.length - 1; i >= 0; i--) {
5303 if (this.entries[i] === entry) {
5304 this.entries.splice(i, 1);
5305 this.length--;
5306 break;
5307 }
5308 }
5309 }
5310
5311 clearToLastMarker() {
5312 while (this.length) {
5313 const entry = this.entries.pop();
5314 this.length--;
5315
5316 if (entry.type === FormattingElementList.MARKER_ENTRY) {
5317 break;
5318 }
5319 }
5320 } //Search
5321
5322
5323 getElementEntryInScopeWithTagName(tagName) {
5324 for (let i = this.length - 1; i >= 0; i--) {
5325 const entry = this.entries[i];
5326
5327 if (entry.type === FormattingElementList.MARKER_ENTRY) {
5328 return null;
5329 }
5330
5331 if (this.treeAdapter.getTagName(entry.element) === tagName) {
5332 return entry;
5333 }
5334 }
5335
5336 return null;
5337 }
5338
5339 getElementEntry(element) {
5340 for (let i = this.length - 1; i >= 0; i--) {
5341 const entry = this.entries[i];
5342
5343 if (entry.type === FormattingElementList.ELEMENT_ENTRY && entry.element === element) {
5344 return entry;
5345 }
5346 }
5347
5348 return null;
5349 }
5350
5351} //Entry types
5352
5353
5354FormattingElementList.MARKER_ENTRY = 'MARKER_ENTRY';
5355FormattingElementList.ELEMENT_ENTRY = 'ELEMENT_ENTRY';
5356var formattingElementList = FormattingElementList;
5357
5358class Mixin {
5359 constructor(host) {
5360 const originalMethods = {};
5361
5362 const overriddenMethods = this._getOverriddenMethods(this, originalMethods);
5363
5364 for (let _i = 0, _Object$keys = Object.keys(overriddenMethods), _length = _Object$keys == null ? 0 : _Object$keys.length; _i < _length; _i++) {
5365 const key = _Object$keys[_i];
5366
5367 if (typeof overriddenMethods[key] === 'function') {
5368 originalMethods[key] = host[key];
5369 host[key] = overriddenMethods[key];
5370 }
5371 }
5372 }
5373
5374 _getOverriddenMethods() {
5375 throw new Error('Not implemented');
5376 }
5377
5378}
5379
5380Mixin.install = function (host, Ctor, opts) {
5381 if (!host.__mixins) {
5382 host.__mixins = [];
5383 }
5384
5385 for (let i = 0; i < host.__mixins.length; i++) {
5386 if (host.__mixins[i].constructor === Ctor) {
5387 return host.__mixins[i];
5388 }
5389 }
5390
5391 const mixin = new Ctor(host, opts);
5392
5393 host.__mixins.push(mixin);
5394
5395 return mixin;
5396};
5397
5398var mixin = Mixin;
5399
5400class PositionTrackingPreprocessorMixin extends mixin {
5401 constructor(preprocessor) {
5402 super(preprocessor);
5403 this.preprocessor = preprocessor;
5404 this.isEol = false;
5405 this.lineStartPos = 0;
5406 this.droppedBufferSize = 0;
5407 this.offset = 0;
5408 this.col = 0;
5409 this.line = 1;
5410 }
5411
5412 _getOverriddenMethods(mxn, orig) {
5413 return {
5414 advance() {
5415 const pos = this.pos + 1;
5416 const ch = this.html[pos]; //NOTE: LF should be in the last column of the line
5417
5418 if (mxn.isEol) {
5419 mxn.isEol = false;
5420 mxn.line++;
5421 mxn.lineStartPos = pos;
5422 }
5423
5424 if (ch === '\n' || ch === '\r' && this.html[pos + 1] !== '\n') {
5425 mxn.isEol = true;
5426 }
5427
5428 mxn.col = pos - mxn.lineStartPos + 1;
5429 mxn.offset = mxn.droppedBufferSize + pos;
5430 return orig.advance.call(this);
5431 },
5432
5433 retreat() {
5434 orig.retreat.call(this);
5435 mxn.isEol = false;
5436 mxn.col = this.pos - mxn.lineStartPos + 1;
5437 },
5438
5439 dropParsedChunk() {
5440 const prevPos = this.pos;
5441 orig.dropParsedChunk.call(this);
5442 const reduction = prevPos - this.pos;
5443 mxn.lineStartPos -= reduction;
5444 mxn.droppedBufferSize += reduction;
5445 mxn.offset = mxn.droppedBufferSize + this.pos;
5446 }
5447
5448 };
5449 }
5450
5451}
5452
5453var preprocessorMixin = PositionTrackingPreprocessorMixin;
5454
5455class LocationInfoTokenizerMixin extends mixin {
5456 constructor(tokenizer) {
5457 super(tokenizer);
5458 this.tokenizer = tokenizer;
5459 this.posTracker = mixin.install(tokenizer.preprocessor, preprocessorMixin);
5460 this.currentAttrLocation = null;
5461 this.ctLoc = null;
5462 }
5463
5464 _getCurrentLocation() {
5465 return {
5466 startLine: this.posTracker.line,
5467 startCol: this.posTracker.col,
5468 startOffset: this.posTracker.offset,
5469 endLine: -1,
5470 endCol: -1,
5471 endOffset: -1
5472 };
5473 }
5474
5475 _attachCurrentAttrLocationInfo() {
5476 this.currentAttrLocation.endLine = this.posTracker.line;
5477 this.currentAttrLocation.endCol = this.posTracker.col;
5478 this.currentAttrLocation.endOffset = this.posTracker.offset;
5479 const currentToken = this.tokenizer.currentToken;
5480 const currentAttr = this.tokenizer.currentAttr;
5481
5482 if (!currentToken.location.attrs) {
5483 currentToken.location.attrs = Object.create(null);
5484 }
5485
5486 currentToken.location.attrs[currentAttr.name] = this.currentAttrLocation;
5487 }
5488
5489 _getOverriddenMethods(mxn, orig) {
5490 const methods = {
5491 _createStartTagToken() {
5492 orig._createStartTagToken.call(this);
5493
5494 this.currentToken.location = mxn.ctLoc;
5495 },
5496
5497 _createEndTagToken() {
5498 orig._createEndTagToken.call(this);
5499
5500 this.currentToken.location = mxn.ctLoc;
5501 },
5502
5503 _createCommentToken() {
5504 orig._createCommentToken.call(this);
5505
5506 this.currentToken.location = mxn.ctLoc;
5507 },
5508
5509 _createDoctypeToken(initialName) {
5510 orig._createDoctypeToken.call(this, initialName);
5511
5512 this.currentToken.location = mxn.ctLoc;
5513 },
5514
5515 _createCharacterToken(type, ch) {
5516 orig._createCharacterToken.call(this, type, ch);
5517
5518 this.currentCharacterToken.location = mxn.ctLoc;
5519 },
5520
5521 _createEOFToken() {
5522 orig._createEOFToken.call(this);
5523
5524 this.currentToken.location = mxn._getCurrentLocation();
5525 },
5526
5527 _createAttr(attrNameFirstCh) {
5528 orig._createAttr.call(this, attrNameFirstCh);
5529
5530 mxn.currentAttrLocation = mxn._getCurrentLocation();
5531 },
5532
5533 _leaveAttrName(toState) {
5534 orig._leaveAttrName.call(this, toState);
5535
5536 mxn._attachCurrentAttrLocationInfo();
5537 },
5538
5539 _leaveAttrValue(toState) {
5540 orig._leaveAttrValue.call(this, toState);
5541
5542 mxn._attachCurrentAttrLocationInfo();
5543 },
5544
5545 _emitCurrentToken() {
5546 const ctLoc = this.currentToken.location; //NOTE: if we have pending character token make it's end location equal to the
5547 //current token's start location.
5548
5549 if (this.currentCharacterToken) {
5550 this.currentCharacterToken.location.endLine = ctLoc.startLine;
5551 this.currentCharacterToken.location.endCol = ctLoc.startCol;
5552 this.currentCharacterToken.location.endOffset = ctLoc.startOffset;
5553 }
5554
5555 if (this.currentToken.type === tokenizer.EOF_TOKEN) {
5556 ctLoc.endLine = ctLoc.startLine;
5557 ctLoc.endCol = ctLoc.startCol;
5558 ctLoc.endOffset = ctLoc.startOffset;
5559 } else {
5560 ctLoc.endLine = mxn.posTracker.line;
5561 ctLoc.endCol = mxn.posTracker.col + 1;
5562 ctLoc.endOffset = mxn.posTracker.offset + 1;
5563 }
5564
5565 orig._emitCurrentToken.call(this);
5566 },
5567
5568 _emitCurrentCharacterToken() {
5569 const ctLoc = this.currentCharacterToken && this.currentCharacterToken.location; //NOTE: if we have character token and it's location wasn't set in the _emitCurrentToken(),
5570 //then set it's location at the current preprocessor position.
5571 //We don't need to increment preprocessor position, since character token
5572 //emission is always forced by the start of the next character token here.
5573 //So, we already have advanced position.
5574
5575 if (ctLoc && ctLoc.endOffset === -1) {
5576 ctLoc.endLine = mxn.posTracker.line;
5577 ctLoc.endCol = mxn.posTracker.col;
5578 ctLoc.endOffset = mxn.posTracker.offset;
5579 }
5580
5581 orig._emitCurrentCharacterToken.call(this);
5582 }
5583
5584 }; //NOTE: patch initial states for each mode to obtain token start position
5585
5586 Object.keys(tokenizer.MODE).forEach(modeName => {
5587 const state = tokenizer.MODE[modeName];
5588
5589 methods[state] = function (cp) {
5590 mxn.ctLoc = mxn._getCurrentLocation();
5591 orig[state].call(this, cp);
5592 };
5593 });
5594 return methods;
5595 }
5596
5597}
5598
5599var tokenizerMixin = LocationInfoTokenizerMixin;
5600
5601class LocationInfoOpenElementStackMixin extends mixin {
5602 constructor(stack, opts) {
5603 super(stack);
5604 this.onItemPop = opts.onItemPop;
5605 }
5606
5607 _getOverriddenMethods(mxn, orig) {
5608 return {
5609 pop() {
5610 mxn.onItemPop(this.current);
5611 orig.pop.call(this);
5612 },
5613
5614 popAllUpToHtmlElement() {
5615 for (let i = this.stackTop; i > 0; i--) {
5616 mxn.onItemPop(this.items[i]);
5617 }
5618
5619 orig.popAllUpToHtmlElement.call(this);
5620 },
5621
5622 remove(element) {
5623 mxn.onItemPop(this.current);
5624 orig.remove.call(this, element);
5625 }
5626
5627 };
5628 }
5629
5630}
5631
5632var openElementStackMixin = LocationInfoOpenElementStackMixin;
5633
5634const $$3 = html.TAG_NAMES;
5635
5636class LocationInfoParserMixin extends mixin {
5637 constructor(parser) {
5638 super(parser);
5639 this.parser = parser;
5640 this.treeAdapter = this.parser.treeAdapter;
5641 this.posTracker = null;
5642 this.lastStartTagToken = null;
5643 this.lastFosterParentingLocation = null;
5644 this.currentToken = null;
5645 }
5646
5647 _setStartLocation(element) {
5648 let loc = null;
5649
5650 if (this.lastStartTagToken) {
5651 loc = Object.assign({}, this.lastStartTagToken.location);
5652 loc.startTag = this.lastStartTagToken.location;
5653 }
5654
5655 this.treeAdapter.setNodeSourceCodeLocation(element, loc);
5656 }
5657
5658 _setEndLocation(element, closingToken) {
5659 const loc = this.treeAdapter.getNodeSourceCodeLocation(element);
5660
5661 if (loc) {
5662 if (closingToken.location) {
5663 const ctLoc = closingToken.location;
5664 const tn = this.treeAdapter.getTagName(element); // NOTE: For cases like <p> <p> </p> - First 'p' closes without a closing
5665 // tag and for cases like <td> <p> </td> - 'p' closes without a closing tag.
5666
5667 const isClosingEndTag = closingToken.type === tokenizer.END_TAG_TOKEN && tn === closingToken.tagName;
5668
5669 if (isClosingEndTag) {
5670 loc.endTag = Object.assign({}, ctLoc);
5671 loc.endLine = ctLoc.endLine;
5672 loc.endCol = ctLoc.endCol;
5673 loc.endOffset = ctLoc.endOffset;
5674 } else {
5675 loc.endLine = ctLoc.startLine;
5676 loc.endCol = ctLoc.startCol;
5677 loc.endOffset = ctLoc.startOffset;
5678 }
5679 }
5680 }
5681 }
5682
5683 _getOverriddenMethods(mxn, orig) {
5684 return {
5685 _bootstrap(document, fragmentContext) {
5686 orig._bootstrap.call(this, document, fragmentContext);
5687
5688 mxn.lastStartTagToken = null;
5689 mxn.lastFosterParentingLocation = null;
5690 mxn.currentToken = null;
5691 const tokenizerMixin$1 = mixin.install(this.tokenizer, tokenizerMixin);
5692 mxn.posTracker = tokenizerMixin$1.posTracker;
5693 mixin.install(this.openElements, openElementStackMixin, {
5694 onItemPop: function onItemPop(element) {
5695 mxn._setEndLocation(element, mxn.currentToken);
5696 }
5697 });
5698 },
5699
5700 _runParsingLoop(scriptHandler) {
5701 orig._runParsingLoop.call(this, scriptHandler); // NOTE: generate location info for elements
5702 // that remains on open element stack
5703
5704
5705 for (let i = this.openElements.stackTop; i >= 0; i--) {
5706 mxn._setEndLocation(this.openElements.items[i], mxn.currentToken);
5707 }
5708 },
5709
5710 //Token processing
5711 _processTokenInForeignContent(token) {
5712 mxn.currentToken = token;
5713
5714 orig._processTokenInForeignContent.call(this, token);
5715 },
5716
5717 _processToken(token) {
5718 mxn.currentToken = token;
5719
5720 orig._processToken.call(this, token); //NOTE: <body> and <html> are never popped from the stack, so we need to updated
5721 //their end location explicitly.
5722
5723
5724 const requireExplicitUpdate = token.type === tokenizer.END_TAG_TOKEN && (token.tagName === $$3.HTML || token.tagName === $$3.BODY && this.openElements.hasInScope($$3.BODY));
5725
5726 if (requireExplicitUpdate) {
5727 for (let i = this.openElements.stackTop; i >= 0; i--) {
5728 const element = this.openElements.items[i];
5729
5730 if (this.treeAdapter.getTagName(element) === token.tagName) {
5731 mxn._setEndLocation(element, token);
5732
5733 break;
5734 }
5735 }
5736 }
5737 },
5738
5739 //Doctype
5740 _setDocumentType(token) {
5741 orig._setDocumentType.call(this, token);
5742
5743 const documentChildren = this.treeAdapter.getChildNodes(this.document);
5744 const cnLength = documentChildren.length;
5745
5746 for (let i = 0; i < cnLength; i++) {
5747 const node = documentChildren[i];
5748
5749 if (this.treeAdapter.isDocumentTypeNode(node)) {
5750 this.treeAdapter.setNodeSourceCodeLocation(node, token.location);
5751 break;
5752 }
5753 }
5754 },
5755
5756 //Elements
5757 _attachElementToTree(element) {
5758 //NOTE: _attachElementToTree is called from _appendElement, _insertElement and _insertTemplate methods.
5759 //So we will use token location stored in this methods for the element.
5760 mxn._setStartLocation(element);
5761
5762 mxn.lastStartTagToken = null;
5763
5764 orig._attachElementToTree.call(this, element);
5765 },
5766
5767 _appendElement(token, namespaceURI) {
5768 mxn.lastStartTagToken = token;
5769
5770 orig._appendElement.call(this, token, namespaceURI);
5771 },
5772
5773 _insertElement(token, namespaceURI) {
5774 mxn.lastStartTagToken = token;
5775
5776 orig._insertElement.call(this, token, namespaceURI);
5777 },
5778
5779 _insertTemplate(token) {
5780 mxn.lastStartTagToken = token;
5781
5782 orig._insertTemplate.call(this, token);
5783
5784 const tmplContent = this.treeAdapter.getTemplateContent(this.openElements.current);
5785 this.treeAdapter.setNodeSourceCodeLocation(tmplContent, null);
5786 },
5787
5788 _insertFakeRootElement() {
5789 orig._insertFakeRootElement.call(this);
5790
5791 this.treeAdapter.setNodeSourceCodeLocation(this.openElements.current, null);
5792 },
5793
5794 //Comments
5795 _appendCommentNode(token, parent) {
5796 orig._appendCommentNode.call(this, token, parent);
5797
5798 const children = this.treeAdapter.getChildNodes(parent);
5799 const commentNode = children[children.length - 1];
5800 this.treeAdapter.setNodeSourceCodeLocation(commentNode, token.location);
5801 },
5802
5803 //Text
5804 _findFosterParentingLocation() {
5805 //NOTE: store last foster parenting location, so we will be able to find inserted text
5806 //in case of foster parenting
5807 mxn.lastFosterParentingLocation = orig._findFosterParentingLocation.call(this);
5808 return mxn.lastFosterParentingLocation;
5809 },
5810
5811 _insertCharacters(token) {
5812 orig._insertCharacters.call(this, token);
5813
5814 const hasFosterParent = this._shouldFosterParentOnInsertion();
5815
5816 const parent = hasFosterParent && mxn.lastFosterParentingLocation.parent || this.openElements.currentTmplContent || this.openElements.current;
5817 const siblings = this.treeAdapter.getChildNodes(parent);
5818 const textNodeIdx = hasFosterParent && mxn.lastFosterParentingLocation.beforeElement ? siblings.indexOf(mxn.lastFosterParentingLocation.beforeElement) - 1 : siblings.length - 1;
5819 const textNode = siblings[textNodeIdx]; //NOTE: if we have location assigned by another token, then just update end position
5820
5821 const tnLoc = this.treeAdapter.getNodeSourceCodeLocation(textNode);
5822
5823 if (tnLoc) {
5824 tnLoc.endLine = token.location.endLine;
5825 tnLoc.endCol = token.location.endCol;
5826 tnLoc.endOffset = token.location.endOffset;
5827 } else {
5828 this.treeAdapter.setNodeSourceCodeLocation(textNode, token.location);
5829 }
5830 }
5831
5832 };
5833 }
5834
5835}
5836
5837var parserMixin = LocationInfoParserMixin;
5838
5839class ErrorReportingMixinBase extends mixin {
5840 constructor(host, opts) {
5841 super(host);
5842 this.posTracker = null;
5843 this.onParseError = opts.onParseError;
5844 }
5845
5846 _setErrorLocation(err) {
5847 err.startLine = err.endLine = this.posTracker.line;
5848 err.startCol = err.endCol = this.posTracker.col;
5849 err.startOffset = err.endOffset = this.posTracker.offset;
5850 }
5851
5852 _reportError(code) {
5853 const err = {
5854 code: code,
5855 startLine: -1,
5856 startCol: -1,
5857 startOffset: -1,
5858 endLine: -1,
5859 endCol: -1,
5860 endOffset: -1
5861 };
5862
5863 this._setErrorLocation(err);
5864
5865 this.onParseError(err);
5866 }
5867
5868 _getOverriddenMethods(mxn) {
5869 return {
5870 _err(code) {
5871 mxn._reportError(code);
5872 }
5873
5874 };
5875 }
5876
5877}
5878
5879var mixinBase = ErrorReportingMixinBase;
5880
5881class ErrorReportingPreprocessorMixin extends mixinBase {
5882 constructor(preprocessor, opts) {
5883 super(preprocessor, opts);
5884 this.posTracker = mixin.install(preprocessor, preprocessorMixin);
5885 this.lastErrOffset = -1;
5886 }
5887
5888 _reportError(code) {
5889 //NOTE: avoid reporting error twice on advance/retreat
5890 if (this.lastErrOffset !== this.posTracker.offset) {
5891 this.lastErrOffset = this.posTracker.offset;
5892
5893 super._reportError(code);
5894 }
5895 }
5896
5897}
5898
5899var preprocessorMixin$1 = ErrorReportingPreprocessorMixin;
5900
5901class ErrorReportingTokenizerMixin extends mixinBase {
5902 constructor(tokenizer, opts) {
5903 super(tokenizer, opts);
5904 const preprocessorMixin = mixin.install(tokenizer.preprocessor, preprocessorMixin$1, opts);
5905 this.posTracker = preprocessorMixin.posTracker;
5906 }
5907
5908}
5909
5910var tokenizerMixin$1 = ErrorReportingTokenizerMixin;
5911
5912class ErrorReportingParserMixin extends mixinBase {
5913 constructor(parser, opts) {
5914 super(parser, opts);
5915 this.opts = opts;
5916 this.ctLoc = null;
5917 this.locBeforeToken = false;
5918 }
5919
5920 _setErrorLocation(err) {
5921 if (this.ctLoc) {
5922 err.startLine = this.ctLoc.startLine;
5923 err.startCol = this.ctLoc.startCol;
5924 err.startOffset = this.ctLoc.startOffset;
5925 err.endLine = this.locBeforeToken ? this.ctLoc.startLine : this.ctLoc.endLine;
5926 err.endCol = this.locBeforeToken ? this.ctLoc.startCol : this.ctLoc.endCol;
5927 err.endOffset = this.locBeforeToken ? this.ctLoc.startOffset : this.ctLoc.endOffset;
5928 }
5929 }
5930
5931 _getOverriddenMethods(mxn, orig) {
5932 return {
5933 _bootstrap(document, fragmentContext) {
5934 orig._bootstrap.call(this, document, fragmentContext);
5935
5936 mixin.install(this.tokenizer, tokenizerMixin$1, mxn.opts);
5937 mixin.install(this.tokenizer, tokenizerMixin);
5938 },
5939
5940 _processInputToken(token) {
5941 mxn.ctLoc = token.location;
5942
5943 orig._processInputToken.call(this, token);
5944 },
5945
5946 _err(code, options) {
5947 mxn.locBeforeToken = options && options.beforeToken;
5948
5949 mxn._reportError(code);
5950 }
5951
5952 };
5953 }
5954
5955}
5956
5957var parserMixin$1 = ErrorReportingParserMixin;
5958
5959var _default = createCommonjsModule(function (module, exports) {
5960
5961 const DOCUMENT_MODE = html.DOCUMENT_MODE; //Node construction
5962
5963 exports.createDocument = function () {
5964 return {
5965 nodeName: '#document',
5966 mode: DOCUMENT_MODE.NO_QUIRKS,
5967 childNodes: []
5968 };
5969 };
5970
5971 exports.createDocumentFragment = function () {
5972 return {
5973 nodeName: '#document-fragment',
5974 childNodes: []
5975 };
5976 };
5977
5978 exports.createElement = function (tagName, namespaceURI, attrs) {
5979 return {
5980 nodeName: tagName,
5981 tagName: tagName,
5982 attrs: attrs,
5983 namespaceURI: namespaceURI,
5984 childNodes: [],
5985 parentNode: null
5986 };
5987 };
5988
5989 exports.createCommentNode = function (data) {
5990 return {
5991 nodeName: '#comment',
5992 data: data,
5993 parentNode: null
5994 };
5995 };
5996
5997 const createTextNode = function createTextNode(value) {
5998 return {
5999 nodeName: '#text',
6000 value: value,
6001 parentNode: null
6002 };
6003 }; //Tree mutation
6004
6005
6006 const appendChild = exports.appendChild = function (parentNode, newNode) {
6007 parentNode.childNodes.push(newNode);
6008 newNode.parentNode = parentNode;
6009 };
6010
6011 const insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) {
6012 const insertionIdx = parentNode.childNodes.indexOf(referenceNode);
6013 parentNode.childNodes.splice(insertionIdx, 0, newNode);
6014 newNode.parentNode = parentNode;
6015 };
6016
6017 exports.setTemplateContent = function (templateElement, contentElement) {
6018 templateElement.content = contentElement;
6019 };
6020
6021 exports.getTemplateContent = function (templateElement) {
6022 return templateElement.content;
6023 };
6024
6025 exports.setDocumentType = function (document, name, publicId, systemId) {
6026 let doctypeNode = null;
6027
6028 for (let i = 0; i < document.childNodes.length; i++) {
6029 if (document.childNodes[i].nodeName === '#documentType') {
6030 doctypeNode = document.childNodes[i];
6031 break;
6032 }
6033 }
6034
6035 if (doctypeNode) {
6036 doctypeNode.name = name;
6037 doctypeNode.publicId = publicId;
6038 doctypeNode.systemId = systemId;
6039 } else {
6040 appendChild(document, {
6041 nodeName: '#documentType',
6042 name: name,
6043 publicId: publicId,
6044 systemId: systemId
6045 });
6046 }
6047 };
6048
6049 exports.setDocumentMode = function (document, mode) {
6050 document.mode = mode;
6051 };
6052
6053 exports.getDocumentMode = function (document) {
6054 return document.mode;
6055 };
6056
6057 exports.detachNode = function (node) {
6058 if (node.parentNode) {
6059 const idx = node.parentNode.childNodes.indexOf(node);
6060 node.parentNode.childNodes.splice(idx, 1);
6061 node.parentNode = null;
6062 }
6063 };
6064
6065 exports.insertText = function (parentNode, text) {
6066 if (parentNode.childNodes.length) {
6067 const prevNode = parentNode.childNodes[parentNode.childNodes.length - 1];
6068
6069 if (prevNode.nodeName === '#text') {
6070 prevNode.value += text;
6071 return;
6072 }
6073 }
6074
6075 appendChild(parentNode, createTextNode(text));
6076 };
6077
6078 exports.insertTextBefore = function (parentNode, text, referenceNode) {
6079 const prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];
6080
6081 if (prevNode && prevNode.nodeName === '#text') {
6082 prevNode.value += text;
6083 } else {
6084 insertBefore(parentNode, createTextNode(text), referenceNode);
6085 }
6086 };
6087
6088 exports.adoptAttributes = function (recipient, attrs) {
6089 const recipientAttrsMap = [];
6090
6091 for (let i = 0; i < recipient.attrs.length; i++) {
6092 recipientAttrsMap.push(recipient.attrs[i].name);
6093 }
6094
6095 for (let j = 0; j < attrs.length; j++) {
6096 if (recipientAttrsMap.indexOf(attrs[j].name) === -1) {
6097 recipient.attrs.push(attrs[j]);
6098 }
6099 }
6100 }; //Tree traversing
6101
6102
6103 exports.getFirstChild = function (node) {
6104 return node.childNodes[0];
6105 };
6106
6107 exports.getChildNodes = function (node) {
6108 return node.childNodes;
6109 };
6110
6111 exports.getParentNode = function (node) {
6112 return node.parentNode;
6113 };
6114
6115 exports.getAttrList = function (element) {
6116 return element.attrs;
6117 }; //Node data
6118
6119
6120 exports.getTagName = function (element) {
6121 return element.tagName;
6122 };
6123
6124 exports.getNamespaceURI = function (element) {
6125 return element.namespaceURI;
6126 };
6127
6128 exports.getTextNodeContent = function (textNode) {
6129 return textNode.value;
6130 };
6131
6132 exports.getCommentNodeContent = function (commentNode) {
6133 return commentNode.data;
6134 };
6135
6136 exports.getDocumentTypeNodeName = function (doctypeNode) {
6137 return doctypeNode.name;
6138 };
6139
6140 exports.getDocumentTypeNodePublicId = function (doctypeNode) {
6141 return doctypeNode.publicId;
6142 };
6143
6144 exports.getDocumentTypeNodeSystemId = function (doctypeNode) {
6145 return doctypeNode.systemId;
6146 }; //Node types
6147
6148
6149 exports.isTextNode = function (node) {
6150 return node.nodeName === '#text';
6151 };
6152
6153 exports.isCommentNode = function (node) {
6154 return node.nodeName === '#comment';
6155 };
6156
6157 exports.isDocumentTypeNode = function (node) {
6158 return node.nodeName === '#documentType';
6159 };
6160
6161 exports.isElementNode = function (node) {
6162 return !!node.tagName;
6163 }; // Source code location
6164
6165
6166 exports.setNodeSourceCodeLocation = function (node, location) {
6167 node.sourceCodeLocation = location;
6168 };
6169
6170 exports.getNodeSourceCodeLocation = function (node) {
6171 return node.sourceCodeLocation;
6172 };
6173});
6174var _default_1 = _default.createDocument;
6175var _default_2 = _default.createDocumentFragment;
6176var _default_3 = _default.createElement;
6177var _default_4 = _default.createCommentNode;
6178var _default_5 = _default.appendChild;
6179var _default_6 = _default.insertBefore;
6180var _default_7 = _default.setTemplateContent;
6181var _default_8 = _default.getTemplateContent;
6182var _default_9 = _default.setDocumentType;
6183var _default_10 = _default.setDocumentMode;
6184var _default_11 = _default.getDocumentMode;
6185var _default_12 = _default.detachNode;
6186var _default_13 = _default.insertText;
6187var _default_14 = _default.insertTextBefore;
6188var _default_15 = _default.adoptAttributes;
6189var _default_16 = _default.getFirstChild;
6190var _default_17 = _default.getChildNodes;
6191var _default_18 = _default.getParentNode;
6192var _default_19 = _default.getAttrList;
6193var _default_20 = _default.getTagName;
6194var _default_21 = _default.getNamespaceURI;
6195var _default_22 = _default.getTextNodeContent;
6196var _default_23 = _default.getCommentNodeContent;
6197var _default_24 = _default.getDocumentTypeNodeName;
6198var _default_25 = _default.getDocumentTypeNodePublicId;
6199var _default_26 = _default.getDocumentTypeNodeSystemId;
6200var _default_27 = _default.isTextNode;
6201var _default_28 = _default.isCommentNode;
6202var _default_29 = _default.isDocumentTypeNode;
6203var _default_30 = _default.isElementNode;
6204var _default_31 = _default.setNodeSourceCodeLocation;
6205var _default_32 = _default.getNodeSourceCodeLocation;
6206
6207var mergeOptions = function mergeOptions(defaults, options) {
6208 options = options || Object.create(null);
6209 return [defaults, options].reduce((merged, optObj) => {
6210 Object.keys(optObj).forEach(key => {
6211 merged[key] = optObj[key];
6212 });
6213 return merged;
6214 }, Object.create(null));
6215};
6216
6217const DOCUMENT_MODE = html.DOCUMENT_MODE; //Const
6218
6219const VALID_DOCTYPE_NAME = 'html';
6220const VALID_SYSTEM_ID = 'about:legacy-compat';
6221const QUIRKS_MODE_SYSTEM_ID = 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd';
6222const QUIRKS_MODE_PUBLIC_ID_PREFIXES = ['+//silmaril//dtd html pro v0r11 19970101//en', '-//advasoft ltd//dtd html 3.0 aswedit + extensions//en', '-//as//dtd html 3.0 aswedit + extensions//en', '-//ietf//dtd html 2.0 level 1//en', '-//ietf//dtd html 2.0 level 2//en', '-//ietf//dtd html 2.0 strict level 1//en', '-//ietf//dtd html 2.0 strict level 2//en', '-//ietf//dtd html 2.0 strict//en', '-//ietf//dtd html 2.0//en', '-//ietf//dtd html 2.1e//en', '-//ietf//dtd html 3.0//en', '-//ietf//dtd html 3.0//en//', '-//ietf//dtd html 3.2 final//en', '-//ietf//dtd html 3.2//en', '-//ietf//dtd html 3//en', '-//ietf//dtd html level 0//en', '-//ietf//dtd html level 0//en//2.0', '-//ietf//dtd html level 1//en', '-//ietf//dtd html level 1//en//2.0', '-//ietf//dtd html level 2//en', '-//ietf//dtd html level 2//en//2.0', '-//ietf//dtd html level 3//en', '-//ietf//dtd html level 3//en//3.0', '-//ietf//dtd html strict level 0//en', '-//ietf//dtd html strict level 0//en//2.0', '-//ietf//dtd html strict level 1//en', '-//ietf//dtd html strict level 1//en//2.0', '-//ietf//dtd html strict level 2//en', '-//ietf//dtd html strict level 2//en//2.0', '-//ietf//dtd html strict level 3//en', '-//ietf//dtd html strict level 3//en//3.0', '-//ietf//dtd html strict//en', '-//ietf//dtd html strict//en//2.0', '-//ietf//dtd html strict//en//3.0', '-//ietf//dtd html//en', '-//ietf//dtd html//en//2.0', '-//ietf//dtd html//en//3.0', '-//metrius//dtd metrius presentational//en', '-//microsoft//dtd internet explorer 2.0 html strict//en', '-//microsoft//dtd internet explorer 2.0 html//en', '-//microsoft//dtd internet explorer 2.0 tables//en', '-//microsoft//dtd internet explorer 3.0 html strict//en', '-//microsoft//dtd internet explorer 3.0 html//en', '-//microsoft//dtd internet explorer 3.0 tables//en', '-//netscape comm. corp.//dtd html//en', '-//netscape comm. corp.//dtd strict html//en', "-//o'reilly and associates//dtd html 2.0//en", "-//o'reilly and associates//dtd html extended 1.0//en", '-//spyglass//dtd html 2.0 extended//en', '-//sq//dtd html 2.0 hotmetal + extensions//en', '-//sun microsystems corp.//dtd hotjava html//en', '-//sun microsystems corp.//dtd hotjava strict html//en', '-//w3c//dtd html 3 1995-03-24//en', '-//w3c//dtd html 3.2 draft//en', '-//w3c//dtd html 3.2 final//en', '-//w3c//dtd html 3.2//en', '-//w3c//dtd html 3.2s draft//en', '-//w3c//dtd html 4.0 frameset//en', '-//w3c//dtd html 4.0 transitional//en', '-//w3c//dtd html experimental 19960712//en', '-//w3c//dtd html experimental 970421//en', '-//w3c//dtd w3 html//en', '-//w3o//dtd w3 html 3.0//en', '-//w3o//dtd w3 html 3.0//en//', '-//webtechs//dtd mozilla html 2.0//en', '-//webtechs//dtd mozilla html//en'];
6223const QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES = QUIRKS_MODE_PUBLIC_ID_PREFIXES.concat(['-//w3c//dtd html 4.01 frameset//', '-//w3c//dtd html 4.01 transitional//']);
6224const QUIRKS_MODE_PUBLIC_IDS = ['-//w3o//dtd w3 html strict 3.0//en//', '-/w3c/dtd html 4.0 transitional/en', 'html'];
6225const LIMITED_QUIRKS_PUBLIC_ID_PREFIXES = ['-//W3C//DTD XHTML 1.0 Frameset//', '-//W3C//DTD XHTML 1.0 Transitional//'];
6226const LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES = LIMITED_QUIRKS_PUBLIC_ID_PREFIXES.concat(['-//W3C//DTD HTML 4.01 Frameset//', '-//W3C//DTD HTML 4.01 Transitional//']); //Utils
6227
6228function enquoteDoctypeId(id) {
6229 const quote = id.indexOf('"') !== -1 ? "'" : '"';
6230 return quote + id + quote;
6231}
6232
6233function hasPrefix(publicId, prefixes) {
6234 for (let i = 0; i < prefixes.length; i++) {
6235 if (publicId.indexOf(prefixes[i]) === 0) {
6236 return true;
6237 }
6238 }
6239
6240 return false;
6241} //API
6242
6243
6244var isConforming = function isConforming(token) {
6245 return token.name === VALID_DOCTYPE_NAME && token.publicId === null && (token.systemId === null || token.systemId === VALID_SYSTEM_ID);
6246};
6247
6248var getDocumentMode = function getDocumentMode(token) {
6249 if (token.name !== VALID_DOCTYPE_NAME) {
6250 return DOCUMENT_MODE.QUIRKS;
6251 }
6252
6253 const systemId = token.systemId;
6254
6255 if (systemId && systemId.toLowerCase() === QUIRKS_MODE_SYSTEM_ID) {
6256 return DOCUMENT_MODE.QUIRKS;
6257 }
6258
6259 let publicId = token.publicId;
6260
6261 if (publicId !== null) {
6262 publicId = publicId.toLowerCase();
6263
6264 if (QUIRKS_MODE_PUBLIC_IDS.indexOf(publicId) > -1) {
6265 return DOCUMENT_MODE.QUIRKS;
6266 }
6267
6268 let prefixes = systemId === null ? QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES : QUIRKS_MODE_PUBLIC_ID_PREFIXES;
6269
6270 if (hasPrefix(publicId, prefixes)) {
6271 return DOCUMENT_MODE.QUIRKS;
6272 }
6273
6274 prefixes = systemId === null ? LIMITED_QUIRKS_PUBLIC_ID_PREFIXES : LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES;
6275
6276 if (hasPrefix(publicId, prefixes)) {
6277 return DOCUMENT_MODE.LIMITED_QUIRKS;
6278 }
6279 }
6280
6281 return DOCUMENT_MODE.NO_QUIRKS;
6282};
6283
6284var serializeContent = function serializeContent(name, publicId, systemId) {
6285 let str = '!DOCTYPE ';
6286
6287 if (name) {
6288 str += name;
6289 }
6290
6291 if (publicId) {
6292 str += ' PUBLIC ' + enquoteDoctypeId(publicId);
6293 } else if (systemId) {
6294 str += ' SYSTEM';
6295 }
6296
6297 if (systemId !== null) {
6298 str += ' ' + enquoteDoctypeId(systemId);
6299 }
6300
6301 return str;
6302};
6303
6304var doctype = {
6305 isConforming: isConforming,
6306 getDocumentMode: getDocumentMode,
6307 serializeContent: serializeContent
6308};
6309
6310var foreignContent = createCommonjsModule(function (module, exports) {
6311
6312 const $ = html.TAG_NAMES;
6313 const NS = html.NAMESPACES;
6314 const ATTRS = html.ATTRS; //MIME types
6315
6316 const MIME_TYPES = {
6317 TEXT_HTML: 'text/html',
6318 APPLICATION_XML: 'application/xhtml+xml'
6319 }; //Attributes
6320
6321 const DEFINITION_URL_ATTR = 'definitionurl';
6322 const ADJUSTED_DEFINITION_URL_ATTR = 'definitionURL';
6323 const SVG_ATTRS_ADJUSTMENT_MAP = {
6324 attributename: 'attributeName',
6325 attributetype: 'attributeType',
6326 basefrequency: 'baseFrequency',
6327 baseprofile: 'baseProfile',
6328 calcmode: 'calcMode',
6329 clippathunits: 'clipPathUnits',
6330 diffuseconstant: 'diffuseConstant',
6331 edgemode: 'edgeMode',
6332 filterunits: 'filterUnits',
6333 glyphref: 'glyphRef',
6334 gradienttransform: 'gradientTransform',
6335 gradientunits: 'gradientUnits',
6336 kernelmatrix: 'kernelMatrix',
6337 kernelunitlength: 'kernelUnitLength',
6338 keypoints: 'keyPoints',
6339 keysplines: 'keySplines',
6340 keytimes: 'keyTimes',
6341 lengthadjust: 'lengthAdjust',
6342 limitingconeangle: 'limitingConeAngle',
6343 markerheight: 'markerHeight',
6344 markerunits: 'markerUnits',
6345 markerwidth: 'markerWidth',
6346 maskcontentunits: 'maskContentUnits',
6347 maskunits: 'maskUnits',
6348 numoctaves: 'numOctaves',
6349 pathlength: 'pathLength',
6350 patterncontentunits: 'patternContentUnits',
6351 patterntransform: 'patternTransform',
6352 patternunits: 'patternUnits',
6353 pointsatx: 'pointsAtX',
6354 pointsaty: 'pointsAtY',
6355 pointsatz: 'pointsAtZ',
6356 preservealpha: 'preserveAlpha',
6357 preserveaspectratio: 'preserveAspectRatio',
6358 primitiveunits: 'primitiveUnits',
6359 refx: 'refX',
6360 refy: 'refY',
6361 repeatcount: 'repeatCount',
6362 repeatdur: 'repeatDur',
6363 requiredextensions: 'requiredExtensions',
6364 requiredfeatures: 'requiredFeatures',
6365 specularconstant: 'specularConstant',
6366 specularexponent: 'specularExponent',
6367 spreadmethod: 'spreadMethod',
6368 startoffset: 'startOffset',
6369 stddeviation: 'stdDeviation',
6370 stitchtiles: 'stitchTiles',
6371 surfacescale: 'surfaceScale',
6372 systemlanguage: 'systemLanguage',
6373 tablevalues: 'tableValues',
6374 targetx: 'targetX',
6375 targety: 'targetY',
6376 textlength: 'textLength',
6377 viewbox: 'viewBox',
6378 viewtarget: 'viewTarget',
6379 xchannelselector: 'xChannelSelector',
6380 ychannelselector: 'yChannelSelector',
6381 zoomandpan: 'zoomAndPan'
6382 };
6383 const XML_ATTRS_ADJUSTMENT_MAP = {
6384 'xlink:actuate': {
6385 prefix: 'xlink',
6386 name: 'actuate',
6387 namespace: NS.XLINK
6388 },
6389 'xlink:arcrole': {
6390 prefix: 'xlink',
6391 name: 'arcrole',
6392 namespace: NS.XLINK
6393 },
6394 'xlink:href': {
6395 prefix: 'xlink',
6396 name: 'href',
6397 namespace: NS.XLINK
6398 },
6399 'xlink:role': {
6400 prefix: 'xlink',
6401 name: 'role',
6402 namespace: NS.XLINK
6403 },
6404 'xlink:show': {
6405 prefix: 'xlink',
6406 name: 'show',
6407 namespace: NS.XLINK
6408 },
6409 'xlink:title': {
6410 prefix: 'xlink',
6411 name: 'title',
6412 namespace: NS.XLINK
6413 },
6414 'xlink:type': {
6415 prefix: 'xlink',
6416 name: 'type',
6417 namespace: NS.XLINK
6418 },
6419 'xml:base': {
6420 prefix: 'xml',
6421 name: 'base',
6422 namespace: NS.XML
6423 },
6424 'xml:lang': {
6425 prefix: 'xml',
6426 name: 'lang',
6427 namespace: NS.XML
6428 },
6429 'xml:space': {
6430 prefix: 'xml',
6431 name: 'space',
6432 namespace: NS.XML
6433 },
6434 xmlns: {
6435 prefix: '',
6436 name: 'xmlns',
6437 namespace: NS.XMLNS
6438 },
6439 'xmlns:xlink': {
6440 prefix: 'xmlns',
6441 name: 'xlink',
6442 namespace: NS.XMLNS
6443 }
6444 }; //SVG tag names adjustment map
6445
6446 const SVG_TAG_NAMES_ADJUSTMENT_MAP = exports.SVG_TAG_NAMES_ADJUSTMENT_MAP = {
6447 altglyph: 'altGlyph',
6448 altglyphdef: 'altGlyphDef',
6449 altglyphitem: 'altGlyphItem',
6450 animatecolor: 'animateColor',
6451 animatemotion: 'animateMotion',
6452 animatetransform: 'animateTransform',
6453 clippath: 'clipPath',
6454 feblend: 'feBlend',
6455 fecolormatrix: 'feColorMatrix',
6456 fecomponenttransfer: 'feComponentTransfer',
6457 fecomposite: 'feComposite',
6458 feconvolvematrix: 'feConvolveMatrix',
6459 fediffuselighting: 'feDiffuseLighting',
6460 fedisplacementmap: 'feDisplacementMap',
6461 fedistantlight: 'feDistantLight',
6462 feflood: 'feFlood',
6463 fefunca: 'feFuncA',
6464 fefuncb: 'feFuncB',
6465 fefuncg: 'feFuncG',
6466 fefuncr: 'feFuncR',
6467 fegaussianblur: 'feGaussianBlur',
6468 feimage: 'feImage',
6469 femerge: 'feMerge',
6470 femergenode: 'feMergeNode',
6471 femorphology: 'feMorphology',
6472 feoffset: 'feOffset',
6473 fepointlight: 'fePointLight',
6474 fespecularlighting: 'feSpecularLighting',
6475 fespotlight: 'feSpotLight',
6476 fetile: 'feTile',
6477 feturbulence: 'feTurbulence',
6478 foreignobject: 'foreignObject',
6479 glyphref: 'glyphRef',
6480 lineargradient: 'linearGradient',
6481 radialgradient: 'radialGradient',
6482 textpath: 'textPath'
6483 }; //Tags that causes exit from foreign content
6484
6485 const EXITS_FOREIGN_CONTENT = {
6486 [$.B]: true,
6487 [$.BIG]: true,
6488 [$.BLOCKQUOTE]: true,
6489 [$.BODY]: true,
6490 [$.BR]: true,
6491 [$.CENTER]: true,
6492 [$.CODE]: true,
6493 [$.DD]: true,
6494 [$.DIV]: true,
6495 [$.DL]: true,
6496 [$.DT]: true,
6497 [$.EM]: true,
6498 [$.EMBED]: true,
6499 [$.H1]: true,
6500 [$.H2]: true,
6501 [$.H3]: true,
6502 [$.H4]: true,
6503 [$.H5]: true,
6504 [$.H6]: true,
6505 [$.HEAD]: true,
6506 [$.HR]: true,
6507 [$.I]: true,
6508 [$.IMG]: true,
6509 [$.LI]: true,
6510 [$.LISTING]: true,
6511 [$.MENU]: true,
6512 [$.META]: true,
6513 [$.NOBR]: true,
6514 [$.OL]: true,
6515 [$.P]: true,
6516 [$.PRE]: true,
6517 [$.RUBY]: true,
6518 [$.S]: true,
6519 [$.SMALL]: true,
6520 [$.SPAN]: true,
6521 [$.STRONG]: true,
6522 [$.STRIKE]: true,
6523 [$.SUB]: true,
6524 [$.SUP]: true,
6525 [$.TABLE]: true,
6526 [$.TT]: true,
6527 [$.U]: true,
6528 [$.UL]: true,
6529 [$.VAR]: true
6530 }; //Check exit from foreign content
6531
6532 exports.causesExit = function (startTagToken) {
6533 const tn = startTagToken.tagName;
6534 const isFontWithAttrs = tn === $.FONT && (tokenizer.getTokenAttr(startTagToken, ATTRS.COLOR) !== null || tokenizer.getTokenAttr(startTagToken, ATTRS.SIZE) !== null || tokenizer.getTokenAttr(startTagToken, ATTRS.FACE) !== null);
6535 return isFontWithAttrs ? true : EXITS_FOREIGN_CONTENT[tn];
6536 }; //Token adjustments
6537
6538
6539 exports.adjustTokenMathMLAttrs = function (token) {
6540 for (let i = 0; i < token.attrs.length; i++) {
6541 if (token.attrs[i].name === DEFINITION_URL_ATTR) {
6542 token.attrs[i].name = ADJUSTED_DEFINITION_URL_ATTR;
6543 break;
6544 }
6545 }
6546 };
6547
6548 exports.adjustTokenSVGAttrs = function (token) {
6549 for (let i = 0; i < token.attrs.length; i++) {
6550 const adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
6551
6552 if (adjustedAttrName) {
6553 token.attrs[i].name = adjustedAttrName;
6554 }
6555 }
6556 };
6557
6558 exports.adjustTokenXMLAttrs = function (token) {
6559 for (let i = 0; i < token.attrs.length; i++) {
6560 const adjustedAttrEntry = XML_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
6561
6562 if (adjustedAttrEntry) {
6563 token.attrs[i].prefix = adjustedAttrEntry.prefix;
6564 token.attrs[i].name = adjustedAttrEntry.name;
6565 token.attrs[i].namespace = adjustedAttrEntry.namespace;
6566 }
6567 }
6568 };
6569
6570 exports.adjustTokenSVGTagName = function (token) {
6571 const adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP[token.tagName];
6572
6573 if (adjustedTagName) {
6574 token.tagName = adjustedTagName;
6575 }
6576 }; //Integration points
6577
6578
6579 function isMathMLTextIntegrationPoint(tn, ns) {
6580 return ns === NS.MATHML && (tn === $.MI || tn === $.MO || tn === $.MN || tn === $.MS || tn === $.MTEXT);
6581 }
6582
6583 function isHtmlIntegrationPoint(tn, ns, attrs) {
6584 if (ns === NS.MATHML && tn === $.ANNOTATION_XML) {
6585 for (let i = 0; i < attrs.length; i++) {
6586 if (attrs[i].name === ATTRS.ENCODING) {
6587 const value = attrs[i].value.toLowerCase();
6588 return value === MIME_TYPES.TEXT_HTML || value === MIME_TYPES.APPLICATION_XML;
6589 }
6590 }
6591 }
6592
6593 return ns === NS.SVG && (tn === $.FOREIGN_OBJECT || tn === $.DESC || tn === $.TITLE);
6594 }
6595
6596 exports.isIntegrationPoint = function (tn, ns, attrs, foreignNS) {
6597 if ((!foreignNS || foreignNS === NS.HTML) && isHtmlIntegrationPoint(tn, ns, attrs)) {
6598 return true;
6599 }
6600
6601 if ((!foreignNS || foreignNS === NS.MATHML) && isMathMLTextIntegrationPoint(tn, ns)) {
6602 return true;
6603 }
6604
6605 return false;
6606 };
6607});
6608var foreignContent_1 = foreignContent.SVG_TAG_NAMES_ADJUSTMENT_MAP;
6609var foreignContent_2 = foreignContent.causesExit;
6610var foreignContent_3 = foreignContent.adjustTokenMathMLAttrs;
6611var foreignContent_4 = foreignContent.adjustTokenSVGAttrs;
6612var foreignContent_5 = foreignContent.adjustTokenXMLAttrs;
6613var foreignContent_6 = foreignContent.adjustTokenSVGTagName;
6614var foreignContent_7 = foreignContent.isIntegrationPoint;
6615
6616const $$4 = html.TAG_NAMES;
6617const NS$1 = html.NAMESPACES;
6618const ATTRS = html.ATTRS;
6619const DEFAULT_OPTIONS = {
6620 scriptingEnabled: true,
6621 sourceCodeLocationInfo: false,
6622 onParseError: null,
6623 treeAdapter: _default
6624}; //Misc constants
6625
6626const HIDDEN_INPUT_TYPE = 'hidden'; //Adoption agency loops iteration count
6627
6628const AA_OUTER_LOOP_ITER = 8;
6629const AA_INNER_LOOP_ITER = 3; //Insertion modes
6630
6631const INITIAL_MODE = 'INITIAL_MODE';
6632const BEFORE_HTML_MODE = 'BEFORE_HTML_MODE';
6633const BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE';
6634const IN_HEAD_MODE = 'IN_HEAD_MODE';
6635const IN_HEAD_NO_SCRIPT_MODE = 'IN_HEAD_NO_SCRIPT_MODE';
6636const AFTER_HEAD_MODE = 'AFTER_HEAD_MODE';
6637const IN_BODY_MODE = 'IN_BODY_MODE';
6638const TEXT_MODE = 'TEXT_MODE';
6639const IN_TABLE_MODE = 'IN_TABLE_MODE';
6640const IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE';
6641const IN_CAPTION_MODE = 'IN_CAPTION_MODE';
6642const IN_COLUMN_GROUP_MODE = 'IN_COLUMN_GROUP_MODE';
6643const IN_TABLE_BODY_MODE = 'IN_TABLE_BODY_MODE';
6644const IN_ROW_MODE = 'IN_ROW_MODE';
6645const IN_CELL_MODE = 'IN_CELL_MODE';
6646const IN_SELECT_MODE = 'IN_SELECT_MODE';
6647const IN_SELECT_IN_TABLE_MODE = 'IN_SELECT_IN_TABLE_MODE';
6648const IN_TEMPLATE_MODE = 'IN_TEMPLATE_MODE';
6649const AFTER_BODY_MODE = 'AFTER_BODY_MODE';
6650const IN_FRAMESET_MODE = 'IN_FRAMESET_MODE';
6651const AFTER_FRAMESET_MODE = 'AFTER_FRAMESET_MODE';
6652const AFTER_AFTER_BODY_MODE = 'AFTER_AFTER_BODY_MODE';
6653const AFTER_AFTER_FRAMESET_MODE = 'AFTER_AFTER_FRAMESET_MODE'; //Insertion mode reset map
6654
6655const INSERTION_MODE_RESET_MAP = {
6656 [$$4.TR]: IN_ROW_MODE,
6657 [$$4.TBODY]: IN_TABLE_BODY_MODE,
6658 [$$4.THEAD]: IN_TABLE_BODY_MODE,
6659 [$$4.TFOOT]: IN_TABLE_BODY_MODE,
6660 [$$4.CAPTION]: IN_CAPTION_MODE,
6661 [$$4.COLGROUP]: IN_COLUMN_GROUP_MODE,
6662 [$$4.TABLE]: IN_TABLE_MODE,
6663 [$$4.BODY]: IN_BODY_MODE,
6664 [$$4.FRAMESET]: IN_FRAMESET_MODE
6665}; //Template insertion mode switch map
6666
6667const TEMPLATE_INSERTION_MODE_SWITCH_MAP = {
6668 [$$4.CAPTION]: IN_TABLE_MODE,
6669 [$$4.COLGROUP]: IN_TABLE_MODE,
6670 [$$4.TBODY]: IN_TABLE_MODE,
6671 [$$4.TFOOT]: IN_TABLE_MODE,
6672 [$$4.THEAD]: IN_TABLE_MODE,
6673 [$$4.COL]: IN_COLUMN_GROUP_MODE,
6674 [$$4.TR]: IN_TABLE_BODY_MODE,
6675 [$$4.TD]: IN_ROW_MODE,
6676 [$$4.TH]: IN_ROW_MODE
6677}; //Token handlers map for insertion modes
6678
6679const TOKEN_HANDLERS = {
6680 [INITIAL_MODE]: {
6681 [tokenizer.CHARACTER_TOKEN]: tokenInInitialMode,
6682 [tokenizer.NULL_CHARACTER_TOKEN]: tokenInInitialMode,
6683 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: ignoreToken,
6684 [tokenizer.COMMENT_TOKEN]: appendComment,
6685 [tokenizer.DOCTYPE_TOKEN]: doctypeInInitialMode,
6686 [tokenizer.START_TAG_TOKEN]: tokenInInitialMode,
6687 [tokenizer.END_TAG_TOKEN]: tokenInInitialMode,
6688 [tokenizer.EOF_TOKEN]: tokenInInitialMode
6689 },
6690 [BEFORE_HTML_MODE]: {
6691 [tokenizer.CHARACTER_TOKEN]: tokenBeforeHtml,
6692 [tokenizer.NULL_CHARACTER_TOKEN]: tokenBeforeHtml,
6693 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: ignoreToken,
6694 [tokenizer.COMMENT_TOKEN]: appendComment,
6695 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6696 [tokenizer.START_TAG_TOKEN]: startTagBeforeHtml,
6697 [tokenizer.END_TAG_TOKEN]: endTagBeforeHtml,
6698 [tokenizer.EOF_TOKEN]: tokenBeforeHtml
6699 },
6700 [BEFORE_HEAD_MODE]: {
6701 [tokenizer.CHARACTER_TOKEN]: tokenBeforeHead,
6702 [tokenizer.NULL_CHARACTER_TOKEN]: tokenBeforeHead,
6703 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: ignoreToken,
6704 [tokenizer.COMMENT_TOKEN]: appendComment,
6705 [tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
6706 [tokenizer.START_TAG_TOKEN]: startTagBeforeHead,
6707 [tokenizer.END_TAG_TOKEN]: endTagBeforeHead,
6708 [tokenizer.EOF_TOKEN]: tokenBeforeHead
6709 },
6710 [IN_HEAD_MODE]: {
6711 [tokenizer.CHARACTER_TOKEN]: tokenInHead,
6712 [tokenizer.NULL_CHARACTER_TOKEN]: tokenInHead,
6713 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
6714 [tokenizer.COMMENT_TOKEN]: appendComment,
6715 [tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
6716 [tokenizer.START_TAG_TOKEN]: startTagInHead,
6717 [tokenizer.END_TAG_TOKEN]: endTagInHead,
6718 [tokenizer.EOF_TOKEN]: tokenInHead
6719 },
6720 [IN_HEAD_NO_SCRIPT_MODE]: {
6721 [tokenizer.CHARACTER_TOKEN]: tokenInHeadNoScript,
6722 [tokenizer.NULL_CHARACTER_TOKEN]: tokenInHeadNoScript,
6723 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
6724 [tokenizer.COMMENT_TOKEN]: appendComment,
6725 [tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
6726 [tokenizer.START_TAG_TOKEN]: startTagInHeadNoScript,
6727 [tokenizer.END_TAG_TOKEN]: endTagInHeadNoScript,
6728 [tokenizer.EOF_TOKEN]: tokenInHeadNoScript
6729 },
6730 [AFTER_HEAD_MODE]: {
6731 [tokenizer.CHARACTER_TOKEN]: tokenAfterHead,
6732 [tokenizer.NULL_CHARACTER_TOKEN]: tokenAfterHead,
6733 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
6734 [tokenizer.COMMENT_TOKEN]: appendComment,
6735 [tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
6736 [tokenizer.START_TAG_TOKEN]: startTagAfterHead,
6737 [tokenizer.END_TAG_TOKEN]: endTagAfterHead,
6738 [tokenizer.EOF_TOKEN]: tokenAfterHead
6739 },
6740 [IN_BODY_MODE]: {
6741 [tokenizer.CHARACTER_TOKEN]: characterInBody,
6742 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6743 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
6744 [tokenizer.COMMENT_TOKEN]: appendComment,
6745 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6746 [tokenizer.START_TAG_TOKEN]: startTagInBody,
6747 [tokenizer.END_TAG_TOKEN]: endTagInBody,
6748 [tokenizer.EOF_TOKEN]: eofInBody
6749 },
6750 [TEXT_MODE]: {
6751 [tokenizer.CHARACTER_TOKEN]: insertCharacters,
6752 [tokenizer.NULL_CHARACTER_TOKEN]: insertCharacters,
6753 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
6754 [tokenizer.COMMENT_TOKEN]: ignoreToken,
6755 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6756 [tokenizer.START_TAG_TOKEN]: ignoreToken,
6757 [tokenizer.END_TAG_TOKEN]: endTagInText,
6758 [tokenizer.EOF_TOKEN]: eofInText
6759 },
6760 [IN_TABLE_MODE]: {
6761 [tokenizer.CHARACTER_TOKEN]: characterInTable,
6762 [tokenizer.NULL_CHARACTER_TOKEN]: characterInTable,
6763 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: characterInTable,
6764 [tokenizer.COMMENT_TOKEN]: appendComment,
6765 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6766 [tokenizer.START_TAG_TOKEN]: startTagInTable,
6767 [tokenizer.END_TAG_TOKEN]: endTagInTable,
6768 [tokenizer.EOF_TOKEN]: eofInBody
6769 },
6770 [IN_TABLE_TEXT_MODE]: {
6771 [tokenizer.CHARACTER_TOKEN]: characterInTableText,
6772 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6773 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInTableText,
6774 [tokenizer.COMMENT_TOKEN]: tokenInTableText,
6775 [tokenizer.DOCTYPE_TOKEN]: tokenInTableText,
6776 [tokenizer.START_TAG_TOKEN]: tokenInTableText,
6777 [tokenizer.END_TAG_TOKEN]: tokenInTableText,
6778 [tokenizer.EOF_TOKEN]: tokenInTableText
6779 },
6780 [IN_CAPTION_MODE]: {
6781 [tokenizer.CHARACTER_TOKEN]: characterInBody,
6782 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6783 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
6784 [tokenizer.COMMENT_TOKEN]: appendComment,
6785 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6786 [tokenizer.START_TAG_TOKEN]: startTagInCaption,
6787 [tokenizer.END_TAG_TOKEN]: endTagInCaption,
6788 [tokenizer.EOF_TOKEN]: eofInBody
6789 },
6790 [IN_COLUMN_GROUP_MODE]: {
6791 [tokenizer.CHARACTER_TOKEN]: tokenInColumnGroup,
6792 [tokenizer.NULL_CHARACTER_TOKEN]: tokenInColumnGroup,
6793 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
6794 [tokenizer.COMMENT_TOKEN]: appendComment,
6795 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6796 [tokenizer.START_TAG_TOKEN]: startTagInColumnGroup,
6797 [tokenizer.END_TAG_TOKEN]: endTagInColumnGroup,
6798 [tokenizer.EOF_TOKEN]: eofInBody
6799 },
6800 [IN_TABLE_BODY_MODE]: {
6801 [tokenizer.CHARACTER_TOKEN]: characterInTable,
6802 [tokenizer.NULL_CHARACTER_TOKEN]: characterInTable,
6803 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: characterInTable,
6804 [tokenizer.COMMENT_TOKEN]: appendComment,
6805 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6806 [tokenizer.START_TAG_TOKEN]: startTagInTableBody,
6807 [tokenizer.END_TAG_TOKEN]: endTagInTableBody,
6808 [tokenizer.EOF_TOKEN]: eofInBody
6809 },
6810 [IN_ROW_MODE]: {
6811 [tokenizer.CHARACTER_TOKEN]: characterInTable,
6812 [tokenizer.NULL_CHARACTER_TOKEN]: characterInTable,
6813 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: characterInTable,
6814 [tokenizer.COMMENT_TOKEN]: appendComment,
6815 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6816 [tokenizer.START_TAG_TOKEN]: startTagInRow,
6817 [tokenizer.END_TAG_TOKEN]: endTagInRow,
6818 [tokenizer.EOF_TOKEN]: eofInBody
6819 },
6820 [IN_CELL_MODE]: {
6821 [tokenizer.CHARACTER_TOKEN]: characterInBody,
6822 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6823 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
6824 [tokenizer.COMMENT_TOKEN]: appendComment,
6825 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6826 [tokenizer.START_TAG_TOKEN]: startTagInCell,
6827 [tokenizer.END_TAG_TOKEN]: endTagInCell,
6828 [tokenizer.EOF_TOKEN]: eofInBody
6829 },
6830 [IN_SELECT_MODE]: {
6831 [tokenizer.CHARACTER_TOKEN]: insertCharacters,
6832 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6833 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
6834 [tokenizer.COMMENT_TOKEN]: appendComment,
6835 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6836 [tokenizer.START_TAG_TOKEN]: startTagInSelect,
6837 [tokenizer.END_TAG_TOKEN]: endTagInSelect,
6838 [tokenizer.EOF_TOKEN]: eofInBody
6839 },
6840 [IN_SELECT_IN_TABLE_MODE]: {
6841 [tokenizer.CHARACTER_TOKEN]: insertCharacters,
6842 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6843 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
6844 [tokenizer.COMMENT_TOKEN]: appendComment,
6845 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6846 [tokenizer.START_TAG_TOKEN]: startTagInSelectInTable,
6847 [tokenizer.END_TAG_TOKEN]: endTagInSelectInTable,
6848 [tokenizer.EOF_TOKEN]: eofInBody
6849 },
6850 [IN_TEMPLATE_MODE]: {
6851 [tokenizer.CHARACTER_TOKEN]: characterInBody,
6852 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6853 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
6854 [tokenizer.COMMENT_TOKEN]: appendComment,
6855 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6856 [tokenizer.START_TAG_TOKEN]: startTagInTemplate,
6857 [tokenizer.END_TAG_TOKEN]: endTagInTemplate,
6858 [tokenizer.EOF_TOKEN]: eofInTemplate
6859 },
6860 [AFTER_BODY_MODE]: {
6861 [tokenizer.CHARACTER_TOKEN]: tokenAfterBody,
6862 [tokenizer.NULL_CHARACTER_TOKEN]: tokenAfterBody,
6863 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
6864 [tokenizer.COMMENT_TOKEN]: appendCommentToRootHtmlElement,
6865 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6866 [tokenizer.START_TAG_TOKEN]: startTagAfterBody,
6867 [tokenizer.END_TAG_TOKEN]: endTagAfterBody,
6868 [tokenizer.EOF_TOKEN]: stopParsing
6869 },
6870 [IN_FRAMESET_MODE]: {
6871 [tokenizer.CHARACTER_TOKEN]: ignoreToken,
6872 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6873 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
6874 [tokenizer.COMMENT_TOKEN]: appendComment,
6875 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6876 [tokenizer.START_TAG_TOKEN]: startTagInFrameset,
6877 [tokenizer.END_TAG_TOKEN]: endTagInFrameset,
6878 [tokenizer.EOF_TOKEN]: stopParsing
6879 },
6880 [AFTER_FRAMESET_MODE]: {
6881 [tokenizer.CHARACTER_TOKEN]: ignoreToken,
6882 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6883 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
6884 [tokenizer.COMMENT_TOKEN]: appendComment,
6885 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6886 [tokenizer.START_TAG_TOKEN]: startTagAfterFrameset,
6887 [tokenizer.END_TAG_TOKEN]: endTagAfterFrameset,
6888 [tokenizer.EOF_TOKEN]: stopParsing
6889 },
6890 [AFTER_AFTER_BODY_MODE]: {
6891 [tokenizer.CHARACTER_TOKEN]: tokenAfterAfterBody,
6892 [tokenizer.NULL_CHARACTER_TOKEN]: tokenAfterAfterBody,
6893 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
6894 [tokenizer.COMMENT_TOKEN]: appendCommentToDocument,
6895 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6896 [tokenizer.START_TAG_TOKEN]: startTagAfterAfterBody,
6897 [tokenizer.END_TAG_TOKEN]: tokenAfterAfterBody,
6898 [tokenizer.EOF_TOKEN]: stopParsing
6899 },
6900 [AFTER_AFTER_FRAMESET_MODE]: {
6901 [tokenizer.CHARACTER_TOKEN]: ignoreToken,
6902 [tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
6903 [tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
6904 [tokenizer.COMMENT_TOKEN]: appendCommentToDocument,
6905 [tokenizer.DOCTYPE_TOKEN]: ignoreToken,
6906 [tokenizer.START_TAG_TOKEN]: startTagAfterAfterFrameset,
6907 [tokenizer.END_TAG_TOKEN]: ignoreToken,
6908 [tokenizer.EOF_TOKEN]: stopParsing
6909 }
6910}; //Parser
6911
6912class Parser {
6913 constructor(options) {
6914 this.options = mergeOptions(DEFAULT_OPTIONS, options);
6915 this.treeAdapter = this.options.treeAdapter;
6916 this.pendingScript = null;
6917
6918 if (this.options.sourceCodeLocationInfo) {
6919 mixin.install(this, parserMixin);
6920 }
6921
6922 if (this.options.onParseError) {
6923 mixin.install(this, parserMixin$1, {
6924 onParseError: this.options.onParseError
6925 });
6926 }
6927 } // API
6928
6929
6930 parse(html) {
6931 const document = this.treeAdapter.createDocument();
6932
6933 this._bootstrap(document, null);
6934
6935 this.tokenizer.write(html, true);
6936
6937 this._runParsingLoop(null);
6938
6939 return document;
6940 }
6941
6942 parseFragment(html, fragmentContext) {
6943 //NOTE: use <template> element as a fragment context if context element was not provided,
6944 //so we will parse in "forgiving" manner
6945 if (!fragmentContext) {
6946 fragmentContext = this.treeAdapter.createElement($$4.TEMPLATE, NS$1.HTML, []);
6947 } //NOTE: create fake element which will be used as 'document' for fragment parsing.
6948 //This is important for jsdom there 'document' can't be recreated, therefore
6949 //fragment parsing causes messing of the main `document`.
6950
6951
6952 const documentMock = this.treeAdapter.createElement('documentmock', NS$1.HTML, []);
6953
6954 this._bootstrap(documentMock, fragmentContext);
6955
6956 if (this.treeAdapter.getTagName(fragmentContext) === $$4.TEMPLATE) {
6957 this._pushTmplInsertionMode(IN_TEMPLATE_MODE);
6958 }
6959
6960 this._initTokenizerForFragmentParsing();
6961
6962 this._insertFakeRootElement();
6963
6964 this._resetInsertionMode();
6965
6966 this._findFormInFragmentContext();
6967
6968 this.tokenizer.write(html, true);
6969
6970 this._runParsingLoop(null);
6971
6972 const rootElement = this.treeAdapter.getFirstChild(documentMock);
6973 const fragment = this.treeAdapter.createDocumentFragment();
6974
6975 this._adoptNodes(rootElement, fragment);
6976
6977 return fragment;
6978 } //Bootstrap parser
6979
6980
6981 _bootstrap(document, fragmentContext) {
6982 this.tokenizer = new tokenizer(this.options);
6983 this.stopped = false;
6984 this.insertionMode = INITIAL_MODE;
6985 this.originalInsertionMode = '';
6986 this.document = document;
6987 this.fragmentContext = fragmentContext;
6988 this.headElement = null;
6989 this.formElement = null;
6990 this.openElements = new openElementStack(this.document, this.treeAdapter);
6991 this.activeFormattingElements = new formattingElementList(this.treeAdapter);
6992 this.tmplInsertionModeStack = [];
6993 this.tmplInsertionModeStackTop = -1;
6994 this.currentTmplInsertionMode = null;
6995 this.pendingCharacterTokens = [];
6996 this.hasNonWhitespacePendingCharacterToken = false;
6997 this.framesetOk = true;
6998 this.skipNextNewLine = false;
6999 this.fosterParentingEnabled = false;
7000 } //Errors
7001
7002
7003 _err() {} // NOTE: err reporting is noop by default. Enabled by mixin.
7004 //Parsing loop
7005
7006
7007 _runParsingLoop(scriptHandler) {
7008 while (!this.stopped) {
7009 this._setupTokenizerCDATAMode();
7010
7011 const token = this.tokenizer.getNextToken();
7012
7013 if (token.type === tokenizer.HIBERNATION_TOKEN) {
7014 break;
7015 }
7016
7017 if (this.skipNextNewLine) {
7018 this.skipNextNewLine = false;
7019
7020 if (token.type === tokenizer.WHITESPACE_CHARACTER_TOKEN && token.chars[0] === '\n') {
7021 if (token.chars.length === 1) {
7022 continue;
7023 }
7024
7025 token.chars = token.chars.substr(1);
7026 }
7027 }
7028
7029 this._processInputToken(token);
7030
7031 if (scriptHandler && this.pendingScript) {
7032 break;
7033 }
7034 }
7035 }
7036
7037 runParsingLoopForCurrentChunk(writeCallback, scriptHandler) {
7038 this._runParsingLoop(scriptHandler);
7039
7040 if (scriptHandler && this.pendingScript) {
7041 const script = this.pendingScript;
7042 this.pendingScript = null;
7043 scriptHandler(script);
7044 return;
7045 }
7046
7047 if (writeCallback) {
7048 writeCallback();
7049 }
7050 } //Text parsing
7051
7052
7053 _setupTokenizerCDATAMode() {
7054 const current = this._getAdjustedCurrentElement();
7055
7056 this.tokenizer.allowCDATA = current && current !== this.document && this.treeAdapter.getNamespaceURI(current) !== NS$1.HTML && !this._isIntegrationPoint(current);
7057 }
7058
7059 _switchToTextParsing(currentToken, nextTokenizerState) {
7060 this._insertElement(currentToken, NS$1.HTML);
7061
7062 this.tokenizer.state = nextTokenizerState;
7063 this.originalInsertionMode = this.insertionMode;
7064 this.insertionMode = TEXT_MODE;
7065 }
7066
7067 switchToPlaintextParsing() {
7068 this.insertionMode = TEXT_MODE;
7069 this.originalInsertionMode = IN_BODY_MODE;
7070 this.tokenizer.state = tokenizer.MODE.PLAINTEXT;
7071 } //Fragment parsing
7072
7073
7074 _getAdjustedCurrentElement() {
7075 return this.openElements.stackTop === 0 && this.fragmentContext ? this.fragmentContext : this.openElements.current;
7076 }
7077
7078 _findFormInFragmentContext() {
7079 let node = this.fragmentContext;
7080
7081 do {
7082 if (this.treeAdapter.getTagName(node) === $$4.FORM) {
7083 this.formElement = node;
7084 break;
7085 }
7086
7087 node = this.treeAdapter.getParentNode(node);
7088 } while (node);
7089 }
7090
7091 _initTokenizerForFragmentParsing() {
7092 if (this.treeAdapter.getNamespaceURI(this.fragmentContext) === NS$1.HTML) {
7093 const tn = this.treeAdapter.getTagName(this.fragmentContext);
7094
7095 if (tn === $$4.TITLE || tn === $$4.TEXTAREA) {
7096 this.tokenizer.state = tokenizer.MODE.RCDATA;
7097 } else if (tn === $$4.STYLE || tn === $$4.XMP || tn === $$4.IFRAME || tn === $$4.NOEMBED || tn === $$4.NOFRAMES || tn === $$4.NOSCRIPT) {
7098 this.tokenizer.state = tokenizer.MODE.RAWTEXT;
7099 } else if (tn === $$4.SCRIPT) {
7100 this.tokenizer.state = tokenizer.MODE.SCRIPT_DATA;
7101 } else if (tn === $$4.PLAINTEXT) {
7102 this.tokenizer.state = tokenizer.MODE.PLAINTEXT;
7103 }
7104 }
7105 } //Tree mutation
7106
7107
7108 _setDocumentType(token) {
7109 const name = token.name || '';
7110 const publicId = token.publicId || '';
7111 const systemId = token.systemId || '';
7112 this.treeAdapter.setDocumentType(this.document, name, publicId, systemId);
7113 }
7114
7115 _attachElementToTree(element) {
7116 if (this._shouldFosterParentOnInsertion()) {
7117 this._fosterParentElement(element);
7118 } else {
7119 const parent = this.openElements.currentTmplContent || this.openElements.current;
7120 this.treeAdapter.appendChild(parent, element);
7121 }
7122 }
7123
7124 _appendElement(token, namespaceURI) {
7125 const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
7126
7127 this._attachElementToTree(element);
7128 }
7129
7130 _insertElement(token, namespaceURI) {
7131 const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
7132
7133 this._attachElementToTree(element);
7134
7135 this.openElements.push(element);
7136 }
7137
7138 _insertFakeElement(tagName) {
7139 const element = this.treeAdapter.createElement(tagName, NS$1.HTML, []);
7140
7141 this._attachElementToTree(element);
7142
7143 this.openElements.push(element);
7144 }
7145
7146 _insertTemplate(token) {
7147 const tmpl = this.treeAdapter.createElement(token.tagName, NS$1.HTML, token.attrs);
7148 const content = this.treeAdapter.createDocumentFragment();
7149 this.treeAdapter.setTemplateContent(tmpl, content);
7150
7151 this._attachElementToTree(tmpl);
7152
7153 this.openElements.push(tmpl);
7154 }
7155
7156 _insertFakeRootElement() {
7157 const element = this.treeAdapter.createElement($$4.HTML, NS$1.HTML, []);
7158 this.treeAdapter.appendChild(this.openElements.current, element);
7159 this.openElements.push(element);
7160 }
7161
7162 _appendCommentNode(token, parent) {
7163 const commentNode = this.treeAdapter.createCommentNode(token.data);
7164 this.treeAdapter.appendChild(parent, commentNode);
7165 }
7166
7167 _insertCharacters(token) {
7168 if (this._shouldFosterParentOnInsertion()) {
7169 this._fosterParentText(token.chars);
7170 } else {
7171 const parent = this.openElements.currentTmplContent || this.openElements.current;
7172 this.treeAdapter.insertText(parent, token.chars);
7173 }
7174 }
7175
7176 _adoptNodes(donor, recipient) {
7177 for (let child = this.treeAdapter.getFirstChild(donor); child; child = this.treeAdapter.getFirstChild(donor)) {
7178 this.treeAdapter.detachNode(child);
7179 this.treeAdapter.appendChild(recipient, child);
7180 }
7181 } //Token processing
7182
7183
7184 _shouldProcessTokenInForeignContent(token) {
7185 const current = this._getAdjustedCurrentElement();
7186
7187 if (!current || current === this.document) {
7188 return false;
7189 }
7190
7191 const ns = this.treeAdapter.getNamespaceURI(current);
7192
7193 if (ns === NS$1.HTML) {
7194 return false;
7195 }
7196
7197 if (this.treeAdapter.getTagName(current) === $$4.ANNOTATION_XML && ns === NS$1.MATHML && token.type === tokenizer.START_TAG_TOKEN && token.tagName === $$4.SVG) {
7198 return false;
7199 }
7200
7201 const isCharacterToken = token.type === tokenizer.CHARACTER_TOKEN || token.type === tokenizer.NULL_CHARACTER_TOKEN || token.type === tokenizer.WHITESPACE_CHARACTER_TOKEN;
7202 const isMathMLTextStartTag = token.type === tokenizer.START_TAG_TOKEN && token.tagName !== $$4.MGLYPH && token.tagName !== $$4.MALIGNMARK;
7203
7204 if ((isMathMLTextStartTag || isCharacterToken) && this._isIntegrationPoint(current, NS$1.MATHML)) {
7205 return false;
7206 }
7207
7208 if ((token.type === tokenizer.START_TAG_TOKEN || isCharacterToken) && this._isIntegrationPoint(current, NS$1.HTML)) {
7209 return false;
7210 }
7211
7212 return token.type !== tokenizer.EOF_TOKEN;
7213 }
7214
7215 _processToken(token) {
7216 TOKEN_HANDLERS[this.insertionMode][token.type](this, token);
7217 }
7218
7219 _processTokenInBodyMode(token) {
7220 TOKEN_HANDLERS[IN_BODY_MODE][token.type](this, token);
7221 }
7222
7223 _processTokenInForeignContent(token) {
7224 if (token.type === tokenizer.CHARACTER_TOKEN) {
7225 characterInForeignContent(this, token);
7226 } else if (token.type === tokenizer.NULL_CHARACTER_TOKEN) {
7227 nullCharacterInForeignContent(this, token);
7228 } else if (token.type === tokenizer.WHITESPACE_CHARACTER_TOKEN) {
7229 insertCharacters(this, token);
7230 } else if (token.type === tokenizer.COMMENT_TOKEN) {
7231 appendComment(this, token);
7232 } else if (token.type === tokenizer.START_TAG_TOKEN) {
7233 startTagInForeignContent(this, token);
7234 } else if (token.type === tokenizer.END_TAG_TOKEN) {
7235 endTagInForeignContent(this, token);
7236 }
7237 }
7238
7239 _processInputToken(token) {
7240 if (this._shouldProcessTokenInForeignContent(token)) {
7241 this._processTokenInForeignContent(token);
7242 } else {
7243 this._processToken(token);
7244 }
7245
7246 if (token.type === tokenizer.START_TAG_TOKEN && token.selfClosing && !token.ackSelfClosing) {
7247 this._err(errorCodes.nonVoidHtmlElementStartTagWithTrailingSolidus);
7248 }
7249 } //Integration points
7250
7251
7252 _isIntegrationPoint(element, foreignNS) {
7253 const tn = this.treeAdapter.getTagName(element);
7254 const ns = this.treeAdapter.getNamespaceURI(element);
7255 const attrs = this.treeAdapter.getAttrList(element);
7256 return foreignContent.isIntegrationPoint(tn, ns, attrs, foreignNS);
7257 } //Active formatting elements reconstruction
7258
7259
7260 _reconstructActiveFormattingElements() {
7261 const listLength = this.activeFormattingElements.length;
7262
7263 if (listLength) {
7264 let unopenIdx = listLength;
7265 let entry = null;
7266
7267 do {
7268 unopenIdx--;
7269 entry = this.activeFormattingElements.entries[unopenIdx];
7270
7271 if (entry.type === formattingElementList.MARKER_ENTRY || this.openElements.contains(entry.element)) {
7272 unopenIdx++;
7273 break;
7274 }
7275 } while (unopenIdx > 0);
7276
7277 for (let i = unopenIdx; i < listLength; i++) {
7278 entry = this.activeFormattingElements.entries[i];
7279
7280 this._insertElement(entry.token, this.treeAdapter.getNamespaceURI(entry.element));
7281
7282 entry.element = this.openElements.current;
7283 }
7284 }
7285 } //Close elements
7286
7287
7288 _closeTableCell() {
7289 this.openElements.generateImpliedEndTags();
7290 this.openElements.popUntilTableCellPopped();
7291 this.activeFormattingElements.clearToLastMarker();
7292 this.insertionMode = IN_ROW_MODE;
7293 }
7294
7295 _closePElement() {
7296 this.openElements.generateImpliedEndTagsWithExclusion($$4.P);
7297 this.openElements.popUntilTagNamePopped($$4.P);
7298 } //Insertion modes
7299
7300
7301 _resetInsertionMode() {
7302 for (let i = this.openElements.stackTop, last = false; i >= 0; i--) {
7303 let element = this.openElements.items[i];
7304
7305 if (i === 0) {
7306 last = true;
7307
7308 if (this.fragmentContext) {
7309 element = this.fragmentContext;
7310 }
7311 }
7312
7313 const tn = this.treeAdapter.getTagName(element);
7314 const newInsertionMode = INSERTION_MODE_RESET_MAP[tn];
7315
7316 if (newInsertionMode) {
7317 this.insertionMode = newInsertionMode;
7318 break;
7319 } else if (!last && (tn === $$4.TD || tn === $$4.TH)) {
7320 this.insertionMode = IN_CELL_MODE;
7321 break;
7322 } else if (!last && tn === $$4.HEAD) {
7323 this.insertionMode = IN_HEAD_MODE;
7324 break;
7325 } else if (tn === $$4.SELECT) {
7326 this._resetInsertionModeForSelect(i);
7327
7328 break;
7329 } else if (tn === $$4.TEMPLATE) {
7330 this.insertionMode = this.currentTmplInsertionMode;
7331 break;
7332 } else if (tn === $$4.HTML) {
7333 this.insertionMode = this.headElement ? AFTER_HEAD_MODE : BEFORE_HEAD_MODE;
7334 break;
7335 } else if (last) {
7336 this.insertionMode = IN_BODY_MODE;
7337 break;
7338 }
7339 }
7340 }
7341
7342 _resetInsertionModeForSelect(selectIdx) {
7343 if (selectIdx > 0) {
7344 for (let i = selectIdx - 1; i > 0; i--) {
7345 const ancestor = this.openElements.items[i];
7346 const tn = this.treeAdapter.getTagName(ancestor);
7347
7348 if (tn === $$4.TEMPLATE) {
7349 break;
7350 } else if (tn === $$4.TABLE) {
7351 this.insertionMode = IN_SELECT_IN_TABLE_MODE;
7352 return;
7353 }
7354 }
7355 }
7356
7357 this.insertionMode = IN_SELECT_MODE;
7358 }
7359
7360 _pushTmplInsertionMode(mode) {
7361 this.tmplInsertionModeStack.push(mode);
7362 this.tmplInsertionModeStackTop++;
7363 this.currentTmplInsertionMode = mode;
7364 }
7365
7366 _popTmplInsertionMode() {
7367 this.tmplInsertionModeStack.pop();
7368 this.tmplInsertionModeStackTop--;
7369 this.currentTmplInsertionMode = this.tmplInsertionModeStack[this.tmplInsertionModeStackTop];
7370 } //Foster parenting
7371
7372
7373 _isElementCausesFosterParenting(element) {
7374 const tn = this.treeAdapter.getTagName(element);
7375 return tn === $$4.TABLE || tn === $$4.TBODY || tn === $$4.TFOOT || tn === $$4.THEAD || tn === $$4.TR;
7376 }
7377
7378 _shouldFosterParentOnInsertion() {
7379 return this.fosterParentingEnabled && this._isElementCausesFosterParenting(this.openElements.current);
7380 }
7381
7382 _findFosterParentingLocation() {
7383 const location = {
7384 parent: null,
7385 beforeElement: null
7386 };
7387
7388 for (let i = this.openElements.stackTop; i >= 0; i--) {
7389 const openElement = this.openElements.items[i];
7390 const tn = this.treeAdapter.getTagName(openElement);
7391 const ns = this.treeAdapter.getNamespaceURI(openElement);
7392
7393 if (tn === $$4.TEMPLATE && ns === NS$1.HTML) {
7394 location.parent = this.treeAdapter.getTemplateContent(openElement);
7395 break;
7396 } else if (tn === $$4.TABLE) {
7397 location.parent = this.treeAdapter.getParentNode(openElement);
7398
7399 if (location.parent) {
7400 location.beforeElement = openElement;
7401 } else {
7402 location.parent = this.openElements.items[i - 1];
7403 }
7404
7405 break;
7406 }
7407 }
7408
7409 if (!location.parent) {
7410 location.parent = this.openElements.items[0];
7411 }
7412
7413 return location;
7414 }
7415
7416 _fosterParentElement(element) {
7417 const location = this._findFosterParentingLocation();
7418
7419 if (location.beforeElement) {
7420 this.treeAdapter.insertBefore(location.parent, element, location.beforeElement);
7421 } else {
7422 this.treeAdapter.appendChild(location.parent, element);
7423 }
7424 }
7425
7426 _fosterParentText(chars) {
7427 const location = this._findFosterParentingLocation();
7428
7429 if (location.beforeElement) {
7430 this.treeAdapter.insertTextBefore(location.parent, chars, location.beforeElement);
7431 } else {
7432 this.treeAdapter.insertText(location.parent, chars);
7433 }
7434 } //Special elements
7435
7436
7437 _isSpecialElement(element) {
7438 const tn = this.treeAdapter.getTagName(element);
7439 const ns = this.treeAdapter.getNamespaceURI(element);
7440 return html.SPECIAL_ELEMENTS[ns][tn];
7441 }
7442
7443}
7444
7445var parser = Parser; //Adoption agency algorithm
7446//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#adoptionAgency)
7447//------------------------------------------------------------------
7448//Steps 5-8 of the algorithm
7449
7450function aaObtainFormattingElementEntry(p, token) {
7451 let formattingElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);
7452
7453 if (formattingElementEntry) {
7454 if (!p.openElements.contains(formattingElementEntry.element)) {
7455 p.activeFormattingElements.removeEntry(formattingElementEntry);
7456 formattingElementEntry = null;
7457 } else if (!p.openElements.hasInScope(token.tagName)) {
7458 formattingElementEntry = null;
7459 }
7460 } else {
7461 genericEndTagInBody(p, token);
7462 }
7463
7464 return formattingElementEntry;
7465} //Steps 9 and 10 of the algorithm
7466
7467
7468function aaObtainFurthestBlock(p, formattingElementEntry) {
7469 let furthestBlock = null;
7470
7471 for (let i = p.openElements.stackTop; i >= 0; i--) {
7472 const element = p.openElements.items[i];
7473
7474 if (element === formattingElementEntry.element) {
7475 break;
7476 }
7477
7478 if (p._isSpecialElement(element)) {
7479 furthestBlock = element;
7480 }
7481 }
7482
7483 if (!furthestBlock) {
7484 p.openElements.popUntilElementPopped(formattingElementEntry.element);
7485 p.activeFormattingElements.removeEntry(formattingElementEntry);
7486 }
7487
7488 return furthestBlock;
7489} //Step 13 of the algorithm
7490
7491
7492function aaInnerLoop(p, furthestBlock, formattingElement) {
7493 let lastElement = furthestBlock;
7494 let nextElement = p.openElements.getCommonAncestor(furthestBlock);
7495
7496 for (let i = 0, element = nextElement; element !== formattingElement; i++, element = nextElement) {
7497 //NOTE: store next element for the next loop iteration (it may be deleted from the stack by step 9.5)
7498 nextElement = p.openElements.getCommonAncestor(element);
7499 const elementEntry = p.activeFormattingElements.getElementEntry(element);
7500 const counterOverflow = elementEntry && i >= AA_INNER_LOOP_ITER;
7501 const shouldRemoveFromOpenElements = !elementEntry || counterOverflow;
7502
7503 if (shouldRemoveFromOpenElements) {
7504 if (counterOverflow) {
7505 p.activeFormattingElements.removeEntry(elementEntry);
7506 }
7507
7508 p.openElements.remove(element);
7509 } else {
7510 element = aaRecreateElementFromEntry(p, elementEntry);
7511
7512 if (lastElement === furthestBlock) {
7513 p.activeFormattingElements.bookmark = elementEntry;
7514 }
7515
7516 p.treeAdapter.detachNode(lastElement);
7517 p.treeAdapter.appendChild(element, lastElement);
7518 lastElement = element;
7519 }
7520 }
7521
7522 return lastElement;
7523} //Step 13.7 of the algorithm
7524
7525
7526function aaRecreateElementFromEntry(p, elementEntry) {
7527 const ns = p.treeAdapter.getNamespaceURI(elementEntry.element);
7528 const newElement = p.treeAdapter.createElement(elementEntry.token.tagName, ns, elementEntry.token.attrs);
7529 p.openElements.replace(elementEntry.element, newElement);
7530 elementEntry.element = newElement;
7531 return newElement;
7532} //Step 14 of the algorithm
7533
7534
7535function aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement) {
7536 if (p._isElementCausesFosterParenting(commonAncestor)) {
7537 p._fosterParentElement(lastElement);
7538 } else {
7539 const tn = p.treeAdapter.getTagName(commonAncestor);
7540 const ns = p.treeAdapter.getNamespaceURI(commonAncestor);
7541
7542 if (tn === $$4.TEMPLATE && ns === NS$1.HTML) {
7543 commonAncestor = p.treeAdapter.getTemplateContent(commonAncestor);
7544 }
7545
7546 p.treeAdapter.appendChild(commonAncestor, lastElement);
7547 }
7548} //Steps 15-19 of the algorithm
7549
7550
7551function aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry) {
7552 const ns = p.treeAdapter.getNamespaceURI(formattingElementEntry.element);
7553 const token = formattingElementEntry.token;
7554 const newElement = p.treeAdapter.createElement(token.tagName, ns, token.attrs);
7555
7556 p._adoptNodes(furthestBlock, newElement);
7557
7558 p.treeAdapter.appendChild(furthestBlock, newElement);
7559 p.activeFormattingElements.insertElementAfterBookmark(newElement, formattingElementEntry.token);
7560 p.activeFormattingElements.removeEntry(formattingElementEntry);
7561 p.openElements.remove(formattingElementEntry.element);
7562 p.openElements.insertAfter(furthestBlock, newElement);
7563} //Algorithm entry point
7564
7565
7566function callAdoptionAgency(p, token) {
7567 let formattingElementEntry;
7568
7569 for (let i = 0; i < AA_OUTER_LOOP_ITER; i++) {
7570 formattingElementEntry = aaObtainFormattingElementEntry(p, token, formattingElementEntry);
7571
7572 if (!formattingElementEntry) {
7573 break;
7574 }
7575
7576 const furthestBlock = aaObtainFurthestBlock(p, formattingElementEntry);
7577
7578 if (!furthestBlock) {
7579 break;
7580 }
7581
7582 p.activeFormattingElements.bookmark = formattingElementEntry;
7583 const lastElement = aaInnerLoop(p, furthestBlock, formattingElementEntry.element);
7584 const commonAncestor = p.openElements.getCommonAncestor(formattingElementEntry.element);
7585 p.treeAdapter.detachNode(lastElement);
7586 aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement);
7587 aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry);
7588 }
7589} //Generic token handlers
7590//------------------------------------------------------------------
7591
7592
7593function ignoreToken() {//NOTE: do nothing =)
7594}
7595
7596function misplacedDoctype(p) {
7597 p._err(errorCodes.misplacedDoctype);
7598}
7599
7600function appendComment(p, token) {
7601 p._appendCommentNode(token, p.openElements.currentTmplContent || p.openElements.current);
7602}
7603
7604function appendCommentToRootHtmlElement(p, token) {
7605 p._appendCommentNode(token, p.openElements.items[0]);
7606}
7607
7608function appendCommentToDocument(p, token) {
7609 p._appendCommentNode(token, p.document);
7610}
7611
7612function insertCharacters(p, token) {
7613 p._insertCharacters(token);
7614}
7615
7616function stopParsing(p) {
7617 p.stopped = true;
7618} // The "initial" insertion mode
7619//------------------------------------------------------------------
7620
7621
7622function doctypeInInitialMode(p, token) {
7623 p._setDocumentType(token);
7624
7625 const mode = token.forceQuirks ? html.DOCUMENT_MODE.QUIRKS : doctype.getDocumentMode(token);
7626
7627 if (!doctype.isConforming(token)) {
7628 p._err(errorCodes.nonConformingDoctype);
7629 }
7630
7631 p.treeAdapter.setDocumentMode(p.document, mode);
7632 p.insertionMode = BEFORE_HTML_MODE;
7633}
7634
7635function tokenInInitialMode(p, token) {
7636 p._err(errorCodes.missingDoctype, {
7637 beforeToken: true
7638 });
7639
7640 p.treeAdapter.setDocumentMode(p.document, html.DOCUMENT_MODE.QUIRKS);
7641 p.insertionMode = BEFORE_HTML_MODE;
7642
7643 p._processToken(token);
7644} // The "before html" insertion mode
7645//------------------------------------------------------------------
7646
7647
7648function startTagBeforeHtml(p, token) {
7649 if (token.tagName === $$4.HTML) {
7650 p._insertElement(token, NS$1.HTML);
7651
7652 p.insertionMode = BEFORE_HEAD_MODE;
7653 } else {
7654 tokenBeforeHtml(p, token);
7655 }
7656}
7657
7658function endTagBeforeHtml(p, token) {
7659 const tn = token.tagName;
7660
7661 if (tn === $$4.HTML || tn === $$4.HEAD || tn === $$4.BODY || tn === $$4.BR) {
7662 tokenBeforeHtml(p, token);
7663 }
7664}
7665
7666function tokenBeforeHtml(p, token) {
7667 p._insertFakeRootElement();
7668
7669 p.insertionMode = BEFORE_HEAD_MODE;
7670
7671 p._processToken(token);
7672} // The "before head" insertion mode
7673//------------------------------------------------------------------
7674
7675
7676function startTagBeforeHead(p, token) {
7677 const tn = token.tagName;
7678
7679 if (tn === $$4.HTML) {
7680 startTagInBody(p, token);
7681 } else if (tn === $$4.HEAD) {
7682 p._insertElement(token, NS$1.HTML);
7683
7684 p.headElement = p.openElements.current;
7685 p.insertionMode = IN_HEAD_MODE;
7686 } else {
7687 tokenBeforeHead(p, token);
7688 }
7689}
7690
7691function endTagBeforeHead(p, token) {
7692 const tn = token.tagName;
7693
7694 if (tn === $$4.HEAD || tn === $$4.BODY || tn === $$4.HTML || tn === $$4.BR) {
7695 tokenBeforeHead(p, token);
7696 } else {
7697 p._err(errorCodes.endTagWithoutMatchingOpenElement);
7698 }
7699}
7700
7701function tokenBeforeHead(p, token) {
7702 p._insertFakeElement($$4.HEAD);
7703
7704 p.headElement = p.openElements.current;
7705 p.insertionMode = IN_HEAD_MODE;
7706
7707 p._processToken(token);
7708} // The "in head" insertion mode
7709//------------------------------------------------------------------
7710
7711
7712function startTagInHead(p, token) {
7713 const tn = token.tagName;
7714
7715 if (tn === $$4.HTML) {
7716 startTagInBody(p, token);
7717 } else if (tn === $$4.BASE || tn === $$4.BASEFONT || tn === $$4.BGSOUND || tn === $$4.LINK || tn === $$4.META) {
7718 p._appendElement(token, NS$1.HTML);
7719
7720 token.ackSelfClosing = true;
7721 } else if (tn === $$4.TITLE) {
7722 p._switchToTextParsing(token, tokenizer.MODE.RCDATA);
7723 } else if (tn === $$4.NOSCRIPT) {
7724 if (p.options.scriptingEnabled) {
7725 p._switchToTextParsing(token, tokenizer.MODE.RAWTEXT);
7726 } else {
7727 p._insertElement(token, NS$1.HTML);
7728
7729 p.insertionMode = IN_HEAD_NO_SCRIPT_MODE;
7730 }
7731 } else if (tn === $$4.NOFRAMES || tn === $$4.STYLE) {
7732 p._switchToTextParsing(token, tokenizer.MODE.RAWTEXT);
7733 } else if (tn === $$4.SCRIPT) {
7734 p._switchToTextParsing(token, tokenizer.MODE.SCRIPT_DATA);
7735 } else if (tn === $$4.TEMPLATE) {
7736 p._insertTemplate(token, NS$1.HTML);
7737
7738 p.activeFormattingElements.insertMarker();
7739 p.framesetOk = false;
7740 p.insertionMode = IN_TEMPLATE_MODE;
7741
7742 p._pushTmplInsertionMode(IN_TEMPLATE_MODE);
7743 } else if (tn === $$4.HEAD) {
7744 p._err(errorCodes.misplacedStartTagForHeadElement);
7745 } else {
7746 tokenInHead(p, token);
7747 }
7748}
7749
7750function endTagInHead(p, token) {
7751 const tn = token.tagName;
7752
7753 if (tn === $$4.HEAD) {
7754 p.openElements.pop();
7755 p.insertionMode = AFTER_HEAD_MODE;
7756 } else if (tn === $$4.BODY || tn === $$4.BR || tn === $$4.HTML) {
7757 tokenInHead(p, token);
7758 } else if (tn === $$4.TEMPLATE) {
7759 if (p.openElements.tmplCount > 0) {
7760 p.openElements.generateImpliedEndTagsThoroughly();
7761
7762 if (p.openElements.currentTagName !== $$4.TEMPLATE) {
7763 p._err(errorCodes.closingOfElementWithOpenChildElements);
7764 }
7765
7766 p.openElements.popUntilTagNamePopped($$4.TEMPLATE);
7767 p.activeFormattingElements.clearToLastMarker();
7768
7769 p._popTmplInsertionMode();
7770
7771 p._resetInsertionMode();
7772 } else {
7773 p._err(errorCodes.endTagWithoutMatchingOpenElement);
7774 }
7775 } else {
7776 p._err(errorCodes.endTagWithoutMatchingOpenElement);
7777 }
7778}
7779
7780function tokenInHead(p, token) {
7781 p.openElements.pop();
7782 p.insertionMode = AFTER_HEAD_MODE;
7783
7784 p._processToken(token);
7785} // The "in head no script" insertion mode
7786//------------------------------------------------------------------
7787
7788
7789function startTagInHeadNoScript(p, token) {
7790 const tn = token.tagName;
7791
7792 if (tn === $$4.HTML) {
7793 startTagInBody(p, token);
7794 } else if (tn === $$4.BASEFONT || tn === $$4.BGSOUND || tn === $$4.HEAD || tn === $$4.LINK || tn === $$4.META || tn === $$4.NOFRAMES || tn === $$4.STYLE) {
7795 startTagInHead(p, token);
7796 } else if (tn === $$4.NOSCRIPT) {
7797 p._err(errorCodes.nestedNoscriptInHead);
7798 } else {
7799 tokenInHeadNoScript(p, token);
7800 }
7801}
7802
7803function endTagInHeadNoScript(p, token) {
7804 const tn = token.tagName;
7805
7806 if (tn === $$4.NOSCRIPT) {
7807 p.openElements.pop();
7808 p.insertionMode = IN_HEAD_MODE;
7809 } else if (tn === $$4.BR) {
7810 tokenInHeadNoScript(p, token);
7811 } else {
7812 p._err(errorCodes.endTagWithoutMatchingOpenElement);
7813 }
7814}
7815
7816function tokenInHeadNoScript(p, token) {
7817 const errCode = token.type === tokenizer.EOF_TOKEN ? errorCodes.openElementsLeftAfterEof : errorCodes.disallowedContentInNoscriptInHead;
7818
7819 p._err(errCode);
7820
7821 p.openElements.pop();
7822 p.insertionMode = IN_HEAD_MODE;
7823
7824 p._processToken(token);
7825} // The "after head" insertion mode
7826//------------------------------------------------------------------
7827
7828
7829function startTagAfterHead(p, token) {
7830 const tn = token.tagName;
7831
7832 if (tn === $$4.HTML) {
7833 startTagInBody(p, token);
7834 } else if (tn === $$4.BODY) {
7835 p._insertElement(token, NS$1.HTML);
7836
7837 p.framesetOk = false;
7838 p.insertionMode = IN_BODY_MODE;
7839 } else if (tn === $$4.FRAMESET) {
7840 p._insertElement(token, NS$1.HTML);
7841
7842 p.insertionMode = IN_FRAMESET_MODE;
7843 } else if (tn === $$4.BASE || tn === $$4.BASEFONT || tn === $$4.BGSOUND || tn === $$4.LINK || tn === $$4.META || tn === $$4.NOFRAMES || tn === $$4.SCRIPT || tn === $$4.STYLE || tn === $$4.TEMPLATE || tn === $$4.TITLE) {
7844 p._err(errorCodes.abandonedHeadElementChild);
7845
7846 p.openElements.push(p.headElement);
7847 startTagInHead(p, token);
7848 p.openElements.remove(p.headElement);
7849 } else if (tn === $$4.HEAD) {
7850 p._err(errorCodes.misplacedStartTagForHeadElement);
7851 } else {
7852 tokenAfterHead(p, token);
7853 }
7854}
7855
7856function endTagAfterHead(p, token) {
7857 const tn = token.tagName;
7858
7859 if (tn === $$4.BODY || tn === $$4.HTML || tn === $$4.BR) {
7860 tokenAfterHead(p, token);
7861 } else if (tn === $$4.TEMPLATE) {
7862 endTagInHead(p, token);
7863 } else {
7864 p._err(errorCodes.endTagWithoutMatchingOpenElement);
7865 }
7866}
7867
7868function tokenAfterHead(p, token) {
7869 p._insertFakeElement($$4.BODY);
7870
7871 p.insertionMode = IN_BODY_MODE;
7872
7873 p._processToken(token);
7874} // The "in body" insertion mode
7875//------------------------------------------------------------------
7876
7877
7878function whitespaceCharacterInBody(p, token) {
7879 p._reconstructActiveFormattingElements();
7880
7881 p._insertCharacters(token);
7882}
7883
7884function characterInBody(p, token) {
7885 p._reconstructActiveFormattingElements();
7886
7887 p._insertCharacters(token);
7888
7889 p.framesetOk = false;
7890}
7891
7892function htmlStartTagInBody(p, token) {
7893 if (p.openElements.tmplCount === 0) {
7894 p.treeAdapter.adoptAttributes(p.openElements.items[0], token.attrs);
7895 }
7896}
7897
7898function bodyStartTagInBody(p, token) {
7899 const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
7900
7901 if (bodyElement && p.openElements.tmplCount === 0) {
7902 p.framesetOk = false;
7903 p.treeAdapter.adoptAttributes(bodyElement, token.attrs);
7904 }
7905}
7906
7907function framesetStartTagInBody(p, token) {
7908 const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
7909
7910 if (p.framesetOk && bodyElement) {
7911 p.treeAdapter.detachNode(bodyElement);
7912 p.openElements.popAllUpToHtmlElement();
7913
7914 p._insertElement(token, NS$1.HTML);
7915
7916 p.insertionMode = IN_FRAMESET_MODE;
7917 }
7918}
7919
7920function addressStartTagInBody(p, token) {
7921 if (p.openElements.hasInButtonScope($$4.P)) {
7922 p._closePElement();
7923 }
7924
7925 p._insertElement(token, NS$1.HTML);
7926}
7927
7928function numberedHeaderStartTagInBody(p, token) {
7929 if (p.openElements.hasInButtonScope($$4.P)) {
7930 p._closePElement();
7931 }
7932
7933 const tn = p.openElements.currentTagName;
7934
7935 if (tn === $$4.H1 || tn === $$4.H2 || tn === $$4.H3 || tn === $$4.H4 || tn === $$4.H5 || tn === $$4.H6) {
7936 p.openElements.pop();
7937 }
7938
7939 p._insertElement(token, NS$1.HTML);
7940}
7941
7942function preStartTagInBody(p, token) {
7943 if (p.openElements.hasInButtonScope($$4.P)) {
7944 p._closePElement();
7945 }
7946
7947 p._insertElement(token, NS$1.HTML); //NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
7948 //on to the next one. (Newlines at the start of pre blocks are ignored as an authoring convenience.)
7949
7950
7951 p.skipNextNewLine = true;
7952 p.framesetOk = false;
7953}
7954
7955function formStartTagInBody(p, token) {
7956 const inTemplate = p.openElements.tmplCount > 0;
7957
7958 if (!p.formElement || inTemplate) {
7959 if (p.openElements.hasInButtonScope($$4.P)) {
7960 p._closePElement();
7961 }
7962
7963 p._insertElement(token, NS$1.HTML);
7964
7965 if (!inTemplate) {
7966 p.formElement = p.openElements.current;
7967 }
7968 }
7969}
7970
7971function listItemStartTagInBody(p, token) {
7972 p.framesetOk = false;
7973 const tn = token.tagName;
7974
7975 for (let i = p.openElements.stackTop; i >= 0; i--) {
7976 const element = p.openElements.items[i];
7977 const elementTn = p.treeAdapter.getTagName(element);
7978 let closeTn = null;
7979
7980 if (tn === $$4.LI && elementTn === $$4.LI) {
7981 closeTn = $$4.LI;
7982 } else if ((tn === $$4.DD || tn === $$4.DT) && (elementTn === $$4.DD || elementTn === $$4.DT)) {
7983 closeTn = elementTn;
7984 }
7985
7986 if (closeTn) {
7987 p.openElements.generateImpliedEndTagsWithExclusion(closeTn);
7988 p.openElements.popUntilTagNamePopped(closeTn);
7989 break;
7990 }
7991
7992 if (elementTn !== $$4.ADDRESS && elementTn !== $$4.DIV && elementTn !== $$4.P && p._isSpecialElement(element)) {
7993 break;
7994 }
7995 }
7996
7997 if (p.openElements.hasInButtonScope($$4.P)) {
7998 p._closePElement();
7999 }
8000
8001 p._insertElement(token, NS$1.HTML);
8002}
8003
8004function plaintextStartTagInBody(p, token) {
8005 if (p.openElements.hasInButtonScope($$4.P)) {
8006 p._closePElement();
8007 }
8008
8009 p._insertElement(token, NS$1.HTML);
8010
8011 p.tokenizer.state = tokenizer.MODE.PLAINTEXT;
8012}
8013
8014function buttonStartTagInBody(p, token) {
8015 if (p.openElements.hasInScope($$4.BUTTON)) {
8016 p.openElements.generateImpliedEndTags();
8017 p.openElements.popUntilTagNamePopped($$4.BUTTON);
8018 }
8019
8020 p._reconstructActiveFormattingElements();
8021
8022 p._insertElement(token, NS$1.HTML);
8023
8024 p.framesetOk = false;
8025}
8026
8027function aStartTagInBody(p, token) {
8028 const activeElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName($$4.A);
8029
8030 if (activeElementEntry) {
8031 callAdoptionAgency(p, token);
8032 p.openElements.remove(activeElementEntry.element);
8033 p.activeFormattingElements.removeEntry(activeElementEntry);
8034 }
8035
8036 p._reconstructActiveFormattingElements();
8037
8038 p._insertElement(token, NS$1.HTML);
8039
8040 p.activeFormattingElements.pushElement(p.openElements.current, token);
8041}
8042
8043function bStartTagInBody(p, token) {
8044 p._reconstructActiveFormattingElements();
8045
8046 p._insertElement(token, NS$1.HTML);
8047
8048 p.activeFormattingElements.pushElement(p.openElements.current, token);
8049}
8050
8051function nobrStartTagInBody(p, token) {
8052 p._reconstructActiveFormattingElements();
8053
8054 if (p.openElements.hasInScope($$4.NOBR)) {
8055 callAdoptionAgency(p, token);
8056
8057 p._reconstructActiveFormattingElements();
8058 }
8059
8060 p._insertElement(token, NS$1.HTML);
8061
8062 p.activeFormattingElements.pushElement(p.openElements.current, token);
8063}
8064
8065function appletStartTagInBody(p, token) {
8066 p._reconstructActiveFormattingElements();
8067
8068 p._insertElement(token, NS$1.HTML);
8069
8070 p.activeFormattingElements.insertMarker();
8071 p.framesetOk = false;
8072}
8073
8074function tableStartTagInBody(p, token) {
8075 if (p.treeAdapter.getDocumentMode(p.document) !== html.DOCUMENT_MODE.QUIRKS && p.openElements.hasInButtonScope($$4.P)) {
8076 p._closePElement();
8077 }
8078
8079 p._insertElement(token, NS$1.HTML);
8080
8081 p.framesetOk = false;
8082 p.insertionMode = IN_TABLE_MODE;
8083}
8084
8085function areaStartTagInBody(p, token) {
8086 p._reconstructActiveFormattingElements();
8087
8088 p._appendElement(token, NS$1.HTML);
8089
8090 p.framesetOk = false;
8091 token.ackSelfClosing = true;
8092}
8093
8094function inputStartTagInBody(p, token) {
8095 p._reconstructActiveFormattingElements();
8096
8097 p._appendElement(token, NS$1.HTML);
8098
8099 const inputType = tokenizer.getTokenAttr(token, ATTRS.TYPE);
8100
8101 if (!inputType || inputType.toLowerCase() !== HIDDEN_INPUT_TYPE) {
8102 p.framesetOk = false;
8103 }
8104
8105 token.ackSelfClosing = true;
8106}
8107
8108function paramStartTagInBody(p, token) {
8109 p._appendElement(token, NS$1.HTML);
8110
8111 token.ackSelfClosing = true;
8112}
8113
8114function hrStartTagInBody(p, token) {
8115 if (p.openElements.hasInButtonScope($$4.P)) {
8116 p._closePElement();
8117 }
8118
8119 p._appendElement(token, NS$1.HTML);
8120
8121 p.framesetOk = false;
8122 p.ackSelfClosing = true;
8123}
8124
8125function imageStartTagInBody(p, token) {
8126 token.tagName = $$4.IMG;
8127 areaStartTagInBody(p, token);
8128}
8129
8130function textareaStartTagInBody(p, token) {
8131 p._insertElement(token, NS$1.HTML); //NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
8132 //on to the next one. (Newlines at the start of textarea elements are ignored as an authoring convenience.)
8133
8134
8135 p.skipNextNewLine = true;
8136 p.tokenizer.state = tokenizer.MODE.RCDATA;
8137 p.originalInsertionMode = p.insertionMode;
8138 p.framesetOk = false;
8139 p.insertionMode = TEXT_MODE;
8140}
8141
8142function xmpStartTagInBody(p, token) {
8143 if (p.openElements.hasInButtonScope($$4.P)) {
8144 p._closePElement();
8145 }
8146
8147 p._reconstructActiveFormattingElements();
8148
8149 p.framesetOk = false;
8150
8151 p._switchToTextParsing(token, tokenizer.MODE.RAWTEXT);
8152}
8153
8154function iframeStartTagInBody(p, token) {
8155 p.framesetOk = false;
8156
8157 p._switchToTextParsing(token, tokenizer.MODE.RAWTEXT);
8158} //NOTE: here we assume that we always act as an user agent with enabled plugins, so we parse
8159//<noembed> as a rawtext.
8160
8161
8162function noembedStartTagInBody(p, token) {
8163 p._switchToTextParsing(token, tokenizer.MODE.RAWTEXT);
8164}
8165
8166function selectStartTagInBody(p, token) {
8167 p._reconstructActiveFormattingElements();
8168
8169 p._insertElement(token, NS$1.HTML);
8170
8171 p.framesetOk = false;
8172
8173 if (p.insertionMode === IN_TABLE_MODE || p.insertionMode === IN_CAPTION_MODE || p.insertionMode === IN_TABLE_BODY_MODE || p.insertionMode === IN_ROW_MODE || p.insertionMode === IN_CELL_MODE) {
8174 p.insertionMode = IN_SELECT_IN_TABLE_MODE;
8175 } else {
8176 p.insertionMode = IN_SELECT_MODE;
8177 }
8178}
8179
8180function optgroupStartTagInBody(p, token) {
8181 if (p.openElements.currentTagName === $$4.OPTION) {
8182 p.openElements.pop();
8183 }
8184
8185 p._reconstructActiveFormattingElements();
8186
8187 p._insertElement(token, NS$1.HTML);
8188}
8189
8190function rbStartTagInBody(p, token) {
8191 if (p.openElements.hasInScope($$4.RUBY)) {
8192 p.openElements.generateImpliedEndTags();
8193 }
8194
8195 p._insertElement(token, NS$1.HTML);
8196}
8197
8198function rtStartTagInBody(p, token) {
8199 if (p.openElements.hasInScope($$4.RUBY)) {
8200 p.openElements.generateImpliedEndTagsWithExclusion($$4.RTC);
8201 }
8202
8203 p._insertElement(token, NS$1.HTML);
8204}
8205
8206function menuStartTagInBody(p, token) {
8207 if (p.openElements.hasInButtonScope($$4.P)) {
8208 p._closePElement();
8209 }
8210
8211 p._insertElement(token, NS$1.HTML);
8212}
8213
8214function mathStartTagInBody(p, token) {
8215 p._reconstructActiveFormattingElements();
8216
8217 foreignContent.adjustTokenMathMLAttrs(token);
8218 foreignContent.adjustTokenXMLAttrs(token);
8219
8220 if (token.selfClosing) {
8221 p._appendElement(token, NS$1.MATHML);
8222 } else {
8223 p._insertElement(token, NS$1.MATHML);
8224 }
8225
8226 token.ackSelfClosing = true;
8227}
8228
8229function svgStartTagInBody(p, token) {
8230 p._reconstructActiveFormattingElements();
8231
8232 foreignContent.adjustTokenSVGAttrs(token);
8233 foreignContent.adjustTokenXMLAttrs(token);
8234
8235 if (token.selfClosing) {
8236 p._appendElement(token, NS$1.SVG);
8237 } else {
8238 p._insertElement(token, NS$1.SVG);
8239 }
8240
8241 token.ackSelfClosing = true;
8242}
8243
8244function genericStartTagInBody(p, token) {
8245 p._reconstructActiveFormattingElements();
8246
8247 p._insertElement(token, NS$1.HTML);
8248} //OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
8249//It's faster than using dictionary.
8250
8251
8252function startTagInBody(p, token) {
8253 const tn = token.tagName;
8254
8255 switch (tn.length) {
8256 case 1:
8257 if (tn === $$4.I || tn === $$4.S || tn === $$4.B || tn === $$4.U) {
8258 bStartTagInBody(p, token);
8259 } else if (tn === $$4.P) {
8260 addressStartTagInBody(p, token);
8261 } else if (tn === $$4.A) {
8262 aStartTagInBody(p, token);
8263 } else {
8264 genericStartTagInBody(p, token);
8265 }
8266
8267 break;
8268
8269 case 2:
8270 if (tn === $$4.DL || tn === $$4.OL || tn === $$4.UL) {
8271 addressStartTagInBody(p, token);
8272 } else if (tn === $$4.H1 || tn === $$4.H2 || tn === $$4.H3 || tn === $$4.H4 || tn === $$4.H5 || tn === $$4.H6) {
8273 numberedHeaderStartTagInBody(p, token);
8274 } else if (tn === $$4.LI || tn === $$4.DD || tn === $$4.DT) {
8275 listItemStartTagInBody(p, token);
8276 } else if (tn === $$4.EM || tn === $$4.TT) {
8277 bStartTagInBody(p, token);
8278 } else if (tn === $$4.BR) {
8279 areaStartTagInBody(p, token);
8280 } else if (tn === $$4.HR) {
8281 hrStartTagInBody(p, token);
8282 } else if (tn === $$4.RB) {
8283 rbStartTagInBody(p, token);
8284 } else if (tn === $$4.RT || tn === $$4.RP) {
8285 rtStartTagInBody(p, token);
8286 } else if (tn !== $$4.TH && tn !== $$4.TD && tn !== $$4.TR) {
8287 genericStartTagInBody(p, token);
8288 }
8289
8290 break;
8291
8292 case 3:
8293 if (tn === $$4.DIV || tn === $$4.DIR || tn === $$4.NAV) {
8294 addressStartTagInBody(p, token);
8295 } else if (tn === $$4.PRE) {
8296 preStartTagInBody(p, token);
8297 } else if (tn === $$4.BIG) {
8298 bStartTagInBody(p, token);
8299 } else if (tn === $$4.IMG || tn === $$4.WBR) {
8300 areaStartTagInBody(p, token);
8301 } else if (tn === $$4.XMP) {
8302 xmpStartTagInBody(p, token);
8303 } else if (tn === $$4.SVG) {
8304 svgStartTagInBody(p, token);
8305 } else if (tn === $$4.RTC) {
8306 rbStartTagInBody(p, token);
8307 } else if (tn !== $$4.COL) {
8308 genericStartTagInBody(p, token);
8309 }
8310
8311 break;
8312
8313 case 4:
8314 if (tn === $$4.HTML) {
8315 htmlStartTagInBody(p, token);
8316 } else if (tn === $$4.BASE || tn === $$4.LINK || tn === $$4.META) {
8317 startTagInHead(p, token);
8318 } else if (tn === $$4.BODY) {
8319 bodyStartTagInBody(p, token);
8320 } else if (tn === $$4.MAIN || tn === $$4.MENU) {
8321 addressStartTagInBody(p, token);
8322 } else if (tn === $$4.FORM) {
8323 formStartTagInBody(p, token);
8324 } else if (tn === $$4.CODE || tn === $$4.FONT) {
8325 bStartTagInBody(p, token);
8326 } else if (tn === $$4.NOBR) {
8327 nobrStartTagInBody(p, token);
8328 } else if (tn === $$4.AREA) {
8329 areaStartTagInBody(p, token);
8330 } else if (tn === $$4.MATH) {
8331 mathStartTagInBody(p, token);
8332 } else if (tn === $$4.MENU) {
8333 menuStartTagInBody(p, token);
8334 } else if (tn !== $$4.HEAD) {
8335 genericStartTagInBody(p, token);
8336 }
8337
8338 break;
8339
8340 case 5:
8341 if (tn === $$4.STYLE || tn === $$4.TITLE) {
8342 startTagInHead(p, token);
8343 } else if (tn === $$4.ASIDE) {
8344 addressStartTagInBody(p, token);
8345 } else if (tn === $$4.SMALL) {
8346 bStartTagInBody(p, token);
8347 } else if (tn === $$4.TABLE) {
8348 tableStartTagInBody(p, token);
8349 } else if (tn === $$4.EMBED) {
8350 areaStartTagInBody(p, token);
8351 } else if (tn === $$4.INPUT) {
8352 inputStartTagInBody(p, token);
8353 } else if (tn === $$4.PARAM || tn === $$4.TRACK) {
8354 paramStartTagInBody(p, token);
8355 } else if (tn === $$4.IMAGE) {
8356 imageStartTagInBody(p, token);
8357 } else if (tn !== $$4.FRAME && tn !== $$4.TBODY && tn !== $$4.TFOOT && tn !== $$4.THEAD) {
8358 genericStartTagInBody(p, token);
8359 }
8360
8361 break;
8362
8363 case 6:
8364 if (tn === $$4.SCRIPT) {
8365 startTagInHead(p, token);
8366 } else if (tn === $$4.CENTER || tn === $$4.FIGURE || tn === $$4.FOOTER || tn === $$4.HEADER || tn === $$4.HGROUP || tn === $$4.DIALOG) {
8367 addressStartTagInBody(p, token);
8368 } else if (tn === $$4.BUTTON) {
8369 buttonStartTagInBody(p, token);
8370 } else if (tn === $$4.STRIKE || tn === $$4.STRONG) {
8371 bStartTagInBody(p, token);
8372 } else if (tn === $$4.APPLET || tn === $$4.OBJECT) {
8373 appletStartTagInBody(p, token);
8374 } else if (tn === $$4.KEYGEN) {
8375 areaStartTagInBody(p, token);
8376 } else if (tn === $$4.SOURCE) {
8377 paramStartTagInBody(p, token);
8378 } else if (tn === $$4.IFRAME) {
8379 iframeStartTagInBody(p, token);
8380 } else if (tn === $$4.SELECT) {
8381 selectStartTagInBody(p, token);
8382 } else if (tn === $$4.OPTION) {
8383 optgroupStartTagInBody(p, token);
8384 } else {
8385 genericStartTagInBody(p, token);
8386 }
8387
8388 break;
8389
8390 case 7:
8391 if (tn === $$4.BGSOUND) {
8392 startTagInHead(p, token);
8393 } else if (tn === $$4.DETAILS || tn === $$4.ADDRESS || tn === $$4.ARTICLE || tn === $$4.SECTION || tn === $$4.SUMMARY) {
8394 addressStartTagInBody(p, token);
8395 } else if (tn === $$4.LISTING) {
8396 preStartTagInBody(p, token);
8397 } else if (tn === $$4.MARQUEE) {
8398 appletStartTagInBody(p, token);
8399 } else if (tn === $$4.NOEMBED) {
8400 noembedStartTagInBody(p, token);
8401 } else if (tn !== $$4.CAPTION) {
8402 genericStartTagInBody(p, token);
8403 }
8404
8405 break;
8406
8407 case 8:
8408 if (tn === $$4.BASEFONT) {
8409 startTagInHead(p, token);
8410 } else if (tn === $$4.FRAMESET) {
8411 framesetStartTagInBody(p, token);
8412 } else if (tn === $$4.FIELDSET) {
8413 addressStartTagInBody(p, token);
8414 } else if (tn === $$4.TEXTAREA) {
8415 textareaStartTagInBody(p, token);
8416 } else if (tn === $$4.TEMPLATE) {
8417 startTagInHead(p, token);
8418 } else if (tn === $$4.NOSCRIPT) {
8419 if (p.options.scriptingEnabled) {
8420 noembedStartTagInBody(p, token);
8421 } else {
8422 genericStartTagInBody(p, token);
8423 }
8424 } else if (tn === $$4.OPTGROUP) {
8425 optgroupStartTagInBody(p, token);
8426 } else if (tn !== $$4.COLGROUP) {
8427 genericStartTagInBody(p, token);
8428 }
8429
8430 break;
8431
8432 case 9:
8433 if (tn === $$4.PLAINTEXT) {
8434 plaintextStartTagInBody(p, token);
8435 } else {
8436 genericStartTagInBody(p, token);
8437 }
8438
8439 break;
8440
8441 case 10:
8442 if (tn === $$4.BLOCKQUOTE || tn === $$4.FIGCAPTION) {
8443 addressStartTagInBody(p, token);
8444 } else {
8445 genericStartTagInBody(p, token);
8446 }
8447
8448 break;
8449
8450 default:
8451 genericStartTagInBody(p, token);
8452 }
8453}
8454
8455function bodyEndTagInBody(p) {
8456 if (p.openElements.hasInScope($$4.BODY)) {
8457 p.insertionMode = AFTER_BODY_MODE;
8458 }
8459}
8460
8461function htmlEndTagInBody(p, token) {
8462 if (p.openElements.hasInScope($$4.BODY)) {
8463 p.insertionMode = AFTER_BODY_MODE;
8464
8465 p._processToken(token);
8466 }
8467}
8468
8469function addressEndTagInBody(p, token) {
8470 const tn = token.tagName;
8471
8472 if (p.openElements.hasInScope(tn)) {
8473 p.openElements.generateImpliedEndTags();
8474 p.openElements.popUntilTagNamePopped(tn);
8475 }
8476}
8477
8478function formEndTagInBody(p) {
8479 const inTemplate = p.openElements.tmplCount > 0;
8480 const formElement = p.formElement;
8481
8482 if (!inTemplate) {
8483 p.formElement = null;
8484 }
8485
8486 if ((formElement || inTemplate) && p.openElements.hasInScope($$4.FORM)) {
8487 p.openElements.generateImpliedEndTags();
8488
8489 if (inTemplate) {
8490 p.openElements.popUntilTagNamePopped($$4.FORM);
8491 } else {
8492 p.openElements.remove(formElement);
8493 }
8494 }
8495}
8496
8497function pEndTagInBody(p) {
8498 if (!p.openElements.hasInButtonScope($$4.P)) {
8499 p._insertFakeElement($$4.P);
8500 }
8501
8502 p._closePElement();
8503}
8504
8505function liEndTagInBody(p) {
8506 if (p.openElements.hasInListItemScope($$4.LI)) {
8507 p.openElements.generateImpliedEndTagsWithExclusion($$4.LI);
8508 p.openElements.popUntilTagNamePopped($$4.LI);
8509 }
8510}
8511
8512function ddEndTagInBody(p, token) {
8513 const tn = token.tagName;
8514
8515 if (p.openElements.hasInScope(tn)) {
8516 p.openElements.generateImpliedEndTagsWithExclusion(tn);
8517 p.openElements.popUntilTagNamePopped(tn);
8518 }
8519}
8520
8521function numberedHeaderEndTagInBody(p) {
8522 if (p.openElements.hasNumberedHeaderInScope()) {
8523 p.openElements.generateImpliedEndTags();
8524 p.openElements.popUntilNumberedHeaderPopped();
8525 }
8526}
8527
8528function appletEndTagInBody(p, token) {
8529 const tn = token.tagName;
8530
8531 if (p.openElements.hasInScope(tn)) {
8532 p.openElements.generateImpliedEndTags();
8533 p.openElements.popUntilTagNamePopped(tn);
8534 p.activeFormattingElements.clearToLastMarker();
8535 }
8536}
8537
8538function brEndTagInBody(p) {
8539 p._reconstructActiveFormattingElements();
8540
8541 p._insertFakeElement($$4.BR);
8542
8543 p.openElements.pop();
8544 p.framesetOk = false;
8545}
8546
8547function genericEndTagInBody(p, token) {
8548 const tn = token.tagName;
8549
8550 for (let i = p.openElements.stackTop; i > 0; i--) {
8551 const element = p.openElements.items[i];
8552
8553 if (p.treeAdapter.getTagName(element) === tn) {
8554 p.openElements.generateImpliedEndTagsWithExclusion(tn);
8555 p.openElements.popUntilElementPopped(element);
8556 break;
8557 }
8558
8559 if (p._isSpecialElement(element)) {
8560 break;
8561 }
8562 }
8563} //OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
8564//It's faster than using dictionary.
8565
8566
8567function endTagInBody(p, token) {
8568 const tn = token.tagName;
8569
8570 switch (tn.length) {
8571 case 1:
8572 if (tn === $$4.A || tn === $$4.B || tn === $$4.I || tn === $$4.S || tn === $$4.U) {
8573 callAdoptionAgency(p, token);
8574 } else if (tn === $$4.P) {
8575 pEndTagInBody(p, token);
8576 } else {
8577 genericEndTagInBody(p, token);
8578 }
8579
8580 break;
8581
8582 case 2:
8583 if (tn === $$4.DL || tn === $$4.UL || tn === $$4.OL) {
8584 addressEndTagInBody(p, token);
8585 } else if (tn === $$4.LI) {
8586 liEndTagInBody(p, token);
8587 } else if (tn === $$4.DD || tn === $$4.DT) {
8588 ddEndTagInBody(p, token);
8589 } else if (tn === $$4.H1 || tn === $$4.H2 || tn === $$4.H3 || tn === $$4.H4 || tn === $$4.H5 || tn === $$4.H6) {
8590 numberedHeaderEndTagInBody(p, token);
8591 } else if (tn === $$4.BR) {
8592 brEndTagInBody(p, token);
8593 } else if (tn === $$4.EM || tn === $$4.TT) {
8594 callAdoptionAgency(p, token);
8595 } else {
8596 genericEndTagInBody(p, token);
8597 }
8598
8599 break;
8600
8601 case 3:
8602 if (tn === $$4.BIG) {
8603 callAdoptionAgency(p, token);
8604 } else if (tn === $$4.DIR || tn === $$4.DIV || tn === $$4.NAV || tn === $$4.PRE) {
8605 addressEndTagInBody(p, token);
8606 } else {
8607 genericEndTagInBody(p, token);
8608 }
8609
8610 break;
8611
8612 case 4:
8613 if (tn === $$4.BODY) {
8614 bodyEndTagInBody(p, token);
8615 } else if (tn === $$4.HTML) {
8616 htmlEndTagInBody(p, token);
8617 } else if (tn === $$4.FORM) {
8618 formEndTagInBody(p, token);
8619 } else if (tn === $$4.CODE || tn === $$4.FONT || tn === $$4.NOBR) {
8620 callAdoptionAgency(p, token);
8621 } else if (tn === $$4.MAIN || tn === $$4.MENU) {
8622 addressEndTagInBody(p, token);
8623 } else {
8624 genericEndTagInBody(p, token);
8625 }
8626
8627 break;
8628
8629 case 5:
8630 if (tn === $$4.ASIDE) {
8631 addressEndTagInBody(p, token);
8632 } else if (tn === $$4.SMALL) {
8633 callAdoptionAgency(p, token);
8634 } else {
8635 genericEndTagInBody(p, token);
8636 }
8637
8638 break;
8639
8640 case 6:
8641 if (tn === $$4.CENTER || tn === $$4.FIGURE || tn === $$4.FOOTER || tn === $$4.HEADER || tn === $$4.HGROUP || tn === $$4.DIALOG) {
8642 addressEndTagInBody(p, token);
8643 } else if (tn === $$4.APPLET || tn === $$4.OBJECT) {
8644 appletEndTagInBody(p, token);
8645 } else if (tn === $$4.STRIKE || tn === $$4.STRONG) {
8646 callAdoptionAgency(p, token);
8647 } else {
8648 genericEndTagInBody(p, token);
8649 }
8650
8651 break;
8652
8653 case 7:
8654 if (tn === $$4.ADDRESS || tn === $$4.ARTICLE || tn === $$4.DETAILS || tn === $$4.SECTION || tn === $$4.SUMMARY || tn === $$4.LISTING) {
8655 addressEndTagInBody(p, token);
8656 } else if (tn === $$4.MARQUEE) {
8657 appletEndTagInBody(p, token);
8658 } else {
8659 genericEndTagInBody(p, token);
8660 }
8661
8662 break;
8663
8664 case 8:
8665 if (tn === $$4.FIELDSET) {
8666 addressEndTagInBody(p, token);
8667 } else if (tn === $$4.TEMPLATE) {
8668 endTagInHead(p, token);
8669 } else {
8670 genericEndTagInBody(p, token);
8671 }
8672
8673 break;
8674
8675 case 10:
8676 if (tn === $$4.BLOCKQUOTE || tn === $$4.FIGCAPTION) {
8677 addressEndTagInBody(p, token);
8678 } else {
8679 genericEndTagInBody(p, token);
8680 }
8681
8682 break;
8683
8684 default:
8685 genericEndTagInBody(p, token);
8686 }
8687}
8688
8689function eofInBody(p, token) {
8690 if (p.tmplInsertionModeStackTop > -1) {
8691 eofInTemplate(p, token);
8692 } else {
8693 p.stopped = true;
8694 }
8695} // The "text" insertion mode
8696//------------------------------------------------------------------
8697
8698
8699function endTagInText(p, token) {
8700 if (token.tagName === $$4.SCRIPT) {
8701 p.pendingScript = p.openElements.current;
8702 }
8703
8704 p.openElements.pop();
8705 p.insertionMode = p.originalInsertionMode;
8706}
8707
8708function eofInText(p, token) {
8709 p._err(errorCodes.eofInElementThatCanContainOnlyText);
8710
8711 p.openElements.pop();
8712 p.insertionMode = p.originalInsertionMode;
8713
8714 p._processToken(token);
8715} // The "in table" insertion mode
8716//------------------------------------------------------------------
8717
8718
8719function characterInTable(p, token) {
8720 const curTn = p.openElements.currentTagName;
8721
8722 if (curTn === $$4.TABLE || curTn === $$4.TBODY || curTn === $$4.TFOOT || curTn === $$4.THEAD || curTn === $$4.TR) {
8723 p.pendingCharacterTokens = [];
8724 p.hasNonWhitespacePendingCharacterToken = false;
8725 p.originalInsertionMode = p.insertionMode;
8726 p.insertionMode = IN_TABLE_TEXT_MODE;
8727
8728 p._processToken(token);
8729 } else {
8730 tokenInTable(p, token);
8731 }
8732}
8733
8734function captionStartTagInTable(p, token) {
8735 p.openElements.clearBackToTableContext();
8736 p.activeFormattingElements.insertMarker();
8737
8738 p._insertElement(token, NS$1.HTML);
8739
8740 p.insertionMode = IN_CAPTION_MODE;
8741}
8742
8743function colgroupStartTagInTable(p, token) {
8744 p.openElements.clearBackToTableContext();
8745
8746 p._insertElement(token, NS$1.HTML);
8747
8748 p.insertionMode = IN_COLUMN_GROUP_MODE;
8749}
8750
8751function colStartTagInTable(p, token) {
8752 p.openElements.clearBackToTableContext();
8753
8754 p._insertFakeElement($$4.COLGROUP);
8755
8756 p.insertionMode = IN_COLUMN_GROUP_MODE;
8757
8758 p._processToken(token);
8759}
8760
8761function tbodyStartTagInTable(p, token) {
8762 p.openElements.clearBackToTableContext();
8763
8764 p._insertElement(token, NS$1.HTML);
8765
8766 p.insertionMode = IN_TABLE_BODY_MODE;
8767}
8768
8769function tdStartTagInTable(p, token) {
8770 p.openElements.clearBackToTableContext();
8771
8772 p._insertFakeElement($$4.TBODY);
8773
8774 p.insertionMode = IN_TABLE_BODY_MODE;
8775
8776 p._processToken(token);
8777}
8778
8779function tableStartTagInTable(p, token) {
8780 if (p.openElements.hasInTableScope($$4.TABLE)) {
8781 p.openElements.popUntilTagNamePopped($$4.TABLE);
8782
8783 p._resetInsertionMode();
8784
8785 p._processToken(token);
8786 }
8787}
8788
8789function inputStartTagInTable(p, token) {
8790 const inputType = tokenizer.getTokenAttr(token, ATTRS.TYPE);
8791
8792 if (inputType && inputType.toLowerCase() === HIDDEN_INPUT_TYPE) {
8793 p._appendElement(token, NS$1.HTML);
8794 } else {
8795 tokenInTable(p, token);
8796 }
8797
8798 token.ackSelfClosing = true;
8799}
8800
8801function formStartTagInTable(p, token) {
8802 if (!p.formElement && p.openElements.tmplCount === 0) {
8803 p._insertElement(token, NS$1.HTML);
8804
8805 p.formElement = p.openElements.current;
8806 p.openElements.pop();
8807 }
8808}
8809
8810function startTagInTable(p, token) {
8811 const tn = token.tagName;
8812
8813 switch (tn.length) {
8814 case 2:
8815 if (tn === $$4.TD || tn === $$4.TH || tn === $$4.TR) {
8816 tdStartTagInTable(p, token);
8817 } else {
8818 tokenInTable(p, token);
8819 }
8820
8821 break;
8822
8823 case 3:
8824 if (tn === $$4.COL) {
8825 colStartTagInTable(p, token);
8826 } else {
8827 tokenInTable(p, token);
8828 }
8829
8830 break;
8831
8832 case 4:
8833 if (tn === $$4.FORM) {
8834 formStartTagInTable(p, token);
8835 } else {
8836 tokenInTable(p, token);
8837 }
8838
8839 break;
8840
8841 case 5:
8842 if (tn === $$4.TABLE) {
8843 tableStartTagInTable(p, token);
8844 } else if (tn === $$4.STYLE) {
8845 startTagInHead(p, token);
8846 } else if (tn === $$4.TBODY || tn === $$4.TFOOT || tn === $$4.THEAD) {
8847 tbodyStartTagInTable(p, token);
8848 } else if (tn === $$4.INPUT) {
8849 inputStartTagInTable(p, token);
8850 } else {
8851 tokenInTable(p, token);
8852 }
8853
8854 break;
8855
8856 case 6:
8857 if (tn === $$4.SCRIPT) {
8858 startTagInHead(p, token);
8859 } else {
8860 tokenInTable(p, token);
8861 }
8862
8863 break;
8864
8865 case 7:
8866 if (tn === $$4.CAPTION) {
8867 captionStartTagInTable(p, token);
8868 } else {
8869 tokenInTable(p, token);
8870 }
8871
8872 break;
8873
8874 case 8:
8875 if (tn === $$4.COLGROUP) {
8876 colgroupStartTagInTable(p, token);
8877 } else if (tn === $$4.TEMPLATE) {
8878 startTagInHead(p, token);
8879 } else {
8880 tokenInTable(p, token);
8881 }
8882
8883 break;
8884
8885 default:
8886 tokenInTable(p, token);
8887 }
8888}
8889
8890function endTagInTable(p, token) {
8891 const tn = token.tagName;
8892
8893 if (tn === $$4.TABLE) {
8894 if (p.openElements.hasInTableScope($$4.TABLE)) {
8895 p.openElements.popUntilTagNamePopped($$4.TABLE);
8896
8897 p._resetInsertionMode();
8898 }
8899 } else if (tn === $$4.TEMPLATE) {
8900 endTagInHead(p, token);
8901 } else if (tn !== $$4.BODY && tn !== $$4.CAPTION && tn !== $$4.COL && tn !== $$4.COLGROUP && tn !== $$4.HTML && tn !== $$4.TBODY && tn !== $$4.TD && tn !== $$4.TFOOT && tn !== $$4.TH && tn !== $$4.THEAD && tn !== $$4.TR) {
8902 tokenInTable(p, token);
8903 }
8904}
8905
8906function tokenInTable(p, token) {
8907 const savedFosterParentingState = p.fosterParentingEnabled;
8908 p.fosterParentingEnabled = true;
8909
8910 p._processTokenInBodyMode(token);
8911
8912 p.fosterParentingEnabled = savedFosterParentingState;
8913} // The "in table text" insertion mode
8914//------------------------------------------------------------------
8915
8916
8917function whitespaceCharacterInTableText(p, token) {
8918 p.pendingCharacterTokens.push(token);
8919}
8920
8921function characterInTableText(p, token) {
8922 p.pendingCharacterTokens.push(token);
8923 p.hasNonWhitespacePendingCharacterToken = true;
8924}
8925
8926function tokenInTableText(p, token) {
8927 let i = 0;
8928
8929 if (p.hasNonWhitespacePendingCharacterToken) {
8930 for (; i < p.pendingCharacterTokens.length; i++) {
8931 tokenInTable(p, p.pendingCharacterTokens[i]);
8932 }
8933 } else {
8934 for (; i < p.pendingCharacterTokens.length; i++) {
8935 p._insertCharacters(p.pendingCharacterTokens[i]);
8936 }
8937 }
8938
8939 p.insertionMode = p.originalInsertionMode;
8940
8941 p._processToken(token);
8942} // The "in caption" insertion mode
8943//------------------------------------------------------------------
8944
8945
8946function startTagInCaption(p, token) {
8947 const tn = token.tagName;
8948
8949 if (tn === $$4.CAPTION || tn === $$4.COL || tn === $$4.COLGROUP || tn === $$4.TBODY || tn === $$4.TD || tn === $$4.TFOOT || tn === $$4.TH || tn === $$4.THEAD || tn === $$4.TR) {
8950 if (p.openElements.hasInTableScope($$4.CAPTION)) {
8951 p.openElements.generateImpliedEndTags();
8952 p.openElements.popUntilTagNamePopped($$4.CAPTION);
8953 p.activeFormattingElements.clearToLastMarker();
8954 p.insertionMode = IN_TABLE_MODE;
8955
8956 p._processToken(token);
8957 }
8958 } else {
8959 startTagInBody(p, token);
8960 }
8961}
8962
8963function endTagInCaption(p, token) {
8964 const tn = token.tagName;
8965
8966 if (tn === $$4.CAPTION || tn === $$4.TABLE) {
8967 if (p.openElements.hasInTableScope($$4.CAPTION)) {
8968 p.openElements.generateImpliedEndTags();
8969 p.openElements.popUntilTagNamePopped($$4.CAPTION);
8970 p.activeFormattingElements.clearToLastMarker();
8971 p.insertionMode = IN_TABLE_MODE;
8972
8973 if (tn === $$4.TABLE) {
8974 p._processToken(token);
8975 }
8976 }
8977 } else if (tn !== $$4.BODY && tn !== $$4.COL && tn !== $$4.COLGROUP && tn !== $$4.HTML && tn !== $$4.TBODY && tn !== $$4.TD && tn !== $$4.TFOOT && tn !== $$4.TH && tn !== $$4.THEAD && tn !== $$4.TR) {
8978 endTagInBody(p, token);
8979 }
8980} // The "in column group" insertion mode
8981//------------------------------------------------------------------
8982
8983
8984function startTagInColumnGroup(p, token) {
8985 const tn = token.tagName;
8986
8987 if (tn === $$4.HTML) {
8988 startTagInBody(p, token);
8989 } else if (tn === $$4.COL) {
8990 p._appendElement(token, NS$1.HTML);
8991
8992 token.ackSelfClosing = true;
8993 } else if (tn === $$4.TEMPLATE) {
8994 startTagInHead(p, token);
8995 } else {
8996 tokenInColumnGroup(p, token);
8997 }
8998}
8999
9000function endTagInColumnGroup(p, token) {
9001 const tn = token.tagName;
9002
9003 if (tn === $$4.COLGROUP) {
9004 if (p.openElements.currentTagName === $$4.COLGROUP) {
9005 p.openElements.pop();
9006 p.insertionMode = IN_TABLE_MODE;
9007 }
9008 } else if (tn === $$4.TEMPLATE) {
9009 endTagInHead(p, token);
9010 } else if (tn !== $$4.COL) {
9011 tokenInColumnGroup(p, token);
9012 }
9013}
9014
9015function tokenInColumnGroup(p, token) {
9016 if (p.openElements.currentTagName === $$4.COLGROUP) {
9017 p.openElements.pop();
9018 p.insertionMode = IN_TABLE_MODE;
9019
9020 p._processToken(token);
9021 }
9022} // The "in table body" insertion mode
9023//------------------------------------------------------------------
9024
9025
9026function startTagInTableBody(p, token) {
9027 const tn = token.tagName;
9028
9029 if (tn === $$4.TR) {
9030 p.openElements.clearBackToTableBodyContext();
9031
9032 p._insertElement(token, NS$1.HTML);
9033
9034 p.insertionMode = IN_ROW_MODE;
9035 } else if (tn === $$4.TH || tn === $$4.TD) {
9036 p.openElements.clearBackToTableBodyContext();
9037
9038 p._insertFakeElement($$4.TR);
9039
9040 p.insertionMode = IN_ROW_MODE;
9041
9042 p._processToken(token);
9043 } else if (tn === $$4.CAPTION || tn === $$4.COL || tn === $$4.COLGROUP || tn === $$4.TBODY || tn === $$4.TFOOT || tn === $$4.THEAD) {
9044 if (p.openElements.hasTableBodyContextInTableScope()) {
9045 p.openElements.clearBackToTableBodyContext();
9046 p.openElements.pop();
9047 p.insertionMode = IN_TABLE_MODE;
9048
9049 p._processToken(token);
9050 }
9051 } else {
9052 startTagInTable(p, token);
9053 }
9054}
9055
9056function endTagInTableBody(p, token) {
9057 const tn = token.tagName;
9058
9059 if (tn === $$4.TBODY || tn === $$4.TFOOT || tn === $$4.THEAD) {
9060 if (p.openElements.hasInTableScope(tn)) {
9061 p.openElements.clearBackToTableBodyContext();
9062 p.openElements.pop();
9063 p.insertionMode = IN_TABLE_MODE;
9064 }
9065 } else if (tn === $$4.TABLE) {
9066 if (p.openElements.hasTableBodyContextInTableScope()) {
9067 p.openElements.clearBackToTableBodyContext();
9068 p.openElements.pop();
9069 p.insertionMode = IN_TABLE_MODE;
9070
9071 p._processToken(token);
9072 }
9073 } else if (tn !== $$4.BODY && tn !== $$4.CAPTION && tn !== $$4.COL && tn !== $$4.COLGROUP || tn !== $$4.HTML && tn !== $$4.TD && tn !== $$4.TH && tn !== $$4.TR) {
9074 endTagInTable(p, token);
9075 }
9076} // The "in row" insertion mode
9077//------------------------------------------------------------------
9078
9079
9080function startTagInRow(p, token) {
9081 const tn = token.tagName;
9082
9083 if (tn === $$4.TH || tn === $$4.TD) {
9084 p.openElements.clearBackToTableRowContext();
9085
9086 p._insertElement(token, NS$1.HTML);
9087
9088 p.insertionMode = IN_CELL_MODE;
9089 p.activeFormattingElements.insertMarker();
9090 } else if (tn === $$4.CAPTION || tn === $$4.COL || tn === $$4.COLGROUP || tn === $$4.TBODY || tn === $$4.TFOOT || tn === $$4.THEAD || tn === $$4.TR) {
9091 if (p.openElements.hasInTableScope($$4.TR)) {
9092 p.openElements.clearBackToTableRowContext();
9093 p.openElements.pop();
9094 p.insertionMode = IN_TABLE_BODY_MODE;
9095
9096 p._processToken(token);
9097 }
9098 } else {
9099 startTagInTable(p, token);
9100 }
9101}
9102
9103function endTagInRow(p, token) {
9104 const tn = token.tagName;
9105
9106 if (tn === $$4.TR) {
9107 if (p.openElements.hasInTableScope($$4.TR)) {
9108 p.openElements.clearBackToTableRowContext();
9109 p.openElements.pop();
9110 p.insertionMode = IN_TABLE_BODY_MODE;
9111 }
9112 } else if (tn === $$4.TABLE) {
9113 if (p.openElements.hasInTableScope($$4.TR)) {
9114 p.openElements.clearBackToTableRowContext();
9115 p.openElements.pop();
9116 p.insertionMode = IN_TABLE_BODY_MODE;
9117
9118 p._processToken(token);
9119 }
9120 } else if (tn === $$4.TBODY || tn === $$4.TFOOT || tn === $$4.THEAD) {
9121 if (p.openElements.hasInTableScope(tn) || p.openElements.hasInTableScope($$4.TR)) {
9122 p.openElements.clearBackToTableRowContext();
9123 p.openElements.pop();
9124 p.insertionMode = IN_TABLE_BODY_MODE;
9125
9126 p._processToken(token);
9127 }
9128 } else if (tn !== $$4.BODY && tn !== $$4.CAPTION && tn !== $$4.COL && tn !== $$4.COLGROUP || tn !== $$4.HTML && tn !== $$4.TD && tn !== $$4.TH) {
9129 endTagInTable(p, token);
9130 }
9131} // The "in cell" insertion mode
9132//------------------------------------------------------------------
9133
9134
9135function startTagInCell(p, token) {
9136 const tn = token.tagName;
9137
9138 if (tn === $$4.CAPTION || tn === $$4.COL || tn === $$4.COLGROUP || tn === $$4.TBODY || tn === $$4.TD || tn === $$4.TFOOT || tn === $$4.TH || tn === $$4.THEAD || tn === $$4.TR) {
9139 if (p.openElements.hasInTableScope($$4.TD) || p.openElements.hasInTableScope($$4.TH)) {
9140 p._closeTableCell();
9141
9142 p._processToken(token);
9143 }
9144 } else {
9145 startTagInBody(p, token);
9146 }
9147}
9148
9149function endTagInCell(p, token) {
9150 const tn = token.tagName;
9151
9152 if (tn === $$4.TD || tn === $$4.TH) {
9153 if (p.openElements.hasInTableScope(tn)) {
9154 p.openElements.generateImpliedEndTags();
9155 p.openElements.popUntilTagNamePopped(tn);
9156 p.activeFormattingElements.clearToLastMarker();
9157 p.insertionMode = IN_ROW_MODE;
9158 }
9159 } else if (tn === $$4.TABLE || tn === $$4.TBODY || tn === $$4.TFOOT || tn === $$4.THEAD || tn === $$4.TR) {
9160 if (p.openElements.hasInTableScope(tn)) {
9161 p._closeTableCell();
9162
9163 p._processToken(token);
9164 }
9165 } else if (tn !== $$4.BODY && tn !== $$4.CAPTION && tn !== $$4.COL && tn !== $$4.COLGROUP && tn !== $$4.HTML) {
9166 endTagInBody(p, token);
9167 }
9168} // The "in select" insertion mode
9169//------------------------------------------------------------------
9170
9171
9172function startTagInSelect(p, token) {
9173 const tn = token.tagName;
9174
9175 if (tn === $$4.HTML) {
9176 startTagInBody(p, token);
9177 } else if (tn === $$4.OPTION) {
9178 if (p.openElements.currentTagName === $$4.OPTION) {
9179 p.openElements.pop();
9180 }
9181
9182 p._insertElement(token, NS$1.HTML);
9183 } else if (tn === $$4.OPTGROUP) {
9184 if (p.openElements.currentTagName === $$4.OPTION) {
9185 p.openElements.pop();
9186 }
9187
9188 if (p.openElements.currentTagName === $$4.OPTGROUP) {
9189 p.openElements.pop();
9190 }
9191
9192 p._insertElement(token, NS$1.HTML);
9193 } else if (tn === $$4.INPUT || tn === $$4.KEYGEN || tn === $$4.TEXTAREA || tn === $$4.SELECT) {
9194 if (p.openElements.hasInSelectScope($$4.SELECT)) {
9195 p.openElements.popUntilTagNamePopped($$4.SELECT);
9196
9197 p._resetInsertionMode();
9198
9199 if (tn !== $$4.SELECT) {
9200 p._processToken(token);
9201 }
9202 }
9203 } else if (tn === $$4.SCRIPT || tn === $$4.TEMPLATE) {
9204 startTagInHead(p, token);
9205 }
9206}
9207
9208function endTagInSelect(p, token) {
9209 const tn = token.tagName;
9210
9211 if (tn === $$4.OPTGROUP) {
9212 const prevOpenElement = p.openElements.items[p.openElements.stackTop - 1];
9213 const prevOpenElementTn = prevOpenElement && p.treeAdapter.getTagName(prevOpenElement);
9214
9215 if (p.openElements.currentTagName === $$4.OPTION && prevOpenElementTn === $$4.OPTGROUP) {
9216 p.openElements.pop();
9217 }
9218
9219 if (p.openElements.currentTagName === $$4.OPTGROUP) {
9220 p.openElements.pop();
9221 }
9222 } else if (tn === $$4.OPTION) {
9223 if (p.openElements.currentTagName === $$4.OPTION) {
9224 p.openElements.pop();
9225 }
9226 } else if (tn === $$4.SELECT && p.openElements.hasInSelectScope($$4.SELECT)) {
9227 p.openElements.popUntilTagNamePopped($$4.SELECT);
9228
9229 p._resetInsertionMode();
9230 } else if (tn === $$4.TEMPLATE) {
9231 endTagInHead(p, token);
9232 }
9233} //12.2.5.4.17 The "in select in table" insertion mode
9234//------------------------------------------------------------------
9235
9236
9237function startTagInSelectInTable(p, token) {
9238 const tn = token.tagName;
9239
9240 if (tn === $$4.CAPTION || tn === $$4.TABLE || tn === $$4.TBODY || tn === $$4.TFOOT || tn === $$4.THEAD || tn === $$4.TR || tn === $$4.TD || tn === $$4.TH) {
9241 p.openElements.popUntilTagNamePopped($$4.SELECT);
9242
9243 p._resetInsertionMode();
9244
9245 p._processToken(token);
9246 } else {
9247 startTagInSelect(p, token);
9248 }
9249}
9250
9251function endTagInSelectInTable(p, token) {
9252 const tn = token.tagName;
9253
9254 if (tn === $$4.CAPTION || tn === $$4.TABLE || tn === $$4.TBODY || tn === $$4.TFOOT || tn === $$4.THEAD || tn === $$4.TR || tn === $$4.TD || tn === $$4.TH) {
9255 if (p.openElements.hasInTableScope(tn)) {
9256 p.openElements.popUntilTagNamePopped($$4.SELECT);
9257
9258 p._resetInsertionMode();
9259
9260 p._processToken(token);
9261 }
9262 } else {
9263 endTagInSelect(p, token);
9264 }
9265} // The "in template" insertion mode
9266//------------------------------------------------------------------
9267
9268
9269function startTagInTemplate(p, token) {
9270 const tn = token.tagName;
9271
9272 if (tn === $$4.BASE || tn === $$4.BASEFONT || tn === $$4.BGSOUND || tn === $$4.LINK || tn === $$4.META || tn === $$4.NOFRAMES || tn === $$4.SCRIPT || tn === $$4.STYLE || tn === $$4.TEMPLATE || tn === $$4.TITLE) {
9273 startTagInHead(p, token);
9274 } else {
9275 const newInsertionMode = TEMPLATE_INSERTION_MODE_SWITCH_MAP[tn] || IN_BODY_MODE;
9276
9277 p._popTmplInsertionMode();
9278
9279 p._pushTmplInsertionMode(newInsertionMode);
9280
9281 p.insertionMode = newInsertionMode;
9282
9283 p._processToken(token);
9284 }
9285}
9286
9287function endTagInTemplate(p, token) {
9288 if (token.tagName === $$4.TEMPLATE) {
9289 endTagInHead(p, token);
9290 }
9291}
9292
9293function eofInTemplate(p, token) {
9294 if (p.openElements.tmplCount > 0) {
9295 p.openElements.popUntilTagNamePopped($$4.TEMPLATE);
9296 p.activeFormattingElements.clearToLastMarker();
9297
9298 p._popTmplInsertionMode();
9299
9300 p._resetInsertionMode();
9301
9302 p._processToken(token);
9303 } else {
9304 p.stopped = true;
9305 }
9306} // The "after body" insertion mode
9307//------------------------------------------------------------------
9308
9309
9310function startTagAfterBody(p, token) {
9311 if (token.tagName === $$4.HTML) {
9312 startTagInBody(p, token);
9313 } else {
9314 tokenAfterBody(p, token);
9315 }
9316}
9317
9318function endTagAfterBody(p, token) {
9319 if (token.tagName === $$4.HTML) {
9320 if (!p.fragmentContext) {
9321 p.insertionMode = AFTER_AFTER_BODY_MODE;
9322 }
9323 } else {
9324 tokenAfterBody(p, token);
9325 }
9326}
9327
9328function tokenAfterBody(p, token) {
9329 p.insertionMode = IN_BODY_MODE;
9330
9331 p._processToken(token);
9332} // The "in frameset" insertion mode
9333//------------------------------------------------------------------
9334
9335
9336function startTagInFrameset(p, token) {
9337 const tn = token.tagName;
9338
9339 if (tn === $$4.HTML) {
9340 startTagInBody(p, token);
9341 } else if (tn === $$4.FRAMESET) {
9342 p._insertElement(token, NS$1.HTML);
9343 } else if (tn === $$4.FRAME) {
9344 p._appendElement(token, NS$1.HTML);
9345
9346 token.ackSelfClosing = true;
9347 } else if (tn === $$4.NOFRAMES) {
9348 startTagInHead(p, token);
9349 }
9350}
9351
9352function endTagInFrameset(p, token) {
9353 if (token.tagName === $$4.FRAMESET && !p.openElements.isRootHtmlElementCurrent()) {
9354 p.openElements.pop();
9355
9356 if (!p.fragmentContext && p.openElements.currentTagName !== $$4.FRAMESET) {
9357 p.insertionMode = AFTER_FRAMESET_MODE;
9358 }
9359 }
9360} // The "after frameset" insertion mode
9361//------------------------------------------------------------------
9362
9363
9364function startTagAfterFrameset(p, token) {
9365 const tn = token.tagName;
9366
9367 if (tn === $$4.HTML) {
9368 startTagInBody(p, token);
9369 } else if (tn === $$4.NOFRAMES) {
9370 startTagInHead(p, token);
9371 }
9372}
9373
9374function endTagAfterFrameset(p, token) {
9375 if (token.tagName === $$4.HTML) {
9376 p.insertionMode = AFTER_AFTER_FRAMESET_MODE;
9377 }
9378} // The "after after body" insertion mode
9379//------------------------------------------------------------------
9380
9381
9382function startTagAfterAfterBody(p, token) {
9383 if (token.tagName === $$4.HTML) {
9384 startTagInBody(p, token);
9385 } else {
9386 tokenAfterAfterBody(p, token);
9387 }
9388}
9389
9390function tokenAfterAfterBody(p, token) {
9391 p.insertionMode = IN_BODY_MODE;
9392
9393 p._processToken(token);
9394} // The "after after frameset" insertion mode
9395//------------------------------------------------------------------
9396
9397
9398function startTagAfterAfterFrameset(p, token) {
9399 const tn = token.tagName;
9400
9401 if (tn === $$4.HTML) {
9402 startTagInBody(p, token);
9403 } else if (tn === $$4.NOFRAMES) {
9404 startTagInHead(p, token);
9405 }
9406} // The rules for parsing tokens in foreign content
9407//------------------------------------------------------------------
9408
9409
9410function nullCharacterInForeignContent(p, token) {
9411 token.chars = unicode.REPLACEMENT_CHARACTER;
9412
9413 p._insertCharacters(token);
9414}
9415
9416function characterInForeignContent(p, token) {
9417 p._insertCharacters(token);
9418
9419 p.framesetOk = false;
9420}
9421
9422function startTagInForeignContent(p, token) {
9423 if (foreignContent.causesExit(token) && !p.fragmentContext) {
9424 while (p.treeAdapter.getNamespaceURI(p.openElements.current) !== NS$1.HTML && !p._isIntegrationPoint(p.openElements.current)) {
9425 p.openElements.pop();
9426 }
9427
9428 p._processToken(token);
9429 } else {
9430 const current = p._getAdjustedCurrentElement();
9431
9432 const currentNs = p.treeAdapter.getNamespaceURI(current);
9433
9434 if (currentNs === NS$1.MATHML) {
9435 foreignContent.adjustTokenMathMLAttrs(token);
9436 } else if (currentNs === NS$1.SVG) {
9437 foreignContent.adjustTokenSVGTagName(token);
9438 foreignContent.adjustTokenSVGAttrs(token);
9439 }
9440
9441 foreignContent.adjustTokenXMLAttrs(token);
9442
9443 if (token.selfClosing) {
9444 p._appendElement(token, currentNs);
9445 } else {
9446 p._insertElement(token, currentNs);
9447 }
9448
9449 token.ackSelfClosing = true;
9450 }
9451}
9452
9453function endTagInForeignContent(p, token) {
9454 for (let i = p.openElements.stackTop; i > 0; i--) {
9455 const element = p.openElements.items[i];
9456
9457 if (p.treeAdapter.getNamespaceURI(element) === NS$1.HTML) {
9458 p._processToken(token);
9459
9460 break;
9461 }
9462
9463 if (p.treeAdapter.getTagName(element).toLowerCase() === token.tagName) {
9464 p.openElements.popUntilElementPopped(element);
9465 break;
9466 }
9467 }
9468}
9469
9470_default.isElementNode = node => 'tagName' in node; // patch defaultTreeAdapter.createCommentNode to support doctype nodes
9471
9472
9473_default.createCommentNode = function createCommentNode(data) {
9474 return typeof data === 'string' ? {
9475 nodeName: '#comment',
9476 data,
9477 parentNode: null
9478 } : Object.assign({
9479 nodeName: '#documentType',
9480 name: data
9481 }, data);
9482};
9483
9484tokenizer.prototype._createDoctypeToken = function _createDoctypeToken() {
9485 const doctypeRegExp = /^(doctype)(\s+)(html)(?:(\s+)(public\s+(["']).*?\6))?(?:(\s+)((["']).*\9))?(\s*)/i;
9486 const doctypeStartRegExp = /doctype\s*$/i;
9487 const offset = this.preprocessor.html.slice(0, this.preprocessor.pos).match(doctypeStartRegExp, '')[0].length;
9488 const innerHTML = this.preprocessor.html.slice(this.preprocessor.pos - offset);
9489
9490 const _Object = Object(innerHTML.match(doctypeRegExp)),
9491 doctype = _Object[1],
9492 before = _Object[2],
9493 name = _Object[3],
9494 beforePublicId = _Object[4],
9495 publicId = _Object[5],
9496 beforeSystemId = _Object[7],
9497 systemId = _Object[8],
9498 after = _Object[10];
9499
9500 this.currentToken = {
9501 type: tokenizer.COMMENT_TOKEN,
9502 data: {
9503 doctype,
9504 name,
9505 publicId,
9506 systemId,
9507 source: {
9508 before,
9509 beforePublicId,
9510 beforeSystemId,
9511 after
9512 }
9513 },
9514 forceQuirks: false,
9515 publicId: null,
9516 systemId: null
9517 };
9518}; // patch _createAttr to include the start offset position for name
9519
9520
9521tokenizer.prototype._createAttr = function _createAttr(attrNameFirstCh) {
9522 this.currentAttr = {
9523 name: attrNameFirstCh,
9524 value: '',
9525 startName: this.preprocessor.pos
9526 };
9527}; // patch _leaveAttrName to support duplicate attributes
9528
9529
9530tokenizer.prototype._leaveAttrName = function _leaveAttrName(toState) {
9531 const startName = this.currentAttr.startName;
9532 const endName = this.currentAttr.endName = this.preprocessor.pos;
9533 this.currentToken.attrs.push(this.currentAttr);
9534 const before = this.preprocessor.html.slice(0, startName).match(/\s*$/)[0];
9535 this.currentAttr.raw = {
9536 name: this.preprocessor.html.slice(startName, endName),
9537 value: null,
9538 source: {
9539 startName,
9540 endName,
9541 startValue: null,
9542 endValue: null,
9543 before,
9544 quote: ''
9545 }
9546 };
9547 this.state = toState;
9548}; // patch _leaveAttrValue to include the offset end position for value
9549
9550
9551tokenizer.prototype._leaveAttrValue = function _leaveAttrValue(toState) {
9552 const startValue = this.currentAttr.endName + 1;
9553 const endValue = this.preprocessor.pos;
9554 const quote = endValue - this.currentAttr.value.length === startValue ? '' : this.preprocessor.html[startValue];
9555 const currentAttrValue = this.preprocessor.html.slice(startValue + quote.length, endValue - quote.length);
9556 this.currentAttr.raw.value = currentAttrValue;
9557 this.currentAttr.raw.source.startValue = startValue;
9558 this.currentAttr.raw.source.endValue = endValue;
9559 this.currentAttr.raw.source.quote = quote;
9560 this.state = toState;
9561}; // patch TAG_OPEN_STATE to support jsx-style fragments
9562
9563
9564const originalTAG_OPEN_STATE = tokenizer.prototype.TAG_OPEN_STATE;
9565
9566tokenizer.prototype.TAG_OPEN_STATE = function TAG_OPEN_STATE(cp) {
9567 const isReactOpeningElement = this.preprocessor.html.slice(this.preprocessor.pos - 1, this.preprocessor.pos + 1) === '<>';
9568 const isReactClosingElement = this.preprocessor.html.slice(this.preprocessor.pos - 1, this.preprocessor.pos + 2) === '</>';
9569
9570 if (isReactOpeningElement) {
9571 this._createStartTagToken();
9572
9573 this._reconsumeInState('TAG_NAME_STATE');
9574 } else if (isReactClosingElement) {
9575 this._createEndTagToken();
9576
9577 this._reconsumeInState('TAG_NAME_STATE');
9578 } else {
9579 originalTAG_OPEN_STATE.call(this, cp);
9580 }
9581};
9582
9583function parseLoose(html, parseOpts) {
9584 this.tokenizer = new tokenizer(this.options);
9585 const document = _default.createDocumentFragment();
9586 const template = _default.createDocumentFragment();
9587
9588 this._bootstrap(document, template);
9589
9590 this._pushTmplInsertionMode('IN_TEMPLATE_MODE');
9591
9592 this._initTokenizerForFragmentParsing();
9593
9594 this._insertFakeRootElement();
9595
9596 this.tokenizer.write(html, true);
9597
9598 this._runParsingLoop(null);
9599
9600 document.childNodes = filter(document.childNodes, parseOpts);
9601 return document;
9602}
9603
9604function parseHTML(input, parseOpts) {
9605 const htmlParser = new parser({
9606 treeAdapter: _default,
9607 sourceCodeLocationInfo: true
9608 });
9609 return parseLoose.call(htmlParser, input, parseOpts);
9610} // filter out generated elements
9611
9612function filter(childNodes, parseOpts) {
9613 return childNodes.reduce((nodes, childNode) => {
9614 const isVoidElement = parseOpts.voidElements.includes(childNode.nodeName);
9615 const grandChildNodes = childNode.childNodes ? filter(childNode.childNodes, parseOpts) : []; // filter child nodes
9616
9617 if (isVoidElement) {
9618 delete childNode.childNodes;
9619 } else {
9620 childNode.childNodes = grandChildNodes;
9621 } // push nodes with source
9622
9623
9624 if (childNode.sourceCodeLocation) {
9625 nodes.push(childNode);
9626 }
9627
9628 if (!childNode.sourceCodeLocation || !childNode.childNodes) {
9629 nodes.push(...grandChildNodes);
9630 }
9631
9632 return nodes;
9633 }, []);
9634}
9635
9636/**
9637* @name Result
9638* @class
9639* @classdesc Create a new syntax tree {@link Result} from a processed input.
9640* @param {Object} processOptions - Custom settings applied to the {@link Result}.
9641* @param {String} processOptions.from - Source input location.
9642* @param {String} processOptions.to - Destination output location.
9643* @param {Array} processOptions.voidElements - Void elements.
9644* @returns {Result}
9645* @property {Result} result - Result of pHTML transformations.
9646* @property {String} result.from - Path to the HTML source file. You should always set from, because it is used in source map generation and syntax error messages.
9647* @property {String} result.to - Path to the HTML output file.
9648* @property {Fragment} result.root - Object representing the parsed nodes of the HTML file.
9649* @property {Array} result.messages - List of the messages gathered during transformations.
9650* @property {Array} result.voidElements - List of the elements that only have a start tag, as they cannot have any content.
9651*/
9652
9653class Result {
9654 constructor(html, processOptions) {
9655 // the "to" and "from" locations are always string values
9656 const from = 'from' in Object(processOptions) && processOptions.from !== undefined && processOptions.from !== null ? String(processOptions.from) : '';
9657 const to = 'to' in Object(processOptions) && processOptions.to !== undefined && processOptions.to !== null ? String(processOptions.to) : from;
9658 const voidElements = 'voidElements' in Object(processOptions) ? [].concat(Object(processOptions).voidElements || []) : Result.voidElements; // prepare visitors (which may be functions or visitors)
9659
9660 const visitors = getVisitors(Object(processOptions).visitors); // prepare the result object
9661
9662 Object.assign(this, {
9663 type: 'result',
9664 from,
9665 to,
9666 input: {
9667 html,
9668 from,
9669 to
9670 },
9671 root: null,
9672 voidElements,
9673 visitors,
9674 messages: []
9675 }); // parse the html and transform it into nodes
9676
9677 const documentFragment = parseHTML(html, {
9678 voidElements
9679 });
9680 this.root = transform(documentFragment, this);
9681 }
9682 /**
9683 * Current {@link Root} as a String.
9684 * @returns {String}
9685 */
9686
9687
9688 get html() {
9689 return String(this.root);
9690 }
9691 /**
9692 * Messages that are warnings.
9693 * @returns {String}
9694 */
9695
9696
9697 get warnings() {
9698 return this.messages.filter(message => Object(message).type === 'warning');
9699 }
9700 /**
9701 * Return a normalized node whose instances match the current {@link Result}.
9702 * @param {Node} [node] - the node to be normalized.
9703 * @returns {Node}
9704 * @example
9705 * result.normalize(someNode)
9706 */
9707
9708
9709 normalize(node) {
9710 return normalize(node);
9711 }
9712 /**
9713 * The current {@link Root} as an Object.
9714 * @returns {Object}
9715 */
9716
9717
9718 toJSON() {
9719 return this.root.toJSON();
9720 }
9721 /**
9722 * Transform the current {@link Node} and any descendants using visitors.
9723 * @param {Node} node - The {@link Node} to be visited.
9724 * @param {Object} [overrideVisitors] - Alternative visitors to be used in place of {@link Result} visitors.
9725 * @returns {ResultPromise}
9726 * @example
9727 * await result.visit(someNode)
9728 * @example
9729 * await result.visit() // visit using the root of the current result
9730 * @example
9731 * await result.visit(root, {
9732 * Element () {
9733 * // do something to an element
9734 * }
9735 * })
9736 */
9737
9738
9739 visit(node, overrideVisitors) {
9740 const nodeToUse = 0 in arguments ? node : this.root;
9741 return visit(nodeToUse, this, overrideVisitors);
9742 }
9743 /**
9744 * Add a warning to the current {@link Root}.
9745 * @param {String} text - The message being sent as the warning.
9746 * @param {Object} [opts] - Additional information about the warning.
9747 * @example
9748 * result.warn('Something went wrong')
9749 * @example
9750 * result.warn('Something went wrong', {
9751 * node: someNode,
9752 * plugin: somePlugin
9753 * })
9754 */
9755
9756
9757 warn(text, rawopts) {
9758 const opts = Object(rawopts);
9759
9760 if (!opts.plugin) {
9761 if (Object(this.currentPlugin).name) {
9762 opts.plugin = this.currentPlugin.name;
9763 }
9764 }
9765
9766 this.messages.push({
9767 type: 'warning',
9768 text,
9769 opts
9770 });
9771 }
9772
9773}
9774
9775Result.voidElements = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
9776
9777function transform(node, result) {
9778 const hasSource = node.sourceCodeLocation === Object(node.sourceCodeLocation);
9779 const source = hasSource ? {
9780 startOffset: node.sourceCodeLocation.startOffset,
9781 endOffset: node.sourceCodeLocation.endOffset,
9782 startInnerOffset: Object(node.sourceCodeLocation.startTag).endOffset || node.sourceCodeLocation.startOffset,
9783 endInnerOffset: Object(node.sourceCodeLocation.endTag).startOffset || node.sourceCodeLocation.endOffset,
9784 input: result.input
9785 } : {
9786 startOffset: 0,
9787 startInnerOffset: 0,
9788 endInnerOffset: result.input.html.length,
9789 endOffset: result.input.html.length,
9790 input: result.input
9791 };
9792
9793 if (Object(node.sourceCodeLocation).startTag) {
9794 source.before = result.input.html.slice(source.startOffset, source.startInnerOffset - 1).match(/\s*\/?$/)[0];
9795 }
9796
9797 if (Object(node.sourceCodeLocation).endTag) {
9798 source.after = result.input.html.slice(source.endInnerOffset + 2 + node.nodeName.length, source.endOffset - 1);
9799 }
9800
9801 const $node = _default.isCommentNode(node) ? new Comment({
9802 comment: node.data,
9803 source,
9804 result
9805 }) : _default.isDocumentTypeNode(node) ? new Doctype(Object.assign(node, {
9806 result,
9807 source: Object.assign({}, node.source, source)
9808 })) : _default.isElementNode(node) ? new Element({
9809 name: result.input.html.slice(source.startOffset + 1, source.startOffset + 1 + node.nodeName.length),
9810 attrs: node.attrs.map(attr => attr.raw),
9811 nodes: node.childNodes instanceof Array ? node.childNodes.map(child => transform(child, result)) : null,
9812 isSelfClosing: /\//.test(source.before),
9813 isWithoutEndTag: !Object(node.sourceCodeLocation).endTag,
9814 isVoid: result.voidElements.includes(node.tagName),
9815 result,
9816 source
9817 }) : _default.isTextNode(node) ? new Text({
9818 data: hasSource ? source.input.html.slice(source.startInnerOffset, source.endInnerOffset) : node.value,
9819 result,
9820 source
9821 }) : new Fragment({
9822 nodes: node.childNodes instanceof Array ? node.childNodes.map(child => transform(child, result)) : null,
9823 result,
9824 source
9825 });
9826 return $node;
9827}
9828/**
9829* A promise to return a syntax tree.
9830* @typedef {Promise} ResultPromise
9831* @example
9832* resultPromise.then(result => {
9833* // do something with the result
9834* })
9835*/
9836
9837/**
9838* A promise to return a syntax tree.
9839* @typedef {Object} ProcessOptions
9840* @property {Object} ProcessOptions - Custom settings applied to the {@link Result}.
9841* @property {String} ProcessOptions.from - Source input location.
9842* @property {String} ProcessOptions.to - Destination output location.
9843* @property {Array} ProcessOptions.voidElements - Void elements.
9844*/
9845
9846/**
9847* @name Element
9848* @class
9849* @extends Container
9850* @classdesc Create a new {@link Element} {@Link Node}.
9851* @param {Object|String} settings - Custom settings applied to the {@link Element} or its tag name.
9852* @param {String} settings.name - Tag name of the {@link Element}.
9853* @param {Boolean} settings.isSelfClosing - Whether the {@link Element} is self-closing.
9854* @param {Boolean} settings.isVoid - Whether the {@link Element} is void.
9855* @param {Boolean} settings.isWithoutEndTag - Whether the {@link Element} uses a closing tag.
9856* @param {Array|AttributeList|Object} settings.attrs - Attributes applied to the {@link Element}.
9857* @param {Array|NodeList} settings.nodes - Nodes appended to the {@link Element}.
9858* @param {Object} settings.source - Source mapping of the {@link Element}.
9859* @param {Array|AttributeList|Object} [attrs] - Conditional override attributes applied to the {@link Element}.
9860* @param {Array|NodeList} [nodes] - Conditional override nodes appended to the {@link Element}.
9861* @returns {Element} A new {@link Element} {@Link Node}
9862* @example
9863* new Element({ name: 'p' }) // returns an element representing <p></p>
9864*
9865* new Element({
9866* name: 'input',
9867* attrs: [{ name: 'type', value: 'search' }],
9868* isVoid: true
9869* }) // returns an element representing <input type="search">
9870* @example
9871* new Element('p') // returns an element representing <p></p>
9872*
9873* new Element('p', null,
9874* new Element(
9875* 'input',
9876* [{ name: 'type', value: 'search' }]
9877* )
9878* ) // returns an element representing <p><input type="search"></p>
9879*/
9880
9881class Element extends Container {
9882 constructor(settings) {
9883 super();
9884
9885 if (settings !== Object(settings)) {
9886 settings = {
9887 name: String(settings == null ? 'span' : settings)
9888 };
9889 }
9890
9891 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
9892 args[_key - 1] = arguments[_key];
9893 }
9894
9895 if (args[0] === Object(args[0])) {
9896 settings.attrs = args[0];
9897 }
9898
9899 if (args.length > 1) {
9900 settings.nodes = args.slice(1);
9901 }
9902
9903 Object.assign(this, settings, {
9904 type: 'element',
9905 name: settings.name,
9906 isSelfClosing: Boolean(settings.isSelfClosing),
9907 isVoid: 'isVoid' in settings ? Boolean(settings.isVoid) : Result.voidElements.includes(settings.name),
9908 isWithoutEndTag: Boolean(settings.isWithoutEndTag),
9909 attrs: AttributeList.from(settings.attrs),
9910 nodes: Array.isArray(settings.nodes) ? new NodeList(this, ...Array.from(settings.nodes)) : settings.nodes !== null && settings.nodes !== undefined ? new NodeList(this, settings.nodes) : new NodeList(this),
9911 source: Object(settings.source)
9912 });
9913 }
9914 /**
9915 * Return the outerHTML of the current {@link Element} as a String.
9916 * @returns {String}
9917 * @example
9918 * element.outerHTML // returns a string of outerHTML
9919 */
9920
9921
9922 get outerHTML() {
9923 return "" + getOpeningTagString(this) + this.nodes.innerHTML + getClosingTagString(this);
9924 }
9925 /**
9926 * Replace the current {@link Element} from a String.
9927 * @param {String} input - Source being processed.
9928 * @returns {Void}
9929 * @example
9930 * element.outerHTML = 'Hello <strong>world</strong>';
9931 */
9932
9933
9934 set outerHTML(outerHTML) {
9935 Object.getOwnPropertyDescriptor(Container.prototype, 'outerHTML').set.call(this, outerHTML);
9936 }
9937 /**
9938 * Return a clone of the current {@link Element}.
9939 * @param {Object} settings - Custom settings applied to the cloned {@link Element}.
9940 * @param {Boolean} isDeep - Whether the descendants of the current {@link Element} should also be cloned.
9941 * @returns {Element} - The cloned Element
9942 */
9943
9944
9945 clone(settings, isDeep) {
9946 const clone = new Element(Object.assign({}, this, {
9947 nodes: []
9948 }, Object(settings)));
9949 const didSetNodes = 'nodes' in Object(settings);
9950
9951 if (isDeep && !didSetNodes) {
9952 clone.nodes = this.nodes.clone(clone);
9953 }
9954
9955 return clone;
9956 }
9957 /**
9958 * Return the Element as a unique Object.
9959 * @returns {Object}
9960 */
9961
9962
9963 toJSON() {
9964 const object = {
9965 name: this.name
9966 }; // conditionally disclose whether the Element is self-closing
9967
9968 if (this.isSelfClosing) {
9969 object.isSelfClosing = true;
9970 } // conditionally disclose whether the Element is void
9971
9972
9973 if (this.isVoid) {
9974 object.isVoid = true;
9975 } // conditionally disclose Attributes applied to the Element
9976
9977
9978 if (this.attrs.length) {
9979 object.attrs = this.attrs.toJSON();
9980 } // conditionally disclose Nodes appended to the Element
9981
9982
9983 if (!this.isSelfClosing && !this.isVoid && this.nodes.length) {
9984 object.nodes = this.nodes.toJSON();
9985 }
9986
9987 return object;
9988 }
9989 /**
9990 * Return the stringified Element.
9991 * @returns {String}
9992 */
9993
9994
9995 toString() {
9996 return "" + getOpeningTagString(this) + (this.nodes || '') + ("" + getClosingTagString(this));
9997 }
9998
9999}
10000
10001function getClosingTagString(element) {
10002 return element.isSelfClosing || element.isVoid || element.isWithoutEndTag ? '' : "</" + element.name + (element.source.after || '') + ">";
10003}
10004
10005function getOpeningTagString(element) {
10006 return "<" + element.name + element.attrs + (element.source.before || '') + ">";
10007}
10008
10009/**
10010* @name Plugin
10011* @class
10012* @classdesc Create a new Plugin.
10013* @param {String} name - Name of the Plugin.
10014* @param {Function} pluginFunction - Function executed by the Plugin during initialization.
10015* @returns {Plugin}
10016* @example
10017* new Plugin('phtml-test', pluginOptions => {
10018* // initialization logic
10019*
10020* return {
10021* Element (element, result) {
10022* // runtime logic, do something with an element
10023* },
10024* Root (root, result) {
10025* // runtime logic, do something with the root
10026* }
10027* }
10028* })
10029* @example
10030* new Plugin('phtml-test', pluginOptions => {
10031* // initialization logic
10032*
10033* return (root, result) => {
10034* // runtime logic, do something with the root
10035* }
10036* })
10037*/
10038
10039class Plugin extends Function {
10040 constructor(name, pluginFunction) {
10041 return Object.defineProperties(pluginFunction, {
10042 constructor: {
10043 value: Plugin,
10044 configurable: true
10045 },
10046 type: {
10047 value: 'plugin',
10048 configurable: true
10049 },
10050 name: {
10051 value: String(name || 'phtml-plugin'),
10052 configurable: true
10053 },
10054 pluginFunction: {
10055 value: typeof pluginFunction === 'function' ? pluginFunction : () => pluginFunction,
10056 configurable: true
10057 },
10058 process: {
10059 value() {
10060 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
10061 args[_key] = arguments[_key];
10062 }
10063
10064 return Plugin.prototype.process.apply(this, args);
10065 },
10066
10067 configurable: true
10068 }
10069 });
10070 }
10071 /**
10072 * Process input with options and plugin options and return the result.
10073 * @param {String} input - Source being processed.
10074 * @param {ProcessOptions} processOptions - Custom settings applied to the Result.
10075 * @param {Object} pluginOptions - Options passed to the Plugin.
10076 * @returns {ResultPromise}
10077 * @example
10078 * plugin.process('some html', processOptions, pluginOptions)
10079 */
10080
10081
10082 process(input, processOptions, pluginOptions) {
10083 const initializedPlugin = this.pluginFunction(pluginOptions);
10084 const result = new Result(input, Object.assign({
10085 visitors: [initializedPlugin]
10086 }, Object(processOptions)));
10087 return result.visit(result.root);
10088 }
10089
10090}
10091
10092/**
10093* @name PHTML
10094* @class
10095* @classdesc Create a new instance of {@link PHTML}.
10096* @param {Array|Object|Plugin|Function} plugins - Plugin or plugins being added.
10097* @returns {PHTML}
10098* @example
10099* new PHTML(plugin)
10100* @example
10101* new PHTML([ somePlugin, anotherPlugin ])
10102*/
10103
10104class PHTML {
10105 constructor(pluginOrPlugins) {
10106 Object.assign(this, {
10107 plugins: []
10108 });
10109 this.use(pluginOrPlugins);
10110 }
10111 /**
10112 * Process input using plugins and return the result
10113 * @param {String} input - Source being processed.
10114 * @param {ProcessOptions} processOptions - Custom settings applied to the Result.
10115 * @returns {ResultPromise}
10116 * @example
10117 * phtml.process('some html', processOptions)
10118 */
10119
10120
10121 process(input, processOptions) {
10122 const result = new Result(input, Object.assign({
10123 visitors: this.plugins
10124 }, Object(processOptions))); // dispatch visitors and promise the result
10125
10126 return result.visit();
10127 }
10128 /**
10129 * Add plugins to the existing instance of PHTML
10130 * @param {Array|Object|Plugin|Function} plugins - Plugin or plugins being added.
10131 * @returns {PHTML}
10132 * @example
10133 * phtml.use(plugin)
10134 * @example
10135 * phtml.use([ somePlugin, anotherPlugin ])
10136 * @example
10137 * phtml.use(somePlugin, anotherPlugin)
10138 */
10139
10140
10141 use(pluginOrPlugins) {
10142 for (var _len = arguments.length, additionalPlugins = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
10143 additionalPlugins[_key - 1] = arguments[_key];
10144 }
10145
10146 const plugins = [pluginOrPlugins, ...additionalPlugins].reduce((flattenedPlugins, plugin) => flattenedPlugins.concat(plugin), []).filter( // Plugins are either a function or an object with keys
10147 plugin => typeof plugin === 'function' || Object(plugin) === plugin && Object.keys(plugin).length);
10148 this.plugins.push(...plugins);
10149 return this;
10150 }
10151 /**
10152 * Process input and return the new {@link Result}
10153 * @param {ProcessOptions} [processOptions] - Custom settings applied to the {@link Result}.
10154 * @param {Array|Object|Plugin|Function} [plugins] - Custom settings applied to the {@link Result}.
10155 * @returns {ResultPromise}
10156 * @example
10157 * PHTML.process('some html', processOptions)
10158 * @example <caption>Process HTML with plugins.</caption>
10159 * PHTML.process('some html', processOptions, plugins) // returns a new PHTML instance
10160 */
10161
10162
10163 static process(input, processOptions, pluginOrPlugins) {
10164 const phtml = new PHTML(pluginOrPlugins);
10165 return phtml.process(input, processOptions);
10166 }
10167 /**
10168 * Return a new {@link PHTML} instance which will use plugins
10169 * @param {Array|Object|Plugin|Function} plugin - Plugin or plugins being added.
10170 * @returns {PHTML} - New {@link PHTML} instance
10171 * @example
10172 * PHTML.use(plugin) // returns a new PHTML instance
10173 * @example
10174 * PHTML.use([ somePlugin, anotherPlugin ]) // returns a new PHTML instance
10175 * @example
10176 * PHTML.use(somePlugin, anotherPlugin) // returns a new PHTML instance
10177 */
10178
10179
10180 static use(pluginOrPlugins) {
10181 for (var _len2 = arguments.length, additionalPlugins = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
10182 additionalPlugins[_key2 - 1] = arguments[_key2];
10183 }
10184
10185 return new PHTML().use(pluginOrPlugins, ...additionalPlugins);
10186 }
10187
10188}
10189
10190PHTML.AttributeList = AttributeList;
10191PHTML.Comment = Comment;
10192PHTML.Container = Container;
10193PHTML.Doctype = Doctype;
10194PHTML.Element = Element;
10195PHTML.Fragment = Fragment;
10196PHTML.Node = Node;
10197PHTML.NodeList = NodeList;
10198PHTML.Plugin = Plugin;
10199PHTML.Result = Result;
10200PHTML.Text = Text;
10201
10202"object"==typeof self?self.phtml=PHTML:"object"==typeof module&&module.exports&&(module.exports=PHTML);}()
10203//# sourceMappingURL=browser.development.js.map