fhir-snapshot-generator
Version:
Generate snapshots for FHIR Profiles
1,665 lines (1,638 loc) • 75.5 kB
JavaScript
import path from 'path';
import fs from 'fs-extra';
import { FhirPackageExplorer } from 'fhir-package-explorer';
// src/utils/element/applyDiffs.ts
var applySingleDiff = (elements, diffElement) => {
const index = elements.findIndex((el) => el.id === diffElement.id);
if (index === -1) {
throw new Error(`Element with id "${diffElement.id}" not found`);
}
const baseElement = { ...elements[index] };
const mergedElement = mergeElement(baseElement, diffElement);
if (mergedElement.sliceName && !mergedElement.id.endsWith(`:${mergedElement.sliceName}`)) {
delete mergedElement.sliceName;
}
const updatedElements = [...elements.slice(0, index), mergedElement, ...elements.slice(index + 1)];
return updatedElements;
};
var rewrite = (original, kind, pathRewriteMap) => {
for (const [illegalPrefix, rewrite2] of pathRewriteMap.entries()) {
if (original === illegalPrefix || original.startsWith(illegalPrefix + ".")) {
return original.replace(illegalPrefix, rewrite2[kind]);
}
}
return original;
};
var applyDiffs = async (elements, diffs, fetcher, logger) => {
let updatedElements = [...elements];
const pathRewriteMap = /* @__PURE__ */ new Map();
if (updatedElements[0].extension) {
delete updatedElements[0].extension;
}
if (diffs.length === 0) return updatedElements;
for (const diff of diffs) {
if (!elementExists(updatedElements, diff.id)) {
updatedElements = await ensureBranch(updatedElements, diff.id, fetcher, logger, pathRewriteMap);
}
const rewrittenDiff = {
...diff,
id: rewrite(diff.id, "id", pathRewriteMap),
path: rewrite(diff.path, "path", pathRewriteMap)
};
updatedElements = applySingleDiff(updatedElements, rewrittenDiff);
}
return updatedElements;
};
// src/utils/element/ensureChild.ts
var ensureChild = async (elements, parentId, childId, fetcher, logger, pathRewriteMap) => {
const parentElementBlock = elements.filter((element) => element.id === parentId || element.id.startsWith(`${parentId}.`));
if (parentElementBlock.length === 0) {
throw new Error(`Parent element '${parentId}' not found in the working snapshot array`);
}
let parentNode = toTree(parentElementBlock);
if (isNodeSliceable(parentNode)) {
parentNode = parentNode.children[0];
}
const isExpanded = parentNode.children.length > 0;
if (!isExpanded) {
parentNode = await expandNode(parentNode, fetcher);
elements = injectElementBlock(elements, parentId, fromTree(parentNode));
}
const [elementName, sliceName] = childId.split(":");
const childElement = parentNode.children.find((element) => element.id.endsWith(`.${elementName}`));
if (!childElement) {
const match = findMonopolyShortcutTarget(parentId, elementName, parentNode.children);
if (match) {
const canonicalId = `${parentId}.${match.rewrittenSegment}`;
const elementDefinition = elements.find((e) => e.id === canonicalId);
const canonicalPath = elementDefinition?.path ?? canonicalId;
pathRewriteMap.set(`${parentId}.${elementName}`, {
id: canonicalId,
path: canonicalPath
});
const virtualDiff = {
id: canonicalId,
path: canonicalPath,
type: [{ code: match.type }]
};
elements = applySingleDiff(elements, virtualDiff);
return elements;
}
throw new Error(`Element '${childId}' is illegal under '${parentId}'.`);
}
if (!sliceName) return elements;
if (!isNodeSliceable(childElement)) {
const aliasId = `${childElement.id}:${sliceName}`;
pathRewriteMap.set(aliasId, {
id: childElement.id,
path: childElement.path
});
return elements;
}
const slice = childElement.children.find((slice2) => slice2.sliceName === sliceName);
if (slice) {
return elements;
}
if (!slice) {
if (elementName.endsWith("[x]") && childElement.children[0].definition?.type?.length === 1) {
const onlyType = childElement.children[0].definition.type[0].code;
const monopolySliceName = `${elementName.slice(0, -3)}${initCap(onlyType)}`;
if (sliceName === monopolySliceName) {
const aliasId = `${childElement.id}:${sliceName}`;
const aliasPath = childElement.path;
pathRewriteMap.set(aliasId, {
id: childElement.id,
path: aliasPath
});
return elements;
}
}
const headSlice = childElement.children[0];
const newId = `${headSlice.id}:${sliceName}`;
const newSlice = rewriteNodePaths(headSlice, newId, headSlice.id);
newSlice.nodeType = "slice";
delete newSlice.definition?.slicing;
delete newSlice.definition?.mustSupport;
newSlice.sliceName = sliceName;
if (newSlice.definition) {
newSlice.definition.sliceName = sliceName;
}
childElement.children.push(newSlice);
elements = injectElementBlock(elements, childElement.id, fromTree(childElement));
}
return elements;
};
// src/utils/element/ensureBranch.ts
var ensureBranch = async (elements, targetElementId, fetcher, logger, pathRewriteMap) => {
const idSegments = targetElementId.split(".");
const rootId = idSegments[0];
let updatedElements = elements;
if (elements[0].id !== rootId) {
throw new Error(`Root element '${rootId}' not found in the working snapshot array`);
}
if (rootId === targetElementId) {
return updatedElements;
}
let canonicalParentId = rootId;
for (let i = 1; i < idSegments.length; i++) {
const rawChildSegment = idSegments[i];
const rewrite2 = pathRewriteMap.get(canonicalParentId);
if (rewrite2) {
canonicalParentId = rewrite2.id;
}
updatedElements = await ensureChild(
updatedElements,
canonicalParentId,
rawChildSegment,
fetcher,
logger,
pathRewriteMap
);
canonicalParentId = `${canonicalParentId}.${rawChildSegment}`;
}
return updatedElements;
};
// src/utils/element/toNodeType.ts
var toNodeType = (element) => {
if (element.id.endsWith("[x]")) {
return "poly";
}
if (element.sliceName) {
if (element.slicing) return "resliced";
return "slice";
}
if (element.base?.max && (element.base.max === "*" || parseInt(element.base.max) > 1)) {
return "array";
}
return "element";
};
// src/utils/element/injectElementBlock.ts
var injectElementBlock = (elements, injectionPoint, elementBlock) => {
const index = elements.findIndex((el) => el.id === injectionPoint);
if (index === -1) throw new Error(`Element with id "${injectionPoint}" not found`);
const before = elements.slice(0, index);
const after = elements.slice(index + 1).filter((element) => !element.id.startsWith(`${injectionPoint}.`) && !element.id.startsWith(`${injectionPoint}:`));
const results = [...before, ...elementBlock, ...after];
return results;
};
// src/utils/element/mergeElement.ts
var mergeElement = (base, diff) => {
if (diff.id !== base.id) {
throw new Error(`Element ID mismatch. Tried to apply "${diff.id}" onto "${base.id}".`);
}
const mergedElement = { ...base };
for (const key of Object.keys(diff)) {
if (["constraint", "condition", "mapping"].includes(key)) {
const baseArr = base[key] || [], diffArr = diff[key] || [];
if (key === "constraint") {
mergedElement.constraint = [...baseArr, ...diffArr];
} else if (key === "condition") {
const ids = Array.from(/* @__PURE__ */ new Set([...baseArr, ...diffArr]));
mergedElement.condition = ids;
} else {
const seen = /* @__PURE__ */ new Set();
const serialize = (obj) => JSON.stringify(Object.entries(obj).sort());
const combined = [...baseArr, ...diffArr];
mergedElement.mapping = combined.filter((m) => {
const s = serialize(m);
return seen.has(s) ? false : seen.add(s);
});
}
} else if (key !== "id" && key !== "path") {
if (diff[key] !== void 0) {
mergedElement[key] = diff[key];
}
}
}
return mergedElement;
};
// src/utils/element/elementExists.ts
var elementExists = (elements, targetElementId) => {
return elements.some((element) => element.id === targetElementId);
};
// src/utils/element/rewriteElementPaths.ts
var rewriteElementPaths = (elements, newPrefix, oldPrefix) => {
const oldPrefixDot = oldPrefix.endsWith(".") ? oldPrefix : oldPrefix + ".";
const newPrefixDot = newPrefix.endsWith(".") ? newPrefix : newPrefix + ".";
const removeSlices = (elementIdPart) => {
const segments = elementIdPart.split(".");
const cleanedSegments = segments.map((segment) => {
const sliceIndex = segment.indexOf(":");
return sliceIndex !== -1 ? segment.slice(0, sliceIndex) : segment;
});
return cleanedSegments.join(".");
};
const replaceId = (str) => str === oldPrefix ? newPrefix : str.startsWith(oldPrefixDot) ? newPrefixDot + str.slice(oldPrefixDot.length) : str;
const replacePath = (elementPath) => {
const newPathPrefix = removeSlices(newPrefixDot);
const oldPathPrefix = removeSlices(oldPrefixDot);
return elementPath === oldPathPrefix ? newPathPrefix : elementPath.startsWith(oldPathPrefix) ? newPathPrefix + elementPath.slice(oldPathPrefix.length) : elementPath;
};
return elements.map((el) => ({
...el,
id: replaceId(el.id),
path: replacePath(el.path)
}));
};
// src/utils/element/migrateElements.ts
var markdownKeys = ["definition", "comment", "requirements", "meaningWhenMissing"];
var ignoredExtensions = [
"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-no-warnings",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-hierarchy",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-interface",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-normative-version",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-applicable-version",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-category",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-security-category",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-summary",
"http://hl7.org/fhir/StructureDefinition/structuredefinition-wg",
"http://hl7.org/fhir/StructureDefinition/replaces",
"http://hl7.org/fhir/StructureDefinition/resource-approvalDate",
"http://hl7.org/fhir/StructureDefinition/resource-effectivePeriod",
"http://hl7.org/fhir/StructureDefinition/resource-lastReviewDate"
];
var replaceRelativeLinks = (markdown) => {
return markdown.replace(
/\[([^\]]+)\]\((?!https?:\/\/)([^)]+)\)/g,
(_match, text, url) => `[${text}](http://hl7.org/fhir/${url})`
);
};
var filterExtensions = (extensions) => {
const result = extensions.filter(
(ext) => !ignoredExtensions.includes(ext.url)
);
return result.length > 0 ? result : void 0;
};
var addSourceToConstraints = (constraints, sourceUrl) => {
return constraints.map((constraint) => ({ source: sourceUrl, ...constraint }));
};
var migrateElements = (elements, sourceUrl) => {
return elements.map((el, index) => {
const updated = { ...el };
if (index === 0 && el.extension) {
const filteredExtensions = filterExtensions(el.extension);
if (filteredExtensions) {
updated.extension = filteredExtensions;
} else {
delete updated.extension;
}
}
if (sourceUrl.startsWith("http://hl7.org/fhir")) {
for (const key of markdownKeys) {
const value = el[key];
if (typeof value === "string") {
updated[key] = replaceRelativeLinks(value);
}
}
}
if (el.constraint) {
updated.constraint = addSourceToConstraints(el.constraint, sourceUrl);
}
return updated;
});
};
// src/utils/element/findMonopolyShortcutTarget.ts
var findMonopolyShortcutTarget = (parentId, missingSegment, elements) => {
const prefix = `${parentId}.`;
const childElements = elements.filter(
(el) => el.id.startsWith(prefix) && el.id !== parentId && el.id.endsWith("[x]")
);
for (const el of childElements) {
const idSegment = el.id.slice(prefix.length);
const base = idSegment.slice(0, -3);
for (const type of el?.children[0]?.definition?.type ?? []) {
const shortcut = base + initCap(type.code);
if (shortcut === missingSegment) {
return {
rewrittenSegment: `${base}[x]`,
type: type.code
};
}
}
}
return null;
};
// src/utils/tree/expandNode.ts
var expandNode = async (node, fetcher) => {
if (isNodeSliceable(node)) {
throw new Error(`Node '${node.id}' is sliceable. Expand node must be called on a specific slice, headslice or a non-sliceable node.`);
}
if (node.children.length > 0) return node;
if (!node.definition) {
throw new Error(`Node '${node.id}' has no ElementDefinition. Cannot expand.`);
}
const definition = node.definition;
if ((!definition.type || definition.type.length === 0) && !definition.contentReference) {
throw new Error(`Node '${node.id}' has no type or contentReference defined. Cannot expand.`);
}
let snapshotElements = [];
if (definition.contentReference) {
snapshotElements = await fetcher.getContentReference(definition.contentReference);
if (!snapshotElements || snapshotElements.length === 0) {
throw new Error(`Snapshot for contentReference '${definition.contentReference}' is empty or missing.`);
}
delete definition.contentReference;
} else if (definition.type && definition.type.length > 1) {
snapshotElements = await fetcher.getBaseType("Element");
if (!snapshotElements || snapshotElements.length === 0) {
throw new Error("Snapshot for base type 'Element' is empty or missing.");
}
} else if (definition.type && definition.type.length === 1) {
const elementType = definition.type[0];
if (elementType.profile && elementType.profile.length === 1) {
const url = elementType.profile[0];
snapshotElements = await fetcher.getByUrl(url);
if (!snapshotElements || snapshotElements.length === 0) {
throw new Error(`Snapshot for type '${url}' is empty or missing.`);
}
} else {
const id = elementType.code;
if (id.startsWith("http://hl7.org/fhirpath/System.")) {
throw new Error(`Cannot expand node '${node.id}', type '${id}' can never have children.`);
}
snapshotElements = await fetcher.getBaseType(id);
if (!snapshotElements || snapshotElements.length === 0) {
throw new Error(`Snapshot for type '${id}' is empty or missing.`);
}
}
}
if (!snapshotElements || snapshotElements.length === 0) {
throw new Error(`Error expanding node '${node.id}' - the snapshot contains no elements.`);
}
const oldPrefix = snapshotElements[0].id;
const newPrefix = node.id;
const rewrittenElements = rewriteElementPaths(snapshotElements, newPrefix, oldPrefix);
const expandedSubtree = toTree(rewrittenElements);
const clonedNode = { ...node, children: expandedSubtree.children };
return clonedNode;
};
// src/utils/tree/fromTree.ts
var fromTree = (tree) => {
const result = [];
function visit(node) {
if (["element", "slice", "headslice"].includes(node.nodeType)) {
if (!node.definition) {
throw new Error(`Node ${node.id} of type ${node.nodeType} is missing its definition`);
}
result.push(node.definition);
}
for (const child of node.children) {
visit(child);
}
}
visit(tree);
return result;
};
// src/utils/tree/toTree.ts
var toTree = (elements) => {
if (elements.length === 0) {
throw new Error("Element array is empty");
}
const idToNode = /* @__PURE__ */ new Map();
const makeSegments = (fullId) => {
const idSegments = fullId.split(".");
const pathSegments = idSegments.map((segment) => segment.split(":")[0]);
return { idSegments, pathSegments };
};
const createNode = (element, forceNodeType) => {
const { idSegments, pathSegments } = makeSegments(element.id);
const nodeType = forceNodeType || toNodeType(element);
const node = {
id: element.id,
path: element.path,
idSegments,
pathSegments,
nodeType,
children: []
};
if (isNodeSliceable(node)) {
const headSlice = {
id: element.id,
path: element.path,
idSegments,
pathSegments,
nodeType: "headslice",
definition: element,
children: []
};
node.children.push(headSlice);
} else {
node.definition = element;
if (element.sliceName) {
node.sliceName = element.sliceName;
}
}
return node;
};
const rootElement = elements[0];
const rootNode = createNode(rootElement, "element");
idToNode.set(rootNode.id, rootNode);
for (let i = 1; i < elements.length; i++) {
const element = elements[i];
const { idSegments } = makeSegments(element.id);
const lastSegment = idSegments[idSegments.length - 1];
const isSlice = lastSegment.includes(":");
const lastSegmentWithoutSlice = isSlice ? lastSegment.split(":")[0] : lastSegment;
const parentPath = isSlice ? idSegments.slice(0, -1).join(".") + `.${lastSegmentWithoutSlice}` : idSegments.slice(0, -1).join(".");
const parentNode = idToNode.get(parentPath);
if (!parentNode) {
throw new Error(`Parent node not found for element ${element.id}`);
}
const newNode = createNode(element);
if (isNodeSliceable(parentNode)) {
if (isSlice) {
parentNode.children.push(newNode);
} else {
parentNode.children[0].children.push(newNode);
}
} else {
parentNode.children.push(newNode);
}
idToNode.set(newNode.id, newNode);
}
return rootNode;
};
// src/utils/tree/rewriteNodePaths.ts
var rewriteNodePaths = (node, newPrefix, oldPrefix) => {
const flattened = fromTree(node);
const rewritten = rewriteElementPaths(flattened, newPrefix, oldPrefix);
const newNode = toTree(rewritten);
return newNode;
};
// src/utils/tree/isNodeSliceable.ts
var isNodeSliceable = (node) => {
return ["array", "poly", "resliced"].includes(node.nodeType);
};
// src/utils/misc/logger.ts
var defaultLogger = {
info: (msg) => console.log(msg),
warn: (msg) => console.warn(msg),
error: (msg) => console.error(msg)
};
var defaultPrethrow = (msg) => {
if (msg instanceof Error) {
return msg;
}
const error = new Error(msg);
return error;
};
var customPrethrower = (logger) => {
return (msg) => {
if (msg instanceof Error) {
logger.error(msg);
return msg;
}
const error = new Error(msg);
logger.error(error);
return error;
};
};
// src/utils/misc/resolveFhirVersion.ts
var fhirVersionMap = {
"3.0.2": "STU3",
"3.0": "STU3",
"R3": "STU3",
"4.0.0": "R4",
"4.0.1": "R4",
"4.0": "R4",
"4.3.0": "R4B",
"4.3": "R4B",
"5.0.0": "R5",
"5.0": "R5"
};
var fhirCorePackages = {
"STU3": "hl7.fhir.r3.core@3.0.2",
"R4": "hl7.fhir.r4.core@4.0.1",
"R4B": "hl7.fhir.r4b.core@4.3.0",
"R5": "hl7.fhir.r5.core@5.0.0"
};
var resolveFhirVersion = (version2, toPackage) => {
const canonicalVersion = fhirVersionMap[version2] || version2;
const corePackage = fhirCorePackages[canonicalVersion];
if (!corePackage) {
throw new Error(`Unsupported FHIR version: ${version2}. Supported versions are: ${Object.keys(fhirCorePackages).join(", ")}`);
}
if (toPackage) {
const [id, version3] = corePackage.split("@");
return { id, version: version3 };
}
return canonicalVersion;
};
// src/utils/misc/resolveBasePackage.ts
var findCorePackage = async (pkg, fpe) => {
if (Object.values(fhirCorePackages).includes(`${pkg.id}@${pkg.version}`)) {
return [{ id: pkg.id, version: pkg.version }];
}
const deps = await fpe.getDirectDependencies(pkg);
return deps.filter((dep) => Object.values(fhirCorePackages).includes(`${dep.id}@${dep.version}`));
};
var resolveBasePackage = async (packageId, packageVersion, fpe, logger) => {
const corePackages = await findCorePackage({ id: packageId, version: packageVersion }, fpe);
if (corePackages.length === 0) {
logger.warn(`No base FHIR package dependency found for ${packageId}@${packageVersion}.`);
const pkgManifest = await fpe.getPackageManifest({ id: packageId, version: packageVersion });
if (pkgManifest["fhir-version-list"] && !pkgManifest.fhirVersions) {
pkgManifest.fhirVersions = pkgManifest["fhir-version-list"];
}
if (pkgManifest.fhirVersions && pkgManifest.fhirVersions.length > 0) {
pkgManifest.fhirVersions.map((fhirVersion) => {
logger.info(`Resolving core package for FHIR version ${fhirVersion}`);
const corePackageId = resolveFhirVersion(fhirVersion, true);
if (corePackageId) {
const { id, version: version3 } = corePackageId;
corePackages.push(
{
id,
version: version3
}
);
} else {
logger.warn(`Unknown FHIR version ${version2} in package ${packageId}@${packageVersion}.`);
}
});
if (corePackages.length === 0) return void 0;
}
}
if (corePackages.length > 1) {
logger.warn(`Multiple base FHIR packages found for ${packageId}@${packageVersion}: ${corePackages.map((pkg) => `${pkg.id}@${pkg.version}`).join(", ")}.`);
return void 0;
}
const version2 = corePackages[0].id === "hl7.fhir.r4.core" && corePackages[0].version === "4.0.0" ? "4.0.1" : corePackages[0].version;
return `${corePackages[0].id}@${version2}`;
};
// src/utils/misc/definitionFetcher.ts
var DefinitionFetcher5 = class {
constructor(sourcePackage, corePackage, fpe, snapshotFetcher) {
// A map to cache previously fetched element arrays for base types, profiles and contentReference.
this.elementCache = /* @__PURE__ */ new Map();
this.sourcePackage = sourcePackage;
this.corePackage = corePackage;
this.snapshotFetcher = snapshotFetcher;
this.fpe = fpe;
}
/**
* Get the definition for one of the base FHIR types.
* @param type The type ID (e.g., "CodeableConcept", "Quantity", etc.).
*/
async getBaseType(type) {
let elements = this.elementCache.get(type);
if (elements) {
return elements;
}
const definition = await this.fpe.resolve({ resourceType: "StructureDefinition", id: type, package: this.corePackage, derivation: ["Element", "Resource"].includes(type) ? void 0 : "specialization" });
if (!definition) {
throw new Error(`FHIR type '${type}' not found in base package '${this.corePackage}'`);
}
if (!definition.snapshot || !definition.snapshot.element || definition.snapshot.element.length === 0) {
throw new Error(`FHIR type '${type}' in base package '${this.corePackage.id}@${this.corePackage.version}' does not have a snapshot`);
}
elements = migrateElements(definition.snapshot.element, definition.url);
this.elementCache.set(type, elements);
return elements;
}
/**
* Get the structure of a contentReference element.
* @param identifier The identifier of the contentReference (e.g., "#Observation.referenceRange").
*/
async getContentReference(identifier) {
if (!identifier.startsWith("#")) {
throw new Error(`Invalid contentReference identifier '${identifier}'. Must start with '#'`);
}
const elements = this.elementCache.get(identifier);
if (elements) {
return elements;
}
const elementId = identifier.substring(1);
const baseType = elementId.split(".")[0];
const allElements = await this.getBaseType(baseType);
const matchingElements = allElements.filter((e) => e?.id === elementId || String(e?.id).startsWith(elementId + "."));
if (matchingElements.length === 0) {
throw new Error(`No matching elements found for contentReference '${identifier}'`);
}
this.elementCache.set(identifier, matchingElements);
return matchingElements;
}
/**
* When a profile references a type using a URL, the target may be either a profile or a base type.
* This method resolves the URL, and if it is a base type (derivation=specialization), returns its snapshot.
* If it is a profile, it returns the snapshot of the profile using the injected snapshotFetcher().
* The snapshotFetcher is expected to return a pre-generated snapshot from the cache or generate a new one.
* @param url Canonical URL of the type or profile.
* @returns The snapshot elements of the resolved type or profile.
*/
async getByUrl(url) {
const elements = this.elementCache.get(url);
if (elements) {
return elements;
}
const metadata = await this.fpe.resolve({ resourceType: "StructureDefinition", url, package: this.sourcePackage });
if (!metadata) {
throw new Error(`StructureDefinition '${url}' not found in package '${this.sourcePackage.id}@${this.sourcePackage.version}'`);
}
if (metadata.derivation === "specialization") {
const sd = await this.fpe.resolve({ filename: metadata.filename, package: { id: metadata.__packageId, version: metadata.__packageVersion } });
const elements2 = migrateElements(sd.snapshot?.element, url);
if (!elements2 || elements2.length === 0) {
throw new Error(`StructureDefinition '${url}' does not have a snapshot`);
}
this.elementCache.set(url, elements2);
return elements2;
}
if (metadata?.derivation === "constraint") {
const elements2 = migrateElements(await this.snapshotFetcher(url), url);
if (!elements2 || elements2.length === 0) {
throw new Error(`Profile '${url}' does not have a snapshot`);
}
this.elementCache.set(url, elements2);
return elements2;
}
throw new Error(`StructureDefinition '${url}' is neither a base type nor a profile`);
}
};
// src/utils/misc/initCap.ts
var initCap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
// package.json
var version = "1.7.0";
// src/utils/misc/getVersionedCacheDir.ts
var versionedCacheDir = `v${version.split(".").slice(0, 2).join(".")}.x`;
// src/utils/terminology/flattenCodeSystemConcepts.ts
function flattenCodeSystemConcepts(cs) {
const map = /* @__PURE__ */ new Map();
const walk = (concepts) => {
if (!Array.isArray(concepts)) return;
for (const c of concepts) {
if (c && typeof c === "object" && typeof c.code === "string") {
if (!map.has(c.code)) map.set(c.code, c.display);
}
if (Array.isArray(c?.concept)) walk(c.concept);
}
};
if (Array.isArray(cs?.concept)) walk(cs.concept);
return map;
}
// src/utils/terminology/systemMapHelpers.ts
function toSystemCodeMapFromContains(contains) {
const out = /* @__PURE__ */ new Map();
if (!Array.isArray(contains)) return out;
for (const item of contains) {
if (!item || typeof item !== "object") continue;
const system = item.system;
const code = item.code;
if (!system || !code) continue;
if (!out.has(system)) out.set(system, /* @__PURE__ */ new Map());
const m = out.get(system);
if (!m.has(code)) m.set(code, item.display);
}
return out;
}
function mergeSystemMaps(target, source) {
for (const [system, codes] of source.entries()) {
if (!target.has(system)) target.set(system, /* @__PURE__ */ new Map());
const t = target.get(system);
for (const [code, display] of codes.entries()) {
if (!t.has(code)) t.set(code, display);
}
}
}
function subtractSystemMaps(target, exclude) {
for (const [system, codes] of exclude.entries()) {
const t = target.get(system);
if (!t) continue;
for (const code of codes.keys()) {
t.delete(code);
}
}
}
function buildExpansionFromSystemMap(map) {
const contains = [];
for (const [system, codes] of map.entries()) {
for (const [code, display] of codes.entries()) {
const concept = { system, code };
if (display !== void 0) {
concept.display = display;
}
contains.push(concept);
}
}
return { contains, total: contains.length };
}
// src/utils/terminology/data/iso-3166-1-codes.json
var iso_3166_1_codes_default = {
AF: "Afghanistan",
AX: "\xC5land Islands",
AL: "Albania",
DZ: "Algeria",
AS: "American Samoa",
AD: "Andorra",
AO: "Angola",
AI: "Anguilla",
AQ: "Antarctica",
AG: "Antigua and Barbuda",
AR: "Argentina",
AM: "Armenia",
AW: "Aruba",
AU: "Australia",
AT: "Austria",
AZ: "Azerbaijan",
BS: "Bahamas",
BH: "Bahrain",
BD: "Bangladesh",
BB: "Barbados",
BY: "Belarus",
BE: "Belgium",
BZ: "Belize",
BJ: "Benin",
BM: "Bermuda",
BT: "Bhutan",
BO: "Bolivia (Plurinational State of)",
BQ: "Bonaire, Sint Eustatius and Saba",
BA: "Bosnia and Herzegovina",
BW: "Botswana",
BV: "Bouvet Island",
BR: "Brazil",
IO: "British Indian Ocean Territory",
BN: "Brunei Darussalam",
BG: "Bulgaria",
BF: "Burkina Faso",
BI: "Burundi",
CV: "Cabo Verde",
KH: "Cambodia",
CM: "Cameroon",
CA: "Canada",
KY: "Cayman Islands",
CF: "Central African Republic",
TD: "Chad",
CL: "Chile",
CN: "China",
CX: "Christmas Island",
CC: "Cocos (Keeling) Islands",
CO: "Colombia",
KM: "Comoros",
CG: "Congo",
CD: "Congo, Democratic Republic of the",
CK: "Cook Islands",
CR: "Costa Rica",
CI: "C\xF4te d'Ivoire",
HR: "Croatia",
CU: "Cuba",
CW: "Cura\xE7ao",
CY: "Cyprus",
CZ: "Czechia",
DK: "Denmark",
DJ: "Djibouti",
DM: "Dominica",
DO: "Dominican Republic",
EC: "Ecuador",
EG: "Egypt",
SV: "El Salvador",
GQ: "Equatorial Guinea",
ER: "Eritrea",
EE: "Estonia",
SZ: "Eswatini",
ET: "Ethiopia",
FK: "Falkland Islands (Malvinas)",
FO: "Faroe Islands",
FJ: "Fiji",
FI: "Finland",
FR: "France",
GF: "French Guiana",
PF: "French Polynesia",
TF: "French Southern Territories",
GA: "Gabon",
GM: "Gambia",
GE: "Georgia",
DE: "Germany",
GH: "Ghana",
GI: "Gibraltar",
GR: "Greece",
GL: "Greenland",
GD: "Grenada",
GP: "Guadeloupe",
GU: "Guam",
GT: "Guatemala",
GG: "Guernsey",
GN: "Guinea",
GW: "Guinea-Bissau",
GY: "Guyana",
HT: "Haiti",
HM: "Heard Island and McDonald Islands",
VA: "Holy See",
HN: "Honduras",
HK: "Hong Kong",
HU: "Hungary",
IS: "Iceland",
IN: "India",
ID: "Indonesia",
IR: "Iran (Islamic Republic of)",
IQ: "Iraq",
IE: "Ireland",
IM: "Isle of Man",
IL: "Israel",
IT: "Italy",
JM: "Jamaica",
JP: "Japan",
JE: "Jersey",
JO: "Jordan",
KZ: "Kazakhstan",
KE: "Kenya",
KI: "Kiribati",
KP: "Korea (Democratic People's Republic of)",
KR: "Korea, Republic of",
KW: "Kuwait",
KG: "Kyrgyzstan",
LA: "Lao People's Democratic Republic",
LV: "Latvia",
LB: "Lebanon",
LS: "Lesotho",
LR: "Liberia",
LY: "Libya",
LI: "Liechtenstein",
LT: "Lithuania",
LU: "Luxembourg",
MO: "Macao",
MG: "Madagascar",
MW: "Malawi",
MY: "Malaysia",
MV: "Maldives",
ML: "Mali",
MT: "Malta",
MH: "Marshall Islands",
MQ: "Martinique",
MR: "Mauritania",
MU: "Mauritius",
YT: "Mayotte",
MX: "Mexico",
FM: "Micronesia (Federated States of)",
MD: "Moldova, Republic of",
MC: "Monaco",
MN: "Mongolia",
ME: "Montenegro",
MS: "Montserrat",
MA: "Morocco",
MZ: "Mozambique",
MM: "Myanmar",
NA: "Namibia",
NR: "Nauru",
NP: "Nepal",
NL: "Netherlands",
NC: "New Caledonia",
NZ: "New Zealand",
NI: "Nicaragua",
NE: "Niger",
NG: "Nigeria",
NU: "Niue",
NF: "Norfolk Island",
MK: "North Macedonia",
MP: "Northern Mariana Islands",
NO: "Norway",
OM: "Oman",
PK: "Pakistan",
PW: "Palau",
PS: "Palestine, State of",
PA: "Panama",
PG: "Papua New Guinea",
PY: "Paraguay",
PE: "Peru",
PH: "Philippines",
PN: "Pitcairn",
PL: "Poland",
PT: "Portugal",
PR: "Puerto Rico",
QA: "Qatar",
RE: "R\xE9union",
RO: "Romania",
RU: "Russian Federation",
RW: "Rwanda",
BL: "Saint Barth\xE9lemy",
SH: "Saint Helena, Ascension and Tristan da Cunha",
KN: "Saint Kitts and Nevis",
LC: "Saint Lucia",
MF: "Saint Martin (French part)",
PM: "Saint Pierre and Miquelon",
VC: "Saint Vincent and the Grenadines",
WS: "Samoa",
SM: "San Marino",
ST: "Sao Tome and Principe",
SA: "Saudi Arabia",
SN: "Senegal",
RS: "Serbia",
SC: "Seychelles",
SL: "Sierra Leone",
SG: "Singapore",
SX: "Sint Maarten (Dutch part)",
SK: "Slovakia",
SI: "Slovenia",
SB: "Solomon Islands",
SO: "Somalia",
ZA: "South Africa",
GS: "South Georgia and the South Sandwich Islands",
SS: "South Sudan",
ES: "Spain",
LK: "Sri Lanka",
SD: "Sudan",
SR: "Suriname",
SJ: "Svalbard and Jan Mayen",
SE: "Sweden",
CH: "Switzerland",
SY: "Syrian Arab Republic",
TW: "Taiwan, Province of China",
TJ: "Tajikistan",
TZ: "Tanzania, United Republic of",
TH: "Thailand",
TL: "Timor-Leste",
TG: "Togo",
TK: "Tokelau",
TO: "Tonga",
TT: "Trinidad and Tobago",
TN: "Tunisia",
TR: "Turkey",
TM: "Turkmenistan",
TC: "Turks and Caicos Islands",
TV: "Tuvalu",
UG: "Uganda",
UA: "Ukraine",
AE: "United Arab Emirates",
GB: "United Kingdom of Great Britain and Northern Ireland",
US: "United States of America",
UM: "United States Minor Outlying Islands",
UY: "Uruguay",
UZ: "Uzbekistan",
VU: "Vanuatu",
VE: "Venezuela (Bolivarian Republic of)",
VN: "Viet Nam",
VG: "Virgin Islands (British)",
VI: "Virgin Islands (U.S.)",
WF: "Wallis and Futuna",
EH: "Western Sahara",
YE: "Yemen",
ZM: "Zambia",
ZW: "Zimbabwe",
AFG: "Afghanistan",
ALA: "\xC5land Islands",
ALB: "Albania",
DZA: "Algeria",
ASM: "American Samoa",
AND: "Andorra",
AGO: "Angola",
AIA: "Anguilla",
ATA: "Antarctica",
ATG: "Antigua and Barbuda",
ARG: "Argentina",
ARM: "Armenia",
ABW: "Aruba",
AUS: "Australia",
AUT: "Austria",
AZE: "Azerbaijan",
BHS: "Bahamas",
BHR: "Bahrain",
BGD: "Bangladesh",
BRB: "Barbados",
BLR: "Belarus",
BEL: "Belgium",
BLZ: "Belize",
BEN: "Benin",
BMU: "Bermuda",
BTN: "Bhutan",
BOL: "Bolivia (Plurinational State of)",
BES: "Bonaire, Sint Eustatius and Saba",
BIH: "Bosnia and Herzegovina",
BWA: "Botswana",
BVT: "Bouvet Island",
BRA: "Brazil",
IOT: "British Indian Ocean Territory",
BRN: "Brunei Darussalam",
BGR: "Bulgaria",
BFA: "Burkina Faso",
BDI: "Burundi",
CPV: "Cabo Verde",
KHM: "Cambodia",
CMR: "Cameroon",
CAN: "Canada",
CYM: "Cayman Islands",
CAF: "Central African Republic",
TCD: "Chad",
CHL: "Chile",
CHN: "China",
CXR: "Christmas Island",
CCK: "Cocos (Keeling) Islands",
COL: "Colombia",
COM: "Comoros",
COG: "Congo",
COD: "Congo, Democratic Republic of the",
COK: "Cook Islands",
CRI: "Costa Rica",
CIV: "C\xF4te d'Ivoire",
HRV: "Croatia",
CUB: "Cuba",
CUW: "Cura\xE7ao",
CYP: "Cyprus",
CZE: "Czechia",
DNK: "Denmark",
DJI: "Djibouti",
DMA: "Dominica",
DOM: "Dominican Republic",
ECU: "Ecuador",
EGY: "Egypt",
SLV: "El Salvador",
GNQ: "Equatorial Guinea",
ERI: "Eritrea",
EST: "Estonia",
SWZ: "Eswatini",
ETH: "Ethiopia",
FLK: "Falkland Islands (Malvinas)",
FRO: "Faroe Islands",
FJI: "Fiji",
FIN: "Finland",
FRA: "France",
GUF: "French Guiana",
PYF: "French Polynesia",
ATF: "French Southern Territories",
GAB: "Gabon",
GMB: "Gambia",
GEO: "Georgia",
DEU: "Germany",
GHA: "Ghana",
GIB: "Gibraltar",
GRC: "Greece",
GRL: "Greenland",
GRD: "Grenada",
GLP: "Guadeloupe",
GUM: "Guam",
GTM: "Guatemala",
GGY: "Guernsey",
GIN: "Guinea",
GNB: "Guinea-Bissau",
GUY: "Guyana",
HTI: "Haiti",
HMD: "Heard Island and McDonald Islands",
VAT: "Holy See",
HND: "Honduras",
HKG: "Hong Kong",
HUN: "Hungary",
ISL: "Iceland",
IND: "India",
IDN: "Indonesia",
IRN: "Iran (Islamic Republic of)",
IRQ: "Iraq",
IRL: "Ireland",
IMN: "Isle of Man",
ISR: "Israel",
ITA: "Italy",
JAM: "Jamaica",
JPN: "Japan",
JEY: "Jersey",
JOR: "Jordan",
KAZ: "Kazakhstan",
KEN: "Kenya",
KIR: "Kiribati",
PRK: "Korea (Democratic People's Republic of)",
KOR: "Korea, Republic of",
KWT: "Kuwait",
KGZ: "Kyrgyzstan",
LAO: "Lao People's Democratic Republic",
LVA: "Latvia",
LBN: "Lebanon",
LSO: "Lesotho",
LBR: "Liberia",
LBY: "Libya",
LIE: "Liechtenstein",
LTU: "Lithuania",
LUX: "Luxembourg",
MAC: "Macao",
MDG: "Madagascar",
MWI: "Malawi",
MYS: "Malaysia",
MDV: "Maldives",
MLI: "Mali",
MLT: "Malta",
MHL: "Marshall Islands",
MTQ: "Martinique",
MRT: "Mauritania",
MUS: "Mauritius",
MYT: "Mayotte",
MEX: "Mexico",
FSM: "Micronesia (Federated States of)",
MDA: "Moldova, Republic of",
MCO: "Monaco",
MNG: "Mongolia",
MNE: "Montenegro",
MSR: "Montserrat",
MAR: "Morocco",
MOZ: "Mozambique",
MMR: "Myanmar",
NAM: "Namibia",
NRU: "Nauru",
NPL: "Nepal",
NLD: "Netherlands",
NCL: "New Caledonia",
NZL: "New Zealand",
NIC: "Nicaragua",
NER: "Niger",
NGA: "Nigeria",
NIU: "Niue",
NFK: "Norfolk Island",
MKD: "North Macedonia",
MNP: "Northern Mariana Islands",
NOR: "Norway",
OMN: "Oman",
PAK: "Pakistan",
PLW: "Palau",
PSE: "Palestine, State of",
PAN: "Panama",
PNG: "Papua New Guinea",
PRY: "Paraguay",
PER: "Peru",
PHL: "Philippines",
PCN: "Pitcairn",
POL: "Poland",
PRT: "Portugal",
PRI: "Puerto Rico",
QAT: "Qatar",
REU: "R\xE9union",
ROU: "Romania",
RUS: "Russian Federation",
RWA: "Rwanda",
BLM: "Saint Barth\xE9lemy",
SHN: "Saint Helena, Ascension and Tristan da Cunha",
KNA: "Saint Kitts and Nevis",
LCA: "Saint Lucia",
MAF: "Saint Martin (French part)",
SPM: "Saint Pierre and Miquelon",
VCT: "Saint Vincent and the Grenadines",
WSM: "Samoa",
SMR: "San Marino",
STP: "Sao Tome and Principe",
SAU: "Saudi Arabia",
SEN: "Senegal",
SRB: "Serbia",
SYC: "Seychelles",
SLE: "Sierra Leone",
SGP: "Singapore",
SXM: "Sint Maarten (Dutch part)",
SVK: "Slovakia",
SVN: "Slovenia",
SLB: "Solomon Islands",
SOM: "Somalia",
ZAF: "South Africa",
SGS: "South Georgia and the South Sandwich Islands",
SSD: "South Sudan",
ESP: "Spain",
LKA: "Sri Lanka",
SDN: "Sudan",
SUR: "Suriname",
SJM: "Svalbard and Jan Mayen",
SWE: "Sweden",
CHE: "Switzerland",
SYR: "Syrian Arab Republic",
TWN: "Taiwan, Province of China",
TJK: "Tajikistan",
TZA: "Tanzania, United Republic of",
THA: "Thailand",
TLS: "Timor-Leste",
TGO: "Togo",
TKL: "Tokelau",
TON: "Tonga",
TTO: "Trinidad and Tobago",
TUN: "Tunisia",
TUR: "Turkey",
TKM: "Turkmenistan",
TCA: "Turks and Caicos Islands",
TUV: "Tuvalu",
UGA: "Uganda",
UKR: "Ukraine",
ARE: "United Arab Emirates",
GBR: "United Kingdom of Great Britain and Northern Ireland",
USA: "United States of America",
UMI: "United States Minor Outlying Islands",
URY: "Uruguay",
UZB: "Uzbekistan",
VUT: "Vanuatu",
VEN: "Venezuela (Bolivarian Republic of)",
VNM: "Viet Nam",
VGB: "Virgin Islands (British)",
VIR: "Virgin Islands (U.S.)",
WLF: "Wallis and Futuna",
ESH: "Western Sahara",
YEM: "Yemen",
ZMB: "Zambia",
ZWE: "Zimbabwe"
};
// src/utils/terminology/data/bcp-47-language-codes.json
var bcp_47_language_codes_default = {
aa: "Afar",
ab: "Abkhazian",
ae: "Avestan",
af: "Afrikaans",
ak: "Akan",
am: "Amharic",
an: "Aragonese",
ar: "Arabic",
as: "Assamese",
av: "Avaric",
ay: "Aymara",
az: "Azerbaijani",
ba: "Bashkir",
be: "Belarusian",
bg: "Bulgarian",
bh: "Bihari languages",
bi: "Bislama",
bm: "Bambara",
bn: "Bengali",
bo: "Tibetan",
br: "Breton",
bs: "Bosnian",
ca: "Catalan",
ce: "Chechen",
ch: "Chamorro",
co: "Corsican",
cr: "Cree",
cs: "Czech",
cu: "Church Slavic",
cv: "Chuvash",
cy: "Welsh",
da: "Danish",
de: "German",
dv: "Divehi",
dz: "Dzongkha",
ee: "Ewe",
el: "Greek",
en: "English",
eo: "Esperanto",
es: "Spanish",
et: "Estonian",
eu: "Basque",
fa: "Persian",
ff: "Fulah",
fi: "Finnish",
fj: "Fijian",
fo: "Faroese",
fr: "French",
fy: "Western Frisian",
ga: "Irish",
gd: "Gaelic",
gl: "Galician",
gn: "Guarani",
gu: "Gujarati",
gv: "Manx",
ha: "Hausa",
he: "Hebrew",
hi: "Hindi",
ho: "Hiri Motu",
hr: "Croatian",
ht: "Haitian",
hu: "Hungarian",
hy: "Armenian",
hz: "Herero",
ia: "Interlingua",
id: "Indonesian",
ie: "Interlingue",
ig: "Igbo",
ii: "Sichuan Yi",
ik: "Inupiaq",
io: "Ido",
is: "Icelandic",
it: "Italian",
iu: "Inuktitut",
ja: "Japanese",
jv: "Javanese",
ka: "Georgian",
kg: "Kongo",
ki: "Kikuyu",
kj: "Kuanyama",
kk: "Kazakh",
kl: "Kalaallisut",
km: "Central Khmer",
kn: "Kannada",
ko: "Korean",
kr: "Kanuri",
ks: "Kashmiri",
ku: "Kurdish",
kv: "Komi",
kw: "Cornish",
ky: "Kirghiz",
la: "Latin",
lb: "Luxembourgish",
lg: "Ganda",
li: "Limburgan",
ln: "Lingala",
lo: "Lao",
lt: "Lithuanian",
lu: "Luba-Katanga",
lv: "Latvian",
mg: "Malagasy",
mh: "Marshallese",
mi: "Maori",
mk: "Macedonian",
ml: "Malayalam",
mn: "Mongolian",
mr: "Marathi",
ms: "Malay",
mt: "Maltese",
my: "Burmese",
na: "Nauru",
nb: "Norwegian Bokm\xE5l",
nd: "North Ndebele",
ne: "Nepali",
ng: "Ndonga",
nl: "Dutch",
nn: "Norwegian Nynorsk",
no: "Norwegian",
nr: "South Ndebele",
nv: "Navajo",
ny: "Chichewa",
oc: "Occitan",
oj: "Ojibwa",
om: "Oromo",
or: "Oriya",
os: "Ossetian",
pa: "Panjabi",
pi: "Pali",
pl: "Polish",
ps: "Pushto",
pt: "Portuguese",
qu: "Quechua",
rm: "Romansh",
rn: "Rundi",
ro: "Romanian",
ru: "Russian",
rw: "Kinyarwanda",
sa: "Sanskrit",
sc: "Sardinian",
sd: "Sindhi",
se: "Northern Sami",
sg: "Sango",
si: "Sinhala",
sk: "Slovak",
sl: "Slovenian",
sm: "Samoan",
sn: "Shona",
so: "Somali",
sq: "Albanian",
sr: "Serbian",
ss: "Swati",
st: "Southern Sotho",
su: "Sundanese",
sv: "Swedish",
sw: "Swahili",
ta: "Tamil",
te: "Telugu",
tg: "Tajik",
th: "Thai",
ti: "Tigrinya",
tk: "Turkmen",
tl: "Tagalog",
tn: "Tswana",
to: "Tonga",
tr: "Turkish",
ts: "Tsonga",
tt: "Tatar",
tw: "Twi",
ty: "Tahitian",
ug: "Uighur",
uk: "Ukrainian",
ur: "Urdu",
uz: "Uzbek",
ve: "Venda",
vi: "Vietnamese",
vo: "Volap\xFCk",
wa: "Walloon",
wo: "Wolof",
xh: "Xhosa",
yi: "Yiddish",
yo: "Yoruba",
za: "Zhuang",
zh: "Chinese",
zu: "Zulu",
"en-AU": "English (Australia)",
"en-CA": "English (Canada)",
"en-GB": "English (United Kingdom)",
"en-IE": "English (Ireland)",
"en-IN": "English (India)",
"en-NZ": "English (New Zealand)",
"en-SG": "English (Singapore)",
"en-US": "English (United States)",
"en-ZA": "English (South Africa)",
"es-AR": "Spanish (Argentina)",
"es-BO": "Spanish (Bolivia)",
"es-CL": "Spanish (Chile)",
"es-CO": "Spanish (Colombia)",
"es-CR": "Spanish (Costa Rica)",
"es-CU": "Spanish (Cuba)",
"es-DO": "Spanish (Dominican Republic)",
"es-EC": "Spanish (Ecuador)",
"es-ES": "Spanish (Spain)",
"es-GT": "Spanish (Guatemala)",
"es-HN": "Spanish (Honduras)",
"es-MX": "Spanish (Mexico)",
"es-NI": "Spanish (Nicaragua)",
"es-PA": "Spanish (Panama)",
"es-PE": "Spanish (Peru)",
"es-PR": "Spanish (Puerto Rico)",
"es-PY": "Spanish (Paraguay)",
"es-SV": "Spanish (El Salvador)",
"es-UY": "Spanish (Uruguay)",
"es-VE": "Spanish (Venezuela)",
"fr-BE": "French (Belgium)",
"fr-CA": "French (Canada)",
"fr-CH": "French (Switzerland)",
"fr-FR": "French (France)",
"fr-LU": "French (Luxembourg)",
"fr-MC": "French (Monaco)",
"de-AT": "German (Austria)",
"de-CH": "German (Switzerland)",
"de-DE": "German (Germany)",
"de-LI": "German (Liechtenstein)",
"de-LU": "German (Luxembourg)",
"it-CH": "Italian (Switzerland)",
"it-IT": "Italian (Italy)",
"pt-BR": "Portuguese (Brazil)",
"pt-PT": "Portuguese (Portugal)",
"zh-CN": "Chinese (China)",
"zh-HK": "Chinese (Hong Kong SAR China)",
"zh-MO": "Chinese (Macao SAR China)",
"zh-SG": "Chinese (Singapore)",
"zh-TW": "Chinese (Taiwan)",
"ar-AE": "Arabic (United Arab Emirates)",
"ar-BH": "Arabic (Bahrain)",
"ar-DZ": "Arabic (Algeria)",
"ar-EG": "Arabic (Egypt)",
"ar-IQ": "Arabic (Iraq)",
"ar-JO": "Arabic (Jordan)",
"ar-KW": "Arabic (Kuwait)",
"ar-LB": "Arabic (Lebanon)",
"ar-LY": "Arabic (Libya)",
"ar-MA": "Arabic (Morocco)",
"ar-OM": "Arabic (Oman)",
"ar-QA": "Arabic (Qatar)",
"ar-SA": "Arabic (Saudi Arabia)",
"ar-SY": "Arabic (Syria)",
"ar-TN": "Arabic (Tunisia)",
"ar-YE": "Arabic (Yemen)",
"ru-BY": "Russian (Belarus)",
"ru-KG": "Russian (Kyrgyzstan)",
"ru-KZ": "Russian (Kazakhstan)",
"ru-MD": "Russian (Moldova)",
"ru-RU": "Russian (Russia)",
"ru-UA": "Russian (Ukraine)",
"hi-IN": "Hindi (India)",
"ja-JP": "Japanese (Japan)",
"ko-KR": "Korean (South Korea)",
"ko-KP": "Korean (North Korea)",
"sv-FI": "Swedish (Finland)",
"sv-SE": "Swedish (Sweden)",
"da-DK": "Danish (Denmark)",
"da-GL": "Danish (Greenland)",
"no-NO": "Norwegian (Norway)",
"nb-NO": "Norwegian Bokm\xE5l (Norway)",
"nn-NO": "Norwegian Nynorsk (Norway)",
"fi-FI": "Finnish (Finland)",
"is-IS": "Icelandic (Iceland)",
"et-EE": "Estonian (Estonia)",
"lv-LV": "Latvian (Latvia)",
"lt-LT": "Lithuanian (Lithuania)",
"pl-PL": "Polish (Poland)",
"cs-CZ": "Czech (Czech Republic)",
"sk-SK": "Slovak (Slovakia)",
"hu-HU": "Hungarian (Hungary)",
"ro-RO": "Romanian (Romania)",
"bg-BG": "Bulgarian (Bulgaria)",
"hr-HR": "Croatian (Croatia)",
"sr-RS": "Serbian (Serbia)",
"bs-BA": "Bosnian (Bosnia and Herzegovina)",
"mk-MK": "Macedonian (Macedonia)",
"sl-SI": "Slovenian (Slovenia)",
"sq-AL": "Albanian (Albania)",
"el-GR": "Greek (Greece)",
"tr-TR": "Turkish (Turkey)",
"he-IL": "Hebrew (Israel)",
"fa-IR": "Persian (Iran)",
"ur-PK": "Urdu (Pakistan)",
"bn-BD": "Bengali (Bangladesh)",
"bn-IN": "Bengali (India)",
"th-TH": "Thai (Thailand)",
"vi-VN": "Vietnamese (Vietnam)",
"ms-MY": "Malay (Malaysia)",
"id-ID": "Indonesian (Indonesia)",
"tl-PH": "Tagalog (Philippines)",
"sw-KE": "Swahili (Kenya)",
"sw-TZ": "Swahili (Tanzania)",
"am-ET": "Amharic (Ethiopia)",
"yo-NG": "Yoruba (Nigeria)",
"ig-NG": "Igbo (Nigeria)",
"ha-NG": "Hausa (Nigeria)",
"af-ZA": "Afrikaans (South Africa)",
"zu-ZA": "Zulu (South Africa)",
"xh-ZA": "Xhosa (South Africa)"
};
// src/utils/terminology/implicitCodeSystems.ts
var Iso3166CountryCodesProvider = class {
constructor() {
this.canonicalUrl = "urn:iso:std:iso:3166";
}
getConcepts() {
if (!this.conceptsCache) {
this.conceptsCache = /* @__PURE__ */ new Map();
for (const [code, name] of Object.entries(iso_3166_1_codes_default)) {
this.conceptsCache.set(code, name);
}
}
return this.conceptsCache;
}
};
var Bcp47LanguageCodesProvider = class {
constructor() {
this.canonicalUrl = "urn:ietf:bcp:47";
}
getConcepts() {
if (!this.conceptsCache) {
this.conceptsCache = /* @__PURE__ */ new Map();
for (const [code, display] of Object.entries(bcp_47_language_codes_default)) {
const normalizedCode = this.normalizeBcp47Code(code);
this.conceptsCache.set(normalizedCode, display);
if (normalizedCode !== code) {
this.conceptsCache.set(code, display);
}
if (code.includes("-")) {
const underscoreVariant = code.replace(/-/g, "_");
this.conceptsCache.set(underscoreVariant, display);
}
}
}
return this.conceptsCache;
}
normalizeBcp47Code(code) {
if (!code.includes("-")) {
return code.toLowerCase();
}
const parts = code.split("-");
const language = parts[0].toLowerCase();
const region = parts[1].toUpperCase();
return `${language}-${region}`;
}
};
var ImplicitCodeSystemRegistry = class {
static {
this.providers = /* @__PURE__ */ new Map([
["urn:iso:std:iso:3166", new Iso3166CountryCodesProvider()],
["urn:ietf:bcp:47", new Bcp47LanguageCodesProvider()]
]);
}
/**
* Check if a canonical URL corresponds to an implicit code system
*/
static isImplicitCodeSystem(canonicalUrl) {
return this.providers.has(canonicalUrl);
}
/**
* Get the provider for an implicit code system
*/
static getProvider(canonicalUrl) {
return this.providers.get(canonicalUrl);
}
/**
* Get all concepts for an implicit code system
*/
static getConcepts(canonicalUrl) {
const provider = this.getProvider(canonicalUrl);
return provider?.getConcepts();
}
/**
* Get all supported implicit code system URLs
*/
static getSupportedSystems() {
return Array.from(this.providers.keys());
}
};
var FhirSnapshotGenerator = class _FhirSnapshotGenerator {
// cache for resolved base packages
constructor(fpe, cacheMode, fhirVersion, logger) {
this.resolvedBasePackages = /* @__PURE__ */ new Map();
if (logger) {
this.logger = logger;
this.prethrow = customPrethrower(this.logger);
} else {
this.logger = defaultLogger;
this.prethrow = defaultPrethrow;
}
this.cacheMode = cacheMode;
this.fhirVersion = fhirVersion;
this.fhirCorePackage = resolveFhirVersion(fhirVersion, true);
this.fpe = fpe;
this.cachePath = fpe.getCachePath();
}
/**
* Creates a new instance of the FhirSnapshotGenerator class.
* @param config - the configuration object for the FhirPackageExplorer
* @returns - a promise that resolves to a new instance of the FhirSnapshotGenerator class
*/
static async create(config) {
const logger = config.logger || defaultLogger;
const prethrow = config.logger ? customPrethrower(logger) : defaultPrethrow;
try {
const cacheMode = config.cacheMode || "lazy";
const fhirVersion = resolveFhirVersion(config.fhirVersion || "4.0.1");
const fpeConfig = { ...config, skipExamples: true };
delete fpeCo