@graphty/graph-io 0.3.15 → 0.3.17
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/chunks/{escape-D1f9-cwf.js → escape-scjHxjpr.js} +2 -2
- package/dist/chunks/{escape-D1f9-cwf.js.map → escape-scjHxjpr.js.map} +1 -1
- package/dist/chunks/{importer-C7mnGdr_.js → importer-B6rKRxzv.js} +3 -3
- package/dist/chunks/importer-B6rKRxzv.js.map +1 -0
- package/dist/chunks/{importer-B8lsjFWx.js → importer-BmOl9gLW.js} +3 -3
- package/dist/chunks/{importer-B8lsjFWx.js.map → importer-BmOl9gLW.js.map} +1 -1
- package/dist/chunks/{importer-D7ZcGCeb.js → importer-Xg07gk7p.js} +3 -3
- package/dist/chunks/{importer-D7ZcGCeb.js.map → importer-Xg07gk7p.js.map} +1 -1
- package/dist/chunks/{importer-CXEiicAN.js → importer-ruMWWvVs.js} +3 -3
- package/dist/chunks/{importer-CXEiicAN.js.map → importer-ruMWWvVs.js.map} +1 -1
- package/dist/chunks/{records-IHsCfv7s.js → records-DSpbTE5s.js} +2 -2
- package/dist/chunks/{records-IHsCfv7s.js.map → records-DSpbTE5s.js.map} +1 -1
- package/dist/chunks/{writer-BtWpUaiH.js → writer-DHHfHn11.js} +206 -115
- package/dist/chunks/writer-DHHfHn11.js.map +1 -0
- package/dist/csv.js +3 -3
- package/dist/dot.js +1 -1
- package/dist/gexf.js +2 -2
- package/dist/gml.js +2 -2
- package/dist/graph-io.js +141 -103
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +1 -1
- package/dist/json.js +1 -1
- package/dist/neo4j.js +3 -3
- package/dist/pajek.js +1 -1
- package/dist/src/common/codes.d.ts +43 -0
- package/dist/src/common/codes.d.ts.map +1 -1
- package/dist/src/common/codes.js +43 -0
- package/dist/src/common/codes.js.map +1 -1
- package/dist/src/common/input.d.ts +9 -0
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +16 -0
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/options.d.ts +12 -1
- package/dist/src/common/options.d.ts.map +1 -1
- package/dist/src/common/options.js +51 -1
- package/dist/src/common/options.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +2 -2
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/index.d.ts +4 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts +21 -3
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +29 -0
- package/dist/src/registry.js.map +1 -1
- package/dist/src/types.d.ts +31 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/package.json +2 -2
- package/src/common/codes.ts +58 -0
- package/src/common/input.ts +16 -0
- package/src/common/options.ts +78 -2
- package/src/formats/json/importer.ts +2 -1
- package/src/index.ts +5 -0
- package/src/registry.ts +35 -2
- package/src/types.ts +40 -1
- package/dist/chunks/importer-C7mnGdr_.js.map +0 -1
- package/dist/chunks/writer-BtWpUaiH.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"importer-CXEiicAN.js","sources":["../../src/formats/graphml/constants.ts","../../src/formats/graphml/tree.ts","../../src/formats/graphml/yfiles.ts","../../src/formats/graphml/exporter.ts","../../src/formats/graphml/importer.ts"],"sourcesContent":["/**\n * What the GraphML importer and exporter share: the namespace, the format facts, the reserved\n * column names of the XML-attribute-derived columns (design section 5.6), the `meta.extra`\n * keys the importer records for the exporter, and the issue and loss codes.\n */\n\nimport {\n BAD_DEFAULT_CODE,\n COLUMN_RENAMED_CODE,\n COUNT_HINT_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_KEY_CODE,\n DUPLICATE_NODE_CODE,\n ENCODING_FALLBACK_CODE,\n HYPEREDGE_CODE,\n ID_MERGED_CODE,\n ID_TEXT_TYPE_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MIXED_DIRECTION_CODE,\n MULTIPLE_GRAPHS_CODE,\n MUTUAL_AS_UNDIRECTED_CODE,\n NO_GRAPH_CODE,\n OPTION_IGNORED_CODE,\n PARENTS_DROPPED_CODE,\n PRECISION_CODE,\n ROLE_DROPPED_CODE,\n ROLE_TAKEN_CODE,\n SINK_OPTION_CODE,\n STRAY_TEXT_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ELEMENT_CODE,\n UNKNOWN_ENCODING_CODE,\n XML_SYNTAX_CODE,\n} from \"../../common/codes.js\";\n\n/** The GraphML namespace. */\nexport const GRAPHML_NAMESPACE = \"http://graphml.graphdrawing.org/xmlns\";\n\n/** The yFiles extension namespace, declared as `xmlns:y` when a yfiles column is written. */\nexport const YFILES_NAMESPACE = \"http://www.yworks.com/xml/graphml\";\n\n/** The XML Schema instance namespace and the schema location the exporter writes. */\nexport const XSI_NAMESPACE = \"http://www.w3.org/2001/XMLSchema-instance\";\n\n/** The GraphML schema location written by the exporter. */\nexport const SCHEMA_LOCATION =\n \"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\";\n\n/** The format name. */\nexport const FORMAT = \"graphml\";\n\n/** File extensions. */\nexport const EXTENSIONS: readonly string[] = Object.freeze([\".graphml\", \".xml\"]);\n\n/** MIME types. */\nexport const MIME_TYPES: readonly string[] = Object.freeze([\"application/graphml+xml\", \"application/xml\", \"text/xml\"]);\n\n/** The `attr.name` of the node key that carries ids rewritten by `sanitizeIds: \"mangle\"` (design section 8.5). */\nexport const ORIGINAL_ID_ATTRIBUTE = \"graphty:originalId\";\n\n/** The node column that keeps original ids when `restoreMangledIds` is off (design section 5.6). */\nexport const ORIGINAL_ID_COLUMN = \"graphty.originalId\";\n\n/** The edge column of the `id` XML attribute (role id, unique). */\nexport const EDGE_ID_COLUMN = \"id\";\n\n/** The edge columns of the `sourceport` / `targetport` XML attributes (roles sourcePort / targetPort). */\nexport const SOURCE_PORT_COLUMN = \"sourceport\";\n\n/** The edge column of the `targetport` XML attribute. */\nexport const TARGET_PORT_COLUMN = \"targetport\";\n\n/** The node column of the containing node of a nested graph (u32, role parent, refersTo node). */\nexport const PARENT_COLUMN = \"parent\";\n\n/** The bool node column marking the hub nodes synthesised for hyperedges under `hyperedges: \"star\"`. */\nexport const HYPEREDGE_HUB_COLUMN = \"graphty.hyperedge\";\n\n/** The column name a node key titled `label` receives the `label` role under. */\nexport const LABEL_COLUMN = \"label\";\n\n/** Edge column names reserved for the XML-attribute-derived columns; a key titled like one is renamed `<name>#<id>`. */\nexport const RESERVED_EDGE_NAMES: ReadonlySet<string> = new Set([\n EDGE_ID_COLUMN,\n SOURCE_PORT_COLUMN,\n TARGET_PORT_COLUMN,\n]);\n\n/** Node column names reserved for the XML-derived columns. */\nexport const RESERVED_NODE_NAMES: ReadonlySet<string> = new Set([PARENT_COLUMN]);\n\n/** The `meta.extra` key under which the importer records what the exporter needs. */\nexport const META_KEY = \"graphml\";\n\n/** What the importer stores under `meta.extra.graphml`. */\nexport interface GraphmlMeta {\n /** The top-level `<graph id>`, or null. */\n readonly graphId: string | null;\n /** The top-level `edgedefault` as written, so a mixed file re-exports with the same layout. */\n readonly edgedefault: \"directed\" | \"undirected\" | null;\n /** The `xmlns:<prefix>` declarations of the root element (yFiles and the like). */\n readonly namespaces: Readonly<Record<string, string>>;\n}\n\n/**\n * The issue codes the GraphML importer records (design section 8.6), by name: the codes shared\n * with the other importers (src/common/codes.ts) and the GraphML-specific ones. A key is the code\n * without its severity and format prefixes.\n */\nexport const GRAPHML_ISSUE = Object.freeze({\n /** Fatal: the input is not well-formed XML. */\n XML_SYNTAX: XML_SYNTAX_CODE,\n /** Fatal: the input holds invalid UTF-8. */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM, a declaration or the encoding option chose (fatal). */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** Fatal: the root element is not `<graphml>`. */\n NOT_GRAPHML: \"E_NOT_GRAPHML\",\n /** Fatal: the document has no `<graph>`. */\n NO_GRAPH: NO_GRAPH_CODE,\n /** A `<key>` without an id. */\n KEY_MISSING_ID: \"E_GRAPHML_KEY_MISSING_ID\",\n /** Two `<key>` elements with the same id. */\n DUPLICATE_KEY: DUPLICATE_KEY_CODE,\n /** A key declared for hyperedges, ports or endpoints (never used). */\n KEY_DOMAIN_UNSUPPORTED: \"W_GRAPHML_KEY_DOMAIN_UNSUPPORTED\",\n /** A `<node>` without an id. */\n MISSING_ID: MISSING_ID_CODE,\n /** An `<edge>` without a source or a target. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A `<data>` whose key was never declared. */\n UNKNOWN_KEY: \"E_GRAPHML_UNKNOWN_KEY\",\n /** A `<data>` whose key is declared for another domain. */\n KEY_DOMAIN: \"W_GRAPHML_KEY_DOMAIN\",\n /** A `<data>` without a key attribute. */\n DATA_MISSING_KEY: \"E_GRAPHML_DATA_MISSING_KEY\",\n /** A `<key>` whose `for` is not a GraphML domain. */\n KEY_FOR_INVALID: \"E_GRAPHML_KEY_FOR_INVALID\",\n /** Data of a nested `<graph>`; only the top-level graph has attributes. */\n NESTED_GRAPH_DATA: \"W_GRAPHML_NESTED_GRAPH_DATA\",\n /** Data of a hyperedge expanded to a star or clique. */\n HYPEREDGE_DATA_DROPPED: \"W_GRAPHML_HYPEREDGE_DATA_DROPPED\",\n /** Nested elements in the `<data>` of a typed (non-yfiles) key. */\n DATA_NESTED: \"E_GRAPHML_DATA_NESTED\",\n /** A `<node>` declared twice. */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** An edge id already used by another edge. */\n DUPLICATE_EDGE_ID: DUPLICATE_EDGE_ID_CODE,\n /** A `directed` attribute that is neither true nor false. */\n INVALID_DIRECTED: \"E_GRAPHML_INVALID_DIRECTED\",\n /** An `edgedefault` that is neither directed nor undirected. */\n INVALID_EDGEDEFAULT: \"E_GRAPHML_INVALID_EDGEDEFAULT\",\n /** A `<graph>` without edgedefault; the `defaultDirected` option applies. */\n EDGEDEFAULT_MISSING: \"W_GRAPHML_EDGEDEFAULT_MISSING\",\n /** A second top-level `<graph>`; its nodes and edges are merged into the first. */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** A `parse.nodes` / `parse.edges` hint the sink cannot reserve (ignored). */\n COUNT_HINT: COUNT_HINT_CODE,\n /** A hyperedge under `hyperedges: \"error\"`. */\n HYPEREDGE: HYPEREDGE_CODE,\n /** Hyperedges skipped under `hyperedges: \"skip\"`. */\n HYPEREDGE_SKIPPED: \"W_GRAPHML_HYPEREDGE_SKIPPED\",\n /** An endpoint of a hyperedge without a node, or with an unknown type. */\n HYPEREDGE_ENDPOINT: \"E_GRAPHML_HYPEREDGE_ENDPOINT\",\n /** `<port>` declarations (and their data) are not kept; sourceport / targetport edge attributes are. */\n PORT_DECLARATION: \"W_GRAPHML_PORT_DECLARATION\",\n /** A GraphML `parse.*` hint on `<graph>`, `<node>` or `<edge>` the importer does not act on (parse.nodeids, parse.order, ...). */\n PARSE_HINT_IGNORED: \"W_GRAPHML_PARSE_HINT_IGNORED\",\n /** An XML attribute GraphML does not define on `<graph>`, `<node>` or `<edge>`; it is not kept. */\n UNKNOWN_XML_ATTRIBUTE: \"W_GRAPHML_UNKNOWN_XML_ATTRIBUTE\",\n /** A `<locator>` element. */\n LOCATOR_DROPPED: \"W_GRAPHML_LOCATOR_DROPPED\",\n /** A `<desc>` of a node, an edge or a hyperedge. */\n DESC_DROPPED: \"W_GRAPHML_DESC_DROPPED\",\n /** An element the GraphML schema does not define at that place. */\n UNKNOWN_ELEMENT: UNKNOWN_ELEMENT_CODE,\n /** Non-whitespace text where the schema allows only elements. */\n STRAY_TEXT: STRAY_TEXT_CODE,\n /** Two distinct id texts merged into one number under `ids: \"number\"`. */\n ID_MERGED: ID_MERGED_CODE,\n /** An option GraphML has no use for (`nodeIdFrom`: nodes are identified by their id attribute). */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A yFiles key under `yfiles: \"skip\"`. */\n YFILES_SKIPPED: \"W_GRAPHML_YFILES_SKIPPED\",\n /** A key renamed `<name>#<id>` because the name was taken (design section 5.6). */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A key declared without its role because the table already holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** A declared type the format does not define (kept as string). */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** A default that does not parse as the declared type. */\n BAD_DEFAULT: BAD_DEFAULT_CODE,\n /** A long value beyond 2^53 rounded. */\n PRECISION: PRECISION_CODE,\n /** A builder-policy option the sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n /** The sink refused the file's direction. */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges forced to the policy's direction. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /** A mixed file under onMixedDirection \"error\" (fatal). */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n});\n\n/**\n * Loss note codes of the GraphML importer (report.lossy) and exporter (check()): the GraphML\n * ones; the generic ones (dtypes, lists, json text, positions, visual and temporal roles,\n * extension tables, id charsets, the weight key clash, name changes) are those of `LOSS`.\n */\nexport const GRAPHML_LOSS = Object.freeze({\n /** yFiles nested XML kept as a JSON tree: structure preserved, not byte-exact. */\n YFILES_JSON: \"W_GRAPHML_YFILES_JSON\",\n /** A mutual pair written as one undirected edge; the mark is lost. */\n MUTUAL_AS_UNDIRECTED: MUTUAL_AS_UNDIRECTED_CODE,\n /** A `parents` (multi-parent) column cannot be written as nested graphs. */\n PARENTS_DROPPED: PARENTS_DROPPED_CODE,\n /** A role column GraphML has no slot for (kind, node ids, ...) written as a plain attribute. */\n ROLE_DROPPED: ROLE_DROPPED_CODE,\n /** Containment order differs from index order; node indices change after a round trip. */\n HIERARCHY_REORDERED: \"W_GRAPHML_HIERARCHY_REORDERED\",\n /** Nodes whose parent chain never reaches a root are written at the top level. */\n PARENT_CYCLE: \"W_GRAPHML_PARENT_CYCLE\",\n /** Node ids that change type after a round trip under the canonical rule (design section 4.1). */\n ID_TEXT_TYPE: ID_TEXT_TYPE_CODE,\n /** A numeric edge id column reads back as string. */\n EDGE_ID_TEXT: \"W_GRAPHML_EDGE_ID_TEXT\",\n /** A `yfiles.*` graphics column that no longer matches its yFiles tree: only the tree is written. */\n YFILES_GRAPHICS_STALE: \"W_GRAPHML_YFILES_GRAPHICS_STALE\",\n /** A yfiles json value that is not a serialisable tree: export() will throw E_COLUMN_TYPE. */\n YFILES_TREE: \"E_GRAPHML_YFILES_TREE\",\n});\n","/**\n * Nested XML inside a GraphML `<data>` element (yFiles / yEd `y:ShapeNode`, `y:PolyLineEdge`,\n * ...) as a JSON tree, the value of a `json` column with `origin.namespace: \"yfiles\"` (design\n * section 8.5: structure preserved, not byte-exact). The shape follows the fast-xml-parser\n * convention graphty-element's parser already navigates: an element is an object whose\n * `@_<name>` keys are its attributes, whose `#text` key is its non-whitespace character data\n * when it also has attributes or children, and whose other keys are its child elements (an\n * array when a name repeats); an element with neither attributes nor children is its text\n * (an empty string for an empty element).\n *\n * The builder consumes the tokenizer events of one subtree; the writer produces the XML text of\n * a tree again, so a yFiles column re-exports as the same nested markup.\n */\n\nimport { GraphFormatError } from \"@graphty/graph-format\";\n\nimport { escapeXmlAttribute, escapeXmlText } from \"../../common/escape.js\";\nimport { isWhitespace, isXmlName } from \"../../common/xml.js\";\n\n/** The prefix of an attribute key in a tree object. */\nconst ATTRIBUTE_PREFIX = \"@_\";\n\n/** The key of an element's character data when it also has attributes or children. */\nconst TEXT_KEY = \"#text\";\n\n/** A tree object: attributes, text and child elements by name. */\ntype XmlTreeObject = Record<string, unknown>;\n\n/** A frame of the builder: one open element. */\ninterface Frame {\n readonly name: string;\n readonly node: XmlTreeObject;\n hasAttrs: boolean;\n hasChildren: boolean;\n text: string;\n}\n\n/**\n * Builds the tree of one subtree from start / end / text events. The outermost frame is the\n * `<data>` element itself; `finish()` returns its content: the object of its children, or its\n * text when it has none.\n */\nexport class XmlTreeBuilder {\n private readonly frames: Frame[] = [];\n\n private readonly root: Frame;\n\n /** Create a builder whose implicit root is the containing element. */\n constructor() {\n this.root = { name: \"\", node: {}, hasAttrs: false, hasChildren: false, text: \"\" };\n }\n\n /**\n * Whether the builder is inside a child element (as opposed to at the root level).\n * @returns true while at least one child element is open\n */\n get open(): boolean {\n return this.frames.length > 0;\n }\n\n /**\n * An element starts.\n * @param name - the element name as written\n * @param attrs - its attributes\n */\n start(name: string, attrs: ReadonlyMap<string, string>): void {\n const node: XmlTreeObject = {};\n let hasAttrs = false;\n for (const [key, value] of attrs) {\n node[ATTRIBUTE_PREFIX + key] = value;\n hasAttrs = true;\n }\n this.frames.push({ name, node, hasAttrs, hasChildren: false, text: \"\" });\n }\n\n /**\n * Character data inside the current element.\n * @param text - the text\n */\n text(text: string): void {\n const frame = this.frames.length > 0 ? this.frames[this.frames.length - 1] : this.root;\n frame.text += text;\n }\n\n /** The current element ends; its value is attached to its parent. */\n end(): void {\n const frame = this.frames.pop();\n if (frame === undefined) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", \"XmlTreeBuilder.end() without a matching start()\", {\n reason: \"tree builder underflow\",\n });\n }\n const parent = this.frames.length > 0 ? this.frames[this.frames.length - 1] : this.root;\n attachChild(parent, frame.name, valueOf(frame));\n }\n\n /**\n * The content of the containing element: its text when it has no child elements, otherwise\n * the object of its children (with `#text` for non-whitespace mixed content).\n * @returns the value to store in the json column\n */\n finish(): unknown {\n if (this.frames.length > 0) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", \"XmlTreeBuilder.finish() with open elements\", {\n reason: \"tree builder open\",\n });\n }\n const { root } = this;\n if (!root.hasChildren) {\n return root.text;\n }\n if (!isWhitespace(root.text)) {\n root.node[TEXT_KEY] = root.text;\n }\n return root.node;\n }\n}\n\n/**\n * The value of a finished element: its text when it has neither attributes nor children,\n * else its node with `#text` set to non-whitespace text.\n * @param frame - the finished frame\n * @returns the value\n */\nfunction valueOf(frame: Frame): unknown {\n if (!frame.hasAttrs && !frame.hasChildren) {\n return frame.text;\n }\n if (!isWhitespace(frame.text)) {\n frame.node[TEXT_KEY] = frame.text;\n }\n return frame.node;\n}\n\n/**\n * Attach a child value under a name, turning a repeated name into an array.\n * @param parent - the parent frame\n * @param name - the child element name\n * @param value - the child value\n */\nfunction attachChild(parent: Frame, name: string, value: unknown): void {\n parent.hasChildren = true;\n const existing = parent.node[name];\n if (existing === undefined) {\n parent.node[name] = value;\n } else if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n parent.node[name] = [existing, value];\n }\n}\n\n/**\n * Whether a value is a tree the writer can serialise: a string, number, boolean or null (text),\n * an array of such trees, or an object whose keys are `#text`, `@_<Name>` or `<Name>` with tree\n * values.\n * @param value - the value\n * @returns true when writeXmlTree() accepts it\n */\nexport function isXmlTree(value: unknown): boolean {\n return treeProblem(value) === null;\n}\n\n/**\n * Why a value is not a serialisable tree.\n * @param value - the value\n * @returns a message, or null when the value is a tree\n */\nexport function treeProblem(value: unknown): string | null {\n if (value === null || typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return null;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n if (Array.isArray(item)) {\n return \"nested arrays cannot be written as elements\";\n }\n const problem = treeProblem(item);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n }\n if (typeof value !== \"object\") {\n return `a ${typeof value} cannot be written as XML`;\n }\n for (const [key, child] of Object.entries(value)) {\n if (key === TEXT_KEY) {\n if (child !== null && typeof child === \"object\") {\n return \"#text must be a scalar\";\n }\n continue;\n }\n if (key.startsWith(ATTRIBUTE_PREFIX)) {\n const name = key.slice(ATTRIBUTE_PREFIX.length);\n if (!isXmlName(name)) {\n return `\"${name}\" is not an XML attribute name`;\n }\n if (child !== null && typeof child === \"object\") {\n return `attribute ${name} must be a scalar`;\n }\n continue;\n }\n if (!isXmlName(key)) {\n return `\"${key}\" is not an XML element name`;\n }\n const problem = treeProblem(child);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n}\n\n/**\n * Write the content of a tree as XML text: the children (and mixed text) of the containing\n * element. Leaf elements are written inline so their text stays exact; elements with children\n * are broken over lines and indented.\n * @param value - the tree (the content of a `<data>` element)\n * @param indent - the indentation of the containing element's children\n * @param out - receives the text parts\n */\nexport function writeXmlTree(value: unknown, indent: string, out: string[]): void {\n const problem = treeProblem(value);\n if (problem !== null) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `a yfiles value cannot be written as XML: ${problem}`, {\n reason: \"xml tree\",\n });\n }\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n out.push(escapeXmlText(scalarText(value)));\n return;\n }\n const object = value as XmlTreeObject;\n let text: string | null = null;\n for (const [key, child] of Object.entries(object)) {\n if (key === TEXT_KEY) {\n text = scalarText(child);\n } else if (!key.startsWith(ATTRIBUTE_PREFIX)) {\n writeElements(key, child, indent, out);\n }\n }\n if (text !== null) {\n out.push(escapeXmlText(text));\n }\n}\n\n/**\n * Write one element (or, for an array, one element per item).\n * @param name - the element name\n * @param value - the element value\n * @param indent - the indentation of this element\n * @param out - receives the text parts\n */\nfunction writeElements(name: string, value: unknown, indent: string, out: string[]): void {\n if (Array.isArray(value)) {\n for (const item of value) {\n writeElements(name, item, indent, out);\n }\n return;\n }\n if (value === null || typeof value !== \"object\") {\n const text = scalarText(value);\n out.push(text.length === 0 ? `\\n${indent}<${name}/>` : `\\n${indent}<${name}>${escapeXmlText(text)}</${name}>`);\n return;\n }\n const object = value as XmlTreeObject;\n let attrs = \"\";\n let text: string | null = null;\n let hasChildren = false;\n for (const [key, child] of Object.entries(object)) {\n if (key === TEXT_KEY) {\n text = scalarText(child);\n } else if (key.startsWith(ATTRIBUTE_PREFIX)) {\n attrs += ` ${key.slice(ATTRIBUTE_PREFIX.length)}=\"${escapeXmlAttribute(scalarText(child))}\"`;\n } else {\n hasChildren = true;\n }\n }\n if (!hasChildren) {\n out.push(\n text === null || text.length === 0\n ? `\\n${indent}<${name}${attrs}/>`\n : `\\n${indent}<${name}${attrs}>${escapeXmlText(text)}</${name}>`,\n );\n return;\n }\n out.push(`\\n${indent}<${name}${attrs}>`);\n const inner = `${indent} `;\n for (const [key, child] of Object.entries(object)) {\n if (key !== TEXT_KEY && !key.startsWith(ATTRIBUTE_PREFIX)) {\n writeElements(key, child, inner, out);\n }\n }\n if (text !== null) {\n out.push(escapeXmlText(text));\n }\n out.push(`\\n${indent}</${name}>`);\n}\n\n/**\n * The text of a scalar tree value.\n * @param value - a string, number, boolean or null\n * @returns the text; an empty string for null\n */\nfunction scalarText(value: unknown): string {\n switch (typeof value) {\n case \"string\":\n return value;\n case \"number\":\n case \"boolean\":\n case \"bigint\":\n return String(value);\n default:\n return \"\";\n }\n}\n","/**\n * yFiles / yEd graphics read out of the JSON tree of a `yfiles.type` key (tree.ts) into typed\n * columns, beside the tree itself: a `y:ShapeNode` gives the node's position, size, fill and\n * border colours, label and shape, and a `y:PolyLineEdge` gives the edge's line colour and width,\n * its arrows and the direction they draw. The values are the ones graphty-element's own GraphML\n * parser produced, so a consumer rebuilds its records by dropping the `yfiles.` prefix: colours\n * are `#RRGGBB` in upper case (a `#RGB` is expanded, any other text is kept as written), numbers\n * are parsed with parseFloat, the position is `[x, y, 0]` and the shape is the yFiles shape type\n * as written. One difference: a label whose text is a number (`<y:NodeLabel>0</y:NodeLabel>`) is\n * kept as that text, where the element's parser turned it into a number and stored `\"\"`, nothing\n * or the number.\n *\n * The columns are views of the tree: the exporter writes the tree and never these columns, and\n * re-importing the tree gives them back. A value edited after import (a layout writing the\n * position) or a tree column removed is therefore not written, and the exporter reports it as a\n * loss (staleGraphicsRows()).\n */\n\nimport { type Column, type ColumnDecl, type JsonColumn } from \"@graphty/graph-format\";\n\nimport { localName } from \"../../common/xml.js\";\n\n/** The name prefix of every column mapped from yFiles graphics. */\nconst YFILES_COLUMN_PREFIX = \"yfiles.\";\n\ntype Tree = Record<string, unknown>;\n\n/** The mapped node columns, by the field name graphty-element's records use. */\nconst NODE_FIELDS: Readonly<Record<string, Omit<ColumnDecl, \"name\">>> = {\n position: { dtype: \"f64\", components: 3, role: \"position\", mutable: true },\n width: { dtype: \"f64\" },\n height: { dtype: \"f64\" },\n color: { dtype: \"string\" },\n borderColor: { dtype: \"string\" },\n borderWidth: { dtype: \"f64\" },\n label: { dtype: \"string\", role: \"label\" },\n shape: { dtype: \"string\" },\n};\n\n/** The mapped edge columns, by field name. */\nconst EDGE_FIELDS: Readonly<Record<string, Omit<ColumnDecl, \"name\">>> = {\n color: { dtype: \"string\" },\n width: { dtype: \"f64\" },\n directed: { dtype: \"bool\" },\n targetArrow: { dtype: \"string\" },\n sourceArrow: { dtype: \"string\" },\n};\n\n/**\n * The declaration of a mapped column.\n * @param domain - node or edge\n * @param field - the field name (a key of the values graphicsValues() returns)\n * @param keyId - the id of the GraphML key whose tree it is read from\n * @returns the declaration\n */\nexport function graphicsDecl(domain: \"node\" | \"edge\", field: string, keyId: string): ColumnDecl {\n const fields = domain === \"node\" ? NODE_FIELDS : EDGE_FIELDS;\n return {\n ...fields[field],\n name: YFILES_COLUMN_PREFIX + field,\n nullable: true,\n origin: {\n format: \"graphml\",\n id: keyId,\n title: null,\n type: domain === \"node\" ? \"ShapeNode\" : \"PolyLineEdge\",\n namespace: \"yfiles\",\n },\n };\n}\n\n/**\n * Whether a column is one graphicsDecl() declared (a view of a yFiles tree, never exported).\n * @param meta - the column's name, dtype and origin\n * @param meta.name - the column name\n * @param meta.dtype - the column dtype\n * @param meta.origin - the column origin\n * @returns true for a mapped graphics column\n */\nexport function isGraphicsColumn(meta: {\n readonly name: string;\n readonly dtype: string;\n readonly origin: { readonly namespace: string | null } | null;\n}): boolean {\n return meta.dtype !== \"json\" && meta.origin?.namespace === \"yfiles\" && meta.name.startsWith(YFILES_COLUMN_PREFIX);\n}\n\n/**\n * The rows of a mapped graphics column whose value is not one its yFiles tree columns (in the\n * same table) give: every set row when no tree column gives a value for the row. A file may\n * declare several yFiles keys for one domain, and the mapped column holds the values of all of\n * them, so a row is current when any tree's value matches. These are the values an export loses,\n * since only the trees are written.\n * @param column - the mapped column (isGraphicsColumn())\n * @param table - the table it is in\n * @param domain - node or edge\n * @returns the number of rows that differ from the trees\n */\nexport function staleGraphicsRows(column: Column, table: Iterable<Column>, domain: \"node\" | \"edge\"): number {\n const field = column.meta.name.slice(YFILES_COLUMN_PREFIX.length);\n const trees: JsonColumn[] = [];\n for (const c of table) {\n if (c.dtype === \"json\" && c.meta.origin?.namespace === \"yfiles\") {\n trees.push(c);\n }\n }\n let stale = 0;\n for (let r = 0; r < column.length; r++) {\n const wants = new Set<string>();\n for (const tree of trees) {\n const want = graphicsValues(domain, tree.values[r]).find(([f]) => f === field);\n if (want !== undefined) {\n wants.add(JSON.stringify(want[1]));\n }\n }\n if (wants.size === 0) {\n wants.add(JSON.stringify(undefined));\n }\n const value = column.value(r);\n const have = column.meta.components > 1 && value !== undefined ? Array.from(value as ArrayLike<number>) : value;\n if (!wants.has(JSON.stringify(have))) {\n stale++;\n }\n }\n return stale;\n}\n\n/**\n * The mapped values of one `<data>` tree of a yFiles key: a ShapeNode's for a node, a\n * PolyLineEdge's for an edge; nothing for any other graphics (GenericNode, BezierEdge, ...).\n * @param domain - node or edge\n * @param tree - the `<data>` content as tree.ts builds it\n * @returns field name -> value, in declaration order\n */\nexport function graphicsValues(domain: \"node\" | \"edge\", tree: unknown): [string, unknown][] {\n const out: [string, unknown][] = [];\n if (domain === \"node\") {\n const shape = child(tree, \"ShapeNode\");\n if (shape !== undefined) {\n shapeNodeValues(shape, out);\n }\n } else {\n const edge = child(tree, \"PolyLineEdge\");\n if (edge !== undefined) {\n polyLineEdgeValues(edge, out);\n }\n }\n return out;\n}\n\n/**\n * Read a ShapeNode.\n * @param shape - the ShapeNode element\n * @param out - receives the values\n */\nfunction shapeNodeValues(shape: unknown, out: [string, unknown][]): void {\n const geometry = child(shape, \"Geometry\");\n // yFiles requires x, y, width and height on Geometry; a position needs both coordinates\n const x = number(attr(geometry, \"x\"));\n const y = number(attr(geometry, \"y\"));\n if (x !== undefined && y !== undefined) {\n out.push([\"position\", [x, y, 0]]);\n }\n push(out, \"width\", number(attr(geometry, \"width\")));\n push(out, \"height\", number(attr(geometry, \"height\")));\n push(out, \"color\", color(attr(child(shape, \"Fill\"), \"color\")));\n const border = child(shape, \"BorderStyle\");\n push(out, \"borderColor\", color(attr(border, \"color\")));\n push(out, \"borderWidth\", number(attr(border, \"width\")));\n const label = child(shape, \"NodeLabel\");\n // an element with no text and no attributes is \"\" (no label); one with attributes but no text is a blank label\n if (typeof label === \"string\" ? label.length > 0 : label !== undefined) {\n // trimmed, as the element's parser (trimValues) reads it: pretty-printed yEd puts whitespace before the label's children\n out.push([\"label\", (typeof label === \"string\" ? label : (text(label) ?? \"\")).trim()]);\n }\n push(out, \"shape\", nonEmpty(attr(child(shape, \"Shape\"), \"type\")));\n}\n\n/**\n * Read a PolyLineEdge.\n * @param edge - the PolyLineEdge element\n * @param out - receives the values\n */\nfunction polyLineEdgeValues(edge: unknown, out: [string, unknown][]): void {\n const line = child(edge, \"LineStyle\");\n push(out, \"color\", color(attr(line, \"color\")));\n push(out, \"width\", number(attr(line, \"width\")));\n const arrows = child(edge, \"Arrows\");\n if (arrows !== undefined && typeof arrows === \"object\") {\n const target = attr(arrows, \"target\");\n const source = attr(arrows, \"source\");\n // yEd draws direction with the target arrow; the file's edgedefault still decides topology\n out.push([\"directed\", target !== undefined && target !== \"none\"]);\n push(out, \"targetArrow\", target === \"none\" ? undefined : nonEmpty(target));\n push(out, \"sourceArrow\", source === \"none\" ? undefined : nonEmpty(source));\n }\n}\n\n/**\n * Append a value when it is defined.\n * @param out - the values\n * @param field - the field name\n * @param value - the value\n */\nfunction push(out: [string, unknown][], field: string, value: unknown): void {\n if (value !== undefined) {\n out.push([field, value]);\n }\n}\n\n/**\n * The first child element of a tree node by local name, whatever its namespace prefix.\n * @param node - the tree node\n * @param local - the local name\n * @returns the child, or undefined\n */\nfunction child(node: unknown, local: string): unknown {\n if (typeof node !== \"object\" || node === null) {\n return undefined;\n }\n for (const [key, value] of Object.entries(node as Tree)) {\n if (!key.startsWith(\"@_\") && key !== \"#text\" && localName(key) === local) {\n return Array.isArray(value) ? value[0] : value;\n }\n }\n return undefined;\n}\n\n/**\n * An attribute of a tree node.\n * @param node - the tree node\n * @param name - the attribute name\n * @returns the text, or undefined\n */\nfunction attr(node: unknown, name: string): string | undefined {\n if (typeof node !== \"object\" || node === null) {\n return undefined;\n }\n const value = (node as Tree)[`@_${name}`];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * The character data of an element that also has attributes or children.\n * @param node - the tree node\n * @returns the text, or undefined\n */\nfunction text(node: unknown): string | undefined {\n const value = typeof node === \"object\" && node !== null ? (node as Tree)[\"#text\"] : undefined;\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * A non-empty text.\n * @param value - the text\n * @returns the text, or undefined when absent or empty\n */\nfunction nonEmpty(value: string | undefined): string | undefined {\n return value === undefined || value.length === 0 ? undefined : value;\n}\n\n/**\n * A number attribute, parsed as graphty-element's parser parsed it.\n * @param value - the text\n * @returns the number, or undefined when absent, empty or not a number\n */\nfunction number(value: string | undefined): number | undefined {\n if (value === undefined || value.length === 0) {\n return undefined;\n }\n const n = Number.parseFloat(value);\n return Number.isNaN(n) ? undefined : n;\n}\n\n/**\n * A colour attribute: `#RRGGBB` upper-cased, `#RGB` expanded, anything else as written.\n * @param value - the text\n * @returns the colour, or undefined when absent or empty\n */\nfunction color(value: string | undefined): string | undefined {\n if (value === undefined || value.length === 0) {\n return undefined;\n }\n if (/^#[0-9A-Fa-f]{6}$/.test(value)) {\n return value.toUpperCase();\n }\n if (/^#[0-9A-Fa-f]{3}$/.test(value)) {\n const [, r, g, b] = value;\n return `#${r}${r}${g}${g}${b}${b}`.toUpperCase();\n }\n return value;\n}\n","/**\n * The GraphML exporter (design section 8.5; research note 07 section 9): `<key>` declarations\n * regenerated from ColumnMeta.origin when the column came from GraphML (key id, attr.name,\n * attr.type, yfiles.type) and derived from the dtype otherwise; node ids sanitised to NMTOKEN\n * (`sanitizeIds: \"error\"` refuses, `\"mangle\"` rewrites and keeps the original in a\n * `graphty:originalId` data attribute the importer restores); mixed direction written with\n * `edgedefault` plus per-edge `directed` attributes, folding expanded pairs back through the\n * `pair` / `directed` role columns; explicit weights only (the role-weight column's validity);\n * containment (`parent` role) as nested graphs; yFiles json columns as nested XML again.\n *\n * check() lists every loss before anything is written: the generic capability gaps of\n * checkCapabilities() (dict / u32 / u8 dtypes, lists, components, options, positions, visual and\n * temporal roles, extension tables) plus the GraphML-specific ones (mutual edges written as\n * undirected, json columns without a yfiles origin written as JSON text, multi-parent columns,\n * containment order, ids that change type under the canonical rule, edge ids that read back as\n * strings, roles GraphML cannot express, yfiles values that are not serialisable trees).\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot, INVALID_INDEX } from \"@graphty/graph-format\";\n\nimport { childrenCsr } from \"../../children.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { escapeXmlAttribute, escapeXmlText } from \"../../common/escape.js\";\nimport {\n capabilities,\n checkCapabilities,\n isNmtoken,\n LOSS,\n mangleNmtoken,\n type SanitizedIds,\n sanitizeIds,\n} from \"../../common/export.js\";\nimport { formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { isCanonicalIntegerText } from \"../../common/ids.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { xmlIllegalTextNotes } from \"../../common/xml.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport {\n EDGE_ID_COLUMN,\n FORMAT,\n GRAPHML_LOSS,\n GRAPHML_NAMESPACE,\n type GraphmlMeta,\n LABEL_COLUMN,\n META_KEY,\n ORIGINAL_ID_ATTRIBUTE,\n PARENT_COLUMN,\n RESERVED_EDGE_NAMES,\n RESERVED_NODE_NAMES,\n SCHEMA_LOCATION,\n SOURCE_PORT_COLUMN,\n TARGET_PORT_COLUMN,\n XSI_NAMESPACE,\n YFILES_NAMESPACE,\n} from \"./constants.js\";\nimport { treeProblem, writeXmlTree } from \"./tree.js\";\nimport { isGraphicsColumn, staleGraphicsRows } from \"./yfiles.js\";\n\n/** The format-specific options of the GraphML exporter. */\nexport interface GraphmlExportOptions {\n /** Indent nested elements (default true); false writes one element per line without indentation. */\n pretty?: boolean | undefined;\n /**\n * The top-level `edgedefault`. By default the one the importer recorded in\n * `meta.extra.graphml` (so a mixed file re-imports with the same edge layout), else the\n * snapshot's direction, with the majority direction for a mixed snapshot.\n */\n edgedefault?: \"directed\" | \"undirected\" | undefined;\n}\n\n/** What GraphML keeps as declared (research note 07 section 9). */\nconst CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: true,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"optional\",\n idCharset: \"nmtoken\",\n dtypes: [\"bool\", \"i32\", \"f32\", \"f64\", \"string\"],\n components: false,\n lists: false,\n json: false,\n defaults: true,\n options: false,\n hierarchy: true,\n temporal: \"none\",\n graphAttributes: true,\n positions: false,\n viz: false,\n});\n\n/** Roles handled structurally (never written as a key) or reported by checkCapabilities() and not written. */\nconst STRUCTURAL_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n]);\nconst DROPPED_ROLES: ReadonlySet<string> = new Set([\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\n/**\n * The roles GraphML has a slot for (checkCapabilities() reports every other role as lost): the\n * label key, the edge `id`, `sourceport` and `targetport` attributes and nested graphs.\n */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"label\", \"id\", \"sourcePort\", \"targetPort\", \"parent\"]);\n\n/** The slot roles written structurally per domain (never as a key); a label is a key titled `label`. */\nconst SLOT_ROLES_BY_DOMAIN: Readonly<Record<Domain, ReadonlySet<string>>> = {\n graph: new Set(),\n node: new Set([\"parent\"]),\n edge: new Set([\"id\", \"sourcePort\", \"targetPort\"]),\n};\n\n/** The names the importer gives the slot columns (design section 5.6), for the name-change notes. */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: LABEL_COLUMN,\n id: EDGE_ID_COLUMN,\n sourcePort: SOURCE_PORT_COLUMN,\n targetPort: TARGET_PORT_COLUMN,\n parent: PARENT_COLUMN,\n});\n\n/** The attr.name of the weight key when the weight did not come from GraphML (the importer's weightFrom default). */\nconst DEFAULT_WEIGHT_NAME = \"weight\";\n\n/** A note-recording callback. */\ntype NoteFn = (code: string, message: string, column?: string | null, count?: number | null) => void;\n\n/** The GraphML attr.type values and the dtype each maps to, for restoring origin.type. */\nconst TYPE_DTYPES: Readonly<Record<string, string>> = {\n boolean: \"bool\",\n int: \"i32\",\n long: \"f64\",\n float: \"f32\",\n double: \"f64\",\n string: \"string\",\n};\n\nconst I32_MAX = 2147483647;\n\n/** The yfiles.type written for a yfiles json column whose origin records none. */\nconst DEFAULT_YFILES_TYPES: Readonly<Record<Domain, string>> = {\n node: \"nodegraphics\",\n edge: \"edgegraphics\",\n graph: \"resources\",\n};\n\n/** The element domains. */\ntype Domain = \"graph\" | \"node\" | \"edge\";\n\n/** One column written as a key. */\ninterface ColumnPlan {\n readonly column: Column;\n readonly domain: Domain;\n /** The key id. */\n keyId: string;\n /** The attr.type, or null for a yfiles key. */\n readonly attrType: string | null;\n /** The attr.name, or null for a yfiles key. */\n readonly attrName: string | null;\n /** The yfiles.type, or null. */\n readonly yfilesType: string | null;\n /** Whether values are written as nested XML trees. */\n readonly yfiles: boolean;\n}\n\n/** One `<key>` element (a for=\"all\" key merges up to three column plans). */\ninterface KeyPlan {\n readonly id: string;\n readonly domains: readonly Domain[];\n readonly attrName: string | null;\n readonly attrType: string | null;\n readonly yfilesType: string | null;\n /** The column whose default and desc are written; null for the weight key. */\n readonly column: Column | null;\n}\n\n/** Containment as the exporter writes it. */\ninterface Hierarchy {\n /** The parent column, or null. */\n readonly parent: Column | null;\n /** Nodes written at the top level, in order (roots, then the roots forced out of cycles). */\n readonly roots: Uint32Array;\n /** CSR of children by parent: childStart[u]..childStart[u+1] over childList. */\n readonly childStart: Uint32Array;\n readonly childList: Uint32Array;\n /** Whether the written order differs from index order. */\n readonly reordered: boolean;\n /** Nodes whose parent chain never reaches a root. */\n readonly unreachable: number;\n}\n\n/** Everything check() and export() agree on. */\ninterface Plan {\n readonly options: ResolvedExportOptions;\n readonly pretty: boolean;\n readonly notes: LossNote[];\n readonly keys: KeyPlan[];\n readonly graphColumns: ColumnPlan[];\n readonly nodeColumns: ColumnPlan[];\n readonly edgeColumns: ColumnPlan[];\n /** The weight key id, attr.type and the explicit weights, or null for an unweighted snapshot. */\n readonly weight: { readonly keyId: string; readonly attrType: string; readonly weights: ExplicitWeights } | null;\n /** The key id of the originalId attribute, when mangled ids are written. */\n readonly originalIdKey: string | null;\n readonly edgedefault: \"directed\" | \"undirected\";\n /** The pair folding: mirrors skipped, source directions. */\n readonly folding: PairFolding;\n readonly edgeIdColumn: Column | null;\n readonly sourcePortColumn: Column | null;\n readonly targetPortColumn: Column | null;\n readonly hierarchy: Hierarchy;\n readonly meta: GraphmlMeta | null;\n readonly needsOriginalIdKey: boolean;\n}\n\n/** The resolved format-specific options. */\ninterface FormatOptions {\n /** Whether to indent. */\n readonly pretty: boolean;\n /** The edgedefault override, or null. */\n readonly edgedefault: \"directed\" | \"undirected\" | null;\n}\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the pretty flag and the edgedefault override\n */\nfunction resolveFormatOptions(options: GraphmlExportOptions | undefined): FormatOptions {\n const pretty = options?.pretty ?? true;\n if (typeof pretty !== \"boolean\") {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option pretty must be a boolean\", {\n option: \"pretty\",\n found: typeof pretty,\n });\n }\n const edgedefault = options?.edgedefault ?? null;\n if (edgedefault !== null && edgedefault !== \"directed\" && edgedefault !== \"undirected\") {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option edgedefault: ${JSON.stringify(edgedefault)} is not \"directed\" or \"undirected\"`,\n { option: \"edgedefault\", found: edgedefault },\n );\n }\n return { pretty, edgedefault };\n}\n\n/**\n * The importer's `meta.extra.graphml`, when the snapshot has one of the expected shape.\n * @param snapshot - the snapshot\n * @returns the meta, or null\n */\nfunction graphmlMetaOf(snapshot: GraphSnapshot): GraphmlMeta | null {\n const value = snapshot.meta.extra[META_KEY];\n if (typeof value !== \"object\" || value === null) {\n return null;\n }\n const record = value as Record<string, unknown>;\n const graphId = typeof record.graphId === \"string\" ? record.graphId : null;\n const edgedefault =\n record.edgedefault === \"directed\" || record.edgedefault === \"undirected\" ? record.edgedefault : null;\n const namespaces: Record<string, string> = {};\n if (typeof record.namespaces === \"object\" && record.namespaces !== null) {\n for (const [prefix, uri] of Object.entries(record.namespaces as Record<string, unknown>)) {\n if (typeof uri === \"string\") {\n namespaces[prefix] = uri;\n }\n }\n }\n return { graphId, edgedefault, namespaces };\n}\n\n/**\n * Build the plan: classify every column, assign key ids, decide the edgedefault and the\n * containment order, and collect every loss note.\n * @param snapshot - the snapshot\n * @param options - the resolved common options\n * @param format - the resolved format options\n * @returns the plan\n */\nfunction planExport(snapshot: GraphSnapshot, options: ResolvedExportOptions, format: FormatOptions): Plan {\n // the generic json note is replaced by planTable()'s (yfiles trees are kept, other json is\n // text); columns mapped from a yfiles tree are never written: planTable() notes the ones\n // that no longer match their tree, the rest lose nothing\n const graphics = new Set(\n [...snapshot.nodes, ...snapshot.edges].filter((c) => isGraphicsColumn(c.meta)).map((c) => c.meta.name),\n );\n const notes = checkCapabilities(snapshot, CAPABILITIES, options, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n }).filter((n) => n.code !== LOSS.JSON && (n.column === null || !graphics.has(n.column)));\n const note: NoteFn = (code, message, column = null, count = null): void => {\n notes.push(Object.freeze({ code, message, column, count }));\n };\n notes.push(...xmlIllegalTextNotes(snapshot));\n const meta = graphmlMetaOf(snapshot);\n const keyIds = new KeyIds();\n\n const graphColumns = planTable(snapshot.graph, \"graph\", notes, note);\n const nodeColumns = planTable(snapshot.nodes, \"node\", notes, note);\n const edgeColumns = planTable(snapshot.edges, \"edge\", notes, note);\n const keys = planKeys([...graphColumns, ...nodeColumns, ...edgeColumns], keyIds);\n reservedNameNotes(nodeColumns, RESERVED_NODE_NAMES, note);\n reservedNameNotes(edgeColumns, RESERVED_EDGE_NAMES, note);\n const weight = planWeight(snapshot, edgeColumns, keyIds, keys, note);\n\n // ids\n const idTypeChanges = countIdTypeChanges(snapshot);\n if (idTypeChanges > 0) {\n note(\n GRAPHML_LOSS.ID_TEXT_TYPE,\n `${idTypeChanges} node id(s) change type when read back under ids: \"canonical\" (string ids that are integer text, non-integer numbers)`,\n null,\n idTypeChanges,\n );\n }\n const edgeIdColumn = snapshot.edges.byRole(\"id\");\n if (edgeIdColumn !== null) {\n planEdgeIds(snapshot, edgeIdColumn, options, note);\n }\n const unrepresentable = countUnrepresentableNodeIds(snapshot);\n const needsOriginalIdKey = unrepresentable > 0 && options.sanitizeIds === \"mangle\";\n const originalIdKey = needsOriginalIdKey ? keyIds.next(null) : null;\n\n // direction: an undirected pair folds to one undirected edge, a mutual pair too (the mark is lost)\n const folding = pairFolding(snapshot, { foldMutual: true });\n if (folding.mutualCount > 0) {\n note(\n GRAPHML_LOSS.MUTUAL_AS_UNDIRECTED,\n `${folding.mutualCount} mutual pair(s) are written as undirected edges; the mutual mark is lost`,\n null,\n folding.mutualCount,\n );\n }\n const edgedefault = planEdgedefault(snapshot, folding, format, meta);\n\n // containment\n const hierarchy = planHierarchy(snapshot);\n if (hierarchy.reordered) {\n note(\n GRAPHML_LOSS.HIERARCHY_REORDERED,\n \"nodes are written in containment order (children nested under their parent); node indices change after a round trip\",\n hierarchy.parent?.meta.name ?? null,\n );\n }\n if (hierarchy.unreachable > 0) {\n note(\n GRAPHML_LOSS.PARENT_CYCLE,\n `${hierarchy.unreachable} node(s) whose parent chain never reaches a root are written at the top level`,\n hierarchy.parent?.meta.name ?? null,\n hierarchy.unreachable,\n );\n }\n\n return {\n options,\n pretty: format.pretty,\n notes,\n keys,\n graphColumns,\n nodeColumns,\n edgeColumns,\n weight,\n originalIdKey,\n edgedefault,\n folding,\n edgeIdColumn,\n sourcePortColumn: snapshot.edges.byRole(\"sourcePort\"),\n targetPortColumn: snapshot.edges.byRole(\"targetPort\"),\n hierarchy,\n meta,\n needsOriginalIdKey,\n };\n}\n\n/**\n * A plain column titled like one of the importer's XML-derived columns (`id`, `sourceport`,\n * `targetport` on edges, `parent` on nodes) reads back renamed `<name>#<key id>` (design section\n * 5.6); the note says so.\n * @param plans - the column plans of one domain, key ids assigned\n * @param reserved - the reserved names of that domain\n * @param note - the note recorder\n */\nfunction reservedNameNotes(plans: readonly ColumnPlan[], reserved: ReadonlySet<string>, note: NoteFn): void {\n for (const plan of plans) {\n const { column, attrName, keyId } = plan;\n if (attrName === null || !reserved.has(attrName)) {\n continue;\n }\n note(\n LOSS.COLUMN_NAME_CHANGED,\n `${plan.domain} column \"${column.meta.name}\" is titled like the importer's ${attrName} column and reads back as \"${attrName}#${keyId}\"`,\n column.meta.name,\n column.length - column.nullCount,\n );\n }\n}\n\n/** The key ids handed out so far: a preferred NMTOKEN when free, else the next free `d<n>`. */\nclass KeyIds {\n private readonly used = new Set<string>();\n private counter = 0;\n\n /**\n * Take a key id.\n * @param preferred - the id to keep when it is an NMTOKEN not handed out yet, or null\n * @returns the id\n */\n next(preferred: string | null): string {\n if (preferred !== null && isNmtoken(preferred) && !this.used.has(preferred)) {\n this.used.add(preferred);\n return preferred;\n }\n for (;;) {\n const candidate = `d${this.counter}`;\n this.counter++;\n if (!this.used.has(candidate)) {\n this.used.add(candidate);\n return candidate;\n }\n }\n }\n}\n\n/**\n * The `<key>` elements: columns sharing a GraphML origin.id across domains become one for=\"all\"\n * key when their name, type and default agree; every other column is its own key.\n * @param all - the column plans of the three domains, in writing order\n * @param keyIds - the key id allocator\n * @returns the keys, in declaration order\n */\nfunction planKeys(all: readonly ColumnPlan[], keyIds: KeyIds): KeyPlan[] {\n const keys: KeyPlan[] = [];\n const byOrigin = new Map<string, ColumnPlan[]>();\n for (const plan of all) {\n const { origin } = plan.column.meta;\n if (origin !== null && origin.format === FORMAT && origin.id !== null) {\n const group = byOrigin.get(origin.id) ?? [];\n group.push(plan);\n byOrigin.set(origin.id, group);\n }\n }\n const planned = new Set<ColumnPlan>();\n for (const plan of all) {\n if (planned.has(plan)) {\n continue;\n }\n const { origin } = plan.column.meta;\n const group =\n origin !== null && origin.format === FORMAT && origin.id !== null\n ? (byOrigin.get(origin.id) ?? [plan])\n : [plan];\n const shared = group.length > 1 && group.every((other) => other === plan || sameKey(plan, other));\n const members = shared ? group : [plan];\n const id = keyIds.next(origin !== null && origin.format === FORMAT ? origin.id : null);\n for (const member of members) {\n member.keyId = id;\n planned.add(member);\n }\n const domains = members.map((member) => member.domain);\n // a yfiles key carries attr.name only when the column name is not the key id (yEd writes none)\n const yfilesName = plan.column.meta.origin?.title ?? plan.column.meta.name;\n let { attrName } = plan;\n if (plan.yfiles) {\n attrName = yfilesName === id ? null : yfilesName;\n }\n keys.push({\n id,\n domains: domains.length > 1 ? [\"graph\", \"node\", \"edge\"] : domains,\n attrName,\n attrType: plan.attrType,\n yfilesType: plan.yfilesType,\n column: plan.column,\n });\n }\n return keys;\n}\n\n/**\n * The weight key of a weighted snapshot (its attr.name and attr.type restored from\n * meta.weightOrigin when the weight came from GraphML), and the note for an edge column the\n * importer would read as THE weight: every edge key titled like the weight key (`weight` by\n * default) is a weight key on import, so such a column reads back as the weight, not as a column.\n * @param snapshot - the snapshot\n * @param edgeColumns - the edge column plans\n * @param keyIds - the key id allocator\n * @param keys - receives the weight key\n * @param note - the note recorder\n * @returns the weight plan, or null for an unweighted snapshot\n */\nfunction planWeight(\n snapshot: GraphSnapshot,\n edgeColumns: readonly ColumnPlan[],\n keyIds: KeyIds,\n keys: KeyPlan[],\n note: NoteFn,\n): Plan[\"weight\"] {\n const weights = explicitWeights(snapshot);\n const origin = snapshot.meta.weightOrigin;\n const fromGraphml = weights.weighted && origin !== null && origin.format === FORMAT;\n const attrName = fromGraphml && origin.title !== null ? origin.title : DEFAULT_WEIGHT_NAME;\n for (const plan of edgeColumns) {\n if (plan.attrName === attrName) {\n note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${plan.column.meta.name}\" is written as a key titled \"${attrName}\", which the importer reads as THE weight (weightFrom); it reads back as the weight, not as a column`,\n plan.column.meta.name,\n plan.column.length - plan.column.nullCount,\n );\n }\n }\n if (!weights.weighted) {\n return null;\n }\n let attrType = \"double\";\n if (fromGraphml && origin.type !== null) {\n const declared = origin.type.trim().toLowerCase();\n if (declared === \"float\" || declared === \"double\" || declared === \"long\" || declared === \"int\") {\n attrType = declared;\n }\n }\n if ((attrType === \"int\" || attrType === \"long\") && !weightsIntegral(snapshot, weights)) {\n // a declared integer weight only survives when every explicit weight is integral\n attrType = \"double\";\n }\n const id = keyIds.next(fromGraphml ? origin.id : null);\n keys.push({ id, domains: [\"edge\"], attrName, attrType, yfilesType: null, column: null });\n return { keyId: id, attrType, weights };\n}\n\n/**\n * The notes about the edge id column: a numeric column reads back as string; ids outside the\n * NMTOKEN charset are refused or mangled per sanitizeIds.\n * @param snapshot - the snapshot\n * @param column - the edge id column\n * @param options - the resolved options\n * @param note - the note recorder\n */\nfunction planEdgeIds(snapshot: GraphSnapshot, column: Column, options: ResolvedExportOptions, note: NoteFn): void {\n if (column.dtype !== \"string\" && column.dtype !== \"dict\") {\n note(\n GRAPHML_LOSS.EDGE_ID_TEXT,\n `edge id column \"${column.meta.name}\" is ${column.dtype}; GraphML edge ids read back as strings`,\n column.meta.name,\n snapshot.edgeCount - column.nullCount,\n );\n }\n const bad = countBadEdgeIds(column);\n if (bad === 0) {\n return;\n }\n if (options.sanitizeIds === \"mangle\") {\n note(LOSS.ID_MANGLED, `${bad} edge id(s) outside the nmtoken charset are rewritten`, column.meta.name, bad);\n } else {\n note(\n LOSS.ID_CHARSET,\n `${bad} edge id(s) outside the nmtoken charset; export() will throw unless sanitizeIds is \"mangle\"`,\n column.meta.name,\n bad,\n );\n }\n}\n\n/**\n * The top-level edgedefault: the override, else undirected for an undirected snapshot, else\n * directed when no written edge is undirected, else the one the importer recorded, else the\n * majority direction.\n * @param snapshot - the snapshot\n * @param folding - the pair folding\n * @param format - the resolved format options\n * @param meta - the importer's meta, or null\n * @returns the edgedefault\n */\nfunction planEdgedefault(\n snapshot: GraphSnapshot,\n folding: PairFolding,\n format: FormatOptions,\n meta: GraphmlMeta | null,\n): \"directed\" | \"undirected\" {\n if (format.edgedefault !== null) {\n return format.edgedefault;\n }\n if (!snapshot.directed) {\n return \"undirected\";\n }\n let directedCount = 0;\n let undirectedCount = 0;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n if (isDirectedEdge(folding, e)) {\n directedCount++;\n } else {\n undirectedCount++;\n }\n }\n if (undirectedCount === 0) {\n return \"directed\";\n }\n const recorded = meta === null ? null : meta.edgedefault;\n if (recorded !== null) {\n return recorded;\n }\n return undirectedCount > directedCount ? \"undirected\" : \"directed\";\n}\n\n/**\n * Whether two column plans can share one for=\"all\" key.\n * @param a - one plan\n * @param b - another\n * @returns true when name, type and default agree\n */\nfunction sameKey(a: ColumnPlan, b: ColumnPlan): boolean {\n return (\n a.attrName === b.attrName &&\n a.attrType === b.attrType &&\n a.yfilesType === b.yfilesType &&\n a.domain !== b.domain &&\n JSON.stringify(a.column.meta.default ?? null) === JSON.stringify(b.column.meta.default ?? null)\n );\n}\n\n/**\n * Classify the columns of one table: which are written as keys and what each loses. A label\n * column is written into the label slot (a key titled `label`, which the importer reads back\n * with the role) unless the table holds another column of that name, in which case it keeps\n * its own title and the role is lost.\n * @param table - the table\n * @param domain - its domain\n * @param notes - the notes so far (the generic name-change note of a label column that cannot take the slot is withdrawn)\n * @param note - the note recorder\n * @returns the plans of the written columns, in declaration order\n */\nfunction planTable(table: Iterable<Column>, domain: Domain, notes: LossNote[], note: NoteFn): ColumnPlan[] {\n const plans: ColumnPlan[] = [];\n const columns = [...table];\n const names = new Set(columns.map((column) => column.meta.name));\n for (const column of columns) {\n const { meta } = column;\n const { role, name } = meta;\n if (isGraphicsColumn(meta)) {\n const stale = domain === \"graph\" ? 0 : staleGraphicsRows(column, columns, domain);\n if (stale > 0) {\n note(\n GRAPHML_LOSS.YFILES_GRAPHICS_STALE,\n `${stale} value(s) of ${domain} column \"${name}\" differ from the yFiles tree it was read from; only the tree is written, so they are lost`,\n name,\n stale,\n );\n }\n continue;\n }\n if (role === \"parents\") {\n note(\n GRAPHML_LOSS.PARENTS_DROPPED,\n `${domain} column \"${name}\" (parents) cannot be written: nested graphs hold one parent per node`,\n name,\n column.length - column.nullCount,\n );\n continue;\n }\n if (\n role !== null &&\n (STRUCTURAL_ROLES.has(role) || DROPPED_ROLES.has(role) || SLOT_ROLES_BY_DOMAIN[domain].has(role))\n ) {\n continue;\n }\n if (role !== null && role !== \"label\" && SLOT_ROLES.has(role)) {\n // the slot belongs to another domain (an edge id on a node, a port on a graph)\n withdrawNameChange(notes, name);\n note(\n LOSS.ROLE,\n `${domain} column \"${name}\" (${role}) is written as a plain attribute; GraphML has no ${role} slot for a ${domain} and the role is lost`,\n name,\n column.length - column.nullCount,\n );\n }\n const yfiles = meta.dtype === \"json\" && meta.origin?.namespace === \"yfiles\";\n if (meta.dtype === \"json\" && !yfiles) {\n note(\n LOSS.JSON,\n `${domain} column \"${name}\" holds nested values; written as JSON text, which reads back as string`,\n name,\n column.length - column.nullCount,\n );\n }\n if (yfiles) {\n const bad = countBadTrees(column);\n if (bad > 0) {\n note(\n GRAPHML_LOSS.YFILES_TREE,\n `${bad} value(s) of yfiles column \"${name}\" are not XML trees; export() will throw E_COLUMN_TYPE`,\n name,\n bad,\n );\n }\n }\n const { origin } = meta;\n const fromGraphml = origin !== null && origin.format === FORMAT;\n let attrName: string | null = null;\n if (!yfiles) {\n attrName = fromGraphml && origin.title !== null ? origin.title : name;\n if (role === \"label\" && domain !== \"graph\" && attrName !== LABEL_COLUMN) {\n attrName = labelSlot(column, domain, names, notes, note);\n } else if (role === null && domain !== \"graph\" && attrName === LABEL_COLUMN) {\n note(\n LOSS.ROLE_ASSUMED,\n `${domain} column \"${name}\" has no role but is titled \"${LABEL_COLUMN}\", which the importer reads back with the label role`,\n name,\n column.length - column.nullCount,\n );\n }\n }\n plans.push({\n column,\n domain,\n keyId: \"\",\n attrType: yfiles ? null : attrTypeFor(column),\n attrName,\n yfilesType: yfiles ? (origin?.type ?? DEFAULT_YFILES_TYPES[domain]) : null,\n yfiles,\n });\n }\n return plans;\n}\n\n/**\n * The title a label column not named `label` is written under: the label slot when the table has\n * no other column of that name (checkCapabilities() has noted the name change), else its own\n * name with the role lost (the name-change note is withdrawn and a role note recorded).\n * @param column - the label column\n * @param domain - its domain\n * @param names - the column names of the table\n * @param notes - the notes so far\n * @param note - the note recorder\n * @returns the attr.name\n */\nfunction labelSlot(\n column: Column,\n domain: Domain,\n names: ReadonlySet<string>,\n notes: LossNote[],\n note: NoteFn,\n): string {\n const { name } = column.meta;\n if (!names.has(LABEL_COLUMN)) {\n return LABEL_COLUMN;\n }\n withdrawNameChange(notes, name);\n note(\n LOSS.ROLE,\n `${domain} column \"${name}\" (label) is written as a plain attribute: the label slot (a key titled \"${LABEL_COLUMN}\") is taken by column \"${LABEL_COLUMN}\" and the role is lost`,\n name,\n column.length - column.nullCount,\n );\n return name;\n}\n\n/**\n * Withdraw the name-change note checkCapabilities() recorded for a role column that does not\n * take the slot after all.\n * @param notes - the notes so far\n * @param name - the column name\n */\nfunction withdrawNameChange(notes: LossNote[], name: string): void {\n const at = notes.findIndex((n) => n.code === LOSS.COLUMN_NAME_CHANGED && n.column === name);\n if (at >= 0) {\n notes.splice(at, 1);\n }\n}\n\n/**\n * The attr.type a column is declared with: the GraphML origin.type when it still describes the\n * column, else the type of the dtype (u32 / u8 as int or long, dict as string, list / json /\n * multi-component as string holding JSON text).\n * @param column - the column\n * @returns the attr.type text\n */\nfunction attrTypeFor(column: Column): string {\n const { meta } = column;\n const { origin } = meta;\n const declared = origin !== null && origin.format === FORMAT && origin.type !== null ? origin.type : null;\n if (meta.components > 1) {\n return \"string\";\n }\n switch (meta.dtype) {\n case \"bool\":\n return \"boolean\";\n case \"i32\":\n return \"int\";\n case \"f32\":\n return \"float\";\n case \"f64\": {\n if (declared !== null && declared.trim().toLowerCase() === \"long\" && columnIntegral(column)) {\n return \"long\";\n }\n return \"double\";\n }\n case \"u8\":\n return \"int\";\n case \"u32\":\n return columnMax(column) <= I32_MAX ? \"int\" : \"long\";\n case \"string\":\n if (declared !== null && TYPE_DTYPES[declared.trim().toLowerCase()] === undefined) {\n // an unknown declared type kept as text (W_UNKNOWN_ATTR_TYPE on import) is restored as declared\n return declared;\n }\n return \"string\";\n case \"dict\":\n case \"list\":\n case \"json\":\n return \"string\";\n default: {\n const { dtype } = meta;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dtype ${String(dtype)}`, { dtype });\n }\n }\n}\n\n/**\n * Whether every set value of a numeric column is an integer.\n * @param column - an f64 column\n * @returns true when all set values are integral\n */\nfunction columnIntegral(column: Column): boolean {\n if (column.dtype !== \"f64\") {\n return false;\n }\n const { data } = column;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && !Number.isInteger(data[r])) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * The largest set value of a u32 column.\n * @param column - a u32 column\n * @returns the maximum, 0 for an empty column\n */\nfunction columnMax(column: Column): number {\n if (column.dtype !== \"u32\") {\n return 0;\n }\n let max = 0;\n const { data } = column;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && data[r] > max) {\n max = data[r];\n }\n }\n return max;\n}\n\n/**\n * Whether every explicit weight is integral (so a declared int / long weight key survives).\n * @param snapshot - the snapshot\n * @param weights - the explicit weights\n * @returns true when all explicit weights are integers\n */\nfunction weightsIntegral(snapshot: GraphSnapshot, weights: ExplicitWeights): boolean {\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (weights.isExplicit(e) && !Number.isInteger(weights.value(e))) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * How many values of a yfiles column are not serialisable trees.\n * @param column - a json column\n * @returns the count\n */\nfunction countBadTrees(column: Column): number {\n if (column.dtype !== \"json\") {\n return 0;\n }\n let bad = 0;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && treeProblem(column.values[r]) !== null) {\n bad++;\n }\n }\n return bad;\n}\n\n/**\n * Node ids that read back as another type under the canonical rule: string ids that are\n * canonical integer text, and numbers that are not safe integers.\n * @param snapshot - the snapshot\n * @returns the count\n */\nfunction countIdTypeChanges(snapshot: GraphSnapshot): number {\n const { ids } = snapshot;\n if (ids.kind === \"identity\" || ids.kind === \"dense\") {\n return 0;\n }\n let count = 0;\n for (let i = 0; i < ids.size; i++) {\n const id = ids.idOf(i);\n if (typeof id === \"string\" ? isNmtoken(id) && isCanonicalIntegerText(id) : !Number.isSafeInteger(id)) {\n count++;\n }\n }\n return count;\n}\n\n/**\n * Node ids the nmtoken charset cannot hold.\n * @param snapshot - the snapshot\n * @returns the count\n */\nfunction countUnrepresentableNodeIds(snapshot: GraphSnapshot): number {\n const { ids } = snapshot;\n if (ids.kind === \"identity\" || ids.kind === \"dense\") {\n return 0;\n }\n let count = 0;\n for (let i = 0; i < ids.size; i++) {\n if (!isNmtoken(String(ids.idOf(i)))) {\n count++;\n }\n }\n return count;\n}\n\n/**\n * Edge ids that are not NMTOKENs.\n * @param column - the edge id column\n * @returns the count\n */\nfunction countBadEdgeIds(column: Column): number {\n let bad = 0;\n for (let e = 0; e < column.length; e++) {\n if (column.isSet(e) && !isNmtoken(edgeIdText(column, e))) {\n bad++;\n }\n }\n return bad;\n}\n\n/**\n * The text of an edge id cell.\n * @param column - the edge id column\n * @param e - the edge\n * @returns the id as text\n */\nfunction edgeIdText(column: Column, e: number): string {\n const value = column.value(e);\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\") {\n return Number.isInteger(value) ? formatInteger(value) : formatF64(value);\n }\n return String(value);\n}\n\n/**\n * Whether a logical edge is written as directed: never in an undirected snapshot; never for a\n * half of an expanded pair (an undirected or a mutual source edge, whose halves the resolver\n * flags directed); otherwise per the directed role column, with directed as the default.\n * @param folding - the pair folding\n * @param e - the edge\n * @returns false for a paired edge or an edge flagged undirected\n */\nfunction isDirectedEdge(folding: PairFolding, e: number): boolean {\n return folding.mateOf(e) === INVALID_INDEX && folding.sourceDirected(e);\n}\n\n/**\n * The containment order: the children CSR over the parent column (src/children.ts), roots in\n * index order, unreachable nodes (cycles) forced to the top level.\n * @param snapshot - the snapshot\n * @returns the hierarchy\n */\nfunction planHierarchy(snapshot: GraphSnapshot): Hierarchy {\n const parent = snapshot.nodes.byRole(\"parent\");\n const csr = childrenCsr(snapshot, { column: parent !== null && parent.dtype === \"u32\" ? parent : null });\n const walk = csr.depthFirst();\n // the top-level nodes in written order: the roots, then the cycle members forced out\n const roots = walk.order.filter((u) => walk.depth[u] === 0);\n return {\n parent: csr.column,\n roots,\n childStart: csr.rowPtr,\n childList: csr.children,\n reordered: walk.reordered,\n unreachable: csr.unreachable,\n };\n}\n\n// ============================================================ writing\n\n/**\n * The text of one set cell for a `<data>` element or a `<default>`.\n * @param column - the column\n * @param row - the row\n * @param attrType - the declared attr.type\n * @returns the text\n */\nfunction cellText(column: Column, row: number, attrType: string | null): string {\n if (column.meta.components > 1) {\n const value = column.value(row);\n return JSON.stringify(Array.from(value as ArrayLike<number>));\n }\n switch (column.dtype) {\n case \"bool\":\n return column.value(row) === true ? \"true\" : \"false\";\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return String(column.data[row]);\n case \"f32\":\n return formatF32(column.data[row]);\n case \"f64\": {\n const value = column.data[row];\n return (attrType === \"long\" || attrType === \"int\") && Number.isInteger(value)\n ? formatInteger(value)\n : formatF64(value);\n }\n case \"string\":\n return column.valueAt(row);\n case \"dict\":\n return column.dictionary[column.codes[row]];\n case \"list\":\n return JSON.stringify(Array.from(column.sliceOf(row)));\n case \"json\":\n return JSON.stringify(column.values[row]) ?? \"\";\n default: {\n const dtype: never = column;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dtype ${String(dtype)}`, {});\n }\n }\n}\n\n/**\n * The text of a declared default.\n * @param column - the column\n * @param attrType - the declared attr.type\n * @returns the text, or null when the column has no default\n */\nfunction defaultText(column: Column, attrType: string | null): string | null {\n const value = column.meta.default;\n if (value === undefined) {\n return null;\n }\n switch (typeof value) {\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"number\":\n if (column.dtype === \"f32\") {\n return formatF32(value);\n }\n return (attrType === \"long\" || attrType === \"int\") && Number.isInteger(value)\n ? formatInteger(value)\n : formatF64(value);\n case \"string\":\n return value;\n default:\n return JSON.stringify(value) ?? \"\";\n }\n}\n\n/**\n * Write one `<data>` element.\n * @param plan - the column plan\n * @param row - the row\n * @param indent - the indentation\n * @param out - receives the parts\n */\nfunction writeData(plan: ColumnPlan, row: number, indent: string, out: string[]): void {\n const { column } = plan;\n if (!column.isSet(row)) {\n return;\n }\n if (plan.yfiles && column.dtype === \"json\") {\n writeTreeData(plan.keyId, column.values[row], indent, out);\n return;\n }\n out.push(`\\n${indent}<data key=\"${plan.keyId}\">${escapeXmlText(cellText(column, row, plan.attrType))}</data>`);\n}\n\n/**\n * Write a `<data>` holding a yfiles tree.\n * @param keyId - the key id\n * @param value - the tree\n * @param indent - the indentation\n * @param out - receives the parts\n */\nfunction writeTreeData(keyId: string, value: unknown, indent: string, out: string[]): void {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n const parts: string[] = [];\n writeXmlTree(value, indent, parts);\n out.push(`\\n${indent}<data key=\"${keyId}\">${parts.join(\"\")}</data>`);\n return;\n }\n out.push(`\\n${indent}<data key=\"${keyId}\">`);\n writeXmlTree(value, `${indent} `, out);\n out.push(`\\n${indent}</data>`);\n}\n\n/**\n * The `<key>` element of a plan.\n * @param key - the key plan\n * @param indent - the indentation\n * @returns the element text\n */\nfunction keyElement(key: KeyPlan, indent: string): string {\n const domain = key.domains.length === 3 ? \"all\" : key.domains[0];\n let text = `${indent}<key id=\"${escapeXmlAttribute(key.id)}\" for=\"${domain}\"`;\n if (key.attrName !== null) {\n text += ` attr.name=\"${escapeXmlAttribute(key.attrName)}\"`;\n }\n if (key.attrType !== null) {\n text += ` attr.type=\"${escapeXmlAttribute(key.attrType)}\"`;\n }\n if (key.yfilesType !== null) {\n text += ` yfiles.type=\"${escapeXmlAttribute(key.yfilesType)}\"`;\n }\n const { column } = key;\n const desc = column?.meta.extra.desc;\n const hasDefault = column !== null && column.meta.default !== undefined;\n if (column === null || (typeof desc !== \"string\" && !hasDefault)) {\n return `${text}/>\\n`;\n }\n const parts: string[] = [`${text}>`];\n const inner = `${indent} `;\n if (typeof desc === \"string\") {\n parts.push(`\\n${inner}<desc>${escapeXmlText(desc)}</desc>`);\n }\n if (hasDefault) {\n if (key.yfilesType !== null) {\n const value = column.meta.default;\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n parts.push(`\\n${inner}<default>`);\n writeXmlTree(value, `${inner} `, parts);\n parts.push(`\\n${inner}</default>`);\n } else {\n const tree: string[] = [];\n writeXmlTree(value, inner, tree);\n parts.push(`\\n${inner}<default>${tree.join(\"\")}</default>`);\n }\n } else {\n parts.push(`\\n${inner}<default>${escapeXmlText(defaultText(column, key.attrType) ?? \"\")}</default>`);\n }\n }\n parts.push(`\\n${indent}</key>\\n`);\n return parts.join(\"\");\n}\n\n/**\n * Sanitised edge ids: NMTOKENs as they are; the rest refused or mangled per sanitizeIds.\n * @param column - the edge id column, or null\n * @param mode - the resolved sanitizeIds option\n * @param edgeCount - the edge count\n * @returns the id text per edge (null for edges without one)\n */\nfunction sanitizeEdgeIds(column: Column | null, mode: \"error\" | \"mangle\", edgeCount: number): (string | null)[] {\n const out: (string | null)[] = new Array<string | null>(edgeCount).fill(null);\n if (column === null) {\n return out;\n }\n const used = new Set<string>();\n const bad: number[] = [];\n for (let e = 0; e < edgeCount; e++) {\n if (!column.isSet(e)) {\n continue;\n }\n const text = edgeIdText(column, e);\n if (isNmtoken(text)) {\n out[e] = text;\n used.add(text);\n } else {\n bad.push(e);\n }\n }\n if (bad.length > 0 && mode === \"error\") {\n throw new GraphFormatError(\n \"E_INVALID_ID\",\n `${bad.length} edge id(s) cannot be written as nmtoken (first: ${JSON.stringify(edgeIdText(column, bad[0]))} at edge ${bad[0]}); pass sanitizeIds: \"mangle\" to rewrite them`,\n { reason: \"charset\", charset: \"nmtoken\", count: bad.length, edge: bad[0] },\n );\n }\n for (const e of bad) {\n const base = mangleNmtoken(edgeIdText(column, e));\n let candidate = base;\n for (let k = 2; used.has(candidate); k++) {\n candidate = `${base}_${k}`;\n }\n used.add(candidate);\n out[e] = candidate;\n }\n return out;\n}\n\n/**\n * The document as text parts.\n * @param snapshot - the snapshot\n * @param plan - the plan\n * @yields one element (or a group of small ones) at a time\n * @returns nothing\n */\nfunction* writeGraphml(snapshot: GraphSnapshot, plan: Plan): Generator<string, void, undefined> {\n const ids: SanitizedIds = sanitizeIds(snapshot, \"nmtoken\", plan.options.sanitizeIds);\n const edgeIds = sanitizeEdgeIds(plan.edgeIdColumn, plan.options.sanitizeIds, snapshot.edgeCount);\n const i1 = plan.pretty ? \" \" : \"\";\n const i2 = plan.pretty ? \" \" : \"\";\n const i3 = plan.pretty ? \" \" : \"\";\n const step = plan.pretty ? \" \" : \"\";\n\n yield '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n let root = `<graphml xmlns=\"${GRAPHML_NAMESPACE}\"`;\n const namespaces: Record<string, string> = { ...(plan.meta?.namespaces ?? {}) };\n if (\n (plan.nodeColumns.some((c) => c.yfiles) ||\n plan.edgeColumns.some((c) => c.yfiles) ||\n plan.graphColumns.some((c) => c.yfiles)) &&\n !Object.values(namespaces).includes(YFILES_NAMESPACE)\n ) {\n namespaces.y = YFILES_NAMESPACE;\n }\n if (!Object.values(namespaces).includes(XSI_NAMESPACE)) {\n namespaces.xsi = XSI_NAMESPACE;\n }\n for (const [prefix, uri] of Object.entries(namespaces)) {\n root += ` xmlns:${prefix}=\"${escapeXmlAttribute(uri)}\"`;\n }\n const xsiPrefix = Object.entries(namespaces).find(([, uri]) => uri === XSI_NAMESPACE)?.[0] ?? \"xsi\";\n root += ` ${xsiPrefix}:schemaLocation=\"${SCHEMA_LOCATION}\">\\n`;\n yield root;\n\n for (const key of plan.keys) {\n yield keyElement(key, i1);\n }\n if (plan.originalIdKey !== null) {\n yield `${i1}<key id=\"${plan.originalIdKey}\" for=\"node\" attr.name=\"${ORIGINAL_ID_ATTRIBUTE}\" attr.type=\"string\"/>\\n`;\n }\n\n const graphId = plan.meta?.graphId ?? \"G\";\n yield `${i1}<graph id=\"${escapeXmlAttribute(graphId)}\" edgedefault=\"${plan.edgedefault}\">`;\n const { description } = snapshot.meta;\n if (description !== null) {\n yield `\\n${i2}<desc>${escapeXmlText(description)}</desc>`;\n }\n const graphParts: string[] = [];\n for (const column of plan.graphColumns) {\n writeData(column, 0, i2, graphParts);\n }\n if (graphParts.length > 0) {\n yield graphParts.join(\"\");\n }\n\n // nodes in containment order, children nested under their parent\n const { hierarchy } = plan;\n const nested = hierarchy.childList.length > 0;\n const stackNode: number[] = [];\n const stackCursor: number[] = [];\n const written = nested ? new Uint8Array(snapshot.nodeCount) : null;\n for (const rootNode of hierarchy.roots) {\n yield* writeNodeSubtree(rootNode, plan, ids, i2, step, stackNode, stackCursor, written);\n }\n\n // edges: primaries only, in index order\n const list = snapshot.edgeList();\n const { folding } = plan;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n const parts: string[] = [`\\n${i2}<edge`];\n const id = edgeIds[e];\n if (id !== null) {\n parts.push(` id=\"${escapeXmlAttribute(id)}\"`);\n }\n parts.push(\n ` source=\"${escapeXmlAttribute(String(ids.idAt(list.src[e])))}\" target=\"${escapeXmlAttribute(String(ids.idAt(list.dst[e])))}\"`,\n );\n const directed = snapshot.directed && isDirectedEdge(folding, e);\n if (directed !== (plan.edgedefault === \"directed\")) {\n parts.push(` directed=\"${directed ? \"true\" : \"false\"}\"`);\n }\n const sourcePort = portText(plan.sourcePortColumn, e);\n if (sourcePort !== null) {\n parts.push(` sourceport=\"${escapeXmlAttribute(sourcePort)}\"`);\n }\n const targetPort = portText(plan.targetPortColumn, e);\n if (targetPort !== null) {\n parts.push(` targetport=\"${escapeXmlAttribute(targetPort)}\"`);\n }\n const open = parts.length;\n if (plan.weight !== null) {\n const { keyId, attrType } = plan.weight;\n const weight = plan.weight.weights.text(e, attrType === \"int\" || attrType === \"long\");\n if (weight !== null) {\n parts.push(`\\n${i3}<data key=\"${keyId}\">${escapeXmlText(weight)}</data>`);\n }\n }\n for (const column of plan.edgeColumns) {\n writeData(column, e, i3, parts);\n }\n if (parts.length === open) {\n parts.push(\"/>\");\n } else {\n parts.splice(open, 0, \">\");\n parts.push(`\\n${i2}</edge>`);\n }\n yield parts.join(\"\");\n }\n\n yield `\\n${i1}</graph>\\n</graphml>\\n`;\n}\n\n/**\n * The text of a port reference cell.\n * @param column - the sourcePort / targetPort column, or null\n * @param e - the edge\n * @returns the port name, or null when unset\n */\nfunction portText(column: Column | null, e: number): string | null {\n if (column === null || !column.isSet(e)) {\n return null;\n }\n const value = column.value(e);\n return typeof value === \"string\" ? value : String(value);\n}\n\n/**\n * Write a top-level node and, nested, every node contained in it (iteratively, so a deep chain\n * cannot overflow the call stack).\n * @param root - the top-level node\n * @param plan - the plan\n * @param ids - the sanitised ids\n * @param indent - the indentation of top-level nodes\n * @param step - one indentation step\n * @param stackNode - a reusable stack of open nodes\n * @param stackCursor - a reusable stack of child cursors\n * @param written - nodes already written (null when nothing is nested)\n * @yields the node elements\n * @returns nothing\n */\nfunction* writeNodeSubtree(\n root: number,\n plan: Plan,\n ids: SanitizedIds,\n indent: string,\n step: string,\n stackNode: number[],\n stackCursor: number[],\n written: Uint8Array | null,\n): Generator<string, void, undefined> {\n const { hierarchy } = plan;\n const hasChildren = (u: number): boolean => hierarchy.childStart[u + 1] > hierarchy.childStart[u];\n const openNode = (u: number, depth: number): string => {\n const pad = indent + step.repeat(depth * 2);\n const parts: string[] = [`\\n${pad}<node id=\"${escapeXmlAttribute(String(ids.idAt(u)))}\"`];\n const open = parts.length;\n if (plan.originalIdKey !== null && ids.isChanged(u)) {\n parts.push(\n `\\n${pad}${step}<data key=\"${plan.originalIdKey}\">${escapeXmlText(String(ids.originalAt(u)))}</data>`,\n );\n }\n for (const column of plan.nodeColumns) {\n writeData(column, u, pad + step, parts);\n }\n if (hasChildren(u)) {\n parts.splice(open, 0, \">\");\n parts.push(\n `\\n${pad}${step}<graph id=\"${escapeXmlAttribute(`${String(ids.idAt(u))}:`)}\" edgedefault=\"${plan.edgedefault}\">`,\n );\n return parts.join(\"\");\n }\n if (parts.length === open) {\n parts.push(\"/>\");\n } else {\n parts.splice(open, 0, \">\");\n parts.push(`\\n${pad}</node>`);\n }\n return parts.join(\"\");\n };\n const closeNode = (depth: number): string => {\n const pad = indent + step.repeat(depth * 2);\n return `\\n${pad}${step}</graph>\\n${pad}</node>`;\n };\n if (written !== null) {\n written[root] = 1;\n }\n yield openNode(root, 0);\n if (!hasChildren(root)) {\n return;\n }\n stackNode.push(root);\n stackCursor.push(hierarchy.childStart[root]);\n while (stackNode.length > 0) {\n const top = stackNode.length - 1;\n const u = stackNode[top];\n const cursor = stackCursor[top];\n if (cursor >= hierarchy.childStart[u + 1]) {\n stackNode.pop();\n stackCursor.pop();\n yield closeNode(top);\n continue;\n }\n stackCursor[top] = cursor + 1;\n const v = hierarchy.childList[cursor];\n if (written !== null && written[v] === 1) {\n continue;\n }\n if (written !== null) {\n written[v] = 1;\n }\n yield openNode(v, top + 1);\n if (hasChildren(v)) {\n stackNode.push(v);\n stackCursor.push(hierarchy.childStart[v]);\n }\n }\n}\n\n/**\n * The GraphML exporter (design section 8.5).\n */\nexport const graphmlExporter: GraphExporter<GraphmlExportOptions> = Object.freeze({\n format: FORMAT,\n capabilities: CAPABILITIES,\n /**\n * Pre-flight: every loss the export would incur.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the notes\n */\n check(snapshot: GraphSnapshot, options?: GraphmlExportOptions & CommonExportOptions): readonly LossNote[] {\n const plan = planExport(snapshot, resolveExportOptions(options), resolveFormatOptions(options));\n return Object.freeze(plan.notes);\n },\n /**\n * Write the document as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: GraphmlExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n const plan = planExport(snapshot, resolveExportOptions(options), resolveFormatOptions(options));\n return encodeChunks(writeGraphml(snapshot, plan));\n },\n /**\n * Write the document as one string.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: GraphmlExportOptions & CommonExportOptions): Promise<string> {\n const plan = planExport(snapshot, resolveExportOptions(options), resolveFormatOptions(options));\n return joinText(writeGraphml(snapshot, plan));\n },\n});\n","/**\n * The GraphML importer (design sections 8.4 and 5.1; research note 07 section 2.3): a single-pass\n * SAX-style reader over the streaming XML tokenizer that pushes scalars into the sink as elements\n * close. `<key>` declarations become typed columns up front (boolean / int / long / float / double\n * / string, with `<default>`, for the node, edge and graph domains; `for=\"all\"` declares in all\n * three with the same origin.id); `edgedefault` and per-edge `directed` go through the common\n * DirectionResolver; a nested `<graph>` inside a node becomes the `parent` column (containment,\n * never topology); `<port>` declarations and `<locator>` elements are reported and dropped while\n * `sourceport` / `targetport` edge attributes are kept as role columns; hyperedges follow the\n * `hyperedges` option (refuse, skip with a report entry, star, clique); yFiles `yfiles.type` keys\n * become `json` columns holding the nested XML as a tree (origin.namespace \"yfiles\"), reported as\n * a loss note because the structure, not the bytes, is preserved; a `y:ShapeNode` or\n * `y:PolyLineEdge` in such a tree is also read into typed `yfiles.*` columns (yfiles.ts).\n *\n * Ids are coerced with the common rule (`ids: \"canonical\"` by default, design section 4.1); the\n * edge attribute whose `attr.name` is `weightFrom` (\"weight\" by default) is THE weight and is\n * passed to `addEdge` rather than stored as a column, with its declaration kept in\n * `meta.weightOrigin`; a node key named `graphty:originalId` restores ids the exporter mangled.\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n GraphFormatError,\n type GraphSink,\n INVALID_INDEX,\n MAX_COUNT,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport {\n declareAttribute,\n type DeclaredAttribute,\n declareResolved,\n losesPrecision,\n parseDeclaredValue,\n PRECISION_CODE,\n takenIn,\n uniqueColumnName,\n} from \"../../common/attributes.js\";\nimport { type DeclaredTypeSpec } from \"../../common/declared-types.js\";\nimport { DirectionResolver, type EdgeKind } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { textChunks, throwIfAborted } from \"../../common/input.js\";\nimport { type ListSyntax } from \"../../common/lists.js\";\nimport {\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { isWeightField, parseWeightText } from \"../../common/weights.js\";\nimport {\n isWhitespace,\n localName,\n tokenizeXml,\n xmlDeclaredEncoding,\n type XmlHandler,\n XmlSyntaxError,\n} from \"../../common/xml.js\";\nimport { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from \"../../types.js\";\nimport {\n EDGE_ID_COLUMN,\n EXTENSIONS,\n FORMAT,\n GRAPHML_ISSUE,\n GRAPHML_LOSS,\n GRAPHML_NAMESPACE,\n type GraphmlMeta,\n HYPEREDGE_HUB_COLUMN,\n LABEL_COLUMN,\n META_KEY,\n MIME_TYPES,\n ORIGINAL_ID_ATTRIBUTE,\n ORIGINAL_ID_COLUMN,\n PARENT_COLUMN,\n RESERVED_EDGE_NAMES,\n RESERVED_NODE_NAMES,\n SOURCE_PORT_COLUMN,\n TARGET_PORT_COLUMN,\n XSI_NAMESPACE,\n} from \"./constants.js\";\nimport { XmlTreeBuilder } from \"./tree.js\";\nimport { graphicsDecl, graphicsValues } from \"./yfiles.js\";\n\n/** The XML attributes the importer reads on `<graph>`, `<node>` and `<edge>`; any other is reported. */\nconst GRAPH_ATTRIBUTES: ReadonlySet<string> = new Set([\"id\", \"edgedefault\", \"parse.nodes\", \"parse.edges\"]);\nconst NODE_ATTRIBUTES: ReadonlySet<string> = new Set([\"id\"]);\nconst EDGE_ATTRIBUTES: ReadonlySet<string> = new Set([\n \"id\",\n \"source\",\n \"target\",\n \"directed\",\n \"sourceport\",\n \"targetport\",\n]);\n\n/** The format-specific options of the GraphML importer. */\nexport interface GraphmlImportOptions {\n /**\n * How keys with a `yfiles.type` (yEd / yFiles graphics) are read: \"json\" (default) keeps the\n * nested XML of each `<data>` as a json column with origin.namespace \"yfiles\"; \"skip\" reports\n * them once and declares nothing.\n */\n yfiles?: \"json\" | \"skip\" | undefined;\n}\n\n/** The per-format defaults of design section 8.4: text-cell ids, undirected when edgedefault is missing, weight key. */\nconst FORMAT_DEFAULTS: ImportFormatDefaults = { ids: \"canonical\", defaultDirected: false, weightFrom: \"weight\" };\n\n/** Bytes inspected by sniff(). */\nconst SNIFF_BYTES = 4096;\n\nconst YFILES_MODES: ReadonlySet<string> = new Set([\"json\", \"skip\"]);\n\n/** Elements between two checks of the cancellation signal. */\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The common options the GraphML importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"long\",\n \"restoreMangledIds\",\n \"hyperedges\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** Where the reader is, by the innermost open element. */\nconst enum Ctx {\n Graphml,\n Desc,\n Key,\n Default,\n Graph,\n Node,\n Edge,\n Hyperedge,\n Data,\n Capture,\n Skip,\n}\n\n/** The element domains a key can be declared for. */\ntype Domain = \"graph\" | \"node\" | \"edge\";\n\n/** A declared column of one domain. */\ninterface ColumnTarget {\n /** The column name in its table. */\n readonly name: string;\n /** The handle (node / edge domains); INVALID_INDEX for the graph domain. */\n readonly handle: ColumnHandle;\n /** The declaration (graph domain, re-sent with every setGraphValue). */\n readonly decl: ColumnDecl;\n /** How text values are parsed; null for a json (yfiles) column. */\n readonly spec: DeclaredTypeSpec | null;\n /** The list syntax (unused by GraphML, which has no list type). */\n readonly listSyntax: ListSyntax;\n}\n\n/** One `<key>` after `</key>`. */\ninterface KeyEntry {\n readonly id: string;\n readonly name: string;\n readonly node: ColumnTarget | null;\n readonly edge: ColumnTarget | null;\n readonly graph: ColumnTarget | null;\n /** The edge domain of this key is THE weight. */\n readonly weight: boolean;\n /** The node domain of this key restores mangled ids. */\n readonly originalId: boolean;\n /** Whether the key holds yFiles nested XML. */\n readonly yfiles: boolean;\n /** Whether data of this key is silently ignored (yfiles: \"skip\"; already reported). */\n readonly skipped: boolean;\n /** The domains the key was declared for, for the mismatch warning. */\n readonly domains: readonly Domain[];\n}\n\n/** A `<key>` while its `<default>` and `<desc>` are being read. */\ninterface PendingKey {\n readonly id: string | null;\n readonly attrName: string | null;\n readonly attrType: string | null;\n readonly yfilesType: string | null;\n readonly domains: readonly Domain[];\n readonly line: number;\n desc: string;\n defaultText: string | null;\n defaultTree: unknown;\n}\n\n/** A `<node>` while open (nodes nest through nested graphs, so these stack). */\ninterface NodeState {\n /** The coerced id, or null when the element is unusable. */\n id: NodeId | null;\n /** The id attribute as written, for the mangled -> original map. */\n idText: string | null;\n /** The node index once added; INVALID_INDEX before. */\n index: number;\n /** The index of the containing node, or INVALID_INDEX at the top level. */\n readonly parent: number;\n /** Data values waiting for the node to be added: handle, value, handle, value... */\n readonly pending: unknown[];\n /** A `graphty:originalId` value, restored as the id. */\n restoredId: string | null;\n failed: boolean;\n readonly line: number;\n}\n\n/** The `<edge>` being read. */\ninterface EdgeState {\n source: NodeId | null;\n target: NodeId | null;\n id: string | null;\n kind: EdgeKind;\n sourcePort: string | null;\n targetPort: string | null;\n weight: number | undefined;\n readonly pending: unknown[];\n failed: boolean;\n line: number;\n}\n\n/** One `<endpoint>` of a hyperedge. */\ninterface Endpoint {\n readonly node: NodeId;\n readonly type: \"in\" | \"out\" | \"undir\";\n}\n\n/** The `<hyperedge>` being read. */\ninterface HyperedgeState {\n id: string | null;\n readonly endpoints: Endpoint[];\n failed: boolean;\n line: number;\n}\n\n/** The `<data>` or `<default>` being read. */\ninterface ContentState {\n key: KeyEntry | null;\n pendingKey: PendingKey | null;\n domain: Domain;\n text: string;\n tree: XmlTreeBuilder | null;\n line: number;\n}\n\n/** Where an issue was found. */\ninterface Where {\n /** The line. */\n readonly line: number;\n /** The element, or null. */\n readonly element: string | null;\n}\n\n/** One open `<graph>`. */\ninterface GraphState {\n readonly directed: boolean;\n readonly parent: number;\n}\n\n/**\n * A growable bit set over node indices, marking the indices declared by a `<node>` element so a\n * second declaration is reported and a node created by an edge reference is not.\n */\nclass IndexFlags {\n private words = new Uint32Array(64);\n\n /**\n * Whether an index is marked.\n * @param index - the node index\n * @returns true when set\n */\n has(index: number): boolean {\n const w = index >>> 5;\n return w < this.words.length && ((this.words[w] >>> (index & 31)) & 1) === 1;\n }\n\n /**\n * Mark an index.\n * @param index - the node index\n */\n add(index: number): void {\n const w = index >>> 5;\n if (w >= this.words.length) {\n let size = this.words.length * 2;\n while (size <= w) {\n size *= 2;\n }\n const grown = new Uint32Array(size);\n grown.set(this.words);\n this.words = grown;\n }\n this.words[w] |= 1 << (index & 31);\n }\n}\n\n/**\n * The event handler that turns the tokenizer's events into sink calls.\n */\nclass GraphmlReader implements XmlHandler {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly yfilesMode: \"json\" | \"skip\";\n\n private readonly coercer: IdCoercer;\n\n private readonly direction: DirectionResolver;\n\n private readonly ctx: Ctx[] = [];\n\n /** Keys by id; one id may be declared once per domain (igraph writes `name` for graph and node). */\n private readonly keys = new Map<string, KeyEntry[]>();\n\n private readonly graphs: GraphState[] = [];\n\n private readonly nodes: NodeState[] = [];\n\n private readonly declared = new IndexFlags();\n\n private readonly edgeIds = new Set<string>();\n\n private elementsSinceCheck = 0;\n\n /** Mangled id text -> the original id restored from `graphty:originalId`, for edge endpoints. */\n private readonly restored = new Map<string, NodeId>();\n\n private readonly graphColumnNames = new Set<string>();\n\n private pendingKey: PendingKey | null = null;\n\n private edge: EdgeState | null = null;\n\n private hyperedge: HyperedgeState | null = null;\n\n private readonly content: ContentState = {\n key: null,\n pendingKey: null,\n domain: \"node\",\n text: \"\",\n tree: null,\n line: 0,\n };\n\n private descTarget: \"graph\" | \"key\" | null = null;\n\n private descText = \"\";\n\n private description: string | null = null;\n\n private graphSeen = false;\n\n private graphId: string | null = null;\n\n private edgedefault: \"directed\" | \"undirected\" | null = null;\n\n private namespaces: Record<string, string> = {};\n\n private weightOrigin: { id: string; title: string | null; type: string | null } | null = null;\n\n private yfilesLossNoted = false;\n\n /** The mapped yFiles graphics columns declared so far, by domain and field. */\n private readonly graphicsColumns = new Map<string, ColumnHandle>();\n\n private hyperedgeCount = 0;\n\n private edgeIdHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private sourcePortHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private targetPortHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private parentHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private hubHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n /**\n * Create a reader for one import call.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param yfilesMode - the resolved yfiles option\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n yfilesMode: \"json\" | \"skip\",\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.yfilesMode = yfilesMode;\n this.coercer = new IdCoercer(options.ids);\n this.direction = new DirectionResolver(sink, report, options.onMixedDirection);\n }\n\n // ------------------------------------------------------------------ tokenizer events\n\n /**\n * An element starts.\n * @param name - the element name\n * @param attrs - its attributes\n * @param line - the line\n */\n start(name: string, attrs: ReadonlyMap<string, string>, line: number): void {\n const parent = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];\n switch (parent) {\n case Ctx.Capture:\n this.captureStart(name, attrs);\n return;\n case Ctx.Skip:\n case Ctx.Desc:\n this.ctx.push(Ctx.Skip);\n return;\n case Ctx.Data:\n case Ctx.Default:\n this.captureStart(name, attrs);\n return;\n default:\n break;\n }\n const local = localName(name);\n switch (parent) {\n case null:\n if (local !== \"graphml\") {\n this.report.fail(GRAPHML_ISSUE.NOT_GRAPHML, `the root element is <${name}>, not <graphml>`, {\n line,\n });\n }\n this.readRoot(attrs);\n this.ctx.push(Ctx.Graphml);\n return;\n case Ctx.Graphml:\n this.startInGraphml(name, local, attrs, line);\n return;\n case Ctx.Key:\n this.startInKey(name, local, line);\n return;\n case Ctx.Graph:\n this.startInGraph(name, local, attrs, line);\n return;\n case Ctx.Node:\n this.startInNode(name, local, attrs, line);\n return;\n case Ctx.Edge:\n this.startInEdge(name, local, attrs, line);\n return;\n case Ctx.Hyperedge:\n this.startInHyperedge(name, local, attrs, line);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * An element ends.\n * @param name - the element name\n * @param _line - the line (unused: issues of an element cite its start line)\n */\n end(name: string, _line: number): void {\n const ctx = this.ctx.pop();\n switch (ctx) {\n case Ctx.Capture:\n this.captureEnd();\n return;\n case Ctx.Skip:\n case Ctx.Graphml:\n case undefined:\n return;\n case Ctx.Desc:\n this.finishDesc();\n return;\n case Ctx.Key:\n this.finishKey();\n return;\n case Ctx.Default:\n this.finishDefault();\n return;\n case Ctx.Data:\n this.finishData();\n return;\n case Ctx.Node:\n this.finishNode();\n return;\n case Ctx.Edge:\n this.finishEdge();\n return;\n case Ctx.Hyperedge:\n this.finishHyperedge();\n return;\n case Ctx.Graph:\n this.graphs.pop();\n return;\n default: {\n const value: never = ctx;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown reader state ${String(value)}`, { name });\n }\n }\n }\n\n /**\n * Character data.\n * @param text - the text\n * @param line - the line\n */\n text(text: string, line: number): void {\n const ctx = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];\n switch (ctx) {\n case Ctx.Capture:\n this.content.tree?.text(text);\n return;\n case Ctx.Data:\n case Ctx.Default:\n if (this.content.tree === null) {\n this.content.text += text;\n } else {\n this.content.tree.text(text);\n }\n return;\n case Ctx.Desc:\n this.descText += text;\n return;\n case Ctx.Skip:\n return;\n default:\n if (!isWhitespace(text)) {\n this.report.warnOnce(\n \"validation-error\",\n GRAPHML_ISSUE.STRAY_TEXT,\n \"text where GraphML allows only elements was ignored\",\n { line },\n );\n }\n }\n }\n\n /**\n * After the last event: the document must have held a graph; the metadata is written.\n */\n finish(): void {\n if (!this.graphSeen) {\n this.report.fail(GRAPHML_ISSUE.NO_GRAPH, \"the document has no <graph> element\");\n }\n const meta: GraphmlMeta = { graphId: this.graphId, edgedefault: this.edgedefault, namespaces: this.namespaces };\n this.sink.setMeta({\n sourceFormat: FORMAT,\n description: this.description ?? undefined,\n weightOrigin:\n this.weightOrigin === null\n ? undefined\n : {\n format: FORMAT,\n id: this.weightOrigin.id,\n title: this.weightOrigin.title,\n type: this.weightOrigin.type,\n namespace: null,\n },\n extra: { [META_KEY]: meta },\n });\n }\n\n // ------------------------------------------------------------------ structure\n\n /**\n * Record the root element's namespace declarations.\n * @param attrs - the root attributes\n */\n private readRoot(attrs: ReadonlyMap<string, string>): void {\n for (const [key, value] of attrs) {\n if (key.startsWith(\"xmlns:\") && value !== GRAPHML_NAMESPACE && value !== XSI_NAMESPACE) {\n this.namespaces[key.slice(6)] = value;\n }\n }\n }\n\n /**\n * A child of `<graphml>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGraphml(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"desc\":\n this.beginDesc(\"graph\");\n return;\n case \"key\":\n this.beginKey(attrs, line);\n return;\n case \"graph\":\n this.beginGraph(attrs, line, INVALID_INDEX);\n return;\n case \"data\":\n this.beginData(attrs, line, \"graph\");\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<key>`.\n * @param name - the element name\n * @param local - its local name\n * @param line - the line\n */\n private startInKey(name: string, local: string, line: number): void {\n switch (local) {\n case \"desc\":\n this.beginDesc(\"key\");\n return;\n case \"default\":\n this.content.key = null;\n this.content.pendingKey = this.pendingKey;\n this.content.text = \"\";\n this.content.tree = null;\n this.content.line = line;\n this.ctx.push(Ctx.Default);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<graph>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGraph(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"desc\":\n if (this.graphs.length === 1) {\n this.beginDesc(\"graph\");\n } else {\n this.ctx.push(Ctx.Skip);\n }\n return;\n case \"data\":\n if (this.graphs.length === 1) {\n this.beginData(attrs, line, \"graph\");\n } else {\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.NESTED_GRAPH_DATA,\n \"data of a nested <graph> cannot be kept; only the top-level graph has attributes\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n }\n return;\n case \"node\":\n this.beginNode(attrs, line);\n return;\n case \"edge\":\n this.beginEdge(attrs, line);\n return;\n case \"hyperedge\":\n this.beginHyperedge(attrs, line);\n return;\n case \"locator\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.LOCATOR_DROPPED,\n \"<locator> references are not followed\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<node>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInNode(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"desc\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.DESC_DROPPED,\n \"node and edge <desc> texts are not kept\",\n {\n line,\n },\n );\n this.ctx.push(Ctx.Skip);\n return;\n case \"data\":\n this.beginData(attrs, line, \"node\");\n return;\n case \"port\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.PORT_DECLARATION,\n \"<port> declarations are not kept; sourceport / targetport edge attributes are\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n return;\n case \"graph\": {\n const node = this.nodes[this.nodes.length - 1];\n this.materializeNode(node);\n this.beginGraph(attrs, line, node.index);\n return;\n }\n case \"locator\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.LOCATOR_DROPPED,\n \"<locator> references are not followed\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<edge>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInEdge(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"desc\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.DESC_DROPPED,\n \"node and edge <desc> texts are not kept\",\n {\n line,\n },\n );\n this.ctx.push(Ctx.Skip);\n return;\n case \"data\":\n this.beginData(attrs, line, \"edge\");\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<hyperedge>` (under the star / clique policies).\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInHyperedge(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"endpoint\":\n this.readEndpoint(attrs, line);\n this.ctx.push(Ctx.Skip);\n return;\n case \"data\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.HYPEREDGE_DATA_DROPPED,\n \"hyperedge data are not kept by the star / clique expansions\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n return;\n case \"desc\":\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * Report an element the schema does not define at this place and skip its subtree.\n * @param name - the element name\n * @param line - the line\n */\n private unknownElement(name: string, line: number): void {\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.UNKNOWN_ELEMENT,\n `element <${name}> is not GraphML and was skipped`,\n {\n line,\n element: name,\n },\n );\n this.ctx.push(Ctx.Skip);\n }\n\n /**\n * Open a `<desc>`.\n * @param target - what the text describes\n */\n private beginDesc(target: \"graph\" | \"key\"): void {\n this.descTarget = target;\n this.descText = \"\";\n this.ctx.push(Ctx.Desc);\n }\n\n /** Close a `<desc>`. */\n private finishDesc(): void {\n const text = this.descText.trim();\n if (this.descTarget === \"key\" && this.pendingKey !== null) {\n this.pendingKey.desc = text;\n } else if (this.descTarget === \"graph\" && text.length > 0) {\n this.description = text;\n }\n this.descTarget = null;\n this.descText = \"\";\n }\n\n // ------------------------------------------------------------------ graphs\n\n /**\n * Report, once per element kind and attribute name, an XML attribute the importer does not read:\n * a GraphML `parse.*` hint as ignored, anything else as unknown. Namespace declarations and\n * `xml:` / `xsi:` attributes are not data and pass silently.\n * @param kind - the element name\n * @param attrs - the element's attributes\n * @param known - the attributes the importer reads on that element\n * @param line - the line\n */\n private reportUnreadAttributes(\n kind: string,\n attrs: ReadonlyMap<string, string>,\n known: ReadonlySet<string>,\n line: number,\n ): void {\n for (const name of attrs.keys()) {\n if (known.has(name) || name === \"xmlns\" || /^(xmlns|xml|xsi):/.test(name)) {\n continue;\n }\n const hint = name.startsWith(\"parse.\");\n const code = hint ? GRAPHML_ISSUE.PARSE_HINT_IGNORED : GRAPHML_ISSUE.UNKNOWN_XML_ATTRIBUTE;\n this.report.warnOnce(\n \"unsupported\",\n code,\n hint\n ? `the <${kind}> parse hint ${name} is ignored`\n : `the <${kind}> attribute ${name} is not a GraphML attribute; it is not kept`,\n { line, element: name },\n `${code}:${kind}:${name}`,\n );\n }\n }\n\n /**\n * Open a `<graph>`: the top-level one sets the sink's direction (rule 1 of design section\n * 8.4); a nested one records its container as the parent of its nodes.\n * @param attrs - the graph attributes\n * @param line - the line\n * @param parent - the containing node's index, or INVALID_INDEX\n */\n private beginGraph(attrs: ReadonlyMap<string, string>, line: number, parent: number): void {\n this.reportUnreadAttributes(\"graph\", attrs, GRAPH_ATTRIBUTES, line);\n const top = this.graphs.length === 0;\n const edgedefault = attrs.get(\"edgedefault\");\n let directed: boolean;\n if (edgedefault === \"directed\" || edgedefault === \"undirected\") {\n directed = edgedefault === \"directed\";\n } else if (edgedefault === undefined) {\n directed = top ? this.options.defaultDirected : this.graphs[this.graphs.length - 1].directed;\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.EDGEDEFAULT_MISSING,\n `<graph> has no edgedefault; read as ${directed ? \"directed\" : \"undirected\"}`,\n { line },\n );\n } else {\n directed = top ? this.options.defaultDirected : this.graphs[this.graphs.length - 1].directed;\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.INVALID_EDGEDEFAULT,\n `edgedefault \"${edgedefault}\" is neither directed nor undirected; read as ${directed ? \"directed\" : \"undirected\"}`,\n { line },\n );\n }\n if (top && this.graphSeen) {\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.MULTIPLE_GRAPHS,\n \"the document holds more than one top-level <graph>; their nodes and edges are merged into one graph\",\n { line, element: attrs.get(\"id\") ?? null },\n );\n } else if (top) {\n this.graphSeen = true;\n this.graphId = attrs.get(\"id\") ?? null;\n this.edgedefault = directed ? \"directed\" : \"undirected\";\n this.direction.setHeader(directed, { line });\n const nodes = this.hint(attrs.get(\"parse.nodes\"), \"parse.nodes\", line);\n const edges = this.hint(attrs.get(\"parse.edges\"), \"parse.edges\", line);\n if (nodes !== null || edges !== null) {\n try {\n this.sink.reserve(nodes ?? undefined, edges ?? undefined);\n } catch (err) {\n if (!(err instanceof GraphFormatError)) {\n throw err;\n }\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.COUNT_HINT,\n `count hint refused: ${err.message}`,\n {\n line,\n },\n );\n }\n }\n }\n this.graphs.push({ directed, parent });\n this.ctx.push(Ctx.Graph);\n }\n\n /**\n * A `parse.nodes` / `parse.edges` hint the sink can reserve; anything else is reported and ignored.\n * @param text - the attribute text, or undefined\n * @param name - the attribute name\n * @param line - the line\n * @returns the count, or null\n */\n private hint(text: string | undefined, name: string, line: number): number | null {\n if (text === undefined) {\n return null;\n }\n const n = hint(text);\n if (n === null || n > MAX_COUNT) {\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.COUNT_HINT,\n `<graph ${name}=\"${text}\"> is not a count the sink can reserve; ignored`,\n { line, element: name },\n );\n return null;\n }\n return n;\n }\n\n // ------------------------------------------------------------------ keys\n\n /**\n * Open a `<key>`; the column is declared at `</key>` once its default is known.\n * @param attrs - the key attributes\n * @param line - the line\n */\n private beginKey(attrs: ReadonlyMap<string, string>, line: number): void {\n const id = attrs.get(\"id\") ?? null;\n const forText = attrs.get(\"for\") ?? \"all\";\n let domains: readonly Domain[];\n switch (forText) {\n case \"all\":\n domains = [\"graph\", \"node\", \"edge\"];\n break;\n case \"graph\":\n case \"node\":\n case \"edge\":\n domains = [forText];\n break;\n case \"hyperedge\":\n case \"port\":\n case \"endpoint\":\n this.report.warning(\n \"unsupported\",\n GRAPHML_ISSUE.KEY_DOMAIN_UNSUPPORTED,\n `key \"${id ?? \"\"}\" is declared for ${forText} elements, which are not kept`,\n { line, element: id },\n );\n domains = [];\n break;\n default:\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.KEY_FOR_INVALID,\n `key \"${id ?? \"\"}\" has an unknown for=\"${forText}\"`,\n { line, element: id },\n );\n domains = [];\n }\n this.pendingKey = {\n id,\n // `name` / `type` without the `attr.` prefix are written by some tools; the spec's spelling wins\n attrName: attrs.get(\"attr.name\") ?? attrs.get(\"name\") ?? null,\n attrType: attrs.get(\"attr.type\") ?? attrs.get(\"type\") ?? null,\n yfilesType: attrs.get(\"yfiles.type\") ?? null,\n domains,\n line,\n desc: \"\",\n defaultText: null,\n defaultTree: undefined,\n };\n this.ctx.push(Ctx.Key);\n }\n\n /** Close a `<key>`: declare its columns. */\n private finishKey(): void {\n const key = this.pendingKey;\n this.pendingKey = null;\n if (key === null) {\n return;\n }\n const where = { line: key.line, element: key.id };\n if (key.id === null || key.id.length === 0) {\n this.report.error(\"validation-error\", GRAPHML_ISSUE.KEY_MISSING_ID, \"<key> without an id\", where);\n return;\n }\n const declared = this.keys.get(key.id) ?? [];\n if (declared.some((entry) => entry.domains.some((domain) => key.domains.includes(domain)))) {\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.DUPLICATE_KEY,\n `key \"${key.id}\" is declared twice for the same kind of element`,\n where,\n );\n return;\n }\n const yfiles = key.yfilesType !== null;\n const name = key.attrName !== null && key.attrName.length > 0 ? key.attrName : key.id;\n const skipped = yfiles && this.yfilesMode === \"skip\";\n if (skipped) {\n this.report.warning(\n \"unsupported\",\n GRAPHML_ISSUE.YFILES_SKIPPED,\n `yFiles key \"${key.id}\" (${key.yfilesType ?? \"\"}) skipped per the yfiles option`,\n where,\n );\n }\n let weight = false;\n let originalId = false;\n let node: ColumnTarget | null = null;\n let edge: ColumnTarget | null = null;\n let graph: ColumnTarget | null = null;\n for (const domain of key.domains) {\n if (skipped) {\n continue;\n }\n if (domain === \"edge\" && !yfiles && isWeightField(name, this.options.weightFrom)) {\n weight = true;\n this.weightOrigin ??= { id: key.id, title: key.attrName, type: key.attrType };\n continue;\n }\n if (domain === \"node\" && !yfiles && name === ORIGINAL_ID_ATTRIBUTE) {\n if (this.options.restoreMangledIds) {\n originalId = true;\n continue;\n }\n node = this.declareOriginalIdColumn(key);\n continue;\n }\n try {\n const target = yfiles ? this.declareYfiles(key, name, domain) : this.declareTyped(key, name, domain);\n if (domain === \"node\") {\n node = target;\n } else if (domain === \"edge\") {\n edge = target;\n } else {\n graph = target;\n }\n } catch (err) {\n this.report.recordError(err, where);\n }\n }\n this.keys.set(key.id, [\n ...declared,\n {\n id: key.id,\n name,\n node,\n edge,\n graph,\n weight,\n originalId,\n yfiles,\n skipped,\n domains: key.domains,\n },\n ]);\n }\n\n /**\n * Declare the column of a typed (or untyped, then string) key in one domain.\n * @param key - the key\n * @param name - the resolved attribute name\n * @param domain - the domain\n * @returns the column target\n */\n private declareTyped(key: PendingKey, name: string, domain: Domain): ColumnTarget {\n const id = key.id ?? \"\";\n const declared: DeclaredAttribute = declareAttribute({\n format: FORMAT,\n id,\n title: key.attrName !== null && key.attrName.length > 0 ? key.attrName : null,\n type: key.attrType,\n defaultText: key.defaultTree === undefined ? key.defaultText : null,\n listSyntax: \"comma\",\n role: domain !== \"graph\" && name === LABEL_COLUMN ? \"label\" : null,\n long: this.options.long,\n taken: this.takenIn(domain),\n });\n for (const issue of declared.issues) {\n this.report.warning(issue.category, issue.code, issue.message, { line: key.line, element: id });\n }\n if (key.defaultTree !== undefined) {\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.DATA_NESTED,\n `the <default> of key \"${id}\" holds elements; a ${key.attrType ?? \"string\"} default must be text`,\n { line: key.line, element: id },\n );\n }\n const { decl } = declared;\n if (key.desc.length > 0) {\n decl.extra = { desc: key.desc };\n }\n return this.declareTarget(domain, decl, declared.spec, declared.listSyntax);\n }\n\n /**\n * Declare the json column of a yFiles key in one domain.\n * @param key - the key\n * @param name - the resolved attribute name\n * @param domain - the domain\n * @returns the column target\n */\n private declareYfiles(key: PendingKey, name: string, domain: Domain): ColumnTarget {\n const id = key.id ?? \"\";\n const columnName = uniqueColumnName(name, id, this.takenIn(domain));\n const decl: ColumnDecl = {\n name: columnName,\n dtype: \"json\",\n nullable: true,\n origin: {\n format: FORMAT,\n id,\n title: key.attrName !== null && key.attrName !== columnName ? key.attrName : null,\n type: key.yfilesType,\n namespace: \"yfiles\",\n },\n };\n if (key.defaultTree !== undefined) {\n decl.default = key.defaultTree;\n } else if (key.defaultText !== null) {\n decl.default = key.defaultText;\n }\n if (key.desc.length > 0) {\n decl.extra = { desc: key.desc };\n }\n return this.declareTarget(domain, decl, null, \"comma\");\n }\n\n /**\n * Declare the `graphty.originalId` column that keeps the exporter's original ids when\n * restoreMangledIds is off.\n * @param key - the key\n * @returns the column target\n */\n private declareOriginalIdColumn(key: PendingKey): ColumnTarget {\n const decl: ColumnDecl = {\n name: uniqueColumnName(ORIGINAL_ID_COLUMN, key.id, this.takenIn(\"node\")),\n dtype: \"string\",\n nullable: true,\n role: \"originalId\",\n origin: { format: FORMAT, id: key.id, title: key.attrName, type: key.attrType, namespace: null },\n };\n return this.declareTarget(\"node\", decl, null, \"comma\");\n }\n\n /**\n * Push a declaration into the sink for one domain through the shared design section 5.6 rule:\n * a role another column already holds is dropped (reported), a name the sink holds with\n * another shape is renamed `<name>#<id>` (reported).\n * @param domain - the domain\n * @param decl - the declaration\n * @param spec - the value spec, or null for json\n * @param listSyntax - the list syntax\n * @returns the target\n */\n private declareTarget(\n domain: Domain,\n decl: ColumnDecl,\n spec: DeclaredTypeSpec | null,\n listSyntax: ListSyntax,\n ): ColumnTarget {\n if (domain === \"graph\") {\n this.sink.setGraphValue(decl.name, undefined, decl);\n this.graphColumnNames.add(decl.name);\n return { name: decl.name, handle: INVALID_INDEX as ColumnHandle, decl, spec, listSyntax };\n }\n const resolved = declareResolved(this.sink, domain, decl, this.report, { element: decl.name });\n return { name: resolved.decl.name, handle: resolved.handle, decl: resolved.decl, spec, listSyntax };\n }\n\n /**\n * The `taken` predicate of a domain: the reserved XML-derived names plus the sink's columns.\n * @param domain - the domain\n * @returns the predicate\n */\n private takenIn(domain: Domain): (name: string) => boolean {\n if (domain === \"graph\") {\n return (name: string): boolean => this.graphColumnNames.has(name);\n }\n const reserved = domain === \"node\" ? RESERVED_NODE_NAMES : RESERVED_EDGE_NAMES;\n const inSink = takenIn(this.sink, domain);\n return (name: string): boolean => reserved.has(name) || inSink(name);\n }\n\n // ------------------------------------------------------------------ data and defaults\n\n /**\n * Open a `<data>`.\n * @param attrs - its attributes\n * @param line - the line\n * @param domain - the domain of the element holding it\n */\n private beginData(attrs: ReadonlyMap<string, string>, line: number, domain: Domain): void {\n const keyId = attrs.get(\"key\");\n const { content } = this;\n content.key = null;\n content.pendingKey = null;\n content.domain = domain;\n content.text = \"\";\n content.tree = null;\n content.line = line;\n if (keyId === undefined) {\n this.report.error(\"validation-error\", GRAPHML_ISSUE.DATA_MISSING_KEY, \"<data> without a key attribute\", {\n line,\n });\n } else {\n const entries = this.keys.get(keyId);\n const key = entries?.find((entry) => entry.domains.includes(domain)) ?? entries?.[0];\n if (key === undefined) {\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.UNKNOWN_KEY,\n `<data> references undeclared key \"${keyId}\"`,\n { line, element: keyId },\n );\n } else if (!key.skipped && !key.domains.includes(domain)) {\n this.report.warnOnce(\n \"validation-error\",\n GRAPHML_ISSUE.KEY_DOMAIN,\n `key \"${keyId}\" is declared for ${key.domains.join(\" / \")} elements but used on a ${domain}; ignored`,\n { line, element: keyId },\n );\n } else {\n content.key = key;\n }\n }\n this.ctx.push(Ctx.Data);\n }\n\n /**\n * A child element inside `<data>` / `<default>`: the content becomes a tree.\n * @param name - the element name\n * @param attrs - its attributes\n */\n private captureStart(name: string, attrs: ReadonlyMap<string, string>): void {\n const { content } = this;\n if (content.tree === null) {\n content.tree = new XmlTreeBuilder();\n if (content.text.length > 0) {\n content.tree.text(content.text);\n content.text = \"\";\n }\n }\n content.tree.start(name, attrs);\n this.ctx.push(Ctx.Capture);\n }\n\n /** A captured element ends. */\n private captureEnd(): void {\n this.content.tree?.end();\n }\n\n /** Close a `<default>`: keep its text or tree for the key. */\n private finishDefault(): void {\n const { content } = this;\n const key = content.pendingKey;\n if (key === null) {\n return;\n }\n if (content.tree !== null) {\n key.defaultTree = content.tree.finish();\n } else {\n key.defaultText = content.text;\n }\n content.tree = null;\n content.text = \"\";\n content.pendingKey = null;\n }\n\n /** Close a `<data>`: parse the value and route it to its element. */\n private finishData(): void {\n const { content } = this;\n const { key } = content;\n const value: unknown = content.tree === null ? content.text : content.tree.finish();\n content.tree = null;\n content.text = \"\";\n content.key = null;\n if (key === null || key.skipped) {\n return;\n }\n const where = { line: content.line, element: key.id };\n switch (content.domain) {\n case \"node\": {\n const node = this.nodes[this.nodes.length - 1];\n if (key.originalId) {\n if (typeof value === \"string\") {\n node.restoredId = value;\n }\n return;\n }\n if (key.yfiles) {\n for (const [handle, mapped] of this.graphics(\"node\", key, value, where)) {\n this.setNodeData(node, handle, mapped);\n }\n }\n if (key.node === null) {\n return;\n }\n const parsed = this.parseValue(key.node, value, where);\n if (parsed !== undefined) {\n this.setNodeData(node, key.node.handle, parsed);\n }\n return;\n }\n case \"edge\": {\n const { edge } = this;\n if (edge === null) {\n return;\n }\n if (key.weight) {\n if (typeof value !== \"string\") {\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.DATA_NESTED,\n \"a weight value must be text\",\n where,\n );\n return;\n }\n try {\n edge.weight = parseWeightText(value);\n } catch (err) {\n this.skipEdge(edge);\n this.report.recordError(err, where);\n }\n return;\n }\n if (key.yfiles) {\n for (const [handle, mapped] of this.graphics(\"edge\", key, value, where)) {\n edge.pending.push(handle, mapped);\n }\n }\n if (key.edge === null) {\n return;\n }\n const parsed = this.parseValue(key.edge, value, where);\n if (parsed !== undefined) {\n edge.pending.push(key.edge.handle, parsed);\n }\n return;\n }\n case \"graph\": {\n if (key.graph === null) {\n return;\n }\n const parsed = this.parseValue(key.graph, value, where);\n if (parsed !== undefined) {\n try {\n this.sink.setGraphValue(key.graph.name, parsed, key.graph.decl);\n } catch (err) {\n this.report.recordError(err, where);\n }\n }\n return;\n }\n default: {\n const { domain } = content;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown data domain ${String(domain)}`, {});\n }\n }\n }\n\n /**\n * Write a node value now, or keep it until the node is added.\n * @param node - the node state\n * @param handle - the column\n * @param value - the value\n */\n private setNodeData(node: NodeState, handle: ColumnHandle, value: unknown): void {\n if (node.index === INVALID_INDEX) {\n node.pending.push(handle, value);\n } else if (!node.failed) {\n this.sink.setNodeValue(handle, node.index, value);\n }\n }\n\n /**\n * The typed values mapped from a yFiles graphics tree (yfiles.ts), each with its column,\n * declared on first use.\n * @param domain - node or edge\n * @param key - the yFiles key\n * @param tree - the `<data>` content\n * @param where - the location for issues\n * @returns column handle and value pairs\n */\n private graphics(domain: \"node\" | \"edge\", key: KeyEntry, tree: unknown, where: Where): [ColumnHandle, unknown][] {\n const out: [ColumnHandle, unknown][] = [];\n for (const [field, value] of graphicsValues(domain, tree)) {\n const id = `${domain}:${field}`;\n let handle = this.graphicsColumns.get(id);\n if (handle === undefined) {\n try {\n ({ handle } = declareResolved(\n this.sink,\n domain,\n graphicsDecl(domain, field, key.id),\n this.report,\n where,\n ));\n } catch (err) {\n this.report.recordError(err, where);\n continue;\n }\n this.graphicsColumns.set(id, handle);\n }\n out.push([handle, value]);\n }\n return out;\n }\n\n /**\n * Parse the content of a `<data>` by its column's declaration.\n * @param target - the column\n * @param value - the text, or the tree of a nested subtree\n * @param where - the location for issues\n * @returns the value to write, or undefined when there is none (blank, or an error was recorded)\n */\n private parseValue(target: ColumnTarget, value: unknown, where: Where): unknown {\n if (target.spec === null) {\n if (!this.yfilesLossNoted) {\n this.yfilesLossNoted = true;\n this.report.loss(\n GRAPHML_LOSS.YFILES_JSON,\n \"yFiles nested XML is kept as a JSON tree: structure preserved, not byte-exact\",\n target.name,\n );\n }\n return value;\n }\n if (typeof value !== \"string\") {\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.DATA_NESTED,\n `<data> of the ${target.spec.declared} attribute \"${target.name}\" holds elements, not text`,\n where,\n );\n return undefined;\n }\n const { spec } = target;\n if (spec.kind !== \"string\" && isWhitespace(value)) {\n return undefined;\n }\n try {\n const parsed = parseDeclaredValue(value, spec, target.listSyntax);\n if (spec.precision && losesPrecision(spec, value)) {\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `long values of \"${target.name}\" beyond 2^53 are stored as the nearest double`,\n { line: where.line, element: target.name },\n );\n }\n return parsed;\n } catch (err) {\n this.report.recordError(err, where);\n return undefined;\n }\n }\n\n // ------------------------------------------------------------------ nodes\n\n /**\n * Open a `<node>`; it is added to the sink when its data is complete (or a nested graph\n * starts), so a `graphty:originalId` value can replace its id.\n * @param attrs - the node attributes\n * @param line - the line\n */\n private beginNode(attrs: ReadonlyMap<string, string>, line: number): void {\n this.reportUnreadAttributes(\"node\", attrs, NODE_ATTRIBUTES, line);\n const graph = this.graphs[this.graphs.length - 1];\n const state: NodeState = {\n id: null,\n idText: null,\n index: INVALID_INDEX,\n parent: graph.parent,\n pending: [],\n restoredId: null,\n failed: false,\n line,\n };\n const idText = attrs.get(\"id\");\n if (idText === undefined || idText.length === 0) {\n this.skipNode(state);\n this.report.error(\"missing-value\", GRAPHML_ISSUE.MISSING_ID, \"<node> without an id\", { line });\n } else {\n try {\n state.id = this.coercer.text(idText);\n state.idText = idText;\n this.reportMerge(idText, line);\n } catch (err) {\n this.skipNode(state);\n this.report.recordError(err, { line, element: idText });\n }\n }\n this.nodes.push(state);\n this.ctx.push(Ctx.Node);\n }\n\n /**\n * Add a node to the sink and flush its pending values.\n * @param node - the node state\n */\n private materializeNode(node: NodeState): void {\n if (node.index !== INVALID_INDEX || node.failed) {\n return;\n }\n const id: NodeId | null = node.restoredId ?? node.id;\n if (id === null) {\n node.failed = true;\n return;\n }\n if (node.restoredId !== null && node.idText !== null) {\n this.restored.set(node.idText, node.restoredId);\n }\n try {\n const existing = this.sink.indexOf(id);\n const index = this.sink.addNode(id);\n if (existing !== INVALID_INDEX && this.declared.has(index)) {\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.DUPLICATE_NODE,\n `node \"${String(id)}\" is declared twice; the declarations are merged`,\n { line: node.line, element: String(id) },\n );\n } else {\n this.report.counts.nodes++;\n }\n this.declared.add(index);\n node.index = index;\n this.checkAbort();\n if (node.parent !== INVALID_INDEX) {\n this.sink.setNodeValue(this.parentColumn(), index, node.parent);\n }\n const { pending } = node;\n for (let i = 0; i < pending.length; i += 2) {\n this.sink.setNodeValue(pending[i] as ColumnHandle, index, pending[i + 1]);\n }\n pending.length = 0;\n } catch (err) {\n this.skipNode(node);\n this.report.recordError(err, { line: node.line, element: String(id) });\n }\n }\n\n /**\n * Mark a node element skipped (once) before its error is recorded, so the report's counts\n * include it even when that error is the one that exceeds the limit.\n * @param node - the node state\n */\n private skipNode(node: NodeState): void {\n if (!node.failed) {\n node.failed = true;\n this.report.counts.skippedNodes++;\n }\n }\n\n /** Close a `<node>`. */\n private finishNode(): void {\n const node = this.nodes.pop();\n if (node !== undefined) {\n this.materializeNode(node);\n }\n }\n\n /**\n * The `parent` column, declared on first use.\n * @returns the handle\n */\n private parentColumn(): ColumnHandle {\n if (this.parentHandle === INVALID_INDEX) {\n this.parentHandle = this.sink.declareNodeColumn({\n name: PARENT_COLUMN,\n dtype: \"u32\",\n role: \"parent\",\n refersTo: \"node\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"graph\", namespace: null },\n });\n }\n return this.parentHandle;\n }\n\n // ------------------------------------------------------------------ edges\n\n /**\n * Open an `<edge>`; it is pushed at `</edge>` once its weight and data are known.\n * @param attrs - the edge attributes\n * @param line - the line\n */\n private beginEdge(attrs: ReadonlyMap<string, string>, line: number): void {\n this.reportUnreadAttributes(\"edge\", attrs, EDGE_ATTRIBUTES, line);\n const graph = this.graphs[this.graphs.length - 1];\n const edge: EdgeState = {\n source: null,\n target: null,\n id: attrs.get(\"id\") ?? null,\n kind: graph.directed ? \"directed\" : \"undirected\",\n sourcePort: attrs.get(\"sourceport\") ?? null,\n targetPort: attrs.get(\"targetport\") ?? null,\n weight: undefined,\n pending: [],\n failed: false,\n line,\n };\n const where = { line, element: edge.id };\n const sourceText = attrs.get(\"source\");\n const targetText = attrs.get(\"target\");\n if (sourceText === undefined || sourceText.length === 0) {\n this.skipEdge(edge);\n this.report.error(\"missing-value\", GRAPHML_ISSUE.MISSING_ENDPOINT, \"<edge> without a source\", where);\n }\n if (targetText === undefined || targetText.length === 0) {\n this.skipEdge(edge);\n this.report.error(\"missing-value\", GRAPHML_ISSUE.MISSING_ENDPOINT, \"<edge> without a target\", where);\n }\n if (!edge.failed && sourceText !== undefined && targetText !== undefined) {\n try {\n edge.source = this.endpointId(sourceText, line);\n edge.target = this.endpointId(targetText, line);\n } catch (err) {\n this.skipEdge(edge);\n this.report.recordError(err, where);\n }\n }\n const directedText = attrs.get(\"directed\");\n if (directedText !== undefined) {\n if (directedText === \"true\") {\n edge.kind = \"directed\";\n } else if (directedText === \"false\") {\n edge.kind = \"undirected\";\n } else {\n this.skipEdge(edge);\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.INVALID_DIRECTED,\n `directed=\"${directedText}\" is neither true nor false`,\n where,\n );\n }\n }\n this.edge = edge;\n this.ctx.push(Ctx.Edge);\n }\n\n /**\n * Close an `<edge>`: push it through the direction resolver and write its values.\n */\n private finishEdge(): void {\n const { edge } = this;\n this.edge = null;\n if (edge === null) {\n return;\n }\n if (edge.failed || edge.source === null || edge.target === null) {\n this.skipEdge(edge);\n return;\n }\n const element = edge.id ?? `${String(edge.source)} -> ${String(edge.target)}`;\n const where = { line: edge.line, element };\n try {\n if (!this.options.addMissingNodes) {\n this.requireNode(edge.source);\n this.requireNode(edge.target);\n }\n if (edge.id !== null && this.edgeIds.has(edge.id)) {\n throw new GraphFormatError(\"E_DUPLICATE_EDGE_ID\", `edge id \"${edge.id}\" is used twice`, {\n id: edge.id,\n });\n }\n const before = this.sink.edgeCount;\n this.countEndpoints(edge.source, edge.target);\n const e = this.direction.addEdge(edge.source, edge.target, edge.kind, edge.weight, where);\n this.report.counts.edges += this.sink.edgeCount - before;\n this.checkAbort();\n if (edge.id !== null) {\n this.edgeIds.add(edge.id);\n this.sink.setEdgeValue(this.edgeIdColumn(), e, edge.id);\n }\n if (edge.sourcePort !== null) {\n this.sink.setEdgeValue(this.portColumn(\"source\"), e, edge.sourcePort);\n }\n if (edge.targetPort !== null) {\n this.sink.setEdgeValue(this.portColumn(\"target\"), e, edge.targetPort);\n }\n const { pending } = edge;\n for (let i = 0; i < pending.length; i += 2) {\n this.sink.setEdgeValue(pending[i] as ColumnHandle, e, pending[i + 1]);\n }\n } catch (err) {\n this.skipEdge(edge);\n this.report.recordError(err, where);\n }\n }\n\n /**\n * Mark an edge (or hyperedge) element skipped once, before its error is recorded.\n * @param edge - the edge state\n */\n private skipEdge(edge: EdgeState | HyperedgeState): void {\n if (!edge.failed) {\n edge.failed = true;\n this.report.counts.skippedEdges++;\n }\n }\n\n /**\n * E_UNKNOWN_NODE when an endpoint was never declared (addMissingNodes false enforced by the\n * importer, whatever the sink allows).\n * @param id - the endpoint id\n */\n private requireNode(id: NodeId): void {\n if (this.sink.indexOf(id) === INVALID_INDEX) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge endpoint \"${String(id)}\" is not a declared node`, {\n id,\n });\n }\n }\n\n /**\n * The edge `id` column (role id, unique), declared on first use.\n * @returns the handle\n */\n private edgeIdColumn(): ColumnHandle {\n if (this.edgeIdHandle === INVALID_INDEX) {\n this.edgeIdHandle = this.sink.declareEdgeColumn({\n name: EDGE_ID_COLUMN,\n dtype: \"string\",\n role: \"id\",\n unique: true,\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"id\", namespace: null },\n });\n }\n return this.edgeIdHandle;\n }\n\n /**\n * The sourceport / targetport column, declared on first use.\n * @param side - which end\n * @returns the handle\n */\n private portColumn(side: \"source\" | \"target\"): ColumnHandle {\n if (side === \"source\") {\n if (this.sourcePortHandle === INVALID_INDEX) {\n this.sourcePortHandle = this.sink.declareEdgeColumn({\n name: SOURCE_PORT_COLUMN,\n dtype: \"string\",\n role: \"sourcePort\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"sourceport\", namespace: null },\n });\n }\n return this.sourcePortHandle;\n }\n if (this.targetPortHandle === INVALID_INDEX) {\n this.targetPortHandle = this.sink.declareEdgeColumn({\n name: TARGET_PORT_COLUMN,\n dtype: \"string\",\n role: \"targetPort\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"targetport\", namespace: null },\n });\n }\n return this.targetPortHandle;\n }\n\n // ------------------------------------------------------------------ hyperedges\n\n /**\n * Open a `<hyperedge>` per the hyperedges option.\n * @param attrs - its attributes\n * @param line - the line\n */\n private beginHyperedge(attrs: ReadonlyMap<string, string>, line: number): void {\n const id = attrs.get(\"id\") ?? null;\n const where = { line, element: id };\n switch (this.options.hyperedges) {\n case \"error\":\n this.report.error(\n \"unsupported\",\n GRAPHML_ISSUE.HYPEREDGE,\n 'hyperedge refused (hyperedges: \"error\")',\n where,\n );\n throw this.report.abort(\"hyperedge refused\", { code: GRAPHML_ISSUE.HYPEREDGE });\n case \"skip\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.HYPEREDGE_SKIPPED,\n 'hyperedges are skipped (hyperedges: \"skip\"); use \"star\" or \"clique\" to expand them',\n where,\n );\n this.report.counts.skippedEdges++;\n this.ctx.push(Ctx.Skip);\n return;\n case \"star\":\n case \"clique\":\n this.hyperedge = { id, endpoints: [], failed: false, line };\n this.ctx.push(Ctx.Hyperedge);\n return;\n default: {\n const policy: never = this.options.hyperedges;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown hyperedges policy ${String(policy)}`, {\n option: \"hyperedges\",\n });\n }\n }\n }\n\n /**\n * An `<endpoint>` of the open hyperedge.\n * @param attrs - its attributes\n * @param line - the line\n */\n private readEndpoint(attrs: ReadonlyMap<string, string>, line: number): void {\n const { hyperedge } = this;\n if (hyperedge === null) {\n return;\n }\n const where = { line, element: hyperedge.id };\n const nodeText = attrs.get(\"node\");\n const typeText = attrs.get(\"type\") ?? \"undir\";\n if (nodeText === undefined || nodeText.length === 0) {\n this.skipEdge(hyperedge);\n this.report.error(\"missing-value\", GRAPHML_ISSUE.HYPEREDGE_ENDPOINT, \"<endpoint> without a node\", where);\n return;\n }\n if (typeText !== \"in\" && typeText !== \"out\" && typeText !== \"undir\") {\n this.skipEdge(hyperedge);\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.HYPEREDGE_ENDPOINT,\n `endpoint type \"${typeText}\" is not in, out or undir`,\n where,\n );\n return;\n }\n try {\n const node = this.endpointId(nodeText, line);\n hyperedge.endpoints.push({ node, type: typeText });\n } catch (err) {\n this.skipEdge(hyperedge);\n this.report.recordError(err, where);\n }\n }\n\n /** Close a `<hyperedge>`: expand it to a star or a clique. */\n private finishHyperedge(): void {\n const { hyperedge } = this;\n this.hyperedge = null;\n if (hyperedge === null) {\n return;\n }\n if (hyperedge.failed) {\n return;\n }\n const where = { line: hyperedge.line, element: hyperedge.id };\n try {\n if (this.options.hyperedges === \"star\") {\n this.expandStar(hyperedge, where);\n } else {\n this.expandClique(hyperedge, where);\n }\n } catch (err) {\n this.skipEdge(hyperedge);\n this.report.recordError(err, where);\n }\n }\n\n /**\n * Star expansion: a synthetic hub node (marked in the `graphty.hyperedge` column) joined to\n * every endpoint; `in` endpoints point at the hub, `out` endpoints are pointed at by it,\n * `undir` endpoints are undirected.\n * @param hyperedge - the hyperedge\n * @param where - the location for issues\n */\n private expandStar(hyperedge: HyperedgeState, where: Where): void {\n this.hyperedgeCount++;\n let hubId = hyperedge.id ?? `hyperedge${this.hyperedgeCount}`;\n for (let n = 2; this.sink.indexOf(hubId) !== INVALID_INDEX; n++) {\n hubId = `${hyperedge.id ?? `hyperedge${this.hyperedgeCount}`}#${n}`;\n }\n const hub = this.sink.addNode(hubId);\n this.declared.add(hub);\n this.report.counts.nodes++;\n if (this.hubHandle === INVALID_INDEX) {\n this.hubHandle = this.sink.declareNodeColumn({\n name: HYPEREDGE_HUB_COLUMN,\n dtype: \"bool\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"hyperedge\", namespace: null },\n });\n }\n this.sink.setNodeValue(this.hubHandle, hub, true);\n for (const endpoint of hyperedge.endpoints) {\n const before = this.sink.edgeCount;\n switch (endpoint.type) {\n case \"in\":\n this.direction.addEdge(endpoint.node, hubId, \"directed\", undefined, where);\n break;\n case \"out\":\n this.direction.addEdge(hubId, endpoint.node, \"directed\", undefined, where);\n break;\n case \"undir\":\n this.direction.addEdge(endpoint.node, hubId, \"undirected\", undefined, where);\n break;\n default: {\n const { type } = endpoint;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown endpoint type ${String(type)}`, {});\n }\n }\n this.report.counts.edges += this.sink.edgeCount - before;\n }\n }\n\n /**\n * Clique expansion: every `in` endpoint points at every `out` endpoint; `undir` endpoints are\n * joined undirected to every other endpoint; two endpoints of the same direction are not joined.\n * @param hyperedge - the hyperedge\n * @param where - the location for issues\n */\n private expandClique(hyperedge: HyperedgeState, where: Where): void {\n const { endpoints } = hyperedge;\n for (let i = 0; i < endpoints.length; i++) {\n for (let j = i + 1; j < endpoints.length; j++) {\n const a = endpoints[i];\n const b = endpoints[j];\n const before = this.sink.edgeCount;\n if (a.type === \"undir\" || b.type === \"undir\") {\n this.direction.addEdge(a.node, b.node, \"undirected\", undefined, where);\n } else if (a.type === \"in\" && b.type === \"out\") {\n this.direction.addEdge(a.node, b.node, \"directed\", undefined, where);\n } else if (a.type === \"out\" && b.type === \"in\") {\n this.direction.addEdge(b.node, a.node, \"directed\", undefined, where);\n } else {\n continue;\n }\n this.report.counts.edges += this.sink.edgeCount - before;\n }\n }\n }\n\n // ------------------------------------------------------------------ options and ids\n\n /**\n * Count the endpoints of an edge the file never declared as nodes of the sink (created under\n * addMissingNodes), so the report describes what the sink holds (design section 8.6).\n * @param source - the source id\n * @param target - the target id\n */\n private countEndpoints(source: NodeId, target: NodeId): void {\n if (!this.options.addMissingNodes) {\n return;\n }\n let created = 0;\n if (this.sink.indexOf(source) === INVALID_INDEX) {\n created++;\n }\n if (source !== target && this.sink.indexOf(target) === INVALID_INDEX) {\n created++;\n }\n this.report.counts.nodes += created;\n }\n\n /** Check the cancellation signal every ABORT_CHECK_INTERVAL elements. */\n private checkAbort(): void {\n if (++this.elementsSinceCheck >= ABORT_CHECK_INTERVAL) {\n this.elementsSinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n\n /**\n * The id an edge endpoint refers to: the original id when the text is a mangled id restored\n * from `graphty:originalId` (the exporter writes endpoints with the mangled id), else the\n * coerced text.\n * @param text - the source / target / endpoint node text\n * @param line - the line\n * @returns the node id\n */\n private endpointId(text: string, line: number): NodeId {\n const restored = this.restored.get(text);\n if (restored !== undefined) {\n return restored;\n }\n const id = this.coercer.text(text);\n this.reportMerge(text, line);\n return id;\n }\n\n /**\n * Report a merge the coercer detected under ids: \"number\".\n * @param text - the id text just coerced\n * @param line - the line\n */\n private reportMerge(text: string, line: number): void {\n const merge = this.coercer.lastMerge;\n if (merge !== null) {\n this.report.warning(\n \"coercion\",\n GRAPHML_ISSUE.ID_MERGED,\n `id \"${merge.text}\" merged with \"${merge.previousText}\" as ${merge.id} under ids: \"number\"`,\n { line, element: text },\n );\n }\n }\n}\n\n/**\n * A `parse.nodes` / `parse.edges` hint as a count.\n * @param text - the attribute text\n * @returns the count, or null when absent or not a non-negative integer\n */\nfunction hint(text: string | undefined): number | null {\n if (text === undefined || !/^[0-9]+$/.test(text)) {\n return null;\n }\n const n = Number(text);\n return Number.isSafeInteger(n) ? n : null;\n}\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the yfiles mode\n */\nfunction resolveYfiles(options: GraphmlImportOptions | undefined): \"json\" | \"skip\" {\n const value = options?.yfiles;\n if (value === undefined) {\n return \"json\";\n }\n if (typeof value !== \"string\" || !YFILES_MODES.has(value)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option yfiles: ${JSON.stringify(value)} is not \"json\" or \"skip\"`, {\n option: \"yfiles\",\n found: value,\n });\n }\n return value;\n}\n\n/**\n * Confidence that a head of bytes is GraphML.\n * @param head - the first bytes\n * @returns 1 for a `<graphml` root in the GraphML namespace, 0.9 for a `<graphml` root, 0.05 for other XML, 0 otherwise\n * or when the head does not start with markup\n */\nfunction sniffGraphml(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\", { fatal: false }).decode(head.subarray(0, SNIFF_BYTES));\n // Only a document that starts as markup: a JSON or CSV value may mention a `<graphml>` tag.\n if (!/^\\uFEFF?\\s*</.test(text)) {\n return 0;\n }\n const root = text.indexOf(\"<graphml\");\n if (root >= 0) {\n return text.includes(GRAPHML_NAMESPACE, root) ? 1 : 0.9;\n }\n return /^\\s*<(\\?xml|!--|!DOCTYPE)/.test(text) ? 0.05 : 0;\n}\n\n/**\n * Import GraphML into a sink.\n * @param input - the document\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report; ImportError when the document cannot be read or the error limit is exceeded\n */\nasync function importGraphml(\n input: ImportInput,\n sink: GraphSink,\n options?: GraphmlImportOptions & CommonImportOptions,\n): Promise<ImportReport> {\n const common = resolveImportOptions(options, FORMAT_DEFAULTS);\n const yfilesMode = resolveYfiles(options);\n const report = new ImportReportBuilder(FORMAT, common.errorLimit);\n reportSinkOptions(sink, options, report, true);\n reportUnusedOptions(options, report, USED_OPTIONS);\n const reader = new GraphmlReader(sink, report, common, yfilesMode);\n try {\n await tokenizeXml(textChunks(input, report, { ...common, declaredEncoding: xmlDeclaredEncoding }), reader);\n } catch (err) {\n if (err instanceof XmlSyntaxError) {\n report.fail(GRAPHML_ISSUE.XML_SYNTAX, err.message, { line: err.line });\n }\n throw err;\n }\n reader.finish();\n throwIfAborted(common.signal);\n return report.finish();\n}\n\n/** The GraphML importer (design section 8.4). */\nexport const graphmlImporter: GraphImporter<GraphmlImportOptions> = Object.freeze({\n format: FORMAT,\n extensions: EXTENSIONS,\n mimeTypes: MIME_TYPES,\n sniff: sniffGraphml,\n import: importGraphml,\n});\n"],"names":["text","child","hint"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"importer-ruMWWvVs.js","sources":["../../src/formats/graphml/constants.ts","../../src/formats/graphml/tree.ts","../../src/formats/graphml/yfiles.ts","../../src/formats/graphml/exporter.ts","../../src/formats/graphml/importer.ts"],"sourcesContent":["/**\n * What the GraphML importer and exporter share: the namespace, the format facts, the reserved\n * column names of the XML-attribute-derived columns (design section 5.6), the `meta.extra`\n * keys the importer records for the exporter, and the issue and loss codes.\n */\n\nimport {\n BAD_DEFAULT_CODE,\n COLUMN_RENAMED_CODE,\n COUNT_HINT_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_KEY_CODE,\n DUPLICATE_NODE_CODE,\n ENCODING_FALLBACK_CODE,\n HYPEREDGE_CODE,\n ID_MERGED_CODE,\n ID_TEXT_TYPE_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MIXED_DIRECTION_CODE,\n MULTIPLE_GRAPHS_CODE,\n MUTUAL_AS_UNDIRECTED_CODE,\n NO_GRAPH_CODE,\n OPTION_IGNORED_CODE,\n PARENTS_DROPPED_CODE,\n PRECISION_CODE,\n ROLE_DROPPED_CODE,\n ROLE_TAKEN_CODE,\n SINK_OPTION_CODE,\n STRAY_TEXT_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ELEMENT_CODE,\n UNKNOWN_ENCODING_CODE,\n XML_SYNTAX_CODE,\n} from \"../../common/codes.js\";\n\n/** The GraphML namespace. */\nexport const GRAPHML_NAMESPACE = \"http://graphml.graphdrawing.org/xmlns\";\n\n/** The yFiles extension namespace, declared as `xmlns:y` when a yfiles column is written. */\nexport const YFILES_NAMESPACE = \"http://www.yworks.com/xml/graphml\";\n\n/** The XML Schema instance namespace and the schema location the exporter writes. */\nexport const XSI_NAMESPACE = \"http://www.w3.org/2001/XMLSchema-instance\";\n\n/** The GraphML schema location written by the exporter. */\nexport const SCHEMA_LOCATION =\n \"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\";\n\n/** The format name. */\nexport const FORMAT = \"graphml\";\n\n/** File extensions. */\nexport const EXTENSIONS: readonly string[] = Object.freeze([\".graphml\", \".xml\"]);\n\n/** MIME types. */\nexport const MIME_TYPES: readonly string[] = Object.freeze([\"application/graphml+xml\", \"application/xml\", \"text/xml\"]);\n\n/** The `attr.name` of the node key that carries ids rewritten by `sanitizeIds: \"mangle\"` (design section 8.5). */\nexport const ORIGINAL_ID_ATTRIBUTE = \"graphty:originalId\";\n\n/** The node column that keeps original ids when `restoreMangledIds` is off (design section 5.6). */\nexport const ORIGINAL_ID_COLUMN = \"graphty.originalId\";\n\n/** The edge column of the `id` XML attribute (role id, unique). */\nexport const EDGE_ID_COLUMN = \"id\";\n\n/** The edge columns of the `sourceport` / `targetport` XML attributes (roles sourcePort / targetPort). */\nexport const SOURCE_PORT_COLUMN = \"sourceport\";\n\n/** The edge column of the `targetport` XML attribute. */\nexport const TARGET_PORT_COLUMN = \"targetport\";\n\n/** The node column of the containing node of a nested graph (u32, role parent, refersTo node). */\nexport const PARENT_COLUMN = \"parent\";\n\n/** The bool node column marking the hub nodes synthesised for hyperedges under `hyperedges: \"star\"`. */\nexport const HYPEREDGE_HUB_COLUMN = \"graphty.hyperedge\";\n\n/** The column name a node key titled `label` receives the `label` role under. */\nexport const LABEL_COLUMN = \"label\";\n\n/** Edge column names reserved for the XML-attribute-derived columns; a key titled like one is renamed `<name>#<id>`. */\nexport const RESERVED_EDGE_NAMES: ReadonlySet<string> = new Set([\n EDGE_ID_COLUMN,\n SOURCE_PORT_COLUMN,\n TARGET_PORT_COLUMN,\n]);\n\n/** Node column names reserved for the XML-derived columns. */\nexport const RESERVED_NODE_NAMES: ReadonlySet<string> = new Set([PARENT_COLUMN]);\n\n/** The `meta.extra` key under which the importer records what the exporter needs. */\nexport const META_KEY = \"graphml\";\n\n/** What the importer stores under `meta.extra.graphml`. */\nexport interface GraphmlMeta {\n /** The top-level `<graph id>`, or null. */\n readonly graphId: string | null;\n /** The top-level `edgedefault` as written, so a mixed file re-exports with the same layout. */\n readonly edgedefault: \"directed\" | \"undirected\" | null;\n /** The `xmlns:<prefix>` declarations of the root element (yFiles and the like). */\n readonly namespaces: Readonly<Record<string, string>>;\n}\n\n/**\n * The issue codes the GraphML importer records (design section 8.6), by name: the codes shared\n * with the other importers (src/common/codes.ts) and the GraphML-specific ones. A key is the code\n * without its severity and format prefixes.\n */\nexport const GRAPHML_ISSUE = Object.freeze({\n /** Fatal: the input is not well-formed XML. */\n XML_SYNTAX: XML_SYNTAX_CODE,\n /** Fatal: the input holds invalid UTF-8. */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM, a declaration or the encoding option chose (fatal). */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** Fatal: the root element is not `<graphml>`. */\n NOT_GRAPHML: \"E_NOT_GRAPHML\",\n /** Fatal: the document has no `<graph>`. */\n NO_GRAPH: NO_GRAPH_CODE,\n /** A `<key>` without an id. */\n KEY_MISSING_ID: \"E_GRAPHML_KEY_MISSING_ID\",\n /** Two `<key>` elements with the same id. */\n DUPLICATE_KEY: DUPLICATE_KEY_CODE,\n /** A key declared for hyperedges, ports or endpoints (never used). */\n KEY_DOMAIN_UNSUPPORTED: \"W_GRAPHML_KEY_DOMAIN_UNSUPPORTED\",\n /** A `<node>` without an id. */\n MISSING_ID: MISSING_ID_CODE,\n /** An `<edge>` without a source or a target. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A `<data>` whose key was never declared. */\n UNKNOWN_KEY: \"E_GRAPHML_UNKNOWN_KEY\",\n /** A `<data>` whose key is declared for another domain. */\n KEY_DOMAIN: \"W_GRAPHML_KEY_DOMAIN\",\n /** A `<data>` without a key attribute. */\n DATA_MISSING_KEY: \"E_GRAPHML_DATA_MISSING_KEY\",\n /** A `<key>` whose `for` is not a GraphML domain. */\n KEY_FOR_INVALID: \"E_GRAPHML_KEY_FOR_INVALID\",\n /** Data of a nested `<graph>`; only the top-level graph has attributes. */\n NESTED_GRAPH_DATA: \"W_GRAPHML_NESTED_GRAPH_DATA\",\n /** Data of a hyperedge expanded to a star or clique. */\n HYPEREDGE_DATA_DROPPED: \"W_GRAPHML_HYPEREDGE_DATA_DROPPED\",\n /** Nested elements in the `<data>` of a typed (non-yfiles) key. */\n DATA_NESTED: \"E_GRAPHML_DATA_NESTED\",\n /** A `<node>` declared twice. */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** An edge id already used by another edge. */\n DUPLICATE_EDGE_ID: DUPLICATE_EDGE_ID_CODE,\n /** A `directed` attribute that is neither true nor false. */\n INVALID_DIRECTED: \"E_GRAPHML_INVALID_DIRECTED\",\n /** An `edgedefault` that is neither directed nor undirected. */\n INVALID_EDGEDEFAULT: \"E_GRAPHML_INVALID_EDGEDEFAULT\",\n /** A `<graph>` without edgedefault; the `defaultDirected` option applies. */\n EDGEDEFAULT_MISSING: \"W_GRAPHML_EDGEDEFAULT_MISSING\",\n /** A second top-level `<graph>`; its nodes and edges are merged into the first. */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** A `parse.nodes` / `parse.edges` hint the sink cannot reserve (ignored). */\n COUNT_HINT: COUNT_HINT_CODE,\n /** A hyperedge under `hyperedges: \"error\"`. */\n HYPEREDGE: HYPEREDGE_CODE,\n /** Hyperedges skipped under `hyperedges: \"skip\"`. */\n HYPEREDGE_SKIPPED: \"W_GRAPHML_HYPEREDGE_SKIPPED\",\n /** An endpoint of a hyperedge without a node, or with an unknown type. */\n HYPEREDGE_ENDPOINT: \"E_GRAPHML_HYPEREDGE_ENDPOINT\",\n /** `<port>` declarations (and their data) are not kept; sourceport / targetport edge attributes are. */\n PORT_DECLARATION: \"W_GRAPHML_PORT_DECLARATION\",\n /** A GraphML `parse.*` hint on `<graph>`, `<node>` or `<edge>` the importer does not act on (parse.nodeids, parse.order, ...). */\n PARSE_HINT_IGNORED: \"W_GRAPHML_PARSE_HINT_IGNORED\",\n /** An XML attribute GraphML does not define on `<graph>`, `<node>` or `<edge>`; it is not kept. */\n UNKNOWN_XML_ATTRIBUTE: \"W_GRAPHML_UNKNOWN_XML_ATTRIBUTE\",\n /** A `<locator>` element. */\n LOCATOR_DROPPED: \"W_GRAPHML_LOCATOR_DROPPED\",\n /** A `<desc>` of a node, an edge or a hyperedge. */\n DESC_DROPPED: \"W_GRAPHML_DESC_DROPPED\",\n /** An element the GraphML schema does not define at that place. */\n UNKNOWN_ELEMENT: UNKNOWN_ELEMENT_CODE,\n /** Non-whitespace text where the schema allows only elements. */\n STRAY_TEXT: STRAY_TEXT_CODE,\n /** Two distinct id texts merged into one number under `ids: \"number\"`. */\n ID_MERGED: ID_MERGED_CODE,\n /** An option GraphML has no use for (`nodeIdFrom`: nodes are identified by their id attribute). */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A yFiles key under `yfiles: \"skip\"`. */\n YFILES_SKIPPED: \"W_GRAPHML_YFILES_SKIPPED\",\n /** A key renamed `<name>#<id>` because the name was taken (design section 5.6). */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A key declared without its role because the table already holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** A declared type the format does not define (kept as string). */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** A default that does not parse as the declared type. */\n BAD_DEFAULT: BAD_DEFAULT_CODE,\n /** A long value beyond 2^53 rounded. */\n PRECISION: PRECISION_CODE,\n /** A builder-policy option the sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n /** The sink refused the file's direction. */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges forced to the policy's direction. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /** A mixed file under onMixedDirection \"error\" (fatal). */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n});\n\n/**\n * Loss note codes of the GraphML importer (report.lossy) and exporter (check()): the GraphML\n * ones; the generic ones (dtypes, lists, json text, positions, visual and temporal roles,\n * extension tables, id charsets, the weight key clash, name changes) are those of `LOSS`.\n */\nexport const GRAPHML_LOSS = Object.freeze({\n /** yFiles nested XML kept as a JSON tree: structure preserved, not byte-exact. */\n YFILES_JSON: \"W_GRAPHML_YFILES_JSON\",\n /** A mutual pair written as one undirected edge; the mark is lost. */\n MUTUAL_AS_UNDIRECTED: MUTUAL_AS_UNDIRECTED_CODE,\n /** A `parents` (multi-parent) column cannot be written as nested graphs. */\n PARENTS_DROPPED: PARENTS_DROPPED_CODE,\n /** A role column GraphML has no slot for (kind, node ids, ...) written as a plain attribute. */\n ROLE_DROPPED: ROLE_DROPPED_CODE,\n /** Containment order differs from index order; node indices change after a round trip. */\n HIERARCHY_REORDERED: \"W_GRAPHML_HIERARCHY_REORDERED\",\n /** Nodes whose parent chain never reaches a root are written at the top level. */\n PARENT_CYCLE: \"W_GRAPHML_PARENT_CYCLE\",\n /** Node ids that change type after a round trip under the canonical rule (design section 4.1). */\n ID_TEXT_TYPE: ID_TEXT_TYPE_CODE,\n /** A numeric edge id column reads back as string. */\n EDGE_ID_TEXT: \"W_GRAPHML_EDGE_ID_TEXT\",\n /** A `yfiles.*` graphics column that no longer matches its yFiles tree: only the tree is written. */\n YFILES_GRAPHICS_STALE: \"W_GRAPHML_YFILES_GRAPHICS_STALE\",\n /** A yfiles json value that is not a serialisable tree: export() will throw E_COLUMN_TYPE. */\n YFILES_TREE: \"E_GRAPHML_YFILES_TREE\",\n});\n","/**\n * Nested XML inside a GraphML `<data>` element (yFiles / yEd `y:ShapeNode`, `y:PolyLineEdge`,\n * ...) as a JSON tree, the value of a `json` column with `origin.namespace: \"yfiles\"` (design\n * section 8.5: structure preserved, not byte-exact). The shape follows the fast-xml-parser\n * convention graphty-element's parser already navigates: an element is an object whose\n * `@_<name>` keys are its attributes, whose `#text` key is its non-whitespace character data\n * when it also has attributes or children, and whose other keys are its child elements (an\n * array when a name repeats); an element with neither attributes nor children is its text\n * (an empty string for an empty element).\n *\n * The builder consumes the tokenizer events of one subtree; the writer produces the XML text of\n * a tree again, so a yFiles column re-exports as the same nested markup.\n */\n\nimport { GraphFormatError } from \"@graphty/graph-format\";\n\nimport { escapeXmlAttribute, escapeXmlText } from \"../../common/escape.js\";\nimport { isWhitespace, isXmlName } from \"../../common/xml.js\";\n\n/** The prefix of an attribute key in a tree object. */\nconst ATTRIBUTE_PREFIX = \"@_\";\n\n/** The key of an element's character data when it also has attributes or children. */\nconst TEXT_KEY = \"#text\";\n\n/** A tree object: attributes, text and child elements by name. */\ntype XmlTreeObject = Record<string, unknown>;\n\n/** A frame of the builder: one open element. */\ninterface Frame {\n readonly name: string;\n readonly node: XmlTreeObject;\n hasAttrs: boolean;\n hasChildren: boolean;\n text: string;\n}\n\n/**\n * Builds the tree of one subtree from start / end / text events. The outermost frame is the\n * `<data>` element itself; `finish()` returns its content: the object of its children, or its\n * text when it has none.\n */\nexport class XmlTreeBuilder {\n private readonly frames: Frame[] = [];\n\n private readonly root: Frame;\n\n /** Create a builder whose implicit root is the containing element. */\n constructor() {\n this.root = { name: \"\", node: {}, hasAttrs: false, hasChildren: false, text: \"\" };\n }\n\n /**\n * Whether the builder is inside a child element (as opposed to at the root level).\n * @returns true while at least one child element is open\n */\n get open(): boolean {\n return this.frames.length > 0;\n }\n\n /**\n * An element starts.\n * @param name - the element name as written\n * @param attrs - its attributes\n */\n start(name: string, attrs: ReadonlyMap<string, string>): void {\n const node: XmlTreeObject = {};\n let hasAttrs = false;\n for (const [key, value] of attrs) {\n node[ATTRIBUTE_PREFIX + key] = value;\n hasAttrs = true;\n }\n this.frames.push({ name, node, hasAttrs, hasChildren: false, text: \"\" });\n }\n\n /**\n * Character data inside the current element.\n * @param text - the text\n */\n text(text: string): void {\n const frame = this.frames.length > 0 ? this.frames[this.frames.length - 1] : this.root;\n frame.text += text;\n }\n\n /** The current element ends; its value is attached to its parent. */\n end(): void {\n const frame = this.frames.pop();\n if (frame === undefined) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", \"XmlTreeBuilder.end() without a matching start()\", {\n reason: \"tree builder underflow\",\n });\n }\n const parent = this.frames.length > 0 ? this.frames[this.frames.length - 1] : this.root;\n attachChild(parent, frame.name, valueOf(frame));\n }\n\n /**\n * The content of the containing element: its text when it has no child elements, otherwise\n * the object of its children (with `#text` for non-whitespace mixed content).\n * @returns the value to store in the json column\n */\n finish(): unknown {\n if (this.frames.length > 0) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", \"XmlTreeBuilder.finish() with open elements\", {\n reason: \"tree builder open\",\n });\n }\n const { root } = this;\n if (!root.hasChildren) {\n return root.text;\n }\n if (!isWhitespace(root.text)) {\n root.node[TEXT_KEY] = root.text;\n }\n return root.node;\n }\n}\n\n/**\n * The value of a finished element: its text when it has neither attributes nor children,\n * else its node with `#text` set to non-whitespace text.\n * @param frame - the finished frame\n * @returns the value\n */\nfunction valueOf(frame: Frame): unknown {\n if (!frame.hasAttrs && !frame.hasChildren) {\n return frame.text;\n }\n if (!isWhitespace(frame.text)) {\n frame.node[TEXT_KEY] = frame.text;\n }\n return frame.node;\n}\n\n/**\n * Attach a child value under a name, turning a repeated name into an array.\n * @param parent - the parent frame\n * @param name - the child element name\n * @param value - the child value\n */\nfunction attachChild(parent: Frame, name: string, value: unknown): void {\n parent.hasChildren = true;\n const existing = parent.node[name];\n if (existing === undefined) {\n parent.node[name] = value;\n } else if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n parent.node[name] = [existing, value];\n }\n}\n\n/**\n * Whether a value is a tree the writer can serialise: a string, number, boolean or null (text),\n * an array of such trees, or an object whose keys are `#text`, `@_<Name>` or `<Name>` with tree\n * values.\n * @param value - the value\n * @returns true when writeXmlTree() accepts it\n */\nexport function isXmlTree(value: unknown): boolean {\n return treeProblem(value) === null;\n}\n\n/**\n * Why a value is not a serialisable tree.\n * @param value - the value\n * @returns a message, or null when the value is a tree\n */\nexport function treeProblem(value: unknown): string | null {\n if (value === null || typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return null;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n if (Array.isArray(item)) {\n return \"nested arrays cannot be written as elements\";\n }\n const problem = treeProblem(item);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n }\n if (typeof value !== \"object\") {\n return `a ${typeof value} cannot be written as XML`;\n }\n for (const [key, child] of Object.entries(value)) {\n if (key === TEXT_KEY) {\n if (child !== null && typeof child === \"object\") {\n return \"#text must be a scalar\";\n }\n continue;\n }\n if (key.startsWith(ATTRIBUTE_PREFIX)) {\n const name = key.slice(ATTRIBUTE_PREFIX.length);\n if (!isXmlName(name)) {\n return `\"${name}\" is not an XML attribute name`;\n }\n if (child !== null && typeof child === \"object\") {\n return `attribute ${name} must be a scalar`;\n }\n continue;\n }\n if (!isXmlName(key)) {\n return `\"${key}\" is not an XML element name`;\n }\n const problem = treeProblem(child);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n}\n\n/**\n * Write the content of a tree as XML text: the children (and mixed text) of the containing\n * element. Leaf elements are written inline so their text stays exact; elements with children\n * are broken over lines and indented.\n * @param value - the tree (the content of a `<data>` element)\n * @param indent - the indentation of the containing element's children\n * @param out - receives the text parts\n */\nexport function writeXmlTree(value: unknown, indent: string, out: string[]): void {\n const problem = treeProblem(value);\n if (problem !== null) {\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `a yfiles value cannot be written as XML: ${problem}`, {\n reason: \"xml tree\",\n });\n }\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n out.push(escapeXmlText(scalarText(value)));\n return;\n }\n const object = value as XmlTreeObject;\n let text: string | null = null;\n for (const [key, child] of Object.entries(object)) {\n if (key === TEXT_KEY) {\n text = scalarText(child);\n } else if (!key.startsWith(ATTRIBUTE_PREFIX)) {\n writeElements(key, child, indent, out);\n }\n }\n if (text !== null) {\n out.push(escapeXmlText(text));\n }\n}\n\n/**\n * Write one element (or, for an array, one element per item).\n * @param name - the element name\n * @param value - the element value\n * @param indent - the indentation of this element\n * @param out - receives the text parts\n */\nfunction writeElements(name: string, value: unknown, indent: string, out: string[]): void {\n if (Array.isArray(value)) {\n for (const item of value) {\n writeElements(name, item, indent, out);\n }\n return;\n }\n if (value === null || typeof value !== \"object\") {\n const text = scalarText(value);\n out.push(text.length === 0 ? `\\n${indent}<${name}/>` : `\\n${indent}<${name}>${escapeXmlText(text)}</${name}>`);\n return;\n }\n const object = value as XmlTreeObject;\n let attrs = \"\";\n let text: string | null = null;\n let hasChildren = false;\n for (const [key, child] of Object.entries(object)) {\n if (key === TEXT_KEY) {\n text = scalarText(child);\n } else if (key.startsWith(ATTRIBUTE_PREFIX)) {\n attrs += ` ${key.slice(ATTRIBUTE_PREFIX.length)}=\"${escapeXmlAttribute(scalarText(child))}\"`;\n } else {\n hasChildren = true;\n }\n }\n if (!hasChildren) {\n out.push(\n text === null || text.length === 0\n ? `\\n${indent}<${name}${attrs}/>`\n : `\\n${indent}<${name}${attrs}>${escapeXmlText(text)}</${name}>`,\n );\n return;\n }\n out.push(`\\n${indent}<${name}${attrs}>`);\n const inner = `${indent} `;\n for (const [key, child] of Object.entries(object)) {\n if (key !== TEXT_KEY && !key.startsWith(ATTRIBUTE_PREFIX)) {\n writeElements(key, child, inner, out);\n }\n }\n if (text !== null) {\n out.push(escapeXmlText(text));\n }\n out.push(`\\n${indent}</${name}>`);\n}\n\n/**\n * The text of a scalar tree value.\n * @param value - a string, number, boolean or null\n * @returns the text; an empty string for null\n */\nfunction scalarText(value: unknown): string {\n switch (typeof value) {\n case \"string\":\n return value;\n case \"number\":\n case \"boolean\":\n case \"bigint\":\n return String(value);\n default:\n return \"\";\n }\n}\n","/**\n * yFiles / yEd graphics read out of the JSON tree of a `yfiles.type` key (tree.ts) into typed\n * columns, beside the tree itself: a `y:ShapeNode` gives the node's position, size, fill and\n * border colours, label and shape, and a `y:PolyLineEdge` gives the edge's line colour and width,\n * its arrows and the direction they draw. The values are the ones graphty-element's own GraphML\n * parser produced, so a consumer rebuilds its records by dropping the `yfiles.` prefix: colours\n * are `#RRGGBB` in upper case (a `#RGB` is expanded, any other text is kept as written), numbers\n * are parsed with parseFloat, the position is `[x, y, 0]` and the shape is the yFiles shape type\n * as written. One difference: a label whose text is a number (`<y:NodeLabel>0</y:NodeLabel>`) is\n * kept as that text, where the element's parser turned it into a number and stored `\"\"`, nothing\n * or the number.\n *\n * The columns are views of the tree: the exporter writes the tree and never these columns, and\n * re-importing the tree gives them back. A value edited after import (a layout writing the\n * position) or a tree column removed is therefore not written, and the exporter reports it as a\n * loss (staleGraphicsRows()).\n */\n\nimport { type Column, type ColumnDecl, type JsonColumn } from \"@graphty/graph-format\";\n\nimport { localName } from \"../../common/xml.js\";\n\n/** The name prefix of every column mapped from yFiles graphics. */\nconst YFILES_COLUMN_PREFIX = \"yfiles.\";\n\ntype Tree = Record<string, unknown>;\n\n/** The mapped node columns, by the field name graphty-element's records use. */\nconst NODE_FIELDS: Readonly<Record<string, Omit<ColumnDecl, \"name\">>> = {\n position: { dtype: \"f64\", components: 3, role: \"position\", mutable: true },\n width: { dtype: \"f64\" },\n height: { dtype: \"f64\" },\n color: { dtype: \"string\" },\n borderColor: { dtype: \"string\" },\n borderWidth: { dtype: \"f64\" },\n label: { dtype: \"string\", role: \"label\" },\n shape: { dtype: \"string\" },\n};\n\n/** The mapped edge columns, by field name. */\nconst EDGE_FIELDS: Readonly<Record<string, Omit<ColumnDecl, \"name\">>> = {\n color: { dtype: \"string\" },\n width: { dtype: \"f64\" },\n directed: { dtype: \"bool\" },\n targetArrow: { dtype: \"string\" },\n sourceArrow: { dtype: \"string\" },\n};\n\n/**\n * The declaration of a mapped column.\n * @param domain - node or edge\n * @param field - the field name (a key of the values graphicsValues() returns)\n * @param keyId - the id of the GraphML key whose tree it is read from\n * @returns the declaration\n */\nexport function graphicsDecl(domain: \"node\" | \"edge\", field: string, keyId: string): ColumnDecl {\n const fields = domain === \"node\" ? NODE_FIELDS : EDGE_FIELDS;\n return {\n ...fields[field],\n name: YFILES_COLUMN_PREFIX + field,\n nullable: true,\n origin: {\n format: \"graphml\",\n id: keyId,\n title: null,\n type: domain === \"node\" ? \"ShapeNode\" : \"PolyLineEdge\",\n namespace: \"yfiles\",\n },\n };\n}\n\n/**\n * Whether a column is one graphicsDecl() declared (a view of a yFiles tree, never exported).\n * @param meta - the column's name, dtype and origin\n * @param meta.name - the column name\n * @param meta.dtype - the column dtype\n * @param meta.origin - the column origin\n * @returns true for a mapped graphics column\n */\nexport function isGraphicsColumn(meta: {\n readonly name: string;\n readonly dtype: string;\n readonly origin: { readonly namespace: string | null } | null;\n}): boolean {\n return meta.dtype !== \"json\" && meta.origin?.namespace === \"yfiles\" && meta.name.startsWith(YFILES_COLUMN_PREFIX);\n}\n\n/**\n * The rows of a mapped graphics column whose value is not one its yFiles tree columns (in the\n * same table) give: every set row when no tree column gives a value for the row. A file may\n * declare several yFiles keys for one domain, and the mapped column holds the values of all of\n * them, so a row is current when any tree's value matches. These are the values an export loses,\n * since only the trees are written.\n * @param column - the mapped column (isGraphicsColumn())\n * @param table - the table it is in\n * @param domain - node or edge\n * @returns the number of rows that differ from the trees\n */\nexport function staleGraphicsRows(column: Column, table: Iterable<Column>, domain: \"node\" | \"edge\"): number {\n const field = column.meta.name.slice(YFILES_COLUMN_PREFIX.length);\n const trees: JsonColumn[] = [];\n for (const c of table) {\n if (c.dtype === \"json\" && c.meta.origin?.namespace === \"yfiles\") {\n trees.push(c);\n }\n }\n let stale = 0;\n for (let r = 0; r < column.length; r++) {\n const wants = new Set<string>();\n for (const tree of trees) {\n const want = graphicsValues(domain, tree.values[r]).find(([f]) => f === field);\n if (want !== undefined) {\n wants.add(JSON.stringify(want[1]));\n }\n }\n if (wants.size === 0) {\n wants.add(JSON.stringify(undefined));\n }\n const value = column.value(r);\n const have = column.meta.components > 1 && value !== undefined ? Array.from(value as ArrayLike<number>) : value;\n if (!wants.has(JSON.stringify(have))) {\n stale++;\n }\n }\n return stale;\n}\n\n/**\n * The mapped values of one `<data>` tree of a yFiles key: a ShapeNode's for a node, a\n * PolyLineEdge's for an edge; nothing for any other graphics (GenericNode, BezierEdge, ...).\n * @param domain - node or edge\n * @param tree - the `<data>` content as tree.ts builds it\n * @returns field name -> value, in declaration order\n */\nexport function graphicsValues(domain: \"node\" | \"edge\", tree: unknown): [string, unknown][] {\n const out: [string, unknown][] = [];\n if (domain === \"node\") {\n const shape = child(tree, \"ShapeNode\");\n if (shape !== undefined) {\n shapeNodeValues(shape, out);\n }\n } else {\n const edge = child(tree, \"PolyLineEdge\");\n if (edge !== undefined) {\n polyLineEdgeValues(edge, out);\n }\n }\n return out;\n}\n\n/**\n * Read a ShapeNode.\n * @param shape - the ShapeNode element\n * @param out - receives the values\n */\nfunction shapeNodeValues(shape: unknown, out: [string, unknown][]): void {\n const geometry = child(shape, \"Geometry\");\n // yFiles requires x, y, width and height on Geometry; a position needs both coordinates\n const x = number(attr(geometry, \"x\"));\n const y = number(attr(geometry, \"y\"));\n if (x !== undefined && y !== undefined) {\n out.push([\"position\", [x, y, 0]]);\n }\n push(out, \"width\", number(attr(geometry, \"width\")));\n push(out, \"height\", number(attr(geometry, \"height\")));\n push(out, \"color\", color(attr(child(shape, \"Fill\"), \"color\")));\n const border = child(shape, \"BorderStyle\");\n push(out, \"borderColor\", color(attr(border, \"color\")));\n push(out, \"borderWidth\", number(attr(border, \"width\")));\n const label = child(shape, \"NodeLabel\");\n // an element with no text and no attributes is \"\" (no label); one with attributes but no text is a blank label\n if (typeof label === \"string\" ? label.length > 0 : label !== undefined) {\n // trimmed, as the element's parser (trimValues) reads it: pretty-printed yEd puts whitespace before the label's children\n out.push([\"label\", (typeof label === \"string\" ? label : (text(label) ?? \"\")).trim()]);\n }\n push(out, \"shape\", nonEmpty(attr(child(shape, \"Shape\"), \"type\")));\n}\n\n/**\n * Read a PolyLineEdge.\n * @param edge - the PolyLineEdge element\n * @param out - receives the values\n */\nfunction polyLineEdgeValues(edge: unknown, out: [string, unknown][]): void {\n const line = child(edge, \"LineStyle\");\n push(out, \"color\", color(attr(line, \"color\")));\n push(out, \"width\", number(attr(line, \"width\")));\n const arrows = child(edge, \"Arrows\");\n if (arrows !== undefined && typeof arrows === \"object\") {\n const target = attr(arrows, \"target\");\n const source = attr(arrows, \"source\");\n // yEd draws direction with the target arrow; the file's edgedefault still decides topology\n out.push([\"directed\", target !== undefined && target !== \"none\"]);\n push(out, \"targetArrow\", target === \"none\" ? undefined : nonEmpty(target));\n push(out, \"sourceArrow\", source === \"none\" ? undefined : nonEmpty(source));\n }\n}\n\n/**\n * Append a value when it is defined.\n * @param out - the values\n * @param field - the field name\n * @param value - the value\n */\nfunction push(out: [string, unknown][], field: string, value: unknown): void {\n if (value !== undefined) {\n out.push([field, value]);\n }\n}\n\n/**\n * The first child element of a tree node by local name, whatever its namespace prefix.\n * @param node - the tree node\n * @param local - the local name\n * @returns the child, or undefined\n */\nfunction child(node: unknown, local: string): unknown {\n if (typeof node !== \"object\" || node === null) {\n return undefined;\n }\n for (const [key, value] of Object.entries(node as Tree)) {\n if (!key.startsWith(\"@_\") && key !== \"#text\" && localName(key) === local) {\n return Array.isArray(value) ? value[0] : value;\n }\n }\n return undefined;\n}\n\n/**\n * An attribute of a tree node.\n * @param node - the tree node\n * @param name - the attribute name\n * @returns the text, or undefined\n */\nfunction attr(node: unknown, name: string): string | undefined {\n if (typeof node !== \"object\" || node === null) {\n return undefined;\n }\n const value = (node as Tree)[`@_${name}`];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * The character data of an element that also has attributes or children.\n * @param node - the tree node\n * @returns the text, or undefined\n */\nfunction text(node: unknown): string | undefined {\n const value = typeof node === \"object\" && node !== null ? (node as Tree)[\"#text\"] : undefined;\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * A non-empty text.\n * @param value - the text\n * @returns the text, or undefined when absent or empty\n */\nfunction nonEmpty(value: string | undefined): string | undefined {\n return value === undefined || value.length === 0 ? undefined : value;\n}\n\n/**\n * A number attribute, parsed as graphty-element's parser parsed it.\n * @param value - the text\n * @returns the number, or undefined when absent, empty or not a number\n */\nfunction number(value: string | undefined): number | undefined {\n if (value === undefined || value.length === 0) {\n return undefined;\n }\n const n = Number.parseFloat(value);\n return Number.isNaN(n) ? undefined : n;\n}\n\n/**\n * A colour attribute: `#RRGGBB` upper-cased, `#RGB` expanded, anything else as written.\n * @param value - the text\n * @returns the colour, or undefined when absent or empty\n */\nfunction color(value: string | undefined): string | undefined {\n if (value === undefined || value.length === 0) {\n return undefined;\n }\n if (/^#[0-9A-Fa-f]{6}$/.test(value)) {\n return value.toUpperCase();\n }\n if (/^#[0-9A-Fa-f]{3}$/.test(value)) {\n const [, r, g, b] = value;\n return `#${r}${r}${g}${g}${b}${b}`.toUpperCase();\n }\n return value;\n}\n","/**\n * The GraphML exporter (design section 8.5; research note 07 section 9): `<key>` declarations\n * regenerated from ColumnMeta.origin when the column came from GraphML (key id, attr.name,\n * attr.type, yfiles.type) and derived from the dtype otherwise; node ids sanitised to NMTOKEN\n * (`sanitizeIds: \"error\"` refuses, `\"mangle\"` rewrites and keeps the original in a\n * `graphty:originalId` data attribute the importer restores); mixed direction written with\n * `edgedefault` plus per-edge `directed` attributes, folding expanded pairs back through the\n * `pair` / `directed` role columns; explicit weights only (the role-weight column's validity);\n * containment (`parent` role) as nested graphs; yFiles json columns as nested XML again.\n *\n * check() lists every loss before anything is written: the generic capability gaps of\n * checkCapabilities() (dict / u32 / u8 dtypes, lists, components, options, positions, visual and\n * temporal roles, extension tables) plus the GraphML-specific ones (mutual edges written as\n * undirected, json columns without a yfiles origin written as JSON text, multi-parent columns,\n * containment order, ids that change type under the canonical rule, edge ids that read back as\n * strings, roles GraphML cannot express, yfiles values that are not serialisable trees).\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot, INVALID_INDEX } from \"@graphty/graph-format\";\n\nimport { childrenCsr } from \"../../children.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { escapeXmlAttribute, escapeXmlText } from \"../../common/escape.js\";\nimport {\n capabilities,\n checkCapabilities,\n isNmtoken,\n LOSS,\n mangleNmtoken,\n type SanitizedIds,\n sanitizeIds,\n} from \"../../common/export.js\";\nimport { formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { isCanonicalIntegerText } from \"../../common/ids.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { xmlIllegalTextNotes } from \"../../common/xml.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport {\n EDGE_ID_COLUMN,\n FORMAT,\n GRAPHML_LOSS,\n GRAPHML_NAMESPACE,\n type GraphmlMeta,\n LABEL_COLUMN,\n META_KEY,\n ORIGINAL_ID_ATTRIBUTE,\n PARENT_COLUMN,\n RESERVED_EDGE_NAMES,\n RESERVED_NODE_NAMES,\n SCHEMA_LOCATION,\n SOURCE_PORT_COLUMN,\n TARGET_PORT_COLUMN,\n XSI_NAMESPACE,\n YFILES_NAMESPACE,\n} from \"./constants.js\";\nimport { treeProblem, writeXmlTree } from \"./tree.js\";\nimport { isGraphicsColumn, staleGraphicsRows } from \"./yfiles.js\";\n\n/** The format-specific options of the GraphML exporter. */\nexport interface GraphmlExportOptions {\n /** Indent nested elements (default true); false writes one element per line without indentation. */\n pretty?: boolean | undefined;\n /**\n * The top-level `edgedefault`. By default the one the importer recorded in\n * `meta.extra.graphml` (so a mixed file re-imports with the same edge layout), else the\n * snapshot's direction, with the majority direction for a mixed snapshot.\n */\n edgedefault?: \"directed\" | \"undirected\" | undefined;\n}\n\n/** What GraphML keeps as declared (research note 07 section 9). */\nconst CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: true,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"optional\",\n idCharset: \"nmtoken\",\n dtypes: [\"bool\", \"i32\", \"f32\", \"f64\", \"string\"],\n components: false,\n lists: false,\n json: false,\n defaults: true,\n options: false,\n hierarchy: true,\n temporal: \"none\",\n graphAttributes: true,\n positions: false,\n viz: false,\n});\n\n/** Roles handled structurally (never written as a key) or reported by checkCapabilities() and not written. */\nconst STRUCTURAL_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n]);\nconst DROPPED_ROLES: ReadonlySet<string> = new Set([\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\n/**\n * The roles GraphML has a slot for (checkCapabilities() reports every other role as lost): the\n * label key, the edge `id`, `sourceport` and `targetport` attributes and nested graphs.\n */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"label\", \"id\", \"sourcePort\", \"targetPort\", \"parent\"]);\n\n/** The slot roles written structurally per domain (never as a key); a label is a key titled `label`. */\nconst SLOT_ROLES_BY_DOMAIN: Readonly<Record<Domain, ReadonlySet<string>>> = {\n graph: new Set(),\n node: new Set([\"parent\"]),\n edge: new Set([\"id\", \"sourcePort\", \"targetPort\"]),\n};\n\n/** The names the importer gives the slot columns (design section 5.6), for the name-change notes. */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: LABEL_COLUMN,\n id: EDGE_ID_COLUMN,\n sourcePort: SOURCE_PORT_COLUMN,\n targetPort: TARGET_PORT_COLUMN,\n parent: PARENT_COLUMN,\n});\n\n/** The attr.name of the weight key when the weight did not come from GraphML (the importer's weightFrom default). */\nconst DEFAULT_WEIGHT_NAME = \"weight\";\n\n/** A note-recording callback. */\ntype NoteFn = (code: string, message: string, column?: string | null, count?: number | null) => void;\n\n/** The GraphML attr.type values and the dtype each maps to, for restoring origin.type. */\nconst TYPE_DTYPES: Readonly<Record<string, string>> = {\n boolean: \"bool\",\n int: \"i32\",\n long: \"f64\",\n float: \"f32\",\n double: \"f64\",\n string: \"string\",\n};\n\nconst I32_MAX = 2147483647;\n\n/** The yfiles.type written for a yfiles json column whose origin records none. */\nconst DEFAULT_YFILES_TYPES: Readonly<Record<Domain, string>> = {\n node: \"nodegraphics\",\n edge: \"edgegraphics\",\n graph: \"resources\",\n};\n\n/** The element domains. */\ntype Domain = \"graph\" | \"node\" | \"edge\";\n\n/** One column written as a key. */\ninterface ColumnPlan {\n readonly column: Column;\n readonly domain: Domain;\n /** The key id. */\n keyId: string;\n /** The attr.type, or null for a yfiles key. */\n readonly attrType: string | null;\n /** The attr.name, or null for a yfiles key. */\n readonly attrName: string | null;\n /** The yfiles.type, or null. */\n readonly yfilesType: string | null;\n /** Whether values are written as nested XML trees. */\n readonly yfiles: boolean;\n}\n\n/** One `<key>` element (a for=\"all\" key merges up to three column plans). */\ninterface KeyPlan {\n readonly id: string;\n readonly domains: readonly Domain[];\n readonly attrName: string | null;\n readonly attrType: string | null;\n readonly yfilesType: string | null;\n /** The column whose default and desc are written; null for the weight key. */\n readonly column: Column | null;\n}\n\n/** Containment as the exporter writes it. */\ninterface Hierarchy {\n /** The parent column, or null. */\n readonly parent: Column | null;\n /** Nodes written at the top level, in order (roots, then the roots forced out of cycles). */\n readonly roots: Uint32Array;\n /** CSR of children by parent: childStart[u]..childStart[u+1] over childList. */\n readonly childStart: Uint32Array;\n readonly childList: Uint32Array;\n /** Whether the written order differs from index order. */\n readonly reordered: boolean;\n /** Nodes whose parent chain never reaches a root. */\n readonly unreachable: number;\n}\n\n/** Everything check() and export() agree on. */\ninterface Plan {\n readonly options: ResolvedExportOptions;\n readonly pretty: boolean;\n readonly notes: LossNote[];\n readonly keys: KeyPlan[];\n readonly graphColumns: ColumnPlan[];\n readonly nodeColumns: ColumnPlan[];\n readonly edgeColumns: ColumnPlan[];\n /** The weight key id, attr.type and the explicit weights, or null for an unweighted snapshot. */\n readonly weight: { readonly keyId: string; readonly attrType: string; readonly weights: ExplicitWeights } | null;\n /** The key id of the originalId attribute, when mangled ids are written. */\n readonly originalIdKey: string | null;\n readonly edgedefault: \"directed\" | \"undirected\";\n /** The pair folding: mirrors skipped, source directions. */\n readonly folding: PairFolding;\n readonly edgeIdColumn: Column | null;\n readonly sourcePortColumn: Column | null;\n readonly targetPortColumn: Column | null;\n readonly hierarchy: Hierarchy;\n readonly meta: GraphmlMeta | null;\n readonly needsOriginalIdKey: boolean;\n}\n\n/** The resolved format-specific options. */\ninterface FormatOptions {\n /** Whether to indent. */\n readonly pretty: boolean;\n /** The edgedefault override, or null. */\n readonly edgedefault: \"directed\" | \"undirected\" | null;\n}\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the pretty flag and the edgedefault override\n */\nfunction resolveFormatOptions(options: GraphmlExportOptions | undefined): FormatOptions {\n const pretty = options?.pretty ?? true;\n if (typeof pretty !== \"boolean\") {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option pretty must be a boolean\", {\n option: \"pretty\",\n found: typeof pretty,\n });\n }\n const edgedefault = options?.edgedefault ?? null;\n if (edgedefault !== null && edgedefault !== \"directed\" && edgedefault !== \"undirected\") {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option edgedefault: ${JSON.stringify(edgedefault)} is not \"directed\" or \"undirected\"`,\n { option: \"edgedefault\", found: edgedefault },\n );\n }\n return { pretty, edgedefault };\n}\n\n/**\n * The importer's `meta.extra.graphml`, when the snapshot has one of the expected shape.\n * @param snapshot - the snapshot\n * @returns the meta, or null\n */\nfunction graphmlMetaOf(snapshot: GraphSnapshot): GraphmlMeta | null {\n const value = snapshot.meta.extra[META_KEY];\n if (typeof value !== \"object\" || value === null) {\n return null;\n }\n const record = value as Record<string, unknown>;\n const graphId = typeof record.graphId === \"string\" ? record.graphId : null;\n const edgedefault =\n record.edgedefault === \"directed\" || record.edgedefault === \"undirected\" ? record.edgedefault : null;\n const namespaces: Record<string, string> = {};\n if (typeof record.namespaces === \"object\" && record.namespaces !== null) {\n for (const [prefix, uri] of Object.entries(record.namespaces as Record<string, unknown>)) {\n if (typeof uri === \"string\") {\n namespaces[prefix] = uri;\n }\n }\n }\n return { graphId, edgedefault, namespaces };\n}\n\n/**\n * Build the plan: classify every column, assign key ids, decide the edgedefault and the\n * containment order, and collect every loss note.\n * @param snapshot - the snapshot\n * @param options - the resolved common options\n * @param format - the resolved format options\n * @returns the plan\n */\nfunction planExport(snapshot: GraphSnapshot, options: ResolvedExportOptions, format: FormatOptions): Plan {\n // the generic json note is replaced by planTable()'s (yfiles trees are kept, other json is\n // text); columns mapped from a yfiles tree are never written: planTable() notes the ones\n // that no longer match their tree, the rest lose nothing\n const graphics = new Set(\n [...snapshot.nodes, ...snapshot.edges].filter((c) => isGraphicsColumn(c.meta)).map((c) => c.meta.name),\n );\n const notes = checkCapabilities(snapshot, CAPABILITIES, options, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n }).filter((n) => n.code !== LOSS.JSON && (n.column === null || !graphics.has(n.column)));\n const note: NoteFn = (code, message, column = null, count = null): void => {\n notes.push(Object.freeze({ code, message, column, count }));\n };\n notes.push(...xmlIllegalTextNotes(snapshot));\n const meta = graphmlMetaOf(snapshot);\n const keyIds = new KeyIds();\n\n const graphColumns = planTable(snapshot.graph, \"graph\", notes, note);\n const nodeColumns = planTable(snapshot.nodes, \"node\", notes, note);\n const edgeColumns = planTable(snapshot.edges, \"edge\", notes, note);\n const keys = planKeys([...graphColumns, ...nodeColumns, ...edgeColumns], keyIds);\n reservedNameNotes(nodeColumns, RESERVED_NODE_NAMES, note);\n reservedNameNotes(edgeColumns, RESERVED_EDGE_NAMES, note);\n const weight = planWeight(snapshot, edgeColumns, keyIds, keys, note);\n\n // ids\n const idTypeChanges = countIdTypeChanges(snapshot);\n if (idTypeChanges > 0) {\n note(\n GRAPHML_LOSS.ID_TEXT_TYPE,\n `${idTypeChanges} node id(s) change type when read back under ids: \"canonical\" (string ids that are integer text, non-integer numbers)`,\n null,\n idTypeChanges,\n );\n }\n const edgeIdColumn = snapshot.edges.byRole(\"id\");\n if (edgeIdColumn !== null) {\n planEdgeIds(snapshot, edgeIdColumn, options, note);\n }\n const unrepresentable = countUnrepresentableNodeIds(snapshot);\n const needsOriginalIdKey = unrepresentable > 0 && options.sanitizeIds === \"mangle\";\n const originalIdKey = needsOriginalIdKey ? keyIds.next(null) : null;\n\n // direction: an undirected pair folds to one undirected edge, a mutual pair too (the mark is lost)\n const folding = pairFolding(snapshot, { foldMutual: true });\n if (folding.mutualCount > 0) {\n note(\n GRAPHML_LOSS.MUTUAL_AS_UNDIRECTED,\n `${folding.mutualCount} mutual pair(s) are written as undirected edges; the mutual mark is lost`,\n null,\n folding.mutualCount,\n );\n }\n const edgedefault = planEdgedefault(snapshot, folding, format, meta);\n\n // containment\n const hierarchy = planHierarchy(snapshot);\n if (hierarchy.reordered) {\n note(\n GRAPHML_LOSS.HIERARCHY_REORDERED,\n \"nodes are written in containment order (children nested under their parent); node indices change after a round trip\",\n hierarchy.parent?.meta.name ?? null,\n );\n }\n if (hierarchy.unreachable > 0) {\n note(\n GRAPHML_LOSS.PARENT_CYCLE,\n `${hierarchy.unreachable} node(s) whose parent chain never reaches a root are written at the top level`,\n hierarchy.parent?.meta.name ?? null,\n hierarchy.unreachable,\n );\n }\n\n return {\n options,\n pretty: format.pretty,\n notes,\n keys,\n graphColumns,\n nodeColumns,\n edgeColumns,\n weight,\n originalIdKey,\n edgedefault,\n folding,\n edgeIdColumn,\n sourcePortColumn: snapshot.edges.byRole(\"sourcePort\"),\n targetPortColumn: snapshot.edges.byRole(\"targetPort\"),\n hierarchy,\n meta,\n needsOriginalIdKey,\n };\n}\n\n/**\n * A plain column titled like one of the importer's XML-derived columns (`id`, `sourceport`,\n * `targetport` on edges, `parent` on nodes) reads back renamed `<name>#<key id>` (design section\n * 5.6); the note says so.\n * @param plans - the column plans of one domain, key ids assigned\n * @param reserved - the reserved names of that domain\n * @param note - the note recorder\n */\nfunction reservedNameNotes(plans: readonly ColumnPlan[], reserved: ReadonlySet<string>, note: NoteFn): void {\n for (const plan of plans) {\n const { column, attrName, keyId } = plan;\n if (attrName === null || !reserved.has(attrName)) {\n continue;\n }\n note(\n LOSS.COLUMN_NAME_CHANGED,\n `${plan.domain} column \"${column.meta.name}\" is titled like the importer's ${attrName} column and reads back as \"${attrName}#${keyId}\"`,\n column.meta.name,\n column.length - column.nullCount,\n );\n }\n}\n\n/** The key ids handed out so far: a preferred NMTOKEN when free, else the next free `d<n>`. */\nclass KeyIds {\n private readonly used = new Set<string>();\n private counter = 0;\n\n /**\n * Take a key id.\n * @param preferred - the id to keep when it is an NMTOKEN not handed out yet, or null\n * @returns the id\n */\n next(preferred: string | null): string {\n if (preferred !== null && isNmtoken(preferred) && !this.used.has(preferred)) {\n this.used.add(preferred);\n return preferred;\n }\n for (;;) {\n const candidate = `d${this.counter}`;\n this.counter++;\n if (!this.used.has(candidate)) {\n this.used.add(candidate);\n return candidate;\n }\n }\n }\n}\n\n/**\n * The `<key>` elements: columns sharing a GraphML origin.id across domains become one for=\"all\"\n * key when their name, type and default agree; every other column is its own key.\n * @param all - the column plans of the three domains, in writing order\n * @param keyIds - the key id allocator\n * @returns the keys, in declaration order\n */\nfunction planKeys(all: readonly ColumnPlan[], keyIds: KeyIds): KeyPlan[] {\n const keys: KeyPlan[] = [];\n const byOrigin = new Map<string, ColumnPlan[]>();\n for (const plan of all) {\n const { origin } = plan.column.meta;\n if (origin !== null && origin.format === FORMAT && origin.id !== null) {\n const group = byOrigin.get(origin.id) ?? [];\n group.push(plan);\n byOrigin.set(origin.id, group);\n }\n }\n const planned = new Set<ColumnPlan>();\n for (const plan of all) {\n if (planned.has(plan)) {\n continue;\n }\n const { origin } = plan.column.meta;\n const group =\n origin !== null && origin.format === FORMAT && origin.id !== null\n ? (byOrigin.get(origin.id) ?? [plan])\n : [plan];\n const shared = group.length > 1 && group.every((other) => other === plan || sameKey(plan, other));\n const members = shared ? group : [plan];\n const id = keyIds.next(origin !== null && origin.format === FORMAT ? origin.id : null);\n for (const member of members) {\n member.keyId = id;\n planned.add(member);\n }\n const domains = members.map((member) => member.domain);\n // a yfiles key carries attr.name only when the column name is not the key id (yEd writes none)\n const yfilesName = plan.column.meta.origin?.title ?? plan.column.meta.name;\n let { attrName } = plan;\n if (plan.yfiles) {\n attrName = yfilesName === id ? null : yfilesName;\n }\n keys.push({\n id,\n domains: domains.length > 1 ? [\"graph\", \"node\", \"edge\"] : domains,\n attrName,\n attrType: plan.attrType,\n yfilesType: plan.yfilesType,\n column: plan.column,\n });\n }\n return keys;\n}\n\n/**\n * The weight key of a weighted snapshot (its attr.name and attr.type restored from\n * meta.weightOrigin when the weight came from GraphML), and the note for an edge column the\n * importer would read as THE weight: every edge key titled like the weight key (`weight` by\n * default) is a weight key on import, so such a column reads back as the weight, not as a column.\n * @param snapshot - the snapshot\n * @param edgeColumns - the edge column plans\n * @param keyIds - the key id allocator\n * @param keys - receives the weight key\n * @param note - the note recorder\n * @returns the weight plan, or null for an unweighted snapshot\n */\nfunction planWeight(\n snapshot: GraphSnapshot,\n edgeColumns: readonly ColumnPlan[],\n keyIds: KeyIds,\n keys: KeyPlan[],\n note: NoteFn,\n): Plan[\"weight\"] {\n const weights = explicitWeights(snapshot);\n const origin = snapshot.meta.weightOrigin;\n const fromGraphml = weights.weighted && origin !== null && origin.format === FORMAT;\n const attrName = fromGraphml && origin.title !== null ? origin.title : DEFAULT_WEIGHT_NAME;\n for (const plan of edgeColumns) {\n if (plan.attrName === attrName) {\n note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${plan.column.meta.name}\" is written as a key titled \"${attrName}\", which the importer reads as THE weight (weightFrom); it reads back as the weight, not as a column`,\n plan.column.meta.name,\n plan.column.length - plan.column.nullCount,\n );\n }\n }\n if (!weights.weighted) {\n return null;\n }\n let attrType = \"double\";\n if (fromGraphml && origin.type !== null) {\n const declared = origin.type.trim().toLowerCase();\n if (declared === \"float\" || declared === \"double\" || declared === \"long\" || declared === \"int\") {\n attrType = declared;\n }\n }\n if ((attrType === \"int\" || attrType === \"long\") && !weightsIntegral(snapshot, weights)) {\n // a declared integer weight only survives when every explicit weight is integral\n attrType = \"double\";\n }\n const id = keyIds.next(fromGraphml ? origin.id : null);\n keys.push({ id, domains: [\"edge\"], attrName, attrType, yfilesType: null, column: null });\n return { keyId: id, attrType, weights };\n}\n\n/**\n * The notes about the edge id column: a numeric column reads back as string; ids outside the\n * NMTOKEN charset are refused or mangled per sanitizeIds.\n * @param snapshot - the snapshot\n * @param column - the edge id column\n * @param options - the resolved options\n * @param note - the note recorder\n */\nfunction planEdgeIds(snapshot: GraphSnapshot, column: Column, options: ResolvedExportOptions, note: NoteFn): void {\n if (column.dtype !== \"string\" && column.dtype !== \"dict\") {\n note(\n GRAPHML_LOSS.EDGE_ID_TEXT,\n `edge id column \"${column.meta.name}\" is ${column.dtype}; GraphML edge ids read back as strings`,\n column.meta.name,\n snapshot.edgeCount - column.nullCount,\n );\n }\n const bad = countBadEdgeIds(column);\n if (bad === 0) {\n return;\n }\n if (options.sanitizeIds === \"mangle\") {\n note(LOSS.ID_MANGLED, `${bad} edge id(s) outside the nmtoken charset are rewritten`, column.meta.name, bad);\n } else {\n note(\n LOSS.ID_CHARSET,\n `${bad} edge id(s) outside the nmtoken charset; export() will throw unless sanitizeIds is \"mangle\"`,\n column.meta.name,\n bad,\n );\n }\n}\n\n/**\n * The top-level edgedefault: the override, else undirected for an undirected snapshot, else\n * directed when no written edge is undirected, else the one the importer recorded, else the\n * majority direction.\n * @param snapshot - the snapshot\n * @param folding - the pair folding\n * @param format - the resolved format options\n * @param meta - the importer's meta, or null\n * @returns the edgedefault\n */\nfunction planEdgedefault(\n snapshot: GraphSnapshot,\n folding: PairFolding,\n format: FormatOptions,\n meta: GraphmlMeta | null,\n): \"directed\" | \"undirected\" {\n if (format.edgedefault !== null) {\n return format.edgedefault;\n }\n if (!snapshot.directed) {\n return \"undirected\";\n }\n let directedCount = 0;\n let undirectedCount = 0;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n if (isDirectedEdge(folding, e)) {\n directedCount++;\n } else {\n undirectedCount++;\n }\n }\n if (undirectedCount === 0) {\n return \"directed\";\n }\n const recorded = meta === null ? null : meta.edgedefault;\n if (recorded !== null) {\n return recorded;\n }\n return undirectedCount > directedCount ? \"undirected\" : \"directed\";\n}\n\n/**\n * Whether two column plans can share one for=\"all\" key.\n * @param a - one plan\n * @param b - another\n * @returns true when name, type and default agree\n */\nfunction sameKey(a: ColumnPlan, b: ColumnPlan): boolean {\n return (\n a.attrName === b.attrName &&\n a.attrType === b.attrType &&\n a.yfilesType === b.yfilesType &&\n a.domain !== b.domain &&\n JSON.stringify(a.column.meta.default ?? null) === JSON.stringify(b.column.meta.default ?? null)\n );\n}\n\n/**\n * Classify the columns of one table: which are written as keys and what each loses. A label\n * column is written into the label slot (a key titled `label`, which the importer reads back\n * with the role) unless the table holds another column of that name, in which case it keeps\n * its own title and the role is lost.\n * @param table - the table\n * @param domain - its domain\n * @param notes - the notes so far (the generic name-change note of a label column that cannot take the slot is withdrawn)\n * @param note - the note recorder\n * @returns the plans of the written columns, in declaration order\n */\nfunction planTable(table: Iterable<Column>, domain: Domain, notes: LossNote[], note: NoteFn): ColumnPlan[] {\n const plans: ColumnPlan[] = [];\n const columns = [...table];\n const names = new Set(columns.map((column) => column.meta.name));\n for (const column of columns) {\n const { meta } = column;\n const { role, name } = meta;\n if (isGraphicsColumn(meta)) {\n const stale = domain === \"graph\" ? 0 : staleGraphicsRows(column, columns, domain);\n if (stale > 0) {\n note(\n GRAPHML_LOSS.YFILES_GRAPHICS_STALE,\n `${stale} value(s) of ${domain} column \"${name}\" differ from the yFiles tree it was read from; only the tree is written, so they are lost`,\n name,\n stale,\n );\n }\n continue;\n }\n if (role === \"parents\") {\n note(\n GRAPHML_LOSS.PARENTS_DROPPED,\n `${domain} column \"${name}\" (parents) cannot be written: nested graphs hold one parent per node`,\n name,\n column.length - column.nullCount,\n );\n continue;\n }\n if (\n role !== null &&\n (STRUCTURAL_ROLES.has(role) || DROPPED_ROLES.has(role) || SLOT_ROLES_BY_DOMAIN[domain].has(role))\n ) {\n continue;\n }\n if (role !== null && role !== \"label\" && SLOT_ROLES.has(role)) {\n // the slot belongs to another domain (an edge id on a node, a port on a graph)\n withdrawNameChange(notes, name);\n note(\n LOSS.ROLE,\n `${domain} column \"${name}\" (${role}) is written as a plain attribute; GraphML has no ${role} slot for a ${domain} and the role is lost`,\n name,\n column.length - column.nullCount,\n );\n }\n const yfiles = meta.dtype === \"json\" && meta.origin?.namespace === \"yfiles\";\n if (meta.dtype === \"json\" && !yfiles) {\n note(\n LOSS.JSON,\n `${domain} column \"${name}\" holds nested values; written as JSON text, which reads back as string`,\n name,\n column.length - column.nullCount,\n );\n }\n if (yfiles) {\n const bad = countBadTrees(column);\n if (bad > 0) {\n note(\n GRAPHML_LOSS.YFILES_TREE,\n `${bad} value(s) of yfiles column \"${name}\" are not XML trees; export() will throw E_COLUMN_TYPE`,\n name,\n bad,\n );\n }\n }\n const { origin } = meta;\n const fromGraphml = origin !== null && origin.format === FORMAT;\n let attrName: string | null = null;\n if (!yfiles) {\n attrName = fromGraphml && origin.title !== null ? origin.title : name;\n if (role === \"label\" && domain !== \"graph\" && attrName !== LABEL_COLUMN) {\n attrName = labelSlot(column, domain, names, notes, note);\n } else if (role === null && domain !== \"graph\" && attrName === LABEL_COLUMN) {\n note(\n LOSS.ROLE_ASSUMED,\n `${domain} column \"${name}\" has no role but is titled \"${LABEL_COLUMN}\", which the importer reads back with the label role`,\n name,\n column.length - column.nullCount,\n );\n }\n }\n plans.push({\n column,\n domain,\n keyId: \"\",\n attrType: yfiles ? null : attrTypeFor(column),\n attrName,\n yfilesType: yfiles ? (origin?.type ?? DEFAULT_YFILES_TYPES[domain]) : null,\n yfiles,\n });\n }\n return plans;\n}\n\n/**\n * The title a label column not named `label` is written under: the label slot when the table has\n * no other column of that name (checkCapabilities() has noted the name change), else its own\n * name with the role lost (the name-change note is withdrawn and a role note recorded).\n * @param column - the label column\n * @param domain - its domain\n * @param names - the column names of the table\n * @param notes - the notes so far\n * @param note - the note recorder\n * @returns the attr.name\n */\nfunction labelSlot(\n column: Column,\n domain: Domain,\n names: ReadonlySet<string>,\n notes: LossNote[],\n note: NoteFn,\n): string {\n const { name } = column.meta;\n if (!names.has(LABEL_COLUMN)) {\n return LABEL_COLUMN;\n }\n withdrawNameChange(notes, name);\n note(\n LOSS.ROLE,\n `${domain} column \"${name}\" (label) is written as a plain attribute: the label slot (a key titled \"${LABEL_COLUMN}\") is taken by column \"${LABEL_COLUMN}\" and the role is lost`,\n name,\n column.length - column.nullCount,\n );\n return name;\n}\n\n/**\n * Withdraw the name-change note checkCapabilities() recorded for a role column that does not\n * take the slot after all.\n * @param notes - the notes so far\n * @param name - the column name\n */\nfunction withdrawNameChange(notes: LossNote[], name: string): void {\n const at = notes.findIndex((n) => n.code === LOSS.COLUMN_NAME_CHANGED && n.column === name);\n if (at >= 0) {\n notes.splice(at, 1);\n }\n}\n\n/**\n * The attr.type a column is declared with: the GraphML origin.type when it still describes the\n * column, else the type of the dtype (u32 / u8 as int or long, dict as string, list / json /\n * multi-component as string holding JSON text).\n * @param column - the column\n * @returns the attr.type text\n */\nfunction attrTypeFor(column: Column): string {\n const { meta } = column;\n const { origin } = meta;\n const declared = origin !== null && origin.format === FORMAT && origin.type !== null ? origin.type : null;\n if (meta.components > 1) {\n return \"string\";\n }\n switch (meta.dtype) {\n case \"bool\":\n return \"boolean\";\n case \"i32\":\n return \"int\";\n case \"f32\":\n return \"float\";\n case \"f64\": {\n if (declared !== null && declared.trim().toLowerCase() === \"long\" && columnIntegral(column)) {\n return \"long\";\n }\n return \"double\";\n }\n case \"u8\":\n return \"int\";\n case \"u32\":\n return columnMax(column) <= I32_MAX ? \"int\" : \"long\";\n case \"string\":\n if (declared !== null && TYPE_DTYPES[declared.trim().toLowerCase()] === undefined) {\n // an unknown declared type kept as text (W_UNKNOWN_ATTR_TYPE on import) is restored as declared\n return declared;\n }\n return \"string\";\n case \"dict\":\n case \"list\":\n case \"json\":\n return \"string\";\n default: {\n const { dtype } = meta;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dtype ${String(dtype)}`, { dtype });\n }\n }\n}\n\n/**\n * Whether every set value of a numeric column is an integer.\n * @param column - an f64 column\n * @returns true when all set values are integral\n */\nfunction columnIntegral(column: Column): boolean {\n if (column.dtype !== \"f64\") {\n return false;\n }\n const { data } = column;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && !Number.isInteger(data[r])) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * The largest set value of a u32 column.\n * @param column - a u32 column\n * @returns the maximum, 0 for an empty column\n */\nfunction columnMax(column: Column): number {\n if (column.dtype !== \"u32\") {\n return 0;\n }\n let max = 0;\n const { data } = column;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && data[r] > max) {\n max = data[r];\n }\n }\n return max;\n}\n\n/**\n * Whether every explicit weight is integral (so a declared int / long weight key survives).\n * @param snapshot - the snapshot\n * @param weights - the explicit weights\n * @returns true when all explicit weights are integers\n */\nfunction weightsIntegral(snapshot: GraphSnapshot, weights: ExplicitWeights): boolean {\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (weights.isExplicit(e) && !Number.isInteger(weights.value(e))) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * How many values of a yfiles column are not serialisable trees.\n * @param column - a json column\n * @returns the count\n */\nfunction countBadTrees(column: Column): number {\n if (column.dtype !== \"json\") {\n return 0;\n }\n let bad = 0;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && treeProblem(column.values[r]) !== null) {\n bad++;\n }\n }\n return bad;\n}\n\n/**\n * Node ids that read back as another type under the canonical rule: string ids that are\n * canonical integer text, and numbers that are not safe integers.\n * @param snapshot - the snapshot\n * @returns the count\n */\nfunction countIdTypeChanges(snapshot: GraphSnapshot): number {\n const { ids } = snapshot;\n if (ids.kind === \"identity\" || ids.kind === \"dense\") {\n return 0;\n }\n let count = 0;\n for (let i = 0; i < ids.size; i++) {\n const id = ids.idOf(i);\n if (typeof id === \"string\" ? isNmtoken(id) && isCanonicalIntegerText(id) : !Number.isSafeInteger(id)) {\n count++;\n }\n }\n return count;\n}\n\n/**\n * Node ids the nmtoken charset cannot hold.\n * @param snapshot - the snapshot\n * @returns the count\n */\nfunction countUnrepresentableNodeIds(snapshot: GraphSnapshot): number {\n const { ids } = snapshot;\n if (ids.kind === \"identity\" || ids.kind === \"dense\") {\n return 0;\n }\n let count = 0;\n for (let i = 0; i < ids.size; i++) {\n if (!isNmtoken(String(ids.idOf(i)))) {\n count++;\n }\n }\n return count;\n}\n\n/**\n * Edge ids that are not NMTOKENs.\n * @param column - the edge id column\n * @returns the count\n */\nfunction countBadEdgeIds(column: Column): number {\n let bad = 0;\n for (let e = 0; e < column.length; e++) {\n if (column.isSet(e) && !isNmtoken(edgeIdText(column, e))) {\n bad++;\n }\n }\n return bad;\n}\n\n/**\n * The text of an edge id cell.\n * @param column - the edge id column\n * @param e - the edge\n * @returns the id as text\n */\nfunction edgeIdText(column: Column, e: number): string {\n const value = column.value(e);\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\") {\n return Number.isInteger(value) ? formatInteger(value) : formatF64(value);\n }\n return String(value);\n}\n\n/**\n * Whether a logical edge is written as directed: never in an undirected snapshot; never for a\n * half of an expanded pair (an undirected or a mutual source edge, whose halves the resolver\n * flags directed); otherwise per the directed role column, with directed as the default.\n * @param folding - the pair folding\n * @param e - the edge\n * @returns false for a paired edge or an edge flagged undirected\n */\nfunction isDirectedEdge(folding: PairFolding, e: number): boolean {\n return folding.mateOf(e) === INVALID_INDEX && folding.sourceDirected(e);\n}\n\n/**\n * The containment order: the children CSR over the parent column (src/children.ts), roots in\n * index order, unreachable nodes (cycles) forced to the top level.\n * @param snapshot - the snapshot\n * @returns the hierarchy\n */\nfunction planHierarchy(snapshot: GraphSnapshot): Hierarchy {\n const parent = snapshot.nodes.byRole(\"parent\");\n const csr = childrenCsr(snapshot, { column: parent !== null && parent.dtype === \"u32\" ? parent : null });\n const walk = csr.depthFirst();\n // the top-level nodes in written order: the roots, then the cycle members forced out\n const roots = walk.order.filter((u) => walk.depth[u] === 0);\n return {\n parent: csr.column,\n roots,\n childStart: csr.rowPtr,\n childList: csr.children,\n reordered: walk.reordered,\n unreachable: csr.unreachable,\n };\n}\n\n// ============================================================ writing\n\n/**\n * The text of one set cell for a `<data>` element or a `<default>`.\n * @param column - the column\n * @param row - the row\n * @param attrType - the declared attr.type\n * @returns the text\n */\nfunction cellText(column: Column, row: number, attrType: string | null): string {\n if (column.meta.components > 1) {\n const value = column.value(row);\n return JSON.stringify(Array.from(value as ArrayLike<number>));\n }\n switch (column.dtype) {\n case \"bool\":\n return column.value(row) === true ? \"true\" : \"false\";\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return String(column.data[row]);\n case \"f32\":\n return formatF32(column.data[row]);\n case \"f64\": {\n const value = column.data[row];\n return (attrType === \"long\" || attrType === \"int\") && Number.isInteger(value)\n ? formatInteger(value)\n : formatF64(value);\n }\n case \"string\":\n return column.valueAt(row);\n case \"dict\":\n return column.dictionary[column.codes[row]];\n case \"list\":\n return JSON.stringify(Array.from(column.sliceOf(row)));\n case \"json\":\n return JSON.stringify(column.values[row]) ?? \"\";\n default: {\n const dtype: never = column;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dtype ${String(dtype)}`, {});\n }\n }\n}\n\n/**\n * The text of a declared default.\n * @param column - the column\n * @param attrType - the declared attr.type\n * @returns the text, or null when the column has no default\n */\nfunction defaultText(column: Column, attrType: string | null): string | null {\n const value = column.meta.default;\n if (value === undefined) {\n return null;\n }\n switch (typeof value) {\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"number\":\n if (column.dtype === \"f32\") {\n return formatF32(value);\n }\n return (attrType === \"long\" || attrType === \"int\") && Number.isInteger(value)\n ? formatInteger(value)\n : formatF64(value);\n case \"string\":\n return value;\n default:\n return JSON.stringify(value) ?? \"\";\n }\n}\n\n/**\n * Write one `<data>` element.\n * @param plan - the column plan\n * @param row - the row\n * @param indent - the indentation\n * @param out - receives the parts\n */\nfunction writeData(plan: ColumnPlan, row: number, indent: string, out: string[]): void {\n const { column } = plan;\n if (!column.isSet(row)) {\n return;\n }\n if (plan.yfiles && column.dtype === \"json\") {\n writeTreeData(plan.keyId, column.values[row], indent, out);\n return;\n }\n out.push(`\\n${indent}<data key=\"${plan.keyId}\">${escapeXmlText(cellText(column, row, plan.attrType))}</data>`);\n}\n\n/**\n * Write a `<data>` holding a yfiles tree.\n * @param keyId - the key id\n * @param value - the tree\n * @param indent - the indentation\n * @param out - receives the parts\n */\nfunction writeTreeData(keyId: string, value: unknown, indent: string, out: string[]): void {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n const parts: string[] = [];\n writeXmlTree(value, indent, parts);\n out.push(`\\n${indent}<data key=\"${keyId}\">${parts.join(\"\")}</data>`);\n return;\n }\n out.push(`\\n${indent}<data key=\"${keyId}\">`);\n writeXmlTree(value, `${indent} `, out);\n out.push(`\\n${indent}</data>`);\n}\n\n/**\n * The `<key>` element of a plan.\n * @param key - the key plan\n * @param indent - the indentation\n * @returns the element text\n */\nfunction keyElement(key: KeyPlan, indent: string): string {\n const domain = key.domains.length === 3 ? \"all\" : key.domains[0];\n let text = `${indent}<key id=\"${escapeXmlAttribute(key.id)}\" for=\"${domain}\"`;\n if (key.attrName !== null) {\n text += ` attr.name=\"${escapeXmlAttribute(key.attrName)}\"`;\n }\n if (key.attrType !== null) {\n text += ` attr.type=\"${escapeXmlAttribute(key.attrType)}\"`;\n }\n if (key.yfilesType !== null) {\n text += ` yfiles.type=\"${escapeXmlAttribute(key.yfilesType)}\"`;\n }\n const { column } = key;\n const desc = column?.meta.extra.desc;\n const hasDefault = column !== null && column.meta.default !== undefined;\n if (column === null || (typeof desc !== \"string\" && !hasDefault)) {\n return `${text}/>\\n`;\n }\n const parts: string[] = [`${text}>`];\n const inner = `${indent} `;\n if (typeof desc === \"string\") {\n parts.push(`\\n${inner}<desc>${escapeXmlText(desc)}</desc>`);\n }\n if (hasDefault) {\n if (key.yfilesType !== null) {\n const value = column.meta.default;\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n parts.push(`\\n${inner}<default>`);\n writeXmlTree(value, `${inner} `, parts);\n parts.push(`\\n${inner}</default>`);\n } else {\n const tree: string[] = [];\n writeXmlTree(value, inner, tree);\n parts.push(`\\n${inner}<default>${tree.join(\"\")}</default>`);\n }\n } else {\n parts.push(`\\n${inner}<default>${escapeXmlText(defaultText(column, key.attrType) ?? \"\")}</default>`);\n }\n }\n parts.push(`\\n${indent}</key>\\n`);\n return parts.join(\"\");\n}\n\n/**\n * Sanitised edge ids: NMTOKENs as they are; the rest refused or mangled per sanitizeIds.\n * @param column - the edge id column, or null\n * @param mode - the resolved sanitizeIds option\n * @param edgeCount - the edge count\n * @returns the id text per edge (null for edges without one)\n */\nfunction sanitizeEdgeIds(column: Column | null, mode: \"error\" | \"mangle\", edgeCount: number): (string | null)[] {\n const out: (string | null)[] = new Array<string | null>(edgeCount).fill(null);\n if (column === null) {\n return out;\n }\n const used = new Set<string>();\n const bad: number[] = [];\n for (let e = 0; e < edgeCount; e++) {\n if (!column.isSet(e)) {\n continue;\n }\n const text = edgeIdText(column, e);\n if (isNmtoken(text)) {\n out[e] = text;\n used.add(text);\n } else {\n bad.push(e);\n }\n }\n if (bad.length > 0 && mode === \"error\") {\n throw new GraphFormatError(\n \"E_INVALID_ID\",\n `${bad.length} edge id(s) cannot be written as nmtoken (first: ${JSON.stringify(edgeIdText(column, bad[0]))} at edge ${bad[0]}); pass sanitizeIds: \"mangle\" to rewrite them`,\n { reason: \"charset\", charset: \"nmtoken\", count: bad.length, edge: bad[0] },\n );\n }\n for (const e of bad) {\n const base = mangleNmtoken(edgeIdText(column, e));\n let candidate = base;\n for (let k = 2; used.has(candidate); k++) {\n candidate = `${base}_${k}`;\n }\n used.add(candidate);\n out[e] = candidate;\n }\n return out;\n}\n\n/**\n * The document as text parts.\n * @param snapshot - the snapshot\n * @param plan - the plan\n * @yields one element (or a group of small ones) at a time\n * @returns nothing\n */\nfunction* writeGraphml(snapshot: GraphSnapshot, plan: Plan): Generator<string, void, undefined> {\n const ids: SanitizedIds = sanitizeIds(snapshot, \"nmtoken\", plan.options.sanitizeIds);\n const edgeIds = sanitizeEdgeIds(plan.edgeIdColumn, plan.options.sanitizeIds, snapshot.edgeCount);\n const i1 = plan.pretty ? \" \" : \"\";\n const i2 = plan.pretty ? \" \" : \"\";\n const i3 = plan.pretty ? \" \" : \"\";\n const step = plan.pretty ? \" \" : \"\";\n\n yield '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n let root = `<graphml xmlns=\"${GRAPHML_NAMESPACE}\"`;\n const namespaces: Record<string, string> = { ...(plan.meta?.namespaces ?? {}) };\n if (\n (plan.nodeColumns.some((c) => c.yfiles) ||\n plan.edgeColumns.some((c) => c.yfiles) ||\n plan.graphColumns.some((c) => c.yfiles)) &&\n !Object.values(namespaces).includes(YFILES_NAMESPACE)\n ) {\n namespaces.y = YFILES_NAMESPACE;\n }\n if (!Object.values(namespaces).includes(XSI_NAMESPACE)) {\n namespaces.xsi = XSI_NAMESPACE;\n }\n for (const [prefix, uri] of Object.entries(namespaces)) {\n root += ` xmlns:${prefix}=\"${escapeXmlAttribute(uri)}\"`;\n }\n const xsiPrefix = Object.entries(namespaces).find(([, uri]) => uri === XSI_NAMESPACE)?.[0] ?? \"xsi\";\n root += ` ${xsiPrefix}:schemaLocation=\"${SCHEMA_LOCATION}\">\\n`;\n yield root;\n\n for (const key of plan.keys) {\n yield keyElement(key, i1);\n }\n if (plan.originalIdKey !== null) {\n yield `${i1}<key id=\"${plan.originalIdKey}\" for=\"node\" attr.name=\"${ORIGINAL_ID_ATTRIBUTE}\" attr.type=\"string\"/>\\n`;\n }\n\n const graphId = plan.meta?.graphId ?? \"G\";\n yield `${i1}<graph id=\"${escapeXmlAttribute(graphId)}\" edgedefault=\"${plan.edgedefault}\">`;\n const { description } = snapshot.meta;\n if (description !== null) {\n yield `\\n${i2}<desc>${escapeXmlText(description)}</desc>`;\n }\n const graphParts: string[] = [];\n for (const column of plan.graphColumns) {\n writeData(column, 0, i2, graphParts);\n }\n if (graphParts.length > 0) {\n yield graphParts.join(\"\");\n }\n\n // nodes in containment order, children nested under their parent\n const { hierarchy } = plan;\n const nested = hierarchy.childList.length > 0;\n const stackNode: number[] = [];\n const stackCursor: number[] = [];\n const written = nested ? new Uint8Array(snapshot.nodeCount) : null;\n for (const rootNode of hierarchy.roots) {\n yield* writeNodeSubtree(rootNode, plan, ids, i2, step, stackNode, stackCursor, written);\n }\n\n // edges: primaries only, in index order\n const list = snapshot.edgeList();\n const { folding } = plan;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n const parts: string[] = [`\\n${i2}<edge`];\n const id = edgeIds[e];\n if (id !== null) {\n parts.push(` id=\"${escapeXmlAttribute(id)}\"`);\n }\n parts.push(\n ` source=\"${escapeXmlAttribute(String(ids.idAt(list.src[e])))}\" target=\"${escapeXmlAttribute(String(ids.idAt(list.dst[e])))}\"`,\n );\n const directed = snapshot.directed && isDirectedEdge(folding, e);\n if (directed !== (plan.edgedefault === \"directed\")) {\n parts.push(` directed=\"${directed ? \"true\" : \"false\"}\"`);\n }\n const sourcePort = portText(plan.sourcePortColumn, e);\n if (sourcePort !== null) {\n parts.push(` sourceport=\"${escapeXmlAttribute(sourcePort)}\"`);\n }\n const targetPort = portText(plan.targetPortColumn, e);\n if (targetPort !== null) {\n parts.push(` targetport=\"${escapeXmlAttribute(targetPort)}\"`);\n }\n const open = parts.length;\n if (plan.weight !== null) {\n const { keyId, attrType } = plan.weight;\n const weight = plan.weight.weights.text(e, attrType === \"int\" || attrType === \"long\");\n if (weight !== null) {\n parts.push(`\\n${i3}<data key=\"${keyId}\">${escapeXmlText(weight)}</data>`);\n }\n }\n for (const column of plan.edgeColumns) {\n writeData(column, e, i3, parts);\n }\n if (parts.length === open) {\n parts.push(\"/>\");\n } else {\n parts.splice(open, 0, \">\");\n parts.push(`\\n${i2}</edge>`);\n }\n yield parts.join(\"\");\n }\n\n yield `\\n${i1}</graph>\\n</graphml>\\n`;\n}\n\n/**\n * The text of a port reference cell.\n * @param column - the sourcePort / targetPort column, or null\n * @param e - the edge\n * @returns the port name, or null when unset\n */\nfunction portText(column: Column | null, e: number): string | null {\n if (column === null || !column.isSet(e)) {\n return null;\n }\n const value = column.value(e);\n return typeof value === \"string\" ? value : String(value);\n}\n\n/**\n * Write a top-level node and, nested, every node contained in it (iteratively, so a deep chain\n * cannot overflow the call stack).\n * @param root - the top-level node\n * @param plan - the plan\n * @param ids - the sanitised ids\n * @param indent - the indentation of top-level nodes\n * @param step - one indentation step\n * @param stackNode - a reusable stack of open nodes\n * @param stackCursor - a reusable stack of child cursors\n * @param written - nodes already written (null when nothing is nested)\n * @yields the node elements\n * @returns nothing\n */\nfunction* writeNodeSubtree(\n root: number,\n plan: Plan,\n ids: SanitizedIds,\n indent: string,\n step: string,\n stackNode: number[],\n stackCursor: number[],\n written: Uint8Array | null,\n): Generator<string, void, undefined> {\n const { hierarchy } = plan;\n const hasChildren = (u: number): boolean => hierarchy.childStart[u + 1] > hierarchy.childStart[u];\n const openNode = (u: number, depth: number): string => {\n const pad = indent + step.repeat(depth * 2);\n const parts: string[] = [`\\n${pad}<node id=\"${escapeXmlAttribute(String(ids.idAt(u)))}\"`];\n const open = parts.length;\n if (plan.originalIdKey !== null && ids.isChanged(u)) {\n parts.push(\n `\\n${pad}${step}<data key=\"${plan.originalIdKey}\">${escapeXmlText(String(ids.originalAt(u)))}</data>`,\n );\n }\n for (const column of plan.nodeColumns) {\n writeData(column, u, pad + step, parts);\n }\n if (hasChildren(u)) {\n parts.splice(open, 0, \">\");\n parts.push(\n `\\n${pad}${step}<graph id=\"${escapeXmlAttribute(`${String(ids.idAt(u))}:`)}\" edgedefault=\"${plan.edgedefault}\">`,\n );\n return parts.join(\"\");\n }\n if (parts.length === open) {\n parts.push(\"/>\");\n } else {\n parts.splice(open, 0, \">\");\n parts.push(`\\n${pad}</node>`);\n }\n return parts.join(\"\");\n };\n const closeNode = (depth: number): string => {\n const pad = indent + step.repeat(depth * 2);\n return `\\n${pad}${step}</graph>\\n${pad}</node>`;\n };\n if (written !== null) {\n written[root] = 1;\n }\n yield openNode(root, 0);\n if (!hasChildren(root)) {\n return;\n }\n stackNode.push(root);\n stackCursor.push(hierarchy.childStart[root]);\n while (stackNode.length > 0) {\n const top = stackNode.length - 1;\n const u = stackNode[top];\n const cursor = stackCursor[top];\n if (cursor >= hierarchy.childStart[u + 1]) {\n stackNode.pop();\n stackCursor.pop();\n yield closeNode(top);\n continue;\n }\n stackCursor[top] = cursor + 1;\n const v = hierarchy.childList[cursor];\n if (written !== null && written[v] === 1) {\n continue;\n }\n if (written !== null) {\n written[v] = 1;\n }\n yield openNode(v, top + 1);\n if (hasChildren(v)) {\n stackNode.push(v);\n stackCursor.push(hierarchy.childStart[v]);\n }\n }\n}\n\n/**\n * The GraphML exporter (design section 8.5).\n */\nexport const graphmlExporter: GraphExporter<GraphmlExportOptions> = Object.freeze({\n format: FORMAT,\n capabilities: CAPABILITIES,\n /**\n * Pre-flight: every loss the export would incur.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the notes\n */\n check(snapshot: GraphSnapshot, options?: GraphmlExportOptions & CommonExportOptions): readonly LossNote[] {\n const plan = planExport(snapshot, resolveExportOptions(options), resolveFormatOptions(options));\n return Object.freeze(plan.notes);\n },\n /**\n * Write the document as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: GraphmlExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n const plan = planExport(snapshot, resolveExportOptions(options), resolveFormatOptions(options));\n return encodeChunks(writeGraphml(snapshot, plan));\n },\n /**\n * Write the document as one string.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: GraphmlExportOptions & CommonExportOptions): Promise<string> {\n const plan = planExport(snapshot, resolveExportOptions(options), resolveFormatOptions(options));\n return joinText(writeGraphml(snapshot, plan));\n },\n});\n","/**\n * The GraphML importer (design sections 8.4 and 5.1; research note 07 section 2.3): a single-pass\n * SAX-style reader over the streaming XML tokenizer that pushes scalars into the sink as elements\n * close. `<key>` declarations become typed columns up front (boolean / int / long / float / double\n * / string, with `<default>`, for the node, edge and graph domains; `for=\"all\"` declares in all\n * three with the same origin.id); `edgedefault` and per-edge `directed` go through the common\n * DirectionResolver; a nested `<graph>` inside a node becomes the `parent` column (containment,\n * never topology); `<port>` declarations and `<locator>` elements are reported and dropped while\n * `sourceport` / `targetport` edge attributes are kept as role columns; hyperedges follow the\n * `hyperedges` option (refuse, skip with a report entry, star, clique); yFiles `yfiles.type` keys\n * become `json` columns holding the nested XML as a tree (origin.namespace \"yfiles\"), reported as\n * a loss note because the structure, not the bytes, is preserved; a `y:ShapeNode` or\n * `y:PolyLineEdge` in such a tree is also read into typed `yfiles.*` columns (yfiles.ts).\n *\n * Ids are coerced with the common rule (`ids: \"canonical\"` by default, design section 4.1); the\n * edge attribute whose `attr.name` is `weightFrom` (\"weight\" by default) is THE weight and is\n * passed to `addEdge` rather than stored as a column, with its declaration kept in\n * `meta.weightOrigin`; a node key named `graphty:originalId` restores ids the exporter mangled.\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n GraphFormatError,\n type GraphSink,\n INVALID_INDEX,\n MAX_COUNT,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport {\n declareAttribute,\n type DeclaredAttribute,\n declareResolved,\n losesPrecision,\n parseDeclaredValue,\n PRECISION_CODE,\n takenIn,\n uniqueColumnName,\n} from \"../../common/attributes.js\";\nimport { type DeclaredTypeSpec } from \"../../common/declared-types.js\";\nimport { DirectionResolver, type EdgeKind } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { textChunks, throwIfAborted } from \"../../common/input.js\";\nimport { type ListSyntax } from \"../../common/lists.js\";\nimport {\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { isWeightField, parseWeightText } from \"../../common/weights.js\";\nimport {\n isWhitespace,\n localName,\n tokenizeXml,\n xmlDeclaredEncoding,\n type XmlHandler,\n XmlSyntaxError,\n} from \"../../common/xml.js\";\nimport { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from \"../../types.js\";\nimport {\n EDGE_ID_COLUMN,\n EXTENSIONS,\n FORMAT,\n GRAPHML_ISSUE,\n GRAPHML_LOSS,\n GRAPHML_NAMESPACE,\n type GraphmlMeta,\n HYPEREDGE_HUB_COLUMN,\n LABEL_COLUMN,\n META_KEY,\n MIME_TYPES,\n ORIGINAL_ID_ATTRIBUTE,\n ORIGINAL_ID_COLUMN,\n PARENT_COLUMN,\n RESERVED_EDGE_NAMES,\n RESERVED_NODE_NAMES,\n SOURCE_PORT_COLUMN,\n TARGET_PORT_COLUMN,\n XSI_NAMESPACE,\n} from \"./constants.js\";\nimport { XmlTreeBuilder } from \"./tree.js\";\nimport { graphicsDecl, graphicsValues } from \"./yfiles.js\";\n\n/** The XML attributes the importer reads on `<graph>`, `<node>` and `<edge>`; any other is reported. */\nconst GRAPH_ATTRIBUTES: ReadonlySet<string> = new Set([\"id\", \"edgedefault\", \"parse.nodes\", \"parse.edges\"]);\nconst NODE_ATTRIBUTES: ReadonlySet<string> = new Set([\"id\"]);\nconst EDGE_ATTRIBUTES: ReadonlySet<string> = new Set([\n \"id\",\n \"source\",\n \"target\",\n \"directed\",\n \"sourceport\",\n \"targetport\",\n]);\n\n/** The format-specific options of the GraphML importer. */\nexport interface GraphmlImportOptions {\n /**\n * How keys with a `yfiles.type` (yEd / yFiles graphics) are read: \"json\" (default) keeps the\n * nested XML of each `<data>` as a json column with origin.namespace \"yfiles\"; \"skip\" reports\n * them once and declares nothing.\n */\n yfiles?: \"json\" | \"skip\" | undefined;\n}\n\n/** The per-format defaults of design section 8.4: text-cell ids, undirected when edgedefault is missing, weight key. */\nconst FORMAT_DEFAULTS: ImportFormatDefaults = { ids: \"canonical\", defaultDirected: false, weightFrom: \"weight\" };\n\n/** Bytes inspected by sniff(). */\nconst SNIFF_BYTES = 4096;\n\nconst YFILES_MODES: ReadonlySet<string> = new Set([\"json\", \"skip\"]);\n\n/** Elements between two checks of the cancellation signal. */\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The common options the GraphML importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"long\",\n \"restoreMangledIds\",\n \"hyperedges\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** Where the reader is, by the innermost open element. */\nconst enum Ctx {\n Graphml,\n Desc,\n Key,\n Default,\n Graph,\n Node,\n Edge,\n Hyperedge,\n Data,\n Capture,\n Skip,\n}\n\n/** The element domains a key can be declared for. */\ntype Domain = \"graph\" | \"node\" | \"edge\";\n\n/** A declared column of one domain. */\ninterface ColumnTarget {\n /** The column name in its table. */\n readonly name: string;\n /** The handle (node / edge domains); INVALID_INDEX for the graph domain. */\n readonly handle: ColumnHandle;\n /** The declaration (graph domain, re-sent with every setGraphValue). */\n readonly decl: ColumnDecl;\n /** How text values are parsed; null for a json (yfiles) column. */\n readonly spec: DeclaredTypeSpec | null;\n /** The list syntax (unused by GraphML, which has no list type). */\n readonly listSyntax: ListSyntax;\n}\n\n/** One `<key>` after `</key>`. */\ninterface KeyEntry {\n readonly id: string;\n readonly name: string;\n readonly node: ColumnTarget | null;\n readonly edge: ColumnTarget | null;\n readonly graph: ColumnTarget | null;\n /** The edge domain of this key is THE weight. */\n readonly weight: boolean;\n /** The node domain of this key restores mangled ids. */\n readonly originalId: boolean;\n /** Whether the key holds yFiles nested XML. */\n readonly yfiles: boolean;\n /** Whether data of this key is silently ignored (yfiles: \"skip\"; already reported). */\n readonly skipped: boolean;\n /** The domains the key was declared for, for the mismatch warning. */\n readonly domains: readonly Domain[];\n}\n\n/** A `<key>` while its `<default>` and `<desc>` are being read. */\ninterface PendingKey {\n readonly id: string | null;\n readonly attrName: string | null;\n readonly attrType: string | null;\n readonly yfilesType: string | null;\n readonly domains: readonly Domain[];\n readonly line: number;\n desc: string;\n defaultText: string | null;\n defaultTree: unknown;\n}\n\n/** A `<node>` while open (nodes nest through nested graphs, so these stack). */\ninterface NodeState {\n /** The coerced id, or null when the element is unusable. */\n id: NodeId | null;\n /** The id attribute as written, for the mangled -> original map. */\n idText: string | null;\n /** The node index once added; INVALID_INDEX before. */\n index: number;\n /** The index of the containing node, or INVALID_INDEX at the top level. */\n readonly parent: number;\n /** Data values waiting for the node to be added: handle, value, handle, value... */\n readonly pending: unknown[];\n /** A `graphty:originalId` value, restored as the id. */\n restoredId: string | null;\n failed: boolean;\n readonly line: number;\n}\n\n/** The `<edge>` being read. */\ninterface EdgeState {\n source: NodeId | null;\n target: NodeId | null;\n id: string | null;\n kind: EdgeKind;\n sourcePort: string | null;\n targetPort: string | null;\n weight: number | undefined;\n readonly pending: unknown[];\n failed: boolean;\n line: number;\n}\n\n/** One `<endpoint>` of a hyperedge. */\ninterface Endpoint {\n readonly node: NodeId;\n readonly type: \"in\" | \"out\" | \"undir\";\n}\n\n/** The `<hyperedge>` being read. */\ninterface HyperedgeState {\n id: string | null;\n readonly endpoints: Endpoint[];\n failed: boolean;\n line: number;\n}\n\n/** The `<data>` or `<default>` being read. */\ninterface ContentState {\n key: KeyEntry | null;\n pendingKey: PendingKey | null;\n domain: Domain;\n text: string;\n tree: XmlTreeBuilder | null;\n line: number;\n}\n\n/** Where an issue was found. */\ninterface Where {\n /** The line. */\n readonly line: number;\n /** The element, or null. */\n readonly element: string | null;\n}\n\n/** One open `<graph>`. */\ninterface GraphState {\n readonly directed: boolean;\n readonly parent: number;\n}\n\n/**\n * A growable bit set over node indices, marking the indices declared by a `<node>` element so a\n * second declaration is reported and a node created by an edge reference is not.\n */\nclass IndexFlags {\n private words = new Uint32Array(64);\n\n /**\n * Whether an index is marked.\n * @param index - the node index\n * @returns true when set\n */\n has(index: number): boolean {\n const w = index >>> 5;\n return w < this.words.length && ((this.words[w] >>> (index & 31)) & 1) === 1;\n }\n\n /**\n * Mark an index.\n * @param index - the node index\n */\n add(index: number): void {\n const w = index >>> 5;\n if (w >= this.words.length) {\n let size = this.words.length * 2;\n while (size <= w) {\n size *= 2;\n }\n const grown = new Uint32Array(size);\n grown.set(this.words);\n this.words = grown;\n }\n this.words[w] |= 1 << (index & 31);\n }\n}\n\n/**\n * The event handler that turns the tokenizer's events into sink calls.\n */\nclass GraphmlReader implements XmlHandler {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly yfilesMode: \"json\" | \"skip\";\n\n private readonly coercer: IdCoercer;\n\n private readonly direction: DirectionResolver;\n\n private readonly ctx: Ctx[] = [];\n\n /** Keys by id; one id may be declared once per domain (igraph writes `name` for graph and node). */\n private readonly keys = new Map<string, KeyEntry[]>();\n\n private readonly graphs: GraphState[] = [];\n\n private readonly nodes: NodeState[] = [];\n\n private readonly declared = new IndexFlags();\n\n private readonly edgeIds = new Set<string>();\n\n private elementsSinceCheck = 0;\n\n /** Mangled id text -> the original id restored from `graphty:originalId`, for edge endpoints. */\n private readonly restored = new Map<string, NodeId>();\n\n private readonly graphColumnNames = new Set<string>();\n\n private pendingKey: PendingKey | null = null;\n\n private edge: EdgeState | null = null;\n\n private hyperedge: HyperedgeState | null = null;\n\n private readonly content: ContentState = {\n key: null,\n pendingKey: null,\n domain: \"node\",\n text: \"\",\n tree: null,\n line: 0,\n };\n\n private descTarget: \"graph\" | \"key\" | null = null;\n\n private descText = \"\";\n\n private description: string | null = null;\n\n private graphSeen = false;\n\n private graphId: string | null = null;\n\n private edgedefault: \"directed\" | \"undirected\" | null = null;\n\n private namespaces: Record<string, string> = {};\n\n private weightOrigin: { id: string; title: string | null; type: string | null } | null = null;\n\n private yfilesLossNoted = false;\n\n /** The mapped yFiles graphics columns declared so far, by domain and field. */\n private readonly graphicsColumns = new Map<string, ColumnHandle>();\n\n private hyperedgeCount = 0;\n\n private edgeIdHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private sourcePortHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private targetPortHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private parentHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private hubHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n /**\n * Create a reader for one import call.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param yfilesMode - the resolved yfiles option\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n yfilesMode: \"json\" | \"skip\",\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.yfilesMode = yfilesMode;\n this.coercer = new IdCoercer(options.ids);\n this.direction = new DirectionResolver(sink, report, options.onMixedDirection);\n }\n\n // ------------------------------------------------------------------ tokenizer events\n\n /**\n * An element starts.\n * @param name - the element name\n * @param attrs - its attributes\n * @param line - the line\n */\n start(name: string, attrs: ReadonlyMap<string, string>, line: number): void {\n const parent = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];\n switch (parent) {\n case Ctx.Capture:\n this.captureStart(name, attrs);\n return;\n case Ctx.Skip:\n case Ctx.Desc:\n this.ctx.push(Ctx.Skip);\n return;\n case Ctx.Data:\n case Ctx.Default:\n this.captureStart(name, attrs);\n return;\n default:\n break;\n }\n const local = localName(name);\n switch (parent) {\n case null:\n if (local !== \"graphml\") {\n this.report.fail(GRAPHML_ISSUE.NOT_GRAPHML, `the root element is <${name}>, not <graphml>`, {\n line,\n });\n }\n this.readRoot(attrs);\n this.ctx.push(Ctx.Graphml);\n return;\n case Ctx.Graphml:\n this.startInGraphml(name, local, attrs, line);\n return;\n case Ctx.Key:\n this.startInKey(name, local, line);\n return;\n case Ctx.Graph:\n this.startInGraph(name, local, attrs, line);\n return;\n case Ctx.Node:\n this.startInNode(name, local, attrs, line);\n return;\n case Ctx.Edge:\n this.startInEdge(name, local, attrs, line);\n return;\n case Ctx.Hyperedge:\n this.startInHyperedge(name, local, attrs, line);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * An element ends.\n * @param name - the element name\n * @param _line - the line (unused: issues of an element cite its start line)\n */\n end(name: string, _line: number): void {\n const ctx = this.ctx.pop();\n switch (ctx) {\n case Ctx.Capture:\n this.captureEnd();\n return;\n case Ctx.Skip:\n case Ctx.Graphml:\n case undefined:\n return;\n case Ctx.Desc:\n this.finishDesc();\n return;\n case Ctx.Key:\n this.finishKey();\n return;\n case Ctx.Default:\n this.finishDefault();\n return;\n case Ctx.Data:\n this.finishData();\n return;\n case Ctx.Node:\n this.finishNode();\n return;\n case Ctx.Edge:\n this.finishEdge();\n return;\n case Ctx.Hyperedge:\n this.finishHyperedge();\n return;\n case Ctx.Graph:\n this.graphs.pop();\n return;\n default: {\n const value: never = ctx;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown reader state ${String(value)}`, { name });\n }\n }\n }\n\n /**\n * Character data.\n * @param text - the text\n * @param line - the line\n */\n text(text: string, line: number): void {\n const ctx = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];\n switch (ctx) {\n case Ctx.Capture:\n this.content.tree?.text(text);\n return;\n case Ctx.Data:\n case Ctx.Default:\n if (this.content.tree === null) {\n this.content.text += text;\n } else {\n this.content.tree.text(text);\n }\n return;\n case Ctx.Desc:\n this.descText += text;\n return;\n case Ctx.Skip:\n return;\n default:\n if (!isWhitespace(text)) {\n this.report.warnOnce(\n \"validation-error\",\n GRAPHML_ISSUE.STRAY_TEXT,\n \"text where GraphML allows only elements was ignored\",\n { line },\n );\n }\n }\n }\n\n /**\n * After the last event: the document must have held a graph; the metadata is written.\n */\n finish(): void {\n if (!this.graphSeen) {\n this.report.fail(GRAPHML_ISSUE.NO_GRAPH, \"the document has no <graph> element\");\n }\n const meta: GraphmlMeta = { graphId: this.graphId, edgedefault: this.edgedefault, namespaces: this.namespaces };\n this.sink.setMeta({\n sourceFormat: FORMAT,\n description: this.description ?? undefined,\n weightOrigin:\n this.weightOrigin === null\n ? undefined\n : {\n format: FORMAT,\n id: this.weightOrigin.id,\n title: this.weightOrigin.title,\n type: this.weightOrigin.type,\n namespace: null,\n },\n extra: { [META_KEY]: meta },\n });\n }\n\n // ------------------------------------------------------------------ structure\n\n /**\n * Record the root element's namespace declarations.\n * @param attrs - the root attributes\n */\n private readRoot(attrs: ReadonlyMap<string, string>): void {\n for (const [key, value] of attrs) {\n if (key.startsWith(\"xmlns:\") && value !== GRAPHML_NAMESPACE && value !== XSI_NAMESPACE) {\n this.namespaces[key.slice(6)] = value;\n }\n }\n }\n\n /**\n * A child of `<graphml>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGraphml(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"desc\":\n this.beginDesc(\"graph\");\n return;\n case \"key\":\n this.beginKey(attrs, line);\n return;\n case \"graph\":\n this.beginGraph(attrs, line, INVALID_INDEX);\n return;\n case \"data\":\n this.beginData(attrs, line, \"graph\");\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<key>`.\n * @param name - the element name\n * @param local - its local name\n * @param line - the line\n */\n private startInKey(name: string, local: string, line: number): void {\n switch (local) {\n case \"desc\":\n this.beginDesc(\"key\");\n return;\n case \"default\":\n this.content.key = null;\n this.content.pendingKey = this.pendingKey;\n this.content.text = \"\";\n this.content.tree = null;\n this.content.line = line;\n this.ctx.push(Ctx.Default);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<graph>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGraph(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"desc\":\n if (this.graphs.length === 1) {\n this.beginDesc(\"graph\");\n } else {\n this.ctx.push(Ctx.Skip);\n }\n return;\n case \"data\":\n if (this.graphs.length === 1) {\n this.beginData(attrs, line, \"graph\");\n } else {\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.NESTED_GRAPH_DATA,\n \"data of a nested <graph> cannot be kept; only the top-level graph has attributes\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n }\n return;\n case \"node\":\n this.beginNode(attrs, line);\n return;\n case \"edge\":\n this.beginEdge(attrs, line);\n return;\n case \"hyperedge\":\n this.beginHyperedge(attrs, line);\n return;\n case \"locator\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.LOCATOR_DROPPED,\n \"<locator> references are not followed\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<node>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInNode(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"desc\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.DESC_DROPPED,\n \"node and edge <desc> texts are not kept\",\n {\n line,\n },\n );\n this.ctx.push(Ctx.Skip);\n return;\n case \"data\":\n this.beginData(attrs, line, \"node\");\n return;\n case \"port\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.PORT_DECLARATION,\n \"<port> declarations are not kept; sourceport / targetport edge attributes are\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n return;\n case \"graph\": {\n const node = this.nodes[this.nodes.length - 1];\n this.materializeNode(node);\n this.beginGraph(attrs, line, node.index);\n return;\n }\n case \"locator\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.LOCATOR_DROPPED,\n \"<locator> references are not followed\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<edge>`.\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInEdge(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"desc\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.DESC_DROPPED,\n \"node and edge <desc> texts are not kept\",\n {\n line,\n },\n );\n this.ctx.push(Ctx.Skip);\n return;\n case \"data\":\n this.beginData(attrs, line, \"edge\");\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * A child of `<hyperedge>` (under the star / clique policies).\n * @param name - the element name\n * @param local - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInHyperedge(name: string, local: string, attrs: ReadonlyMap<string, string>, line: number): void {\n switch (local) {\n case \"endpoint\":\n this.readEndpoint(attrs, line);\n this.ctx.push(Ctx.Skip);\n return;\n case \"data\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.HYPEREDGE_DATA_DROPPED,\n \"hyperedge data are not kept by the star / clique expansions\",\n { line },\n );\n this.ctx.push(Ctx.Skip);\n return;\n case \"desc\":\n this.ctx.push(Ctx.Skip);\n return;\n default:\n this.unknownElement(name, line);\n }\n }\n\n /**\n * Report an element the schema does not define at this place and skip its subtree.\n * @param name - the element name\n * @param line - the line\n */\n private unknownElement(name: string, line: number): void {\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.UNKNOWN_ELEMENT,\n `element <${name}> is not GraphML and was skipped`,\n {\n line,\n element: name,\n },\n );\n this.ctx.push(Ctx.Skip);\n }\n\n /**\n * Open a `<desc>`.\n * @param target - what the text describes\n */\n private beginDesc(target: \"graph\" | \"key\"): void {\n this.descTarget = target;\n this.descText = \"\";\n this.ctx.push(Ctx.Desc);\n }\n\n /** Close a `<desc>`. */\n private finishDesc(): void {\n const text = this.descText.trim();\n if (this.descTarget === \"key\" && this.pendingKey !== null) {\n this.pendingKey.desc = text;\n } else if (this.descTarget === \"graph\" && text.length > 0) {\n this.description = text;\n }\n this.descTarget = null;\n this.descText = \"\";\n }\n\n // ------------------------------------------------------------------ graphs\n\n /**\n * Report, once per element kind and attribute name, an XML attribute the importer does not read:\n * a GraphML `parse.*` hint as ignored, anything else as unknown. Namespace declarations and\n * `xml:` / `xsi:` attributes are not data and pass silently.\n * @param kind - the element name\n * @param attrs - the element's attributes\n * @param known - the attributes the importer reads on that element\n * @param line - the line\n */\n private reportUnreadAttributes(\n kind: string,\n attrs: ReadonlyMap<string, string>,\n known: ReadonlySet<string>,\n line: number,\n ): void {\n for (const name of attrs.keys()) {\n if (known.has(name) || name === \"xmlns\" || /^(xmlns|xml|xsi):/.test(name)) {\n continue;\n }\n const hint = name.startsWith(\"parse.\");\n const code = hint ? GRAPHML_ISSUE.PARSE_HINT_IGNORED : GRAPHML_ISSUE.UNKNOWN_XML_ATTRIBUTE;\n this.report.warnOnce(\n \"unsupported\",\n code,\n hint\n ? `the <${kind}> parse hint ${name} is ignored`\n : `the <${kind}> attribute ${name} is not a GraphML attribute; it is not kept`,\n { line, element: name },\n `${code}:${kind}:${name}`,\n );\n }\n }\n\n /**\n * Open a `<graph>`: the top-level one sets the sink's direction (rule 1 of design section\n * 8.4); a nested one records its container as the parent of its nodes.\n * @param attrs - the graph attributes\n * @param line - the line\n * @param parent - the containing node's index, or INVALID_INDEX\n */\n private beginGraph(attrs: ReadonlyMap<string, string>, line: number, parent: number): void {\n this.reportUnreadAttributes(\"graph\", attrs, GRAPH_ATTRIBUTES, line);\n const top = this.graphs.length === 0;\n const edgedefault = attrs.get(\"edgedefault\");\n let directed: boolean;\n if (edgedefault === \"directed\" || edgedefault === \"undirected\") {\n directed = edgedefault === \"directed\";\n } else if (edgedefault === undefined) {\n directed = top ? this.options.defaultDirected : this.graphs[this.graphs.length - 1].directed;\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.EDGEDEFAULT_MISSING,\n `<graph> has no edgedefault; read as ${directed ? \"directed\" : \"undirected\"}`,\n { line },\n );\n } else {\n directed = top ? this.options.defaultDirected : this.graphs[this.graphs.length - 1].directed;\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.INVALID_EDGEDEFAULT,\n `edgedefault \"${edgedefault}\" is neither directed nor undirected; read as ${directed ? \"directed\" : \"undirected\"}`,\n { line },\n );\n }\n if (top && this.graphSeen) {\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.MULTIPLE_GRAPHS,\n \"the document holds more than one top-level <graph>; their nodes and edges are merged into one graph\",\n { line, element: attrs.get(\"id\") ?? null },\n );\n } else if (top) {\n this.graphSeen = true;\n this.graphId = attrs.get(\"id\") ?? null;\n this.edgedefault = directed ? \"directed\" : \"undirected\";\n this.direction.setHeader(directed, { line });\n const nodes = this.hint(attrs.get(\"parse.nodes\"), \"parse.nodes\", line);\n const edges = this.hint(attrs.get(\"parse.edges\"), \"parse.edges\", line);\n if (nodes !== null || edges !== null) {\n try {\n this.sink.reserve(nodes ?? undefined, edges ?? undefined);\n } catch (err) {\n if (!(err instanceof GraphFormatError)) {\n throw err;\n }\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.COUNT_HINT,\n `count hint refused: ${err.message}`,\n {\n line,\n },\n );\n }\n }\n }\n this.graphs.push({ directed, parent });\n this.ctx.push(Ctx.Graph);\n }\n\n /**\n * A `parse.nodes` / `parse.edges` hint the sink can reserve; anything else is reported and ignored.\n * @param text - the attribute text, or undefined\n * @param name - the attribute name\n * @param line - the line\n * @returns the count, or null\n */\n private hint(text: string | undefined, name: string, line: number): number | null {\n if (text === undefined) {\n return null;\n }\n const n = hint(text);\n if (n === null || n > MAX_COUNT) {\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.COUNT_HINT,\n `<graph ${name}=\"${text}\"> is not a count the sink can reserve; ignored`,\n { line, element: name },\n );\n return null;\n }\n return n;\n }\n\n // ------------------------------------------------------------------ keys\n\n /**\n * Open a `<key>`; the column is declared at `</key>` once its default is known.\n * @param attrs - the key attributes\n * @param line - the line\n */\n private beginKey(attrs: ReadonlyMap<string, string>, line: number): void {\n const id = attrs.get(\"id\") ?? null;\n const forText = attrs.get(\"for\") ?? \"all\";\n let domains: readonly Domain[];\n switch (forText) {\n case \"all\":\n domains = [\"graph\", \"node\", \"edge\"];\n break;\n case \"graph\":\n case \"node\":\n case \"edge\":\n domains = [forText];\n break;\n case \"hyperedge\":\n case \"port\":\n case \"endpoint\":\n this.report.warning(\n \"unsupported\",\n GRAPHML_ISSUE.KEY_DOMAIN_UNSUPPORTED,\n `key \"${id ?? \"\"}\" is declared for ${forText} elements, which are not kept`,\n { line, element: id },\n );\n domains = [];\n break;\n default:\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.KEY_FOR_INVALID,\n `key \"${id ?? \"\"}\" has an unknown for=\"${forText}\"`,\n { line, element: id },\n );\n domains = [];\n }\n this.pendingKey = {\n id,\n // `name` / `type` without the `attr.` prefix are written by some tools; the spec's spelling wins\n attrName: attrs.get(\"attr.name\") ?? attrs.get(\"name\") ?? null,\n attrType: attrs.get(\"attr.type\") ?? attrs.get(\"type\") ?? null,\n yfilesType: attrs.get(\"yfiles.type\") ?? null,\n domains,\n line,\n desc: \"\",\n defaultText: null,\n defaultTree: undefined,\n };\n this.ctx.push(Ctx.Key);\n }\n\n /** Close a `<key>`: declare its columns. */\n private finishKey(): void {\n const key = this.pendingKey;\n this.pendingKey = null;\n if (key === null) {\n return;\n }\n const where = { line: key.line, element: key.id };\n if (key.id === null || key.id.length === 0) {\n this.report.error(\"validation-error\", GRAPHML_ISSUE.KEY_MISSING_ID, \"<key> without an id\", where);\n return;\n }\n const declared = this.keys.get(key.id) ?? [];\n if (declared.some((entry) => entry.domains.some((domain) => key.domains.includes(domain)))) {\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.DUPLICATE_KEY,\n `key \"${key.id}\" is declared twice for the same kind of element`,\n where,\n );\n return;\n }\n const yfiles = key.yfilesType !== null;\n const name = key.attrName !== null && key.attrName.length > 0 ? key.attrName : key.id;\n const skipped = yfiles && this.yfilesMode === \"skip\";\n if (skipped) {\n this.report.warning(\n \"unsupported\",\n GRAPHML_ISSUE.YFILES_SKIPPED,\n `yFiles key \"${key.id}\" (${key.yfilesType ?? \"\"}) skipped per the yfiles option`,\n where,\n );\n }\n let weight = false;\n let originalId = false;\n let node: ColumnTarget | null = null;\n let edge: ColumnTarget | null = null;\n let graph: ColumnTarget | null = null;\n for (const domain of key.domains) {\n if (skipped) {\n continue;\n }\n if (domain === \"edge\" && !yfiles && isWeightField(name, this.options.weightFrom)) {\n weight = true;\n this.weightOrigin ??= { id: key.id, title: key.attrName, type: key.attrType };\n continue;\n }\n if (domain === \"node\" && !yfiles && name === ORIGINAL_ID_ATTRIBUTE) {\n if (this.options.restoreMangledIds) {\n originalId = true;\n continue;\n }\n node = this.declareOriginalIdColumn(key);\n continue;\n }\n try {\n const target = yfiles ? this.declareYfiles(key, name, domain) : this.declareTyped(key, name, domain);\n if (domain === \"node\") {\n node = target;\n } else if (domain === \"edge\") {\n edge = target;\n } else {\n graph = target;\n }\n } catch (err) {\n this.report.recordError(err, where);\n }\n }\n this.keys.set(key.id, [\n ...declared,\n {\n id: key.id,\n name,\n node,\n edge,\n graph,\n weight,\n originalId,\n yfiles,\n skipped,\n domains: key.domains,\n },\n ]);\n }\n\n /**\n * Declare the column of a typed (or untyped, then string) key in one domain.\n * @param key - the key\n * @param name - the resolved attribute name\n * @param domain - the domain\n * @returns the column target\n */\n private declareTyped(key: PendingKey, name: string, domain: Domain): ColumnTarget {\n const id = key.id ?? \"\";\n const declared: DeclaredAttribute = declareAttribute({\n format: FORMAT,\n id,\n title: key.attrName !== null && key.attrName.length > 0 ? key.attrName : null,\n type: key.attrType,\n defaultText: key.defaultTree === undefined ? key.defaultText : null,\n listSyntax: \"comma\",\n role: domain !== \"graph\" && name === LABEL_COLUMN ? \"label\" : null,\n long: this.options.long,\n taken: this.takenIn(domain),\n });\n for (const issue of declared.issues) {\n this.report.warning(issue.category, issue.code, issue.message, { line: key.line, element: id });\n }\n if (key.defaultTree !== undefined) {\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.DATA_NESTED,\n `the <default> of key \"${id}\" holds elements; a ${key.attrType ?? \"string\"} default must be text`,\n { line: key.line, element: id },\n );\n }\n const { decl } = declared;\n if (key.desc.length > 0) {\n decl.extra = { desc: key.desc };\n }\n return this.declareTarget(domain, decl, declared.spec, declared.listSyntax);\n }\n\n /**\n * Declare the json column of a yFiles key in one domain.\n * @param key - the key\n * @param name - the resolved attribute name\n * @param domain - the domain\n * @returns the column target\n */\n private declareYfiles(key: PendingKey, name: string, domain: Domain): ColumnTarget {\n const id = key.id ?? \"\";\n const columnName = uniqueColumnName(name, id, this.takenIn(domain));\n const decl: ColumnDecl = {\n name: columnName,\n dtype: \"json\",\n nullable: true,\n origin: {\n format: FORMAT,\n id,\n title: key.attrName !== null && key.attrName !== columnName ? key.attrName : null,\n type: key.yfilesType,\n namespace: \"yfiles\",\n },\n };\n if (key.defaultTree !== undefined) {\n decl.default = key.defaultTree;\n } else if (key.defaultText !== null) {\n decl.default = key.defaultText;\n }\n if (key.desc.length > 0) {\n decl.extra = { desc: key.desc };\n }\n return this.declareTarget(domain, decl, null, \"comma\");\n }\n\n /**\n * Declare the `graphty.originalId` column that keeps the exporter's original ids when\n * restoreMangledIds is off.\n * @param key - the key\n * @returns the column target\n */\n private declareOriginalIdColumn(key: PendingKey): ColumnTarget {\n const decl: ColumnDecl = {\n name: uniqueColumnName(ORIGINAL_ID_COLUMN, key.id, this.takenIn(\"node\")),\n dtype: \"string\",\n nullable: true,\n role: \"originalId\",\n origin: { format: FORMAT, id: key.id, title: key.attrName, type: key.attrType, namespace: null },\n };\n return this.declareTarget(\"node\", decl, null, \"comma\");\n }\n\n /**\n * Push a declaration into the sink for one domain through the shared design section 5.6 rule:\n * a role another column already holds is dropped (reported), a name the sink holds with\n * another shape is renamed `<name>#<id>` (reported).\n * @param domain - the domain\n * @param decl - the declaration\n * @param spec - the value spec, or null for json\n * @param listSyntax - the list syntax\n * @returns the target\n */\n private declareTarget(\n domain: Domain,\n decl: ColumnDecl,\n spec: DeclaredTypeSpec | null,\n listSyntax: ListSyntax,\n ): ColumnTarget {\n if (domain === \"graph\") {\n this.sink.setGraphValue(decl.name, undefined, decl);\n this.graphColumnNames.add(decl.name);\n return { name: decl.name, handle: INVALID_INDEX as ColumnHandle, decl, spec, listSyntax };\n }\n const resolved = declareResolved(this.sink, domain, decl, this.report, { element: decl.name });\n return { name: resolved.decl.name, handle: resolved.handle, decl: resolved.decl, spec, listSyntax };\n }\n\n /**\n * The `taken` predicate of a domain: the reserved XML-derived names plus the sink's columns.\n * @param domain - the domain\n * @returns the predicate\n */\n private takenIn(domain: Domain): (name: string) => boolean {\n if (domain === \"graph\") {\n return (name: string): boolean => this.graphColumnNames.has(name);\n }\n const reserved = domain === \"node\" ? RESERVED_NODE_NAMES : RESERVED_EDGE_NAMES;\n const inSink = takenIn(this.sink, domain);\n return (name: string): boolean => reserved.has(name) || inSink(name);\n }\n\n // ------------------------------------------------------------------ data and defaults\n\n /**\n * Open a `<data>`.\n * @param attrs - its attributes\n * @param line - the line\n * @param domain - the domain of the element holding it\n */\n private beginData(attrs: ReadonlyMap<string, string>, line: number, domain: Domain): void {\n const keyId = attrs.get(\"key\");\n const { content } = this;\n content.key = null;\n content.pendingKey = null;\n content.domain = domain;\n content.text = \"\";\n content.tree = null;\n content.line = line;\n if (keyId === undefined) {\n this.report.error(\"validation-error\", GRAPHML_ISSUE.DATA_MISSING_KEY, \"<data> without a key attribute\", {\n line,\n });\n } else {\n const entries = this.keys.get(keyId);\n const key = entries?.find((entry) => entry.domains.includes(domain)) ?? entries?.[0];\n if (key === undefined) {\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.UNKNOWN_KEY,\n `<data> references undeclared key \"${keyId}\"`,\n { line, element: keyId },\n );\n } else if (!key.skipped && !key.domains.includes(domain)) {\n this.report.warnOnce(\n \"validation-error\",\n GRAPHML_ISSUE.KEY_DOMAIN,\n `key \"${keyId}\" is declared for ${key.domains.join(\" / \")} elements but used on a ${domain}; ignored`,\n { line, element: keyId },\n );\n } else {\n content.key = key;\n }\n }\n this.ctx.push(Ctx.Data);\n }\n\n /**\n * A child element inside `<data>` / `<default>`: the content becomes a tree.\n * @param name - the element name\n * @param attrs - its attributes\n */\n private captureStart(name: string, attrs: ReadonlyMap<string, string>): void {\n const { content } = this;\n if (content.tree === null) {\n content.tree = new XmlTreeBuilder();\n if (content.text.length > 0) {\n content.tree.text(content.text);\n content.text = \"\";\n }\n }\n content.tree.start(name, attrs);\n this.ctx.push(Ctx.Capture);\n }\n\n /** A captured element ends. */\n private captureEnd(): void {\n this.content.tree?.end();\n }\n\n /** Close a `<default>`: keep its text or tree for the key. */\n private finishDefault(): void {\n const { content } = this;\n const key = content.pendingKey;\n if (key === null) {\n return;\n }\n if (content.tree !== null) {\n key.defaultTree = content.tree.finish();\n } else {\n key.defaultText = content.text;\n }\n content.tree = null;\n content.text = \"\";\n content.pendingKey = null;\n }\n\n /** Close a `<data>`: parse the value and route it to its element. */\n private finishData(): void {\n const { content } = this;\n const { key } = content;\n const value: unknown = content.tree === null ? content.text : content.tree.finish();\n content.tree = null;\n content.text = \"\";\n content.key = null;\n if (key === null || key.skipped) {\n return;\n }\n const where = { line: content.line, element: key.id };\n switch (content.domain) {\n case \"node\": {\n const node = this.nodes[this.nodes.length - 1];\n if (key.originalId) {\n if (typeof value === \"string\") {\n node.restoredId = value;\n }\n return;\n }\n if (key.yfiles) {\n for (const [handle, mapped] of this.graphics(\"node\", key, value, where)) {\n this.setNodeData(node, handle, mapped);\n }\n }\n if (key.node === null) {\n return;\n }\n const parsed = this.parseValue(key.node, value, where);\n if (parsed !== undefined) {\n this.setNodeData(node, key.node.handle, parsed);\n }\n return;\n }\n case \"edge\": {\n const { edge } = this;\n if (edge === null) {\n return;\n }\n if (key.weight) {\n if (typeof value !== \"string\") {\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.DATA_NESTED,\n \"a weight value must be text\",\n where,\n );\n return;\n }\n try {\n edge.weight = parseWeightText(value);\n } catch (err) {\n this.skipEdge(edge);\n this.report.recordError(err, where);\n }\n return;\n }\n if (key.yfiles) {\n for (const [handle, mapped] of this.graphics(\"edge\", key, value, where)) {\n edge.pending.push(handle, mapped);\n }\n }\n if (key.edge === null) {\n return;\n }\n const parsed = this.parseValue(key.edge, value, where);\n if (parsed !== undefined) {\n edge.pending.push(key.edge.handle, parsed);\n }\n return;\n }\n case \"graph\": {\n if (key.graph === null) {\n return;\n }\n const parsed = this.parseValue(key.graph, value, where);\n if (parsed !== undefined) {\n try {\n this.sink.setGraphValue(key.graph.name, parsed, key.graph.decl);\n } catch (err) {\n this.report.recordError(err, where);\n }\n }\n return;\n }\n default: {\n const { domain } = content;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown data domain ${String(domain)}`, {});\n }\n }\n }\n\n /**\n * Write a node value now, or keep it until the node is added.\n * @param node - the node state\n * @param handle - the column\n * @param value - the value\n */\n private setNodeData(node: NodeState, handle: ColumnHandle, value: unknown): void {\n if (node.index === INVALID_INDEX) {\n node.pending.push(handle, value);\n } else if (!node.failed) {\n this.sink.setNodeValue(handle, node.index, value);\n }\n }\n\n /**\n * The typed values mapped from a yFiles graphics tree (yfiles.ts), each with its column,\n * declared on first use.\n * @param domain - node or edge\n * @param key - the yFiles key\n * @param tree - the `<data>` content\n * @param where - the location for issues\n * @returns column handle and value pairs\n */\n private graphics(domain: \"node\" | \"edge\", key: KeyEntry, tree: unknown, where: Where): [ColumnHandle, unknown][] {\n const out: [ColumnHandle, unknown][] = [];\n for (const [field, value] of graphicsValues(domain, tree)) {\n const id = `${domain}:${field}`;\n let handle = this.graphicsColumns.get(id);\n if (handle === undefined) {\n try {\n ({ handle } = declareResolved(\n this.sink,\n domain,\n graphicsDecl(domain, field, key.id),\n this.report,\n where,\n ));\n } catch (err) {\n this.report.recordError(err, where);\n continue;\n }\n this.graphicsColumns.set(id, handle);\n }\n out.push([handle, value]);\n }\n return out;\n }\n\n /**\n * Parse the content of a `<data>` by its column's declaration.\n * @param target - the column\n * @param value - the text, or the tree of a nested subtree\n * @param where - the location for issues\n * @returns the value to write, or undefined when there is none (blank, or an error was recorded)\n */\n private parseValue(target: ColumnTarget, value: unknown, where: Where): unknown {\n if (target.spec === null) {\n if (!this.yfilesLossNoted) {\n this.yfilesLossNoted = true;\n this.report.loss(\n GRAPHML_LOSS.YFILES_JSON,\n \"yFiles nested XML is kept as a JSON tree: structure preserved, not byte-exact\",\n target.name,\n );\n }\n return value;\n }\n if (typeof value !== \"string\") {\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.DATA_NESTED,\n `<data> of the ${target.spec.declared} attribute \"${target.name}\" holds elements, not text`,\n where,\n );\n return undefined;\n }\n const { spec } = target;\n if (spec.kind !== \"string\" && isWhitespace(value)) {\n return undefined;\n }\n try {\n const parsed = parseDeclaredValue(value, spec, target.listSyntax);\n if (spec.precision && losesPrecision(spec, value)) {\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `long values of \"${target.name}\" beyond 2^53 are stored as the nearest double`,\n { line: where.line, element: target.name },\n );\n }\n return parsed;\n } catch (err) {\n this.report.recordError(err, where);\n return undefined;\n }\n }\n\n // ------------------------------------------------------------------ nodes\n\n /**\n * Open a `<node>`; it is added to the sink when its data is complete (or a nested graph\n * starts), so a `graphty:originalId` value can replace its id.\n * @param attrs - the node attributes\n * @param line - the line\n */\n private beginNode(attrs: ReadonlyMap<string, string>, line: number): void {\n this.reportUnreadAttributes(\"node\", attrs, NODE_ATTRIBUTES, line);\n const graph = this.graphs[this.graphs.length - 1];\n const state: NodeState = {\n id: null,\n idText: null,\n index: INVALID_INDEX,\n parent: graph.parent,\n pending: [],\n restoredId: null,\n failed: false,\n line,\n };\n const idText = attrs.get(\"id\");\n if (idText === undefined || idText.length === 0) {\n this.skipNode(state);\n this.report.error(\"missing-value\", GRAPHML_ISSUE.MISSING_ID, \"<node> without an id\", { line });\n } else {\n try {\n state.id = this.coercer.text(idText);\n state.idText = idText;\n this.reportMerge(idText, line);\n } catch (err) {\n this.skipNode(state);\n this.report.recordError(err, { line, element: idText });\n }\n }\n this.nodes.push(state);\n this.ctx.push(Ctx.Node);\n }\n\n /**\n * Add a node to the sink and flush its pending values.\n * @param node - the node state\n */\n private materializeNode(node: NodeState): void {\n if (node.index !== INVALID_INDEX || node.failed) {\n return;\n }\n const id: NodeId | null = node.restoredId ?? node.id;\n if (id === null) {\n node.failed = true;\n return;\n }\n if (node.restoredId !== null && node.idText !== null) {\n this.restored.set(node.idText, node.restoredId);\n }\n try {\n const existing = this.sink.indexOf(id);\n const index = this.sink.addNode(id);\n if (existing !== INVALID_INDEX && this.declared.has(index)) {\n this.report.warning(\n \"validation-error\",\n GRAPHML_ISSUE.DUPLICATE_NODE,\n `node \"${String(id)}\" is declared twice; the declarations are merged`,\n { line: node.line, element: String(id) },\n );\n } else {\n this.report.counts.nodes++;\n }\n this.declared.add(index);\n node.index = index;\n this.checkAbort();\n if (node.parent !== INVALID_INDEX) {\n this.sink.setNodeValue(this.parentColumn(), index, node.parent);\n }\n const { pending } = node;\n for (let i = 0; i < pending.length; i += 2) {\n this.sink.setNodeValue(pending[i] as ColumnHandle, index, pending[i + 1]);\n }\n pending.length = 0;\n } catch (err) {\n this.skipNode(node);\n this.report.recordError(err, { line: node.line, element: String(id) });\n }\n }\n\n /**\n * Mark a node element skipped (once) before its error is recorded, so the report's counts\n * include it even when that error is the one that exceeds the limit.\n * @param node - the node state\n */\n private skipNode(node: NodeState): void {\n if (!node.failed) {\n node.failed = true;\n this.report.counts.skippedNodes++;\n }\n }\n\n /** Close a `<node>`. */\n private finishNode(): void {\n const node = this.nodes.pop();\n if (node !== undefined) {\n this.materializeNode(node);\n }\n }\n\n /**\n * The `parent` column, declared on first use.\n * @returns the handle\n */\n private parentColumn(): ColumnHandle {\n if (this.parentHandle === INVALID_INDEX) {\n this.parentHandle = this.sink.declareNodeColumn({\n name: PARENT_COLUMN,\n dtype: \"u32\",\n role: \"parent\",\n refersTo: \"node\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"graph\", namespace: null },\n });\n }\n return this.parentHandle;\n }\n\n // ------------------------------------------------------------------ edges\n\n /**\n * Open an `<edge>`; it is pushed at `</edge>` once its weight and data are known.\n * @param attrs - the edge attributes\n * @param line - the line\n */\n private beginEdge(attrs: ReadonlyMap<string, string>, line: number): void {\n this.reportUnreadAttributes(\"edge\", attrs, EDGE_ATTRIBUTES, line);\n const graph = this.graphs[this.graphs.length - 1];\n const edge: EdgeState = {\n source: null,\n target: null,\n id: attrs.get(\"id\") ?? null,\n kind: graph.directed ? \"directed\" : \"undirected\",\n sourcePort: attrs.get(\"sourceport\") ?? null,\n targetPort: attrs.get(\"targetport\") ?? null,\n weight: undefined,\n pending: [],\n failed: false,\n line,\n };\n const where = { line, element: edge.id };\n const sourceText = attrs.get(\"source\");\n const targetText = attrs.get(\"target\");\n if (sourceText === undefined || sourceText.length === 0) {\n this.skipEdge(edge);\n this.report.error(\"missing-value\", GRAPHML_ISSUE.MISSING_ENDPOINT, \"<edge> without a source\", where);\n }\n if (targetText === undefined || targetText.length === 0) {\n this.skipEdge(edge);\n this.report.error(\"missing-value\", GRAPHML_ISSUE.MISSING_ENDPOINT, \"<edge> without a target\", where);\n }\n if (!edge.failed && sourceText !== undefined && targetText !== undefined) {\n try {\n edge.source = this.endpointId(sourceText, line);\n edge.target = this.endpointId(targetText, line);\n } catch (err) {\n this.skipEdge(edge);\n this.report.recordError(err, where);\n }\n }\n const directedText = attrs.get(\"directed\");\n if (directedText !== undefined) {\n if (directedText === \"true\") {\n edge.kind = \"directed\";\n } else if (directedText === \"false\") {\n edge.kind = \"undirected\";\n } else {\n this.skipEdge(edge);\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.INVALID_DIRECTED,\n `directed=\"${directedText}\" is neither true nor false`,\n where,\n );\n }\n }\n this.edge = edge;\n this.ctx.push(Ctx.Edge);\n }\n\n /**\n * Close an `<edge>`: push it through the direction resolver and write its values.\n */\n private finishEdge(): void {\n const { edge } = this;\n this.edge = null;\n if (edge === null) {\n return;\n }\n if (edge.failed || edge.source === null || edge.target === null) {\n this.skipEdge(edge);\n return;\n }\n const element = edge.id ?? `${String(edge.source)} -> ${String(edge.target)}`;\n const where = { line: edge.line, element };\n try {\n if (!this.options.addMissingNodes) {\n this.requireNode(edge.source);\n this.requireNode(edge.target);\n }\n if (edge.id !== null && this.edgeIds.has(edge.id)) {\n throw new GraphFormatError(\"E_DUPLICATE_EDGE_ID\", `edge id \"${edge.id}\" is used twice`, {\n id: edge.id,\n });\n }\n const before = this.sink.edgeCount;\n this.countEndpoints(edge.source, edge.target);\n const e = this.direction.addEdge(edge.source, edge.target, edge.kind, edge.weight, where);\n this.report.counts.edges += this.sink.edgeCount - before;\n this.checkAbort();\n if (edge.id !== null) {\n this.edgeIds.add(edge.id);\n this.sink.setEdgeValue(this.edgeIdColumn(), e, edge.id);\n }\n if (edge.sourcePort !== null) {\n this.sink.setEdgeValue(this.portColumn(\"source\"), e, edge.sourcePort);\n }\n if (edge.targetPort !== null) {\n this.sink.setEdgeValue(this.portColumn(\"target\"), e, edge.targetPort);\n }\n const { pending } = edge;\n for (let i = 0; i < pending.length; i += 2) {\n this.sink.setEdgeValue(pending[i] as ColumnHandle, e, pending[i + 1]);\n }\n } catch (err) {\n this.skipEdge(edge);\n this.report.recordError(err, where);\n }\n }\n\n /**\n * Mark an edge (or hyperedge) element skipped once, before its error is recorded.\n * @param edge - the edge state\n */\n private skipEdge(edge: EdgeState | HyperedgeState): void {\n if (!edge.failed) {\n edge.failed = true;\n this.report.counts.skippedEdges++;\n }\n }\n\n /**\n * E_UNKNOWN_NODE when an endpoint was never declared (addMissingNodes false enforced by the\n * importer, whatever the sink allows).\n * @param id - the endpoint id\n */\n private requireNode(id: NodeId): void {\n if (this.sink.indexOf(id) === INVALID_INDEX) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge endpoint \"${String(id)}\" is not a declared node`, {\n id,\n });\n }\n }\n\n /**\n * The edge `id` column (role id, unique), declared on first use.\n * @returns the handle\n */\n private edgeIdColumn(): ColumnHandle {\n if (this.edgeIdHandle === INVALID_INDEX) {\n this.edgeIdHandle = this.sink.declareEdgeColumn({\n name: EDGE_ID_COLUMN,\n dtype: \"string\",\n role: \"id\",\n unique: true,\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"id\", namespace: null },\n });\n }\n return this.edgeIdHandle;\n }\n\n /**\n * The sourceport / targetport column, declared on first use.\n * @param side - which end\n * @returns the handle\n */\n private portColumn(side: \"source\" | \"target\"): ColumnHandle {\n if (side === \"source\") {\n if (this.sourcePortHandle === INVALID_INDEX) {\n this.sourcePortHandle = this.sink.declareEdgeColumn({\n name: SOURCE_PORT_COLUMN,\n dtype: \"string\",\n role: \"sourcePort\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"sourceport\", namespace: null },\n });\n }\n return this.sourcePortHandle;\n }\n if (this.targetPortHandle === INVALID_INDEX) {\n this.targetPortHandle = this.sink.declareEdgeColumn({\n name: TARGET_PORT_COLUMN,\n dtype: \"string\",\n role: \"targetPort\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"targetport\", namespace: null },\n });\n }\n return this.targetPortHandle;\n }\n\n // ------------------------------------------------------------------ hyperedges\n\n /**\n * Open a `<hyperedge>` per the hyperedges option.\n * @param attrs - its attributes\n * @param line - the line\n */\n private beginHyperedge(attrs: ReadonlyMap<string, string>, line: number): void {\n const id = attrs.get(\"id\") ?? null;\n const where = { line, element: id };\n switch (this.options.hyperedges) {\n case \"error\":\n this.report.error(\n \"unsupported\",\n GRAPHML_ISSUE.HYPEREDGE,\n 'hyperedge refused (hyperedges: \"error\")',\n where,\n );\n throw this.report.abort(\"hyperedge refused\", { code: GRAPHML_ISSUE.HYPEREDGE });\n case \"skip\":\n this.report.warnOnce(\n \"unsupported\",\n GRAPHML_ISSUE.HYPEREDGE_SKIPPED,\n 'hyperedges are skipped (hyperedges: \"skip\"); use \"star\" or \"clique\" to expand them',\n where,\n );\n this.report.counts.skippedEdges++;\n this.ctx.push(Ctx.Skip);\n return;\n case \"star\":\n case \"clique\":\n this.hyperedge = { id, endpoints: [], failed: false, line };\n this.ctx.push(Ctx.Hyperedge);\n return;\n default: {\n const policy: never = this.options.hyperedges;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown hyperedges policy ${String(policy)}`, {\n option: \"hyperedges\",\n });\n }\n }\n }\n\n /**\n * An `<endpoint>` of the open hyperedge.\n * @param attrs - its attributes\n * @param line - the line\n */\n private readEndpoint(attrs: ReadonlyMap<string, string>, line: number): void {\n const { hyperedge } = this;\n if (hyperedge === null) {\n return;\n }\n const where = { line, element: hyperedge.id };\n const nodeText = attrs.get(\"node\");\n const typeText = attrs.get(\"type\") ?? \"undir\";\n if (nodeText === undefined || nodeText.length === 0) {\n this.skipEdge(hyperedge);\n this.report.error(\"missing-value\", GRAPHML_ISSUE.HYPEREDGE_ENDPOINT, \"<endpoint> without a node\", where);\n return;\n }\n if (typeText !== \"in\" && typeText !== \"out\" && typeText !== \"undir\") {\n this.skipEdge(hyperedge);\n this.report.error(\n \"validation-error\",\n GRAPHML_ISSUE.HYPEREDGE_ENDPOINT,\n `endpoint type \"${typeText}\" is not in, out or undir`,\n where,\n );\n return;\n }\n try {\n const node = this.endpointId(nodeText, line);\n hyperedge.endpoints.push({ node, type: typeText });\n } catch (err) {\n this.skipEdge(hyperedge);\n this.report.recordError(err, where);\n }\n }\n\n /** Close a `<hyperedge>`: expand it to a star or a clique. */\n private finishHyperedge(): void {\n const { hyperedge } = this;\n this.hyperedge = null;\n if (hyperedge === null) {\n return;\n }\n if (hyperedge.failed) {\n return;\n }\n const where = { line: hyperedge.line, element: hyperedge.id };\n try {\n if (this.options.hyperedges === \"star\") {\n this.expandStar(hyperedge, where);\n } else {\n this.expandClique(hyperedge, where);\n }\n } catch (err) {\n this.skipEdge(hyperedge);\n this.report.recordError(err, where);\n }\n }\n\n /**\n * Star expansion: a synthetic hub node (marked in the `graphty.hyperedge` column) joined to\n * every endpoint; `in` endpoints point at the hub, `out` endpoints are pointed at by it,\n * `undir` endpoints are undirected.\n * @param hyperedge - the hyperedge\n * @param where - the location for issues\n */\n private expandStar(hyperedge: HyperedgeState, where: Where): void {\n this.hyperedgeCount++;\n let hubId = hyperedge.id ?? `hyperedge${this.hyperedgeCount}`;\n for (let n = 2; this.sink.indexOf(hubId) !== INVALID_INDEX; n++) {\n hubId = `${hyperedge.id ?? `hyperedge${this.hyperedgeCount}`}#${n}`;\n }\n const hub = this.sink.addNode(hubId);\n this.declared.add(hub);\n this.report.counts.nodes++;\n if (this.hubHandle === INVALID_INDEX) {\n this.hubHandle = this.sink.declareNodeColumn({\n name: HYPEREDGE_HUB_COLUMN,\n dtype: \"bool\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"hyperedge\", namespace: null },\n });\n }\n this.sink.setNodeValue(this.hubHandle, hub, true);\n for (const endpoint of hyperedge.endpoints) {\n const before = this.sink.edgeCount;\n switch (endpoint.type) {\n case \"in\":\n this.direction.addEdge(endpoint.node, hubId, \"directed\", undefined, where);\n break;\n case \"out\":\n this.direction.addEdge(hubId, endpoint.node, \"directed\", undefined, where);\n break;\n case \"undir\":\n this.direction.addEdge(endpoint.node, hubId, \"undirected\", undefined, where);\n break;\n default: {\n const { type } = endpoint;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown endpoint type ${String(type)}`, {});\n }\n }\n this.report.counts.edges += this.sink.edgeCount - before;\n }\n }\n\n /**\n * Clique expansion: every `in` endpoint points at every `out` endpoint; `undir` endpoints are\n * joined undirected to every other endpoint; two endpoints of the same direction are not joined.\n * @param hyperedge - the hyperedge\n * @param where - the location for issues\n */\n private expandClique(hyperedge: HyperedgeState, where: Where): void {\n const { endpoints } = hyperedge;\n for (let i = 0; i < endpoints.length; i++) {\n for (let j = i + 1; j < endpoints.length; j++) {\n const a = endpoints[i];\n const b = endpoints[j];\n const before = this.sink.edgeCount;\n if (a.type === \"undir\" || b.type === \"undir\") {\n this.direction.addEdge(a.node, b.node, \"undirected\", undefined, where);\n } else if (a.type === \"in\" && b.type === \"out\") {\n this.direction.addEdge(a.node, b.node, \"directed\", undefined, where);\n } else if (a.type === \"out\" && b.type === \"in\") {\n this.direction.addEdge(b.node, a.node, \"directed\", undefined, where);\n } else {\n continue;\n }\n this.report.counts.edges += this.sink.edgeCount - before;\n }\n }\n }\n\n // ------------------------------------------------------------------ options and ids\n\n /**\n * Count the endpoints of an edge the file never declared as nodes of the sink (created under\n * addMissingNodes), so the report describes what the sink holds (design section 8.6).\n * @param source - the source id\n * @param target - the target id\n */\n private countEndpoints(source: NodeId, target: NodeId): void {\n if (!this.options.addMissingNodes) {\n return;\n }\n let created = 0;\n if (this.sink.indexOf(source) === INVALID_INDEX) {\n created++;\n }\n if (source !== target && this.sink.indexOf(target) === INVALID_INDEX) {\n created++;\n }\n this.report.counts.nodes += created;\n }\n\n /** Check the cancellation signal every ABORT_CHECK_INTERVAL elements. */\n private checkAbort(): void {\n if (++this.elementsSinceCheck >= ABORT_CHECK_INTERVAL) {\n this.elementsSinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n\n /**\n * The id an edge endpoint refers to: the original id when the text is a mangled id restored\n * from `graphty:originalId` (the exporter writes endpoints with the mangled id), else the\n * coerced text.\n * @param text - the source / target / endpoint node text\n * @param line - the line\n * @returns the node id\n */\n private endpointId(text: string, line: number): NodeId {\n const restored = this.restored.get(text);\n if (restored !== undefined) {\n return restored;\n }\n const id = this.coercer.text(text);\n this.reportMerge(text, line);\n return id;\n }\n\n /**\n * Report a merge the coercer detected under ids: \"number\".\n * @param text - the id text just coerced\n * @param line - the line\n */\n private reportMerge(text: string, line: number): void {\n const merge = this.coercer.lastMerge;\n if (merge !== null) {\n this.report.warning(\n \"coercion\",\n GRAPHML_ISSUE.ID_MERGED,\n `id \"${merge.text}\" merged with \"${merge.previousText}\" as ${merge.id} under ids: \"number\"`,\n { line, element: text },\n );\n }\n }\n}\n\n/**\n * A `parse.nodes` / `parse.edges` hint as a count.\n * @param text - the attribute text\n * @returns the count, or null when absent or not a non-negative integer\n */\nfunction hint(text: string | undefined): number | null {\n if (text === undefined || !/^[0-9]+$/.test(text)) {\n return null;\n }\n const n = Number(text);\n return Number.isSafeInteger(n) ? n : null;\n}\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the yfiles mode\n */\nfunction resolveYfiles(options: GraphmlImportOptions | undefined): \"json\" | \"skip\" {\n const value = options?.yfiles;\n if (value === undefined) {\n return \"json\";\n }\n if (typeof value !== \"string\" || !YFILES_MODES.has(value)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option yfiles: ${JSON.stringify(value)} is not \"json\" or \"skip\"`, {\n option: \"yfiles\",\n found: value,\n });\n }\n return value;\n}\n\n/**\n * Confidence that a head of bytes is GraphML.\n * @param head - the first bytes\n * @returns 1 for a `<graphml` root in the GraphML namespace, 0.9 for a `<graphml` root, 0.05 for other XML, 0 otherwise\n * or when the head does not start with markup\n */\nfunction sniffGraphml(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\", { fatal: false }).decode(head.subarray(0, SNIFF_BYTES));\n // Only a document that starts as markup: a JSON or CSV value may mention a `<graphml>` tag.\n if (!/^\\uFEFF?\\s*</.test(text)) {\n return 0;\n }\n const root = text.indexOf(\"<graphml\");\n if (root >= 0) {\n return text.includes(GRAPHML_NAMESPACE, root) ? 1 : 0.9;\n }\n return /^\\s*<(\\?xml|!--|!DOCTYPE)/.test(text) ? 0.05 : 0;\n}\n\n/**\n * Import GraphML into a sink.\n * @param input - the document\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report; ImportError when the document cannot be read or the error limit is exceeded\n */\nasync function importGraphml(\n input: ImportInput,\n sink: GraphSink,\n options?: GraphmlImportOptions & CommonImportOptions,\n): Promise<ImportReport> {\n const common = resolveImportOptions(options, FORMAT_DEFAULTS);\n const yfilesMode = resolveYfiles(options);\n const report = new ImportReportBuilder(FORMAT, common.errorLimit);\n reportSinkOptions(sink, options, report, true);\n reportUnusedOptions(options, report, USED_OPTIONS);\n const reader = new GraphmlReader(sink, report, common, yfilesMode);\n try {\n await tokenizeXml(textChunks(input, report, { ...common, declaredEncoding: xmlDeclaredEncoding }), reader);\n } catch (err) {\n if (err instanceof XmlSyntaxError) {\n report.fail(GRAPHML_ISSUE.XML_SYNTAX, err.message, { line: err.line });\n }\n throw err;\n }\n reader.finish();\n throwIfAborted(common.signal);\n return report.finish();\n}\n\n/** The GraphML importer (design section 8.4). */\nexport const graphmlImporter: GraphImporter<GraphmlImportOptions> = Object.freeze({\n format: FORMAT,\n extensions: EXTENSIONS,\n mimeTypes: MIME_TYPES,\n sniff: sniffGraphml,\n import: importGraphml,\n});\n"],"names":["text","child","hint"],"mappings":"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"}
|