diff --git a/index.html b/index.html
index 3fca4ae..69998aa 100644
--- a/index.html
+++ b/index.html
@@ -214,7 +214,7 @@
if (/^[\d.]*$/.test(searchString)) {
results = this.biblio.clauses
.filter(clause => clause.number.substring(0, searchString.length) === searchString)
- .map(clause => ({ entry: clause }));
+ .map(clause => ({ key: getKey(clause), entry: clause }));
} else {
results = [];
@@ -455,25 +455,68 @@
};
function findActiveClause(root, path) {
- let clauses = getChildClauses(root);
path = path || [];
- for (let $clause of clauses) {
- let rect = $clause.getBoundingClientRect();
+ let visibleClauses = getVisibleClauses(root, path);
+ let midpoint = Math.floor(window.innerHeight / 2);
+
+ for (let [$clause, path] of visibleClauses) {
+ let { top: clauseTop, bottom: clauseBottom } = $clause.getBoundingClientRect();
+ let isFullyVisibleAboveTheFold =
+ clauseTop > 0 && clauseTop < midpoint && clauseBottom < window.innerHeight;
+ if (isFullyVisibleAboveTheFold) {
+ return path;
+ }
+ }
+
+ visibleClauses.sort(([, pathA], [, pathB]) => pathB.length - pathA.length);
+ for (let [$clause, path] of visibleClauses) {
+ let { top: clauseTop, bottom: clauseBottom } = $clause.getBoundingClientRect();
let $header = $clause.querySelector('h1');
+ let clauseStyles = getComputedStyle($clause);
let marginTop = Math.max(
- parseInt(getComputedStyle($clause)['margin-top']),
+ 0,
+ parseInt(clauseStyles['margin-top']),
parseInt(getComputedStyle($header)['margin-top'])
);
-
- if (rect.top - marginTop <= 1 && rect.bottom > 0) {
- return findActiveClause($clause, path.concat($clause)) || path;
+ let marginBottom = Math.max(0, parseInt(clauseStyles['margin-bottom']));
+ let crossesMidpoint =
+ clauseTop - marginTop <= midpoint && clauseBottom + marginBottom >= midpoint;
+ if (crossesMidpoint) {
+ return path;
}
}
return path;
}
+function getVisibleClauses(root, path) {
+ let childClauses = getChildClauses(root);
+ path = path || [];
+
+ let result = [];
+
+ let seenVisibleClause = false;
+ for (let $clause of childClauses) {
+ let { top: clauseTop, bottom: clauseBottom } = $clause.getBoundingClientRect();
+ let isPartiallyVisible =
+ (clauseTop > 0 && clauseTop < window.innerHeight) ||
+ (clauseBottom > 0 && clauseBottom < window.innerHeight) ||
+ (clauseTop < 0 && clauseBottom > window.innerHeight);
+
+ if (isPartiallyVisible) {
+ seenVisibleClause = true;
+ let innerPath = path.concat($clause);
+ result.push([$clause, innerPath]);
+ result.push(...getVisibleClauses($clause, innerPath));
+ } else if (seenVisibleClause) {
+ break;
+ }
+ }
+
+ return result;
+}
+
function* getChildClauses(root) {
for (let el of root.children) {
switch (el.nodeName) {
@@ -754,6 +797,7 @@
let $spacer = document.createElement('div');
$spacer.setAttribute('id', 'references-pane-spacer');
+ $spacer.classList.add('menu-spacer');
this.$pane = document.createElement('div');
this.$pane.setAttribute('id', 'references-pane');
@@ -902,6 +946,7 @@
e.preventDefault();
e.stopPropagation();
menu.togglePinEntry(this.entry.id);
+ this.$pinLink.textContent = menu._pinnedIds[this.entry.id] ? 'Unpin' : 'Pin';
});
this.$refsLink = document.createElement('a');
@@ -922,6 +967,7 @@
sdoBox.deactivate();
this.active = true;
this.entry = entry;
+ this.$pinLink.textContent = menu._pinnedIds[entry.id] ? 'Unpin' : 'Pin';
this.$outer.classList.add('active');
this.top = el.offsetTop - this.$outer.offsetHeight;
this.left = el.offsetLeft - 10;
@@ -1117,41 +1163,270 @@
referencePane.init();
});
+// preserve state during navigation
+
+function getTocPath(li) {
+ let path = [];
+ let pointer = li;
+ while (true) {
+ let parent = pointer.parentElement;
+ if (parent == null) {
+ return null;
+ }
+ let index = [].indexOf.call(parent.children, pointer);
+ if (index == -1) {
+ return null;
+ }
+ path.unshift(index);
+ pointer = parent.parentElement;
+ if (pointer == null) {
+ return null;
+ }
+ if (pointer.id === 'menu-toc') {
+ break;
+ }
+ if (pointer.tagName !== 'LI') {
+ return null;
+ }
+ }
+ return path;
+}
+
+function activateTocPath(path) {
+ try {
+ let pointer = document.getElementById('menu-toc');
+ for (let index of path) {
+ pointer = pointer.querySelector('ol').children[index];
+ }
+ pointer.classList.add('active');
+ } catch (e) {
+ // pass
+ }
+}
+
+function getActiveTocPaths() {
+ return [...menu.$menu.querySelectorAll('.active')].map(getTocPath).filter(p => p != null);
+}
+
+function initTOCExpansion(visibleItemLimit) {
+ // Initialize to a reasonable amount of TOC expansion:
+ // * Expand any full-breadth nesting level up to visibleItemLimit.
+ // * Expand any *single-item* level while under visibleItemLimit (even if that pushes over it).
+
+ // Limit to initialization by bailing out if any parent item is already expanded.
+ const tocItems = Array.from(document.querySelectorAll('#menu-toc li'));
+ if (tocItems.some(li => li.classList.contains('active') && li.querySelector('li'))) {
+ return;
+ }
+
+ const selfAndSiblings = maybe => Array.from(maybe?.parentNode.children ?? []);
+ let currentLevelItems = selfAndSiblings(tocItems[0]);
+ let availableCount = visibleItemLimit - currentLevelItems.length;
+ while (availableCount > 0 && currentLevelItems.length) {
+ const nextLevelItems = currentLevelItems.flatMap(li => selfAndSiblings(li.querySelector('li')));
+ availableCount -= nextLevelItems.length;
+ if (availableCount > 0 || currentLevelItems.length === 1) {
+ // Expand parent items of the next level down (i.e., current-level items with children).
+ for (const ol of new Set(nextLevelItems.map(li => li.parentNode))) {
+ ol.closest('li').classList.add('active');
+ }
+ }
+ currentLevelItems = nextLevelItems;
+ }
+}
+
+function initState() {
+ if (typeof menu === 'undefined' || window.navigating) {
+ return;
+ }
+ const storage = typeof sessionStorage !== 'undefined' ? sessionStorage : Object.create(null);
+ if (storage.referencePaneState != null) {
+ let state = JSON.parse(storage.referencePaneState);
+ if (state != null) {
+ if (state.type === 'ref') {
+ let entry = menu.search.biblio.byId[state.id];
+ if (entry != null) {
+ referencePane.showReferencesFor(entry);
+ }
+ } else if (state.type === 'sdo') {
+ let sdos = sdoMap[state.id];
+ if (sdos != null) {
+ referencePane.$headerText.innerHTML = state.html;
+ referencePane.showSDOsBody(sdos, state.id);
+ }
+ }
+ delete storage.referencePaneState;
+ }
+ }
+
+ if (storage.activeTocPaths != null) {
+ document.querySelectorAll('#menu-toc li.active').forEach(li => li.classList.remove('active'));
+ let active = JSON.parse(storage.activeTocPaths);
+ active.forEach(activateTocPath);
+ delete storage.activeTocPaths;
+ } else {
+ initTOCExpansion(20);
+ }
+
+ if (storage.searchValue != null) {
+ let value = JSON.parse(storage.searchValue);
+ menu.search.$searchBox.value = value;
+ menu.search.search(value);
+ delete storage.searchValue;
+ }
+
+ if (storage.tocScroll != null) {
+ let tocScroll = JSON.parse(storage.tocScroll);
+ menu.$toc.scrollTop = tocScroll;
+ delete storage.tocScroll;
+ }
+}
+
+document.addEventListener('DOMContentLoaded', initState);
+
+window.addEventListener('pageshow', initState);
+
+window.addEventListener('beforeunload', () => {
+ if (!window.sessionStorage || typeof menu === 'undefined') {
+ return;
+ }
+ sessionStorage.referencePaneState = JSON.stringify(referencePane.state || null);
+ sessionStorage.activeTocPaths = JSON.stringify(getActiveTocPaths());
+ sessionStorage.searchValue = JSON.stringify(menu.search.$searchBox.value);
+ sessionStorage.tocScroll = JSON.stringify(menu.$toc.scrollTop);
+});
+
'use strict';
-let decimalBullet = Array.from({ length: 100 }, (a, i) => '' + (i + 1));
-let alphaBullet = Array.from({ length: 26 }, (a, i) => String.fromCharCode('a'.charCodeAt(0) + i));
-
-// prettier-ignore
-let romanBullet = ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix', 'x', 'xi', 'xii', 'xiii', 'xiv', 'xv', 'xvi', 'xvii', 'xviii', 'xix', 'xx', 'xxi', 'xxii', 'xxiii', 'xxiv', 'xxv'];
-// prettier-ignore
-let bullets = [decimalBullet, alphaBullet, romanBullet, decimalBullet, alphaBullet, romanBullet];
-
-function addStepNumberText(ol, parentIndex) {
- for (let i = 0; i < ol.children.length; ++i) {
- let child = ol.children[i];
- let index = parentIndex.concat([i]);
- let applicable = bullets[Math.min(index.length - 1, 5)];
- let span = document.createElement('span');
- span.textContent = (applicable[i] || '?') + '. ';
- span.style.fontSize = '0';
- span.setAttribute('aria-hidden', 'true');
- child.prepend(span);
- let sublist = child.querySelector('ol');
- if (sublist != null) {
- addStepNumberText(sublist, index);
+
+// Manually prefix algorithm step list items with hidden counter representations
+// corresponding with their markers so they get selected and copied with content.
+// We read list-style-type to avoid divergence with the style sheet, but
+// for efficiency assume that all lists at the same nesting depth use the same
+// style (except for those associated with replacement steps).
+// We also precompute some initial items for each supported style type.
+// https://w3c.github.io/csswg-drafts/css-counter-styles/
+
+const lowerLetters = Array.from({ length: 26 }, (_, i) =>
+ String.fromCharCode('a'.charCodeAt(0) + i)
+);
+// Implement the lower-alpha 'alphabetic' algorithm,
+// adjusting for indexing from 0 rather than 1.
+// https://w3c.github.io/csswg-drafts/css-counter-styles/#simple-alphabetic
+// https://w3c.github.io/csswg-drafts/css-counter-styles/#alphabetic-system
+const lowerAlphaTextForIndex = i => {
+ let S = '';
+ for (const N = lowerLetters.length; i >= 0; i--) {
+ S = lowerLetters[i % N] + S;
+ i = Math.floor(i / N);
+ }
+ return S;
+};
+
+const weightedLowerRomanSymbols = Object.entries({
+ m: 1000,
+ cm: 900,
+ d: 500,
+ cd: 400,
+ c: 100,
+ xc: 90,
+ l: 50,
+ xl: 40,
+ x: 10,
+ ix: 9,
+ v: 5,
+ iv: 4,
+ i: 1,
+});
+// Implement the lower-roman 'additive' algorithm,
+// adjusting for indexing from 0 rather than 1.
+// https://w3c.github.io/csswg-drafts/css-counter-styles/#simple-numeric
+// https://w3c.github.io/csswg-drafts/css-counter-styles/#additive-system
+const lowerRomanTextForIndex = i => {
+ let value = i + 1;
+ let S = '';
+ for (const [symbol, weight] of weightedLowerRomanSymbols) {
+ if (!value) break;
+ if (weight > value) continue;
+ const reps = Math.floor(value / weight);
+ S += symbol.repeat(reps);
+ value -= weight * reps;
+ }
+ return S;
+};
+
+// Memoize pure index-to-text functions with an exposed cache for fast retrieval.
+const makeCounter = (pureGetTextForIndex, precomputeCount = 30) => {
+ const cache = Array.from({ length: precomputeCount }, (_, i) => pureGetTextForIndex(i));
+ const getTextForIndex = i => {
+ if (i >= cache.length) cache[i] = pureGetTextForIndex(i);
+ return cache[i];
+ };
+ return { getTextForIndex, cache };
+};
+
+const counterByStyle = {
+ __proto__: null,
+ decimal: makeCounter(i => String(i + 1)),
+ 'lower-alpha': makeCounter(lowerAlphaTextForIndex),
+ 'upper-alpha': makeCounter(i => lowerAlphaTextForIndex(i).toUpperCase()),
+ 'lower-roman': makeCounter(lowerRomanTextForIndex),
+ 'upper-roman': makeCounter(i => lowerRomanTextForIndex(i).toUpperCase()),
+};
+const fallbackCounter = makeCounter(() => '?');
+const counterByDepth = [];
+
+function addStepNumberText(
+ ol,
+ depth = 0,
+ special = [...ol.classList].some(c => c.startsWith('nested-'))
+) {
+ let counter = !special && counterByDepth[depth];
+ if (!counter) {
+ const counterStyle = getComputedStyle(ol)['list-style-type'];
+ counter = counterByStyle[counterStyle];
+ if (!counter) {
+ console.warn('unsupported list-style-type', {
+ ol,
+ counterStyle,
+ id: ol.closest('[id]')?.getAttribute('id'),
+ });
+ counterByStyle[counterStyle] = fallbackCounter;
+ counter = fallbackCounter;
+ }
+ if (!special) {
+ counterByDepth[depth] = counter;
}
}
+ const { cache, getTextForIndex } = counter;
+ let i = (Number(ol.getAttribute('start')) || 1) - 1;
+ for (const li of ol.children) {
+ const marker = document.createElement('span');
+ marker.textContent = `${i < cache.length ? cache[i] : getTextForIndex(i)}. `;
+ marker.setAttribute('aria-hidden', 'true');
+ const attributesContainer = li.querySelector('.attributes-tag');
+ if (attributesContainer == null) {
+ li.prepend(marker);
+ } else {
+ attributesContainer.insertAdjacentElement('afterend', marker);
+ }
+ for (const sublist of li.querySelectorAll(':scope > ol')) {
+ addStepNumberText(sublist, depth + 1, special);
+ }
+ i++;
+ }
}
+
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('emu-alg > ol').forEach(ol => {
- addStepNumberText(ol, []);
+ addStepNumberText(ol);
});
});
let sdoMap = JSON.parse(`{"prod-KCDyML_C":{"Early":{"clause":"1.2.1","ids":["prod-p4aAXPL4"]}}}`);
-let biblio = JSON.parse(`{"refsByClause":{"sec-jsx-string-characters":["_ref_0","_ref_60","_ref_61","_ref_62"],"sec-jsx-PrimaryExpression":["_ref_1","_ref_2"],"sec-jsx-elements":["_ref_3","_ref_4","_ref_5","_ref_6","_ref_7","_ref_8","_ref_9","_ref_10","_ref_11","_ref_12","_ref_13","_ref_14","_ref_15","_ref_16","_ref_17","_ref_18","_ref_19","_ref_20","_ref_21","_ref_22","_ref_23","_ref_24"],"sec-jsx-elements-early-errors":["_ref_25","_ref_26","_ref_27","_ref_28","_ref_29","_ref_30","_ref_31"],"sec-jsx-attributes":["_ref_32","_ref_33","_ref_34","_ref_35","_ref_36","_ref_37","_ref_38","_ref_39","_ref_40","_ref_41","_ref_42","_ref_43","_ref_44","_ref_45","_ref_46","_ref_47","_ref_48","_ref_49","_ref_50"],"sec-jsx-children":["_ref_51","_ref_52","_ref_53","_ref_54","_ref_55","_ref_56","_ref_57","_ref_58","_ref_59"],"sec-HTMLCharacterReference":["_ref_63","_ref_64","_ref_65","_ref_66"],"sec-jsx-JSXString":["_ref_67","_ref_68","_ref_69"],"sec-jsx-JSXString-SV":["_ref_70","_ref_71","_ref_72","_ref_73"]},"entries":[{"type":"clause","id":"sec-rationale","titleHTML":"Rationale","number":""},{"type":"clause","id":"sec-intro","titleHTML":"Introduction","number":""},{"type":"clause","id":"sec-jsx-PrimaryExpression","titleHTML":"Modified Productions","number":"1.1"},{"type":"production","id":"prod-JSXElement","name":"JSXElement","referencingIds":["_ref_1","_ref_43","_ref_54"]},{"type":"production","id":"prod-JSXSelfClosingElement","name":"JSXSelfClosingElement","referencingIds":["_ref_3"]},{"type":"production","id":"prod-JSXOpeningElement","name":"JSXOpeningElement","referencingIds":["_ref_4","_ref_25","_ref_29"]},{"type":"production","id":"prod-JSXClosingElement","name":"JSXClosingElement","referencingIds":["_ref_6","_ref_27","_ref_31"]},{"type":"production","id":"prod-JSXFragment","name":"JSXFragment","referencingIds":["_ref_2","_ref_44","_ref_55"]},{"type":"production","id":"prod-JSXElementName","name":"JSXElementName","referencingIds":["_ref_7","_ref_9","_ref_11","_ref_28","_ref_30"]},{"type":"production","id":"prod-JSXIdentifier","name":"JSXIdentifier","referencingIds":["_ref_13","_ref_16","_ref_17","_ref_18","_ref_19","_ref_20","_ref_21","_ref_22","_ref_24","_ref_38"]},{"type":"production","id":"prod-JSXNamespacedName","name":"JSXNamespacedName","referencingIds":["_ref_14","_ref_39"]},{"type":"production","id":"prod-JSXMemberExpression","name":"JSXMemberExpression","referencingIds":["_ref_15","_ref_23"]},{"type":"clause","id":"sec-jsx-elements-early-errors","titleHTML":"Static Semantics: Early Errors","number":"1.2.1"},{"type":"clause","id":"sec-jsx-elements","titleHTML":"JSX Elements","number":"1.2"},{"type":"production","id":"prod-JSXAttributes","name":"JSXAttributes","referencingIds":["_ref_8","_ref_10","_ref_33","_ref_35"]},{"type":"production","id":"prod-JSXSpreadAttribute","name":"JSXSpreadAttribute","referencingIds":["_ref_32"]},{"type":"production","id":"prod-JSXAttribute","name":"JSXAttribute","referencingIds":["_ref_34"]},{"type":"production","id":"prod-JSXAttributeName","name":"JSXAttributeName","referencingIds":["_ref_36"]},{"type":"production","id":"prod-JSXAttributeInitializer","name":"JSXAttributeInitializer","referencingIds":["_ref_37"]},{"type":"production","id":"prod-JSXAttributeValue","name":"JSXAttributeValue","referencingIds":["_ref_40","_ref_60"]},{"type":"production","id":"prod-JSXDoubleStringCharacters","name":"JSXDoubleStringCharacters","referencingIds":["_ref_41","_ref_46","_ref_67"]},{"type":"production","id":"prod-JSXDoubleStringCharacter","name":"JSXDoubleStringCharacter","referencingIds":["_ref_45"]},{"type":"production","id":"prod-JSXSingleStringCharacters","name":"JSXSingleStringCharacters","referencingIds":["_ref_42","_ref_49","_ref_68"]},{"type":"production","id":"prod-JSXSingleStringCharacter","name":"JSXSingleStringCharacter","referencingIds":["_ref_48"]},{"type":"clause","id":"sec-jsx-attributes","titleHTML":"JSX Attributes","number":"1.3"},{"type":"production","id":"prod-JSXChildren","name":"JSXChildren","referencingIds":["_ref_5","_ref_12","_ref_26","_ref_52"]},{"type":"production","id":"prod-JSXChild","name":"JSXChild","referencingIds":["_ref_51"]},{"type":"production","id":"prod-JSXText","name":"JSXText","referencingIds":["_ref_53","_ref_58","_ref_61","_ref_69"]},{"type":"production","id":"prod-JSXTextCharacter","name":"JSXTextCharacter","referencingIds":["_ref_57"]},{"type":"production","id":"prod-JSXChildExpression","name":"JSXChildExpression","referencingIds":["_ref_56"]},{"type":"clause","id":"sec-jsx-children","titleHTML":"JSX Children","number":"1.4"},{"type":"production","id":"prod-JSXStringCharacter","name":"JSXStringCharacter","referencingIds":["_ref_47","_ref_50","_ref_59","_ref_71"]},{"type":"clause","id":"sec-jsx-string-characters","titleHTML":"JSX String Characters","number":"1.5.1"},{"type":"production","id":"prod-HTMLCharacterReference","name":"HTMLCharacterReference","referencingIds":["_ref_62"]},{"type":"production","id":"prod-HTMLDecimalCharacterReference","name":"HTMLDecimalCharacterReference","referencingIds":["_ref_63"]},{"type":"production","id":"prod-HTMLHexCharacterReference","name":"HTMLHexCharacterReference","referencingIds":["_ref_64"]},{"type":"production","id":"prod-HTMLNamedCharacterReference","name":"HTMLNamedCharacterReference","referencingIds":["_ref_65"]},{"type":"production","id":"prod-HTMLNamedCharacterReferenceName","name":"HTMLNamedCharacterReferenceName","referencingIds":["_ref_66","_ref_72","_ref_73"]},{"type":"clause","id":"sec-HTMLCharacterReference","titleHTML":"HTML Character References","number":"1.5.2","referencingIds":["_ref_0"]},{"type":"production","id":"prod-JSXString","name":"JSXString","referencingIds":["_ref_70"]},{"type":"clause","id":"sec-jsx-JSXString-SV","titleHTML":"Static Semantics: SV","number":"1.5.3.1"},{"type":"clause","id":"sec-jsx-JSXString","titleHTML":"JSX String Definition","number":"1.5.3"},{"type":"clause","id":"sec-jsx-string","titleHTML":"JSX Strings","number":"1.5"},{"type":"clause","id":"sec-jsx","titleHTML":"JSX Definition","number":"1"},{"type":"clause","id":"sec-why-not-template-literals","titleHTML":"Why not Template Literals?","number":"A"},{"type":"clause","id":"sec-why-not-JXON","titleHTML":"Why not JXON?","number":"B"},{"type":"clause","id":"sec-prior-art","titleHTML":"Prior Art","number":"C"},{"type":"clause","id":"sec-license","titleHTML":"License","number":"D"}]}`);
+let biblio = JSON.parse(`{"refsByClause":{"sec-jsx-string-characters":["_ref_0","_ref_62","_ref_63","_ref_64"],"sec-jsx-PrimaryExpression":["_ref_1","_ref_2"],"sec-jsx-elements":["_ref_3","_ref_4","_ref_5","_ref_6","_ref_7","_ref_8","_ref_9","_ref_10","_ref_11","_ref_12","_ref_13","_ref_14","_ref_15","_ref_16","_ref_17","_ref_18","_ref_19","_ref_20","_ref_21","_ref_22","_ref_23","_ref_24","_ref_32","_ref_33"],"sec-jsx-elements-early-errors":["_ref_25","_ref_26","_ref_27","_ref_28","_ref_29","_ref_30","_ref_31"],"sec-jsx-attributes":["_ref_34","_ref_35","_ref_36","_ref_37","_ref_38","_ref_39","_ref_40","_ref_41","_ref_42","_ref_43","_ref_44","_ref_45","_ref_46","_ref_47","_ref_48","_ref_49","_ref_50","_ref_51","_ref_52"],"sec-jsx-children":["_ref_53","_ref_54","_ref_55","_ref_56","_ref_57","_ref_58","_ref_59","_ref_60","_ref_61"],"sec-HTMLCharacterReference":["_ref_65","_ref_66","_ref_67","_ref_68"],"sec-jsx-JSXString":["_ref_69","_ref_70","_ref_71"],"sec-jsx-JSXString-SV":["_ref_72","_ref_73","_ref_74","_ref_75"]},"entries":[{"type":"clause","id":"sec-rationale","titleHTML":"Rationale","number":""},{"type":"clause","id":"sec-intro","titleHTML":"Introduction","number":""},{"type":"clause","id":"sec-jsx-PrimaryExpression","titleHTML":"Modified Productions","number":"1.1"},{"type":"production","id":"prod-JSXElement","name":"JSXElement","referencingIds":["_ref_1","_ref_45","_ref_56"]},{"type":"production","id":"prod-JSXSelfClosingElement","name":"JSXSelfClosingElement","referencingIds":["_ref_3"]},{"type":"production","id":"prod-JSXOpeningElement","name":"JSXOpeningElement","referencingIds":["_ref_4","_ref_25","_ref_29"]},{"type":"production","id":"prod-JSXClosingElement","name":"JSXClosingElement","referencingIds":["_ref_6","_ref_27","_ref_31"]},{"type":"production","id":"prod-JSXFragment","name":"JSXFragment","referencingIds":["_ref_2","_ref_46","_ref_57"]},{"type":"production","id":"prod-JSXElementName","name":"JSXElementName","referencingIds":["_ref_7","_ref_9","_ref_11","_ref_28","_ref_30"]},{"type":"production","id":"prod-JSXIdentifier","name":"JSXIdentifier","referencingIds":["_ref_13","_ref_16","_ref_17","_ref_18","_ref_19","_ref_20","_ref_21","_ref_22","_ref_24","_ref_32","_ref_33","_ref_40"]},{"type":"production","id":"prod-JSXNamespacedName","name":"JSXNamespacedName","referencingIds":["_ref_14","_ref_41"]},{"type":"production","id":"prod-JSXMemberExpression","name":"JSXMemberExpression","referencingIds":["_ref_15","_ref_23"]},{"type":"clause","id":"sec-jsx-elements-early-errors","titleHTML":"Static Semantics: Early Errors","number":"1.2.1"},{"type":"clause","id":"sec-jsx-elements","titleHTML":"JSX Elements","number":"1.2"},{"type":"production","id":"prod-JSXAttributes","name":"JSXAttributes","referencingIds":["_ref_8","_ref_10","_ref_35","_ref_37"]},{"type":"production","id":"prod-JSXSpreadAttribute","name":"JSXSpreadAttribute","referencingIds":["_ref_34"]},{"type":"production","id":"prod-JSXAttribute","name":"JSXAttribute","referencingIds":["_ref_36"]},{"type":"production","id":"prod-JSXAttributeName","name":"JSXAttributeName","referencingIds":["_ref_38"]},{"type":"production","id":"prod-JSXAttributeInitializer","name":"JSXAttributeInitializer","referencingIds":["_ref_39"]},{"type":"production","id":"prod-JSXAttributeValue","name":"JSXAttributeValue","referencingIds":["_ref_42","_ref_62"]},{"type":"production","id":"prod-JSXDoubleStringCharacters","name":"JSXDoubleStringCharacters","referencingIds":["_ref_43","_ref_48","_ref_69"]},{"type":"production","id":"prod-JSXDoubleStringCharacter","name":"JSXDoubleStringCharacter","referencingIds":["_ref_47"]},{"type":"production","id":"prod-JSXSingleStringCharacters","name":"JSXSingleStringCharacters","referencingIds":["_ref_44","_ref_51","_ref_70"]},{"type":"production","id":"prod-JSXSingleStringCharacter","name":"JSXSingleStringCharacter","referencingIds":["_ref_50"]},{"type":"clause","id":"sec-jsx-attributes","titleHTML":"JSX Attributes","number":"1.3"},{"type":"production","id":"prod-JSXChildren","name":"JSXChildren","referencingIds":["_ref_5","_ref_12","_ref_26","_ref_54"]},{"type":"production","id":"prod-JSXChild","name":"JSXChild","referencingIds":["_ref_53"]},{"type":"production","id":"prod-JSXText","name":"JSXText","referencingIds":["_ref_55","_ref_60","_ref_63","_ref_71"]},{"type":"production","id":"prod-JSXTextCharacter","name":"JSXTextCharacter","referencingIds":["_ref_59"]},{"type":"production","id":"prod-JSXChildExpression","name":"JSXChildExpression","referencingIds":["_ref_58"]},{"type":"clause","id":"sec-jsx-children","titleHTML":"JSX Children","number":"1.4"},{"type":"production","id":"prod-JSXStringCharacter","name":"JSXStringCharacter","referencingIds":["_ref_49","_ref_52","_ref_61","_ref_73"]},{"type":"clause","id":"sec-jsx-string-characters","titleHTML":"JSX String Characters","number":"1.5.1"},{"type":"production","id":"prod-HTMLCharacterReference","name":"HTMLCharacterReference","referencingIds":["_ref_64"]},{"type":"production","id":"prod-HTMLDecimalCharacterReference","name":"HTMLDecimalCharacterReference","referencingIds":["_ref_65"]},{"type":"production","id":"prod-HTMLHexCharacterReference","name":"HTMLHexCharacterReference","referencingIds":["_ref_66"]},{"type":"production","id":"prod-HTMLNamedCharacterReference","name":"HTMLNamedCharacterReference","referencingIds":["_ref_67"]},{"type":"production","id":"prod-HTMLNamedCharacterReferenceName","name":"HTMLNamedCharacterReferenceName","referencingIds":["_ref_68","_ref_74","_ref_75"]},{"type":"clause","id":"sec-HTMLCharacterReference","titleHTML":"HTML Character References","number":"1.5.2","referencingIds":["_ref_0"]},{"type":"production","id":"prod-JSXString","name":"JSXString","referencingIds":["_ref_72"]},{"type":"clause","id":"sec-jsx-JSXString-SV","titleHTML":"Static Semantics: SV","number":"1.5.3.1"},{"type":"clause","id":"sec-jsx-JSXString","titleHTML":"JSX String Definition","number":"1.5.3"},{"type":"clause","id":"sec-jsx-string","titleHTML":"JSX Strings","number":"1.5"},{"type":"clause","id":"sec-jsx","titleHTML":"JSX Definition","number":"1"},{"type":"clause","id":"sec-why-not-template-literals","titleHTML":"Why not Template Literals?","number":"A"},{"type":"clause","id":"sec-why-not-JXON","titleHTML":"Why not JXON?","number":"B"},{"type":"clause","id":"sec-prior-art","titleHTML":"Prior Art","number":"C"},{"type":"clause","id":"sec-license","titleHTML":"License","number":"D"}]}`);
;let usesMultipage = false