@softarc/native-federation-orchestrator 4.5.3 → 4.6.1

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.
Files changed (33) hide show
  1. package/README.md +2 -2
  2. package/fesm2022/@softarc/native-federation-orchestrator.mjs +1184 -266
  3. package/fesm2022/@softarc/native-federation-orchestrator.mjs.map +4 -4
  4. package/fesm2022/module-federation.mjs +34 -20
  5. package/fesm2022/module-federation.mjs.map +3 -3
  6. package/fesm2022/node.mjs +1084 -247
  7. package/fesm2022/node.mjs.map +4 -4
  8. package/node-loader/loader.mjs +19 -2
  9. package/node-loader/loader.mjs.map +2 -2
  10. package/package.json +1 -1
  11. package/quickstart.mjs +15 -15
  12. package/types/lib/core/1.domain/externals/basis.d.ts +17 -2
  13. package/types/lib/core/1.domain/externals/version.contract.d.ts +1 -0
  14. package/types/lib/core/1.domain/remote-entry/remote-entry.contract.d.ts +1 -0
  15. package/types/lib/core/2.app/driver-ports/init/drivers.contract.d.ts +2 -0
  16. package/types/lib/core/2.app/driver-ports/init/for-determining-shared-externals.port.d.ts +8 -1
  17. package/types/lib/core/2.app/driver-ports/init/for-marking-pools-for-reelection.port.d.ts +6 -0
  18. package/types/lib/core/2.app/driver-ports/init/for-pooling-shared-externals.port.d.ts +3 -1
  19. package/types/lib/core/2.app/driving-ports/for-shared-chunks-storage.port.d.ts +1 -0
  20. package/types/lib/core/2.app/driving-ports/for-shared-externals-storage.port.d.ts +1 -2
  21. package/types/lib/core/2.app/steps/apply-winner.d.ts +18 -0
  22. package/types/lib/core/2.app/steps/pooling/anchoring.d.ts +69 -0
  23. package/types/lib/core/2.app/steps/pooling/mark-pools-for-reelection.d.ts +5 -0
  24. package/types/lib/core/2.app/steps/pooling/pool-dynamic-externals.d.ts +3 -1
  25. package/types/lib/core/2.app/steps/pooling/pool-graph.d.ts +10 -5
  26. package/types/lib/core/2.app/steps/pooling/pool-shared-externals.d.ts +30 -1
  27. package/types/lib/core/2.app/steps/pooling/pool-views.d.ts +63 -0
  28. package/types/lib/core/2.app/steps/pooling/pool.types.d.ts +30 -1
  29. package/types/lib/core/2.app/steps/pooling/pool.util.d.ts +15 -0
  30. package/types/lib/core/2.app/steps/store-remote-entry.d.ts +1 -1
  31. package/types/lib/core/3.adapters/browser/sse-handler.d.ts +0 -8
  32. package/types/lib/testing/pooling/no-tear.d.ts +37 -0
  33. package/types/scripts/node-loader.d.ts +1 -0
@@ -1,3 +1,22 @@
1
+ // src/lib/core/1.domain/externals/basis.ts
2
+ function versionEntries(version) {
3
+ return collectEntries(version, void 0);
4
+ }
5
+ function forEachVersionEntry(version, accepts, visit) {
6
+ for (const remote of version.remotes) {
7
+ if (remote.servedBy) continue;
8
+ if (accepts && !accepts(remote)) continue;
9
+ for (const entrypoint in remote.entries) visit(entrypoint, remote);
10
+ }
11
+ }
12
+ function collectEntries(version, accepts) {
13
+ const entries = /* @__PURE__ */ new Map();
14
+ forEachVersionEntry(version, accepts, (entrypoint, remote) => {
15
+ if (!entries.has(entrypoint)) entries.set(entrypoint, remote);
16
+ });
17
+ return entries;
18
+ }
19
+
1
20
  // src/lib/utils/path.ts
2
21
  function join(pathA, pathB) {
3
22
  pathA = pathA.endsWith("/") ? pathA.slice(0, -1) : pathA;
@@ -20,26 +39,21 @@ function createGetShared(ports) {
20
39
  for (const version of versions) {
21
40
  if (!version.remotes[0]) continue;
22
41
  const requiredVersion = resolveRequiredVersion(version, options, scopeType);
23
- const claimed = /* @__PURE__ */ new Set();
24
- for (const source of version.remotes) {
25
- for (const [entryName, file] of Object.entries(source.entries)) {
26
- if (claimed.has(entryName)) continue;
27
- claimed.add(entryName);
28
- const url = resolveUrl(source, file);
29
- if (!url) continue;
30
- const shareObject = {
31
- version: version.tag,
32
- get: () => ports.browser.importModule(url).then((module) => () => module),
33
- shareConfig: {
34
- singleton,
35
- requiredVersion,
36
- ...scopeType === "strict" ? { strictVersion: true } : {}
37
- }
38
- };
39
- if (scopeType !== "global") shareObject.scope = scope;
40
- if (!shared[entryName]) shared[entryName] = [];
41
- shared[entryName].push(shareObject);
42
- }
42
+ for (const [entryName, source] of versionEntries(version)) {
43
+ const url = resolveUrl(source, source.entries[entryName]);
44
+ if (!url) continue;
45
+ const shareObject = {
46
+ version: version.tag,
47
+ get: () => ports.browser.importModule(url).then((module) => () => module),
48
+ shareConfig: {
49
+ singleton,
50
+ requiredVersion,
51
+ ...scopeType === "strict" ? { strictVersion: true } : {}
52
+ }
53
+ };
54
+ if (scopeType !== "global") shareObject.scope = scope;
55
+ if (!shared[entryName]) shared[entryName] = [];
56
+ shared[entryName].push(shareObject);
43
57
  }
44
58
  }
45
59
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/lib/utils/path.ts", "../../src/lib/module-federation/get-shared.ts"],
4
- "sourcesContent": ["function join(pathA: string, pathB: string): string {\n pathA = pathA.endsWith('/') ? pathA.slice(0, -1) : pathA;\n pathB = pathB.startsWith('/') ? pathB.slice(1) : pathB;\n return `${pathA}/${pathB}`;\n}\n\nfunction getScope(path: string) {\n if (!path) return '';\n\n const parts = path.split('/');\n\n if (parts[parts.length - 1] === '' || parts[parts.length - 1]!.includes('.')) {\n parts.pop();\n }\n if (parts.length < 1) return '';\n\n return `${parts.join('/')}/`;\n}\n\nexport { join, getScope };\n", "import type { DrivingContract } from 'lib/core/2.app/driving-ports/driving.contract';\nimport type { SharedVersion, SharedVersionMeta } from 'lib/core/1.domain';\nimport type { GetSharedOptions, ShareInfos, Shared } from './share-infos.contract';\nimport * as _path from 'lib/utils/path';\n\n/**\n * Adapts native federation's shared externals to the `ShareInfos` shape webpack\n * Module Federation expects (see `docs/module-federation.md`).\n */\nexport function createGetShared(\n ports: Pick<DrivingContract, 'sharedExternalsRepo' | 'remoteInfoRepo' | 'browser'>\n): (options?: GetSharedOptions) => ShareInfos {\n return (options = {}) => {\n const shared: ShareInfos = {};\n\n for (const scope of ports.sharedExternalsRepo.getScopes({ includeGlobal: true })) {\n const scopeType = ports.sharedExternalsRepo.scopeType(scope);\n const externals = ports.sharedExternalsRepo.getFromScope(scope);\n\n for (const external of Object.values(externals)) {\n const shareVersions = external.versions.filter(v => v.action === 'share');\n if (shareVersions.length === 0) continue;\n\n // The strict scope is a version -> location map: every version is shared\n // side by side and stays non-singleton. Other scopes share one singleton.\n const versions = scopeType === 'strict' ? shareVersions : shareVersions.slice(0, 1);\n const singleton = scopeType === 'strict' ? false : (options.singleton ?? true);\n\n for (const version of versions) {\n if (!version.remotes[0]) continue;\n\n const requiredVersion = resolveRequiredVersion(version, options, scopeType);\n\n // MF's shared config is flat: one key per entrypoint. Emit a separate\n // Shared for each entry so secondary entrypoints reach MF consumers.\n const claimed = new Set<string>();\n for (const source of version.remotes) {\n for (const [entryName, file] of Object.entries(source.entries)) {\n if (claimed.has(entryName)) continue;\n claimed.add(entryName);\n\n const url = resolveUrl(source, file);\n if (!url) continue;\n\n const shareObject: Shared = {\n version: version.tag,\n get: () => ports.browser.importModule(url).then(module => () => module),\n shareConfig: {\n singleton,\n requiredVersion,\n ...(scopeType === 'strict' ? { strictVersion: true } : {}),\n },\n };\n if (scopeType !== 'global') shareObject.scope = scope;\n\n if (!shared[entryName]) shared[entryName] = [];\n shared[entryName]!.push(shareObject);\n }\n }\n }\n }\n }\n\n return shared;\n };\n\n function resolveUrl(source: SharedVersionMeta, file: string): string | undefined {\n return ports.remoteInfoRepo\n .tryGet(source.name)\n .map(remote => _path.join(remote.scopeUrl, file))\n .get();\n }\n}\n\nfunction resolveRequiredVersion(\n version: SharedVersion,\n options: GetSharedOptions,\n scopeType: 'global' | 'strict' | 'shareScope'\n): string {\n // Strict shares a specific version, not a range: pin to the exact tag so a\n // consumer reuses only that version (MF matches via satisfy(version, required)).\n if (scopeType === 'strict') return version.tag;\n if (typeof options.requiredVersionPrefix === 'string') {\n return `${options.requiredVersionPrefix}${version.tag}`;\n }\n // `remotes[0]` is the serving basis, ordered by entrypoint coverage: it says nothing about\n // what the version demands. Advertising its range would let MF hand a sibling a copy that\n // sibling's own range rejects, so a disagreement pins to the tag \u2014 the only value no remote\n // can reject, and the one the import map already commits to.\n const declared = new Set(version.remotes.map(r => r.requiredVersion));\n if (declared.size > 1) return version.tag;\n\n return version.remotes[0]?.requiredVersion || `^${version.tag}`;\n}\n"],
5
- "mappings": ";AAAA,SAAS,KAAK,OAAe,OAAuB;AAClD,UAAQ,MAAM,SAAS,GAAG,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;AACnD,UAAQ,MAAM,WAAW,GAAG,IAAI,MAAM,MAAM,CAAC,IAAI;AACjD,SAAO,GAAG,KAAK,IAAI,KAAK;AAC1B;;;ACKO,SAAS,gBACd,OAC4C;AAC5C,SAAO,CAAC,UAAU,CAAC,MAAM;AACvB,UAAM,SAAqB,CAAC;AAE5B,eAAW,SAAS,MAAM,oBAAoB,UAAU,EAAE,eAAe,KAAK,CAAC,GAAG;AAChF,YAAM,YAAY,MAAM,oBAAoB,UAAU,KAAK;AAC3D,YAAM,YAAY,MAAM,oBAAoB,aAAa,KAAK;AAE9D,iBAAW,YAAY,OAAO,OAAO,SAAS,GAAG;AAC/C,cAAM,gBAAgB,SAAS,SAAS,OAAO,OAAK,EAAE,WAAW,OAAO;AACxE,YAAI,cAAc,WAAW,EAAG;AAIhC,cAAM,WAAW,cAAc,WAAW,gBAAgB,cAAc,MAAM,GAAG,CAAC;AAClF,cAAM,YAAY,cAAc,WAAW,QAAS,QAAQ,aAAa;AAEzE,mBAAW,WAAW,UAAU;AAC9B,cAAI,CAAC,QAAQ,QAAQ,CAAC,EAAG;AAEzB,gBAAM,kBAAkB,uBAAuB,SAAS,SAAS,SAAS;AAI1E,gBAAM,UAAU,oBAAI,IAAY;AAChC,qBAAW,UAAU,QAAQ,SAAS;AACpC,uBAAW,CAAC,WAAW,IAAI,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG;AAC9D,kBAAI,QAAQ,IAAI,SAAS,EAAG;AAC5B,sBAAQ,IAAI,SAAS;AAErB,oBAAM,MAAM,WAAW,QAAQ,IAAI;AACnC,kBAAI,CAAC,IAAK;AAEV,oBAAM,cAAsB;AAAA,gBAC1B,SAAS,QAAQ;AAAA,gBACjB,KAAK,MAAM,MAAM,QAAQ,aAAa,GAAG,EAAE,KAAK,YAAU,MAAM,MAAM;AAAA,gBACtE,aAAa;AAAA,kBACX;AAAA,kBACA;AAAA,kBACA,GAAI,cAAc,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;AAAA,gBAC1D;AAAA,cACF;AACA,kBAAI,cAAc,SAAU,aAAY,QAAQ;AAEhD,kBAAI,CAAC,OAAO,SAAS,EAAG,QAAO,SAAS,IAAI,CAAC;AAC7C,qBAAO,SAAS,EAAG,KAAK,WAAW;AAAA,YACrC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,QAA2B,MAAkC;AAC/E,WAAO,MAAM,eACV,OAAO,OAAO,IAAI,EAClB,IAAI,YAAgB,KAAK,OAAO,UAAU,IAAI,CAAC,EAC/C,IAAI;AAAA,EACT;AACF;AAEA,SAAS,uBACP,SACA,SACA,WACQ;AAGR,MAAI,cAAc,SAAU,QAAO,QAAQ;AAC3C,MAAI,OAAO,QAAQ,0BAA0B,UAAU;AACrD,WAAO,GAAG,QAAQ,qBAAqB,GAAG,QAAQ,GAAG;AAAA,EACvD;AAKA,QAAM,WAAW,IAAI,IAAI,QAAQ,QAAQ,IAAI,OAAK,EAAE,eAAe,CAAC;AACpE,MAAI,SAAS,OAAO,EAAG,QAAO,QAAQ;AAEtC,SAAO,QAAQ,QAAQ,CAAC,GAAG,mBAAmB,IAAI,QAAQ,GAAG;AAC/D;",
3
+ "sources": ["../../src/lib/core/1.domain/externals/basis.ts", "../../src/lib/utils/path.ts", "../../src/lib/module-federation/get-shared.ts"],
4
+ "sourcesContent": ["import type { SharedVersion, SharedVersionMeta } from './version.contract';\n\nconst coverage = (remote: SharedVersionMeta): number => Object.keys(remote.entries).length;\n\n// `remotes[0]` is the basis: the copy every consumer of the version resolves to. Host and cached\n// outrank coverage because repointing them invalidates a committed import map.\nexport function isBetterBasis(candidate: SharedVersionMeta, basis: SharedVersionMeta): boolean {\n if (basis.cached !== candidate.cached) return candidate.cached;\n return coverage(candidate) > coverage(basis);\n}\n\nexport function addRemoteToVersion(\n version: SharedVersion,\n remote: SharedVersionMeta,\n isHost = false\n): void {\n if (isHost) {\n version.host = true;\n version.remotes.unshift(remote);\n return;\n }\n\n const basis = version.remotes[0];\n if (basis && !version.host && isBetterBasis(remote, basis)) {\n version.remotes.unshift(remote);\n return;\n }\n\n version.remotes.push(remote);\n}\n\n// `remotes[0]` answers \"who serves this version\", never \"what does this version demand\":\n// `requiredVersion`, `strictVersion` and `cached` are per-build settings, so remotes sharing a tag\n// can disagree on all three. Negotiation must therefore aggregate over every remote, or basis\n// precedence would decide compatibility. Deduped because those settings repeat across a version's\n// remotes, which keeps the resolver's O(versions\u00B2) selection from also scaling with remote count.\nexport function versionDemands(version: SharedVersion): SharedVersionMeta[] {\n if (version.remotes.length < 2) return version.remotes;\n\n const distinct = new Map<string, SharedVersionMeta>();\n for (const remote of version.remotes) {\n const key = `${remote.requiredVersion}|${remote.strictVersion}|${remote.cached}`;\n if (!distinct.has(key)) distinct.set(key, remote);\n }\n return Array.from(distinct.values());\n}\n\n// Coverage enforcement can leave a `scope` version beside a shareable one at the same tag.\nexport function findVersionForTag(\n versions: SharedVersion[],\n tag: string\n): SharedVersion | undefined {\n let scoped: SharedVersion | undefined;\n for (const version of versions) {\n if (version.tag !== tag) continue;\n if (version.action !== 'scope') return version;\n scoped ??= version;\n }\n return scoped;\n}\n\n// Every copy of a version builds the same tag, so a specifier only some of them bundle is not a\n// tear: the version exposes the union of its copies' entrypoints, each served by the first copy\n// that declares it \u2014 basis precedence first. See\n// docs/version-resolver.md#entrypoint-coverage-and-tearing.\n//\n// Only copies that publish their own files count. Pooling anchors a copy on a foreign build via\n// `servedBy`, and the import map then names the anchor's files for it, per consumer \u2014 so what such a\n// copy bundles answers for nobody but itself, and counting it would promise a specifier no consumer of\n// this version can resolve. Pooling keeps an anchored copy out of the basis slot for exactly this\n// reason, so a `share` version's basis always survives the skip.\nexport function versionEntries(version: SharedVersion): Map<string, SharedVersionMeta> {\n return collectEntries(version, undefined);\n}\n\n// The part of that surface a committed import map already publishes, which on the dynamic path is less than\n// all of it: a copy that joined at runtime served its extra entrypoints into its own scope alone, so it is\n// part of the version yet can serve nobody else. `cached` is set by whichever import-map builder mapped the\n// copy, so it answers exactly that. Only a consumer that resolves through the committed mapping needs this\n// \u2014 a per-consumer override names its provider outright and can use any copy.\nexport function committedEntries(version: SharedVersion): Map<string, SharedVersionMeta> {\n return collectEntries(version, remote => remote.cached);\n}\n\n/**\n * The walk both of those keep the first claim of: which copies of a version may publish a specifier, in basis\n * precedence. Exposed so a caller that models the same fill order without needing the map \u2014 the pooling gates\n * ask which build a consumer lands on, per specifier \u2014 reads the `servedBy` rule from here instead of\n * restating it. It deliberately does not dedup: the callers do, and this way the walk allocates nothing.\n *\n * `accepts` is for a caller with a further reason to discount a copy (pooling islands one, so it self-serves).\n * Filtering the *result* is not the same thing \u2014 that drops the specifier instead of letting the next copy\n * claim it.\n */\nexport function forEachVersionEntry(\n version: SharedVersion,\n accepts: ((remote: SharedVersionMeta) => boolean) | undefined,\n visit: (entrypoint: string, remote: SharedVersionMeta) => void\n): void {\n for (const remote of version.remotes) {\n if (remote.servedBy) continue;\n if (accepts && !accepts(remote)) continue;\n for (const entrypoint in remote.entries) visit(entrypoint, remote);\n }\n}\n\nfunction collectEntries(\n version: SharedVersion,\n accepts: ((remote: SharedVersionMeta) => boolean) | undefined\n): Map<string, SharedVersionMeta> {\n const entries = new Map<string, SharedVersionMeta>();\n forEachVersionEntry(version, accepts, (entrypoint, remote) => {\n if (!entries.has(entrypoint)) entries.set(entrypoint, remote);\n });\n return entries;\n}\n\n// A `versionEntries` map or a bare name set both answer \"can this be served?\".\ntype Covered = Pick<ReadonlySet<string>, 'has'>;\n\nexport function uncoveredEntrypoints(remote: SharedVersionMeta, covered: Covered): string[] {\n return Object.keys(remote.entries).filter(entrypoint => !covered.has(entrypoint));\n}\n\n// `uncoveredEntrypoints` without materializing the names: the resolver's O(versions\u00B2) selection\n// loop asks this once per remote per candidate and only needs the count. Keep the two in sync.\nexport function countUncoveredEntrypoints(remote: SharedVersionMeta, covered: Covered): number {\n let uncovered = 0;\n for (const entrypoint in remote.entries) {\n if (!covered.has(entrypoint)) uncovered++;\n }\n return uncovered;\n}\n", "function join(pathA: string, pathB: string): string {\n pathA = pathA.endsWith('/') ? pathA.slice(0, -1) : pathA;\n pathB = pathB.startsWith('/') ? pathB.slice(1) : pathB;\n return `${pathA}/${pathB}`;\n}\n\nfunction getScope(path: string) {\n if (!path) return '';\n\n const parts = path.split('/');\n\n if (parts[parts.length - 1] === '' || parts[parts.length - 1]!.includes('.')) {\n parts.pop();\n }\n if (parts.length < 1) return '';\n\n return `${parts.join('/')}/`;\n}\n\nexport { join, getScope };\n", "import type { DrivingContract } from 'lib/core/2.app/driving-ports/driving.contract';\nimport type { SharedVersion, SharedVersionMeta } from 'lib/core/1.domain';\nimport { versionEntries } from 'lib/core/1.domain/externals/basis';\nimport type { GetSharedOptions, ShareInfos, Shared } from './share-infos.contract';\nimport * as _path from 'lib/utils/path';\n\n/**\n * Adapts native federation's shared externals to the `ShareInfos` shape webpack\n * Module Federation expects (see `docs/module-federation.md`).\n */\nexport function createGetShared(\n ports: Pick<DrivingContract, 'sharedExternalsRepo' | 'remoteInfoRepo' | 'browser'>\n): (options?: GetSharedOptions) => ShareInfos {\n return (options = {}) => {\n const shared: ShareInfos = {};\n\n for (const scope of ports.sharedExternalsRepo.getScopes({ includeGlobal: true })) {\n const scopeType = ports.sharedExternalsRepo.scopeType(scope);\n const externals = ports.sharedExternalsRepo.getFromScope(scope);\n\n for (const external of Object.values(externals)) {\n const shareVersions = external.versions.filter(v => v.action === 'share');\n if (shareVersions.length === 0) continue;\n\n // The strict scope is a version -> location map: every version is shared\n // side by side and stays non-singleton. Other scopes share one singleton.\n const versions = scopeType === 'strict' ? shareVersions : shareVersions.slice(0, 1);\n const singleton = scopeType === 'strict' ? false : (options.singleton ?? true);\n\n for (const version of versions) {\n if (!version.remotes[0]) continue;\n\n const requiredVersion = resolveRequiredVersion(version, options, scopeType);\n\n // MF's shared config is flat: one key per entrypoint. Emit a separate\n // Shared for each merged entry so secondary entrypoints reach MF consumers.\n for (const [entryName, source] of versionEntries(version)) {\n const url = resolveUrl(source, source.entries[entryName]!);\n if (!url) continue;\n\n const shareObject: Shared = {\n version: version.tag,\n get: () => ports.browser.importModule(url).then(module => () => module),\n shareConfig: {\n singleton,\n requiredVersion,\n ...(scopeType === 'strict' ? { strictVersion: true } : {}),\n },\n };\n if (scopeType !== 'global') shareObject.scope = scope;\n\n if (!shared[entryName]) shared[entryName] = [];\n shared[entryName]!.push(shareObject);\n }\n }\n }\n }\n\n return shared;\n };\n\n function resolveUrl(source: SharedVersionMeta, file: string): string | undefined {\n return ports.remoteInfoRepo\n .tryGet(source.name)\n .map(remote => _path.join(remote.scopeUrl, file))\n .get();\n }\n}\n\nfunction resolveRequiredVersion(\n version: SharedVersion,\n options: GetSharedOptions,\n scopeType: 'global' | 'strict' | 'shareScope'\n): string {\n // Strict shares a specific version, not a range: pin to the exact tag so a\n // consumer reuses only that version (MF matches via satisfy(version, required)).\n if (scopeType === 'strict') return version.tag;\n if (typeof options.requiredVersionPrefix === 'string') {\n return `${options.requiredVersionPrefix}${version.tag}`;\n }\n // `remotes[0]` is the serving basis, ordered by entrypoint coverage: it says nothing about\n // what the version demands. Advertising its range would let MF hand a sibling a copy that\n // sibling's own range rejects, so a disagreement pins to the tag \u2014 the only value no remote\n // can reject, and the one the import map already commits to.\n const declared = new Set(version.remotes.map(r => r.requiredVersion));\n if (declared.size > 1) return version.tag;\n\n return version.remotes[0]?.requiredVersion || `^${version.tag}`;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }