@edynamix/mf-isolation 0.0.31 → 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/postcss.js CHANGED
@@ -1,5 +1,5 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { list } from 'postcss';
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
+ import { basename, dirname, join } from 'node:path';
3
3
  import selectorParser from 'postcss-selector-parser';
4
4
  import valueParser from 'postcss-value-parser';
5
5
  import { getMfScopeSelector, MF_ROOT_SELECTOR, MF_SCOPE_ATTRIBUTE, validateMfScopeId } from './index.js';
@@ -172,12 +172,33 @@ const hasRootOnlySelector = (selectorList) => {
172
172
  }).processSync(selectorList);
173
173
  return result;
174
174
  };
175
+ const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
176
+ // A component stylesheet need not be named *.component.scss (CampaignManagement's create-campaign.ts uses
177
+ // `styleUrl: './create-campaign.scss'`); treated as global CSS, Angular would then encapsulate the boundary itself and
178
+ // the rules could never match. Such a file is a component's when a sibling component source references it.
179
+ const referencingComponentSourceOf = (stylePath) => {
180
+ const directory = dirname(stylePath);
181
+ if (!existsSync(directory)) {
182
+ return undefined;
183
+ }
184
+ const reference = new RegExp(`styleUrls?\\s*:\\s*(?:\\[[^\\]]*?)?['"\`]\\./${escapeRegExp(basename(stylePath))}['"\`]`);
185
+ for (const fileName of readdirSync(directory)) {
186
+ if (!fileName.endsWith('.ts') || /\.(?:spec|test|d)\.ts$/.test(fileName)) {
187
+ continue;
188
+ }
189
+ const sourcePath = join(directory, fileName);
190
+ if (reference.test(readFileSync(sourcePath, 'utf8'))) {
191
+ return sourcePath;
192
+ }
193
+ }
194
+ return undefined;
195
+ };
175
196
  const getAngularComponentSourcePath = (stylePath) => {
176
197
  const cleanStylePath = stylePath.replace(/[?#].*$/, '');
177
- if (!ANGULAR_COMPONENT_STYLE_PATTERN.test(cleanStylePath)) {
178
- return undefined;
198
+ if (ANGULAR_COMPONENT_STYLE_PATTERN.test(cleanStylePath)) {
199
+ return cleanStylePath.replace(/\.(?:css|less|sass|scss)$/i, '.ts');
179
200
  }
180
- return cleanStylePath.replace(/\.(?:css|less|sass|scss)$/i, '.ts');
201
+ return /\.(?:css|less|sass|scss)$/i.test(cleanStylePath) ? referencingComponentSourceOf(cleanStylePath) : undefined;
181
202
  };
182
203
  const usesViewEncapsulationNone = (stylePath) => {
183
204
  const componentSourcePath = getAngularComponentSourcePath(stylePath);
@@ -265,67 +286,6 @@ const scopeSelectorList = (selectorList, scopeId, scopeSelector, rootScopeSelect
265
286
  }
266
287
  }).processSync(selectorList);
267
288
  };
268
- const findFunctionalPseudoEnd = (selector, openParenthesisIndex) => {
269
- let depth = 0;
270
- let quote;
271
- for (let index = openParenthesisIndex; index < selector.length; index += 1) {
272
- const character = selector[index];
273
- const previousCharacter = selector[index - 1];
274
- if (quote) {
275
- if (character === quote && previousCharacter !== '\\') {
276
- quote = undefined;
277
- }
278
- continue;
279
- }
280
- if (character === '"' || character === "'") {
281
- quote = character;
282
- continue;
283
- }
284
- if (character === '(') {
285
- depth += 1;
286
- }
287
- else if (character === ')') {
288
- depth -= 1;
289
- if (depth === 0) {
290
- return index;
291
- }
292
- }
293
- }
294
- return -1;
295
- };
296
- const scopeAngularSelector = (selector, boundarySelector) => {
297
- const normalizedSelector = selector.trim();
298
- const angularBoundary = `:host-context(${boundarySelector})`;
299
- const normalizedBoundary = normalizedSelector.slice(0, angularBoundary.length).replaceAll("'", '"');
300
- if (normalizedBoundary === angularBoundary) {
301
- return normalizedSelector;
302
- }
303
- if (/^:host-context\(/i.test(normalizedSelector)) {
304
- return `${angularBoundary}${normalizedSelector}`;
305
- }
306
- if (/^:host\(/i.test(normalizedSelector)) {
307
- const openParenthesisIndex = normalizedSelector.indexOf('(');
308
- const closeParenthesisIndex = findFunctionalPseudoEnd(normalizedSelector, openParenthesisIndex);
309
- if (closeParenthesisIndex !== -1) {
310
- const hostSelector = normalizedSelector.slice(openParenthesisIndex + 1, closeParenthesisIndex);
311
- const remainder = normalizedSelector.slice(closeParenthesisIndex + 1);
312
- return list
313
- .comma(hostSelector)
314
- .map((hostSelectorVariant) => `${angularBoundary}${hostSelectorVariant}${remainder}`)
315
- .join(', ');
316
- }
317
- }
318
- if (/^:host\b/i.test(normalizedSelector)) {
319
- return normalizedSelector.replace(/^:host\b/i, angularBoundary);
320
- }
321
- return `${angularBoundary} ${normalizedSelector}`;
322
- };
323
- const scopeAngularSelectorList = (selectorList, boundarySelector) => {
324
- return list
325
- .comma(selectorList)
326
- .map((selector) => scopeAngularSelector(selector, boundarySelector))
327
- .join(', ');
328
- };
329
289
  const namespaceKeyframes = (root, keyframePrefix) => {
330
290
  const keyframes = new Map();
331
291
  root.walkAtRules((atRule) => {
@@ -514,13 +474,15 @@ const scopeGlobalRoot = (root, scopeId, scopeSelector, keyframePrefix, warn) =>
514
474
  }
515
475
  });
516
476
  };
517
- const scopeAngularComponentRoot = (root, boundarySelector, keyframePrefix) => {
477
+ // Emulated component CSS keeps its selectors exactly as written, so Angular compiles what it compiled on the module's
478
+ // own page and every rule keeps its weight and reach: `mat-form-field[_ngcontent-x]` (0,1,1) still loses to a global
479
+ // `.mat-sidenav-content .mat-mdc-form-field` (0,2,0), template content rendered in an overlay (outside the component's
480
+ // host) keeps its component styles, and a top-level `::ng-deep` rule stays global to the module. Wrapping every rule in
481
+ // :host-context(<boundary>) added (0,2,0) to each, and limited all of them to the component's host. Isolation needs no
482
+ // boundary here: Angular's _ngcontent and _nghost attributes are unique to each component, and a hosted module's
483
+ // component styles live in its own shadow root.
484
+ const scopeAngularComponentRoot = (root, keyframePrefix) => {
518
485
  namespaceKeyframes(root, keyframePrefix);
519
- root.walkRules((rule) => {
520
- if (!isKeyframesRule(rule)) {
521
- rule.selector = scopeAngularSelectorList(rule.selector, boundarySelector);
522
- }
523
- });
524
486
  };
525
487
  export const scopeRemoteCss = ({ scopeId }) => {
526
488
  const validScopeId = validateMfScopeId(scopeId);
@@ -536,13 +498,12 @@ export const scopeRemoteCss = ({ scopeId }) => {
536
498
  export const scopeAngularRemoteCss = ({ scopeId }) => {
537
499
  const validScopeId = validateMfScopeId(scopeId);
538
500
  const scopeSelector = getMfScopeSelector(validScopeId);
539
- const boundarySelector = `[${MF_SCOPE_ATTRIBUTE}="${validScopeId}"]`;
540
501
  const keyframePrefix = `edyn-mf-${validScopeId}--`;
541
502
  return {
542
503
  postcssPlugin: `edyn-mf-angular-isolation-${validScopeId}`,
543
504
  Once(root, { result }) {
544
505
  if (shouldUseAngularComponentScoping(root.source?.input.file)) {
545
- scopeAngularComponentRoot(root, boundarySelector, keyframePrefix);
506
+ scopeAngularComponentRoot(root, keyframePrefix);
546
507
  return;
547
508
  }
548
509
  scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix, (node, text) => node.warn(result, text));
@@ -1 +1 @@
1
- {"version":3,"file":"postcss.js","sourceRoot":"","sources":["../src/postcss.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { type Declaration, list, type Plugin, type Root, type Rule } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\nimport valueParser from 'postcss-value-parser';\nimport { getMfScopeSelector, MF_ROOT_SELECTOR, MF_SCOPE_ATTRIBUTE, validateMfScopeId } from './index.js';\nimport { MF_ROOT_FONT_SIZE_PROPERTY } from './root-font-size.js';\n\nexport interface IScopeRemoteCssOptions {\n scopeId: string;\n}\n\nconst ANGULAR_COMPONENT_STYLE_PATTERN = /\\.component\\.(?:css|less|sass|scss)$/i;\nconst VIEW_ENCAPSULATION_NONE_PATTERN = /(?:^|[,{])\\s*encapsulation\\s*:\\s*(?:[A-Za-z_$][\\w$]*\\s*\\.\\s*)+None\\b/m;\nconst MF_OVERLAY_ATTRIBUTE = 'data-edyn-mf-overlay';\n\ntype TTypeScriptMaskState = 'block-comment' | 'code' | 'double-quote' | 'line-comment' | 'single-quote' | 'template';\n\nconst maskTypeScriptCommentsAndStrings = (source: string): string => {\n let maskedSource = '';\n let state: TTypeScriptMaskState = 'code';\n let escaped = false;\n\n const maskCharacter = (character: string): string => {\n return character === '\\n' || character === '\\r' ? character : ' ';\n };\n\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index] ?? '';\n const nextCharacter = source[index + 1];\n\n if (state === 'code') {\n if (character === '/' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'line-comment';\n } else if (character === '/' && nextCharacter === '*') {\n maskedSource += ' ';\n index += 1;\n state = 'block-comment';\n } else if (character === \"'\") {\n maskedSource += ' ';\n state = 'single-quote';\n } else if (character === '\"') {\n maskedSource += ' ';\n state = 'double-quote';\n } else if (character === '`') {\n maskedSource += ' ';\n state = 'template';\n } else {\n maskedSource += character;\n }\n continue;\n }\n\n if (state === 'line-comment') {\n maskedSource += maskCharacter(character);\n if (character === '\\n' || character === '\\r') {\n state = 'code';\n }\n continue;\n }\n\n if (state === 'block-comment') {\n if (character === '*' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'code';\n } else {\n maskedSource += maskCharacter(character);\n }\n continue;\n }\n\n maskedSource += maskCharacter(character);\n if (escaped) {\n escaped = false;\n } else if (character === '\\\\') {\n escaped = true;\n } else if (\n (state === 'single-quote' && character === \"'\") ||\n (state === 'double-quote' && character === '\"') ||\n (state === 'template' && character === '`')\n ) {\n state = 'code';\n }\n }\n\n return maskedSource;\n};\n\nconst isKeyframesRule = (rule: Rule): boolean => {\n const parent = rule.parent;\n return parent?.type === 'atrule' && /keyframes$/i.test(parent.name);\n};\n\nconst isRootNode = (node: selectorParser.Node): boolean => {\n return (\n (node.type === 'tag' && (node.value.toLowerCase() === 'html' || node.value.toLowerCase() === 'body')) ||\n (node.type === 'pseudo' && (node.value === ':root' || node.value === MF_ROOT_SELECTOR))\n );\n};\n\nconst isScopeNode = (node: selectorParser.Node | undefined, scopeId: string): boolean => {\n if (node?.type === 'attribute' && node.attribute === MF_SCOPE_ATTRIBUTE && node.operator === '=' && node.value === scopeId) {\n return true;\n }\n\n const normalized = node?.toString().replaceAll('\"', '').replaceAll(\"'\", '');\n return (\n node?.type === 'pseudo' &&\n (normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}])` ||\n normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}]:not([${MF_OVERLAY_ATTRIBUTE}]))`)\n );\n};\n\nconst startsWithHostPseudo = (selector: selectorParser.Selector): boolean => {\n return selector.first?.type === 'pseudo' && selector.first.value === ':host';\n};\n\nconst removeRootIdentityIds = (selector: selectorParser.Selector): void => {\n let compound: selectorParser.Node[] = [];\n const removeIdsFromRootCompound = (): void => {\n if (compound.some(isRootNode)) {\n for (const node of compound) {\n if (node.type === 'id') {\n node.remove();\n }\n }\n }\n };\n\n for (const node of [...selector.nodes]) {\n if (node.type === 'combinator') {\n removeIdsFromRootCompound();\n compound = [];\n } else {\n compound.push(node);\n }\n }\n removeIdsFromRootCompound();\n};\n\nconst SPECIFICITY_CARRIER = 'edyn-mf-root';\n\n// Legacy rules such as `html body button` or `html body#app .mdc-checkbox__background` are weighed against Angular\n// Material's own rules by the html, body and #app they start from, so the scope that replaces that root must weigh\n// exactly the same. A plain scope attribute (0,1,0) drops the id of `body#app`, letting Material's checked colour win,\n// and outweighs the two types of `html body`, letting an override that lost to `.mat-mdc-button` on the old site win\n// hosted. The root becomes :where(<scope>):not(<carrier>): :where() weighs nothing, and the carrier has the same id,\n// class and type counts as the root part it replaces and never matches the scope element, so :not() always matches and\n// weighs exactly that. Neutral names keep `html`, `body` and `#app` out of the emitted CSS.\nconst rootSpecificityCarrier = (selector: selectorParser.Selector): string => {\n const compounds: selectorParser.Node[][] = [[]];\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n const carrier: string[] = [];\n for (const compound of compounds) {\n if (!compound.some(isRootNode)) {\n continue;\n }\n const types = compound.filter((node) => node.type === 'tag' && isRootNode(node)).length;\n const pseudoRoots = compound.filter((node) => node.type === 'pseudo' && isRootNode(node)).length;\n const ids = compound.filter((node) => node.type === 'id').length;\n carrier.push(\n `${SPECIFICITY_CARRIER.repeat(Math.min(types, 1))}${`.${SPECIFICITY_CARRIER}`.repeat(pseudoRoots)}${`#${SPECIFICITY_CARRIER}`.repeat(ids)}`,\n );\n }\n\n return carrier.filter(Boolean).join(' ');\n};\n\nconst rootedDescendantScope = (selector: selectorParser.Selector, scopeId: string): string => {\n return `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]):not(${rootSpecificityCarrier(selector)})`;\n};\n\nconst isRootOnlySelector = (selector: selectorParser.Selector): boolean => {\n const compounds: selectorParser.Node[][] = [[]];\n\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n return compounds.every((compound) => compound.some(isRootNode));\n};\n\nconst hasRootOnlySelector = (selectorList: string): boolean => {\n let result = false;\n selectorParser((root) => {\n result = root.nodes.some(isRootOnlySelector);\n }).processSync(selectorList);\n return result;\n};\n\nconst getAngularComponentSourcePath = (stylePath: string): string | undefined => {\n const cleanStylePath = stylePath.replace(/[?#].*$/, '');\n if (!ANGULAR_COMPONENT_STYLE_PATTERN.test(cleanStylePath)) {\n return undefined;\n }\n\n return cleanStylePath.replace(/\\.(?:css|less|sass|scss)$/i, '.ts');\n};\n\nconst usesViewEncapsulationNone = (stylePath: string): boolean => {\n const componentSourcePath = getAngularComponentSourcePath(stylePath);\n if (!componentSourcePath || !existsSync(componentSourcePath)) {\n return false;\n }\n\n const componentSource = readFileSync(componentSourcePath, 'utf8');\n return VIEW_ENCAPSULATION_NONE_PATTERN.test(maskTypeScriptCommentsAndStrings(componentSource));\n};\n\nexport const shouldUseAngularComponentScoping = (stylePath: string | undefined): boolean => {\n return !!stylePath && !!getAngularComponentSourcePath(stylePath) && !usesViewEncapsulationNone(stylePath);\n};\n\nconst scopeSelectorList = (selectorList: string, scopeId: string, scopeSelector: string, rootScopeSelectors: string[]): string => {\n return selectorParser((root) => {\n const sourceSelectors = [...root.nodes];\n\n for (const selector of sourceSelectors) {\n const rootNodes = selector.nodes.filter(isRootNode);\n\n if (rootNodes.length > 0) {\n const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [rootedDescendantScope(selector, scopeId)];\n\n for (const replacementSelector of replacementSelectors) {\n const variant = selector.clone();\n removeRootIdentityIds(variant);\n const [firstRoot, ...duplicateRoots] = variant.nodes.filter(isRootNode);\n // The replacement can be a compound of several nodes, e.g. :where(<scope>):not(<carrier>).\n const scopeNodes = selectorParser()\n .astSync(replacementSelector)\n .first.nodes.map((node) => node.clone());\n const [scopeNode, ...followingScopeNodes] = scopeNodes;\n if (firstRoot && scopeNode) {\n firstRoot.replaceWith(scopeNode);\n let previous = scopeNode;\n for (const node of followingScopeNodes) {\n variant.insertAfter(previous, node);\n previous = node;\n }\n }\n\n for (const duplicateRoot of duplicateRoots) {\n const previous = duplicateRoot.prev();\n if (previous?.type === 'combinator') {\n previous.remove();\n }\n duplicateRoot.remove();\n }\n\n root.insertBefore(selector, variant);\n }\n selector.remove();\n continue;\n }\n\n if (startsWithHostPseudo(selector) || isScopeNode(selector.first, scopeId)) {\n continue;\n }\n\n const first = selector.first;\n const needsBoundaryVariant = first?.type === 'universal' || (first?.type === 'pseudo' && first.value.startsWith('::'));\n\n if (needsBoundaryVariant) {\n const hasSiblingCombinator = selector.nodes.some((node) => node.type === 'combinator' && (node.value === '+' || node.value === '~'));\n\n if (!hasSiblingCombinator) {\n const boundaryVariant = selector.clone();\n const boundaryScope = selectorParser().astSync(scopeSelector).first.first.clone();\n boundaryVariant.first.rawSpaceBefore = '';\n if (boundaryVariant.first.type === 'universal') {\n boundaryVariant.first.replaceWith(boundaryScope);\n } else {\n boundaryVariant.prepend(boundaryScope);\n }\n root.insertBefore(selector, boundaryVariant);\n }\n }\n\n const descendantScope = selectorParser().astSync(`${scopeSelector} *`).first;\n const prefixNodes = descendantScope.nodes.slice(0, -1).map((node) => node.clone());\n selector.first.rawSpaceBefore = '';\n for (const prefixNode of prefixNodes.reverse()) {\n selector.prepend(prefixNode);\n }\n }\n\n const seenSelectors = new Set<string>();\n for (const selector of [...root.nodes]) {\n const normalizedSelector = selector.toString().trim();\n if (seenSelectors.has(normalizedSelector)) {\n selector.remove();\n } else {\n seenSelectors.add(normalizedSelector);\n }\n }\n }).processSync(selectorList);\n};\n\nconst findFunctionalPseudoEnd = (selector: string, openParenthesisIndex: number): number => {\n let depth = 0;\n let quote: '\"' | \"'\" | undefined;\n\n for (let index = openParenthesisIndex; index < selector.length; index += 1) {\n const character = selector[index];\n const previousCharacter = selector[index - 1];\n\n if (quote) {\n if (character === quote && previousCharacter !== '\\\\') {\n quote = undefined;\n }\n continue;\n }\n\n if (character === '\"' || character === \"'\") {\n quote = character;\n continue;\n }\n\n if (character === '(') {\n depth += 1;\n } else if (character === ')') {\n depth -= 1;\n if (depth === 0) {\n return index;\n }\n }\n }\n\n return -1;\n};\n\nconst scopeAngularSelector = (selector: string, boundarySelector: string): string => {\n const normalizedSelector = selector.trim();\n const angularBoundary = `:host-context(${boundarySelector})`;\n const normalizedBoundary = normalizedSelector.slice(0, angularBoundary.length).replaceAll(\"'\", '\"');\n\n if (normalizedBoundary === angularBoundary) {\n return normalizedSelector;\n }\n\n if (/^:host-context\\(/i.test(normalizedSelector)) {\n return `${angularBoundary}${normalizedSelector}`;\n }\n\n if (/^:host\\(/i.test(normalizedSelector)) {\n const openParenthesisIndex = normalizedSelector.indexOf('(');\n const closeParenthesisIndex = findFunctionalPseudoEnd(normalizedSelector, openParenthesisIndex);\n if (closeParenthesisIndex !== -1) {\n const hostSelector = normalizedSelector.slice(openParenthesisIndex + 1, closeParenthesisIndex);\n const remainder = normalizedSelector.slice(closeParenthesisIndex + 1);\n return list\n .comma(hostSelector)\n .map((hostSelectorVariant) => `${angularBoundary}${hostSelectorVariant}${remainder}`)\n .join(', ');\n }\n }\n\n if (/^:host\\b/i.test(normalizedSelector)) {\n return normalizedSelector.replace(/^:host\\b/i, angularBoundary);\n }\n\n return `${angularBoundary} ${normalizedSelector}`;\n};\n\nconst scopeAngularSelectorList = (selectorList: string, boundarySelector: string): string => {\n return list\n .comma(selectorList)\n .map((selector) => scopeAngularSelector(selector, boundarySelector))\n .join(', ');\n};\n\nconst namespaceKeyframes = (root: Root, keyframePrefix: string): void => {\n const keyframes = new Map<string, string>();\n\n root.walkAtRules((atRule) => {\n if (!/keyframes$/i.test(atRule.name) || atRule.params.startsWith(keyframePrefix)) {\n return;\n }\n\n const originalName = atRule.params.trim();\n const scopedName = `${keyframePrefix}${originalName}`;\n keyframes.set(originalName, scopedName);\n atRule.params = scopedName;\n });\n\n root.walkDecls((declaration) => {\n if (!/^(?:-webkit-)?animation(?:-name)?$/i.test(declaration.prop) && !declaration.prop.startsWith('--animate-')) {\n return;\n }\n\n const parsed = valueParser(declaration.value);\n parsed.walk((node) => {\n if (node.type === 'word') {\n node.value = keyframes.get(node.value) ?? node.value;\n }\n });\n declaration.value = parsed.toString();\n });\n};\n\nconst INITIAL_FONT_SIZE_PX = 16;\n// Absolute-size keywords as browsers compute them, and the relative ones as they resolve on the root, whose parent size\n// is the initial 16px.\nconst FONT_SIZE_KEYWORDS_PX: Readonly<Record<string, number>> = {\n 'xx-small': 9,\n 'x-small': 10,\n small: 13,\n medium: 16,\n large: 18,\n 'x-large': 24,\n 'xx-large': 32,\n 'xxx-large': 48,\n smaller: INITIAL_FONT_SIZE_PX / 1.2,\n larger: INITIAL_FONT_SIZE_PX * 1.2,\n};\n// On the root, every global keyword gives the initial size.\nconst GLOBAL_KEYWORDS = new Set(['inherit', 'initial', 'revert', 'revert-layer', 'unset']);\n// em, rem and % on the root are relative to the initial size.\nconst FONT_SIZE_UNITS_PX: Readonly<Record<string, number>> = {\n '%': INITIAL_FONT_SIZE_PX / 100,\n cm: 96 / 2.54,\n em: INITIAL_FONT_SIZE_PX,\n in: 96,\n mm: 96 / 25.4,\n pc: 16,\n pt: 96 / 72,\n px: 1,\n q: 96 / 101.6,\n rem: INITIAL_FONT_SIZE_PX,\n};\n\nconst fontSizeOfWord = (word: string): number | undefined => {\n const keyword = FONT_SIZE_KEYWORDS_PX[word.toLowerCase()];\n if (keyword !== undefined) {\n return keyword;\n }\n const dimension = valueParser.unit(word);\n const unitPx = dimension ? FONT_SIZE_UNITS_PX[dimension.unit.toLowerCase()] : undefined;\n const amount = Number(dimension ? dimension.number : Number.NaN);\n return unitPx !== undefined && Number.isFinite(amount) && amount >= 0 ? amount * unitPx : undefined;\n};\n\nconst significantValueNodes = (value: string): valueParser.Node[] => {\n return valueParser(value).nodes.filter((node) => node.type !== 'space' && node.type !== 'comment');\n};\n\nconst globalKeywordFontSize = (nodes: valueParser.Node[]): number | undefined => {\n const [only] = nodes;\n return nodes.length === 1 && only?.type === 'word' && GLOBAL_KEYWORDS.has(only.value.toLowerCase()) ? INITIAL_FONT_SIZE_PX : undefined;\n};\n\nconst resolveFontSize = (value: string): number | undefined => {\n const nodes = significantValueNodes(value);\n const [only] = nodes;\n return globalKeywordFontSize(nodes) ?? (nodes.length === 1 && only?.type === 'word' ? fontSizeOfWord(only.value) : undefined);\n};\n\n// `font: [style] [variant] [weight] [stretch] <size>[/<line-height>] <family>`: the size is the word before `/`, or else\n// the first word that is a size. A function (var(), calc()) or a family name reached first means it cannot be read.\nconst resolveFontShorthandSize = (value: string): number | undefined => {\n const nodes = significantValueNodes(value);\n const globalSize = globalKeywordFontSize(nodes);\n if (globalSize !== undefined) {\n return globalSize;\n }\n\n const slashIndex = nodes.findIndex((node) => node.type === 'div' && node.value === '/');\n if (slashIndex > 0) {\n const size = nodes[slashIndex - 1];\n return size?.type === 'word' ? fontSizeOfWord(size.value) : undefined;\n }\n\n for (const node of nodes) {\n if (node.type !== 'word') {\n return undefined;\n }\n const size = fontSizeOfWord(node.value);\n if (size !== undefined) {\n return size;\n }\n }\n return undefined;\n};\n\n// `html` and `:root` size the document root, so rem; `body` and `html body` size only the body.\nconst targetsDocumentRoot = (selector: selectorParser.Selector): boolean => {\n let subject: selectorParser.Node[] = [];\n for (const node of selector.nodes) {\n subject = node.type === 'combinator' ? [] : [...subject, node];\n }\n return subject.some((node) => (node.type === 'tag' && node.value.toLowerCase() === 'html') || (node.type === 'pseudo' && node.value === ':root'));\n};\n\nconst documentRootSelectorsOf = (selectorList: string): string[] => {\n const selectors: string[] = [];\n selectorParser((root) => {\n for (const selector of root.nodes) {\n if (targetsDocumentRoot(selector)) {\n selectors.push(selector.toString().trim());\n }\n }\n }).processSync(selectorList);\n return selectors;\n};\n\ntype TWarn = (node: Declaration, text: string) => void;\n\n// Hosted, rem resolves against the host page's root, not the root size the module's own page set. Each rule that sizes\n// the document root gets a sibling rule right after it that records that size as MF_ROOT_FONT_SIZE_PROPERTY, under the\n// same conditions (@media, importance) and in the same cascade order; scoping then moves it onto the module boundary,\n// where followModuleRootFontSize() makes rem lengths read it. CSS that never sizes the root is left byte-identical.\nconst recordRootFontSize = (root: Root, warn: TWarn): void => {\n root.walkRules((rule) => {\n if (isKeyframesRule(rule)) {\n return;\n }\n\n let sizing: Declaration | undefined;\n for (const node of rule.nodes) {\n if (node.type === 'decl' && /^font(?:-size)?$/i.test(node.prop) && (node.important || !sizing?.important)) {\n sizing = node;\n }\n }\n if (!sizing) {\n return;\n }\n\n const rootSelectors = documentRootSelectorsOf(rule.selector);\n if (rootSelectors.length === 0) {\n return;\n }\n\n const sizePx = sizing.prop.toLowerCase() === 'font' ? resolveFontShorthandSize(sizing.value) : resolveFontSize(sizing.value);\n if (sizePx === undefined) {\n warn(\n sizing,\n `Cannot resolve the document root font size \"${sizing.value}\" at build time; rem lengths in the hosted module will use the host page's root size.`,\n );\n return;\n }\n\n const recorded = rule.clone({ selector: rootSelectors.join(', ') });\n recorded.raws.before = rule.raws.before || '\\n';\n recorded.removeAll();\n // The recorded size points back at the declaration it came from, so source maps keep a source for it.\n recorded.append({\n important: sizing.important,\n prop: MF_ROOT_FONT_SIZE_PROPERTY,\n source: sizing.source,\n value: `${Number(sizePx.toFixed(4))}px`,\n });\n rule.after(recorded);\n });\n};\n\nconst scopeGlobalRoot = (root: Root, scopeId: string, scopeSelector: string, keyframePrefix: string, warn: TWarn): void => {\n recordRootFontSize(root, warn);\n namespaceKeyframes(root, keyframePrefix);\n const contentRootSelector = `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]:not([${MF_OVERLAY_ATTRIBUTE}]))`;\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n const declarations = rule.nodes.filter((node) => node.type === 'decl');\n const customProperties = declarations.filter((declaration) => declaration.prop.startsWith('--'));\n const standardDeclarations = declarations.filter((declaration) => !declaration.prop.startsWith('--'));\n\n if (customProperties.length > 0 && standardDeclarations.length > 0 && hasRootOnlySelector(rule.selector)) {\n const customPropertyRule = rule.cloneBefore();\n customPropertyRule.walkDecls((declaration) => {\n if (!declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n customPropertyRule.selector = scopeSelectorList(customPropertyRule.selector, scopeId, scopeSelector, [':host', scopeSelector]);\n rule.walkDecls((declaration) => {\n if (declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n }\n\n const containsOnlyCustomProperties = declarations.length > 0 && declarations.every((declaration) => declaration.prop.startsWith('--'));\n const rootScopeSelectors = containsOnlyCustomProperties ? [':host', scopeSelector] : [':host', contentRootSelector];\n rule.selector = scopeSelectorList(rule.selector, scopeId, scopeSelector, rootScopeSelectors);\n }\n });\n};\n\nconst scopeAngularComponentRoot = (root: Root, boundarySelector: string, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n rule.selector = scopeAngularSelectorList(rule.selector, boundarySelector);\n }\n });\n};\n\nexport const scopeRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-isolation-${validScopeId}`,\n Once(root, { result }) {\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix, (node, text) => node.warn(result, text));\n },\n };\n};\n\nexport const scopeAngularRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const boundarySelector = `[${MF_SCOPE_ATTRIBUTE}=\"${validScopeId}\"]`;\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-angular-isolation-${validScopeId}`,\n Once(root, { result }) {\n if (shouldUseAngularComponentScoping(root.source?.input.file)) {\n scopeAngularComponentRoot(root, boundarySelector, keyframePrefix);\n return;\n }\n\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix, (node, text) => node.warn(result, text));\n },\n };\n};\n"]}
1
+ {"version":3,"file":"postcss.js","sourceRoot":"","sources":["../src/postcss.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEpD,OAAO,cAAc,MAAM,yBAAyB,CAAC;AACrD,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzG,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAMjE,MAAM,+BAA+B,GAAG,uCAAuC,CAAC;AAChF,MAAM,+BAA+B,GAAG,uEAAuE,CAAC;AAChH,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAIpD,MAAM,gCAAgC,GAAG,CAAC,MAAc,EAAU,EAAE;IAClE,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,IAAI,KAAK,GAAyB,MAAM,CAAC;IACzC,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,aAAa,GAAG,CAAC,SAAiB,EAAU,EAAE;QAClD,OAAO,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;IACpE,CAAC,CAAC;IAEF,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAExC,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACrB,IAAI,SAAS,KAAK,GAAG,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;gBAC/C,YAAY,IAAI,IAAI,CAAC;gBACrB,KAAK,IAAI,CAAC,CAAC;gBACX,KAAK,GAAG,cAAc,CAAC;YACzB,CAAC;iBAAM,IAAI,SAAS,KAAK,GAAG,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;gBACtD,YAAY,IAAI,IAAI,CAAC;gBACrB,KAAK,IAAI,CAAC,CAAC;gBACX,KAAK,GAAG,eAAe,CAAC;YAC1B,CAAC;iBAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;gBAC7B,YAAY,IAAI,GAAG,CAAC;gBACpB,KAAK,GAAG,cAAc,CAAC;YACzB,CAAC;iBAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;gBAC7B,YAAY,IAAI,GAAG,CAAC;gBACpB,KAAK,GAAG,cAAc,CAAC;YACzB,CAAC;iBAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;gBAC7B,YAAY,IAAI,GAAG,CAAC;gBACpB,KAAK,GAAG,UAAU,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,YAAY,IAAI,SAAS,CAAC;YAC5B,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;YAC7B,YAAY,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;YACzC,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBAC7C,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,KAAK,KAAK,eAAe,EAAE,CAAC;YAC9B,IAAI,SAAS,KAAK,GAAG,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;gBAC/C,YAAY,IAAI,IAAI,CAAC;gBACrB,KAAK,IAAI,CAAC,CAAC;gBACX,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,YAAY,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;YAC3C,CAAC;YACD,SAAS;QACX,CAAC;QAED,YAAY,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;aAAM,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YAC9B,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IACL,CAAC,KAAK,KAAK,cAAc,IAAI,SAAS,KAAK,GAAG,CAAC;YAC/C,CAAC,KAAK,KAAK,cAAc,IAAI,SAAS,KAAK,GAAG,CAAC;YAC/C,CAAC,KAAK,KAAK,UAAU,IAAI,SAAS,KAAK,GAAG,CAAC,EAC3C,CAAC;YACD,KAAK,GAAG,MAAM,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,IAAU,EAAW,EAAE;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,OAAO,MAAM,EAAE,IAAI,KAAK,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,IAAyB,EAAW,EAAE;IACxD,OAAO,CACL,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;QACrG,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,KAAK,gBAAgB,CAAC,CAAC,CACxF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,IAAqC,EAAE,OAAe,EAAW,EAAE;IACtF,IAAI,IAAI,EAAE,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,SAAS,KAAK,kBAAkB,IAAI,IAAI,CAAC,QAAQ,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;QAC3H,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5E,OAAO,CACL,IAAI,EAAE,IAAI,KAAK,QAAQ;QACvB,CAAC,UAAU,KAAK,WAAW,kBAAkB,IAAI,OAAO,IAAI;YAC1D,UAAU,KAAK,WAAW,kBAAkB,IAAI,OAAO,UAAU,oBAAoB,KAAK,CAAC,CAC9F,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,QAAiC,EAAW,EAAE;IAC1E,OAAO,QAAQ,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC;AAC/E,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,QAAiC,EAAQ,EAAE;IACxE,IAAI,QAAQ,GAA0B,EAAE,CAAC;IACzC,MAAM,yBAAyB,GAAG,GAAS,EAAE;QAC3C,IAAI,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC5B,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBACvB,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC/B,yBAAyB,EAAE,CAAC;YAC5B,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,yBAAyB,EAAE,CAAC;AAC9B,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAE3C,mHAAmH;AACnH,mHAAmH;AACnH,uHAAuH;AACvH,qHAAqH;AACrH,qHAAqH;AACrH,uHAAuH;AACvH,4FAA4F;AAC5F,MAAM,sBAAsB,GAAG,CAAC,QAAiC,EAAU,EAAE;IAC3E,MAAM,SAAS,GAA4B,CAAC,EAAE,CAAC,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QACxF,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QACjG,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;QACjE,OAAO,CAAC,IAAI,CACV,GAAG,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,mBAAmB,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,mBAAmB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC5I,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,QAAiC,EAAE,OAAe,EAAU,EAAE;IAC3F,OAAO,WAAW,kBAAkB,KAAK,OAAO,WAAW,sBAAsB,CAAC,QAAQ,CAAC,GAAG,CAAC;AACjG,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,QAAiC,EAAW,EAAE;IACxE,MAAM,SAAS,GAA4B,CAAC,EAAE,CAAC,CAAC;IAEhD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AAClE,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,YAAoB,EAAW,EAAE;IAC5D,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;QACtB,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAE3F,0GAA0G;AAC1G,uHAAuH;AACvH,2GAA2G;AAC3G,MAAM,4BAA4B,GAAG,CAAC,SAAiB,EAAsB,EAAE;IAC7E,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,gDAAgD,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC;IACxH,KAAK,MAAM,QAAQ,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzE,SAAS;QACX,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC7C,IAAI,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;YACrD,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,6BAA6B,GAAG,CAAC,SAAiB,EAAsB,EAAE;IAC9E,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACxD,IAAI,+BAA+B,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QACzD,OAAO,cAAc,CAAC,OAAO,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,4BAA4B,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtH,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,SAAiB,EAAW,EAAE;IAC/D,MAAM,mBAAmB,GAAG,6BAA6B,CAAC,SAAS,CAAC,CAAC;IACrE,IAAI,CAAC,mBAAmB,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC7D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,eAAe,GAAG,YAAY,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAClE,OAAO,+BAA+B,CAAC,IAAI,CAAC,gCAAgC,CAAC,eAAe,CAAC,CAAC,CAAC;AACjG,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,SAA6B,EAAW,EAAE;IACzF,OAAO,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,6BAA6B,CAAC,SAAS,CAAC,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;AAC5G,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,YAAoB,EAAE,OAAe,EAAE,aAAqB,EAAE,kBAA4B,EAAU,EAAE;IAC/H,OAAO,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;QAC7B,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAExC,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAEpD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;gBAE5H,KAAK,MAAM,mBAAmB,IAAI,oBAAoB,EAAE,CAAC;oBACvD,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;oBACjC,qBAAqB,CAAC,OAAO,CAAC,CAAC;oBAC/B,MAAM,CAAC,SAAS,EAAE,GAAG,cAAc,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;oBACxE,2FAA2F;oBAC3F,MAAM,UAAU,GAAG,cAAc,EAAE;yBAChC,OAAO,CAAC,mBAAmB,CAAC;yBAC5B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;oBAC3C,MAAM,CAAC,SAAS,EAAE,GAAG,mBAAmB,CAAC,GAAG,UAAU,CAAC;oBACvD,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;wBAC3B,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;wBACjC,IAAI,QAAQ,GAAG,SAAS,CAAC;wBACzB,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE,CAAC;4BACvC,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;4BACpC,QAAQ,GAAG,IAAI,CAAC;wBAClB,CAAC;oBACH,CAAC;oBAED,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;wBAC3C,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC;wBACtC,IAAI,QAAQ,EAAE,IAAI,KAAK,YAAY,EAAE,CAAC;4BACpC,QAAQ,CAAC,MAAM,EAAE,CAAC;wBACpB,CAAC;wBACD,aAAa,CAAC,MAAM,EAAE,CAAC;oBACzB,CAAC;oBAED,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACvC,CAAC;gBACD,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAClB,SAAS;YACX,CAAC;YAED,IAAI,oBAAoB,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC3E,SAAS;YACX,CAAC;YAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;YAC7B,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAAI,KAAK,WAAW,IAAI,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAEvH,IAAI,oBAAoB,EAAE,CAAC;gBACzB,MAAM,oBAAoB,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC;gBAErI,IAAI,CAAC,oBAAoB,EAAE,CAAC;oBAC1B,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;oBACzC,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;oBAClF,eAAe,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;oBAC1C,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;wBAC/C,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;oBACnD,CAAC;yBAAM,CAAC;wBACN,eAAe,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;oBACzC,CAAC;oBACD,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;YAED,MAAM,eAAe,GAAG,cAAc,EAAE,CAAC,OAAO,CAAC,GAAG,aAAa,IAAI,CAAC,CAAC,KAAK,CAAC;YAC7E,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACnF,QAAQ,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;YACnC,KAAK,MAAM,UAAU,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC/C,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QACxC,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,MAAM,kBAAkB,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;YACtD,IAAI,aAAa,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC1C,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,IAAU,EAAE,cAAsB,EAAQ,EAAE;IACtE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE5C,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,EAAE;QAC1B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YACjF,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,GAAG,cAAc,GAAG,YAAY,EAAE,CAAC;QACtD,SAAS,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;QAC7B,IAAI,CAAC,qCAAqC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAChH,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACnB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACzB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,CAAC;QACH,WAAW,CAAC,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAChC,wHAAwH;AACxH,uBAAuB;AACvB,MAAM,qBAAqB,GAAqC;IAC9D,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,EAAE;IACb,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,oBAAoB,GAAG,GAAG;IACnC,MAAM,EAAE,oBAAoB,GAAG,GAAG;CACnC,CAAC;AACF,4DAA4D;AAC5D,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3F,8DAA8D;AAC9D,MAAM,kBAAkB,GAAqC;IAC3D,GAAG,EAAE,oBAAoB,GAAG,GAAG;IAC/B,EAAE,EAAE,EAAE,GAAG,IAAI;IACb,EAAE,EAAE,oBAAoB;IACxB,EAAE,EAAE,EAAE;IACN,EAAE,EAAE,EAAE,GAAG,IAAI;IACb,EAAE,EAAE,EAAE;IACN,EAAE,EAAE,EAAE,GAAG,EAAE;IACX,EAAE,EAAE,CAAC;IACL,CAAC,EAAE,EAAE,GAAG,KAAK;IACb,GAAG,EAAE,oBAAoB;CAC1B,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,IAAY,EAAsB,EAAE;IAC1D,MAAM,OAAO,GAAG,qBAAqB,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxF,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACtG,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,KAAa,EAAsB,EAAE;IAClE,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;AACrG,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,KAAyB,EAAsB,EAAE;IAC9E,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACrB,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,MAAM,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC;AACzI,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,KAAa,EAAsB,EAAE;IAC5D,MAAM,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACrB,OAAO,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAChI,CAAC,CAAC;AAEF,yHAAyH;AACzH,oHAAoH;AACpH,MAAM,wBAAwB,GAAG,CAAC,KAAa,EAAsB,EAAE;IACrE,MAAM,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC;IACxF,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QACnC,OAAO,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,gGAAgG;AAChG,MAAM,mBAAmB,GAAG,CAAC,QAAiC,EAAW,EAAE;IACzE,IAAI,OAAO,GAA0B,EAAE,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC;AACpJ,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,CAAC,YAAoB,EAAY,EAAE;IACjE,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;QACtB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,IAAI,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAClC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IAC7B,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAIF,uHAAuH;AACvH,uHAAuH;AACvH,sHAAsH;AACtH,oHAAoH;AACpH,MAAM,kBAAkB,GAAG,CAAC,IAAU,EAAE,IAAW,EAAQ,EAAE;IAC3D,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;QACtB,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,IAAI,MAA+B,CAAC;QACpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;gBAC1G,MAAM,GAAG,IAAI,CAAC;YAChB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,MAAM,aAAa,GAAG,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,wBAAwB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7H,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CACF,MAAM,EACN,+CAA+C,MAAM,CAAC,KAAK,uFAAuF,CACnJ,CAAC;YACF,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpE,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;QAChD,QAAQ,CAAC,SAAS,EAAE,CAAC;QACrB,sGAAsG;QACtG,QAAQ,CAAC,MAAM,CAAC;YACd,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,IAAI,EAAE,0BAA0B;YAChC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI;SACxC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,IAAU,EAAE,OAAe,EAAE,aAAqB,EAAE,cAAsB,EAAE,IAAW,EAAQ,EAAE;IACxH,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/B,kBAAkB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACzC,MAAM,mBAAmB,GAAG,WAAW,kBAAkB,KAAK,OAAO,WAAW,oBAAoB,KAAK,CAAC;IAC1G,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;QACtB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;YACvE,MAAM,gBAAgB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YACjG,MAAM,oBAAoB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAEtG,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzG,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC9C,kBAAkB,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;oBAC3C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;wBACvC,WAAW,CAAC,MAAM,EAAE,CAAC;oBACvB,CAAC;gBACH,CAAC,CAAC,CAAC;gBACH,kBAAkB,CAAC,QAAQ,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;gBAC/H,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;oBAC7B,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;wBACtC,WAAW,CAAC,MAAM,EAAE,CAAC;oBACvB,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,4BAA4B,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YACvI,MAAM,kBAAkB,GAAG,4BAA4B,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;YACpH,IAAI,CAAC,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,kBAAkB,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,sHAAsH;AACtH,qHAAqH;AACrH,uHAAuH;AACvH,wHAAwH;AACxH,uHAAuH;AACvH,iHAAiH;AACjH,gDAAgD;AAChD,MAAM,yBAAyB,GAAG,CAAC,IAAU,EAAE,cAAsB,EAAQ,EAAE;IAC7E,kBAAkB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAAE,OAAO,EAA0B,EAAU,EAAE;IAC5E,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACvD,MAAM,cAAc,GAAG,WAAW,YAAY,IAAI,CAAC;IAEnD,OAAO;QACL,aAAa,EAAE,qBAAqB,YAAY,EAAE;QAClD,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE;YACnB,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9G,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EAAE,OAAO,EAA0B,EAAU,EAAE;IACnF,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACvD,MAAM,cAAc,GAAG,WAAW,YAAY,IAAI,CAAC;IAEnD,OAAO;QACL,aAAa,EAAE,6BAA6B,YAAY,EAAE;QAC1D,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE;YACnB,IAAI,gCAAgC,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9D,yBAAyB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;gBAChD,OAAO;YACT,CAAC;YAED,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9G,CAAC;KACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { existsSync, readdirSync, readFileSync } from 'node:fs';\nimport { basename, dirname, join } from 'node:path';\nimport type { Declaration, Plugin, Root, Rule } from 'postcss';\nimport selectorParser from 'postcss-selector-parser';\nimport valueParser from 'postcss-value-parser';\nimport { getMfScopeSelector, MF_ROOT_SELECTOR, MF_SCOPE_ATTRIBUTE, validateMfScopeId } from './index.js';\nimport { MF_ROOT_FONT_SIZE_PROPERTY } from './root-font-size.js';\n\nexport interface IScopeRemoteCssOptions {\n scopeId: string;\n}\n\nconst ANGULAR_COMPONENT_STYLE_PATTERN = /\\.component\\.(?:css|less|sass|scss)$/i;\nconst VIEW_ENCAPSULATION_NONE_PATTERN = /(?:^|[,{])\\s*encapsulation\\s*:\\s*(?:[A-Za-z_$][\\w$]*\\s*\\.\\s*)+None\\b/m;\nconst MF_OVERLAY_ATTRIBUTE = 'data-edyn-mf-overlay';\n\ntype TTypeScriptMaskState = 'block-comment' | 'code' | 'double-quote' | 'line-comment' | 'single-quote' | 'template';\n\nconst maskTypeScriptCommentsAndStrings = (source: string): string => {\n let maskedSource = '';\n let state: TTypeScriptMaskState = 'code';\n let escaped = false;\n\n const maskCharacter = (character: string): string => {\n return character === '\\n' || character === '\\r' ? character : ' ';\n };\n\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index] ?? '';\n const nextCharacter = source[index + 1];\n\n if (state === 'code') {\n if (character === '/' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'line-comment';\n } else if (character === '/' && nextCharacter === '*') {\n maskedSource += ' ';\n index += 1;\n state = 'block-comment';\n } else if (character === \"'\") {\n maskedSource += ' ';\n state = 'single-quote';\n } else if (character === '\"') {\n maskedSource += ' ';\n state = 'double-quote';\n } else if (character === '`') {\n maskedSource += ' ';\n state = 'template';\n } else {\n maskedSource += character;\n }\n continue;\n }\n\n if (state === 'line-comment') {\n maskedSource += maskCharacter(character);\n if (character === '\\n' || character === '\\r') {\n state = 'code';\n }\n continue;\n }\n\n if (state === 'block-comment') {\n if (character === '*' && nextCharacter === '/') {\n maskedSource += ' ';\n index += 1;\n state = 'code';\n } else {\n maskedSource += maskCharacter(character);\n }\n continue;\n }\n\n maskedSource += maskCharacter(character);\n if (escaped) {\n escaped = false;\n } else if (character === '\\\\') {\n escaped = true;\n } else if (\n (state === 'single-quote' && character === \"'\") ||\n (state === 'double-quote' && character === '\"') ||\n (state === 'template' && character === '`')\n ) {\n state = 'code';\n }\n }\n\n return maskedSource;\n};\n\nconst isKeyframesRule = (rule: Rule): boolean => {\n const parent = rule.parent;\n return parent?.type === 'atrule' && /keyframes$/i.test(parent.name);\n};\n\nconst isRootNode = (node: selectorParser.Node): boolean => {\n return (\n (node.type === 'tag' && (node.value.toLowerCase() === 'html' || node.value.toLowerCase() === 'body')) ||\n (node.type === 'pseudo' && (node.value === ':root' || node.value === MF_ROOT_SELECTOR))\n );\n};\n\nconst isScopeNode = (node: selectorParser.Node | undefined, scopeId: string): boolean => {\n if (node?.type === 'attribute' && node.attribute === MF_SCOPE_ATTRIBUTE && node.operator === '=' && node.value === scopeId) {\n return true;\n }\n\n const normalized = node?.toString().replaceAll('\"', '').replaceAll(\"'\", '');\n return (\n node?.type === 'pseudo' &&\n (normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}])` ||\n normalized === `:where([${MF_SCOPE_ATTRIBUTE}=${scopeId}]:not([${MF_OVERLAY_ATTRIBUTE}]))`)\n );\n};\n\nconst startsWithHostPseudo = (selector: selectorParser.Selector): boolean => {\n return selector.first?.type === 'pseudo' && selector.first.value === ':host';\n};\n\nconst removeRootIdentityIds = (selector: selectorParser.Selector): void => {\n let compound: selectorParser.Node[] = [];\n const removeIdsFromRootCompound = (): void => {\n if (compound.some(isRootNode)) {\n for (const node of compound) {\n if (node.type === 'id') {\n node.remove();\n }\n }\n }\n };\n\n for (const node of [...selector.nodes]) {\n if (node.type === 'combinator') {\n removeIdsFromRootCompound();\n compound = [];\n } else {\n compound.push(node);\n }\n }\n removeIdsFromRootCompound();\n};\n\nconst SPECIFICITY_CARRIER = 'edyn-mf-root';\n\n// Legacy rules such as `html body button` or `html body#app .mdc-checkbox__background` are weighed against Angular\n// Material's own rules by the html, body and #app they start from, so the scope that replaces that root must weigh\n// exactly the same. A plain scope attribute (0,1,0) drops the id of `body#app`, letting Material's checked colour win,\n// and outweighs the two types of `html body`, letting an override that lost to `.mat-mdc-button` on the old site win\n// hosted. The root becomes :where(<scope>):not(<carrier>): :where() weighs nothing, and the carrier has the same id,\n// class and type counts as the root part it replaces and never matches the scope element, so :not() always matches and\n// weighs exactly that. Neutral names keep `html`, `body` and `#app` out of the emitted CSS.\nconst rootSpecificityCarrier = (selector: selectorParser.Selector): string => {\n const compounds: selectorParser.Node[][] = [[]];\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n const carrier: string[] = [];\n for (const compound of compounds) {\n if (!compound.some(isRootNode)) {\n continue;\n }\n const types = compound.filter((node) => node.type === 'tag' && isRootNode(node)).length;\n const pseudoRoots = compound.filter((node) => node.type === 'pseudo' && isRootNode(node)).length;\n const ids = compound.filter((node) => node.type === 'id').length;\n carrier.push(\n `${SPECIFICITY_CARRIER.repeat(Math.min(types, 1))}${`.${SPECIFICITY_CARRIER}`.repeat(pseudoRoots)}${`#${SPECIFICITY_CARRIER}`.repeat(ids)}`,\n );\n }\n\n return carrier.filter(Boolean).join(' ');\n};\n\nconst rootedDescendantScope = (selector: selectorParser.Selector, scopeId: string): string => {\n return `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]):not(${rootSpecificityCarrier(selector)})`;\n};\n\nconst isRootOnlySelector = (selector: selectorParser.Selector): boolean => {\n const compounds: selectorParser.Node[][] = [[]];\n\n for (const node of selector.nodes) {\n if (node.type === 'combinator') {\n compounds.push([]);\n } else {\n compounds.at(-1)?.push(node);\n }\n }\n\n return compounds.every((compound) => compound.some(isRootNode));\n};\n\nconst hasRootOnlySelector = (selectorList: string): boolean => {\n let result = false;\n selectorParser((root) => {\n result = root.nodes.some(isRootOnlySelector);\n }).processSync(selectorList);\n return result;\n};\n\nconst escapeRegExp = (text: string): string => text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n// A component stylesheet need not be named *.component.scss (CampaignManagement's create-campaign.ts uses\n// `styleUrl: './create-campaign.scss'`); treated as global CSS, Angular would then encapsulate the boundary itself and\n// the rules could never match. Such a file is a component's when a sibling component source references it.\nconst referencingComponentSourceOf = (stylePath: string): string | undefined => {\n const directory = dirname(stylePath);\n if (!existsSync(directory)) {\n return undefined;\n }\n const reference = new RegExp(`styleUrls?\\\\s*:\\\\s*(?:\\\\[[^\\\\]]*?)?['\"\\`]\\\\./${escapeRegExp(basename(stylePath))}['\"\\`]`);\n for (const fileName of readdirSync(directory)) {\n if (!fileName.endsWith('.ts') || /\\.(?:spec|test|d)\\.ts$/.test(fileName)) {\n continue;\n }\n const sourcePath = join(directory, fileName);\n if (reference.test(readFileSync(sourcePath, 'utf8'))) {\n return sourcePath;\n }\n }\n return undefined;\n};\n\nconst getAngularComponentSourcePath = (stylePath: string): string | undefined => {\n const cleanStylePath = stylePath.replace(/[?#].*$/, '');\n if (ANGULAR_COMPONENT_STYLE_PATTERN.test(cleanStylePath)) {\n return cleanStylePath.replace(/\\.(?:css|less|sass|scss)$/i, '.ts');\n }\n return /\\.(?:css|less|sass|scss)$/i.test(cleanStylePath) ? referencingComponentSourceOf(cleanStylePath) : undefined;\n};\n\nconst usesViewEncapsulationNone = (stylePath: string): boolean => {\n const componentSourcePath = getAngularComponentSourcePath(stylePath);\n if (!componentSourcePath || !existsSync(componentSourcePath)) {\n return false;\n }\n\n const componentSource = readFileSync(componentSourcePath, 'utf8');\n return VIEW_ENCAPSULATION_NONE_PATTERN.test(maskTypeScriptCommentsAndStrings(componentSource));\n};\n\nexport const shouldUseAngularComponentScoping = (stylePath: string | undefined): boolean => {\n return !!stylePath && !!getAngularComponentSourcePath(stylePath) && !usesViewEncapsulationNone(stylePath);\n};\n\nconst scopeSelectorList = (selectorList: string, scopeId: string, scopeSelector: string, rootScopeSelectors: string[]): string => {\n return selectorParser((root) => {\n const sourceSelectors = [...root.nodes];\n\n for (const selector of sourceSelectors) {\n const rootNodes = selector.nodes.filter(isRootNode);\n\n if (rootNodes.length > 0) {\n const replacementSelectors = isRootOnlySelector(selector) ? rootScopeSelectors : [rootedDescendantScope(selector, scopeId)];\n\n for (const replacementSelector of replacementSelectors) {\n const variant = selector.clone();\n removeRootIdentityIds(variant);\n const [firstRoot, ...duplicateRoots] = variant.nodes.filter(isRootNode);\n // The replacement can be a compound of several nodes, e.g. :where(<scope>):not(<carrier>).\n const scopeNodes = selectorParser()\n .astSync(replacementSelector)\n .first.nodes.map((node) => node.clone());\n const [scopeNode, ...followingScopeNodes] = scopeNodes;\n if (firstRoot && scopeNode) {\n firstRoot.replaceWith(scopeNode);\n let previous = scopeNode;\n for (const node of followingScopeNodes) {\n variant.insertAfter(previous, node);\n previous = node;\n }\n }\n\n for (const duplicateRoot of duplicateRoots) {\n const previous = duplicateRoot.prev();\n if (previous?.type === 'combinator') {\n previous.remove();\n }\n duplicateRoot.remove();\n }\n\n root.insertBefore(selector, variant);\n }\n selector.remove();\n continue;\n }\n\n if (startsWithHostPseudo(selector) || isScopeNode(selector.first, scopeId)) {\n continue;\n }\n\n const first = selector.first;\n const needsBoundaryVariant = first?.type === 'universal' || (first?.type === 'pseudo' && first.value.startsWith('::'));\n\n if (needsBoundaryVariant) {\n const hasSiblingCombinator = selector.nodes.some((node) => node.type === 'combinator' && (node.value === '+' || node.value === '~'));\n\n if (!hasSiblingCombinator) {\n const boundaryVariant = selector.clone();\n const boundaryScope = selectorParser().astSync(scopeSelector).first.first.clone();\n boundaryVariant.first.rawSpaceBefore = '';\n if (boundaryVariant.first.type === 'universal') {\n boundaryVariant.first.replaceWith(boundaryScope);\n } else {\n boundaryVariant.prepend(boundaryScope);\n }\n root.insertBefore(selector, boundaryVariant);\n }\n }\n\n const descendantScope = selectorParser().astSync(`${scopeSelector} *`).first;\n const prefixNodes = descendantScope.nodes.slice(0, -1).map((node) => node.clone());\n selector.first.rawSpaceBefore = '';\n for (const prefixNode of prefixNodes.reverse()) {\n selector.prepend(prefixNode);\n }\n }\n\n const seenSelectors = new Set<string>();\n for (const selector of [...root.nodes]) {\n const normalizedSelector = selector.toString().trim();\n if (seenSelectors.has(normalizedSelector)) {\n selector.remove();\n } else {\n seenSelectors.add(normalizedSelector);\n }\n }\n }).processSync(selectorList);\n};\n\nconst namespaceKeyframes = (root: Root, keyframePrefix: string): void => {\n const keyframes = new Map<string, string>();\n\n root.walkAtRules((atRule) => {\n if (!/keyframes$/i.test(atRule.name) || atRule.params.startsWith(keyframePrefix)) {\n return;\n }\n\n const originalName = atRule.params.trim();\n const scopedName = `${keyframePrefix}${originalName}`;\n keyframes.set(originalName, scopedName);\n atRule.params = scopedName;\n });\n\n root.walkDecls((declaration) => {\n if (!/^(?:-webkit-)?animation(?:-name)?$/i.test(declaration.prop) && !declaration.prop.startsWith('--animate-')) {\n return;\n }\n\n const parsed = valueParser(declaration.value);\n parsed.walk((node) => {\n if (node.type === 'word') {\n node.value = keyframes.get(node.value) ?? node.value;\n }\n });\n declaration.value = parsed.toString();\n });\n};\n\nconst INITIAL_FONT_SIZE_PX = 16;\n// Absolute-size keywords as browsers compute them, and the relative ones as they resolve on the root, whose parent size\n// is the initial 16px.\nconst FONT_SIZE_KEYWORDS_PX: Readonly<Record<string, number>> = {\n 'xx-small': 9,\n 'x-small': 10,\n small: 13,\n medium: 16,\n large: 18,\n 'x-large': 24,\n 'xx-large': 32,\n 'xxx-large': 48,\n smaller: INITIAL_FONT_SIZE_PX / 1.2,\n larger: INITIAL_FONT_SIZE_PX * 1.2,\n};\n// On the root, every global keyword gives the initial size.\nconst GLOBAL_KEYWORDS = new Set(['inherit', 'initial', 'revert', 'revert-layer', 'unset']);\n// em, rem and % on the root are relative to the initial size.\nconst FONT_SIZE_UNITS_PX: Readonly<Record<string, number>> = {\n '%': INITIAL_FONT_SIZE_PX / 100,\n cm: 96 / 2.54,\n em: INITIAL_FONT_SIZE_PX,\n in: 96,\n mm: 96 / 25.4,\n pc: 16,\n pt: 96 / 72,\n px: 1,\n q: 96 / 101.6,\n rem: INITIAL_FONT_SIZE_PX,\n};\n\nconst fontSizeOfWord = (word: string): number | undefined => {\n const keyword = FONT_SIZE_KEYWORDS_PX[word.toLowerCase()];\n if (keyword !== undefined) {\n return keyword;\n }\n const dimension = valueParser.unit(word);\n const unitPx = dimension ? FONT_SIZE_UNITS_PX[dimension.unit.toLowerCase()] : undefined;\n const amount = Number(dimension ? dimension.number : Number.NaN);\n return unitPx !== undefined && Number.isFinite(amount) && amount >= 0 ? amount * unitPx : undefined;\n};\n\nconst significantValueNodes = (value: string): valueParser.Node[] => {\n return valueParser(value).nodes.filter((node) => node.type !== 'space' && node.type !== 'comment');\n};\n\nconst globalKeywordFontSize = (nodes: valueParser.Node[]): number | undefined => {\n const [only] = nodes;\n return nodes.length === 1 && only?.type === 'word' && GLOBAL_KEYWORDS.has(only.value.toLowerCase()) ? INITIAL_FONT_SIZE_PX : undefined;\n};\n\nconst resolveFontSize = (value: string): number | undefined => {\n const nodes = significantValueNodes(value);\n const [only] = nodes;\n return globalKeywordFontSize(nodes) ?? (nodes.length === 1 && only?.type === 'word' ? fontSizeOfWord(only.value) : undefined);\n};\n\n// `font: [style] [variant] [weight] [stretch] <size>[/<line-height>] <family>`: the size is the word before `/`, or else\n// the first word that is a size. A function (var(), calc()) or a family name reached first means it cannot be read.\nconst resolveFontShorthandSize = (value: string): number | undefined => {\n const nodes = significantValueNodes(value);\n const globalSize = globalKeywordFontSize(nodes);\n if (globalSize !== undefined) {\n return globalSize;\n }\n\n const slashIndex = nodes.findIndex((node) => node.type === 'div' && node.value === '/');\n if (slashIndex > 0) {\n const size = nodes[slashIndex - 1];\n return size?.type === 'word' ? fontSizeOfWord(size.value) : undefined;\n }\n\n for (const node of nodes) {\n if (node.type !== 'word') {\n return undefined;\n }\n const size = fontSizeOfWord(node.value);\n if (size !== undefined) {\n return size;\n }\n }\n return undefined;\n};\n\n// `html` and `:root` size the document root, so rem; `body` and `html body` size only the body.\nconst targetsDocumentRoot = (selector: selectorParser.Selector): boolean => {\n let subject: selectorParser.Node[] = [];\n for (const node of selector.nodes) {\n subject = node.type === 'combinator' ? [] : [...subject, node];\n }\n return subject.some((node) => (node.type === 'tag' && node.value.toLowerCase() === 'html') || (node.type === 'pseudo' && node.value === ':root'));\n};\n\nconst documentRootSelectorsOf = (selectorList: string): string[] => {\n const selectors: string[] = [];\n selectorParser((root) => {\n for (const selector of root.nodes) {\n if (targetsDocumentRoot(selector)) {\n selectors.push(selector.toString().trim());\n }\n }\n }).processSync(selectorList);\n return selectors;\n};\n\ntype TWarn = (node: Declaration, text: string) => void;\n\n// Hosted, rem resolves against the host page's root, not the root size the module's own page set. Each rule that sizes\n// the document root gets a sibling rule right after it that records that size as MF_ROOT_FONT_SIZE_PROPERTY, under the\n// same conditions (@media, importance) and in the same cascade order; scoping then moves it onto the module boundary,\n// where followModuleRootFontSize() makes rem lengths read it. CSS that never sizes the root is left byte-identical.\nconst recordRootFontSize = (root: Root, warn: TWarn): void => {\n root.walkRules((rule) => {\n if (isKeyframesRule(rule)) {\n return;\n }\n\n let sizing: Declaration | undefined;\n for (const node of rule.nodes) {\n if (node.type === 'decl' && /^font(?:-size)?$/i.test(node.prop) && (node.important || !sizing?.important)) {\n sizing = node;\n }\n }\n if (!sizing) {\n return;\n }\n\n const rootSelectors = documentRootSelectorsOf(rule.selector);\n if (rootSelectors.length === 0) {\n return;\n }\n\n const sizePx = sizing.prop.toLowerCase() === 'font' ? resolveFontShorthandSize(sizing.value) : resolveFontSize(sizing.value);\n if (sizePx === undefined) {\n warn(\n sizing,\n `Cannot resolve the document root font size \"${sizing.value}\" at build time; rem lengths in the hosted module will use the host page's root size.`,\n );\n return;\n }\n\n const recorded = rule.clone({ selector: rootSelectors.join(', ') });\n recorded.raws.before = rule.raws.before || '\\n';\n recorded.removeAll();\n // The recorded size points back at the declaration it came from, so source maps keep a source for it.\n recorded.append({\n important: sizing.important,\n prop: MF_ROOT_FONT_SIZE_PROPERTY,\n source: sizing.source,\n value: `${Number(sizePx.toFixed(4))}px`,\n });\n rule.after(recorded);\n });\n};\n\nconst scopeGlobalRoot = (root: Root, scopeId: string, scopeSelector: string, keyframePrefix: string, warn: TWarn): void => {\n recordRootFontSize(root, warn);\n namespaceKeyframes(root, keyframePrefix);\n const contentRootSelector = `:where([${MF_SCOPE_ATTRIBUTE}=\"${scopeId}\"]:not([${MF_OVERLAY_ATTRIBUTE}]))`;\n root.walkRules((rule) => {\n if (!isKeyframesRule(rule)) {\n const declarations = rule.nodes.filter((node) => node.type === 'decl');\n const customProperties = declarations.filter((declaration) => declaration.prop.startsWith('--'));\n const standardDeclarations = declarations.filter((declaration) => !declaration.prop.startsWith('--'));\n\n if (customProperties.length > 0 && standardDeclarations.length > 0 && hasRootOnlySelector(rule.selector)) {\n const customPropertyRule = rule.cloneBefore();\n customPropertyRule.walkDecls((declaration) => {\n if (!declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n customPropertyRule.selector = scopeSelectorList(customPropertyRule.selector, scopeId, scopeSelector, [':host', scopeSelector]);\n rule.walkDecls((declaration) => {\n if (declaration.prop.startsWith('--')) {\n declaration.remove();\n }\n });\n }\n\n const containsOnlyCustomProperties = declarations.length > 0 && declarations.every((declaration) => declaration.prop.startsWith('--'));\n const rootScopeSelectors = containsOnlyCustomProperties ? [':host', scopeSelector] : [':host', contentRootSelector];\n rule.selector = scopeSelectorList(rule.selector, scopeId, scopeSelector, rootScopeSelectors);\n }\n });\n};\n\n// Emulated component CSS keeps its selectors exactly as written, so Angular compiles what it compiled on the module's\n// own page and every rule keeps its weight and reach: `mat-form-field[_ngcontent-x]` (0,1,1) still loses to a global\n// `.mat-sidenav-content .mat-mdc-form-field` (0,2,0), template content rendered in an overlay (outside the component's\n// host) keeps its component styles, and a top-level `::ng-deep` rule stays global to the module. Wrapping every rule in\n// :host-context(<boundary>) added (0,2,0) to each, and limited all of them to the component's host. Isolation needs no\n// boundary here: Angular's _ngcontent and _nghost attributes are unique to each component, and a hosted module's\n// component styles live in its own shadow root.\nconst scopeAngularComponentRoot = (root: Root, keyframePrefix: string): void => {\n namespaceKeyframes(root, keyframePrefix);\n};\n\nexport const scopeRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-isolation-${validScopeId}`,\n Once(root, { result }) {\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix, (node, text) => node.warn(result, text));\n },\n };\n};\n\nexport const scopeAngularRemoteCss = ({ scopeId }: IScopeRemoteCssOptions): Plugin => {\n const validScopeId = validateMfScopeId(scopeId);\n const scopeSelector = getMfScopeSelector(validScopeId);\n const keyframePrefix = `edyn-mf-${validScopeId}--`;\n\n return {\n postcssPlugin: `edyn-mf-angular-isolation-${validScopeId}`,\n Once(root, { result }) {\n if (shouldUseAngularComponentScoping(root.source?.input.file)) {\n scopeAngularComponentRoot(root, keyframePrefix);\n return;\n }\n\n scopeGlobalRoot(root, validScopeId, scopeSelector, keyframePrefix, (node, text) => node.warn(result, text));\n },\n };\n};\n"]}
@@ -1,11 +1,7 @@
1
1
  export declare const MF_ROOT_FONT_SIZE_PROPERTY = "--edyn-mf-rem";
2
+ export declare const ROOT_FONT_SIZE_DECLARATION_PATTERN: RegExp;
3
+ export declare const REM_LENGTH_HINT_PATTERN: RegExp;
4
+ export declare const UNFOLLOWED_REM_PATTERN: RegExp;
2
5
  /** Rewrites every rem length in CSS declaration text to follow the module's root font size; running it again changes nothing. */
3
6
  export declare const rewriteRemLengths: (declarations: string) => string;
4
- /**
5
- * Makes rem lengths in a hosted module's shadow root follow the root font size its own page had, once the module's
6
- * CSS declares one (see MF_ROOT_FONT_SIZE_PROPERTY). Covers stylesheets already in the root and every one added or
7
- * changed later, such as the component styles Angular adds as components first render. A module whose CSS never sizes
8
- * its root is left untouched. Returns a function that stops following; rewritten rules stay rewritten.
9
- */
10
- export declare const followModuleRootFontSize: (root: ShadowRoot) => (() => void);
11
7
  //# sourceMappingURL=root-font-size.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-font-size.d.ts","sourceRoot":"","sources":["../src/root-font-size.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,0BAA0B,kBAAkB,CAAC;AAc1D,iIAAiI;AACjI,eAAO,MAAM,iBAAiB,GAAI,cAAc,MAAM,KAAG,MAQxD,CAAC;AAuEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAI,MAAM,UAAU,KAAG,CAAC,MAAM,IAAI,CA+DtE,CAAC","sourcesContent":["// `rem` always resolves against the page's <html>, even inside a shadow root. A module page that sized its own root\n// (`html, body { font-size: 12px }`) drew every rem length from that size, but hosted, the same lengths use the host\n// page's root (16px): Material's `.mat-mdc-button > .mat-icon { font-size: 1.125rem }` drew 13.5px on the old page and\n// 18px hosted. The build-time PostCSS plugin records the module's root size as this property on the module boundary;\n// followModuleRootFontSize() rewrites every rem length in the module's shadow root to read it.\nexport const MF_ROOT_FONT_SIZE_PROPERTY = '--edyn-mf-rem';\n\nconst ROOT_FONT_SIZE_FALLBACK = `var(${MF_ROOT_FONT_SIZE_PROPERTY}, 1rem)`;\nconst ROOT_FONT_SIZE_DECLARATION_PATTERN = new RegExp(`${MF_ROOT_FONT_SIZE_PROPERTY}\\\\s*:`);\nconst REM_LENGTH_HINT_PATTERN = /\\drem/i;\n// A number with the rem unit that is not part of an identifier (`foo-2rem`) and not the fallback this rewrite writes.\nconst REM_LENGTH_PATTERN = new RegExp(`(?<![\\\\w.-]|var\\\\(${MF_ROOT_FONT_SIZE_PROPERTY},\\\\s*)(-?(?:\\\\d+\\\\.?\\\\d*|\\\\.\\\\d+))rem(?![\\\\w-])`, 'gi');\n// Strings and url() keep their text: `content: \"2rem\"` or `url(2rem.png)` are not lengths.\nconst VERBATIM_PATTERN = /\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|url\\((?:[^()\"'\\\\]|\\\\.)*\\)/gi;\n\nconst rewriteOutsideVerbatim = (text: string): string => {\n return text.replace(REM_LENGTH_PATTERN, (_match, amount: string) => `calc(${amount} * ${ROOT_FONT_SIZE_FALLBACK})`);\n};\n\n/** Rewrites every rem length in CSS declaration text to follow the module's root font size; running it again changes nothing. */\nexport const rewriteRemLengths = (declarations: string): string => {\n let rewritten = '';\n let start = 0;\n for (const verbatim of declarations.matchAll(VERBATIM_PATTERN)) {\n rewritten += rewriteOutsideVerbatim(declarations.slice(start, verbatim.index)) + verbatim[0];\n start = verbatim.index + verbatim[0].length;\n }\n return rewritten + rewriteOutsideVerbatim(declarations.slice(start));\n};\n\nconst isFontFaceRule = (rule: CSSRule): boolean => {\n return typeof CSSFontFaceRule !== 'undefined' && rule instanceof CSSFontFaceRule;\n};\n\n// Rule kinds are told apart by what they carry, not by class: @import has a sheet, style and keyframe rules have\n// declarations, and grouping rules (@media, @supports, @container, @layer, @keyframes, nesting) have child rules.\nconst importedSheetOf = (rule: CSSRule): CSSStyleSheet | undefined => {\n return 'styleSheet' in rule && rule.styleSheet ? (rule.styleSheet as CSSStyleSheet) : undefined;\n};\n\nconst declarationsOf = (rule: CSSRule): CSSStyleDeclaration | undefined => {\n return 'style' in rule && rule.style && !isFontFaceRule(rule) ? (rule.style as CSSStyleDeclaration) : undefined;\n};\n\nconst childRulesOf = (rule: CSSRule): CSSRuleList | undefined => {\n return 'cssRules' in rule && rule.cssRules ? (rule.cssRules as CSSRuleList) : undefined;\n};\n\n// Only declaration blocks change, through the CSSOM: @media, @container and @supports conditions keep their rem (var()\n// is invalid there, and a media query rem is the browser's initial size anyway), and !important stays with its value.\nconst rewriteRules = (rules: CSSRuleList): void => {\n for (const rule of Array.from(rules)) {\n const importedSheet = importedSheetOf(rule);\n if (importedSheet) {\n rewriteSheet(importedSheet);\n }\n const declarations = declarationsOf(rule);\n if (declarations && REM_LENGTH_HINT_PATTERN.test(declarations.cssText)) {\n const rewritten = rewriteRemLengths(declarations.cssText);\n if (rewritten !== declarations.cssText) {\n declarations.cssText = rewritten;\n }\n }\n const childRules = childRulesOf(rule);\n if (childRules) {\n rewriteRules(childRules);\n }\n }\n};\n\nconst readRules = (sheet: CSSStyleSheet): CSSRuleList | undefined => {\n try {\n return sheet.cssRules;\n } catch {\n // A cross-origin sheet (a font service's @font-face list) cannot be read, and none of its rules are module rules.\n return undefined;\n }\n};\n\nconst rewriteSheet = (sheet: CSSStyleSheet): void => {\n const rules = readRules(sheet);\n if (rules) {\n rewriteRules(rules);\n }\n};\n\nconst declaresRootFontSize = (rules: CSSRuleList): boolean => {\n return Array.from(rules).some((rule) => {\n const childRules = childRulesOf(rule);\n return !!declarationsOf(rule)?.getPropertyValue(MF_ROOT_FONT_SIZE_PROPERTY) || (!!childRules && declaresRootFontSize(childRules));\n });\n};\n\ntype TStyleOwner = HTMLLinkElement | HTMLStyleElement;\n\nconst isStyleOwner = (node: Node): node is TStyleOwner => {\n return node.nodeName === 'STYLE' || (node.nodeName === 'LINK' && (node as HTMLLinkElement).rel.split(/\\s+/).includes('stylesheet'));\n};\n\n/**\n * Makes rem lengths in a hosted module's shadow root follow the root font size its own page had, once the module's\n * CSS declares one (see MF_ROOT_FONT_SIZE_PROPERTY). Covers stylesheets already in the root and every one added or\n * changed later, such as the component styles Angular adds as components first render. A module whose CSS never sizes\n * its root is left untouched. Returns a function that stops following; rewritten rules stay rewritten.\n */\nexport const followModuleRootFontSize = (root: ShadowRoot): (() => void) => {\n let following = false;\n const rewrittenSheets = new WeakSet<CSSStyleSheet>();\n const watchedOwners = new WeakSet<TStyleOwner>();\n\n const owners = (): TStyleOwner[] => Array.from(root.childNodes).filter(isStyleOwner);\n\n const sheetsOf = (styleOwners: TStyleOwner[]): CSSStyleSheet[] => {\n return [...(root.adoptedStyleSheets ?? []), ...styleOwners.map((owner) => owner.sheet).filter((sheet): sheet is CSSStyleSheet => !!sheet)];\n };\n\n // A <style>'s own text is the cheap check; linked and adopted sheets have only their rules.\n const findsRootFontSize = (styleOwners: TStyleOwner[]): boolean => {\n const styles = styleOwners.filter((owner) => owner.nodeName === 'STYLE');\n if (styles.some((style) => ROOT_FONT_SIZE_DECLARATION_PATTERN.test(style.textContent ?? ''))) {\n return true;\n }\n return sheetsOf(styleOwners.filter((owner) => owner.nodeName === 'LINK')).some((sheet) => {\n const rules = readRules(sheet);\n return !!rules && declaresRootFontSize(rules);\n });\n };\n\n const observer = new MutationObserver(() => update());\n\n const update = (): void => {\n const styleOwners = owners();\n for (const owner of styleOwners) {\n if (owner.nodeName === 'STYLE' && !watchedOwners.has(owner)) {\n // Replacing a <style>'s text gives it a new sheet, which must be rewritten again.\n observer.observe(owner, { characterData: true, childList: true, subtree: true });\n watchedOwners.add(owner);\n }\n }\n\n following ||= findsRootFontSize(styleOwners);\n if (!following) {\n return;\n }\n\n for (const sheet of sheetsOf(styleOwners)) {\n if (!rewrittenSheets.has(sheet)) {\n rewriteSheet(sheet);\n rewrittenSheets.add(sheet);\n }\n }\n };\n\n // A <link> sheet has no rules until it loads; load does not bubble, so it is caught on the way down.\n const onLoad = (event: Event): void => {\n if (event.target instanceof Node && isStyleOwner(event.target)) {\n update();\n }\n };\n\n observer.observe(root, { childList: true });\n root.addEventListener('load', onLoad, true);\n update();\n\n return () => {\n observer.disconnect();\n root.removeEventListener('load', onLoad, true);\n };\n};\n"]}
1
+ {"version":3,"file":"root-font-size.d.ts","sourceRoot":"","sources":["../src/root-font-size.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,0BAA0B,kBAAkB,CAAC;AAG1D,eAAO,MAAM,kCAAkC,QAAmD,CAAC;AACnG,eAAO,MAAM,uBAAuB,QAAW,CAAC;AAQhD,eAAO,MAAM,sBAAsB,QAA6C,CAAC;AAMjF,iIAAiI;AACjI,eAAO,MAAM,iBAAiB,GAAI,cAAc,MAAM,KAAG,MAQxD,CAAC","sourcesContent":["// `rem` always resolves against the page's <html>, even inside a shadow root. A module page that sized its own root\n// (`html, body { font-size: 12px }`) drew every rem length from that size, but hosted, the same lengths use the host\n// page's root (16px): Material's `.mat-mdc-button > .mat-icon { font-size: 1.125rem }` drew 13.5px on the old page and\n// 18px hosted. The build-time PostCSS plugin records the module's root size as this property on the module boundary;\n// followModuleRootFontSize() rewrites every rem length in the module's shadow root to read it.\nexport const MF_ROOT_FONT_SIZE_PROPERTY = '--edyn-mf-rem';\n\nconst ROOT_FONT_SIZE_FALLBACK = `var(${MF_ROOT_FONT_SIZE_PROPERTY}, 1rem)`;\nexport const ROOT_FONT_SIZE_DECLARATION_PATTERN = new RegExp(`${MF_ROOT_FONT_SIZE_PROPERTY}\\\\s*:`);\nexport const REM_LENGTH_HINT_PATTERN = /\\drem/i;\n// A number with the rem unit that is not part of an identifier (`foo-2rem`) and not the fallback this rewrite writes.\nconst REM_LENGTH_PATTERN = new RegExp(`(?<![\\\\w.-]|var\\\\(${MF_ROOT_FONT_SIZE_PROPERTY},\\\\s*)(-?(?:\\\\d+\\\\.?\\\\d*|\\\\.\\\\d+))rem(?![\\\\w-])`, 'gi');\n// Strings and url() keep their text: `content: \"2rem\"` or `url(2rem.png)` are not lengths.\nconst VERBATIM_PATTERN = /\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|url\\((?:[^()\"'\\\\]|\\\\.)*\\)/gi;\n\n// The same match without the global flag, as a quick test: it skips the fallback this rewrite writes, so a followed\n// value does not look like work again.\nexport const UNFOLLOWED_REM_PATTERN = new RegExp(REM_LENGTH_PATTERN.source, 'i');\n\nconst rewriteOutsideVerbatim = (text: string): string => {\n return text.replace(REM_LENGTH_PATTERN, (_match, amount: string) => `calc(${amount} * ${ROOT_FONT_SIZE_FALLBACK})`);\n};\n\n/** Rewrites every rem length in CSS declaration text to follow the module's root font size; running it again changes nothing. */\nexport const rewriteRemLengths = (declarations: string): string => {\n let rewritten = '';\n let start = 0;\n for (const verbatim of declarations.matchAll(VERBATIM_PATTERN)) {\n rewritten += rewriteOutsideVerbatim(declarations.slice(start, verbatim.index)) + verbatim[0];\n start = verbatim.index + verbatim[0].length;\n }\n return rewritten + rewriteOutsideVerbatim(declarations.slice(start));\n};\n"]}
@@ -5,12 +5,15 @@
5
5
  // followModuleRootFontSize() rewrites every rem length in the module's shadow root to read it.
6
6
  export const MF_ROOT_FONT_SIZE_PROPERTY = '--edyn-mf-rem';
7
7
  const ROOT_FONT_SIZE_FALLBACK = `var(${MF_ROOT_FONT_SIZE_PROPERTY}, 1rem)`;
8
- const ROOT_FONT_SIZE_DECLARATION_PATTERN = new RegExp(`${MF_ROOT_FONT_SIZE_PROPERTY}\\s*:`);
9
- const REM_LENGTH_HINT_PATTERN = /\drem/i;
8
+ export const ROOT_FONT_SIZE_DECLARATION_PATTERN = new RegExp(`${MF_ROOT_FONT_SIZE_PROPERTY}\\s*:`);
9
+ export const REM_LENGTH_HINT_PATTERN = /\drem/i;
10
10
  // A number with the rem unit that is not part of an identifier (`foo-2rem`) and not the fallback this rewrite writes.
11
11
  const REM_LENGTH_PATTERN = new RegExp(`(?<![\\w.-]|var\\(${MF_ROOT_FONT_SIZE_PROPERTY},\\s*)(-?(?:\\d+\\.?\\d*|\\.\\d+))rem(?![\\w-])`, 'gi');
12
12
  // Strings and url() keep their text: `content: "2rem"` or `url(2rem.png)` are not lengths.
13
13
  const VERBATIM_PATTERN = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|url\((?:[^()"'\\]|\\.)*\)/gi;
14
+ // The same match without the global flag, as a quick test: it skips the fallback this rewrite writes, so a followed
15
+ // value does not look like work again.
16
+ export const UNFOLLOWED_REM_PATTERN = new RegExp(REM_LENGTH_PATTERN.source, 'i');
14
17
  const rewriteOutsideVerbatim = (text) => {
15
18
  return text.replace(REM_LENGTH_PATTERN, (_match, amount) => `calc(${amount} * ${ROOT_FONT_SIZE_FALLBACK})`);
16
19
  };
@@ -24,123 +27,4 @@ export const rewriteRemLengths = (declarations) => {
24
27
  }
25
28
  return rewritten + rewriteOutsideVerbatim(declarations.slice(start));
26
29
  };
27
- const isFontFaceRule = (rule) => {
28
- return typeof CSSFontFaceRule !== 'undefined' && rule instanceof CSSFontFaceRule;
29
- };
30
- // Rule kinds are told apart by what they carry, not by class: @import has a sheet, style and keyframe rules have
31
- // declarations, and grouping rules (@media, @supports, @container, @layer, @keyframes, nesting) have child rules.
32
- const importedSheetOf = (rule) => {
33
- return 'styleSheet' in rule && rule.styleSheet ? rule.styleSheet : undefined;
34
- };
35
- const declarationsOf = (rule) => {
36
- return 'style' in rule && rule.style && !isFontFaceRule(rule) ? rule.style : undefined;
37
- };
38
- const childRulesOf = (rule) => {
39
- return 'cssRules' in rule && rule.cssRules ? rule.cssRules : undefined;
40
- };
41
- // Only declaration blocks change, through the CSSOM: @media, @container and @supports conditions keep their rem (var()
42
- // is invalid there, and a media query rem is the browser's initial size anyway), and !important stays with its value.
43
- const rewriteRules = (rules) => {
44
- for (const rule of Array.from(rules)) {
45
- const importedSheet = importedSheetOf(rule);
46
- if (importedSheet) {
47
- rewriteSheet(importedSheet);
48
- }
49
- const declarations = declarationsOf(rule);
50
- if (declarations && REM_LENGTH_HINT_PATTERN.test(declarations.cssText)) {
51
- const rewritten = rewriteRemLengths(declarations.cssText);
52
- if (rewritten !== declarations.cssText) {
53
- declarations.cssText = rewritten;
54
- }
55
- }
56
- const childRules = childRulesOf(rule);
57
- if (childRules) {
58
- rewriteRules(childRules);
59
- }
60
- }
61
- };
62
- const readRules = (sheet) => {
63
- try {
64
- return sheet.cssRules;
65
- }
66
- catch {
67
- // A cross-origin sheet (a font service's @font-face list) cannot be read, and none of its rules are module rules.
68
- return undefined;
69
- }
70
- };
71
- const rewriteSheet = (sheet) => {
72
- const rules = readRules(sheet);
73
- if (rules) {
74
- rewriteRules(rules);
75
- }
76
- };
77
- const declaresRootFontSize = (rules) => {
78
- return Array.from(rules).some((rule) => {
79
- const childRules = childRulesOf(rule);
80
- return !!declarationsOf(rule)?.getPropertyValue(MF_ROOT_FONT_SIZE_PROPERTY) || (!!childRules && declaresRootFontSize(childRules));
81
- });
82
- };
83
- const isStyleOwner = (node) => {
84
- return node.nodeName === 'STYLE' || (node.nodeName === 'LINK' && node.rel.split(/\s+/).includes('stylesheet'));
85
- };
86
- /**
87
- * Makes rem lengths in a hosted module's shadow root follow the root font size its own page had, once the module's
88
- * CSS declares one (see MF_ROOT_FONT_SIZE_PROPERTY). Covers stylesheets already in the root and every one added or
89
- * changed later, such as the component styles Angular adds as components first render. A module whose CSS never sizes
90
- * its root is left untouched. Returns a function that stops following; rewritten rules stay rewritten.
91
- */
92
- export const followModuleRootFontSize = (root) => {
93
- let following = false;
94
- const rewrittenSheets = new WeakSet();
95
- const watchedOwners = new WeakSet();
96
- const owners = () => Array.from(root.childNodes).filter(isStyleOwner);
97
- const sheetsOf = (styleOwners) => {
98
- return [...(root.adoptedStyleSheets ?? []), ...styleOwners.map((owner) => owner.sheet).filter((sheet) => !!sheet)];
99
- };
100
- // A <style>'s own text is the cheap check; linked and adopted sheets have only their rules.
101
- const findsRootFontSize = (styleOwners) => {
102
- const styles = styleOwners.filter((owner) => owner.nodeName === 'STYLE');
103
- if (styles.some((style) => ROOT_FONT_SIZE_DECLARATION_PATTERN.test(style.textContent ?? ''))) {
104
- return true;
105
- }
106
- return sheetsOf(styleOwners.filter((owner) => owner.nodeName === 'LINK')).some((sheet) => {
107
- const rules = readRules(sheet);
108
- return !!rules && declaresRootFontSize(rules);
109
- });
110
- };
111
- const observer = new MutationObserver(() => update());
112
- const update = () => {
113
- const styleOwners = owners();
114
- for (const owner of styleOwners) {
115
- if (owner.nodeName === 'STYLE' && !watchedOwners.has(owner)) {
116
- // Replacing a <style>'s text gives it a new sheet, which must be rewritten again.
117
- observer.observe(owner, { characterData: true, childList: true, subtree: true });
118
- watchedOwners.add(owner);
119
- }
120
- }
121
- following ||= findsRootFontSize(styleOwners);
122
- if (!following) {
123
- return;
124
- }
125
- for (const sheet of sheetsOf(styleOwners)) {
126
- if (!rewrittenSheets.has(sheet)) {
127
- rewriteSheet(sheet);
128
- rewrittenSheets.add(sheet);
129
- }
130
- }
131
- };
132
- // A <link> sheet has no rules until it loads; load does not bubble, so it is caught on the way down.
133
- const onLoad = (event) => {
134
- if (event.target instanceof Node && isStyleOwner(event.target)) {
135
- update();
136
- }
137
- };
138
- observer.observe(root, { childList: true });
139
- root.addEventListener('load', onLoad, true);
140
- update();
141
- return () => {
142
- observer.disconnect();
143
- root.removeEventListener('load', onLoad, true);
144
- };
145
- };
146
30
  //# sourceMappingURL=root-font-size.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-font-size.js","sourceRoot":"","sources":["../src/root-font-size.ts"],"names":[],"mappings":"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","sourcesContent":["// `rem` always resolves against the page's <html>, even inside a shadow root. A module page that sized its own root\n// (`html, body { font-size: 12px }`) drew every rem length from that size, but hosted, the same lengths use the host\n// page's root (16px): Material's `.mat-mdc-button > .mat-icon { font-size: 1.125rem }` drew 13.5px on the old page and\n// 18px hosted. The build-time PostCSS plugin records the module's root size as this property on the module boundary;\n// followModuleRootFontSize() rewrites every rem length in the module's shadow root to read it.\nexport const MF_ROOT_FONT_SIZE_PROPERTY = '--edyn-mf-rem';\n\nconst ROOT_FONT_SIZE_FALLBACK = `var(${MF_ROOT_FONT_SIZE_PROPERTY}, 1rem)`;\nconst ROOT_FONT_SIZE_DECLARATION_PATTERN = new RegExp(`${MF_ROOT_FONT_SIZE_PROPERTY}\\\\s*:`);\nconst REM_LENGTH_HINT_PATTERN = /\\drem/i;\n// A number with the rem unit that is not part of an identifier (`foo-2rem`) and not the fallback this rewrite writes.\nconst REM_LENGTH_PATTERN = new RegExp(`(?<![\\\\w.-]|var\\\\(${MF_ROOT_FONT_SIZE_PROPERTY},\\\\s*)(-?(?:\\\\d+\\\\.?\\\\d*|\\\\.\\\\d+))rem(?![\\\\w-])`, 'gi');\n// Strings and url() keep their text: `content: \"2rem\"` or `url(2rem.png)` are not lengths.\nconst VERBATIM_PATTERN = /\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|url\\((?:[^()\"'\\\\]|\\\\.)*\\)/gi;\n\nconst rewriteOutsideVerbatim = (text: string): string => {\n return text.replace(REM_LENGTH_PATTERN, (_match, amount: string) => `calc(${amount} * ${ROOT_FONT_SIZE_FALLBACK})`);\n};\n\n/** Rewrites every rem length in CSS declaration text to follow the module's root font size; running it again changes nothing. */\nexport const rewriteRemLengths = (declarations: string): string => {\n let rewritten = '';\n let start = 0;\n for (const verbatim of declarations.matchAll(VERBATIM_PATTERN)) {\n rewritten += rewriteOutsideVerbatim(declarations.slice(start, verbatim.index)) + verbatim[0];\n start = verbatim.index + verbatim[0].length;\n }\n return rewritten + rewriteOutsideVerbatim(declarations.slice(start));\n};\n\nconst isFontFaceRule = (rule: CSSRule): boolean => {\n return typeof CSSFontFaceRule !== 'undefined' && rule instanceof CSSFontFaceRule;\n};\n\n// Rule kinds are told apart by what they carry, not by class: @import has a sheet, style and keyframe rules have\n// declarations, and grouping rules (@media, @supports, @container, @layer, @keyframes, nesting) have child rules.\nconst importedSheetOf = (rule: CSSRule): CSSStyleSheet | undefined => {\n return 'styleSheet' in rule && rule.styleSheet ? (rule.styleSheet as CSSStyleSheet) : undefined;\n};\n\nconst declarationsOf = (rule: CSSRule): CSSStyleDeclaration | undefined => {\n return 'style' in rule && rule.style && !isFontFaceRule(rule) ? (rule.style as CSSStyleDeclaration) : undefined;\n};\n\nconst childRulesOf = (rule: CSSRule): CSSRuleList | undefined => {\n return 'cssRules' in rule && rule.cssRules ? (rule.cssRules as CSSRuleList) : undefined;\n};\n\n// Only declaration blocks change, through the CSSOM: @media, @container and @supports conditions keep their rem (var()\n// is invalid there, and a media query rem is the browser's initial size anyway), and !important stays with its value.\nconst rewriteRules = (rules: CSSRuleList): void => {\n for (const rule of Array.from(rules)) {\n const importedSheet = importedSheetOf(rule);\n if (importedSheet) {\n rewriteSheet(importedSheet);\n }\n const declarations = declarationsOf(rule);\n if (declarations && REM_LENGTH_HINT_PATTERN.test(declarations.cssText)) {\n const rewritten = rewriteRemLengths(declarations.cssText);\n if (rewritten !== declarations.cssText) {\n declarations.cssText = rewritten;\n }\n }\n const childRules = childRulesOf(rule);\n if (childRules) {\n rewriteRules(childRules);\n }\n }\n};\n\nconst readRules = (sheet: CSSStyleSheet): CSSRuleList | undefined => {\n try {\n return sheet.cssRules;\n } catch {\n // A cross-origin sheet (a font service's @font-face list) cannot be read, and none of its rules are module rules.\n return undefined;\n }\n};\n\nconst rewriteSheet = (sheet: CSSStyleSheet): void => {\n const rules = readRules(sheet);\n if (rules) {\n rewriteRules(rules);\n }\n};\n\nconst declaresRootFontSize = (rules: CSSRuleList): boolean => {\n return Array.from(rules).some((rule) => {\n const childRules = childRulesOf(rule);\n return !!declarationsOf(rule)?.getPropertyValue(MF_ROOT_FONT_SIZE_PROPERTY) || (!!childRules && declaresRootFontSize(childRules));\n });\n};\n\ntype TStyleOwner = HTMLLinkElement | HTMLStyleElement;\n\nconst isStyleOwner = (node: Node): node is TStyleOwner => {\n return node.nodeName === 'STYLE' || (node.nodeName === 'LINK' && (node as HTMLLinkElement).rel.split(/\\s+/).includes('stylesheet'));\n};\n\n/**\n * Makes rem lengths in a hosted module's shadow root follow the root font size its own page had, once the module's\n * CSS declares one (see MF_ROOT_FONT_SIZE_PROPERTY). Covers stylesheets already in the root and every one added or\n * changed later, such as the component styles Angular adds as components first render. A module whose CSS never sizes\n * its root is left untouched. Returns a function that stops following; rewritten rules stay rewritten.\n */\nexport const followModuleRootFontSize = (root: ShadowRoot): (() => void) => {\n let following = false;\n const rewrittenSheets = new WeakSet<CSSStyleSheet>();\n const watchedOwners = new WeakSet<TStyleOwner>();\n\n const owners = (): TStyleOwner[] => Array.from(root.childNodes).filter(isStyleOwner);\n\n const sheetsOf = (styleOwners: TStyleOwner[]): CSSStyleSheet[] => {\n return [...(root.adoptedStyleSheets ?? []), ...styleOwners.map((owner) => owner.sheet).filter((sheet): sheet is CSSStyleSheet => !!sheet)];\n };\n\n // A <style>'s own text is the cheap check; linked and adopted sheets have only their rules.\n const findsRootFontSize = (styleOwners: TStyleOwner[]): boolean => {\n const styles = styleOwners.filter((owner) => owner.nodeName === 'STYLE');\n if (styles.some((style) => ROOT_FONT_SIZE_DECLARATION_PATTERN.test(style.textContent ?? ''))) {\n return true;\n }\n return sheetsOf(styleOwners.filter((owner) => owner.nodeName === 'LINK')).some((sheet) => {\n const rules = readRules(sheet);\n return !!rules && declaresRootFontSize(rules);\n });\n };\n\n const observer = new MutationObserver(() => update());\n\n const update = (): void => {\n const styleOwners = owners();\n for (const owner of styleOwners) {\n if (owner.nodeName === 'STYLE' && !watchedOwners.has(owner)) {\n // Replacing a <style>'s text gives it a new sheet, which must be rewritten again.\n observer.observe(owner, { characterData: true, childList: true, subtree: true });\n watchedOwners.add(owner);\n }\n }\n\n following ||= findsRootFontSize(styleOwners);\n if (!following) {\n return;\n }\n\n for (const sheet of sheetsOf(styleOwners)) {\n if (!rewrittenSheets.has(sheet)) {\n rewriteSheet(sheet);\n rewrittenSheets.add(sheet);\n }\n }\n };\n\n // A <link> sheet has no rules until it loads; load does not bubble, so it is caught on the way down.\n const onLoad = (event: Event): void => {\n if (event.target instanceof Node && isStyleOwner(event.target)) {\n update();\n }\n };\n\n observer.observe(root, { childList: true });\n root.addEventListener('load', onLoad, true);\n update();\n\n return () => {\n observer.disconnect();\n root.removeEventListener('load', onLoad, true);\n };\n};\n"]}
1
+ {"version":3,"file":"root-font-size.js","sourceRoot":"","sources":["../src/root-font-size.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,qHAAqH;AACrH,uHAAuH;AACvH,qHAAqH;AACrH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAC;AAE1D,MAAM,uBAAuB,GAAG,OAAO,0BAA0B,SAAS,CAAC;AAC3E,MAAM,CAAC,MAAM,kCAAkC,GAAG,IAAI,MAAM,CAAC,GAAG,0BAA0B,OAAO,CAAC,CAAC;AACnG,MAAM,CAAC,MAAM,uBAAuB,GAAG,QAAQ,CAAC;AAChD,sHAAsH;AACtH,MAAM,kBAAkB,GAAG,IAAI,MAAM,CAAC,qBAAqB,0BAA0B,iDAAiD,EAAE,IAAI,CAAC,CAAC;AAC9I,2FAA2F;AAC3F,MAAM,gBAAgB,GAAG,iEAAiE,CAAC;AAE3F,oHAAoH;AACpH,uCAAuC;AACvC,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEjF,MAAM,sBAAsB,GAAG,CAAC,IAAY,EAAU,EAAE;IACtD,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAc,EAAE,EAAE,CAAC,QAAQ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC;AACtH,CAAC,CAAC;AAEF,iIAAiI;AACjI,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,YAAoB,EAAU,EAAE;IAChE,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,QAAQ,IAAI,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC/D,SAAS,IAAI,sBAAsB,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC7F,KAAK,GAAG,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9C,CAAC;IACD,OAAO,SAAS,GAAG,sBAAsB,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC","sourcesContent":["// `rem` always resolves against the page's <html>, even inside a shadow root. A module page that sized its own root\n// (`html, body { font-size: 12px }`) drew every rem length from that size, but hosted, the same lengths use the host\n// page's root (16px): Material's `.mat-mdc-button > .mat-icon { font-size: 1.125rem }` drew 13.5px on the old page and\n// 18px hosted. The build-time PostCSS plugin records the module's root size as this property on the module boundary;\n// followModuleRootFontSize() rewrites every rem length in the module's shadow root to read it.\nexport const MF_ROOT_FONT_SIZE_PROPERTY = '--edyn-mf-rem';\n\nconst ROOT_FONT_SIZE_FALLBACK = `var(${MF_ROOT_FONT_SIZE_PROPERTY}, 1rem)`;\nexport const ROOT_FONT_SIZE_DECLARATION_PATTERN = new RegExp(`${MF_ROOT_FONT_SIZE_PROPERTY}\\\\s*:`);\nexport const REM_LENGTH_HINT_PATTERN = /\\drem/i;\n// A number with the rem unit that is not part of an identifier (`foo-2rem`) and not the fallback this rewrite writes.\nconst REM_LENGTH_PATTERN = new RegExp(`(?<![\\\\w.-]|var\\\\(${MF_ROOT_FONT_SIZE_PROPERTY},\\\\s*)(-?(?:\\\\d+\\\\.?\\\\d*|\\\\.\\\\d+))rem(?![\\\\w-])`, 'gi');\n// Strings and url() keep their text: `content: \"2rem\"` or `url(2rem.png)` are not lengths.\nconst VERBATIM_PATTERN = /\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|url\\((?:[^()\"'\\\\]|\\\\.)*\\)/gi;\n\n// The same match without the global flag, as a quick test: it skips the fallback this rewrite writes, so a followed\n// value does not look like work again.\nexport const UNFOLLOWED_REM_PATTERN = new RegExp(REM_LENGTH_PATTERN.source, 'i');\n\nconst rewriteOutsideVerbatim = (text: string): string => {\n return text.replace(REM_LENGTH_PATTERN, (_match, amount: string) => `calc(${amount} * ${ROOT_FONT_SIZE_FALLBACK})`);\n};\n\n/** Rewrites every rem length in CSS declaration text to follow the module's root font size; running it again changes nothing. */\nexport const rewriteRemLengths = (declarations: string): string => {\n let rewritten = '';\n let start = 0;\n for (const verbatim of declarations.matchAll(VERBATIM_PATTERN)) {\n rewritten += rewriteOutsideVerbatim(declarations.slice(start, verbatim.index)) + verbatim[0];\n start = verbatim.index + verbatim[0].length;\n }\n return rewritten + rewriteOutsideVerbatim(declarations.slice(start));\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edynamix/mf-isolation",
3
- "version": "0.0.31",
3
+ "version": "0.0.32",
4
4
  "description": "CSS and overlay isolation helpers for eDynamix microfrontends.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -94,6 +94,7 @@
94
94
  "@playwright/test": "1.60.0",
95
95
  "@types/bun": "1.3.14",
96
96
  "@types/node": "22.20.2",
97
+ "happy-dom": "20.11.2",
97
98
  "knip": "6.32.2",
98
99
  "postcss": "8.5.28",
99
100
  "typescript": "5.8.3",