UNPKG

bliss-svg-builder

Version:

Compose, render, and manipulate Blissymbolics SVG using a compact DSL and a programmatic mutation API.

1 lines 964 kB
{"version":3,"file":"bliss-svg-builder.cjs","names":["endX","endY","sc.createZeroSizedAnchor","sc.createSpace","sc.createDot","sc.createComma","sc.createHeart","sc.createEar","sc.createFiber","sc.createCircle","sc.createHalfCircle","sc.createQuarterCircle","sc.createOpenCircle","sc.createWave","sc.createHalfWave","sc.createHorizontalQuarterWave","sc.createVerticalQuarterWave","sc.createVerticalLine","sc.createHorizontalLine","sc.createAscendingDiagonalLine","sc.createDescendingDiagonalLine","sc.createDiagonalLineOutsideCircle","sc.createAscendingDiagonalLineInsideCircle","sc.createDescendingDiagonalLineInsideCircle","sc.createExternalGlyph","#wrapWithAnchorAndGroup","#separateAnchorAndGroupOptions","#classifyParts","#children","#isEmptyGroup","#isEmptyGlyph","#blissObj","#parentElement","#inkStartX","#relativeToParentX","#inkEndX","#relativeToParentY","#previousElement","#level","#sharedOptions","#key","#codeName","#externalGlyphSpacing","#childStartOffset","#getFirstCharacterElement","#classifiedParts","#isSpaceGroup","#advanceX","#char","#isBlissGlyph","#isExternalGlyph","#positionIndicatorGroup","#leafWidth","#leafHeight","#handlePredefinedElement","#handleCompositeElement","#anchorOffsetX","#anchorOffsetY","#leafX","#leafY","#isCharacter","#isShape","#classifyIndicator","#calculateBounds","#extraPathOptions","#getInheritedOption","#extractPositionFromOptions","#hasMultipleOptionBrackets","#parseOptions","#applyDefinitionMetadata","#applyEffectiveMetadata","#flagCompositePart","#expandPartRecursive","#parseCodeStringToParts","#ctx","#level","#nodeRef","#parentRef","#generation","#resolveIndex","#relocate","#assertReachable","#findSnapshot","#forwardParseWarnings","#parseGlyphArg","#applyDefaultsOverrides","#syncGeneration","#parsePartArg","#fillEmptyGroupWithPart","#inFailFlaggedGroup","#clearGlyphIdentity","#removeGlyphFromGroup","#applyOrClearWordIndicators","#applyOrClearIndicators","#warnIndicatorNoop","#updateGlyphIdentityAfterIndicatorChange","#processOptions","#processAllOptions","#resolveOpts","#normalizeGlyphCodes","#normalizePartlessGlyphs","#toRaw","#flagWordParts","#rawBlissObj","#rebuild","#mutationCtx","#isRawSpaceGroup","#makeSpaceGroup","#removeGlyphGroup","#generation","#mutationWarnings","#assignKeys","#isNonHeadMarkerNode","#isNonHeadMarkerGroup","#dropSpaceOptions","#isSpaceGlyphNode","#elementsCache","#groupsCache","#warnings","#normalizeMalformedPartInvariant","#normalizeFailedWordInvariant","#normalizeSpacePartInvariant","#normalizeSpaceInvariant","#normalizeIndicatorInvariant","#sharedOptions","#processedOptions","#getNonSpaceGroupIndices","#parseGroupWithOpts","#textFallbackInternalForm","#reapplyGlyphMetadata","#normalizePartCodes","#flagWordPartsInArray","#NON_HEAD_MARKER_CODES","#SPACE_KEPT_OPTION_KEYS","#isBareAliasDefinition","#decomposeCodeString","#preservedWrittenName","#renameChainIsPure","#resolveToBuiltInCode","#canonicalGlyphParts","#svgCode","#X_NAMESPACE_PATTERN","#RESERVED_SYNTAX_NAMES","#validateCode","#assertReplaceable","#extractReferencedCodes","#detectType","#validateReferences","#hasCircularReference","#assertNoIndicatorBakeDependents","#assertNoWordInternalCoordinates","#normalizeSpaceSegments","#defineShape","#assertNoGlobalOnlyDefaultOptions","#defineGlyph","#defineExternalGlyph","#resolveBareAliases","#hasCompositePartViolation","#defineBare","#ownsDefinition"],"sources":["../src/external-font-data/liberation-sans-svg-path-data.js","../src/lib/bliss-constants.js","../src/lib/bliss-shape-creators.js","../src/lib/bliss-glyph-data.js","../src/lib/bliss-element-definitions.js","../src/lib/indicator-utils.js","../src/lib/bliss-head-glyph-exclusions.js","../src/lib/bliss-element.js","../src/lib/bliss-parser.js","../src/lib/element-handle.js","../src/lib/bliss-svg-builder.js","../src/index.js"],"sourcesContent":["/**\r\n * liberation-sans-svg-path-data.js\r\n *\r\n * Derived from Liberation Sans Regular (Liberation Fonts Project)\r\n * Copyright © 2012–2018 Red Hat, Inc.\r\n *\r\n * This file contains extracted and modified glyph path data.\r\n * Licensed under the Apache License, Version 2.0.\r\n * See the FONT_LICENSE file in this directory for the full license text.\r\n *\r\n * SPDX-License-Identifier: Apache-2.0\r\n */\r\n\r\n// Somewhat arbitrary numbers. Need to be somewhat adjusted to align with normal font letter spacing...\r\nconst defaultLeftSideBearing = 107;\r\nconst defaultRightSideBearing = 165;\r\nconst fontUnitToGridUnitDivisor = 356;\r\n\r\nfunction getGridUnitWidth(width) {\r\n  return (width - defaultLeftSideBearing - defaultRightSideBearing) / fontUnitToGridUnitDivisor;\r\n}\r\n\r\nfunction getGridUnitKerningRule(kerning) {\r\n  return kerning / fontUnitToGridUnitDivisor;\r\n}\r\n\r\nfunction precision(pathString, decimals = 7) {\r\n  return pathString.replace(/-?\\d+\\.?\\d*/g, match => \r\n    parseFloat(parseFloat(match).toFixed(decimals)).toString()\r\n  );\r\n}\r\n\r\nconst alphabetData = {\r\n  // e[X]ternal glyphs (i.e. letters and other non-Bliss characters).\r\n  // Supports: Base Latin (a-z, A-Z), Latin Extended (European languages), Cyrillic (Russian).\r\n  'Xa': {\r\n    getPath: () => precision(`M1.1633399724960327,16.04509925842285q-0.45802998542785645,0,-0.6884499788284302,-0.24165916442871094t-0.23041999340057373,-0.6631603240966797q0,-0.4720802307128906,0.3105049729347229,-0.7249794006347656t1.0017650723457336,-0.2697601318359375l0.6828298568725586,-0.011240005493164062l0,-0.16579055786132812q0,-0.37091922760009766,-0.15735983848571777,-0.5310897827148438t-0.4945601224899292,-0.1601696014404297q-0.3400099277496338,0,-0.4945598840713501,0.11520957946777344t-0.18546003103256226,0.36810970306396484l-0.5282800197601318,-0.04776954650878906q0.12926000356674194,-0.8205204010009766,1.2195399403572083,-0.8205204010009766q0.5732401609420776,0,0.8626700639724731,0.26273536682128906t0.2894299030303955,0.7601051330566406l0,1.3094596862792969q0,0.22480010986328125,0.05901002883911133,0.3386049270629883t0.22480010986328125,0.11380481719970703q0.0730600357055664,0,0.16578984260559082,-0.019669532775878906l0,0.31472015380859375q-0.19107985496520996,0.04496002197265625,-0.39058995246887207,0.04496002197265625q-0.28099989891052246,0,-0.40885496139526367,-0.14752483367919922t-0.1447150707244873,-0.46224498748779297l-0.016860008239746094,0q-0.19388985633850098,0.34843921661376953,-0.45100486278533936,0.49315452575683594t-0.6252250671386719,0.14471435546875ZM1.2785500288009644,15.665749549865723q0.278190016746521,0,0.49456000328063965,-0.1264495849609375t0.34141504764556885,-0.34703540802001953t0.1250448226928711,-0.4538145065307617l0,-0.2500896453857422l-0.5535699129104614,0.011240005493164062q-0.3568699359893799,0.005620002746582031,-0.5409250259399414,0.0730600357055664t-0.28240495920181274,0.20793914794921875t-0.09834998846054077,0.36811065673828125q0,0.24728012084960938,0.13347500562667847,0.3821601867675781t0.3807550072669983,0.13487911224365234Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16.05,\r\n    char: \"a\"\r\n  },\r\n  'Xb': {\r\n    getPath: () => precision(`M2.958930015563965,14.45464038848877q0,1.590458869934082,-1.118380069732666,1.590458869934082q-0.3456299304962158,0,-0.574644923210144,-0.1250438690185547t-0.37232500314712524,-0.40323543548583984l-0.005620002746582031,0q0,0.08711051940917969,-0.011240005493164062,0.2655448913574219t-0.016860008239746094,0.20653533935546875l-0.4889400005340576,0q0.016860008239746094,-0.15174007415771484,0.016860008239746094,-0.6266298294067383l0,-3.543410301208496l0.5058000087738037,0l0,1.1886301040649414q0,0.1826496124267578,-0.011240005493164062,0.4299297332763672l0.011240005493164062,0q0.140500009059906,-0.2922401428222656,0.37232500314712524,-0.4186897277832031t0.574644923210144,-0.1264505386352539q0.5760500431060791,0,0.847214937210083,0.38778018951416016t0.271165132522583,1.1745805740356445ZM2.427839994430542,14.471500396728516q0,-0.6378707885742188,-0.16860008239746094,-0.9132499694824219t-0.5479499101638794,-0.27538013458251953q-0.4271199703216553,0,-0.6224149465560913,0.2922401428222656t-0.1952950358390808,0.9272994995117188q0,0.5985298156738281,0.1910800337791443,0.8837451934814453t0.6210099458694458,0.2852144241333008q0.3821600675582886,0,0.5521649122238159,-0.28240489959716797t0.17000508308410645,-0.9174642562866211Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16.05,\r\n    char: \"b\"\r\n  },\r\n  'Xc': {\r\n    getPath: () => precision(`M0.7727500200271606,14.45464038848877q0,0.606959342956543,0.1910799741744995,0.8991994857788086t0.5760500431060791,0.2922401428222656q0.26976001262664795,0,0.4510049819946289,-0.1461200714111328t0.22339487075805664,-0.4496002197265625l0.5114200115203857,0.03372001647949219q-0.05900979042053223,0.43836021423339844,-0.373729944229126,0.6996898651123047t-0.7980399131774902,0.26132965087890625q-0.6378700733184814,0,-0.9736650586128235,-0.40323448181152344t-0.33579498529434204,-1.1759843826293945q0,-0.7671308517456055,0.33719998598098755,-1.170365333557129t0.966640055179596,-0.40323543548583984q0.4664599895477295,0,0.7741549015045166,0.24166011810302734t0.38637495040893555,0.6659698486328125l-0.5198497772216797,0.03934001922607422q-0.03934001922607422,-0.252899169921875,-0.1995100975036621,-0.40182971954345703t-0.45521998405456543,-0.14892959594726562q-0.4018300771713257,0,-0.5816700458526611,0.2669496536254883t-0.17983996868133545,0.899200439453125Z`),\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16.05,\r\n    char: \"c\"\r\n  },\r\n  'Xd': {\r\n    getPath: () => precision(`M2.3070099353790283,15.499959945678711q-0.14049983024597168,0.2922401428222656,-0.37232494354248047,0.4186897277832031t-0.5746450424194336,0.1264495849609375q-0.5760499238967896,0,-0.847214937210083,-0.38777923583984375t-0.27116501331329346,-1.1745796203613281q0,-1.5904607772827148,1.1183799505233765,-1.5904607772827148q0.34563004970550537,0,0.5760500431060791,0.1264505386352539t0.37091994285583496,0.40182971954345703l0.005620002746582031,0l-0.005620002746582031,-0.3400096893310547l0,-1.2616901397705078l0.5058000087738037,0l0,3.543410301208496q0,0.47488975524902344,0.016860008239746094,0.6266298294067383l-0.4833199977874756,0q-0.008430004119873047,-0.04496002197265625,-0.0182650089263916,-0.20794010162353516t-0.009835004806518555,-0.28100013732910156l-0.011240005493164062,0ZM0.7727500200271606,14.465880393981934q0,0.6378698348999023,0.1685999631881714,0.9132499694824219t0.547950029373169,0.2753791809082031q0.4299299716949463,0,0.6238200664520264,-0.29785919189453125t0.19388985633850098,-0.9244899749755859q0,-0.6041507720947266,-0.19388985633850098,-0.8851499557495117t-0.6182000637054443,-0.28100013732910156q-0.3821600675582886,0,-0.5521650314331055,0.28240489959716797t-0.1700049638748169,0.9174652099609375Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16.05,\r\n    char: \"d\"\r\n  },\r\n  'Xe': {\r\n    getPath: () => precision(`M0.7755600214004517,14.575469970703125q0,0.5226602554321289,0.21636998653411865,0.8064699172973633t0.6322499513626099,0.2838096618652344q0.3287700414657593,0,0.5268751382827759,-0.13206958770751953t0.2683548927307129,-0.33438968658447266l0.44397997856140137,0.1264495849609375q-0.2725698947906494,0.7193593978881836,-1.2392100095748901,0.7193593978881836q-0.6743999719619751,0,-1.0270549654960632,-0.40182971954345703t-0.35265499353408813,-1.194249153137207q0,-0.7530803680419922,0.35265499353408813,-1.1549100875854492t1.0073849558830261,-0.40183067321777344q1.3403700590133667,0,1.3403700590133667,1.6157503128051758l0,0.06744003295898438l-2.169319987297058,0ZM2.42221999168396,14.187689781188965q-0.042150020599365234,-0.48050975799560547,-0.24446988105773926,-0.7010946273803711t-0.5816701650619507,-0.22058486938476562q-0.36810994148254395,0,-0.5830749273300171,0.24587440490722656t-0.23182499408721924,0.6758050918579102l1.6410399675369263,0Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16.05,\r\n    char: \"e\"\r\n  },\r\n  'Xf': {\r\n    getPath: () => precision(`M1.0144100189208984,13.316590309143066l0,2.6723098754882812l-0.5058000087738037,0l0,-2.6723098754882812l-0.42712000757455826,0l0,-0.36811065673828125l0.42712000757455826,0l0,-0.3428192138671875q0,-0.4158802032470703,0.18264997005462646,-0.5985307693481445t0.559190034866333,-0.1826496124267578q0.21074998378753662,0,0.3568699359893799,0.03372001647949219l0,0.38496971130371094q-0.12644994258880615,-0.022480010986328125,-0.2247999906539917,-0.022480010986328125q-0.19388997554779053,0,-0.281000018119812,0.09835052490234375t-0.08710992336273193,0.3568696975708008l0,0.2725696563720703l0.5929099321365356,0l0,0.36811065673828125l-0.5929099321365356,0Z`),\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 15.99,\r\n    char: \"f\",\r\n    kerningRules: {\r\n      \"f\": getGridUnitKerningRule(37),\r\n    }\r\n  },\r\n  'Xg': {\r\n    getPath: () => precision(`M1.5398800373077393,17.183149337768555q-0.49737000465393066,0,-0.7924200296401978,-0.19529342651367188t-0.3793500065803528,-0.5549755096435547l0.5086100101470947,-0.07306098937988281q0.050579965114593506,0.21075057983398438,0.22339493036270142,0.3245563507080078t0.4538151025772095,0.11380386352539062q0.755889892578125,0,0.755889892578125,-0.8851499557495117l0,-0.4889392852783203l-0.005620002746582031,0q-0.1433098316192627,0.2922391891479492,-0.3933999538421631,0.43976497650146484t-0.5844799280166626,0.1475238800048828q-0.559190034866333,0,-0.8219250440597534,-0.37091922760009766t-0.2627350091934204,-1.1661500930786133q0,-0.8064699172973633,0.2824050188064575,-1.1900348663330078t0.8584549427032471,-0.38356494903564453q0.32315003871917725,0,0.5605950355529785,0.14752483367919922t0.36670494079589844,0.42009544372558594l0.005620002746582031,0q0,-0.08430004119873047,0.011240005493164062,-0.2922401428222656t0.022480010986328125,-0.22761058807373047l0.48050999641418457,0q-0.016860008239746094,0.15174007415771484,-0.016860008239746094,0.6294403076171875l0,2.3238697052001953q0,1.2813596725463867,-1.2729299068450928,1.2813596725463867ZM2.3098199367523193,14.468689918518066q0,-0.37092018127441406,-0.10116004943847656,-0.6392745971679688t-0.285214900970459,-0.4102602005004883t-0.4172849655151367,-0.1419048309326172q-0.3877800703048706,0,-0.564810037612915,0.28100013732910156t-0.17702996730804443,0.9104394912719727q0,0.6238203048706055,0.16578996181488037,0.8963899612426758t0.567620038986206,0.2725696563720703q0.23884999752044678,0,0.42430996894836426,-0.14049911499023438t0.2866199016571045,-0.40323543548583984t0.10116004943847656,-0.6252250671386719Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 17.18,\r\n    char: \"g\"\r\n  },\r\n  'Xh': {\r\n    getPath: () => precision(`M0.8907700181007385,13.468330383300781q0.16298002004623413,-0.29786014556884766,0.39199501276016235,-0.43695545196533203t0.5802649259567261,-0.13909530639648438q0.49456000328063965,0,0.7291951179504395,0.24587535858154297t0.2346348762512207,0.8247346878051758l0,2.026010513305664l-0.5086100101470947,0l0,-1.9276599884033203q0,-0.3203401565551758,-0.05901002883911133,-0.47629547119140625t-0.19388985633850098,-0.22901439666748047t-0.3737300634384155,-0.0730600357055664q-0.3568699359893799,0,-0.5718350410461426,0.24728012084960938t-0.21496492624282837,0.6659698486328125l0,1.7927799224853516l-0.5058000385761261,0l0,-4.170040130615234l0.5058000385761261,0l0,1.0846595764160156q0,0.17141056060791016,-0.009835004806518555,0.35406017303466797t-0.01264500617980957,0.21075057983398438l0.008430004119873047,0Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 15.99,\r\n    char: \"h\"\r\n  },\r\n  'Xi': {\r\n    getPath: () => precision(`M0.3849700093269348,12.302180290222168l0,-0.4833202362060547l0.5058000087738037,0l0,0.4833202362060547l-0.5058000087738037,0ZM0.3849700093269348,15.988900184631348l0,-3.0404205322265625l0.5058000087738037,0l0,3.0404205322265625l-0.5058000087738037,0Z`),\r\n    get width() { return getGridUnitWidth(455); },\r\n    height: 15.99,\r\n    char: \"i\"\r\n  },\r\n  'Xj': {\r\n    getPath: () => precision(`M0.3849700093269348,12.302180290222168l0,-0.4833202362060547l0.5058000087738037,0l0,0.4833202362060547l-0.5058000087738037,0ZM0.8907700181007385,16.365440368652344q0,0.4299297332763672,-0.16860002279281616,0.6238193511962891t-0.5057999938726425,0.19388961791992188q-0.21637000143527985,0,-0.35686999559402466,-0.025289535522460938l0,-0.3905906677246094l0.1742199957370758,0.0168609619140625q0.19389000535011292,0,0.27256999909877777,-0.10116004943847656t0.07868000864982605,-0.3934001922607422l0,-3.341090202331543l0.5058000087738037,0l0,3.4169607162475586Z`),\r\n    get width() { return getGridUnitWidth(455); },\r\n    height: 17.18,\r\n    char: \"j\"\r\n  },\r\n  'Xk': {\r\n    getPath: () => precision(`M2.2929599285125732,15.988900184631348l-1.028459906578064,-1.3881397247314453l-0.37092000246047974,0.3062896728515625l0,1.0818500518798828l-0.5058000087738037,0l0,-4.170040130615234l0.5058000087738037,0l0,2.604869842529297l1.3347498774528503,-1.475250244140625l0.5929100513458252,0l-1.233590006828308,1.306650161743164l1.2982200384140015,1.7337703704833984l-0.5929100513458252,0Z`),\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 15.99,\r\n    char: \"k\"\r\n  },\r\n  'Xl': {\r\n    getPath: () => precision(`M0.38778001070022583,15.988900184631348l0,-4.170040130615234l0.5058000087738037,0l0,4.170040130615234l-0.5058000087738037,0Z`),\r\n    get width() { return getGridUnitWidth(455); },\r\n    height: 15.99,\r\n    char: \"l\"\r\n  },\r\n  'Xm': {\r\n    getPath: () => precision(`M2.1580801010131836,15.988900184631348l0,-1.9276599884033203q0,-0.44116973876953125,-0.12083005905151367,-0.6097698211669922t-0.43555009365081787,-0.16860008239746094q-0.3231499195098877,0,-0.5114198923110962,0.24728012084960938t-0.18827003240585327,0.6968793869018555l0,1.7618703842163086l-0.5029900372028351,0l0,-2.3913097381591797q0,-0.5310907363891602,-0.016859978437423706,-0.6491107940673828l0.47769999504089355,0q0.0028100013732910156,0.014050483703613281,0.005620002746582031,0.07587051391601562t0.007025003433227539,0.1419048309326172t0.009835004806518555,0.3020753860473633l0.008430004119873047,0q0.16298002004623413,-0.323150634765625,0.37373000383377075,-0.4496002197265625t0.5142300128936768,-0.1264505386352539q0.34563004970550537,0,0.5465449094772339,0.13769054412841797t0.27959513664245605,0.43836021423339844l0.008430004119873047,0q0.15735983848571777,-0.3062906265258789,0.3807549476623535,-0.44117069244384766t0.5409250259399414,-0.13488006591796875q0.46083998680114746,0,0.670184850692749,0.2500905990600586t0.20934486389160156,0.8205194473266602l0,2.026010513305664l-0.5001797676086426,0l0,-1.9276599884033203q0,-0.44116973876953125,-0.12083005905151367,-0.6097698211669922t-0.4355499744415283,-0.16860008239746094q-0.33157992362976074,0,-0.5156350135803223,0.24587440490722656t-0.18405485153198242,0.6982851028442383l0,1.7618703842163086l-0.5001800060272217,0Z`),\r\n    get width() { return getGridUnitWidth(1706); },\r\n    height: 15.99,\r\n    char: \"m\"\r\n  },\r\n  'Xn': {\r\n    getPath: () => precision(`M2.3182499408721924,15.988900184631348l0,-1.9276599884033203q0,-0.3006706237792969,-0.05901002883911133,-0.4664602279663086t-0.18826985359191895,-0.23884963989257812t-0.37935006618499756,-0.0730600357055664q-0.36529994010925293,0,-0.5760500431060791,0.2500896453857422t-0.21074992418289185,0.6940698623657227l0,1.7618703842163086l-0.5058000385761261,0l0,-2.3913097381591797q0,-0.5310907363891602,-0.016859978437423706,-0.6491107940673828l0.47769999504089355,0q0.0028100013732910156,0.014050483703613281,0.005620002746582031,0.07587051391601562t0.007025003433227539,0.1419048309326172t0.009835004806518555,0.3020753860473633l0.008430004119873047,0q0.1742200255393982,-0.31472015380859375,0.4032350182533264,-0.4453849792480469t0.569024920463562,-0.13066577911376953q0.5001800060272217,0,0.7320051193237305,0.2486858367919922t0.2318248748779297,0.8219242095947266l0,2.026010513305664l-0.5086100101470947,0Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 15.99,\r\n    char: \"n\"\r\n  },\r\n  'Xo': {\r\n    getPath: () => precision(`M2.958930015563965,14.465880393981934q0,0.798039436340332,-0.35124993324279785,1.188629150390625t-1.02003014087677,0.39058971405029297q-0.665969967842102,0,-1.0059799551963806,-0.40604400634765625t-0.34000998735427856,-1.1731748580932617q0,-1.5736007690429688,1.3628499507904053,-1.5736007690429688q0.6968799829483032,0,1.025650143623352,0.38356494903564453t0.3287699222564697,1.1900358200073242ZM2.427839994430542,14.465880393981934q0,-0.6294403076171875,-0.18686509132385254,-0.9146556854248047t-0.6280349493026733,-0.2852144241333008q-0.44397997856140137,0,-0.6420849561691284,0.2908344268798828t-0.19810497760772705,0.9090356826782227q0,0.6013393402099609,0.19529497623443604,0.9034147262573242t0.6139850616455078,0.3020744323730469q0.45521998405456543,0,0.6505148410797119,-0.2922391891479492t0.19529509544372559,-0.9132499694824219Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16.05,\r\n    char: \"o\"\r\n  },\r\n  'Xp': {\r\n    getPath: () => precision(`M2.958930015563965,14.45464038848877q0,1.590458869934082,-1.118380069732666,1.590458869934082q-0.7024999856948853,0,-0.9441599249839783,-0.5282793045043945l-0.014050006866455078,0q0.011240005493164062,0.022480010986328125,0.011240005493164062,0.47770023345947266l0,1.188629150390625l-0.5058000087738037,0l0,-3.613658905029297q0,-0.4692707061767578,-0.016860008239746094,-0.6210107803344727l0.4889400005340576,0q0.0028100013732910156,0.011240005493164062,0.008430004119873047,0.08008575439453125t0.01264500617980957,0.21215438842773438t0.007025003433227539,0.1967000961303711l0.011240005493164062,0q0.13488000631332397,-0.28100013732910156,0.35686999559402466,-0.4116649627685547t0.5844799280166626,-0.13066482543945312q0.562000036239624,0,0.8401901721954346,0.3765401840209961t0.27818989753723145,1.1830101013183594ZM2.427839994430542,14.465880393981934q0,-0.6350603103637695,-0.17141008377075195,-0.9076299667358398t-0.5451399087905884,-0.2725706100463867q-0.3006700277328491,0,-0.470674991607666,0.1264505386352539t-0.2585200071334839,0.3948049545288086t-0.08851498365402222,0.6982851028442383q0,0.5985298156738281,0.1910800337791443,0.8823394775390625t0.6210099458694458,0.2838096618652344q0.37654006481170654,0,0.5493549108505249,-0.27678489685058594t0.17281508445739746,-0.9287042617797852Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 17.18,\r\n    char: \"p\"\r\n  },\r\n  'Xq': {\r\n    getPath: () => precision(`M1.3600399494171143,16.04509925842285q-0.5788599252700806,0,-0.8486199378967285,-0.39058971405029297t-0.26976001262664795,-1.171769142150879q0,-1.5904607772827148,1.1183799505233765,-1.5904607772827148q0.34563004970550537,0,0.5704300403594971,0.12223529815673828t0.376539945602417,0.40604496002197266l0.005620002746582031,0q0,-0.08430004119873047,0.011240005493164062,-0.2908344268798828t0.022480010986328125,-0.22058582305908203l0.4861299991607666,0q-0.01967000961303711,0.16579055786132812,-0.01967000961303711,0.8289499282836914l0,3.4450597763061523l-0.5058000087738037,0l0,-1.2335891723632812l0.011240005493164062,-0.46084022521972656l-0.005620002746582031,0q-0.15173983573913574,0.30066967010498047,-0.373729944229126,0.4285249710083008t-0.5788600444793701,0.1278543472290039ZM2.3070099353790283,14.432160377502441q0,-0.5929107666015625,-0.19388985633850098,-0.8795299530029297t-0.6182000637054443,-0.2866201400756836q-0.3849700689315796,0,-0.553570032119751,0.2866201400756836t-0.1685999631881714,0.9132499694824219q0,0.6378698348999023,0.1700049638748169,0.9132499694824219t0.5465450286865234,0.2753791809082031q0.4299299716949463,0,0.6238200664520264,-0.3062896728515625t0.19388985633850098,-0.9160594940185547Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 17.18,\r\n    char: \"q\"\r\n  },\r\n  'Xr': {\r\n    getPath: () => precision(`M0.3990199863910675,15.988900184631348l0,-2.3323001861572266q0,-0.3203401565551758,-0.016859978437423706,-0.7081203460693359l0.47769999504089355,0q0.022480010986328125,0.5170402526855469,0.022480010986328125,0.6210107803344727l0.011240005493164062,0q0.1208299994468689,-0.3905906677246094,0.2781899571418762,-0.533900260925293t0.44397997856140137,-0.143310546875q0.10116004943847656,0,0.20513010025024414,0.028100013732910156l0,0.4636507034301758q-0.10116004943847656,-0.028100013732910156,-0.26976001262664795,-0.028100013732910156q-0.3147200345993042,0,-0.48050999641418457,0.2711648941040039t-0.16579002141952515,0.7769651412963867l0,1.5848398208618164l-0.5058000385761261,0Z`),\r\n    get width() { return getGridUnitWidth(682); },\r\n    height: 15.99,\r\n    char: \"r\"\r\n  },\r\n  'Xs': {\r\n    getPath: () => precision(`M2.6695001125335693,15.148710250854492q0,0.4299297332763672,-0.3245551586151123,0.6631593704223633t-0.9090349674224854,0.2332296371459961q-0.5676199793815613,0,-0.8753150105476379,-0.18686389923095703t-0.4004249721765518,-0.5830755233764648l0.4467899948358536,-0.08710956573486328q0.06462997198104858,0.24446964263916016,0.26695001125335693,0.3582744598388672t0.5619999766349792,0.11380481719970703q0.3849700689315796,0,0.5634050369262695,-0.11801910400390625t0.1784350872039795,-0.35406017303466797q0,-0.179840087890625,-0.12364006042480469,-0.2922401428222656t-0.39902007579803467,-0.18546009063720703l-0.3624899387359619,-0.09554004669189453q-0.4355500340461731,-0.11240005493164062,-0.6196050643920898,-0.22058486938476562t-0.2880249619483948,-0.26273536682128906t-0.10397002100944519,-0.3793497085571289q0,-0.4158802032470703,0.2964549958705902,-0.6336545944213867t0.8640750050544739,-0.2177753448486328q0.5029900074005127,0,0.7994449138641357,0.17702960968017578t0.3751351833343506,0.5676202774047852l-0.45521998405456543,0.05620002746582031q-0.042150020599365234,-0.20232009887695312,-0.22620511054992676,-0.3105049133300781t-0.49315500259399414,-0.108184814453125q-0.34282004833221436,0,-0.5058000087738037,0.10396957397460938t-0.16297996044158936,0.31472015380859375q0,0.12926006317138672,0.0674399733543396,0.2135601043701172t0.19951003789901733,0.1433095932006836t0.5563799142837524,0.1629800796508789q0.4018300771713257,0.10116004943847656,0.5788601636886597,0.18686485290527344t0.27959489822387695,0.18967533111572266t0.15876507759094238,0.24025535583496094t0.05620002746582031,0.3105049133300781Z`),\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16.05,\r\n    char: \"s\"\r\n  },\r\n  'Xt': {\r\n    getPath: () => precision(`M1.5567400455474854,15.96642017364502q-0.25009000301361084,0.06743907928466797,-0.5114200115203857,0.06743907928466797q-0.6069600284099579,0,-0.6069600284099579,-0.6884489059448242l0,-2.028820037841797l-0.3512500077486038,0l0,-0.36811065673828125l0.37091998755931854,0l0.14893001317977905,-0.6800193786621094l0.33719998598098755,0l0,0.6800193786621094l0.562000036239624,0l0,0.36811065673828125l-0.562000036239624,0l0,1.919229507446289q0,0.21918010711669922,0.0716550350189209,0.3076953887939453t0.24868500232696533,0.08851432800292969q0.10115993022918701,0,0.2922400236129761,-0.03933906555175781l0,0.3737297058105469Z`),\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16.03,\r\n    char: \"t\"\r\n  },\r\n  'Xu': {\r\n    getPath: () => precision(`M0.8823400139808655,12.948479652404785l0,1.9276599884033203q0,0.3006706237792969,0.05900996923446655,0.4664602279663086t0.1882699728012085,0.23885059356689453t0.37935006618499756,0.07305908203125q0.36529994010925293,0,0.5760500431060791,-0.2500896453857422t0.21074986457824707,-0.6940698623657227l0,-1.7618703842163086l0.5058000087738037,0l0,2.391310691833496q0,0.5310897827148438,0.016860008239746094,0.6491098403930664l-0.47769999504089355,0q-0.0028100013732910156,-0.014050483703613281,-0.005620002746582031,-0.07587051391601562t-0.007025003433227539,-0.1419048309326172t-0.009835004806518555,-0.3020744323730469l-0.008430004119873047,0q-0.17421984672546387,0.31471920013427734,-0.40323495864868164,0.4453849792480469t-0.569024920463562,0.13066387176513672q-0.5001800656318665,0,-0.7320050597190857,-0.24868392944335938t-0.23182499408721924,-0.821925163269043l0,-2.026010513305664l0.5086100101470947,0Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16.05,\r\n    char: \"u\"\r\n  },\r\n  'Xv': {\r\n    getPath: () => precision(`M1.7225300073623657,15.988900184631348l-0.5985300540924072,0l-1.1043299529701471,-3.0404205322265625l0.5395199749618769,0l0.6687800288200378,1.9782400131225586q0.0365300178527832,0.11240005493164062,0.19388997554779053,0.6659708023071289l0.09835004806518555,-0.32877063751220703l0.10958993434906006,-0.33158016204833984l0.6912599802017212,-1.9838600158691406l0.5367100238800049,0Z`),\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 15.99,\r\n    char: \"v\"\r\n  },\r\n  'Xw': {\r\n    getPath: () => precision(`M3.2989399433135986,15.988900184631348l-0.5872900485992432,0l-0.5310897827148438,-2.1496505737304688l-0.10116004943847656,-0.47488975524902344q-0.02529001235961914,0.1264505386352539,-0.07868003845214844,0.3638954162597656t-0.5732400417327881,2.2606449127197266l-0.5844799876213074,0l-0.851429995149374,-3.0404205322265625l0.5001800023019314,0l0.5142300128936768,2.0653505325317383q0.01967000961303711,0.06744003295898438,0.12082993984222412,0.5563802719116211l0.047770023345947266,-0.20794010162353516l0.6350600719451904,-2.413790702819824l0.5423299074172974,0l0.5310900211334229,2.0878305435180664l0.12926006317138672,0.533900260925293l0.08711004257202148,-0.3905906677246094l0.5760498046875,-2.23114013671875l0.49456024169921875,0Z`),\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 15.99,\r\n    char: \"w\"\r\n  },\r\n  'Xx': {\r\n    getPath: () => precision(`M2.250809907913208,15.988900184631348l-0.8177099227905273,-1.247640609741211l-0.8233299851417542,1.247640609741211l-0.5451399981975555,0l1.0818499624729156,-1.5623598098754883l-1.0312699675559998,-1.4780607223510742l0.5591899752616882,0l0.7587000131607056,1.1830101013183594l0.7530801296234131,-1.1830101013183594l0.5648097991943359,0l-1.031269907951355,1.4724407196044922l1.0958999395370483,1.5679798126220703l-0.564810037612915,0Z`),\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 15.99,\r\n    char: \"x\"\r\n  },\r\n  'Xy': {\r\n    getPath: () => precision(`M0.5367100238800049,17.183149337768555q-0.207940012216568,0,-0.348440021276474,-0.030908584594726562l0,-0.3793506622314453q0.10677999258041382,0.016859054565429688,0.23603999614715576,0.016859054565429688q0.4720800220966339,0,0.7474599778652191,-0.6940689086914062l0.047770023345947266,-0.12083053588867188l-1.205489999614656,-3.026370048522949l0.5395199721679091,0l0.6406800150871277,1.6803808212280273q0.014050006866455078,0.03933906555175781,0.03372001647949219,0.09413433074951172t0.12644994258880615,0.36670494079589844t0.11521005630493164,0.34844017028808594l0.19669997692108154,-0.5535697937011719l0.665969967842102,-1.9360904693603516l0.5339000225067139,0l-1.1689599752426147,3.0404205322265625q-0.1882699728012085,0.4861307144165039,-0.3512500524520874,0.7235746383666992t-0.3610849380493164,0.3540611267089844t-0.4481949806213379,0.11661338806152344Z`),\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 17.18,\r\n    char: \"y\"\r\n  },\r\n  'Xz': {\r\n    getPath: () => precision(`M0.23322999477386475,15.988900184631348l0,-0.38496971130371094l1.7000499963760376,-2.264860153198242l-1.6045099794864655,0l0,-0.3905906677246094l2.2030400335788727,0l0,0.38497066497802734l-1.7028600573539734,2.264860153198242l1.7618700861930847,0l0,0.39058971405029297l-2.357590079307556,0Z`),\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 15.99,\r\n    char: \"z\"\r\n  },\r\n  'Xå': {\r\n    getPath: () => precision(`M1.1633399724960327,16.04509925842285q-0.45802998542785645,0,-0.6884499788284302,-0.24165916442871094t-0.23041999340057373,-0.6631603240966797q0,-0.4720802307128906,0.3105049729347229,-0.7249794006347656t1.0017650723457336,-0.2697601318359375l0.6828298568725586,-0.011240005493164062l0,-0.16579055786132812q0,-0.37091922760009766,-0.15735983848571777,-0.5310897827148438t-0.4945601224899292,-0.1601696014404297q-0.3400099277496338,0,-0.4945598840713501,0.11520957946777344t-0.18546003103256226,0.36810970306396484l-0.5282800197601318,-0.04776954650878906q0.12926000356674194,-0.8205204010009766,1.2195399403572083,-0.8205204010009766q0.5732401609420776,0,0.8626700639724731,0.26273536682128906t0.2894299030303955,0.7601051330566406l0,1.3094596862792969q0,0.22480010986328125,0.05901002883911133,0.3386049270629883t0.22480010986328125,0.11380481719970703q0.0730600357055664,0,0.16578984260559082,-0.019669532775878906l0,0.31472015380859375q-0.19107985496520996,0.04496002197265625,-0.39058995246887207,0.04496002197265625q-0.28099989891052246,0,-0.40885496139526367,-0.14752483367919922t-0.1447150707244873,-0.46224498748779297l-0.016860008239746094,0q-0.19388985633850098,0.34843921661376953,-0.45100486278533936,0.49315452575683594t-0.6252250671386719,0.14471435546875ZM1.2785500288009644,15.665749549865723q0.278190016746521,0,0.49456000328063965,-0.1264495849609375t0.34141504764556885,-0.34703540802001953t0.1250448226928711,-0.4538145065307617l0,-0.2500896453857422l-0.5535699129104614,0.011240005493164062q-0.3568699359893799,0.005620002746582031,-0.5409250259399414,0.0730600357055664t-0.28240495920181274,0.20793914794921875t-0.09834998846054077,0.36811065673828125q0,0.24728012084960938,0.13347500562667847,0.3821601867675781t0.3807550072669983,0.13487911224365234ZM2.245189905166626,12.026800155639648q0,0.28100013732910156,-0.199509859085083,0.48050975799560547t-0.48050999641418457,0.1995096206665039t-0.48050999641418457,-0.1995096206665039t-0.19951003789901733,-0.48050975799560547q0,-0.2838106155395508,0.19951003789901733,-0.48050975799560547t0.48050999641418457,-0.1967000961303711q0.27818989753723145,0,0.47910499572753906,0.1981048583984375t0.20091485977172852,0.47910499572753906ZM1.9417099952697754,12.026800155639648q0,-0.15736007690429688,-0.10959005355834961,-0.2669506072998047t-0.2669498920440674,-0.1095895767211914q-0.1601700782775879,0,-0.26976001262664795,0.1095895767211914t-0.10959005355834961,0.2669506072998047q0,0.15454959869384766,0.1067800521850586,0.2697601318359375t0.27257001399993896,0.11520957946777344q0.16297996044158936,0,0.2697598934173584,-0.11380481719970703t0.1067800521850586,-0.2711648941040039Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16.05,\r\n    char: \"å\"\r\n  },\r\n  'Xä': {\r\n    getPath: () => precision(`M1.1633399724960327,16.04509925842285q-0.45802998542785645,0,-0.6884499788284302,-0.24165916442871094t-0.23041999340057373,-0.6631603240966797q0,-0.4720802307128906,0.3105049729347229,-0.7249794006347656t1.0017650723457336,-0.2697601318359375l0.6828298568725586,-0.011240005493164062l0,-0.16579055786132812q0,-0.37091922760009766,-0.15735983848571777,-0.5310897827148438t-0.4945601224899292,-0.1601696014404297q-0.3400099277496338,0,-0.4945598840713501,0.11520957946777344t-0.18546003103256226,0.36810970306396484l-0.5282800197601318,-0.04776954650878906q0.12926000356674194,-0.8205204010009766,1.2195399403572083,-0.8205204010009766q0.5732401609420776,0,0.8626700639724731,0.26273536682128906t0.2894299030303955,0.7601051330566406l0,1.3094596862792969q0,0.22480010986328125,0.05901002883911133,0.3386049270629883t0.22480010986328125,0.11380481719970703q0.0730600357055664,0,0.16578984260559082,-0.019669532775878906l0,0.31472015380859375q-0.19107985496520996,0.04496002197265625,-0.39058995246887207,0.04496002197265625q-0.28099989891052246,0,-0.40885496139526367,-0.14752483367919922t-0.1447150707244873,-0.46224498748779297l-0.016860008239746094,0q-0.19388985633850098,0.34843921661376953,-0.45100486278533936,0.49315452575683594t-0.6252250671386719,0.14471435546875ZM1.2785500288009644,15.665749549865723q0.278190016746521,0,0.49456000328063965,-0.1264495849609375t0.34141504764556885,-0.34703540802001953t0.1250448226928711,-0.4538145065307617l0,-0.2500896453857422l-0.5535699129104614,0.011240005493164062q-0.3568699359893799,0.005620002746582031,-0.5409250259399414,0.0730600357055664t-0.28240495920181274,0.20793914794921875t-0.09834998846054077,0.36811065673828125q0,0.24728012084960938,0.13347500562667847,0.3821601867675781t0.3807550072669983,0.13487911224365234ZM1.8939399719238281,12.563509941101074l0,-0.5170402526855469l0.45802998542785645,0l0,0.5170402526855469l-0.45802998542785645,0ZM0.7868000268936157,12.563509941101074l0,-0.5170402526855469l0.4636499881744385,0l0,0.5170402526855469l-0.4636499881744385,0Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16.05,\r\n    char: \"ä\"\r\n  },\r\n  'Xö': {\r\n    getPath: () => precision(`M2.958930015563965,14.465880393981934q0,0.798039436340332,-0.35124993324279785,1.188629150390625t-1.02003014087677,0.39058971405029297q-0.665969967842102,0,-1.0059799551963806,-0.40604400634765625t-0.34000998735427856,-1.1731748580932617q0,-1.5736007690429688,1.3628499507904053,-1.5736007690429688q0.6968799829483032,0,1.025650143623352,0.38356494903564453t0.3287699222564697,1.1900358200073242ZM2.427839994430542,14.465880393981934q0,-0.6294403076171875,-0.18686509132385254,-0.9146556854248047t-0.6280349493026733,-0.2852144241333008q-0.44397997856140137,0,-0.6420849561691284,0.2908344268798828t-0.19810497760772705,0.9090356826782227q0,0.6013393402099609,0.19529497623443604,0.9034147262573242t0.6139850616455078,0.3020744323730469q0.45521998405456543,0,0.6505148410797119,-0.2922391891479492t0.19529509544372559,-0.9132499694824219ZM1.9360899925231934,12.563509941101074l0,-0.5170402526855469l0.45802998542785645,0l0,0.5170402526855469l-0.45802998542785645,0ZM0.8289499878883362,12.563509941101074l0,-0.5170402526855469l0.46365004777908325,0l0,0.5170402526855469l-0.46365004777908325,0Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16.05,\r\n    char: \"ö\"\r\n  },\r\n  'XA': {\r\n    getPath: () => precision(`M3.2792699337005615,15.988900184631348l-0.4524099826812744,-1.1577205657958984l-1.8040199279785156,0l-0.4552200436592102,1.1577205657958984l-0.5563799794763327,0l1.6157499607652426,-3.9592905044555664l0.6097699403762817,0l1.5904600620269775,3.9592905044555664l-0.547950029373169,0ZM1.9248499870300293,12.434249877929688l-0.02529001235961914,0.07868003845214844q-0.07024991512298584,0.2332296371459961,-0.2079399824142456,0.5985298156738281l-0.5058000087738037,1.301030158996582l1.4808701276779175,0l-0.5086100101470947,-1.306650161743164q-0.07868003845214844,-0.19388961791992188,-0.15736007690429688,-0.43835926055908203Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"A\",\r\n    kerningRules: {\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"T\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'XB': {\r\n    getPath: () => precision(`M3.534980058670044,14.873330116271973q0,0.5282802581787109,-0.38496994972229004,0.821925163269043t-1.0706100463867188,0.29364490509033203l-1.6073200702667236,0l0,-3.9592905044555664l1.4387199878692627,0q1.3937599658966064,0,1.3937599658966064,0.9610204696655273q0,0.35124969482421875,-0.196699857711792,0.5901002883911133t-0.556380033493042,0.3203392028808594q0.4720799922943115,0.05620002746582031,0.7277898788452148,0.31612491607666016t0.2557101249694824,0.6561355590820312ZM2.7650399208068848,13.055259704589844q0,-0.3203401565551758,-0.21917986869812012,-0.45802974700927734t-0.6350600719451904,-0.13768959045410156l-0.9020099639892578,0l0,1.2532596588134766l0.9020099639892578,0q0.4299299716949463,0,0.642085075378418,-0.1615753173828125t0.21215486526489258,-0.49596500396728516ZM2.992650032043457,14.83117961883545q0,-0.6996898651123047,-0.9835000038146973,-0.6996898651123047l-1.0003600120544434,0l0,1.427480697631836l1.0425100326538086,0q0.49175000190734863,0,0.7165498733520508,-0.18265056610107422t0.22480010986328125,-0.545140266418457Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"B\"\r\n  },\r\n  'XC': {\r\n    getPath: () => precision(`M2.225519895553589,12.408960342407227q-0.6575398445129395,0,-1.022839903831482,0.42290496826171875t-0.3652999997138977,1.1591243743896484q0,0.7277898788452148,0.3807550072669983,1.170365333557129t1.0298649072647095,0.44257545471191406q0.8317601680755615,0,1.2504501342773438,-0.8233308792114258l0.43835997581481934,0.21918010711669922q-0.24447011947631836,0.5114202499389648,-0.6870450973510742,0.7783699035644531t-1.027055025100708,0.2669496536254883q-0.5985299348831177,0,-1.0354849100112915,-0.24868392944335938t-0.665969967842102,-0.7109298706054688t-0.2290150225162506,-1.0944957733154297q0,-0.9469699859619141,0.5114199817180634,-1.4836797714233398t1.4162399172782898,-0.5367097854614258q0.6322500705718994,0,1.0565600395202637,0.24728012084960938t0.6238200664520264,0.7334098815917969l-0.5086100101470947,0.16860008239746094q-0.13769006729125977,-0.3456306457519531,-0.44257497787475586,-0.5282802581787109t-0.7235751152038574,-0.1826496124267578Z`),\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16.05,\r\n    char: \"C\"\r\n  },\r\n  'XD': {\r\n    getPath: () => precision(`M3.8806099891662598,13.968509674072266q0,0.6125802993774414,-0.23884987831115723,1.0720157623291016t-0.6772100925445557,0.7039041519165039t-1.0116000175476074,0.24447059631347656l-1.480870008468628,0l0,-3.9592905044555664l1.3094600439071655,0q1.0059798955917358,0,1.5525249242782593,0.5043954849243164t0.5465450286865234,1.434504508972168ZM3.341089963912964,13.968509674072266q0,-0.7362194061279297,-0.40323495864868164,-1.1225948333740234t-1.1675549745559692,-0.38637447357177734l-0.7615100145339966,0l0,3.0994300842285156l0.8823399543762207,0q0.4355499744415283,0,0.7657251358032227,-0.19108009338378906t0.5072050094604492,-0.5507602691650391t0.17702984809875488,-0.8486204147338867Z`),\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 15.99,\r\n    char: \"D\"\r\n  },\r\n  'XE': {\r\n    getPath: () => precision(`M0.4720799922943115,15.988900184631348l0,-3.9592905044555664l3.003890037536621,0l0,0.43836021423339844l-2.467180013656616,0l0,1.2701196670532227l2.2985799312591553,0l0,0.4327402114868164l-2.2985799312591553,0l0,1.3797101974487305l2.582390069961548,0l0,0.43836021423339844l-3.1191000938415527,0Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"E\"\r\n  },\r\n  'XF': {\r\n    getPath: () => precision(`M1.0087900161743164,12.46796989440918l0,1.4724397659301758l2.2086598873138428,0l0,0.44398021697998047l-2.2086598873138428,0l0,1.6045103073120117l-0.5367100238800049,0l0,-3.9592905044555664l2.812809944152832,0l0,0.43836021423339844l-2.276099920272827,0Z`),\r\n    get width() { return getGridUnitWidth(1251); },\r\n    height: 15.99,\r\n    char: \"F\",\r\n    kerningRules: {\r\n      \"A\": getGridUnitKerningRule(113)\r\n    }\r\n  },\r\n  'XG': {\r\n    getPath: () => precision(`M0.28942999243736267,13.990989685058594q0,-0.9638299942016602,0.5170399844646454,-1.4921092987060547t1.452769935131073,-0.5282802581787109q0.6575400829315186,0,1.0678000450134277,0.22198963165283203t0.6322500705718994,0.7109298706054688l-0.5114200115203857,0.15174007415771484q-0.16860008239746094,-0.3372001647949219,-0.465054988861084,-0.49174976348876953t-0.7376251220703125,-0.15454959869384766q-0.6856398582458496,0,-1.048129916191101,0.4144744873046875t-0.3624899983406067,1.1675548553466797q0,0.750269889831543,0.3849700093269348,1.1844148635864258t1.0649899244308472,0.4341459274291992q0.38778018951416016,0,0.7235751152038574,-0.11802005767822266t0.5437350273132324,-0.3203401565551758l0,-0.713740348815918l-1.1830101013183594,0l0,-0.4496002197265625l1.677570104598999,0l0,1.3656606674194336q-0.31472015380859375,0.3203392028808594,-0.7713451385498047,0.49596500396728516t-0.9905250072479248,0.17562389373779297q-0.6210099458694458,0,-1.0706099271774292,-0.24727916717529297t-0.6870449781417847,-0.7123346328735352t-0.23744502663612366,-1.0944957733154297Z`),\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16.05,\r\n    char: \"G\"\r\n  },\r\n  'XH': {\r\n    getPath: () => precision(`M3.150010108947754,15.988900184631348l0,-1.834930419921875l-2.1412200927734375,0l0,1.834930419921875l-0.5367100238800049,0l0,-3.9592905044555664l0.5367100238800049,0l0,1.674759864807129l2.1412200927734375,0l0,-1.674759864807129l0.5367097854614258,0l0,3.9592905044555664l-0.5367097854614258,0Z`),\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 15.99,\r\n    char: \"H\"\r\n  },\r\n  'XI': {\r\n    getPath: () => precision(`M0.5310900211334229,15.988900184631348l0,-3.9592905044555664l0.5367100238800049,0l0,3.9592905044555664l-0.5367100238800049,0Z`),\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 15.99,\r\n    char: \"I\"\r\n  },\r\n  'XJ': {\r\n    getPath: () => precision(`M1.2841700315475464,16.04509925842285q-1.0059800446033478,0,-1.1942500323057175,-1.0396995544433594l0.5254700034856796,-0.08710956573486328q0.05058002471923828,0.3259601593017578,0.22760999202728271,0.5086097717285156t0.44398003816604614,0.18265056610107422q0.2922400236129761,0,0.46083998680114746,-0.20091533660888672t0.1685999631881714,-0.5886955261230469l0,-2.3519697189331055l-0.7615100145339966,0l0,-0.43836021423339844l1.2954100370407104,0l0,2.77908992767334q0,0.5760507583618164,-0.31190991401672363,0.9062252044677734t-0.8542400598526001,0.33017444610595703Z`),\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16.05,\r\n    char: \"J\"\r\n  },\r\n  'XK': {\r\n    getPath: () => precision(`M3.1078600883483887,15.988900184631348l-1.5820300579071045,-1.9107999801635742l-0.5170400142669678,0.3934001922607422l0,1.517399787902832l-0.5367100238800049,0l0,-3.9592905044555664l0.5367100238800049,0l0,1.9838600158691406l1.9079899787902832,-1.9838600158691406l0.6322500705718994,0l-1.686000108718872,1.7197198867797852l1.9107999801635742,2.2395706176757812l-0.6659698486328125,0Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"K\"\r\n  },\r\n  'XL': {\r\n    getPath: () => precision(`M0.4720799922943115,15.988900184631348l0,-3.9592905044555664l0.5367100238800049,0l0,3.520930290222168l2.0007200241088867,0l0,0.43836021423339844l-2.5374300479888916,0Z`),\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 15.99,\r\n    char: \"L\",\r\n    kerningRules: {\r\n      \"y\": getGridUnitKerningRule(76),\r\n      \"Y\": getGridUnitKerningRule(152),\r\n      \"W\": getGridUnitKerningRule(152),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"T\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'XM': {\r\n    getPath: () => precision(`M3.8384599685668945,15.988900184631348l0,-2.6414003372192383q0,-0.43836021423339844,0.02529001235961914,-0.8429994583129883q-0.13769006729125977,0.5029897689819336,-0.24727988243103027,0.786799430847168l-1.0228400230407715,2.6976003646850586l-0.3765401840209961,0l-1.036889910697937,-2.6976003646850586l-0.15735995769500732,-0.47770023345947266l-0.09273004531860352,-0.3090991973876953l0.008430004119873047,0.31190967559814453l0.011240005493164062,0.5310897827148438l0,2.6414003372192383l-0.47769999504089355,0l0,-3.9592905044555664l0.7053099870681763,0l1.053749918937683,2.7453699111938477q0.05620002746582031,0.16579055786132812,0.1081850528717041,0.3554649353027344t0.06884503364562988,0.2739753723144531q0.022480010986328125,-0.11240005493164062,0.09413504600524902,-0.3414144515991211t0.09694504737854004,-0.2880258560180664l1.0340800285339355,-2.7453699111938477l0.6884500980377197,0l0,3.9592905044555664l-0.4833202362060547,0Z`),\r\n    get width() { return getGridUnitWidth(1706); },\r\n    height: 15.99,\r\n    char: \"M\"\r\n  },\r\n  'XN': {\r\n    getPath: () => precision(`M3.0404200553894043,15.988900184631348l-2.1187400817871094,-3.371999740600586l0.014050006866455078,0.2725696563720703l0.014050006866455078,0.4692697525024414l0,2.630160331726074l-0.47769999504089355,0l0,-3.9592905044555664l0.6238200664520264,0l2.1412198543548584,3.3944807052612305q-0.03372001647949219,-0.5507602691650391,-0.03372001647949219,-0.7980403900146484l0,-2.596440315246582l0.4833199977874756,0l0,3.9592905044555664l-0.6462998390197754,0Z`),\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 15.99,\r\n    char: \"N\"\r\n  },\r\n  'XO': {\r\n    getPath: () => precision(`M4.2009501457214355,13.990989685058594q0,0.6210107803344727,-0.23744511604309082,1.0874700546264648t-0.6814250946044922,0.7165498733520508t-1.0481300354003906,0.2500896453857422q-0.6097699403762817,0,-1.0523449182510376,-0.24727916717529297t-0.6758049726486206,-0.7151451110839844t-0.23322999477386475,-1.0916852951049805q0,-0.9497795104980469,0.5198500156402588,-1.4850845336914062t1.4471498727798462,-0.5353050231933594q0.6041500568389893,0,1.0481300354003906,0.24025440216064453t0.6786150932312012,0.6982851028442383t0.2346351146697998,1.0818500518798828ZM3.6530001163482666,13.990989685058594q0,-0.7390298843383789,-0.36951518058776855,-1.1605300903320312t-1.043915033340454,-0.42149925231933594q-0.6800198554992676,0,-1.050939917564392,0.4158792495727539t-0.37092000246047974,1.1661500930786133q0,0.7446498870849609,0.37513500452041626,1.181605339050293t1.0411049127578735,0.43695545196533203q0.6856400966644287,0,1.0523450374603271,-0.42290592193603516t0.36670517921447754,-1.1956548690795898Z`),\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16.05,\r\n    char: \"O\"\r\n  },\r\n  'XP': {\r\n    getPath: () => precision(`M3.534980058670044,13.221050262451172q0,0.5619993209838867,-0.36670494079589844,0.8935794830322266t-0.9961450099945068,0.33158016204833984l-1.1633400917053223,0l0,1.5426902770996094l-0.5367100238800049,0l0,-3.9592905044555664l1.666330099105835,0q0.6659698486328125,0,1.0312700271606445,0.31191062927246094t0.36529994010925293,0.8795299530029297ZM2.995460033416748,13.226670265197754q0,-0.7671298980712891,-0.9216799736022949,-0.7671298980712891l-1.0649900436401367,0l0,1.5623598098754883l1.0874700546264648,0q0.8991999626159668,0,0.8991999626159668,-0.7952299118041992Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"P\",\r\n    kerningRules: {\r\n      \"A\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'XQ': {\r\n    getPath: () => precision(`M4.2009501457214355,13.990989685058594q0,0.8373804092407227,-0.42150020599365234,1.3769006729125977t-1.1717698574066162,0.6378698348999023q0.11520981788635254,0.35405921936035156,0.3020749092102051,0.5114192962646484t0.47348499298095703,0.15736007690429688q0.15455007553100586,0,0.3231499195098877,-0.036529541015625l0,0.3765392303466797q-0.26132988929748535,0.06182098388671875,-0.5001800060272217,0.06182098388671875q-0.42430996894836426,0,-0.6982848644256592,-0.24025535583496094t-0.4481949806213379,-0.8022556304931641q-0.556380033493042,-0.02809906005859375,-0.9596151113510132,-0.28240394592285156t-0.6153899431228638,-0.7081203460693359t-0.21215498447418213,-1.0523452758789062q0,-0.9497795104980469,0.5198500156402588,-1.4850845336914062t1.4471498727798462,-0.5353050231933594q0.6041500568389893,0,1.0481300354003906,0.24025440216064453t0.6786150932312012,0.6982851028442383t0.2346351146697998,1.0818500518798828ZM3.6530001163482666,13.990989685058594q0,-0.7390298843383789,-0.36951518058776855,-1.1605300903320312t-1.043915033340454,-0.42149925231933594q-0.6800198554992676,0,-1.050939917564392,0.4158792495727539t-0.37092000246047974,1.1661500930786133q0,0.7446498870849609,0.37513500452041626,1.181605339050293t1.0411049127578735,0.43695545196533203q0.6856400966644287,0,1.0523450374603271,-0.42290592193603516t0.36670517921447754,-1.1956548690795898Z`),\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 17.08,\r\n    char: \"Q\"\r\n  },\r\n  'XR': {\r\n    getPath: () => precision(`M3.2708399295806885,15.988900184631348l-1.0284600257873535,-1.643850326538086l-1.2335898876190186,0l0,1.643850326538086l-0.5367100238800049,0l0,-3.9592905044555664l1.863029956817627,0q0.6687800884246826,0,1.03267502784729,0.29926490783691406t0.3638949394226074,0.833165168762207q0,0.44117069244384766,-0.25711488723754883,0.7418403625488281t-0.7095251083374023,0.3793497085571289l1.124000072479248,1.7056703567504883l-0.6182000637054443,0ZM3.19215989112854,13.167659759521484q0,-0.3456296920776367,-0.2346348762512207,-0.5268745422363281t-0.6758050918579102,-0.1812448501586914l-1.2729299068450928,0l0,1.4611997604370117l1.295409917831421,0q0.42430996894836426,0,0.656135082244873,-0.1981048583984375t0.2318248748779297,-0.5549755096435547Z`),\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 15.99,\r\n    char: \"R\",\r\n    kerningRules: {\r\n      \"Y\": getGridUnitKerningRule(37),\r\n      \"W\": getGridUnitKerningRule(37),\r\n      \"V\": getGridUnitKerningRule(37),\r\n      \"T\": getGridUnitKerningRule(37)\r\n    }\r\n  },\r\n  'XS': {\r\n    getPath: () => precision(`M3.574320077896118,14.8958101272583q0,0.5479497909545898,-0.4285249710083008,0.8486194610595703t-1.206895112991333,0.30066967010498047q-1.4471499919891357,0,-1.6775699853897095,-1.0059795379638672l0.5198500156402588,-0.10396957397460938q0.08991998434066772,0.3568696975708008,0.382159948348999,0.5240650177001953t0.7952300310134888,0.16719436645507812q0.5198500156402588,0,0.8022549152374268,-0.1784343719482422t0.28240513801574707,-0.5240650177001953q0,-0.19389057159423828,-0.08851504325866699,-0.31472015380859375t-0.24868512153625488,-0.1995096206665039t-0.382159948348999,-0.13207054138183594t-0.49175000190734863,-0.11520957946777344q-0.4692699909210205,-0.10397052764892578,-0.7123349905014038,-0.20794010162353516t-0.38356494903564453,-0.2318248748779297t-0.21496498584747314,-0.29926490783691406t-0.07446500658988953,-0.3934001922607422q0,-0.5086097717285156,0.38918498158454895,-0.7839899063110352t1.1141650080680847,-0.27538013458251953q0.6744000911712646,0,1.0312700271606445,0.20653533935546875t0.5001800060272217,0.7039041519165039l-0.5282800197601318,0.09273052215576172q-0.08711004257202148,-0.31472015380859375,-0.33157992362976074,-0.45662498474121094t-0.6772100925445557,-0.1419048309326172q-0.47488999366760254,0,-0.7249799966812134,0.15736007690429688t-0.25009000301361084,0.4692697525024414q0,0.1826496124267578,0.09694504737854004,0.3020744323730469t0.27959489822387695,0.20232009887695312t0.727790117263794,0.20372486114501953q0.18264985084533691,0.04215049743652344,0.3638949394226074,0.08570575714111328t0.34703493118286133,0.10396957397460938t0.3105051517486572,0.1419048309326172t0.2514948844909668,0.1995105743408203t0.16719508171081543,0.27818965911865234t0.060415029525756836,0.3765401840209961Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16.05,\r\n    char: \"S\"\r\n  },\r\n  'XT': {\r\n    getPath: () => precision(`M2.023200035095215,12.46796989440918l0,3.520930290222168l-0.5339000225067139,0l0,-3.520930290222168l-1.360040009021759,0l0,-0.43836021423339844l3.253979980945587,0l0,0.43836021423339844l-1.3600399494171143,0Z`),\r\n    get width() { return getGridUnitWidth(1251); },\r\n    height: 15.99,\r\n    char: \"T\",\r\n    kerningRules: {\r\n      \"y\": getGridUnitKerningRule(113),\r\n      \"w\": getGridUnitKerningRule(113),\r\n      \"u\": getGridUnitKerningRule(76),\r\n      \"ù\": getGridUnitKerningRule(76),\r\n      \"ú\": getGridUnitKerningRule(76),\r\n      \"û\": getGridUnitKerningRule(76),\r\n      \"ü\": getGridUnitKerningRule(76),\r\n      \"ū\": getGridUnitKerningRule(76),\r\n      \"ű\": getGridUnitKerningRule(76),\r\n      \"ų\": getGridUnitKerningRule(76),\r\n      \"s\": getGridUnitKerningRule(227),\r\n      \"š\": getGridUnitKerningRule(227),\r\n      \"ś\": getGridUnitKerningRule(227),\r\n      \"r\": getGridUnitKerningRule(76),\r\n      \"o\": getGridUnitKerningRule(227),\r\n      \"ò\": getGridUnitKerningRule(227),\r\n      \"ó\": getGridUnitKerningRule(227),\r\n      \"ô\": getGridUnitKerningRule(227),\r\n      \"õ\": getGridUnitKerningRule(227),\r\n      \"ö\": getGridUnitKerningRule(227),\r\n      \"ø\": getGridUnitKerningRule(227),\r\n      \"ō\": getGridUnitKerningRule(227),\r\n      \"ő\": getGridUnitKerningRule(227),\r\n      \"i\": getGridUnitKerningRule(76),\r\n      \"ì\": getGridUnitKerningRule(76),\r\n      \"í\": getGridUnitKerningRule(76),\r\n      \"î\": getGridUnitKerningRule(76),\r\n      \"ï\": getGridUnitKerningRule(76),\r\n      \"ī\": getGridUnitKerningRule(76),\r\n      \"į\": getGridUnitKerningRule(76),\r\n      \"e\": getGridUnitKerningRule(227),\r\n      \"è\": getGridUnitKerningRule(227),\r\n      \"é\": getGridUnitKerningRule(227),\r\n      \"ê\": getGridUnitKerningRule(227),\r\n      \"ë\": getGridUnitKerningRule(227),\r\n      \"ē\": getGridUnitKerningRule(227),\r\n      \"ė\": getGridUnitKerningRule(227),\r\n      \"ę\": getGridUnitKerningRule(227),\r\n      \"c\": getGridUnitKerningRule(227),\r\n      \"ć\": getGridUnitKerningRule(227),\r\n      \"č\": getGridUnitKerningRule(227),\r\n      \"ç\": getGridUnitKerningRule(227),\r\n      \"a\": getGridUnitKerningRule(227),\r\n      \"à\": getGridUnitKerningRule(227),\r\n      \"á\": getGridUnitKerningRule(227),\r\n      \"â\": getGridUnitKerningRule(227),\r\n      \"ã\": getGridUnitKerningRule(227),\r\n      \"ä\": getGridUnitKerningRule(227),\r\n      \"å\": getGridUnitKerningRule(227),\r\n      \"ā\": getGridUnitKerningRule(227),\r\n      \"ą\": getGridUnitKerningRule(227),\r\n      \"æ\": getGridUnitKerningRule(227),\r\n      \"O\": getGridUnitKerningRule(37),\r\n      \"Ò\": getGridUnitKerningRule(37),\r\n      \"Ó\": getGridUnitKerningRule(37),\r\n      \"Ô\": getGridUnitKerningRule(37),\r\n      \"Õ\": getGridUnitKerningRule(37),\r\n      \"Ö\": getGridUnitKerningRule(37),\r\n      \"Ø\": getGridUnitKerningRule(37),\r\n      \"Ō\": getGridUnitKerningRule(37),\r\n      \"Ő\": getGridUnitKerningRule(37),\r\n      \"A\": getGridUnitKerningRule(152),\r\n      \"À\": getGridUnitKerningRule(152),\r\n      \"Á\": getGridUnitKerningRule(152),\r\n      \"Â\": getGridUnitKerningRule(152),\r\n      \"Ã\": getGridUnitKerningRule(152),\r\n      \"Ä\": getGridUnitKerningRule(152),\r\n      \"Å\": getGridUnitKerningRule(152),\r\n      \"Ā\": getGridUnitKerningRule(152),\r\n      \"Ą\": getGridUnitKerningRule(152),\r\n      \"Æ\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'XU': {\r\n    getPath: () => precision(`M2.054110050201416,16.04509925842285q-0.4861299991607666,0,-0.8486200571060181,-0.17702960968017578t-0.5619999766349792,-0.5142297744750977t-0.19951000809669495,-0.8036594390869141l0,-2.520570755004883l0.5367099940776825,0l0,2.4756107330322266q0,0.5423297882080078,0.27538001537323,0.8233299255371094t0.7952300310134888,0.28100013732910156q0.5339000225067139,0,0.8303549289703369,-0.2908353805541992t0.29645490646362305,-0.8500251770019531l0,-2.439080238342285l0.5339000225067139,0l0,2.4699907302856445q0,0.48050975799560547,-0.20372486114501953,0.8289499282836914t-0.5760500431060791,0.5324945449829102t-0.8781249523162842,0.18405437469482422Z`),\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16.05,\r\n    char: \"U\"\r\n  },\r\n  'XV': {\r\n    getPath: () => precision(`M2.1974198818206787,15.988900184631348l-0.5563799142837524,0l-1.6157499682158232,-3.9592905044555664l0.5648099910467863,0l1.0958999991416931,2.787520408630371l0.23603999614715576,0.6996898651123047l0.2360401153564453,-0.6996898651123047l1.0902798175811768,-2.787520408630371l0.564810037612915,0Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"V\",\r\n    kerningRules: {\r\n      \"y\": getGridUnitKerningRule(76),\r\n      \"ý\": getGridUnitKerningRule(76),\r\n      \"ÿ\": getGridUnitKerningRule(76),\r\n      \"u\": getGridUnitKerningRule(76),\r\n      \"ù\": getGridUnitKerningRule(76),\r\n      \"ú\": getGridUnitKerningRule(76),\r\n      \"û\": getGridUnitKerningRule(76),\r\n      \"ü\": getGridUnitKerningRule(76),\r\n      \"ū\": getGridUnitKerningRule(76),\r\n      \"ű\": getGridUnitKerningRule(76),\r\n      \"ų\": getGridUnitKerningRule(76),\r\n      \"r\": getGridUnitKerningRule(76),\r\n      \"o\": getGridUnitKerningRule(113),\r\n      \"ò\": getGridUnitKerningRule(113),\r\n      \"ó\": getGridUnitKerningRule(113),\r\n      \"ô\": getGridUnitKerningRule(113),\r\n      \"õ\": getGridUnitKerningRule(113),\r\n      \"ö\": getGridUnitKerningRule(113),\r\n      \"ø\": getGridUnitKerningRule(113),\r\n      \"ō\": getGridUnitKerningRule(113),\r\n      \"ő\": getGridUnitKerningRule(113),\r\n      \"i\": getGridUnitKerningRule(37),\r\n      \"ì\": getGridUnitKerningRule(37),\r\n      \"í\": getGridUnitKerningRule(37),\r\n      \"î\": getGridUnitKerningRule(37),\r\n      \"ï\": getGridUnitKerningRule(37),\r\n      \"ī\": getGridUnitKerningRule(37),\r\n      \"į\": getGridUnitKerningRule(37),\r\n      \"e\": getGridUnitKerningRule(113),\r\n      \"è\": getGridUnitKerningRule(113),\r\n      \"é\": getGridUnitKerningRule(113),\r\n      \"ê\": getGridUnitKerningRule(113),\r\n      \"ë\": getGridUnitKerningRule(113),\r\n      \"ē\": getGridUnitKerningRule(113),\r\n      \"ė\": getGridUnitKerningRule(113),\r\n      \"ę\": getGridUnitKerningRule(113),\r\n      \"a\": getGridUnitKerningRule(227),\r\n      \"à\": getGridUnitKerningRule(227),\r\n      \"á\": getGridUnitKerningRule(227),\r\n      \"â\": getGridUnitKerningRule(227),\r\n      \"ã\": getGridUnitKerningRule(227),\r\n      \"ä\": getGridUnitKerningRule(227),\r\n      \"å\": getGridUnitKerningRule(227),\r\n      \"ā\": getGridUnitKerningRule(227),\r\n      \"ą\": getGridUnitKerningRule(227),\r\n      \"æ\": getGridUnitKerningRule(227),\r\n      \"A\": getGridUnitKerningRule(152),\r\n      \"À\": getGridUnitKerningRule(152),\r\n      \"Á\": getGridUnitKerningRule(152),\r\n      \"Â\": getGridUnitKerningRule(152),\r\n      \"Ã\": getGridUnitKerningRule(152),\r\n      \"Ä\": getGridUnitKerningRule(152),\r\n      \"Å\": getGridUnitKerningRule(152),\r\n      \"Ā\": getGridUnitKerningRule(152),\r\n      \"Ą\": getGridUnitKerningRule(152),\r\n      \"Æ\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'XW': {\r\n    getPath: () => precision(`M4.245910167694092,15.988900184631348l-0.6406800746917725,0l-0.6856400966644287,-2.5149497985839844q-0.06744003295898438,-0.2360401153564453,-0.1967000961303711,-0.8458099365234375q-0.0730597972869873,0.3259592056274414,-0.12363982200622559,0.5451393127441406t-0.7671301364898682,2.8156204223632812l-0.6406799554824829,0l-1.1661499869078398,-3.9592905044555664l0.5591899883002043,0l0.7109300494194031,2.514950752258301q0.12644994258880615,0.4720792770385742,0.23322999477386475,0.972259521484375q0.06743991374969482,-0.3091001510620117,0.15595495700836182,-0.6744003295898438t0.7797750234603882,-2.812809944152832l0.5142300128936768,0l0.6884498596191406,2.4643707275390625q0.15736007690429688,0.6041498184204102,0.24728012084960938,1.0228395462036133l0.02529001235961914,-0.09834957122802734q0.07587003707885742,-0.323150634765625,0.12364006042480469,-0.5268754959106445t0.7896099090576172,-2.861985206604004l0.5591897964477539,0Z`),\r\n    get width() { return getGridUnitWidth(1933); },\r\n    height: 15.99,\r\n    char: \"W\",\r\n    kerningRules: {\r\n      \"y\": getGridUnitKerningRule(18),\r\n      \"ý\": getGridUnitKerningRule(18),\r\n      \"ÿ\": getGridUnitKerningRule(18),\r\n      \"u\": getGridUnitKerningRule(37),\r\n      \"ù\": getGridUnitKerningRule(37),\r\n      \"ú\": getGridUnitKerningRule(37),\r\n      \"û\": getGridUnitKerningRule(37),\r\n      \"ü\": getGridUnitKerningRule(37),\r\n      \"ū\": getGridUnitKerningRule(37),\r\n      \"ű\": getGridUnitKerningRule(37),\r\n      \"ų\": getGridUnitKerningRule(37),\r\n      \"r\": getGridUnitKerningRule(37),\r\n      \"o\": getGridUnitKerningRule(37),\r\n      \"ò\": getGridUnitKerningRule(37),\r\n      \"ó\": getGridUnitKerningRule(37),\r\n      \"ô\": getGridUnitKerningRule(37),\r\n      \"õ\": getGridUnitKerningRule(37),\r\n      \"ö\": getGridUnitKerningRule(37),\r\n      \"ø\": getGridUnitKerningRule(37),\r\n      \"ō\": getGridUnitKerningRule(37),\r\n      \"ő\": getGridUnitKerningRule(37),\r\n      \"e\": getGridUnitKerningRule(37),\r\n      \"è\": getGridUnitKerningRule(37),\r\n      \"é\": getGridUnitKerningRule(37),\r\n      \"ê\": getGridUnitKerningRule(37),\r\n      \"ë\": getGridUnitKerningRule(37),\r\n      \"ē\": getGridUnitKerningRule(37),\r\n      \"ė\": getGridUnitKerningRule(37),\r\n      \"ę\": getGridUnitKerningRule(37),\r\n      \"a\": getGridUnitKerningRule(76),\r\n      \"à\": getGridUnitKerningRule(76),\r\n      \"á\": getGridUnitKerningRule(76),\r\n      \"â\": getGridUnitKerningRule(76),\r\n      \"ã\": getGridUnitKerningRule(76),\r\n      \"ä\": getGridUnitKerningRule(76),\r\n      \"å\": getGridUnitKerningRule(76),\r\n      \"ā\": getGridUnitKerningRule(76),\r\n      \"ą\": getGridUnitKerningRule(76),\r\n      \"æ\": getGridUnitKerningRule(76),\r\n      \"A\": getGridUnitKerningRule(76),\r\n      \"À\": getGridUnitKerningRule(76),\r\n      \"Á\": getGridUnitKerningRule(76),\r\n      \"Â\": getGridUnitKerningRule(76),\r\n      \"Ã\": getGridUnitKerningRule(76),\r\n      \"Ä\": getGridUnitKerningRule(76),\r\n      \"Å\": getGridUnitKerningRule(76),\r\n      \"Ā\": getGridUnitKerningRule(76),\r\n      \"Ą\": getGridUnitKerningRule(76),\r\n      \"Æ\": getGridUnitKerningRule(76)\r\n    }\r\n  },\r\n  'XX': {\r\n    getPath: () => precision(`M3.1247200965881348,15.988900184631348l-1.1886301040649414,-1.7309598922729492l-1.213919997215271,1.7309598922729492l-0.5929099917411804,0l1.5061599612236023,-2.056920051574707l-1.3909499645233154,-1.9023704528808594l0.5929099917411804,0l1.1015200018882751,1.5539302825927734l1.0706100463867188,-1.5539302825927734l0.5929100513458252,0l-1.3544201850891113,1.882699966430664l1.4696300029754639,2.0765905380249023l-0.5929098129272461,0Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"X\"\r\n  },\r\n  'XY': {\r\n    getPath: () => precision(`M2.1833701133728027,14.347860336303711l0,1.6410398483276367l-0.5339001417160034,0l0,-1.6410398483276367l-1.5230199694633484,-2.3182506561279297l0.5900999903678894,0l1.205489993095398,1.8855104446411133l1.1998701095581055,-1.8855104446411133l0.5900998115539551,0Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"Y\",\r\n    kerningRules: {\r\n      \"v\": getGridUnitKerningRule(113),\r\n      \"u\": getGridUnitKerningRule(113),\r\n      \"ù\": getGridUnitKerningRule(113),\r\n      \"ú\": getGridUnitKerningRule(113),\r\n      \"û\": getGridUnitKerningRule(113),\r\n      \"ü\": getGridUnitKerningRule(113),\r\n      \"ū\": getGridUnitKerningRule(113),\r\n      \"ű\": getGridUnitKerningRule(113),\r\n      \"ų\": getGridUnitKerningRule(113),\r\n      \"q\": getGridUnitKerningRule(188),\r\n      \"p\": getGridUnitKerningRule(152),\r\n      \"o\": getGridUnitKerningRule(188),\r\n      \"ò\": getGridUnitKerningRule(188),\r\n      \"ó\": getGridUnitKerningRule(188),\r\n      \"ô\": getGridUnitKerningRule(188),\r\n      \"õ\": getGridUnitKerningRule(188),\r\n      \"ö\": getGridUnitKerningRule(188),\r\n      \"ø\": getGridUnitKerningRule(188),\r\n      \"ō\": getGridUnitKerningRule(188),\r\n      \"ő\": getGridUnitKerningRule(188),\r\n      \"i\": getGridUnitKerningRule(76),\r\n      \"ì\": getGridUnitKerningRule(76),\r\n      \"í\": getGridUnitKerningRule(76),\r\n      \"î\": getGridUnitKerningRule(76),\r\n      \"ï\": getGridUnitKerningRule(76),\r\n      \"ī\": getGridUnitKerningRule(76),\r\n      \"į\": getGridUnitKerningRule(76),\r\n      \"e\": getGridUnitKerningRule(188),\r\n      \"è\": getGridUnitKerningRule(188),\r\n      \"é\": getGridUnitKerningRule(188),\r\n      \"ê\": getGridUnitKerningRule(188),\r\n      \"ë\": getGridUnitKerningRule(188),\r\n      \"ē\": getGridUnitKerningRule(188),\r\n      \"ė\": getGridUnitKerningRule(188),\r\n      \"ę\": getGridUnitKerningRule(188),\r\n      \"a\": getGridUnitKerningRule(152),\r\n      \"à\": getGridUnitKerningRule(152),\r\n      \"á\": getGridUnitKerningRule(152),\r\n      \"â\": getGridUnitKerningRule(152),\r\n      \"ã\": getGridUnitKerningRule(152),\r\n      \"ä\": getGridUnitKerningRule(152),\r\n      \"å\": getGridUnitKerningRule(152),\r\n      \"ā\": getGridUnitKerningRule(152),\r\n      \"ą\": getGridUnitKerningRule(152),\r\n      \"æ\": getGridUnitKerningRule(152),\r\n      \"A\": getGridUnitKerningRule(152),\r\n      \"À\": getGridUnitKerningRule(152),\r\n      \"Á\": getGridUnitKerningRule(152),\r\n      \"Â\": getGridUnitKerningRule(152),\r\n      \"Ã\": getGridUnitKerningRule(152),\r\n      \"Ä\": getGridUnitKerningRule(152),\r\n      \"Å\": getGridUnitKerningRule(152),\r\n      \"Ā\": getGridUnitKerningRule(152),\r\n      \"Ą\": getGridUnitKerningRule(152),\r\n      \"Æ\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'XZ': {\r\n    getPath: () => precision(`M3.335469961166382,15.988900184631348l-3.152819961309433,0l0,-0.40182971954345703l2.410980075597763,-3.119100570678711l-2.205850064754486,0l0,-0.43836021423339844l2.8156198859214783,0l0,0.3905906677246094l-2.4109798669815063,3.1303396224975586l2.543049931526184,0l0,0.43836021423339844Z`),\r\n    get width() { return getGridUnitWidth(1251); },\r\n    height: 15.99,\r\n    char: \"Z\"\r\n  },\r\n  'XÅ': {\r\n    getPath: () => precision(`M3.2792699337005615,15.988900184631348l-0.4524099826812744,-1.1577205657958984l-1.8040199279785156,0l-0.4552200436592102,1.1577205657958984l-0.5563799794763327,0l1.6157499607652426,-3.9592905044555664l0.6097699403762817,0l1.5904600620269775,3.9592905044555664l-0.547950029373169,0ZM1.9248499870300293,12.434249877929688l-0.02529001235961914,0.07868003845214844q-0.07024991512298584,0.2332296371459961,-0.2079399824142456,0.5985298156738281l-0.5058000087738037,1.301030158996582l1.4808701276779175,0l-0.5086100101470947,-1.306650161743164q-0.07868003845214844,-0.19388961791992188,-0.15736007690429688,-0.43835926055908203ZM2.607680082321167,11.64463996887207q0,0.28100013732910156,-0.1995100975036621,0.48050975799560547t-0.48050999641418457,0.1995105743408203t-0.48050999641418457,-0.1995105743408203t-0.19950997829437256,-0.48050975799560547q0,-0.2838096618652344,0.19950997829437256,-0.48050975799560547t0.48050999641418457,-0.1967000961303711q0.27818989753723145,0,0.47910499572753906,0.1981048583984375t0.20091509819030762,0.47910499572753906ZM2.3041999340057373,11.64463996887207q0,-0.15736007690429688,-0.10958981513977051,-0.2669496536254883t-0.2669501304626465,-0.10959053039550781q-0.16016995906829834,0,-0.26976001262664795,0.10959053039550781t-0.10958993434906006,0.2669496536254883q0,0.15454959869384766,0.10677993297576904,0.2697601318359375t0.27257001399993896,0.11520957946777344q0.1629800796508789,0,0.2697598934173584,-0.11380481719970703t0.1067800521850586,-0.2711648941040039Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"Å\",\r\n    kerningRules: {\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"T\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'XÄ': {\r\n    getPath: () => precision(`M3.2792699337005615,15.988900184631348l-0.4524099826812744,-1.1577205657958984l-1.8040199279785156,0l-0.4552200436592102,1.1577205657958984l-0.5563799794763327,0l1.6157499607652426,-3.9592905044555664l0.6097699403762817,0l1.5904600620269775,3.9592905044555664l-0.547950029373169,0ZM1.9248499870300293,12.434249877929688l-0.02529001235961914,0.07868003845214844q-0.07024991512298584,0.2332296371459961,-0.2079399824142456,0.5985298156738281l-0.5058000087738037,1.301030158996582l1.4808701276779175,0l-0.5086100101470947,-1.306650161743164q-0.07868003845214844,-0.19388961791992188,-0.15736007690429688,-0.43835926055908203ZM2.25642991065979,11.689599990844727l0,-0.5170402526855469l0.45802998542785645,0l0,0.5170402526855469l-0.45802998542785645,0ZM1.1492899656295776,11.689599990844727l0,-0.5170402526855469l0.4636499881744385,0l0,0.5170402526855469l-0.4636499881744385,0Z`),\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 15.99,\r\n    char: \"Ä\",\r\n    kerningRules: {\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"T\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'XÖ': {\r\n    getPath: () => precision(`M4.2009501457214355,13.990989685058594q0,0.6210107803344727,-0.23744511604309082,1.0874700546264648t-0.6814250946044922,0.7165498733520508t-1.0481300354003906,0.2500896453857422q-0.6097699403762817,0,-1.0523449182510376,-0.24727916717529297t-0.6758049726486206,-0.7151451110839844t-0.23322999477386475,-1.0916852951049805q0,-0.9497795104980469,0.5198500156402588,-1.4850845336914062t1.4471498727798462,-0.5353050231933594q0.6041500568389893,0,1.0481300354003906,0.24025440216064453t0.6786150932312012,0.6982851028442383t0.2346351146697998,1.0818500518798828ZM3.6530001163482666,13.990989685058594q0,-0.7390298843383789,-0.36951518058776855,-1.1605300903320312t-1.043915033340454,-0.42149925231933594q-0.6800198554992676,0,-1.050939917564392,0.4158792495727539t-0.37092000246047974,1.1661500930786133q0,0.7446498870849609,0.37513500452041626,1.181605339050293t1.0411049127578735,0.43695545196533203q0.6856400966644287,0,1.0523450374603271,-0.42290592193603516t0.36670517921447754,-1.1956548690795898ZM2.5571000576019287,11.689599990844727l0,-0.5170402526855469l0.45802998542785645,0l0,0.5170402526855469l-0.45802998542785645,0ZM1.4499599933624268,11.689599990844727l0,-0.5170402526855469l0.4636499881744385,0l0,0.5170402526855469l-0.4636499881744385,0Z`),\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16.05,\r\n    char: \"Ö\"\r\n  },\r\n  // Kerning inherited from 'A'\r\n  'XÀ': {\r\n    getPath: () => `M3.2781,16l-0.4522,-1.1573h-1.8034l-0.4551,1.1573h-0.5562l1.6152,-3.9579h0.6096l1.5899,3.9579h-0.5478zM1.9242,12.4466l-0.0253,0.0787q-0.0702,0.2331,-0.2079,0.5983l-0.5056,1.3006h1.4803l-0.5084,-1.3062q-0.0787,-0.1938,-0.1573,-0.4382zM2.1067,11.7022l-0.8708,-0.6096v-0.0815h0.5815l0.6096,0.6348v0.0562h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"À\",\r\n    kerningRules: {\r\n      \"T\": getGridUnitKerningRule(152),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  // Kerning inherited from 'A'\r\n  'XÁ': {\r\n    getPath: () => `M3.2781,16l-0.4522,-1.1573h-1.8034l-0.4551,1.1573h-0.5562l1.6152,-3.9579h0.6096l1.5899,3.9579h-0.5478zM1.9242,12.4466l-0.0253,0.0787q-0.0702,0.2331,-0.2079,0.5983l-0.5056,1.3006h1.4803l-0.5084,-1.3062q-0.0787,-0.1938,-0.1573,-0.4382zM1.5365,11.7022v-0.0562l0.6096,-0.6348h0.5815v0.0815l-0.8708,0.6096h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Á\",\r\n    kerningRules: {\r\n      \"T\": getGridUnitKerningRule(152),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  // Kerning inherited from 'A'\r\n  'XÂ': {\r\n    getPath: () => `M3.2781,16l-0.4522,-1.1573h-1.8034l-0.4551,1.1573h-0.5562l1.6152,-3.9579h0.6096l1.5899,3.9579h-0.5478zM1.9242,12.4466l-0.0253,0.0787q-0.0702,0.2331,-0.2079,0.5983l-0.5056,1.3006h1.4803l-0.5084,-1.3062q-0.0787,-0.1938,-0.1573,-0.4382zM2.8483,11.6461v0.0562h-0.2949l-0.6152,-0.3904h-0.0056l-0.6517,0.3904h-0.2921v-0.0562l0.6573,-0.6742h0.573z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Â\",\r\n    kerningRules: {\r\n      \"T\": getGridUnitKerningRule(152),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  // Kerning inherited from 'A'\r\n  'XÃ': {\r\n    getPath: () => `M3.2781,16l-0.4522,-1.1573h-1.8034l-0.4551,1.1573h-0.5562l1.6152,-3.9579h0.6096l1.5899,3.9579h-0.5478zM1.9242,12.4466l-0.0253,0.0787q-0.0702,0.2331,-0.2079,0.5983l-0.5056,1.3006h1.4803l-0.5084,-1.3062q-0.0787,-0.1938,-0.1573,-0.4382zM2.3652,11.7022q-0.118,0,-0.236,-0.052t-0.2275,-0.1152t-0.2093,-0.1152t-0.1868,-0.052q-0.1545,0,-0.2303,0.0871t-0.1011,0.2472h-0.2556q0.0309,-0.2865,0.0983,-0.434t0.1812,-0.2331t0.2907,-0.0857q0.1236,0,0.2416,0.052t0.2275,0.1152t0.2065,0.1152t0.1812,0.052q0.2809,0,0.3287,-0.3343h0.2584q-0.0478,0.4157,-0.1882,0.5843t-0.3792,0.1685z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ã\",\r\n    kerningRules: {\r\n      \"T\": getGridUnitKerningRule(152),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  // Kerning inherited from 'A'\r\n  'XÆ': {\r\n    getPath: () => `M2.7219,16v-1.1573h-1.5393l-0.5562,1.1573h-0.559l1.927,-3.9579h3.3961v0.4382h-2.132v1.2697h1.9635v0.4326h-1.9635v1.3792h2.2472v0.4382h-2.7837zM2.7219,12.4551h-0.4242l-0.0787,0.177l-0.8399,1.7921h1.3427v-1.9691z`,\r\n    get width() { return getGridUnitWidth(2048); },\r\n    height: 16,\r\n    char: \"Æ\",\r\n    kerningRules: {\r\n      \"T\": getGridUnitKerningRule(152),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'XÇ': {\r\n    getPath: () => `M2.2247,12.4213q-0.6573,0,-1.0225,0.4228t-0.3652,1.1587q0,0.7275,0.3806,1.1699t1.0295,0.4424q0.8315,0,1.25,-0.823l0.4382,0.2191q-0.2444,0.5112,-0.6868,0.7781t-1.0267,0.2669q-0.5983,0,-1.0351,-0.2486t-0.6657,-0.7107t-0.2289,-1.0941q0,-0.9466,0.5112,-1.4831t1.4157,-0.5365q0.632,0,1.0562,0.2472t0.6236,0.7331l-0.5084,0.1685q-0.1376,-0.3455,-0.4424,-0.5281t-0.7233,-0.1826zM2.7893,16.7107q0,0.5084,-0.7697,0.5084q-0.1601,0,-0.2528,-0.0112v-0.2753q0.1376,0.0169,0.2416,0.0169q0.4129,0,0.4129,-0.2275q0,-0.2163,-0.3736,-0.2163q-0.1208,0,-0.1601,0.0056l0.1826,-0.5112h0.3006l-0.1096,0.2809q0.264,0.0084,0.3961,0.1222t0.132,0.3076z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ç\"\r\n  },\r\n  'XÈ': {\r\n    getPath: () => `M0.4719,16v-3.9579h3.0028v0.4382h-2.4663v1.2697h2.2978v0.4326h-2.2978v1.3792h2.5815v0.4382h-3.118zM2.0646,11.7022l-0.8708,-0.6096v-0.0815h0.5815l0.6096,0.6348v0.0562h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"È\"\r\n  },\r\n  'XÉ': {\r\n    getPath: () => `M0.4719,16v-3.9579h3.0028v0.4382h-2.4663v1.2697h2.2978v0.4326h-2.2978v1.3792h2.5815v0.4382h-3.118zM1.5478,11.7022v-0.0562l0.6096,-0.6348h0.5815v0.0815l-0.8708,0.6096h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"É\"\r\n  },\r\n  'XÊ': {\r\n    getPath: () => `M0.4719,16v-3.9579h3.0028v0.4382h-2.4663v1.2697h2.2978v0.4326h-2.2978v1.3792h2.5815v0.4382h-3.118zM2.9129,11.6461v0.0562h-0.2949l-0.6152,-0.3904h-0.0056l-0.6517,0.3904h-0.2921v-0.0562l0.6573,-0.6742h0.573z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ê\"\r\n  },\r\n  'XË': {\r\n    getPath: () => `M0.4719,16v-3.9579h3.0028v0.4382h-2.4663v1.2697h2.2978v0.4326h-2.2978v1.3792h2.5815v0.4382h-3.118zM2.2921,11.7022v-0.5169h0.4579v0.5169h-0.4579zM1.1854,11.7022v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ë\"\r\n  },\r\n  'XÌ': {\r\n    getPath: () => `M0.5309,16v-3.9579h0.5365v3.9579h-0.5365zM0.8961,11.7022l-0.8708,-0.6096v-0.0815h0.5815l0.6096,0.6348v0.0562h-0.3202z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"Ì\"\r\n  },\r\n  'XÍ': {\r\n    getPath: () => `M0.5309,16v-3.9579h0.5365v3.9579h-0.5365zM0.3989,11.7022v-0.0562l0.6096,-0.6348h0.5815v0.0815l-0.8708,0.6096h-0.3202z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"Í\"\r\n  },\r\n  'XÎ': {\r\n    getPath: () => `M0.5309,16v-3.9579h0.5365v3.9579h-0.5365zM1.7303,11.6461v0.0562h-0.2949l-0.6152,-0.3904h-0.0056l-0.6517,0.3904h-0.2921v-0.0562l0.6573,-0.6742h0.573z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"Î\"\r\n  },\r\n  'XÏ': {\r\n    getPath: () => `M0.5309,16v-3.9579h0.5365v3.9579h-0.5365zM1.1264,11.7022v-0.5169h0.4579v0.5169h-0.4579zM0.0197,11.7022v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"Ï\"\r\n  },\r\n  'XÐ': {\r\n    getPath: () => `M0.0393,13.75h0.4326v-1.7079h1.309q1.0056,0,1.552,0.5042t0.5463,1.434q0,0.6124,-0.2388,1.0716t-0.677,0.7037t-1.0112,0.2444h-1.4803v-1.8174h-0.4326v-0.4326zM3.3399,13.9803q0,-0.736,-0.4031,-1.1222t-1.1671,-0.3862h-0.7612v1.2781h1.1404v0.4326h-1.1404v1.3876h0.882q0.4354,0,0.7654,-0.191t0.507,-0.5506t0.177,-0.8483z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ð\"\r\n  },\r\n  'XÑ': {\r\n    getPath: () => `M3.0393,16l-2.118,-3.3708l0.014,0.2725l0.014,0.4691v2.6292h-0.4775v-3.9579h0.6236l2.1404,3.3933q-0.0337,-0.5506,-0.0337,-0.7978v-2.5955h0.4831v3.9579h-0.6461zM2.5534,11.7022q-0.118,0,-0.236,-0.052t-0.2275,-0.1152t-0.2093,-0.1152t-0.1868,-0.052q-0.1545,0,-0.2303,0.0871t-0.1011,0.2472h-0.2556q0.0309,-0.2865,0.0983,-0.434t0.1812,-0.2331t0.2907,-0.0857q0.1236,0,0.2416,0.052t0.2275,0.1152t0.2065,0.1152t0.1812,0.052q0.2809,0,0.3287,-0.3343h0.2584q-0.0478,0.4157,-0.1882,0.5843t-0.3792,0.1685z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ñ\"\r\n  },\r\n  'XÒ': {\r\n    getPath: () => `M4.1994,14.0028q0,0.6208,-0.2374,1.0871t-0.6812,0.7163t-1.0478,0.25q-0.6096,0,-1.052,-0.2472t-0.6756,-0.7149t-0.2331,-1.0913q0,-0.9494,0.5197,-1.4846t1.4466,-0.5351q0.6039,0,1.0478,0.2402t0.6784,0.698t0.2346,1.0815zM3.6517,14.0028q0,-0.7388,-0.3694,-1.1601t-1.0435,-0.4213q-0.6798,0,-1.0506,0.4157t-0.3708,1.1657q0,0.7444,0.375,1.1812t1.0407,0.4368q0.6854,0,1.052,-0.4228t0.3666,-1.1952zM2.3989,11.7022l-0.8708,-0.6096v-0.0815h0.5815l0.6096,0.6348v0.0562h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16,\r\n    char: \"Ò\"\r\n  },\r\n  'XÓ': {\r\n    getPath: () => `M4.1994,14.0028q0,0.6208,-0.2374,1.0871t-0.6812,0.7163t-1.0478,0.25q-0.6096,0,-1.052,-0.2472t-0.6756,-0.7149t-0.2331,-1.0913q0,-0.9494,0.5197,-1.4846t1.4466,-0.5351q0.6039,0,1.0478,0.2402t0.6784,0.698t0.2346,1.0815zM3.6517,14.0028q0,-0.7388,-0.3694,-1.1601t-1.0435,-0.4213q-0.6798,0,-1.0506,0.4157t-0.3708,1.1657q0,0.7444,0.375,1.1812t1.0407,0.4368q0.6854,0,1.052,-0.4228t0.3666,-1.1952zM1.7444,11.7022v-0.0562l0.6096,-0.6348h0.5815v0.0815l-0.8708,0.6096h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16,\r\n    char: \"Ó\"\r\n  },\r\n  'XÔ': {\r\n    getPath: () => `M4.1994,14.0028q0,0.6208,-0.2374,1.0871t-0.6812,0.7163t-1.0478,0.25q-0.6096,0,-1.052,-0.2472t-0.6756,-0.7149t-0.2331,-1.0913q0,-0.9494,0.5197,-1.4846t1.4466,-0.5351q0.6039,0,1.0478,0.2402t0.6784,0.698t0.2346,1.0815zM3.6517,14.0028q0,-0.7388,-0.3694,-1.1601t-1.0435,-0.4213q-0.6798,0,-1.0506,0.4157t-0.3708,1.1657q0,0.7444,0.375,1.1812t1.0407,0.4368q0.6854,0,1.052,-0.4228t0.3666,-1.1952zM3.177,11.6461v0.0562h-0.2949l-0.6152,-0.3904h-0.0056l-0.6517,0.3904h-0.2921v-0.0562l0.6573,-0.6742h0.573z`,\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16,\r\n    char: \"Ô\"\r\n  },\r\n  'XÕ': {\r\n    getPath: () => `M4.1994,14.0028q0,0.6208,-0.2374,1.0871t-0.6812,0.7163t-1.0478,0.25q-0.6096,0,-1.052,-0.2472t-0.6756,-0.7149t-0.2331,-1.0913q0,-0.9494,0.5197,-1.4846t1.4466,-0.5351q0.6039,0,1.0478,0.2402t0.6784,0.698t0.2346,1.0815zM3.6517,14.0028q0,-0.7388,-0.3694,-1.1601t-1.0435,-0.4213q-0.6798,0,-1.0506,0.4157t-0.3708,1.1657q0,0.7444,0.375,1.1812t1.0407,0.4368q0.6854,0,1.052,-0.4228t0.3666,-1.1952zM2.6433,11.7022q-0.118,0,-0.236,-0.052t-0.2275,-0.1152t-0.2093,-0.1152t-0.1868,-0.052q-0.1545,0,-0.2303,0.0871t-0.1011,0.2472h-0.2556q0.0309,-0.2865,0.0983,-0.434t0.1812,-0.2331t0.2907,-0.0857q0.1236,0,0.2416,0.052t0.2275,0.1152t0.2065,0.1152t0.1812,0.052q0.2809,0,0.3287,-0.3343h0.2584q-0.0478,0.4157,-0.1882,0.5843t-0.3792,0.1685z`,\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16,\r\n    char: \"Õ\"\r\n  },\r\n  'XØ': {\r\n    getPath: () => `M4.1994,14.0028q0,0.6208,-0.2374,1.0871t-0.6812,0.7163t-1.0478,0.25q-0.691,0,-1.1629,-0.3146l-0.3371,0.4073h-0.5337l0.5618,-0.677q-0.4888,-0.5393,-0.4888,-1.4691q0,-0.9494,0.5197,-1.4846t1.4466,-0.5351q0.6938,0,1.1629,0.309l0.3399,-0.4101h0.5393l-0.5646,0.6798q0.4831,0.5337,0.4831,1.441zM3.6517,14.0028q0,-0.6292,-0.2753,-1.0337l-1.9916,2.3961q0.3427,0.2556,0.8483,0.2556q0.6854,0,1.052,-0.4228t0.3666,-1.1952zM0.8174,14.0028q0,0.6433,0.2837,1.0618l1.986,-2.3961q-0.3483,-0.2472,-0.8483,-0.2472q-0.6798,0,-1.0506,0.4157t-0.3708,1.1657z`,\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16,\r\n    char: \"Ø\"\r\n  },\r\n  'XÙ': {\r\n    getPath: () => `M2.0534,16.0562q-0.486,0,-0.8483,-0.177t-0.5618,-0.514t-0.1994,-0.8034v-2.5197h0.5365v2.4747q0,0.5421,0.2753,0.823t0.7949,0.2809q0.5337,0,0.8301,-0.2907t0.2963,-0.8497v-2.4382h0.5337v2.4691q0,0.4803,-0.2037,0.8287t-0.5758,0.5323t-0.8778,0.184zM2.2837,11.7022l-0.8708,-0.6096v-0.0815h0.5815l0.6096,0.6348v0.0562h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ù\"\r\n  },\r\n  'XÚ': {\r\n    getPath: () => `M2.0534,16.0562q-0.486,0,-0.8483,-0.177t-0.5618,-0.514t-0.1994,-0.8034v-2.5197h0.5365v2.4747q0,0.5421,0.2753,0.823t0.7949,0.2809q0.5337,0,0.8301,-0.2907t0.2963,-0.8497v-2.4382h0.5337v2.4691q0,0.4803,-0.2037,0.8287t-0.5758,0.5323t-0.8778,0.184zM1.5871,11.7022v-0.0562l0.6096,-0.6348h0.5815v0.0815l-0.8708,0.6096h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ú\"\r\n  },\r\n  'XÛ': {\r\n    getPath: () => `M2.0534,16.0562q-0.486,0,-0.8483,-0.177t-0.5618,-0.514t-0.1994,-0.8034v-2.5197h0.5365v2.4747q0,0.5421,0.2753,0.823t0.7949,0.2809q0.5337,0,0.8301,-0.2907t0.2963,-0.8497v-2.4382h0.5337v2.4691q0,0.4803,-0.2037,0.8287t-0.5758,0.5323t-0.8778,0.184zM3.0056,11.6461v0.0562h-0.2949l-0.6152,-0.3904h-0.0056l-0.6517,0.3904h-0.2921v-0.0562l0.6573,-0.6742h0.573z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Û\"\r\n  },\r\n  'XÜ': {\r\n    getPath: () => `M2.0534,16.0562q-0.486,0,-0.8483,-0.177t-0.5618,-0.514t-0.1994,-0.8034v-2.5197h0.5365v2.4747q0,0.5421,0.2753,0.823t0.7949,0.2809q0.5337,0,0.8301,-0.2907t0.2963,-0.8497v-2.4382h0.5337v2.4691q0,0.4803,-0.2037,0.8287t-0.5758,0.5323t-0.8778,0.184zM2.3961,11.7022v-0.5169h0.4579v0.5169h-0.4579zM1.2893,11.7022v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ü\"\r\n  },\r\n  // Kerning inherited from 'Y'\r\n  'XÝ': {\r\n    getPath: () => `M2.1826,14.3596v1.6404h-0.5337v-1.6404l-1.5225,-2.3174h0.5899l1.2051,1.8848l1.1994,-1.8848h0.5899zM1.5056,11.7022v-0.0562l0.6096,-0.6348h0.5815v0.0815l-0.8708,0.6096h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ý\",\r\n    kerningRules: {\r\n      \"a\": getGridUnitKerningRule(152),\r\n      \"A\": getGridUnitKerningRule(152),\r\n      \"e\": getGridUnitKerningRule(188),\r\n      \"i\": getGridUnitKerningRule(76),\r\n      \"o\": getGridUnitKerningRule(188),\r\n      \"p\": getGridUnitKerningRule(152),\r\n      \"q\": getGridUnitKerningRule(188),\r\n      \"u\": getGridUnitKerningRule(113),\r\n      \"v\": getGridUnitKerningRule(113)\r\n    }\r\n  },\r\n  // Kerning inherited from 'T'\r\n  'XÞ': {\r\n    getPath: () => `M3.5337,13.9354q0,0.3596,-0.1629,0.639t-0.4705,0.4354t-0.7289,0.1559h-1.1629v0.8343h-0.5365v-3.9579h0.5365v0.7079h1.1292q0.6713,0,1.0337,0.3118t0.3624,0.8736zM2.9944,13.9466q0,-0.3764,-0.2303,-0.5857t-0.691,-0.2093h-1.0646v1.618h1.0871q0.4298,0,0.6643,-0.2177t0.2346,-0.6053z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Þ\",\r\n    kerningRules: {\r\n      \"a\": getGridUnitKerningRule(227),\r\n      \"A\": getGridUnitKerningRule(152),\r\n      \"c\": getGridUnitKerningRule(227),\r\n      \"e\": getGridUnitKerningRule(227),\r\n      \"i\": getGridUnitKerningRule(76),\r\n      \"o\": getGridUnitKerningRule(227),\r\n      \"O\": getGridUnitKerningRule(37),\r\n      \"r\": getGridUnitKerningRule(76),\r\n      \"s\": getGridUnitKerningRule(227),\r\n      \"u\": getGridUnitKerningRule(76),\r\n      \"w\": getGridUnitKerningRule(113),\r\n      \"y\": getGridUnitKerningRule(113)\r\n    }\r\n  },\r\n  'Xß': {\r\n    getPath: () => `M3.2781,15.1713q0,0.4213,-0.264,0.6531t-0.7416,0.2317q-0.4803,0,-0.7949,-0.1376l-0.0056,-0.4607q0.1461,0.0815,0.3708,0.1376t0.4185,0.0562q0.2584,0,0.3961,-0.1208t0.1376,-0.3427q0,-0.1798,-0.1194,-0.323t-0.3919,-0.3062q-0.2584,-0.1517,-0.3862,-0.3371t-0.1278,-0.427q0,-0.1713,0.0801,-0.3118t0.2317,-0.2669q0.1629,-0.1348,0.2374,-0.2528t0.0744,-0.2584q0,-0.2163,-0.1882,-0.3469t-0.4944,-0.1306q-0.4157,0,-0.611,0.2247t-0.1952,0.6798v2.868h-0.5056v-2.8848q0,-0.6376,0.3301,-0.9607t0.9817,-0.323q0.5337,0,0.8497,0.2261t0.316,0.6081q0,0.4017,-0.3174,0.691q-0.2219,0.2022,-0.2697,0.2711t-0.0478,0.1503q0,0.1067,0.0772,0.1896t0.1924,0.1629t0.25,0.1699q0.5169,0.3483,0.5169,0.8708z`,\r\n    get width() { return getGridUnitWidth(1251); },\r\n    height: 16,\r\n    char: \"ß\"\r\n  },\r\n  'Xà': {\r\n    getPath: () => `M1.1629,16.0562q-0.4579,0,-0.6882,-0.2416t-0.2303,-0.6629q0,-0.4719,0.3104,-0.7247t1.0014,-0.2697l0.6826,-0.0112v-0.1657q0,-0.3708,-0.1573,-0.5309t-0.4944,-0.1601q-0.3399,0,-0.4944,0.1152t-0.1854,0.368l-0.5281,-0.0478q0.1292,-0.8202,1.2191,-0.8202q0.573,0,0.8624,0.2626t0.2893,0.7598v1.309q0,0.2247,0.059,0.3385t0.2247,0.1138q0.073,0,0.1657,-0.0197v0.3146q-0.191,0.0449,-0.3904,0.0449q-0.2809,0,-0.4087,-0.1475t-0.1447,-0.4621h-0.0169q-0.1938,0.3483,-0.4508,0.493t-0.625,0.1447zM1.2781,15.677q0.2781,0,0.4944,-0.1264t0.3413,-0.3469t0.125,-0.4537v-0.25l-0.5534,0.0112q-0.3567,0.0056,-0.5407,0.073t-0.2823,0.2079t-0.0983,0.368q0,0.2472,0.1334,0.382t0.3806,0.1348zM1.7528,12.6264l-0.927,-0.7809v-0.0815h0.5815l0.6096,0.8062v0.0562h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"à\"\r\n  },\r\n  'Xá': {\r\n    getPath: () => `M1.1629,16.0562q-0.4579,0,-0.6882,-0.2416t-0.2303,-0.6629q0,-0.4719,0.3104,-0.7247t1.0014,-0.2697l0.6826,-0.0112v-0.1657q0,-0.3708,-0.1573,-0.5309t-0.4944,-0.1601q-0.3399,0,-0.4944,0.1152t-0.1854,0.368l-0.5281,-0.0478q0.1292,-0.8202,1.2191,-0.8202q0.573,0,0.8624,0.2626t0.2893,0.7598v1.309q0,0.2247,0.059,0.3385t0.2247,0.1138q0.073,0,0.1657,-0.0197v0.3146q-0.191,0.0449,-0.3904,0.0449q-0.2809,0,-0.4087,-0.1475t-0.1447,-0.4621h-0.0169q-0.1938,0.3483,-0.4508,0.493t-0.625,0.1447zM1.2781,15.677q0.2781,0,0.4944,-0.1264t0.3413,-0.3469t0.125,-0.4537v-0.25l-0.5534,0.0112q-0.3567,0.0056,-0.5407,0.073t-0.2823,0.2079t-0.0983,0.368q0,0.2472,0.1334,0.382t0.3806,0.1348zM1.1573,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"á\"\r\n  },\r\n  'Xâ': {\r\n    getPath: () => `M1.1629,16.0562q-0.4579,0,-0.6882,-0.2416t-0.2303,-0.6629q0,-0.4719,0.3104,-0.7247t1.0014,-0.2697l0.6826,-0.0112v-0.1657q0,-0.3708,-0.1573,-0.5309t-0.4944,-0.1601q-0.3399,0,-0.4944,0.1152t-0.1854,0.368l-0.5281,-0.0478q0.1292,-0.8202,1.2191,-0.8202q0.573,0,0.8624,0.2626t0.2893,0.7598v1.309q0,0.2247,0.059,0.3385t0.2247,0.1138q0.073,0,0.1657,-0.0197v0.3146q-0.191,0.0449,-0.3904,0.0449q-0.2809,0,-0.4087,-0.1475t-0.1447,-0.4621h-0.0169q-0.1938,0.3483,-0.4508,0.493t-0.625,0.1447zM1.2781,15.677q0.2781,0,0.4944,-0.1264t0.3413,-0.3469t0.125,-0.4537v-0.25l-0.5534,0.0112q-0.3567,0.0056,-0.5407,0.073t-0.2823,0.2079t-0.0983,0.368q0,0.2472,0.1334,0.382t0.3806,0.1348zM2.4719,12.5702v0.0562h-0.2949l-0.6152,-0.4747h-0.0056l-0.6517,0.4747h-0.2921v-0.0562l0.6573,-0.7584h0.573z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"â\"\r\n  },\r\n  'Xã': {\r\n    getPath: () => `M1.1629,16.0562q-0.4579,0,-0.6882,-0.2416t-0.2303,-0.6629q0,-0.4719,0.3104,-0.7247t1.0014,-0.2697l0.6826,-0.0112v-0.1657q0,-0.3708,-0.1573,-0.5309t-0.4944,-0.1601q-0.3399,0,-0.4944,0.1152t-0.1854,0.368l-0.5281,-0.0478q0.1292,-0.8202,1.2191,-0.8202q0.573,0,0.8624,0.2626t0.2893,0.7598v1.309q0,0.2247,0.059,0.3385t0.2247,0.1138q0.073,0,0.1657,-0.0197v0.3146q-0.191,0.0449,-0.3904,0.0449q-0.2809,0,-0.4087,-0.1475t-0.1447,-0.4621h-0.0169q-0.1938,0.3483,-0.4508,0.493t-0.625,0.1447zM1.2781,15.677q0.2781,0,0.4944,-0.1264t0.3413,-0.3469t0.125,-0.4537v-0.25l-0.5534,0.0112q-0.3567,0.0056,-0.5407,0.073t-0.2823,0.2079t-0.0983,0.368q0,0.2472,0.1334,0.382t0.3806,0.1348zM2.0702,12.6264q-0.118,0,-0.236,-0.052t-0.2275,-0.1152t-0.2093,-0.1152t-0.1868,-0.052q-0.1545,0,-0.2303,0.0871t-0.1011,0.2472h-0.2556q0.0309,-0.2865,0.0983,-0.434t0.1812,-0.2331t0.2907,-0.0857q0.1236,0,0.2416,0.052t0.2275,0.1152t0.2065,0.1152t0.1812,0.052q0.2809,0,0.3287,-0.3343h0.2584q-0.0478,0.4157,-0.1882,0.5843t-0.3792,0.1685z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ã\"\r\n  },\r\n  'Xæ': {\r\n    getPath: () => `M2.7191,14.5871v0.0478q0.0056,0.5084,0.2163,0.7753t0.6039,0.2669q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.9017,0,-1.1882,-0.7219q-0.2219,0.3933,-0.5169,0.5576t-0.7051,0.1643q-0.4691,0,-0.7065,-0.2416t-0.2374,-0.6629q0,-0.4888,0.3343,-0.736t1.014,-0.2584l0.6742,-0.0112v-0.1657q0,-0.3792,-0.1559,-0.5351t-0.4958,-0.1559q-0.3539,0,-0.5126,0.1124t-0.1952,0.3708l-0.5281,-0.0478q0.1292,-0.8202,1.2472,-0.8202q0.7022,0,0.9803,0.3904q0.3315,-0.3904,0.9719,-0.3904q1.3399,0,1.3399,1.6152v0.0674h-2.1404zM2.2079,14.5l-0.5478,0.0112q-0.3736,0.0084,-0.5716,0.0829t-0.2907,0.2163t-0.0927,0.3497q0,0.2444,0.1404,0.3806t0.4017,0.1362q0.2865,0,0.5014,-0.125t0.3371,-0.3427t0.1222,-0.4593v-0.25zM4.3371,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.3567,0,-0.5632,0.2402t-0.2233,0.6812h1.6124z`,\r\n    get width() { return getGridUnitWidth(1821); },\r\n    height: 16,\r\n    char: \"æ\"\r\n  },\r\n  'Xç': {\r\n    getPath: () => `M0.7725,14.4663q0,0.6067,0.191,0.8989t0.5758,0.2921q0.2697,0,0.4508,-0.1461t0.2233,-0.4494l0.5112,0.0337q-0.059,0.4382,-0.3736,0.6994t-0.7978,0.2612q-0.6376,0,-0.9733,-0.4031t-0.3357,-1.1756q0,-0.7669,0.3371,-1.1699t0.9663,-0.4031q0.4663,0,0.7739,0.2416t0.3862,0.6657l-0.5197,0.0393q-0.0393,-0.2528,-0.1994,-0.4017t-0.4551,-0.1489q-0.4017,0,-0.5815,0.2669t-0.1798,0.8989zM2.1096,16.7107q0,0.5084,-0.7697,0.5084q-0.1601,0,-0.2528,-0.0112v-0.2753q0.1376,0.0169,0.2416,0.0169q0.4129,0,0.4129,-0.2275q0,-0.2163,-0.3736,-0.2163q-0.1208,0,-0.1601,0.0056l0.1826,-0.5112h0.3006l-0.1096,0.2809q0.264,0.0084,0.3961,0.1222t0.132,0.3076z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"ç\"\r\n  },\r\n  'Xè': {\r\n    getPath: () => `M0.7753,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.6742,0,-1.0267,-0.4017t-0.3525,-1.1938q0,-0.7528,0.3525,-1.1545t1.007,-0.4017q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4213,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404zM1.8455,12.6264l-0.927,-0.7809v-0.0815h0.5815l0.6096,0.8062v0.0562h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"è\"\r\n  },\r\n  'Xé': {\r\n    getPath: () => `M0.7753,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.6742,0,-1.0267,-0.4017t-0.3525,-1.1938q0,-0.7528,0.3525,-1.1545t1.007,-0.4017q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4213,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404zM1.236,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"é\"\r\n  },\r\n  'Xê': {\r\n    getPath: () => `M0.7753,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.6742,0,-1.0267,-0.4017t-0.3525,-1.1938q0,-0.7528,0.3525,-1.1545t1.007,-0.4017q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4213,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404zM2.5478,12.5702v0.0562h-0.2949l-0.6152,-0.4747h-0.0056l-0.6517,0.4747h-0.2921v-0.0562l0.6573,-0.7584h0.573z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ê\"\r\n  },\r\n  'Xë': {\r\n    getPath: () => `M0.7753,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.6742,0,-1.0267,-0.4017t-0.3525,-1.1938q0,-0.7528,0.3525,-1.1545t1.007,-0.4017q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4213,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404zM1.9298,12.5758v-0.5169h0.4579v0.5169h-0.4579zM0.823,12.5758v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ë\"\r\n  },\r\n  'Xì': {\r\n    getPath: () => `M0.5449,16v-3.0393h0.5056v3.0393h-0.5056zM0.9551,12.6264l-0.927,-0.7809v-0.0815h0.5815l0.6096,0.8062v0.0562h-0.264z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"ì\"\r\n  },\r\n  'Xí': {\r\n    getPath: () => `M0.5449,16v-3.0393h0.5056v3.0393h-0.5056zM0.3792,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"í\"\r\n  },\r\n  'Xî': {\r\n    getPath: () => `M0.5449,16v-3.0393h0.5056v3.0393h-0.5056zM1.7331,12.5702v0.0562h-0.2949l-0.6152,-0.4747h-0.0056l-0.6517,0.4747h-0.2921v-0.0562l0.6573,-0.7584h0.573z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"î\"\r\n  },\r\n  'Xï': {\r\n    getPath: () => `M0.5449,16v-3.0393h0.5056v3.0393h-0.5056zM1.1292,12.5758v-0.5169h0.4579v0.5169h-0.4579zM0.0225,12.5758v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"ï\"\r\n  },\r\n  'Xð': {\r\n    getPath: () => `M1.5899,16.0562q-0.6517,0,-1,-0.3624t-0.3483,-1.0449q0,-0.6854,0.3483,-1.0421t1.0197,-0.3567q0.3848,0,0.6489,0.1657q-0.3062,-0.6096,-0.6573,-0.9298l-0.8455,0.3736v-0.3202l0.6124,-0.264q-0.3062,-0.2444,-0.6798,-0.4438h0.5871q0.2247,0.1011,0.4775,0.2865l0.8596,-0.3708l-0.0028,0.3146l-0.5927,0.2584q0.4803,0.4382,0.7247,1.0084t0.2444,1.2219v0.0169q0,0.7331,-0.3497,1.111t-1.0463,0.3778zM2.4551,14.6489q0,-0.5393,-0.198,-0.7823t-0.6362,-0.243q-0.441,0,-0.6447,0.2444t-0.2037,0.7809q0,0.5337,0.2022,0.7837t0.6096,0.25q0.4522,0,0.6615,-0.2458t0.2093,-0.7879z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ð\"\r\n  },\r\n  'Xñ': {\r\n    getPath: () => `M2.3287,16v-1.927q0,-0.3006,-0.059,-0.4663t-0.1882,-0.2388t-0.3792,-0.073q-0.3652,0,-0.5758,0.25t-0.2107,0.6938v1.7612h-0.5056v-2.3904q0,-0.5309,-0.0169,-0.6489h0.4775q0.0028,0.014,0.0056,0.0758t0.007,0.1419t0.0098,0.302h0.0084q0.1742,-0.3146,0.4031,-0.4452t0.5688,-0.1306q0.5,0,0.7317,0.2486t0.2317,0.8216v2.0253h-0.5084zM2.0702,12.6264q-0.118,0,-0.236,-0.052t-0.2275,-0.1152t-0.2093,-0.1152t-0.1868,-0.052q-0.1545,0,-0.2303,0.0871t-0.1011,0.2472h-0.2556q0.0309,-0.2865,0.0983,-0.434t0.1812,-0.2331t0.2907,-0.0857q0.1236,0,0.2416,0.052t0.2275,0.1152t0.2065,0.1152t0.1812,0.052q0.2809,0,0.3287,-0.3343h0.2584q-0.0478,0.4157,-0.1882,0.5843t-0.3792,0.1685z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ñ\"\r\n  },\r\n  'Xò': {\r\n    getPath: () => `M2.9579,14.4775q0,0.7978,-0.3511,1.1882t-1.0197,0.3904q-0.6657,0,-1.0056,-0.4059t-0.3399,-1.1728q0,-1.573,1.3624,-1.573q0.6966,0,1.0253,0.3834t0.3287,1.1896zM2.427,14.4775q0,-0.6292,-0.1868,-0.9143t-0.6278,-0.2851q-0.4438,0,-0.6419,0.2907t-0.198,0.9087q0,0.6011,0.1952,0.9031t0.6138,0.302q0.4551,0,0.6503,-0.2921t0.1952,-0.9129zM1.8511,12.6264l-0.927,-0.7809v-0.0815h0.5815l0.6096,0.8062v0.0562h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ò\"\r\n  },\r\n  'Xó': {\r\n    getPath: () => `M2.9579,14.4775q0,0.7978,-0.3511,1.1882t-1.0197,0.3904q-0.6657,0,-1.0056,-0.4059t-0.3399,-1.1728q0,-1.573,1.3624,-1.573q0.6966,0,1.0253,0.3834t0.3287,1.1896zM2.427,14.4775q0,-0.6292,-0.1868,-0.9143t-0.6278,-0.2851q-0.4438,0,-0.6419,0.2907t-0.198,0.9087q0,0.6011,0.1952,0.9031t0.6138,0.302q0.4551,0,0.6503,-0.2921t0.1952,-0.9129zM1.2107,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ó\"\r\n  },\r\n  'Xô': {\r\n    getPath: () => `M2.9579,14.4775q0,0.7978,-0.3511,1.1882t-1.0197,0.3904q-0.6657,0,-1.0056,-0.4059t-0.3399,-1.1728q0,-1.573,1.3624,-1.573q0.6966,0,1.0253,0.3834t0.3287,1.1896zM2.427,14.4775q0,-0.6292,-0.1868,-0.9143t-0.6278,-0.2851q-0.4438,0,-0.6419,0.2907t-0.198,0.9087q0,0.6011,0.1952,0.9031t0.6138,0.302q0.4551,0,0.6503,-0.2921t0.1952,-0.9129zM2.5337,12.5702v0.0562h-0.2949l-0.6152,-0.4747h-0.0056l-0.6517,0.4747h-0.2921v-0.0562l0.6573,-0.7584h0.573z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ô\"\r\n  },\r\n  'Xõ': {\r\n    getPath: () => `M2.9579,14.4775q0,0.7978,-0.3511,1.1882t-1.0197,0.3904q-0.6657,0,-1.0056,-0.4059t-0.3399,-1.1728q0,-1.573,1.3624,-1.573q0.6966,0,1.0253,0.3834t0.3287,1.1896zM2.427,14.4775q0,-0.6292,-0.1868,-0.9143t-0.6278,-0.2851q-0.4438,0,-0.6419,0.2907t-0.198,0.9087q0,0.6011,0.1952,0.9031t0.6138,0.302q0.4551,0,0.6503,-0.2921t0.1952,-0.9129zM2.0758,12.6264q-0.118,0,-0.236,-0.052t-0.2275,-0.1152t-0.2093,-0.1152t-0.1868,-0.052q-0.1545,0,-0.2303,0.0871t-0.1011,0.2472h-0.2556q0.0309,-0.2865,0.0983,-0.434t0.1812,-0.2331t0.2907,-0.0857q0.1236,0,0.2416,0.052t0.2275,0.1152t0.2065,0.1152t0.1812,0.052q0.2809,0,0.3287,-0.3343h0.2584q-0.0478,0.4157,-0.1882,0.5843t-0.3792,0.1685z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"õ\"\r\n  },\r\n  'Xø': {\r\n    getPath: () => `M3.1236,14.4775q0,0.7978,-0.3511,1.1882t-1.0197,0.3904q-0.5478,0,-0.8792,-0.2753l-0.2809,0.3258h-0.4691l0.5169,-0.6011q-0.2331,-0.3876,-0.2331,-1.0281q0,-1.573,1.3624,-1.573q0.5646,0,0.8876,0.2556l0.2556,-0.2949h0.4691l-0.486,0.5646q0.2275,0.3736,0.2275,1.0478zM2.5927,14.4775q0,-0.3624,-0.0646,-0.6208l-1.3567,1.5787q0.191,0.2472,0.5758,0.2472q0.4551,0,0.6503,-0.2921t0.1952,-0.9129zM0.9382,14.4775q0,0.3652,0.0674,0.6039l1.3539,-1.5758q-0.1882,-0.2275,-0.5815,-0.2275q-0.4438,0,-0.6419,0.2907t-0.198,0.9087z`,\r\n    get width() { return getGridUnitWidth(1251); },\r\n    height: 16,\r\n    char: \"ø\"\r\n  },\r\n  'Xù': {\r\n    getPath: () => `M0.8989,12.9607v1.927q0,0.3006,0.059,0.4663t0.1882,0.2388t0.3792,0.073q0.3652,0,0.5758,-0.25t0.2107,-0.6938v-1.7612h0.5056v2.3904q0,0.5309,0.0169,0.6489h-0.4775q-0.0028,-0.014,-0.0056,-0.0758t-0.007,-0.1419t-0.0098,-0.302h-0.0084q-0.1742,0.3146,-0.4031,0.4452t-0.5688,0.1306q-0.5,0,-0.7317,-0.2486t-0.2317,-0.8216v-2.0253h0.5084zM1.8876,12.6264l-0.927,-0.7809v-0.0815h0.5815l0.6096,0.8062v0.0562h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ù\"\r\n  },\r\n  'Xú': {\r\n    getPath: () => `M0.8989,12.9607v1.927q0,0.3006,0.059,0.4663t0.1882,0.2388t0.3792,0.073q0.3652,0,0.5758,-0.25t0.2107,-0.6938v-1.7612h0.5056v2.3904q0,0.5309,0.0169,0.6489h-0.4775q-0.0028,-0.014,-0.0056,-0.0758t-0.007,-0.1419t-0.0098,-0.302h-0.0084q-0.1742,0.3146,-0.4031,0.4452t-0.5688,0.1306q-0.5,0,-0.7317,-0.2486t-0.2317,-0.8216v-2.0253h0.5084zM1.1657,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ú\"\r\n  },\r\n  'Xû': {\r\n    getPath: () => `M0.8989,12.9607v1.927q0,0.3006,0.059,0.4663t0.1882,0.2388t0.3792,0.073q0.3652,0,0.5758,-0.25t0.2107,-0.6938v-1.7612h0.5056v2.3904q0,0.5309,0.0169,0.6489h-0.4775q-0.0028,-0.014,-0.0056,-0.0758t-0.007,-0.1419t-0.0098,-0.302h-0.0084q-0.1742,0.3146,-0.4031,0.4452t-0.5688,0.1306q-0.5,0,-0.7317,-0.2486t-0.2317,-0.8216v-2.0253h0.5084zM2.5309,12.5702v0.0562h-0.2949l-0.6152,-0.4747h-0.0056l-0.6517,0.4747h-0.2921v-0.0562l0.6573,-0.7584h0.573z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"û\"\r\n  },\r\n  'Xü': {\r\n    getPath: () => `M0.8989,12.9607v1.927q0,0.3006,0.059,0.4663t0.1882,0.2388t0.3792,0.073q0.3652,0,0.5758,-0.25t0.2107,-0.6938v-1.7612h0.5056v2.3904q0,0.5309,0.0169,0.6489h-0.4775q-0.0028,-0.014,-0.0056,-0.0758t-0.007,-0.1419t-0.0098,-0.302h-0.0084q-0.1742,0.3146,-0.4031,0.4452t-0.5688,0.1306q-0.5,0,-0.7317,-0.2486t-0.2317,-0.8216v-2.0253h0.5084zM1.8989,12.5758v-0.5169h0.4579v0.5169h-0.4579zM0.7921,12.5758v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ü\"\r\n  },\r\n  'Xý': {\r\n    getPath: () => `M0.5365,17.1938q-0.2079,0,-0.3483,-0.0309v-0.3792q0.1067,0.0169,0.236,0.0169q0.4719,0,0.7472,-0.6938l0.0478,-0.1208l-1.2051,-3.0253h0.5393l0.6404,1.6798q0.014,0.0393,0.0337,0.0941t0.1264,0.3666t0.1152,0.3483l0.1966,-0.5534l0.6657,-1.9354h0.5337l-1.1685,3.0393q-0.1882,0.486,-0.3511,0.7233t-0.361,0.3539t-0.448,0.1166zM0.9972,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"ý\"\r\n  },\r\n  'Xþ': {\r\n    getPath: () => `M0.3876,11.8315h0.5056v1.1882q0,0.1826,-0.0112,0.4298h0.0169q0.1348,-0.2809,0.3567,-0.4115t0.5843,-0.1306q0.5618,0,0.8399,0.3764t0.2781,1.1826q0,1.5899,-1.118,1.5899q-0.7022,0,-0.9438,-0.5281h-0.014q0.0112,0.0225,0.0112,0.4775v1.1882h-0.5056v-5.3624zM2.427,14.4775q0,-0.6348,-0.1713,-0.9073t-0.5449,-0.2725q-0.3006,0,-0.4705,0.1264t-0.2584,0.3947t-0.0885,0.698q0,0.5983,0.191,0.882t0.6208,0.2837q0.3764,0,0.5492,-0.2767t0.1728,-0.9284z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"þ\"\r\n  },\r\n  'Xÿ': {\r\n    getPath: () => `M0.5365,17.1938q-0.2079,0,-0.3483,-0.0309v-0.3792q0.1067,0.0169,0.236,0.0169q0.4719,0,0.7472,-0.6938l0.0478,-0.1208l-1.2051,-3.0253h0.5393l0.6404,1.6798q0.014,0.0393,0.0337,0.0941t0.1264,0.3666t0.1152,0.3483l0.1966,-0.5534l0.6657,-1.9354h0.5337l-1.1685,3.0393q-0.1882,0.486,-0.3511,0.7233t-0.361,0.3539t-0.448,0.1166zM1.7584,12.5758v-0.5169h0.4579v0.5169h-0.4579zM0.6517,12.5758v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"ÿ\"\r\n  },\r\n  // Kerning inherited from 'A'\r\n  'XĀ': {\r\n    getPath: () => `M3.2781,16l-0.4522,-1.1573h-1.8034l-0.4551,1.1573h-0.5562l1.6152,-3.9579h0.6096l1.5899,3.9579h-0.5478zM1.9242,12.4466l-0.0253,0.0787q-0.0702,0.2331,-0.2079,0.5983l-0.5056,1.3006h1.4803l-0.5084,-1.3062q-0.0787,-0.1938,-0.1573,-0.4382zM2.6966,11.6039h-1.5421v-0.3567h1.5421v0.3567z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ā\",\r\n    kerningRules: {\r\n      \"T\": getGridUnitKerningRule(152),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'Xā': {\r\n    getPath: () => `M1.1629,16.0562q-0.4579,0,-0.6882,-0.2416t-0.2303,-0.6629q0,-0.4719,0.3104,-0.7247t1.0014,-0.2697l0.6826,-0.0112v-0.1657q0,-0.3708,-0.1573,-0.5309t-0.4944,-0.1601q-0.3399,0,-0.4944,0.1152t-0.1854,0.368l-0.5281,-0.0478q0.1292,-0.8202,1.2191,-0.8202q0.573,0,0.8624,0.2626t0.2893,0.7598v1.309q0,0.2247,0.059,0.3385t0.2247,0.1138q0.073,0,0.1657,-0.0197v0.3146q-0.191,0.0449,-0.3904,0.0449q-0.2809,0,-0.4087,-0.1475t-0.1447,-0.4621h-0.0169q-0.1938,0.3483,-0.4508,0.493t-0.625,0.1447zM1.2781,15.677q0.2781,0,0.4944,-0.1264t0.3413,-0.3469t0.125,-0.4537v-0.25l-0.5534,0.0112q-0.3567,0.0056,-0.5407,0.073t-0.2823,0.2079t-0.0983,0.368q0,0.2472,0.1334,0.382t0.3806,0.1348zM2.3399,12.5281h-1.5421v-0.3567h1.5421v0.3567z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ā\"\r\n  },\r\n  // Kerning inherited from 'A'\r\n  'XĄ': {\r\n    getPath: () => `M3.2781,16l-0.4522,-1.1573h-1.8034l-0.4551,1.1573h-0.5562l1.6152,-3.9579h0.6096l1.5899,3.9579h-0.5478zM1.9242,12.4466l-0.0253,0.0787q-0.0702,0.2331,-0.2079,0.5983l-0.5056,1.3006h1.4803l-0.5084,-1.3062q-0.0787,-0.1938,-0.1573,-0.4382zM3.8736,17.0927q-0.177,0.0758,-0.3904,0.0758q-0.2949,0,-0.4438,-0.1433t-0.1489,-0.382q0,-0.1966,0.1222,-0.382t0.3132,-0.2921h0.3736q-0.0702,0.0393,-0.1433,0.1025t-0.1334,0.1461t-0.0983,0.1812t-0.0379,0.2079q0,0.118,0.0688,0.1854t0.1952,0.0674q0.1517,0,0.323,-0.0674v0.3006z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ą\",\r\n    kerningRules: {\r\n      \"T\": getGridUnitKerningRule(152),\r\n      \"v\": getGridUnitKerningRule(37),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"w\": getGridUnitKerningRule(37),\r\n      \"W\": getGridUnitKerningRule(76),\r\n      \"y\": getGridUnitKerningRule(37),\r\n      \"Y\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'Xą': {\r\n    getPath: () => `M1.1629,16.0562q-0.4579,0,-0.6882,-0.2416t-0.2303,-0.6629q0,-0.4719,0.3104,-0.7247t1.0014,-0.2697l0.6826,-0.0112v-0.1657q0,-0.3708,-0.1573,-0.5309t-0.4944,-0.1601q-0.3399,0,-0.4944,0.1152t-0.1854,0.368l-0.5281,-0.0478q0.1292,-0.8202,1.2191,-0.8202q0.573,0,0.8624,0.2626t0.2893,0.7598v1.309q0,0.2247,0.059,0.3385t0.2247,0.1138q0.073,0,0.1657,-0.0197v0.3146q-0.191,0.0449,-0.3904,0.0449q-0.2809,0,-0.4087,-0.1475t-0.1447,-0.4621h-0.0169q-0.1938,0.3483,-0.4508,0.493t-0.625,0.1447zM1.2781,15.677q0.2781,0,0.4944,-0.1264t0.3413,-0.3469t0.125,-0.4537v-0.25l-0.5534,0.0112q-0.3567,0.0056,-0.5407,0.073t-0.2823,0.2079t-0.0983,0.368q0,0.2472,0.1334,0.382t0.3806,0.1348zM3.1994,17.1236q-0.177,0.0758,-0.3904,0.0758q-0.2949,0,-0.4438,-0.1433t-0.1489,-0.382q0,-0.1966,0.1222,-0.382t0.3132,-0.2921h0.3736q-0.0702,0.0393,-0.1433,0.1025t-0.1334,0.1461t-0.0983,0.1812t-0.0379,0.2079q0,0.118,0.0688,0.1854t0.1952,0.0674q0.1517,0,0.323,-0.0674v0.3006z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ą\"\r\n  },\r\n  'XĆ': {\r\n    getPath: () => `M2.2247,12.4213q-0.6573,0,-1.0225,0.4228t-0.3652,1.1587q0,0.7275,0.3806,1.1699t1.0295,0.4424q0.8315,0,1.25,-0.823l0.4382,0.2191q-0.2444,0.5112,-0.6868,0.7781t-1.0267,0.2669q-0.5983,0,-1.0351,-0.2486t-0.6657,-0.7107t-0.2289,-1.0941q0,-0.9466,0.5112,-1.4831t1.4157,-0.5365q0.632,0,1.0562,0.2472t0.6236,0.7331l-0.5084,0.1685q-0.1376,-0.3455,-0.4424,-0.5281t-0.7233,-0.1826zM1.8736,11.7022v-0.0562l0.6096,-0.6348h0.5815v0.0815l-0.8708,0.6096h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ć\"\r\n  },\r\n  'Xć': {\r\n    getPath: () => `M0.7725,14.4663q0,0.6067,0.191,0.8989t0.5758,0.2921q0.2697,0,0.4508,-0.1461t0.2233,-0.4494l0.5112,0.0337q-0.059,0.4382,-0.3736,0.6994t-0.7978,0.2612q-0.6376,0,-0.9733,-0.4031t-0.3357,-1.1756q0,-0.7669,0.3371,-1.1699t0.9663,-0.4031q0.4663,0,0.7739,0.2416t0.3862,0.6657l-0.5197,0.0393q-0.0393,-0.2528,-0.1994,-0.4017t-0.4551,-0.1489q-0.4017,0,-0.5815,0.2669t-0.1798,0.8989zM1.2107,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"ć\"\r\n  },\r\n  'XČ': {\r\n    getPath: () => `M2.2247,12.4213q-0.6573,0,-1.0225,0.4228t-0.3652,1.1587q0,0.7275,0.3806,1.1699t1.0295,0.4424q0.8315,0,1.25,-0.823l0.4382,0.2191q-0.2444,0.5112,-0.6868,0.7781t-1.0267,0.2669q-0.5983,0,-1.0351,-0.2486t-0.6657,-0.7107t-0.2289,-1.0941q0,-0.9466,0.5112,-1.4831t1.4157,-0.5365q0.632,0,1.0562,0.2472t0.6236,0.7331l-0.5084,0.1685q-0.1376,-0.3455,-0.4424,-0.5281t-0.7233,-0.1826zM2.5225,11.7022h-0.573l-0.6573,-0.6713v-0.059h0.2921l0.6517,0.3904h0.0056l0.6152,-0.3904h0.2949v0.059z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Č\"\r\n  },\r\n  'Xč': {\r\n    getPath: () => `M0.7725,14.4663q0,0.6067,0.191,0.8989t0.5758,0.2921q0.2697,0,0.4508,-0.1461t0.2233,-0.4494l0.5112,0.0337q-0.059,0.4382,-0.3736,0.6994t-0.7978,0.2612q-0.6376,0,-0.9733,-0.4031t-0.3357,-1.1756q0,-0.7669,0.3371,-1.1699t0.9663,-0.4031q0.4663,0,0.7739,0.2416t0.3862,0.6657l-0.5197,0.0393q-0.0393,-0.2528,-0.1994,-0.4017t-0.4551,-0.1489q-0.4017,0,-0.5815,0.2669t-0.1798,0.8989zM1.8315,12.6264h-0.573l-0.6573,-0.7584v-0.0562h0.2921l0.6517,0.4747h0.0056l0.6152,-0.4747h0.2949v0.0562z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"č\"\r\n  },\r\n  'XĒ': {\r\n    getPath: () => `M0.4719,16v-3.9579h3.0028v0.4382h-2.4663v1.2697h2.2978v0.4326h-2.2978v1.3792h2.5815v0.4382h-3.118zM2.7472,11.6039h-1.5421v-0.3567h1.5421v0.3567z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ē\"\r\n  },\r\n  'Xē': {\r\n    getPath: () => `M0.7753,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.6742,0,-1.0267,-0.4017t-0.3525,-1.1938q0,-0.7528,0.3525,-1.1545t1.007,-0.4017q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4213,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404zM2.3736,12.5281h-1.5421v-0.3567h1.5421v0.3567z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ē\"\r\n  },\r\n  'XĖ': {\r\n    getPath: () => `M0.4719,16v-3.9579h3.0028v0.4382h-2.4663v1.2697h2.2978v0.4326h-2.2978v1.3792h2.5815v0.4382h-3.118zM1.7219,11.4916v-0.4831h0.5056v0.4831h-0.5056z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ė\"\r\n  },\r\n  'Xė': {\r\n    getPath: () => `M0.7753,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.6742,0,-1.0267,-0.4017t-0.3525,-1.1938q0,-0.7528,0.3525,-1.1545t1.007,-0.4017q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4213,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404zM1.3483,12.3146v-0.4831h0.5056v0.4831h-0.5056z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ė\"\r\n  },\r\n  'XĘ': {\r\n    getPath: () => `M0.4719,16v-3.9579h3.0028v0.4382h-2.4663v1.2697h2.2978v0.4326h-2.2978v1.3792h2.5815v0.4382h-3.118zM3.5899,17.1236q-0.177,0.0758,-0.3904,0.0758q-0.2949,0,-0.4438,-0.1433t-0.1489,-0.382q0,-0.1966,0.1222,-0.382t0.3132,-0.2921h0.3736q-0.0702,0.0393,-0.1433,0.1025t-0.1334,0.1461t-0.0983,0.1812t-0.0379,0.2079q0,0.118,0.0688,0.1854t0.1952,0.0674q0.1517,0,0.323,-0.0674v0.3006z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ę\"\r\n  },\r\n  'Xę': {\r\n    getPath: () => `M0.7753,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.6742,0,-1.0267,-0.4017t-0.3525,-1.1938q0,-0.7528,0.3525,-1.1545t1.007,-0.4017q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4213,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404zM2.2781,17.1236q-0.177,0.0758,-0.3904,0.0758q-0.2949,0,-0.4438,-0.1433t-0.1489,-0.382q0,-0.1966,0.1222,-0.382t0.3132,-0.2921h0.3736q-0.0702,0.0393,-0.1433,0.1025t-0.1334,0.1461t-0.0983,0.1812t-0.0379,0.2079q0,0.118,0.0688,0.1854t0.1952,0.0674q0.1517,0,0.323,-0.0674v0.3006z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ę\"\r\n  },\r\n  'XĢ': {\r\n    getPath: () => `M0.2893,14.0028q0,-0.9635,0.5169,-1.4916t1.4522,-0.5281q0.6573,0,1.0674,0.2219t0.632,0.7107l-0.5112,0.1517q-0.1685,-0.3371,-0.4649,-0.4916t-0.7374,-0.1545q-0.6854,0,-1.0478,0.4143t-0.3624,1.1671q0,0.75,0.3848,1.184t1.0646,0.434q0.3876,0,0.7233,-0.118t0.5435,-0.3202v-0.7135h-1.1826v-0.4494h1.677v1.3652q-0.3146,0.3202,-0.7711,0.4958t-0.9902,0.1756q-0.6208,0,-1.0702,-0.2472t-0.6868,-0.7121t-0.2374,-1.0941zM2.5787,16.5421q0,0.2444,-0.0618,0.3947t-0.1742,0.2823h-0.3287q0.1264,-0.1348,0.1952,-0.2556t0.0688,-0.25h-0.2472v-0.4382h0.5478v0.2669z`,\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16,\r\n    char: \"Ģ\"\r\n  },\r\n  'Xģ': {\r\n    getPath: () => `M1.5393,17.1938q-0.4972,0,-0.7921,-0.1952t-0.3792,-0.5548l0.5084,-0.073q0.0506,0.2107,0.2233,0.3244t0.4537,0.1138q0.7556,0,0.7556,-0.8848v-0.4888h-0.0056q-0.1433,0.2921,-0.3933,0.4396t-0.5843,0.1475q-0.559,0,-0.8216,-0.3708t-0.2626,-1.1657q0,-0.8062,0.2823,-1.1896t0.8581,-0.3834q0.323,0,0.5604,0.1475t0.3666,0.4199h0.0056q0,-0.0843,0.0112,-0.2921t0.0225,-0.2275h0.4803q-0.0169,0.1517,-0.0169,0.6292v2.323q0,1.2809,-1.2725,1.2809zM2.309,14.4803q0,-0.3708,-0.1011,-0.639t-0.2851,-0.4101t-0.4171,-0.1419q-0.3876,0,-0.5646,0.2809t-0.177,0.9101q0,0.6236,0.1657,0.8961t0.5674,0.2725q0.2388,0,0.4242,-0.1404t0.2865,-0.4031t0.1011,-0.625zM1.2416,12.3006q0,-0.2444,0.0618,-0.4087t0.1742,-0.2963h0.3287q-0.264,0.2809,-0.264,0.5337h0.2472v0.4691h-0.5478v-0.2978z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ģ\"\r\n  },\r\n  'XĪ': {\r\n    getPath: () => `M0.5309,16v-3.9579h0.5365v3.9579h-0.5365zM1.5758,11.6039h-1.5421v-0.3567h1.5421v0.3567z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"Ī\"\r\n  },\r\n  'Xī': {\r\n    getPath: () => `M0.5449,16v-3.0393h0.5056v3.0393h-0.5056zM1.5758,12.5281h-1.5421v-0.3567h1.5421v0.3567z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"ī\"\r\n  },\r\n  'XĮ': {\r\n    getPath: () => `M0.5309,16v-3.9579h0.5365v3.9579h-0.5365zM1.2416,17.1236q-0.177,0.0758,-0.3904,0.0758q-0.2949,0,-0.4438,-0.1433t-0.1489,-0.382q0,-0.1966,0.1222,-0.382t0.3132,-0.2921h0.3736q-0.0702,0.0393,-0.1433,0.1025t-0.1334,0.1461t-0.0983,0.1812t-0.0379,0.2079q0,0.118,0.0688,0.1854t0.1952,0.0674q0.1517,0,0.323,-0.0674v0.3006z`,\r\n    get width() { return getGridUnitWidth(569); },\r\n    height: 16,\r\n    char: \"Į\"\r\n  },\r\n  'Xį': {\r\n    getPath: () => `M0.3848,12.3146v-0.4831h0.5056v0.4831h-0.5056zM0.3848,16v-3.0393h0.5056v3.0393h-0.5056zM1.0702,17.1236q-0.177,0.0758,-0.3904,0.0758q-0.2949,0,-0.4438,-0.1433t-0.1489,-0.382q0,-0.1966,0.1222,-0.382t0.3132,-0.2921h0.3736q-0.0702,0.0393,-0.1433,0.1025t-0.1334,0.1461t-0.0983,0.1812t-0.0379,0.2079q0,0.118,0.0688,0.1854t0.1952,0.0674q0.1517,0,0.323,-0.0674v0.3006z`,\r\n    get width() { return getGridUnitWidth(455); },\r\n    height: 16,\r\n    char: \"į\"\r\n  },\r\n  'XĶ': {\r\n    getPath: () => `M3.1067,16l-1.5815,-1.9101l-0.5169,0.3933v1.5169h-0.5365v-3.9579h0.5365v1.9831l1.9073,-1.9831h0.632l-1.6854,1.7191l1.9101,2.2388h-0.6657zM2.2612,16.5421q0,0.2444,-0.0618,0.3947t-0.1742,0.2823h-0.3287q0.1264,-0.1348,0.1952,-0.2556t0.0688,-0.25h-0.2472v-0.4382h0.5478v0.2669z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ķ\"\r\n  },\r\n  'Xķ': {\r\n    getPath: () => `M2.2921,16l-1.0281,-1.3876l-0.3708,0.3062v1.0815h-0.5056v-4.1685h0.5056v2.6039l1.3343,-1.4747h0.5927l-1.2331,1.3062l1.2978,1.7331h-0.5927zM1.8596,16.5421q0,0.2444,-0.0618,0.3947t-0.1742,0.2823h-0.3287q0.1264,-0.1348,0.1952,-0.2556t0.0688,-0.25h-0.2472v-0.4382h0.5478v0.2669z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"ķ\"\r\n  },\r\n  // Kerning inherited from 'L'\r\n  'XĻ': {\r\n    getPath: () => `M0.4719,16v-3.9579h0.5365v3.5197h2v0.4382h-2.5365zM2.014,16.5421q0,0.2444,-0.0618,0.3947t-0.1742,0.2823h-0.3287q0.1264,-0.1348,0.1952,-0.2556t0.0688,-0.25h-0.2472v-0.4382h0.5478v0.2669z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"Ļ\",\r\n    kerningRules: {\r\n      \"T\": getGridUnitKerningRule(152),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"W\": getGridUnitKerningRule(152),\r\n      \"y\": getGridUnitKerningRule(76),\r\n      \"Y\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'Xļ': {\r\n    getPath: () => `M0.3876,16v-4.1685h0.5056v4.1685h-0.5056zM0.9185,16.5421q0,0.2444,-0.0618,0.3947t-0.1742,0.2823h-0.3287q0.1264,-0.1348,0.1952,-0.2556t0.0688,-0.25h-0.2472v-0.4382h0.5478v0.2669z`,\r\n    get width() { return getGridUnitWidth(455); },\r\n    height: 16,\r\n    char: \"ļ\"\r\n  },\r\n  // Kerning inherited from 'L'\r\n  'XŁ': {\r\n    getPath: () => `M1.7303,13.7612l-0.7219,0.4185v1.382h2v0.4382h-2.5365v-1.5112l-0.4157,0.2388v-0.4438l0.4157,-0.2388v-2.0028h0.5365v1.6938l0.7219,-0.4157v0.441z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"Ł\",\r\n    kerningRules: {\r\n      \"T\": getGridUnitKerningRule(152),\r\n      \"V\": getGridUnitKerningRule(152),\r\n      \"W\": getGridUnitKerningRule(152),\r\n      \"y\": getGridUnitKerningRule(76),\r\n      \"Y\": getGridUnitKerningRule(152)\r\n    }\r\n  },\r\n  'Xł': {\r\n    getPath: () => `M0.3876,16v-1.5225l-0.3427,0.191v-0.4438l0.3427,-0.191v-2.2022h0.5056v1.9101l0.3483,-0.2022v0.4466l-0.3483,0.1994v1.8146h-0.5056z`,\r\n    get width() { return getGridUnitWidth(455); },\r\n    height: 16,\r\n    char: \"ł\"\r\n  },\r\n  'XŃ': {\r\n    getPath: () => `M3.0393,16l-2.118,-3.3708l0.014,0.2725l0.014,0.4691v2.6292h-0.4775v-3.9579h0.6236l2.1404,3.3933q-0.0337,-0.5506,-0.0337,-0.7978v-2.5955h0.4831v3.9579h-0.6461zM1.6882,11.7022v-0.0562l0.6096,-0.6348h0.5815v0.0815l-0.8708,0.6096h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ń\"\r\n  },\r\n  'Xń': {\r\n    getPath: () => `M2.3287,16v-1.927q0,-0.3006,-0.059,-0.4663t-0.1882,-0.2388t-0.3792,-0.073q-0.3652,0,-0.5758,0.25t-0.2107,0.6938v1.7612h-0.5056v-2.3904q0,-0.5309,-0.0169,-0.6489h0.4775q0.0028,0.014,0.0056,0.0758t0.007,0.1419t0.0098,0.302h0.0084q0.1742,-0.3146,0.4031,-0.4452t0.5688,-0.1306q0.5,0,0.7317,0.2486t0.2317,0.8216v2.0253h-0.5084zM1.2921,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ń\"\r\n  },\r\n  'XŅ': {\r\n    getPath: () => `M3.0393,16l-2.118,-3.3708l0.014,0.2725l0.014,0.4691v2.6292h-0.4775v-3.9579h0.6236l2.1404,3.3933q-0.0337,-0.5506,-0.0337,-0.7978v-2.5955h0.4831v3.9579h-0.6461zM2.3483,16.5421q0,0.2444,-0.0618,0.3947t-0.1742,0.2823h-0.3287q0.1264,-0.1348,0.1952,-0.2556t0.0688,-0.25h-0.2472v-0.4382h0.5478v0.2669z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ņ\"\r\n  },\r\n  'Xņ': {\r\n    getPath: () => `M2.3287,16v-1.927q0,-0.3006,-0.059,-0.4663t-0.1882,-0.2388t-0.3792,-0.073q-0.3652,0,-0.5758,0.25t-0.2107,0.6938v1.7612h-0.5056v-2.3904q0,-0.5309,-0.0169,-0.6489h0.4775q0.0028,0.014,0.0056,0.0758t0.007,0.1419t0.0098,0.302h0.0084q0.1742,-0.3146,0.4031,-0.4452t0.5688,-0.1306q0.5,0,0.7317,0.2486t0.2317,0.8216v2.0253h-0.5084zM1.8961,16.5421q0,0.2444,-0.0618,0.3947t-0.1742,0.2823h-0.3287q0.1264,-0.1348,0.1952,-0.2556t0.0688,-0.25h-0.2472v-0.4382h0.5478v0.2669z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ņ\"\r\n  },\r\n  'XŐ': {\r\n    getPath: () => `M4.1994,14.0028q0,0.6208,-0.2374,1.0871t-0.6812,0.7163t-1.0478,0.25q-0.6096,0,-1.052,-0.2472t-0.6756,-0.7149t-0.2331,-1.0913q0,-0.9494,0.5197,-1.4846t1.4466,-0.5351q0.6039,0,1.0478,0.2402t0.6784,0.698t0.2346,1.0815zM3.6517,14.0028q0,-0.7388,-0.3694,-1.1601t-1.0435,-0.4213q-0.6798,0,-1.0506,0.4157t-0.3708,1.1657q0,0.7444,0.375,1.1812t1.0407,0.4368q0.6854,0,1.052,-0.4228t0.3666,-1.1952zM1.4438,11.7022v-0.0562l0.5534,-0.6376h0.5815v0.0815l-0.8708,0.6124h-0.264zM2.4185,11.7022v-0.0562l0.5534,-0.6376h0.5815v0.0815l-0.8708,0.6124h-0.264z`,\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16,\r\n    char: \"Ő\"\r\n  },\r\n  'Xő': {\r\n    getPath: () => `M2.9579,14.4775q0,0.7978,-0.3511,1.1882t-1.0197,0.3904q-0.6657,0,-1.0056,-0.4059t-0.3399,-1.1728q0,-1.573,1.3624,-1.573q0.6966,0,1.0253,0.3834t0.3287,1.1896zM2.427,14.4775q0,-0.6292,-0.1868,-0.9143t-0.6278,-0.2851q-0.4438,0,-0.6419,0.2907t-0.198,0.9087q0,0.6011,0.1952,0.9031t0.6138,0.302q0.4551,0,0.6503,-0.2921t0.1952,-0.9129zM0.8062,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264zM1.7809,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ő\"\r\n  },\r\n  'XŒ': {\r\n    getPath: () => `M2.8062,16q-0.1882,0.0281,-0.5899,0.0281q-0.9073,0,-1.4256,-0.5421t-0.5183,-1.4831q0,-0.9326,0.5169,-1.4621t1.4326,-0.5295q0.3006,0,0.5955,0.0309h2.5674v0.4382h-2.2556v1.2697h2.0871v0.4326h-2.0871v1.3792h2.3708v0.4382h-2.6938zM2.2163,15.5927q0.2303,0,0.3764,-0.0112v-3.1208q-0.1236,-0.0112,-0.2261,-0.0112h-0.1447q-0.6882,0,-1.0463,0.4017t-0.3581,1.1517q0,0.7528,0.3694,1.1713t1.0295,0.4185z`,\r\n    get width() { return getGridUnitWidth(2048); },\r\n    height: 16,\r\n    char: \"Œ\"\r\n  },\r\n  'Xœ': {\r\n    getPath: () => `M3.0056,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.7725,0,-1.1124,-0.514q-0.3483,0.514,-1.1264,0.514q-0.6685,0,-1.0211,-0.4059t-0.3525,-1.1728q0,-0.7837,0.3553,-1.1784t1.0351,-0.3947q0.7893,0,1.118,0.4972q0.3539,-0.4972,1.0843,-0.4972q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4747,14.4775q0,-0.6152,-0.1938,-0.9073t-0.6404,-0.2921q-0.4551,0,-0.6615,0.2992t-0.2065,0.9003q0,1.2051,0.8371,1.2051q0.4607,0,0.6629,-0.2921t0.2022,-0.9129zM4.6517,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404z`,\r\n    get width() { return getGridUnitWidth(1933); },\r\n    height: 16,\r\n    char: \"œ\"\r\n  },\r\n  'XŚ': {\r\n    getPath: () => `M3.573,14.9073q0,0.5478,-0.4284,0.8483t-1.2065,0.3006q-1.4466,0,-1.677,-1.0056l0.5197,-0.1039q0.0899,0.3567,0.382,0.5239t0.7949,0.1671q0.5197,0,0.802,-0.1784t0.2823,-0.5239q0,-0.1938,-0.0885,-0.3146t-0.2486,-0.1994t-0.382,-0.132t-0.4916,-0.1152q-0.4691,-0.1039,-0.7121,-0.2079t-0.3834,-0.2317t-0.2149,-0.2992t-0.0744,-0.3933q0,-0.5084,0.389,-0.7837t1.1138,-0.2753q0.6742,0,1.0309,0.2065t0.5,0.7037l-0.5281,0.0927q-0.0871,-0.3146,-0.3315,-0.4565t-0.677,-0.1419q-0.4747,0,-0.7247,0.1573t-0.25,0.4691q0,0.1826,0.0969,0.302t0.2795,0.2022t0.7275,0.2037q0.1826,0.0421,0.3638,0.0857t0.3469,0.1039t0.3104,0.1419t0.2514,0.1994t0.1671,0.2781t0.0604,0.3764zM1.5787,11.7022v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ś\"\r\n  },\r\n  'Xś': {\r\n    getPath: () => `M2.6685,15.1601q0,0.4298,-0.3244,0.6629t-0.9087,0.2331q-0.5674,0,-0.875,-0.1868t-0.4003,-0.5829l0.4466,-0.0871q0.0646,0.2444,0.2669,0.3581t0.5618,0.1138q0.3848,0,0.5632,-0.118t0.1784,-0.3539q0,-0.1798,-0.1236,-0.2921t-0.3989,-0.1854l-0.3624,-0.0955q-0.4354,-0.1124,-0.6194,-0.2205t-0.2879,-0.2626t-0.1039,-0.3792q0,-0.4157,0.2963,-0.6334t0.8638,-0.2177q0.5028,0,0.7992,0.177t0.375,0.5674l-0.4551,0.0562q-0.0421,-0.2022,-0.2261,-0.3104t-0.493,-0.1081q-0.3427,0,-0.5056,0.1039t-0.1629,0.3146q0,0.1292,0.0674,0.2135t0.1994,0.1433t0.5562,0.1629q0.4017,0.1011,0.5787,0.1868t0.2795,0.1896t0.1587,0.2402t0.0562,0.3104zM1.0815,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"ś\"\r\n  },\r\n  'XŠ': {\r\n    getPath: () => `M3.573,14.9073q0,0.5478,-0.4284,0.8483t-1.2065,0.3006q-1.4466,0,-1.677,-1.0056l0.5197,-0.1039q0.0899,0.3567,0.382,0.5239t0.7949,0.1671q0.5197,0,0.802,-0.1784t0.2823,-0.5239q0,-0.1938,-0.0885,-0.3146t-0.2486,-0.1994t-0.382,-0.132t-0.4916,-0.1152q-0.4691,-0.1039,-0.7121,-0.2079t-0.3834,-0.2317t-0.2149,-0.2992t-0.0744,-0.3933q0,-0.5084,0.389,-0.7837t1.1138,-0.2753q0.6742,0,1.0309,0.2065t0.5,0.7037l-0.5281,0.0927q-0.0871,-0.3146,-0.3315,-0.4565t-0.677,-0.1419q-0.4747,0,-0.7247,0.1573t-0.25,0.4691q0,0.1826,0.0969,0.302t0.2795,0.2022t0.7275,0.2037q0.1826,0.0421,0.3638,0.0857t0.3469,0.1039t0.3104,0.1419t0.2514,0.1994t0.1671,0.2781t0.0604,0.3764zM2.2725,11.7022h-0.573l-0.6573,-0.6713v-0.059h0.2921l0.6517,0.3904h0.0056l0.6152,-0.3904h0.2949v0.059z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Š\"\r\n  },\r\n  'Xš': {\r\n    getPath: () => `M2.6685,15.1601q0,0.4298,-0.3244,0.6629t-0.9087,0.2331q-0.5674,0,-0.875,-0.1868t-0.4003,-0.5829l0.4466,-0.0871q0.0646,0.2444,0.2669,0.3581t0.5618,0.1138q0.3848,0,0.5632,-0.118t0.1784,-0.3539q0,-0.1798,-0.1236,-0.2921t-0.3989,-0.1854l-0.3624,-0.0955q-0.4354,-0.1124,-0.6194,-0.2205t-0.2879,-0.2626t-0.1039,-0.3792q0,-0.4157,0.2963,-0.6334t0.8638,-0.2177q0.5028,0,0.7992,0.177t0.375,0.5674l-0.4551,0.0562q-0.0421,-0.2022,-0.2261,-0.3104t-0.493,-0.1081q-0.3427,0,-0.5056,0.1039t-0.1629,0.3146q0,0.1292,0.0674,0.2135t0.1994,0.1433t0.5562,0.1629q0.4017,0.1011,0.5787,0.1868t0.2795,0.1896t0.1587,0.2402t0.0562,0.3104zM1.7163,12.6264h-0.573l-0.6573,-0.7584v-0.0562h0.2921l0.6517,0.4747h0.0056l0.6152,-0.4747h0.2949v0.0562z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"š\"\r\n  },\r\n  'XŪ': {\r\n    getPath: () => `M2.0534,16.0562q-0.486,0,-0.8483,-0.177t-0.5618,-0.514t-0.1994,-0.8034v-2.5197h0.5365v2.4747q0,0.5421,0.2753,0.823t0.7949,0.2809q0.5337,0,0.8301,-0.2907t0.2963,-0.8497v-2.4382h0.5337v2.4691q0,0.4803,-0.2037,0.8287t-0.5758,0.5323t-0.8778,0.184zM2.8511,11.6039h-1.5421v-0.3567h1.5421v0.3567z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ū\"\r\n  },\r\n  'Xū': {\r\n    getPath: () => `M0.882,12.9607v1.927q0,0.3006,0.059,0.4663t0.1882,0.2388t0.3792,0.073q0.3652,0,0.5758,-0.25t0.2107,-0.6938v-1.7612h0.5056v2.3904q0,0.5309,0.0169,0.6489h-0.4775q-0.0028,-0.014,-0.0056,-0.0758t-0.007,-0.1419t-0.0098,-0.302h-0.0084q-0.1742,0.3146,-0.4031,0.4452t-0.5688,0.1306q-0.5,0,-0.7317,-0.2486t-0.2317,-0.8216v-2.0253h0.5084zM2.3596,12.5281h-1.5421v-0.3567h1.5421v0.3567z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ū\"\r\n  },\r\n  'XŰ': {\r\n    getPath: () => `M2.0534,16.0562q-0.486,0,-0.8483,-0.177t-0.5618,-0.514t-0.1994,-0.8034v-2.5197h0.5365v2.4747q0,0.5421,0.2753,0.823t0.7949,0.2809q0.5337,0,0.8301,-0.2907t0.2963,-0.8497v-2.4382h0.5337v2.4691q0,0.4803,-0.2037,0.8287t-0.5758,0.5323t-0.8778,0.184zM1.25,11.7022v-0.0562l0.5534,-0.6376h0.5815v0.0815l-0.8708,0.6124h-0.264zM2.2247,11.7022v-0.0562l0.5534,-0.6376h0.5815v0.0815l-0.8708,0.6124h-0.264z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ű\"\r\n  },\r\n  'Xű': {\r\n    getPath: () => `M0.882,12.9607v1.927q0,0.3006,0.059,0.4663t0.1882,0.2388t0.3792,0.073q0.3652,0,0.5758,-0.25t0.2107,-0.6938v-1.7612h0.5056v2.3904q0,0.5309,0.0169,0.6489h-0.4775q-0.0028,-0.014,-0.0056,-0.0758t-0.007,-0.1419t-0.0098,-0.302h-0.0084q-0.1742,0.3146,-0.4031,0.4452t-0.5688,0.1306q-0.5,0,-0.7317,-0.2486t-0.2317,-0.8216v-2.0253h0.5084zM0.7949,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264zM1.7697,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ű\"\r\n  },\r\n  'XŲ': {\r\n    getPath: () => `M2.0534,16.0562q-0.486,0,-0.8483,-0.177t-0.5618,-0.514t-0.1994,-0.8034v-2.5197h0.5365v2.4747q0,0.5421,0.2753,0.823t0.7949,0.2809q0.5337,0,0.8301,-0.2907t0.2963,-0.8497v-2.4382h0.5337v2.4691q0,0.4803,-0.2037,0.8287t-0.5758,0.5323t-0.8778,0.184zM2.736,17.1236q-0.177,0.0758,-0.3904,0.0758q-0.2949,0,-0.4438,-0.1433t-0.1489,-0.382q0,-0.1966,0.1222,-0.382t0.3132,-0.2921h0.3736q-0.0702,0.0393,-0.1433,0.1025t-0.1334,0.1461t-0.0983,0.1812t-0.0379,0.2079q0,0.118,0.0688,0.1854t0.1952,0.0674q0.1517,0,0.323,-0.0674v0.3006z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Ų\"\r\n  },\r\n  'Xų': {\r\n    getPath: () => `M0.882,12.9607v1.927q0,0.3006,0.059,0.4663t0.1882,0.2388t0.3792,0.073q0.3652,0,0.5758,-0.25t0.2107,-0.6938v-1.7612h0.5056v2.3904q0,0.5309,0.0169,0.6489h-0.4775q-0.0028,-0.014,-0.0056,-0.0758t-0.007,-0.1419t-0.0098,-0.302h-0.0084q-0.1742,0.3146,-0.4031,0.4452t-0.5688,0.1306q-0.5,0,-0.7317,-0.2486t-0.2317,-0.8216v-2.0253h0.5084zM2.8904,17.1236q-0.177,0.0758,-0.3904,0.0758q-0.2949,0,-0.4438,-0.1433t-0.1489,-0.382q0,-0.1966,0.1222,-0.382t0.3132,-0.2921h0.3736q-0.0702,0.0393,-0.1433,0.1025t-0.1334,0.1461t-0.0983,0.1812t-0.0379,0.2079q0,0.118,0.0688,0.1854t0.1952,0.0674q0.1517,0,0.323,-0.0674v0.3006z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ų\"\r\n  },\r\n  // Kerning inherited from 'Y'\r\n  'XŸ': {\r\n    getPath: () => `M2.1826,14.3596v1.6404h-0.5337v-1.6404l-1.5225,-2.3174h0.5899l1.2051,1.8848l1.1994,-1.8848h0.5899zM2.2444,11.7022v-0.5169h0.4579v0.5169h-0.4579zM1.1376,11.7022v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Ÿ\",\r\n    kerningRules: {\r\n      \"a\": getGridUnitKerningRule(152),\r\n      \"A\": getGridUnitKerningRule(152),\r\n      \"e\": getGridUnitKerningRule(188),\r\n      \"i\": getGridUnitKerningRule(76),\r\n      \"o\": getGridUnitKerningRule(188),\r\n      \"p\": getGridUnitKerningRule(152),\r\n      \"q\": getGridUnitKerningRule(188),\r\n      \"u\": getGridUnitKerningRule(113),\r\n      \"v\": getGridUnitKerningRule(113)\r\n    }\r\n  },\r\n  'XŹ': {\r\n    getPath: () => `M3.3343,16h-3.1517v-0.4017l2.4101,-3.118h-2.2051v-0.4382h2.8146v0.3904l-2.4101,3.1292h2.5421v0.4382zM1.3708,11.7022v-0.0562l0.6096,-0.6348h0.5815v0.0815l-0.8708,0.6096h-0.3202z`,\r\n    get width() { return getGridUnitWidth(1251); },\r\n    height: 16,\r\n    char: \"Ź\"\r\n  },\r\n  'Xź': {\r\n    getPath: () => `M0.2331,16v-0.3848l1.6994,-2.264h-1.6039v-0.3904h2.2022v0.3848l-1.7022,2.264h1.7612v0.3904h-2.3567zM1.0702,12.6264v-0.0562l0.6096,-0.8062h0.5815v0.0815l-0.927,0.7809h-0.264z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"ź\"\r\n  },\r\n  'XŻ': {\r\n    getPath: () => `M3.3343,16h-3.1517v-0.4017l2.4101,-3.118h-2.2051v-0.4382h2.8146v0.3904l-2.4101,3.1292h2.5421v0.4382zM1.5056,11.4916v-0.4831h0.5056v0.4831h-0.5056z`,\r\n    get width() { return getGridUnitWidth(1251); },\r\n    height: 16,\r\n    char: \"Ż\"\r\n  },\r\n  'Xż': {\r\n    getPath: () => `M0.2331,16v-0.3848l1.6994,-2.264h-1.6039v-0.3904h2.2022v0.3848l-1.7022,2.264h1.7612v0.3904h-2.3567zM1.1489,12.3146v-0.4831h0.5056v0.4831h-0.5056z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"ż\"\r\n  },\r\n  'XŽ': {\r\n    getPath: () => `M3.3343,16h-3.1517v-0.4017l2.4101,-3.118h-2.2051v-0.4382h2.8146v0.3904l-2.4101,3.1292h2.5421v0.4382zM2.1067,11.7022h-0.573l-0.6573,-0.6713v-0.059h0.2921l0.6517,0.3904h0.0056l0.6152,-0.3904h0.2949v0.059z`,\r\n    get width() { return getGridUnitWidth(1251); },\r\n    height: 16,\r\n    char: \"Ž\"\r\n  },\r\n  'Xž': {\r\n    getPath: () => `M0.2331,16v-0.3848l1.6994,-2.264h-1.6039v-0.3904h2.2022v0.3848l-1.7022,2.264h1.7612v0.3904h-2.3567zM1.6685,12.6264h-0.573l-0.6573,-0.7584v-0.0562h0.2921l0.6517,0.4747h0.0056l0.6152,-0.4747h0.2949v0.0562z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"ž\"\r\n  },\r\n  'Xа': {\r\n    getPath: () => `M1.1629,16.0562q-0.4579,0,-0.6882,-0.2416t-0.2303,-0.6629q0,-0.4719,0.3104,-0.7247t1.0014,-0.2697l0.6826,-0.0112v-0.1657q0,-0.3708,-0.1573,-0.5309t-0.4944,-0.1601q-0.3399,0,-0.4944,0.1152t-0.1854,0.368l-0.5281,-0.0478q0.1292,-0.8202,1.2191,-0.8202q0.573,0,0.8624,0.2626t0.2893,0.7598v1.309q0,0.2247,0.059,0.3385t0.2247,0.1138q0.073,0,0.1657,-0.0197v0.3146q-0.191,0.0449,-0.3904,0.0449q-0.2809,0,-0.4087,-0.1475t-0.1447,-0.4621h-0.0169q-0.1938,0.3483,-0.4508,0.493t-0.625,0.1447zM1.2781,15.677q0.2781,0,0.4944,-0.1264t0.3413,-0.3469t0.125,-0.4537v-0.25l-0.5534,0.0112q-0.3567,0.0056,-0.5407,0.073t-0.2823,0.2079t-0.0983,0.368q0,0.2472,0.1334,0.382t0.3806,0.1348z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"а\"\r\n  },\r\n  'Xб': {\r\n    getPath: () => `M2.5225,14.5899q0,-0.5674,-0.1854,-0.8357t-0.6039,-0.2683q-0.4466,0,-0.6559,0.2725t-0.2093,0.8315q0,0.5449,0.1952,0.8188t0.6138,0.2739q0.4522,0,0.6489,-0.2626t0.1966,-0.8301zM1.8399,13.1152q0.6236,0,0.9185,0.3666t0.2949,1.1025q0,0.7444,-0.3511,1.1081t-1.0197,0.3638q-0.691,0,-1.0183,-0.4522t-0.3272,-1.3904q0,-0.4775,0.0646,-0.8385t0.2022,-0.6222t0.3553,-0.4354t0.5478,-0.2809t1.4031,-0.2556v0.4522q-1.177,0.1517,-1.5239,0.2893t-0.4874,0.4382t-0.1517,0.8989q0.1208,-0.3511,0.4045,-0.5478t0.6882,-0.1966z`,\r\n    get width() { return getGridUnitWidth(1173); },\r\n    height: 16,\r\n    char: \"б\"\r\n  },\r\n  'Xв': {\r\n    getPath: () => `M1.5843,12.9607q0.5618,0,0.8427,0.1966t0.2809,0.5646q0,0.2612,-0.1601,0.4354t-0.4663,0.2331v0.0197q0.3624,0.0478,0.5435,0.2303t0.1812,0.4831q0,0.4129,-0.3076,0.6447t-0.8497,0.2317h-1.25v-3.0393h1.1854zM0.9045,15.6264h0.6629q0.3876,0,0.5449,-0.1194t0.1573,-0.3806q0,-0.2837,-0.1671,-0.4003t-0.5688,-0.1166h-0.6292v1.0169zM0.9045,13.3455v0.8989h0.6067q0.3596,0,0.5126,-0.1011t0.1531,-0.3539q0,-0.2303,-0.1433,-0.3371t-0.4831,-0.1067h-0.6461z`,\r\n    get width() { return getGridUnitWidth(1088); },\r\n    height: 16,\r\n    char: \"в\"\r\n  },\r\n  'Xг': {\r\n    getPath: () => `M1.9298,12.9607v0.368h-1.0253v2.6713h-0.5056v-3.0393h1.5309z`,\r\n    get width() { return getGridUnitWidth(747); },\r\n    height: 16,\r\n    char: \"г\"\r\n  },\r\n  'Xд': {\r\n    getPath: () => `M2.3427,13.3287h-0.8596q-0.1039,0.764,-0.2303,1.3301t-0.3062,0.9733h1.3961v-2.3034zM3.2584,17.1461h-0.4579v-1.1461h-2.2865v1.1461h-0.4579v-1.514h0.3343q0.2107,-0.3511,0.3652,-0.9972t0.2837,-1.6742h1.809v2.6713h0.4101v1.514z`,\r\n    get width() { return getGridUnitWidth(1195); },\r\n    height: 16,\r\n    char: \"д\"\r\n  },\r\n  'Xе': {\r\n    getPath: () => `M0.7753,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.6742,0,-1.0267,-0.4017t-0.3525,-1.1938q0,-0.7528,0.3525,-1.1545t1.007,-0.4017q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4213,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"е\"\r\n  },\r\n  'Xё': {\r\n    getPath: () => `M0.7753,14.5871q0,0.5225,0.2163,0.8062t0.632,0.2837q0.3287,0,0.5267,-0.132t0.2683,-0.3343l0.4438,0.1264q-0.2725,0.7191,-1.2388,0.7191q-0.6742,0,-1.0267,-0.4017t-0.3525,-1.1938q0,-0.7528,0.3525,-1.1545t1.007,-0.4017q1.3399,0,1.3399,1.6152v0.0674h-2.1685zM2.4213,14.1994q-0.0421,-0.4803,-0.2444,-0.7008t-0.5815,-0.2205q-0.368,0,-0.5829,0.2458t-0.2317,0.6756h1.6404zM1.9298,12.5758v-0.5169h0.4579v0.5169h-0.4579zM0.823,12.5758v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"ё\"\r\n  },\r\n  'Xж': {\r\n    getPath: () => `M1.6713,14.6601q-0.073,0,-0.1643,-0.0169t-0.1447,-0.0393l-0.7809,1.3961h-0.5618l0.9916,-1.6629q-0.0983,-0.0815,-0.3596,-0.4635l-0.6067,-0.9129h0.5281l0.4157,0.6713q0.1854,0.2978,0.2865,0.4284t0.184,0.1812t0.2121,0.0506v-1.3315h0.5056v1.3315q0.0843,0,0.1517,-0.0225t0.1404,-0.0941t0.1657,-0.2008t0.6404,-1.014h0.5281l-0.6067,0.9129q-0.2612,0.382,-0.3596,0.4635l0.9916,1.6629h-0.5618l-0.7809,-1.3961q-0.0534,0.0225,-0.1447,0.0393t-0.1643,0.0169v1.3399h-0.5056v-1.3399z`,\r\n    get width() { return getGridUnitWidth(1370); },\r\n    height: 16,\r\n    char: \"ж\"\r\n  },\r\n  'Xз': {\r\n    getPath: () => `M1.2865,16.0562q-0.4691,0,-0.7458,-0.1756t-0.4031,-0.5379l0.4466,-0.1236q0.1489,0.4607,0.7135,0.4607q0.2697,0,0.4284,-0.132t0.1587,-0.3876q0,-0.5618,-0.9298,-0.5618v-0.3848q0.4522,0,0.6657,-0.118t0.2135,-0.3652q0,-0.2079,-0.139,-0.3287t-0.4003,-0.1208q-0.25,0,-0.4087,0.1039t-0.1924,0.3006l-0.4551,-0.0562q0.1292,-0.7247,1.059,-0.7247q0.4719,0,0.7612,0.2233t0.2893,0.5772q0,0.2837,-0.2037,0.4747t-0.493,0.2163v0.0056q0.3399,0.0365,0.5548,0.2374t0.2149,0.507q0,0.427,-0.302,0.6685t-0.8329,0.2416z`,\r\n    get width() { return getGridUnitWidth(939); },\r\n    height: 16,\r\n    char: \"з\"\r\n  },\r\n  'Xи': {\r\n    getPath: () => `M0.8876,12.9607v1.6629l-0.0281,0.7781l1.4017,-2.441h0.5534v3.0393h-0.4831v-1.8539q0,-0.1011,0.0098,-0.3062t0.0183,-0.2921l-1.4213,2.4522h-0.5393v-3.0393h0.4888z`,\r\n    get width() { return getGridUnitWidth(1144); },\r\n    height: 16,\r\n    char: \"и\"\r\n  },\r\n  'Xй': {\r\n    getPath: () => `M0.8876,12.9607v1.6629l-0.0281,0.7781l1.4017,-2.441h0.5534v3.0393h-0.4831v-1.8539q0,-0.1011,0.0098,-0.3062t0.0183,-0.2921l-1.4213,2.4522h-0.5393v-3.0393h0.4888zM1.6124,12.6292q-1,0,-1.0309,-0.8989h0.4607q0.0337,0.559,0.5702,0.559t0.5702,-0.559h0.4607q-0.0309,0.8989,-1.0309,0.8989z`,\r\n    get width() { return getGridUnitWidth(1144); },\r\n    height: 16,\r\n    char: \"й\"\r\n  },\r\n  'Xк': {\r\n    getPath: () => `M0.3876,12.9607h0.5056v1.3315q0.0843,0,0.1517,-0.0225t0.1404,-0.0941t0.1657,-0.2008t0.6404,-1.014h0.5281l-0.6067,0.9129q-0.2612,0.382,-0.3596,0.4635l0.9916,1.6629h-0.5618l-0.7809,-1.3961q-0.0534,0.0225,-0.1447,0.0393t-0.1643,0.0169v1.3399h-0.5056v-3.0393z`,\r\n    get width() { return getGridUnitWidth(896); },\r\n    height: 16,\r\n    char: \"к\"\r\n  },\r\n  'Xл': {\r\n    getPath: () => `M2.4494,16v-2.6713h-1.0534q-0.1657,1.2247,-0.2556,1.6531t-0.1938,0.6475t-0.257,0.323t-0.3947,0.1039q-0.1404,0,-0.264,-0.0365v-0.3624q0.0702,0.0253,0.191,0.0253q0.1545,0,0.2486,-0.1545t0.1713,-0.5337t0.1756,-1.1208l0.1236,-0.9129h2.0169v3.0393h-0.5084z`,\r\n    get width() { return getGridUnitWidth(1195); },\r\n    height: 16,\r\n    char: \"л\"\r\n  },\r\n  'Xм': {\r\n    getPath: () => `M2.2107,16h-0.4298l-0.9101,-2.6713q0.0169,0.4382,0.0169,0.6376v2.0337h-0.4888v-3.0393h0.7865l0.618,1.8567q0.1461,0.4017,0.191,0.8034q0.0618,-0.4522,0.191,-0.8034l0.618,-1.8567h0.7556v3.0393h-0.486v-2.0337l0.0084,-0.3202l0.014,-0.323z`,\r\n    get width() { return getGridUnitWidth(1408); },\r\n    height: 16,\r\n    char: \"м\"\r\n  },\r\n  'Xн': {\r\n    getPath: () => `M0.9045,12.9607v1.2865h1.368v-1.2865h0.5056v3.0393h-0.5056v-1.3848h-1.368v1.3848h-0.5056v-3.0393h0.5056z`,\r\n    get width() { return getGridUnitWidth(1131); },\r\n    height: 16,\r\n    char: \"н\"\r\n  },\r\n  'Xо': {\r\n    getPath: () => `M2.9579,14.4775q0,0.7978,-0.3511,1.1882t-1.0197,0.3904q-0.6657,0,-1.0056,-0.4059t-0.3399,-1.1728q0,-1.573,1.3624,-1.573q0.6966,0,1.0253,0.3834t0.3287,1.1896zM2.427,14.4775q0,-0.6292,-0.1868,-0.9143t-0.6278,-0.2851q-0.4438,0,-0.6419,0.2907t-0.198,0.9087q0,0.6011,0.1952,0.9031t0.6138,0.302q0.4551,0,0.6503,-0.2921t0.1952,-0.9129z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"о\"\r\n  },\r\n  'Xп': {\r\n    getPath: () => `M2.7163,12.9607v3.0393h-0.5056v-2.6713h-1.3062v2.6713h-0.5056v-3.0393h2.3174z`,\r\n    get width() { return getGridUnitWidth(1109); },\r\n    height: 16,\r\n    char: \"п\"\r\n  },\r\n  'Xр': {\r\n    getPath: () => `M2.9579,14.4663q0,1.5899,-1.118,1.5899q-0.7022,0,-0.9438,-0.5281h-0.014q0.0112,0.0225,0.0112,0.4775v1.1882h-0.5056v-3.6124q0,-0.4691,-0.0169,-0.6208h0.4888q0.0028,0.0112,0.0084,0.0801t0.0126,0.2121t0.007,0.1966h0.0112q0.1348,-0.2809,0.3567,-0.4115t0.5843,-0.1306q0.5618,0,0.8399,0.3764t0.2781,1.1826zM2.427,14.4775q0,-0.6348,-0.1713,-0.9073t-0.5449,-0.2725q-0.3006,0,-0.4705,0.1264t-0.2584,0.3947t-0.0885,0.698q0,0.5983,0.191,0.882t0.6208,0.2837q0.3764,0,0.5492,-0.2767t0.1728,-0.9284z`,\r\n    get width() { return getGridUnitWidth(1139); },\r\n    height: 16,\r\n    char: \"р\"\r\n  },\r\n  'Xс': {\r\n    getPath: () => `M0.7725,14.4663q0,0.6067,0.191,0.8989t0.5758,0.2921q0.2697,0,0.4508,-0.1461t0.2233,-0.4494l0.5112,0.0337q-0.059,0.4382,-0.3736,0.6994t-0.7978,0.2612q-0.6376,0,-0.9733,-0.4031t-0.3357,-1.1756q0,-0.7669,0.3371,-1.1699t0.9663,-0.4031q0.4663,0,0.7739,0.2416t0.3862,0.6657l-0.5197,0.0393q-0.0393,-0.2528,-0.1994,-0.4017t-0.4551,-0.1489q-0.4017,0,-0.5815,0.2669t-0.1798,0.8989z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"с\"\r\n  },\r\n  'Xт': {\r\n    getPath: () => `M0.0983,12.9607h2.4382v0.368h-0.9663v2.6713h-0.5056v-2.6713h-0.9663v-0.368z`,\r\n    get width() { return getGridUnitWidth(938); },\r\n    height: 16,\r\n    char: \"т\"\r\n  },\r\n  'Xу': {\r\n    getPath: () => `M0.5365,17.1938q-0.2079,0,-0.3483,-0.0309v-0.3792q0.1067,0.0169,0.236,0.0169q0.4719,0,0.7472,-0.6938l0.0478,-0.1208l-1.2051,-3.0253h0.5393l0.6404,1.6798q0.014,0.0393,0.0337,0.0941t0.1264,0.3666t0.1152,0.3483l0.1966,-0.5534l0.6657,-1.9354h0.5337l-1.1685,3.0393q-0.1882,0.486,-0.3511,0.7233t-0.361,0.3539t-0.448,0.1166z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"у\"\r\n  },\r\n  'Xф': {\r\n    getPath: () => `M4.4888,14.4663q0,0.7978,-0.2598,1.1938t-0.7654,0.3961q-0.6348,0,-0.8567,-0.5281h-0.0169q0.014,0.2444,0.014,0.4775v1.1882h-0.4775v-1.1882q0,-0.3062,0.014,-0.4944h-0.014q-0.1292,0.2921,-0.3385,0.4185t-0.5211,0.1264q-0.5225,0,-0.7739,-0.3862t-0.2514,-1.1756q0,-1.5899,1.0253,-1.5899q0.3146,0,0.5239,0.1264t0.3357,0.4017h0.014l-0.014,-0.4242v-1.177h0.4775v1.1798l-0.0084,0.4382h0.014q0.1292,-0.2921,0.3315,-0.4171t0.5225,-0.125q0.514,0,0.7697,0.3834t0.2556,1.1756zM0.7725,14.4775q0,0.632,0.1531,0.9101t0.4846,0.2781q0.3652,0,0.5365,-0.2767t0.1798,-0.8778v-0.0674q0,-0.5927,-0.1671,-0.8792t-0.5435,-0.2865q-0.3399,0,-0.4916,0.2893t-0.1517,0.9101zM3.9579,14.4775q0,-0.6124,-0.1503,-0.8961t-0.4874,-0.2837q-0.264,0,-0.4129,0.1292t-0.2261,0.3947t-0.0772,0.6952v0.0646q0.0056,0.5646,0.177,0.8329t0.5337,0.2683q0.3343,0,0.4888,-0.2879t0.1545,-0.9171z`,\r\n    get width() { return getGridUnitWidth(1685); },\r\n    height: 16,\r\n    char: \"ф\"\r\n  },\r\n  'Xх': {\r\n    getPath: () => `M2.25,16l-0.8174,-1.2472l-0.823,1.2472h-0.5449l1.0815,-1.5618l-1.0309,-1.4775h0.559l0.7584,1.1826l0.7528,-1.1826h0.5646l-1.0309,1.4719l1.0955,1.5674h-0.5646z`,\r\n    get width() { return getGridUnitWidth(1024); },\r\n    height: 16,\r\n    char: \"х\"\r\n  },\r\n  'Xц': {\r\n    getPath: () => `M0.9045,12.9607v2.6713h1.3399v-2.6713h0.5056v2.6713h0.4129v1.514h-0.4579v-1.1461h-2.3062v-3.0393h0.5056z`,\r\n    get width() { return getGridUnitWidth(1173); },\r\n    height: 16,\r\n    char: \"ц\"\r\n  },\r\n  'Xч': {\r\n    getPath: () => `M0.8483,12.9607v1.1292q0,0.4551,0.4663,0.4551q0.309,0,0.7753,-0.132v-1.4522h0.5056v3.0393h-0.5056v-1.2949l-0.2191,0.0843q-0.4101,0.1573,-0.764,0.1573q-0.3624,0,-0.5632,-0.2177t-0.2008,-0.6138v-1.1545h0.5056z`,\r\n    get width() { return getGridUnitWidth(1067); },\r\n    height: 16,\r\n    char: \"ч\"\r\n  },\r\n  'Xш': {\r\n    getPath: () => `M0.3989,16v-3.0393h0.5056v2.6713h1.1517v-2.6713h0.5056v2.6713h1.1489v-2.6713h0.5056v3.0393h-3.8174z`,\r\n    get width() { return getGridUnitWidth(1643); },\r\n    height: 16,\r\n    char: \"ш\"\r\n  },\r\n  'Xщ': {\r\n    getPath: () => `M0.3989,16v-3.0393h0.5056v2.6713h1.1376v-2.6713h0.5056v2.6713h1.1348v-2.6713h0.5056v2.6713h0.4129v1.514h-0.4579v-1.1461h-3.7444z`,\r\n    get width() { return getGridUnitWidth(1685); },\r\n    height: 16,\r\n    char: \"щ\"\r\n  },\r\n  'Xъ': {\r\n    getPath: () => `M2.1938,14.2472q0.5758,0,0.8708,0.2065t0.2949,0.6531q0,0.4326,-0.3034,0.6629t-0.8596,0.2303h-1.1489v-2.6713h-0.9213v-0.368h1.427v1.2865h0.6404zM1.5534,15.6433h0.5674q0.3652,0,0.5337,-0.1292t0.1685,-0.4073q0,-0.264,-0.1629,-0.3862t-0.5365,-0.1222h-0.5702v1.0449z`,\r\n    get width() { return getGridUnitWidth(1280); },\r\n    height: 16,\r\n    char: \"ъ\"\r\n  },\r\n  'Xы': {\r\n    getPath: () => `M1.5449,14.2472q0.5758,0,0.8708,0.2065t0.2949,0.6531q0,0.4326,-0.3034,0.6629t-0.8596,0.2303h-1.1489v-3.0393h0.5056v1.2865h0.6404zM0.9045,15.6433h0.5674q0.3652,0,0.5337,-0.1292t0.1685,-0.4073q0,-0.264,-0.1629,-0.3862t-0.5365,-0.1222h-0.5702v1.0449zM3.2303,16v-3.0393h0.5056v3.0393h-0.5056z`,\r\n    get width() { return getGridUnitWidth(1472); },\r\n    height: 16,\r\n    char: \"ы\"\r\n  },\r\n  'Xь': {\r\n    getPath: () => `M1.5955,14.2472q0.5758,0,0.8708,0.2065t0.2949,0.6531q0,0.4326,-0.3034,0.6629t-0.8596,0.2303h-1.1994v-3.0393h0.5056v1.2865h0.691zM0.9045,15.6433h0.618q0.3652,0,0.5337,-0.1292t0.1685,-0.4073q0,-0.264,-0.1629,-0.3862t-0.5365,-0.1222h-0.6208v1.0449z`,\r\n    get width() { return getGridUnitWidth(1067); },\r\n    height: 16,\r\n    char: \"ь\"\r\n  },\r\n  'Xэ': {\r\n    getPath: () => `M0.1545,15.1152l0.5112,-0.0337q0.0449,0.3034,0.2317,0.4494t0.4677,0.1461q0.3624,0,0.5618,-0.2486t0.2331,-0.7823h-1.1601v-0.368h1.1601q-0.0225,-0.5309,-0.2121,-0.764t-0.5772,-0.2331q-0.5899,0,-0.6798,0.5506l-0.5197,-0.0393q0.0787,-0.4185,0.3919,-0.6531t0.7935,-0.2346q0.6461,0,0.9902,0.4045t0.3441,1.1685q0,0.7753,-0.3441,1.177t-0.9958,0.4017q-0.4972,0,-0.8174,-0.2528t-0.3792,-0.6882z`,\r\n    get width() { return getGridUnitWidth(1045); },\r\n    height: 16,\r\n    char: \"э\"\r\n  },\r\n  'Xю': {\r\n    getPath: () => `M4.073,14.4775q0,0.7978,-0.3301,1.1882t-0.9565,0.3904q-0.5955,0,-0.9143,-0.3694t-0.3441,-1.0716h-0.6236v1.3848h-0.5056v-3.0393h0.5056v1.2865h0.6264q0.0927,-1.3427,1.2725,-1.3427q0.6657,0,0.9677,0.3933t0.302,1.1798zM3.5421,14.4775q0,-0.6292,-0.1685,-0.9143t-0.5618,-0.2851q-0.3989,0,-0.5772,0.2907t-0.1784,0.9087q0,0.6124,0.177,0.9087t0.5506,0.2963q0.4101,0,0.5843,-0.2935t0.1742,-0.9115z`,\r\n    get width() { return getGridUnitWidth(1536); },\r\n    height: 16,\r\n    char: \"ю\"\r\n  },\r\n  'Xя': {\r\n    getPath: () => `M1.5028,14.7135l-0.8848,1.2865h-0.5702l0.9663,-1.323q-0.6994,-0.1433,-0.6994,-0.8764q0,-0.4185,0.3034,-0.6292t0.8848,-0.2107h1.2135v3.0393h-0.5056v-1.2865h-0.7079zM2.2107,13.3174h-0.6573q-0.3652,0,-0.5337,0.1292t-0.1685,0.3904q0,0.264,0.1503,0.3947t0.4986,0.1306h0.7107v-1.0449z`,\r\n    get width() { return getGridUnitWidth(1109); },\r\n    height: 16,\r\n    char: \"я\"\r\n  },\r\n  'XА': {\r\n    getPath: () => `M3.2781,16l-0.4522,-1.1573h-1.8034l-0.4551,1.1573h-0.5562l1.6152,-3.9579h0.6096l1.5899,3.9579h-0.5478zM1.9242,12.4466l-0.0253,0.0787q-0.0702,0.2331,-0.2079,0.5983l-0.5056,1.3006h1.4803l-0.5084,-1.3062q-0.0787,-0.1938,-0.1573,-0.4382z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"А\"\r\n  },\r\n  'XБ': {\r\n    getPath: () => `M3.4775,14.8399q0,0.5253,-0.3624,0.8427t-1,0.3174h-1.6433v-3.9579h2.6011v0.4382h-2.0646v1.236h1.073q0.6629,0,1.0295,0.2949t0.3666,0.8287zM2.9382,14.8455q0,-0.3399,-0.2303,-0.5211t-0.691,-0.1812h-1.0084v1.4326h1.0309q0.4607,0,0.6798,-0.191t0.2191,-0.5393z`,\r\n    get width() { return getGridUnitWidth(1344); },\r\n    height: 16,\r\n    char: \"Б\"\r\n  },\r\n  'XВ': {\r\n    getPath: () => `M3.5337,14.8848q0,0.5281,-0.3848,0.8216t-1.0702,0.2935h-1.6067v-3.9579h1.4382q1.3933,0,1.3933,0.9607q0,0.3511,-0.1966,0.5899t-0.5562,0.3202q0.4719,0.0562,0.7275,0.316t0.2556,0.6559zM2.764,13.0674q0,-0.3202,-0.2191,-0.4579t-0.6348,-0.1376h-0.9017v1.2528h0.9017q0.4298,0,0.6419,-0.1615t0.2121,-0.4958zM2.9916,14.8427q0,-0.6994,-0.9831,-0.6994h-1v1.427h1.0421q0.4916,0,0.7163,-0.1826t0.2247,-0.5449z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"В\"\r\n  },\r\n  'XГ': {\r\n    getPath: () => `M3.0084,12.0393v0.4382h-2v3.5197h-0.5365v-3.9579h2.5365z`,\r\n    get width() { return getGridUnitWidth(1109); },\r\n    height: 16,\r\n    char: \"Г\"\r\n  },\r\n  'XД': {\r\n    getPath: () => `M3.2978,15.5506h0.4916v1.5955h-0.5056v-1.1461h-2.736v1.1461h-0.5056v-1.5955h0.4045q0.2191,-0.2725,0.3722,-0.7654t0.257,-1.3104l0.1882,-1.4326h2.0337v3.5084zM2.7753,15.5506v-3.059h-1.0534l-0.1376,1.0337q-0.1039,0.7697,-0.2303,1.2556t-0.3034,0.7697h1.7247z`,\r\n    get width() { return getGridUnitWidth(1387); },\r\n    height: 16,\r\n    char: \"Д\"\r\n  },\r\n  'XЕ': {\r\n    getPath: () => `M0.4719,16v-3.9579h3.0028v0.4382h-2.4663v1.2697h2.2978v0.4326h-2.2978v1.3792h2.5815v0.4382h-3.118z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Е\"\r\n  },\r\n  'XЁ': {\r\n    getPath: () => `M0.4719,16v-3.9579h3.0028v0.4382h-2.4663v1.2697h2.2978v0.4326h-2.2978v1.3792h2.5815v0.4382h-3.118zM2.2921,11.7022v-0.5169h0.4579v0.5169h-0.4579zM1.1854,11.7022v-0.5169h0.4635v0.5169h-0.4635z`,\r\n    get width() { return getGridUnitWidth(1367); },\r\n    height: 16,\r\n    char: \"Ё\"\r\n  },\r\n  'XЖ': {\r\n    getPath: () => `M2.3876,14.1882q-0.1039,0,-0.2598,-0.0365t-0.2261,-0.0702l-1.1994,1.9185h-0.6236l1.4298,-2.177q-0.1348,-0.0983,-0.5028,-0.6292l-0.7949,-1.1517h0.5618l0.5758,0.8567q0.3118,0.4691,0.4466,0.6194t0.2584,0.2065t0.3343,0.0562v-1.7388h0.5365v1.7388q0.2107,0,0.3371,-0.0576t0.264,-0.2135t0.4382,-0.611l0.5758,-0.8567h0.5618l-0.7949,1.1517q-0.368,0.5309,-0.5028,0.6292l1.4298,2.177h-0.6236l-1.1994,-1.9185q-0.0702,0.0337,-0.2233,0.0702t-0.2626,0.0365v1.8118h-0.5365v-1.8118z`,\r\n    get width() { return getGridUnitWidth(1891); },\r\n    height: 16,\r\n    char: \"Ж\"\r\n  },\r\n  'XЗ': {\r\n    getPath: () => `M1.7444,16.0562q-0.573,0,-0.9438,-0.2261t-0.6124,-0.7514l0.4635,-0.2163q0.3343,0.764,1.073,0.764q0.4298,0,0.677,-0.1994t0.2472,-0.559q0,-0.3736,-0.2697,-0.5393t-0.8371,-0.1657h-0.1994v-0.4157h0.1994q0.5084,0,0.7514,-0.1671t0.243,-0.5126q0,-0.3006,-0.2037,-0.4733t-0.5829,-0.1728q-0.3539,0,-0.5955,0.1643t-0.3848,0.5295l-0.5,-0.1713q0.1966,-0.486,0.5674,-0.7219t0.9326,-0.236q0.5955,0,0.9494,0.2795t0.3539,0.7542q0,0.3567,-0.2022,0.5899t-0.5843,0.323q0.427,0.0646,0.6657,0.3104t0.2388,0.6166q0,0.5478,-0.389,0.8722t-1.0576,0.3244z`,\r\n    get width() { return getGridUnitWidth(1237); },\r\n    height: 16,\r\n    char: \"З\"\r\n  },\r\n  'XИ': {\r\n    getPath: () => `M0.4719,16v-3.9579h0.4831v2.5955q0,0.3202,-0.0225,0.7697l2.1067,-3.3652h0.6236v3.9579h-0.4775v-2.6292q0,-0.3427,0.0169,-0.7135l-2.0843,3.3427h-0.6461z`,\r\n    get width() { return getGridUnitWidth(1472); },\r\n    height: 16,\r\n    char: \"И\"\r\n  },\r\n  'XЙ': {\r\n    getPath: () => `M0.4719,16v-3.9579h0.4831v2.5955q0,0.3202,-0.0225,0.7697l2.1067,-3.3652h0.6236v3.9579h-0.4775v-2.6292q0,-0.3427,0.0169,-0.7135l-2.0843,3.3427h-0.6461zM2.0843,11.7022q-1,0,-1.0309,-0.8989h0.4607q0.0337,0.559,0.5702,0.559t0.5702,-0.559h0.4607q-0.0309,0.8989,-1.0309,0.8989z`,\r\n    get width() { return getGridUnitWidth(1472); },\r\n    height: 16,\r\n    char: \"Й\"\r\n  },\r\n  'XК': {\r\n    getPath: () => `M0.4719,12.0421h0.5365v1.7388q0.2107,0,0.3371,-0.0576t0.264,-0.2135t0.4382,-0.611l0.5758,-0.8567h0.5618l-0.7949,1.1517q-0.368,0.5309,-0.5028,0.6292l1.4298,2.177h-0.6236l-1.1994,-1.9185q-0.0702,0.0337,-0.2233,0.0702t-0.2626,0.0365v1.8118h-0.5365v-3.9579z`,\r\n    get width() { return getGridUnitWidth(1193); },\r\n    height: 16,\r\n    char: \"К\"\r\n  },\r\n  'XЛ': {\r\n    getPath: () => `M2.7837,12.4916h-1.1742l-0.1376,1.0337q-0.1433,1.118,-0.2767,1.6096t-0.3357,0.7008t-0.5674,0.2093q-0.1629,0,-0.2416,-0.0281v-0.427q0.0534,0.0197,0.1573,0.0197q0.1489,0,0.243,-0.0913t0.1756,-0.3034t0.1629,-0.6292t0.1629,-1.0281t0.1994,-1.5154h2.1545v3.9579h-0.5225v-3.5084z`,\r\n    get width() { return getGridUnitWidth(1344); },\r\n    height: 16,\r\n    char: \"Л\"\r\n  },\r\n  'XМ': {\r\n    getPath: () => `M3.8371,16v-2.6404q0,-0.4382,0.0253,-0.8427q-0.1376,0.5028,-0.2472,0.7865l-1.0225,2.6966h-0.3764l-1.0365,-2.6966l-0.1573,-0.4775l-0.0927,-0.309l0.0084,0.3118l0.0112,0.5309v2.6404h-0.4775v-3.9579h0.7051l1.0534,2.7444q0.0562,0.1657,0.1081,0.3553t0.0688,0.2739q0.0225,-0.1124,0.0941,-0.3413t0.0969,-0.2879l1.0337,-2.7444h0.6882v3.9579h-0.4831z`,\r\n    get width() { return getGridUnitWidth(1706); },\r\n    height: 16,\r\n    char: \"М\"\r\n  },\r\n  'XН': {\r\n    getPath: () => `M3.1489,16v-1.8343h-2.1404v1.8343h-0.5365v-3.9579h0.5365v1.6742h2.1404v-1.6742h0.5365v3.9579h-0.5365z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Н\"\r\n  },\r\n  'XО': {\r\n    getPath: () => `M4.1994,14.0028q0,0.6208,-0.2374,1.0871t-0.6812,0.7163t-1.0478,0.25q-0.6096,0,-1.052,-0.2472t-0.6756,-0.7149t-0.2331,-1.0913q0,-0.9494,0.5197,-1.4846t1.4466,-0.5351q0.6039,0,1.0478,0.2402t0.6784,0.698t0.2346,1.0815zM3.6517,14.0028q0,-0.7388,-0.3694,-1.1601t-1.0435,-0.4213q-0.6798,0,-1.0506,0.4157t-0.3708,1.1657q0,0.7444,0.375,1.1812t1.0407,0.4368q0.6854,0,1.052,-0.4228t0.3666,-1.1952z`,\r\n    get width() { return getGridUnitWidth(1593); },\r\n    height: 16,\r\n    char: \"О\"\r\n  },\r\n  'XП': {\r\n    getPath: () => `M3.1433,16v-3.5056h-2.1404v3.5056h-0.5365v-3.9579h3.2135v3.9579h-0.5365z`,\r\n    get width() { return getGridUnitWidth(1472); },\r\n    height: 16,\r\n    char: \"П\"\r\n  },\r\n  'XР': {\r\n    getPath: () => `M3.5337,13.2331q0,0.5618,-0.3666,0.8933t-0.9958,0.3315h-1.1629v1.5421h-0.5365v-3.9579h1.6657q0.6657,0,1.0309,0.3118t0.3652,0.8792zM2.9944,13.2388q0,-0.7669,-0.9213,-0.7669h-1.0646v1.5618h1.0871q0.8989,0,0.8989,-0.7949z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Р\"\r\n  },\r\n  'XС': {\r\n    getPath: () => `M2.2247,12.4213q-0.6573,0,-1.0225,0.4228t-0.3652,1.1587q0,0.7275,0.3806,1.1699t1.0295,0.4424q0.8315,0,1.25,-0.823l0.4382,0.2191q-0.2444,0.5112,-0.6868,0.7781t-1.0267,0.2669q-0.5983,0,-1.0351,-0.2486t-0.6657,-0.7107t-0.2289,-1.0941q0,-0.9466,0.5112,-1.4831t1.4157,-0.5365q0.632,0,1.0562,0.2472t0.6236,0.7331l-0.5084,0.1685q-0.1376,-0.3455,-0.4424,-0.5281t-0.7233,-0.1826z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"С\"\r\n  },\r\n  'XТ': {\r\n    getPath: () => `M2.0225,12.4803v3.5197h-0.5337v-3.5197h-1.3596v-0.4382h3.2528v0.4382h-1.3596z`,\r\n    get width() { return getGridUnitWidth(1251); },\r\n    height: 16,\r\n    char: \"Т\"\r\n  },\r\n  'XУ': {\r\n    getPath: () => `M0.9326,16.0562q-0.1742,0,-0.3638,-0.0534t-0.3188,-0.1433l0.2275,-0.4045q0.264,0.1657,0.4663,0.1657q0.1433,0,0.2402,-0.0548t0.1952,-0.1882t0.3848,-0.6559l-1.6096,-2.6798h0.6124l1.2612,2.2022l1.0787,-2.2022h0.5758l-1.6208,3.0646q-0.2388,0.4494,-0.3876,0.6208t-0.3244,0.25t-0.4171,0.0787z`,\r\n    get width() { return getGridUnitWidth(1301); },\r\n    height: 16,\r\n    char: \"У\"\r\n  },\r\n  'XФ': {\r\n    getPath: () => `M4.0421,13.9326q0,0.4298,-0.1784,0.7626t-0.5126,0.5154t-0.7837,0.1826h-0.1124v0.6376h-0.5365v-0.6376h-0.1124q-0.4522,0,-0.7865,-0.184t-0.5112,-0.5169t-0.177,-0.7598q0,-0.6685,0.3919,-1.0379t1.1138,-0.3694h0.0815v-0.5112h0.5365v0.5112h0.0787q0.7247,0,1.1166,0.3708t0.3919,1.0365zM3.5028,13.9438q0,-1.0309,-1.0337,-1.0309h-0.014v2.0955h0.0365q0.4888,0,0.75,-0.2697t0.2612,-0.7949zM0.8708,13.9438q0,0.5253,0.2612,0.7949t0.75,0.2697h0.0365v-2.0955h-0.0253q-0.5112,0,-0.7669,0.2528t-0.2556,0.7781z`,\r\n    get width() { return getGridUnitWidth(1557); },\r\n    height: 16,\r\n    char: \"Ф\"\r\n  },\r\n  'XХ': {\r\n    getPath: () => `M3.1236,16l-1.1882,-1.7303l-1.2135,1.7303h-0.5927l1.5056,-2.0562l-1.3904,-1.9017h0.5927l1.1011,1.5534l1.0702,-1.5534h0.5927l-1.3539,1.882l1.4691,2.0758h-0.5927z`,\r\n    get width() { return getGridUnitWidth(1366); },\r\n    height: 16,\r\n    char: \"Х\"\r\n  },\r\n  'XЦ': {\r\n    getPath: () => `M4.1489,15.5506v1.5955h-0.5056v-1.1461h-3.1713v-3.9579h0.5365v3.5084h2.1264v-3.5084h0.5225v3.5084h0.4916z`,\r\n    get width() { return getGridUnitWidth(1515); },\r\n    height: 16,\r\n    char: \"Ц\"\r\n  },\r\n  'XЧ': {\r\n    getPath: () => `M2.8315,14.573q-0.4354,0.0955,-0.691,0.1292t-0.4551,0.0337q-0.6236,0,-0.9298,-0.2542t-0.3062,-0.7711v-1.6685h0.5337v1.6124q0,0.3455,0.1826,0.4972t0.559,0.1517q0.4185,0,1.1067,-0.1376v-2.1236h0.5337v3.9579h-0.5337v-1.427z`,\r\n    get width() { return getGridUnitWidth(1365); },\r\n    height: 16,\r\n    char: \"Ч\"\r\n  },\r\n  'XШ': {\r\n    getPath: () => `M0.4719,16v-3.9579h0.5365v3.5084h1.3736v-3.5084h0.5225v3.5084h1.3736v-3.5084h0.5225v3.9579h-4.3287z`,\r\n    get width() { return getGridUnitWidth(1877); },\r\n    height: 16,\r\n    char: \"Ш\"\r\n  },\r\n  'XЩ': {\r\n    getPath: () => `M5.1657,15.5506v1.5955h-0.5056v-1.1461h-4.1882v-3.9579h0.5365v3.5084h1.3118v-3.5084h0.5225v3.5084h1.309v-3.5084h0.5225v3.5084h0.4916z`,\r\n    get width() { return getGridUnitWidth(1920); },\r\n    height: 16,\r\n    char: \"Щ\"\r\n  },\r\n  'XЪ': {\r\n    getPath: () => `M1.9551,13.7163h0.9045q0.6629,0,1.0295,0.2949t0.3666,0.8287q0,0.5253,-0.3624,0.8427t-1,0.3174h-1.4747v-3.5197h-1.2893v-0.4382h1.8258v1.6742zM3.7163,14.8455q0,-0.3399,-0.2303,-0.5211t-0.691,-0.1812h-0.8399v1.4326h0.8624q0.4607,0,0.6798,-0.191t0.2191,-0.5393z`,\r\n    get width() { return getGridUnitWidth(1621); },\r\n    height: 16,\r\n    char: \"Ъ\"\r\n  },\r\n  'XЫ': {\r\n    getPath: () => `M3.4775,14.8399q0,0.5253,-0.3624,0.8427t-1,0.3174h-1.6433v-3.9579h0.5365v1.6742h1.073q0.6629,0,1.0295,0.2949t0.3666,0.8287zM2.9382,14.8455q0,-0.3399,-0.2303,-0.5211t-0.691,-0.1812h-1.0084v1.4326h1.0309q0.4607,0,0.6798,-0.191t0.2191,-0.5393zM4.0843,16v-3.9579h0.5365v3.9579h-0.5365z`,\r\n    get width() { return getGridUnitWidth(1813); },\r\n    height: 16,\r\n    char: \"Ы\"\r\n  },\r\n  'XЬ': {\r\n    getPath: () => `M3.4775,14.8399q0,0.5253,-0.3624,0.8427t-1,0.3174h-1.6433v-3.9579h0.5365v1.6742h1.073q0.6629,0,1.0295,0.2949t0.3666,0.8287zM2.9382,14.8567q0,-0.3399,-0.2303,-0.5239t-0.691,-0.184h-1.0084v1.427h1.0309q0.8989,0,0.8989,-0.7191z`,\r\n    get width() { return getGridUnitWidth(1344); },\r\n    height: 16,\r\n    char: \"Ь\"\r\n  },\r\n  'XЭ': {\r\n    getPath: () => `M2.0028,12.4213q-0.427,0,-0.7331,0.1896t-0.4326,0.5211l-0.5084,-0.1685q0.1994,-0.486,0.6236,-0.7331t1.0562,-0.2472q0.9045,0,1.4157,0.5365t0.5112,1.4831q0,0.6264,-0.2275,1.0899t-0.6615,0.7135t-1.0379,0.25q-1.1966,0,-1.7135,-1.0449l0.4382,-0.2191q0.1938,0.3933,0.5169,0.6081t0.7303,0.2149q0.5983,0,0.9733,-0.3806t0.4284,-1.0267h-1.8371v-0.4326h1.8371q-0.059,-0.6433,-0.4199,-0.9986t-0.9593,-0.3553z`,\r\n    get width() { return getGridUnitWidth(1472); },\r\n    height: 16,\r\n    char: \"Э\"\r\n  },\r\n  'XЮ': {\r\n    getPath: () => `M5.5365,14.0028q0,0.6208,-0.2247,1.0885t-0.6461,0.7163t-0.9831,0.2486q-0.8287,0,-1.316,-0.5028t-0.5295,-1.3876h-0.8287v1.8343h-0.5365v-3.9579h0.5365v1.6742h0.8371q0.0758,-0.8202,0.5576,-1.2767t1.2851,-0.4565q0.8708,0,1.3596,0.5379t0.4888,1.4817zM4.9888,14.0028q0,-0.7388,-0.3413,-1.1601t-0.9593,-0.4213q-0.6264,0,-0.9677,0.4157t-0.3413,1.1657q0,0.7444,0.3469,1.1812t0.9565,0.4368q0.6264,0,0.9663,-0.4199t0.3399,-1.198z`,\r\n    get width() { return getGridUnitWidth(2069); },\r\n    height: 16,\r\n    char: \"Ю\"\r\n  },\r\n  'XЯ': {\r\n    getPath: () => `M0.2697,16l1.1236,-1.7051q-0.4522,-0.0787,-0.7093,-0.3792t-0.257,-0.7416q0,-0.5337,0.3624,-0.8329t1.0337,-0.2992h1.8624v3.9579h-0.5365v-1.6433h-1.2331l-1.0281,1.6433h-0.618zM0.9663,13.1798q0,0.3567,0.2317,0.5548t0.6559,0.198h1.2949v-1.4607h-1.2725q-0.441,0,-0.6756,0.1812t-0.2346,0.5267z`,\r\n    get width() { return getGridUnitWidth(1479); },\r\n    height: 16,\r\n    char: \"Я\"\r\n  }\r\n};\r\n\r\nfor (const letter of Object.values(alphabetData)) {\r\n  letter.specialRule = \"external glyph\";\r\n  letter.leftSideBearing = parseFloat((defaultLeftSideBearing / fontUnitToGridUnitDivisor).toFixed(7));\r\n  letter.rightSideBearing = parseFloat((defaultRightSideBearing / fontUnitToGridUnitDivisor).toFixed(7));\r\n}\r\n\r\nexport { alphabetData };","/**\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n\n// Replaced at build time by Vite's define (also available in Vitest and VitePress).\n// Falls back to empty string when imported outside Vite (e.g. bare Node).\nexport const LIB_VERSION = typeof __LIB_VERSION__ !== 'undefined' ? __LIB_VERSION__ : '';\n\n/**\n * Known option keys (kebab-case) that are explicitly processed in #processOptions().\n * Any option key NOT in this set will be passed through as-is (for unknown SVG attributes like stroke-dasharray).\n */\nexport const KNOWN_OPTION_KEYS = new Set([\n  'stroke-width', 'dot-extra-width', 'sdot-extra-width', 'dot-width', 'sdot-width',\n  'char-space', 'word-space', 'external-glyph-space',\n  'margin', 'margin-top', 'margin-bottom', 'margin-left', 'margin-right',\n  'min-width', 'center',\n  'crop', 'crop-top', 'crop-bottom', 'crop-left', 'crop-right',\n  'grid', 'grid-color', 'grid-major-color', 'grid-medium-color', 'grid-minor-color',\n  'grid-sky-color', 'grid-earth-color',\n  'grid-stroke-width', 'grid-major-stroke-width', 'grid-medium-stroke-width',\n  'grid-minor-stroke-width', 'grid-sky-stroke-width', 'grid-earth-stroke-width',\n  'color', 'background', 'background-top', 'background-mid', 'background-bottom',\n  'text', 'svg-desc', 'svg-title', 'svg-height', 'error-placeholder',\n  'key'\n]);\n\n/**\n * Returns false for event handler attribute names (on*) or names containing\n * characters outside the safe allowlist to prevent XSS.\n */\nexport const isSafeAttributeName = (name) =>\n  /^[a-zA-Z][a-zA-Z0-9-]*$/.test(name) && !/^on/i.test(name);\n\n/**\n * Escapes HTML special characters to prevent XSS in SVG output.\n */\nexport const escapeHtml = (str) => String(str)\n  .replace(/&/g, '&amp;')\n  .replace(/</g, '&lt;')\n  .replace(/>/g, '&gt;')\n  .replace(/\"/g, '&quot;')\n  .replace(/'/g, '&#39;');\n\n/**\n * Converts a camelCase string to kebab-case.\n * e.g., strokeWidth → stroke-width, gridSkyColor → grid-sky-color\n * Single-word keys (color, grid, margin) pass through unchanged.\n */\nexport const camelToKebab = (str) => str.replace(/[A-Z]/g, m => '-' + m.toLowerCase());\n\n/**\n * Serializes one option VALUE for DSL emission (`[key=value]` brackets).\n * A value carrying characters the DSL grammar would otherwise claim (`;`\n * splits options and parts, `]` ends the bracket, `[` opens one, `|` splits\n * groups and the global prefix, quotes confuse the value grammar) or\n * leading/trailing whitespace (trimmed on parse) is wrapped in double\n * quotes with inner `\"` escaped as `\\\"` — the exact spelling the option\n * parser strips and unescapes on the way back in. Everything else emits\n * byte-unchanged. Lives here because both the builder (toString) and the\n * parser (`;;`-overlay rebuild) emit option values, and the builder already\n * imports the parser. Known residue: a backslash abutting the escaping\n * (`a\\\"b` class, trailing `\\`) cannot round-trip — the parser unescapes\n * ONLY `\\\"`.\n */\nexport const serializeOptionValue = (value) => {\n  const str = String(value);\n  return /[;\\[\\]|\"']/.test(str) || /^\\s|\\s$/.test(str)\n    ? `\"${str.replace(/\"/g, '\\\\\"')}\"`\n    : str;\n};\n\n/**\n * Bracket-content grammar (a regex SOURCE fragment) shared by every site\n * that tokenizes or (re-)extracts one `[option]` bracket: a quoted span\n * (\"...\" or '...', with \\-escapes) may carry `]` `;` `|` `[` — mirroring\n * the option parser's value grammar so tokenization and value parsing agree\n * on where a bracket ends (a quoted `]` used to truncate the bracket).\n * Each step commits through an atomic lookahead ((?=(?<atom>...))\\k<atom>):\n * ECMAScript lookaheads discard their interior choice points once matched,\n * so an UNCLOSED bracket fails in LINEAR time — the plain alternation form\n * backtracks exponentially there (measured ~2s at 40 stray quotes, hours at\n * 60). Trade-off: an unclosed bracket whose only `]`s sit inside complete\n * quoted spans no longer half-tokenizes; it falls through whole to the\n * malformed/unknown warn paths (visible, not silently truncated).\n * Embed at most once per composed regex (the group is named); the counterpart\n * of [[serializeOptionValue]] above.\n */\nexport const OPTION_BRACKET_CONTENT = String.raw`(?:(?=(?<atom>\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|[^\\]]))\\k<atom>)*`;\n\n/**\n * Generates a random 8-character key for element identity.\n * ~2.8 trillion combinations — negligible collision probability.\n */\nexport function generateKey() {\n  const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';\n  let key = '';\n  for (let i = 0; i < 8; i++) key += chars[Math.floor(Math.random() * 36)];\n  return key;\n}\n\n/**\n * Builder-canvas option keys (kebab-case, as written in the DSL) that take\n * effect ONLY in the global `[opts]||` bracket. Written at group `[opts]|`,\n * character `[opts]`, or part `[opts]>` level they are inert, so the parser\n * warns MISPLACED_GLOBAL_OPTION and drops the key (audit N-2).\n *\n * Deliberately curated, NOT INTERNAL_OPTIONS verbatim:\n * - `text` is excluded: it is an unimplemented stub at EVERY level including\n *   global (the deferred `{text}` overlay), so it is not \"misplaced\" anywhere.\n * - The dot-sizing family (dot-width/dot-extra-width/sdot-*) is excluded: it\n *   genuinely applies per element via option inheritance.\n * - x/y/key and kerning are excluded: positioning and identity, handled by\n *   their own extraction logic.\n */\nexport const GLOBAL_ONLY_OPTION_KEYS = new Set([\n  'margin', 'margin-top', 'margin-bottom', 'margin-left', 'margin-right',\n  'crop', 'crop-top', 'crop-bottom', 'crop-left', 'crop-right',\n  'grid', 'grid-color', 'grid-major-color', 'grid-medium-color',\n  'grid-minor-color', 'grid-sky-color', 'grid-earth-color',\n  'grid-stroke-width', 'grid-major-stroke-width', 'grid-medium-stroke-width',\n  'grid-minor-stroke-width', 'grid-sky-stroke-width', 'grid-earth-stroke-width',\n  'background', 'background-top', 'background-mid', 'background-bottom',\n  'center', 'min-width', 'char-space', 'word-space', 'external-glyph-space',\n  'svg-title', 'svg-desc', 'svg-height', 'error-placeholder'\n]);\n\n/**\n * Options that should NOT be rendered as SVG attributes.\n *\n * Builder-level options: handled by SVG construction logic (margins, grid, cropping, etc.)\n * Element-level positioning: handled by element positioning logic (x, y, kerning)\n * Internal calculation options: used for calculations but not rendered (dot family: dotExtraWidth, sdotExtraWidth, dotWidth, sdotWidth)\n *\n * Note: strokeWidth is NOT here - it's a multi-level option like 'color'\n * that can appear at both global and element levels as SVG attributes.\n */\nexport const INTERNAL_OPTIONS = new Set([\n  // Grid options (builder-level only)\n  'grid',\n  'gridSkyColor',\n  'gridEarthColor',\n  'gridMajorColor',\n  'gridMediumColor',\n  'gridMinorColor',\n  'gridSkyStrokeWidth',\n  'gridEarthStrokeWidth',\n  'gridMajorStrokeWidth',\n  'gridMediumStrokeWidth',\n  'gridMinorStrokeWidth',\n\n  // Cropping and margins (builder-level only)\n  'cropTop',\n  'cropBottom',\n  'cropLeft',\n  'cropRight',\n  'marginTop',\n  'marginBottom',\n  'marginLeft',\n  'marginRight',\n\n  // Internal calculation options\n  'dotExtraWidth',\n  'sdotExtraWidth',\n  'dotWidth',\n  'sdotWidth',\n\n  // Builder-level settings\n  'background',\n  'backgroundTop',\n  'backgroundMid',\n  'backgroundBottom',\n  'charSpace',\n  'wordSpace',\n\n  'externalGlyphSpace',\n  'minWidth',\n  'center',\n  'autoVertical',\n  'cropCompact',\n  'text',\n  'svgDesc',\n  'svgTitle',\n  'svgHeight',\n  'errorPlaceholder',\n\n  // Element identity (extracted to node.key before option processing)\n  'key',\n\n  // Element positioning (handled by positioning logic, not SVG attributes)\n  'x',\n  'y',\n  'relativeKerning',\n  'absoluteKerning'\n]);\n\n/**\n * Upper bound for the absolute `dot-width` / `sdot-width` options (a rendered\n * dot diameter in glyph units). Mirrors the `stroke-width` ceiling so an\n * absolute dot cannot exceed what the relative `dot-extra-width` knob can\n * already reach. The lower bound is 0 (an invisible dot; no crash).\n */\nexport const DOT_WIDTH_MAX = 1.5;\n\n/**\n * The complete warning-code vocabulary. Single source of truth: every warning\n * emitted on `builder.warnings` references `WARNING_CODES.X` rather than an inline\n * literal, so the set is typo-proof and discoverable in one place.\n *\n * Verb convention (see `.claude/plans/2026-06-24-warning-code-vocabulary-design.md`):\n *   MALFORMED_   input did not parse in the required shape (a FORMAT failure;\n *                INVALID_/OUT_OF_RANGE are reserved for future VALUE/range checks)\n *   MISPLACED_   a well-formed token in the wrong position\n *   MULTIPLE_    more than one where one is allowed (resolved by picking the first)\n *   DUPLICATE_   the same identifier twice\n *   UNKNOWN_     an unrecognized reference\n *   DROPPED_     something discarded (first-wins / merge)\n *   UNSUPPORTED_ valid, but not implemented yet\n *   NOOP_        a mutation call had no effect\n *   …_AS_PART    an illegal operand in a ;-part slot\n *\n * Structural attachment points use group/glyph/part (matches `toJSON()`); the\n * linguistic indicator concepts use word/character (a word-indicator sets a\n * word's part-of-speech; a space-group has none).\n */\nexport const WARNING_CODES = Object.freeze({\n  // malformed-syntax: input did not parse in the required shape\n  MALFORMED_GLOBAL_OPTIONS: 'MALFORMED_GLOBAL_OPTIONS',\n  MALFORMED_GROUP_OPTIONS: 'MALFORMED_GROUP_OPTIONS',\n  MALFORMED_WORD_INDICATOR: 'MALFORMED_WORD_INDICATOR',\n  MALFORMED_COORDINATES: 'MALFORMED_COORDINATES',\n  MALFORMED_KERNING_VALUE: 'MALFORMED_KERNING_VALUE',\n  // misplaced: a well-formed token in the wrong position\n  MISPLACED_HEAD_MARKER: 'MISPLACED_HEAD_MARKER',\n  MISPLACED_CHARACTER_INDICATOR: 'MISPLACED_CHARACTER_INDICATOR',\n  // a well-formed word-level indicator (`;;`) on a target that cannot carry\n  // one (a space word)\n  MISPLACED_WORD_INDICATOR: 'MISPLACED_WORD_INDICATOR',\n  MISPLACED_PART_OPTION: 'MISPLACED_PART_OPTION',\n  MISPLACED_CHARACTER_OPTION: 'MISPLACED_CHARACTER_OPTION',\n  MISPLACED_GROUP_OPTION: 'MISPLACED_GROUP_OPTION',\n  // a global-only (builder-canvas) option KEY inside a group/character/part\n  // bracket: the key is well-formed but its scope is the whole SVG\n  MISPLACED_GLOBAL_OPTION: 'MISPLACED_GLOBAL_OPTION',\n  // a coordinate (`:x,y`) or an option (`[opts]` at any scope) on a TSP/QSP\n  // space: a space is a pure word-separator with no ink to position or style,\n  // so the decoration is dropped and the space keeps its identity (ZSA is\n  // content and is exempt; use it for a positionable/styleable blank)\n  MISPLACED_SPACE_DECORATION: 'MISPLACED_SPACE_DECORATION',\n  // an indicator part that precedes default-positioned content in a glyph's\n  // part list: an indicator is only meaningful in the trailing indicator run\n  // (BASE;INDICATOR), so the misplaced indicator is dropped from render and\n  // serialization while the character still renders. Content explicitly\n  // positioned at a non-origin `:x,y` does not convict a preceding indicator\n  // (a compound indicator's decomposed anatomy must round-trip), and neither\n  // does an unclassifiable part (unknown code, error node).\n  MISPLACED_INDICATOR_PART: 'MISPLACED_INDICATOR_PART',\n  // a space code (TSP/QSP) in a `;`-part slot: a space is a word-level\n  // separator, never a character part, so the space part is dropped from\n  // render and serialization while the character still renders. A single-part\n  // space glyph IS the space itself and is untouched; ZSA is content (a\n  // positionable inkless shape) and is exempt.\n  MISPLACED_SPACE: 'MISPLACED_SPACE',\n  // too-many / duplicate\n  MULTIPLE_HEAD_MARKERS: 'MULTIPLE_HEAD_MARKERS',\n  MULTIPLE_OPTION_BRACKETS: 'MULTIPLE_OPTION_BRACKETS',\n  DUPLICATE_KEY: 'DUPLICATE_KEY',\n  // unrecognized reference\n  UNKNOWN_CODE: 'UNKNOWN_CODE',\n  // discarded\n  DROPPED_WORD_INDICATOR: 'DROPPED_WORD_INDICATOR',\n  // unsupported feature\n  UNSUPPORTED_TEXT_BLOCKS: 'UNSUPPORTED_TEXT_BLOCKS',\n  // no-op mutation\n  NOOP_INDICATOR_MUTATION: 'NOOP_INDICATOR_MUTATION',\n  // illegal operand in a ;-part slot (also used as an internal part.errorCode)\n  COMPOSITE_AS_PART: 'COMPOSITE_AS_PART',\n  WORD_AS_PART: 'WORD_AS_PART',\n  // illegal operand in a ;; word-indicator slot: a recognized non-indicator\n  // (a real base) supplied where a word-level indicator is required\n  NON_INDICATOR_AS_WORD_INDICATOR: 'NON_INDICATOR_AS_WORD_INDICATOR',\n  // same rule one level down: a recognized non-indicator supplied to the\n  // glyph-level applyIndicators() slot (the API's character-indicator channel)\n  NON_INDICATOR_AS_CHARACTER_INDICATOR: 'NON_INDICATOR_AS_CHARACTER_INDICATOR',\n});\n\n/**\n * Maps semantic indicator types to their root B-codes.\n * When overriding indicators, the semantic root is preserved by default\n * unless the new indicators include a semantic indicator or strip-semantic (!) is used.\n */\nexport const SEMANTIC_INDICATOR_ROOTS = {\n  thing: 'B97',\n  abstract: 'B6436'\n};\n\n/**\n * Maximum allowed depth for element nesting and parser recursion.\n * Prevents stack overflow on pathological or self-referential definitions.\n */\nexport const MAX_RECURSION_DEPTH = 50;\n\n/**\n * Approximate minimum y-coordinate for content bounds in external glyphs\n * and text fallbacks. Actual values vary per glyph; this is used for\n * effectiveBounds estimation only.\n */\nexport const APPROX_GLYPH_MIN_Y = 11;\n","/** \r\n * This Source Code Form is subject to the terms of the Mozilla Public\r\n * License, v. 2.0. If a copy of the MPL was not distributed with this\r\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\r\n */\r\n\r\nimport { alphabetData } from \"../external-font-data/liberation-sans-svg-path-data.js\";\r\nimport { escapeHtml, APPROX_GLYPH_MIN_Y } from \"./bliss-constants.js\";\r\n\r\n/**\r\n * Checks if a character has hardcoded path data available.\r\n *\r\n * @param {string} char - The character to check.\r\n * @return {boolean} True if path data exists, false if text fallback would be used.\r\n */\r\nexport function hasPathData(char) {\r\n  return !!alphabetData[`X${char}`];\r\n}\r\n\r\n/**\r\n * Creates a text fallback glyph for characters without hardcoded path data.\r\n * Uses SVG <text> element which relies on system fonts.\r\n *\r\n * @param {string} str - The character or string to render.\r\n * @return {object} A glyph object compatible with createExternalGlyph.\r\n */\r\nexport function createTextFallbackGlyph(str) {\r\n  // Use known character widths where available, generous fallback for unknown.\r\n  // Users may need manual kerning/cropping for precise layouts with unknown chars.\r\n  const unknownCharWidth = 2.5;\r\n  const defaultCharSpace = 272 / 356; // ~0.764\r\n  const charWidths = [...str].reduce((sum, char) => {\r\n    const glyphData = alphabetData[`X${char}`];\r\n    return sum + (glyphData ? glyphData.width : unknownCharWidth);\r\n  }, 0);\r\n  const charSpacing = (str.length - 1) * defaultCharSpace;\r\n  const width = charWidths + charSpacing;\r\n  const approxMinY = APPROX_GLYPH_MIN_Y;\r\n  const maxY = 16;\r\n\r\n  return {\r\n    getPath: (x, y, options = {}) => {\r\n      const fill = escapeHtml(options.color || '#000000');\r\n      const safeStr = escapeHtml(str);\r\n      const closePath = `\"/>`;\r\n      const openPath = `<path d=\"`;\r\n      const baseline = 16;\r\n      const textX = x - 0.3;\r\n      const textY = y + baseline;\r\n      return `${closePath}<text x=\"${textX}\" y=\"${textY}\" font-family=\"Liberation Sans, sans-serif\" font-size=\"5.7\" stroke-width=\"0\" fill=\"${fill}\">${safeStr}</text>${openPath}`;\r\n    },\r\n    width,\r\n    y: approxMinY,\r\n    height: maxY - approxMinY,\r\n    isExternalGlyph: true,\r\n    // Single-char fallback IS a single glyph: `char` + `glyphCode`,\r\n    // parallel to single X-codes.\r\n    // Multi-char fallback is a composite carrying multiple chars: no\r\n    // `char`, no `glyphCode`, but a `codeName` (alias-style identifier).\r\n    ...(str.length === 1\r\n      ? { char: str, glyphCode: `XTXT_${str}` }\r\n      : { codeName: `XTXT_${str}` }),\r\n  };\r\n}\r\n\r\n/**\r\n * Create an invisible zero-sized anchor element with zero width and height.\r\n * Used to prevent normalization when explicit positioning is needed.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createZeroSizedAnchor() {\r\n  return {\r\n    getPath: () => '',\r\n    width: 0,\r\n    height: 0,\r\n  };\r\n}\r\n\r\n/**\r\n * Create an invisible space glyph.\r\n * Width is 0 (invisible). advanceWidth controls cursor movement.\r\n * @param {number} advanceWidth - Default advance width (may be overridden by BlissSVGBuilder based on options)\r\n * @returns {Object} - An object with getPath, width, height, and advanceWidth.\r\n */\r\nexport function createSpace(advanceWidth) {\r\n  return {\r\n    getPath: () => '',\r\n    width: 0,\r\n    height: 0,\r\n    advanceWidth,\r\n  };\r\n}\r\n\r\n/**\r\n * Create a circle object with a specified radius.\r\n * @param {number} radius - The radius of the circle.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createCircle(radius) {\r\n  const initialX = 0;\r\n  const initialY = radius;\r\n\r\n  return {\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}a${radius},${radius} 0 1,1 ${radius * 2},0a${radius},${radius} 0 1,1 ${-radius * 2},0`;\r\n    },\r\n    width: radius * 2,\r\n    height: radius * 2,\r\n  };\r\n}\r\n\r\n/**\r\n * Create a half circle object with a specified radius and radial direction.\r\n * @param {number} radius - The radius of the half circle.\r\n * @param {'N'|'S'|'W'|'E'} radialDirection - The direction of the half circle's arc.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createHalfCircle(radius, radialDirection) {\r\n  const directionMapping = {\r\n    'N': { initialX: 0, initialY: radius, endX: radius * 2, endY: 0, sweepFlag: 1, width: radius * 2, height: radius },\r\n    'S': { initialX: 0, initialY: 0, endX: radius * 2, endY: 0, sweepFlag: 0, width: radius * 2, height: radius },\r\n    'W': { initialX: radius, initialY: 0, endX: 0, endY: radius * 2, sweepFlag: 0, width: radius, height: radius * 2 },\r\n    'E': { initialX: 0, initialY: 0, endX: 0, endY: radius * 2, sweepFlag: 1, width: radius, height: radius * 2 },\r\n  };\r\n\r\n  const { initialX, initialY, endX, endY, sweepFlag, width, height } = directionMapping[radialDirection];\r\n\r\n  return {\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}a${radius},${radius} 0 1,${sweepFlag} ${endX},${endY}`;\r\n    },\r\n    width,\r\n    height,\r\n  };\r\n}\r\n\r\n/**\r\n * Create a quarter circle object with a specified radius and radial direction.\r\n * @param {number} radius - The radius of the quarter circle.\r\n * @param {'NW'|'NE'|'SW'|'SE'} radialDirection - The direction of the quarter circle's arc.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createQuarterCircle(radius, radialDirection) {\r\n  const directionMapping = {\r\n    'NW': { initialX: 0, initialY: radius, endX: radius, endY: -radius, sweepFlag: 1 },\r\n    'NE': { initialX: 0, initialY: 0, endX: radius, endY: radius, sweepFlag: 1 },\r\n    'SW': { initialX: 0, initialY: 0, endX: radius, endY: radius, sweepFlag: 0 },\r\n    'SE': { initialX: 0, initialY: radius, endX: radius, endY: -radius, sweepFlag: 0 },\r\n  };\r\n\r\n  const { initialX, initialY, endX, endY, sweepFlag } = directionMapping[radialDirection];\r\n\r\n  return {\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}a${radius},${radius} 0 0,${sweepFlag} ${endX},${endY}`;\r\n    },\r\n    width: radius,\r\n    height: radius,\r\n  };\r\n}\r\n\r\n/**\r\n * Create an open circle object with a specified radius and opening direction.\r\n * @param {number} radius - The radius of the open circle.\r\n * @param {'NW'|'NE'|'SW'|'SE'} openingDirection - The direction of the open circle's opening.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createOpenCircle(radius, openingDirection) {\r\n  const directionMapping = {\r\n    'NW': { initialX: radius, initialY: 0, endX: -radius, endY: radius, sweepFlag: 1 },\r\n    'NE': { initialX: radius * 2, initialY: radius, endX: -radius, endY: -radius, sweepFlag: 1 },\r\n    'SW': { initialX: 0, initialY: radius, endX: radius, endY: radius, sweepFlag: 1 },\r\n    'SE': { initialX: radius, initialY: radius * 2, endX: radius, endY: -radius, sweepFlag: 1 },\r\n  };\r\n\r\n  const { initialX, initialY, endX, endY, sweepFlag } = directionMapping[openingDirection];\r\n\r\n  return {\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}a${radius},${radius} 0 1,${sweepFlag} ${endX},${endY}`;\r\n    },\r\n    width: radius * 2,\r\n    height: radius * 2,\r\n  };\r\n}\r\n\r\n/**\r\n * Create an wave object with a specified length and radial direction.\r\n * @param {number} length - The width (N/S) or height (W/E) of the wave.\r\n * @param {'N'|'S'|'W'|'E'} radialDirection - The direction of the leftmost (W/E) or uppermost (N/S) half-wave's arc.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createWave(length, radialDirection) {\r\n  const radius = length * 5 / 8 / 2;\r\n\r\n  const directionMapping = {\r\n    'N': { initialX: 0, initialY: length / 8, endX: length / 2, endY: 0, firstSweepFlag: 1, secondSweepFlag: 0, width: length, height: length / 4 },\r\n    'S': { initialX: 0, initialY: length / 8, endX: length / 2, endY: 0, firstSweepFlag: 0, secondSweepFlag: 1, width: length, height: length / 4 },\r\n    'W': { initialX: length / 8, initialY: 0, endX: 0, endY: length / 2, firstSweepFlag: 0, secondSweepFlag: 1, width: length / 4, height: length },\r\n    'E': { initialX: length / 8, initialY: 0, endX: 0, endY: length / 2, firstSweepFlag: 1, secondSweepFlag: 0, width: length / 4, height: length },\r\n  };\r\n\r\n  const { initialX, initialY, endX, endY, firstSweepFlag, secondSweepFlag, width, height } = directionMapping[radialDirection];\r\n\r\n  return {\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}a${radius},${radius} 0 0,${firstSweepFlag} ${endX},${endY}a${radius},${radius} 0 0,${secondSweepFlag} ${endX},${endY}`;\r\n    },\r\n    width,\r\n    height,\r\n  }\r\n}\r\n\r\n/**\r\n * Create an half-wave arc object with a specified length and radial direction.\r\n * @param {number} length - The width (N/S) or height (W/E) of the half-wave arc.\r\n * @param {'N'|'S'|'W'|'E'} radialDirection - The direction of the half-wave's arc.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createHalfWave(length, radialDirection) {\r\n  const radius = length * 5 / 8;\r\n\r\n  const directionMapping = {\r\n    'N': { initialX: 0, initialY: length / 4, endX: length, endY: 0, sweepFlag: 1, width: length, height: length / 4 },\r\n    'S': { initialX: 0, initialY: 0, endX: length, endY: 0, sweepFlag: 0, width: length, height: length / 4 },\r\n    'W': { initialX: length / 4, initialY: 0, endX: 0, endY: length, sweepFlag: 0, width: length / 4, height: length },\r\n    'E': { initialX: 0, initialY: 0, endX: 0, endY: length, sweepFlag: 1, width: length / 4, height: length },\r\n  };\r\n\r\n  const { initialX, initialY, endX, endY, sweepFlag, width, height } = directionMapping[radialDirection];\r\n\r\n  return {\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}a${radius},${radius} 0 0,${sweepFlag} ${endX},${endY}`;\r\n    },\r\n    width,\r\n    height,\r\n  };\r\n}\r\n\r\n/**\r\n * Create a horizontal quarter-wave arc object with a specified width and radial direction.\r\n * @param {number} width - The width of the quarter-wave arc.\r\n * @param {'NW'|'NE'|'SW'|'SE'} radialDirection - The direction of the quarter-wave's arc.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createHorizontalQuarterWave(width, radialDirection) {\r\n  const radius = width * 5 / 4;\r\n\r\n  const directionMapping = {\r\n    'NW': { initialX: 0, initialY: width / 2, endX: width, endY: -width / 2, sweepFlag: 1 },\r\n    'NE': { initialX: 0, initialY: 0, endX: width, endY: width / 2, sweepFlag: 1 },\r\n    'SW': { initialX: 0, initialY: 0, endX: width, endY: width / 2, sweepFlag: 0 },\r\n    'SE': { initialX: 0, initialY: width / 2, endX: width, endY: -width / 2, sweepFlag: 0 },\r\n  };\r\n\r\n  const { initialX, initialY, endX, endY, sweepFlag } = directionMapping[radialDirection];\r\n\r\n  return {\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}a${radius},${radius} 0 0,${sweepFlag} ${endX},${endY}`;\r\n    },\r\n    width,\r\n    height: width / 2,\r\n  };\r\n}\r\n\r\n/**\r\n * Create a vertical quarter-wave arc object with a specified height and radial direction.\r\n * @param {number} height - The height of the quarter-wave arc.\r\n * @param {'NW'|'NE'|'SW'|'SE'} radialDirection - The direction of the quarter-wave's arc.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createVerticalQuarterWave(height, radialDirection) {\r\n  const radius = height * 5 / 4;\r\n\r\n  const directionMapping = {\r\n    'NW': { initialX: height / 2, initialY: 0, endX: -height / 2, endY: height, sweepFlag: 0 },\r\n    'NE': { initialX: 0, initialY: 0, endX: height / 2, endY: height, sweepFlag: 1 },\r\n    'SW': { initialX: 0, initialY: 0, endX: height / 2, endY: height, sweepFlag: 0 },\r\n    'SE': { initialX: height / 2, initialY: 0, endX: -height / 2, endY: height, sweepFlag: 1 },\r\n  };\r\n\r\n  const { initialX, initialY, endX, endY, sweepFlag } = directionMapping[radialDirection];\r\n\r\n  return {\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}a${radius},${radius} 0 0,${sweepFlag} ${endX},${endY}`;\r\n    },\r\n    width: height / 2,\r\n    height,\r\n  };\r\n}\r\n\r\n/**\r\n * Create a vertical line object with a specified length.\r\n * @param {number} length - The length of the line.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createVerticalLine(length) {\r\n  return {\r\n    getPath: (x, y) => `M${x},${y}v${length}`,\r\n    width: 0,\r\n    height: length,\r\n  };\r\n}\r\n\r\n/**\r\n * Create a horizontal line object with a specified length.\r\n * @param {number} length - The length of the line.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createHorizontalLine(length) {\r\n  return {\r\n    getPath: (x, y) => `M${x},${y}h${length}`,\r\n    width: length,\r\n    height: 0,\r\n  };\r\n}\r\n\r\n/**\r\n * Create an ascending diagonal line object with a specified width and height.\r\n * @param {number} width - The horizontal length of the line.\r\n * @param {number} height - The vertical length of the line.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createAscendingDiagonalLine(width, height) {\r\n  return {\r\n    getPath: (x, y) => `M${x},${y + height}l${width},${-height}`,\r\n    width,\r\n    height,\r\n  };\r\n};\r\n\r\n/**\r\n * Create a descending diagonal line object with a specified width and height.\r\n * @param {number} width - The horizontal length of the line.\r\n * @param {number} height - The vertical length of the line.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createDescendingDiagonalLine(width, height) {\r\n  return {\r\n    getPath: (x, y) => `M${x},${y}l${width},${height}`,\r\n    width,\r\n    height,\r\n  };\r\n};\r\n\r\n/** \r\n * Create a diagonal line between a circle and a corner of a square in a specified direction, for a square/circle with a specified width/height/diameter.\r\n * @param {number} size - The width/height/diameter of the circle/square.\r\n * @param {'NW'|'NE'|'SW'|'SE'} direction - The direction of the diagonal line.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n*/\r\nexport function createDiagonalLineOutsideCircle(size, direction) {\r\n  const radius = size / 2;\r\n  const lineWidth = radius * (1 - Math.SQRT1_2);\r\n  const lineHeight = lineWidth;\r\n\r\n  const directionMapping = {\r\n    'NW': { initialX: 0, initialY: 0, endX: lineWidth, endY: lineHeight },\r\n    'NE': { initialX: size - lineWidth, initialY: lineHeight, endX: lineWidth, endY: -lineHeight },\r\n    'SW': { initialX: 0, initialY: size, endX: lineWidth, endY: -lineHeight },\r\n    'SE': { initialX: size - lineWidth, initialY: size - lineHeight, endX: lineWidth, endY: lineHeight },\r\n  };\r\n\r\n  const { initialX, initialY, endX, endY } = directionMapping[direction];\r\n\r\n  return {\r\n    //x and y are in this case the coordinates of the square that the diagonal lines are related to. Also width and height relates to the square.\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}l${endX},${endY}`;\r\n    },\r\n    width: size,\r\n    height: size,\r\n  };\r\n}\r\n\r\n/** \r\n * Create an ascending diagonal line inside a circle with a specified radius.\r\n * @param {number} radius - The radius of the circle.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n*/\r\nexport function createAscendingDiagonalLineInsideCircle(radius) {\r\n  const lineWidth = radius * 2 * Math.SQRT1_2;\r\n  const lineHeight = lineWidth;\r\n\r\n  return {\r\n    //x and y are in this case the coordinates of the bounding box of the circle that the diagonal lines are related to. Also width and height relates to the square.\r\n    getPath: (x, y) => {\r\n      const startX = radius - lineWidth / 2 + x;\r\n      const startY = radius + lineHeight / 2 + y;\r\n      const endX = lineWidth;\r\n      const endY = -lineHeight;\r\n      return `M${startX},${startY}l${endX},${endY}`;\r\n    },\r\n    width: radius * 2,\r\n    height: radius * 2,\r\n  };\r\n}\r\n\r\n/** \r\n * Create a descending diagonal line inside a circle with a specified radius.\r\n * @param {number} radius - The radius of the circle.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n*/\r\nexport function createDescendingDiagonalLineInsideCircle(radius) {\r\n  const lineWidth = radius * 2 * Math.SQRT1_2;\r\n  const lineHeight = lineWidth;\r\n\r\n  return {\r\n    //x and y are in this case the coordinates of the bounding box of the circle that the diagonal lines are related to. Also width and height relates to the square.\r\n    getPath: (x, y) => {\r\n      const startX = radius - lineWidth / 2 + x;\r\n      const startY = radius - lineHeight / 2 + y;\r\n      const endX = lineWidth;\r\n      const endY = lineHeight;\r\n      return `M${startX},${startY}l${endX},${endY}`;\r\n    },\r\n    width: radius * 2,\r\n    height: radius * 2,\r\n  };\r\n}\r\n\r\n/** \r\n * Create a heart with a specified size.\r\n * @param {number} size - The size of the heart.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n*/\r\nexport function createHeart(size) {\r\n  const radius = size / 4\r\n\r\n  return {\r\n    getPath: (x, y) => `M${x},${y + radius}a${radius},${radius} 0 1,1 ${radius * 2},0a${radius},${radius} 0 1,1 ${radius * 2},0q0,${size * 3 / 8} ${-(size / 2)},${size * 3 / 4}q${-(size / 2)},${-(size * 3 / 8)} ${-(size / 2)},${-(size * 3 / 4)}`,\r\n    width: size,\r\n    height: size,\r\n  };\r\n}\r\n\r\n/** \r\n * Create an ear with a specified height.\r\n * @param {number} height - The height of the ear.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n*/\r\nexport function createEar(height) {\r\n  const radius = height / 4\r\n  \r\n  return {\r\n    getPath: (x, y) => `M${x},${y + radius}a${radius},${radius} 0 1,1 ${radius * 2},0q0,${height * 3 / 8} ${-(height / 2)},${height * 3 / 4}`,\r\n    width: height / 2,\r\n    height,\r\n  };\r\n}\r\n\r\n/** \r\n * Create a dot.\r\n * @param {number} defaultBaseStrokeWidth - The default stroke width to use with returned functions. The stroke-width of a normal line in the SVG, used to derive other dimensions of the dot.\r\n * @param {number} defaultExtraDotWidth - The default extra dot width do use with returned functions. The outer diameter of the dot is the normal stroke-width + extra-dot-width.\r\n * @returns {Object} - An object with a getDotData method, getDotSVGString method, width, and height properties.\r\n*/\r\nexport function createDot(defaultBaseStrokeWidth = 0.5, defaultExtraDotWidth = 0.333) {\r\n  const dot = {\r\n    /**\r\n     * Create an object with SVG string parts closePath, openPath, dotPath and openPath\r\n     * so that joining these can be used along with other shapes' getPath functions,\r\n     * based on specified strokeWidth and extraDotWidth.\r\n     * @param {number} x - The x-coordinate of the dot's position.\r\n     * @param {number} y - The y-coordinate of the dot's position.\r\n     * @param {number} baseStrokeWidth - The stroke-width of a normal line in the SVG, used to derive other dimensions of the dot.\r\n     * @param {number} extraDotWidth - A dot's outer diameter is the normal line stroke-width + extraDotWidth.\r\n     * @param {number} [settings.dotWidth] - Optional absolute rendered diameter; when set, overrides baseStrokeWidth/extraDotWidth (ink stroke-width = dotWidth/2).\r\n     * @returns {Object} - An object with closePath, openPath, dotPath and openPath properties.\r\n     */\r\n    getDotData: (x, y, settings = { baseStrokeWidth: defaultBaseStrokeWidth, extraDotWidth: defaultExtraDotWidth }) => {\r\n      const dotStrokeWidth = settings.dotWidth !== undefined\r\n        ? settings.dotWidth / 2\r\n        : (settings.baseStrokeWidth + settings.extraDotWidth) / 2;\r\n      const dotStrokeRadius = dotStrokeWidth / 2;\r\n      return {\r\n        closePath: `\"/>`,\r\n        openWrapper: `<g stroke-width=\"${dotStrokeWidth}\">`,\r\n        openDotPath: `<path d=\"`,\r\n        dotPath: `M${x - dotStrokeRadius},${y}a${dotStrokeRadius},${dotStrokeRadius} 0 1,1 ${dotStrokeRadius * 2},0a${dotStrokeRadius},${dotStrokeRadius} 0 1,1 ${-dotStrokeRadius * 2},0`,\r\n        closeDotPath: `\"/>`,\r\n        closeWrapper: `</g>`,\r\n        openPath: `<path d=\"`\r\n      };\r\n    },\r\n    width: 0,\r\n    height: 0,\r\n  };\r\n\r\n  /**\r\n   * Create an SVG string with the components closePath, openDotPath, dotPath and openPath\r\n   * so that joining these can be used along with other shapes' getPath functions,\r\n   * based on specified baseStrokeWidth and extraDotWidth.\r\n   * @param {number} x - The x-coordinate of the dot's position.\r\n   * @param {number} y - The y-coordinate of the dot's position.\r\n   * @param {number} baseStrokeWidth - The stroke-width of a normal line in the SVG, used to derive other dimensions of the dot.\r\n   * @param {number} extraDotWidth - A dot's outer diameter is the normal line stroke-width + extraDotWidth.\r\n   * @returns {Object} - An object with closePath, openPath, dotPath and openPath properties.\r\n   */\r\n  dot.getPath = (x, y, settings = { baseStrokeWidth: defaultBaseStrokeWidth, extraDotWidth: defaultExtraDotWidth }) => {\r\n    const { closePath, openWrapper, openDotPath, dotPath, closeDotPath, closeWrapper, openPath } = dot.getDotData(x, y, settings);\r\n    return `${closePath}${openWrapper}${openDotPath}${dotPath}${closeDotPath}${closeWrapper}${openPath}`;\r\n  };\r\n\r\n  return dot;\r\n}\r\n\r\n/** \r\n * Create a comma.\r\n * @param {number} defaultBaseStrokeWidth - The default stroke width to use with returned functions. The stroke-width of a normal line in the SVG, used to derive other dimensions of the comma.\r\n * @param {number} defaultExtraDotWidth - The default extra dot width to use with returned functions. The outer diameter of the dot (which the comma is partly made of) is the normal stroke-width + the extra dot width.\r\n * @returns {Object} - An object with a getCommaData method, getCommaSVGString method, width, and height properties.\r\n*/\r\nexport function createComma(defaultBaseStrokeWidth = 0.5, defaultExtraDotWidth = 0.333) {\r\n  const comma = {\r\n    /**\r\n     * Create an object with SVG string parts closePath, openDotPath, dotPath, openCommaPath, commaPath and openPath so that joining these can be used along with other shapes' getPath functions, based on specified strokeWidth and extraDotWidth.\r\n     * @param {number} x - The x-coordinate of the dot's position.\r\n     * @param {number} y - The y-coordinate of the dot's position.\r\n     * @param {number} baseStrokeWidth - The stroke-width of a normal line in the SVG, used to derive other dimensions of the comma.\r\n     * @param {number} extraDotWidth - A dot's outer diameter is the normal line stroke-width + extraDotWidth.\r\n     * @param {number} [settings.dotWidth] - Optional absolute rendered dot diameter; when set, overrides baseStrokeWidth/extraDotWidth (ink stroke-width = dotWidth/2). The comma tail scales off it too.\r\n     * @returns {Object} - An object with closePath, openDotPath, dotPath, commaPath and openPath properties.\r\n     */\r\n    getCommaData: (x, y, settings = { baseStrokeWidth: defaultBaseStrokeWidth, extraDotWidth: defaultExtraDotWidth }) => {\r\n      const dotStrokeWidth = settings.dotWidth !== undefined\r\n        ? settings.dotWidth / 2\r\n        : (settings.baseStrokeWidth + settings.extraDotWidth) / 2;\r\n      const dotStrokeRadius = dotStrokeWidth / 2;\r\n      const commaStrokeWidth = dotStrokeWidth * 2 / 3;\r\n      const commaStartX = commaStrokeWidth + x;\r\n      const commaStartY = y;\r\n      const commaEndX = commaStrokeWidth * -2;\r\n      const commaEndY = commaStrokeWidth * 4;\r\n      const commaQX = commaStrokeWidth / 4\r\n      const commaQY = commaStrokeWidth * 2.5;\r\n      return {\r\n        closePath: `\"/>`,\r\n        openDotWrapper: `<g stroke-width=\"${dotStrokeWidth}\">`,\r\n        openDotPath: `<path d=\"`,\r\n        dotPath: `M${x - dotStrokeRadius},${y}a${dotStrokeRadius},${dotStrokeRadius} 0 1,1 ${dotStrokeRadius * 2},0a${dotStrokeRadius},${dotStrokeRadius} 0 1,1 ${-dotStrokeRadius * 2},0`,\r\n        closeDotPath: `\"/>`,\r\n        closeDotWrapper: `</g>`,\r\n        openCommaWrapper: `<g stroke-width=\"${commaStrokeWidth}\">`,\r\n        openCommaPath: `<path d=\"`,\r\n        commaPath: `M${commaStartX},${commaStartY}q${commaQX},${commaQY} ${commaEndX},${commaEndY}`,\r\n        closeCommaPath: `\"/>`,\r\n        closeCommaWrapper: `</g>`,\r\n        openPath: `<path d=\"`\r\n      };\r\n    },\r\n    width: 0,\r\n    height: (defaultBaseStrokeWidth + defaultExtraDotWidth) * 4 / 3,\r\n  };\r\n\r\n  /**\r\n   * Create an SVG string with the components closePath, openDotPath, dotPath, openCommaPath, commaPath and openPath\r\n   * so that joining these can be used along with other elements' getPath functions,\r\n   * based on specified baseStrokeWidth and extraDotWidth.\r\n   * @param {number} x - The x-coordinate of the dot's position.\r\n   * @param {number} y - The y-coordinate of the dot's position.\r\n   * @param {number} baseStrokeWidth - The stroke-width of a normal line in the SVG, used to derive other dimensions of the comma.\r\n   * @param {number} extraDotWidth - A dot's outer diameter is the normal line stroke-width + extraDotWidth.\r\n   * @returns {Object} - An object with closePath, openDotPath, dotPath, openCommaPath, commaPath and openPath properties.\r\n   */\r\n  comma.getPath = (x, y, settings = { baseStrokeWidth: defaultBaseStrokeWidth, extraDotWidth: defaultExtraDotWidth }) => {\r\n    const { closePath, openDotWrapper, openDotPath, dotPath, closeDotPath, closeDotWrapper, openCommaWrapper, openCommaPath, commaPath, closeCommaPath, closeCommaWrapper, openPath } = comma.getCommaData(x, y, settings);\r\n    return `${closePath}${openDotWrapper}${openDotPath}${dotPath}${closeDotPath}${closeDotWrapper}${openCommaWrapper}${openCommaPath}${commaPath}${closeCommaPath}${closeCommaWrapper}${openPath}`;\r\n  };\r\n\r\n  return comma;\r\n}\r\n\r\n/**\r\n * Create a fiber with a specified height.\r\n * @param {number} height - The height of the fiber.\r\n * @returns {Object} - An object with a getPath method, width, and height properties.\r\n */\r\nexport function createFiber(height) {\r\n  const radius = height * 5 / 8;\r\n  const initialX = 0;\r\n  const initialY = height;\r\n  const midX = height / 4;\r\n  const midY = -height / 2;\r\n  const endX = height / 4;\r\n  const endY = -height / 2;\r\n\r\n  return {\r\n    getPath: (x, y) => {\r\n      const startX = initialX + x;\r\n      const startY = initialY + y;\r\n      return `M${startX},${startY}a${radius},${radius} 0 0,1 ${midX},${midY}a${radius},${radius} 0 0,0 ${endX},${endY}`;\r\n    },\r\n    width: height / 2,\r\n    height,\r\n  };\r\n}\r\n\r\n/**\r\n * Creates an external glyph object for the given rendered character.\r\n *\r\n * @param {string} char - The rendered character (e.g. \"a\" from input code \"Xa\").\r\n * @return {object} An object with getPath, width, kerningRules, char, glyphCode, isExternalGlyph properties.\r\n */\r\nexport function createExternalGlyph(char) {\r\n  const aObj = alphabetData[`X${char}`];\r\n  const adjustX = -aObj.leftSideBearing;\r\n  const adjustY = -0.015; //revisit this\r\n  const closePath = `\"/>`;\r\n  const glyphPath = aObj?.getPath() || \"\";\r\n  const openPath = `<path d=\"`;\r\n\r\n  const round = (num) => parseFloat(num.toFixed(4));\r\n\r\n  // aObj.height is actually maxY (where the bottom of the glyph path sits), not content height.\r\n  const approxMinY = APPROX_GLYPH_MIN_Y;\r\n  const maxY = aObj.height || 0;\r\n\r\n  return {\r\n    getPath: (x, y, options = {}) => {\r\n      // Transform all M coordinates directly (paths use relative commands after M)\r\n      const transformedPath = glyphPath.replace(\r\n        /M(-?\\d+\\.?\\d*),(-?\\d+\\.?\\d*)/g,\r\n        (_, mx, my) => `M${round(parseFloat(mx) + x + adjustX)},${round(parseFloat(my) + y + adjustY)}`\r\n      );\r\n      const fill = options.color || \"#000000\";\r\n      const openGlyphPath = `<path stroke=\"none\" fill=\"${fill}\" d=\"`;\r\n      return `${closePath}${openGlyphPath}${transformedPath}${closePath}${openPath}`;\r\n    },\r\n    width: aObj.width || 0,\r\n    y: approxMinY,\r\n    height: maxY - approxMinY,\r\n    // Indicates that this \"shape\" is an external, non-Bliss glyph.\r\n    isExternalGlyph: true,\r\n    // The rendered character.\r\n    char: aObj.char,\r\n    // Single external glyph identifier (parallel to B-codes' glyphCode).\r\n    glyphCode: `X${aObj.char}`,\r\n    // The kerning rules for the glyph\r\n    kerningRules: {...aObj.kerningRules}\r\n  }\r\n}\r\n","/*\r\n * This Source Code Form is subject to the terms of the Mozilla Public\r\n * License, v. 2.0. If a copy of the MPL was not distributed with this\r\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\r\n */\r\n\r\nconst digitKerning = {\r\n  B9: -1, B10: -1, B11: -1, B12: -1, B13: -1,\r\n  B14: -1, B15: -1, B16: -1, B17: -1, B18: -1\r\n};\r\n\r\nconst smallDigitKerning = {\r\n  B19: -1, B20: -1, B21: -1, B22: -1, B23: -1,\r\n  B24: -1, B25: -1, B26: -1, B27: -1, B28: -1\r\n};\r\n\r\nconst glyphData = {\r\n  B1: {\r\n    codeString: \"VL6:0,8;DOT:0,16\",\r\n    shrinksPrecedingWordSpace: true\r\n  },\r\n  B2: {\r\n    codeString: \"C2:0,8;DL4-8N:0,8;C2:2,14\",\r\n    shrinksPrecedingWordSpace: true\r\n  },\r\n  B3: {\r\n    codeString: \"OC4SW:0,8;VL2:2,12;DOT:2,16\",\r\n    shrinksPrecedingWordSpace: true\r\n  },\r\n  B4: {\r\n    codeString: \"DOT:0,16\",\r\n    shrinksPrecedingWordSpace: true\r\n  },\r\n  B5: {\r\n    codeString: \"COMMA:0,16\",\r\n    shrinksPrecedingWordSpace: true\r\n  },\r\n  B6: {\r\n    codeString: \"DOT:0,14;DOT:0,16\",\r\n    shrinksPrecedingWordSpace: true\r\n  },\r\n  B7: {\r\n    codeString: \"COMMA:0,8\",\r\n    shrinksPrecedingWordSpace: true\r\n  },\r\n  B8: {\r\n    codeString: \"C2:0,8\"\r\n  },\r\n  B9: {\r\n    codeString: \"HC2N:0,12;VL2:0,13;HC2S:0,15;VL2:2,13\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B10: {\r\n    codeString: \"DL1N:0,12;VL4:1,12;HL2:0,16\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B11: {\r\n    codeString: \"HC2N:0,12;DL2-3N:0,13;HL2:0,16\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B12: {\r\n    codeString: \"OC2SW:0,12;OC2NW:0,14\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B13: {\r\n    codeString: \"VL2:0,12;HL2:0,14;VL4:2,12\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B14: {\r\n    codeString: \"HL2:0,12;VL2:0,12;HL1:0,14;HL1:0,16;HC2E:1,14\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B15: {\r\n    codeString: \"HC2N:0,12;VL2:0,13;C2:0,14\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B16: {\r\n    codeString: \"HL2:0,12;DL1-4N:1,12\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B17: {\r\n    codeString: \"C2:0,12;C2:0,14\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B18: {\r\n    codeString: \"C2:0,12;HC2S:0,15;VL2:2,13\",\r\n    kerningRules: digitKerning\r\n  },\r\n  B19: {\r\n    codeString: \"HC1N:0,14;VL1:0,14.5;HC1S:0,15.5;VL1:1,14.5\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B20: {\r\n    codeString: \"DL.5N:0,14;VL2:0.5,14;HL1:0,16\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B21: {\r\n    codeString: \"HC1N:0,14;DL1-1.5N:0,14.5;HL1:0,16\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B22: {\r\n    codeString: \"OC1SW:0,14;OC1NW:0,15\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B23: {\r\n    codeString: \"VL1:0,14;HL1:0,15;VL2:1,14\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B24: {\r\n    codeString: \"HL1:0,14;VL1:0,14;HL.5:0,15;HL.5:0,16;HC1E:0.5,15\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B25: {\r\n    codeString: \"HC1N:0,14;VL1:0,14.5;C1:0,15\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B26: {\r\n    codeString: \"HL1:0,14;DL.5-2N:0.5,14\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B27: {\r\n    codeString: \"C1:0,14;C1:0,15\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B28: {\r\n    codeString: \"C1:0,14;HC1S:0,15.5;VL1:1,14.5\",\r\n    kerningRules: smallDigitKerning\r\n  },\r\n  B81: {\r\n    codeString: \"AA2N:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    name: \"INDICATOR ACTION\"\r\n  },\r\n  B82: {\r\n    codeString: \"AA2E:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    name: \"INDICATOR ACTIVE\"\r\n  },\r\n  B83: {\r\n    codeString: \"OC1SW:0,4;VL.25:0.5,5;SDOT:0.5,6\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 1,\r\n    name: \"INDICATOR PRESENT CONDITIONAL\"\r\n  },\r\n  B84: {\r\n    codeString: \"B86;SDOT:3,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'adjectival',\r\n    anchorOffsetX: -0.5,\r\n    width: 3,\r\n    name: \"INDICATOR DESCRIPTION AFTER THE FACT\"\r\n  },\r\n  B85: {\r\n    codeString: \"SDOT:0,4;B86:1,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'adjectival',\r\n    anchorOffsetX:  0.5,\r\n    width: 3,\r\n    name: \"INDICATOR DESCRIPTION BEFORE THE FACT\"\r\n  },\r\n  B86: {\r\n    codeString: \"AA2S:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'adjectival',\r\n    name: \"INDICATOR DESCRIPTION\"\r\n  },\r\n  B87: {\r\n    codeString: \"HW2W:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 0.5,\r\n    name: \"INDICATOR FUTURE\"\r\n  },\r\n  B88: {\r\n    codeString: \"B83;B87:2,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 2.5,\r\n    name: \"INDICATOR FUTURE CONDITIONAL\"\r\n  },\r\n  B89: {\r\n    codeString: \"B91;B87:3,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 3.5,\r\n    name: \"INDICATOR FUTURE PASSIVE\"\r\n  },\r\n  B90: {\r\n    codeString: \"B91;B88:3,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 5.5,\r\n    name: \"INDICATOR FUTURE PASSIVE CONDITIONAL\"\r\n  },\r\n  B91: {\r\n    codeString: \"AA2W:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    name: \"INDICATOR PASSIVE\"\r\n  },\r\n  B92: {\r\n    codeString: \"HW2E:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 0.5,\r\n    name: \"INDICATOR PAST\"\r\n  },\r\n  B93: {\r\n    codeString: \"B83;B92:2,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 2.5,\r\n    name: \"INDICATOR PAST CONDITIONAL\"\r\n  },\r\n  B94: {\r\n    codeString: \"B91;B93:3,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 5.5,\r\n    name: \"INDICATOR PAST PASSIVE CONDITIONAL\"\r\n  },\r\n  B95: {\r\n    codeString: \"B91;B92:3,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 3.5,\r\n    name: \"INDICATOR PAST PASSIVE\"\r\n  },\r\n  B96: {\r\n    codeString: \"B91;B83:3,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 4,\r\n    name: \"INDICATOR PRESENT PASSIVE CONDITIONAL\"\r\n  },\r\n  B97: {\r\n    codeString: \"S2:0,4\",\r\n    isIndicator: true,\r\n    semanticIndicator: 'thing',\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR THING\"\r\n  },\r\n  B98: {\r\n    codeString: \"B97;B99:3,0\",\r\n    isIndicator: true,\r\n    semanticIndicator: 'thing',\r\n    indicatorRole: 'nominal',\r\n    width: 5,\r\n    name: \"INDICATOR PLURAL THING\"\r\n  },\r\n  B99: {\r\n    codeString: \"DC2:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR PLURAL\"\r\n  },\r\n  B100: {\r\n    codeString: \"DL2S:0,11\"\r\n  },\r\n  B101: {\r\n    codeString: \"B270;B297:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B102: {\r\n    codeString: \"RA4E:0,10\"\r\n  },\r\n  B103: {\r\n    codeString: \"B239;VL6:2,8;HL4:2,8;VL6:6,8\"\r\n  },\r\n  B104: {\r\n    codeString: \"VL6:2,10;HL4:0,12;HL4:0,14\"\r\n  },\r\n  B105: {\r\n    codeString: \"AA8N:0,8\"\r\n  },\r\n  B106: {\r\n    codeString: \"AA4N:0,12\"\r\n  },\r\n  B107: {\r\n    codeString: \"SC8:0,8\"\r\n  },\r\n  B108: {\r\n    codeString: \"B325;HL4:0,8;HL4:0,16\"\r\n  },\r\n  B109: {\r\n    codeString: \"B428;B270:2,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B110: {\r\n    codeString: \"B270;B270:2,0\"\r\n  },\r\n  B111: {\r\n    codeString: \"RA4W:0,10;RA4W:2,10\"\r\n  },\r\n  B112: {\r\n    codeString: \"HW4E:0,12\"\r\n  },\r\n  B113: {\r\n    codeString: \"B335;B335:0,4\"\r\n  },\r\n  B114: {\r\n    codeString: \"B597;B473:4,0\"\r\n  },\r\n  B115: {\r\n    codeString: \"B708;B700:2,0\"\r\n  },\r\n  B116: {\r\n    codeString: \"RA8S:0,8;VL4:4,12;HL8:0,16\"\r\n  },\r\n  B117: {\r\n    codeString: \"B291;B459\"\r\n  },\r\n  B118: {\r\n    codeString: \"Xa;Xb:3.2354,0;Xc:6.4708,0\"\r\n  },\r\n  B119: {\r\n    codeString: \"P4W:0,6;P4E:4,10;P4W:0,14\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B120: {\r\n    codeString: \"SC4:0,10\"\r\n  },\r\n  B121: {\r\n    codeString: \"DL8N:0,8;HL8:0,16\"\r\n  },\r\n  B122: {\r\n    codeString: \"HL8:0,12;AA4N:0,12;AA4N:4,12\"\r\n  },\r\n  B123: {\r\n    codeString: \"B122;B737:4,2\"\r\n  },\r\n  B124: {\r\n    codeString: \"HC4W:0,8;B122:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B125: {\r\n    codeString: \"B122;B737:4,0\"\r\n  },\r\n  B126: {\r\n    codeString: \"B122;HC2N:0,15;HC2N:4,15;HC2N:8,15\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B127: {\r\n    codeString: \"B122;B695:0,6\"\r\n  },\r\n  B128: {\r\n    codeString: \"P4E:0,14;B514:3,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B129: {\r\n    codeString: \"B291;B699:3,0\"\r\n  },\r\n  B130: {\r\n    codeString: \"B281;B100:3,0\"\r\n  },\r\n  B131: {\r\n    codeString: \"HC4N:0,10;HC4N:4,10;HC8S:0,12;QC4NW:4,8\"\r\n  },\r\n  B132: {\r\n    codeString: \"RA4SW:0,8\"\r\n  },\r\n  B133: {\r\n    codeString: \"B212;HL4:0,10;VL2:4,10\"\r\n  },\r\n  B134: {\r\n    codeString: \"B255;B270\"\r\n  },\r\n  B135: {\r\n    codeString: \"RA4E:0,10;B270:4,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B136: {\r\n    codeString: \"LARRC8SC:0,8;B5840:3,0\"\r\n  },\r\n  B137: {\r\n    codeString: \"B257;B11:7,0;B500:8,0\"\r\n  },\r\n  B138: {\r\n    codeString: \"QC4NW:3,4;VQW4NW:1,8;VQW4NE:3,8;HW4W:0,12;HW4E:5,12;B528:2.5,0;HL4:1,16\",\r\n    anchorOffsetX: -0.5,\r\n    anchorOffsetY: -4\r\n  },\r\n  B139: {\r\n    codeString: \"VL4:0,10;P4E:8,10\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B140: {\r\n    codeString: \"C4:0,12;VL4:4,12;HL4:4,14;VL4:8,12\"\r\n  },\r\n  B141: {\r\n    codeString: \"C4:0,12;AA4W:4,12\"\r\n  },\r\n  B142: {\r\n    codeString: \"C4:0,12;AT4W:4,12\"\r\n  },\r\n  B143: {\r\n    codeString: \"P4E:0,6;B518:3,0\",\r\n    anchorOffsetX: 1.5,\r\n    anchorOffsetY: -1\r\n  },\r\n  B144: {\r\n    codeString: \"B335;B145:0,4\"\r\n  },\r\n  B145: {\r\n    codeString: \"LARR8W:0,10\"\r\n  },\r\n  B146: {\r\n    codeString: \"VL4:0,8;HL8:0,8;VL4:8,8;HC8S:0,12\"\r\n  },\r\n  B147: {\r\n    codeString: \"HC4N:2,10;R84:0,12\"\r\n  },\r\n  B148: {\r\n    codeString: \"C4:0,12;HL4:0,14\"\r\n  },\r\n  B149: {\r\n    codeString: \"C8:0,4;QC4SE:0,12\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B150: {\r\n    codeString: \"QC4NW:0,4;HW8E:0,8;HC8E:0,8\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B151: {\r\n    codeString: \"B612;B428:12,0\"\r\n  },\r\n  B152: {\r\n    codeString: \"B122;B708\"\r\n  },\r\n  B153: {\r\n    codeString: \"B281;B695:8,4\"\r\n  },\r\n  B154: {\r\n    codeString: \"B801;C4:1,10\"\r\n  },\r\n  B155: {\r\n    codeString: \"B1139;P4W:7,16\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B156: {\r\n    codeString: \"VL8:0,8;HL8:0,12;DL4N:4,8;VL8:8,8\"\r\n  },\r\n  B157: {\r\n    codeString: \"B400;HC8N:2,8;HL8:2,12\"\r\n  },\r\n  B158: {\r\n    codeString: \"B270;B428:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B159: {\r\n    codeString: \"B428;B335\"\r\n  },\r\n  B160: {\r\n    codeString: \"B120:0,4\"\r\n  },\r\n  B161: {\r\n    codeString: \"C4:0,10;QC4NE:4,12\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B162: {\r\n    codeString: \"B428;B270:2,0;B428:4,0\"\r\n  },\r\n  B163: {\r\n    codeString: \"B708;AA2N:3,12\"\r\n  },\r\n  B164: {\r\n    codeString: \"B163;B695:0,6\"\r\n  },\r\n  B165: {\r\n    codeString: \"HW8W:0,8;HL8:2,8;HL2:2,16;HL2:8,16;HW8E:10,8;B140:2,-2;LARR4S:4,16\"\r\n  },\r\n  B166: {\r\n    codeString: \"B548;B622:3,0\"\r\n  },\r\n  B167: {\r\n    codeString: \"B712;B509\"\r\n  },\r\n  B168: {\r\n    codeString: \"S4:0,10;DL2N:0,8;HL4:2,8;DL2N:4,8;VL4:6,8;DL2N:4,12\"\r\n  },\r\n  B169: {\r\n    codeString: \"B639;P4N:2,13\"\r\n  },\r\n  B170: {\r\n    codeString: \"VL4:4,8;HL8:0,12;B239\"\r\n  },\r\n  B171: {\r\n    codeString: \"HW8W:0,8;HL8:2,8;HL8:2,16;HW8E:10,8\"\r\n  },\r\n  B172: {\r\n    codeString: \"DOT:0,8;VL4:0,10;DOT:0,16\"\r\n  },\r\n  B173: {\r\n    codeString: \"B497;OR48W:4,8\"\r\n  },\r\n  B174: {\r\n    codeString: \"VL4:2,8;C4:0,12\"\r\n  },\r\n  B175: {\r\n    codeString: \"B291;P4N:2,17\"\r\n  },\r\n  B176: {\r\n    codeString: \"C4:0,10;C4:4,10;RA4N:2,14\"\r\n  },\r\n  B177: {\r\n    codeString: \"S8:0,8;DL4N:0,4;HL8:4,4;DL4N:8,4;VL8:12,4;DL4N:8,12\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B178: {\r\n    codeString: \"C4:0,8;B106\"\r\n  },\r\n  B179: {\r\n    codeString: \"B666;P4W:9,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B180: {\r\n    codeString: \"HW4W:0,12;HL8:1,12;HL8:1,16;HW4E:9,12\"\r\n  },\r\n  B181: {\r\n    codeString: \"B171;P4N:2,12;P4N:6,12\"\r\n  },\r\n  B182: {\r\n    codeString: \"B1154;HC8N:4,12;B1154:12,0\"\r\n  },\r\n  B183: {\r\n    codeString: \"OR84S:0,12;VL8:4,8\"\r\n  },\r\n  B184: {\r\n    codeString: \"OR84N:0,8;VL8:4,8\"\r\n  },\r\n  B185: {\r\n    codeString: \"B345;P4W:5,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B186: {\r\n    codeString: \"B123;HC4N:0,10\"\r\n  },\r\n  B187: {\r\n    codeString: \"B1137;P4W:7,16\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B188: {\r\n    codeString: \"B892;DL2N:9,9;DL2S:10,10\"\r\n  },\r\n  B189: {\r\n    codeString: \"B884;B188:10,0;HL10:12,16\"\r\n  },\r\n  B190: {\r\n    codeString: \"QC4SE:0,10;VL6:4,10;QC4SW:4,10\"\r\n  },\r\n  B191: {\r\n    codeString: \"B451:2,0;B239\"\r\n  },\r\n  B192: {\r\n    codeString: \"HL4:0,12;VL4:4,10\"\r\n  },\r\n  B193: {\r\n    codeString: \"HW8W:0,8;HW8E:2,8;HW8W:4,8;HW8E:6,8\"\r\n  },\r\n  B194: {\r\n    codeString: \"P4E:0,10;B518:3,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B195: {\r\n    codeString: \"RA4W:0,10\"\r\n  },\r\n  B196: {\r\n    codeString: \"B422;HC4N:2,10\"\r\n  },\r\n  B197: {\r\n    codeString: \"B391;HC4N:0,10;HC4N:4,10\",\r\n    anchorOffsetX: -3\r\n  },\r\n  B198: {\r\n    codeString: \"B291;B424\"\r\n  },\r\n  B199: {\r\n    codeString: \"VL4:0,8;B688;RA8N:0,4;VL4:8,8\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B200: {\r\n    codeString: \"C4:0,8;VL4:0,10;VL4:4,10;HC4S:0,14\"\r\n  },\r\n  B201: {\r\n    codeString: \"B700:3,0;B939\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B202: {\r\n    codeString: \"B688;DL2N:5,9;DL2S:6,10\"\r\n  },\r\n  B203: {\r\n    codeString: \"QC4NW:4,12;B281;AA4S:2,16\"\r\n  },\r\n  B204: {\r\n    codeString: \"B1099;LARR4E:4,8\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B205: {\r\n    codeString: \"HL14:0,8;VL8:0,8;C4:2,10;HL6:4,10;C4:8,10;VL8:14,8;HL14:0,16\"\r\n  },\r\n  B206: {\r\n    codeString: \"RT8E:0,8\"\r\n  },\r\n  B207: {\r\n    codeString: \"B644;DOT:2,14\"\r\n  },\r\n  B208: {\r\n    codeString: \"B572;P4N:2,9\"\r\n  },\r\n  B209: {\r\n    codeString: \"B1119;VL6:2,8;VL8:4,8;VL6:6,8;HC4S:2,14\"\r\n  },\r\n  B210: {\r\n    codeString: \"HC4N:0,10;VL2:0,12;HC4S:0,14;VL10:2,8\"\r\n  },\r\n  B211: {\r\n    codeString: \"B265;B357:6,0\"\r\n  },\r\n  B212: {\r\n    codeString: \"VL8:0,8;HL4:0,12;VL4:4,12\"\r\n  },\r\n  B213: {\r\n    codeString: \"B423;B695\"\r\n  },\r\n  B214: {\r\n    codeString: \"B306;P4W:9,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B215: {\r\n    codeString: \"RA4NE:0,12;QC4SW:0,12\"\r\n  },\r\n  B216: {\r\n    codeString: \"DL8N:0,8;VL4:8,8;B651:6,2\",\r\n    anchorOffsetX: 3\r\n  },\r\n  B217: {\r\n    codeString: \"B338;B528:1.5,0;HW4W:5,8;C4:4,12;B528:5.5,0\"\r\n  },\r\n  B218: {\r\n    codeString: \"B171;P4N:4,12\"\r\n  },\r\n  B219: {\r\n    codeString: \"S8:0,8;HL8:0,12;DOT:4,10;DOT:4,14\"\r\n  },\r\n  B220: {\r\n    codeString: \"C4:0,8;B956\"\r\n  },\r\n  B221: {\r\n    codeString: \"B1132;P4W:9,6\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B222: {\r\n    codeString: \"B306;P4N:2,17\"\r\n  },\r\n  B223: {\r\n    codeString: \"B368:0,-4;HL4:0,12;B303:0,2\"\r\n  },\r\n  B224: {\r\n    codeString: \"B1085;P4N:4,17\"\r\n  },\r\n  B225: {\r\n    codeString: \"B281;B433:2,0\"\r\n  },\r\n  B226: {\r\n    codeString: \"B126;P4W:11,14\",\r\n    anchorOffsetX: -2.5\r\n  },\r\n  B227: {\r\n    codeString: \"B978;P4W:8,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B228: {\r\n    codeString: \"VL8:2,8;VL8:6,8;HL8:0,10;HL8:0,14\"\r\n  },\r\n  B229: {\r\n    codeString: \"B228;B548\"\r\n  },\r\n  B230: {\r\n    codeString: \"B597;W8N:0,7\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B231: {\r\n    codeString: \"OR84N:0,12;VL4:4,12\"\r\n  },\r\n  B232: {\r\n    codeString: \"C4:0,10;C4:2,10\"\r\n  },\r\n  B233: {\r\n    codeString: \"C2:0,4;C2:1,4\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B234: {\r\n    codeString: \"B622:0,4;B255:1,0\"\r\n  },\r\n  B235: {\r\n    codeString: \"HC4N:0,8;HC4N:4,8;VL6:0,10;VL6:4,10;VL6:8,10;HL8:0,16\"\r\n  },\r\n  B236: {\r\n    codeString: \"W8S:0,11;B285:6,0\",\r\n    anchorOffsetX: 3\r\n  },\r\n  B237: {\r\n    codeString: \"RA8N:0,8;HC8S:0,12\"\r\n  },\r\n  B238: {\r\n    codeString: \"B447;B447:0,-4\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B239: {\r\n    codeString: \"HC8S:0,12\"\r\n  },\r\n  B240: {\r\n    codeString: \"B687;DOT:4,10;DOT:4,12;DOT:4,14\"\r\n  },\r\n  B241: {\r\n    codeString: \"B572;P4W:9,14\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B242: {\r\n    codeString: \"DL4S:0,8;OR84S:4,12\"\r\n  },\r\n  B243: {\r\n    codeString: \"B281;B322:4,0\"\r\n  },\r\n  B244: {\r\n    codeString: \"B281;B666\"\r\n  },\r\n  B245: {\r\n    codeString: \"B433;B710:4,0\"\r\n  },\r\n  B246: {\r\n    codeString: \"B433;B548:2,0;B710:8,0\"\r\n  },\r\n  B247: {\r\n    codeString: \"AT8N:0,8\"\r\n  },\r\n  B248: {\r\n    codeString: \"VL8:2,8;HL4:0,10\"\r\n  },\r\n  B249: {\r\n    codeString: \"B171;P4N:4,17\"\r\n  },\r\n  B250: {\r\n    codeString: \"RA4N:0,8;B651;RA4S:0,14\"\r\n  },\r\n  B251: {\r\n    codeString: \"B352;HC4E:4,10\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B252: {\r\n    codeString: \"S8:0,8;DOT:2,12;VL8:4,8;DOT:6,12\"\r\n  },\r\n  B253: {\r\n    codeString: \"B161;C4:0,14;HW4N:4,15\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B254: {\r\n    codeString: \"OS8S:0,8;QC4SE:0,8;QC4SW:4,8\"\r\n  },\r\n  B255: {\r\n    codeString: \"HC8E:0,8\"\r\n  },\r\n  B256: {\r\n    codeString: \"B247;B401:4,0\"\r\n  },\r\n  B257: {\r\n    codeString: \"B548;B314:2,0\"\r\n  },\r\n  B258: {\r\n    codeString: \"B281;B636\"\r\n  },\r\n  B259: {\r\n    codeString: \"B423;B939\"\r\n  },\r\n  B260: {\r\n    codeString: \"B447;B292\"\r\n  },\r\n  B261: {\r\n    codeString: \"B213;LARR8E:8,10\",\r\n    anchorOffsetX: -4\r\n  },\r\n  B262: {\r\n    codeString: \"B939;B578:2,0\"\r\n  },\r\n  B263: {\r\n    codeString: \"C4:0,12;HW4E:5,12\"\r\n  },\r\n  B264: {\r\n    codeString: \"B939;B562\"\r\n  },\r\n  B265: {\r\n    codeString: \"DL4S:0,12;HL8:4,16;DL4N:12,12\"\r\n  },\r\n  B266: {\r\n    codeString: \"DOT:4,10;HL8:0,12;DOT:4,14\"\r\n  },\r\n  B267: {\r\n    codeString: \"VL12:2,6;OC4SE:0,8;OC4NW:0,12\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B268: {\r\n    codeString: \"HC4E:0,14;B851:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B269: {\r\n    codeString: \"OS8S:0,8\"\r\n  },\r\n  B270: {\r\n    codeString: \"DOT:0,12\"\r\n  },\r\n  B271: {\r\n    codeString: \"LARR8S:0,8\"\r\n  },\r\n  B272: {\r\n    codeString: \"RA4SW:0,12;DL8N:0,8\"\r\n  },\r\n  B273: {\r\n    codeString: \"DL8S:0,8;RA4SE:4,12\"\r\n  },\r\n  B274: {\r\n    codeString: \"B219;P4W:9,8\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B275: {\r\n    codeString: \"B695;B329:2,0\"\r\n  },\r\n  B276: {\r\n    codeString: \"B391;HC4N:2,10\",\r\n    anchorOffsetX: -3\r\n  },\r\n  B277: {\r\n    codeString: \"B426;B270:4,-6\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B278: {\r\n    codeString: \"E:0,8\"\r\n  },\r\n  B279: {\r\n    codeString: \"B651;B278:2,0\"\r\n  },\r\n  B280: {\r\n    codeString: \"DL8S:0,8;C8:0,8\"\r\n  },\r\n  B281: {\r\n    codeString: \"HL8:0,16\"\r\n  },\r\n  B282: {\r\n    codeString: \"B636;P4E:5,10\"\r\n  },\r\n  B283: {\r\n    codeString: \"B639;P4S:6,9\"\r\n  },\r\n  B284: {\r\n    codeString: \"B559;OR48W:0,8\"\r\n  },\r\n  B285: {\r\n    codeString: \"C8:0,8;HW4N:2,11;HW4S:2,12\"\r\n  },\r\n  B286: {\r\n    codeString: \"B270;RA4E:0,10\"\r\n  },\r\n  B287: {\r\n    codeString: \"P4E:0,10;B132:3,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B288: {\r\n    codeString: \"DL4N:0,8;HL4:0,12;DL4N:0,12\"\r\n  },\r\n  B289: {\r\n    codeString: \"DL8-4S:0,10;VL4:8,10;DL8-4S:8,10\"\r\n  },\r\n  B290: {\r\n    codeString: \"B171;B894:4,0\"\r\n  },\r\n  B291: {\r\n    codeString: \"S8:0,8\"\r\n  },\r\n  B292: {\r\n    codeString: \"B335;B428:8,0\"\r\n  },\r\n  B293: {\r\n    codeString: \"B289;B636:4,0\"\r\n  },\r\n  B294: {\r\n    codeString: \"B712;B695\"\r\n  },\r\n  B295: {\r\n    codeString: \"B518;DL2N:0,10\"\r\n  },\r\n  B296: {\r\n    codeString: \"VL2:2,6;HW8W:0,8;HW8E:2,8\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B297: {\r\n    codeString: \"AA8S:0,8\"\r\n  },\r\n  B298: {\r\n    codeString: \"B281;VQW4NE:4,12;QC4NE:4,12\"\r\n  },\r\n  B299: {\r\n    codeString: \"B894;B1154\"\r\n  },\r\n  B300: {\r\n    codeString: \"B666;QC4SE:0,10;QC4SW:4,10\"\r\n  },\r\n  B301: {\r\n    codeString: \"B447;B1042:2,0\"\r\n  },\r\n  B302: {\r\n    codeString: \"LARR4W:0,10;LARR4N:4,6;B651:4,0;LARR4E:8,10;LARR4S:4,14\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B303: {\r\n    codeString: \"C4:0,10;DOT:2,12\"\r\n  },\r\n  B304: {\r\n    codeString: \"B1138;P4W:5,6\",\r\n    anchorOffsetX: -1.5,\r\n    anchorOffsetY: -2\r\n  },\r\n  B305: {\r\n    codeString: \"B303;P4S:0,7\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B306: {\r\n    codeString: \"B376;DOT:2,10;DOT:6,10\"\r\n  },\r\n  B307: {\r\n    codeString: \"B447;B299:2,0\"\r\n  },\r\n  B308: {\r\n    codeString: \"B393;B704:10,0\"\r\n  },\r\n  B309: {\r\n    codeString: \"B513;B548:2,0;B513:8,0\"\r\n  },\r\n  B310: {\r\n    codeString: \"HC8N:0,8;RA8S:0,12\"\r\n  },\r\n  B311: {\r\n    codeString: \"B548;B317\"\r\n  },\r\n  B312: {\r\n    codeString: \"B548;B433:2,0\"\r\n  },\r\n  B313: {\r\n    codeString: \"H:0,8\"\r\n  },\r\n  B314: {\r\n    codeString: \"AT4N:0,12\"\r\n  },\r\n  B315: {\r\n    codeString: \"B1135;P4W:17,12\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B316: {\r\n    codeString: \"B171;B140:2,-2\"\r\n  },\r\n  B317: {\r\n    codeString: \"B357;B281\"\r\n  },\r\n  B318: {\r\n    codeString: \"B374;P4W:5,6\",\r\n    anchorOffsetX: -1.5,\r\n    anchorOffsetY: -1\r\n  },\r\n  B319: {\r\n    codeString: \"W8E:0,8\"\r\n  },\r\n  B320: {\r\n    codeString: \"B484;B319:3,0\"\r\n  },\r\n  B321: {\r\n    codeString: \"HC8S:0,12;HC8N:0,12\"\r\n  },\r\n  B322: {\r\n    codeString: \"VL8:0,8;OS4W:0,8\"\r\n  },\r\n  B323: {\r\n    codeString: \"B572;P4N:2,17\"\r\n  },\r\n  B324: {\r\n    codeString: \"B572;P4S:2,13\"\r\n  },\r\n  B325: {\r\n    codeString: \"C4:0,8;VL4:2,12\"\r\n  },\r\n  B326: {\r\n    codeString: \"B1137;P4W:7,8\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B327: {\r\n    codeString: \"B400;B708:2,0\"\r\n  },\r\n  B328: {\r\n    codeString: \"B597;B695\"\r\n  },\r\n  B329: {\r\n    codeString: \"B457;B1154\"\r\n  },\r\n  B330: {\r\n    codeString: \"B418;P4S:8,13\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B331: {\r\n    codeString: \"P4N:0,8;P4S:0,14\"\r\n  },\r\n  B332: {\r\n    codeString: \"RA4E:0,10;RA4E:2,10\"\r\n  },\r\n  B333: {\r\n    codeString: \"B306;P4S:2,7\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B334: {\r\n    codeString: \"DL6N:0,10;DL4S:2,10;DL2N:2,8;DL2N:6,12\"\r\n  },\r\n  B335: {\r\n    codeString: \"LARR8E:0,10\"\r\n  },\r\n  B336: {\r\n    codeString: \"B484;B313\"\r\n  },\r\n  B337: {\r\n    codeString: \"VL4:0,10;P4E:2,10\"\r\n  },\r\n  B338: {\r\n    codeString: \"QC4NW:2,8;C4:0,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B339: {\r\n    codeString: \"B293;B291:4,0\"\r\n  },\r\n  B340: {\r\n    codeString: \"B1141;P4W:7,8\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B341: {\r\n    codeString: \"HW8W:0,8\"\r\n  },\r\n  B342: {\r\n    codeString: \"B392;B700;B700:4,0\"\r\n  },\r\n  B343: {\r\n    codeString: \"B239;B694\"\r\n  },\r\n  B344: {\r\n    codeString: \"B281;B325:2,0\"\r\n  },\r\n  B345: {\r\n    codeString: \"B678;C4:0,10\"\r\n  },\r\n  B346: {\r\n    codeString: \"LARR4E:0,10;LARR4S:4,6;LARR4N:4,14;LARR4W:8,10\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B347: {\r\n    codeString: \"B106;B314:4,0\"\r\n  },\r\n  B348: {\r\n    codeString: \"B368;B457:0,-2\"\r\n  },\r\n  B349: {\r\n    codeString: \"B518;P4W:1,10\"\r\n  },\r\n  B350: {\r\n    codeString: \"B122;VL8:8,4;HL4:8,4\",\r\n    anchorOffsetX: -2,\r\n    anchorOffsetY: -4\r\n  },\r\n  B351: {\r\n    codeString: \"C4:0,8;B314\"\r\n  },\r\n  B352: {\r\n    codeString: \"OR48N:0,8\"\r\n  },\r\n  B353: {\r\n    codeString: \"B303;HC4N:4,10;B303:8,0\"\r\n  },\r\n  B354: {\r\n    codeString: \"OS8S:0,8;B148:2,0\"\r\n  },\r\n  B355: {\r\n    codeString: \"AA8N:0,4;HL2:0,12;HL2:6,12;B247\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B356: {\r\n    codeString: \"B239;B651:2,0\"\r\n  },\r\n  B357: {\r\n    codeString: \"B366;B366:4,0\"\r\n  },\r\n  B358: {\r\n    codeString: \"B312;B500:8,0\"\r\n  },\r\n  B359: {\r\n    codeString: \"B312;B455:8,0\"\r\n  },\r\n  B360: {\r\n    codeString: \"B312;B312:8,0\"\r\n  },\r\n  B361: {\r\n    codeString: \"B455;B500:8,0\"\r\n  },\r\n  B362: {\r\n    codeString: \"B455;B455:8,0\"\r\n  },\r\n  B363: {\r\n    codeString: \"B455;B312:8,0\"\r\n  },\r\n  B364: {\r\n    codeString: \"B500;B500:8,0\"\r\n  },\r\n  B365: {\r\n    codeString: \"C4:0,10;C4:4,10;C4:2,14;QC4NW:4,8\"\r\n  },\r\n  B366: {\r\n    codeString: \"QC4NW:0,12\"\r\n  },\r\n  B367: {\r\n    codeString: \"B281;HL8:0,20;VL2:8,18\"\r\n  },\r\n  B368: {\r\n    codeString: \"DC4:0,12\"\r\n  },\r\n  B369: {\r\n    codeString: \"HL12:0,12;HC4S:1,12\"\r\n  },\r\n  B370: {\r\n    codeString: \"B394;B271:2,0\"\r\n  },\r\n  B371: {\r\n    codeString: \"HW2W:0,10;HW2W:2,10;HW2W:4,10\"\r\n  },\r\n  B372: {\r\n    codeString: \"B1143;P4W:7,4\",\r\n    anchorOffsetX: -0.5,\r\n    anchorOffsetY: -3\r\n  },\r\n  B373: {\r\n    codeString: \"DL6N:0,10;DL4S:4,8\"\r\n  },\r\n  B374: {\r\n    codeString: \"DL4S:0,12;VL8:4,8\"\r\n  },\r\n  B375: {\r\n    codeString: \"B239;HL8:0,12;HC4N:2,10\"\r\n  },\r\n  B376: {\r\n    codeString: \"C8:0,8;VL4:4,10;HL4:2,14\"\r\n  },\r\n  B377: {\r\n    codeString: \"B132;VL8:4,8\"\r\n  },\r\n  B378: {\r\n    codeString: \"P4W:0,10;B319:3,0;P4E:6,10\"\r\n  },\r\n  B379: {\r\n    codeString: \"B122:4,0;DL4S:0,8;DL4S:4,8;DL4S:8,8\",\r\n    anchorOffsetX: 2\r\n  },\r\n  B380: {\r\n    codeString: \"P4E:0,14;B418:3,0\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B381: {\r\n    codeString: \"B983;B700:2,0\"\r\n  },\r\n  B382: {\r\n    codeString: \"DL4-8N:0,8;B513:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B383: {\r\n    codeString: \"RA4E:0,10;B270:4,0;B270:6,0\",\r\n    anchorOffsetX: 2\r\n  },\r\n  B384: {\r\n    codeString: \"B418;P4W:5,6\",\r\n    anchorOffsetX: -2,\r\n    anchorOffsetY: -2\r\n  },\r\n  B385: {\r\n    codeString: \"B127;DL4N:8,8;DL2S:12,8\",\r\n    anchorOffsetX: -3\r\n  },\r\n  B386: {\r\n    codeString: \"B1154;B239:4,4;B1154:12,0\"\r\n  },\r\n  B387: {\r\n    codeString: \"HL8:0,12;RA4S:8,12\"\r\n  },\r\n  B388: {\r\n    codeString: \"B454;P4W:9,14\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B389: {\r\n    codeString: \"HL8:0,12;HC4N:4,10;QC4SE:8,8;QC4NE:8,12\"\r\n  },\r\n  B390: {\r\n    codeString: \"B123;P4W:9,8\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B391: {\r\n    codeString: \"B122;DL4N:8,8;DL2S:12,8\",\r\n    anchorOffsetX: -3\r\n  },\r\n  B392: {\r\n    codeString: \"B878;B548\"\r\n  },\r\n  B393: {\r\n    codeString: \"B433;B548:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B394: {\r\n    codeString: \"B695;B651:2,0\"\r\n  },\r\n  B395: {\r\n    codeString: \"AT4S:0,12;HC4N:0,10\"\r\n  },\r\n  B396: {\r\n    codeString: \"B418;QC4SE:0,16;QC4SE:8,16\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B397: {\r\n    codeString: \"B447;B271:2,0\"\r\n  },\r\n  B398: {\r\n    codeString: \"B291;B270:4,0\"\r\n  },\r\n  B399: {\r\n    codeString: \"VL4:0,10;HL4:0,12;R84:4,10;HL4:12,12\"\r\n  },\r\n  B400: {\r\n    codeString: \"AA4N:0,12;AA4N:4,12;AA4N:8,12\"\r\n  },\r\n  B401: {\r\n    codeString: \"VL3:0,10;DOT:0,14\"\r\n  },\r\n  B402: {\r\n    codeString: \"B335;B291:4,0\",\r\n    anchorOffsetX: 2\r\n  },\r\n  B403: {\r\n    codeString: \"QC4NW:0,12;HC4N:4,10;HL4:4,12;VL4:8,12;HL8:0,16\"\r\n  },\r\n  B404: {\r\n    codeString: \"B695:0,4;B281:8,0;B695:16,4\"\r\n  },\r\n  B405: {\r\n    codeString: \"VL4:0,12\"\r\n  },\r\n  B406: {\r\n    codeString: \"P4E:0,14;B1002:3,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B407: {\r\n    codeString: \"HL8:0,12;HC4S:0,12;VL4:8,12\"\r\n  },\r\n  B408: {\r\n    codeString: \"B457;B457:4,0\"\r\n  },\r\n  B409: {\r\n    codeString: \"DS8:0,4;QC4SE:0,12\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B410: {\r\n    codeString: \"B514;P4W:5,14\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B411: {\r\n    codeString: \"DL4S:0,12;DL8N:0,8\"\r\n  },\r\n  B412: {\r\n    codeString: \"B447;OR84N:0,12\"\r\n  },\r\n  B413: {\r\n    codeString: \"VL8:0,8;HL4:0,10;HL4:0,14;VL8:4,8\"\r\n  },\r\n  B414: {\r\n    codeString: \"B457;B278:2,0\"\r\n  },\r\n  B415: {\r\n    codeString: \"B281;B366:4,0\"\r\n  },\r\n  B416: {\r\n    codeString: \"HW8W:0,8;VL8:2,8;HW8E:2,8\"\r\n  },\r\n  B417: {\r\n    codeString: \"B418;P4W:7,10\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B418: {\r\n    codeString: \"AA8N:0,8;HL4:0,16;HL4:8,16\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B419: {\r\n    codeString: \"QC4NW:2,4;HW8W:0,8;HW8E:2,8\",\r\n    anchorOffsetX: -1,\r\n    anchorOffsetY: -4\r\n  },\r\n  B420: {\r\n    codeString: \"VL4:0,10;HL8:0,12;VL4:8,10\"\r\n  },\r\n  B421: {\r\n    codeString: \"B291;RA8S:0,8\"\r\n  },\r\n  B422: {\r\n    codeString: \"B281;QC4NE:0,12;B366:4,0\"\r\n  },\r\n  B423: {\r\n    codeString: \"B636;VL8:4,8\"\r\n  },\r\n  B424: {\r\n    codeString: \"B636;B303:2,0\"\r\n  },\r\n  B425: {\r\n    codeString: \"B597;B288:4,0\"\r\n  },\r\n  B426: {\r\n    codeString: \"VL8:0,8;B655;VL8:8,8\"\r\n  },\r\n  B427: {\r\n    codeString: \"B428;B428:8,0\"\r\n  },\r\n  B428: {\r\n    codeString: \"VL8:0,8\"\r\n  },\r\n  B429: {\r\n    codeString: \"P4S:0,7;B457;P4N:0,15\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B430: {\r\n    codeString: \"B818;HC4E:0,8;HC4W:6,8\"\r\n  },\r\n  B431: {\r\n    codeString: \"HL4:0,12;B313:4,0;B335:8,0\"\r\n  },\r\n  B432: {\r\n    codeString: \"B636;B700:2,0\"\r\n  },\r\n  B433: {\r\n    codeString: \"VL4:2,8;B106\"\r\n  },\r\n  B434: {\r\n    codeString: \"B518;DL2S:0,12\"\r\n  },\r\n  B435: {\r\n    codeString: \"W8E:0,8;QC4NW:1,4;B528:1.5,0;HC8E:1,8\"\r\n  },\r\n  B436: {\r\n    codeString: \"HL2:0,10;RA4N:2,8;HL2:6,10;RA4E:0,10;RA4W:6,10;HL8:0,14;VL2:4,14\"\r\n  },\r\n  B437: {\r\n    codeString: \"B548;B232:1,2\"\r\n  },\r\n  B438: {\r\n    codeString: \"B651;B1154\"\r\n  },\r\n  B439: {\r\n    codeString: \"B580;B829:3,0\"\r\n  },\r\n  B440: {\r\n    codeString: \"B509;B447;B457:2,0\"\r\n  },\r\n  B441: {\r\n    codeString: \"B420;VL4:4,10\"\r\n  },\r\n  B442: {\r\n    codeString: \"C8:0,8;C4:2,10;QC4NW:4,4\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B443: {\r\n    codeString: \"VL4:0,8;VL4:2,8;VL4:4,8;VL4:6,8;VL10:8,6;VL4:10,8;VL4:12,8;VL4:14,8;VL4:16,8;HL16:0,12;HL4:6,16\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B444: {\r\n    codeString: \"B457:0,-6;VL8:2,8;B1154\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B445: {\r\n    codeString: \"B289;B291:4,0\"\r\n  },\r\n  B446: {\r\n    codeString: \"B291;P4S:2,10\"\r\n  },\r\n  B447: {\r\n    codeString: \"HC8N:0,8\"\r\n  },\r\n  B448: {\r\n    codeString: \"B456;B270:6,2\"\r\n  },\r\n  B449: {\r\n    codeString: \"HL4:0,12\"\r\n  },\r\n  B450: {\r\n    codeString: \"DL4S:0,8;ARR4SW:0,12\"\r\n  },\r\n  B451: {\r\n    codeString: \"C4:0,8;C4:0,12;VL8:2,8\"\r\n  },\r\n  B452: {\r\n    codeString: \"VL8:0,8;HC8E:0,8\"\r\n  },\r\n  B453: {\r\n    codeString: \"HW8E:0,8;HC8E:0,8\"\r\n  },\r\n  B454: {\r\n    codeString: \"HC8N:0,12;B281\"\r\n  },\r\n  B455: {\r\n    codeString: \"B548;B710:2,0\"\r\n  },\r\n  B456: {\r\n    codeString: \"RT8SE:0,8\"\r\n  },\r\n  B457: {\r\n    codeString: \"C4:0,10\"\r\n  },\r\n  B458: {\r\n    codeString: \"B695:0,4;HL12:0,16\"\r\n  },\r\n  B459: {\r\n    codeString: \"DC8:0,8\"\r\n  },\r\n  B460: {\r\n    codeString: \"B718;P4W:5,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B461: {\r\n    codeString: \"HC4N:0,10;HL4:0,12;VL4:2,12\"\r\n  },\r\n  B462: {\r\n    codeString: \"VL6:4,8;C4:0,12\"\r\n  },\r\n  B463: {\r\n    codeString: \"HL4:0,8;VL8:2,8\"\r\n  },\r\n  B464: {\r\n    codeString: \"B509;B457:2,0\"\r\n  },\r\n  B465: {\r\n    codeString: \"B1142;P4W:6,16\"\r\n  },\r\n  B466: {\r\n    codeString: \"B171;P4S:4,5\",\r\n    anchorOffsetY: -3\r\n  },\r\n  B467: {\r\n    codeString: \"HL4:0,16;DL4-8N:2,8\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B468: {\r\n    codeString: \"VL8:0,8;HC4E:0,8\"\r\n  },\r\n  B469: {\r\n    codeString: \"B303;B278:2,0\"\r\n  },\r\n  B470: {\r\n    codeString: \"B281;B453:4,0\"\r\n  },\r\n  B471: {\r\n    codeString: \"B440;B939\"\r\n  },\r\n  B472: {\r\n    codeString: \"B636;P4N:2,9\"\r\n  },\r\n  B473: {\r\n    codeString: \"DL4-8N:0,8;HL4:0,16\"\r\n  },\r\n  B474: {\r\n    codeString: \"B112;B648:3,0\"\r\n  },\r\n  B475: {\r\n    codeString: \"B449:2,0;B281\"\r\n  },\r\n  B476: {\r\n    codeString: \"P4W:0,10;B477:3,0;P4E:12,10\"\r\n  },\r\n  B477: {\r\n    codeString: \"B136;P2E:1,11\"\r\n  },\r\n  B478: {\r\n    codeString: \"DL4-8N:1,8;HL8:2,10;DL4-8N:5,8;HL8:0,14\"\r\n  },\r\n  B479: {\r\n    codeString: \"B548;B347\"\r\n  },\r\n  B480: {\r\n    codeString: \"B695;B695:0,4\"\r\n  },\r\n  B481: {\r\n    codeString: \"QC4NW:1,8;HW4W:0,12;HW4E:1,12\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B482: {\r\n    codeString: \"B1154;P4S:0,14\"\r\n  },\r\n  B483: {\r\n    codeString: \"B281;C4:2,16;HW4W:3,16;HW4E:4,16\"\r\n  },\r\n  B484: {\r\n    codeString: \"OS8N:0,8\"\r\n  },\r\n  B485: {\r\n    codeString: \"B447;B457:2,0\"\r\n  },\r\n  B486: {\r\n    codeString: \"DL2N:0,8;VL8:2,8;DL2N:2,14\"\r\n  },\r\n  B487: {\r\n    codeString: \"B558;B558:4,0\"\r\n  },\r\n  B488: {\r\n    codeString: \"RA4W:0,10;B270:2,0\"\r\n  },\r\n  B489: {\r\n    codeString: \"B338;HW4W:1,12;HW4E:2,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B490: {\r\n    codeString: \"B291;B270:10,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B491: {\r\n    codeString: \"B291;B335:4,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B492: {\r\n    codeString: \"B291;B271:2,4\"\r\n  },\r\n  B493: {\r\n    codeString: \"B634;B270:4,-2\"\r\n  },\r\n  B494: {\r\n    codeString: \"HW8N:0,12;HL8:0,14;HW8S:0,14;B695:0,6\"\r\n  },\r\n  B495: {\r\n    codeString: \"HC4N:2,10;HL8:0,12;DL2-4S:0,12;HL4:2,16;DL2-4N:6,12\"\r\n  },\r\n  B496: {\r\n    codeString: \"HC4N:0,8;HC4N:4,8;VL6:4,10\"\r\n  },\r\n  B497: {\r\n    codeString: \"R48:0,8\"\r\n  },\r\n  B498: {\r\n    codeString: \"B428;B428:2,0\"\r\n  },\r\n  B499: {\r\n    codeString: \"HL12:0,8;VL8:0,8;RA8E:0,8;RA8W:8,8;VL8:12,8;HL12:0,16\"\r\n  },\r\n  B500: {\r\n    codeString: \"B548;B513:2,0\"\r\n  },\r\n  B501: {\r\n    codeString: \"B325;B281:2,0;B666:6,0\"\r\n  },\r\n  B502: {\r\n    codeString: \"DOT:2,10;HL4:0,12;DOT:2,14\"\r\n  },\r\n  B503: {\r\n    codeString: \"HW8E:0,8\"\r\n  },\r\n  B504: {\r\n    codeString: \"B122;P4W:9,14\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B505: {\r\n    codeString: \"B712;B313\"\r\n  },\r\n  B506: {\r\n    codeString: \"QC4NW:4,8;HC4N:0,10;HC4N:4,10;HC8S:0,12;B528:3.5,0\"\r\n  },\r\n  B507: {\r\n    codeString: \"QC4NW:3,4;VQW4NW:1,8;VQW4NE:3,8;HW4W:0,12;HW4E:5,12;HL4:1,16\",\r\n    anchorOffsetX: -0.5,\r\n    anchorOffsetY: -4\r\n  },\r\n  B508: {\r\n    codeString: \"B801;C2:2,9;C2:2,13\"\r\n  },\r\n  B509: {\r\n    codeString: \"DL8S:0,8\"\r\n  },\r\n  B510: {\r\n    codeString: \"B434;P4W:3,12\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B511: {\r\n    codeString: \"QC4NW:2,4;VL2:2,8;HC2N:0,9;HC2N:2,9;VL4:0,10;VL4:4,10;HC4S:0,14\",\r\n    anchorOffsetX: -1,\r\n    anchorOffsetY: -4\r\n  },\r\n  B512: {\r\n    codeString: \"HL8:0,16;VL8:4,8\"\r\n  },\r\n  B513: {\r\n    codeString: \"HL4:0,16;VL8:2,8\"\r\n  },\r\n  B514: {\r\n    codeString: \"VL4:0,8;DL4S:0,12;HL4:0,16\"\r\n  },\r\n  B515: {\r\n    codeString: \"HL8:0,16;VL4:8,12\"\r\n  },\r\n  B516: {\r\n    codeString: \"RA8N:0,12;VL4:8,12\"\r\n  },\r\n  B517: {\r\n    codeString: \"VL4:0,8;HL4:0,12;VL4:4,12\"\r\n  },\r\n  B518: {\r\n    codeString: \"VL8:0,8;HL4:0,16\"\r\n  },\r\n  B519: {\r\n    codeString: \"RA8E:0,8;HL4:0,16\"\r\n  },\r\n  B520: {\r\n    codeString: \"OR84S:0,12;HL2:8,16;B695:10,4;B170:10,0\"\r\n  },\r\n  B521: {\r\n    codeString: \"HC4S:0,8;HC4W:2,8;B122:4,0\",\r\n    anchorOffsetX: 2\r\n  },\r\n  B522: {\r\n    codeString: \"B156;P4S:6,5\",\r\n    anchorOffsetX: -1,\r\n    anchorOffsetY: -3\r\n  },\r\n  B523: {\r\n    codeString: \"B1140;P4W:9,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B524: {\r\n    codeString: \"HL4:0,12;VL4:2,12\"\r\n  },\r\n  B525: {\r\n    codeString: \"QC4NE:0,4;VL4:4,4;QC4NW:4,4;HC4N:2,8;VL4:2,10;VL4:6,10;HC4S:2,14\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B526: {\r\n    codeString: \"B1086;P4W:13,12\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B527: {\r\n    codeString: \"C4:0,12;HL8:2,12;HL8:2,16\"\r\n  },\r\n  B528: {\r\n    codeString: \"HW2W:0,13;HW2E:0.5,13\"\r\n  },\r\n  B529: {\r\n    codeString: \"B180;HL8:1,14\"\r\n  },\r\n  B530: {\r\n    codeString: \"DL4S:0,8;OR48N:4,8;HC4E:8,10\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B531: {\r\n    codeString: \"B281;P4S:2,14\"\r\n  },\r\n  B532: {\r\n    codeString: \"B447;B840\"\r\n  },\r\n  B533: {\r\n    codeString: \"B325;QC4NW:2,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B534: {\r\n    codeString: \"B884;B688:10,0;HL6:12,16\"\r\n  },\r\n  B535: {\r\n    codeString: \"HC4W:0,8;DC4:2,12;HC4E:6,8\"\r\n  },\r\n  B536: {\r\n    codeString: \"B411;B281\"\r\n  },\r\n  B537: {\r\n    codeString: \"B338;B528:1.5,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B538: {\r\n    codeString: \"B411;P4W:9,6\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B539: {\r\n    codeString: \"B878;B695\"\r\n  },\r\n  B540: {\r\n    codeString: \"B559;B270:6,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B541: {\r\n    codeString: \"B620;VL8:0,8;HL8:0,16\"\r\n  },\r\n  B542: {\r\n    codeString: \"OR84N:0,12;DL4N:8,8\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B543: {\r\n    codeString: \"HW2N:1,9.5;VL6:1,10;HL2:0,12;HL3:1,16;HC2E:4,14\"\r\n  },\r\n  B544: {\r\n    codeString: \"DOT:0,16;DOT:4,12;DOT:4,16\"\r\n  },\r\n  B545: {\r\n    codeString: \"B289;B105:4,0\"\r\n  },\r\n  B546: {\r\n    codeString: \"B503;B341:4,0\"\r\n  },\r\n  B547: {\r\n    codeString: \"B198;LARR4E:8,10\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B548: {\r\n    codeString: \"RA8N:0,8\"\r\n  },\r\n  B549: {\r\n    codeString: \"B1129;P4W:9,16\"\r\n  },\r\n  B550: {\r\n    codeString: \"HL16:0,16;HL8:8,8;VL8:16,8\"\r\n  },\r\n  B551: {\r\n    codeString: \"B559;B559:4,0\"\r\n  },\r\n  B552: {\r\n    codeString: \"AT8N:0,8;DL8-4S:4,8;DL4N:8,12\"\r\n  },\r\n  B553: {\r\n    codeString: \"B484;B699:3,0\"\r\n  },\r\n  B554: {\r\n    codeString: \"B335:4,0;B335:0,4\"\r\n  },\r\n  B555: {\r\n    codeString: \"DL4N:0,12;DLOC4SW:4,8;C4:4,8;SC4:4,8\"\r\n  },\r\n  B556: {\r\n    codeString: \"B695;B271:2,0\"\r\n  },\r\n  B557: {\r\n    codeString: \"C2:0,11;C2:2,10;C2:2,12;QC4NE:4,12\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B558: {\r\n    codeString: \"RA8W:0,8\"\r\n  },\r\n  B559: {\r\n    codeString: \"RA8E:0,8\"\r\n  },\r\n  B560: {\r\n    codeString: \"B548;B513:6,0;B548:8,0\"\r\n  },\r\n  B561: {\r\n    codeString: \"COMMA:0,12;COMMA:2,12\"\r\n  },\r\n  B562: {\r\n    codeString: \"B313;B281\"\r\n  },\r\n  B563: {\r\n    codeString: \"B428;B145:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B564: {\r\n    codeString: \"B391;QC2SE:14,8\",\r\n    anchorOffsetX: -4\r\n  },\r\n  B565: {\r\n    codeString: \"B695:0,4;B357:2,0\"\r\n  },\r\n  B566: {\r\n    codeString: \"RA8SW:0,8;RA2NE:0,14\"\r\n  },\r\n  B567: {\r\n    codeString: \"C8:0,8;C4:2,10\"\r\n  },\r\n  B568: {\r\n    codeString: \"B335;B695:0,4\"\r\n  },\r\n  B569: {\r\n    codeString: \"B1148;P4S:2,13\"\r\n  },\r\n  B570: {\r\n    codeString: \"HW4W:0,12;HL4:1,12;HL4:1,16;HW4E:5,12\"\r\n  },\r\n  B571: {\r\n    codeString: \"B418;B700:0,4;B700:8,4\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B572: {\r\n    codeString: \"OS8W:0,8\"\r\n  },\r\n  B573: {\r\n    codeString: \"B1119;QC4SW:4,16\"\r\n  },\r\n  B574: {\r\n    codeString: \"VL4:0,8;B239;VL4:8,8\"\r\n  },\r\n  B575: {\r\n    codeString: \"VL8:0,8;DL4S:0,8;HL4:0,12\"\r\n  },\r\n  B576: {\r\n    codeString: \"B170;DL4S:4,8\"\r\n  },\r\n  B577: {\r\n    codeString: \"B265;QC4NE:4,12;QC4NW:8,12\"\r\n  },\r\n  B578: {\r\n    codeString: \"HL4:0,10;HL4:0,14\"\r\n  },\r\n  B579: {\r\n    codeString: \"DL12N:0,8;RA4SE:4,12;RA4SE:8,8\"\r\n  },\r\n  B580: {\r\n    codeString: \"B447;B247\"\r\n  },\r\n  B581: {\r\n    codeString: \"C4:0,12;VL8:4,8;C4:4,12\"\r\n  },\r\n  B582: {\r\n    codeString: \"VL8:0,8;W8E:2,8;VL8:6,8\"\r\n  },\r\n  B583: {\r\n    codeString: \"B291;B457:2,0\"\r\n  },\r\n  B584: {\r\n    codeString: \"B281;DOT:2,18;DOT:6,18\"\r\n  },\r\n  B585: {\r\n    codeString: \"DL8-4N:0,10;AT4N:2,12\"\r\n  },\r\n  B586: {\r\n    codeString: \"C4:2,8;C4:0,12;C4:4,12;VL2:4,14;QC4SE:0,16\"\r\n  },\r\n  B587: {\r\n    codeString: \"OS8S:0,8;HL8:0,12\"\r\n  },\r\n  B588: {\r\n    codeString: \"B1006;P4W:9,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B589: {\r\n    codeString: \"B171;P4S:8,5\",\r\n    anchorOffsetY: -3\r\n  },\r\n  B590: {\r\n    codeString: \"HL4:0,8;VL6:2,8;HL4:0,14;HC4S:0,14\"\r\n  },\r\n  B591: {\r\n    codeString: \"B572;B556\"\r\n  },\r\n  B592: {\r\n    codeString: \"B171;P4W:13,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B593: {\r\n    codeString: \"B291;P4W:9,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B594: {\r\n    codeString: \"B239;B271:2,4\"\r\n  },\r\n  B595: {\r\n    codeString: \"B239;B695\"\r\n  },\r\n  B596: {\r\n    codeString: \"B688;QC4SE:8,8\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B597: {\r\n    codeString: \"HL8:0,8\"\r\n  },\r\n  B598: {\r\n    codeString: \"B1084;OS4S:0,12\"\r\n  },\r\n  B599: {\r\n    codeString: \"B291;B303:2,0\"\r\n  },\r\n  B600: {\r\n    codeString: \"B473;B1154:0,2\"\r\n  },\r\n  B601: {\r\n    codeString: \"HL8:0,16;HC4N:4,14;DL4N:8,12\"\r\n  },\r\n  B602: {\r\n    codeString: \"HC4N:0,12;HC4S:4,14;HC4N:8,12\"\r\n  },\r\n  B603: {\r\n    codeString: \"B602;B695:2,6\"\r\n  },\r\n  B604: {\r\n    codeString: \"B695;VL6:4,8;B622:3,4\"\r\n  },\r\n  B605: {\r\n    codeString: \"B604;P4W:6,14\"\r\n  },\r\n  B606: {\r\n    codeString: \"B651:0,2;B651:4,-2\"\r\n  },\r\n  B607: {\r\n    codeString: \"B548;B106:2,0\"\r\n  },\r\n  B608: {\r\n    codeString: \"B278;B1154\"\r\n  },\r\n  B609: {\r\n    codeString: \"B265;B695:4,0\"\r\n  },\r\n  B610: {\r\n    codeString: \"B636;P4S:2,13\"\r\n  },\r\n  B611: {\r\n    codeString: \"RA8SW:0,8;DL4N:0,12\"\r\n  },\r\n  B612: {\r\n    codeString: \"W8S:0,11;HW4N:8,11;HW4S:8,12\"\r\n  },\r\n  B613: {\r\n    codeString: \"C4:2,10;HC8N:0,12;HW4E:4,12\"\r\n  },\r\n  B614: {\r\n    codeString: \"DL4N:0,12;DLOC4SW:4,8;C4:4,8\"\r\n  },\r\n  B615: {\r\n    codeString: \"DL4-8S:0,8;HL4:4,16\"\r\n  },\r\n  B616: {\r\n    codeString: \"B513;B548:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B617: {\r\n    codeString: \"B482;B457\"\r\n  },\r\n  B618: {\r\n    codeString: \"B1119;C8:0,8;C4:2,10\"\r\n  },\r\n  B619: {\r\n    codeString: \"RA4NW:0,12;RA4NW:4,8\"\r\n  },\r\n  B620: {\r\n    codeString: \"HL8:0,8;VL4:4,8;HL4:4,12;VL8:8,8\"\r\n  },\r\n  B621: {\r\n    codeString: \"AT8N:0,8;AT8S:0,10\"\r\n  },\r\n  B622: {\r\n    codeString: \"VL4:1,10;DC2:0,11\"\r\n  },\r\n  B623: {\r\n    codeString: \"B695;B678:2,0\"\r\n  },\r\n  B624: {\r\n    codeString: \"B572;B623\"\r\n  },\r\n  B625: {\r\n    codeString: \"B325;P4W:3,12\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B626: {\r\n    codeString: \"B393;B455:10,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B627: {\r\n    codeString: \"B704;B312:8,0\"\r\n  },\r\n  B628: {\r\n    codeString: \"B171;P4S:4,10\"\r\n  },\r\n  B629: {\r\n    codeString: \"RT4SE:0,12\"\r\n  },\r\n  B630: {\r\n    codeString: \"B291;B319:3,0\"\r\n  },\r\n  B631: {\r\n    codeString: \"B161;DOT:1,12;DOT:3,12;DOT:2,13\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B632: {\r\n    codeString: \"B1150;P4S:2,13\"\r\n  },\r\n  B633: {\r\n    codeString: \"DOT:0,8;HL4:2,8;DOT:8,8;VL4:0,10;VL4:8,10;DOT:0,16;HL4:2,16;DOT:8,16\"\r\n  },\r\n  B634: {\r\n    codeString: \"HL8:0,12\"\r\n  },\r\n  B635: {\r\n    codeString: \"B1063;B335:4,0\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B636: {\r\n    codeString: \"C8:0,8\"\r\n  },\r\n  B637: {\r\n    codeString: \"B695:0,4;B1154\"\r\n  },\r\n  B638: {\r\n    codeString: \"B851;W8W:7,8;DL2S:8,8\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B639: {\r\n    codeString: \"OR84S:0,12\"\r\n  },\r\n  B640: {\r\n    codeString: \"P4E:0,8;B124:3,0\",\r\n    anchorOffsetX: 2.5\r\n  },\r\n  B641: {\r\n    codeString: \"B201:0,-4;HL15:0,12;B700:3,0;B700:7,0;B700:11,0;DL2N:12,9;DL2S:13,10\",\r\n    anchorOffsetX: 1.5,\r\n    anchorOffsetY: -4\r\n  },\r\n  B642: {\r\n    codeString: \"B473;B457\"\r\n  },\r\n  B643: {\r\n    codeString: \"B108;HL4:0,12\"\r\n  },\r\n  B644: {\r\n    codeString: \"B1121;B1121:4,0\"\r\n  },\r\n  B645: {\r\n    codeString: \"B927;DOT:2,18\"\r\n  },\r\n  B646: {\r\n    codeString: \"B270:0,2;B647:1,0\",\r\n    anchorOffsetX: 0.5\r\n  },\r\n  B647: {\r\n    codeString: \"DL2N:0,11\"\r\n  },\r\n  B648: {\r\n    codeString: \"HW4W:0,12\"\r\n  },\r\n  B649: {\r\n    codeString: \"B270;B270:2,0;RA4W:4,10\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B650: {\r\n    codeString: \"RT4E:0,10\"\r\n  },\r\n  B651: {\r\n    codeString: \"S4:0,10\"\r\n  },\r\n  B652: {\r\n    codeString: \"B647;B270:3,-2\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B653: {\r\n    codeString: \"B335;B428:4,0\"\r\n  },\r\n  B654: {\r\n    codeString: \"P4E:0,10;B374:3,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B655: {\r\n    codeString: \"C8:0,8;RA4SW:4,8\"\r\n  },\r\n  B656: {\r\n    codeString: \"B700;P4W:5,12\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B657: {\r\n    codeString: \"P4E:0,10;VL4:4,10\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B658: {\r\n    codeString: \"B418;P4W:13,14\",\r\n    anchorOffsetX: -3.5\r\n  },\r\n  B659: {\r\n    codeString: \"B695:0,4;B212:2,0\"\r\n  },\r\n  B660: {\r\n    codeString: \"B374;B651:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B661: {\r\n    codeString: \"B291;P4S:2,5\",\r\n    anchorOffsetY: -3\r\n  },\r\n  B662: {\r\n    codeString: \"AT4S:0,12;VL2:2,10\"\r\n  },\r\n  B663: {\r\n    codeString: \"VL2:2,6;VL2:6,6;S8:0,8;VL2:2,16;VL2:6,16\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B664: {\r\n    codeString: \"B827;HL4:8,12;B700:8,0;DL2N:9,9;DL2S:10,10\"\r\n  },\r\n  B665: {\r\n    codeString: \"RA2NE:0,14;HL8:2,16;RA2NW:10,14\"\r\n  },\r\n  B666: {\r\n    codeString: \"QC4SE:0,8;VL8:4,8;QC4SW:4,8\"\r\n  },\r\n  B667: {\r\n    codeString: \"B281;B700:2,0\"\r\n  },\r\n  B668: {\r\n    codeString: \"B188;OS4S:0,8\"\r\n  },\r\n  B669: {\r\n    codeString: \"B666;P4W:5,12\"\r\n  },\r\n  B670: {\r\n    codeString: \"B447;B1048\"\r\n  },\r\n  B671: {\r\n    codeString: \"B281;C4:2,16;B416:2,0\"\r\n  },\r\n  B672: {\r\n    codeString: \"B122;HC8N:0,8;DL4N:8,8\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B673: {\r\n    codeString: \"B447;B502:2,0\"\r\n  },\r\n  B674: {\r\n    codeString: \"B548;VL6:4,8;HC4S:4,14\"\r\n  },\r\n  B675: {\r\n    codeString: \"B607;B11:7,0;B500:8,0\"\r\n  },\r\n  B676: {\r\n    codeString: \"B634;B270:4,2\"\r\n  },\r\n  B677: {\r\n    codeString: \"VL4:2,10;P4E:0,10\"\r\n  },\r\n  B678: {\r\n    codeString: \"LARR8N:0,8\"\r\n  },\r\n  B679: {\r\n    codeString: \"DL8S:0,8;RA4NW:0,8\"\r\n  },\r\n  B680: {\r\n    codeString: \"DL8N:0,8;RA4NE:4,8\"\r\n  },\r\n  B681: {\r\n    codeString: \"B171;B314:4,-2\"\r\n  },\r\n  B682: {\r\n    codeString: \"HW8W:0,8;HL8:2,8;HL2:2,16;HL2:8,16;HW8E:10,8;B314:4,-2;P4N:4,16\"\r\n  },\r\n  B683: {\r\n    codeString: \"B1144;P4S:10,13\"\r\n  },\r\n  B684: {\r\n    codeString: \"C4:2,12;B1119\"\r\n  },\r\n  B685: {\r\n    codeString: \"QC4NW:4,12;B281;C4:2,16\"\r\n  },\r\n  B686: {\r\n    codeString: \"B685;HW4W:3,16;HW4E:4,16\"\r\n  },\r\n  B687: {\r\n    codeString: \"HC4N:2,8;VL4:2,10;VL4:6,10;HC4S:2,14;B1119\"\r\n  },\r\n  B688: {\r\n    codeString: \"HL8:0,12;B700;B700:4,0\"\r\n  },\r\n  B689: {\r\n    codeString: \"DL4S:0,8;B688:4,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B690: {\r\n    codeString: \"B171:3,0;P4E:0,10;P4W:16,10\"\r\n  },\r\n  B691: {\r\n    codeString: \"B572;P4W:9,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B692: {\r\n    codeString: \"DC2:0,8;VL8:1,8\"\r\n  },\r\n  B693: {\r\n    codeString: \"B411;DL4N:8,12;DL8S:4,8\"\r\n  },\r\n  B694: {\r\n    codeString: \"B939;B651:2,0\"\r\n  },\r\n  B695: {\r\n    codeString: \"W8N:0,11\"\r\n  },\r\n  B696: {\r\n    codeString: \"B636;B556\"\r\n  },\r\n  B697: {\r\n    codeString: \"HL8:0,12;AT4N:2,12\"\r\n  },\r\n  B698: {\r\n    codeString: \"B636;P4W:1,10\"\r\n  },\r\n  B699: {\r\n    codeString: \"OC2SW:0,10;VL1:1,12;DOT:1,14\"\r\n  },\r\n  B700: {\r\n    codeString: \"C4:0,12;DLIC4N:0,12;DLIC4S:0,12\"\r\n  },\r\n  B701: {\r\n    codeString: \"B212;B700\"\r\n  },\r\n  B702: {\r\n    codeString: \"B281;B561:3,0\"\r\n  },\r\n  B703: {\r\n    codeString: \"B281;B699:3,0\"\r\n  },\r\n  B704: {\r\n    codeString: \"B548;B710:6,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B705: {\r\n    codeString: \"B114;B335:4,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B706: {\r\n    codeString: \"B291;SC8:0,8\"\r\n  },\r\n  B707: {\r\n    codeString: \"B291;VL8:2,8;VL8:6,8;HL8:0,10;HL8:0,14\"\r\n  },\r\n  B708: {\r\n    codeString: \"QC4NE:0,8;QC4NW:4,8\"\r\n  },\r\n  B709: {\r\n    codeString: \"B120:0,-4\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B710: {\r\n    codeString: \"VL4:2,8;B314\"\r\n  },\r\n  B711: {\r\n    codeString: \"B106;B106:0,-4\"\r\n  },\r\n  B712: {\r\n    codeString: \"B597;B281\"\r\n  },\r\n  B713: {\r\n    codeString: \"HL12:0,16;B602:0,4\"\r\n  },\r\n  B714: {\r\n    codeString: \"B132;P4W:1,6\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B715: {\r\n    codeString: \"B1135;P4S:10,13\"\r\n  },\r\n  B716: {\r\n    codeString: \"LARRC8EC:0,8\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B717: {\r\n    codeString: \"AA4S:0,8;HL4:0,12;HL4:0,14;VL4:2,12\"\r\n  },\r\n  B718: {\r\n    codeString: \"B132;HC4N:0,10\"\r\n  },\r\n  B719: {\r\n    codeString: \"B377;B106\"\r\n  },\r\n  B720: {\r\n    codeString: \"VL8:4,8;DL4N:0,8;HL4:0,12\"\r\n  },\r\n  B721: {\r\n    codeString: \"B170;DL4N:0,8\"\r\n  },\r\n  B722: {\r\n    codeString: \"B695;B617:2,0\"\r\n  },\r\n  B723: {\r\n    codeString: \"B678;B271:4,0\"\r\n  },\r\n  B724: {\r\n    codeString: \"VL8:0,8;HW4N:0,7;HW4S:0,8;HW4S:0,16;VL8:4,8\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B725: {\r\n    codeString: \"B313;B355\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B726: {\r\n    codeString: \"B313;B247\"\r\n  },\r\n  B727: {\r\n    codeString: \"B313;B733\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B728: {\r\n    codeString: \"B513;B737:0,-2\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B729: {\r\n    codeString: \"B708;B513:2,0\"\r\n  },\r\n  B730: {\r\n    codeString: \"B246;B622:5,0\"\r\n  },\r\n  B731: {\r\n    codeString: \"HC2W:0,14;HL8:1,14;HL8:1,16;HC2E:9,14\"\r\n  },\r\n  B732: {\r\n    codeString: \"B570;HL6:0,14\"\r\n  },\r\n  B733: {\r\n    codeString: \"B447:0,-4;B247\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B734: {\r\n    codeString: \"P4W:0,10;B355:3,0;P4E:12,10\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B735: {\r\n    codeString: \"B313;B894:2,0\"\r\n  },\r\n  B736: {\r\n    codeString: \"B803;B513:2,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B737: {\r\n    codeString: \"HC4S:0,8\"\r\n  },\r\n  B738: {\r\n    codeString: \"HW4W:0,8;HW4E:3,8\"\r\n  },\r\n  B739: {\r\n    codeString: \"B500;B548:8,0\"\r\n  },\r\n  B740: {\r\n    codeString: \"B455;B548:8,0\"\r\n  },\r\n  B741: {\r\n    codeString: \"B312;B548:8,0\"\r\n  },\r\n  B742: {\r\n    codeString: \"B739;B622:11,0\"\r\n  },\r\n  B743: {\r\n    codeString: \"B712;B303:2,0\"\r\n  },\r\n  B744: {\r\n    codeString: \"HL12:0,10;VL6:0,10;VL2:10,12;HL8:2,14;VL6:12,10;HL12:0,16\"\r\n  },\r\n  B745: {\r\n    codeString: \"W8E:0,8;W8W:6,8;HL6:1,16\"\r\n  },\r\n  B746: {\r\n    codeString: \"B412;B699:3,0\"\r\n  },\r\n  B747: {\r\n    codeString: \"RT8S:0,8;VL4:4,12;HL8:0,16\"\r\n  },\r\n  B748: {\r\n    codeString: \"C8:0,8;B894:2,0\"\r\n  },\r\n  B749: {\r\n    codeString: \"HL4:0,11;HL4:0,13;HC4N:2,8;VL4:2,10;HC4S:2,14\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B750: {\r\n    codeString: \"B467;HL4:8,16;DL4-8S:6,8\"\r\n  },\r\n  B751: {\r\n    codeString: \"B447;B106:2,0\"\r\n  },\r\n  B752: {\r\n    codeString: \"HC8N:0,8;HL12:0,12\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B753: {\r\n    codeString: \"B167;B457:2,0\"\r\n  },\r\n  B754: {\r\n    codeString: \"HW8N:0,12;HL8:0,14;HW8S:0,14\"\r\n  },\r\n  B755: {\r\n    codeString: \"HL4:0,8;VL8:0,8;VL8:2,8;VL8:4,8\"\r\n  },\r\n  B756: {\r\n    codeString: \"B731:0,-4;B700:1,0;B700:5,0\"\r\n  },\r\n  B757: {\r\n    codeString: \"B518:2,0;B700\"\r\n  },\r\n  B758: {\r\n    codeString: \"B292;B335:8,0\"\r\n  },\r\n  B759: {\r\n    codeString: \"C4:0,10;C4:3,10;C4:6,10\"\r\n  },\r\n  B760: {\r\n    codeString: \"HC8E:0,8;LARR8E:0,10\"\r\n  },\r\n  B761: {\r\n    codeString: \"B695:0,4;P4S:0,12\"\r\n  },\r\n  B762: {\r\n    codeString: \"B720;P4W:5,12\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B763: {\r\n    codeString: \"B720:1,0;P4N:0,13\",\r\n    anchorOffsetX: 0.5\r\n  },\r\n  B764: {\r\n    codeString: \"B170;P4S:5,9\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B765: {\r\n    codeString: \"B170;P4W:9,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B766: {\r\n    codeString: \"P4E:0,10;B170:3,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B767: {\r\n    codeString: \"B170;P4N:2,17\"\r\n  },\r\n  B768: {\r\n    codeString: \"B170;P4N:2,13\"\r\n  },\r\n  B769: {\r\n    codeString: \"B170;VL4:0,12\"\r\n  },\r\n  B770: {\r\n    codeString: \"B695:0,4;DL4N:1,12;DL4N:3,14;DL2S:1,16;DL2S:5,12;DL5N:6,8\"\r\n  },\r\n  B771: {\r\n    codeString: \"B695:0,4;DL4N:1,12;DL4N:3,14;DL2S:1,16;DL2S:5,12;DL2N:6,11;DL4N:7,6;DL4N:9,8;DL2S:7,10;DL2S:11,6\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B772: {\r\n    codeString: \"B170;RA4NW:0,8\"\r\n  },\r\n  B773: {\r\n    codeString: \"HC8N:0,4;B1040\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B774: {\r\n    codeString: \"C8:0,4;OR42N:2,12\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B775: {\r\n    codeString: \"B392;B270:4,0\"\r\n  },\r\n  B776: {\r\n    codeString: \"B265;HC8N:4,12\"\r\n  },\r\n  B777: {\r\n    codeString: \"DOT:0,10;DOT:0,14;DOT:4,10;DOT:4,14\"\r\n  },\r\n  B778: {\r\n    codeString: \"S4:0,8;VL4:2,12\"\r\n  },\r\n  B779: {\r\n    codeString: \"HC4N:0,8;VL4:0,10;VL4:4,10;HL4:0,14;VL2:2,14\"\r\n  },\r\n  B780: {\r\n    codeString: \"B395;P4W:4,8\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B781: {\r\n    codeString: \"R84:0,10;RA4E:0,10;RA4W:6,10\"\r\n  },\r\n  B782: {\r\n    codeString: \"RT4E:0,10;S4:2,10;RT4W:6,10\"\r\n  },\r\n  B783: {\r\n    codeString: \"LARRHC8NC:0,8;LARRHC8SC:2,12\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B784: {\r\n    codeString: \"B450;B428:4,0\"\r\n  },\r\n  B785: {\r\n    codeString: \"ARR4NW:0,8;ARR4SW:0,12;B428:4,0\"\r\n  },\r\n  B786: {\r\n    codeString: \"B374;B457:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B787: {\r\n    codeString: \"DL4S:0,8;DL4N:5,8;VL4:4,12;VL4:5,12\"\r\n  },\r\n  B788: {\r\n    codeString: \"B630;P4S:2,5\",\r\n    anchorOffsetY: -3\r\n  },\r\n  B789: {\r\n    codeString: \"OS4N:0,12;HC4E:4,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B790: {\r\n    codeString: \"OS4N:0,12;DL4N:4,8\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B791: {\r\n    codeString: \"HL8:0,10;HC4N:2,8\"\r\n  },\r\n  B792: {\r\n    codeString: \"HC4W:0,8;OS8N:2,8;HC4E:10,8\"\r\n  },\r\n  B793: {\r\n    codeString: \"HL2:0,14;R84:2,12;HL2:10,14\"\r\n  },\r\n  B794: {\r\n    codeString: \"B280;P4W:8,7\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B795: {\r\n    codeString: \"B280;P4W:9,14\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B796: {\r\n    codeString: \"B280:3,0;P4E:0,6\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B797: {\r\n    codeString: \"B695:0,4;B456:8,0\"\r\n  },\r\n  B798: {\r\n    codeString: \"OR84N:0,8;RA4S:0,8;RA4S:4,8\"\r\n  },\r\n  B799: {\r\n    codeString: \"B281;B695:8,4;B281:16,0\"\r\n  },\r\n  B800: {\r\n    codeString: \"HL12:0,12;C8:2,8\"\r\n  },\r\n  B801: {\r\n    codeString: \"HW8W:0,8;HW8E:4,8\"\r\n  },\r\n  B802: {\r\n    codeString: \"B447;B699:3,0\"\r\n  },\r\n  B803: {\r\n    codeString: \"B447;LARR4E:8,10\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B804: {\r\n    codeString: \"B377;B447\"\r\n  },\r\n  B805: {\r\n    codeString: \"B1130;P4W:8,8\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B806: {\r\n    codeString: \"B1131;P4W:9,15\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B807: {\r\n    codeString: \"B321;QC2SW:8,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B808: {\r\n    codeString: \"B1134;P4W:9,13\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B809: {\r\n    codeString: \"B1133;P4W:9,15\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B810: {\r\n    codeString: \"B123;QC2SW:8,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B811: {\r\n    codeString: \"B566;P4N:2,17\"\r\n  },\r\n  B812: {\r\n    codeString: \"B851;VL2:0,16;VL2:4,16;VL2:8,16\"\r\n  },\r\n  B813: {\r\n    codeString: \"B447;HL4:2,12;AT4N:2,12\"\r\n  },\r\n  B814: {\r\n    codeString: \"R84:0,10;VL4:4,10\"\r\n  },\r\n  B815: {\r\n    codeString: \"B291;B723\"\r\n  },\r\n  B816: {\r\n    codeString: \"B817;B548:8,0;HL8:8,16;VL8:12,8;VL4:16,12\"\r\n  },\r\n  B817: {\r\n    codeString: \"B392;VL8:4,8\"\r\n  },\r\n  B818: {\r\n    codeString: \"B321;VL4:0,8;VL4:8,8\"\r\n  },\r\n  B819: {\r\n    codeString: \"B550;B191:8,0\"\r\n  },\r\n  B820: {\r\n    codeString: \"B803;B451:2,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B821: {\r\n    codeString: \"OR48N:0,8;RA4N:0,6\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B822: {\r\n    codeString: \"B566:3,0;P4E:0,10\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B823: {\r\n    codeString: \"B428;B120:2,0;B428:8,0\"\r\n  },\r\n  B824: {\r\n    codeString: \"R84:0,10\"\r\n  },\r\n  B825: {\r\n    codeString: \"RA4N:0,6;VL8:0,8;HL16:0,16;VL4:4,8;RA8N:4,8;VL4:12,8;RA4N:12,6;VL8:16,8\"\r\n  },\r\n  B826: {\r\n    codeString: \"B447;B206:4,0\"\r\n  },\r\n  B827: {\r\n    codeString: \"C8:0,8;DLIC8N:0,8;DLIC8S:0,8\"\r\n  },\r\n  B828: {\r\n    codeString: \"B447;B829:3,0\"\r\n  },\r\n  B829: {\r\n    codeString: \"VL2:1,10;C2:0,13\"\r\n  },\r\n  B830: {\r\n    codeString: \"HL12:0,12;AA4N:4,12;AA4N:8,12;VL4:12,8;HL2:12,8\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B831: {\r\n    codeString: \"LARR8W:0,10;VL4:8,8\"\r\n  },\r\n  B832: {\r\n    codeString: \"B239;B829:3,0\"\r\n  },\r\n  B833: {\r\n    codeString: \"HC4N:0,10;R84:0,12\"\r\n  },\r\n  B834: {\r\n    codeString: \"B122;B845\"\r\n  },\r\n  B835: {\r\n    codeString: \"B447;B678:2,0\"\r\n  },\r\n  B836: {\r\n    codeString: \"LARRHC8NC:0,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B837: {\r\n    codeString: \"B945;B433:2,0\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B838: {\r\n    codeString: \"B945;B513:2,0\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B839: {\r\n    codeString: \"B945;B710:2,0\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B840: {\r\n    codeString: \"RT8N:0,12\"\r\n  },\r\n  B841: {\r\n    codeString: \"B412;B270:4,0\"\r\n  },\r\n  B842: {\r\n    codeString: \"HC4N:0,8;VL4:0,10;VL4:4,10;HC4S:0,14\"\r\n  },\r\n  B843: {\r\n    codeString: \"B265;HL8:4,14\"\r\n  },\r\n  B844: {\r\n    codeString: \"HL8:0,12;DL4S:0,12\"\r\n  },\r\n  B845: {\r\n    codeString: \"DL2S:0,10;DL2S:2,10;DL2S:4,10\"\r\n  },\r\n  B846: {\r\n    codeString: \"DL8-4N:0,12;HL4:8,12\"\r\n  },\r\n  B847: {\r\n    codeString: \"B695:0,4;B366:4,0\"\r\n  },\r\n  B848: {\r\n    codeString: \"B639;P4S:2,9\"\r\n  },\r\n  B849: {\r\n    codeString: \"HL8:0,12;VL4:2,12;VL4:6,12;HL8:0,16\"\r\n  },\r\n  B850: {\r\n    codeString: \"B391;DL2N:13,7\",\r\n    anchorOffsetX: -3.5\r\n  },\r\n  B851: {\r\n    codeString: \"HC8N:0,12;B695:0,4\"\r\n  },\r\n  B852: {\r\n    codeString: \"B871;P4W:5,8\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B853: {\r\n    codeString: \"B871;P4W:5,14\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B854: {\r\n    codeString: \"HC8N:0,12\"\r\n  },\r\n  B855: {\r\n    codeString: \"B856;P4W:9,12\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B856: {\r\n    codeString: \"VL8:4,8;HW8N:0,12;HL8:0,14\"\r\n  },\r\n  B857: {\r\n    codeString: \"VL6:2,8;VL8:4,8;VL6:6,8;HC4S:2,14;B281;C4:2,16\"\r\n  },\r\n  B858: {\r\n    codeString: \"DOT:0,8;DOT:0,12;DOT:0,16;DOT:4,10;DOT:4,14;DOT:8,10;DOT:8,14;B695:6,0\"\r\n  },\r\n  B859: {\r\n    codeString: \"OR84S:0,12;HC8S:0,12\"\r\n  },\r\n  B860: {\r\n    codeString: \"B695;B939\"\r\n  },\r\n  B861: {\r\n    codeString: \"B866;DOT:2,10;DOT:2,12\"\r\n  },\r\n  B862: {\r\n    codeString: \"B527;DOT:6,14;DOT:8,14\"\r\n  },\r\n  B863: {\r\n    codeString: \"B114;B695:2,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B864: {\r\n    codeString: \"R84:0,10;VL4:2,10;VL4:4,10;VL4:6,10\"\r\n  },\r\n  B865: {\r\n    codeString: \"B651;B462:2,0\"\r\n  },\r\n  B866: {\r\n    codeString: \"VL8:0,8;VL8:4,8;C4:0,14\"\r\n  },\r\n  B867: {\r\n    codeString: \"HL4:0,8;B866\"\r\n  },\r\n  B868: {\r\n    codeString: \"B871;P4W:5,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B869: {\r\n    codeString: \"QC4NW:0,12;HL2:4,12;QC4NW:2,12;HL2:0,16\"\r\n  },\r\n  B870: {\r\n    codeString: \"B871;P4W:5,6\",\r\n    anchorOffsetX: -1.5,\r\n    anchorOffsetY: -1\r\n  },\r\n  B871: {\r\n    codeString: \"HL4:0,8;HL4:0,10;HL4:0,12;HL4:0,14;HL4:0,16\"\r\n  },\r\n  B872: {\r\n    codeString: \"VL8:0,8;P4W:1,8\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B873: {\r\n    codeString: \"B856;P4W:5,8\"\r\n  },\r\n  B874: {\r\n    codeString: \"B871;P4W:5,12\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B875: {\r\n    codeString: \"B573;VL8:4,8\"\r\n  },\r\n  B876: {\r\n    codeString: \"B736;LARR4W:14,10\",\r\n    anchorOffsetX: -5\r\n  },\r\n  B877: {\r\n    codeString: \"B597;B423;B281\"\r\n  },\r\n  B878: {\r\n    codeString: \"OR84N:0,12\"\r\n  },\r\n  B879: {\r\n    codeString: \"B391;P4W:9,14\",\r\n    anchorOffsetX: -3\r\n  },\r\n  B880: {\r\n    codeString: \"HC8W:0,8;HC4E:4,8;HC4E:4,12\"\r\n  },\r\n  B881: {\r\n    codeString: \"B391;P4W:15,8\",\r\n    anchorOffsetX: -4.5\r\n  },\r\n  B882: {\r\n    codeString: \"B1128;P4W:7,10\"\r\n  },\r\n  B883: {\r\n    codeString: \"P4W:0,10;B513:3,0;P4E:8,10\"\r\n  },\r\n  B884: {\r\n    codeString: \"OR84S:0,12;HL4:8,16\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B885: {\r\n    codeString: \"B803;B457:2,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B886: {\r\n    codeString: \"B238;B2115:4,0\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B887: {\r\n    codeString: \"LARROC8NWC:0,8\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B888: {\r\n    codeString: \"B887;B281:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B889: {\r\n    codeString: \"B1136;P4S:10,13\"\r\n  },\r\n  B890: {\r\n    codeString: \"B695;HW4N:4,11\"\r\n  },\r\n  B891: {\r\n    codeString: \"VL4:0,10;HL4:0,12\"\r\n  },\r\n  B892: {\r\n    codeString: \"HL12:0,12;B700;B700:4,0;B700:8,0\"\r\n  },\r\n  B893: {\r\n    codeString: \"B271:2,0;B281\"\r\n  },\r\n  B894: {\r\n    codeString: \"C4:0,10;VL4:2,10\"\r\n  },\r\n  B895: {\r\n    codeString: \"B635;VL8:12,8\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B896: {\r\n    codeString: \"C8:0,8;B622:3,0\"\r\n  },\r\n  B897: {\r\n    codeString: \"B447;B516\"\r\n  },\r\n  B898: {\r\n    codeString: \"B438;DOT:2,12\"\r\n  },\r\n  B899: {\r\n    codeString: \"R48:0,8;HL4:0,12\"\r\n  },\r\n  B900: {\r\n    codeString: \"B280;P2SW:5,10\"\r\n  },\r\n  B901: {\r\n    codeString: \"B291;B829:3,0\"\r\n  },\r\n  B902: {\r\n    codeString: \"B86;B81:2,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'adjectival',\r\n    width: 4,\r\n    name: \"INDICATOR DESCRIPTION OF ACTION\"\r\n  },\r\n  B903: {\r\n    codeString: \"HL2:0,5\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    name: \"INDICATOR CONTINUOUS\"\r\n  },\r\n  B904: {\r\n    codeString: \"DL2N:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR DEFINITE\"\r\n  },\r\n  // Not planned for Unicode\r\n  B905: {\r\n    codeString: \"AT2N:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR FEMININE\"\r\n  },\r\n  // Not planned for Unicode\r\n  B906: {\r\n    codeString: \"VL2:0.5,4;HL1:0,6;DL.5N:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    width: 1,\r\n    name: \"INDICATOR FIRST PERSON\"\r\n  },\r\n  B907: {\r\n    codeString: \"VL1.25:0,4;SDOT:0,6\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    width: 0,\r\n    name: \"INDICATOR IMPERATIVE\"\r\n  },\r\n  // Not planned for Unicode\r\n  B908: {\r\n    codeString: \"DL2S:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR INDEFINITE\"\r\n  },\r\n  // Not planned for Unicode\r\n  B909: {\r\n    codeString: \"VL2:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    width: 0,\r\n    name: \"INDICATOR NEUTER\"\r\n  },\r\n  // Not planned for Unicode\r\n  B910: {\r\n    codeString: \"P2E:0,4;VL2:2,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR DIRECT OBJECT\"\r\n  },\r\n  B911: {\r\n    codeString: \"B92;B86:1.5,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'adjectival',\r\n    width: 3.5,\r\n    name: \"INDICATOR PAST PARTICIPLE\"\r\n  },\r\n  B912: {\r\n    codeString: \"B92;SDOT:1.5,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'adjectival',\r\n    anchorOffsetX: -0.5,\r\n    width: 1.5,\r\n    name: \"INDICATOR PAST PERFECTIVE PARTICIPLE\"\r\n  },\r\n  // Not planned for Unicode\r\n  B913: {\r\n    codeString: \"SC2:0,4\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR POSSESSIVE\"\r\n  },\r\n  B914: {\r\n    codeString: \"B928;B86:3,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'adjectival',\r\n    width: 5,\r\n    name: \"INDICATOR PRESENT PARTICIPLE\"\r\n  },\r\n  // Not planned for Unicode\r\n  B915: {\r\n    codeString: \"HC1N:0,4;DL1-1.5N:0,4.5;HL1:0,6\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    width: 1,\r\n    name: \"INDICATOR SECOND PERSON\"\r\n  },\r\n  // Not planned for Unicode\r\n  B916: {\r\n    codeString: \"OC1SW:0,4;OC1NW:0,5\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    width: 1,\r\n    name: \"INDICATOR THIRD PERSON\"\r\n  },\r\n  B917: {\r\n    codeString: \"B239;LARR4E:8,10\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B918: {\r\n    codeString: \"B239;HC2E:8,12\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B919: {\r\n    codeString: \"QC4SW:0,12\"\r\n  },\r\n  B920: {\r\n    codeString: \"B239;B271:2,0\"\r\n  },\r\n  B921: {\r\n    codeString: \"HL8:0,12;C4:2,10\"\r\n  },\r\n  B922: {\r\n    codeString: \"HW2E:0,11;HW4E:1,10;HW8E:1,8\"\r\n  },\r\n  B923: {\r\n    codeString: \"P4S:0,9;B619:1,0\",\r\n    anchorOffsetX: 0.5\r\n  },\r\n  B924: {\r\n    codeString: \"B695;B325:2,0\"\r\n  },\r\n  B925: {\r\n    codeString: \"C2:0,8;C8:1,8;C2:8,8;DOT:3,12;DOT:7,12;DOT:5,14\"\r\n  },\r\n  B926: {\r\n    codeString: \"LARRHC8NCC:0,12\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B927: {\r\n    codeString: \"B936;HL4:0,12\"\r\n  },\r\n  B928: {\r\n    codeString: \"B92;B87:1.5,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'verbal',\r\n    name: \"INDICATOR PRESENT\"\r\n  },\r\n  B929: {\r\n    codeString: \"B335;B651:8,0\",\r\n    anchorOffsetX: 4\r\n  },\r\n  B930: {\r\n    codeString: \"B447;B319:3,0\"\r\n  },\r\n  B931: {\r\n    codeString: \"B447;B303:2,0\"\r\n  },\r\n  B932: {\r\n    codeString: \"B447;B660\"\r\n  },\r\n  B933: {\r\n    codeString: \"HL4:0,12;DL4S:4,12\"\r\n  },\r\n  B934: {\r\n    codeString: \"DC8:0,8;VL4:0,12;VL4:8,12\"\r\n  },\r\n  B935: {\r\n    codeString: \"B335;B392:4,0\",\r\n    anchorOffsetX: 2\r\n  },\r\n  B936: {\r\n    codeString: \"HL4:0,8;VL8:2,8;HL4:0,16\"\r\n  },\r\n  B937: {\r\n    codeString: \"B368:0,-4;HL4:0,12\"\r\n  },\r\n  B938: {\r\n    codeString: \"B447;B2115:4,0\"\r\n  },\r\n  B939: {\r\n    codeString: \"DL8N:0,8\"\r\n  },\r\n  B940: {\r\n    codeString: \"B335;VL2:8,8;VL2:8,14\"\r\n  },\r\n  B941: {\r\n    codeString: \"LARR4W:0,10;LARR4N:4,6;LARR4S:4,14;LARR4E:8,10\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B942: {\r\n    codeString: \"C4:0,12;HC8N:2,8;C4:8,12\"\r\n  },\r\n  B943: {\r\n    codeString: \"B335;VL2:4,8;VL2:4,14\"\r\n  },\r\n  B944: {\r\n    codeString: \"B239;LARRHC8NC:4,10\",\r\n    anchorOffsetX: -3\r\n  },\r\n  B945: {\r\n    codeString: \"B597;B894:2,-6\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B946: {\r\n    codeString: \"VL4:0,10;VL4:8,10\"\r\n  },\r\n  B947: {\r\n    codeString: \"B239;HL8:0,12\"\r\n  },\r\n  B948: {\r\n    codeString: \"B412;B335:4,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B949: {\r\n    codeString: \"B239;B678:2,0\"\r\n  },\r\n  B950: {\r\n    codeString: \"S8:0,8;VL8:2,8;VL8:4,8;VL8:6,8;HL8:0,10;HL8:0,12;HL8:0,14\"\r\n  },\r\n  B951: {\r\n    codeString: \"B10:0,-4;DL4-8N:2,8;B11:6,0\"\r\n  },\r\n  B952: {\r\n    codeString: \"HL4:0,8;HL4:0,16\"\r\n  },\r\n  B953: {\r\n    codeString: \"HL4:0,16;B120:0,2\"\r\n  },\r\n  B954: {\r\n    codeString: \"B447;B401:3,0;B401:5,0\"\r\n  },\r\n  B955: {\r\n    codeString: \"B447;B401:4,0\"\r\n  },\r\n  B956: {\r\n    codeString: \"HL4:0,12;VL4:2,12;HL4:0,16\"\r\n  },\r\n  B957: {\r\n    codeString: \"HL4:0,12;HL4:0,16\"\r\n  },\r\n  B958: {\r\n    codeString: \"W8W:0,8;VL8:1,8\"\r\n  },\r\n  B959: {\r\n    codeString: \"B281;B107\"\r\n  },\r\n  B960: {\r\n    codeString: \"B447;B653\"\r\n  },\r\n  B961: {\r\n    codeString: \"B803;LARR4E:8,14\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B962: {\r\n    codeString: \"B10:0,-4;DL4-8N:2,8;B13:6,0\"\r\n  },\r\n  B963: {\r\n    codeString: \"B428;B428:4,0\"\r\n  },\r\n  B964: {\r\n    codeString: \"B447;B10:1,0;VL8:4,8\"\r\n  },\r\n  B965: {\r\n    codeString: \"VL4:0,10;HL4:0,12;VL4:4,10\"\r\n  },\r\n  B966: {\r\n    codeString: \"B695;DOT:6,10;DOT:6,14;DOT:10,10;DOT:10,14;DOT:14,8;DOT:14,12;DOT:14,16\"\r\n  },\r\n  B967: {\r\n    codeString: \"B377;HC4N:0,10\"\r\n  },\r\n  B968: {\r\n    codeString: \"HL4:0,8;B368:0,-4\"\r\n  },\r\n  B969: {\r\n    codeString: \"B484;B303:2,0\"\r\n  },\r\n  B970: {\r\n    codeString: \"B313;B457:2,0\"\r\n  },\r\n  B971: {\r\n    codeString: \"B411;B457:2,0\"\r\n  },\r\n  B972: {\r\n    codeString: \"XA;XB:3.87;XC:7.75\"\r\n  },\r\n  B973: {\r\n    codeString: \"B651;LARR4S:0,14\"\r\n  },\r\n  B974: {\r\n    codeString: \"B700;B1154\"\r\n  },\r\n  B975: {\r\n    codeString: \"B291;B313\"\r\n  },\r\n  B976: {\r\n    codeString: \"B145;B291:4,0\",\r\n    anchorOffsetX: 2\r\n  },\r\n  B977: {\r\n    codeString: \"B291;B678:2,-4\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B978: {\r\n    codeString: \"B163;HC2N:1,13;HC2N:5,13\"\r\n  },\r\n  B979: {\r\n    codeString: \"P4W:0,10;B288:3,0;P4E:8,10\"\r\n  },\r\n  B980: {\r\n    codeString: \"B651;P4W:5,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B981: {\r\n    codeString: \"P4W:0,10;B982:3,0;P4E:12,10\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B982: {\r\n    codeString: \"B814;HW2N:3,8.5;HW4N:2,7;HW2S:3,15;HW4S:2,16\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B983: {\r\n    codeString: \"DL8-4N:0,8;DL8-4S:0,8;VL2:4,10\"\r\n  },\r\n  B984: {\r\n    codeString: \"P4E:0,10;B651:3,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B985: {\r\n    codeString: \"B447;B894:2,0\"\r\n  },\r\n  B986: {\r\n    codeString: \"P4S:0,7;B651\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B987: {\r\n    codeString: \"B428;B288:2,0;B428:8,0\"\r\n  },\r\n  B988: {\r\n    codeString: \"RA4SW:0,12;DL8N:0,8;RA4NE:4,8\"\r\n  },\r\n  B989: {\r\n    codeString: \"LARRHC8SCC:2,12;P4N:0,12\"\r\n  },\r\n  B990: {\r\n    codeString: \"B651;P4N:0,15\"\r\n  },\r\n  B991: {\r\n    codeString: \"B447;B288:2,0\"\r\n  },\r\n  // Not planned for Unicode\r\n  B992: {\r\n    codeString: \"HL2:0,4;VL2:1,4;HL2:0,6\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR DIMINUTIVE\"\r\n  },\r\n  B993: {\r\n    codeString: \"HW8W:0,8;HL4:2,8;HL4:2,16;HW8E:6,8;DOT:4,12\"\r\n  },\r\n  B994: {\r\n    codeString: \"B270;B1028:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B995: {\r\n    codeString: \"W8E:0,4;B122:1,0\",\r\n    anchorOffsetX: 0.5,\r\n    anchorOffsetY: -4\r\n  },\r\n  B996: {\r\n    codeString: \"VL4:0,10;DOT:2,16;DOT:4,16;DOT:6,16;P4E:8,10\"\r\n  },\r\n  B997: {\r\n    codeString: \"B238;B449:2,0\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B998: {\r\n    codeString: \"B148:2,0;B281\"\r\n  },\r\n  B999: {\r\n    codeString: \"B216;C8:4,8\",\r\n    anchorOffsetX: 2\r\n  },\r\n  B1000: {\r\n    codeString: \"B939;B303:1,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B1001: {\r\n    codeString: \"B153;B335:4,0\"\r\n  },\r\n  B1002: {\r\n    codeString: \"B172;HL4:2,16;DOT:8,16\"\r\n  },\r\n  B1003: {\r\n    codeString: \"B174;P4W:3,6\",\r\n    anchorOffsetX: -0.5,\r\n    anchorOffsetY: -2\r\n  },\r\n  B1004: {\r\n    codeString: \"P4S:3,9;B180;P4N:3,17\"\r\n  },\r\n  B1005: {\r\n    codeString: \"P4E:0,10;B518:3,0;P4W:4,10\",\r\n    anchorOffsetX: -0.5\r\n  },\r\n  B1006: {\r\n    codeString: \"B291;B651:2,0\"\r\n  },\r\n  B1007: {\r\n    codeString: \"P4W:0,10;B394:2,0;P4E:10,10\"\r\n  },\r\n  B1008: {\r\n    codeString: \"B335;B651:8,0;B145:12,0\"\r\n  },\r\n  B1009: {\r\n    codeString: \"B239:0,-4\"\r\n  },\r\n  B1010: {\r\n    codeString: \"B239:0,4\"\r\n  },\r\n  B1011: {\r\n    codeString: \"B1094;P4W:9,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B1012: {\r\n    codeString: \"B447;B120:2,0\"\r\n  },\r\n  B1013: {\r\n    codeString: \"B447;B449:2,0\"\r\n  },\r\n  B1014: {\r\n    codeString: \"B710;B710:4,0\"\r\n  },\r\n  B1015: {\r\n    codeString: \"B433;B433:4,0\"\r\n  },\r\n  B1016: {\r\n    codeString: \"C4:0,8;DLOC4SE:0,8;SC4:0,8;DL4S:4,12;B555:4,0\"\r\n  },\r\n  B1017: {\r\n    codeString: \"B278:2,0;B939\"\r\n  },\r\n  B1018: {\r\n    codeString: \"B153;B145:4,0\"\r\n  },\r\n  B1019: {\r\n    codeString: \"B335;B1063:8,0\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B1020: {\r\n    codeString: \"VL8:0,8;P4S:0,14;VL8:4,8\"\r\n  },\r\n  B1021: {\r\n    codeString: \"B236;B939:6,0\",\r\n    anchorOffsetX: 3\r\n  },\r\n  B1022: {\r\n    codeString: \"B428;B449:2,0;B428:8,0\"\r\n  },\r\n  B1023: {\r\n    codeString: \"DL2-4N:0,8;DL2-4S:2,8;DL2-4S:0,12;DL2-4N:2,12\"\r\n  },\r\n  B1024: {\r\n    codeString: \"B590:2,0;B281\"\r\n  },\r\n  B1025: {\r\n    codeString: \"VL8:0,8;B829:3,0;VL8:8,8\"\r\n  },\r\n  B1026: {\r\n    codeString: \"B712;B829:3,0\"\r\n  },\r\n  B1027: {\r\n    codeString: \"B505;B939\"\r\n  },\r\n  B1028: {\r\n    codeString: \"AA4S:0,12\"\r\n  },\r\n  B1029: {\r\n    codeString: \"B920;P4N:2,8\"\r\n  },\r\n  B1030: {\r\n    codeString: \"B319:3,0;B939\"\r\n  },\r\n  B1031: {\r\n    codeString: \"P4S:0,7;B303;P4N:0,15\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B1032: {\r\n    codeString: \"B303;P4N:0,15\"\r\n  },\r\n  B1033: {\r\n    codeString: \"VL4:0,10;DOT:2,16;DOT:4,16;DOT:6,16;VL4:8,10\"\r\n  },\r\n  B1034: {\r\n    codeString: \"P4E:0,10;B428:2,0;DOT:4,16;DOT:6,16;DOT:8,16;B428:10,0;P4W:10,10\"\r\n  },\r\n  B1035: {\r\n    codeString: \"P4E:0,10;B428:2,0;B428:10,0;P4W:10,10\"\r\n  },\r\n  B1036: {\r\n    codeString: \"B695:0,4;B239\"\r\n  },\r\n  B1037: {\r\n    codeString: \"B325;P4W:5,8\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B1038: {\r\n    codeString: \"B428;LARRQC4NEC:0,12;B634:0,4\"\r\n  },\r\n  B1039: {\r\n    codeString: \"B695;B651:6,0\"\r\n  },\r\n  B1040: {\r\n    codeString: \"B597;B271:2,0\"\r\n  },\r\n  B1041: {\r\n    codeString: \"QC4NW:2,8;AT4S:0,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B1042: {\r\n    codeString: \"B341;B699:2,0\"\r\n  },\r\n  B1043: {\r\n    codeString: \"B238;B120:2,0\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B1044: {\r\n    codeString: \"B281;B651:2,4\"\r\n  },\r\n  B1045: {\r\n    codeString: \"B391;P4E:7,7\",\r\n    anchorOffsetX: -3,\r\n    anchorOffsetY: -1\r\n  },\r\n  B1046: {\r\n    codeString: \"P4E:0,10;B391:3,0\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B1047: {\r\n    codeString: \"B399;P4W:17,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B1048: {\r\n    codeString: \"B247;B699:3,1\"\r\n  },\r\n  B1049: {\r\n    codeString: \"VL4:0,12;HC8S:0,12;VL4:8,12\"\r\n  },\r\n  B1050: {\r\n    codeString: \"B548;B341:2,0;B699:3,0\"\r\n  },\r\n  B1051: {\r\n    codeString: \"HL4:0,8;VL8:4,8\"\r\n  },\r\n  B1052: {\r\n    codeString: \"B418;P4W:7,10;P4S:10,13\",\r\n    anchorOffsetX: -3\r\n  },\r\n  B1053: {\r\n    codeString: \"B428;DOT:2,16;DOT:4,16;DOT:6,16;B428:8,0\"\r\n  },\r\n  B1054: {\r\n    codeString: \"B1127;P4W:9,4\",\r\n    anchorOffsetY: -3\r\n  },\r\n  B1055: {\r\n    codeString: \"B335;B329:8,0;B145:12,0\"\r\n  },\r\n  B1056: {\r\n    codeString: \"C8:0,8;DOT:2,12;DOT:6,12;HW4N:0,11;HW4S:0,12;HW4N:4,11;HW4S:4,12\"\r\n  },\r\n  B1057: {\r\n    codeString: \"B335;B145:10,0\"\r\n  },\r\n  B1058: {\r\n    codeString: \"B1057:0,-2;B1066:0,2\"\r\n  },\r\n  B1059: {\r\n    codeString: \"B444:2,0;B708\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B1060: {\r\n    codeString: \"VL4:0,10;VL4:4,10\"\r\n  },\r\n  B1061: {\r\n    codeString: \"B423;B335:4,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B1062: {\r\n    codeString: \"B457:2,0;B939\"\r\n  },\r\n  B1063: {\r\n    codeString: \"B145:0,-4;B145:0,4\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B1064: {\r\n    codeString: \"B171;B678:4,-4\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B1065: {\r\n    codeString: \"B392;B270:10,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B1066: {\r\n    codeString: \"B145;B335:10,0\"\r\n  },\r\n  B1067: {\r\n    codeString: \"HC8N:0,4;B960\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B1068: {\r\n    codeString: \"C8:0,8;DLIC8N:0,8;DLIC8S:0,8;VL8:4,8\"\r\n  },\r\n  B1069: {\r\n    codeString: \"B449:0,-2;B120:0,2\"\r\n  },\r\n  B1070: {\r\n    codeString: \"B120:0,2\"\r\n  },\r\n  B1071: {\r\n    codeString: \"B548;B695:0,4\"\r\n  },\r\n  B1072: {\r\n    codeString: \"B548;P4W:9,10\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B1073: {\r\n    codeString: \"B651;LARR4E:4,10\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B1075: {\r\n    codeString: \"C8:0,8;DOT:4,12\"\r\n  },\r\n  B1076: {\r\n    codeString: \"B784;B447\"\r\n  },\r\n  B1077: {\r\n    codeString: \"B517;B335:0,4\"\r\n  },\r\n  B1078: {\r\n    codeString: \"HL4:0,8;VL8:0,8\"\r\n  },\r\n  B1079: {\r\n    codeString: \"B392;B939\"\r\n  },\r\n  B1080: {\r\n    codeString: \"VL4:0,12;P4S:0,14;VL4:4,12\"\r\n  },\r\n  B1081: {\r\n    codeString: \"VL4:0,12;HL4:0,16;VL4:2,12;VL4:4,12\"\r\n  },\r\n  B1082: {\r\n    codeString: \"B708;B148:2,0\"\r\n  },\r\n  B1083: {\r\n    codeString: \"B517;B1084\"\r\n  },\r\n  B1084: {\r\n    codeString: \"HL8:0,16;QC4SE:8,12\"\r\n  },\r\n  B1085: {\r\n    codeString: \"B457:0,2;HL8:2,16;B319:9,0\"\r\n  },\r\n  B1086: {\r\n    codeString: \"B457:0,2;HL10:2,16;VL4:8,12;B319:9,0;VL4:12,12\"\r\n  },\r\n  B1087: {\r\n    codeString: \"HW8W:0,8;VL12:2,8;HL4:0,12;HW8E:2,8\"\r\n  },\r\n  B1088: {\r\n    codeString: \"AA4N:0,8;B651:0,2\"\r\n  },\r\n  B1089: {\r\n    codeString: \"B612;B939:6,0\"\r\n  },\r\n  B1090: {\r\n    codeString: \"OC4NE:0,8;OC4NE:2,10;OC4NE:4,12\"\r\n  },\r\n  B1091: {\r\n    codeString: \"B457;LARRQC4NEC:4,12\",\r\n    anchorOffsetX: -3\r\n  },\r\n  B1092: {\r\n    codeString: \"B615;B148:6,0\"\r\n  },\r\n  B1093: {\r\n    codeString: \"B615;B263:6,0\"\r\n  },\r\n  B1094: {\r\n    codeString: \"DS8:0,8\"\r\n  },\r\n  B1095: {\r\n    codeString: \"B651;B695:2,0\"\r\n  },\r\n  B1096: {\r\n    codeString: \"P4E:0,10;B428:2,0;B428:6,0;P4W:6,10\"\r\n  },\r\n  B1097: {\r\n    codeString: \"B695:0,-4;B695;B695:0,4\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B1098: {\r\n    codeString: \"B291:0,-4;B700;B700:4,0\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B1099: {\r\n    codeString: \"B651:0,-2;B700\"\r\n  },\r\n  B1100: {\r\n    codeString: \"B666;B939\"\r\n  },\r\n  B1101: {\r\n    codeString: \"LARRHC8EC:0,8\"\r\n  },\r\n  B1102: {\r\n    codeString: \"B676:0,4\"\r\n  },\r\n  B1103: {\r\n    codeString: \"B335;B412:4,0\",\r\n    anchorOffsetX: 2\r\n  },\r\n  B1104: {\r\n    codeString: \"B428;LARRQC4NECC:0,10;B634:0,4\"\r\n  },\r\n  B1105: {\r\n    codeString: \"S8:0,8;DC8:0,8;SC8:0,8\"\r\n  },\r\n  B1106: {\r\n    codeString: \"QC4NW:0,12;QC4SE:0,12;B127:4,0\",\r\n    anchorOffsetX: 2\r\n  },\r\n  B1107: {\r\n    codeString: \"B281;B695\"\r\n  },\r\n  B1108: {\r\n    codeString: \"B428;P4W:0,10;P4E:6,10;B428:8,0\"\r\n  },\r\n  B1109: {\r\n    codeString: \"B239;DL4N:8,8\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B1110: {\r\n    codeString: \"B710;P4W:4,12\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B1111: {\r\n    codeString: \"B430;P4W:9,8\",\r\n    anchorOffsetX: -1.5\r\n  },\r\n  B1112: {\r\n    codeString: \"B710;B548:2,0;B710:8,0\"\r\n  },\r\n  B1113: {\r\n    codeString: \"B433;B548:2,0;B433:8,0\"\r\n  },\r\n  B1114: {\r\n    codeString: \"B1112;B622:5,0\"\r\n  },\r\n  B1115: {\r\n    codeString: \"B1113;B622:5,0\"\r\n  },\r\n  B1116: {\r\n    codeString: \"HL4:0,10;HL4:0,12;HL4:0,14\"\r\n  },\r\n  B1117: {\r\n    codeString: \"B695:0,4\"\r\n  },\r\n  B1118: {\r\n    codeString: \"B423;B281\"\r\n  },\r\n  B1119: {\r\n    codeString: \"B281;QC4SE:0,16\"\r\n  },\r\n  B1120: {\r\n    codeString: \"B616;B500:10,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B1121: {\r\n    codeString: \"AT4S:0,12\"\r\n  },\r\n  B1122: {\r\n    codeString: \"QC4NW:0,12;QC4SE:4,8\"\r\n  },\r\n  B1123: {\r\n    codeString: \"B291;B145:4,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B1124: {\r\n    codeString: \"B291;B271:2,-4\",\r\n    anchorOffsetY: -4\r\n  },\r\n  B1125: {\r\n    codeString: \"B291;B678:2,4\"\r\n  },\r\n  B1126: {\r\n    codeString: \"DL2S:0,8;DL2N:0,10;DL2S:0,12;DL2N:0,14\"\r\n  },\r\n  B1127: {\r\n    codeString: \"B171;B371:3.5,-4\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B1128: {\r\n    codeString: \"B171;DOT:6,12\"\r\n  },\r\n  B1129: {\r\n    codeString: \"B171;B371:3.5,6\"\r\n  },\r\n  B1130: {\r\n    codeString: \"B392;HL8:0,12\"\r\n  },\r\n  B1131: {\r\n    codeString: \"B392;VL2:0,16;HL8:0,18;VL2:8,16\"\r\n  },\r\n  B1132: {\r\n    codeString: \"B392;VL4:8,8\"\r\n  },\r\n  B1133: {\r\n    codeString: \"B392;VL2:0,16;VL2:8,16\"\r\n  },\r\n  B1134: {\r\n    codeString: \"B392;HL8:0,14\"\r\n  },\r\n  B1135: {\r\n    codeString: \"B392;HL8:8,16;VL4:16,12\"\r\n  },\r\n  B1136: {\r\n    codeString: \"B392;B281:8,0;B392:16,0\"\r\n  },\r\n  B1137: {\r\n    codeString: \"B325:2,0;B483\"\r\n  },\r\n  B1138: {\r\n    codeString: \"B303;HL4:0,8\"\r\n  },\r\n  B1139: {\r\n    codeString: \"B306;B371:1.5,6\"\r\n  },\r\n  B1140: {\r\n    codeString: \"B306;DOT:7,12\"\r\n  },\r\n  B1141: {\r\n    codeString: \"B371:1.5,0;B122\"\r\n  },\r\n  B1142: {\r\n    codeString: \"B376;VL2:3,16;VL2:5,16\"\r\n  },\r\n  B1143: {\r\n    codeString: \"B376;B371:1.5,-4\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B1144: {\r\n    codeString: \"RT8SW:0,8;B281:8,0;B456:16,0\"\r\n  },\r\n  B1145: {\r\n    codeString: \"B171;B271:4,4\"\r\n  },\r\n  B1146: {\r\n    codeString: \"P4S:0,10\"\r\n  },\r\n  B1147: {\r\n    codeString: \"RA2S:0,11\"\r\n  },\r\n  B1148: {\r\n    codeString: \"HL16:0,16;B202:8,0\"\r\n  },\r\n  B1149: {\r\n    codeString: \"B202;P4W:8,7\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B1150: {\r\n    codeString: \"B281;B392:8,0\"\r\n  },\r\n  B1151: {\r\n    codeString: \"B10:0,-4;DL4-8N:2,8;B12:6,0\"\r\n  },\r\n  B1152: {\r\n    codeString: \"B11:0,-4;DL4-8N:2,8;B12:6,0\"\r\n  },\r\n  B1153: {\r\n    codeString: \"B12:0,-4;DL4-8N:2,8;B13:6,0\"\r\n  },\r\n  B1154: {\r\n    codeString: \"HL4:0,16\"\r\n  },\r\n  B1155: {\r\n    codeString: \"B859;P4S:2,9\"\r\n  },\r\n  B1156: {\r\n    codeString: \"B636;P3NE:3,10\"\r\n  },\r\n  B1157: {\r\n    codeString: \"B636;P3NW:2,10\"\r\n  },\r\n  B1158: {\r\n    codeString: \"B636;P3SE:3,11\"\r\n  },\r\n  B1159: {\r\n    codeString: \"B636;P3SW:2,11\"\r\n  },\r\n  B1160: {\r\n    codeString: \"B376;P4S:2,5\",\r\n    anchorOffsetY: -3\r\n  },\r\n  B1161: {\r\n    codeString: \"B303;B1154\"\r\n  },\r\n  B1162: {\r\n    codeString: \"HL4:0,12;VL4:4,12;B335:4,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B1163: {\r\n    codeString: \"LARR4W:0,10;LARR4E:4,10\"\r\n  },\r\n  B1218: {\r\n    codeString: \"B335;B428:10,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B1470: {\r\n    codeString: \"B513;B513:6,0\"\r\n  },\r\n  B1525: {\r\n    codeString: \"B428;B335:2,0\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B1999: {\r\n    codeString: \"VL2:2,6;R48:0,8;VL2:2,16\",\r\n    anchorOffsetY: -2\r\n  },\r\n  B2115: {\r\n    codeString: \"VL8:0,8;B11:2,0\"\r\n  },\r\n  B2343: {\r\n    codeString: \"B10;VL8:4,8\"\r\n  },\r\n  B5061: {\r\n    codeString: \"B335;B335:10,0\"\r\n  },\r\n  B5640: {\r\n    codeString: \"B335;B940:10,0\"\r\n  },\r\n  B5836: {\r\n    codeString: \"B428;B109:2,0\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B5837: {\r\n    codeString: \"HC4N:0,8\"\r\n  },\r\n  B5838: {\r\n    codeString: \"B5840:0,-1;B5840:0,3;B5840:4,-1;B5840:4,3\"\r\n  },\r\n  B5839: {\r\n    codeString: \"B171;P4S:6,13\"\r\n  },\r\n  B5840: {\r\n    codeString: \"C2:0,11\"\r\n  },\r\n  B5841: {\r\n    codeString: \"B572;B191\"\r\n  },\r\n  B5842: {\r\n    codeString: \"B629;B366:4,0\"\r\n  },\r\n  B5843: {\r\n    codeString: \"B5844;VL6:3,8\"\r\n  },\r\n  B5844: {\r\n    codeString: \"B106;B314:2,0\"\r\n  },\r\n  B5995: {\r\n    codeString: \"B457;P4S:0,7\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B5996: {\r\n    codeString: \"B99;B904:3,0\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    width: 5,\r\n    name: \"INDICATOR DEFINITE PLURAL\"\r\n  },\r\n  B5997: {\r\n    codeString: \"B97;B904:3,0\",\r\n    isIndicator: true,\r\n    semanticIndicator: 'thing',\r\n    indicatorRole: 'nominal',\r\n    width: 5,\r\n    name: \"INDICATOR DEFINITE THING\"\r\n  },\r\n  B5998: {\r\n    codeString: \"B97;B5996:3,0\",\r\n    isIndicator: true,\r\n    semanticIndicator: 'thing',\r\n    indicatorRole: 'nominal',\r\n    width: 8,\r\n    name: \"INDICATOR DEFINITE PLURAL THING\"\r\n  },\r\n  B5999: {\r\n    codeString: \"B956:0,2\"\r\n  },\r\n  B6000: {\r\n    codeString: \"B314:0,2\"\r\n  },\r\n  B6001: {\r\n    codeString: \"HL4:0,18;VL4:2,14\"\r\n  },\r\n  B6002: {\r\n    codeString: \"B106:0,2\"\r\n  },\r\n  B6003: {\r\n    codeString: \"B657:0,4\",\r\n    anchorOffsetX: -1\r\n  },\r\n  B6013: {\r\n    codeString: \"B696;LARR4E:8,10\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B6015: {\r\n    codeString: \"B213;LARR4E:8,10\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B6091: { // Temporarily removed from Blissary as its status for inclusion by BCI is unclear. Graphically, it's the opposite of COMPRESSION B1008.\r\n    codeString: \"B145;B651:8,0;B335:12,0\"\r\n  },\r\n  B6106: {\r\n    codeString: \"HW8E:0,8;HL6:0,8;HL6:0,16;HW8W:4,8\"\r\n  },\r\n  B6109: {\r\n    codeString: \"HW8W:0,8;HW8E:2,8\"\r\n  },\r\n  B6168: {\r\n    codeString: \"B303;B651:4,0\"\r\n  },\r\n  B6232: {\r\n    codeString: \"B917;B651:2,0\",\r\n    anchorOffsetX: -2\r\n  },\r\n  B6287: {\r\n    codeString: \"B700;HL8:2,12;HL8:2,16;B700:8,0\"\r\n  },\r\n  B6300: {\r\n    codeString: \"B303;VL2:2,8;VL2:2,14;HL8:2,8;HL8:2,16;VL8:10,8\",\r\n    anchorOffsetX: 1\r\n  },\r\n  B6321: {\r\n    codeString: \"DL1N:0,8;VL4:1,8;DL1N:1,11;B968:3,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B6393: {\r\n    codeString: \"P4S:0,7;B1116\",\r\n    anchorOffsetY: -1\r\n  },\r\n  B6414: {\r\n    codeString: \"DL8-4N:0,10\"\r\n  },\r\n  B6415: {\r\n    codeString: \"DL8-4S:0,10\"\r\n  },\r\n  B6420: {\r\n    codeString: \"DL4-8N:0,8\"\r\n  },\r\n  B6435: {\r\n    codeString: \"HC8W:0,8;HW8W:2,8;B622:4,0\"\r\n  },\r\n  B6436: {\r\n    codeString: \"HC2N:0,4\",\r\n    isIndicator: true,\r\n    semanticIndicator: 'abstract',\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR ABSTRACT\"\r\n  },\r\n  B6437: {\r\n    codeString: \"B814;B695:6,0\"\r\n  },\r\n  B6438: {\r\n    codeString: \"DL1N:0,8;VL4:1,8;DL1N:1,11;B937:3,0\",\r\n    anchorOffsetX: 1.5\r\n  },\r\n  B6439: {\r\n    codeString: \"P2E:0,4;B910:1.5\",\r\n    isIndicator: true,\r\n    indicatorRole: 'nominal',\r\n    name: \"INDICATOR INDIRECT OBJECT\",\r\n    width: 3.5\r\n  }\r\n}\r\n\r\nexport { glyphData };","/** \r\n * This Source Code Form is subject to the terms of the Mozilla Public\r\n * License, v. 2.0. If a copy of the MPL was not distributed with this\r\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\r\n */\r\n\r\nimport * as sc from \"./bliss-shape-creators.js\";\r\nimport { glyphData } from \"./bliss-glyph-data.js\";\r\nimport { alphabetData } from \"../external-font-data/liberation-sans-svg-path-data.js\";\r\n\r\n/**\r\n * Special space glyph codes: TSP and QSP\r\n * These codes have dynamic width calculated by BlissElement.\r\n * DO NOT rename or remove these without updating BlissElement.\r\n */\r\nconst SPACE_GLYPH_CODES = ['TSP', 'QSP'];\r\n\r\nexport function isSpaceGlyph(code) {\r\n  return SPACE_GLYPH_CODES.includes(code);\r\n}\r\n\r\n// Non-shape elements: spacing and anchors\r\nconst nonShapeDefinitions = {\r\n  'ZSA': sc.createZeroSizedAnchor(),\r\n  'TSP': sc.createSpace(6),\r\n  'QSP': sc.createSpace(2),\r\n};\r\n\r\n// Reference glyphs: visual aids for positioning and alignment\r\nconst referenceGlyphDefinitions = {\r\n  'REFSQUARE': { codeString: \"S8:0,8\", glyphCode: 'REFSQUARE', isBlissGlyph: true, defaultOptions: { 'stroke-dasharray': '0 0.999' } },\r\n  'ANCHORRING': { codeString: \"C2:0,4\", glyphCode: 'ANCHORRING', isBlissGlyph: true, isIndicator: true, defaultOptions: { 'stroke-dasharray': '0 0.777' } },\r\n};\r\n\r\n// Shape primitives\r\nconst shapeDefinitions = {\r\n  'DOT': sc.createDot(0.5, 0.333),\r\n  'SDOT': sc.createDot(0.5, 0.1665),\r\n  'COMMA': sc.createComma(0.5, 0.333),\r\n  'H': sc.createHeart(8),\r\n  'E': sc.createEar(8),\r\n  'F': sc.createFiber(8),\r\n  'C8': sc.createCircle(4),\r\n  'C4': sc.createCircle(2),\r\n  'C2': sc.createCircle(1),\r\n  'C1': sc.createCircle(0.5),\r\n  'HC8N': sc.createHalfCircle(4, 'N'),\r\n  'HC4N': sc.createHalfCircle(2, 'N'),\r\n  'HC2N': sc.createHalfCircle(1, 'N'),\r\n  'HC1N': sc.createHalfCircle(0.5, 'N'),\r\n  'HC.5N': sc.createHalfCircle(0.25, 'N'),\r\n  'HC8S': sc.createHalfCircle(4, 'S'),\r\n  'HC4S': sc.createHalfCircle(2, 'S'),\r\n  'HC2S': sc.createHalfCircle(1, 'S'),\r\n  'HC1S': sc.createHalfCircle(0.5, 'S'),\r\n  'HC.5S': sc.createHalfCircle(0.25, 'S'),\r\n  'HC8W': sc.createHalfCircle(4, 'W'),\r\n  'HC4W': sc.createHalfCircle(2, 'W'),\r\n  'HC2W': sc.createHalfCircle(1, 'W'),\r\n  'HC1W': sc.createHalfCircle(0.5, 'W'),\r\n  'HC.5W': sc.createHalfCircle(0.25, 'W'),\r\n  'HC8E': sc.createHalfCircle(4, 'E'),\r\n  'HC4E': sc.createHalfCircle(2, 'E'),\r\n  'HC2E': sc.createHalfCircle(1, 'E'),\r\n  'HC1E': sc.createHalfCircle(0.5, 'E'),\r\n  'HC.5E': sc.createHalfCircle(0.25, 'E'),\r\n  'QC4NW': sc.createQuarterCircle(4, 'NW'),\r\n  'QC2NW': sc.createQuarterCircle(2, 'NW'),\r\n  'QC1NW': sc.createQuarterCircle(1, 'NW'),\r\n  'QC.5NW': sc.createQuarterCircle(0.5, 'NW'),\r\n  'QC4NE': sc.createQuarterCircle(4, 'NE'),\r\n  'QC2NE': sc.createQuarterCircle(2, 'NE'),\r\n  'QC1NE': sc.createQuarterCircle(1, 'NE'),\r\n  'QC.5NE': sc.createQuarterCircle(0.5, 'NE'),\r\n  'QC4SW': sc.createQuarterCircle(4, 'SW'),\r\n  'QC2SW': sc.createQuarterCircle(2, 'SW'),\r\n  'QC1SW': sc.createQuarterCircle(1, 'SW'),\r\n  'QC.5SW': sc.createQuarterCircle(0.5, 'SW'),\r\n  'QC4SE': sc.createQuarterCircle(4, 'SE'),\r\n  'QC2SE': sc.createQuarterCircle(2, 'SE'),\r\n  'QC1SE': sc.createQuarterCircle(1, 'SE'),\r\n  'QC.5SE': sc.createQuarterCircle(0.5, 'SE'),\r\n  'OC8NW': sc.createOpenCircle(4, 'NW'),\r\n  'OC4NW': sc.createOpenCircle(2, 'NW'),\r\n  'OC2NW': sc.createOpenCircle(1, 'NW'),\r\n  'OC1NW': sc.createOpenCircle(0.5, 'NW'),\r\n  'OC8NE': sc.createOpenCircle(4, 'NE'),\r\n  'OC4NE': sc.createOpenCircle(2, 'NE'),\r\n  'OC2NE': sc.createOpenCircle(1, 'NE'),\r\n  'OC1NE': sc.createOpenCircle(0.5, 'NE'),\r\n  'OC8SW': sc.createOpenCircle(4, 'SW'),\r\n  'OC4SW': sc.createOpenCircle(2, 'SW'),\r\n  'OC2SW': sc.createOpenCircle(1, 'SW'),\r\n  'OC1SW': sc.createOpenCircle(0.5, 'SW'),\r\n  'OC8SE': sc.createOpenCircle(4, 'SE'),\r\n  'OC4SE': sc.createOpenCircle(2, 'SE'),\r\n  'OC2SE': sc.createOpenCircle(1, 'SE'),\r\n  'OC1SE': sc.createOpenCircle(0.5, 'SE'),\r\n  'W8N': sc.createWave(8, 'N'),\r\n  'W8S': sc.createWave(8, 'S'),\r\n  'W8W': sc.createWave(8, 'W'),\r\n  'W8E': sc.createWave(8, 'E'),\r\n  'HW8N': sc.createHalfWave(8, 'N'),\r\n  'HW4N': sc.createHalfWave(4, 'N'),\r\n  'HW2N': sc.createHalfWave(2, 'N'),\r\n  'HW8S': sc.createHalfWave(8, 'S'),\r\n  'HW4S': sc.createHalfWave(4, 'S'),\r\n  'HW2S': sc.createHalfWave(2, 'S'),\r\n  'HW8W': sc.createHalfWave(8, 'W'),\r\n  'HW4W': sc.createHalfWave(4, 'W'),\r\n  'HW2W': sc.createHalfWave(2, 'W'),\r\n  'HW8E': sc.createHalfWave(8, 'E'),\r\n  'HW4E': sc.createHalfWave(4, 'E'),\r\n  'HW2E': sc.createHalfWave(2, 'E'),\r\n  'HQW4NW': sc.createHorizontalQuarterWave(4, 'NW'),\r\n  'HQW2NW': sc.createHorizontalQuarterWave(2, 'NW'),\r\n  'HQW1NW': sc.createHorizontalQuarterWave(1, 'NW'),\r\n  'HQW4NE': sc.createHorizontalQuarterWave(4, 'NE'),\r\n  'HQW2NE': sc.createHorizontalQuarterWave(2, 'NE'),\r\n  'HQW1NE': sc.createHorizontalQuarterWave(1, 'NE'),\r\n  'HQW4SW': sc.createHorizontalQuarterWave(4, 'SW'),\r\n  'HQW2SW': sc.createHorizontalQuarterWave(2, 'SW'),\r\n  'HQW1SW': sc.createHorizontalQuarterWave(1, 'SW'),\r\n  'HQW4SE': sc.createHorizontalQuarterWave(4, 'SE'),\r\n  'HQW2SE': sc.createHorizontalQuarterWave(2, 'SE'),\r\n  'HQW1SE': sc.createHorizontalQuarterWave(1, 'SE'),\r\n  'VQW4NW': sc.createVerticalQuarterWave(4, 'NW'),\r\n  'VQW2NW': sc.createVerticalQuarterWave(2, 'NW'),\r\n  'VQW1NW': sc.createVerticalQuarterWave(1, 'NW'),\r\n  'VQW4NE': sc.createVerticalQuarterWave(4, 'NE'),\r\n  'VQW2NE': sc.createVerticalQuarterWave(2, 'NE'),\r\n  'VQW1NE': sc.createVerticalQuarterWave(1, 'NE'),\r\n  'VQW4SW': sc.createVerticalQuarterWave(4, 'SW'),\r\n  'VQW2SW': sc.createVerticalQuarterWave(2, 'SW'),\r\n  'VQW1SW': sc.createVerticalQuarterWave(1, 'SW'),\r\n  'VQW4SE': sc.createVerticalQuarterWave(4, 'SE'),\r\n  'VQW2SE': sc.createVerticalQuarterWave(2, 'SE'),\r\n  'VQW1SE': sc.createVerticalQuarterWave(1, 'SE'),\r\n  'VL12': sc.createVerticalLine(12),\r\n  'VL10': sc.createVerticalLine(10),\r\n  'VL8': sc.createVerticalLine(8),\r\n  'VL6': sc.createVerticalLine(6),\r\n  'VL4': sc.createVerticalLine(4),\r\n  'VL3': sc.createVerticalLine(3),\r\n  'VL2': sc.createVerticalLine(2),\r\n  'VL1.5': sc.createVerticalLine(1.5),\r\n  'VL1.25': sc.createVerticalLine(1.25),\r\n  'VL1': sc.createVerticalLine(1),\r\n  'VL.5': sc.createVerticalLine(0.5),\r\n  'VL.25': sc.createVerticalLine(0.25),\r\n  'HL16': sc.createHorizontalLine(16),\r\n  'HL15': sc.createHorizontalLine(15),\r\n  'HL14': sc.createHorizontalLine(14),\r\n  'HL12': sc.createHorizontalLine(12),\r\n  'HL10': sc.createHorizontalLine(10),\r\n  'HL8': sc.createHorizontalLine(8),\r\n  'HL6': sc.createHorizontalLine(6),\r\n  'HL4': sc.createHorizontalLine(4),\r\n  'HL3': sc.createHorizontalLine(3),\r\n  'HL2': sc.createHorizontalLine(2),\r\n  'HL1.5': sc.createHorizontalLine(1.5),\r\n  'HL1': sc.createHorizontalLine(1),\r\n  'HL.5': sc.createHorizontalLine(0.5),\r\n  'HL.25': sc.createHorizontalLine(0.25),\r\n  'DL12N': sc.createAscendingDiagonalLine(12, 12),\r\n  'DL8N': sc.createAscendingDiagonalLine(8, 8),\r\n  'DL6N': sc.createAscendingDiagonalLine(6, 6),\r\n  'DL5N': sc.createAscendingDiagonalLine(5, 5),\r\n  'DL4N': sc.createAscendingDiagonalLine(4, 4),\r\n  'DL3N': sc.createAscendingDiagonalLine(3, 3),\r\n  'DL2N': sc.createAscendingDiagonalLine(2, 2),\r\n  'DL1.5N': sc.createAscendingDiagonalLine(1.5, 1.5),\r\n  'DL1N': sc.createAscendingDiagonalLine(1, 1),\r\n  \"DL.5N\": sc.createAscendingDiagonalLine(0.5, 0.5),\r\n  'DL2-3N': sc.createAscendingDiagonalLine(2, 3),\r\n  'DL1-1.5N': sc.createAscendingDiagonalLine(1, 1.5),\r\n  'DL3-2N': sc.createAscendingDiagonalLine(3, 2),\r\n  'DL1.5-1N': sc.createAscendingDiagonalLine(1.5, 1),\r\n  'DL4-8N': sc.createAscendingDiagonalLine(4, 8),\r\n  'DL2-4N': sc.createAscendingDiagonalLine(2, 4),\r\n  'DL1-2N': sc.createAscendingDiagonalLine(1, 2),\r\n  'DL.5-1N': sc.createAscendingDiagonalLine(0.5, 1),\r\n  'DL8-4N': sc.createAscendingDiagonalLine(8, 4),\r\n  'DL4-2N': sc.createAscendingDiagonalLine(4, 2),\r\n  'DL2-1N': sc.createAscendingDiagonalLine(2, 1),\r\n  'DL1-.5N': sc.createAscendingDiagonalLine(1, 0.5),\r\n  'DL1-4N': sc.createAscendingDiagonalLine(1, 4),\r\n  'DL.5-2N': sc.createAscendingDiagonalLine(0.5, 2),\r\n  'DL4-1N': sc.createAscendingDiagonalLine(4, 1),\r\n  'DL2-.5N': sc.createAscendingDiagonalLine(2, 0.5),\r\n  'DL12S': sc.createDescendingDiagonalLine(12, 12),\r\n  'DL8S': sc.createDescendingDiagonalLine(8, 8),\r\n  'DL6S': sc.createDescendingDiagonalLine(6, 6),\r\n  'DL5S': sc.createDescendingDiagonalLine(5, 5),\r\n  'DL4S': sc.createDescendingDiagonalLine(4, 4),\r\n  'DL3S': sc.createDescendingDiagonalLine(3, 3),\r\n  'DL2S': sc.createDescendingDiagonalLine(2, 2),\r\n  'DL1.5S': sc.createDescendingDiagonalLine(1.5, 1.5),\r\n  'DL1S': sc.createDescendingDiagonalLine(1, 1),\r\n  'DL.5S': sc.createDescendingDiagonalLine(0.5, 0.5),\r\n  'DL2-3S': sc.createDescendingDiagonalLine(2, 3),\r\n  'DL1-1.5S': sc.createDescendingDiagonalLine(1, 1.5),\r\n  'DL3-2S': sc.createDescendingDiagonalLine(3, 2),\r\n  'DL1.5-1S': sc.createDescendingDiagonalLine(1.5, 1),\r\n  'DL4-8S': sc.createDescendingDiagonalLine(4, 8),\r\n  'DL2-4S': sc.createDescendingDiagonalLine(2, 4),\r\n  'DL1-2S': sc.createDescendingDiagonalLine(1, 2),\r\n  'DL.5-1S': sc.createDescendingDiagonalLine(0.5, 1),\r\n  'DL8-4S': sc.createDescendingDiagonalLine(8, 4),\r\n  'DL4-2S': sc.createDescendingDiagonalLine(4, 2),\r\n  'DL2-1S': sc.createDescendingDiagonalLine(2, 1),\r\n  'DL1-.5S': sc.createDescendingDiagonalLine(1, 0.5),\r\n  'DL1-4S': sc.createDescendingDiagonalLine(1, 4),\r\n  'DL.5-2S': sc.createDescendingDiagonalLine(0.5, 2),\r\n  'DL4-1S': sc.createDescendingDiagonalLine(4, 1),\r\n  'DL2-.5S': sc.createDescendingDiagonalLine(2, 0.5),\r\n  'DLOC8NW': sc.createDiagonalLineOutsideCircle(8, 'NW'),\r\n  'DLOC8NE': sc.createDiagonalLineOutsideCircle(8, 'NE'),\r\n  'DLOC8SW': sc.createDiagonalLineOutsideCircle(8, 'SW'),\r\n  'DLOC8SE': sc.createDiagonalLineOutsideCircle(8, 'SE'),\r\n  'DLOC4NW': sc.createDiagonalLineOutsideCircle(4, 'NW'),\r\n  'DLOC4NE': sc.createDiagonalLineOutsideCircle(4, 'NE'),\r\n  'DLOC4SW': sc.createDiagonalLineOutsideCircle(4, 'SW'),\r\n  'DLOC4SE': sc.createDiagonalLineOutsideCircle(4, 'SE'),\r\n  'DLIC8N': sc.createAscendingDiagonalLineInsideCircle(4),\r\n  'DLIC4N': sc.createAscendingDiagonalLineInsideCircle(2),\r\n  'DLIC8S': sc.createDescendingDiagonalLineInsideCircle(4),\r\n  'DLIC4S': sc.createDescendingDiagonalLineInsideCircle(2),\r\n  'RA8NW': { codeString: \"VL8;HL8\" },\r\n  'RA4NW': { codeString: \"VL4;HL4\" },\r\n  'RA3NW': { codeString: \"VL3;HL3\" },\r\n  'RA2NW': { codeString: \"VL2;HL2\" },\r\n  'RA1.5NW': { codeString: \"VL1.5;HL1.5\" },\r\n  'RA1NW': { codeString: \"VL1;HL1\" },\r\n  'RA8NE': { codeString: \"HL8;VL8:8,0\" },\r\n  'RA4NE': { codeString: \"HL4;VL4:4,0\" },\r\n  'RA3NE': { codeString: \"HL3;VL3:3,0\" },\r\n  'RA2NE': { codeString: \"HL2;VL2:2,0\" },\r\n  'RA1.5NE': { codeString: \"HL1.5;VL1.5:1.5,0\" },\r\n  'RA1NE': { codeString: \"HL1;VL1:1,0\" },\r\n  'RA8SW': { codeString: \"VL8;HL8:0,8\" },\r\n  'RA4SW': { codeString: \"VL4;HL4:0,4\" },\r\n  'RA3SW': { codeString: \"VL3;HL3:0,3\" },\r\n  'RA2SW': { codeString: \"VL2;HL2:0,2\" },\r\n  'RA1.5SW': { codeString: \"VL1.5;HL1.5:0,1.5\" },\r\n  'RA1SW': { codeString: \"VL1;HL1:0,1\" },\r\n  'RA8SE': { codeString: \"HL8:0,8;VL8:8,0\" },\r\n  'RA4SE': { codeString: \"HL4:0,4;VL4:4,0\" },\r\n  'RA3SE': { codeString: \"HL3:0,3;VL3:3,0\" },\r\n  'RA2SE': { codeString: \"HL2:0,2;VL2:2,0\" },\r\n  'RA1.5SE': { codeString: \"HL1.5:0,1.5;VL1.5:1.5,0\" },\r\n  'RA1SE': { codeString: \"HL1:0,1;VL1:1,0\" },\r\n  'RA8N': { codeString: \"DL4N;DL4S:4,0\" },\r\n  'RA4N': { codeString: \"DL2N;DL2S:2,0\" },\r\n  'RA3N': { codeString: \"DL1.5N;DL1.5S:1.5,0\" },\r\n  'RA2N': { codeString: \"DL1N;DL1S:1,0\" },\r\n  'RA1N': { codeString: \"DL.5N;DL.5S:0.5,0\" },\r\n  'RA8S': { codeString: \"DL4S;DL4N:4,0\" },\r\n  'RA4S': { codeString: \"DL2S;DL2N:2,0\" },\r\n  'RA3S': { codeString: \"DL1.5S;DL1.5N:1.5,0\" },\r\n  'RA2S': { codeString: \"DL1S;DL1N:1,0\" },\r\n  'RA1S': { codeString: \"DL.5S;DL.5N:.5,0\" },\r\n  'RA8W': { codeString: \"DL4N;DL4S:0,4\" },\r\n  'RA4W': { codeString: \"DL2N;DL2S:0,2\" },\r\n  'RA3W': { codeString: \"DL1.5N;DL1.5S:0,1.5\" },\r\n  'RA2W': { codeString: \"DL1N;DL1S:0,1\" },\r\n  'RA1W': { codeString: \"DL.5N;DL.5S:0,0.5\" },\r\n  'RA8E': { codeString: \"DL4S;DL4N:0,4\" },\r\n  'RA4E': { codeString: \"DL2S;DL2N:0,2\" },\r\n  'RA3E': { codeString: \"DL1.5S;DL1.5N:0,1.5\" },\r\n  'RA2E': { codeString: \"DL1S;DL1N:0,1\" },\r\n  'RA1E': { codeString: \"DL.5S;DL.5N:0,0.5\" },\r\n  'AA8N': { codeString: \"DL4-8N;DL4-8S:4,0\" },\r\n  'AA4N': { codeString: \"DL2-4N;DL2-4S:2,0\" },\r\n  'AA2N': { codeString: \"DL1-2N;DL1-2S:1,0\" },\r\n  'AA8S': { codeString: \"DL4-8S;DL4-8N:4,0\" },\r\n  'AA4S': { codeString: \"DL2-4S;DL2-4N:2,0\" },\r\n  'AA2S': { codeString: \"DL1-2S;DL1-2N:1,0\" },\r\n  'AA8W': { codeString: \"DL8-4N;DL8-4S:0,4\" },\r\n  'AA4W': { codeString: \"DL4-2N;DL4-2S:0,2\" },\r\n  'AA2W': { codeString: \"DL2-1N;DL2-1S:0,1\" },\r\n  'AA8E': { codeString: \"DL8-4S;DL8-4N:0,4\" },\r\n  'AA4E': { codeString: \"DL4-2S;DL4-2N:0,2\" },\r\n  'AA2E': { codeString: \"DL2-1S;DL2-1N:0,1\" },\r\n  'SC8': { codeString: \"HL8:0,4;VL8:4,0\" },\r\n  'SC4': { codeString: \"HL4:0,2;VL4:2,0\" },\r\n  'SC2': { codeString: \"HL2:0,1;VL2:1,0\" },\r\n  'DC8': { codeString: \"DL8S;DL8N\" },\r\n  'DC4': { codeString: \"DL4S;DL4N\" },\r\n  'DC2': { codeString: \"DL2S;DL2N\" },\r\n  'RT8SW': { codeString: \"VL8;HL8:0,8;DL8S\" },\r\n  'RT4SW': { codeString: \"VL4;HL4:0,4;DL4S\" },\r\n  'RT2SW': { codeString: \"VL2;HL2:0,2;DL2S\" },\r\n  'RT8NW': { codeString: \"VL8;HL8;DL8N\" },\r\n  'RT4NW': { codeString: \"VL4;HL4;DL4N\" },\r\n  'RT2NW': { codeString: \"VL2;HL2;DL2N\" },\r\n  'RT8NE': { codeString: \"HL8;VL8:8,0;DL8S\" },\r\n  'RT4NE': { codeString: \"HL4;VL4:4,0;DL4S\" },\r\n  'RT2NE': { codeString: \"HL2;VL2:2,0;DL2S\" },\r\n  'RT8SE': { codeString: \"HL8:0,8;VL8:8,0;DL8N\" },\r\n  'RT4SE': { codeString: \"HL4:0,4;VL4:4,0;DL4N\" },\r\n  'RT2SE': { codeString: \"HL2:0,2;VL2:2,0;DL2N\" },\r\n  'RT8N': { codeString: \"DL4N;DL4S:4,0;HL8:0,4\" },\r\n  'RT4N': { codeString: \"DL2N;DL2S:2,0;HL4:0,2\" },\r\n  'RT2N': { codeString: \"DL1N;DL1S:1,0;HL2:0,1\" },\r\n  'RT8S': { codeString: \"DL4S;DL4N:4,0;HL8\" },\r\n  'RT4S': { codeString: \"DL2S;DL2N:2,0;HL4\" },\r\n  'RT2S': { codeString: \"DL1S;DL1N:1,0;HL2\" },\r\n  'RT8W': { codeString: \"DL4N;DL4S:0,4;VL8:4,0\" },\r\n  'RT4W': { codeString: \"DL2N;DL2S:0,2;VL4:2,0\" },\r\n  'RT2W': { codeString: \"DL1N;DL1S:0,1;VL2:1,0\" },\r\n  'RT8E': { codeString: \"DL4S;DL4N:0,4;VL8\" },\r\n  'RT4E': { codeString: \"DL2S;DL2N:0,2;VL4\" },\r\n  'RT2E': { codeString: \"DL1S;DL1N:0,1;VL2\" },\r\n  'AT8N': { codeString: \"DL4-8N;DL4-8S:4,0;HL8:0,8\" },\r\n  'AT4N': { codeString: \"DL2-4N;DL2-4S:2,0;HL4:0,4\" },\r\n  'AT2N': { codeString: \"DL1-2N;DL1-2S:1,0;HL2:0,2\" },\r\n  'AT8S': { codeString: \"DL4-8S;DL4-8N:4,0;HL8\" },\r\n  'AT4S': { codeString: \"DL2-4S;DL2-4N:2,0;HL4\" },\r\n  'AT2S': { codeString: \"DL1-2S;DL1-2N:1,0;HL2\" },\r\n  'AT8W': { codeString: \"DL8-4N;DL8-4S:0,4;VL8:8,0\" },\r\n  'AT4W': { codeString: \"DL4-2N;DL4-2S:0,2;VL4:4,0\" },\r\n  'AT2W': { codeString: \"DL2-1N;DL2-1S:0,1;VL2:2,0\" },\r\n  'AT8E': { codeString: \"DL8-4S;DL8-4N:0,4;VL8\" },\r\n  'AT4E': { codeString: \"DL4-2S;DL4-2N:0,2;VL4\" },\r\n  'AT2E': { codeString: \"DL2-1S;DL2-1N:0,1;VL2\" },\r\n  'S8': { codeString: \"HL8;HL8:0,8;VL8;VL8:8,0\" },\r\n  'S4': { codeString: \"HL4;HL4:0,4;VL4;VL4:4,0\" },\r\n  'S2': { codeString: \"HL2;HL2:0,2;VL2;VL2:2,0\" },\r\n  'DS8': { codeString: \"DL4N;DL4S:4,0;DL4S:0,4;DL4N:4,4\" },\r\n  'DS4': { codeString: \"DL2N;DL2S:2,0;DL2S:0,2;DL2N:2,2\" },\r\n  'DS2': { codeString: \"DL1N;DL1S:1,0;DL1S:0,1;DL1N:1,1\" },\r\n  'OS8N': { codeString: \"VL8;HL8:0,8;VL8:8,0\" },\r\n  'OS4N': { codeString: \"VL4;HL4:0,4;VL4:4,0\" },\r\n  'OS2N': { codeString: \"VL2;HL2:0,2;VL2:2,0\" },\r\n  'OS8S': { codeString: \"VL8;HL8;VL8:8,0\" },\r\n  'OS4S': { codeString: \"VL4;HL4;VL4:4,0\" },\r\n  'OS2S': { codeString: \"VL2;HL2;VL2:2,0\" },\r\n  'OS8W': { codeString: \"HL8;HL8:0,8;VL8:8,0\" },\r\n  'OS4W': { codeString: \"HL4;HL4:0,4;VL4:4,0\" },\r\n  'OS2W': { codeString: \"HL2;HL2:0,2;VL2:2,0\" },\r\n  'OS8E': { codeString: \"VL8;HL8;HL8:0,8\" },\r\n  'OS4E': { codeString: \"VL4;HL4;HL4:0,4\" },\r\n  'OS2E': { codeString: \"VL2;HL2;HL2:0,2\" },\r\n  'R84': { codeString: \"HL8;HL8:0,4;VL4;VL4:8,0\" },\r\n  'R42': { codeString: \"HL4;HL4:0,2;VL2;VL2:4,0\" },\r\n  'R48': { codeString: \"HL4;HL4:0,8;VL8;VL8:4,0\" },\r\n  'R24': { codeString: \"HL2;HL2:0,4;VL4;VL4:2,0\" },\r\n  'OR84N': { codeString: \"VL4;HL8:0,4;VL4:8,0\" },\r\n  'OR42N': { codeString: \"VL2;HL4:0,2;VL2:4,0\" },\r\n  'OR84S': { codeString: \"VL4;HL8;VL4:8,0\" },\r\n  'OR42S': { codeString: \"VL2;HL4;VL2:4,0\" },\r\n  'OR84W': { codeString: \"HL8;HL8:0,4;VL4:8,0\" },\r\n  'OR42W': { codeString: \"HL4;HL4:0,2;VL2:4,0\" },\r\n  'OR84E': { codeString: \"VL4;HL8;HL8:0,4\" },\r\n  'OR42E': { codeString: \"VL2;HL4;HL4:0,2\" },\r\n  'OR48N': { codeString: \"VL8;HL4:0,8;VL8:4,0\" },\r\n  'OR24N': { codeString: \"VL4;HL2:0,4;VL4:2,0\" },\r\n  'OR48S': { codeString: \"VL8;HL4;VL8:4,0\" },\r\n  'OR24S': { codeString: \"VL4;HL2;VL4:2,0\" },\r\n  'OR48W': { codeString: \"HL4;HL4:0,8;VL8:4,0\" },\r\n  'OR24W': { codeString: \"HL2;HL2:0,4;VL4:2,0\" },\r\n  'OR48E': { codeString: \"VL8;HL4;HL4:0,8\" },\r\n  'OR24E': { codeString: \"VL4;HL2;HL2:0,4\" },\r\n  'LARR8W': { codeString: \"P4W;HL8:0,2\" },\r\n  'ARR8W': { codeString: \"P3W;HL8:0,1.5\" },\r\n  'LARR4W': { codeString: \"P4W;HL4:0,2\" },\r\n  'ARR4W': { codeString: \"P3W;HL3:0,1.5\" },\r\n  'LARR8E': { codeString: \"HL8:0,2;P4E:6,0\" },\r\n  'ARR8E': { codeString: \"HL8:0,1.5;P3E:6.5,0\" },\r\n  'LARR4E': { codeString: \"HL4:0,2;P4E:2,0\" },\r\n  'ARR4E': { codeString: \"HL4:0,1.5;P3E:2.5,0\" },\r\n  'LARR8N': { codeString: \"P4N;VL8:2,0\" },\r\n  'ARR8N': { codeString: \"P3N;VL8:1.5,0\" },\r\n  'LARR4N': { codeString: \"P4N;VL4:2,0\" },\r\n  'ARR4N': { codeString: \"P3N;VL4:1.5,0\" },\r\n  'LARR8S': { codeString: \"P4S:0,6;VL8:2,0\" },\r\n  'ARR8S': { codeString: \"P3S:0,6.5;VL8:1.5,0\" },\r\n  'LARR4S': { codeString: \"P4S:0,2;VL4:2,0\" },\r\n  'ARR4S': { codeString: \"P3S:0,2.5;VL4:1.5,0\" },\r\n  'LARR8NW': { codeString: \"DL8S;P3NW\" },\r\n  'ARR8NW': { codeString: \"DL8S;P2NW\" },\r\n  'LARR4NW': { codeString: \"DL4S;P3NW\" },\r\n  'ARR4NW': { codeString: \"DL4S;P2NW\" },\r\n  'LARR8NE': { codeString: \"DL8N;P3NE:5,0\" },\r\n  'ARR8NE': { codeString: \"DL8N;P2NE:6,0\" },\r\n  'LARR4NE': { codeString: \"DL4N;P3NE:1,0\" },\r\n  'ARR4NE': { codeString: \"DL4N;P2NE:2,0\" },\r\n  'LARR8SW': { codeString: \"DL8N;P3SW:0,5\" },\r\n  'ARR8SW': { codeString: \"DL8N;P2SW:0,6\" },\r\n  'LARR4SW': { codeString: \"DL4N;P3SW:0,1\" },\r\n  'ARR4SW': { codeString: \"DL4N;P2SW:0,2\" },\r\n  'LARR8SE': { codeString: \"DL8S;P3SE:5,5\" },\r\n  'ARR8SE': { codeString: \"DL8S;P2SE:6,6\" },\r\n  'LARR4SE': { codeString: \"DL4S;P3SE:1,1\" },\r\n  'ARR4SE': { codeString: \"DL4S;P2SE:2,2\" },\r\n  'P4N': { codeString: \"RA4N\" },\r\n  'P3N': { codeString: \"RA3N\" },\r\n  'P2N': { codeString: \"RA2N\" },\r\n  'P4S': { codeString: \"RA4S\" },\r\n  'P3S': { codeString: \"RA3S\" },\r\n  'P2S': { codeString: \"RA2S\" },\r\n  'P4W': { codeString: \"RA4W\" },\r\n  'P3W': { codeString: \"RA3W\" },\r\n  'P2W': { codeString: \"RA2W\" },\r\n  'P4E': { codeString: \"RA4E\" },\r\n  'P3E': { codeString: \"RA3E\" },\r\n  'P2E': { codeString: \"RA2E\" },\r\n  'P3NW': { codeString: \"RA3NW\" },\r\n  'P3NE': { codeString: \"RA3NE\" },\r\n  'P3SW': { codeString: \"RA3SW\" },\r\n  'P3SE': { codeString: \"RA3SE\" },\r\n  'P2NW': { codeString: \"RA2NW\" },\r\n  'P2NE': { codeString: \"RA2NE\" },\r\n  'P2SW': { codeString: \"RA2SW\" },\r\n  'P2SE': { codeString: \"RA2SE\" },\r\n  'P1.5NW': { codeString: \"RA1.5NW\" },\r\n  'P1.5NE': { codeString: \"RA1.5NE\" },\r\n  'P1.5SW': { codeString: \"RA1.5SW\" },\r\n  'P1.5SE': { codeString: \"RA1.5SE\" },\r\n  'LARRC8EC': { codeString: \"C8;P4S:6,2\" },\r\n  'ARRC8EC': { codeString: \"C8;P3S:6.5,2.5\" },\r\n  'LARRC8WC': { codeString: \"P4N:0,4;C8:2,0\" },\r\n  'ARRC8WC': { codeString: \"P3N:0,4;C8:1.5,0\" },\r\n  'LARRC8NC': { codeString: \"C8:0,2;P4E:2,0\" },\r\n  'ARRC8NC': { codeString: \"C8:0,1.5;P3E:2.5,0\" },\r\n  'LARRC8SC': { codeString: \"C8;P4W:4,6\" },\r\n  'ARRC8SC': { codeString: \"C8;P3W:4,6.5\" },\r\n  'LARRC8ECC': { codeString: \"C8;P4N:6,4\" },\r\n  'ARRC8ECC': { codeString: \"C8;P3N:6.5,4\" },\r\n  'LARRC8WCC': { codeString: \"P4S:0,2;C8:2,0\" },\r\n  'ARRC8WCC': { codeString: \"P3S:0,2.5;C8:1.5,0\" },\r\n  'LARRC8NCC': { codeString: \"C8:0,2;P4W:4,0\" },\r\n  'ARRC8NCC': { codeString: \"C8:0,1.5;P3W:4,0\" },\r\n  'LARRC8SCC': { codeString: \"C8;P4E:2,6\" },\r\n  'ARRC8SCC': { codeString: \"C8;P3E:2.5,6.5\" },\r\n  'LARROC8SEC': { codeString: \"OC8SE;P4S:6,2\" },\r\n  'ARROC8SEC': { codeString: \"OC8SE;P3S:6.5,2.5\" },\r\n  'LARROC8NWC': { codeString: \"P4N:0,4;OC8NW:2,0\" },\r\n  'ARROC8NWC': { codeString: \"P3N:0,4;OC8NW:1.5,0\" },\r\n  'LARROC8NEC': { codeString: \"OC8NE:0,2;P4E:2,0\" },\r\n  'ARROC8NEC': { codeString: \"OC8NE:0,1.5;P3E:2.5,0\" },\r\n  'LARROC8SWC': { codeString: \"OC8SW;P4W:4,6\" },\r\n  'ARROC8SWC': { codeString: \"OC8SW;P3W:4,6.5\" },\r\n  'LARROC8SECC': { codeString: \"OC8SE;P4E:2,6\" },\r\n  'ARROC8SECC': { codeString: \"OC8SE;P3E:2.5,6.5\" },\r\n  'LARROC8NWCC': { codeString: \"OC8NW:0,2;P4W:4,0\" },\r\n  'ARROC8NWCC': { codeString: \"OC8NW:0,1.5;P3W:4,0\" },\r\n  'LARROC8NECC': { codeString: \"OC8NE;P4N:6,4\" },\r\n  'ARROC8NECC': { codeString: \"OC8NE;P3N:6.5,4\" },\r\n  'LARROC8SWCC': { codeString: \"P4S:0,2;OC8SW:2,0\" },\r\n  'ARROC8SWCC': { codeString: \"P3S:0,2.5;OC8SW:1.5,0\" },\r\n  'LARRHC8NC': { codeString: \"HC8N;P4S:6,2\" },\r\n  'ARRHC8NC': { codeString: \"HC8N;P3S:6.5,2.5\" },\r\n  'LARRHC8SC': { codeString: \"P4N;HC8S:2,0\" },\r\n  'ARRHC8SC': { codeString: \"P3N;HC8S:1.5,0\" },\r\n  'LARRHC8WC': { codeString: \"HC8W:0,2;P4E:2,0\" },\r\n  'ARRHC8WC': { codeString: \"HC8W:0,1.5;P3E:2.5,0\" },\r\n  'LARRHC8EC': { codeString: \"HC8E;P4W:0,6\" },\r\n  'ARRHC8EC': { codeString: \"HC8E;P3W:0,6.5\" },\r\n  'LARRHC8NCC': { codeString: \"P4S:0,2;HC8N:2,0\" },\r\n  'ARRHC8NCC': { codeString: \"P3S:0,2.5;HC8N:1.5,0\" },\r\n  'LARRHC8SCC': { codeString: \"HC8S;P4N:6,0\" },\r\n  'ARRHC8SCC': { codeString: \"HC8S;P3N:6.5,0\" },\r\n  'LARRHC8WCC': { codeString: \"HC8W;P4E:2,6\" },\r\n  'ARRHC8WCC': { codeString: \"HC8W;P3E:2.5,6.5\" },\r\n  'LARRHC8ECC': { codeString: \"P4W;HC8E:0,2\" },\r\n  'ARRHC8ECC': { codeString: \"P3W;HC8E:0,1.5\" },\r\n  'LARRQC4NWC': { codeString: \"QC4NW:0,2;P4E:2,0\" },\r\n  'ARRQC4NWC': { codeString: \"QC4NW:0,1.5;P3E:2.5,0\" },\r\n  'LARRQC4SWC': { codeString: \"P4N;QC4SW:2,0\" },\r\n  'ARRQC4SWC': { codeString: \"P3N;QC4SW:1.5,0\" },\r\n  'LARRQC4NEC': { codeString: \"QC4NE;P4S:2,2\" },\r\n  'ARRQC4NEC': { codeString: \"QC4NE;P3S:2.5,2.5\" },\r\n  'LARRQC4SEC': { codeString: \"QC4SE;P4W:0,2\" },\r\n  'ARRQC4SEC': { codeString: \"QC4SE;P3W:0,2.5\" },\r\n  'LARRQC4NWCC': { codeString: \"P4S:0,2;QC4NW:2,0\" },\r\n  'ARRQC4NWCC': { codeString: \"P3S:0,2.5;QC4NW:1.5,0\" },\r\n  'LARRQC4SWCC': { codeString: \"QC4SW;P4E:2,2\" },\r\n  'ARRQC4SWCC': { codeString: \"QC4SW;P3E:2.5,2.5\" },\r\n  'LARRQC4NECC': { codeString: \"P4W;QC4NE:0,2\" },\r\n  'ARRQC4NECC': { codeString: \"P3W;QC4NE:0,1.5\" },\r\n  'LARRQC4SECC': { codeString: \"QC4SE;P4N:2,0\" },\r\n  'ARRQC4SECC': { codeString: \"QC4SE;P3N:2.5,0\" }\r\n};\r\n\r\nshapeDefinitions['DOT'].extraPathOptions = {\r\n  baseStrokeWidth: 0.5,\r\n  extraDotWidth: 0.333\r\n};\r\n\r\nshapeDefinitions['SDOT'].extraPathOptions = {\r\n  baseStrokeWidth: 0.5,\r\n  extraDotWidth: 0.1665\r\n};\r\n\r\nshapeDefinitions['COMMA'].extraPathOptions = {\r\n  baseStrokeWidth: 0.5,\r\n  extraDotWidth: 0.333\r\n};\r\n\r\n// Dot family: which per-type sizing knobs apply to each dot-bearing shape.\r\n// DOT and COMMA take the dot-* knobs; SDOT takes the sdot-* knobs (and\r\n// halves dot-extra-width by default). Read in bliss-element.js getSvgContent.\r\nshapeDefinitions['DOT'].dotFamily = 'dot';\r\nshapeDefinitions['SDOT'].dotFamily = 'sdot';\r\nshapeDefinitions['COMMA'].dotFamily = 'dot';\r\n\r\n/**\r\n * External glyph definitions derived from alphabetData in liberation-sans-svg-path-data.js.\r\n *\r\n * Supported character sets:\r\n * - Base Latin (a-z, A-Z) - English\r\n * - Latin Extended - European languages:\r\n *   - Swedish/Finnish: å, ä, ö, Å, Ä, Ö\r\n *   - Norwegian/Danish: å, æ, ø, Å, Æ, Ø\r\n *   - Icelandic: á, é, í, ó, ú, ý, ð, þ, æ, ö, Á, É, Í, Ó, Ú, Ý, Ð, Þ, Æ, Ö\r\n *   - German: ä, ö, ü, ß, Ä, Ö, Ü\r\n *   - French: à, â, ç, è, é, ê, ë, î, ï, ô, ù, û, ü, ÿ, œ, æ, Œ, Æ\r\n *   - Spanish: á, é, í, ó, ú, ü, ñ, Á, É, Í, Ó, Ú, Ü, Ñ\r\n *   - Portuguese: á, â, ã, à, ç, é, ê, í, ó, ô, õ, ú, Á, Â, Ã, À, Ç, É, Ê, Í, Ó, Ô, Õ, Ú\r\n *   - Italian: à, è, é, ì, ò, ù, À, È, É, Ì, Ò, Ù\r\n *   - Dutch: é, ë, ï, ö, ü\r\n *   - Polish: ą, ć, ę, ł, ń, ó, ś, ź, ż, Ą, Ć, Ę, Ł, Ń, Ó, Ś, Ź, Ż\r\n *   - Czech/Slovak: á, č, é, í, ó, š, ú, ý, ž (partial)\r\n *   - Hungarian: á, é, í, ó, ö, ő, ú, ü, ű, Á, É, Í, Ó, Ö, Ő, Ú, Ü, Ű\r\n *   - Lithuanian: ą, č, ę, ė, į, š, ų, ū, ž, Ą, Č, Ę, Ė, Į, Š, Ų, Ū, Ž\r\n *   - Latvian: ā, č, ē, ģ, ī, ķ, ļ, ņ, š, ū, ž, Ā, Č, Ē, Ģ, Ī, Ķ, Ļ, Ņ, Š, Ū, Ž\r\n *   - Estonian: ä, ö, ü, õ\r\n *   - Slovenian/Croatian: č, š, ž (partial)\r\n *   - Afrikaans: ê, ë, î, ï, ô, û\r\n * - Cyrillic (Russian): а-я, А-Я, ё, Ё\r\n *\r\n * To add more characters, add them to alphabetData in liberation-sans-svg-path-data.js.\r\n */\r\nconst externalGlyphDefinitions = {};\r\nfor (const [code, data] of Object.entries(alphabetData)) {\r\n  externalGlyphDefinitions[code] = sc.createExternalGlyph(data.char);\r\n}\r\n\r\nfor (const definition of Object.values(shapeDefinitions)) {\r\n  definition.isShape = true;\r\n}\r\n\r\nconst blissElementDefinitions = {\r\n  ...nonShapeDefinitions,\r\n  ...referenceGlyphDefinitions,\r\n  ...shapeDefinitions,\r\n  ...externalGlyphDefinitions,\r\n};\r\n\r\n// Add Bliss glyph definitions (B-codes use Blissary ID:s)\r\nfor (const [code, definition] of Object.entries(glyphData)) {\r\n  definition.glyphCode = code;\r\n  definition.isBlissGlyph = true;\r\n}\r\nObject.assign(blissElementDefinitions, glyphData);\r\n\r\n// Track built-in codes so removeDefinition can prevent deleting them\r\nconst builtInCodes = new Set(Object.keys(blissElementDefinitions));\r\n\r\n// Letter aliases: B-codes that map to external glyph X-codes.\r\n// Registered after builtInCodes so they're treated as aliases, not built-in Bliss glyphs.\r\nconst letterAliases = {\r\n  B29: { codeString: \"Xa\" },  B30: { codeString: \"Xb\" },  B31: { codeString: \"Xc\" },\r\n  B32: { codeString: \"Xd\" },  B33: { codeString: \"Xe\" },  B34: { codeString: \"Xf\" },\r\n  B35: { codeString: \"Xg\" },  B36: { codeString: \"Xh\" },  B37: { codeString: \"Xi\" },\r\n  B38: { codeString: \"Xj\" },  B39: { codeString: \"Xk\" },  B40: { codeString: \"Xl\" },\r\n  B41: { codeString: \"Xm\" },  B42: { codeString: \"Xn\" },  B43: { codeString: \"Xo\" },\r\n  B44: { codeString: \"Xp\" },  B45: { codeString: \"Xq\" },  B46: { codeString: \"Xr\" },\r\n  B47: { codeString: \"Xs\" },  B48: { codeString: \"Xt\" },  B49: { codeString: \"Xu\" },\r\n  B50: { codeString: \"Xv\" },  B51: { codeString: \"Xw\" },  B52: { codeString: \"Xx\" },\r\n  B53: { codeString: \"Xy\" },  B54: { codeString: \"Xz\" },\r\n  B55: { codeString: \"XA\" },  B56: { codeString: \"XB\" },  B57: { codeString: \"XC\" },\r\n  B58: { codeString: \"XD\" },  B59: { codeString: \"XE\" },  B60: { codeString: \"XF\" },\r\n  B61: { codeString: \"XG\" },  B62: { codeString: \"XH\" },  B63: { codeString: \"XI\" },\r\n  B64: { codeString: \"XJ\" },  B65: { codeString: \"XK\" },  B66: { codeString: \"XL\" },\r\n  B67: { codeString: \"XM\" },  B68: { codeString: \"XN\" },  B69: { codeString: \"XO\" },\r\n  B70: { codeString: \"XP\" },  B71: { codeString: \"XQ\" },  B72: { codeString: \"XR\" },\r\n  B73: { codeString: \"XS\" },  B74: { codeString: \"XT\" },  B75: { codeString: \"XU\" },\r\n  B76: { codeString: \"XV\" },  B77: { codeString: \"XW\" },  B78: { codeString: \"XX\" },\r\n  B79: { codeString: \"XY\" },  B80: { codeString: \"XZ\" },\r\n};\r\nObject.assign(blissElementDefinitions, letterAliases);\r\n\r\n// Every code shipped with the library is permanent vocabulary: the letter\r\n// aliases stay OUT of builtInCodes (so resolution and decomposition keep\r\n// treating them as aliases — B29 emits Xa) but must be just as immune to\r\n// overwrite/patch/remove, or a portable composition using letters could\r\n// render differently per instance. This is the guard set for those three\r\n// routes and the isBuiltIn report; builtInCodes stays the resolution set.\r\nconst protectedCodes = new Set([...builtInCodes, ...Object.keys(letterAliases)]);\r\n\r\nexport { blissElementDefinitions, builtInCodes, protectedCodes };","/**\r\n * This Source Code Form is subject to the terms of the Mozilla Public\r\n * License, v. 2.0. If a copy of the MPL was not distributed with this\r\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\r\n */\r\n\r\nimport { OPTION_BRACKET_CONTENT, SEMANTIC_INDICATOR_ROOTS } from './bliss-constants.js';\r\n\r\n// Quote-aware option-prefix matchers: overlay codes arrive RESTORED, so a\r\n// quoted value may carry ']'/';'/':' and a lazy `\\[.*?\\]` would cut inside\r\n// it. Group 2 is the shared grammar's internal atom; group 3 the remainder.\r\nconst PART_OPTION_PREFIX = new RegExp(String.raw`^(\\[` + OPTION_BRACKET_CONTENT + String.raw`\\])>(.+)$`);\r\nconst CHAR_OPTION_PREFIX = new RegExp(String.raw`^(\\[` + OPTION_BRACKET_CONTENT + String.raw`\\])(?!>)`);\r\n// Like CHAR_OPTION_PREFIX but requiring a non-empty remainder (group 3), the\r\n// strip form used by the overlay store gate: a baseless bracket (`[opts]`)\r\n// stays whole and classifies UNKNOWN_CODE instead of stripping to nothing\r\n// (mirrors the DSL gate's `(.+)` requirement, round-3 review F3).\r\nconst CHAR_OPTION_STRIP = new RegExp(String.raw`^(\\[` + OPTION_BRACKET_CONTENT + String.raw`\\])(?!>)(.+)$`);\r\n\r\n// A codeString that is one clean code token (no separators, coordinates,\r\n// options, or markers): the only form a pure-rename alias can hold.\r\n// \\w+ rather than letter-first: define() accepts digit-leading names (the\r\n// Blissary-ID pattern, e.g. '1219'), and an alias to one must resolve like\r\n// any other single-code rename (review MINOR-4).\r\nexport const SINGLE_CODE_TOKEN = /^\\w+$/;\r\n\r\n/**\r\n * Resolve a definition to its EFFECTIVE definition by following pure-rename\r\n * bare aliases: a definition whose whole content is a single-code codeString\r\n * (no `/`, `;`, `:`, options, `^`) and which carries no identity or metadata\r\n * of its own (no glyph/shape/externalGlyph flags, no getPath, no isIndicator)\r\n * is transparent, so indicator-ness and layout metadata read through it.\r\n * The chain stops at the first definition with identity (a flagged glyph, a\r\n * shape, an external glyph, an indicator) or whose codeString is not a single\r\n * clean token — so a multi-code composition NEVER resolves through (the\r\n * single-code-target guardrail, user ruling 2026-07-17), and a definition's\r\n * own metadata is never bypassed. Unregistered targets end the chain at the\r\n * alias itself (classified like any recognized non-indicator).\r\n *\r\n * Shared by the `;;` classifier (partitionWordIndicators), the render-merge\r\n * filter (filterToIndicators), the semantic helpers, and the parser's part\r\n * metadata application, so every indicator surface resolves aliases\r\n * identically (GH #35).\r\n *\r\n * @param {Object|undefined} definition - the starting definition entry\r\n * @param {Object} definitions - the live definitions registry\r\n * @returns {Object|undefined} the effective definition (the input when no\r\n *   chain applies)\r\n */\r\nexport function resolveEffectiveDefinition(definition, definitions) {\r\n  let current = definition;\r\n  const seen = new Set();\r\n  while (\r\n    current &&\r\n    current.isIndicator !== true &&\r\n    !current.isBlissGlyph && !current.isShape && !current.isExternalGlyph &&\r\n    !current.glyphCode && typeof current.getPath !== 'function' &&\r\n    typeof current.codeString === 'string' &&\r\n    SINGLE_CODE_TOKEN.test(current.codeString) &&\r\n    !seen.has(current.codeString) &&\r\n    Object.prototype.hasOwnProperty.call(definitions, current.codeString)\r\n  ) {\r\n    seen.add(current.codeString);\r\n    current = definitions[current.codeString];\r\n  }\r\n  return current ?? definition;\r\n}\r\n\r\n/**\r\n * Look up a code's effective definition: registry lookup (own properties\r\n * only) followed by pure-rename resolution. The single predicate source for\r\n * \"is this code an indicator\" across the `;;` store, the render-merge, and\r\n * the semantic classification helpers.\r\n */\r\nfunction lookupEffectiveDefinition(bareCode, definitions) {\r\n  const definition = Object.prototype.hasOwnProperty.call(definitions, bareCode)\r\n    ? definitions[bareCode]\r\n    : undefined;\r\n  return definition ? resolveEffectiveDefinition(definition, definitions) : undefined;\r\n}\r\n\r\n/**\r\n * Extract the bare B-code from a code string that may include\r\n * option prefixes (e.g. '[color=red]>B81') and position suffixes (':0,4').\r\n */\r\nexport function getBareCode(str) {\r\n  const partLevelMatch = str.match(PART_OPTION_PREFIX);\r\n  if (partLevelMatch) return partLevelMatch[3].split(':')[0].split(';')[0];\r\n  const optionsMatch = str.match(CHAR_OPTION_PREFIX);\r\n  const code = optionsMatch ? str.slice(optionsMatch[1].length) : str;\r\n  return code.split(':')[0].split(';')[0];\r\n}\r\n\r\n/**\r\n * Get semantic indicator root from a list of indicator codes.\r\n * Returns the root B-code (e.g. 'B97') or null.\r\n */\r\nexport function getSemanticRoot(indicatorCodes, definitions) {\r\n  for (const ind of indicatorCodes) {\r\n    const bareInd = getBareCode(ind);\r\n    const indDef = lookupEffectiveDefinition(bareInd, definitions);\r\n    if (indDef?.semanticIndicator) {\r\n      return SEMANTIC_INDICATOR_ROOTS[indDef.semanticIndicator];\r\n    }\r\n  }\r\n  return null;\r\n}\r\n\r\n/**\r\n * Check if any indicator in the list carries a semanticIndicator flag.\r\n */\r\nexport function hasSemantic(indicatorCodes, definitions) {\r\n  return indicatorCodes.some(ind => lookupEffectiveDefinition(getBareCode(ind), definitions)?.semanticIndicator);\r\n}\r\n\r\n/**\r\n * Filter codes to only include real indicators (isIndicator: true), reading\r\n * indicator-ness through pure-rename aliases (GH #35).\r\n * Non-indicator codes passed in indicator position are silently dropped.\r\n */\r\nexport function filterToIndicators(codes, definitions) {\r\n  return codes.filter(code => lookupEffectiveDefinition(getBareCode(code), definitions)?.isIndicator === true);\r\n}\r\n\r\n/**\r\n * Detect a TOP-LEVEL character separator (`/`) in an indicator code: outside\r\n * option brackets and outside a quoted option value (same scan state as\r\n * `splitTopLevelSemicolons`). A `/` hidden behind a coordinate suffix\r\n * (`B81:1,2/ZZ9`) escapes `getBareCode` (which reads only up to the `:`), yet\r\n * the serialized form re-parses as word structure, so an indicator slot can\r\n * never hold such a code (round-2 external review F2).\r\n */\r\nfunction hasTopLevelSlash(code) {\r\n  let depth = 0;\r\n  let quote = null;\r\n  for (let i = 0; i < code.length; i++) {\r\n    const ch = code[i];\r\n    if (quote !== null) {\r\n      if (ch === '\\\\' && i + 1 < code.length) i++;\r\n      else if (ch === quote) quote = null;\r\n      continue;\r\n    }\r\n    if ((ch === '\"' || ch === \"'\") && depth > 0) quote = ch;\r\n    else if (ch === '[') depth++;\r\n    else if (ch === ']') { if (depth > 0) depth--; }\r\n    else if (ch === '/' && depth === 0) return true;\r\n  }\r\n  return false;\r\n}\r\n\r\n/**\r\n * Partition a list of `;;` word-level indicator codes into the ones that are\r\n * real indicators (kept) and the ones that must be rejected. A word-level\r\n * indicator must BE an indicator (isIndicator: true); a recognized non-indicator\r\n * (a real base such as B291) is rejected as `'non-indicator'`, an unrecognized\r\n * code as `'unknown'`, and a code carrying word structure (a top-level `/`,\r\n * which no indicator slot can serialize back out) as `'word-structure'`.\r\n * Shared by the DSL `;;` parser path, the API `applyIndicators` overlay path,\r\n * AND the glyph-level `applyIndicators` character-indicator gate, so all three\r\n * classify an indicator code identically (DSL/API parity; the \"word\" in the\r\n * name is historical — the classification itself is level-agnostic). The\r\n * kept-code test mirrors `filterToIndicators`, so a code accepted here always\r\n * survives the later resolve.\r\n *\r\n * @param {string[]} codes - raw `;;` codes (may carry options/coords)\r\n * @param {Object} definitions\r\n * @returns {{ valid: string[], rejected: Array<{ code: string, reason: 'non-indicator'|'unknown'|'word-structure' }> }}\r\n *   `valid` preserves each code verbatim (options/coords intact); each rejected\r\n *   `code` is the bare offending code (options/coords stripped), except a\r\n *   `'word-structure'` reject, which keeps the full code (its bare form would\r\n *   hide the offending `/`).\r\n */\r\nexport function partitionWordIndicators(codes, definitions) {\r\n  const valid = [];\r\n  const rejected = [];\r\n  for (const code of codes) {\r\n    if (hasTopLevelSlash(code)) {\r\n      rejected.push({ code, reason: 'word-structure' });\r\n      continue;\r\n    }\r\n    const bare = getBareCode(code);\r\n    // Own-property check (inside lookupEffectiveDefinition): a normal\r\n    // definitions object inherits Object.prototype members (toString,\r\n    // constructor, __proto__), so a plain `definitions[bare]` lookup would\r\n    // classify those names as recognized non-indicators. Only an OWN key is a\r\n    // real registered code; everything else is unknown. Indicator-ness reads\r\n    // through pure-rename aliases (GH #35): the effective definition is\r\n    // checked, so a 1:1 alias to an indicator is accepted, while an alias to\r\n    // a multi-code composition stays a recognized non-indicator (the\r\n    // single-code-target guardrail).\r\n    const definition = lookupEffectiveDefinition(bare, definitions);\r\n    if (definition?.isIndicator === true) {\r\n      valid.push(code);\r\n    } else {\r\n      rejected.push({ code: bare, reason: definition ? 'non-indicator' : 'unknown' });\r\n    }\r\n  }\r\n  return { valid, rejected };\r\n}\r\n\r\n/**\r\n * Resolve a `;;` word-level indicator overlay from raw codes plus a stripSemantic\r\n * flag: validate each code (a `;;` code must BE an indicator) and apply the store\r\n * decision. The single source of truth shared by the DSL parser, the API\r\n * (`applyIndicators` overlay), and the object constructor, so all three input\r\n * surfaces classify and store a `;;` overlay identically (DSL/API/object parity).\r\n *\r\n * Each rejected code is reported via `onReject({ code, reason })` so the caller\r\n * emits a surface-appropriate warning (parser `parseWarnings` vs the API mutation\r\n * channel vs the object `_parseWarnings` channel).\r\n *\r\n * Store decision: return an overlay only when it carries meaning -- a surviving\r\n * indicator, an explicit strip, or a deliberately-empty input (`rawCodes` empty,\r\n * a bare `;;` clear). An input whose codes were ALL dropped as invalid (and no\r\n * strip) returns null: the overlay is discarded, not rewritten as an empty one.\r\n *\r\n * A CHARACTER-form option prefix (`[opts]CODE`, no `>`) is inert in overlay\r\n * position for every key -- the render-merge extracts parts only, so the\r\n * bracket styles nothing (`[opts]>` is the styled form). The DSL `;;` store\r\n * gate strips + warns these before storing; the API and object surfaces reach\r\n * this resolver with raw codes, so the same strip applies here for parity\r\n * (external review of ce80c1b, F2: the quote-aware bare-code lookup otherwise\r\n * silently stored the inert prefix). Every leading char-form bracket strips\r\n * (one `onCharOptionStrip` report each) BEFORE validation; the code itself is\r\n * kept and validated normally. The parser's codes arrive pre-stripped, so the\r\n * pass is a no-op on the DSL path (no double warning).\r\n *\r\n * @param {string[]} rawCodes\r\n * @param {boolean} stripSemantic\r\n * @param {Object} definitions\r\n * @param {(rejected: { code: string, reason: 'non-indicator'|'unknown'|'word-structure' }) => void} [onReject]\r\n * @param {(stripped: { bracket: string, code: string, source: string }) => void} [onCharOptionStrip]\r\n * @returns {{ codes: string[], stripSemantic: boolean } | null}\r\n */\r\nexport function resolveWordIndicatorOverlay(rawCodes, stripSemantic, definitions, onReject, onCharOptionStrip) {\r\n  const gatedCodes = rawCodes.map((code) => {\r\n    let current = code;\r\n    let charPrefix;\r\n    while ((charPrefix = current.match(CHAR_OPTION_STRIP)) !== null) {\r\n      if (onCharOptionStrip) onCharOptionStrip({ bracket: charPrefix[1], code: charPrefix[3], source: current });\r\n      current = charPrefix[3];\r\n    }\r\n    return current;\r\n  });\r\n  const { valid, rejected } = partitionWordIndicators(gatedCodes, definitions);\r\n  if (onReject) for (const r of rejected) onReject(r);\r\n  if (valid.length > 0 || stripSemantic || rawCodes.length === 0) {\r\n    return { codes: valid, stripSemantic };\r\n  }\r\n  return null;\r\n}\r\n\r\n/**\r\n * Split a `;`-separated indicator code list on TOP-LEVEL semicolons only, leaving\r\n * a `;` inside an option block (`[color=red;stroke-width=2]>B81`) intact. The DSL\r\n * parser protects option-block semicolons with placeholders before splitting; the\r\n * API receives raw strings, so it needs this bracket-aware split to tokenize a\r\n * multi-key-option indicator the same way (DSL/API parity). Inside a bracket, a\r\n * quoted span owns its characters — a `[`/`]`/`;` in a quoted option value\r\n * (`[data-t=\"a[b\"]>B81;B86`) must not move the depth or split (external review\r\n * of ce80c1b, F1: a quoted `[` held the depth open across the real separator,\r\n * joining two indicators into one stored code). Escapes (`\\\"`) consume the next\r\n * character, matching the option parser's quote grammar. Trims and drops empty\r\n * segments, matching the prior naive `code.split(';').map(trim).filter(Boolean)`.\r\n */\r\nexport function splitTopLevelSemicolons(code) {\r\n  const result = [];\r\n  let depth = 0;\r\n  let quote = null;\r\n  let current = '';\r\n  for (let i = 0; i < code.length; i++) {\r\n    const ch = code[i];\r\n    if (quote !== null) {\r\n      current += ch;\r\n      if (ch === '\\\\' && i + 1 < code.length) current += code[++i];\r\n      else if (ch === quote) quote = null;\r\n      continue;\r\n    }\r\n    if ((ch === '\"' || ch === \"'\") && depth > 0) quote = ch;\r\n    else if (ch === '[') depth++;\r\n    else if (ch === ']') { if (depth > 0) depth--; }\r\n    if (ch === ';' && depth === 0) {\r\n      result.push(current);\r\n      current = '';\r\n    } else {\r\n      current += ch;\r\n    }\r\n  }\r\n  result.push(current);\r\n  return result.map(s => s.trim()).filter(Boolean);\r\n}\r\n\r\n/**\r\n * Determine whether auto-preserved semantic root goes before or after new indicators.\r\n * Default: semantic first (nominal). If ALL non-semantic new indicators are verbal or\r\n * adjectival, semantic goes last (the word is being used as a verb/adjective).\r\n */\r\nexport function semanticGoesLast(newIndicatorCodes, definitions) {\r\n  const nonSemantic = newIndicatorCodes.filter(ind =>\r\n    !lookupEffectiveDefinition(getBareCode(ind), definitions)?.semanticIndicator);\r\n  return nonSemantic.length > 0 &&\r\n    nonSemantic.every(ind => {\r\n      const role = lookupEffectiveDefinition(getBareCode(ind), definitions)?.indicatorRole;\r\n      return role === 'verbal' || role === 'adjectival';\r\n    });\r\n}\r\n\r\n/**\r\n * Build the indicator list with semantic root in the correct position.\r\n * Returns an array (not a joined string) to preserve position coordinates\r\n * on individual codes (e.g. 'B86:0,4').\r\n */\r\nexport function buildWithSemantic(semanticRoot, newInds, definitions) {\r\n  return semanticGoesLast(newInds, definitions)\r\n    ? [...newInds, semanticRoot]\r\n    : [semanticRoot, ...newInds];\r\n}\r\n\r\n/**\r\n * Resolve the final indicator code list from existing indicators, the\r\n * requested new codes, and the stripSemantic flag. Shared decision logic\r\n * for both the DSL `;;` parser path and the character-level mutation path:\r\n *\r\n * - Preserve the existing semantic root (unless stripSemantic) and place it\r\n *   relative to the new indicators per the placement rule.\r\n * - Replace-all: the new indicators replace any existing grammatical ones.\r\n * - Never double a semantic root the new codes already carry.\r\n * - Drop non-indicator codes; an empty result keeps the root alone (or [] if\r\n *   there is no root to keep).\r\n *\r\n * Returns an array of code strings (position coordinates preserved).\r\n */\r\nexport function resolveIndicatorCodes(existingIndicatorCodes, newCodes, { stripSemantic } = {}, definitions) {\r\n  const semanticRoot = !stripSemantic ? getSemanticRoot(existingIndicatorCodes, definitions) : null;\r\n  const validNew = filterToIndicators(newCodes, definitions);\r\n  if (validNew.length > 0) {\r\n    return semanticRoot && !hasSemantic(validNew, definitions)\r\n      ? buildWithSemantic(semanticRoot, validNew, definitions)\r\n      : validNew;\r\n  }\r\n  return semanticRoot ? [semanticRoot] : [];\r\n}\r\n\r\n/**\r\n * Classify an indicator code's kind for introspection: 'semantic' when its\r\n * definition carries a semanticIndicator flag (e.g. THING), 'grammatical'\r\n * otherwise, or null when the definition cannot be resolved. The caller gates\r\n * on the node's `isIndicator` first; this only reads the definition, so the\r\n * handle (raw node) and the snapshot classify identically (DSL/API parity).\r\n *\r\n * @param {string|null} code - the indicator's bare codeName\r\n * @param {Object} definitions\r\n * @returns {'semantic'|'grammatical'|null}\r\n */\r\nexport function classifyIndicatorKind(code, definitions) {\r\n  const definition = lookupEffectiveDefinition(code, definitions);\r\n  if (!definition) return null;\r\n  return definition.semanticIndicator ? 'semantic' : 'grammatical';\r\n}\r\n\r\n/**\r\n * Resolve a word-level indicator overlay onto a head glyph's parts at decode\r\n * time. The single merge used by render (#rebuild) and, under flatten, by\r\n * serialize, so the DSL `;;` path and the API word-level path cannot drift.\r\n *\r\n * Splits the head's parts into base parts and trailing indicator parts, runs\r\n * resolveIndicatorCodes against the overlay (replace-all with semantic-root\r\n * preservation), and returns a new array of [...baseParts, ...resolved], each\r\n * resolved indicator appended strictly after every base part. A resolved code\r\n * that matches an existing character-level `;` indicator part REUSES that part\r\n * (a shallow clone keeping its key and its 'character' origin) so navigation\r\n * round-trips it (N14-2); a genuinely overlay-added code is parsed fresh and\r\n * tagged `_indicatorOrigin: 'word'`. The input glyph is not mutated. A head\r\n * whose parts hold a non-indicator after an indicator is returned unchanged.\r\n *\r\n * @param {{parts: Array}} headGlyph - the head glyph node (has .parts)\r\n * @param {{codes: string[], stripSemantic?: boolean}} overlay\r\n * @param {Object} definitions\r\n * @param {(code: string) => Object} parse - parser used to build part nodes\r\n * @returns {Array} the resolved parts array\r\n */\r\nexport function mergeWordIndicatorsOntoHead(headGlyph, overlay, definitions, parse) {\r\n  const parts = headGlyph?.parts ?? [];\r\n  // The first part is always the base, even when it is itself an indicator\r\n  // (e.g. a head whose bareCode is B85): scan for the first trailing indicator\r\n  // from index 1, so a word-level overlay onto an indicator base adds rather\r\n  // than replaces it.\r\n  const firstIndicatorIndex = parts.findIndex((p, i) => i > 0 && p.isIndicator === true);\r\n  const baseParts = firstIndicatorIndex === -1 ? parts.slice() : parts.slice(0, firstIndicatorIndex);\r\n  const existingIndicatorParts = firstIndicatorIndex === -1 ? [] : parts.slice(firstIndicatorIndex);\r\n\r\n  // A non-indicator after the first indicator is not a clean base+indicator\r\n  // shape; leave the glyph untouched rather than guess where the boundary is.\r\n  if (!existingIndicatorParts.every(p => p.isIndicator === true)) return parts.slice();\r\n\r\n  const existingIndicatorCodes = existingIndicatorParts.map(p => p.codeName);\r\n  const finalCodes = resolveIndicatorCodes(\r\n    existingIndicatorCodes,\r\n    overlay?.codes ?? [],\r\n    { stripSemantic: overlay?.stripSemantic === true },\r\n    definitions\r\n  );\r\n\r\n  // N14-2: reuse an existing character-level `;` indicator part when a resolved\r\n  // code matches it, so the reordered part keeps its raw key (navigation and\r\n  // getElementByKey round-trip it) and its true 'character' origin, instead of\r\n  // re-parsing into a fresh keyless node tagged 'word'. A code with no existing\r\n  // match is genuinely overlay-added, so it is parsed fresh and tagged 'word'.\r\n  const reusable = existingIndicatorParts.slice();\r\n  const indicatorParts = [];\r\n  for (const code of finalCodes) {\r\n    const reuseIndex = reusable.findIndex(p => p.codeName === code);\r\n    if (reuseIndex !== -1) {\r\n      indicatorParts.push({ ...reusable.splice(reuseIndex, 1)[0] });\r\n      continue;\r\n    }\r\n    const parsedParts = parse(code)?.groups?.[0]?.glyphs?.[0]?.parts;\r\n    // A custom flagged compound indicator (e.g. define COMBI = 'B97;B99:3,0')\r\n    // parses at GLYPH level into multiple decomposed parts, unlike a built-in\r\n    // compound (B98) which the parser keeps as one nested part. Taking parts[0]\r\n    // dropped the rest of the anatomy from render AND flatten (`;;COMBI` rendered\r\n    // only B97; backlog: custom compound `;;` anatomy truncation). Wrap the whole\r\n    // anatomy back into one atomic part, mirroring the `;`-slot form (`B291;COMBI`);\r\n    // the shared indicator-metadata stamp below then flags it, so `;` and `;;`\r\n    // agree for the same definition.\r\n    let node = parsedParts?.length > 1\r\n      ? { codeName: getBareCode(code), parts: parsedParts }\r\n      : parsedParts?.[0];\r\n    if (node) {\r\n      const bare = getBareCode(code);\r\n      const immediate = Object.prototype.hasOwnProperty.call(definitions, bare)\r\n        ? definitions[bare]\r\n        : undefined;\r\n      // A single-code rename overlay (e.g. MYIND -> C2, BAREIND -> B81) loses\r\n      // the written code at parse; record it so preserve-mode serialization\r\n      // restores it (Phase 2.3b). This stamp is load-bearing for the `;;`\r\n      // surface: the standalone parse resolves the alias at glyph level, so the\r\n      // parser's own single-ref rename recording never fires for this node\r\n      // (unlike an object-input part, where it does). A multi-part wrap keeps its\r\n      // own code (its codeName is already `bare`): stamping the alias on just the\r\n      // first part would mislabel it.\r\n      if (parsedParts.length === 1 && node.codeName !== bare) {\r\n        node._aliasCodeName = bare;\r\n      }\r\n      // The `;;` overlay parses its code standalone, which (unlike the `;`-slot's\r\n      // #applyDefinitionMetadata) does not carry a single-code alias's own\r\n      // indicator metadata onto the node when the alias target is not itself an\r\n      // indicator (MYIND -> C2, isIndicator on the definition); the compound wrap\r\n      // above also starts bare. Apply it here from the effective definition so\r\n      // `;` and `;;` place the indicator identically and the flatten+preserve\r\n      // round-trip is svg-stable (external review MAJOR-1). Built-in indicators\r\n      // already carry the flag, so the guard makes this a no-op for them.\r\n      if (node.isIndicator !== true) {\r\n        const effective = resolveEffectiveDefinition(immediate, definitions);\r\n        if (effective?.isIndicator) {\r\n          node.isIndicator = true;\r\n          node.width = effective.width ?? 2;\r\n          if (effective.anchorOffsetX !== undefined) node.anchorOffsetX = effective.anchorOffsetX;\r\n        }\r\n      }\r\n      // A standalone parse of an alias code lands the alias definition's\r\n      // defaultOptions at GLYPH level, so the extracted part node would\r\n      // silently lose them (`;;` diverging from the `;`-part slot). Merge them\r\n      // here with the same precedence as #applyDefinitionMetadata: explicit\r\n      // options on the code win.\r\n      if (immediate?.defaultOptions) {\r\n        node.options = { ...immediate.defaultOptions, ...(node.options || {}) };\r\n      }\r\n      indicatorParts.push({ ...node, _indicatorOrigin: 'word' });\r\n    }\r\n  }\r\n\r\n  return [...baseParts, ...indicatorParts];\r\n}\r\n","/*\r\n * This Source Code Form is subject to the terms of the Mozilla Public\r\n * License, v. 2.0. If a copy of the MPL was not distributed with this\r\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\r\n */\r\n\r\n/**\r\n * Bliss Head Glyph Exclusions\r\n *\r\n * Characters and sequences to skip when finding the head glyph (the character\r\n * that receives grammatical indicators).\r\n *\r\n * Priority hierarchy for head glyph selection (highest to lowest):\r\n * 1. Non-exclusions - always head if present\r\n * 2. Regular exclusions - head if no non-exclusions available\r\n * 3. Low-priority exclusions (B401, B699) - head only if alone or with same/lower priority\r\n * 4. Absolute never-head (B233) - never outranks another glyph, but is the\r\n *    head when it is the sole candidate (structural marker like quotation marks)\r\n *\r\n * When prefix modifiers are used, it's recommended to mark the head glyph\r\n * explicitly with ^ to avoid ambiguity.\r\n *\r\n * Examples:\r\n * 'B486/B1108^' (narrowness)\r\n * 'B486/B1108;B86^' (narrow)\r\n */\r\n\r\n/**\r\n * Absolute never-head codes (lowest priority tier).\r\n * These never outrank another glyph when competing for the head: any other\r\n * candidate wins. But a never-head code is still the head when it is the sole\r\n * candidate, because something must carry the indicator (an atypical or\r\n * structural glyph is a valid head at the default position when it stands\r\n * alone). They are purely structural markers (like quotation marks).\r\n */\r\nexport const absoluteNeverHead = [\r\n  'B233', // combine marker (structural, like quotation mark)\r\n];\r\n\r\n/**\r\n * Low-priority exclusions.\r\n * These are skipped as prefixes like regular exclusions, but can only be head\r\n * when alone or together with other low-priority codes (no regular exclusions present).\r\n */\r\nexport const lowPriorityExclusions = [\r\n  'B401', // exclamatory - when alone or with other B401s, can take indicator\r\n  'B699', // interrogative - when alone or with other B699s, can take indicator\r\n];\r\n\r\n/**\r\n * Conditional exceptions.\r\n * Format: [excludedCode, notExcludedWhenFollowedBy]\r\n * The excludedCode is NOT treated as an exclusion when immediately followed by\r\n * the specified code.\r\n */\r\nexport const conditionalExceptions = [\r\n  ['B10', 'B4'], // B10 (one) is NOT excluded when followed by B4\r\n];\r\n\r\n/**\r\n * Main exclusion list.\r\n * Characters and sequences to skip when finding the head glyph.\r\n * Includes all categories (regular, low-priority, and never-head).\r\n */\r\nexport const blissHeadGlyphExclusions = [\r\n  // Structural markers (absolute never-head)\r\n  'B233', // combine marker\r\n\r\n  // Pragmatic lexical markers (low-priority)\r\n  'B401', // exclamatory when used as a prefix, otherwise a specifier\r\n  'B699', // interrogative when used as a prefix, otherwise a specifier\r\n\r\n  // Scalar degree operators\r\n  'B937', // more (comparative)\r\n  'B968', // most (superlative)\r\n  'B6438', // less (comparative)\r\n  'B6321', // least (superlative)\r\n\r\n  // Identity-affecting operators\r\n  'B449/B401', // not (logical negation)\r\n  'B486', // opposite to (antonymy)\r\n\r\n  // Concept-transforming operators\r\n  'B1060/B578/B608/B292', // rhymes with\r\n  'B1060/B578/B303', // looks similar to\r\n  'B1060/B578/B608', // sounds similar to\r\n  'B1060/B578/B374', // feels similar to\r\n  'B1060/B578/B473', // smells similar to\r\n  'B1060/B578/B642', // tastes similar to\r\n  'B1060/B578', // similar to\r\n  'B578/B303', // looks like\r\n  'B578/B608', // sounds like\r\n  'B578/B374', // feels like\r\n  'B578/B473', // smells like\r\n  'B578/B642', // tastes like\r\n  'B348', // generalization of\r\n  'B444', // metaphor for\r\n\r\n  // Relational operators\r\n  'B449', // without (privative negation)\r\n  'B578', // same as\r\n  'B502/B167', // part of Blissymbol\r\n  'B502', // part of\r\n  'B102', // about\r\n  'B104', // across\r\n  'B109', // after\r\n  'B111', // against\r\n  'B120/B120', // along with\r\n  'B162/B368', // among\r\n  'B134', // around\r\n  'B135', // at\r\n  'B158', // before\r\n  'B162', // between\r\n  'B195', // by\r\n  'B482', // on\r\n  'B491', // out of (forward)\r\n  'B492', // out of (downward)\r\n  'B977', // out of (upward)\r\n  'B976', // out of (backward)\r\n  'B402', // into (forward)\r\n  'B1124', // into (downward)\r\n  'B1125', // into (upward)\r\n  'B1123', // into (backward)\r\n  'B490', // outside\r\n  'B398', // inside\r\n  'B493', // over, above\r\n  'B676', // under, below\r\n  'B1102', // under (ground level)\r\n  'B331', // instead of\r\n  'B332', // for the purpose of\r\n  'B337', // from\r\n  'B657', // to, toward\r\n  'B653', // through\r\n  'B677', // until\r\n  'B160', // belongs to\r\n\r\n  // Determiners\r\n  'B100', // a, an (indefinite)\r\n  'B647', // the (definite)\r\n\r\n  // Quantifiers\r\n  'B368/B368/B368', // many/much x3 (city)\r\n  'B368/B368', // many/much x2 (ocean, town)\r\n  'B368', // many/much (lake, village)\r\n  // pending: few (not yet in bliss-glyph-data.js)\r\n  'B117', // all\r\n  'B11/B117', // both\r\n  'B10/B117', // each/every\r\n  'B286', // either\r\n  'B449/B286', // neither\r\n  'B951', // half\r\n  'B962', // quarter\r\n  'B1151', // one third\r\n  'B1152', // two thirds\r\n  'B1153', // three quarters\r\n  'B559/B11', // several\r\n  'B9', // zero\r\n  'B10', // one (note: NOT excluded when followed by B4 - see conditionalExceptions)\r\n  'B11', // two\r\n  'B12', // three\r\n  'B13', // four\r\n  'B14', // five\r\n  'B15', // six\r\n  'B16', // seven\r\n  'B17', // eight\r\n  'B18', // nine\r\n];\r\n\r\n/**\r\n * Head-scan code for one glyph: the value fed per-glyph to resolveHeadIndex.\r\n * A head-exclusion code (e.g. B486 \"opposite-to\") excludes only when it stands\r\n * alone as a single glyph; a fused multi-part character is a character, not a\r\n * leading operator, so it is non-excludable (returns undefined). A named glyph\r\n * (custom code or single built-in) is classified by its own identity code.\r\n * Shared by the builder render path and the element snapshot so the two\r\n * head-resolution sites cannot drift apart.\r\n *\r\n * @param {string|undefined} identityCode - the glyph's own code (glyphCode / codeName), if any\r\n * @param {number} partCount - number of parts composing the glyph\r\n * @param {string|undefined} firstPartCode - codeName of the first part\r\n * @returns {string|undefined} the head-scan code, or undefined when non-excludable\r\n */\r\n// `||` (not `??`) is deliberate: an identity-less snapshot glyph carries\r\n// codeName === '' (an empty string, not nullish), which must fall through to\r\n// the part-count branch. `??` would return that bogus '' identity.\r\nexport const headScanCode = (identityCode, partCount, firstPartCode) =>\r\n  identityCode || (partCount > 1 ? undefined : firstPartCode);\r\n\r\n/**\r\n * Resolve which glyph index of a word is the fallback head, given each\r\n * glyph's head-scan code (its base character code, or a custom glyph's own\r\n * identity). Skips leading exclusion patterns (single- and multi-code, plus\r\n * the conditional B10/B4 exception); when every code is an exclusion, picks by\r\n * priority tier (regular > low-priority > absolute-never-head). This is the\r\n * single source of truth for fallback head selection, shared by the parser\r\n * (parse-time crowning) and the builder/element layers (query-time\r\n * resolution), so an explicit `^`/designation stays the only persistent\r\n * override.\r\n *\r\n * @param {string[]} headCodes - one head-scan code per glyph, in word order\r\n * @returns {number} index of the fallback head (0 for an empty list)\r\n */\r\nexport const resolveHeadIndex = (headCodes) => {\r\n  // Conditional exception (e.g. B10/B4): an otherwise-excluded code is not\r\n  // excluded when immediately followed by its paired code.\r\n  const isExcluded = (code, index) => {\r\n    for (const [excl, notWhenFollowedBy] of conditionalExceptions) {\r\n      if (code === excl && index + 1 < headCodes.length && headCodes[index + 1] === notWhenFollowedBy) {\r\n        return false;\r\n      }\r\n    }\r\n    return true;\r\n  };\r\n\r\n  // Skip leading exclusion patterns from the start.\r\n  let startIndex = 0;\r\n  let foundMatch = true;\r\n  while (foundMatch && startIndex < headCodes.length) {\r\n    foundMatch = false;\r\n    for (const pattern of blissHeadGlyphExclusions) {\r\n      const codes = pattern.split('/');\r\n      if (startIndex + codes.length <= headCodes.length) {\r\n        let matches = true;\r\n        for (let i = 0; i < codes.length; i++) {\r\n          const code = headCodes[startIndex + i];\r\n          if (code !== codes[i] || (codes.length === 1 && !isExcluded(code, startIndex + i))) {\r\n            matches = false;\r\n            break;\r\n          }\r\n        }\r\n        if (matches) {\r\n          startIndex += codes.length;\r\n          foundMatch = true;\r\n          break;\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  if (startIndex < headCodes.length) return startIndex;\r\n\r\n  // All exclusions: find best head by priority (regular > low-priority > never-head).\r\n  let best = 0;\r\n  let bestPriority = absoluteNeverHead.includes(headCodes[0]) ? 0 : lowPriorityExclusions.includes(headCodes[0]) ? 1 : 2;\r\n  for (let i = 1; i < headCodes.length; i++) {\r\n    const code = headCodes[i];\r\n    const priority = absoluteNeverHead.includes(code) ? 0 : lowPriorityExclusions.includes(code) ? 1 : 2;\r\n    if (priority > bestPriority || (priority === bestPriority && priority > 0)) {\r\n      best = i;\r\n      bestPriority = priority;\r\n    }\r\n  }\r\n  return best;\r\n};\r\n","/*\r\n * This Source Code Form is subject to the terms of the Mozilla Public\r\n * License, v. 2.0. If a copy of the MPL was not distributed with this\r\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\r\n */\r\n\r\nimport { blissElementDefinitions, isSpaceGlyph } from \"./bliss-element-definitions.js\";\r\nimport { INTERNAL_OPTIONS, isSafeAttributeName, generateKey, MAX_RECURSION_DEPTH, WARNING_CODES } from \"./bliss-constants.js\";\r\nimport { createTextFallbackGlyph } from \"./bliss-shape-creators.js\";\r\nimport { classifyIndicatorKind } from \"./indicator-utils.js\";\r\nimport { resolveHeadIndex, headScanCode } from \"./bliss-head-glyph-exclusions.js\";\r\n\r\n// Horizontal gap (in glyph units) between consecutive indicators in a stack.\r\n// Shared by the character-level indicator layout (#positionIndicatorGroup) and\r\n// the nested compound-indicator layout (#handleCompositeElement) so the two\r\n// cannot drift.\r\nconst INDICATOR_GAP = 1;\r\n\r\nexport class BlissElement {\r\n  //#region Private Properties\r\n  #key\r\n  #level\r\n  #blissObj\r\n  #extraPathOptions\r\n  #isCharacter\r\n  #isShape\r\n  #isBlissGlyph\r\n  #isExternalGlyph\r\n  #leafX\r\n  #leafY\r\n  #leafWidth\r\n  #leafHeight\r\n  #anchorOffsetX\r\n  #anchorOffsetY\r\n  #advanceX\r\n  #children\r\n  #relativeToParentX\r\n  #relativeToParentY\r\n  #codeName\r\n  #char\r\n  #externalGlyphSpacing\r\n  #isSpaceGroup\r\n  #isEmptyGlyph\r\n  #isEmptyGroup\r\n  //#endregion\r\n  #childStartOffset\r\n  #parentElement;\r\n  #previousElement;\r\n  #classifiedParts; // Cached result of #classifyParts (level 2 only)\r\n\r\n  /**\r\n   * Stamps a non-inherited `vector-effect` onto bare <path> elements.\r\n   *\r\n   * vector-effect does not inherit and has no rendering effect on a <g>, so a\r\n   * pass-through vector-effect is relocated from the group onto each descendant\r\n   * <path> that does not already declare one. Innermost scope wins, because\r\n   * inner groups are rendered before their enclosing content.\r\n   *\r\n   * @param {string} content - inner SVG string (may contain nested <g>/<path>)\r\n   * @param {string} value - already-escaped vector-effect value\r\n   * @returns {string} content with vector-effect applied to bare <path> elements\r\n   */\r\n  static applyVectorEffectToPaths(content, value) {\r\n    // Skip empty placeholder paths (<path d=\"\"/>): they draw nothing and are\r\n    // stripped later, so stamping them would defeat that cleanup. Skip paths\r\n    // that already declare a vector-effect so an inner scope wins.\r\n    return content.replace(/<path (?!d=\"\")(?![^>]*\\bvector-effect=)/g, () => `<path vector-effect=\"${value}\" `);\r\n  }\r\n\r\n  /**\r\n   * Wraps content with <a> and/or <g> tags based on options.\r\n   * Ensures consistent wrapping behavior across all element levels.\r\n   *\r\n   * @param {string} content - The content to wrap (raw path data or HTML string)\r\n   * @param {Object} options - The options containing anchor and group attributes\r\n   * @returns {string} The wrapped content\r\n   */\r\n  static #wrapWithAnchorAndGroup(content, options) {\r\n    const { anchorAttrs, groupAttrs, hasHref, vectorEffect } = BlissElement.#separateAnchorAndGroupOptions(options);\r\n\r\n    // Content that starts with '<' is already wrapped in proper tags\r\n    // Raw path data or fragments need wrapping\r\n    const needsPathWrapper = !content.startsWith('<');\r\n\r\n    // vector-effect is non-inherited: relocate it onto the <path>, not the <g>.\r\n    const stamp = (inner) => vectorEffect ? BlissElement.applyVectorEffectToPaths(inner, vectorEffect) : inner;\r\n\r\n    if (hasHref) {\r\n      const wrappedContent = stamp(needsPathWrapper ? `<path d=\"${content}\"/>` : content);\r\n      if (groupAttrs) {\r\n        return `<a ${anchorAttrs} style=\"cursor: pointer;\"><g ${groupAttrs}>${wrappedContent}</g></a>`;\r\n      }\r\n      return `<a ${anchorAttrs} style=\"cursor: pointer;\">${wrappedContent}</a>`;\r\n    }\r\n\r\n    if (groupAttrs) {\r\n      const wrappedContent = stamp(needsPathWrapper ? `<path d=\"${content}\"/>` : content);\r\n      return `<g ${groupAttrs}>${wrappedContent}</g>`;\r\n    }\r\n\r\n    if (vectorEffect) {\r\n      return stamp(needsPathWrapper ? `<path d=\"${content}\"/>` : content);\r\n    }\r\n\r\n    return content;\r\n  }\r\n\r\n  static #separateAnchorAndGroupOptions(options) {\r\n    if (!options || typeof options !== 'object') {\r\n      return { anchorAttrs: '', groupAttrs: '', hasHref: false };\r\n    }\r\n\r\n    const anchorAttrNames = new Set([\r\n      'href',\r\n      'target',\r\n      'rel',\r\n      'download',\r\n      'hreflang',\r\n      'type',\r\n      'referrerpolicy'\r\n    ]);\r\n\r\n    // Use shared INTERNAL_OPTIONS constant\r\n    // Multi-level options (strokeWidth, color, fill, opacity, etc.) are NOT in this set - they should render as attributes.\r\n\r\n    const attrMap = {\r\n      'color': 'stroke',\r\n      'strokeWidth': 'stroke-width'\r\n    };\r\n\r\n    const anchorAttrs = [];\r\n    const groupAttrs = new Map(); // attrName -> value; deduped, explicit name beats alias\r\n    let hasHref = false;\r\n    let hasPointerEvents = false;\r\n    let vectorEffect = null;\r\n\r\n    const isSafeHref = (value) => {\r\n      const cleaned = String(value).replace(/[\\x00-\\x1f\\x7f]/g, '').trim();\r\n      return /^(https?:|mailto:|tel:|\\/|#)/i.test(cleaned);\r\n    };\r\n\r\n    // Values are already escaped by #processOptions at the input boundary\r\n    for (const [key, value] of Object.entries(options)) {\r\n      if (INTERNAL_OPTIONS.has(key) || !isSafeAttributeName(key)) continue;\r\n\r\n      if (anchorAttrNames.has(key)) {\r\n        if (key === 'href') {\r\n          if (!isSafeHref(value)) continue;\r\n          hasHref = true;\r\n        }\r\n        anchorAttrs.push(`${key}=\"${value}\"`);\r\n      } else {\r\n        const attrName = attrMap[key] || key;\r\n        // vector-effect is non-inherited; capture it for relocation onto paths\r\n        if (attrName === 'vector-effect') { vectorEffect = value; continue; }\r\n        if (key === 'pointer-events') hasPointerEvents = true;\r\n        // Each attribute name is emitted once (issue #28). On a collision the\r\n        // explicitly-named attribute wins over an alias (color -> stroke,\r\n        // strokeWidth -> stroke-width). Today #processOptions already orders the\r\n        // color alias ahead of a passthrough stroke, so the skip branch is\r\n        // defensive: it keeps explicit-wins an invariant rather than an artifact\r\n        // of that ordering, independent of option order.\r\n        const isAlias = attrName !== key;\r\n        if (!groupAttrs.has(attrName) || !isAlias) {\r\n          groupAttrs.set(attrName, value);\r\n        }\r\n      }\r\n    }\r\n\r\n    if (hasHref && !hasPointerEvents) {\r\n      groupAttrs.set('pointer-events', 'bounding-box');\r\n    }\r\n\r\n    const groupAttrStrings = [...groupAttrs].map(([name, value]) => `${name}=\"${value}\"`);\r\n\r\n    return {\r\n      anchorAttrs: anchorAttrs.join(' '),\r\n      groupAttrs: groupAttrStrings.join(' '),\r\n      hasHref,\r\n      vectorEffect\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Classifies character parts into glyph parts and indicator parts.\r\n   * Valid pattern: [non-indicators...][indicators...] (no mixing)\r\n   *\r\n   * @param {BlissElement[]} children - Array of child elements to classify\r\n   * @returns {{ glyphParts: BlissElement[], indicatorParts: BlissElement[], isValidPattern: boolean }}\r\n   */\r\n  static #classifyParts(children) {\r\n    if (!children || children.length === 0) {\r\n      return { glyphParts: [], indicatorParts: [], isValidPattern: true };\r\n    }\r\n\r\n    const firstIndicatorIndex = children.findIndex(c => c.isIndicator);\r\n\r\n    // No indicators: all parts are glyph parts\r\n    if (firstIndicatorIndex === -1) {\r\n      return { glyphParts: children, indicatorParts: [], isValidPattern: true };\r\n    }\r\n\r\n    const glyphParts = children.slice(0, firstIndicatorIndex);\r\n    const indicatorParts = children.slice(firstIndicatorIndex);\r\n\r\n    // Validate: no non-indicators after the first indicator\r\n    const isValidPattern = indicatorParts.every(c => c.isIndicator);\r\n\r\n    return { glyphParts, indicatorParts, isValidPattern };\r\n  }\r\n\r\n  #sharedOptions;\r\n\r\n  /**\r\n   * Gets the first character element of the first group (level 2 element).\r\n   * Returns null if the structure doesn't have the expected depth.\r\n   * @returns {BlissElement|null}\r\n   */\r\n  #getFirstCharacterElement() {\r\n    // Content-empty groups are invisible to layout: the reparse of toString()\r\n    // (which omits them) computes indicator overhang from the first\r\n    // content-bearing group, so the live render must skip empties too.\r\n    const firstGroup = this.#children?.find(g => !g.#isEmptyGroup);\r\n    if (!firstGroup) return null;\r\n\r\n    // Empty-parts glyphs are invisible to layout: the reparse of toString()\r\n    // (which omits them) computes indicator overhang from the first\r\n    // content-bearing character, so the live render must too.\r\n    const firstCharacter = firstGroup.#children?.find(c => !c.#isEmptyGlyph);\r\n    if (!firstCharacter || !firstCharacter.#children) return null;\r\n\r\n    return firstCharacter;\r\n  }\r\n\r\n  /**\r\n   * Gets inherited options by walking up the parent chain.\r\n   * Child options take precedence over parent options.\r\n   * @param {string} optionName - The option name to look for\r\n   * @returns {*} The option value, or undefined if not found\r\n   */\r\n  #getInheritedOption(optionName) {\r\n    // Check this element's options first\r\n    if (this.#blissObj.options?.[optionName] !== undefined) {\r\n      return this.#blissObj.options[optionName];\r\n    }\r\n    // Walk up parent chain\r\n    let current = this.#parentElement;\r\n    while (current) {\r\n      if (current.#blissObj.options?.[optionName] !== undefined) {\r\n        return current.#blissObj.options[optionName];\r\n      }\r\n      current = current.#parentElement;\r\n    }\r\n    return undefined;\r\n  }\r\n\r\n  /**\r\n   * True ink start within this element's own frame: 0 for a leaf (path data\r\n   * draws from the origin); for a composite, the leftmost child ink edge.\r\n   * A displaced single-child composite keeps its baked offset (SIB-3), so its\r\n   * ink begins right of x=0 while its reported width still spans from the\r\n   * origin — indicator centering reads this to skip the leading gap (XC-1).\r\n   */\r\n  get #inkStartX() {\r\n    if (!this.#children || this.#children.length === 0) return 0;\r\n    return Math.min(...this.#children.map(child => child.#relativeToParentX + child.#inkStartX));\r\n  }\r\n\r\n  /**\r\n   * True ink end within this element's own frame: the width for a leaf; for a\r\n   * composite, the rightmost child ink edge. A negative-min composite reports\r\n   * its width as a span SIZE (max - min), not a right-edge coordinate, so\r\n   * position + width overstates where the ink stops (XC-1 review F1).\r\n   */\r\n  get #inkEndX() {\r\n    if (!this.#children || this.#children.length === 0) return this.width;\r\n    return Math.max(...this.#children.map(child => child.#relativeToParentX + child.#inkEndX));\r\n  }\r\n\r\n  /**\r\n   * Positions indicator parts as a centered group above the glyph.\r\n   * First indicator is positioned so the entire group is centered over the glyph anchor.\r\n   * Subsequent indicators are positioned relative to the previous indicator.\r\n   *\r\n   * @param {BlissElement[]} glyphParts - The non-indicator parts (the base glyph)\r\n   * @param {BlissElement[]} indicatorParts - The indicator parts to position\r\n   */\r\n  #positionIndicatorGroup(glyphParts, indicatorParts) {\r\n    if (indicatorParts.length === 0) return;\r\n\r\n    // Calculate base glyph metrics over the TRUE INK SPAN (XC-1): both edges\r\n    // add each part's internal ink offsets so a displaced composite base does\r\n    // not count a leading gap (positive baked offset) as ink, and a negative\r\n    // baked offset does not overstate the right edge (its reported width is a\r\n    // span size, not an edge coordinate).\r\n    const glyphMinX = glyphParts.length > 0\r\n      ? Math.min(...glyphParts.map(p => p.#relativeToParentX + p.#inkStartX))\r\n      : 0;\r\n    const glyphMaxX = glyphParts.length > 0\r\n      ? Math.max(...glyphParts.map(p => p.#relativeToParentX + p.#inkEndX))\r\n      : 0;\r\n    const glyphWidth = glyphMaxX - glyphMinX;\r\n    const glyphCenterX = glyphMinX + glyphWidth / 2;\r\n\r\n    // Anchor offset belongs to the base only when there is a single base part.\r\n    // A multi-part / atypical base has no single owner, so it uses the default\r\n    // (0,0) anchor, which keeps the indicator order-independent under base-part\r\n    // reordering (coordinate ownership). A single base part uses its own\r\n    // anchorOffset. The geometric center (glyphCenterX) is already\r\n    // order-independent and is kept above.\r\n    const baseAnchor = glyphParts.length === 1 ? glyphParts[0].anchorOffset : undefined;\r\n    const baseAnchorOffsetX = baseAnchor?.x || 0;\r\n    const baseAnchorOffsetY = baseAnchor?.y || 0;\r\n    const anchorX = glyphCenterX + baseAnchorOffsetX;\r\n\r\n    // Calculate total indicator group width (including gaps)\r\n    const totalIndicatorWidth = indicatorParts.reduce((sum, ind) => sum + ind.width, 0)\r\n      + (indicatorParts.length - 1) * INDICATOR_GAP;\r\n\r\n    // Center the group's CONTENT span over the glyph anchor.\r\n    //\r\n    // An indicator's anchorOffsetX marks the center of its CONTENT (B84: the\r\n    // description arrow with an annotation dot trailing right, a = -0.5; B85\r\n    // mirrored, a = +0.5): the content center sits at width/2 + a, and the\r\n    // dot occupies the remaining 2|a| on the opposite side. Alone over a\r\n    // character, the arrow centers on the anchor and the dot hangs outside\r\n    // the measurement (the single-indicator rule below). In a group, the\r\n    // reader centers the same thing: the row of content from the FIRST\r\n    // member's content-left edge to the LAST member's content-right edge\r\n    // (\"spaced apart and centered as a group\", docs handbook/writing/\r\n    // characters-bcodes). An edge dot facing OUTWARD hangs off the row and\r\n    // is excluded — its member's content edge pulls in by 2|a| — while a dot\r\n    // facing INTO the row and any middle member's dot sit inside it and move\r\n    // nothing:\r\n    //   span   = [P + max(0, 2*a1), P + totalWidth + min(0, 2*aN)]\r\n    //   center = P + totalWidth/2 + max(0, a1) + min(0, aN) = glyphAnchorX\r\n    //   =>  shift = -max(0, a1) - min(0, aN)\r\n    //\r\n    // A single indicator is the n = 1 degenerate case (first == last, one of\r\n    // the two terms is a, the other 0):\r\n    //   x = glyphAnchorX - width/2 - anchorOffsetX\r\n    // sitting its content center exactly on the glyph anchor.\r\n    //\r\n    // (The pre-2026-07-08 rule centered the MIDPOINT of the first/last\r\n    // anchor points instead. Its (wN - w1)/4 width term sat any group whose\r\n    // edge members differ in CONTENT width (width minus the outer 2|a| dot\r\n    // allowance) off the anchor, order-dependently: B391;B81;B90 vs\r\n    // B391;B90;B81, ±0.875. Where edge content widths are equal — B84/B85\r\n    // beside a w=2 partner (3 - 1 = 2) — the old width term coincidentally\r\n    // equaled this dot exclusion, which is why those pairs render exactly as\r\n    // before. Width never skews the group; only outward edge dots move it,\r\n    // by half their 2|a| allowance.)\r\n    const firstAnchorOffsetX = indicatorParts[0].anchorOffset?.x || 0;\r\n    const lastAnchorOffsetX = indicatorParts[indicatorParts.length - 1].anchorOffset?.x || 0;\r\n    const anchorShift = -Math.max(0, firstAnchorOffsetX) - Math.min(0, lastAnchorOffsetX);\r\n\r\n    // Position indicators. A baseless stack (no base part) has nothing to\r\n    // center over, so it lays its parts out left-to-right from the origin; a\r\n    // based stack centers the group over the base anchor. Either way explicit\r\n    // :x,y overrides below.\r\n    let currentX = glyphParts.length === 0\r\n      ? 0\r\n      : anchorX - totalIndicatorWidth / 2 + anchorShift;\r\n\r\n    for (const indicator of indicatorParts) {\r\n      // X positioning: only override if no explicit x was provided\r\n      // Position by left edge to maintain visual 1-unit gaps between indicators\r\n      // (a member's own anchorOffsetX never repositions it INSIDE the group;\r\n      // outward edge dots act once, via anchorShift above)\r\n      if (indicator.#blissObj.x === undefined) {\r\n        indicator.#relativeToParentX = currentX;\r\n      } else {\r\n        indicator.#relativeToParentX = indicator.#blissObj.x;\r\n      }\r\n\r\n      // Y positioning: use same logic as before, but reference base glyph\r\n      if (indicator.#blissObj.y !== undefined) {\r\n        indicator.#relativeToParentY = indicator.#blissObj.y;\r\n      } else {\r\n        const defaultIndicatorY = 4;\r\n        const baseDefaultAnchorY = 4;\r\n        const baseAnchorY = baseDefaultAnchorY + baseAnchorOffsetY;\r\n        const indicatorAnchorOffsetY = indicator.#blissObj.anchorOffsetY || 0;\r\n        indicator.#relativeToParentY = baseAnchorY - indicatorAnchorOffsetY - defaultIndicatorY;\r\n      }\r\n\r\n      // Move to next indicator position\r\n      currentX += indicator.width + INDICATOR_GAP;\r\n    }\r\n  }\r\n\r\n  constructor(blissObj = {}, { parentElement = null, previousElement = null, level = 0, sharedOptions = null } = {}) {\r\n    this.#blissObj = blissObj;\r\n    this.#parentElement = parentElement;\r\n    this.#previousElement = previousElement;\r\n    this.#level = level;\r\n    this.#sharedOptions = sharedOptions || { charSpace: 2, wordSpace: 8, externalGlyphSpace: 0.8 };\r\n\r\n    // Assign key: user-provided key takes precedence, otherwise auto-generate\r\n    this.#key = this.#blissObj.key || generateKey();\r\n\r\n    // Duplicate key detection (only when builder provides sharedOptions with key tracking).\r\n    // The `this.#blissObj.key` guard limits warnings to user-assigned keys only;\r\n    // auto-generated 8-char random keys have negligible collision probability (~2.8T combinations).\r\n    if (this.#sharedOptions.keys) {\r\n      if (this.#blissObj.key && this.#sharedOptions.keys.has(this.#key)) {\r\n        this.#sharedOptions.warnings.push({\r\n          code: WARNING_CODES.DUPLICATE_KEY,\r\n          message: `Duplicate element key: \"${this.#key}\"`,\r\n          source: this.#key,\r\n        });\r\n      }\r\n      this.#sharedOptions.keys.add(this.#key);\r\n    }\r\n\r\n    this.#codeName = \"\";\r\n    this.#relativeToParentX = 0;\r\n    this.#relativeToParentY = 0;\r\n    this.#children = [];\r\n    this.#externalGlyphSpacing = this.#sharedOptions.externalGlyphSpace - (this.kerningRules?.[previousElement?.char] ?? 0);\r\n    this.#childStartOffset = 0;\r\n\r\n    if (this.#level === 0) {\r\n      // Root level (sequence)\r\n      if (!this.#blissObj.groups) {\r\n        this.#blissObj = { groups: [this.#blissObj] };\r\n      }\r\n\r\n      for (const group of this.#blissObj.groups) {\r\n        const child = new BlissElement(group, { parentElement: this, previousElement: this.#children[this.#children.length - 1], level: this.#level + 1, sharedOptions: this.#sharedOptions });\r\n        this.#children.push(child);\r\n      }\r\n      \r\n      // Calculate indicator overhang for first character\r\n      const firstCharacter = this.#getFirstCharacterElement();\r\n      if (firstCharacter && firstCharacter.#classifiedParts) {\r\n        const { glyphParts, indicatorParts } = firstCharacter.#classifiedParts;\r\n\r\n        // Only calculate overhang if we have both glyph parts and indicator parts\r\n        if (glyphParts.length > 0 && indicatorParts.length > 0 && !firstCharacter.isIndicator) {\r\n          // Find how far the leftmost indicator extends left of x=0 (glyph start)\r\n          const indicatorLeftX = indicatorParts[0].#relativeToParentX;\r\n          if (indicatorLeftX < 0) {\r\n            this.#childStartOffset = -indicatorLeftX;\r\n          }\r\n        }\r\n      }\r\n      this.#relativeToParentX = this.#childStartOffset + (this.#blissObj.x ?? 0);\r\n      this.#relativeToParentY = this.#blissObj.y ?? 0;\r\n\r\n      this.getSvgContent = (x = 0, y = 0) => {\r\n        const childContents = this.#children.map(child =>\r\n          child.getSvgContent(this.#relativeToParentX + x, this.#relativeToParentY + y)\r\n        );\r\n\r\n        const hasTaggedContent = childContents.some(c => c.startsWith('<'));\r\n        const hasRawContent = childContents.some(c => !c.startsWith('<'));\r\n\r\n        const content = hasTaggedContent && hasRawContent\r\n          ? childContents.map(c => c.startsWith('<') ? c : `<path d=\"${c}\"/>`).join('')\r\n          : childContents.join('');\r\n\r\n        // At level 0 (sentence/global), only pass anchor attributes to #wrapWithAnchorAndGroup\r\n        // SVG-level attributes (stroke-width, color, etc.) are handled by the SVG builder\r\n        const anchorAttrNames = new Set(['href', 'target', 'rel', 'download', 'hreflang', 'type', 'referrerpolicy']);\r\n        const filteredOptions = {};\r\n        if (this.#blissObj.options) {\r\n          for (const [key, value] of Object.entries(this.#blissObj.options)) {\r\n            if (anchorAttrNames.has(key)) {\r\n              filteredOptions[key] = value;\r\n            }\r\n          }\r\n        }\r\n\r\n        return BlissElement.#wrapWithAnchorAndGroup(content, filteredOptions);\r\n      };\r\n    } else if (this.#level === 1) {\r\n      // Group level\r\n      if (!this.#blissObj.glyphs) {\r\n        this.#blissObj = { glyphs: [this.#blissObj] };\r\n      }\r\n\r\n      // A fail-flagged group (group.errorCode) can no longer appear here:\r\n      // the builder's #normalizeFailedWordInvariant drops such groups before\r\n      // construction, and BlissElement itself is not exported.\r\n\r\n      // Empty-parts glyphs are skipped in the sibling chain so surviving\r\n      // neighbors pair up for spacing and kerning exactly as they do when\r\n      // the serialized form (which omits empty glyphs) is reparsed.\r\n      let previousLayoutGlyph = null;\r\n      for (const glyph of this.#blissObj.glyphs) {\r\n        const child = new BlissElement(glyph, { parentElement: this, previousElement: previousLayoutGlyph, level: this.#level + 1, sharedOptions: this.#sharedOptions });\r\n        this.#children.push(child);\r\n        if (!child.#isEmptyGlyph) previousLayoutGlyph = child;\r\n      }\r\n\r\n      // Content-empty groups (zero glyphs, or only empty-parts glyphs)\r\n      // render nothing and contribute no document extent, mirroring\r\n      // #isEmptyGlyph one level up.\r\n      this.#isEmptyGroup = this.#children.every(child => child.#isEmptyGlyph);\r\n\r\n\r\n      // Check if this is a space group (all glyphs are space glyphs: TSP or QSP).\r\n      // A group with zero glyphs has no space semantics: content-empty groups\r\n      // stay visible to navigation and are never classified as space groups.\r\n      this.#isSpaceGroup = (this.#blissObj.glyphs?.length > 0) && this.#blissObj.glyphs.every(g => {\r\n        const code = g.parts?.[0]?.codeName;\r\n        return code && isSpaceGlyph(code);\r\n      });\r\n      const isSpaceGroup = this.#isSpaceGroup;\r\n\r\n      if (this.#previousElement) {\r\n        if (this.#blissObj.x === undefined) {\r\n          // Position based on previous element's advanceX\r\n          this.#relativeToParentX = this.#previousElement.#relativeToParentX + this.#previousElement.#advanceX;\r\n        } else {\r\n          this.#relativeToParentX = this.#previousElement.#relativeToParentX + this.#previousElement.width + this.#blissObj.x;\r\n        }\r\n      } else if (this.#parentElement) {\r\n        this.#relativeToParentX = this.#parentElement.#relativeToParentX + (this.#blissObj.x ?? 0);\r\n      } else {\r\n        this.#relativeToParentX = this.#blissObj.x ?? 0;\r\n      }\r\n\r\n      if (this.#parentElement) {\r\n        this.#relativeToParentY = this.#parentElement.#relativeToParentY + (this.#blissObj.y ?? 0);\r\n      } else {\r\n        this.#relativeToParentY = this.#blissObj.y ?? 0;\r\n      }\r\n\r\n      // Space groups: advanceX is the sum of their dynamically-calculated glyph widths\r\n      // Regular groups: advanceX is baseGroupWidth + charSpace (the charSpace pairs with TSP to make full wordSpace)\r\n      if (isSpaceGroup) {\r\n        // Sum dynamically-calculated widths for all space glyphs\r\n        this.#advanceX = this.#blissObj.glyphs.reduce((sum, g) => {\r\n          const code = g.parts?.[0]?.codeName;\r\n          if (code === 'TSP') {\r\n            return sum + (this.#sharedOptions.wordSpace - this.#sharedOptions.charSpace);\r\n          } else if (code === 'QSP') {\r\n            return sum + (this.#sharedOptions.wordSpace / 2 - this.#sharedOptions.charSpace);\r\n          }\r\n          return sum;\r\n        }, 0);\r\n      } else if (this.#children.every(child => child.#isEmptyGlyph)) {\r\n        // A group whose every glyph is empty has no layout content: it\r\n        // advances nothing, matching its serialized form, which omits it.\r\n        // Deliberately not #isEmptyGroup: this branch also covers\r\n        // fail-flagged groups (vacuously, with error-placeholder off).\r\n        this.#advanceX = 0;\r\n      } else {\r\n        this.#advanceX = this.baseGroupWidth + this.#sharedOptions.charSpace;\r\n      }\r\n\r\n      this.getSvgContent = (x = 0, y = 0) => {\r\n        const childContents = this.#children.map(child =>\r\n          child.getSvgContent(this.#relativeToParentX + x, this.#relativeToParentY + y)\r\n        );\r\n\r\n        const hasTaggedContent = childContents.some(c => c.startsWith('<'));\r\n        const hasRawContent = childContents.some(c => !c.startsWith('<'));\r\n\r\n        const content = hasTaggedContent && hasRawContent\r\n          ? childContents.map(c => c.startsWith('<') ? c : `<path d=\"${c}\"/>`).join('')\r\n          : childContents.join('');\r\n\r\n        return BlissElement.#wrapWithAnchorAndGroup(content, this.#blissObj.options);\r\n      };\r\n\r\n      // A fail-flagged group (group.errorCode) can no longer reach here: the\r\n      // builder's #normalizeFailedWordInvariant drops such groups before\r\n      // construction, so no L1 fail-render override is needed.\r\n    } else {\r\n      if (this.#level === 2) {\r\n        // Character level\r\n\r\n        // codeName at glyph level: the input code that produces this glyph,\r\n        // when the glyph is actually a glyph. Empty string for composites,\r\n        // bare shape primitives, ad-hoc composites, and multi-char text\r\n        // fallback. The presence of glyphCode IS the \"this is a glyph\" signal:\r\n        // the parser only sets it for registered glyphs (B-codes, X-codes,\r\n        // single-char text fallback, define()d 'glyph'-type aliases). The JSON\r\n        // postParse step (bliss-svg-builder.js) normalizes JSON's codeName\r\n        // field back to glyphCode, so glyph-level codeName never reaches\r\n        // construction. For single-char text fallback the parser stores\r\n        // 'XTXT_<char>' as the internal routing key; surface it publicly as\r\n        // 'X<char>'.\r\n        if (typeof this.#blissObj.glyphCode === 'string') {\r\n          const code = this.#blissObj.glyphCode;\r\n          this.#codeName = code.startsWith('XTXT_') ? 'X' + code.slice(5) : code;\r\n        } else {\r\n          this.#codeName = \"\";\r\n        }\r\n\r\n        this.#char = this.#blissObj.char ?? \"\";\r\n        this.#isBlissGlyph = !!this.#blissObj.isBlissGlyph;\r\n        this.#isExternalGlyph = !!this.#blissObj.isExternalGlyph;\r\n\r\n        if (!this.#blissObj.parts) {\r\n          this.#blissObj = { parts: [this.#blissObj] };\r\n        }\r\n\r\n        // A glyph whose parts array is empty (mutation-emptied, or a DSL\r\n        // options-only token like `[color=red]`) is invisible to layout:\r\n        // zero width, zero advance, no output. Serialization omits it, so\r\n        // the live render must not let it occupy a spacing slot.\r\n        this.#isEmptyGlyph = this.#blissObj.parts.length === 0;\r\n\r\n        const warningCountBefore = this.#sharedOptions?.warnings?.length ?? 0;\r\n\r\n        for (const part of this.#blissObj.parts) {\r\n          const child = new BlissElement(part, { parentElement: this, previousElement: this.#children[this.#children.length - 1], level: this.#level + 1, sharedOptions: this.#sharedOptions });\r\n          this.#children.push(child);\r\n        }\r\n\r\n        // If any part failed (unknown code), replace the entire character\r\n        const hasFailedParts = (this.#sharedOptions?.warnings?.length ?? 0) > warningCountBefore;\r\n        if (hasFailedParts) {\r\n          if (this.#sharedOptions?.errorPlaceholder) {\r\n            // Replace all children with a single placeholder character\r\n            this.#children = [];\r\n            const placeholderParts = structuredClone(this.#sharedOptions.errorPlaceholderParts);\r\n            for (const placeholderPart of placeholderParts) {\r\n              const child = new BlissElement(placeholderPart, {\r\n                parentElement: this,\r\n                previousElement: this.#children[this.#children.length - 1],\r\n                level: this.#level + 1,\r\n                sharedOptions: this.#sharedOptions,\r\n              });\r\n              this.#children.push(child);\r\n            }\r\n          } else {\r\n            // Zero-width invisible character\r\n            this.#children = [];\r\n          }\r\n        }\r\n\r\n        // Classify parts into glyph parts and indicator parts (cache for reuse by getters)\r\n        this.#classifiedParts = BlissElement.#classifyParts(this.#children);\r\n        const { glyphParts, indicatorParts, isValidPattern } = this.#classifiedParts;\r\n\r\n        // Position the indicator group. Runs whenever there are indicator parts\r\n        // in a valid pattern, with or without a base: a based stack centers over\r\n        // the base anchor; a baseless stack (every part an indicator) lays out\r\n        // from origin (#positionIndicatorGroup branches on glyphParts.length).\r\n        // Invalid patterns (e.g., B291;B99;H) fall through to default combination.\r\n        // A single-part all-indicator composite (e.g., B98) lays out at origin,\r\n        // unchanged, keeping its baked internal positioning.\r\n        const hasPositionedIndicators = indicatorParts.length > 0 && isValidPattern;\r\n        if (hasPositionedIndicators) {\r\n          this.#positionIndicatorGroup(glyphParts, indicatorParts);\r\n        }\r\n\r\n        // Normalize: shift parts right only if any child extends left of origin (negative x)\r\n        // Skip normalization for characters with indicators above glyph (they have their own positioning)\r\n        if (!hasPositionedIndicators && this.#children.length > 0) {\r\n          const minX = Math.min(...this.#children.map(child => child.#relativeToParentX));\r\n          if (minX < 0) {\r\n            for (const child of this.#children) {\r\n              child.#relativeToParentX -= minX;\r\n            }\r\n          }\r\n        }\r\n\r\n        if (!this.#previousElement) {\r\n          this.#relativeToParentX = this.#parentElement.#relativeToParentX + (this.#blissObj.x ?? 0);\r\n        } else {\r\n          // An empty-parts glyph must not re-space its neighbor: its serialized\r\n          // form is absent (or a glyphless options token), so the reparse never\r\n          // applies these identity-based adjustments. The RK/AK option blocks\r\n          // below stay ungated — their serialized markers re-apply on reparse.\r\n          if (this.isExternalGlyph && this.#previousElement.isExternalGlyph && !this.#isEmptyGlyph) {\r\n            this.#previousElement.#advanceX = this.#previousElement.width + this.#externalGlyphSpacing;\r\n          }\r\n\r\n          if (!this.#isEmptyGlyph && !this.isExternalGlyph && !this.#previousElement.isExternalGlyph &&\r\n              this.#previousElement.kerningRules && this.codeName) {\r\n            const kerningAdjustment = this.#previousElement.kerningRules[this.codeName] ?? 0;\r\n            if (kerningAdjustment !== 0) {\r\n              this.#previousElement.#advanceX = this.#previousElement.width + this.#sharedOptions.charSpace + kerningAdjustment;\r\n            }\r\n          }\r\n\r\n          if (typeof this.#blissObj.options?.relativeKerning === \"number\") {\r\n            this.#previousElement.#advanceX += this.#blissObj.options.relativeKerning;\r\n          } else if (typeof this.#blissObj.options?.absoluteKerning === \"number\") {\r\n            this.#previousElement.#advanceX = this.#previousElement.width + this.#blissObj.options.absoluteKerning;\r\n          }\r\n\r\n          if (this.#blissObj.x === undefined) {\r\n            this.#relativeToParentX = this.#previousElement.#relativeToParentX + this.#previousElement.#advanceX;\r\n          } else {\r\n            this.#relativeToParentX = this.#previousElement.#relativeToParentX + this.#previousElement.width + this.#blissObj.x;\r\n          }\r\n        }\r\n\r\n        this.#relativeToParentY = this.#blissObj.y ?? 0;\r\n\r\n        if (hasFailedParts && !this.#sharedOptions?.errorPlaceholder) {\r\n          // Invisible failed character takes zero space\r\n          this.#advanceX = 0;\r\n          this.getSvgContent = () => '';\r\n        } else if (this.#isEmptyGlyph) {\r\n          // Empty-parts glyph: no advance (not even charSpace) and no output,\r\n          // so the live render equals the reparse of toString().\r\n          this.#advanceX = 0;\r\n          this.getSvgContent = () => '';\r\n        } else {\r\n          // Dynamic advanceX calculation for space glyphs (TSP, QSP)\r\n          const code = this.#blissObj.parts?.[0]?.codeName;\r\n          if (code && isSpaceGlyph(code)) {\r\n            if (code === 'TSP') {\r\n              this.#advanceX = this.#sharedOptions.wordSpace - this.#sharedOptions.charSpace;\r\n            } else if (code === 'QSP') {\r\n              this.#advanceX = this.#sharedOptions.wordSpace / 2 - this.#sharedOptions.charSpace;\r\n            }\r\n          } else {\r\n            this.#advanceX = this.baseGlyphWidth + this.#sharedOptions.charSpace;\r\n          }\r\n\r\n          this.getSvgContent = (x = 0, y = 0) => {\r\n            const childContents = this.#children.map(child =>\r\n              child.getSvgContent(this.#relativeToParentX + x, this.#relativeToParentY + y)\r\n            );\r\n\r\n            const hasTaggedContent = childContents.some(c => c.startsWith('<'));\r\n            const hasRawContent = childContents.some(c => !c.startsWith('<'));\r\n\r\n            const content = hasTaggedContent && hasRawContent\r\n              ? childContents.map(c => c.startsWith('<') ? c : `<path d=\"${c}\"/>`).join('')\r\n              : childContents.join('');\r\n\r\n            return BlissElement.#wrapWithAnchorAndGroup(content, this.#blissObj.options);\r\n          };\r\n        }\r\n      } else {\r\n        // Part level (level >= 3)\r\n        const elementDefinition = this.#blissObj.codeName?.startsWith('XTXT_')\r\n          ? (() => { const g = createTextFallbackGlyph(this.#blissObj.codeName.slice(5)); g.isShape = true; return g; })()\r\n          : blissElementDefinitions[this.#blissObj.codeName];\r\n        const isPredefinedElement = !!elementDefinition && !!elementDefinition.getPath;\r\n        const isCompositeElement = !!this.#blissObj.parts && this.#blissObj.parts.length > 0;\r\n  \r\n        this.#relativeToParentX = this.#blissObj.x ?? 0;\r\n        this.#relativeToParentY = this.#blissObj.y ?? 0;\r\n\r\n        if (this.#blissObj.errorCode === 'COMPOSITE_AS_PART') {\r\n          // A composed unflagged alias used as a non-leading ;-part (the\r\n          // part-merge operand rule). The part is a composite, so it never\r\n          // reaches the leaf-fail branch below; record the warning and render\r\n          // invisible so the level-2 character fails (placeholder per\r\n          // error-placeholder), mirroring WORD_AS_PART.\r\n          if (!this.#sharedOptions?.warnings) {\r\n            throw new Error(`Unable to create Bliss element: ${this.#blissObj.error || this.#blissObj.codeName || 'unknown'}`);\r\n          }\r\n          this.#sharedOptions.warnings.push({\r\n            code: WARNING_CODES.COMPOSITE_AS_PART,\r\n            message: this.#blissObj.error,\r\n            source: this.#blissObj.codeName || 'unknown',\r\n          });\r\n          this.#leafWidth = 0;\r\n          this.#leafHeight = 0;\r\n          this.getSvgContent = () => '';\r\n        } else if (!isPredefinedElement && !isCompositeElement) {\r\n          // When constructed directly (no builder), throw to preserve existing behaviour\r\n          if (!this.#sharedOptions?.warnings) {\r\n            const failedCode = this.#blissObj.codeName || this.#blissObj.error || 'unknown';\r\n            throw new Error(`Unable to create Bliss element: ${failedCode}`);\r\n          }\r\n\r\n          if (this.#blissObj.errorCode === WARNING_CODES.WORD_AS_PART) {\r\n            this.#sharedOptions.warnings.push({\r\n              code: WARNING_CODES.WORD_AS_PART,\r\n              message: this.#blissObj.error,\r\n              source: this.#blissObj.codeName || 'unknown',\r\n            });\r\n          } else if (this.#blissObj.errorCode === WARNING_CODES.MALFORMED_COORDINATES) {\r\n            // A valid code with a malformed coordinate suffix: the parser tagged\r\n            // it (parsePartString) so the warning names the coordinate, not the\r\n            // code. The token is still dropped (rendered invisible below).\r\n            this.#sharedOptions.warnings.push({\r\n              code: WARNING_CODES.MALFORMED_COORDINATES,\r\n              message: this.#blissObj.error,\r\n              source: this.#blissObj.error,\r\n            });\r\n          } else {\r\n            const failedCode = this.#blissObj.codeName || this.#blissObj.error || 'unknown';\r\n            this.#sharedOptions.warnings.push({\r\n              code: WARNING_CODES.UNKNOWN_CODE,\r\n              message: `Unknown or invalid code: \"${failedCode}\"`,\r\n              source: failedCode,\r\n            });\r\n          }\r\n\r\n          // Render as zero-width invisible. Character level (level 2) handles\r\n          // placeholder display for the entire character when any part fails.\r\n          this.#leafWidth = 0;\r\n          this.#leafHeight = 0;\r\n          this.getSvgContent = () => '';\r\n        } else if (isPredefinedElement) {\r\n          this.#handlePredefinedElement(elementDefinition);\r\n\r\n          // For predefined (leaf) elements with explicit coordinates, use them directly\r\n          if (this.#blissObj.y !== undefined) {\r\n            this.#relativeToParentY = this.#blissObj.y;\r\n          }\r\n        } else if (isCompositeElement) {\r\n          // Surface 'XTXT_<chars>' (internal text-fallback routing key) as\r\n          // 'X<chars>' publicly. Internal lookup uses #blissObj.codeName.\r\n          const raw = this.#blissObj.codeName || \"\";\r\n          this.#codeName = raw.startsWith('XTXT_') ? 'X' + raw.slice(5) : raw;\r\n          this.#handleCompositeElement(this.#blissObj.parts);\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  get parentElement() {\r\n    return this.#parentElement;\r\n  }\r\n\r\n  get previousElement() {\r\n    return this.#previousElement;\r\n  }\r\n\r\n  get advanceX() {\r\n    return this.#advanceX || 0;\r\n  }\r\n\r\n  get children() {\r\n    return this.#children;\r\n  }\r\n\r\n  get codeName() {\r\n    return this.#codeName || \"\";\r\n  }\r\n\r\n  get anchorOffset() {\r\n    return {\r\n      x: this.#anchorOffsetX || 0,\r\n      y: this.#anchorOffsetY || 0\r\n    }\r\n  }\r\n\r\n  get width() {\r\n    if (this.#leafWidth !== undefined) return this.#leafWidth;\r\n    if (!this.#children || this.#children.length === 0) return 0;\r\n\r\n    // Empty-parts glyphs and content-empty groups contribute no extent\r\n    // (they render nothing and serialization omits them).\r\n    const layoutChildren = this.#level === 0\r\n      ? this.#children.filter(child => !child.#isEmptyGroup)\r\n      : this.#level === 1\r\n        ? this.#children.filter(child => !child.#isEmptyGlyph)\r\n        : this.#children;\r\n    if (layoutChildren.length === 0) return 0;\r\n\r\n    const minRelativeX = Math.min(...layoutChildren.map(child => child.#relativeToParentX));\r\n\r\n    let maxRelativeXPlusWidth;\r\n    if (this.#level === 1) {\r\n      maxRelativeXPlusWidth = Math.max(...layoutChildren.map(child =>\r\n        child.#relativeToParentX + child.rightExtendedGlyphWidth));\r\n    } else {\r\n      maxRelativeXPlusWidth = Math.max(...layoutChildren.map(child =>\r\n        child.#relativeToParentX + child.width));\r\n    }\r\n\r\n    let width;\r\n    if (this.#level === 0) {\r\n      width = maxRelativeXPlusWidth - minRelativeX + this.#childStartOffset;\r\n    } else {\r\n      // When minRelativeX > 0, the left boundary is still the element's origin (0),\r\n      // not the leftmost child. Only subtract negative offsets (e.g., indicator overhang).\r\n      width = maxRelativeXPlusWidth - Math.min(0, minRelativeX);\r\n    }\r\n\r\n    return width;\r\n  }\r\n\r\n  get rightExtendedGlyphWidth() {\r\n    if (this.#level !== 2) throw new Error('rightExtendedGlyphWidth can only be called on glyph elements (level 2)');\r\n\r\n    const parts = this.#children;\r\n    if (parts.length === 0) return 0;\r\n\r\n    // Use cached classification (computed once in constructor)\r\n    const { glyphParts } = this.#classifiedParts;\r\n\r\n    // If no glyph parts (all indicators), use all parts for spacing\r\n    const spacingParts = glyphParts.length > 0 ? glyphParts : parts;\r\n\r\n    const minRelativeX = Math.min(...spacingParts.map(part => part.#relativeToParentX));\r\n    const maxRelativeXPlusWidth = Math.max(...parts.map(part => part.#relativeToParentX + part.width));\r\n    // When minRelativeX > 0, the left boundary is still the element's origin (0).\r\n    // Only subtract negative offsets (e.g., indicator overhang).\r\n    const rightExtendedGlyphWidth = maxRelativeXPlusWidth - Math.min(0, minRelativeX);\r\n\r\n    return rightExtendedGlyphWidth;\r\n  }\r\n\r\n  get baseGlyphWidth() {\r\n    if (this.#level !== 2) throw new Error('baseGlyphWidth can only be called on glyph elements (level 2)');\r\n\r\n    const parts = this.#children;\r\n    if (parts.length === 0) return 0;\r\n\r\n    // Use cached classification (computed once in constructor)\r\n    const { glyphParts } = this.#classifiedParts;\r\n\r\n    // If no glyph parts (all indicators), use all parts for width\r\n    const spacingParts = glyphParts.length > 0 ? glyphParts : parts;\r\n\r\n    const minRelativeX = Math.min(...spacingParts.map(part => part.#relativeToParentX));\r\n    const maxRelativeXPlusWidth = Math.max(...spacingParts.map(part => part.#relativeToParentX + part.width));\r\n    // When minRelativeX > 0, the left boundary is still the element's origin (0).\r\n    // Only subtract negative offsets (e.g., indicator overhang).\r\n    const baseGlyphWidth = maxRelativeXPlusWidth - Math.min(0, minRelativeX);\r\n\r\n    return baseGlyphWidth;\r\n  }\r\n\r\n  get baseGroupWidth() {\r\n    if (this.#level !== 1) throw new Error('baseGroupWidth can only be called on group elements (level 1)');\r\n\r\n    const group = this;\r\n    // Empty-parts glyphs contribute no extent (they render nothing and\r\n    // serialization omits them).\r\n    const glyphs = group.#children.filter(glyph => !glyph.#isEmptyGlyph);\r\n    if (glyphs.length === 0) return 0;\r\n\r\n    const firstGlyph = glyphs[0];\r\n    const lastGlyph = glyphs[glyphs.length - 1];\r\n    const lastGlyphBaseWidth = lastGlyph.baseGlyphWidth;\r\n    const baseGroupWidth = lastGlyph.#relativeToParentX + lastGlyphBaseWidth - firstGlyph.#relativeToParentX;\r\n\r\n    return baseGroupWidth;\r\n  }\r\n\r\n  get baseWidth() {\r\n    if (this.#level === 0) {\r\n      // Content-empty groups contribute no extent here either: centering\r\n      // reads baseWidth, so a leaked trailing-empty position term would\r\n      // shift the viewBox and clip ink (mirrors baseGroupWidth's\r\n      // empty-glyph exclusion one level down).\r\n      const groups = this.#children.filter(group => !group.#isEmptyGroup);\r\n      if (groups.length === 0) return 0;\r\n\r\n      const firstGroup = groups[0];\r\n      const lastGroup = groups[groups.length - 1];\r\n      const lastGroupBaseWidth = lastGroup.baseGroupWidth;\r\n      const baseWidth = lastGroup.#relativeToParentX + lastGroupBaseWidth - firstGroup.#relativeToParentX;\r\n      return baseWidth;\r\n    }\r\n\r\n    if (this.#level === 1) return this.baseGroupWidth;\r\n    if (this.#level === 2) return this.baseGlyphWidth;\r\n\r\n    return this.width;\r\n  }\r\n\r\n  get height() {\r\n    if (this.#leafHeight !== undefined) return this.#leafHeight;\r\n    if (this.#level === 2) {\r\n      return 20;\r\n    }\r\n    if (this.#children && this.#children.length > 0) {\r\n      return Math.max(...this.#children.map(child => child.#relativeToParentY + child.height));\r\n    }\r\n    return 0;\r\n  }\r\n\r\n  get baseX() {\r\n    if (this.#leafX !== undefined) return this.#leafX;\r\n    if (!this.#children || this.#children.length === 0) return 0;\r\n\r\n    return this.#relativeToParentX;\r\n  }\r\n\r\n  get x() {\r\n    if (this.#leafX !== undefined) return this.#leafX;\r\n    if (!this.#children || this.#children.length === 0) return 0;\r\n\r\n    const x = Math.min(\r\n      this.#relativeToParentX,\r\n      ...this.#children.map(child => this.#relativeToParentX + child.x)\r\n    );\r\n\r\n    return x;\r\n  }\r\n\r\n  get y() {\r\n    if (this.#level <= 1) return 0;\r\n    if (this.#leafY !== undefined) return this.#leafY;\r\n    if (!this.#children || this.#children.length === 0) return 0;\r\n\r\n    return Math.min(\r\n      this.#relativeToParentY,\r\n      ...this.#children.map(child => this.#relativeToParentY + child.y)\r\n    );\r\n  }\r\n\r\n  get isCharacter() {\r\n    return this.#isCharacter;\r\n  }\r\n\r\n  get char() {\r\n    return this.#char ?? \"\";\r\n  }\r\n\r\n  get kerningRules() {\r\n    return this.#blissObj.kerningRules || {};\r\n  }\r\n\r\n  get isIndicator() {\r\n    return this.#blissObj.isIndicator || false;\r\n  }\r\n\r\n  /**\r\n   * Classifies an indicator part for introspection (R14 Task 6).\r\n   * `indicatorLevel` separates a word-level overlay indicator (tagged\r\n   * `_indicatorOrigin: 'word'` when merged onto the head at decode) from a\r\n   * character-level one; `indicatorKind` reads the definition's\r\n   * `semanticIndicator` flag via the shared `classifyIndicatorKind` (so the\r\n   * snapshot and the handle classify identically). Both null for a\r\n   * non-indicator and for an indicator whose definition cannot be resolved\r\n   * (never throws): the `code` gate maps a non-indicator to null, and\r\n   * `classifyIndicatorKind(null)` is null, so both fall through one return.\r\n   * A composite indicator's internal sub-parts (level >= 3, `isIndicator`\r\n   * inherited) also classify here, mirroring the `isIndicator` field.\r\n   * @returns {{ indicatorLevel: ('word'|'character'|null), indicatorKind: ('semantic'|'grammatical'|null) }}\r\n   */\r\n  #classifyIndicator() {\r\n    const code = this.isIndicator ? this.#blissObj.codeName : null;\r\n    const indicatorKind = classifyIndicatorKind(code, blissElementDefinitions);\r\n    if (indicatorKind === null) return { indicatorLevel: null, indicatorKind: null };\r\n    return {\r\n      indicatorLevel: this.#blissObj._indicatorOrigin === 'word' ? 'word' : 'character',\r\n      indicatorKind,\r\n    };\r\n  }\r\n\r\n  get isShape() {\r\n    return this.#isShape;\r\n  }\r\n\r\n  get isBlissGlyph() {\r\n    return this.#isBlissGlyph;\r\n  }\r\n\r\n  get isExternalGlyph() {\r\n    return this.#isExternalGlyph;\r\n  }\r\n\r\n  get isRoot() {\r\n    return this.#level === 0;\r\n  }\r\n\r\n  get isGroup() {\r\n    return this.#level === 1;\r\n  }\r\n\r\n  get isGlyph() {\r\n    return this.#level === 2;\r\n  }\r\n\r\n  get isPart() {\r\n    return this.#level >= 3;\r\n  }\r\n\r\n  get key() {\r\n    return this.#key;\r\n  }\r\n\r\n  /**\r\n   * Returns a frozen snapshot of this element's data.\r\n   * Snapshots are plain objects safe to expose publicly — no live references.\r\n   *\r\n   * @param {number} [parentOffsetX=0] - Accumulated x offset from ancestors\r\n   * @param {number} [parentOffsetY=0] - Accumulated y offset from ancestors\r\n   * @param {number} [index=0] - Index within parent's children\r\n   * @returns {Object} Frozen ElementSnapshot\r\n   */\r\n  snapshot(parentOffsetX = 0, parentOffsetY = 0, index = 0) {\r\n    const absX = parentOffsetX + this.#relativeToParentX;\r\n    const absY = parentOffsetY + this.#relativeToParentY;\r\n\r\n    let childSnapshots = (this.#children || []).map((child, i) =>\r\n      child.snapshot(absX, absY, i)\r\n    );\r\n\r\n    // For group elements (level 1): resolve isHeadGlyph so every word has exactly one.\r\n    // The parser stamps only an explicit `^`/designation; an unmarked word's head\r\n    // is resolved here at query time (R15 WS-4) via the shared exclusion scan, so\r\n    // it stays correct after a structural mutation reorders the glyphs.\r\n    if (this.#level === 1 && childSnapshots.length > 0) {\r\n      const marked = childSnapshots.findIndex(c => c.isHeadGlyph);\r\n      if (marked === -1) {\r\n        // Empty-parts glyphs cannot head a word (serialization omits them and\r\n        // the overlay resolver skips them); resolve among the others. A word\r\n        // of only empty glyphs has no head at all.\r\n        const contentIndexes = this.#children.flatMap((el, i) => (el.#isEmptyGlyph ? [] : [i]));\r\n        if (contentIndexes.length > 0) {\r\n          const headIndex = contentIndexes[resolveHeadIndex(\r\n            contentIndexes.map(i => headScanCode(\r\n              childSnapshots[i].codeName,\r\n              childSnapshots[i].children?.length ?? 0,\r\n              childSnapshots[i].children?.[0]?.codeName\r\n            ))\r\n          )];\r\n          childSnapshots[headIndex] = Object.freeze({ ...childSnapshots[headIndex], isHeadGlyph: true });\r\n        }\r\n      }\r\n    }\r\n\r\n    const children = Object.freeze(childSnapshots);\r\n\r\n    const { indicatorLevel, indicatorKind } = this.#classifyIndicator();\r\n\r\n    return Object.freeze({\r\n      key: this.#key,\r\n      codeName: this.#codeName || '',\r\n      char: this.#char ?? '',\r\n      x: absX,\r\n      y: absY,\r\n      offsetX: this.#relativeToParentX,\r\n      offsetY: this.#relativeToParentY,\r\n      width: this.width,\r\n      height: this.height,\r\n      advanceX: this.#advanceX || 0,\r\n      baseWidth: this.baseWidth,\r\n      level: this.#level,\r\n      isRoot: this.#level === 0,\r\n      isGroup: this.#level === 1,\r\n      isGlyph: this.#level === 2,\r\n      isPart: this.#level >= 3,\r\n      bounds: Object.freeze(this.#calculateBounds(parentOffsetX, parentOffsetY)),\r\n      isIndicator: this.isIndicator,\r\n      indicatorLevel,\r\n      indicatorKind,\r\n      isShape: !!this.#isShape,\r\n      isBlissGlyph: !!this.#isBlissGlyph,\r\n      isExternalGlyph: !!this.#isExternalGlyph,\r\n      isHeadGlyph: !!this.#blissObj.isHeadGlyph,\r\n      isSpaceGroup: !!this.#isSpaceGroup,\r\n      index,\r\n      parentKey: this.#parentElement ? this.#parentElement.#key : null,\r\n      children\r\n    });\r\n  }\r\n\r\n  get effectiveBounds() {\r\n    // Accumulate offsets from all ancestors\r\n    let offsetX = 0;\r\n    let offsetY = 0;\r\n    let current = this.#parentElement;\r\n    while (current) {\r\n      offsetX += current.#relativeToParentX;\r\n      offsetY += current.#relativeToParentY;\r\n      current = current.#parentElement;\r\n    }\r\n    return this.#calculateBounds(offsetX, offsetY);\r\n  }\r\n\r\n  #calculateBounds(offsetX, offsetY) {\r\n    const absX = offsetX + this.#relativeToParentX;\r\n    const absY = offsetY + this.#relativeToParentY;\r\n\r\n    if (this.#leafHeight !== undefined && this.#leafWidth !== undefined) {\r\n      const leafY = this.#leafY || 0;\r\n      const leafX = this.#leafX || 0;\r\n      const minX = absX + leafX;\r\n      const maxX = absX + leafX + this.#leafWidth;\r\n      const minY = absY + leafY;\r\n      const maxY = absY + leafY + this.#leafHeight;\r\n      return {\r\n        minX,\r\n        maxX,\r\n        minY,\r\n        maxY,\r\n        width: maxX - minX,\r\n        height: maxY - minY\r\n      };\r\n    }\r\n\r\n    if (!this.#children || this.#children.length === 0) {\r\n      return {\r\n        minX: absX,\r\n        maxX: absX,\r\n        minY: absY,\r\n        maxY: absY,\r\n        width: 0,\r\n        height: 0\r\n      };\r\n    }\r\n\r\n    // Content-empty groups and empty-parts glyphs are excluded from bounds\r\n    // like they are from the width getter; an element left with no layout\r\n    // children collapses to a point at its origin instead of Math.min/max\r\n    // over nothing (Infinity).\r\n    const layoutChildren = this.#level === 0\r\n      ? this.#children.filter(child => !child.#isEmptyGroup)\r\n      : this.#level === 1\r\n        ? this.#children.filter(child => !child.#isEmptyGlyph)\r\n        : this.#children;\r\n    if (layoutChildren.length === 0) {\r\n      return {\r\n        minX: absX,\r\n        maxX: absX,\r\n        minY: absY,\r\n        maxY: absY,\r\n        width: 0,\r\n        height: 0\r\n      };\r\n    }\r\n\r\n    const childBounds = layoutChildren.map(child =>\r\n      child.#calculateBounds(absX, absY)\r\n    );\r\n\r\n    const minX = Math.min(...childBounds.map(b => b.minX));\r\n    const maxX = Math.max(...childBounds.map(b => b.maxX));\r\n    const minY = Math.min(...childBounds.map(b => b.minY));\r\n    const maxY = Math.max(...childBounds.map(b => b.maxY));\r\n\r\n    return {\r\n      minX,\r\n      maxX,\r\n      minY,\r\n      maxY,\r\n      width: maxX - minX,\r\n      height: maxY - minY\r\n    };\r\n  }\r\n\r\n  toString() {\r\n    const obj = this.toJSON();\r\n\r\n    function traverse(obj, level = 1) {\r\n      if (!obj.elements) {\r\n          let str =  obj.codeName;\r\n          if (obj.x !== 0 || obj.y !== 0) {\r\n            str = `${str}:${obj.x},${obj.y}`;\r\n          }\r\n          return str;\r\n      }\r\n      \r\n      const delimiterMap = {\r\n          1: '//',\r\n          2: '/',\r\n          3: ';',\r\n      };\r\n\r\n      const results = obj.elements.map(subObj => traverse(subObj, level + 1)).join(delimiterMap[level]);\r\n  \r\n      return results;\r\n    }\r\n\r\n    return traverse(obj);\r\n  }\r\n\r\n  toJSON() {\r\n    let obj = {};\r\n\r\n    // B-code glyphs with a known code are emitted as leaf nodes (normalized)\r\n    // Shapes, external glyphs, and other named elements are also leaves\r\n    // Only unnamed composites (no codeName) recurse into children\r\n    if (this.#codeName) {\r\n        const element = {};\r\n        element.codeName = this.codeName;\r\n        element.width = this.width;\r\n        element.x = this.#relativeToParentX;\r\n        element.y = this.#relativeToParentY;\r\n        obj = element;\r\n    } else if (this.#children) {\r\n      obj.elements = []\r\n      for (const child of this.#children) {\r\n        obj.elements.push(child.toJSON());\r\n      }\r\n    }\r\n\r\n    return obj;\r\n  }\r\n\r\n\r\n  #handlePredefinedElement(definition) {\r\n    if (typeof definition?.getPath !== 'function') throw new Error('An element is only predefined if has a proper getPath function.');\r\n\r\n    // Surface 'XTXT_<chars>' (internal text-fallback routing key) as\r\n    // 'X<chars>' publicly. Internal lookup uses #blissObj.codeName.\r\n    const raw = this.#blissObj.codeName;\r\n    this.#codeName = (typeof raw === 'string' && raw.startsWith('XTXT_'))\r\n      ? 'X' + raw.slice(5)\r\n      : raw;\r\n    this.#extraPathOptions = definition.extraPathOptions || {}; //default: empty object\r\n    this.#isCharacter = !!definition.isCharacter;               //default: false\r\n    this.#isShape = !!definition.isShape;                      //default: false\r\n    this.#leafWidth = definition.width;\r\n    this.#leafHeight = definition.height;\r\n    this.#leafX = definition.x;\r\n    this.#leafY = definition.y;\r\n    \r\n    this.getSvgContent = (x = 0, y = 0) => {\r\n      // Build path options with inheritance: extraPathOptions < inherited < element-level\r\n      // Use #getInheritedOption for options which already handle the inheritance chain\r\n      const inheritedColor = this.#getInheritedOption('color');\r\n      const inheritedStrokeWidth = this.#getInheritedOption('strokeWidth');\r\n      const inheritedDotExtraWidth = this.#getInheritedOption('dotExtraWidth');\r\n      const inheritedSdotExtraWidth = this.#getInheritedOption('sdotExtraWidth');\r\n      const inheritedDotWidth = this.#getInheritedOption('dotWidth');\r\n      const inheritedSdotWidth = this.#getInheritedOption('sdotWidth');\r\n\r\n      // Per-family dot sizing. Absolute (dot-width/sdot-width) beats relative\r\n      // (dot-extra-width/sdot-extra-width). DOT/COMMA take dot-extra-width\r\n      // as-is; SDOT follows as half by default (the bulk knob preserves the\r\n      // DOT:SDOT half-relationship), but its own sdot-* options override that.\r\n      // Non-dot shapes get no dot knob (they ignore it).\r\n      const dotFamily = definition.dotFamily;\r\n      let dotPathOpts = {};\r\n      if (dotFamily === 'dot') {\r\n        if (inheritedDotWidth !== undefined) dotPathOpts = { dotWidth: inheritedDotWidth };\r\n        else if (inheritedDotExtraWidth !== undefined) dotPathOpts = { extraDotWidth: inheritedDotExtraWidth };\r\n      } else if (dotFamily === 'sdot') {\r\n        if (inheritedSdotWidth !== undefined) dotPathOpts = { dotWidth: inheritedSdotWidth };\r\n        else if (inheritedSdotExtraWidth !== undefined) dotPathOpts = { extraDotWidth: inheritedSdotExtraWidth };\r\n        else if (inheritedDotExtraWidth !== undefined) dotPathOpts = { extraDotWidth: inheritedDotExtraWidth / 2 };\r\n      }\r\n\r\n      const pathOptions = {\r\n        ...this.#extraPathOptions,\r\n        ...(inheritedColor !== undefined && { color: inheritedColor }),\r\n        ...(inheritedStrokeWidth !== undefined && { baseStrokeWidth: inheritedStrokeWidth }),\r\n        ...dotPathOpts\r\n      };\r\n      const pathData = definition.getPath(\r\n        this.#relativeToParentX + x,\r\n        this.#relativeToParentY + y,\r\n        pathOptions\r\n      );\r\n\r\n      return BlissElement.#wrapWithAnchorAndGroup(pathData, this.#blissObj.options);\r\n    };\r\n  }\r\n\r\n  #handleCompositeElement(parts) {\r\n    if (this.#level > MAX_RECURSION_DEPTH) throw new Error('Maximum element nesting depth exceeded');\r\n    this.#children = [];\r\n\r\n    for (const part of parts) {\r\n      const child = new BlissElement(part, {\r\n        parentElement: this,\r\n        previousElement: this.#children[this.#children.length - 1],\r\n        level: this.#level + 1,\r\n        sharedOptions: this.#sharedOptions,\r\n      });\r\n      this.#children.push(child);\r\n    }\r\n\r\n    // A compound indicator whose sub-parts carry no baked positions must lay\r\n    // them out as a baseless stack (left-to-right from origin), the same as\r\n    // #positionIndicatorGroup does for a baseless stack at the character level.\r\n    // Without this, an unpositioned all-indicator composite (e.g. a user-defined\r\n    // COMBO_IND = B86;B97) collapses its sub-parts to x=0 when nested as a glyph\r\n    // part, so a sibling stacked indicator overlaps it and the composite's width\r\n    // (derived from its children) under-reports. Built-in compound indicators\r\n    // bake explicit x on their parts (B98 = B97;B99:3,0), so the x === undefined\r\n    // guard leaves them untouched. R15 3b-5.\r\n    // (#handleCompositeElement is only reached for a non-empty parts list, so\r\n    // children is non-empty here and .every is never vacuous.)\r\n    if (this.#children.every(c => c.isIndicator)) {\r\n      let currentX = 0;\r\n      for (const child of this.#children) {\r\n        if (child.#blissObj.x === undefined) child.#relativeToParentX = currentX;\r\n        currentX = child.#relativeToParentX + child.width + INDICATOR_GAP;\r\n      }\r\n    }\r\n\r\n    // Check if this is an indicator at level 3 that will be positioned by #positionIndicatorGroup\r\n    // If so, skip normalization here - let level 2 handle the positioning\r\n    const isIndicatorAtLevel3 = this.#level === 3 && this.isIndicator;\r\n\r\n    // Normalize: shift the child parts so the leftmost lands at x=0 and the\r\n    // stripped common min moves onto the composite as displacement (XC-2),\r\n    // either sign. This holds for a SINGLE child too (its own x IS the n=1\r\n    // common min): the offset is not discarded, so a use-site coord still ADDS\r\n    // to it rather than replacing it (SIB-3's concern), while the composite's\r\n    // frame now equals its ink span. Keeping the offset on a lone child instead\r\n    // (the former length > 1 gate) left a nonzero baked offset inside the\r\n    // frame: a negative one made the frame a span wider than the ink (a phantom\r\n    // right gap in the canvas + advance) and let the ink escape level-2's\r\n    // negatives-only normalization, so the render disagreed with its own\r\n    // decomposed toString. The serializer's decompose uniformly ADDS baked and\r\n    // use-site coords; moving the min onto the composite matches that, and\r\n    // level 2's negatives-only normalization then acts on the resulting final\r\n    // absolute position exactly as it does for the decomposed form. Skip for a\r\n    // level-3 indicator the parent #positionIndicatorGroup will place; the y\r\n    // axis is never re-origined.\r\n    if (!isIndicatorAtLevel3 && this.#children.length > 0) {\r\n      const minX = Math.min(...this.#children.map(child => child.#relativeToParentX));\r\n      if (minX !== 0) {\r\n        for (const child of this.#children) {\r\n          child.#relativeToParentX -= minX;\r\n        }\r\n        this.#relativeToParentX += minX;\r\n      }\r\n    }\r\n\r\n    // Note: Indicator positioning (X and Y) is now handled at level 2 by #positionIndicatorGroup\r\n    // This method no longer needs to calculate indicator positions\r\n\r\n    this.#anchorOffsetX = this.#blissObj.anchorOffsetX || 0;\r\n    this.#anchorOffsetY = this.#blissObj.anchorOffsetY || 0;\r\n\r\n    this.getSvgContent = (x = 0, y = 0) => {\r\n      const childContents = this.#children.map(child =>\r\n        child.getSvgContent(this.#relativeToParentX + x, this.#relativeToParentY + y)\r\n      );\r\n\r\n      const hasTaggedContent = childContents.some(c => c.startsWith('<'));\r\n      const hasRawContent = childContents.some(c => !c.startsWith('<'));\r\n\r\n      const content = hasTaggedContent && hasRawContent\r\n        ? childContents.map(c => c.startsWith('<') ? c : `<path d=\"${c}\"/>`).join('')\r\n        : childContents.join('');\r\n\r\n      return BlissElement.#wrapWithAnchorAndGroup(content, this.#blissObj.options);\r\n    };\r\n  }\r\n}\r\n\r\n","/*\r\n * This Source Code Form is subject to the terms of the Mozilla Public\r\n * License, v. 2.0. If a copy of the MPL was not distributed with this\r\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\r\n */\r\n\r\nimport { blissElementDefinitions, builtInCodes, isSpaceGlyph } from \"./bliss-element-definitions.js\";\r\nimport { hasPathData, createTextFallbackGlyph } from \"./bliss-shape-creators.js\";\r\nimport {\r\n  resolveHeadIndex\r\n} from \"./bliss-head-glyph-exclusions.js\";\r\nimport { resolveEffectiveDefinition, resolveWordIndicatorOverlay } from \"./indicator-utils.js\";\r\nimport { GLOBAL_ONLY_OPTION_KEYS, MAX_RECURSION_DEPTH, OPTION_BRACKET_CONTENT, WARNING_CODES, serializeOptionValue } from \"./bliss-constants.js\";\r\n\r\n// The coordinate-suffix grammar parsePartString accepts: ':' with EACH axis\r\n// optional (:2 | :2, | :,2 | :2,3 | :). Every site that strips a coordinate\r\n// suffix before a definition lookup must strip this SAME grammar, or\r\n// equivalent spellings take different semantic paths (a y-only ':,2' used to\r\n// bypass the misplacement gates while ':0,2' met them).\r\nconst COORD_SUFFIX_PATTERN = /:(?:-?(?:\\d+(?:\\.\\d*)?|\\.\\d+))?(?:,(?:-?(?:\\d+(?:\\.\\d*)?|\\.\\d+))?)?$/;\r\n\r\n// A codeString beginning with a part option ([color=red]>B291) must nest-parse\r\n// like a multi-code string; treated as a plain codeName it becomes one unknown\r\n// token. Shared by the string parser and the object-rebuild expansion paths so\r\n// a toJSON() round-trip reconstructs what the string parser accepted.\r\nconst PART_OPTION_CODESTRING = /^\\[.*?\\]>/;\r\n\r\n// A `>`-less bracket is a CHARACTER option by syntax; inside a `;`-part slot\r\n// only part options ([opts]>) apply, so the bracket is misplaced on an\r\n// otherwise-valid code: peel + warn + drop, then parse the remainder normally.\r\n// The quote-aware grammar keeps the match to ONE bracket token — a `.*?` body\r\n// would backtrack across `]…[` and capture a bracket pair as one blob, and a\r\n// bare `[^\\]]`-class body would truncate at a quoted `]` in a RAW\r\n// definition-sourced part string (top-level input is placeholder-tokenized,\r\n// definition codeStrings are not; review fix, 2026-07-17). Group 1 is the\r\n// bracket, group 2 the grammar's internal atom, group 3 the remainder. The\r\n// non-empty remainder (.+) keeps a dangling bracket with no code on the\r\n// whole-character fail path.\r\nconst PART_SLOT_CHAR_OPTION_PATTERN = new RegExp(String.raw`^(\\[` + OPTION_BRACKET_CONTENT + String.raw`\\])(?!>)(.+)$`);\r\n\r\n// Quote-aware bracket matchers built from the shared grammar (see\r\n// OPTION_BRACKET_CONTENT in bliss-constants.js for the rationale and the\r\n// linear-time guarantee; probe: probe-chunk11-option-value-quoting.mjs).\r\n// The tokenizer pre-pass and #parseOptions' own extraction must agree, or a\r\n// quoted `]` truncates at one layer even when the other accepts it.\r\nconst BRACKET_TOKEN_PATTERN = new RegExp(String.raw`\\{(.*)\\}|\\[(` + OPTION_BRACKET_CONTENT + String.raw`)\\]`, 'g');\r\nconst BRACKET_EXTRACT_PATTERN = new RegExp(String.raw`\\[(` + OPTION_BRACKET_CONTENT + String.raw`)\\]`);\r\n// The overlay prefix matchers run on RESTORED strings (the `;;` store keeps\r\n// codes verbatim), so they need the same quote-aware grammar; group 2 is the\r\n// grammar's internal atom, group 3 the remainder after the bracket.\r\nconst OVERLAY_CHAR_OPTION_PATTERN = new RegExp(String.raw`^(\\[` + OPTION_BRACKET_CONTENT + String.raw`\\])(?!>)(.+)$`);\r\nconst OVERLAY_PART_OPTION_PATTERN = new RegExp(String.raw`^(\\[` + OPTION_BRACKET_CONTENT + String.raw`\\])>(.+)$`);\r\n\r\n// Strips one layer of syntactic decoration from a codeString reference (an\r\n// option prefix, a trailing head marker, a coordinate suffix) so a DECORATED\r\n// alias hop ('[color=green]WORD', 'WORD^', 'WORD:1,2') still resolves for\r\n// wordness; define() inlines only undecorated direct references.\r\nconst stripReferenceDecoration = (s) => s\r\n  .replace(/^(?:\\[.*?\\]>?)+/, '')\r\n  .replace(/\\^+$/, '')\r\n  .replace(COORD_SUFFIX_PATTERN, '');\r\n\r\nexport class BlissParser {\r\n  static parse(codeStr, options) {\r\n      const result = this.fromString(codeStr);\r\n\r\n      if (options) {\r\n        result.options = {...result.options, ...options};\r\n      }\r\n\r\n      return result;\r\n  }\r\n\r\n  static #extractPositionFromOptions(obj) {\r\n    if (obj.options) {\r\n      if (obj.options.x !== undefined && obj.x === undefined) {\r\n        obj.x = Number(obj.options.x);\r\n      }\r\n      if (obj.options.y !== undefined && obj.y === undefined) {\r\n        obj.y = Number(obj.options.y);\r\n      }\r\n    }\r\n  }\r\n\r\n  // Only one option bracket is allowed per level ([a][b]|| is invalid; the\r\n  // canonical multi-option form is [a;b]||). A duplicate is detected only when\r\n  // BOTH forms agree: the tokenized (placeholder) form shows more than one\r\n  // bracket — braces are opaque placeholders there, so a '[' inside {…} never\r\n  // counts — AND the restored form still shows more than one top-level '['\r\n  // once quoted values are stripped with #parseOptions's own quote grammar.\r\n  // The second condition was added to veto the then-quote-unaware pre-pass\r\n  // (a quoted ']' split ONE user bracket into two tokenized ones); the\r\n  // pre-pass is quote-aware since Chunk 11, so both arms now agree on\r\n  // [k=\"][\"]-class inputs and the veto is belt-and-suspenders (kept; the\r\n  // Phase 6 Stryker re-baseline adjudicates its reachability).\r\n  static #hasMultipleOptionBrackets(tokenized, restored) {\r\n    const QUOTED_SPAN = /\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/g;\r\n    return (tokenized.match(/\\[/g) || []).length > 1\r\n      && (restored.replace(QUOTED_SPAN, '').match(/\\[/g) || []).length > 1;\r\n  }\r\n\r\n  static #parseOptions(optionsString) {\r\n    if (!optionsString) return;\r\n\r\n    const bracketMatch = optionsString.match(BRACKET_EXTRACT_PATTERN);\r\n    // Stryker disable next-line all: internal invariant, unreachable from public API\r\n    if (!bracketMatch) {\r\n      throw new Error(`#parseOptions: expected bracketed input, got: ${optionsString}`);\r\n    }\r\n    const extractedContent = bracketMatch[1];\r\n    if (!extractedContent) return;\r\n\r\n    const parsedObject = Object.create(null);\r\n\r\n    const regex = /([\\w-]+)(?:\\s*=\\s*(\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|[^;]*))?/g;\r\n    let match;\r\n\r\n    while ((match = regex.exec(extractedContent)) !== null) {\r\n      const key = match[1].trim();\r\n\r\n      if (match[2] === undefined) {\r\n        // Bare key (e.g., [grid]) — treat as boolean true\r\n        parsedObject[key] = true;\r\n      } else {\r\n        let value = match[2].trim();\r\n\r\n        // Remove quotes and handle escapes for both double and single quotes\r\n        if (value.startsWith('\"') && value.endsWith('\"')) {\r\n          value = value.slice(1, -1).replace(/\\\\\"/g, '\"');\r\n        } else if (value.startsWith(\"'\") && value.endsWith(\"'\")) {\r\n          value = value.slice(1, -1).replace(/\\\\'/g, \"'\");\r\n        }\r\n\r\n        parsedObject[key] = value;\r\n      }\r\n    }\r\n\r\n    return parsedObject;\r\n  }\r\n\r\n  static parsePartString(str, restoreFunction = (s) => s) {\r\n    const part = {};\r\n\r\n    let optionsString, codeString;\r\n    const match = str.match(/^(\\[.*?\\])>(.*)$/);\r\n    if (match) {\r\n      optionsString = match[1];\r\n      codeString = match[2];\r\n      part.options = this.#parseOptions(restoreFunction(optionsString));\r\n    } else {\r\n      codeString = str;\r\n    }\r\n\r\n    if (codeString) {\r\n      const matched = codeString.match(/^([a-zA-Z0-9\\u00C0-\\u017F\\u0370-\\u03FF\\u0400-\\u04FF\\-._]+)(?::(\\-?(?:\\d+(?:\\.\\d*)?|\\.\\d+))?(?:,(\\-?(?:\\d+(?:\\.\\d*)?|\\.\\d+))?)?)?$/);\r\n\r\n      if (matched) {\r\n        let [, code, x, y] = matched;\r\n        part.codeName = code;\r\n        x !== undefined && (part.x = Number(x));\r\n        y !== undefined && (part.y = Number(y));\r\n      } else {\r\n        // Restore placeholders in the MESSAGE only (a tokenized bracket\r\n        // otherwise leaks as a literal [PLACEHOLDER_n], round-2 review\r\n        // NOTE-2); the format checks below stay on the tokenized string.\r\n        part.error = `Invalid format: ${restoreFunction(codeString)}`;\r\n        // A recognizable code followed by a malformed coordinate suffix\r\n        // (B291:abc, B291:., B291:5,6,7) is a coordinate FORMAT error, not an\r\n        // unknown code: the code lexes fine, only the `:x,y` failed to parse.\r\n        // Tag it so the renderer surfaces MALFORMED_COORDINATES instead of the\r\n        // misleading UNKNOWN_CODE. The token is still dropped (invalid syntax is\r\n        // not carried forward); only the warning code differs. The syntax error\r\n        // is reported before semantics, so an unknown code with a bad suffix\r\n        // (ZZ:abc) is MALFORMED_COORDINATES too. The `:` (not `,`) is the\r\n        // trigger: it is the marker that says \"a coordinate follows\".\r\n        if (/^[a-zA-Z0-9À-ſͰ-ϿЀ-ӿ\\-._]+:/.test(codeString)) {\r\n          part.errorCode = WARNING_CODES.MALFORMED_COORDINATES;\r\n        }\r\n      }\r\n    }\r\n\r\n    return part;\r\n  }\r\n  static fromString(inputString) {\r\n    if (typeof inputString === 'string' && inputString.length > 10_000) {\r\n      throw new Error('Input string exceeds maximum length of 10,000 characters');\r\n    }\r\n    inputString = inputString.trim();\r\n    const result = {};\r\n    const parseWarnings = [];\r\n\r\n    // Parse a Blissymbolics string and convert it to an internal representation (BlissComposition)\r\n    //Ex. \r\n    //inputString = \"[stroke-width=0.4;stroke-width=0.3]||[stroke-width=0.2]|H:3,4;E:2,4{hej}/C8:0,8;[color=green]E:0,11{hopp}/AA8N:0,2\"\r\n    //inputString = \"[stroke-width=0.4;stroke-width=0.3]||[stroke-width=0.2]|H:3,4;E:2,4/C8:0,8;[color=green]E:0,11/AA8N:0,2{hej hopp}\"\r\n\r\n    let placeholderMap = {};\r\n    let placeholderCount = 0;\r\n\r\n    // Preserve content in both {...} and [...] to protect spaces.\r\n    // {...} uses greedy match because text content must be able to contain any\r\n    // characters, including literal `{` and `}`. The downside is that multiple\r\n    // `{...}` blocks in one input collapse into a single match, which silently\r\n    // merges the glyphs between them. We emit UNSUPPORTED_TEXT_BLOCKS below to\r\n    // make that visible. Proper multi-block support requires a stateful\r\n    // tokenizer and ships with the {text} rendering feature\r\n    // (see .claude/backlog/text-overlay.md).\r\n    // [...] uses non-greedy match since it can appear multiple times.\r\n    const originalInput = inputString;\r\n    inputString = inputString.replace(BRACKET_TOKEN_PATTERN, (match, textContent, optionContent) => {\r\n      let placeholder = `PLACEHOLDER_${placeholderCount++}`;\r\n      if (textContent !== undefined) {\r\n        placeholderMap[placeholder] = { content: textContent, openBracket: '{', closeBracket: '}' };\r\n        return '{' + placeholder + '}';\r\n      } else {\r\n        placeholderMap[placeholder] = { content: optionContent, openBracket: '[', closeBracket: ']' };\r\n        return '[' + placeholder + ']';\r\n      }\r\n    });\r\n\r\n    // {text} blocks parse onto group.text but do not render yet and are\r\n    // dropped from toString(), so EVERY block warns — a silent single block\r\n    // violated visible-not-silent. Counting `{` AFTER tokenization means a\r\n    // quoted `{` inside an option value never counts, a whole block counts\r\n    // once regardless of nested braces in its content, and a stray unmatched\r\n    // `{` still counts as a failed block attempt.\r\n    if ((inputString.match(/\\{/g) || []).length > 0) {\r\n      parseWarnings.push({\r\n        code: WARNING_CODES.UNSUPPORTED_TEXT_BLOCKS,\r\n        message: 'Text blocks ({...}) are not supported yet: the text does not render and is dropped from toString() output. Multiple {...} blocks in one input have undefined parse behavior until text-block tokenization ships. Use a single trailing {text} per group.',\r\n        source: originalInput,\r\n      });\r\n    }\r\n\r\n    // Remove all spaces in input string (but not in preserved content)\r\n    inputString = inputString.replace(/\\s/g, '');\r\n\r\n    // Helper function to restore placeholders in a string\r\n    const restorePlaceholders = (str) => {\r\n      if (!str) return str; // Handle undefined/null/empty (matches #parseOptions behavior)\r\n      return str.replace(/(\\{|\\[)PLACEHOLDER_(\\d+)(\\}|\\])/g, (match, open, num, close) => {\r\n        const placeholder = placeholderMap[`PLACEHOLDER_${num}`];\r\n        if (placeholder) {\r\n          const { content, openBracket, closeBracket } = placeholder;\r\n          return openBracket + content + closeBracket;\r\n        }\r\n        return match;\r\n      });\r\n    };\r\n\r\n    // Builder-canvas option keys configure the whole SVG, so they are valid\r\n    // only in the global [opts]|| bracket. At group/character/part level they\r\n    // are inert but used to serialize + round-trip silently (audit N-2): warn\r\n    // per key and drop it, keeping the bracket's other options. Returns the\r\n    // mutated object, or undefined when every key was dropped, so call sites\r\n    // store \"no options\" instead of an empty artifact. `text` is exempt via\r\n    // the curated set (an unimplemented stub at EVERY level, not misplaced).\r\n    const dropMisplacedGlobalKeys = (options, levelName) => {\r\n      if (!options) return options;\r\n      for (const key of Object.keys(options)) {\r\n        if (!GLOBAL_ONLY_OPTION_KEYS.has(key)) continue;\r\n        const written = options[key] === true ? key : `${key}=${options[key]}`;\r\n        parseWarnings.push({\r\n          code: WARNING_CODES.MISPLACED_GLOBAL_OPTION,\r\n          message: `Global option (${written}) ignored at ${levelName} level: it configures the whole SVG. Use [${written}]|| to apply it globally.`,\r\n          source: written,\r\n        });\r\n        delete options[key];\r\n      }\r\n      return Object.keys(options).length > 0 ? options : undefined;\r\n    };\r\n\r\n    // Extract global options\r\n    let [_, globalOptionsString, globalCodeString] = inputString.match(/^\\s*(?:([^|]*)\\s*\\|\\|)?(.*)$/);\r\n    if (globalOptionsString && globalOptionsString.match(/^\\[.*\\]$/)) {\r\n      const restoredGlobal = restorePlaceholders(globalOptionsString);\r\n      // #parseOptions keeps the first bracket, so a duplicate warns and drops.\r\n      if (BlissParser.#hasMultipleOptionBrackets(globalOptionsString, restoredGlobal)) {\r\n        parseWarnings.push({\r\n          code: WARNING_CODES.MULTIPLE_OPTION_BRACKETS,\r\n          message: `Multiple option brackets before ||: \"${restoredGlobal}\". Only the first is applied; combine options in one bracket, e.g. [a;b]||.`,\r\n          source: restoredGlobal,\r\n        });\r\n      }\r\n      result.options = this.#parseOptions(restoredGlobal) || {};\r\n    } else {\r\n      if (globalOptionsString && globalOptionsString.length > 0) {\r\n        const restored = restorePlaceholders(globalOptionsString);\r\n        parseWarnings.push({\r\n          code: WARNING_CODES.MALFORMED_GLOBAL_OPTIONS,\r\n          message: `Invalid global options syntax: \"${restored}||\" - expected [options]|| format. Ignoring.`,\r\n          source: restored,\r\n        });\r\n      }\r\n      result.options = {};\r\n    }\r\n\r\n    // Step 1: Replace // patterns with /SP/ (space placeholder)\r\n    // Each // adds one SP, /// adds two SPs, etc.\r\n    const normalized = globalCodeString.replace(/\\/{2,}/g, match =>\r\n      '/' + 'SP/'.repeat(match.length - 1)\r\n    );\r\n\r\n    // Step 2: Split on / and group consecutive items by type (space vs non-space)\r\n    const glyphCodes = normalized.split('/').filter(s => s !== '');\r\n    const isSpaceCode = code => code === 'SP' || code === 'TSP' || code === 'QSP';\r\n\r\n    const groupedCodes = []; // Array of { codes: [...], isSpace: boolean }\r\n    for (const code of glyphCodes) {\r\n      const isSpace = isSpaceCode(code);\r\n      const lastGroup = groupedCodes[groupedCodes.length - 1];\r\n      if (lastGroup && lastGroup.isSpace === isSpace) {\r\n        lastGroup.codes.push(code);\r\n      } else {\r\n        groupedCodes.push({ codes: [code], isSpace });\r\n      }\r\n    }\r\n\r\n    // Step 3: Build parsed groups, staging spaces for TSP/QSP resolution\r\n    const parsedGroups = [];\r\n    for (let gi = 0; gi < groupedCodes.length; gi++) {\r\n      const { codes, isSpace } = groupedCodes[gi];\r\n\r\n      if (isSpace) {\r\n        // Keep explicit spaces and mark implicit SP for the later TSP/QSP pass.\r\n        // See Step 4 below for SP -> TSP/QSP resolution.\r\n        const spaceGlyphs = codes.map(code => {\r\n          const fromSP = code === 'SP';\r\n          return { parts: [{ codeName: fromSP ? 'TSP' : code, _fromSP: fromSP }] };\r\n        });\r\n        parsedGroups.push({ glyphs: spaceGlyphs, _isSpaceGroup: true, _spaceIndex: gi });\r\n        continue;\r\n      }\r\n\r\n      // Non-space group: parse normally\r\n      const tpgs = codes.join('/');\r\n\r\n      let group = { glyphs: [] };\r\n\r\n      let [_, twoPartGroupString, textKey] = tpgs.match(/(.*?)(?:\\{(.*?(?<!\\\\))\\})?$/);\r\n\r\n      if (textKey) {\r\n        group.text = placeholderMap[textKey]?.content ?? textKey;\r\n      }\r\n\r\n      let groupCodeString;\r\n      if (twoPartGroupString.includes('|')) {\r\n        const [beforePipe, afterPipe] = twoPartGroupString.split(\"|\", 2);\r\n        if (beforePipe.match(/^\\[.*\\]$/)) {\r\n          const restoredBeforePipe = restorePlaceholders(beforePipe);\r\n          // #parseOptions keeps the first bracket, so a duplicate warns and drops.\r\n          if (BlissParser.#hasMultipleOptionBrackets(beforePipe, restoredBeforePipe)) {\r\n            parseWarnings.push({\r\n              code: WARNING_CODES.MULTIPLE_OPTION_BRACKETS,\r\n              message: `Multiple option brackets before |: \"${restoredBeforePipe}\". Only the first is applied; combine options in one bracket, e.g. [a;b]|.`,\r\n              source: restoredBeforePipe,\r\n            });\r\n          }\r\n          group.options = dropMisplacedGlobalKeys(this.#parseOptions(restoredBeforePipe), 'group');\r\n          groupCodeString = afterPipe;\r\n        } else if (beforePipe.length > 0) {\r\n          const restoredBeforePipe = restorePlaceholders(beforePipe);\r\n          parseWarnings.push({\r\n            code: WARNING_CODES.MALFORMED_GROUP_OPTIONS,\r\n            message: `Invalid group options syntax: \"${restoredBeforePipe}|\" - expected [options]| format. Ignoring.`,\r\n            source: restoredBeforePipe\r\n          });\r\n          groupCodeString = afterPipe;\r\n        } else {\r\n          groupCodeString = afterPipe;\r\n        }\r\n      } else {\r\n        groupCodeString = twoPartGroupString;\r\n      }\r\n\r\n      function processXCodes(codeString) {\r\n        // First, expand multi-char X-codes (like Xhello -> Xh/Xe/Xl/Xl/Xo or XTXT_héllo)\r\n        // Anchor to a glyph boundary (start of string or after /) so an X+letters\r\n        // sequence embedded in a longer code name (e.g. a custom code EXTRA) is not\r\n        // rewritten mid-token. Match Latin, Latin Extended, and Cyrillic letters.\r\n        // An option bracket ([opts] or [opts]>) at the boundary must not hide\r\n        // the X-run from routing (run-to-stable 2.2). For an ALL-OUTLINED run\r\n        // the prefix rides the FIRST expanded glyph, matching the written\r\n        // /-expansion exactly ([opts]Xab \\u2261 [opts]Xa/Xb \\u2014 X-runs are\r\n        // string-level sugar there). A run containing ANY fallback letter\r\n        // stays ONE XTXT_ glyph (the pre-existing whole-run-fallback rule),\r\n        // so its prefix scopes the whole run; that deliberately differs from\r\n        // the written sequence form, where a prefix binds one member and the\r\n        // member stands alone (review disposition, 2026-07-17).\r\n        let expanded = codeString.replace(/(?<=^|\\/)(\\[[^\\[\\]]*\\]>?)?X([a-zA-Z\\u00C0-\\u017F\\u0370-\\u03FF\\u0400-\\u04FF]{2,})/g, (match, optionPrefix = '', chars, offset) => {\r\n          // Skip expansion when followed by ; (word expansion would break composition).\r\n          // A past-the-end index reads as undefined, which is never ';', so no bounds guard.\r\n          const after = codeString[offset + match.length] === ';';\r\n          if (after) return match;\r\n\r\n          const allHavePath = [...chars].every(char => hasPathData(char));\r\n          if (allHavePath) {\r\n            return optionPrefix + [...chars].map(char => `X${char}`).join('/');\r\n          } else {\r\n            return `${optionPrefix}XTXT_${chars}`;\r\n          }\r\n        });\r\n\r\n        // Then, process sequences of single-char X-codes (like Xh/Xé/Xl -> XTXT_hél if any needs fallback)\r\n        const parts = expanded.split('/');\r\n        const result = [];\r\n        let currentXSequence = [];\r\n\r\n        const flushXSequence = () => {\r\n          if (currentXSequence.length === 0) return;\r\n\r\n          if (currentXSequence.length === 1) {\r\n            const char = currentXSequence[0].slice(1);\r\n            if (hasPathData(char)) {\r\n              result.push(currentXSequence[0]);\r\n            } else {\r\n              result.push(`XTXT_${char}`);\r\n            }\r\n          } else {\r\n            const chars = currentXSequence.map(code => code.slice(1)).join('');\r\n            const allHavePath = [...chars].every(char => hasPathData(char));\r\n\r\n            if (allHavePath) {\r\n              currentXSequence.forEach(code => result.push(code));\r\n            } else {\r\n              result.push(`XTXT_${chars}`);\r\n            }\r\n          }\r\n          currentXSequence = [];\r\n        };\r\n\r\n        for (const part of parts) {\r\n          // Match single-char X-codes: Latin, Latin Extended, and Cyrillic letters\r\n          if (/^X[a-zA-Z\\u00C0-\\u017F\\u0370-\\u03FF\\u0400-\\u04FF]$/.test(part)) {\r\n            currentXSequence.push(part);\r\n            continue;\r\n          }\r\n          flushXSequence();\r\n          // An option-prefixed single-char X-code stands alone: the option\r\n          // scopes to that one character, so it never merges into a\r\n          // whole-run fallback. An outlined letter passes through unchanged\r\n          // (it resolves via its definition downstream); only a fallback\r\n          // letter is rewritten so the XTXT_ route can see it.\r\n          const prefixed = part.match(/^(\\[[^\\[\\]]*\\]>?)X([a-zA-Z\\u00C0-\\u017F\\u0370-\\u03FF\\u0400-\\u04FF])$/);\r\n          if (prefixed && !hasPathData(prefixed[2])) {\r\n            result.push(`${prefixed[1]}XTXT_${prefixed[2]}`);\r\n          } else {\r\n            result.push(part);\r\n          }\r\n        }\r\n        flushXSequence();\r\n\r\n        return result.join('/');\r\n      }\r\n\r\n      function replaceWithDefinition(str, definitions) {\r\n        const wordCode = str;\r\n\r\n        // Rule-3 automatic scan: skip exclusions from the start, stop at the\r\n        // first non-excluded character, or pick by priority tier when the\r\n        // whole word is exclusions. Custom glyph identity (glyphCode) governs\r\n        // first: a custom glyph wrapping an exclusion is its own character,\r\n        // not that exclusion. Without an identity, _scanCode (the character\r\n        // code stashed at part creation) keeps exclusion matching immune to\r\n        // decorations written onto part strings by outer expansion levels.\r\n        const findFallbackHeadIndex = (parts) => {\r\n          const getCode = (i) => parts[i].glyphCode ?? parts[i]._scanCode ?? parts[i].part.split(';')[0];\r\n          return resolveHeadIndex(parts.map((_, i) => getCode(i)));\r\n        };\r\n\r\n        // A space carries neither a designation nor a word indicator: TSP/\r\n        // QSP/ZSA groups serialize as bare word breaks ('//'), so a `^` or\r\n        // `;;` stored on one is eaten by toString and lost on reparse\r\n        // (round-2 external review F1). A DECORATED space token skips the\r\n        // step-2 space branch (the token is not exactly SP/TSP/QSP) and lands\r\n        // here; classify by the expanded part's resolved code.\r\n        const isSpacePart = (p) => {\r\n          const partCode = p._scanCode ?? (p.part ? p.part.split(';')[0].split(':')[0] : '');\r\n          return partCode === 'TSP' || partCode === 'QSP' || partCode === 'ZSA';\r\n        };\r\n\r\n        // Per-word-string head resolution (head-marker contract):\r\n        // rule 2 -- the leftmost written marker (_marker) in this word-string\r\n        // wins; later ones warn and drop. With no written marker, rule 3\r\n        // scans for the head position and rule 4 redirects the crown to the\r\n        // designated head (_designation) of the fragment the scan stopped in.\r\n        const resolveWordStringHead = (parts, label) => {\r\n          const markerIndexes = parts.flatMap((p, i) => (p._marker ? [i] : []));\r\n          for (const laterIndex of markerIndexes.slice(1)) {\r\n            delete parts[laterIndex]._marker;\r\n            parseWarnings.push({ code: WARNING_CODES.MULTIPLE_HEAD_MARKERS, message: `Multiple head markers (^) found in word: ${label}. Using first marked glyph.`, source: label });\r\n          }\r\n          if (markerIndexes.length > 0) {\r\n            delete parts[markerIndexes[0]]._marker;\r\n            return { index: markerIndexes[0], isDesignated: true };\r\n          }\r\n          const stop = findFallbackHeadIndex(parts);\r\n          // Designated parts always carry _frag, so a fragment-less stop\r\n          // (frag === undefined) can never match one.\r\n          const frag = parts[stop]._frag;\r\n          const designated = parts.findIndex(p => p._frag === frag && p._designation);\r\n          if (designated !== -1) return { index: designated, isDesignated: true };\r\n          return { index: stop, isDesignated: false };\r\n        };\r\n\r\n        // Consume a fragment's resolution into a single upward-facing\r\n        // designation: an embedded alias contributes its characters plus at\r\n        // most one designated head (rule 4); deeper bookkeeping is cleared.\r\n        let fragCounter = 0;\r\n        // Seal a span into upward-facing designations. A span containing\r\n        // _wordBreak markers (a nested multi-word alias) is chunked at the\r\n        // breaks and each word-string is sealed on its own fragment, so a\r\n        // marker in a non-first word keeps its designation (rule 2: each\r\n        // // word-string resolves independently). Returns the first word's\r\n        // resolution in full-span coordinates, for callers that target the\r\n        // first word's head (WORD;INDICATORS). A break-free span seals as a\r\n        // single fragment, exactly as before.\r\n        const sealFragment = (parts, label) => {\r\n          let firstResolved = null;\r\n          const sealChunk = (start, end) => {\r\n            const chunk = parts.slice(start, end);\r\n            // Skip empty chunks (adjacent/leading/trailing breaks, or an empty\r\n            // span) so resolveWordStringHead is never handed []. Also the empty\r\n            // -span guard: a break-free empty span produces one empty chunk and\r\n            // returns null.\r\n            if (chunk.length === 0) return;\r\n            const resolved = resolveWordStringHead(chunk, label);\r\n            const fragId = ++fragCounter;\r\n            for (const p of chunk) {\r\n              delete p._designation;\r\n              p._frag = fragId;\r\n            }\r\n            if (resolved.isDesignated) chunk[resolved.index]._designation = true;\r\n            if (firstResolved === null) {\r\n              firstResolved = { index: start + resolved.index, isDesignated: resolved.isDesignated };\r\n            }\r\n          };\r\n          let chunkStart = 0;\r\n          for (let i = 0; i < parts.length; i++) {\r\n            if (parts[i]._wordBreak) {\r\n              sealChunk(chunkStart, i);\r\n              chunkStart = i + 1;\r\n            }\r\n          }\r\n          sealChunk(chunkStart, parts.length);\r\n          return firstResolved;\r\n        };\r\n\r\n        // Resolve and crown one final word: only an explicit `^`/designation\r\n        // is stamped. Fallback heads stay unstamped and are resolved at query\r\n        // time (render/serialize/snapshot) via resolveHeadIndex, so the stamp\r\n        // can never go stale after a structural mutation reorders the word.\r\n        const crownWordChunk = (parts, label) => {\r\n          if (parts.length === 0) return;\r\n          const resolved = resolveWordStringHead(parts, label);\r\n          if (resolved.isDesignated) {\r\n            parts[resolved.index].isHeadGlyph = true;\r\n          }\r\n        };\r\n\r\n        // Split expanded parts at word-break markers and crown each word\r\n        // independently (rule 2: words split by // each have their own head).\r\n        const crownWordChunks = (parts, label) => {\r\n          let chunk = [];\r\n          for (const p of parts) {\r\n            if (p._wordBreak) {\r\n              crownWordChunk(chunk, label);\r\n              chunk = [];\r\n            } else {\r\n              chunk.push(p);\r\n            }\r\n          }\r\n          crownWordChunk(chunk, label);\r\n        };\r\n\r\n        // Helper: resolve codeString through aliases to check if it's a word.\r\n        // A hop that is not itself a registry key may still be a DECORATED\r\n        // reference ('[color=green]WORD', 'WORD^', 'WORD:1,2') — strip the\r\n        // decoration and keep resolving, else a decorated word alias escapes\r\n        // wordness detection (external review 2026-07-02 F2).\r\n        const resolveToFinalCodeString = (code, visited = new Set()) => {\r\n          if (visited.has(code)) return null;\r\n          visited.add(code);\r\n          const def = definitions[code];\r\n          if (!def?.codeString) return null;\r\n          if (!definitions[def.codeString]) {\r\n            const core = stripReferenceDecoration(def.codeString);\r\n            if (core !== def.codeString && definitions[core]) {\r\n              return resolveToFinalCodeString(core, visited) ?? def.codeString;\r\n            }\r\n            return def.codeString;\r\n          }\r\n          return resolveToFinalCodeString(def.codeString, visited);\r\n        };\r\n\r\n        // An indicator (char-level `;` or word-level `;;`) binds to exactly one\r\n        // word. When it is bound to a single ALIAS token that expands to MORE\r\n        // THAN ONE word (a `_wordBreak` survives expansion), there is no single\r\n        // head to carry it, so the binding is invalid. Fail the whole unit:\r\n        // collapse the word-break expansion into one group (filter the breaks so\r\n        // no `//` split survives) and flag it with `_wordError`, exactly like the\r\n        // malformed-`;;` path. The assembly loop lifts the flag onto\r\n        // group.errorCode and the L1 fail-render mechanism collapses it to ONE\r\n        // placeholder (error-placeholder on) or nothing (off). This replaces the\r\n        // legacy silent drop (direct `//` alias) and first-word-head attach\r\n        // (nested alias / `;;` overlay). errorSource is the whole group string\r\n        // (`wordCode`) so toString re-emits it and parse(toString(x)) re-flags;\r\n        // the flag is static + sticky and the splitAt/mergeWithNext guards key\r\n        // off group.errorCode. R2 corpus task 4, Decision 6 (applies uniformly to\r\n        // direct and nested aliases). See [[feedback_no_indicator_of_a_part]].\r\n        const failMultiWordIndicator = (parts) => {\r\n          // Filtering the `_wordBreak` markers collapses the multi-word\r\n          // expansion into one group; any head markers the words carried are\r\n          // already sealed to per-word designations by sealFragment during\r\n          // expansion (so the collapse cannot re-trigger MULTIPLE_HEAD_MARKERS)\r\n          // and are inert anyway, since a placeholder renders for the unit.\r\n          const collapsed = parts.filter(p => !p._wordBreak);\r\n          if (collapsed.length > 0) {\r\n            // Restore placeholders: errorSource re-emits from toString, so a\r\n            // stored placeholder token would replace the user's option text.\r\n            collapsed[0]._wordError = {\r\n              code: WARNING_CODES.MALFORMED_WORD_INDICATOR,\r\n              message: `Indicator bound to the multi-word unit \"${restorePlaceholders(wordCode)}\": an indicator targets a single word, but this expands to multiple words.`,\r\n              source: restorePlaceholders(wordCode),\r\n            };\r\n          }\r\n          return collapsed;\r\n        };\r\n\r\n        // Detect ;; for word-level indicators on inline multi-character expressions.\r\n        // Pattern: baseCode;;indicators. R14: instead of baking the indicators\r\n        // onto the head glyph, store them as a reversible overlay on the group.\r\n        // The base glyphs expand and crown as usual; the overlay is resolved onto\r\n        // the head at decode time (render + serialize) via\r\n        // mergeWordIndicatorsOntoHead, so `;;` round-trips and clears non-\r\n        // destructively. Single ;; on a pre-defined word also becomes an overlay\r\n        // (scope-fenced: single ; on a word still bakes via replaceWithDefinition).\r\n        const wordLevelMatch = str.match(/^(.+);;(.*)$/);\r\n        if (wordLevelMatch) {\r\n          const [_, baseCode, rawIndicators] = wordLevelMatch;\r\n\r\n          // A word-level indicator list must be the trailing part of the word:\r\n          // exactly one `;;`, and no `/`-separated glyph after the indicators\r\n          // (greedy match means rawIndicators holds everything after the last\r\n          // `;;`). Otherwise the whole WORD is invalid: a word-level indicator\r\n          // is a word property (it sets part-of-speech), so a malformed one\r\n          // invalidates the word, not one character. Stash a word-error on the\r\n          // first part; the assembly loop lifts it onto group.errorCode, where\r\n          // the element collapses the word to a single error placeholder (the\r\n          // L1 analogue of the L2 character placeholder) and records ONE warning.\r\n          // str is inside the wordLevelMatch guard, so it always contains `;;`\r\n          // (match is non-null). The base still expands to real (non-space)\r\n          // glyphs so the failed group advances like a normal word; those glyphs\r\n          // are not rendered (the placeholder stands in), and toString re-emits\r\n          // the original `str` so parse(toString(x)) re-flags (round-trip).\r\n          const isMalformed = str.match(/;;/g).length > 1 || rawIndicators.includes('/');\r\n          if (isMalformed) {\r\n            // Expand the fallback NOT at top level: this malformed `;;` already\r\n            // fail-renders with MALFORMED_WORD_INDICATOR, so the re-expansion must\r\n            // not also emit a spurious char-level MISPLACED_CHARACTER_INDICATOR\r\n            // when the base is a bare alias or word. (Strict Indicator Separation.)\r\n            const fallbackParts = str.replace(/;;/g, ';').split('/').flatMap(strPart => expand(strPart, definitions, false));\r\n            // A malformed `;;` whose base expands past a word break (a multi-word\r\n            // `//` alias) yields several word-groups; rendering them all makes\r\n            // toString re-emit the full expansion, so the round-trip grows without\r\n            // bound on every pass. Collapse to one fail-placeholder (verbatim\r\n            // round-trip via errorSource = wordCode), mirroring the well-formed\r\n            // multi-word `;;` fail below. (Strict Indicator Separation.)\r\n            if (fallbackParts.some(p => p._wordBreak)) {\r\n              return failMultiWordIndicator(fallbackParts);\r\n            }\r\n            crownWordChunks(fallbackParts, wordCode);\r\n            if (fallbackParts.length > 0) {\r\n              // Restore placeholders: errorSource re-emits from toString, so a\r\n              // stored placeholder token would replace the user's option text.\r\n              fallbackParts[0]._wordError = {\r\n                code: WARNING_CODES.MALFORMED_WORD_INDICATOR,\r\n                message: `Malformed word-level indicator in \"${restorePlaceholders(str)}\": ;; must be the trailing part of a word.`,\r\n                source: restorePlaceholders(str),\r\n              };\r\n            }\r\n            return fallbackParts;\r\n          }\r\n\r\n          const stripSemantic = rawIndicators.startsWith('!');\r\n          const indicators = stripSemantic ? rawIndicators.slice(1) : rawIndicators;\r\n\r\n          // Process baseCode using the normal flow (splits on / and expands each\r\n          // part): definitions, ^ markers, options, etc.\r\n          const expandedParts = baseCode.split('/').flatMap(strPart => expand(strPart, definitions));\r\n\r\n          // A ;; overlay binds to ONE word. Bound to a multi-word alias (the base\r\n          // expands past a word break), it has no single head: fail the whole\r\n          // unit instead of overlaying only the first word. Decision 6 (uniform\r\n          // with the char-level multi-word-alias fail in expandSegment).\r\n          if (expandedParts.some(part => part._wordBreak)) {\r\n            return failMultiWordIndicator(expandedParts);\r\n          }\r\n\r\n          // A space carries no word indicator (round-2 review F1): the overlay\r\n          // would be stored, then eaten by the '//' serialization. Warn ONCE\r\n          // for the whole overlay (strip included) and keep the plain space —\r\n          // a misplaced decoration on valid content is dropped, not\r\n          // fail-rendered.\r\n          if (expandedParts.length > 0 && expandedParts.every(isSpacePart)) {\r\n            parseWarnings.push({\r\n              code: WARNING_CODES.MISPLACED_WORD_INDICATOR,\r\n              message: `Word-level indicator (;;${rawIndicators}) ignored on \"${restorePlaceholders(str)}\": a space cannot carry a word indicator.`,\r\n              source: restorePlaceholders(str),\r\n            });\r\n            crownWordChunks(expandedParts, wordCode);\r\n            return expandedParts;\r\n          }\r\n\r\n          // Resolve and crown the word so the head is identifiable at decode.\r\n          crownWordChunks(expandedParts, wordCode);\r\n\r\n          // Stash the overlay on the first part; the assembly loop lifts it onto\r\n          // the group. Codes are merged/indicator-filtered at decode, not here;\r\n          // filter(Boolean) drops empties so a bare `;;` yields an empty list.\r\n          // With char-level promotion gone, no leading glyph can pre-claim the\r\n          // word-level slot, so this explicit `;;` overlay always wins here. (A\r\n          // `/`-composition of two explicit `;;` overlays is still resolved\r\n          // first-wins by the assembly loop below.) (Strict Indicator Separation.)\r\n          // Restore each code's placeholders AFTER splitting: a part-level\r\n          // option (`[color=red]>B81`) is placeholder-substituted early, so its\r\n          // internal `;` is safe to split on here; restoring before the split\r\n          // would re-expose that `;` and break a multi-key option. (SIB-2.)\r\n          const rawCodes = indicators.split(';').filter(Boolean).map((c) => restorePlaceholders(c));\r\n\r\n          // An overlay code may carry a part option ([opts]>B81, SIB-2). Its\r\n          // bracket meets the same global-only key gate as any part bracket,\r\n          // but the overlay stores code STRINGS verbatim (parsed only at\r\n          // render-merge), so a gated key must be stripped from the stored\r\n          // string itself or toString would re-serialize the warned no-op\r\n          // forever. Clean codes pass through untouched (SIB-2 fidelity); a\r\n          // stripped prefix is rebuilt with the shared quote-aware key=value\r\n          // emission (serializeOptionValue), so a kept quoted value survives\r\n          // the rebuild.\r\n          const gatedCodes = rawCodes.map((code) => {\r\n            // A CHARACTER-form prefix ([opts]CODE, no >) is inert in overlay\r\n            // position for EVERY key -- the render-merge extracts parts only,\r\n            // so the bracket styles nothing, yet it used to re-serialize\r\n            // forever with no warning anywhere (external review 2026-07-02\r\n            // F2). The whole bracket is misplaced (a word-indicator code has\r\n            // no character to bind to); [opts]> is the styled form. EVERY\r\n            // leading char-form bracket strips in this ONE pass (one warning\r\n            // each) BEFORE the part-form gate runs: the part-form regex would\r\n            // otherwise backtrack across stacked brackets ([a][b]>CODE read\r\n            // as one prefix whose #parseOptions sees only bracket one),\r\n            // leaving later keys unreached or losing a valid later bracket\r\n            // with the misplaced first one (review-fix round 2, F2).\r\n            let current = code;\r\n            let charPrefix;\r\n            while ((charPrefix = current.match(OVERLAY_CHAR_OPTION_PATTERN)) !== null) {\r\n              parseWarnings.push({\r\n                code: WARNING_CODES.MISPLACED_CHARACTER_OPTION,\r\n                message: `Character option (${charPrefix[1]}) ignored on the word indicator \"${charPrefix[3]}\": a ;; code has no character to style. Use ${charPrefix[1]}>${charPrefix[3]} to style the indicator part.`,\r\n                source: current,\r\n              });\r\n              current = charPrefix[3];\r\n            }\r\n            const optionPrefix = current.match(OVERLAY_PART_OPTION_PATTERN);\r\n            if (!optionPrefix) return current;\r\n            const parsed = BlissParser.#parseOptions(optionPrefix[1]) ?? {};\r\n            const keyCount = Object.keys(parsed).length;\r\n            const kept = dropMisplacedGlobalKeys(parsed, 'part');\r\n            const keptEntries = kept ? Object.entries(kept) : [];\r\n            if (keptEntries.length === keyCount) return current;\r\n            if (keptEntries.length === 0) return optionPrefix[3];\r\n            return `[${keptEntries.map(([k, v]) => v === true ? k : `${k}=${serializeOptionValue(v)}`).join(';')}]>${optionPrefix[3]}`;\r\n          });\r\n\r\n          // A `;;` word-level indicator must BE an indicator. Validate + drop here\r\n          // (not silently at render): a recognized non-indicator (a real base)\r\n          // warns NON_INDICATOR_AS_WORD_INDICATOR, an unrecognized code warns\r\n          // UNKNOWN_CODE, and either way the offender is DROPPED so it does not\r\n          // re-serialize. The base still renders as written -- a bad decoration on\r\n          // valid content is dropped, not fail-rendered ([[feedback_error_granularity]]).\r\n          // resolveWordIndicatorOverlay is the shared classify + store rule (the\r\n          // DSL, API, and object surfaces all use it, so they agree); it returns\r\n          // null when the codes were all dropped and there is no strip. (Strict\r\n          // Indicator Separation.) Its 'word-structure' reject reason cannot\r\n          // fire on this path: any `/` in the `;;` tail already failed the\r\n          // whole word at the isMalformed gate above, so this callback maps\r\n          // only 'non-indicator' and 'unknown'.\r\n          const overlay = resolveWordIndicatorOverlay(gatedCodes, stripSemantic, definitions, ({ code: badCode, reason }) => {\r\n            parseWarnings.push(reason === 'non-indicator'\r\n              ? {\r\n                  code: WARNING_CODES.NON_INDICATOR_AS_WORD_INDICATOR,\r\n                  message: `Word-level indicator \"${badCode}\" after ;; is not an indicator; it is ignored. A ;; code must be an indicator (e.g. B81).`,\r\n                  source: badCode,\r\n                }\r\n              : {\r\n                  code: WARNING_CODES.UNKNOWN_CODE,\r\n                  message: `Word-level indicator \"${badCode}\" after ;; is not a known code; it is ignored.`,\r\n                  source: badCode,\r\n                });\r\n          });\r\n\r\n          if (overlay && expandedParts.length > 0) {\r\n            expandedParts[0]._wordIndicators = overlay;\r\n          }\r\n\r\n          return expandedParts;\r\n        }\r\n\r\n        // isTopLevel: true for user input, false for internal codeString expansion\r\n        // Indicator replacement only applies at top level (user input)\r\n        function expand(str, definitions, isTopLevel = true, depth = 0) {\r\n          let hasMarker = false;\r\n          if (str.endsWith('^')) {\r\n            hasMarker = true;\r\n            str = str.slice(0, -1);\r\n          }\r\n          // A head marker attaches to the END of a character, after its\r\n          // indicators (`B291;B81^`). A character includes its indicators, so a\r\n          // `^` written on the base before the indicator separator (`B291^;B81`)\r\n          // is MISPLACED -- not a synonym for the trailing form. Strip it so the\r\n          // base is not lost as an unknown code (`B291^`), but DROP it with a\r\n          // warning rather than honoring it (parallel to a `^` on a multi-\r\n          // character alias below); the user must write it at the character's end.\r\n          const caretBeforeIndicator = str.match(/^(.*?)\\^(;.*)$/);\r\n          if (caretBeforeIndicator) {\r\n            const cleaned = caretBeforeIndicator[1] + caretBeforeIndicator[2];\r\n            parseWarnings.push({\r\n              code: WARNING_CODES.MISPLACED_HEAD_MARKER,\r\n              message: `Head marker (^) ignored on \"${restorePlaceholders(str)}\": it must mark the end of a character, after its indicators (e.g. \"${restorePlaceholders(cleaned)}^\"), not the base before them.`,\r\n              source: restorePlaceholders(str),\r\n            });\r\n            str = cleaned;\r\n          }\r\n          const parts = expandSegment(str, definitions, isTopLevel, depth);\r\n          if (hasMarker) {\r\n            if (parts.length === 1) {\r\n              if (isSpacePart(parts[0])) {\r\n                // A space cannot be a word's head (round-2 review F1): warn +\r\n                // drop, never store a designation the space serialization\r\n                // ('//') cannot re-emit.\r\n                parseWarnings.push({\r\n                  code: WARNING_CODES.MISPLACED_HEAD_MARKER,\r\n                  message: `Head marker (^) ignored on \"${restorePlaceholders(str)}\": a space cannot be a word's head.`,\r\n                  source: restorePlaceholders(str),\r\n                });\r\n              } else {\r\n                // Rule 1: ^ attaches to a character (one expanded glyph),\r\n                // including an alias that resolves to a single character.\r\n                parts[0]._marker = true;\r\n              }\r\n            } else {\r\n              parseWarnings.push({\r\n                code: WARNING_CODES.MISPLACED_HEAD_MARKER,\r\n                message: `Head marker (^) ignored on \"${restorePlaceholders(str)}\": it expands to multiple characters. Mark a single character instead.`,\r\n                source: restorePlaceholders(str),\r\n              });\r\n            }\r\n          }\r\n          return parts;\r\n        }\r\n\r\n        function expandSegment(str, definitions, isTopLevel, depth) {\r\n          if (depth > MAX_RECURSION_DEPTH) throw new Error('Maximum recursion depth exceeded');\r\n\r\n          // Handle part-level options with > (like [x=2]>B291 or [color=red]>XW)\r\n          const partLevelMatch = str.match(/^(\\[.*?\\])>(.+)$/);\r\n          if (partLevelMatch) {\r\n            const optionBracket = partLevelMatch[1];\r\n            let partContent = partLevelMatch[2];\r\n            // Option-placement scope gate (mirrors the char-level `;` MISPLACED\r\n            // gate below). A part option binds to a single part, so `[opts]>` on\r\n            // an alias that expands to a WORD is MISPLACED: warn, drop the\r\n            // option, and expand the rest as if written bare (a trailing\r\n            // `;`-part then meets the normal gate). The word check runs at ANY\r\n            // level -- a definition baking `[opts]>WORDALIAS` behaves like the\r\n            // written form (the old WORD_AS_PART fail serialized to a form that\r\n            // re-parsed differently). A `;`-part behind a validly placed\r\n            // `[opts]>` on a bare alias meets the same MISPLACED rule this\r\n            // early return used to bypass (F2): warn, drop the parts, keep the\r\n            // option on the base; scoped to top level in parity with the `;`\r\n            // gate below.\r\n            const [gateBaseRaw, ...gateParts] = partContent.split(';');\r\n            const gateCoordMatch = gateBaseRaw.match(COORD_SUFFIX_PATTERN);\r\n            const gateBase = gateCoordMatch && gateCoordMatch.index > 0\r\n              ? gateBaseRaw.slice(0, gateCoordMatch.index)\r\n              : gateBaseRaw;\r\n            if (resolveToFinalCodeString(gateBase)?.includes('/')) {\r\n              parseWarnings.push({\r\n                code: WARNING_CODES.MISPLACED_PART_OPTION,\r\n                message: `Part option (${restorePlaceholders(optionBracket)}>) ignored on \"${restorePlaceholders(gateBase)}\": > applies an option to a single part, but this is a word. Use ${restorePlaceholders(optionBracket)}|| to apply it to the whole content.`,\r\n                source: restorePlaceholders(gateBase),\r\n              });\r\n              return expandSegment(partContent, definitions, isTopLevel, depth);\r\n            }\r\n            if (isTopLevel) {\r\n              const gateDef = definitions[gateBase];\r\n              const gateBaseIsBareAlias = !!gateDef && gateDef.codeString !== undefined\r\n                && !gateDef.isBlissGlyph && !gateDef.isShape\r\n                && !gateDef.isExternalGlyph && !gateDef.glyphCode;\r\n              const droppedParts = gateParts.filter(p => p !== '');\r\n              if (gateBaseIsBareAlias && droppedParts.length > 0) {\r\n                parseWarnings.push({\r\n                  code: WARNING_CODES.MISPLACED_CHARACTER_INDICATOR,\r\n                  message: `Character indicator (;${droppedParts.join(';')}) ignored on \"${restorePlaceholders(gateBase)}\": ; composes onto a single character, but this is a word. Use ;; for a word-level indicator.`,\r\n                  source: restorePlaceholders(gateBase),\r\n                });\r\n                partContent = gateBaseRaw;\r\n                str = `${optionBracket}>${gateBaseRaw}`;\r\n              }\r\n            }\r\n            const codeForKerning = partContent.split(':')[0];\r\n            const definition = definitions[codeForKerning] || {};\r\n            return [{\r\n              part: str,\r\n              _scanCode: partContent.split(';')[0].split(':')[0],\r\n              ...(definition.isExternalGlyph && { isExternalGlyph: definition.isExternalGlyph }),\r\n              ...(definition.char && { char: definition.char }),\r\n              ...(definition.kerningRules && { kerningRules: definition.kerningRules }),\r\n            }];\r\n          }\r\n\r\n          // Strip leading glyph-level bracket options\r\n          const optionsMatch = str.match(/^(\\[.*?\\])(?!>)/);\r\n          const optionsPrefix = optionsMatch ? optionsMatch[1] : '';\r\n          const codeForLookup = optionsPrefix ? str.slice(optionsPrefix.length) : str;\r\n\r\n          const [potentialBaseCodeRaw, ...rawIndicators] = codeForLookup.split(';');\r\n          // Strict Indicator Separation: `;` is dumb part-composition, so the\r\n          // `!` strip-semantic shortcut no longer has a special parse. A `!`\r\n          // after a single `;` is just part of an (invalid) appended code.\r\n          const filteredIndicators = rawIndicators.filter(ind => ind !== '');\r\n\r\n          // Strip position modifier (e.g. \":2,0\", \":,2\", \":-1.5,3\") from base\r\n          // code so definition lookup works for codes like \"WORD:2,0\"; the\r\n          // shared pattern matches the full grammar parsePartString accepts,\r\n          // so a y-only \":,2\" resolves the same definition as \":0,2\".\r\n          const posMatch = potentialBaseCodeRaw.match(COORD_SUFFIX_PATTERN);\r\n          const hasPosSuffix = posMatch && posMatch.index > 0;\r\n          const potentialBaseCode = hasPosSuffix\r\n            ? potentialBaseCodeRaw.slice(0, posMatch.index)\r\n            : potentialBaseCodeRaw;\r\n          const positionSuffix = hasPosSuffix ? posMatch[0] : '';\r\n\r\n          const resolvedCodeString = resolveToFinalCodeString(potentialBaseCode);\r\n          const isWordDefinition = resolvedCodeString?.includes('/') ?? false;\r\n\r\n          // A bare alias (a `{codeString}`-only definition, no glyph flag) is a\r\n          // WORD unit, not a single character; a multi-glyph word is many\r\n          // characters. In both cases a char-level `;`-part has no single\r\n          // character to attach to, so it is MISPLACED: warn once, drop it, and\r\n          // render the base as defined (the head keeps any baked indicator). A\r\n          // glyph / literal / unknown code is a single character and dumb-appends\r\n          // the part (base case / built-in path below). Use `;;` for a word-level\r\n          // indicator. See [[feedback_no_indicator_of_a_part]] (Strict Indicator\r\n          // Separation, supersedes R15 Task 3b promotion).\r\n          const baseCodeDef = definitions[potentialBaseCode];\r\n          const baseIsBareAlias = !!baseCodeDef && baseCodeDef.codeString !== undefined\r\n            && !baseCodeDef.isBlissGlyph && !baseCodeDef.isShape\r\n            && !baseCodeDef.isExternalGlyph && !baseCodeDef.glyphCode;\r\n          const misplacedCharIndicator = isTopLevel\r\n            && (baseIsBareAlias || isWordDefinition)\r\n            && filteredIndicators.length > 0;\r\n          if (misplacedCharIndicator) {\r\n            parseWarnings.push({\r\n              code: WARNING_CODES.MISPLACED_CHARACTER_INDICATOR,\r\n              message: `Character indicator (;${filteredIndicators.join(';')}) ignored on \"${restorePlaceholders(potentialBaseCode)}\": ; composes onto a single character, but this is a word. Use ;; for a word-level indicator.`,\r\n              source: restorePlaceholders(potentialBaseCode),\r\n            });\r\n          }\r\n\r\n          // A trailing/empty `;` (no real part: `B291;`, `WORD;`) is inert. It\r\n          // must resolve the BASE definition so the code keeps its identity and\r\n          // metadata (the `;` is normalized away in toString); it is neither a\r\n          // dumb append nor misplaced.\r\n          const isEmptyStrip = rawIndicators.length > 0 && filteredIndicators.length === 0;\r\n\r\n          // Use base code lookup for words, a misplaced char indicator (both\r\n          // render the base definition; the misplaced part is dropped), and an\r\n          // inert empty `;` (preserve the base definition's metadata).\r\n          const useBaseCodeLookup = isWordDefinition || misplacedCharIndicator || isEmptyStrip;\r\n          const definition = useBaseCodeLookup\r\n            ? (definitions[potentialBaseCode] || {})\r\n            : codeForLookup.startsWith('XTXT_')\r\n              ? (() => { const g = createTextFallbackGlyph(codeForLookup.slice(5)); g.isShape = true; return g; })()\r\n              : (definitions[codeForLookup] || {});\r\n\r\n          // If we have a codeString, recursively expand it\r\n          if (definition.codeString) {\r\n            // Strict Indicator Separation: `;` no longer rewrites a definition's\r\n            // baked indicators, so the codeString expands verbatim.\r\n            const codeStringToExpand = definition.codeString;\r\n\r\n            // Built-in single-character codes: skip expansion, let parseParts handle it.\r\n            // This eliminates the flatten-then-unflatten pattern where expand() substitutes\r\n            // a B-code's codeString (e.g. B291 → \"S8:0,8\") only for a later wrapping patch\r\n            // to reconstruct the nesting. Word codes (codeString with /) must still be\r\n            // expanded here because word decomposition produces multiple glyphs.\r\n            if (builtInCodes.has(potentialBaseCode)\r\n                && !codeStringToExpand.includes('/')) {\r\n              return [{\r\n                part: str.replace(/;$/, ''),\r\n                _scanCode: potentialBaseCode,\r\n                ...(definition.shrinksPrecedingWordSpace === true && { shrinksPrecedingWordSpace: true }),\r\n                ...(definition.isIndicator === true && { isIndicator: true }),\r\n                ...(definition.isExternalGlyph && { isExternalGlyph: definition.isExternalGlyph }),\r\n                ...(definition.char && { char: definition.char }),\r\n                ...(definition.kerningRules && { kerningRules: definition.kerningRules }),\r\n                ...(definition.glyphCode && { glyphCode: definition.glyphCode }),\r\n                ...(definition.isBlissGlyph && { isBlissGlyph: definition.isBlissGlyph }),\r\n                ...(definition.defaultOptions && { defaultOptions: definition.defaultOptions }),\r\n              }];\r\n            }\r\n\r\n            // Handle // in codeString: split into word segments with break markers\r\n            if (codeStringToExpand.includes('//')) {\r\n              const wordSegments = codeStringToExpand.split('//');\r\n              const allParts = [];\r\n              for (let i = 0; i < wordSegments.length; i++) {\r\n                if (i > 0) allParts.push({ part: '', _wordBreak: true });\r\n                const segmentParts = wordSegments[i].split('/')\r\n                  .flatMap(s => expand(s, definitions, false, depth + 1));\r\n                // Rule 2: each //-segment of the codeString is its own\r\n                // word-string; seal its markers into a fragment designation.\r\n                sealFragment(segmentParts, potentialBaseCode);\r\n                allParts.push(...segmentParts);\r\n              }\r\n              // Apply position suffix to first non-break part\r\n              if (positionSuffix && allParts.length > 0) {\r\n                const firstReal = allParts.find(p => !p._wordBreak);\r\n                if (firstReal) {\r\n                  const semiParts = firstReal.part.split(';');\r\n                  if (!/:-?[\\d.]/.test(semiParts[0])) {\r\n                    semiParts[0] += positionSuffix;\r\n                  }\r\n                  firstReal.part = semiParts.join(';');\r\n                }\r\n              }\r\n              // A char-level option on a multi-word (//) alias is MISPLACED\r\n              // (B4): a character option applies to a single character. Warn +\r\n              // drop at top level; nested expansion keeps its prepend behavior.\r\n              if (optionsPrefix && allParts.length > 0) {\r\n                if (isTopLevel) {\r\n                  parseWarnings.push({\r\n                    code: WARNING_CODES.MISPLACED_CHARACTER_OPTION,\r\n                    message: `Character option (${restorePlaceholders(optionsPrefix)}) ignored on \"${restorePlaceholders(potentialBaseCode)}\": it applies to a single character, but this expands to multiple words. Use ${restorePlaceholders(optionsPrefix)}|| to apply it to the whole content.`,\r\n                    source: restorePlaceholders(potentialBaseCode),\r\n                  });\r\n                } else {\r\n                  allParts[0].part = optionsPrefix + allParts[0].part;\r\n                }\r\n              }\r\n              // A char-level `;`-part on a multi-word (//) alias is MISPLACED\r\n              // (warned up front): render every word and drop the part. D1.\r\n              return allParts;\r\n            }\r\n\r\n            // First expand to get all parts (including nested expansions)\r\n            const rawExpandedParts = codeStringToExpand.split('/')\r\n              .flatMap(subStr => expand(subStr, definitions, false, depth + 1));\r\n\r\n            // Check if final expansion has multiple glyphs (word vs single-character composite)\r\n            // This covers nested aliases like TestAlias → TestWord1 → H/C\r\n            const isMultiGlyphWord = rawExpandedParts.length > 1;\r\n\r\n            const expandedParts = rawExpandedParts.map(expandedSubPart => {\r\n                // Word-break markers carry no glyph identity; pass them through\r\n                // untouched so definition props don't attach and the break\r\n                // survives into final word-chunk crowning (N6).\r\n                if (expandedSubPart._wordBreak) return expandedSubPart;\r\n                // Apply properties from the definition, falling back to existing values\r\n                const isIndicator = definition.isIndicator ?? expandedSubPart.isIndicator;\r\n                const isExternalGlyph = expandedSubPart.isExternalGlyph;\r\n                const kerningRules = definition.kerningRules ?? expandedSubPart.kerningRules;\r\n                const char = expandedSubPart.char;\r\n                const shrinksPrecedingWordSpace = definition.shrinksPrecedingWordSpace;\r\n                // For multi-glyph words, each part keeps its own glyphCode.\r\n                // For single-character composites: outer definition's glyphCode wins\r\n                // (preserves custom glyph identity, e.g., LOVE wrapping B431).\r\n                const glyphCode = isMultiGlyphWord\r\n                  ? expandedSubPart.glyphCode\r\n                  : (definition.glyphCode ?? expandedSubPart.glyphCode);\r\n                const isBlissGlyph = expandedSubPart.isBlissGlyph ?? definition.isBlissGlyph;\r\n                return {\r\n                  part: expandedSubPart.part,\r\n                  ...(shrinksPrecedingWordSpace === true && { shrinksPrecedingWordSpace }),\r\n                  ...(isIndicator === true && { isIndicator }),\r\n                  ...(isExternalGlyph && { isExternalGlyph }),\r\n                  ...(char && { char }),\r\n                  ...(kerningRules && { kerningRules }),\r\n                  ...(glyphCode && { glyphCode }),\r\n                  ...(isBlissGlyph && { isBlissGlyph }),\r\n                  ...(expandedSubPart._marker && { _marker: true }),\r\n                  ...(expandedSubPart._designation && { _designation: true }),\r\n                  ...(expandedSubPart._frag !== undefined && { _frag: expandedSubPart._frag }),\r\n                  ...(expandedSubPart._scanCode !== undefined && { _scanCode: expandedSubPart._scanCode }),\r\n                  ...(expandedSubPart._aliasCodeName !== undefined && { _aliasCodeName: expandedSubPart._aliasCodeName }),\r\n                  ...(expandedSubPart.defaultOptions && { defaultOptions: expandedSubPart.defaultOptions })\r\n                };\r\n              });\r\n\r\n            // A char-level `;`-part on a nested alias that expands past a word\r\n            // break is MISPLACED (warned up front): render the words, drop the\r\n            // part. D1.\r\n\r\n            // Rule 2: a definition's codeString is its own word-string.\r\n            // Resolve its written markers now (head resolution rule 4); the\r\n            // call mutates expandedParts in place, so its return is not needed.\r\n            sealFragment(expandedParts, potentialBaseCode);\r\n\r\n            // Strict Indicator Separation: a char-level `;`-part on a multi-glyph\r\n            // word is handled up front -- a real part is MISPLACED and dropped\r\n            // (warned above), a trailing `;` is inert. Either way the head is NOT\r\n            // modified here: the word renders as defined, keeping any baked head\r\n            // indicator. Use `;;` for a word-level indicator.\r\n\r\n            // Apply position suffix from outer code (e.g. WORD:2,0) to first glyph's first part\r\n            if (positionSuffix && expandedParts.length > 0) {\r\n              const firstPart = expandedParts[0].part;\r\n              const semiParts = firstPart.split(';');\r\n              // Only add position if the first sub-part doesn't already have coordinates\r\n              if (!/:-?[\\d.]/.test(semiParts[0])) {\r\n                semiParts[0] += positionSuffix;\r\n              }\r\n              expandedParts[0].part = semiParts.join(';');\r\n            }\r\n\r\n            // Carry defaultOptions from the definition as data on the first expanded part\r\n            if (definition.defaultOptions && expandedParts.length > 0) {\r\n              expandedParts[0].defaultOptions = definition.defaultOptions;\r\n            }\r\n\r\n            // Prepend options to the first expanded part. A char-level option\r\n            // is valid on a single character only: on an alias expanding to a\r\n            // multi-character word it is MISPLACED (B4; folds audit N-3 -- it\r\n            // used to land silently on the FIRST character). Warn + drop at\r\n            // top level; nested expansion keeps its prepend behavior.\r\n            if (optionsPrefix && expandedParts.length > 0) {\r\n              if (isTopLevel && isMultiGlyphWord) {\r\n                parseWarnings.push({\r\n                  code: WARNING_CODES.MISPLACED_CHARACTER_OPTION,\r\n                  message: `Character option (${restorePlaceholders(optionsPrefix)}) ignored on \"${restorePlaceholders(potentialBaseCode)}\": it applies to a single character, but this expands to a word. Use ${restorePlaceholders(optionsPrefix)}|| to apply it to the whole content.`,\r\n                  source: restorePlaceholders(potentialBaseCode),\r\n                });\r\n              } else {\r\n                expandedParts[0].part = optionsPrefix + expandedParts[0].part;\r\n              }\r\n            }\r\n\r\n            // A pure single-code rename (a bare alias whose chain bottoms out\r\n            // at a definition with identity: a glyph, an indicator, a shape,\r\n            // an external glyph, or a getPath primitive) dissolves its written\r\n            // name into this expansion, which `preserve` could then never\r\n            // restore. Record it in the Phase 2.3b side channel, extended to\r\n            // character level here. The outermost written name wins (this\r\n            // overwrites an inner frame's recording); a chain ending on a bare\r\n            // alias (multi-code shorthand or an unresolved forward ref)\r\n            // records nothing, so shorthand keeps serializing expanded. The\r\n            // length guard keeps the recording off multi-glyph expansions,\r\n            // where it would mislabel the first glyph.\r\n            if (expandedParts.length === 1 && baseIsBareAlias) {\r\n              const effective = resolveEffectiveDefinition(definition, definitions);\r\n              if (effective && (effective.isIndicator === true\r\n                  || effective.isBlissGlyph || effective.isShape\r\n                  || effective.isExternalGlyph || effective.glyphCode\r\n                  || typeof effective.getPath === 'function')) {\r\n                expandedParts[0]._aliasCodeName = potentialBaseCode;\r\n              }\r\n            } else if (expandedParts.length === 1 && definition.isShape) {\r\n              // A typed shape has no glyphCode identity channel, so its own\r\n              // written name dissolves into this expansion too. Record it the\r\n              // same way (a typed definition keeps its name whatever its\r\n              // anatomy, per the ratified preserve statement); built-in\r\n              // shapes never reach this branch (early return above).\r\n              expandedParts[0]._aliasCodeName = potentialBaseCode;\r\n            }\r\n\r\n            return expandedParts;\r\n          }\r\n\r\n          // Base case - create object with properties from definition\r\n          const isIndicator = definition.isIndicator;\r\n          const isExternalGlyph = definition.isExternalGlyph;\r\n          const kerningRules = definition.kerningRules;\r\n          const char = definition.char;\r\n          const glyphCode = definition.glyphCode;\r\n          const isBlissGlyph = definition.isBlissGlyph;\r\n          const shrinksPrecedingWordSpace = definition.shrinksPrecedingWordSpace;\r\n          // Strict Indicator Separation: `;` dumb-appends, so `str` is kept\r\n          // verbatim (a trailing `;` is normalized away; an invalid appended\r\n          // part such as `!B81` falls through to UNKNOWN_CODE in parseParts).\r\n          return [{\r\n            part: str.replace(/;$/, ''),\r\n            _scanCode: potentialBaseCode,\r\n            ...(shrinksPrecedingWordSpace === true && { shrinksPrecedingWordSpace }),\r\n            ...(isIndicator === true && { isIndicator }),\r\n            ...(isExternalGlyph && { isExternalGlyph }),\r\n            ...(char && { char }),\r\n            ...(kerningRules && { kerningRules }),\r\n            ...(glyphCode && { glyphCode }),\r\n            ...(isBlissGlyph && { isBlissGlyph })\r\n          }];\r\n        }\r\n\r\n        const expandedParts = str.split('/').flatMap(strPart => expand(strPart, definitions));\r\n\r\n        // Resolve and crown the head of each final word (head-marker contract)\r\n        crownWordChunks(expandedParts, wordCode);\r\n\r\n        return expandedParts;\r\n      }\r\n\r\n      const processedGroupCodeString = processXCodes(groupCodeString);\r\n      const expandedGlyphParts = replaceWithDefinition(processedGroupCodeString, blissElementDefinitions);\r\n\r\n      // A group option binds to ONE word-group. Bound to an alias whose\r\n      // expansion crosses a word break (a multi-word // alias), there is no\r\n      // single group to carry it -- it used to style only the FIRST word,\r\n      // silently. Warn + drop the bracket + render every word. The written\r\n      // [opts]|a//b form never reaches this gate: a top-level // splits\r\n      // groups BEFORE option parsing, so that bracket binds to group 1 by\r\n      // syntax (the same alias-vs-written split as the character-level gate).\r\n      // The malformed-;; fail path collapses its word breaks, so a\r\n      // fail-rendered unit keeps its bracket (errorSource round-trips it).\r\n      // Two separator kinds span words: a // word break AND an explicit space\r\n      // code between glyphs (external review 2026-07-02 F3: an in-alias TSP is\r\n      // not a _wordBreak, but its serialized /TSP/ splits groups on reparse,\r\n      // silently rebinding the bracket to the first word). A separator with\r\n      // inked content on ONE side only (a trailing space or //) does NOT span\r\n      // words: the bracket still binds the only inked word and round-trips\r\n      // stably, so it keeps its option.\r\n      const expansionSpansWords = (parts) => {\r\n        let sawWord = false;\r\n        let sawSeparatorAfterWord = false;\r\n        for (const p of parts) {\r\n          // A part re-splits into its own group on reparse ONLY as a bare\r\n          // space token (the top-level split matches the exact token), so a\r\n          // composed (TSP;B81) or decorated space stays in-group and\r\n          // separates nothing; kerning markers are neither ink nor a\r\n          // separator (they decorate the next glyph). (Review-fix round 2,\r\n          // F3: matching _scanCode over-classified both.)\r\n          const partCode = p._scanCode ?? (p.part ? p.part.split(';')[0].split(':')[0] : '');\r\n          if (partCode === 'RK' || partCode === 'AK') continue;\r\n          if (p._wordBreak || isSpaceCode(p.part)) {\r\n            if (sawWord) sawSeparatorAfterWord = true;\r\n          } else if (p.part !== '') {\r\n            if (sawSeparatorAfterWord) return true;\r\n            sawWord = true;\r\n          }\r\n        }\r\n        return false;\r\n      };\r\n      if (group.options && expansionSpansWords(expandedGlyphParts)) {\r\n        const written = Object.entries(group.options)\r\n          .map(([k, v]) => v === true ? k : `${k}=${v}`).join(';');\r\n        const aliasSource = restorePlaceholders(groupCodeString);\r\n        parseWarnings.push({\r\n          code: WARNING_CODES.MISPLACED_GROUP_OPTION,\r\n          message: `Group option ([${written}]) ignored on \"${aliasSource}\": | applies options to a single word, but this expands to multiple words. Use [${written}]|| to apply them to the whole content.`,\r\n          source: aliasSource,\r\n        });\r\n        delete group.options;\r\n      }\r\n\r\n      let pendingRelativeKerning;\r\n      let pendingAbsoluteKerning;\r\n\r\n      for (let { part, shrinksPrecedingWordSpace, isIndicator, isExternalGlyph, char, kerningRules, glyphCode, isBlissGlyph, isHeadGlyph, defaultOptions, _aliasCodeName, _wordBreak, _wordIndicators, _wordError } of expandedGlyphParts) {\r\n        // Lift a word-level fail-render flag onto its enclosing group (mirrors\r\n        // the _wordIndicators lift below). A malformed `;;` makes the whole word\r\n        // invalid; the element reads group.errorCode and collapses it to one\r\n        // placeholder. The flag is static (no `;;` structure survives to\r\n        // re-derive from), so it persists across rebuild; errorSource carries the\r\n        // original string for the toString round-trip.\r\n        if (_wordError) {\r\n          group.errorCode = _wordError.code;\r\n          group.error = _wordError.message;\r\n          group.errorSource = _wordError.source;\r\n        }\r\n        // R14/R15: lift a word-level indicator overlay onto its enclosing group.\r\n        // The word-level ;; slot is a WORD property owned by the FIRST glyph:\r\n        // the first glyph (group.glyphs still empty) claims it; a later glyph's\r\n        // promoted overlay is dropped + DROPPED_WORD_INDICATOR (first-wins, so\r\n        // `/`-composition matches mergeWithNext). An empty first slot still wins.\r\n        if (_wordIndicators) {\r\n          if (group.glyphs.length === 0) {\r\n            group.wordIndicators = _wordIndicators;\r\n          } else {\r\n            const { codes = [], stripSemantic } = _wordIndicators;\r\n            const dropped = ';;' + (stripSemantic ? '!' : '') + codes.join(';');\r\n            parseWarnings.push({\r\n              code: WARNING_CODES.DROPPED_WORD_INDICATOR,\r\n              message: `Composing glyphs into one word dropped a later glyph's word-level indicator overlay (${dropped}). The word keeps only the first glyph's overlay.`,\r\n              source: dropped,\r\n            });\r\n          }\r\n        }\r\n        // Word break marker from // in bare alias codeString:\r\n        // push current group, add a default space group, start a new group\r\n        if (_wordBreak) {\r\n          if (group.glyphs.length > 0) {\r\n            this.#extractPositionFromOptions(group);\r\n            parsedGroups.push(group);\r\n          }\r\n          parsedGroups.push({ glyphs: [{ parts: [{ codeName: 'SP', _fromSP: true }] }], _isSpaceGroup: true, _spaceIndex: parsedGroups.length });\r\n          group = { glyphs: [] };\r\n          continue;\r\n        }\r\n        if (part === \"\") continue;\r\n\r\n        const glyphObj = {\r\n          parts: [],\r\n          ...(shrinksPrecedingWordSpace === true && { shrinksPrecedingWordSpace }),\r\n          ...(typeof isIndicator === \"boolean\" && { isIndicator }),\r\n          ...(typeof isExternalGlyph === \"boolean\" && { isExternalGlyph }),\r\n          ...(typeof char === \"string\" && { char }),\r\n          ...((kerningRules !== null && kerningRules?.constructor === Object) && { kerningRules }),\r\n          ...(typeof glyphCode === \"string\" && { glyphCode }),\r\n          ...(isBlissGlyph === true && { isBlissGlyph }),\r\n          ...(isHeadGlyph === true && { isHeadGlyph })\r\n        };\r\n\r\n        const kerningMatch = part.match(/^(RK|AK)(?::([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)))?$/);\r\n        if (kerningMatch) {\r\n          const [_, kerningType, kerningValue] = kerningMatch;\r\n          // A bare marker (RK/AK with no `:value`) is absent: it applies no\r\n          // kerning and is not persisted, so it never materializes a default\r\n          // (RK:0/AK:0 on serialization) or collapses the pair gap (a bare AK).\r\n          // Only an explicit value (including :0, the deliberate zero-gap\r\n          // spelling) is kept. Still `continue` so a bare marker is consumed,\r\n          // not misread as an UNKNOWN_CODE.\r\n          if (kerningValue !== undefined) {\r\n            if (kerningType === \"RK\") pendingRelativeKerning = Number(kerningValue);\r\n            if (kerningType === \"AK\") pendingAbsoluteKerning = Number(kerningValue);\r\n          }\r\n          continue;\r\n        }\r\n\r\n        // A kerning marker (RK:/AK:) whose value failed the grammar above is a\r\n        // malformed kerning value (RK:abc, RK:., RK:.5.5, RK:5e2, RK:). Warn and\r\n        // drop it — apply no kerning, leaving the next glyph unshifted — rather\r\n        // than letting it fall through as a misleading UNKNOWN_CODE. The ^ anchor\r\n        // keeps a real code that merely contains RK:/AK: (e.g. B86RK:abc) from\r\n        // being mis-read as kerning.\r\n        if (/^(RK|AK):/.test(part)) {\r\n          parseWarnings.push({\r\n            code: WARNING_CODES.MALFORMED_KERNING_VALUE,\r\n            message: `Malformed kerning value \"${part}\"; the marker is ignored.`,\r\n            source: part,\r\n          });\r\n          continue;\r\n        }\r\n\r\n        if (pendingRelativeKerning !== undefined) {\r\n          (glyphObj.options ??= {}).relativeKerning = pendingRelativeKerning;\r\n          pendingRelativeKerning = undefined;\r\n        }\r\n\r\n        if (pendingAbsoluteKerning !== undefined) {\r\n          (glyphObj.options ??= {}).absoluteKerning = pendingAbsoluteKerning;\r\n          pendingAbsoluteKerning = undefined;\r\n        }\r\n\r\n        // Merge defaultOptions carried from expand() (standalone/composition case)\r\n        if (defaultOptions) {\r\n          glyphObj.options = { ...defaultOptions, ...(glyphObj.options || {}) };\r\n        }\r\n\r\n        let glyphCodeString = part;\r\n        // The [^\\[\\]] class keeps the char-option match to ONE bracket token.\r\n        // The old `.*?` class backtracked across `]>…;[` when the lookahead\r\n        // failed, capturing `[a]>CODE;[b]` as one character-option blob —\r\n        // every part before the second bracket was silently eaten.\r\n        const glyphMatch = part.match(/^(\\[[^\\[\\]]*\\])(?!>)(.*)/);\r\n        if (glyphMatch) {\r\n          const parsedOptions = dropMisplacedGlobalKeys(\r\n            this.#parseOptions(restorePlaceholders(glyphMatch[1])), 'character');\r\n          // Merge only when something remains: a bracket fully emptied by the\r\n          // gate (or written empty) must not leave an options: {} artifact on\r\n          // the glyph -- the gated form's toJSON matches the bare form's.\r\n          if (glyphObj.options || parsedOptions) {\r\n            glyphObj.options = { ...glyphObj.options, ...parsedOptions };\r\n          }\r\n          glyphCodeString = glyphMatch[2];\r\n        }\r\n\r\n        const parseParts = (partsString, depth = 0) => {\r\n          if (depth > MAX_RECURSION_DEPTH) throw new Error('Maximum recursion depth exceeded');\r\n          const parts = [];\r\n\r\n          // Split on ; (top-level input is placeholder-tokenized here;\r\n          // definition-sourced strings carry RAW brackets). An empty segment\r\n          // is inert (a leading ';' yields an indicator-only glyph, a\r\n          // trailing ';' is normalized away) but still counts as a SEPARATOR:\r\n          // the peel gate uses the raw index, so a bracket after ANY ';' sits\r\n          // in a part slot even when the base is empty (';[opts]B86' — review\r\n          // fix, 2026-07-17). #flagCompositePart keeps the filtered index\r\n          // (position among real parts). Word-level ';;' is resolved upstream\r\n          // and never reaches here.\r\n          const segments = partsString.split(';');\r\n          let partIndex = 0;\r\n          for (const [rawIndex, rawPartString] of segments.entries()) {\r\n            if (rawPartString === '') continue;\r\n            let twoPartPartString = rawPartString;\r\n            // Slot 0 is the character's own option position (its bracket was\r\n            // already stripped at the glyph level); a `>`-less bracket in a\r\n            // LATER slot is a misplaced character option: peel one warning\r\n            // per bracket, drop it, and parse the remaining code normally.\r\n            if (rawIndex > 0) {\r\n              let peeled;\r\n              while ((peeled = twoPartPartString.match(PART_SLOT_CHAR_OPTION_PATTERN)) !== null) {\r\n                parseWarnings.push({\r\n                  code: WARNING_CODES.MISPLACED_CHARACTER_OPTION,\r\n                  message: `Character option (${restorePlaceholders(peeled[1])}) ignored on \"${restorePlaceholders(peeled[3])}\": a ; part slot takes part options. Use ${restorePlaceholders(peeled[1])}>${restorePlaceholders(peeled[3])} to style the part.`,\r\n                  source: restorePlaceholders(rawPartString),\r\n                });\r\n                twoPartPartString = peeled[3];\r\n              }\r\n            }\r\n            const part = this.parsePartString(twoPartPartString, restorePlaceholders);\r\n            if (part.options) {\r\n              part.options = dropMisplacedGlobalKeys(part.options, 'part');\r\n              if (!part.options) delete part.options;\r\n            }\r\n\r\n            const definition = part.codeName?.startsWith('XTXT_')\r\n              ? (() => { const g = createTextFallbackGlyph(part.codeName.slice(5)); g.isShape = true; return g; })()\r\n              : (blissElementDefinitions[part.codeName] || {});\r\n            const codeString = definition.codeString;\r\n\r\n            if (codeString) {\r\n              if (codeString.includes('/')) {\r\n                // Word codeString at part level — cannot be expanded here.\r\n                // Keep original codeName; post-parse decomposition resolves it.\r\n              } else if (codeString.includes(';') || codeString.includes(':')\r\n                  || PART_OPTION_CODESTRING.test(codeString)\r\n                  || blissElementDefinitions[codeString]?.codeString ) {\r\n                part.parts = parseParts(definition.codeString, depth + 1);\r\n                // Keep part.codeName to preserve identifier alongside expansion\r\n              } else {\r\n                // Single-code rename to a primitive replaces codeName, which\r\n                // would lose the user-written name even under `preserve`\r\n                // (Phase 2.3b). Record it so preserve-mode serialization can\r\n                // restore it; default output keeps the resolved target.\r\n                part._aliasCodeName = part.codeName;\r\n                part.codeName = definition.codeString;\r\n              }\r\n            }\r\n\r\n            // Detect unexpanded multi-char X-codes (word text used as ; part)\r\n            if (/^X[a-zA-Z\\u00C0-\\u017F\\u0370-\\u03FF\\u0400-\\u04FF]{2,}$/.test(part.codeName)) {\r\n              part.error = `Multi-character text \"${part.codeName.slice(1)}\" is a word and cannot be composed with ;`;\r\n              part.errorCode = 'WORD_AS_PART';\r\n            }\r\n\r\n            BlissParser.#applyDefinitionMetadata(part, definition);\r\n            BlissParser.#applyEffectiveMetadata(part, definition);\r\n            BlissParser.#flagCompositePart(part, partIndex);\r\n            partIndex++;\r\n\r\n            this.#extractPositionFromOptions(part);\r\n            parts.push(part);\r\n          }\r\n          return parts;\r\n        };\r\n\r\n        glyphObj.parts = parseParts(glyphCodeString);\r\n\r\n        // Land a character-level rename recording on the parsed sole part,\r\n        // where the Phase 2.3b preserve-restore already operates; a space\r\n        // stays canonical (spaces take no custom identity). The recording\r\n        // also rides the glyph itself: a multi-part anatomy or a custom\r\n        // typed-glyph identity (glyphCode) has no part-level carrier, and\r\n        // the serializer consult (preserve-completeness chunk) restores the\r\n        // written name only for a clean instance of the definition.\r\n        if (_aliasCodeName\r\n            && !(glyphObj.parts.length === 1 && isSpaceGlyph(glyphObj.parts[0].codeName))) {\r\n          if (glyphObj.parts.length === 1\r\n              && (!glyphObj.glyphCode || builtInCodes.has(glyphObj.glyphCode))) {\r\n            glyphObj.parts[0]._aliasCodeName = _aliasCodeName;\r\n          }\r\n          glyphObj._aliasCodeName = _aliasCodeName;\r\n        }\r\n\r\n        this.#extractPositionFromOptions(glyphObj);\r\n        group.glyphs.push(glyphObj);\r\n      }\r\n\r\n      this.#extractPositionFromOptions(group);\r\n      parsedGroups.push(group);\r\n    }\r\n\r\n    // Step 4: Resolve SP→QSP for space groups before punctuation\r\n    // For implicit spaces (_fromSP): change code to QSP\r\n    // For explicit spaces: compare against default and flag _differsFromDefault\r\n    for (let i = 0; i < parsedGroups.length; i++) {\r\n      const group = parsedGroups[i];\r\n      if (group._isSpaceGroup) {\r\n        // Determine default space code for this position\r\n        const nextGroup = parsedGroups[i + 1];\r\n        const isPunctuation = nextGroup && !nextGroup._isSpaceGroup &&\r\n          (nextGroup.glyphs?.length > 0) &&\r\n          nextGroup.glyphs.every(g => g.shrinksPrecedingWordSpace === true);\r\n        const defaultCode = isPunctuation ? 'QSP' : 'TSP';\r\n\r\n        for (const glyph of group.glyphs) {\r\n          const part = glyph.parts[0];\r\n          if (part._fromSP) {\r\n            // Implicit space: resolve to default\r\n            part.codeName = defaultCode;\r\n          } else {\r\n            // Explicit space: flag if it differs from default\r\n            if (part.codeName !== defaultCode) {\r\n              part._differsFromDefault = true;\r\n            }\r\n          }\r\n          delete part._fromSP;\r\n        }\r\n      }\r\n      // Clean up internal markers\r\n      delete group._isSpaceGroup;\r\n      delete group._spaceIndex;\r\n    }\r\n\r\n    result.groups = parsedGroups;\r\n\r\n    if (parseWarnings.length) result._parseWarnings = parseWarnings;\r\n    this.#extractPositionFromOptions(result);\r\n    return result;\r\n  }\r\n\r\n  /**\r\n   * Walk a blissObj structure and expand any PARTs that have a codeName\r\n   * but no sub-parts. This supports toJSON round-trips where nested\r\n   * parts were stripped.\r\n   *\r\n   * @param {Object} blissObj - Raw parsed structure with groups/glyphs/parts\r\n   * @returns {Object} The same object, mutated with expanded parts\r\n   */\r\n  static expandParts(blissObj) {\r\n    if (!blissObj?.groups) return blissObj;\r\n    for (const group of blissObj.groups) {\r\n      if (!group.glyphs) continue;\r\n      for (const glyph of group.glyphs) {\r\n        if (!glyph.parts) continue;\r\n        for (const [partIndex, part] of glyph.parts.entries()) {\r\n          BlissParser.#expandPartRecursive(part);\r\n          BlissParser.#flagCompositePart(part, partIndex);\r\n        }\r\n      }\r\n    }\r\n    return blissObj;\r\n  }\r\n\r\n  /**\r\n   * Re-derive the COMPOSITE_AS_PART flag on every (already-expanded) part of a\r\n   * structure, in place. The flag is position-dependent (a composed alias is a\r\n   * violation only when non-leading), so it must be recomputed whenever the\r\n   * mutation API reassembles a glyph: insertPart parses a new part through an\r\n   * `H;<code>` scaffold (index 1) and may then place it at index 0, and\r\n   * removePart can shift a non-leading part to the leading slot. Unlike\r\n   * expandParts this does not expand, so it is safe to run on every rebuild.\r\n   */\r\n  static reflagCompositeParts(blissObj) {\r\n    if (!blissObj?.groups) return blissObj;\r\n    for (const group of blissObj.groups) {\r\n      if (!group.glyphs) continue;\r\n      for (const glyph of group.glyphs) {\r\n        if (!glyph.parts) continue;\r\n        for (const [partIndex, part] of glyph.parts.entries()) {\r\n          BlissParser.#flagCompositePart(part, partIndex);\r\n        }\r\n      }\r\n    }\r\n    return blissObj;\r\n  }\r\n\r\n  /**\r\n   * Flag a non-leading ;-part whose operand is a composed, unflagged alias.\r\n   * `;` is part-merge, so its operands must be PARTS: a primitive, or a flagged\r\n   * reusable definition (an indicator, a type:'glyph', or a type:'shape'). A\r\n   * character/word alias that expands to multiple parts is a higher-level unit;\r\n   * superimposing it as a part would bury its internal structure (e.g. a baked\r\n   * indicator), so it is rejected. The predicate:\r\n   * - index > 0: a leading operand is the base (and the promotion path), not a part;\r\n   * - part.parts.length > 1: a composition (a primitive or single-code rename\r\n   *   alias expands to <= 1 part and stays legal);\r\n   * - part.isIndicator !== true: a flagged indicator is a legal part (excludes a\r\n   *   built-in compound indicator such as B85 = B270;B86 or B98 = B97;B99);\r\n   * - the definition is not a flagged glyph/shape: isBlissGlyph / isShape are\r\n   *   carried by the DEFINITION, not stamped onto the part, so they are read from\r\n   *   the registry (this exempts the ~1000 built-in composite characters and\r\n   *   custom type:'glyph'/'shape' definitions, which are legal parts).\r\n   * Must run AFTER #applyDefinitionMetadata stamps part.isIndicator. The element\r\n   * layer then fails the whole character to render with a COMPOSITE_AS_PART\r\n   * warning. Shared by parseParts (DSL input) and expandParts (object input).\r\n   */\r\n  static #flagCompositePart(part, index) {\r\n    const def = blissElementDefinitions[part.codeName];\r\n    if (index > 0 && part.parts?.length > 1 && part.isIndicator !== true &&\r\n        def?.isBlissGlyph !== true && def?.isShape !== true) {\r\n      part.error = `\"${part.codeName}\" is a composition and cannot be a part; a ; part must be a primitive or a flagged glyph`;\r\n      part.errorCode = 'COMPOSITE_AS_PART';\r\n    } else if (part.errorCode === 'COMPOSITE_AS_PART') {\r\n      // The flag is position-dependent, so it is authoritative at the CURRENT\r\n      // index: clear a stale one stamped elsewhere. The mutation API parses a\r\n      // new part through an `H;<code>` scaffold (index 1) and may then insert it\r\n      // at index 0; re-evaluation here on rebuild must un-bury it.\r\n      delete part.errorCode;\r\n      delete part.error;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Apply the EFFECTIVE definition's metadata after the immediate one: a\r\n   * pure-rename bare alias (single-code codeString, no identity of its own)\r\n   * is transparent, so the resolved target's indicator-ness and anchor\r\n   * metadata must reach the part (GH #35 — indicator-ness carries through an\r\n   * alias). Runs second so explicit part options and the alias's own\r\n   * defaultOptions keep precedence over the target's. A no-op whenever no\r\n   * rename chain applies (effective === immediate).\r\n   */\r\n  static #applyEffectiveMetadata(part, definition) {\r\n    const effective = resolveEffectiveDefinition(definition, blissElementDefinitions);\r\n    if (effective !== definition) {\r\n      BlissParser.#applyDefinitionMetadata(part, effective);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Copy definition metadata (defaultOptions, indicator, anchor offsets)\r\n   * onto a part object. Shared by parseParts, #expandPartRecursive, and\r\n   * #parseCodeStringToParts to keep the logic in one place.\r\n   */\r\n  static #applyDefinitionMetadata(part, definition) {\r\n    if (definition.defaultOptions) {\r\n      part.options = { ...definition.defaultOptions, ...(part.options || {}) };\r\n    }\r\n    if (definition.isIndicator) {\r\n      part.isIndicator = true;\r\n      part.width = definition.width ?? 2;\r\n    } else if (definition.anchorOffsetY !== undefined) {\r\n      part.anchorOffsetY = definition.anchorOffsetY;\r\n    }\r\n    if (definition.anchorOffsetX !== undefined) {\r\n      part.anchorOffsetX = definition.anchorOffsetX;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Recursively expand a single part from its definition's codeString.\r\n   * Only expands if the part has a codeName, a matching definition with\r\n   * codeString, and no existing sub-parts.\r\n   */\r\n  static #expandPartRecursive(part) {\r\n    if (!part.codeName || part.parts?.length > 0) return;\r\n\r\n    const definition = blissElementDefinitions[part.codeName];\r\n    if (!definition?.codeString) return;\r\n\r\n    const codeString = definition.codeString;\r\n\r\n    // Skip word-level codeStrings (contain /) — handled by word-as-part decomposition\r\n    if (codeString.includes('/')) return;\r\n\r\n    if (codeString.includes(';') || codeString.includes(':')\r\n        || PART_OPTION_CODESTRING.test(codeString)\r\n        || blissElementDefinitions[codeString]?.codeString) {\r\n      part.parts = BlissParser.#parseCodeStringToParts(codeString);\r\n    } else {\r\n      // Same single-code rename recording as parseParts (Phase 2.3b).\r\n      part._aliasCodeName = part.codeName;\r\n      part.codeName = codeString;\r\n    }\r\n\r\n    BlissParser.#applyDefinitionMetadata(part, definition);\r\n    BlissParser.#applyEffectiveMetadata(part, definition);\r\n  }\r\n\r\n  /**\r\n   * Parse a codeString like \"HL8;HL8:0,8;VL8;VL8:8,0\" into an array\r\n   * of part objects, recursively expanding nested definitions.\r\n   */\r\n  static #parseCodeStringToParts(codeString, depth = 0) {\r\n    if (depth > MAX_RECURSION_DEPTH) throw new Error('Maximum recursion depth exceeded');\r\n    // Drop empty segments, mirroring parseParts: a definition codeString with a\r\n    // leading ';' (an empty base) must expand to an indicator-only glyph here too,\r\n    // so a custom baseless glyph round-trips identically when re-expanded from a\r\n    // toJSON-stripped nested part instead of injecting a failed empty part.\r\n    const segments = codeString.split(';').filter(s => s !== '');\r\n    const parts = [];\r\n\r\n    for (const segment of segments) {\r\n      const part = BlissParser.parsePartString(segment);\r\n\r\n      const definition = blissElementDefinitions[part.codeName] || {};\r\n      const innerCodeString = definition.codeString;\r\n\r\n      if (innerCodeString) {\r\n        if (innerCodeString.includes('/')) {\r\n          // Word codeString — skip expansion at part level\r\n        } else if (innerCodeString.includes(';') || innerCodeString.includes(':')\r\n            || PART_OPTION_CODESTRING.test(innerCodeString)\r\n            || blissElementDefinitions[innerCodeString]?.codeString) {\r\n          part.parts = BlissParser.#parseCodeStringToParts(innerCodeString, depth + 1);\r\n        } else {\r\n          // Same single-code rename recording as parseParts (Phase 2.3b).\r\n          part._aliasCodeName = part.codeName;\r\n          part.codeName = innerCodeString;\r\n        }\r\n      }\r\n\r\n      BlissParser.#applyDefinitionMetadata(part, definition);\r\n      BlissParser.#applyEffectiveMetadata(part, definition);\r\n      parts.push(part);\r\n    }\r\n\r\n    return parts;\r\n  }\r\n\r\n}\r\n","/**\r\n * This Source Code Form is subject to the terms of the Mozilla Public\r\n * License, v. 2.0. If a copy of the MPL was not distributed with this\r\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\r\n */\r\n\r\nimport { camelToKebab, WARNING_CODES } from \"./bliss-constants.js\";\r\nimport { builtInCodes, blissElementDefinitions } from \"./bliss-element-definitions.js\";\r\nimport { resolveIndicatorCodes, classifyIndicatorKind, filterToIndicators, partitionWordIndicators, resolveWordIndicatorOverlay, splitTopLevelSemicolons } from \"./indicator-utils.js\";\r\n\r\n// Shared arg guard for the mutation families: a code arg is a string or omitted.\r\nexport function assertCodeArg(method, code) {\r\n  if (code !== undefined && typeof code !== 'string') {\r\n    throw new TypeError(`${method}() requires a DSL code string`);\r\n  }\r\n}\r\n\r\n// Shared arg guard for the mutation families: an opts arg is a plain options\r\n// object or omitted. Nullish (undefined/null) means \"no options\"; a string,\r\n// number, boolean, or array is a designed error. Thrown beside assertCodeArg,\r\n// before any parse or warning-forward, so a rejected opts never leaks the\r\n// code's parse-time warnings and never leaves the builder half-mutated.\r\nexport function assertOptsArg(method, opts) {\r\n  if (opts == null) return;\r\n  if (typeof opts !== 'object' || Array.isArray(opts)) {\r\n    throw new TypeError(`${method}() options must be an object`);\r\n  }\r\n}\r\n\r\n/**\r\n * A lightweight handle that references a node in `#rawBlissObj` by identity.\r\n * Survives `#rebuild()` because it holds a direct reference to the raw node,\r\n * and resolves its current index dynamically when needed.\r\n *\r\n * Handles survive mutations to other parts of the tree. A handle only\r\n * becomes invalid when its own node is removed from the tree. Relocated\r\n * nodes (e.g. glyphs absorbed by mergeWithNext) are found via a full\r\n * tree scan and the handle's parent reference is updated automatically.\r\n */\r\nexport class ElementHandle {\r\n  #ctx;\r\n  #level;\r\n  #nodeRef;\r\n  #parentRef;\r\n  #generation;\r\n\r\n  constructor(ctx, level, nodeRef, parentRef) {\r\n    this.#ctx = ctx;\r\n    this.#level = level;\r\n    this.#nodeRef = nodeRef;\r\n    this.#parentRef = parentRef;\r\n    this.#generation = ctx.getGeneration();\r\n  }\r\n\r\n  #assertReachable() {\r\n    // Fast path: no mutations since last check\r\n    if (this.#generation === this.#ctx.getGeneration()) return;\r\n\r\n    // Parent-based lookup (fast)\r\n    const idx = this.#resolveIndex();\r\n    if (idx !== null && idx !== -1) {\r\n      this.#generation = this.#ctx.getGeneration();\r\n      return;\r\n    }\r\n\r\n    // Full tree scan (node may have moved to a different parent)\r\n    if (this.#relocate()) {\r\n      this.#generation = this.#ctx.getGeneration();\r\n      return;\r\n    }\r\n\r\n    throw new Error(\r\n      'ElementHandle references an element that has been removed.'\r\n    );\r\n  }\r\n\r\n  // Full tree scan: find this node anywhere in the raw tree.\r\n  // Updates #parentRef if the node moved to a different parent.\r\n  // Returns true if found, false if the node is gone.\r\n  #relocate() {\r\n    const raw = this.#ctx.getRaw();\r\n    const groups = raw.groups || [];\r\n\r\n    if (this.#level === 1) {\r\n      return groups.indexOf(this.#nodeRef) >= 0;\r\n    }\r\n\r\n    if (this.#level === 2) {\r\n      for (const group of groups) {\r\n        const gi = (group.glyphs || []).indexOf(this.#nodeRef);\r\n        if (gi >= 0) {\r\n          this.#parentRef = group;\r\n          return true;\r\n        }\r\n      }\r\n      return false;\r\n    }\r\n\r\n    if (this.#level === 3) {\r\n      for (const group of groups) {\r\n        for (const glyph of (group.glyphs || [])) {\r\n          const pi = (glyph.parts || []).indexOf(this.#nodeRef);\r\n          if (pi >= 0) {\r\n            this.#parentRef = { group, glyph };\r\n            return true;\r\n          }\r\n        }\r\n      }\r\n      return false;\r\n    }\r\n\r\n    return false;\r\n  }\r\n\r\n  // Update this handle's generation after a mutation it initiated,\r\n  // so chaining (e.g. handle.setOptions(...).addPart(...)) keeps working.\r\n  #syncGeneration() {\r\n    this.#generation = this.#ctx.getGeneration();\r\n  }\r\n\r\n  get level() {\r\n    return this.#level;\r\n  }\r\n\r\n  get isGroup() {\r\n    return this.#level === 1;\r\n  }\r\n\r\n  get isGlyph() {\r\n    return this.#level === 2;\r\n  }\r\n\r\n  get isPart() {\r\n    return this.#level >= 3;\r\n  }\r\n\r\n  get codeName() {\r\n    this.#assertReachable();\r\n    const node = this.#nodeRef;\r\n    if (!node) return '';\r\n\r\n    // Glyph level: the input code that produces this glyph, when it is\r\n    // actually a glyph. Empty string for composites, bare shape primitives,\r\n    // and multi-char text fallback. The presence of glyphCode IS the\r\n    // \"this is a glyph\" signal (set by the parser for B-codes, X-codes,\r\n    // single-char text fallback, and define()d 'glyph'-type aliases).\r\n    // For single-char text fallback the internal routing key 'XTXT_<char>'\r\n    // is surfaced publicly as 'X<char>'. Mirrors the rule in BlissElement.\r\n    if (this.#level === 2) {\r\n      if (typeof node.glyphCode === 'string') {\r\n        return node.glyphCode.startsWith('XTXT_')\r\n          ? 'X' + node.glyphCode.slice(5)\r\n          : node.glyphCode;\r\n      }\r\n      return '';\r\n    }\r\n\r\n    // Part level: structural lookup key. Group level: groups have no\r\n    // codeName field on their data object, so this returns ''.\r\n    // For text-fallback parts the internal routing key 'XTXT_<chars>' is\r\n    // surfaced publicly as 'X<chars>'.\r\n    const code = node.codeName ?? '';\r\n    return code.startsWith('XTXT_') ? 'X' + code.slice(5) : code;\r\n  }\r\n\r\n  get char() {\r\n    this.#assertReachable();\r\n    return this.#nodeRef?.char ?? '';\r\n  }\r\n\r\n  get isIndicator() {\r\n    this.#assertReachable();\r\n    if (this.#level !== 3) return false;\r\n    return this.#nodeRef?.isIndicator === true;\r\n  }\r\n\r\n  /**\r\n   * Indicator origin level for a part handle: 'character' for an indicator\r\n   * part, or null for a non-indicator or non-part handle. Read off the raw\r\n   * node (like isIndicator), NOT via the snapshot: a handle references a raw\r\n   * node, and a word-level overlay (`;;`) has no raw node (OQ1), so a handle\r\n   * can only ever surface 'character' here — 'word' is introspected on\r\n   * `snapshot()`. Reading the node also avoids the snapshot's positional\r\n   * lookup, which an overlay-merged head reorders and which cannot resolve a\r\n   * nested sub-part (so this never throws and always describes THIS node).\r\n   * @returns {'character'|null}\r\n   */\r\n  get indicatorLevel() {\r\n    this.#assertReachable();\r\n    if (this.#level !== 3 || this.#nodeRef?.isIndicator !== true) return null;\r\n    return 'character';\r\n  }\r\n\r\n  /**\r\n   * Indicator kind for a part handle: 'semantic' (the definition carries a\r\n   * semanticIndicator) or 'grammatical', null for a non-indicator part, a\r\n   * non-part handle, or a part whose definition cannot be resolved. Read off\r\n   * the raw node via the shared classifier (same logic as the snapshot).\r\n   * @returns {'semantic'|'grammatical'|null}\r\n   */\r\n  get indicatorKind() {\r\n    this.#assertReachable();\r\n    if (this.#level !== 3 || this.#nodeRef?.isIndicator !== true) return null;\r\n    return classifyIndicatorKind(this.#nodeRef.codeName, blissElementDefinitions);\r\n  }\r\n\r\n  // --- Dimensions (read-only, from snapshot) ---\r\n\r\n  #findSnapshot() {\r\n    this.#assertReachable();\r\n    const idx = this.#resolveIndex();\r\n    if (idx === null || idx === -1) {\r\n      throw new Error('Snapshot not found: handle index could not be resolved.');\r\n    }\r\n    const snap = this.#ctx.getSnapshot();\r\n\r\n    if (this.#level === 1) {\r\n      const groupSnap = snap.children[idx];\r\n      if (!groupSnap) throw new Error('Snapshot not found for group handle.');\r\n      return groupSnap;\r\n    }\r\n\r\n    if (this.#level === 2) {\r\n      const groupSnap = snap.children[idx.groupIndex];\r\n      if (!groupSnap) throw new Error('Snapshot not found for group in glyph handle.');\r\n      const glyphs = groupSnap.children.filter(c => c.isGlyph);\r\n      const glyphSnap = glyphs[idx.glyphIndex];\r\n      if (!glyphSnap) throw new Error('Snapshot not found for glyph handle.');\r\n      return glyphSnap;\r\n    }\r\n\r\n    if (this.#level === 3) {\r\n      const groupSnap = snap.children[idx.groupIndex];\r\n      if (!groupSnap) throw new Error('Snapshot not found for group in part handle.');\r\n      const glyphs = groupSnap.children.filter(c => c.isGlyph);\r\n      const glyphSnap = glyphs[idx.glyphIndex];\r\n      if (!glyphSnap) throw new Error('Snapshot not found for glyph in part handle.');\r\n      // Map to the snapshot part by identity, not raw position: a `;;` word\r\n      // overlay on a head injects and reorders the resolved indicator parts\r\n      // (semantic-root preservation), so the raw partIndex no longer aligns with\r\n      // the snapshot array. Both a base part and (since N14-2) a reordered\r\n      // character-level `;` indicator keep their object key through the merge, so\r\n      // match by key. The by-code match is a defensive fallback for a keyless\r\n      // node (e.g. a deep nested sub-part that #assignKeys does not key). Fall\r\n      // back to position when nothing matches (no overlay).\r\n      const node = this.#nodeRef;\r\n      const parts = glyphSnap.children;\r\n      if (node?.key != null) {\r\n        const byKey = parts.find(c => c.key === node.key);\r\n        if (byKey) return byKey;\r\n      }\r\n      if (node?.isIndicator === true) {\r\n        const byCode = parts.find(c => c.isIndicator === true && c.codeName === node.codeName);\r\n        if (byCode) return byCode;\r\n      }\r\n      return parts[idx.partIndex];\r\n    }\r\n\r\n    throw new Error(`Unsupported handle level: ${this.#level}`);\r\n  }\r\n\r\n  get x() { return this.#findSnapshot().x; }\r\n  get y() { return this.#findSnapshot().y; }\r\n  get offsetX() { return this.#findSnapshot().offsetX; }\r\n  get offsetY() { return this.#findSnapshot().offsetY; }\r\n  get width() { return this.#findSnapshot().width; }\r\n  get height() { return this.#findSnapshot().height; }\r\n  get bounds() { return this.#findSnapshot().bounds; }\r\n  get advanceX() { return this.#findSnapshot().advanceX; }\r\n  get baseWidth() { return this.#findSnapshot().baseWidth; }\r\n\r\n  // --- Identity (read-only, from snapshot) ---\r\n\r\n  get key() { return this.#findSnapshot().key; }\r\n\r\n  // --- Content flags (read-only, from snapshot) ---\r\n\r\n  get isShape() { return this.#findSnapshot().isShape; }\r\n  get isBlissGlyph() { return this.#findSnapshot().isBlissGlyph; }\r\n  get isExternalGlyph() { return this.#findSnapshot().isExternalGlyph; }\r\n  get isHeadGlyph() { return this.#findSnapshot().isHeadGlyph; }\r\n  get isSpaceGroup() { return this.#findSnapshot().isSpaceGroup; }\r\n\r\n  measure() {\r\n    const snap = this.#findSnapshot();\r\n    return Object.freeze({\r\n      x: snap.x,\r\n      y: snap.y,\r\n      offsetX: snap.offsetX,\r\n      offsetY: snap.offsetY,\r\n      width: snap.width,\r\n      height: snap.height,\r\n      bounds: snap.bounds,\r\n      advanceX: snap.advanceX,\r\n      baseWidth: snap.baseWidth,\r\n    });\r\n  }\r\n\r\n  // Resolve the current index of this node within its parent array\r\n  #resolveIndex() {\r\n    if (this.#level === 1) {\r\n      const groups = this.#ctx.getRaw().groups;\r\n      return groups.indexOf(this.#nodeRef);\r\n    }\r\n    if (this.#level === 2) {\r\n      const groupIndex = this.#ctx.getRaw().groups.indexOf(this.#parentRef);\r\n      if (groupIndex < 0) return null;\r\n      const glyphIndex = this.#parentRef.glyphs?.indexOf(this.#nodeRef) ?? -1;\r\n      if (glyphIndex < 0) return null;\r\n      return { groupIndex, glyphIndex };\r\n    }\r\n    if (this.#level === 3) {\r\n      const raw = this.#ctx.getRaw();\r\n      const groupIndex = raw.groups.indexOf(this.#parentRef.group);\r\n      if (groupIndex < 0) return null;\r\n      const glyphIndex = this.#parentRef.group.glyphs?.indexOf(this.#parentRef.glyph) ?? -1;\r\n      if (glyphIndex < 0) return null;\r\n      const partIndex = this.#parentRef.glyph.parts?.indexOf(this.#nodeRef) ?? -1;\r\n      if (partIndex < 0) return null;\r\n      return { groupIndex, glyphIndex, partIndex };\r\n    }\r\n    return null;\r\n  }\r\n\r\n  // Surface a mutation parse's warnings on the builder's persistent mutation\r\n  // channel. The parse result is otherwise discarded, which would make a\r\n  // parser-side drop (e.g. the global-only option key gate) silent when the\r\n  // string arrives through the API instead of the constructor.\r\n  #forwardParseWarnings(parsed) {\r\n    for (const warning of parsed?._parseWarnings ?? []) {\r\n      this.#ctx.addMutationWarning(warning);\r\n    }\r\n  }\r\n\r\n  // Parse a mutation arg in glyph context: exactly one glyph, no document or\r\n  // word-level artifacts (document options, a fail flag, word options, or a\r\n  // word indicator list belong above the glyph). Empty/omitted means a\r\n  // deliberate empty glyph ({parts: []}). Warnings forward only when the arg\r\n  // is accepted.\r\n  #parseGlyphArg(code) {\r\n    if (code === undefined || code.trim() === '') return { parts: [] };\r\n    const parsed = this.#ctx.parse(code);\r\n    const groupCount = parsed.groups?.length ?? 0;\r\n    if (groupCount !== 1) {\r\n      throw new Error(`Expected a single group, but code \"${code}\" produced ${groupCount} groups`);\r\n    }\r\n    // An empty \"||\" prefix sets no options and stays plain content.\r\n    if (Object.keys(parsed.options ?? {}).length > 0) {\r\n      throw new Error(`Code \"${code}\" carries document-level options (\"[opts]||\"). Set document options on the builder input, or style the glyph itself (\"[opts]CODE\" or the opts parameter)`);\r\n    }\r\n    const group = parsed.groups[0];\r\n    if (group.errorCode !== undefined) {\r\n      throw new Error(`Code \"${code}\" is not a single valid glyph (it fails as a word: ${group.errorCode}). Fix the code, or use addGroup() to work with whole words`);\r\n    }\r\n    if (group.options) {\r\n      throw new Error(`Code \"${code}\" carries word-level options (\"[opts]|\"). Style the glyph itself (\"[opts]CODE\" or the opts parameter), or use addGroup() for word content`);\r\n    }\r\n    if (group.wordIndicators) {\r\n      throw new Error(`Code \"${code}\" carries a word-level indicator list (\";;\"). Use applyIndicators() on the word, or addGroup() for word content`);\r\n    }\r\n    const glyphs = group.glyphs ?? [];\r\n    if (glyphs.length !== 1) {\r\n      throw new Error(`Expected a single glyph, but code \"${code}\" produced ${glyphs.length} glyphs`);\r\n    }\r\n    this.#forwardParseWarnings(parsed);\r\n    return glyphs[0];\r\n  }\r\n\r\n  // Parse a mutation arg in part context: exactly one part. A word\r\n  // (multi-glyph code) keeps the existing WORD_AS_PART error-part contract.\r\n  // Empty/omitted throws: a part references a shape and has no empty form\r\n  // (unlike group/glyph containers). Warnings forward only when the arg is\r\n  // accepted.\r\n  #parsePartArg(code) {\r\n    if (code === undefined || code.trim() === '') {\r\n      throw new Error('Expected a single part, but code \"\" produced none. '\r\n        + 'A part is a reference to a shape and cannot be empty; '\r\n        + 'to reserve an empty slot, use addGlyph(\"\") for an empty glyph.');\r\n    }\r\n    const rawParsed = this.#ctx.parse(code);\r\n    const groupCount = rawParsed.groups?.length ?? 0;\r\n    if (groupCount !== 1) {\r\n      throw new Error(`Expected parts within a single group, but code \"${code}\" produced ${groupCount} groups`);\r\n    }\r\n    const rawGroup = rawParsed.groups[0];\r\n    if (!rawGroup.glyphs || rawGroup.glyphs.length === 0) {\r\n      throw new Error(`Expected a single part, but code \"${code}\" produced no glyphs`);\r\n    }\r\n    if (rawGroup.glyphs.length > 1) {\r\n      // Multi-glyph code is a word: words cannot be composed with ;\r\n      return { codeName: code, error: `\"${code}\" is a word and cannot be composed with ;`, errorCode: 'WORD_AS_PART' };\r\n    }\r\n    // A single-glyph arg must not smuggle artifacts from above the part\r\n    // level: the helper embedding below would silently launder them away\r\n    // (document/word options, a word indicator list, a fail flag, or a head\r\n    // marker all describe something a part cannot carry). Words take the\r\n    // WORD_AS_PART route above instead, artifacts and all.\r\n    if (Object.keys(rawParsed.options ?? {}).length > 0) {\r\n      throw new Error(`Code \"${code}\" carries document-level options (\"[opts]||\"). Set document options on the builder input, or style the part itself (\"[opts]>CODE\" or the opts parameter)`);\r\n    }\r\n    if (rawGroup.options) {\r\n      throw new Error(`Code \"${code}\" carries word-level options (\"[opts]|\"). Style the part itself (\"[opts]>CODE\" or the opts parameter), or use addGroup() for word content`);\r\n    }\r\n    if (rawGroup.wordIndicators) {\r\n      throw new Error(`Code \"${code}\" carries a word-level indicator list (\";;\"). Use applyIndicators() on the word, or addGroup() for word content`);\r\n    }\r\n    if (rawGroup.errorCode !== undefined) {\r\n      throw new Error(`Code \"${code}\" is not a single valid part (it fails as a word: ${rawGroup.errorCode}). Fix the code, or use addGroup() to work with whole words`);\r\n    }\r\n    if (rawGroup.glyphs[0].isHeadGlyph) {\r\n      throw new Error(`Code \"${code}\" carries a head marker (\"^\"). A head marker belongs on a character: pass it to the glyph methods (\"CODE^\"), or use addGroup() for word content`);\r\n    }\r\n    // Single glyph: helper-glyph embedding for proper part-level expansion.\r\n    // Forward only THIS parse's warnings (the raw parse above ran the same\r\n    // gates; forwarding both would double-warn).\r\n    const parsed = this.#ctx.parse(`H;${code}`);\r\n    const glyph = parsed.groups?.[0]?.glyphs?.[0];\r\n    const parts = glyph?.parts?.length >= 2\r\n      ? glyph.parts.slice(1)\r\n      : (rawGroup.glyphs[0].parts || []);\r\n    if (parts.length !== 1) {\r\n      throw new Error(`Expected a single part, but code \"${code}\" produced ${parts.length} parts`);\r\n    }\r\n    this.#forwardParseWarnings(parsed);\r\n    return parts[0];\r\n  }\r\n\r\n  // Apply defaults/overrides merge to a node's options.\r\n  // Accepts { defaults, overrides } or flat options (treated as overrides).\r\n  #applyDefaultsOverrides(node, opts) {\r\n    if (!opts) return;\r\n    let defaults, overrides;\r\n    if ('defaults' in opts || 'overrides' in opts) {\r\n      ({ defaults, overrides } = opts);\r\n    } else {\r\n      overrides = opts;\r\n    }\r\n    if (!defaults && !overrides) return;\r\n    const rawDefaults = defaults ? this.#ctx.toRaw(defaults) : {};\r\n    const rawOverrides = overrides ? this.#ctx.toRaw(overrides) : {};\r\n    const merged = { ...rawDefaults, ...(node.options ?? {}), ...rawOverrides };\r\n    // An empty opts (e.g. {}) resolves to no keys: don't stamp a bare\r\n    // options:{} onto the node, which would be toJSON noise.\r\n    if (Object.keys(merged).length > 0) node.options = merged;\r\n  }\r\n\r\n  // --- Navigation ---\r\n\r\n  /**\r\n   * Returns the head glyph handle within this group.\r\n   * Uses the composition snapshot to determine which glyph is the head.\r\n   * @returns {ElementHandle|null}\r\n   */\r\n  headGlyph() {\r\n    this.#assertReachable();\r\n    if (this.#level !== 1) return null;\r\n    const group = this.#nodeRef;\r\n    if (!group?.glyphs?.length) return null;\r\n\r\n    const groupIndex = this.#ctx.getRaw().groups.indexOf(this.#nodeRef);\r\n    if (groupIndex < 0) return null;\r\n\r\n    // Find the head glyph via the snapshot tree\r\n    const snap = this.#ctx.getSnapshot();\r\n    const groupSnap = snap.children[groupIndex];\r\n    if (!groupSnap) return null;\r\n\r\n    const glyphs = groupSnap.children.filter(c => c.isGlyph);\r\n    const headIndex = glyphs.findIndex(g => g.isHeadGlyph);\r\n    const index = headIndex >= 0 ? headIndex : 0;\r\n\r\n    if (index >= group.glyphs.length) return null;\r\n    return new ElementHandle(this.#ctx, 2, group.glyphs[index], group);\r\n  }\r\n\r\n  glyph(index) {\r\n    this.#assertReachable();\r\n    if (this.#level !== 1) return null;\r\n    const group = this.#nodeRef;\r\n    if (!group?.glyphs?.length) return null;\r\n    if (index < 0) index = group.glyphs.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= group.glyphs.length) return null;\r\n    return new ElementHandle(this.#ctx, 2, group.glyphs[index], group);\r\n  }\r\n\r\n  part(index) {\r\n    this.#assertReachable();\r\n    if (this.#level === 2) {\r\n      const glyph = this.#nodeRef;\r\n      if (!glyph?.parts?.length) return null;\r\n      if (index < 0) index = glyph.parts.length + index;\r\n      if (!Number.isInteger(index) || index < 0 || index >= glyph.parts.length) return null;\r\n      return new ElementHandle(this.#ctx, 3, glyph.parts[index], {\r\n        group: this.#parentRef,\r\n        glyph\r\n      });\r\n    }\r\n    if (this.#level === 3) {\r\n      const part = this.#nodeRef;\r\n      if (!part?.parts?.length) return null;\r\n      if (index < 0) index = part.parts.length + index;\r\n      if (!Number.isInteger(index) || index < 0 || index >= part.parts.length) return null;\r\n      return new ElementHandle(this.#ctx, 3, part.parts[index], this.#parentRef);\r\n    }\r\n    return null;\r\n  }\r\n\r\n  // --- Mutation: add/insert ---\r\n\r\n  // A fail-flagged word (malformed `;;` sets group.errorCode) is TERMINAL: it\r\n  // renders as a single placeholder and toString replays its stored\r\n  // errorSource verbatim, so a content mutation inside it would change the\r\n  // live tree while the serialized form stays frozen (toJSON/toString\r\n  // divergence, round-2 external review F5). Every content mutator no-ops on\r\n  // it — SILENTLY, matching the shipped splitAt/mergeWithNext terminal arms —\r\n  // whether it targets the group handle or a child glyph/part handle inside.\r\n  // Recovery: replaceGroup, or removing the whole word (group detach/remove).\r\n  // Group-level setOptions/removeOptions are exempt: group options serialize\r\n  // OUTSIDE the error source (`[opts]|errorSource`) and round-trip.\r\n  #inFailFlaggedGroup() {\r\n    if (this.#level === 1) return this.#nodeRef?.errorCode !== undefined;\r\n    if (this.#level === 2) return this.#parentRef?.errorCode !== undefined;\r\n    if (this.#level === 3) return this.#parentRef?.group?.errorCode !== undefined;\r\n    return false;\r\n  }\r\n\r\n  addGlyph(code, opts) {\r\n    this.#assertReachable();\r\n    if (this.#level !== 1) return this;\r\n    const group = this.#nodeRef;\r\n    if (!group) return this;\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup. Gated here too\r\n    // (not only in the insertGlyph delegate) so the silent no-op wins over\r\n    // the argument guard below, per the validation ordering rule.\r\n    if (group.errorCode) return this;\r\n    assertCodeArg('addGlyph', code);\r\n    assertOptsArg('addGlyph', opts);\r\n    return this.insertGlyph(group.glyphs?.length ?? 0, code, opts);\r\n  }\r\n\r\n  insertGlyph(index, code, opts) {\r\n    this.#assertReachable();\r\n    if (this.#level !== 1) return this;\r\n    const group = this.#nodeRef;\r\n    if (!group) return this;\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup.\r\n    if (group.errorCode) return this;\r\n    assertCodeArg('insertGlyph', code);\r\n    assertOptsArg('insertGlyph', opts);\r\n    if (!Number.isInteger(index)) return this;\r\n    const newGlyph = this.#parseGlyphArg(code);\r\n    this.#applyDefaultsOverrides(newGlyph, opts);\r\n    if (!group.glyphs) group.glyphs = [];\r\n    group.glyphs.splice(index, 0, newGlyph);\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  // A glyph recomposed by part mutation is no longer the single code it was\r\n  // parsed from, so drop its glyph-level identity and let toString() serialize\r\n  // the individual parts instead of the stale code. No-op on a glyph that never\r\n  // had identity (an inline composite carries no glyphCode to begin with).\r\n  #clearGlyphIdentity(glyph) {\r\n    delete glyph.isBlissGlyph;\r\n    delete glyph.codeName;\r\n    delete glyph.glyphCode;\r\n  }\r\n\r\n  // Level-1 addPart/insertPart on a group with zero glyphs: create a carrier\r\n  // glyph so the part is not silently dropped (mirrors the empty-builder\r\n  // routing one level down). Parses BEFORE any state change so a rejected\r\n  // arg leaves the group untouched.\r\n  #fillEmptyGroupWithPart(group, method, code, opts) {\r\n    assertCodeArg(method, code);\r\n    assertOptsArg(method, opts);\r\n    const newPart = this.#parsePartArg(code);\r\n    this.#applyDefaultsOverrides(newPart, opts);\r\n    group.glyphs = [{ parts: [newPart] }];\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  addPart(code, opts) {\r\n    this.#assertReachable();\r\n    // Group level: delegate to last glyph\r\n    if (this.#level === 1) {\r\n      const group = this.#nodeRef;\r\n      if (!group) return this;\r\n      // Terminal fail-flagged word: see #inFailFlaggedGroup.\r\n      if (group.errorCode) return this;\r\n      if (!group.glyphs?.length) {\r\n        return this.#fillEmptyGroupWithPart(group, 'addPart', code, opts);\r\n      }\r\n      const lastGlyph = group.glyphs[group.glyphs.length - 1];\r\n      const glyphHandle = new ElementHandle(this.#ctx, 2, lastGlyph, group);\r\n      glyphHandle.addPart(code, opts);\r\n      this.#syncGeneration();\r\n      return this;\r\n    }\r\n    if (this.#level !== 2) return this;\r\n    const glyph = this.#nodeRef;\r\n    if (!glyph) return this;\r\n    // Terminal fail-flagged word: gated here too (not only in the insertPart\r\n    // delegate) so the silent no-op wins over the argument guard below, per\r\n    // the validation ordering rule.\r\n    if (this.#inFailFlaggedGroup()) return this;\r\n    assertCodeArg('addPart', code);\r\n    assertOptsArg('addPart', opts);\r\n    return this.insertPart(glyph.parts?.length ?? 0, code, opts);\r\n  }\r\n\r\n  insertPart(index, code, opts) {\r\n    this.#assertReachable();\r\n    // Group level: delegate to last glyph\r\n    if (this.#level === 1) {\r\n      const group = this.#nodeRef;\r\n      if (!group) return this;\r\n      // Terminal fail-flagged word: see #inFailFlaggedGroup.\r\n      if (group.errorCode) return this;\r\n      if (!group.glyphs?.length) {\r\n        // The index is irrelevant for a first part.\r\n        return this.#fillEmptyGroupWithPart(group, 'insertPart', code, opts);\r\n      }\r\n      const lastGlyph = group.glyphs[group.glyphs.length - 1];\r\n      const glyphHandle = new ElementHandle(this.#ctx, 2, lastGlyph, group);\r\n      glyphHandle.insertPart(index, code, opts);\r\n      this.#syncGeneration();\r\n      return this;\r\n    }\r\n    if (this.#level !== 2) return this;\r\n    const glyph = this.#nodeRef;\r\n    if (!glyph) return this;\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup. Defense-in-depth\r\n    // for the group-handle delegation forms, which gate at level 1 already.\r\n    if (this.#inFailFlaggedGroup()) return this;\r\n    assertCodeArg('insertPart', code);\r\n    assertOptsArg('insertPart', opts);\r\n    if (!Number.isInteger(index)) return this;\r\n    const newPart = this.#parsePartArg(code);\r\n    this.#applyDefaultsOverrides(newPart, opts);\r\n    if (!glyph.parts) glyph.parts = [];\r\n    glyph.parts.splice(index, 0, newPart);\r\n    this.#clearGlyphIdentity(glyph);\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  // --- Mutation: detach (plain splice, no cascade) ---\r\n\r\n  /**\r\n   * Removes this node from the tree without cascading deletions to its parent.\r\n   * Terminal mutation: returns undefined (not chainable), since the handle's\r\n   * node is no longer reachable after detach.\r\n   * @returns {undefined}\r\n   */\r\n  detach() {\r\n    this.#assertReachable();\r\n    // Terminal fail-flagged word: child content cannot be detached (see\r\n    // #inFailFlaggedGroup); detaching the WHOLE word (level 1) stays allowed —\r\n    // removal of the unit is consistent with its frozen serialization.\r\n    if (this.#level !== 1 && this.#inFailFlaggedGroup()) return undefined;\r\n\r\n    if (this.#level === 3) {\r\n      const glyph = this.#parentRef.glyph;\r\n      if (!glyph?.parts) return undefined;\r\n      const partIndex = glyph.parts.indexOf(this.#nodeRef);\r\n      if (partIndex < 0) return undefined;\r\n      glyph.parts.splice(partIndex, 1);\r\n      // A glyph recomposed by part removal is no longer the single code it was\r\n      // parsed from; drop its cached identity so an emptied glyph does not\r\n      // re-emit a phantom codeName from toString (mirrors insertPart). N16.\r\n      this.#clearGlyphIdentity(glyph);\r\n      // An EMPTIED glyph serializes to nothing, so a head designation on it\r\n      // would live only in toJSON while toString dropped it (round-2 external\r\n      // review F4): the designation dies visibly with its glyph's content.\r\n      // detach is the only mutation that leaves an empty glyph in the tree\r\n      // (remove/removePart cascade the whole glyph away).\r\n      if (glyph.parts.length === 0) delete glyph.isHeadGlyph;\r\n      this.#ctx.rebuild();\r\n      return undefined;\r\n    }\r\n\r\n    if (this.#level === 2) {\r\n      const group = this.#parentRef;\r\n      if (!group?.glyphs) return undefined;\r\n      const glyphIndex = group.glyphs.indexOf(this.#nodeRef);\r\n      if (glyphIndex < 0) return undefined;\r\n      group.glyphs.splice(glyphIndex, 1);\r\n      this.#ctx.rebuild();\r\n      return undefined;\r\n    }\r\n\r\n    if (this.#level === 1) {\r\n      const groups = this.#ctx.getRaw().groups;\r\n      const groupIndex = groups.indexOf(this.#nodeRef);\r\n      if (groupIndex < 0) return undefined;\r\n      groups.splice(groupIndex, 1);\r\n      this.#ctx.rebuild();\r\n      return undefined;\r\n    }\r\n\r\n    return undefined;\r\n  }\r\n\r\n  // --- Mutation: remove ---\r\n\r\n  /**\r\n   * Removes this node and cascades cleanup upward (e.g. removing the last\r\n   * part also removes its glyph; removing the last glyph also removes its\r\n   * group and surrounding spaces). Terminal mutation: returns undefined\r\n   * (not chainable), since the handle's node is no longer reachable.\r\n   * @returns {undefined}\r\n   */\r\n  remove() {\r\n    this.#assertReachable();\r\n    // Terminal fail-flagged word: mirrors detach — child removal no-ops,\r\n    // whole-word removal (level 1) stays allowed.\r\n    if (this.#level !== 1 && this.#inFailFlaggedGroup()) return undefined;\r\n    const raw = this.#ctx.getRaw();\r\n    const groups = raw.groups;\r\n\r\n    if (this.#level === 3) {\r\n      const idx = this.#resolveIndex();\r\n      if (!idx) return undefined;\r\n      const glyph = this.#parentRef.glyph;\r\n      if (!glyph?.parts) return undefined;\r\n      const partIndex = glyph.parts.indexOf(this.#nodeRef);\r\n      if (partIndex < 0) return undefined;\r\n      glyph.parts.splice(partIndex, 1);\r\n      // Cascade: last part → remove glyph\r\n      if (glyph.parts.length === 0) {\r\n        return this.#removeGlyphFromGroup(groups, this.#parentRef.group, glyph);\r\n      }\r\n      this.#ctx.rebuild();\r\n      return undefined;\r\n    }\r\n\r\n    if (this.#level === 2) {\r\n      const group = this.#parentRef;\r\n      return this.#removeGlyphFromGroup(groups, group, this.#nodeRef);\r\n    }\r\n\r\n    if (this.#level === 1) {\r\n      const groupIndex = groups.indexOf(this.#nodeRef);\r\n      if (groupIndex < 0) return undefined;\r\n      this.#ctx.removeGlyphGroup(raw, groupIndex);\r\n      this.#ctx.rebuild();\r\n      return undefined;\r\n    }\r\n\r\n    return undefined;\r\n  }\r\n\r\n  removeGlyph(index) {\r\n    this.#assertReachable();\r\n    if (this.#level !== 1) return this;\r\n    const group = this.#nodeRef;\r\n    if (!group?.glyphs?.length) return this;\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup.\r\n    if (group.errorCode) return this;\r\n    if (index < 0) index = group.glyphs.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= group.glyphs.length) return this;\r\n    group.glyphs.splice(index, 1);\r\n    if (group.glyphs.length === 0) {\r\n      const raw = this.#ctx.getRaw();\r\n      const groupIndex = raw.groups.indexOf(group);\r\n      if (groupIndex >= 0) {\r\n        this.#ctx.removeGlyphGroup(raw, groupIndex);\r\n      }\r\n    }\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  removePart(index) {\r\n    this.#assertReachable();\r\n    if (this.#level !== 2) return this;\r\n    const glyph = this.#nodeRef;\r\n    if (!glyph?.parts?.length) return this;\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup.\r\n    if (this.#inFailFlaggedGroup()) return this;\r\n    if (index < 0) index = glyph.parts.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= glyph.parts.length) return this;\r\n    glyph.parts.splice(index, 1);\r\n    if (glyph.parts.length === 0) {\r\n      this.#removeGlyphFromGroup(\r\n        this.#ctx.getRaw().groups, this.#parentRef, glyph\r\n      );\r\n      this.#syncGeneration();\r\n      return this;\r\n    }\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  #removeGlyphFromGroup(groups, group, glyph) {\r\n    const raw = this.#ctx.getRaw();\r\n    if (!group?.glyphs) return undefined;\r\n    const glyphIndex = group.glyphs.indexOf(glyph);\r\n    if (glyphIndex < 0) return undefined;\r\n    group.glyphs.splice(glyphIndex, 1);\r\n    // Cascade: last glyph → remove group + space\r\n    if (group.glyphs.length === 0) {\r\n      const groupIndex = groups.indexOf(group);\r\n      if (groupIndex >= 0) {\r\n        this.#ctx.removeGlyphGroup(raw, groupIndex);\r\n      }\r\n    }\r\n    this.#ctx.rebuild();\r\n    return undefined;\r\n  }\r\n\r\n  // --- Mutation: parent-centric replace ---\r\n\r\n  replaceGlyph(index, code, opts) {\r\n    this.#assertReachable();\r\n    if (this.#level !== 1) return this;\r\n    const group = this.#nodeRef;\r\n    if (!group) return this;\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup.\r\n    if (group.errorCode) return this;\r\n    assertCodeArg('replaceGlyph', code);\r\n    assertOptsArg('replaceGlyph', opts);\r\n    if (!group.glyphs?.length) return this;\r\n    if (index < 0) index = group.glyphs.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= group.glyphs.length) return this;\r\n    const newGlyph = this.#parseGlyphArg(code);\r\n    this.#applyDefaultsOverrides(newGlyph, opts);\r\n    group.glyphs[index] = newGlyph;\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  replacePart(index, code, opts) {\r\n    this.#assertReachable();\r\n    if (this.#level !== 2) return this;\r\n    const glyph = this.#nodeRef;\r\n    if (!glyph) return this;\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup.\r\n    if (this.#inFailFlaggedGroup()) return this;\r\n    assertCodeArg('replacePart', code);\r\n    assertOptsArg('replacePart', opts);\r\n    if (!glyph.parts?.length) return this;\r\n    if (index < 0) index = glyph.parts.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= glyph.parts.length) return this;\r\n    const newPart = this.#parsePartArg(code);\r\n    this.#applyDefaultsOverrides(newPart, opts);\r\n    glyph.parts[index] = newPart;\r\n    this.#clearGlyphIdentity(glyph);\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  // --- Mutation: self-centric replace ---\r\n\r\n  replace(code, opts) {\r\n    this.#assertReachable();\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup (levels 2/3 only;\r\n    // there is no level-1 replace arm — replaceGroup is the recovery).\r\n    if (this.#inFailFlaggedGroup()) return this;\r\n    if (this.#level === 2) {\r\n      assertCodeArg('replace', code);\r\n      assertOptsArg('replace', opts);\r\n      const group = this.#parentRef;\r\n      if (!group?.glyphs) return this;\r\n      const glyphIndex = group.glyphs.indexOf(this.#nodeRef);\r\n      if (glyphIndex < 0) return this;\r\n      const newGlyph = this.#parseGlyphArg(code);\r\n      this.#applyDefaultsOverrides(newGlyph, opts);\r\n      group.glyphs[glyphIndex] = newGlyph;\r\n      this.#nodeRef = newGlyph;\r\n      this.#ctx.rebuild();\r\n      this.#syncGeneration();\r\n      return this;\r\n    }\r\n\r\n    if (this.#level === 3) {\r\n      assertCodeArg('replace', code);\r\n      assertOptsArg('replace', opts);\r\n      const glyph = this.#parentRef.glyph;\r\n      if (!glyph?.parts) return this;\r\n      const partIndex = glyph.parts.indexOf(this.#nodeRef);\r\n      if (partIndex < 0) return this;\r\n      const newPart = this.#parsePartArg(code);\r\n      this.#applyDefaultsOverrides(newPart, opts);\r\n      glyph.parts[partIndex] = newPart;\r\n      this.#clearGlyphIdentity(glyph);\r\n      this.#nodeRef = newPart;\r\n      this.#ctx.rebuild();\r\n      this.#syncGeneration();\r\n      return this;\r\n    }\r\n\r\n    return this;\r\n  }\r\n\r\n  // --- Mutation: indicators ---\r\n\r\n  applyIndicators(code, opts) {\r\n    this.#assertReachable();\r\n    // A non-string, non-nullish code is a type error, not DSL content. Without\r\n    // this guard it would tokenize to zero codes and silently store the\r\n    // render-significant empty overlay (external review F2).\r\n    if (code !== undefined && code !== null && typeof code !== 'string') {\r\n      throw new TypeError('applyIndicators() code must be a string (or omitted for the empty indicator set).');\r\n    }\r\n    // An empty request (no argument, '', or whitespace-only) is the deliberate\r\n    // spelling of the EMPTY indicator set, not an error: a group handle stores\r\n    // the empty `;;` overlay (hides the head's character-level indicators,\r\n    // adds none); a glyph handle gets the same state effect as\r\n    // clearIndicators() (a bare base stays a harmless no-op, like a trailing\r\n    // `;` in the DSL). stripSemantic lives on apply only, so\r\n    // applyIndicators('', { stripSemantic: true }) is the strip spelling\r\n    // (formerly clearIndicators({ stripSemantic: true })).\r\n    const normalized = (code === undefined || code === null || code.trim() === '') ? '' : code;\r\n    // Group handle (level 1): word-level overlay channel. Glyph handle\r\n    // (level 2): character-level parts. Other levels: no-op via the level-2 path.\r\n    if (this.#level === 1) return this.#applyOrClearWordIndicators(normalized, opts);\r\n    return this.#applyOrClearIndicators(normalized, opts);\r\n  }\r\n\r\n  clearIndicators(opts) {\r\n    this.#assertReachable();\r\n    // Clear is the PURE UNDO: it only removes (the `;;` overlay on a group\r\n    // handle, baked grammatical indicators on a glyph handle) and takes no\r\n    // stripSemantic (both #applyOrClear* paths force it off for a clear).\r\n    if (this.#level === 1) return this.#applyOrClearWordIndicators(null, opts);\r\n    return this.#applyOrClearIndicators(null, opts);\r\n  }\r\n\r\n  // `suppressNoop` is set by the flatten-clear delegation when it has already\r\n  // removed a `;;` overlay: that removal is the real effect, so a char-level\r\n  // no-op here is not an overall no-op and must not be reported. It is a private\r\n  // positional argument (not an opts key) so it is unreachable from the public\r\n  // applyIndicators/clearIndicators surface.\r\n  #applyOrClearIndicators(code, opts, suppressNoop = false) {\r\n    if (this.#level !== 2) return this;\r\n    const glyph = this.#nodeRef;\r\n    if (!glyph) return this;\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup. (The flatten\r\n    // delegation cannot reach here for a flagged group — the word-level path\r\n    // gates first.)\r\n    if (this.#inFailFlaggedGroup()) return this;\r\n    if (!glyph.parts) glyph.parts = [];\r\n\r\n    const definitions = this.#ctx.getDefinitions();\r\n    // stripSemantic is an apply-only option: a clear (code === null) is the\r\n    // pure undo and never strips the semantic root.\r\n    const stripSemantic = code !== null && opts?.stripSemantic === true;\r\n    const targetCode = glyph.codeName || glyph.parts[0]?.codeName || 'unknown';\r\n\r\n    // A space glyph is not a base for indicators. Under the i>0 rule its single\r\n    // part would otherwise classify as a base, so carve it out and keep the\r\n    // no-op + warning (R15 Task 5).\r\n    if (this.#ctx.isRawSpaceGroup(this.#parentRef)) {\r\n      if (!suppressNoop) {\r\n        const verb = code === null ? 'clearIndicators()' : `applyIndicators('${code}')`;\r\n        // `||` deliberately (not `??`): the empty apply's '' must fall back to\r\n        // the target code, never become an empty source (external review F4).\r\n        this.#warnIndicatorNoop(\r\n          `${verb} had no effect: the target glyph '${targetCode}' is a space.`,\r\n          code || targetCode,\r\n        );\r\n      }\r\n      return this;\r\n    }\r\n\r\n    // Classify parts: the first part is always the base (even when it is itself\r\n    // an indicator), so scan for the first TRAILING indicator from index 1.\r\n    // Mirrors mergeWordIndicatorsOntoHead, so a lone indicator or an empty glyph\r\n    // carries a further indicator rather than no-opping (the atypical-base\r\n    // contract, R15 Task 5).\r\n    const firstIndicatorIndex = glyph.parts.findIndex((p, i) => i > 0 && p.isIndicator === true);\r\n\r\n    let baseParts, indicatorParts;\r\n    if (firstIndicatorIndex === -1) {\r\n      baseParts = glyph.parts;\r\n      indicatorParts = [];\r\n    } else {\r\n      baseParts = glyph.parts.slice(0, firstIndicatorIndex);\r\n      indicatorParts = glyph.parts.slice(firstIndicatorIndex);\r\n    }\r\n\r\n    // Validate pattern: no non-indicators after the first indicator\r\n    const isValidPattern = indicatorParts.every(p => p.isIndicator === true);\r\n    if (!isValidPattern) {\r\n      if (!suppressNoop) {\r\n        const verb = code === null ? 'clearIndicators()' : `applyIndicators('${code}')`;\r\n        // `||` deliberately (not `??`): see the space-glyph arm above (F4).\r\n        this.#warnIndicatorNoop(\r\n          `${verb} had no effect: the target glyph '${targetCode}' has a non-indicator part after an indicator part (an invalid indicator pattern).`,\r\n          code || targetCode,\r\n        );\r\n      }\r\n      return this;\r\n    }\r\n\r\n    // Extract existing indicator codes for semantic analysis\r\n    const existingIndCodes = indicatorParts.map(p => p.codeName);\r\n\r\n    // Determine the final indicator code list (replace-all with semantic\r\n    // preservation; clearIndicators passes no new codes), then parse each\r\n    // into a proper part node with metadata.\r\n    const requestedCodes = code !== null ? splitTopLevelSemicolons(code) : [];\r\n\r\n    // A character-level indicator slot takes indicators only (the same rule,\r\n    // one level down, as the group `;;` overlay path — shared classifier for\r\n    // parity). Each rejected code warns individually on the persistent\r\n    // mutation channel; this REPLACES the old single \"applied no indicator\"\r\n    // no-op arm (strictly more informative: it names each offending code even\r\n    // when the valid subset makes the call a real mutation). A code carrying\r\n    // word structure (a top-level `/`, hidden from the bare-code classifier\r\n    // behind a coordinate suffix) can never be a single indicator part, so it\r\n    // is rejected too. The surviving codes are then PARSED BEFORE the glyph is\r\n    // touched: a code whose decoration fails to parse (e.g. `B81:bad`) yields\r\n    // only a codeName-less error part, so it is excluded — the forwarded parse\r\n    // warnings (MALFORMED_COORDINATES etc.) are its visibility channel. An\r\n    // apply left with NOTHING attachable REFUSES: explicit failed content is\r\n    // not deliberate emptiness (that spelling is applyIndicators('')), so the\r\n    // existing indicators stay untouched and nothing strips as a side effect\r\n    // (parity with the group overlay's null-resolver refuse arm; round-2\r\n    // external review F2).\r\n    let attachableEntries = [];\r\n    if (code !== null && requestedCodes.length > 0) {\r\n      const { valid, rejected } = partitionWordIndicators(requestedCodes, definitions);\r\n      for (const { code: badCode, reason } of rejected) {\r\n        this.#ctx.addMutationWarning(reason === 'word-structure'\r\n          ? {\r\n              code: WARNING_CODES.MISPLACED_CHARACTER_INDICATOR,\r\n              message: `applyIndicators('${code}'): \"${badCode}\" spans multiple characters (it contains a top-level /); a character-level indicator code must be a single indicator. It cannot be applied.`,\r\n              source: badCode,\r\n            }\r\n          : reason === 'non-indicator'\r\n            ? {\r\n                code: WARNING_CODES.NON_INDICATOR_AS_CHARACTER_INDICATOR,\r\n                message: `applyIndicators('${code}'): \"${badCode}\" is not an indicator; it cannot be applied. A character-level indicator code must be an indicator (e.g. B81).`,\r\n                source: badCode,\r\n              }\r\n            : {\r\n                code: WARNING_CODES.UNKNOWN_CODE,\r\n                message: `applyIndicators('${code}'): unknown indicator code \"${badCode}\"; it cannot be applied.`,\r\n                source: badCode,\r\n              });\r\n      }\r\n      for (const validCode of valid) {\r\n        const parsed = this.#ctx.parse(validCode);\r\n        this.#forwardParseWarnings(parsed);\r\n        const glyphs = parsed.groups?.length === 1 ? parsed.groups[0].glyphs : null;\r\n        const parts = glyphs?.length === 1 ? glyphs[0].parts : null;\r\n        if (parts?.length > 0 && parts.every(p => p.isIndicator === true)) {\r\n          attachableEntries.push({ code: validCode, parts });\r\n        } else {\r\n          // An error part's warning used to surface at render, AFTER it was\r\n          // already inserted; the part is now never inserted, so its parse\r\n          // error (e.g. MALFORMED_COORDINATES) is re-emitted on the mutation\r\n          // channel as the excluded code's visibility.\r\n          const errorPart = parts?.find(p => p.errorCode);\r\n          const detail = errorPart?.error ? ` (${errorPart.error})` : '';\r\n          this.#ctx.addMutationWarning({\r\n            code: errorPart?.errorCode ?? WARNING_CODES.UNKNOWN_CODE,\r\n            message: `applyIndicators('${code}'): \"${validCode}\" cannot be applied as an indicator part${detail}.`,\r\n            source: validCode,\r\n          });\r\n        }\r\n      }\r\n      if (attachableEntries.length === 0) return this;\r\n    }\r\n\r\n    const finalCodes = resolveIndicatorCodes(existingIndCodes, attachableEntries.map(e => e.code), { stripSemantic }, definitions);\r\n\r\n    // D4: a clear with no indicator parts had nothing to remove. (A clear that\r\n    // preserves a semantic root is a documented no-op and is intentionally not\r\n    // warned. The apply-side \"applied no indicator\" arm is gone: the per-code\r\n    // validation warnings above cover every rejected apply code.)\r\n    if (!suppressNoop) {\r\n      if (code === null && indicatorParts.length === 0) {\r\n        this.#warnIndicatorNoop(\r\n          `clearIndicators() had no effect: the target glyph '${targetCode}' has no indicators to clear.`,\r\n          targetCode,\r\n        );\r\n      }\r\n    }\r\n\r\n    // Assemble the new indicator parts. A requested code reuses the part\r\n    // nodes from its validation parse above (parsing again would forward its\r\n    // warnings twice); a code the resolver added back (the preserved semantic\r\n    // root) parses fresh. Entries are consumed in order so a duplicated\r\n    // requested code yields distinct part nodes.\r\n    const newIndicatorParts = [];\r\n    for (const indCode of finalCodes) {\r\n      const entryIndex = attachableEntries.findIndex(e => e.code === indCode);\r\n      if (entryIndex !== -1) {\r\n        newIndicatorParts.push(...attachableEntries.splice(entryIndex, 1)[0].parts);\r\n        continue;\r\n      }\r\n      const parsed = this.#ctx.parse(indCode);\r\n      this.#forwardParseWarnings(parsed);\r\n      const partNode = parsed.groups?.[0]?.glyphs?.[0]?.parts?.[0];\r\n      if (partNode) newIndicatorParts.push(partNode);\r\n    }\r\n\r\n    // Reassemble glyph parts\r\n    glyph.parts = [...baseParts, ...newIndicatorParts];\r\n\r\n    // Update glyph identity\r\n    this.#updateGlyphIdentityAfterIndicatorChange(glyph, definitions);\r\n\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  // D4: emit a mutation warning (one per no-op call) when an indicator\r\n  // apply/clear had no effect. Uses the persistent mutation-warning channel\r\n  // (survives #rebuild), not the parse `#warnings` (which resets each rebuild).\r\n  #warnIndicatorNoop(message, source) {\r\n    this.#ctx.addMutationWarning({\r\n      code: WARNING_CODES.NOOP_INDICATOR_MUTATION,\r\n      message,\r\n      source,\r\n    });\r\n  }\r\n\r\n  #updateGlyphIdentityAfterIndicatorChange(glyph, definitions) {\r\n    // A custom (non-built-in) Bliss glyph keeps its identity through indicator\r\n    // changes so { preserve: true } can re-emit the delta against the baked\r\n    // definition state, matching the DSL replacement path (DSL/API parity).\r\n    // Built-in glyphs decompose, so they fall through to the reset logic below.\r\n    if (glyph.isBlissGlyph === true\r\n        && typeof glyph.glyphCode === 'string'\r\n        && !builtInCodes.has(glyph.glyphCode)) {\r\n      return;\r\n    }\r\n    const hasIndicators = glyph.parts.some(p => p.isIndicator === true);\r\n    if (!hasIndicators && glyph.parts.length === 1) {\r\n      const baseCode = glyph.parts[0].codeName;\r\n      const def = definitions[baseCode];\r\n      if (def?.isBlissGlyph) {\r\n        glyph.isBlissGlyph = true;\r\n        glyph.codeName = baseCode;\r\n        if (def.glyphCode) glyph.glyphCode = def.glyphCode;\r\n      } else {\r\n        delete glyph.isBlissGlyph;\r\n        delete glyph.codeName;\r\n        delete glyph.glyphCode;\r\n      }\r\n    } else {\r\n      delete glyph.isBlissGlyph;\r\n      delete glyph.codeName;\r\n      delete glyph.glyphCode;\r\n    }\r\n  }\r\n\r\n  // Word-level indicator channel for a group handle. Sets/clears the reversible\r\n  // `group.wordIndicators` overlay (the DSL `;;` form), leaving the base glyphs\r\n  // intact so a later clear restores them (N12). `flatten` opts out of the\r\n  // overlay and bakes onto the head as character-level parts instead (the\r\n  // pre-overlay, character-level shape). `code` is null for clear, '' for the\r\n  // deliberate empty apply (== the DSL's bare `;;`). Mirrors the parser overlay\r\n  // store -- including `;;` non-indicator validation -- so the API and the `;;`\r\n  // DSL marker produce byte-identical state (DSL/API parity).\r\n  #applyOrClearWordIndicators(code, opts) {\r\n    const group = this.#nodeRef;\r\n    // Overlay clear/apply are pure state ops on the group node, so they must\r\n    // keep working when every glyph was detached — a stale overlay on an\r\n    // emptied word would otherwise be unreachable and resurrect on the next\r\n    // addGlyph (round-2 external review F3). Only flatten needs glyphs (below).\r\n    if (!group) return this;\r\n    // Terminal fail-flagged word: see #inFailFlaggedGroup.\r\n    if (group.errorCode) return this;\r\n    // A space group carries no word indicator: refuse + warn (parity with the\r\n    // glyph-level space arm), never store an overlay the space's '//'\r\n    // serialization would eat (round-2 external review F1).\r\n    if (this.#ctx.isRawSpaceGroup(group)) {\r\n      const verb = code === null ? 'clearIndicators()' : `applyIndicators('${code}')`;\r\n      const targetCode = group.glyphs[0]?.parts?.[0]?.codeName || 'unknown';\r\n      // `||` deliberately (not `??`): the empty apply's '' falls back to the\r\n      // target code, never an empty source (parity with the glyph arm).\r\n      this.#warnIndicatorNoop(\r\n        `${verb} had no effect: the target word is a space; a space cannot carry a word indicator.`,\r\n        code || targetCode,\r\n      );\r\n      return this;\r\n    }\r\n    // stripSemantic is an apply-only option: a clear is the pure undo.\r\n    const stripSemantic = code !== null && opts?.stripSemantic === true;\r\n\r\n    if (opts?.flatten === true) {\r\n      // Flatten bakes onto a head, so it still requires glyphs (an empty word\r\n      // has nothing to bake onto; the overlay stays for a non-flatten op).\r\n      if (!group.glyphs?.length) return this;\r\n      // Bake onto the head; drop any overlay so the indicator is not applied\r\n      // twice (once baked, once re-merged at render). N15: only drop the overlay\r\n      // when the bake actually lands. A clear always bakes (removal is the\r\n      // effect), and so does the empty apply (same clear state effect, strip\r\n      // honored); a code-carrying apply bakes only if it carries a recognized\r\n      // indicator, else the overlay is kept rather than silently destroyed\r\n      // (R15 Task 5).\r\n      const head = this.headGlyph();\r\n      const hadOverlay = group.wordIndicators !== undefined;\r\n      const requestedCodes = code === null || code === '' ? [] : splitTopLevelSemicolons(code);\r\n      const bakeApplies = code === null || code === ''\r\n        || filterToIndicators(requestedCodes, this.#ctx.getDefinitions()).length > 0;\r\n      if (bakeApplies) delete group.wordIndicators;\r\n      if (head) {\r\n        // When an overlay was removed, that removal IS the effect, so the\r\n        // delegated char-level clear-nothing must not warn as a no-op. The\r\n        // suppress signal is passed as a private positional arg (not an opts\r\n        // key), so it goes through the private method, not public clearIndicators.\r\n        // An apply is left unsuppressed so an unrecognized code still warns; but\r\n        // stripSemantic is forwarded only when the bake applies, so a refused\r\n        // non-indicator apply stays a pure no-op (it must not strip the head as\r\n        // a side effect while keeping the overlay — F2). The strip spelling is\r\n        // applyIndicators('', { flatten: true, stripSemantic: true }).\r\n        if (code === null) head.#applyOrClearIndicators(null, {}, hadOverlay);\r\n        else head.applyIndicators(code, { stripSemantic: bakeApplies && stripSemantic });\r\n      } else if (hadOverlay && bakeApplies) {\r\n        this.#ctx.rebuild();\r\n      }\r\n      this.#syncGeneration();\r\n      return this;\r\n    }\r\n\r\n    if (code === null) {\r\n      // Clear: the pure undo. Removing the overlay fully restores the base --\r\n      // the head's own character-level indicators, replaced at render while\r\n      // the overlay existed, become visible again. A clear that finds no\r\n      // overlay warns (D4 parity with the glyph-level clear-nothing arm).\r\n      const hadOverlay = group.wordIndicators !== undefined;\r\n      delete group.wordIndicators;\r\n      if (!hadOverlay) {\r\n        const headNode = this.headGlyph()?.#nodeRef ?? group.glyphs?.[0];\r\n        const targetCode = headNode?.codeName || headNode?.parts?.[0]?.codeName || 'unknown';\r\n        this.#warnIndicatorNoop(\r\n          `clearIndicators() had no effect: the word has no word-level (;;) indicator overlay to clear.`,\r\n          targetCode,\r\n        );\r\n      }\r\n    } else {\r\n      // A `;;` overlay code must BE an indicator (same rule as the DSL `;;`\r\n      // parser path). Tokenize bracket-aware so a multi-key option block's inner\r\n      // `;` is not split (DSL/API parity), then validate + drop non-indicators\r\n      // via the shared resolver, warning on the persistent mutation channel so\r\n      // the warning survives the rebuild below.\r\n      const requestedCodes = splitTopLevelSemicolons(code);\r\n      const overlay = resolveWordIndicatorOverlay(requestedCodes, stripSemantic, this.#ctx.getDefinitions(), ({ code: badCode, reason }) => {\r\n        this.#ctx.addMutationWarning(reason === 'word-structure'\r\n          ? {\r\n              // Round-2 external review F2: a `/` hidden behind a coordinate\r\n              // suffix escaped the bare-code classifier, so the stored code\r\n              // serialized to a string the DSL re-parses as word structure.\r\n              code: WARNING_CODES.MALFORMED_WORD_INDICATOR,\r\n              message: `applyIndicators('${code}'): \"${badCode}\" contains a character separator (a top-level /), which a word-level indicator cannot hold; it is ignored.`,\r\n              source: badCode,\r\n            }\r\n          : reason === 'non-indicator'\r\n            ? {\r\n                code: WARNING_CODES.NON_INDICATOR_AS_WORD_INDICATOR,\r\n                message: `applyIndicators('${code}'): \"${badCode}\" is not an indicator; it is ignored. A word-level indicator code must be an indicator (e.g. B81).`,\r\n                source: badCode,\r\n              }\r\n            : {\r\n                code: WARNING_CODES.UNKNOWN_CODE,\r\n                message: `applyIndicators('${code}'): unknown indicator code \"${badCode}\"; it is ignored.`,\r\n                source: badCode,\r\n              });\r\n      }, ({ bracket, code: keptCode, source }) => {\r\n        this.#ctx.addMutationWarning({\r\n          code: WARNING_CODES.MISPLACED_CHARACTER_OPTION,\r\n          message: `applyIndicators('${code}'): character option (${bracket}) ignored on the word indicator \"${keptCode}\": a ;; code has no character to style. Use ${bracket}>${keptCode} to style the indicator part.`,\r\n          source,\r\n        });\r\n      });\r\n      // Store every overlay the shared resolver returns: surviving indicators,\r\n      // an explicit strip, or the deliberately-empty set (the resolver's\r\n      // bare-`;;` arm — an empty apply IS the empty overlay, DSL parity). An\r\n      // apply whose codes are all non-indicators (resolver null) asked for\r\n      // nothing valid: warn and leave any existing overlay untouched rather\r\n      // than silently destroying it. Mirrors the flatten N15 rule.\r\n      if (overlay) {\r\n        group.wordIndicators = overlay;\r\n      }\r\n    }\r\n\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  // --- Mutation: word structure ---\r\n\r\n  /**\r\n   * Splits this word group into two at the glyph boundary, inserting\r\n   * a space group between. Only valid on group-level handles.\r\n   * @param {number} glyphIndex - Split point (1 to glyphs.length - 1)\r\n   * @returns {this}\r\n   */\r\n  splitAt(glyphIndex) {\r\n    this.#assertReachable();\r\n    if (this.#level !== 1) return this;\r\n    const group = this.#nodeRef;\r\n    if (!group?.glyphs) return this;\r\n    // A fail-flagged word (malformed `;;`) is terminal: it renders as a single\r\n    // placeholder, and its hidden base glyphs must not escape across a group\r\n    // boundary and render as valid. No-op; only replaceGroup recovers it.\r\n    if (group.errorCode) return this;\r\n    const len = group.glyphs.length;\r\n    if (!Number.isInteger(glyphIndex) || glyphIndex <= 0 || glyphIndex >= len) {\r\n      throw new Error(`splitAt(${glyphIndex}) is out of range: must be between 1 and ${len - 1} (inclusive) for a group with ${len} glyphs`);\r\n    }\r\n\r\n    // Resolve raw index before any destructive mutation\r\n    const groups = this.#ctx.getRaw().groups;\r\n    const rawIndex = groups.indexOf(this.#nodeRef);\r\n    if (rawIndex < 0) return this;\r\n\r\n    // Splice trailing glyphs from the original group (mutate in-place)\r\n    const rightGlyphs = group.glyphs.splice(glyphIndex);\r\n\r\n    // The word-level overlay is a WORD property, not head-bound, so the first\r\n    // (left) part always keeps it; the left group already retains\r\n    // group.wordIndicators here, so there is nothing to move. The `^` head\r\n    // marker obeys first-wins on a structural split: a marked glyph that lands\r\n    // in the second part loses its marker (that part re-derives its head from\r\n    // glyph 0), while a marker that stays in the first part is kept. This keeps\r\n    // split -> merge lossless for the word-slot and matches mergeWithNext.\r\n    for (const g of rightGlyphs) delete g.isHeadGlyph;\r\n\r\n    // Build right-half group with copied options\r\n    const rightGroup = { glyphs: rightGlyphs };\r\n    if (group.options) {\r\n      rightGroup.options = { ...group.options };\r\n    }\r\n\r\n    const spaceGroup = this.#ctx.makeSpaceGroup();\r\n\r\n    // Insert [space, rightGroup] after the original group\r\n    groups.splice(rawIndex + 1, 0, spaceGroup, rightGroup);\r\n\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Merges this word group with the next non-space group, removing any\r\n   * space groups between them. Only valid on group-level handles.\r\n   * No-op if no next word group exists or if this is a space group.\r\n   * The absorbed group's options are discarded; only this group's\r\n   * options apply to the merged result. Its word-level (`;;`) overlay is\r\n   * dropped with a `DROPPED_WORD_INDICATOR` warning, and its `^` head marker\r\n   * is dropped silently (the merged word resolves a single head).\r\n   * @returns {this}\r\n   */\r\n  mergeWithNext() {\r\n    this.#assertReachable();\r\n    if (this.#level !== 1) return this;\r\n    const group = this.#nodeRef;\r\n    if (!group?.glyphs) return this;\r\n\r\n    const groups = this.#ctx.getRaw().groups;\r\n    const rawIndex = groups.indexOf(this.#nodeRef);\r\n    if (rawIndex < 0) return this;\r\n\r\n    // No-op for space groups\r\n    if (this.#ctx.isRawSpaceGroup(group)) return this;\r\n    // No-op when this word is fail-flagged (malformed `;;`): it is terminal and\r\n    // cannot absorb a neighbor (the merged glyphs would render through the\r\n    // re-emitted error source, silently dropping the absorbed word).\r\n    if (group.errorCode) return this;\r\n\r\n    // Scan right to find the next non-space group\r\n    let nextWordIndex = -1;\r\n    for (let i = rawIndex + 1; i < groups.length; i++) {\r\n      if (!this.#ctx.isRawSpaceGroup(groups[i])) {\r\n        nextWordIndex = i;\r\n        break;\r\n      }\r\n    }\r\n    if (nextWordIndex < 0) return this;\r\n\r\n    // No-op if the next group has no glyphs to absorb\r\n    const nextGroup = groups[nextWordIndex];\r\n    if (!nextGroup.glyphs?.length) return this;\r\n    // No-op when the neighbor is fail-flagged (malformed `;;`): absorbing its\r\n    // hidden base glyphs would let the failed word's content render as valid\r\n    // (a silent un-fail). The failed word stays separate until replaced.\r\n    if (nextGroup.errorCode) return this;\r\n\r\n    // Absorb the next word group's glyphs\r\n    group.glyphs.push(...nextGroup.glyphs);\r\n\r\n    // R15 WS-3: `^` is word-scoped and first-wins, so the absorbed word's head\r\n    // marker is dropped silently (a re-derived head is not data loss). Clear it\r\n    // on the absorbed glyphs so the merged word keeps at most the first word's\r\n    // `^`; mirrors splitAt's right-side clear and keeps merge ≡ `/`-compose.\r\n    for (const g of nextGroup.glyphs) delete g.isHeadGlyph;\r\n\r\n    // The merged word keeps THIS group's word-level overlay; the absorbed\r\n    // group's overlay is dropped (one head governs the merged word, and it is\r\n    // this group's). Data loss must be loud, so warn rather than drop silently.\r\n    if (nextGroup.wordIndicators) {\r\n      const { codes = [], stripSemantic } = nextGroup.wordIndicators;\r\n      const dropped = ';;' + (stripSemantic ? '!' : '') + codes.join(';');\r\n      this.#ctx.addMutationWarning({\r\n        code: WARNING_CODES.DROPPED_WORD_INDICATOR,\r\n        message: `mergeWithNext() dropped the absorbed word's word-level indicator overlay (${dropped}). The merged word keeps only the first word's overlay.`,\r\n        source: dropped,\r\n      });\r\n    }\r\n\r\n    // Remove everything from rawIndex+1 through nextWordIndex (spaces + absorbed word)\r\n    groups.splice(rawIndex + 1, nextWordIndex - rawIndex);\r\n\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  // --- Mutation: options ---\r\n\r\n  setOptions(opts) {\r\n    this.#assertReachable();\r\n    // Terminal fail-flagged word: CHILD options live inside the frozen error\r\n    // source and no-op; GROUP options are the documented exemption (they\r\n    // serialize outside it, `[opts]|errorSource`, and round-trip).\r\n    if (this.#level !== 1 && this.#inFailFlaggedGroup()) return this;\r\n    const node = this.#nodeRef;\r\n    if (!node) return this;\r\n    assertOptsArg('setOptions', opts);\r\n    this.#applyDefaultsOverrides(node, opts);\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n\r\n  removeOptions(...keys) {\r\n    this.#assertReachable();\r\n    // Terminal fail-flagged word: mirrors setOptions (group-level exempt).\r\n    if (this.#level !== 1 && this.#inFailFlaggedGroup()) return this;\r\n    const node = this.#nodeRef;\r\n    if (!node?.options) return this;\r\n    for (const key of keys) {\r\n      const kebab = camelToKebab(key);\r\n      delete node.options[kebab];\r\n      delete node.options[key];\r\n    }\r\n    // Clean up empty options object\r\n    if (Object.keys(node.options).length === 0) {\r\n      delete node.options;\r\n    }\r\n    this.#ctx.rebuild();\r\n    this.#syncGeneration();\r\n    return this;\r\n  }\r\n}\r\n","/** \r\n * This Source Code Form is subject to the terms of the Mozilla Public\r\n * License, v. 2.0. If a copy of the MPL was not distributed with this\r\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\r\n */\r\n\r\nimport { blissElementDefinitions, builtInCodes, isSpaceGlyph, protectedCodes } from \"./bliss-element-definitions.js\";\r\nimport { BlissElement } from \"./bliss-element.js\";\r\nimport { BlissParser } from \"./bliss-parser.js\";\r\nimport { INTERNAL_OPTIONS, KNOWN_OPTION_KEYS, GLOBAL_ONLY_OPTION_KEYS, DOT_WIDTH_MAX, escapeHtml, isSafeAttributeName, camelToKebab, generateKey, LIB_VERSION, WARNING_CODES, serializeOptionValue } from \"./bliss-constants.js\";\r\nimport { ElementHandle, assertCodeArg, assertOptsArg } from \"./element-handle.js\";\r\nimport { mergeWordIndicatorsOntoHead, resolveEffectiveDefinition, resolveWordIndicatorOverlay, SINGLE_CODE_TOKEN } from \"./indicator-utils.js\";\r\nimport { resolveHeadIndex, headScanCode } from \"./bliss-head-glyph-exclusions.js\";\r\n\r\n// Pre-parsed error placeholder (REFSQUARE + question mark). Parsed once at module\r\n// load so BlissElement can clone it without importing BlissParser itself.\r\nconst ERROR_PLACEHOLDER_PARTS = BlissParser.parse('REFSQUARE;B699:3').groups[0].glyphs[0].parts;\r\n\r\n// Head-scan code for a raw blissObj glyph: a custom glyph's own identity, else\r\n// its base part's codeName when single-part. A fused multi-part character is a\r\n// character (not a leading operator), so an exclusion code among its parts does\r\n// not exclude it: headScanCode is the single source shared with the element\r\n// snapshot so the two query-time head sites stay in lockstep.\r\nconst getHeadCode = (glyph) =>\r\n  headScanCode(glyph.glyphCode, glyph.parts?.length ?? 0, glyph.parts?.[0]?.codeName);\r\n\r\n// Mirrors toString()'s glyph emission for an empty-parts glyph: it re-emits\r\n// a token only when some option survives serialization. `key` is stripped by\r\n// toJSON, the kerning keys emit as RK/AK segments (which cannot carry a `^`),\r\n// and `false` values are filtered by serializeOptions.\r\nconst GLYPH_OPTION_KEYS_WITHOUT_TOKEN = new Set(['key', 'relativeKerning', 'absoluteKerning']);\r\nconst glyphEmitsOptionsToken = (glyph) =>\r\n  Object.entries(glyph.options ?? {}).some(([k, v]) =>\r\n    v !== false && !GLYPH_OPTION_KEYS_WITHOUT_TOKEN.has(k));\r\n\r\n// Serialize an options object to [key=val;key2=val2] DSL format. Shared by\r\n// toString() serialization and the preserve-mode canonical anatomy compare\r\n// (one emitter, so the two surfaces cannot drift).\r\nfunction serializeOptions(opts, skipKeys) {\r\n  if (!opts) return '';\r\n  const entries = Object.entries(opts);\r\n  const filtered = entries.filter(([k, v]) =>\r\n    v !== false && !(skipKeys?.has(k))\r\n  );\r\n  if (filtered.length === 0) return '';\r\n  const parts = filtered.map(([k, v]) => v === true ? k : `${k}=${serializeOptionValue(v)}`);\r\n  return `[${parts.join(';')}]`;\r\n}\r\n\r\n// The anchor-attribute family, mirroring the two anchorAttrNames sets inside\r\n// BlissElement (keep all three in sync: a name added there but not here would\r\n// leak onto the content <g>). At global scope these travel through the level-0 <a> wrap\r\n// (with its href safety allowlist), so they must never double-emit as plain\r\n// content-<g> attributes: href is not a valid <g> attribute, and an\r\n// allowlist-rejected href would resurface verbatim.\r\nconst ANCHOR_ATTRIBUTE_NAMES = ['href', 'target', 'rel', 'download', 'hreflang', 'type', 'referrerpolicy'];\r\n\r\n// Resolves which glyph carries a word-level (`;;`) overlay. A stored\r\n// designation wins; the fallback resolves among content-bearing glyphs only,\r\n// because serialization omits a bare empty-parts glyph, so a reparse of\r\n// toString() resolves the head without it. Returns -1 when no glyph can\r\n// carry the overlay (every glyph is empty).\r\nconst resolveOverlayHeadIndex = (glyphs) => {\r\n  const marked = glyphs.findIndex(g => g.isHeadGlyph === true);\r\n  if (marked !== -1) return marked;\r\n  const contentIndexes = glyphs.flatMap((g, i) => (g.parts?.length ? [i] : []));\r\n  if (!contentIndexes.length) return -1;\r\n  return contentIndexes[resolveHeadIndex(contentIndexes.map(i => getHeadCode(glyphs[i])))];\r\n};\r\n\r\n// Note: BlissSVGBuilder.LIB_VERSION is attached at the public entry point\r\n// (src/index.js), not declared here. Code that imports the class directly\r\n// from this file (e.g. internal tests) will see LIB_VERSION as undefined.\r\n// External consumers always go through src/index.js, where the static is set.\r\nclass BlissSVGBuilder {\r\n  #processedOptions;\r\n  #sharedOptions;\r\n  #mutationCtx;\r\n  #warnings = [];\r\n  // Warnings raised by mutation operations (e.g. mergeWithNext dropping an\r\n  // absorbed word-level overlay). Unlike #warnings, these are NOT reset by\r\n  // #rebuild — they record one-time data-loss events for the builder's\r\n  // lifetime, since the lost data leaves no trace in the rebuilt tree.\r\n  #mutationWarnings = [];\r\n  #generation = 0;\r\n\r\n  // Processes raw options (kebab-case) into internal options (camelCase).\r\n  // Bulk options expanded here (not in output): 'margin', 'crop', 'grid-color', 'grid-stroke-width'.\r\n  // @param {boolean} addBuilderDefaults - If true, adds defaults for builder-level options (grid, etc.)\r\n  #processOptions(rawOptions = {}, addBuilderDefaults = false) {\r\n    const options = {};\r\n\r\n    // stroke-width: Number, clamped 0.1-1.5\r\n    if ('stroke-width' in rawOptions && !isNaN(rawOptions['stroke-width'])) {\r\n      let strokeWidth = Number(rawOptions['stroke-width']);\r\n      if (strokeWidth < 0.1) {\r\n        strokeWidth = 0.1;\r\n      } else if (strokeWidth > 1.5) {\r\n        strokeWidth = 1.5;\r\n      }\r\n      options.strokeWidth = strokeWidth;\r\n    }\r\n\r\n    // dot-extra-width: Number, clamped 0-1\r\n    if ('dot-extra-width' in rawOptions && !isNaN(rawOptions['dot-extra-width'])) {\r\n      let dotExtraWidth = Number(rawOptions['dot-extra-width']);\r\n      if (dotExtraWidth < 0) {\r\n        dotExtraWidth = 0;\r\n      } else if (dotExtraWidth > 1) {\r\n        dotExtraWidth = 1;\r\n      }\r\n      options.dotExtraWidth = dotExtraWidth;\r\n    }\r\n\r\n    // sdot-extra-width: Number, clamped 0-1 (small-dot override of the dot-extra-width half-default)\r\n    if ('sdot-extra-width' in rawOptions && !isNaN(rawOptions['sdot-extra-width'])) {\r\n      let sdotExtraWidth = Number(rawOptions['sdot-extra-width']);\r\n      if (sdotExtraWidth < 0) {\r\n        sdotExtraWidth = 0;\r\n      } else if (sdotExtraWidth > 1) {\r\n        sdotExtraWidth = 1;\r\n      }\r\n      options.sdotExtraWidth = sdotExtraWidth;\r\n    }\r\n\r\n    // dot-width: absolute rendered dot diameter, clamped [0, DOT_WIDTH_MAX]\r\n    if ('dot-width' in rawOptions && !isNaN(rawOptions['dot-width'])) {\r\n      let dotWidth = Number(rawOptions['dot-width']);\r\n      if (dotWidth < 0) {\r\n        dotWidth = 0;\r\n      } else if (dotWidth > DOT_WIDTH_MAX) {\r\n        dotWidth = DOT_WIDTH_MAX;\r\n      }\r\n      options.dotWidth = dotWidth;\r\n    }\r\n\r\n    // sdot-width: absolute rendered dot diameter, clamped [0, DOT_WIDTH_MAX]\r\n    if ('sdot-width' in rawOptions && !isNaN(rawOptions['sdot-width'])) {\r\n      let sdotWidth = Number(rawOptions['sdot-width']);\r\n      if (sdotWidth < 0) {\r\n        sdotWidth = 0;\r\n      } else if (sdotWidth > DOT_WIDTH_MAX) {\r\n        sdotWidth = DOT_WIDTH_MAX;\r\n      }\r\n      options.sdotWidth = sdotWidth;\r\n    }\r\n\r\n    // char-space: Number, clamped 0-10\r\n    if ('char-space' in rawOptions && !isNaN(rawOptions['char-space'])) {\r\n      let charSpace = Number(rawOptions['char-space']);\r\n      if (charSpace < 0) {\r\n        charSpace = 0;\r\n      } else if (charSpace > 10) {\r\n        charSpace = 10;\r\n      }\r\n      options.charSpace = charSpace;\r\n    }\r\n\r\n    // word-space: Number, clamped 0-20\r\n    if ('word-space' in rawOptions && !isNaN(rawOptions['word-space'])) {\r\n      let wordSpace = Number(rawOptions['word-space']);\r\n      if (wordSpace < 0) {\r\n        wordSpace = 0;\r\n      } else if (wordSpace > 20) {\r\n        wordSpace = 20;\r\n      }\r\n      options.wordSpace = wordSpace;\r\n    }\r\n\r\n    // external-glyph-space: Number, clamped 0-3\r\n    if ('external-glyph-space' in rawOptions && !isNaN(rawOptions['external-glyph-space'])) {\r\n      let externalGlyphSpace = Number(rawOptions['external-glyph-space']);\r\n      if (externalGlyphSpace < 0) {\r\n        externalGlyphSpace = 0;\r\n      } else if (externalGlyphSpace > 3) {\r\n        externalGlyphSpace = 3;\r\n      }\r\n      options.externalGlyphSpace = externalGlyphSpace;\r\n    }\r\n\r\n    // margin: Sets ALL 4 margins\r\n    if ('margin' in rawOptions && !isNaN(rawOptions['margin'])) {\r\n      const m = Number(rawOptions['margin']);\r\n      options.marginTop = m;\r\n      options.marginBottom = m;\r\n      options.marginLeft = m;\r\n      options.marginRight = m;\r\n    }\r\n\r\n    // Individual margins (override the above if present)\r\n    if ('margin-top' in rawOptions && !isNaN(rawOptions['margin-top'])) {\r\n      options.marginTop = Number(rawOptions['margin-top']);\r\n    }\r\n    if ('margin-bottom' in rawOptions && !isNaN(rawOptions['margin-bottom'])) {\r\n      options.marginBottom = Number(rawOptions['margin-bottom']);\r\n    }\r\n    if ('margin-left' in rawOptions && !isNaN(rawOptions['margin-left'])) {\r\n      options.marginLeft = Number(rawOptions['margin-left']);\r\n    }\r\n    if ('margin-right' in rawOptions && !isNaN(rawOptions['margin-right'])) {\r\n      options.marginRight = Number(rawOptions['margin-right']);\r\n    }\r\n\r\n    // min-width: Number, clamped to 0 minimum (negative values become 0)\r\n    if ('min-width' in rawOptions && !isNaN(rawOptions['min-width'])) {\r\n      let minWidth = Number(rawOptions['min-width']);\r\n      if (minWidth < 0) {\r\n        minWidth = 0;\r\n      }\r\n      options.minWidth = minWidth;\r\n    }\r\n\r\n    // Boolean options: [option] = true, absence = false\r\n    if (rawOptions.center === true) {\r\n      options.center = true;\r\n    }\r\n    if (rawOptions.grid === true) {\r\n      options.grid = true;\r\n    }\r\n    if (rawOptions['error-placeholder'] === true) {\r\n      options.errorPlaceholder = true;\r\n    }\r\n\r\n    // Grid colors - hierarchy: bulk → category → specific\r\n    // Only process if builder defaults requested or if grid options present\r\n    if (addBuilderDefaults || Object.keys(rawOptions).some(k => k.startsWith('grid-'))) {\r\n      // Start with defaults\r\n      let skyColor = \"#858585\";\r\n      let earthColor = \"#858585\";\r\n      let majorColor = \"#c7c7c7\";  // major grid (non-semantic)\r\n      let mediumColor = \"#ebebeb\";\r\n      let minorColor = \"#ebebeb\";\r\n\r\n      // Apply bulk option (sets all grid colors)\r\n      if ('grid-color' in rawOptions) {\r\n        const gc = rawOptions['grid-color'];\r\n        skyColor = earthColor = majorColor = mediumColor = minorColor = gc;\r\n      }\r\n\r\n      // Apply category option for major grids (overrides bulk for major lines)\r\n      if ('grid-major-color' in rawOptions) {\r\n        const gmc = rawOptions['grid-major-color'];\r\n        skyColor = earthColor = majorColor = gmc;\r\n      }\r\n\r\n      // Apply category option for medium grid (overrides bulk)\r\n      if ('grid-medium-color' in rawOptions) {\r\n        mediumColor = rawOptions['grid-medium-color'];\r\n      }\r\n\r\n      // Apply category option for minor grid (overrides bulk)\r\n      if ('grid-minor-color' in rawOptions) {\r\n        minorColor = rawOptions['grid-minor-color'];\r\n      }\r\n\r\n      // Apply specific options (most specific, override everything)\r\n      if ('grid-sky-color' in rawOptions) {\r\n        skyColor = rawOptions['grid-sky-color'];\r\n      }\r\n\r\n      if ('grid-earth-color' in rawOptions) {\r\n        earthColor = rawOptions['grid-earth-color'];\r\n      }\r\n\r\n      // Assign to options object (escaped for safe SVG output)\r\n      options.gridSkyColor = escapeHtml(skyColor);\r\n      options.gridEarthColor = escapeHtml(earthColor);\r\n      options.gridMajorColor = escapeHtml(majorColor);\r\n      options.gridMediumColor = escapeHtml(mediumColor);\r\n      options.gridMinorColor = escapeHtml(minorColor);\r\n    }\r\n\r\n    // Grid stroke widths - same hierarchy pattern\r\n    // Only process if builder defaults requested or if grid options present\r\n    if (addBuilderDefaults || Object.keys(rawOptions).some(k => k.startsWith('grid-'))) {\r\n      // Start with defaults\r\n      let skyWidth = 0.166;\r\n      let earthWidth = 0.166;\r\n      let majorWidth = 0.166;  // major grid (non-semantic)\r\n      let mediumWidth = 0.166;\r\n      let minorWidth = 0.166;\r\n\r\n      // Apply bulk option (sets all grid widths)\r\n      if ('grid-stroke-width' in rawOptions) {\r\n        const gsw = Number(rawOptions['grid-stroke-width']);\r\n        skyWidth = earthWidth = majorWidth = mediumWidth = minorWidth = gsw;\r\n      }\r\n\r\n      // Apply category option for major grids (overrides bulk for major lines)\r\n      if ('grid-major-stroke-width' in rawOptions) {\r\n        const gmsw = Number(rawOptions['grid-major-stroke-width']);\r\n        skyWidth = earthWidth = majorWidth = gmsw;\r\n      }\r\n\r\n      // Apply category option for medium grid (overrides bulk)\r\n      if ('grid-medium-stroke-width' in rawOptions) {\r\n        mediumWidth = Number(rawOptions['grid-medium-stroke-width']);\r\n      }\r\n\r\n      // Apply category option for minor grid (overrides bulk)\r\n      if ('grid-minor-stroke-width' in rawOptions) {\r\n        minorWidth = Number(rawOptions['grid-minor-stroke-width']);\r\n      }\r\n\r\n      // Apply specific options (most specific, override everything)\r\n      if ('grid-sky-stroke-width' in rawOptions) {\r\n        skyWidth = Number(rawOptions['grid-sky-stroke-width']);\r\n      }\r\n\r\n      if ('grid-earth-stroke-width' in rawOptions) {\r\n        earthWidth = Number(rawOptions['grid-earth-stroke-width']);\r\n      }\r\n\r\n      // Assign to options object\r\n      options.gridSkyStrokeWidth = skyWidth;\r\n      options.gridEarthStrokeWidth = earthWidth;\r\n      options.gridMajorStrokeWidth = majorWidth;\r\n      options.gridMediumStrokeWidth = mediumWidth;\r\n      options.gridMinorStrokeWidth = minorWidth;\r\n    }\r\n\r\n    // crop: Sets ALL 4 crop values (number or 'auto')\r\n    if ('crop' in rawOptions) {\r\n      const c = rawOptions['crop'];\r\n      if (c === 'auto') {\r\n        options.cropTop = 'auto';\r\n        options.cropBottom = 'auto';\r\n        options.cropLeft = 'auto';\r\n        options.cropRight = 'auto';\r\n      } else if (c === 'auto-vertical') {\r\n        options.autoVertical = true;\r\n      } else if (c === 'compact') {\r\n        options.cropCompact = true;\r\n      } else if (!isNaN(c)) {\r\n        const n = Number(c);\r\n        options.cropTop = n;\r\n        options.cropBottom = n;\r\n        options.cropLeft = n;\r\n        options.cropRight = n;\r\n      }\r\n    }\r\n\r\n    // Individual crop values (override the above if present)\r\n    // Each can be a number or 'auto'\r\n    const parseCropValue = (val) => val === 'auto' ? 'auto' : Number(val);\r\n    if ('crop-top' in rawOptions) {\r\n      options.cropTop = parseCropValue(rawOptions['crop-top']);\r\n    }\r\n    if ('crop-bottom' in rawOptions) {\r\n      options.cropBottom = parseCropValue(rawOptions['crop-bottom']);\r\n    }\r\n    if ('crop-left' in rawOptions) {\r\n      options.cropLeft = parseCropValue(rawOptions['crop-left']);\r\n    }\r\n    if ('crop-right' in rawOptions) {\r\n      options.cropRight = parseCropValue(rawOptions['crop-right']);\r\n    }\r\n\r\n    // Other string options\r\n    if ('color' in rawOptions) {\r\n      options.color = escapeHtml(rawOptions.color);\r\n    }\r\n    if ('background' in rawOptions) {\r\n      options.background = escapeHtml(rawOptions.background); // empty string => transparent background\r\n    }\r\n    if ('background-top' in rawOptions) {\r\n      options.backgroundTop = escapeHtml(rawOptions['background-top']);\r\n    }\r\n    if ('background-mid' in rawOptions) {\r\n      options.backgroundMid = escapeHtml(rawOptions['background-mid']);\r\n    }\r\n    if ('background-bottom' in rawOptions) {\r\n      options.backgroundBottom = escapeHtml(rawOptions['background-bottom']);\r\n    }\r\n    if ('text' in rawOptions) {\r\n      options.text = escapeHtml(rawOptions.text);\r\n    }\r\n    if ('svg-desc' in rawOptions) {\r\n      options.svgDesc = escapeHtml(rawOptions['svg-desc']);\r\n    }\r\n    if ('svg-title' in rawOptions) {\r\n      options.svgTitle = escapeHtml(rawOptions['svg-title']);\r\n    }\r\n\r\n    // SVG element height (presentation size, not viewBox)\r\n    if ('svg-height' in rawOptions && !isNaN(rawOptions['svg-height'])) {\r\n      options.svgHeight = Number(rawOptions['svg-height']);\r\n    }\r\n\r\n    // Preserve any options that weren't explicitly processed (like fill, opacity, stroke-dasharray, etc.)\r\n    // Only skip options that are in KNOWN_OPTION_KEYS (already processed above)\r\n    // String values are escaped here at the input boundary so downstream code can use them safely.\r\n    // Numeric values pass through as-is — they're used for calculations, not SVG markup.\r\n    for (const [key, value] of Object.entries(rawOptions)) {\r\n      if (!KNOWN_OPTION_KEYS.has(key)) {\r\n        options[key] = typeof value === 'string' ? escapeHtml(value) : value;\r\n      }\r\n    }\r\n\r\n    return options;\r\n  }\r\n\r\n  // Recursively process options at all levels (groups, glyphs, parts)\r\n  #processAllOptions(obj, isTopLevel = false) {\r\n    if (obj.options) {\r\n      // Extract key from options (key is element identity, not an SVG option)\r\n      if (obj.options.key !== undefined) {\r\n        obj.key = obj.options.key;\r\n        delete obj.options.key;\r\n      }\r\n      obj.options = this.#processOptions(obj.options, isTopLevel);\r\n    }\r\n    if (obj.groups) {\r\n      for (const group of obj.groups) {\r\n        this.#processAllOptions(group, false);\r\n      }\r\n    }\r\n    if (obj.glyphs) {\r\n      for (const glyph of obj.glyphs) {\r\n        this.#processAllOptions(glyph, false);\r\n      }\r\n    }\r\n    if (obj.parts) {\r\n      for (const part of obj.parts) {\r\n        this.#processAllOptions(part, false);\r\n      }\r\n    }\r\n  }\r\n\r\n  #rawBlissObj; // Stored for toJSON() round-trip\r\n\r\n  constructor(input, options = {}) {\r\n    assertOptsArg('BlissSVGBuilder', options);\r\n    const { defaults, overrides } = BlissSVGBuilder.#resolveOpts(options);\r\n\r\n    // Allow empty constructor for building from scratch\r\n    if (input === undefined || input === '') {\r\n      input = '';\r\n    } else if (typeof input !== 'string' && (typeof input !== 'object' || input === null || Array.isArray(input))) {\r\n      throw new Error('Input must be a DSL string or a plain object from toJSON()');\r\n    }\r\n\r\n    // Accept both string (DSL) and object (from toJSON()) input\r\n    const blissObj = (typeof input === 'string')\r\n      ? BlissParser.parse(input)\r\n      : structuredClone(input);\r\n\r\n    // For object input (from toJSON), re-expand any parts that were stripped\r\n    if (typeof input !== 'string') {\r\n      BlissParser.expandParts(blissObj);\r\n    }\r\n\r\n    // Reverse toJSON() normalization: codeName → internal field names\r\n    if (typeof input !== 'string' && blissObj.groups) {\r\n      BlissSVGBuilder.#normalizeGlyphCodes(blissObj.groups);\r\n      BlissSVGBuilder.#normalizePartlessGlyphs(blissObj.groups);\r\n    }\r\n\r\n    // A `wordIndicators` overlay from object input (persisted toJSON, or hand-\r\n    // authored) must pass the same \"a `;;` code must BE an indicator\" rule as the\r\n    // DSL and API, so all three input surfaces agree. Older/hand-authored data can\r\n    // carry a non-indicator overlay code; validate + drop it here via the shared\r\n    // resolver, routing warnings through `_parseWarnings` like the parser (they\r\n    // surface in `warnings` and are stripped from `toJSON()`).\r\n    if (typeof input !== 'string' && blissObj.groups) {\r\n      for (const group of blissObj.groups) {\r\n        if (!group.wordIndicators) continue;\r\n        const { codes = [], stripSemantic = false } = group.wordIndicators;\r\n        const overlay = resolveWordIndicatorOverlay(codes, stripSemantic, blissElementDefinitions, ({ code: badCode, reason }) => {\r\n          (blissObj._parseWarnings ??= []).push(reason === 'word-structure'\r\n            ? {\r\n                // Round-2 external review F2: a `/` hidden behind a coordinate\r\n                // suffix serialized to a string the DSL re-parses as word\r\n                // structure; the DSL/API surfaces reject it, so object input must too.\r\n                code: WARNING_CODES.MALFORMED_WORD_INDICATOR,\r\n                message: `Word-level indicator \"${badCode}\" contains a character separator (a top-level /), which a word-level indicator cannot hold; it is ignored.`,\r\n                source: badCode,\r\n              }\r\n            : reason === 'non-indicator'\r\n              ? {\r\n                  code: WARNING_CODES.NON_INDICATOR_AS_WORD_INDICATOR,\r\n                  message: `Word-level indicator \"${badCode}\" is not an indicator; it is ignored. A ;; code must be an indicator (e.g. B81).`,\r\n                  source: badCode,\r\n                }\r\n              : {\r\n                  code: WARNING_CODES.UNKNOWN_CODE,\r\n                  message: `Word-level indicator \"${badCode}\" is not a known code; it is ignored.`,\r\n                  source: badCode,\r\n                });\r\n        }, ({ bracket, code: keptCode, source }) => {\r\n          (blissObj._parseWarnings ??= []).push({\r\n            code: WARNING_CODES.MISPLACED_CHARACTER_OPTION,\r\n            message: `Character option (${bracket}) ignored on the word indicator \"${keptCode}\": a ;; code has no character to style. Use ${bracket}>${keptCode} to style the indicator part.`,\r\n            source,\r\n          });\r\n        });\r\n        if (overlay) group.wordIndicators = overlay;\r\n        else delete group.wordIndicators;\r\n      }\r\n    }\r\n\r\n    // Merge: defaults (lowest) < string options (middle) < overrides (highest)\r\n    if (defaults || overrides) {\r\n      const rawDefaults = defaults ? BlissSVGBuilder.#toRaw(defaults) : {};\r\n      const rawOverrides = overrides ? BlissSVGBuilder.#toRaw(overrides) : {};\r\n      blissObj.options = { ...rawDefaults, ...(blissObj.options ?? {}), ...rawOverrides };\r\n    }\r\n\r\n    // Flag word-as-part references (e.g. H;TW where TW = B291/B291) with\r\n    // error so BlissElement emits a WORD_AS_PART warning instead of rendering.\r\n    BlissSVGBuilder.#flagWordParts(blissObj);\r\n\r\n    // Store a clean copy after option merging but before processing mutates it\r\n    this.#rawBlissObj = structuredClone(blissObj);\r\n\r\n    this.#rebuild();\r\n\r\n    this.#mutationCtx = {\r\n      getRaw: () => this.#rawBlissObj,\r\n      rebuild: () => this.#rebuild(),\r\n      parse: (code) => {\r\n        const parsed = BlissParser.parse(code);\r\n        BlissSVGBuilder.#flagWordParts(parsed);\r\n        return parsed;\r\n      },\r\n      toRaw: (obj) => BlissSVGBuilder.#toRaw(obj),\r\n      isRawSpaceGroup: (g) => BlissSVGBuilder.#isRawSpaceGroup(g),\r\n      makeSpaceGroup: () => BlissSVGBuilder.#makeSpaceGroup(),\r\n      removeGlyphGroup: (obj, gi) => this.#removeGlyphGroup(obj, gi),\r\n      getSnapshot: () => this.snapshot(),\r\n      getGeneration: () => this.#generation,\r\n      getDefinitions: () => blissElementDefinitions,\r\n      addMutationWarning: (warning) => this.#mutationWarnings.push(warning),\r\n    };\r\n  }\r\n\r\n  // Resolve opts: accepts { defaults, overrides } or flat options (treated as overrides).\r\n  static #resolveOpts(opts) {\r\n    if (!opts) return { defaults: undefined, overrides: undefined };\r\n    if ('defaults' in opts || 'overrides' in opts) {\r\n      return { defaults: opts.defaults, overrides: opts.overrides };\r\n    }\r\n    return { defaults: undefined, overrides: opts };\r\n  }\r\n\r\n  static #toRaw(obj) {\r\n    const raw = {};\r\n    for (const [key, value] of Object.entries(obj)) {\r\n      if (value === null || value === undefined) continue;\r\n      if (typeof value === 'object') continue;\r\n      const kebabKey = camelToKebab(key);\r\n      if (typeof value === 'boolean') {\r\n        raw[kebabKey] = value;\r\n      } else {\r\n        raw[kebabKey] = String(value);\r\n      }\r\n    }\r\n    return raw;\r\n  }\r\n\r\n  // Assigns stable keys to the three DSL-visible levels in #rawBlissObj:\r\n  // groups (//), glyphs (/), and immediate parts (;).\r\n  // Called before structuredClone so keys persist across rebuilds.\r\n  // Deeper nested parts (definition expansions) are intentionally skipped —\r\n  // they are not user-addressable and receive ephemeral keys from BlissElement.\r\n  static #assignKeys(rawObj) {\r\n    if (!rawObj.key) rawObj.key = generateKey();\r\n    if (rawObj.groups) {\r\n      for (const group of rawObj.groups) {\r\n        if (!group.key) group.key = generateKey();\r\n        if (group.glyphs) {\r\n          for (const glyph of group.glyphs) {\r\n            if (!glyph.key) glyph.key = generateKey();\r\n            if (glyph.parts) {\r\n              for (const part of glyph.parts) {\r\n                if (!part.key) part.key = generateKey();\r\n              }\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  // Space-invariant normalization (round-3/round-4 external review F1): a\r\n  // structural mutation (replaceGlyph/removeGlyph/replacePart/detach/\r\n  // addGlyph-on-empty/insertGlyph), an alias expanding an in-word space, or\r\n  // hand-authored object input can leave space state the DSL cannot express —\r\n  // an overlay/designation on a space that '//' serialization eats, or a bare\r\n  // space glyph INSIDE a word whose serialized token the parser re-splits\r\n  // into separate groups (so toString diverges from toJSON and the reparse\r\n  // renders differently, silently). Enforced HERE, the one chokepoint every\r\n  // mutation route and input surface passes through (parse and the indicator\r\n  // API already gate their own ingestion):\r\n  //  1. A non-head marker (a space glyph or the ZSA anchor) never carries a\r\n  //     designation (deleted silently, matching the structural `^` drops in\r\n  //     splitAt/mergeWithNext). Likewise a glyph serialization omits entirely\r\n  //     (empty parts, no codeName, no options that would re-emit it as an\r\n  //     options-only token): its designation has no serialized form, so it\r\n  //     dies with the glyph's content (the round-2 F4 contract, enforced here\r\n  //     for hand-authored object input).\r\n  //  2. An all-non-head-marker word never carries a `;;` overlay (dropped\r\n  //     LOUDLY, matching mergeWithNext's DROPPED_WORD_INDICATOR, since data\r\n  //     loss must be visible). The deletion makes the sweep warn once, not per\r\n  //     rebuild. An EMPTY group keeps its overlay (the F3 pure-state-op\r\n  //     contract; isNonHeadMarkerGroup is false).\r\n  //  3. A bare space glyph never lives inside a word: the word is split at\r\n  //     its space runs into real space groups — canonicalization, SILENT\r\n  //     (nothing is lost: glyph nodes move; the first word run keeps the\r\n  //     group node, overlay, and options; later word runs get an options\r\n  //     copy, splitAt parity, and keep their own designations, which\r\n  //     round-trip per word). A fail-flagged group is exempt (terminal;\r\n  //     splitting it would duplicate its errorSource replay). A multi-part\r\n  //     glyph merely LED by a space-code part (`ZSA;B291`) is not a space\r\n  //     glyph and is never touched.\r\n  //  4. Adjacent space groups merge (a reparse groups consecutive space\r\n  //     tokens into ONE group, so separate neighbors could not round-trip).\r\n  #normalizeSpaceInvariant() {\r\n    const groups = this.#rawBlissObj.groups ?? [];\r\n    for (const group of groups) {\r\n      for (const glyph of group.glyphs ?? []) {\r\n        if (glyph.isHeadGlyph === true && BlissSVGBuilder.#isNonHeadMarkerNode(glyph)) {\r\n          delete glyph.isHeadGlyph;\r\n        }\r\n        if (glyph.isHeadGlyph === true && !glyph.parts?.length\r\n            && !glyph.glyphCode && !glyph.codeName && !glyphEmitsOptionsToken(glyph)) {\r\n          delete glyph.isHeadGlyph;\r\n        }\r\n      }\r\n      if (group.wordIndicators && !group.errorCode && BlissSVGBuilder.#isNonHeadMarkerGroup(group)) {\r\n        const { codes = [], stripSemantic } = group.wordIndicators;\r\n        const dropped = ';;' + (stripSemantic ? '!' : '') + codes.join(';');\r\n        delete group.wordIndicators;\r\n        this.#mutationWarnings.push({\r\n          code: WARNING_CODES.DROPPED_WORD_INDICATOR,\r\n          message: `A space or anchor cannot carry a word indicator, so the word-level indicator overlay (${dropped}) was dropped.`,\r\n          source: dropped,\r\n        });\r\n      }\r\n    }\r\n    const createdSpaceGroups = [];\r\n    const movedSpaceGlyphs = [];\r\n    // A TSP/QSP space is a pure word-separator: a coordinate (`:x,y`) or an\r\n    // option (`[opts]` at any scope) on one cannot position or style whitespace,\r\n    // so it is dropped with a MISPLACED_SPACE_DECORATION warning and the space\r\n    // keeps its identity. ZSA is content (a positionable inkless shape) and is\r\n    // exempt: the strip targets only #isSpaceGlyphNode (= {TSP, QSP}). A stripped\r\n    // glyph joins movedSpaceGlyphs so the _differsFromDefault re-flag below keeps\r\n    // a bared QSP serializing as `QSP`, not the default `//`. Kerning\r\n    // (GLYPH_INTERNAL_KEYS) and the runtime key are spared.\r\n    const warnSpaceDrop = (kind, source) => this.#mutationWarnings.push({\r\n      code: WARNING_CODES.MISPLACED_SPACE_DECORATION,\r\n      message: `A space cannot carry ${kind === 'coordinate' ? 'a coordinate' : 'an option'}, so \"${source}\" was dropped.`,\r\n      source,\r\n    });\r\n    for (const group of groups) {\r\n      if (group.errorCode || !group.glyphs?.length) continue;\r\n      const pureSpace = BlissSVGBuilder.#isRawSpaceGroup(group);\r\n      let groupStripped = false;\r\n      if (pureSpace) {\r\n        const repr = BlissSVGBuilder.#dropSpaceOptions(group.options);\r\n        if (repr) {\r\n          if (Object.keys(group.options).length === 0) delete group.options;\r\n          warnSpaceDrop('option', repr);\r\n          groupStripped = true;\r\n        }\r\n      }\r\n      for (const glyph of group.glyphs) {\r\n        if (!BlissSVGBuilder.#isSpaceGlyphNode(glyph)) continue;\r\n        let touched = groupStripped;\r\n        const glyphRepr = BlissSVGBuilder.#dropSpaceOptions(glyph.options);\r\n        if (glyphRepr) {\r\n          if (Object.keys(glyph.options).length === 0) delete glyph.options;\r\n          warnSpaceDrop('option', glyphRepr);\r\n          touched = true;\r\n        }\r\n        const part = glyph.parts[0];\r\n        const partRepr = BlissSVGBuilder.#dropSpaceOptions(part.options);\r\n        if (partRepr) {\r\n          if (Object.keys(part.options).length === 0) delete part.options;\r\n          warnSpaceDrop('option', partRepr);\r\n          touched = true;\r\n        }\r\n        if (part.x !== undefined || part.y !== undefined) {\r\n          const source = `:${part.x ?? 0},${part.y ?? 0}`;\r\n          const meaningful = (part.x ?? 0) !== 0 || (part.y ?? 0) !== 0;\r\n          delete part.x;\r\n          delete part.y;\r\n          if (meaningful) warnSpaceDrop('coordinate', source);\r\n          touched = true;\r\n        }\r\n        // Re-flag for identity even when nothing survived to strip: a space that\r\n        // arrived carrying a global-only option key (`[grid]|QSP`) is stripped by\r\n        // the parser first (as MISPLACED_GLOBAL_OPTION), which leaves the QSP bared\r\n        // but UNflagged, so it would serialize to the default `//` and lose its\r\n        // quarter-space identity. Re-flag only a currently-UNflagged pure-space\r\n        // glyph (set-only via the loop below): an already-flagged space is left\r\n        // untouched, so a correctly parsed space never gets its flag cleared.\r\n        if (touched || (pureSpace && !part._differsFromDefault)) movedSpaceGlyphs.push(glyph);\r\n      }\r\n    }\r\n    // Pass 3: split mixed words at their space runs.\r\n    for (let i = 0; i < groups.length; i++) {\r\n      const group = groups[i];\r\n      if (group.errorCode || !group.glyphs?.length) continue;\r\n      if (!group.glyphs.some(g => BlissSVGBuilder.#isSpaceGlyphNode(g))) continue;\r\n      if (BlissSVGBuilder.#isRawSpaceGroup(group)) continue;\r\n      const runs = [];\r\n      for (const glyph of group.glyphs) {\r\n        const isSpace = BlissSVGBuilder.#isSpaceGlyphNode(glyph);\r\n        const last = runs[runs.length - 1];\r\n        if (last && last.isSpace === isSpace) last.glyphs.push(glyph);\r\n        else runs.push({ isSpace, glyphs: [glyph] });\r\n      }\r\n      let keeperAssigned = false;\r\n      const replacement = runs.map((run) => {\r\n        if (run.isSpace) {\r\n          const spaceGroup = { glyphs: run.glyphs };\r\n          createdSpaceGroups.push(spaceGroup);\r\n          movedSpaceGlyphs.push(...run.glyphs);\r\n          return spaceGroup;\r\n        }\r\n        if (!keeperAssigned) {\r\n          keeperAssigned = true;\r\n          group.glyphs = run.glyphs;\r\n          return group;\r\n        }\r\n        const wordGroup = { glyphs: run.glyphs };\r\n        if (group.options) wordGroup.options = { ...group.options };\r\n        return wordGroup;\r\n      });\r\n      groups.splice(i, 1, ...replacement);\r\n      i += replacement.length - 1;\r\n    }\r\n    // Merge a CREATED space group into an adjacent space group (the native\r\n    // node survives, keeping its key): '//' serialization counts N spaces as\r\n    // N+1 slashes, so two separate neighbors would concatenate into a slash\r\n    // run the reparse reads as one bigger group. Only normalization-created\r\n    // groups merge — space groups the raw element API placed deliberately are\r\n    // its documented \"no automatic space management\" business (GH #19 owns\r\n    // reparse-side re-collapse).\r\n    if (createdSpaceGroups.length > 0) {\r\n      const created = new Set(createdSpaceGroups);\r\n      for (let i = groups.length - 1; i > 0; i--) {\r\n        const right = groups[i];\r\n        const left = groups[i - 1];\r\n        if (!created.has(right) && !created.has(left)) continue;\r\n        if (right.errorCode || left.errorCode) continue;\r\n        if (!BlissSVGBuilder.#isRawSpaceGroup(right) || !BlissSVGBuilder.#isRawSpaceGroup(left)) continue;\r\n        if (created.has(left) && !created.has(right)) {\r\n          right.glyphs.unshift(...left.glyphs);\r\n          groups.splice(i - 1, 1);\r\n        } else {\r\n          left.glyphs.push(...right.glyphs);\r\n          groups.splice(i, 1);\r\n        }\r\n      }\r\n    }\r\n    // Flag the moved space parts against their position's default space code\r\n    // (mirrors the parser's step-4 SP/QSP resolution): the serializer emits\r\n    // '//' only for the default, so an explicit QSP must carry\r\n    // _differsFromDefault or its identity (and width) would be lost. Both a\r\n    // Pass-3 split and the decoration strip above feed movedSpaceGlyphs; a bared\r\n    // QSP whose coordinate suppressed its parse-time flag is re-flagged here.\r\n    // ZSA is content and never a moved space glyph, so it never reaches this path.\r\n    if (movedSpaceGlyphs.length > 0) {\r\n      const moved = new Set(movedSpaceGlyphs);\r\n      for (let i = 0; i < groups.length; i++) {\r\n        const group = groups[i];\r\n        if (!group.glyphs?.some(g => moved.has(g))) continue;\r\n        const nextGroup = groups[i + 1];\r\n        const isPunctuation = !!nextGroup && !BlissSVGBuilder.#isRawSpaceGroup(nextGroup)\r\n          && nextGroup.glyphs?.length > 0\r\n          && nextGroup.glyphs.every(g => g.shrinksPrecedingWordSpace === true);\r\n        const defaultCode = isPunctuation ? 'QSP' : 'TSP';\r\n        for (const glyph of group.glyphs) {\r\n          if (!moved.has(glyph)) continue;\r\n          const part = glyph.parts[0];\r\n          if (part.codeName !== defaultCode) part._differsFromDefault = true;\r\n          else delete part._differsFromDefault;\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  // Space-as-part invariant (row 78, extended row 81): a space (TSP/QSP, and\r\n  // the transient default-space SP that `//` expands to) is a word-level\r\n  // separator, never a `;`-part — a space cannot stay a character inside a\r\n  // word (#normalizeSpaceInvariant Pass 3 splits it out) and cannot carry a\r\n  // decoration, so a space in a part slot is the same misplacement one level\r\n  // down. The space part is dropped LOUDLY (MISPLACED_SPACE) from render\r\n  // and serialization while the character still renders; a coordinate or\r\n  // option on it dies with the part (a positionable inkless blank is ZSA's\r\n  // job — ZSA is content and is exempt). SP is barred via a LOCAL check only:\r\n  // it is never added to the {TSP,QSP} classifier (isSpaceGlyph), which drives\r\n  // space-run coalescing, navigation, and counting (feedback_zsa_is_content_not_space).\r\n  // A single-part REAL-space glyph (TSP/QSP) IS the space itself and is\r\n  // untouched; a lone transient SP (not a real space glyph, so a mutation can\r\n  // strand it as a lone character part) instead drops to an empty glyph rather\r\n  // than re-emitting bare and reparsing as a word separator (row 81). A\r\n  // fail-flagged word re-emits verbatim (replay fidelity) and an atomic\r\n  // compound-indicator glyph's anatomy is definition-owned, so both are\r\n  // skipped, mirroring #normalizeIndicatorInvariant. define() already rejects\r\n  // a glyph definition referencing a space, so the isIndicator skip only\r\n  // matters for hand-authored object input. Uncertainty exemption (the\r\n  // indicator invariant's exemption 2, one rule over): when the non-space\r\n  // remainder holds no definition-known part (only an unknown code like `ZZ9`,\r\n  // whose nature is uncertain), the drop is skipped, applied uniformly to\r\n  // TSP/QSP/SP; the character already fail-renders and the unknown-code warning\r\n  // is the visibility. An all-space list still drops (the empty glyph is inert\r\n  // pure state). Runs FIRST among the\r\n  // rebuild normalizers: before #normalizeSpaceInvariant so an emptied glyph\r\n  // gets its head-designation cleanup, and before\r\n  // #normalizeIndicatorInvariant so a space is never a content witness that\r\n  // convicts a trailing indicator (`B86;QSP` keeps B86).\r\n  #normalizeSpacePartInvariant() {\r\n    for (const group of this.#rawBlissObj.groups ?? []) {\r\n      if (group.errorCode) continue;\r\n      for (const glyph of group.glyphs ?? []) {\r\n        if (glyph.isIndicator === true) continue;\r\n        const parts = glyph.parts;\r\n        if (!Array.isArray(parts) || parts.length === 0) continue;\r\n        // A lone REAL-space glyph (TSP/QSP) IS the space itself and is\r\n        // untouched; a lone transient SP is processed (it drops to an empty\r\n        // glyph below) instead of surviving to re-emit bare. A lone non-space\r\n        // part has no misplaced space and falls through the loop as a no-op.\r\n        if (parts.length === 1 && isSpaceGlyph(parts[0]?.codeName)) continue;\r\n        const misplaced = [];\r\n        let remainderCount = 0;\r\n        let knownRemainder = false;\r\n        for (let i = 0; i < parts.length; i++) {\r\n          const p = parts[i];\r\n          // SP is barred here via a local check but never added to isSpaceGlyph\r\n          // (the {TSP,QSP} classifier), per feedback_zsa_is_content_not_space.\r\n          if (p.codeName === 'SP' || isSpaceGlyph(p.codeName)) {\r\n            misplaced.push(i);\r\n            continue;\r\n          }\r\n          remainderCount++;\r\n          if (!p.error && ((p.codeName && blissElementDefinitions[p.codeName]) || p.parts?.length > 0)) {\r\n            knownRemainder = true;\r\n          }\r\n        }\r\n        if (misplaced.length === 0) continue;\r\n        if (remainderCount > 0 && !knownRemainder) continue;\r\n        for (const i of misplaced) {\r\n          const p = parts[i];\r\n          const coords = p.x !== undefined || p.y !== undefined ? `:${p.x ?? 0},${p.y ?? 0}` : '';\r\n          const source = `${p.codeName}${coords}`;\r\n          this.#mutationWarnings.push({\r\n            code: WARNING_CODES.MISPLACED_SPACE,\r\n            message: `A space is a word separator, not a character part, so \"${source}\" was dropped.`,\r\n            source,\r\n          });\r\n        }\r\n        for (let k = misplaced.length - 1; k >= 0; k--) {\r\n          parts.splice(misplaced[k], 1);\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  // Indicator-sequence invariant (row 67): an indicator part is only\r\n  // meaningful inside the maximal trailing indicator run of its glyph's part\r\n  // list (the character's indicator row: BASE;INDICATOR). An indicator that\r\n  // precedes default-positioned known content is a misplaced decoration:\r\n  // dropped LOUDLY (MISPLACED_INDICATOR_PART) from render and serialization,\r\n  // the warn+drop model of MISPLACED_HEAD_MARKER and\r\n  // MISPLACED_SPACE_DECORATION, while the character still renders. Three\r\n  // deliberate exemptions:\r\n  //  1. Content explicitly positioned at a non-origin `:x,y` does not convict\r\n  //     a preceding indicator: a compound indicator's decomposed serialization\r\n  //     (`B86;SDOT:3,4`) is hand-placed anatomy and must round-trip\r\n  //     (composition portability). An origin `:0,0` counts as\r\n  //     default-positioned because serialization drops it, so it could not\r\n  //     carry the exemption across a round-trip.\r\n  //  2. A part whose nature is uncertain (unknown code awaiting a definition,\r\n  //     or a malformed error node) is no witness: the character already\r\n  //     fail-renders, and dropping on uncertainty would destroy input the\r\n  //     unknown-code retention contract keeps.\r\n  //  3. A compound-indicator glyph (glyph-level isIndicator) is an atomic\r\n  //     unit whose internal anatomy is definition-owned.\r\n  // Enforced here, the chokepoint every input surface and mutation route\r\n  // passes through (see #normalizeSpaceInvariant above for the rationale).\r\n  #normalizeIndicatorInvariant() {\r\n    for (const group of this.#rawBlissObj.groups ?? []) {\r\n      if (group.errorCode) continue;\r\n      for (const glyph of group.glyphs ?? []) {\r\n        if (glyph.isIndicator === true) continue;\r\n        const parts = glyph.parts;\r\n        if (!Array.isArray(parts) || parts.length < 2) continue;\r\n        let lastWitness = -1;\r\n        for (let i = parts.length - 1; i >= 1 && lastWitness === -1; i--) {\r\n          const p = parts[i];\r\n          if (p.isIndicator === true || p.error) continue;\r\n          if ((p.x ?? 0) !== 0 || (p.y ?? 0) !== 0) continue;\r\n          if ((p.codeName && blissElementDefinitions[p.codeName]) || p.parts?.length > 0) {\r\n            lastWitness = i;\r\n          }\r\n        }\r\n        if (lastWitness === -1) continue;\r\n        const misplaced = [];\r\n        for (let i = 0; i < lastWitness; i++) {\r\n          if (parts[i].isIndicator === true) misplaced.push(i);\r\n        }\r\n        for (const i of misplaced) {\r\n          const p = parts[i];\r\n          const coords = p.x !== undefined || p.y !== undefined ? `:${p.x ?? 0},${p.y ?? 0}` : '';\r\n          const source = `${p.codeName}${coords}`;\r\n          this.#mutationWarnings.push({\r\n            code: WARNING_CODES.MISPLACED_INDICATOR_PART,\r\n            message: `An indicator can only follow its base parts at the end of a character (BASE;INDICATOR), so \"${source}\" was dropped.`,\r\n            source,\r\n          });\r\n        }\r\n        for (let k = misplaced.length - 1; k >= 0; k--) {\r\n          parts.splice(misplaced[k], 1);\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  // Retention family (row 31): malformed SYNTAX is a parse-time warning, never\r\n  // persisted. A malformed part token is a pure error node (an `{error}` node\r\n  // with no codeName and no nested parts): `!` (Invalid format) or a code with\r\n  // an unparseable `:x,y` suffix (MALFORMED_COORDINATES). Dropping only the bad\r\n  // part would let a valid sibling collapse into a DIFFERENT valid character\r\n  // (the E->F hazard: `B291;!;B97` -> `B291;B97`), so the WHOLE character is\r\n  // dropped from render and BOTH serializations, keeping the parse-time warning\r\n  // as the only trace (no persisted `{error}` node). Exempt: an UNKNOWN code\r\n  // (`ZZ9`, a codeName that cannot yet resolve) is CONTENT, kept + warned\r\n  // (define it later and it renders); a word/composite misused as a part\r\n  // (WORD_AS_PART / COMPOSITE_AS_PART) carries a codeName or nested parts and\r\n  // re-emits visibly; a compound-indicator glyph (glyph-level isIndicator) is\r\n  // atomic. A fail-flagged word (group.errorCode) is dropped whole by\r\n  // #normalizeFailedWordInvariant, so its glyphs are skipped. Runs FIRST among\r\n  // the rebuild normalizers so a doomed glyph raises exactly one drop warning,\r\n  // not also a space-part or indicator warning.\r\n  #normalizeMalformedPartInvariant() {\r\n    for (const group of this.#rawBlissObj.groups ?? []) {\r\n      if (group.errorCode) continue;\r\n      const glyphs = group.glyphs;\r\n      if (!Array.isArray(glyphs)) continue;\r\n      const doomed = [];\r\n      for (let gi = 0; gi < glyphs.length; gi++) {\r\n        const glyph = glyphs[gi];\r\n        if (glyph.isIndicator === true) continue;\r\n        const parts = glyph.parts;\r\n        if (!Array.isArray(parts)) continue;\r\n        const errorParts = parts.filter(p => p.error && !p.codeName && !(p.parts?.length > 0));\r\n        if (errorParts.length === 0) continue;\r\n        for (const p of errorParts) {\r\n          // Mirror BlissElement's leaf-fail warning so the visibility survives\r\n          // the drop: a code with a bad `:x,y` suffix names the coordinate\r\n          // error, any other malformed token is UNKNOWN_CODE.\r\n          if (p.errorCode === WARNING_CODES.MALFORMED_COORDINATES) {\r\n            this.#mutationWarnings.push({ code: WARNING_CODES.MALFORMED_COORDINATES, message: p.error, source: p.error });\r\n          } else {\r\n            this.#mutationWarnings.push({ code: WARNING_CODES.UNKNOWN_CODE, message: `Unknown or invalid code: \"${p.error}\"`, source: p.error });\r\n          }\r\n        }\r\n        doomed.push(gi);\r\n      }\r\n      for (let k = doomed.length - 1; k >= 0; k--) glyphs.splice(doomed[k], 1);\r\n    }\r\n  }\r\n\r\n  // Retention family (row 80): a malformed word-level indicator (a doubled `;;`,\r\n  // or a `;;` bound to a multi-word alias) fails the WHOLE word at parse\r\n  // (group.errorCode = MALFORMED_WORD_INDICATOR, group.errorSource = the raw\r\n  // text). The failed word is not content: it is dropped from render and BOTH\r\n  // serializations, reserving no extent, and neither errorCode nor errorSource\r\n  // is persisted. The parse-time warning (formerly surfaced by the element's L1\r\n  // fail-render, gone with the group) is re-emitted here before the drop so it\r\n  // survives; the drop makes the sweep warn once, not per rebuild. Runs before\r\n  // #normalizeSpaceInvariant so its adjacent-space merge sees the post-drop\r\n  // layout (a dropped middle word can leave two neighbor spaces).\r\n  #normalizeFailedWordInvariant() {\r\n    const groups = this.#rawBlissObj.groups;\r\n    if (!Array.isArray(groups)) return;\r\n    const survivors = [];\r\n    for (const group of groups) {\r\n      if (group.errorCode) {\r\n        this.#mutationWarnings.push({\r\n          code: group.errorCode,\r\n          message: group.error,\r\n          source: group.errorSource,\r\n        });\r\n        continue;\r\n      }\r\n      survivors.push(group);\r\n    }\r\n    if (survivors.length !== groups.length) this.#rawBlissObj.groups = survivors;\r\n  }\r\n\r\n  #rebuild() {\r\n    this.#generation++;\r\n    this.#elementsCache = undefined;\r\n    this.#groupsCache = undefined;\r\n    this.#warnings = [];\r\n\r\n    this.#normalizeMalformedPartInvariant();\r\n    this.#normalizeFailedWordInvariant();\r\n    this.#normalizeSpacePartInvariant();\r\n    this.#normalizeSpaceInvariant();\r\n    this.#normalizeIndicatorInvariant();\r\n    BlissSVGBuilder.#assignKeys(this.#rawBlissObj);\r\n\r\n    // Re-derive position-dependent composite-as-part flags on the AUTHORING\r\n    // structure (#rawBlissObj), before the render clone: a mutation (insertPart\r\n    // via its `H;<code>` scaffold, removePart) can move a part to/from the\r\n    // leading slot, staling the parse-time flag. Serialization reads\r\n    // #rawBlissObj, so the flag must be accurate there, not only on the clone:\r\n    // a genuinely-failed part re-emits by its written name (row 80) while a\r\n    // legal leading alias re-flattens. reflag only touches error/errorCode (no\r\n    // expansion), so it is safe on the base-only structure; the clone inherits.\r\n    BlissParser.reflagCompositeParts(this.#rawBlissObj);\r\n    const blissObj = structuredClone(this.#rawBlissObj);\r\n\r\n    // R14 resolve site 1 (render): merge each group's word-level indicator\r\n    // overlay onto its head glyph, on the clone only so #rawBlissObj (and the\r\n    // handles that reference it) stay base-only. The head is the explicitly\r\n    // marked glyph (isHeadGlyph), else the query-time fallback (R15 WS-4) so a\r\n    // structural mutation re-derives it instead of floating onto a stale stamp.\r\n    for (const group of blissObj.groups ?? []) {\r\n      if (group.wordIndicators && group.glyphs?.length) {\r\n        const headIndex = resolveOverlayHeadIndex(group.glyphs);\r\n        // Every glyph is empty: nothing can carry the rendered overlay. The\r\n        // stored overlay persists (F3 pure-state contract) but renders\r\n        // nothing, exactly like the reparse of the serialized form.\r\n        if (headIndex === -1) continue;\r\n        const head = group.glyphs[headIndex];\r\n        // The overlay stores code STRINGS (SIB-2); this render-merge parse is\r\n        // where a definition-baked misplacement (e.g. a global-only option\r\n        // key inside an indicator definition) first becomes observable, so\r\n        // its parse warnings must reach builder.warnings. #warnings was reset\r\n        // above, so they re-derive per rebuild instead of accumulating.\r\n        head.parts = mergeWordIndicatorsOntoHead(\r\n          head, group.wordIndicators, blissElementDefinitions, (code) => {\r\n            const parsed = BlissParser.parse(code);\r\n            this.#warnings.push(...(parsed._parseWarnings ?? []));\r\n            return parsed;\r\n          }\r\n        );\r\n      }\r\n    }\r\n\r\n    this.#processAllOptions(blissObj, true);\r\n\r\n    const { charSpace, wordSpace, externalGlyphSpace, errorPlaceholder, ...remainingOptions } = blissObj.options ?? {};\r\n    this.#sharedOptions = {\r\n      charSpace: charSpace ?? 2,\r\n      wordSpace: wordSpace ?? 8,\r\n      externalGlyphSpace: externalGlyphSpace ?? 0.8,\r\n      warnings: this.#warnings,\r\n      errorPlaceholder: errorPlaceholder === true,\r\n      errorPlaceholderParts: ERROR_PLACEHOLDER_PARTS,\r\n      keys: new Set(),\r\n    };\r\n    if (blissObj._parseWarnings) {\r\n      this.#warnings.push(...blissObj._parseWarnings);\r\n      delete blissObj._parseWarnings;\r\n    }\r\n    blissObj.options = remainingOptions;\r\n    this.#processedOptions = blissObj.options;\r\n\r\n    const attrMap = { 'color': 'stroke' };\r\n    this.globalSvgAttributes = {};\r\n    for (const [key, value] of Object.entries(blissObj.options ?? {})) {\r\n      if (!INTERNAL_OPTIONS.has(key) && isSafeAttributeName(key)) {\r\n        this.globalSvgAttributes[attrMap[key] || camelToKebab(key)] = value;\r\n      }\r\n    }\r\n\r\n    this.composition = new BlissElement(blissObj, { sharedOptions: this.#sharedOptions });\r\n  }\r\n\r\n  /**\r\n   * Returns warnings generated during parsing/rendering, followed by any\r\n   * one-time mutation warnings (e.g. an overlay dropped by mergeWithNext).\r\n   * Each warning has { code, message, source } describing the issue.\r\n   * @returns {Array<{ code: string, message: string, source: string }>}\r\n   */\r\n  get warnings() {\r\n    return [...this.#warnings, ...this.#mutationWarnings];\r\n  }\r\n\r\n  #elementsCache;\r\n\r\n  /**\r\n   * Returns the root element snapshot — a frozen tree of all element data.\r\n   * Cached on first access (builder instances are immutable).\r\n   *\r\n   * @returns {ElementSnapshot} Frozen root snapshot with nested children\r\n   */\r\n  get elements() {\r\n    if (!this.#elementsCache) {\r\n      this.#elementsCache = this.composition.snapshot();\r\n    }\r\n    return this.#elementsCache;\r\n  }\r\n\r\n  /**\r\n   * Depth-first traversal of all element snapshots.\r\n   * Return false from the callback to stop traversal early.\r\n   *\r\n   * @param {function(ElementSnapshot): boolean|void} callback\r\n   */\r\n  traverse(callback) {\r\n    function walk(el) {\r\n      if (callback(el) === false) return false;\r\n      for (const child of el.children) {\r\n        if (walk(child) === false) return false;\r\n      }\r\n    }\r\n    walk(this.elements);\r\n  }\r\n\r\n  /**\r\n   * Find all element snapshots matching a predicate.\r\n   *\r\n   * @param {function(ElementSnapshot): boolean} predicate\r\n   * @returns {ElementSnapshot[]}\r\n   */\r\n  query(predicate) {\r\n    const results = [];\r\n    this.traverse(el => { if (predicate(el)) results.push(el); });\r\n    return results;\r\n  }\r\n\r\n  /**\r\n   * Look up an element by its snapshot key, returning a live ElementHandle.\r\n   *\r\n   * @param {string} key\r\n   * @returns {ElementHandle|null}\r\n   */\r\n  getElementByKey(key) {\r\n    const snap = this.snapshot();\r\n    const groups = snap.children;\r\n    const rawGroups = this.#rawBlissObj.groups;\r\n\r\n    // Walk snapshot tree in parallel with raw groups\r\n    for (let rawGi = 0; rawGi < groups.length; rawGi++) {\r\n      const groupSnap = groups[rawGi];\r\n      const rawGroup = rawGroups[rawGi];\r\n\r\n      if (groupSnap.key === key) {\r\n        return new ElementHandle(this.#mutationCtx, 1, rawGroup);\r\n      }\r\n\r\n      const glyphs = groupSnap.children.filter(c => c.isGlyph);\r\n      for (let gi = 0; gi < glyphs.length; gi++) {\r\n        const rawGlyph = rawGroup.glyphs[gi];\r\n        if (glyphs[gi].key === key) {\r\n          return new ElementHandle(this.#mutationCtx, 2, rawGlyph, rawGroup);\r\n        }\r\n        const parts = glyphs[gi].children;\r\n        for (let pi = 0; pi < parts.length; pi++) {\r\n          if (parts[pi].key === key) {\r\n            // Match the raw part by key, not snapshot position: a `;;` head's\r\n            // snapshot carries an extra overlay-injected indicator part with no\r\n            // raw node. Match-by-key keeps base parts addressable and returns\r\n            // null for the overlay part (it lives only in the resolved tree).\r\n            const rawPart = rawGlyph.parts.find(rp => rp.key === key);\r\n            return rawPart\r\n              ? new ElementHandle(this.#mutationCtx, 3, rawPart, { group: rawGroup, glyph: rawGlyph })\r\n              : null;\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n\r\n  // --- Live Navigation ---\r\n\r\n  #getNonSpaceGroupIndices() {\r\n    const indices = [];\r\n    const groups = this.#rawBlissObj.groups || [];\r\n    for (let i = 0; i < groups.length; i++) {\r\n      if (!BlissSVGBuilder.#isRawSpaceGroup(groups[i])) {\r\n        indices.push(i);\r\n      }\r\n    }\r\n    return indices;\r\n  }\r\n\r\n  /**\r\n   * Returns a live ElementHandle for the non-space group at the given index.\r\n   * @param {number} index\r\n   * @returns {ElementHandle|null}\r\n   */\r\n  group(index) {\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n    if (index < 0) index = indices.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= indices.length) return null;\r\n    const rawGroup = this.#rawBlissObj.groups[indices[index]];\r\n    return new ElementHandle(this.#mutationCtx, 1, rawGroup);\r\n  }\r\n\r\n  /**\r\n   * Returns a live ElementHandle for any group (including spaces) at the given raw index.\r\n   * @param {number} index - Raw index (supports negative: -1 = last)\r\n   * @returns {ElementHandle|null}\r\n   */\r\n  element(index) {\r\n    const groups = this.#rawBlissObj.groups;\r\n    if (index < 0) index = groups.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= groups.length) return null;\r\n    return new ElementHandle(this.#mutationCtx, 1, groups[index]);\r\n  }\r\n\r\n  /**\r\n   * Total number of raw groups (including space groups).\r\n   * @returns {number}\r\n   */\r\n  get elementCount() {\r\n    return this.#rawBlissObj.groups.length;\r\n  }\r\n\r\n  /**\r\n   * Returns a live ElementHandle for the glyph at the given flat index across all groups.\r\n   * @param {number} flatIndex\r\n   * @returns {ElementHandle|null}\r\n   */\r\n  glyph(flatIndex) {\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n    if (flatIndex < 0) {\r\n      let total = 0;\r\n      for (const gi of indices) {\r\n        total += (this.#rawBlissObj.groups[gi].glyphs || []).length;\r\n      }\r\n      flatIndex = total + flatIndex;\r\n    }\r\n    if (!Number.isInteger(flatIndex) || flatIndex < 0) return null;\r\n    let count = 0;\r\n    for (const gi of indices) {\r\n      const group = this.#rawBlissObj.groups[gi];\r\n      const glyphs = group.glyphs || [];\r\n      if (flatIndex < count + glyphs.length) {\r\n        return new ElementHandle(this.#mutationCtx, 2, glyphs[flatIndex - count], group);\r\n      }\r\n      count += glyphs.length;\r\n    }\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * Returns a live ElementHandle for the part at the given flat index across all glyphs.\r\n   * @param {number} flatIndex\r\n   * @returns {ElementHandle|null}\r\n   */\r\n  part(flatIndex) {\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n    if (flatIndex < 0) {\r\n      let total = 0;\r\n      for (const gi of indices) {\r\n        for (const glyph of (this.#rawBlissObj.groups[gi].glyphs || [])) {\r\n          total += (glyph.parts || []).length;\r\n        }\r\n      }\r\n      flatIndex = total + flatIndex;\r\n    }\r\n    if (!Number.isInteger(flatIndex) || flatIndex < 0) return null;\r\n    let count = 0;\r\n    for (const gi of indices) {\r\n      const group = this.#rawBlissObj.groups[gi];\r\n      const glyphs = group.glyphs || [];\r\n      for (const glyph of glyphs) {\r\n        const parts = glyph.parts || [];\r\n        if (flatIndex < count + parts.length) {\r\n          return new ElementHandle(this.#mutationCtx, 3, parts[flatIndex - count], { group, glyph });\r\n        }\r\n        count += parts.length;\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * Returns a frozen snapshot of the element tree.\r\n   * @returns {ElementSnapshot}\r\n   */\r\n  snapshot() {\r\n    return this.elements;\r\n  }\r\n\r\n  // --- Builder Convenience Methods ---\r\n\r\n  /**\r\n   * Appends a new glyph group with automatic space management.\r\n   * @param {string} [code] - DSL code string; empty, whitespace-only, or omitted appends an empty group\r\n   * @param {Object | { defaults?: Object, overrides?: Object }} [opts]\r\n   * @returns {this}\r\n   */\r\n  addGroup(code, opts) {\r\n    assertCodeArg('addGroup', code);\r\n    assertOptsArg('addGroup', opts);\r\n    const nonSpaceCount = this.#getNonSpaceGroupIndices().length;\r\n    return this.insertGroup(nonSpaceCount, code, opts);\r\n  }\r\n\r\n  /**\r\n   * Inserts a new glyph group at the given semantic (non-space) index\r\n   * with automatic space management.\r\n   * @param {number} index - Semantic non-space group index\r\n   * @param {string} [code] - DSL code string; empty, whitespace-only, or omitted inserts an empty group\r\n   * @param {Object | { defaults?: Object, overrides?: Object }} [opts]\r\n   * @returns {this}\r\n   */\r\n  insertGroup(index, code, opts) {\r\n    assertCodeArg('insertGroup', code);\r\n    assertOptsArg('insertGroup', opts);\r\n    if (!Number.isInteger(index)) return this;\r\n    const newGroup = this.#parseGroupWithOpts(code, opts);\r\n    const groups = this.#rawBlissObj.groups;\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n\r\n    if (groups.length === 0 || indices.length === 0) {\r\n      // Empty — just push, no spaces needed\r\n      groups.push(newGroup);\r\n    } else if (index <= 0) {\r\n      // Insert at start: [newGroup, space, ...existing]\r\n      groups.splice(0, 0, newGroup, BlissSVGBuilder.#makeSpaceGroup());\r\n    } else if (index >= indices.length) {\r\n      // Insert at end: [...existing, space, newGroup]\r\n      groups.push(BlissSVGBuilder.#makeSpaceGroup());\r\n      groups.push(newGroup);\r\n    } else {\r\n      // Insert in middle: before the target raw index, add [space, newGroup]\r\n      const rawIndex = indices[index];\r\n      groups.splice(rawIndex, 0, newGroup, BlissSVGBuilder.#makeSpaceGroup());\r\n    }\r\n\r\n    this.#rebuild();\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Appends a glyph to the last non-space group (creates one if empty).\r\n   * An omitted, empty, or whitespace-only code appends an empty glyph.\r\n   * @param {string} [code] - DSL code string\r\n   * @param {Object | { defaults?: Object, overrides?: Object }} [opts]\r\n   * @returns {this}\r\n   */\r\n  addGlyph(code, opts) {\r\n    assertCodeArg('addGlyph', code);\r\n    assertOptsArg('addGlyph', opts);\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n    if (indices.length === 0) {\r\n      // Empty builder: validate at glyph level FIRST. The scaffold group is\r\n      // attached only after the handle call succeeds, so a rejected arg\r\n      // leaves the builder untouched, and opts land at glyph level exactly\r\n      // as they do on a non-empty builder.\r\n      const newGroup = { glyphs: [] };\r\n      new ElementHandle(this.#mutationCtx, 1, newGroup).addGlyph(code, opts);\r\n      this.#rawBlissObj.groups.push(newGroup);\r\n      this.#rebuild();\r\n      return this;\r\n    }\r\n    const lastGi = indices[indices.length - 1];\r\n    const rawGroup = this.#rawBlissObj.groups[lastGi];\r\n    const handle = new ElementHandle(this.#mutationCtx, 1, rawGroup);\r\n    handle.addGlyph(code, opts);\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Appends a part to the last non-space group's last glyph (on an empty\r\n   * document, creates the group and a glyph around the part).\r\n   * A part references a shape, so an omitted or empty code throws;\r\n   * use addGlyph('') to reserve an empty slot instead.\r\n   * @param {string} code - DSL code string resolving to exactly one part\r\n   * @param {Object | { defaults?: Object, overrides?: Object }} [opts]\r\n   * @returns {this}\r\n   */\r\n  addPart(code, opts) {\r\n    assertCodeArg('addPart', code);\r\n    assertOptsArg('addPart', opts);\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n    if (indices.length === 0) {\r\n      // Empty builder: validate at part level FIRST. The scaffold group is\r\n      // attached only after the handle call succeeds, so a rejected arg\r\n      // leaves the builder untouched, and opts land at part level exactly\r\n      // as they do on a non-empty builder.\r\n      const newGroup = { glyphs: [] };\r\n      new ElementHandle(this.#mutationCtx, 1, newGroup).addPart(code, opts);\r\n      this.#rawBlissObj.groups.push(newGroup);\r\n      this.#rebuild();\r\n      return this;\r\n    }\r\n    const lastGi = indices[indices.length - 1];\r\n    const rawGroup = this.#rawBlissObj.groups[lastGi];\r\n    const handle = new ElementHandle(this.#mutationCtx, 1, rawGroup);\r\n    handle.addPart(code, opts);\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Removes the non-space group at the given semantic index.\r\n   * @param {number} index - Semantic index (supports negative)\r\n   * @returns {this}\r\n   */\r\n  removeGroup(index) {\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n    if (index < 0) index = indices.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= indices.length) return this;\r\n    const rawIndex = indices[index];\r\n    this.#removeGlyphGroup(this.#rawBlissObj, rawIndex);\r\n    this.#rebuild();\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Replaces the non-space group at the given semantic index.\r\n   * @param {number} index - Semantic index (supports negative)\r\n   * @param {string} [code] - DSL code string; empty, whitespace-only, or omitted swaps in an empty group\r\n   * @param {Object | { defaults?: Object, overrides?: Object }} [opts]\r\n   * @returns {this}\r\n   */\r\n  replaceGroup(index, code, opts) {\r\n    assertCodeArg('replaceGroup', code);\r\n    assertOptsArg('replaceGroup', opts);\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n    if (index < 0) index = indices.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= indices.length) return this;\r\n    const newGroup = this.#parseGroupWithOpts(code, opts);\r\n    const rawIndex = indices[index];\r\n    this.#rawBlissObj.groups[rawIndex] = newGroup;\r\n    this.#rebuild();\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Merges another builder's content into this one. Appends the other\r\n   * builder's word groups (with a space group between) and discards\r\n   * its global options. The other builder is not modified.\r\n   *\r\n   * @param {BlissSVGBuilder} other\r\n   * @returns {this}\r\n   */\r\n  merge(other) {\r\n    if (!other || typeof other.toJSON !== 'function') {\r\n      throw new Error('merge() requires a BlissSVGBuilder instance');\r\n    }\r\n\r\n    const otherRaw = other.toJSON({ deep: true });\r\n    const otherGroups = otherRaw.groups;\r\n    if (!otherGroups || otherGroups.length === 0) return this;\r\n\r\n    // Filter out groups that are only spaces (no real content)\r\n    const hasContent = otherGroups.some(\r\n      g => !BlissSVGBuilder.#isRawSpaceGroup(g)\r\n    );\r\n    if (!hasContent) return this;\r\n\r\n    // Re-ingest toJSON output into internal format (same order as constructor)\r\n    BlissParser.expandParts({ groups: otherGroups });\r\n    BlissSVGBuilder.#normalizeGlyphCodes(otherGroups);\r\n    // Parity with the constructor's object-ingest: a partless glyph node\r\n    // normalizes to the first-class empty glyph. A no-op today (a builder's\r\n    // toJSON never emits a bare partless node, it emits `{ parts: [] }`), so\r\n    // this only guards a future toJSON shape or re-ingest path from re-opening\r\n    // the phantom-advance defect the constructor pass already closes.\r\n    BlissSVGBuilder.#normalizePartlessGlyphs(otherGroups);\r\n    BlissSVGBuilder.#flagWordParts({ groups: otherGroups });\r\n\r\n    const groups = this.#rawBlissObj.groups;\r\n\r\n    // Insert space before appended content if this builder has content\r\n    const hasExisting = groups.some(\r\n      g => !BlissSVGBuilder.#isRawSpaceGroup(g)\r\n    );\r\n    if (hasExisting) {\r\n      groups.push(BlissSVGBuilder.#makeSpaceGroup());\r\n    }\r\n\r\n    groups.push(...otherGroups);\r\n    this.#rebuild();\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Splits this builder into two at the given non-space group boundary.\r\n   * This builder keeps groups 0 through groupIndex-1. A new builder is\r\n   * returned with groups from groupIndex onward. Both builders share the\r\n   * same global options. Space groups at the split boundary are consumed.\r\n   *\r\n   * @param {number} groupIndex - Non-space group index (1 to groupCount-1)\r\n   * @returns {BlissSVGBuilder} New builder with the right-half groups\r\n   */\r\n  splitAt(groupIndex) {\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n    if (indices.length < 2) {\r\n      throw new Error('splitAt() requires at least 2 groups');\r\n    }\r\n    if (!Number.isInteger(groupIndex) || groupIndex <= 0 || groupIndex >= indices.length) {\r\n      throw new Error(\r\n        `splitAt(${groupIndex}) is out of range: must be between 1 and ${indices.length - 1} (inclusive) for a builder with ${indices.length} groups`\r\n      );\r\n    }\r\n\r\n    // Find the raw index of the split point\r\n    const rawSplitIndex = indices[groupIndex];\r\n\r\n    // Extract right-half groups (from rawSplitIndex onward)\r\n    const rightGroups = this.#rawBlissObj.groups.splice(rawSplitIndex);\r\n\r\n    // Clean up: remove trailing space groups from the left half\r\n    while (\r\n      this.#rawBlissObj.groups.length > 0 &&\r\n      BlissSVGBuilder.#isRawSpaceGroup(\r\n        this.#rawBlissObj.groups[this.#rawBlissObj.groups.length - 1]\r\n      )\r\n    ) {\r\n      this.#rawBlissObj.groups.pop();\r\n    }\r\n\r\n    // Clean up: remove leading space groups from the right half\r\n    while (\r\n      rightGroups.length > 0 &&\r\n      BlissSVGBuilder.#isRawSpaceGroup(rightGroups[0])\r\n    ) {\r\n      rightGroups.shift();\r\n    }\r\n\r\n    // Rebuild the left half (this builder)\r\n    this.#rebuild();\r\n\r\n    // Build the right half as a new builder\r\n    // Copy global options so both builders have the same styling\r\n    const rightObj = {\r\n      groups: rightGroups,\r\n    };\r\n    if (this.#rawBlissObj.options) {\r\n      rightObj.options = { ...this.#rawBlissObj.options };\r\n    }\r\n\r\n    return new BlissSVGBuilder(rightObj);\r\n  }\r\n\r\n  /**\r\n   * Parses a code string into exactly one group and applies option layers.\r\n   * An omitted, empty, or whitespace-only code yields an empty group.\r\n   *\r\n   * An accepted arg's parse-time warnings (a misplaced option, head marker, or\r\n   * word indicator) forward to the persistent mutation channel: they live on\r\n   * no node, so unlike a kept UNKNOWN_CODE they never re-derive at rebuild and\r\n   * would otherwise vanish. Forwarded last (after the opts resolve), so a\r\n   * rejected code or bad opts leaks nothing, matching the handle family's\r\n   * #forwardParseWarnings accept-only rule.\r\n   * @param {string} [code]\r\n   * @param {Object | { defaults?: Object, overrides?: Object }} [opts]\r\n   * @returns {object} parsed group\r\n   */\r\n  #parseGroupWithOpts(code, opts) {\r\n    let newGroup;\r\n    let parseWarnings;\r\n    if (code === undefined || code.trim() === '') {\r\n      // \"Add a group with nothing in it\" is meaningful: '' is the DSL\r\n      // counterpart of the already-valid {glyphs: []} object state.\r\n      newGroup = { glyphs: [] };\r\n    } else {\r\n      const parsed = BlissParser.parse(code);\r\n      const groupCount = parsed.groups?.length ?? 0;\r\n      if (groupCount !== 1) {\r\n        throw new Error(`Expected a single group, but code \"${code}\" produced ${groupCount} groups`);\r\n      }\r\n      // Document-level options have no home on a single group: the same\r\n      // string given to the constructor would style the whole document, so\r\n      // stripping them here would be silent loss. An empty \"||\" prefix sets\r\n      // no options and stays plain content.\r\n      if (Object.keys(parsed.options ?? {}).length > 0) {\r\n        throw new Error(`Code \"${code}\" carries document-level options (\"[opts]||\"). Set document options on the builder input, or style the group itself (\"[opts]|\" in the code or the opts parameter)`);\r\n      }\r\n      newGroup = parsed.groups[0];\r\n      parseWarnings = parsed._parseWarnings;\r\n    }\r\n    if (opts) {\r\n      const { defaults, overrides } = BlissSVGBuilder.#resolveOpts(opts);\r\n      if (defaults || overrides) {\r\n        const rawDefaults = defaults ? BlissSVGBuilder.#toRaw(defaults) : {};\r\n        const rawOverrides = overrides ? BlissSVGBuilder.#toRaw(overrides) : {};\r\n        const merged = { ...rawDefaults, ...(newGroup.options ?? {}), ...rawOverrides };\r\n        // An empty opts (e.g. {}) resolves to no keys: don't stamp a bare\r\n        // options:{} onto the group, which would be toJSON noise.\r\n        if (Object.keys(merged).length > 0) newGroup.options = merged;\r\n      }\r\n    }\r\n    if (parseWarnings?.length) this.#mutationWarnings.push(...parseWarnings);\r\n    return newGroup;\r\n  }\r\n\r\n  // --- Raw Element CRUD (no automatic space management) ---\r\n\r\n  /**\r\n   * Appends a raw group with no automatic space management.\r\n   * @param {string} [code] - DSL code string; empty, whitespace-only, or omitted appends an empty group\r\n   * @param {Object | { defaults?: Object, overrides?: Object }} [opts]\r\n   * @returns {this}\r\n   */\r\n  addElement(code, opts) {\r\n    assertCodeArg('addElement', code);\r\n    assertOptsArg('addElement', opts);\r\n    const newGroup = this.#parseGroupWithOpts(code, opts);\r\n    this.#rawBlissObj.groups.push(newGroup);\r\n    this.#rebuild();\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Inserts a raw group at the given index with no automatic space management.\r\n   * @param {number} index - Raw index (supports negative: -1 = before last)\r\n   * @param {string} [code] - DSL code string; empty, whitespace-only, or omitted inserts an empty group\r\n   * @param {Object | { defaults?: Object, overrides?: Object }} [opts]\r\n   * @returns {this}\r\n   */\r\n  insertElement(index, code, opts) {\r\n    assertCodeArg('insertElement', code);\r\n    assertOptsArg('insertElement', opts);\r\n    if (!Number.isInteger(index)) return this;\r\n    const newGroup = this.#parseGroupWithOpts(code, opts);\r\n    const groups = this.#rawBlissObj.groups;\r\n    if (index < 0) index = groups.length + index;\r\n    if (index < 0) index = 0;\r\n    if (index >= groups.length) {\r\n      groups.push(newGroup);\r\n    } else {\r\n      groups.splice(index, 0, newGroup);\r\n    }\r\n    this.#rebuild();\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Removes the raw group at the given index (plain splice, no space cleanup).\r\n   * @param {number} index - Raw index (supports negative: -1 = last)\r\n   * @returns {this}\r\n   */\r\n  removeElement(index) {\r\n    const groups = this.#rawBlissObj.groups;\r\n    if (index < 0) index = groups.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= groups.length) return this;\r\n    groups.splice(index, 1);\r\n    this.#rebuild();\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Replaces the raw group at the given index with new content.\r\n   * @param {number} index - Raw index (supports negative: -1 = last)\r\n   * @param {string} [code] - DSL code string; empty, whitespace-only, or omitted swaps in an empty group\r\n   * @param {Object | { defaults?: Object, overrides?: Object }} [opts]\r\n   * @returns {this}\r\n   */\r\n  replaceElement(index, code, opts) {\r\n    assertCodeArg('replaceElement', code);\r\n    assertOptsArg('replaceElement', opts);\r\n    const groups = this.#rawBlissObj.groups;\r\n    if (index < 0) index = groups.length + index;\r\n    if (!Number.isInteger(index) || index < 0 || index >= groups.length) return this;\r\n    const newGroup = this.#parseGroupWithOpts(code, opts);\r\n    groups[index] = newGroup;\r\n    this.#rebuild();\r\n    return this;\r\n  }\r\n\r\n  /**\r\n   * Removes all content from the builder.\r\n   * @returns {this}\r\n   */\r\n  clear() {\r\n    this.#rawBlissObj.groups = [];\r\n    this.#rebuild();\r\n    return this;\r\n  }\r\n\r\n  #groupsCache;\r\n\r\n  /**\r\n   * Returns non-space group snapshots.\r\n   * Cached and frozen.\r\n   *\r\n   * @returns {ElementSnapshot[]}\r\n   */\r\n  get groups() {\r\n    if (!this.#groupsCache) {\r\n      const groups = this.elements.children.filter(g =>\r\n        g.isGroup && !g.isSpaceGroup\r\n      );\r\n      this.#groupsCache = Object.freeze(groups);\r\n    }\r\n    return this.#groupsCache;\r\n  }\r\n\r\n  /**\r\n   * Returns group and glyph counts.\r\n   *\r\n   * @returns {{ groupCount: number, glyphCount: number }}\r\n   */\r\n  get stats() {\r\n    const indices = this.#getNonSpaceGroupIndices();\r\n    let glyphCount = 0;\r\n    for (const gi of indices) {\r\n      glyphCount += (this.#rawBlissObj.groups[gi].glyphs || []).length;\r\n    }\r\n    return { groupCount: indices.length, glyphCount };\r\n  }\r\n\r\n  // --- Manipulation helpers ---\r\n\r\n  // --- Word-as-part detection ---\r\n  // When a word definition (codeString with /) appears at the part level,\r\n  // the parser keeps it as a single codeName. This post-parse step marks\r\n  // those references with an error so BlissElement can emit a warning.\r\n\r\n  /**\r\n   * Reverse toJSON() normalization for object input:\r\n   *  - Glyph level: codeName → glyphCode rename.\r\n   *  - Glyphs and parts: surface text-fallback form 'X<chars>' → internal\r\n   *    routing key 'XTXT_<chars>' so BlissElement / parser routing works.\r\n   * @param {Object[]} groups - Array of raw group objects\r\n   */\r\n  static #normalizeGlyphCodes(groups) {\r\n    for (const group of groups) {\r\n      if (!group.glyphs) continue;\r\n      for (const glyph of group.glyphs) {\r\n        if (glyph.codeName && !glyph.glyphCode) {\r\n          glyph.glyphCode = BlissSVGBuilder.#textFallbackInternalForm(glyph.codeName);\r\n          delete glyph.codeName;\r\n        }\r\n        // Re-derive glyph-classification metadata that toJSON() omits (it is\r\n        // fully derived from the code, not authored). The element reads these\r\n        // directly and they round-trip external-glyph navigation/spacing, so\r\n        // restore them from the resolved code the same way the parser does.\r\n        BlissSVGBuilder.#reapplyGlyphMetadata(glyph);\r\n        if (glyph.parts) BlissSVGBuilder.#normalizePartCodes(glyph.parts);\r\n      }\r\n    }\r\n  }\r\n\r\n  static #normalizePartCodes(parts) {\r\n    for (const part of parts) {\r\n      if (part.codeName) {\r\n        part.codeName = BlissSVGBuilder.#textFallbackInternalForm(part.codeName);\r\n      }\r\n      if (part.parts) BlissSVGBuilder.#normalizePartCodes(part.parts);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Normalize a degenerate partless glyph node from object input to the\r\n   * first-class empty glyph. A glyph with no `parts` array and no code identity\r\n   * has no renderable content, but the element layer treats a partless glyph as\r\n   * a glyph-that-IS-one-part shorthand and wraps it, so `{}` became a failed\r\n   * part that warned UNKNOWN_CODE and reserved a phantom advance while\r\n   * `toString()` omitted it (svg round-trip false). Setting `parts: []` makes it\r\n   * render invisibly and match its omitting serialization, exactly like a\r\n   * `{ parts: [] }` node. Options and key survive (an `{ options: {...} }` node\r\n   * becomes an options-carrying empty glyph). Object input only; the DSL never\r\n   * produces a partless glyph node. Must run AFTER `#normalizeGlyphCodes`, which\r\n   * renames the code identity to `glyphCode`, so a `{ codeName: 'B291' }`\r\n   * shorthand keeps its identity and still renders (its `glyphCode` is set here).\r\n   */\r\n  static #normalizePartlessGlyphs(groups) {\r\n    for (const group of groups) {\r\n      if (!group.glyphs) continue;\r\n      for (const glyph of group.glyphs) {\r\n        if (!glyph.parts && !glyph.glyphCode) {\r\n          glyph.parts = [];\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  // 'X<chars>' (public text-fallback form) → 'XTXT_<chars>' (internal\r\n  // routing key). Built-in / registered codes (Xa, XL8, B431, …) and\r\n  // already-internal forms pass through unchanged.\r\n  static #textFallbackInternalForm(code) {\r\n    if (code.startsWith('XTXT_')) return code;\r\n    if (code.length < 2 || code[0] !== 'X') return code;\r\n    if (blissElementDefinitions[code]) return code;\r\n    return 'XTXT_' + code.slice(1);\r\n  }\r\n\r\n  // Re-derive glyph-classification metadata (isBlissGlyph / isExternalGlyph /\r\n  // char / kerningRules) from a glyph's resolved glyphCode. toJSON() omits these\r\n  // (they are pure derived data, not authored composition), so object input must\r\n  // restore them like the parser does on string input: a registered code copies\r\n  // them from its definition; a text-fallback 'XTXT_<chars>' derives them (a\r\n  // single char is that rendered glyph, multi-char is '' since it is text, not\r\n  // one glyph). A composite (no glyphCode) carries no glyph-level identity.\r\n  static #reapplyGlyphMetadata(glyph) {\r\n    const code = glyph.glyphCode;\r\n    if (!code) return;\r\n    const def = blissElementDefinitions[code];\r\n    if (def) {\r\n      if (def.isBlissGlyph) glyph.isBlissGlyph = true;\r\n      if (def.isExternalGlyph) glyph.isExternalGlyph = true;\r\n      if (typeof def.char === 'string') glyph.char = def.char;\r\n      if (def.kerningRules) glyph.kerningRules = def.kerningRules;\r\n    } else if (code.startsWith('XTXT_')) {\r\n      const chars = code.slice(5);\r\n      glyph.isExternalGlyph = true;\r\n      glyph.char = chars.length === 1 ? chars : '';\r\n      glyph.kerningRules = {};\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Walk a raw parsed structure and flag any word-as-part references.\r\n   * @param {Object} rawObj - Raw parsed blissObj with groups/glyphs/parts\r\n   */\r\n  static #flagWordParts(rawObj) {\r\n    if (!rawObj.groups) return;\r\n    for (const group of rawObj.groups) {\r\n      if (!group.glyphs) continue;\r\n      for (const glyph of group.glyphs) {\r\n        if (!glyph.parts) continue;\r\n        glyph.parts = BlissSVGBuilder.#flagWordPartsInArray(glyph.parts);\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Flag word-definition parts with an error. Recurses into nested parts.\r\n   */\r\n  static #flagWordPartsInArray(parts) {\r\n    const result = [];\r\n    for (const part of parts) {\r\n      const def = blissElementDefinitions[part.codeName];\r\n      if (def?.codeString?.includes('/')) {\r\n        part.error = `\"${part.codeName}\" is a word and cannot be composed with ;`;\r\n        part.errorCode = 'WORD_AS_PART';\r\n        result.push(part);\r\n      } else {\r\n        if (part.parts) {\r\n          part.parts = BlissSVGBuilder.#flagWordPartsInArray(part.parts);\r\n        }\r\n        result.push(part);\r\n      }\r\n    }\r\n    return result;\r\n  }\r\n\r\n  // Content-vs-whitespace classification: only TSP/QSP are spaces (the canonical\r\n  // set, shared with the element snapshot and toString via isSpaceGlyph). ZSA is\r\n  // an inkless positionable shape that counts, navigates, and serializes as\r\n  // content; SP is a parser-internal placeholder that never reaches a real tree.\r\n  // Drives group counting, navigation, word-splitting, and adjacent-space merges.\r\n  /** Returns true if a raw glyph node is a space glyph (one space-code part) */\r\n  static #isSpaceGlyphNode(glyph) {\r\n    return glyph.parts?.length === 1 && isSpaceGlyph(glyph.parts[0].codeName);\r\n  }\r\n\r\n  /** Returns true if a raw group is a space group */\r\n  static #isRawSpaceGroup(group) {\r\n    if (!group.glyphs || group.glyphs.length === 0) return false;\r\n    return group.glyphs.every(g => BlissSVGBuilder.#isSpaceGlyphNode(g));\r\n  }\r\n\r\n  // Head / word-indicator eligibility is BROADER than space classification: a\r\n  // ZSA counts as content but, like a space, can never be a word's head or carry\r\n  // a ;; overlay (the frozen parser's isSpacePart = {TSP,QSP,ZSA} rejects both).\r\n  // The rebuild normalizer strips a head/overlay a mutation or object input left\r\n  // on one so the tree stays reparse-valid.\r\n  static #NON_HEAD_MARKER_CODES = new Set(['TSP', 'QSP', 'ZSA']);\r\n\r\n  /** Returns true if a raw glyph node cannot be a word head (space or anchor). */\r\n  static #isNonHeadMarkerNode(glyph) {\r\n    return glyph.parts?.length === 1 && BlissSVGBuilder.#NON_HEAD_MARKER_CODES.has(glyph.parts[0].codeName);\r\n  }\r\n\r\n  /** Returns true if every glyph in a group is a non-head marker. */\r\n  static #isNonHeadMarkerGroup(group) {\r\n    return group.glyphs?.length > 0 && group.glyphs.every(g => BlissSVGBuilder.#isNonHeadMarkerNode(g));\r\n  }\r\n\r\n  // Option keys a space glyph keeps when its decorations are stripped: the\r\n  // runtime key (identity, re-assigned each rebuild) and kerning (RK/AK, which\r\n  // adjusts spacing between glyphs, a separate backlogged space-sizing concern).\r\n  static #SPACE_KEPT_OPTION_KEYS = new Set(['key', 'relativeKerning', 'absoluteKerning']);\r\n\r\n  /**\r\n   * Removes every non-internal option (a styling decoration) from a space's\r\n   * options object and returns a `[k=v;…]` representation of what was dropped,\r\n   * or null if there was nothing to drop. Kerning and the runtime key are\r\n   * spared. Mutates `options` in place.\r\n   */\r\n  static #dropSpaceOptions(options) {\r\n    if (!options) return null;\r\n    const keys = Object.keys(options).filter(k => !BlissSVGBuilder.#SPACE_KEPT_OPTION_KEYS.has(k));\r\n    if (keys.length === 0) return null;\r\n    const repr = '[' + keys.map(k => (options[k] === true ? k : `${k}=${options[k]}`)).join(';') + ']';\r\n    for (const k of keys) delete options[k];\r\n    return repr;\r\n  }\r\n\r\n  /** Creates a default space group for insertion between words */\r\n  static #makeSpaceGroup() {\r\n    return { glyphs: [{ parts: [{ codeName: 'TSP' }] }] };\r\n  }\r\n\r\n  /** Internal: removes a glyph group and its adjacent space from groups array */\r\n  #removeGlyphGroup(obj, groupIndex) {\r\n    const groups = obj.groups;\r\n    // Determine which space group to also remove\r\n    const prevIsSpace = groupIndex > 0 && BlissSVGBuilder.#isRawSpaceGroup(groups[groupIndex - 1]);\r\n    const nextIsSpace = groupIndex < groups.length - 1 && BlissSVGBuilder.#isRawSpaceGroup(groups[groupIndex + 1]);\r\n\r\n    if (prevIsSpace) {\r\n      // Remove space before + the word\r\n      groups.splice(groupIndex - 1, 2);\r\n    } else if (nextIsSpace) {\r\n      // Remove the word + space after\r\n      groups.splice(groupIndex, 2);\r\n    } else {\r\n      // No adjacent space, just remove the word\r\n      groups.splice(groupIndex, 1);\r\n    }\r\n    return obj;\r\n  }\r\n\r\n  /**\r\n   * Returns a portable DSL string. Custom codes are decomposed to built-in\r\n   * codes by default. `preserve` keeps a custom name that stands for a\r\n   * single glyph, indicator, or shape: every typed definition (whatever its\r\n   * anatomy) and every bare alias renaming one existing code; multi-code\r\n   * shorthand always serializes expanded.\r\n   *\r\n   * @param {Object} [options]\r\n   * @param {boolean} [options.preserve=false] - Keep custom glyph/shape code names\r\n   * @param {boolean} [options.flattenIndicators=false] - Collapse word-level (`;;`) indicators onto the head as character-level `;`\r\n   * @returns {string}\r\n   */\r\n  toString(options = {}) {\r\n    // toString always needs nested parts so serializeParts can decompose\r\n    // custom codes. The string output itself stays flat (;-delimited).\r\n    const obj = this.toJSON({ preserve: options.preserve, deep: true, flattenIndicators: options.flattenIndicators });\r\n\r\n    const GLYPH_INTERNAL_KEYS = new Set(['relativeKerning', 'absoluteKerning']);\r\n\r\n    // Serialize a part with ; delimiter and :x,y positions.\r\n    // Recursively decomposes custom shapes and glyphs unless preserve is set.\r\n    function serializeParts(parts, offsetX = 0, offsetY = 0) {\r\n      return parts.map((part, partIndex) => {\r\n        // An invalid part (no codeName, e.g. the `!B81` in `B291;[x=2]>!B81`)\r\n        // must not let a coordinate suffix or `[opts]>` prefix decorate it into\r\n        // a truthy literal-`undefined` string; drop it before decoration. It\r\n        // already warned UNKNOWN_CODE at parse. (F3.)\r\n        if (!part.codeName) return '';\r\n        const x = (part.x ?? 0) + offsetX;\r\n        const y = (part.y ?? 0) + offsetY;\r\n        // Under preserve a BASE-slot custom name with `;`-siblings still\r\n        // decomposes when the name is a bare alias: a bare-alias base drops\r\n        // its appended parts on reparse (strict separation), so emitting the\r\n        // name would silently shed the siblings. A typed custom base keeps\r\n        // its name (a typed base dumb-appends on reparse).\r\n        const isBareAliasBase = options.preserve && partIndex === 0 && parts.length > 1\r\n          && BlissSVGBuilder.#isBareAliasDefinition(blissElementDefinitions[part.codeName]);\r\n        // A failed part (COMPOSITE_AS_PART keeps its expanded `.parts`) must\r\n        // re-emit by its written name, never decomposed: decomposing a\r\n        // composite alias (`_X` -> `B291;B81`) changes what the warned string\r\n        // re-parses to (the buried baked indicator resurfaces, the whole-char\r\n        // failure becomes a different valid character). preserve already keeps\r\n        // the name; this makes default agree. (Row 80.) WORD_AS_PART has no\r\n        // `.parts`, so it already round-tripped; the guard just unifies them.\r\n        if ((!options.preserve || isBareAliasBase)\r\n            && !builtInCodes.has(part.codeName) && !part.errorCode) {\r\n          // Custom code with nested parts (e.g., positioned custom glyph)\r\n          if (part.parts) {\r\n            // A part-level option on the custom base must survive decomposition,\r\n            // but `[opts]>` binds to ONE code, so a multi-code (`;`) result\r\n            // re-emits the option before EACH decomposed part\r\n            // (`[opts]>B291;[opts]>C8`): render applied it to the whole\r\n            // `;`-character, and per-part emission computes to the same ink.\r\n            // Merging structurally, inner keys winning, keeps a part's own\r\n            // option authoritative, the order nested <g> attribute inheritance\r\n            // resolves to. Keys collide at the ATTRIBUTE level, not the key\r\n            // level: `color` aliases `stroke` (and camel `strokeWidth` its\r\n            // kebab form), and the renderer dedupes explicit-beats-alias, so an\r\n            // outer `stroke` merged next to a part's own `color` would flip the\r\n            // part's paint on round-trip unless it yields here. (TF-3G / TF-3.)\r\n            const attrChannel = (k) =>\r\n              k === 'color' ? 'stroke' : k === 'strokeWidth' ? 'stroke-width' : k;\r\n            const innerParts = part.options\r\n              ? part.parts.map(p => {\r\n                  const ownChannels = new Set(Object.keys(p.options ?? {}).map(attrChannel));\r\n                  const outer = Object.entries(part.options)\r\n                    .filter(([k]) => !ownChannels.has(attrChannel(k)));\r\n                  return { ...p, options: { ...Object.fromEntries(outer), ...p.options } };\r\n                })\r\n              : part.parts;\r\n            return serializeParts(innerParts, x, y);\r\n          }\r\n          // Custom composite shape (has codeString, no getPath)\r\n          const def = blissElementDefinitions[part.codeName];\r\n          if (def?.isShape && def.codeString && !def.getPath) {\r\n            return BlissSVGBuilder.#decomposeCodeString(def.codeString, x, y);\r\n          }\r\n        }\r\n        // Surface text-fallback routing key 'XTXT_<chars>' as 'X<chars>'.\r\n        let str = part.codeName.startsWith('XTXT_')\r\n          ? 'X' + part.codeName.slice(5)\r\n          : part.codeName;\r\n        if (x !== 0 || y !== 0) {\r\n          str += `:${x},${y}`;\r\n        }\r\n        // Prefix part-level options with [opts]> syntax\r\n        const optPrefix = serializeOptions(part.options);\r\n        if (optPrefix) str = `${optPrefix}>${str}`;\r\n        return str;\r\n      })\r\n        // Drop empty entries (invalid parts dropped by the codeName guard above,\r\n        // or an inner decomposition that emitted nothing) so no dangling `;`\r\n        // appears and toString round-trips. (Strict Indicator Separation\r\n        // surfaced this; the empty-separator artifact predates it.)\r\n        .filter(Boolean)\r\n        .join(';');\r\n    }\r\n\r\n    // Under preserve, keep a custom glyph's name but re-emit any per-instance\r\n    // indicator delta against the definition's baked state, so a glyph whose\r\n    // indicators were modified (`_X;B81`, `_X;!B81`, `_X;!`) round-trips\r\n    // instead of collapsing to the bare name. Bare name when state is baked.\r\n    function serializeCustomGlyphDelta(glyph) {\r\n      const def = blissElementDefinitions[glyph.codeName];\r\n      if (!def?.codeString || !glyph.parts) return glyph.codeName;\r\n      const currentInds = glyph.parts\r\n        .filter(p => p.isIndicator)\r\n        .map(p => p.codeName);\r\n      // Baked indicators are identified by isIndicator, not by position: a\r\n      // baseless compound indicator (e.g. 'B86;B97') has no base segment to\r\n      // skip, so its first segment counts too. A real base is non-indicator and\r\n      // the filter excludes it anyway, so skipping the first segment is wrong\r\n      // for the baseless case and redundant otherwise.\r\n      const bakedInds = def.codeString.split(';')\r\n        .filter(c => blissElementDefinitions[c.split(':')[0]]?.isIndicator);\r\n      if (currentInds.length === bakedInds.length\r\n          && currentInds.every((c, i) => c === bakedInds[i])) {\r\n        return glyph.codeName;\r\n      }\r\n      // The smart API changed the indicator state. Only a compound-indicator\r\n      // glyph bakes indicators (D-S1a), and the API can reorder or strip those\r\n      // baked parts; a dumb char-level `;` delta against the name can no longer\r\n      // encode that (re-appending a baked code doubles it, a `;!` strip becomes\r\n      // an invalid append), so decompose to primitives, which dumb `;` rebuilds\r\n      // exactly. (Strict Indicator Separation; supersedes the old `;`/`;!` delta.)\r\n      if (bakedInds.length > 0) {\r\n        return serializeParts(glyph.parts);\r\n      }\r\n      // A base-only glyph bakes no indicator, so the API only appends: a dumb\r\n      // `;` delta against the name round-trips faithfully and keeps the local\r\n      // name, which `preserve` must do independently of `flattenIndicators`\r\n      // (R3b2-2 orthogonality). But `name;codes` maps each part's bare codeName\r\n      // and re-references the base opaquely at 0,0, so it cannot encode a baked\r\n      // base offset, a per-instance indicator coord, or a part-level option. If\r\n      // any part would emit a `:x,y` / `[opts]>` suffix (the same test\r\n      // serializeParts uses), decompose to primitives, which DO carry it,\r\n      // instead of silently dropping it; the bare case still keeps the name.\r\n      const carriesPositionOrOptions = (p) =>\r\n        (p.x ?? 0) !== 0 || (p.y ?? 0) !== 0 || serializeOptions(p.options) !== '';\r\n      if (glyph.parts.some(carriesPositionOrOptions)) {\r\n        return serializeParts(glyph.parts);\r\n      }\r\n      return glyph.codeName + ';' + currentInds.join(';');\r\n    }\r\n\r\n    // Serialize a glyph: B-codes emit their code, compositions emit parts.\r\n    // Custom glyphs are decomposed to their codeString unless preserve is set.\r\n    // Returns an array (kerning codes are emitted as separate entries).\r\n    function serializeGlyph(glyph) {\r\n      const result = [];\r\n\r\n      // Emit kerning as separate RK/AK codes before the glyph\r\n      if (glyph.options?.relativeKerning !== undefined) {\r\n        result.push(`RK:${glyph.options.relativeKerning}`);\r\n      }\r\n      if (glyph.options?.absoluteKerning !== undefined) {\r\n        result.push(`AK:${glyph.options.absoluteKerning}`);\r\n      }\r\n\r\n      // Build the glyph code string\r\n      let code;\r\n      if (glyph.isBlissGlyph && glyph.codeName) {\r\n        // Decompose custom glyphs (non-built-in) to portable output\r\n        // Use the glyph's parts (which have correct positions) rather than\r\n        // re-decomposing from the definition (which would lose position offsets)\r\n        if (!options.preserve && !builtInCodes.has(glyph.codeName)) {\r\n          if (glyph.parts) {\r\n            code = serializeParts(glyph.parts);\r\n          } else {\r\n            const def = blissElementDefinitions[glyph.codeName];\r\n            if (def?.codeString) {\r\n              code = BlissSVGBuilder.#decomposeCodeString(def.codeString, 0, 0);\r\n            }\r\n          }\r\n        } else if (options.preserve && !builtInCodes.has(glyph.codeName)) {\r\n          code = serializeCustomGlyphDelta(glyph);\r\n        }\r\n        if (!code) {\r\n          // A built-in glyph can re-acquire identity while its parts still hold\r\n          // detail the bare code would drop: a sole part with a relocation\r\n          // offset and/or a part-level option (N13, e.g. clearIndicators on\r\n          // `[color=red]>B291:2,3;B86` restores codeName 'B291' but parts[0]\r\n          // keeps x/y + options), or an applied indicator part beyond the bare\r\n          // identity (a base-only custom glyph whose codeName collapsed to its\r\n          // built-in base after `applyIndicators`). Route any non-empty parts\r\n          // through serializeParts so all of them round-trip. No UNMODIFIED\r\n          // built-in reaches here multi-part (its snapshot part is a single\r\n          // self-reference), so this never over-decomposes a plain composite.\r\n          code = glyph.parts?.length\r\n            ? serializeParts(glyph.parts)\r\n            : glyph.codeName;\r\n        }\r\n      } else if (glyph.parts) {\r\n        code = serializeParts(glyph.parts);\r\n      } else {\r\n        code = glyph.codeName || '';\r\n      }\r\n\r\n      // Written-name consult (preserve-completeness chunk): whatever route\r\n      // computed `code`, a glyph that is a clean instance of a recorded\r\n      // definition emits the written name. The recording rides the glyph\r\n      // (parser stamp, kept in deep output); object input may carry the\r\n      // name as a glyph-level codeName instead. A diverged glyph never\r\n      // matches the anatomy, so the route's own output stands ('MYGL1;B81'\r\n      // stays a typed delta: a `;`-part on a bare-alias base drops on\r\n      // reparse).\r\n      if (options.preserve) {\r\n        const name = glyph._aliasCodeName\r\n          ?? (!glyph.isBlissGlyph && glyph.codeName && !builtInCodes.has(glyph.codeName)\r\n              ? glyph.codeName : null);\r\n        const written = name\r\n          ? BlissSVGBuilder.#preservedWrittenName(name, serializeParts(glyph.parts ?? []))\r\n          : null;\r\n        if (written) code = written;\r\n      }\r\n\r\n      // Prefix glyph-level options (skip internal kerning keys)\r\n      const optPrefix = serializeOptions(glyph.options, GLYPH_INTERNAL_KEYS);\r\n      result.push(optPrefix + code);\r\n      return result;\r\n    }\r\n\r\n    // Check if a group is a space (TSP or QSP). ZSA is content: it serializes as\r\n    // its own code, not a slash, so a standalone ZSA round-trips faithfully.\r\n    function isSpaceGroup(group) {\r\n      if (!group.glyphs || group.glyphs.length === 0) return false;\r\n      return group.glyphs.every(g =>\r\n        g.parts?.length === 1 && isSpaceGlyph(g.parts[0].codeName)\r\n      );\r\n    }\r\n\r\n    const segments = [];\r\n    // Space groups and bare content-empty groups coalesce into maximal runs so\r\n    // serialized spacing always matches rendered spacing: N default space\r\n    // glyphs emit N+1 slashes once per run; a run holding any non-default\r\n    // space code emits the explicit code list instead; bare empty groups\r\n    // contribute no units and never split a run.\r\n    let spaceRun = null;\r\n    const flushSpaceRun = () => {\r\n      if (!spaceRun) return;\r\n      // Defensive: only space groups open a run, and a space group always\r\n      // holds a glyph. Empties never open one (they only skip the flush).\r\n      if (spaceRun.glyphCount > 0) {\r\n        segments.push(spaceRun.hasNonDefault\r\n          ? spaceRun.codes.join('/')\r\n          : '/'.repeat(spaceRun.glyphCount + 1));\r\n      }\r\n      spaceRun = null;\r\n    };\r\n    for (const group of obj.groups || []) {\r\n      if (!group.glyphs) continue;\r\n      // A malformed word (parser group.errorCode) never reaches serialization:\r\n      // #normalizeFailedWordInvariant drops it from #rawBlissObj at rebuild\r\n      // (retention family, rows 31/80), so no errorSource replay survives here.\r\n      if (isSpaceGroup(group)) {\r\n        spaceRun ??= { glyphCount: 0, codes: [], hasNonDefault: false };\r\n        spaceRun.glyphCount += group.glyphs.length;\r\n        spaceRun.codes.push(...group.glyphs.map(g => g.parts[0].codeName));\r\n        if (group.glyphs.some(g => g.parts?.some(p => p._differsFromDefault))) {\r\n          spaceRun.hasNonDefault = true;\r\n        }\r\n        continue;\r\n      }\r\n      const glyphArrays = group.glyphs.map(serializeGlyph);\r\n      let groupStr = glyphArrays.flat().filter(Boolean).join('/');\r\n      // Head-marker fidelity (rc.4): a stored designation ALWAYS re-emits as\r\n      // `^` on the marked glyph's last segment, matching toJSON's isHeadGlyph,\r\n      // so a string round-trip never loses the designation — even when the\r\n      // automatic head pick would re-derive the same glyph. Words without a\r\n      // stored designation stay unmarked (the automatic pick is derived at\r\n      // query time, never stored).\r\n      const headIndex = group.glyphs.findIndex(g => g.isHeadGlyph === true);\r\n      if (headIndex !== -1 && groupStr) {\r\n        const headSegments = glyphArrays[headIndex];\r\n        if (headSegments.length && headSegments[headSegments.length - 1]) {\r\n          headSegments[headSegments.length - 1] += '^';\r\n          groupStr = glyphArrays.flat().filter(Boolean).join('/');\r\n        }\r\n      }\r\n      // R14: re-emit a word-level indicator overlay as trailing `;;` (kept by\r\n      // default; `flatten` collapses it onto the head as `;` instead).\r\n      if (group.wordIndicators && groupStr) {\r\n        const { codes = [], stripSemantic } = group.wordIndicators;\r\n        groupStr += ';;' + (stripSemantic ? '!' : '') + codes.join(';');\r\n      }\r\n      // Prefix group-level options with [opts]| syntax\r\n      const groupOptPrefix = serializeOptions(group.options);\r\n      if (groupOptPrefix) groupStr = `${groupOptPrefix}|${groupStr}`;\r\n      if (groupStr === '') continue; // bare content-empty: no segment, run stays open\r\n      flushSpaceRun();\r\n      segments.push(groupStr);\r\n    }\r\n    flushSpaceRun();\r\n    // Join: slash-only segments already include separators, others need /\r\n    let result = segments.reduce((acc, seg) => {\r\n      if (acc === '') return seg;\r\n      if (seg.startsWith('/')) return acc + seg;\r\n      if (acc.endsWith('/')) return acc + seg;\r\n      return acc + '/' + seg;\r\n    }, '');\r\n\r\n    // Prefix global options with [opts]|| syntax\r\n    const globalOptPrefix = serializeOptions(obj.options);\r\n    if (globalOptPrefix) result = `${globalOptPrefix}||${result}`;\r\n\r\n    return result;\r\n  }\r\n\r\n  /**\r\n   * Returns the normalized parsed structure. Custom codes are decomposed to\r\n   * built-in codes by default; { preserve: true } keeps custom names under\r\n   * the same rule as toString() (typed definitions and bare aliases to one\r\n   * existing code; multi-code shorthand always expands).\r\n   *\r\n   * @param {Object} [options]\r\n   * @param {boolean} [options.preserve=false] - Keep custom glyph/shape code names\r\n   * @param {boolean} [options.flattenIndicators=false] - Bake word-level (`;;`) indicators onto the head and omit the wordIndicators field\r\n   * @returns {Object} Plain object with groups/glyphs/options structure\r\n   */\r\n  toJSON(options = {}) {\r\n    const obj = structuredClone(this.#rawBlissObj);\r\n\r\n    // Internal parse-warning record: consumed by #rebuild to repopulate\r\n    // `warnings`, never part of the public composition data (absent from the\r\n    // BlissJSON type). Strip it so toJSON() is clean authoring data and a JSON\r\n    // round-trip does not re-emit a warning for an offender already dropped.\r\n    delete obj._parseWarnings;\r\n\r\n    // Strip keys from all levels (keys are runtime identity, not composition data)\r\n    delete obj.key;\r\n    if (obj.options) delete obj.options.key;\r\n\r\n    if (obj.groups) {\r\n      // Strip keys from parts. Unless deep: true, also strip nested sub-parts\r\n      // (internal expansion detail). The constructor re-expands from codeName\r\n      // via BlissParser.expandParts().\r\n      const stripParts = (parts) => {\r\n        for (const [partIndex, part] of parts.entries()) {\r\n          delete part.key;\r\n          // Internal origin tag from the word-indicator merge (flatten path):\r\n          // not composition data, never surfaced in serialized output.\r\n          delete part._indicatorOrigin;\r\n          // Single-code rename resolution records the user-written name\r\n          // (Phase 2.3b; extended to character level in Chunk 6): preserve\r\n          // restores it, so `B291;MYIND` keeps MYIND and a standalone alias\r\n          // keeps its name instead of leaking the resolved target. A BASE\r\n          // slot with `;`-siblings restores only a name that survives\r\n          // reparse: a `;`-part on a bare-alias base drops (strict\r\n          // separation), so a bare-alias name stays decomposed there, while\r\n          // a typed name dumb-appends and round-trips. Deep output keeps the\r\n          // field for the toString()/merge() pipelines; public output drops it.\r\n          if (options.preserve && part._aliasCodeName) {\r\n            const namedDef = blissElementDefinitions[part._aliasCodeName];\r\n            // A decorated part (coordinates or options) restores only a PURE\r\n            // rename chain: a decorated custom anatomy dissolved its own\r\n            // state into this part, and the written name would re-emit it as\r\n            // instance decoration (preserve-completeness chunk; the glyph-\r\n            // level consult keeps such a name at the clean-glyph level).\r\n            const decorated = (part.x ?? 0) !== 0 || (part.y ?? 0) !== 0 || part.options;\r\n            if ((partIndex > 0 || parts.length === 1\r\n                || (namedDef && !BlissSVGBuilder.#isBareAliasDefinition(namedDef)))\r\n                && (!decorated || BlissSVGBuilder.#renameChainIsPure(part._aliasCodeName))) {\r\n              part.codeName = part._aliasCodeName;\r\n            }\r\n          }\r\n          if (!options.deep) delete part._aliasCodeName;\r\n          if (part.options) delete part.options.key;\r\n          // Surface text-fallback routing key 'XTXT_<chars>' as 'X<chars>'.\r\n          if (part.codeName?.startsWith('XTXT_')) {\r\n            part.codeName = 'X' + part.codeName.slice(5);\r\n          }\r\n          // Default output drops definition-derived anchor metadata the renderer\r\n          // recomputes from the code; isIndicator/width stay (a documented part of\r\n          // the default shape). deep output keeps everything for toString()/merge().\r\n          if (!options.deep) {\r\n            delete part.anchorOffsetX;\r\n            delete part.anchorOffsetY;\r\n          }\r\n          if (options.deep && part.parts) {\r\n            stripParts(part.parts);\r\n          } else {\r\n            delete part.parts;\r\n          }\r\n        }\r\n      };\r\n\r\n      for (const group of obj.groups) {\r\n        delete group.key;\r\n        if (group.options) delete group.options.key;\r\n\r\n        // R14: flattenIndicators bakes the word-level overlay onto the head as\r\n        // character-level parts and drops the field, reproducing the pre-overlay\r\n        // (primitive) serialization. Default keeps the overlay (resolved at\r\n        // render, re-emitted as `;;`).\r\n        // (An all-empty word keeps its unflattenable overlay: headIndex -1.)\r\n        const overlayHeadIndex = options.flattenIndicators && group.wordIndicators && group.glyphs?.length\r\n          ? resolveOverlayHeadIndex(group.glyphs)\r\n          : -1;\r\n        if (overlayHeadIndex !== -1) {\r\n          const head = group.glyphs[overlayHeadIndex];\r\n          head.parts = mergeWordIndicatorsOntoHead(\r\n            head, group.wordIndicators, blissElementDefinitions, (code) => BlissParser.parse(code)\r\n          );\r\n          // A head with baked indicator parts is no longer a bare single code,\r\n          // so clear its single-code identity to force part-based serialization\r\n          // (`B291;B81`); otherwise serializeGlyph emits the bare codeName and\r\n          // drops the baked parts. The one exception is a custom glyph under\r\n          // `preserve`: it keeps its name and re-emits the overlay as a delta\r\n          // (`_LOVE;B81`), so leave its identity intact.\r\n          if (head.glyphCode && head.parts.some(p => p.isIndicator)\r\n              && !(options.preserve && !builtInCodes.has(head.glyphCode))) {\r\n            delete head.glyphCode;\r\n            delete head.isBlissGlyph;\r\n          }\r\n          delete group.wordIndicators;\r\n        }\r\n\r\n        if (group.glyphs) {\r\n          for (const glyph of group.glyphs) {\r\n            delete glyph.key;\r\n            if (glyph.options) delete glyph.options.key;\r\n            if (glyph.parts) stripParts(glyph.parts);\r\n\r\n            // Normalize glyphCode → codeName for public API\r\n            if (glyph.glyphCode) {\r\n              // Surface text-fallback routing key 'XTXT_<chars>' as 'X<chars>'.\r\n              const publicCode = glyph.glyphCode.startsWith('XTXT_')\r\n                ? 'X' + glyph.glyphCode.slice(5)\r\n                : glyph.glyphCode;\r\n              // Decompose custom glyphs to portable codes by default\r\n              if (!options.preserve && !builtInCodes.has(glyph.glyphCode)) {\r\n                const def = blissElementDefinitions[glyph.glyphCode];\r\n                if (def?.codeString) {\r\n                  // Resolve to the underlying built-in code (null for complex compositions)\r\n                  const resolved = BlissSVGBuilder.#resolveToBuiltInCode(glyph.glyphCode);\r\n                  if (resolved) glyph.codeName = resolved;\r\n                  // This resolution is the one place a typed glyph's identity\r\n                  // drops from deep output, which feeds re-ingest pipelines\r\n                  // (merge): record the written name so preserve can restore\r\n                  // a clean instance downstream. An existing recording (a\r\n                  // bare alias written OVER this glyph) outranks its own name.\r\n                  // The deep gate pairs with the `!options.deep` strip below;\r\n                  // either alone keeps public output clean, so keep both.\r\n                  if (options.deep) glyph._aliasCodeName ??= publicCode;\r\n                } else {\r\n                  glyph.codeName = publicCode;\r\n                }\r\n              } else {\r\n                glyph.codeName = publicCode;\r\n              }\r\n              delete glyph.glyphCode;\r\n            }\r\n            // Parts already use codeName internally, no rename needed\r\n\r\n            // Glyph-level rename recording (preserve-completeness chunk):\r\n            // public preserve output restores the written name only for a\r\n            // clean instance of the definition's anatomy. Deep output stays\r\n            // raw (codeName = the typed target) so serializeCustomGlyphDelta\r\n            // keeps computing the divergence delta against the right\r\n            // definition; toString restores via its own consult instead.\r\n            // The recording never reaches public output in either mode.\r\n            if (options.preserve && !options.deep) {\r\n              const name = glyph._aliasCodeName\r\n                ?? (glyph.codeName && !builtInCodes.has(glyph.codeName) ? glyph.codeName : null);\r\n              if (name) {\r\n                const canonical = BlissSVGBuilder.#canonicalGlyphParts(glyph.parts);\r\n                const written = canonical !== null\r\n                  ? BlissSVGBuilder.#preservedWrittenName(name, canonical) : null;\r\n                if (written) glyph.codeName = written;\r\n              }\r\n            }\r\n            if (!options.deep) delete glyph._aliasCodeName;\r\n\r\n            // Default output omits glyph-classification metadata: it is fully\r\n            // derived from the code and re-derived on reconstruction (see\r\n            // #reapplyGlyphMetadata), so it is not user-authored composition data.\r\n            // deep output keeps it for toString()/merge(). (issue #28 toJSON audit)\r\n            if (!options.deep) {\r\n              delete glyph.char;\r\n              delete glyph.isBlissGlyph;\r\n              delete glyph.isExternalGlyph;\r\n              delete glyph.kerningRules;\r\n              delete glyph.shrinksPrecedingWordSpace;\r\n              delete glyph.isIndicator;\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return obj;\r\n  }\r\n\r\n\r\n\r\n  /**\r\n   * Returns the SVG content (path elements and groups) as a string.\r\n   * This is useful when you need only the primary graphical content of the SVG for manipulation or for use in complex SVG compositions.\r\n   *\r\n   * @returns {string} SVG content string\r\n   */\r\n  get svgContent() {\r\n    const content = this.composition.getSvgContent();\r\n\r\n    // If content already contains complete SVG tags (like <g> from hierarchical options), return as-is\r\n    if (content.startsWith('<')) {\r\n      return content;\r\n    }\r\n\r\n    // Otherwise, wrap raw path data in a <path> element\r\n    return `<path d=\"${content}\"/>`;\r\n  }\r\n\r\n  /**\r\n   * Returns the SVG as a DOM Element.\r\n   * This property is useful when you need to directly manipulate the SVG using the native DOM API.\r\n   * \r\n   * @returns {SVGSVGElement} SVG DOM element\r\n   */\r\n  get svgElement() {\r\n    const parser = new DOMParser();\r\n    const doc = parser.parseFromString(this.#svgCode, 'image/svg+xml');\r\n    return doc.documentElement;\r\n  }\r\n  \r\n  /**\r\n   * Returns the SVG code as a string, without the XML declaration.\r\n   * This is suitable for embedding the SVG within HTML documents or using it with virtual DOM libraries like React and Preact.\r\n   * \r\n   * @returns {string} SVG string without XML declaration\r\n   */\r\n  get svgCode() {\r\n    return this.#svgCode;\r\n  }\r\n\r\n  /**\r\n   * Returns the SVG code as a string, including the XML declaration.\r\n   * This is suitable for creating standalone SVG files.\r\n   * \r\n   * @returns {string} SVG string with XML declaration\r\n   */\r\n  get standaloneSvg() {\r\n    return `<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n${this.#svgCode}`;\r\n  }\r\n\r\n\r\n  // The external-character namespace: X followed by one or more letters in\r\n  // the parser recognition ranges (Latin, Latin-1/Ext-A, Greek, Cyrillic).\r\n  // Matches the parser's X-run tokenizer ranges exactly: written input of\r\n  // this shape is always read as external text, never as a definition name,\r\n  // so such a definition would be unreachable (1.4 fence; Phase 2.3 guard).\r\n  static #X_NAMESPACE_PATTERN = /^X[a-zA-ZÀ-ſͰ-ϿЀ-ӿ]+$/;\r\n\r\n  // Parser-transient tokens that are DSL syntax, not registry codes: defining\r\n  // one would change what the bare token means at the use site (a definition\r\n  // named RK shadows the kerning marker).\r\n  static #RESERVED_SYNTAX_NAMES = new Set(['RK', 'AK', 'SP']);\r\n\r\n  // Validates a definition code string\r\n  static #validateCode(code) {\r\n    if (typeof code !== 'string' || code.trim().length === 0) {\r\n      throw new Error('Definition code must be a non-empty, non-whitespace string.');\r\n    }\r\n    // Control (Cc) and format (Cf) characters — and any whitespace other\r\n    // than a plain space (no-break space, line/paragraph separators) — make\r\n    // a key that LOOKS like a normal code but can never be typed at a use\r\n    // site: the definition registers unreachable, silently. Reject with the\r\n    // code point named. A plain interior space stays allowed (the full code\r\n    // grammar is a separate decision).\r\n    const invisible = code.match(/[\\p{Cc}\\p{Cf}]|[^\\S ]/u);\r\n    if (invisible) {\r\n      const hex = invisible[0].codePointAt(0).toString(16).toUpperCase().padStart(4, '0');\r\n      throw new Error(`Definition code contains an invisible character (U+${hex}). Use visible characters only.`);\r\n    }\r\n    if (BlissSVGBuilder.#X_NAMESPACE_PATTERN.test(code)) {\r\n      throw new Error(`\"${code}\" collides with the external-character namespace (X followed by letters): the parser reads such tokens as external text, so this definition would be unreachable. Choose a name that is not X followed by letters.`);\r\n    }\r\n    if (BlissSVGBuilder.#RESERVED_SYNTAX_NAMES.has(code)) {\r\n      throw new Error(`\"${code}\" is reserved DSL syntax (the kerning and space markers RK, AK, SP) and cannot be defined.`);\r\n    }\r\n  }\r\n\r\n  // Existence/overwrite gate shared by all four define paths. A built-in\r\n  // definition is part of the universal primitive set every portable\r\n  // composition relies on: replacing one would change what existing strings\r\n  // render in this instance only, so overwrite:true refuses it (mirroring\r\n  // removeDefinition/patchDefinition). Without overwrite, an existing code\r\n  // (built-in or custom) keeps landing in skipped[] via the already-exists\r\n  // throw.\r\n  static #assertReplaceable(code, options) {\r\n    if (!blissElementDefinitions[code]) return;\r\n    if (options.overwrite && protectedCodes.has(code)) {\r\n      throw new Error(`define(\"${code}\"): cannot overwrite built-in definitions.`);\r\n    }\r\n    if (!options.overwrite) {\r\n      // Typed so define()'s catch classifies by code, not by message text: a\r\n      // definition NAMED \"already exists\" must land in errors, not skipped\r\n      // (review MINOR-5).\r\n      const error = new Error(`define(\"${code}\"): code already exists. Use { overwrite: true } to replace.`);\r\n      error.code = 'ALREADY_EXISTS';\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  // ── Define validation helpers ───────────────────────────────────\r\n\r\n  // Extract referenced codes from a codeString (strips positions, options, etc.)\r\n  static #extractReferencedCodes(codeString) {\r\n    if (!codeString) return [];\r\n    return codeString\r\n      .split(/[;/]+/)\r\n      .map(part => part.replace(/\\[.*?\\]>?/g, '').split(':')[0].replace(/\\^$/, ''))\r\n      .filter(code => code.length > 0);\r\n  }\r\n\r\n  // Recursively decompose a codeString to built-in codes, adjusting coordinates.\r\n  // Used by toString() for portable output of custom shapes and glyphs.\r\n  static #decomposeCodeString(codeString, offsetX, offsetY) {\r\n    const parts = codeString.split(';');\r\n    return parts.map(part => {\r\n      const posMatch = part.match(/^([^:]+)(?::(-?[\\d.]+),(-?[\\d.]+))?$/);\r\n      if (!posMatch) return part;\r\n\r\n      const [, code, xStr, yStr] = posMatch;\r\n      const x = (parseFloat(xStr) || 0) + offsetX;\r\n      const y = (parseFloat(yStr) || 0) + offsetY;\r\n\r\n      // Recursively decompose custom composite shapes\r\n      if (!builtInCodes.has(code)) {\r\n        const def = blissElementDefinitions[code];\r\n        if (def?.isShape && def.codeString && !def.getPath) {\r\n          return BlissSVGBuilder.#decomposeCodeString(def.codeString, x, y);\r\n        }\r\n        if (def?.isBlissGlyph && def.codeString) {\r\n          return BlissSVGBuilder.#decomposeCodeString(def.codeString, x, y);\r\n        }\r\n      }\r\n\r\n      if (x === 0 && y === 0) return code;\r\n      return `${code}:${x},${y}`;\r\n    }).join(';');\r\n  }\r\n\r\n  // Resolve a custom glyph code to its underlying built-in code (for toJSON).\r\n  // Follows the chain until a built-in code is found.\r\n  static #resolveToBuiltInCode(code, visited = new Set()) {\r\n    if (visited.has(code)) return code;\r\n    visited.add(code);\r\n    const def = blissElementDefinitions[code];\r\n    if (!def?.codeString) return code;\r\n    // If codeString is a single code reference (no ; or / or :), resolve further\r\n    if (!def.codeString.includes(';') && !def.codeString.includes('/') && !def.codeString.includes(':')) {\r\n      if (builtInCodes.has(def.codeString)) return def.codeString;\r\n      return BlissSVGBuilder.#resolveToBuiltInCode(def.codeString, visited);\r\n    }\r\n    return null; // Complex codeString — parts already expanded, no single code\r\n  }\r\n\r\n  // Determine the type of a definition entry.\r\n  // Single source of truth used by getDefinition, listDefinitions,\r\n  // patchDefinition, and #validateReferences.\r\n  static #detectType(def) {\r\n    if (def.isShape) return 'shape';\r\n    if (def.isExternalGlyph) return 'externalGlyph';\r\n    if (def.isBlissGlyph || def.glyphCode) return 'glyph';\r\n    if (def.codeString !== undefined) return 'bare';\r\n    return 'space';\r\n  }\r\n\r\n  // The bare-alias discriminator for the preserve-mode base-slot guards: a\r\n  // name whose definition is a pure rename ({codeString} only, no identity)\r\n  // sheds its `;`-siblings on reparse (strict separation), so such a name\r\n  // never heads a multi-part emission; typed names dumb-append and round-trip.\r\n  static #isBareAliasDefinition(def) {\r\n    return !!def && BlissSVGBuilder.#detectType(def) === 'bare';\r\n  }\r\n\r\n  // Preserve-completeness chunk: written-name consult for the glyph-level\r\n  // recording. Walks single-code links from `name`; the chain's anatomy is\r\n  // the first non-single-token codeString (or the terminal bare token), and\r\n  // the name is emittable only when the chain passes a CUSTOM definition\r\n  // with identity (typed shape/glyph/indicator; bare shorthand never\r\n  // qualifies) AND the glyph's serialized parts equal that anatomy as\r\n  // written, i.e. the glyph is a clean instance of the definition.\r\n  static #preservedWrittenName(name, serialized) {\r\n    let code = name;\r\n    let identityDef = null;\r\n    const seen = new Set();\r\n    while (!seen.has(code)) {\r\n      seen.add(code);\r\n      if (builtInCodes.has(code)) break;\r\n      const def = Object.prototype.hasOwnProperty.call(blissElementDefinitions, code)\r\n        ? blissElementDefinitions[code] : undefined;\r\n      if (!def || typeof def.codeString !== 'string') break;\r\n      if (def.isBlissGlyph || def.isShape || def.isExternalGlyph\r\n          || def.glyphCode || def.isIndicator === true\r\n          || typeof def.getPath === 'function') {\r\n        identityDef = def;\r\n      }\r\n      if (!SINGLE_CODE_TOKEN.test(def.codeString)) {\r\n        return identityDef && serialized === def.codeString ? name : null;\r\n      }\r\n      code = def.codeString;\r\n    }\r\n    return identityDef && serialized === code ? name : null;\r\n  }\r\n\r\n  // A rename chain is pure when every link is a single bare token down to a\r\n  // built-in, primitive, or unknown end. A decorated custom anatomy\r\n  // (coordinates, options, or several parts) dissolves its state INTO the\r\n  // parsed part, so restoring the written name onto a decorated part would\r\n  // re-emit that state as instance decoration and shift the reparse.\r\n  static #renameChainIsPure(name) {\r\n    let code = name;\r\n    const seen = new Set();\r\n    while (!builtInCodes.has(code)) {\r\n      if (seen.has(code)) return false;\r\n      seen.add(code);\r\n      const def = Object.prototype.hasOwnProperty.call(blissElementDefinitions, code)\r\n        ? blissElementDefinitions[code] : undefined;\r\n      if (!def || typeof def.codeString !== 'string') return true;\r\n      if (!SINGLE_CODE_TOKEN.test(def.codeString)) return false;\r\n      code = def.codeString;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  // Canonical `;`-joined token form of a glyph's top-level parts (an\r\n  // `[opts]>` prefix via the shared serializeOptions emitter, codeName, and\r\n  // a non-origin :x,y suffix), for comparison against a definition's\r\n  // written codeString. Returns null when any part carries state this form\r\n  // cannot express (nested parts, an error), so the caller falls back to\r\n  // decomposed output.\r\n  static #canonicalGlyphParts(parts) {\r\n    if (!Array.isArray(parts) || parts.length === 0) return null;\r\n    const tokens = [];\r\n    for (const part of parts) {\r\n      if (!part.codeName || part.parts || part.error || part.errorCode) return null;\r\n      const optPrefix = serializeOptions(part.options);\r\n      const x = part.x ?? 0;\r\n      const y = part.y ?? 0;\r\n      const token = x !== 0 || y !== 0 ? `${part.codeName}:${x},${y}` : part.codeName;\r\n      tokens.push(optPrefix ? `${optPrefix}>${token}` : token);\r\n    }\r\n    return tokens.join(';');\r\n  }\r\n\r\n  // Check if a codeString references only allowed types\r\n  static #validateReferences(code, codeString, allowedTypes) {\r\n    const refs = BlissSVGBuilder.#extractReferencedCodes(codeString);\r\n    for (const ref of refs) {\r\n      if (ref === code) {\r\n        return `\"${code}\": circular reference (references itself)`;\r\n      }\r\n      const def = blissElementDefinitions[ref];\r\n      if (!def) continue; // Unknown codes will fail at parse time\r\n      const type = BlissSVGBuilder.#detectType(def);\r\n      if (!allowedTypes.includes(type)) {\r\n        return `\"${code}\": cannot reference ${type} \"${ref}\". Allowed types: ${allowedTypes.join(', ')}`;\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n\r\n  // Detect circular references via depth-first traversal\r\n  static #hasCircularReference(code, codeString) {\r\n    const visited = new Set();\r\n    const walk = (refs) => {\r\n      for (const ref of refs) {\r\n        if (ref === code) return true;\r\n        if (visited.has(ref)) continue;\r\n        visited.add(ref);\r\n        const def = blissElementDefinitions[ref];\r\n        if (def?.codeString) {\r\n          const subRefs = BlissSVGBuilder.#extractReferencedCodes(def.codeString);\r\n          if (walk(subRefs)) return true;\r\n        }\r\n      }\r\n      return false;\r\n    };\r\n    return walk(BlissSVGBuilder.#extractReferencedCodes(codeString));\r\n  }\r\n\r\n  // Deferred validation of forward references (Phase 2.3): define() accepts\r\n  // a codeString that references a not-yet-defined code, so the\r\n  // indicator-bake guard (D-S1a) can be bypassed by definition ORDER — the\r\n  // glyph registers while its reference is unknown, and a later define/patch\r\n  // makes that reference an indicator. This scan runs at that later moment,\r\n  // the completing call: with `code` about to become `newEntry`, every\r\n  // custom glyph definition (not itself a compound indicator) is re-checked\r\n  // for a reference that would now resolve to an indicator (through\r\n  // pure-rename aliases too, so a bare-alias completion cannot slip\r\n  // through). A conflict rejects the COMPLETING call and changes nothing:\r\n  // either definition order ends in the same refusal.\r\n  static #assertNoIndicatorBakeDependents(callName, code, newEntry) {\r\n    const view = { ...blissElementDefinitions, [code]: newEntry };\r\n    const dependents = [];\r\n    for (const [depCode, depDef] of Object.entries(blissElementDefinitions)) {\r\n      if (depCode === code) continue;\r\n      if (depDef.isBlissGlyph !== true || depDef.isIndicator === true || typeof depDef.codeString !== 'string') continue;\r\n      const refs = BlissSVGBuilder.#extractReferencedCodes(depDef.codeString);\r\n      const bakes = refs.some(ref => {\r\n        const refDef = Object.prototype.hasOwnProperty.call(view, ref) ? view[ref] : undefined;\r\n        return refDef !== undefined && resolveEffectiveDefinition(refDef, view)?.isIndicator === true;\r\n      });\r\n      if (bakes) dependents.push(depCode);\r\n    }\r\n    if (dependents.length > 0) {\r\n      const plural = dependents.length > 1 ? 's' : '';\r\n      const list = dependents.map(d => `\"${d}\"`).join(', ');\r\n      throw new Error(`${callName}(\"${code}\"): making \"${code}\" an indicator would make the glyph definition${plural} ${list} bake an indicator, a state define() rejects. Remove or redefine the dependent definition${plural} first, then define \"${code}\".`);\r\n    }\r\n  }\r\n\r\n  // Word-internal coordinate guard shared by #defineBare and patchDefinition\r\n  // (coordinate ownership: coordinates belong at the usage site, never baked\r\n  // into a portable word alias). Kerning markers (RK:/AK:) are spacing, not\r\n  // coordinates, so their `:` values are exempt (GH #36 false-positive fix).\r\n  static #assertNoWordInternalCoordinates(callName, code, codeString) {\r\n    if (!codeString.includes('/')) return;\r\n    const segments = codeString.split(/[/;]/).filter(Boolean);\r\n    const hasCoords = segments.some(seg => !/^(?:RK|AK)(?::|$)/.test(seg) && /:-?[\\d.]/.test(seg));\r\n    if (hasCoords) {\r\n      throw new Error(`${callName}(\"${code}\"): word definitions (containing /) cannot have internal coordinates. Move coordinates to the usage site.`);\r\n    }\r\n  }\r\n\r\n  // An SP segment in a stored codeString can never resolve: SP has meaning\r\n  // only at the top level, where punctuation context turns it into TSP/QSP.\r\n  // `/SP/` is written sugar for `//`, so a definition using it normalizes to\r\n  // the `//` form silently (user ruling 2026-07-18). Quote-bearing\r\n  // codeStrings are left untouched: definition ingestion is quote-unaware\r\n  // today (post-1.0.0 family), and a naive split could cut inside a quoted\r\n  // option value.\r\n  static #normalizeSpaceSegments(codeString) {\r\n    if (!codeString.includes('/') || /[\"']/.test(codeString)) return codeString;\r\n    const segments = codeString.split('/');\r\n    const normalized = [];\r\n    for (let i = 0; i < segments.length; i++) {\r\n      if (segments[i] === 'SP') {\r\n        normalized.push('');\r\n        // An interior SP sits between two real slashes, so one empty segment\r\n        // reproduces `//`; an edge SP has only one neighboring slash, so it\r\n        // needs a second empty segment or the space silently vanishes\r\n        // (`SP/B291` must store `//B291`, not `/B291`; review MAJOR-1).\r\n        if (i === 0 || i === segments.length - 1) normalized.push('');\r\n      } else {\r\n        normalized.push(segments[i]);\r\n      }\r\n    }\r\n    return normalized.join('/');\r\n  }\r\n\r\n  // ── Private define helpers ──────────────────────────────────────\r\n\r\n  static #defineShape(code, definition, options = {}) {\r\n    BlissSVGBuilder.#validateCode(code);\r\n\r\n    const hasGetPath = typeof definition?.getPath === 'function';\r\n    const hasCodeString = typeof definition?.codeString === 'string' && definition.codeString.trim().length > 0;\r\n\r\n    if (!hasGetPath && !hasCodeString) {\r\n      throw new Error(`define(\"${code}\"): shape requires either \"getPath\" (function) or \"codeString\" (non-empty, non-whitespace string).`);\r\n    }\r\n\r\n    if (hasGetPath) {\r\n      if (typeof definition.width !== 'number' || !isFinite(definition.width)) {\r\n        throw new Error(`define(\"${code}\"): \"width\" must be a finite number.`);\r\n      }\r\n      if (typeof definition.height !== 'number' || !isFinite(definition.height)) {\r\n        throw new Error(`define(\"${code}\"): \"height\" must be a finite number.`);\r\n      }\r\n    }\r\n\r\n    // Shapes can only reference other shapes\r\n    if (hasCodeString) {\r\n      const refError = BlissSVGBuilder.#validateReferences(code, definition.codeString, ['shape']);\r\n      if (refError) throw new Error(`define(${refError})`);\r\n      if (BlissSVGBuilder.#hasCircularReference(code, definition.codeString)) {\r\n        throw new Error(`define(\"${code}\"): circular reference detected`);\r\n      }\r\n      // A shape is a single character; `/` and `//` are word separators, so a\r\n      // `/`-bearing codeString is a word, not a shape. Define a word as a bare\r\n      // alias (omit type:\"shape\"). (Strict Indicator Separation, F4.)\r\n      if (definition.codeString.includes('/')) {\r\n        throw new Error(`define(\"${code}\"): a shape definition cannot be a multi-character word (its codeString contains \"/\"). Define a word as a bare alias (omit type:\"shape\").`);\r\n      }\r\n\r\n      // `;;` is a word-level indicator (a word property); a shape is a single\r\n      // character, so it cannot carry one. (Strict Indicator Separation.)\r\n      if (definition.codeString.includes(';;')) {\r\n        throw new Error(`define(\"${code}\"): a shape definition cannot contain a word-level indicator (\";;\"); a shape is a single character.`);\r\n      }\r\n    }\r\n\r\n    BlissSVGBuilder.#assertReplaceable(code, options);\r\n\r\n    const entry = { isShape: true };\r\n\r\n    if (hasGetPath) {\r\n      entry.getPath = definition.getPath;\r\n      entry.width = definition.width;\r\n      entry.height = definition.height;\r\n      if (definition.x !== undefined) entry.x = definition.x;\r\n      if (definition.y !== undefined) entry.y = definition.y;\r\n      if (definition.extraPathOptions) entry.extraPathOptions = definition.extraPathOptions;\r\n    } else {\r\n      entry.codeString = definition.codeString;\r\n    }\r\n\r\n    if (definition.defaultOptions && typeof definition.defaultOptions === 'object') {\r\n      // Snapshot ONCE, validate the snapshot, store the SAME snapshot: the\r\n      // guard must judge exactly what the registry keeps, or an accessor /\r\n      // Proxy could show one set of keys to validation and another to storage\r\n      // (round-4 review F1).\r\n      const defaultOptionsSnapshot = { ...definition.defaultOptions };\r\n      if (Object.keys(defaultOptionsSnapshot).length > 0) {\r\n        BlissSVGBuilder.#assertNoGlobalOnlyDefaultOptions('define', code, defaultOptionsSnapshot);\r\n        entry.defaultOptions = defaultOptionsSnapshot;\r\n      }\r\n    }\r\n\r\n    blissElementDefinitions[code] = entry;\r\n  }\r\n\r\n  // A definition's defaultOptions attach at glyph/part level, where a\r\n  // builder-canvas (global-only) option key is inert at EVERY use form — and a\r\n  // ;; overlay stores the definition NAME, so such a key would never reach a\r\n  // parse boundary that could warn (silent forever; review-fix round 2, F1).\r\n  // A definition must be clean: reject at the source, like the codeString\r\n  // guards. Both spellings are checked (defaultOptions are stored verbatim,\r\n  // so a camelCase key is just as inert).\r\n  static #assertNoGlobalOnlyDefaultOptions(callName, code, defaultOptions) {\r\n    for (const key of Object.keys(defaultOptions)) {\r\n      // Trim before matching: the serializer emits a padded key as\r\n      // '[ margin=2]' and #parseOptions reads that as plain 'margin', so a\r\n      // whitespace-padded spelling IS the global-only key at the next\r\n      // boundary (round-3 review F1).\r\n      const normalized = key.trim();\r\n      // A key must be a well-formed option name at all (camelCase names pass\r\n      // the same test): anything else — '=', ';', brackets, inner spaces —\r\n      // would smuggle arbitrary option text into the serialized bracket,\r\n      // where the parser can read a key this guard never saw\r\n      // ('margin=2;color' emits as '[margin=2;color=red]').\r\n      if (!isSafeAttributeName(normalized)) {\r\n        throw new Error(`${callName}(\"${code}\"): defaultOptions key \"${key}\" is not a valid option name.`);\r\n      }\r\n      if (GLOBAL_ONLY_OPTION_KEYS.has(normalized) || GLOBAL_ONLY_OPTION_KEYS.has(camelToKebab(normalized))) {\r\n        throw new Error(`${callName}(\"${code}\"): defaultOptions cannot include the global-only option \"${key}\"; it configures the whole SVG and would be inert on a definition. Set it in the global bracket ([...]||) or the builder options instead.`);\r\n      }\r\n    }\r\n  }\r\n\r\n  static #defineGlyph(code, definition, options = {}) {\r\n    BlissSVGBuilder.#validateCode(code);\r\n\r\n    if (typeof definition?.codeString !== 'string' || definition.codeString.trim().length === 0) {\r\n      throw new Error(`define(\"${code}\"): \"codeString\" must be a non-empty, non-whitespace string.`);\r\n    }\r\n\r\n    // A glyph is a single character; `/` and `//` are word separators, so a\r\n    // `/`-bearing codeString is a word, not a glyph. Define a word as a bare\r\n    // alias (omit type:\"glyph\"). (Strict Indicator Separation, F4.)\r\n    if (definition.codeString.includes('/')) {\r\n      throw new Error(`define(\"${code}\"): a glyph definition cannot be a multi-character word (its codeString contains \"/\"). Define a word as a bare alias (omit type:\"glyph\").`);\r\n    }\r\n\r\n    // `;;` is a word-level indicator (a word property); a glyph is a single\r\n    // character, so it cannot carry one. (Strict Indicator Separation.)\r\n    if (definition.codeString.includes(';;')) {\r\n      throw new Error(`define(\"${code}\"): a glyph definition cannot contain a word-level indicator (\";;\"); a glyph is a single character. Apply a word indicator at the use site (WORD;;INDICATOR).`);\r\n    }\r\n\r\n    // Glyphs can reference other glyphs and shapes, but not external glyphs or bare aliases\r\n    const refError = BlissSVGBuilder.#validateReferences(code, definition.codeString, ['glyph', 'shape']);\r\n    if (refError) throw new Error(`define(${refError})`);\r\n    if (BlissSVGBuilder.#hasCircularReference(code, definition.codeString)) {\r\n      throw new Error(`define(\"${code}\"): circular reference detected`);\r\n    }\r\n\r\n    // D-S1a: a glyph is a base character or a compound indicator, never a\r\n    // base+indicator combo. Reject a glyph def (not flagged isIndicator) that\r\n    // bakes in an indicator part; define such combos as bare aliases instead.\r\n    if (definition.isIndicator !== true) {\r\n      const refs = BlissSVGBuilder.#extractReferencedCodes(definition.codeString);\r\n      if (refs.some(ref => blissElementDefinitions[ref]?.isIndicator === true)) {\r\n        throw new Error(`define(\"${code}\"): a glyph definition cannot bake in an indicator. Define a base+indicator combination as a bare alias (omit type:\"glyph\"), attach the indicator at the use site (BASE;INDICATOR), or flag a compound indicator with isIndicator:true.`);\r\n      }\r\n    }\r\n\r\n    BlissSVGBuilder.#assertReplaceable(code, options);\r\n\r\n    const entry = {\r\n      codeString: definition.codeString,\r\n      glyphCode: code,\r\n      isBlissGlyph: true\r\n    };\r\n    if (definition.isIndicator === true) entry.isIndicator = true;\r\n    if (typeof definition.anchorOffsetX === 'number' && isFinite(definition.anchorOffsetX)) {\r\n      entry.anchorOffsetX = definition.anchorOffsetX;\r\n    }\r\n    if (typeof definition.anchorOffsetY === 'number' && isFinite(definition.anchorOffsetY)) {\r\n      entry.anchorOffsetY = definition.anchorOffsetY;\r\n    }\r\n    if (typeof definition.width === 'number' && isFinite(definition.width)) {\r\n      entry.width = definition.width;\r\n    }\r\n    if (definition.kerningRules && typeof definition.kerningRules === 'object') {\r\n      entry.kerningRules = { ...definition.kerningRules };\r\n    }\r\n    if (definition.shrinksPrecedingWordSpace === true) {\r\n      entry.shrinksPrecedingWordSpace = true;\r\n    }\r\n    if (definition.defaultOptions && typeof definition.defaultOptions === 'object') {\r\n      // Snapshot ONCE, validate the snapshot, store the SAME snapshot: the\r\n      // guard must judge exactly what the registry keeps, or an accessor /\r\n      // Proxy could show one set of keys to validation and another to storage\r\n      // (round-4 review F1).\r\n      const defaultOptionsSnapshot = { ...definition.defaultOptions };\r\n      if (Object.keys(defaultOptionsSnapshot).length > 0) {\r\n        BlissSVGBuilder.#assertNoGlobalOnlyDefaultOptions('define', code, defaultOptionsSnapshot);\r\n        entry.defaultOptions = defaultOptionsSnapshot;\r\n      }\r\n    }\r\n\r\n    if (entry.isIndicator === true) {\r\n      BlissSVGBuilder.#assertNoIndicatorBakeDependents('define', code, entry);\r\n    }\r\n\r\n    blissElementDefinitions[code] = entry;\r\n  }\r\n\r\n  static #defineExternalGlyph(code, definition, options = {}) {\r\n    BlissSVGBuilder.#validateCode(code);\r\n\r\n    if (typeof definition?.getPath !== 'function') {\r\n      throw new Error(`define(\"${code}\"): \"getPath\" must be a function.`);\r\n    }\r\n    if (typeof definition.width !== 'number' || !isFinite(definition.width)) {\r\n      throw new Error(`define(\"${code}\"): \"width\" must be a finite number.`);\r\n    }\r\n    if (typeof definition.char !== 'string' || definition.char.length === 0) {\r\n      throw new Error(`define(\"${code}\"): \"char\" must be a non-empty string.`);\r\n    }\r\n\r\n    BlissSVGBuilder.#assertReplaceable(code, options);\r\n\r\n    const entry = {\r\n      getPath: definition.getPath,\r\n      width: definition.width,\r\n      char: definition.char,\r\n      isExternalGlyph: true\r\n    };\r\n    if (typeof definition.y === 'number') entry.y = definition.y;\r\n    if (typeof definition.height === 'number') entry.height = definition.height;\r\n    if (definition.kerningRules && typeof definition.kerningRules === 'object') {\r\n      entry.kerningRules = { ...definition.kerningRules };\r\n    }\r\n    if (definition.defaultOptions && typeof definition.defaultOptions === 'object') {\r\n      // Snapshot ONCE, validate the snapshot, store the SAME snapshot: the\r\n      // guard must judge exactly what the registry keeps, or an accessor /\r\n      // Proxy could show one set of keys to validation and another to storage\r\n      // (round-4 review F1).\r\n      const defaultOptionsSnapshot = { ...definition.defaultOptions };\r\n      if (Object.keys(defaultOptionsSnapshot).length > 0) {\r\n        BlissSVGBuilder.#assertNoGlobalOnlyDefaultOptions('define', code, defaultOptionsSnapshot);\r\n        entry.defaultOptions = defaultOptionsSnapshot;\r\n      }\r\n    }\r\n\r\n    blissElementDefinitions[code] = entry;\r\n  }\r\n\r\n  // Resolution VIEW of a codeString, for validation only — never stored\r\n  // (store-as-written, ratified 2026-07-22: definition content keeps\r\n  // bare-alias references verbatim and the parser resolves them late).\r\n  // Replaces bare alias tokens with their resolved codeString, repeating\r\n  // until no more aliases remain (up to depth 50), so a guard can judge\r\n  // what a reference chain would deliver (the word-internal-coordinate\r\n  // guard in #defineBare and patchDefinition).\r\n  // Head-marker contract: marked invocations (ALIAS^) and aliases whose\r\n  // codeString carries a ^ designation stay as references, so the parser\r\n  // resolves the marker in its own word-string scope (rules 2 and 4).\r\n  // Inlining them would silently rebind the marker to a different scope.\r\n  static #resolveBareAliases(codeString) {\r\n    let resolved = codeString;\r\n    for (let depth = 0; depth < 50; depth++) {\r\n      let changed = false;\r\n      // \\w+ (not letter-first): define() accepts digit-leading names (the\r\n      // Blissary-ID pattern, e.g. '1219'), so aliases to them must resolve\r\n      // like any other single-code rename (review MINOR-4). The lookbehind/\r\n      // lookahead boundaries keep coordinate and kerning values (after ':')\r\n      // out of reach.\r\n      resolved = resolved.replace(\r\n        /(?<=^|[/;])(\\w+)(?=$|[/;:])/g,\r\n        (match, token) => {\r\n          const def = blissElementDefinitions[token];\r\n          if (def && def.codeString && !def.codeString.includes('^')\r\n              && !def.isBlissGlyph && !def.isShape && !def.isExternalGlyph && !def.glyphCode) {\r\n            changed = true;\r\n            return def.codeString;\r\n          }\r\n          return match;\r\n        }\r\n      );\r\n      if (!changed) break;\r\n    }\r\n    return resolved;\r\n  }\r\n\r\n  /**\r\n   * Part-merge operand check (reuses the runtime predicate via the parser):\r\n   * true if the codeString uses a composed unflagged alias as a non-leading\r\n   * ;-part, which the parser flags COMPOSITE_AS_PART. Run on the written\r\n   * codeString — the form that gets stored (store-as-written).\r\n   * Parse failures (e.g. a circular reference) are not this check's concern.\r\n   */\r\n  static #hasCompositePartViolation(codeString) {\r\n    let parsed;\r\n    try {\r\n      parsed = BlissParser.parse(codeString);\r\n    } catch {\r\n      return false;\r\n    }\r\n    for (const group of parsed.groups ?? []) {\r\n      for (const glyph of group.glyphs ?? []) {\r\n        for (const part of glyph.parts ?? []) {\r\n          if (part.errorCode === 'COMPOSITE_AS_PART') return true;\r\n        }\r\n      }\r\n    }\r\n    return false;\r\n  }\r\n\r\n  static #defineBare(code, definition, options = {}) {\r\n    BlissSVGBuilder.#validateCode(code);\r\n\r\n    if (typeof definition?.codeString !== 'string' || definition.codeString.trim().length === 0) {\r\n      throw new Error(`define(\"${code}\"): \"codeString\" must be a non-empty, non-whitespace string.`);\r\n    }\r\n\r\n    // `;;` is a word-level indicator applied at the USE SITE (WORD;;INDICATOR),\r\n    // never baked into a stored definition -- the same rule #defineGlyph and\r\n    // #defineShape enforce, extended to bare aliases. Baking it in is nonsensical:\r\n    // a further use-site `;;` on such a definition would nest word-indicators, yet\r\n    // a word carries only one. Reject ANY `;;`, whether or not the code after it\r\n    // is itself an indicator. (Strict Indicator Separation.)\r\n    if (definition.codeString.includes(';;')) {\r\n      throw new Error(`define(\"${code}\"): a definition cannot contain a word-level indicator (\";;\"); apply a word indicator at the use site (WORD;;INDICATOR).`);\r\n    }\r\n\r\n    // Reject a definition cycle at define time. Bare aliases can reference any\r\n    // type (glyph/shape/bare), so unlike #defineGlyph/#defineShape this path had\r\n    // no cycle guard: a cycle (CA -> CB -> CA, or a direct self-reference) was\r\n    // stored and then crashed at render with \"Maximum recursion depth\". Rejecting\r\n    // one side here leaves the chain terminating at an unregistered code instead.\r\n    if (BlissSVGBuilder.#hasCircularReference(code, definition.codeString)) {\r\n      throw new Error(`define(\"${code}\"): circular reference detected`);\r\n    }\r\n\r\n    // Part-merge operand rule: a ; part must be a part (a primitive or a flagged\r\n    // glyph/indicator), never a composition. Reject a codeString that uses a\r\n    // composed unflagged alias as a ;-part (checked on the written codeString,\r\n    // which is also what gets stored), so define() is consistent with the\r\n    // use-site failure.\r\n    if (BlissSVGBuilder.#hasCompositePartViolation(definition.codeString)) {\r\n      throw new Error(`define(\"${code}\"): a ; part cannot be a composition (\"${definition.codeString}\"). A ; part must be a primitive or a flagged glyph; attach indicators at the use site (BASE;INDICATOR) or compose words with /.`);\r\n    }\r\n\r\n    BlissSVGBuilder.#assertReplaceable(code, options);\r\n\r\n    // Store-as-written (ratified 2026-07-22): bare-alias references in the\r\n    // codeString stay verbatim, so definition content is late-bound like a\r\n    // native code (a redefine of a referenced code flows through to every\r\n    // composition using it). Only /SP/ space segments normalize.\r\n    const stored = BlissSVGBuilder.#normalizeSpaceSegments(definition.codeString);\r\n\r\n    // Word definitions (containing /) must not have internal position\r\n    // modifiers, not even through a referenced alias: the guard judges the\r\n    // RESOLVED VIEW so a stored 'POSX/B313' cannot bake coordinates via\r\n    // POSX = 'B291:2,3'. Position belongs at the usage site, e.g. WORD:2,0.\r\n    BlissSVGBuilder.#assertNoWordInternalCoordinates(\r\n      'define', code, BlissSVGBuilder.#resolveBareAliases(stored)\r\n    );\r\n\r\n    const entry = { codeString: stored };\r\n\r\n    if (definition.defaultOptions && typeof definition.defaultOptions === 'object') {\r\n      // Snapshot ONCE, validate the snapshot, store the SAME snapshot: the\r\n      // guard must judge exactly what the registry keeps, or an accessor /\r\n      // Proxy could show one set of keys to validation and another to storage\r\n      // (round-4 review F1).\r\n      const defaultOptionsSnapshot = { ...definition.defaultOptions };\r\n      if (Object.keys(defaultOptionsSnapshot).length > 0) {\r\n        BlissSVGBuilder.#assertNoGlobalOnlyDefaultOptions('define', code, defaultOptionsSnapshot);\r\n        entry.defaultOptions = defaultOptionsSnapshot;\r\n      }\r\n    }\r\n\r\n    if (resolveEffectiveDefinition(entry, blissElementDefinitions)?.isIndicator === true) {\r\n      BlissSVGBuilder.#assertNoIndicatorBakeDependents('define', code, entry);\r\n    }\r\n\r\n    blissElementDefinitions[code] = entry;\r\n  }\r\n\r\n  /**\r\n   * Define one or more codes. The single public entry point for all definitions.\r\n   *\r\n   * Use the optional `type` field to specify the definition type:\r\n   * - `type: 'glyph'` — Bliss character (sets isBlissGlyph, glyphCode)\r\n   * - `type: 'shape'` — shape (primitive with getPath, or composite with codeString)\r\n   * - `type: 'externalGlyph'` — external glyph (getPath + glyph)\r\n   * - No type — bare definition (word, alias, or any codeString-based code)\r\n   *\r\n   * When no `type` is specified, auto-detection applies for getPath-based definitions:\r\n   * - Has getPath + glyph → externalGlyph\r\n   * - Has getPath (no glyph) → shape\r\n   * - Has codeString (no type) → bare definition\r\n   *\r\n   * @param {Object.<string, Object>} definitions - Map of code → definition\r\n   * @param {Object} [options]\r\n   * @param {boolean} [options.overwrite=false]\r\n   * @returns {{ defined: string[], skipped: string[], errors: string[] }}\r\n   */\r\n  static define(definitions, options = {}) {\r\n    const result = { defined: [], skipped: [], errors: [] };\r\n\r\n    if (!definitions || typeof definitions !== 'object') {\r\n      return result;\r\n    }\r\n\r\n    for (const [code, definition] of Object.entries(definitions)) {\r\n      try {\r\n        const type = definition?.type;\r\n\r\n        if (type && type !== 'glyph' && type !== 'shape' && type !== 'externalGlyph') {\r\n          result.errors.push(`\"${code}\": unknown type \"${type}\". Use 'glyph', 'shape', or 'externalGlyph'.`);\r\n          continue;\r\n        }\r\n\r\n        // isIndicator declares a compound indicator glyph and is honored only\r\n        // on a type:'glyph' definition. On a bare alias, shape, or external\r\n        // glyph the flag was silently dropped, so the `;`-slot render and the\r\n        // `;;` gate disagreed with the stated intent (run-to-stable Phase 2.4c).\r\n        // Reject it and point to the documented form. Indicator-ness still\r\n        // rides through an unflagged bare alias whose target is a real\r\n        // indicator (e.g. { codeString: 'B81' }); only the flag on a non-glyph\r\n        // definition is rejected.\r\n        if (definition?.isIndicator === true && type !== 'glyph') {\r\n          result.errors.push(`\"${code}\": isIndicator is only valid on a type:'glyph' definition (a compound indicator glyph). To declare a custom indicator, use type:'glyph' with isIndicator:true.`);\r\n          continue;\r\n        }\r\n\r\n        if (type === 'glyph') {\r\n          BlissSVGBuilder.#defineGlyph(code, definition, options);\r\n        } else if (type === 'shape') {\r\n          BlissSVGBuilder.#defineShape(code, definition, options);\r\n        } else if (type === 'externalGlyph') {\r\n          BlissSVGBuilder.#defineExternalGlyph(code, definition, options);\r\n        } else if (typeof definition?.getPath === 'function' && typeof definition?.char === 'string') {\r\n          BlissSVGBuilder.#defineExternalGlyph(code, definition, options);\r\n        } else if (typeof definition?.getPath === 'function') {\r\n          BlissSVGBuilder.#defineShape(code, definition, options);\r\n        } else if (typeof definition?.codeString === 'string') {\r\n          BlissSVGBuilder.#defineBare(code, definition, options);\r\n        } else {\r\n          result.errors.push(`\"${code}\": unable to detect definition type. Provide codeString, type+getPath+width+height (shape), or type+getPath+char (externalGlyph).`);\r\n          continue;\r\n        }\r\n        result.defined.push(code);\r\n      } catch (err) {\r\n        if (err.code === 'ALREADY_EXISTS') {\r\n          result.skipped.push(code);\r\n        } else {\r\n          result.errors.push(`\"${code}\": ${err.message}`);\r\n        }\r\n      }\r\n    }\r\n\r\n    return result;\r\n  }\r\n\r\n  // Registry membership is OWN-property membership: the definitions object\r\n  // inherits from Object.prototype, so a plain `in` or truthy lookup reports\r\n  // inherited names (toString, constructor, __proto__, ...) as defined codes\r\n  // and hands back JS built-ins as definitions. define()'s existence gate\r\n  // (#assertReplaceable) intentionally keeps its truthy check: it classifies\r\n  // inherited names as already-exists in the DEFAULT path. That accident does\r\n  // NOT hold under overwrite:true, where a non-literal \"__proto__\" key (e.g.\r\n  // JSON.parse output) still reaches the registry assignment and reassigns\r\n  // the registry's prototype through the inherited setter; the define-side\r\n  // name-policy backlog item tracks closing that vector.\r\n  static #ownsDefinition(code) {\r\n    return Object.prototype.hasOwnProperty.call(blissElementDefinitions, code);\r\n  }\r\n\r\n  /**\r\n   * Check if a code is defined.\r\n   * @param {string} code\r\n   * @returns {boolean}\r\n   */\r\n  static isDefined(code) {\r\n    return BlissSVGBuilder.#ownsDefinition(code);\r\n  }\r\n\r\n  /**\r\n   * Get definition metadata for a code (frozen copy, not the live object).\r\n   *\r\n   * @param {string} code\r\n   * @returns {Object|null} Frozen metadata object, or null if not found\r\n   */\r\n  static getDefinition(code) {\r\n    if (!BlissSVGBuilder.#ownsDefinition(code)) return null;\r\n    const def = blissElementDefinitions[code];\r\n\r\n    const copy = {};\r\n    for (const [key, value] of Object.entries(def)) {\r\n      if (typeof value === 'object' && value !== null) {\r\n        copy[key] = Object.freeze({ ...value });\r\n      } else {\r\n        copy[key] = value;\r\n      }\r\n    }\r\n\r\n    copy.type = BlissSVGBuilder.#detectType(def);\r\n\r\n    copy.isBuiltIn = protectedCodes.has(code);\r\n\r\n    return Object.freeze(copy);\r\n  }\r\n\r\n  /**\r\n   * List all defined codes, optionally filtered by type.\r\n   *\r\n   * @param {Object} [filter]\r\n   * @param {'shape'|'glyph'|'externalGlyph'|'bare'|'space'} [filter.type]\r\n   * @returns {string[]}\r\n   */\r\n  static listDefinitions(filter = {}) {\r\n    const codes = Object.keys(blissElementDefinitions);\r\n\r\n    if (!filter.type) return codes;\r\n\r\n    return codes.filter(code => {\r\n      return BlissSVGBuilder.#detectType(blissElementDefinitions[code]) === filter.type;\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Remove a custom definition. Built-in definitions cannot be removed.\r\n   *\r\n   * @param {string} code\r\n   * @returns {boolean} true if removed\r\n   * @throws {Error} If attempting to remove a built-in definition\r\n   */\r\n  static removeDefinition(code) {\r\n    if (protectedCodes.has(code)) {\r\n      throw new Error(`removeDefinition(\"${code}\"): cannot remove built-in definitions.`);\r\n    }\r\n    if (!BlissSVGBuilder.#ownsDefinition(code)) {\r\n      return false;\r\n    }\r\n    delete blissElementDefinitions[code];\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Patch one or more properties on an existing custom definition.\r\n   * Only allowed keys for the definition's type are accepted.\r\n   * Built-in definitions cannot be patched.\r\n   *\r\n   * @param {string} code - The code to patch\r\n   * @param {Object} changes - Properties to update\r\n   * @returns {{ patched: true }}\r\n   * @throws {Error} If code is not defined, is built-in, or changes are invalid\r\n   */\r\n  static patchDefinition(code, changes) {\r\n    if (!BlissSVGBuilder.#ownsDefinition(code)) {\r\n      throw new Error(`patchDefinition(\"${code}\"): code is not defined.`);\r\n    }\r\n    if (protectedCodes.has(code)) {\r\n      throw new Error(`patchDefinition(\"${code}\"): cannot patch built-in definitions.`);\r\n    }\r\n    if (!changes || typeof changes !== 'object') {\r\n      throw new Error(`patchDefinition(\"${code}\"): changes must be an object.`);\r\n    }\r\n\r\n    const def = blissElementDefinitions[code];\r\n\r\n    const type = BlissSVGBuilder.#detectType(def);\r\n\r\n    // Reject type changes and internal flags\r\n    const internalKeys = new Set(['type', 'isShape', 'isExternalGlyph', 'isBlissGlyph', 'glyphCode', 'isBuiltIn']);\r\n    for (const key of Object.keys(changes)) {\r\n      if (internalKeys.has(key)) {\r\n        throw new Error(`patchDefinition(\"${code}\"): cannot change \"${key}\" via patch.`);\r\n      }\r\n    }\r\n\r\n    // Allowed keys per type\r\n    const allowedByType = {\r\n      glyph: ['codeString', 'anchorOffsetX', 'anchorOffsetY', 'width', 'isIndicator', 'shrinksPrecedingWordSpace', 'kerningRules', 'defaultOptions'],\r\n      shape: ['getPath', 'codeString', 'width', 'height', 'x', 'y', 'extraPathOptions', 'defaultOptions'],\r\n      externalGlyph: ['getPath', 'width', 'char', 'y', 'height', 'kerningRules', 'defaultOptions'],\r\n      bare: ['codeString', 'defaultOptions'],\r\n      space: ['defaultOptions']\r\n    };\r\n\r\n    const allowed = new Set(allowedByType[type] || []);\r\n    for (const key of Object.keys(changes)) {\r\n      if (!allowed.has(key)) {\r\n        throw new Error(`patchDefinition(\"${code}\"): \"${key}\" is not a valid property for type \"${type}\".`);\r\n      }\r\n    }\r\n\r\n    // Validate getPath is a function if provided\r\n    if ('getPath' in changes && typeof changes.getPath !== 'function') {\r\n      throw new Error(`patchDefinition(\"${code}\"): \"getPath\" must be a function.`);\r\n    }\r\n\r\n    // If codeString is being patched, validate references and circular refs\r\n    if ('codeString' in changes) {\r\n      const newCodeString = changes.codeString;\r\n      if (typeof newCodeString !== 'string' || newCodeString.trim().length === 0) {\r\n        throw new Error(`patchDefinition(\"${code}\"): \"codeString\" must be a non-empty, non-whitespace string.`);\r\n      }\r\n      // A `;;` word-level indicator is a use-site construct (WORD;;INDICATOR);\r\n      // NO definition of any type may bake one in, so this guard is universal.\r\n      // A `/` word separator is glyph/shape-only (a bare alias may itself be a\r\n      // word). Mirror the #defineGlyph/#defineShape/#defineBare guards so\r\n      // patchDefinition cannot construct a state define() forbids. (Strict\r\n      // Indicator Separation.)\r\n      if (newCodeString.includes(';;')) {\r\n        throw new Error(`patchDefinition(\"${code}\"): a definition cannot contain a word-level indicator (\";;\"); apply a word indicator at the use site (WORD;;INDICATOR).`);\r\n      }\r\n      if ((type === 'glyph' || type === 'shape') && newCodeString.includes('/')) {\r\n        throw new Error(`patchDefinition(\"${code}\"): a ${type} definition cannot be a multi-character word (its codeString contains \"/\"). Define a word as a bare alias (omit type:\"${type}\").`);\r\n      }\r\n      const allowedRefTypes = type === 'glyph' ? ['glyph', 'shape']\r\n        : type === 'shape' ? ['shape']\r\n        : ['glyph', 'shape', 'bare', 'externalGlyph'];\r\n      const refError = BlissSVGBuilder.#validateReferences(code, newCodeString, allowedRefTypes);\r\n      if (refError) throw new Error(`patchDefinition(${refError})`);\r\n      if (BlissSVGBuilder.#hasCircularReference(code, newCodeString)) {\r\n        throw new Error(`patchDefinition(\"${code}\"): circular reference detected`);\r\n      }\r\n      // Part-merge operand rule, mirroring #defineBare so both definition\r\n      // surfaces agree: a bare codeString cannot use a composed unflagged alias\r\n      // as a ;-part (checked on the written codeString, the form that gets stored).\r\n      if (type === 'bare' && BlissSVGBuilder.#hasCompositePartViolation(newCodeString)) {\r\n        throw new Error(`patchDefinition(\"${code}\"): a ; part cannot be a composition (\"${newCodeString}\"). A ; part must be a primitive or a flagged glyph; attach indicators at the use site (BASE;INDICATOR) or compose words with /.`);\r\n      }\r\n    }\r\n\r\n    // D-S1a on the patch surface: a glyph (not flagged isIndicator) cannot\r\n    // bake an indicator, whichever property the patch changes — a codeString\r\n    // gaining indicator anatomy, or an isIndicator un-flag on a compound\r\n    // indicator that keeps its anatomy. The POST-patch state is judged, so\r\n    // codeString + isIndicator:true in one patch stays legal.\r\n    if (type === 'glyph' && ('codeString' in changes || 'isIndicator' in changes)) {\r\n      const nextCodeString = 'codeString' in changes ? changes.codeString : def.codeString;\r\n      const nextIsIndicator = 'isIndicator' in changes ? changes.isIndicator === true : def.isIndicator === true;\r\n      if (!nextIsIndicator && typeof nextCodeString === 'string') {\r\n        const refs = BlissSVGBuilder.#extractReferencedCodes(nextCodeString);\r\n        if (refs.some(ref => blissElementDefinitions[ref]?.isIndicator === true)) {\r\n          throw new Error(`patchDefinition(\"${code}\"): a glyph definition cannot bake in an indicator. Define a base+indicator combination as a bare alias (omit type:\"glyph\"), attach the indicator at the use site (BASE;INDICATOR), or flag a compound indicator with isIndicator:true.`);\r\n        }\r\n      }\r\n    }\r\n\r\n    // For bare definitions, store the codeString as written (bare-alias\r\n    // references stay verbatim and resolve at parse time); SP segments\r\n    // normalize to word breaks and the word-internal-coordinate guard\r\n    // judges the resolved view, mirroring #defineBare (patch cannot\r\n    // construct a state define() forbids).\r\n    if ('codeString' in changes && type === 'bare') {\r\n      const stored = BlissSVGBuilder.#normalizeSpaceSegments(changes.codeString);\r\n      BlissSVGBuilder.#assertNoWordInternalCoordinates(\r\n        'patchDefinition', code, BlissSVGBuilder.#resolveBareAliases(stored)\r\n      );\r\n      changes = { ...changes, codeString: stored };\r\n    }\r\n\r\n    // Deferred validation at the completing patch (Phase 2.3): a patch that\r\n    // makes this definition an indicator — a glyph isIndicator flip, or a\r\n    // bare codeString now resolving to an indicator — re-checks every custom\r\n    // glyph referencing it, exactly like the completing define.\r\n    const becomesIndicator =\r\n      (type === 'glyph' && changes.isIndicator === true && def.isIndicator !== true) ||\r\n      (type === 'bare' && 'codeString' in changes &&\r\n        resolveEffectiveDefinition({ codeString: changes.codeString }, blissElementDefinitions)?.isIndicator === true);\r\n    if (becomesIndicator) {\r\n      BlissSVGBuilder.#assertNoIndicatorBakeDependents('patchDefinition', code, { ...def, ...changes });\r\n    }\r\n\r\n    // Validate BEFORE the apply loop, like every other patch guard: a\r\n    // rejected patch must leave the definition fully unchanged, not partially\r\n    // mutated depending on property order (round-3 review F2). The snapshot\r\n    // taken here REPLACES the caller's object in `changes`, so the apply loop\r\n    // stores exactly what was validated — an accessor / Proxy cannot show\r\n    // different keys to the two reads (round-4 review F1).\r\n    if (changes.defaultOptions && typeof changes.defaultOptions === 'object') {\r\n      const defaultOptionsSnapshot = { ...changes.defaultOptions };\r\n      if (Object.keys(defaultOptionsSnapshot).length > 0) {\r\n        BlissSVGBuilder.#assertNoGlobalOnlyDefaultOptions('patchDefinition', code, defaultOptionsSnapshot);\r\n      }\r\n      changes = { ...changes, defaultOptions: defaultOptionsSnapshot };\r\n    }\r\n\r\n    // Apply changes\r\n    for (const [key, value] of Object.entries(changes)) {\r\n      if (key === 'defaultOptions') {\r\n        if (value && typeof value === 'object' && Object.keys(value).length > 0) {\r\n          def.defaultOptions = { ...value };\r\n        } else {\r\n          delete def.defaultOptions;\r\n        }\r\n      } else if (key === 'kerningRules') {\r\n        if (value && typeof value === 'object') {\r\n          def.kerningRules = { ...value };\r\n        } else {\r\n          delete def.kerningRules;\r\n        }\r\n      } else {\r\n        def[key] = value;\r\n      }\r\n    }\r\n\r\n    return { patched: true };\r\n  }\r\n\r\n  get #svgCode() {\r\n    // Computed rendering dimensions\r\n    const width = Math.max(this.composition.width, this.#processedOptions.minWidth ?? 0);\r\n    const height = 20;\r\n\r\n    // User-provided options with defaults\r\n    const color = this.#processedOptions.color ?? \"#000000\";\r\n    const strokeWidth = this.#processedOptions.strokeWidth ?? 0.5;\r\n    const marginTop = this.#processedOptions.marginTop ?? 0.75;\r\n    const marginBottom = this.#processedOptions.marginBottom ?? 0.75;\r\n    const marginLeft = this.#processedOptions.marginLeft ?? 0.75;\r\n    const marginRight = this.#processedOptions.marginRight ?? 0.75;\r\n\r\n    // Compute crop values - can be numeric or 'auto' (computed from effectiveBounds)\r\n    const bounds = this.composition.effectiveBounds;\r\n    const rawCropLeft = this.#processedOptions.cropLeft ?? 0;\r\n    const rawCropRight = this.#processedOptions.cropRight ?? 0;\r\n\r\n    // Compact mode: crop up to 4 units total, preferring top then bottom,\r\n    // limited by actual empty space (never crop into ink).\r\n    // Explicit crop-top/crop-bottom override (not add to) the compact defaults.\r\n    let rawCropTop, rawCropBottom;\r\n    if (this.#processedOptions.cropCompact) {\r\n      const topRoom = bounds.minY;\r\n      const bottomRoom = height - bounds.maxY;\r\n      const compactTop = Math.min(4, topRoom);\r\n      const compactBottom = Math.min(4 - compactTop, bottomRoom);\r\n      rawCropTop = this.#processedOptions.cropTop ?? compactTop;\r\n      rawCropBottom = this.#processedOptions.cropBottom ?? compactBottom;\r\n    } else if (this.#processedOptions.autoVertical) {\r\n      rawCropTop = this.#processedOptions.cropTop ?? 'auto';\r\n      rawCropBottom = this.#processedOptions.cropBottom ?? 'auto';\r\n    } else {\r\n      rawCropTop = this.#processedOptions.cropTop ?? 0;\r\n      rawCropBottom = this.#processedOptions.cropBottom ?? 0;\r\n    }\r\n\r\n    const cropTop = rawCropTop === 'auto' ? bounds.minY : rawCropTop;\r\n    const cropBottom = rawCropBottom === 'auto' ? (height - bounds.maxY) : rawCropBottom;\r\n    let cropLeft = rawCropLeft === 'auto' ? bounds.minX : rawCropLeft;\r\n    let cropRight = rawCropRight === 'auto' ? (width - bounds.maxX) : rawCropRight;\r\n\r\n    // Ensure min-width is respected after auto horizontal cropping.\r\n    // Numeric crops are deliberate, so only limit auto-computed crops.\r\n    const minW = this.#processedOptions.minWidth ?? 0;\r\n    if (minW > 0 && (rawCropLeft === 'auto' || rawCropRight === 'auto')) {\r\n      const croppedWidth = width - cropLeft - cropRight;\r\n      if (croppedWidth < minW) {\r\n        const deficit = minW - croppedWidth;\r\n        const autoLeft = rawCropLeft === 'auto' ? cropLeft : 0;\r\n        const autoRight = rawCropRight === 'auto' ? cropRight : 0;\r\n        const autoTotal = autoLeft + autoRight;\r\n        if (autoTotal > 0) {\r\n          const reduce = Math.min(deficit, autoTotal);\r\n          if (rawCropLeft === 'auto') cropLeft -= reduce * (autoLeft / autoTotal);\r\n          if (rawCropRight === 'auto') cropRight -= reduce * (autoRight / autoTotal);\r\n        }\r\n      }\r\n    }\r\n\r\n    let viewBoxX = -marginLeft + cropLeft;\r\n    const viewBoxY = -marginTop + cropTop;\r\n    let gridOffsetX = 0;\r\n\r\n    if (this.#processedOptions.center === true && width > this.composition.width) {\r\n      const leftOverhang = -this.composition.x;\r\n      const rightOverhang = (this.composition.x + this.composition.width) - this.composition.baseWidth;\r\n      const maxOverhang = Math.max(leftOverhang, rightOverhang);\r\n      const symmetricWidth = this.composition.baseWidth + 2 * maxOverhang;\r\n      const extraSpace = width - symmetricWidth;\r\n      const offset = extraSpace / 2;\r\n      viewBoxX -= offset;\r\n      gridOffsetX = viewBoxX + marginLeft;\r\n    }\r\n    const content = this.svgContent;\r\n    // Clamp to >= 0: when crop insets past the available box (an empty\r\n    // document, or a crop larger than the content), the raw difference goes\r\n    // negative, which is invalid SVG. Flooring at 0 keeps the crop monotonic\r\n    // (a wider crop shrinks the box toward 0 and stays there) and valid.\r\n    const viewBoxWidth = Math.max(0, width + marginLeft + marginRight - cropLeft - cropRight);\r\n    const viewBoxHeight = Math.max(0, height + marginTop + marginBottom - cropTop - cropBottom);\r\n    const svgAttributeMultiplier = 6;\r\n\r\n    // Calculate SVG element dimensions (maintaining aspect ratio)\r\n    let svgWidth, svgHeight;\r\n    if (this.#processedOptions.svgHeight !== undefined) {\r\n      // Height specified: calculate width to maintain aspect ratio.\r\n      // Guard the clamped viewBoxHeight === 0 case so it never divides to NaN.\r\n      svgHeight = this.#processedOptions.svgHeight;\r\n      svgWidth = viewBoxHeight > 0 ? (viewBoxWidth / viewBoxHeight) * svgHeight : 0;\r\n    } else {\r\n      // Auto-calculate both dimensions\r\n      svgWidth = svgAttributeMultiplier * viewBoxWidth;\r\n      svgHeight = svgAttributeMultiplier * viewBoxHeight;\r\n    }\r\n\r\n    const round = (num) => parseFloat(num.toFixed(4));\r\n\r\n    const svgTitle = this.#processedOptions.svgTitle ?? \"\";\r\n    const svgDesc = this.#processedOptions.svgDesc ?? \"\";\r\n    const background = this.#processedOptions.background ?? \"\";\r\n    const backgroundTop = this.#processedOptions.backgroundTop;\r\n    const backgroundMid = this.#processedOptions.backgroundMid;\r\n    const backgroundBottom = this.#processedOptions.backgroundBottom;\r\n    const hasZones = backgroundTop || backgroundMid || backgroundBottom;\r\n\r\n    let title = svgTitle ? `  <title>${svgTitle}</title>` : \"\";\r\n    let desc = svgDesc ? `  <desc>${svgDesc}</desc>` : \"\";\r\n    let gridPath = \"\";\r\n    let svgText = \"\";\r\n\r\n    let backgroundContent;\r\n    if (hasZones) {\r\n      const bulkBg = background;\r\n      const topColor = backgroundTop || bulkBg;\r\n      const midColor = backgroundMid || bulkBg;\r\n      const bottomColor = backgroundBottom || bulkBg;\r\n      const zoneX = round(viewBoxX);\r\n      const zoneWidth = round(viewBoxWidth);\r\n      const topY = round(viewBoxY);\r\n      // Zone heights floor at 0 like the outer viewBox dimensions above: an\r\n      // ordinary vertical crop can push the viewBox past the sky (y=8) or\r\n      // earth (y=16) boundary, and a negative height is invalid SVG on <rect>.\r\n      const topHeight = round(Math.max(0, 8 - viewBoxY));\r\n      const bottomHeight = round(Math.max(0, viewBoxY + viewBoxHeight - 16));\r\n\r\n      const zoneRects = [\r\n        topColor ? `    <rect class=\"bliss-background--top\" x=\"${zoneX}\" y=\"${topY}\" width=\"${zoneWidth}\" height=\"${topHeight}\" stroke=\"none\" fill=\"${topColor}\"/>` : '',\r\n        midColor ? `    <rect class=\"bliss-background--mid\" x=\"${zoneX}\" y=\"8\" width=\"${zoneWidth}\" height=\"8\" stroke=\"none\" fill=\"${midColor}\"/>` : '',\r\n        bottomColor ? `    <rect class=\"bliss-background--bottom\" x=\"${zoneX}\" y=\"16\" width=\"${zoneWidth}\" height=\"${bottomHeight}\" stroke=\"none\" fill=\"${bottomColor}\"/>` : '',\r\n      ].filter(Boolean).join('\\n');\r\n\r\n      backgroundContent = `  <g class=\"bliss-background\">\\n${zoneRects}\\n  </g>`;\r\n    } else {\r\n      backgroundContent = background === \"\" ? \"\" : `  <rect class=\"bliss-background\" x=\"${viewBoxX}\" y=\"${viewBoxY}\" width=\"100%\" height=\"100%\" stroke=\"none\" fill=\"${background}\"/>`;\r\n    }\r\n\r\n    // Grid boundaries adjusted for cropping\r\n    const gridStartX = gridOffsetX + cropLeft;\r\n    const gridLineWidth = width - cropLeft - cropRight;\r\n    const gridMinY = cropTop;\r\n    const gridMaxY = height - cropBottom;\r\n\r\n    const hLine = (y) => `M${gridStartX},${y}h${gridLineWidth}`;\r\n    const hLines = (ys) => ys.filter(y => y >= gridMinY && y <= gridMaxY).map(hLine).join('');\r\n\r\n    let getVerticalLines = (type) => {\r\n      let pathData = \"\";\r\n      let xs = [];\r\n\r\n      switch(type) {\r\n        case \"minor\":\r\n          //odd numbers\r\n          for (let x = 1; x <= width; x += 2) xs.push(x);\r\n          break;\r\n        case \"medium\":\r\n          //even numbers not divisible with 4\r\n          for (let x = 2; x <= width; x += 4) xs.push(x);\r\n          break;\r\n        case \"major\":\r\n          //even numbers divisible with 4\r\n          for (let x = 0; x <= width; x += 4) xs.push(x);\r\n          break;\r\n      }\r\n      for (const x of xs.filter(x => x >= cropLeft && x <= width - cropRight)) {\r\n        pathData += `M${gridOffsetX + x},${gridMinY}V${gridMaxY}`;\r\n      }\r\n      return pathData;\r\n    }\r\n    if (this.#processedOptions.grid) {\r\n      const gridMinorStrokeWidth = this.#processedOptions.gridMinorStrokeWidth ?? 0.166;\r\n      const gridMinorColor = this.#processedOptions.gridMinorColor ?? \"#ebebeb\";\r\n      const gridMediumStrokeWidth = this.#processedOptions.gridMediumStrokeWidth ?? 0.166;\r\n      const gridMediumColor = this.#processedOptions.gridMediumColor ?? \"#ebebeb\";\r\n      const gridMajorStrokeWidth = this.#processedOptions.gridMajorStrokeWidth ?? 0.166;\r\n      const gridMajorColor = this.#processedOptions.gridMajorColor ?? \"#c7c7c7\";\r\n      const gridSkyStrokeWidth = this.#processedOptions.gridSkyStrokeWidth ?? 0.166;\r\n      const gridSkyColor = this.#processedOptions.gridSkyColor ?? \"#858585\";\r\n      const gridEarthStrokeWidth = this.#processedOptions.gridEarthStrokeWidth ?? 0.166;\r\n      const gridEarthColor = this.#processedOptions.gridEarthColor ?? \"#858585\";\r\n\r\n      const minorD = hLines([1,3,5,7,9,11,13,15,17,19]) + getVerticalLines(\"minor\");\r\n      const mediumD = hLines([2,6,10,14,18]) + getVerticalLines(\"medium\");\r\n      const majorD = hLines([0,4,12,20]) + getVerticalLines(\"major\");\r\n      const skyD = 8 >= gridMinY && 8 <= gridMaxY ? hLine(8) : '';\r\n      const earthD = 16 >= gridMinY && 16 <= gridMaxY ? hLine(16) : '';\r\n\r\n      const gridLines = [\r\n        minorD ? `    <path class=\"bliss-grid-line bliss-grid-line--minor\" stroke-width=\"${gridMinorStrokeWidth}\" stroke=\"${gridMinorColor}\" stroke-linecap=\"square\" stroke-linejoin=\"miter\" d=\"${minorD}\"/>` : '',\r\n        mediumD ? `    <path class=\"bliss-grid-line bliss-grid-line--medium\" stroke-width=\"${gridMediumStrokeWidth}\" stroke=\"${gridMediumColor}\" stroke-linecap=\"square\" stroke-linejoin=\"miter\" d=\"${mediumD}\"/>` : '',\r\n        majorD ? `    <path class=\"bliss-grid-line bliss-grid-line--major\" stroke-width=\"${gridMajorStrokeWidth}\" stroke=\"${gridMajorColor}\" stroke-linecap=\"square\" stroke-linejoin=\"miter\" d=\"${majorD}\"/>` : '',\r\n        skyD ? `    <path class=\"bliss-grid-line bliss-grid-line--major bliss-grid-line--sky\" stroke-width=\"${gridSkyStrokeWidth}\" stroke=\"${gridSkyColor}\" stroke-linecap=\"square\" stroke-linejoin=\"miter\" d=\"${skyD}\"/>` : '',\r\n        earthD ? `    <path class=\"bliss-grid-line bliss-grid-line--major bliss-grid-line--earth\" stroke-width=\"${gridEarthStrokeWidth}\" stroke=\"${gridEarthColor}\" stroke-linecap=\"square\" stroke-linejoin=\"miter\" d=\"${earthD}\"/>` : '',\r\n      ].filter(Boolean).join('\\n');\r\n\r\n      gridPath = [\r\n        '  <style>',\r\n        '    @supports (-webkit-hyphens: none) {',\r\n        '      .bliss-grid-line { shape-rendering: geometricPrecision; }',\r\n        '    }',\r\n        '  </style>',\r\n        '  <g class=\"bliss-grid\" shape-rendering=\"crispEdges\">',\r\n        gridLines,\r\n        '  </g>',\r\n      ].join('\\n');\r\n    }\r\n\r\n    // Build content group attributes: defaults + all global SVG attributes\r\n    const contentDefaults = {\r\n      fill: 'none',\r\n      stroke: color,\r\n      'stroke-linejoin': 'round',\r\n      'stroke-linecap': 'round',\r\n      'stroke-width': strokeWidth,\r\n    };\r\n    const contentAttrs = { ...contentDefaults, ...this.globalSvgAttributes };\r\n    // A global `class` option merges with the structural bliss-content class\r\n    // instead of emitting a second class attribute (invalid SVG; issue #28).\r\n    const userClass = contentAttrs['class'];\r\n    delete contentAttrs['class'];\r\n    const contentClass = userClass ? `bliss-content ${userClass}` : 'bliss-content';\r\n    // Link attributes belong to the level-0 anchor wrap, never the content <g>.\r\n    for (const name of ANCHOR_ATTRIBUTE_NAMES) delete contentAttrs[name];\r\n    // vector-effect is non-inherited; relocate it from the content group onto\r\n    // the glyph paths so it actually takes effect. Always remove it from the\r\n    // group (even an empty value, which would otherwise be a dead attribute on\r\n    // the <g>); only stamp the paths when there is a value, matching the\r\n    // element-scope handling in BlissElement.\r\n    let contentInner = content;\r\n    if ('vector-effect' in contentAttrs) {\r\n      const vectorEffect = contentAttrs['vector-effect'];\r\n      delete contentAttrs['vector-effect'];\r\n      if (vectorEffect) contentInner = BlissElement.applyVectorEffectToPaths(content, vectorEffect);\r\n    }\r\n    const contentAttrsStr = Object.entries(contentAttrs)\r\n      .map(([key, value]) => `${key}=\"${value}\"`)\r\n      .join(' ');\r\n\r\n    const generator = LIB_VERSION ? `bliss-svg-builder/${LIB_VERSION}` : 'bliss-svg-builder';\r\n\r\n    let svgStr = [\r\n      `<svg xmlns=\"http://www.w3.org/2000/svg\" data-generator=\"${generator}\" width=\"${round(svgWidth)}\" height=\"${round(svgHeight)}\" viewBox=\"${round(viewBoxX)} ${round(viewBoxY)} ${round(viewBoxWidth)} ${round(viewBoxHeight)}\">`,\r\n      title,\r\n      desc,\r\n      backgroundContent,\r\n      gridPath,\r\n      `  <g class=\"${contentClass}\" ${contentAttrsStr}>`,\r\n      `    ${contentInner}`,\r\n      '  </g>',\r\n      svgText,\r\n      '</svg>',\r\n    ].filter(Boolean).join('\\n');\r\n\r\n    // Clean up empty <path d=\"\"/> elements from DOT/COMMA/external glyphs\r\n    svgStr = svgStr.replace(/<path d=\"\"\\/>/g, '');\r\n\r\n    return svgStr;\r\n  }\r\n}\r\n\r\nexport { BlissSVGBuilder };\r\n","import { BlissSVGBuilder } from './lib/bliss-svg-builder.js';\nimport { LIB_VERSION } from './lib/bliss-constants.js';\n\n// Hoist LIB_VERSION onto the class so IIFE consumers, where\n// `window.BlissSVGBuilder` is the class itself, can read the\n// version as `BlissSVGBuilder.LIB_VERSION`.\nBlissSVGBuilder.LIB_VERSION = LIB_VERSION;\n\nexport { BlissSVGBuilder, LIB_VERSION };\nexport default BlissSVGBuilder;\n"],"mappings":"AAgBA,OAAM,iBAAA,QAA4B,CAAA,WAAA,CAAA,MAAA,EAAA,GAAA,OAAA,aAAA,CAAA,MAAA,QAAA,CAAA,CAAA,EAIlC,IAAA,EAAA,IAEA,EAAS,IACP,EAAiB,IACnB,SAAA,EAAA,EAAA,CAEA,OAAS,EAAA,EAAiC,GAAG,EAI7C,SAAA,EAAA,EAAA,CAEA,OAAM,EAAA,WAIF,EAAe,EAAU,EAAA,EAAA,QACrB,EAAQ,QAAA,eAAA,GAAA,WAAA,WAAA,CAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,CAAA,SAAA,CAAA,MAAiC,EAAA,IAC7C,CACA,YAAM,EAAA,gvDAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,itCAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,i8BAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,4sCAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,s7BAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,4oBAAA,EACN,IAAA,OAAA,CAGF,OAAA,EAAA,GAAA,CACA,EACE,OAAA,MACA,KAAI,iBAAiB,CAAA,EAAA,EAAqB,EAAA,CAAA,MAC1C,CACA,YAAM,EAAA,ooDAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,wyBAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,4PAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,GAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,+iBAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,GAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,6XAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,8HAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,GAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,w2CAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,04BAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,w0BAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,ixCAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,qsCAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,wqBAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,GAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,4kDAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,4mBAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,GAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,24BAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,8XAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,guBAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,kbAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,81BAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,oSAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,wlFAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,4+DAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,skCAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,gnBAAA,EACN,IAAA,OAAA,CACE,OAAK,EAAA,IAAuB,UAEvB,WACA,iBACA,CACL,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,EAAA,EAC9B,EAAA,EAAA,EAAA,EACF,EAAA,EAAA,GAAA,EACA,EAAM,EAAA,EAAA,EACJ,EAAA,EAAyB,GAAA,EACzB,EAAI,EAAQ,GAAA,OACZ,CACA,YAAM,EAAA,yhCAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,47BAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,+qBAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,wSAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,8PAAA,EACN,IAAA,OAAA,CAGF,OAAA,EAAA,IAAA,CACA,EACE,OAAA,MACA,KAAI,iBAAiB,CAAA,EAAA,EAAqB,GAAA,CAAA,MAC1C,CACA,YAAM,EAAA,2iCAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,sSAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,+HAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,GAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,yjBAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,gYAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,yKAAA,EACN,IAAA,OAAA,CACE,OAAK,EAAA,IAAuB,UAEvB,WACA,iBACA,CACP,EAAA,EAAA,EAAA,EACF,EAAA,EAAA,GAAA,EACA,EAAM,EAAA,GAAA,EACJ,EAAA,EAAyB,GAAA,EACzB,EAAI,EAAQ,GAAA,OACZ,CACA,YAAM,EAAA,u6BAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,mcAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,y+BAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,2jBAAA,EACN,IAAA,OAAA,CAGF,OAAA,EAAA,IAAA,CACA,EACE,OAAA,MACA,KAAI,iBAAiB,CAAA,EAAA,EAAqB,GAAA,CAAA,MAC1C,CACA,YAAM,EAAA,o1CAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,suBAAA,EACN,IAAA,OAAA,CACE,OAAK,EAAA,IAAuB,UAEvB,WACA,IACP,aAAA,CACF,EAAA,EAAA,EAAA,EACA,EAAM,EAAA,EAAA,EACJ,EAAA,EAAyB,EAAA,EACzB,EAAI,EAAQ,EAAA,OACZ,CACA,YAAM,EAAA,gsDAAA,EACR,IAAA,OAAA,CACA,OAAM,EAAA,IAAA,CACJ,EACA,OAAI,WAAU,QACd,CACA,YAAM,EAAA,kNAAA,EACN,IAAA,OAAA,CACE,OAAK,EAAA,IAAuB,UAEvB,WACA,iBACA,CACL,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,EAAE,EAC9B,EAAK,EAAuB,EAAE,EAC9B,EAAK,EAAuB,EAAE,EAC9B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,EAAE,EAC9B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,EAAE,EAC9B,EAAK,EAAuB,EAAE,EAC9B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,EAAA,EAC5B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAG,EAC/B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,GAAE,EAC9B,EAAK,EAAuB,EAAE,EAC9B,EAAK,EAAuB,EAAE,EAC9B,EAAK,EAAuB,EAAE,EAC9B,EAAK,EA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AAK,WAAA,QAAA,KACH,CACA,WAAA,wCACF,aAAA,CACA,MACE,CACA,WAAA,8BACF,aAAA,CACA,MACE,CACA,WAAA,iCACF,aAAA,CACA,MACE,CACA,WAAA,wBACF,aAAA,CACA,MACE,CACA,WAAA,6BACF,aAAA,CACA,MACE,CACA,WAAA,gDACF,aAAA,CACA,MACE,CACA,WAAA,6BACF,aAAA,CACA,MACE,CACA,WAAA,uBACF,aAAA,CACA,MACE,CACA,WAAA,kBACF,aAAA,CACA,MACE,CACA,WAAA,6BACF,aAAA,CACA,MACE,CACA,WAAA,8CACF,aAAA,CACA,MACE,CACA,WAAA,iCACF,aAAA,CACA,MACE,CACA,WAAA,qCACF,aAAA,CACA,MACE,CACA,WAAA,wBACF,aAAA,CACA,MACE,CACA,WAAA,6BACF,aAAA,CACA,MACE,CACA,WAAA,oDACF,aAAA,CACA,MACE,CACA,WAAA,+BACF,aAAA,CACA,MACE,CACA,WAAA,0BACF,aAAA,CACA,MACE,CACA,WAAA,kBACF,aAAA,CACA,MACE,CACA,WAAA,iCACA,aAAA,GAEF,IAAA,CACA,WAAK,WACH,YAAY,GACZ,cAAa,SACb,KAAA,oBAEF,IAAA,CACA,WAAK,WACH,YAAY,GACZ,cAAa,SACb,KAAA,wBAEA,CACF,WAAA,mCACA,YAAK,GACH,cAAY,SACZ,MAAA,EACA,KAAA,qCAEA,CACA,WAAM,eACR,YAAA,GACA,cAAK,aACH,cAAY,IACZ,MAAA,EACA,KAAA,4CAEA,CACA,WAAM,mBACR,YAAA,GACA,cAAK,aACH,cAAY,GACZ,MAAA,EACA,KAAA,yCAEF,IAAA,CACA,WAAK,WACH,YAAY,GACZ,cAAa,aACb,KAAA,6BAEA,CACF,WAAA,WACA,YAAK,GACH,cAAY,SACZ,MAAA,GACA,KAAA,wBAEA,CACF,WAAA,cACA,YAAK,GACH,cAAY,SACZ,MAAA,IACA,KAAA,oCAEA,CACF,WAAA,cACA,YAAK,GACH,cAAY,SACZ,MAAA,IACA,KAAA,gCAEA,CACF,WAAA,cACA,YAAK,GACH,cAAY,SACZ,MAAA,IACA,KAAA,wCAEF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"}