@pubid/pubid 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/artifact/corpus.json.gz +0 -0
  2. package/dist/conformance/cli.js +5 -1
  3. package/dist/flavors/amca/grammar.d.ts +4 -0
  4. package/dist/flavors/amca/grammar.js +87 -0
  5. package/dist/flavors/amca/index.d.ts +4 -0
  6. package/dist/flavors/amca/index.js +76 -0
  7. package/dist/flavors/amca/model.d.ts +29 -0
  8. package/dist/flavors/amca/model.js +146 -0
  9. package/dist/flavors/ansi/index.d.ts +24 -0
  10. package/dist/flavors/ansi/index.js +147 -0
  11. package/dist/flavors/api/grammar.d.ts +4 -0
  12. package/dist/flavors/api/grammar.js +79 -0
  13. package/dist/flavors/api/index.d.ts +4 -0
  14. package/dist/flavors/api/index.js +71 -0
  15. package/dist/flavors/api/model.d.ts +27 -0
  16. package/dist/flavors/api/model.js +114 -0
  17. package/dist/flavors/ashrae/grammar.d.ts +2 -0
  18. package/dist/flavors/ashrae/grammar.js +667 -0
  19. package/dist/flavors/ashrae/index.d.ts +4 -0
  20. package/dist/flavors/ashrae/index.js +306 -0
  21. package/dist/flavors/ashrae/model.d.ts +87 -0
  22. package/dist/flavors/ashrae/model.js +335 -0
  23. package/dist/flavors/ashrae/preprocessor.d.ts +7 -0
  24. package/dist/flavors/ashrae/preprocessor.js +44 -0
  25. package/dist/flavors/asme/grammar.d.ts +2 -0
  26. package/dist/flavors/asme/grammar.js +200 -0
  27. package/dist/flavors/asme/index.d.ts +4 -0
  28. package/dist/flavors/asme/index.js +138 -0
  29. package/dist/flavors/asme/model.d.ts +34 -0
  30. package/dist/flavors/asme/model.js +123 -0
  31. package/dist/flavors/astm/grammar.d.ts +2 -0
  32. package/dist/flavors/astm/grammar.js +110 -0
  33. package/dist/flavors/astm/index.d.ts +2 -0
  34. package/dist/flavors/astm/index.js +127 -0
  35. package/dist/flavors/astm/model.d.ts +42 -0
  36. package/dist/flavors/astm/model.js +263 -0
  37. package/dist/flavors/bipm/index.d.ts +30 -0
  38. package/dist/flavors/bipm/index.js +434 -0
  39. package/dist/flavors/bsi/grammar.d.ts +4 -0
  40. package/dist/flavors/bsi/grammar.js +535 -0
  41. package/dist/flavors/bsi/index.d.ts +4 -0
  42. package/dist/flavors/bsi/index.js +941 -0
  43. package/dist/flavors/bsi/model.d.ts +127 -0
  44. package/dist/flavors/bsi/model.js +863 -0
  45. package/dist/flavors/calconnect/index.d.ts +21 -0
  46. package/dist/flavors/calconnect/index.js +113 -0
  47. package/dist/flavors/cen_cenelec/grammar.d.ts +4 -0
  48. package/dist/flavors/cen_cenelec/grammar.js +107 -0
  49. package/dist/flavors/cen_cenelec/index.d.ts +5 -0
  50. package/dist/flavors/cen_cenelec/index.js +263 -0
  51. package/dist/flavors/cen_cenelec/model.d.ts +45 -0
  52. package/dist/flavors/cen_cenelec/model.js +490 -0
  53. package/dist/flavors/cie/grammar.d.ts +5 -0
  54. package/dist/flavors/cie/grammar.js +127 -0
  55. package/dist/flavors/cie/index.d.ts +2 -0
  56. package/dist/flavors/cie/index.js +311 -0
  57. package/dist/flavors/cie/model.d.ts +122 -0
  58. package/dist/flavors/cie/model.js +464 -0
  59. package/dist/flavors/csa/grammar.d.ts +6 -0
  60. package/dist/flavors/csa/grammar.js +239 -0
  61. package/dist/flavors/csa/index.d.ts +2 -0
  62. package/dist/flavors/csa/index.js +634 -0
  63. package/dist/flavors/csa/model.d.ts +33 -0
  64. package/dist/flavors/csa/model.js +505 -0
  65. package/dist/flavors/doi/index.d.ts +13 -0
  66. package/dist/flavors/doi/index.js +65 -0
  67. package/dist/flavors/easc/index.d.ts +4 -0
  68. package/dist/flavors/easc/index.js +107 -0
  69. package/dist/flavors/ecma/index.d.ts +4 -0
  70. package/dist/flavors/ecma/index.js +117 -0
  71. package/dist/flavors/etsi/index.d.ts +14 -0
  72. package/dist/flavors/etsi/index.js +307 -0
  73. package/dist/flavors/evs/grammar.d.ts +2 -0
  74. package/dist/flavors/evs/grammar.js +22 -0
  75. package/dist/flavors/evs/index.d.ts +2 -0
  76. package/dist/flavors/evs/index.js +24 -0
  77. package/dist/flavors/evs/model.d.ts +19 -0
  78. package/dist/flavors/evs/model.js +36 -0
  79. package/dist/flavors/gb/index.d.ts +24 -0
  80. package/dist/flavors/gb/index.js +111 -0
  81. package/dist/flavors/gost/grammar.d.ts +2 -0
  82. package/dist/flavors/gost/grammar.js +46 -0
  83. package/dist/flavors/gost/index.d.ts +2 -0
  84. package/dist/flavors/gost/index.js +165 -0
  85. package/dist/flavors/gost/model.d.ts +61 -0
  86. package/dist/flavors/gost/model.js +147 -0
  87. package/dist/flavors/gost/prefix_routes.d.ts +15 -0
  88. package/dist/flavors/gost/prefix_routes.js +192 -0
  89. package/dist/flavors/iala/index.d.ts +32 -0
  90. package/dist/flavors/iala/index.js +300 -0
  91. package/dist/flavors/iana/index.d.ts +19 -0
  92. package/dist/flavors/iana/index.js +71 -0
  93. package/dist/flavors/idf/grammar.d.ts +2 -0
  94. package/dist/flavors/idf/grammar.js +71 -0
  95. package/dist/flavors/idf/index.d.ts +2 -0
  96. package/dist/flavors/idf/index.js +100 -0
  97. package/dist/flavors/idf/model.d.ts +54 -0
  98. package/dist/flavors/idf/model.js +359 -0
  99. package/dist/flavors/iec/grammar.d.ts +3 -0
  100. package/dist/flavors/iec/grammar.js +187 -0
  101. package/dist/flavors/iec/index.d.ts +4 -0
  102. package/dist/flavors/iec/index.js +507 -0
  103. package/dist/flavors/iec/model.d.ts +54 -0
  104. package/dist/flavors/iec/model.js +437 -0
  105. package/dist/flavors/ieee/grammar.d.ts +2 -0
  106. package/dist/flavors/ieee/grammar.js +626 -0
  107. package/dist/flavors/ieee/index.d.ts +3 -0
  108. package/dist/flavors/ieee/index.js +1186 -0
  109. package/dist/flavors/ieee/model.d.ts +142 -0
  110. package/dist/flavors/ieee/model.js +1148 -0
  111. package/dist/flavors/ieee/preprocessor.d.ts +8 -0
  112. package/dist/flavors/ieee/preprocessor.js +410 -0
  113. package/dist/flavors/ieee/update_codes.d.ts +8 -0
  114. package/dist/flavors/ieee/update_codes.js +191 -0
  115. package/dist/flavors/ietf/index.d.ts +30 -0
  116. package/dist/flavors/ietf/index.js +151 -0
  117. package/dist/flavors/iho/index.d.ts +4 -0
  118. package/dist/flavors/iho/index.js +126 -0
  119. package/dist/flavors/index.d.ts +9 -0
  120. package/dist/flavors/index.js +136 -0
  121. package/dist/flavors/isbn/index.d.ts +13 -0
  122. package/dist/flavors/isbn/index.js +97 -0
  123. package/dist/flavors/iso/grammar.d.ts +2 -0
  124. package/dist/flavors/iso/grammar.js +207 -0
  125. package/dist/flavors/iso/index.d.ts +2 -0
  126. package/dist/flavors/iso/index.js +343 -0
  127. package/dist/flavors/iso/model.d.ts +159 -0
  128. package/dist/flavors/iso/model.js +802 -0
  129. package/dist/flavors/iso/stages.generated.d.ts +13 -0
  130. package/dist/flavors/iso/stages.generated.js +391 -0
  131. package/dist/flavors/itu/grammar.d.ts +4 -0
  132. package/dist/flavors/itu/grammar.js +205 -0
  133. package/dist/flavors/itu/index.d.ts +2 -0
  134. package/dist/flavors/itu/index.js +224 -0
  135. package/dist/flavors/itu/model.d.ts +184 -0
  136. package/dist/flavors/itu/model.js +599 -0
  137. package/dist/flavors/jcgm/index.d.ts +7 -0
  138. package/dist/flavors/jcgm/index.js +300 -0
  139. package/dist/flavors/jis/index.d.ts +4 -0
  140. package/dist/flavors/jis/index.js +267 -0
  141. package/dist/flavors/nist/grammar.d.ts +2 -0
  142. package/dist/flavors/nist/grammar.js +287 -0
  143. package/dist/flavors/nist/index.d.ts +2 -0
  144. package/dist/flavors/nist/index.js +1244 -0
  145. package/dist/flavors/nist/model.d.ts +155 -0
  146. package/dist/flavors/nist/model.js +823 -0
  147. package/dist/flavors/nist/preprocessor.d.ts +11 -0
  148. package/dist/flavors/nist/preprocessor.js +281 -0
  149. package/dist/flavors/oasis/index.d.ts +23 -0
  150. package/dist/flavors/oasis/index.js +110 -0
  151. package/dist/flavors/ogc/index.d.ts +20 -0
  152. package/dist/flavors/ogc/index.js +75 -0
  153. package/dist/flavors/oiml/grammar.d.ts +2 -0
  154. package/dist/flavors/oiml/grammar.js +180 -0
  155. package/dist/flavors/oiml/implementation.d.ts +9 -0
  156. package/dist/flavors/oiml/implementation.js +16 -0
  157. package/dist/flavors/oiml/model.d.ts +4 -0
  158. package/dist/flavors/oiml/model.js +462 -0
  159. package/dist/flavors/omg/index.d.ts +14 -0
  160. package/dist/flavors/omg/index.js +73 -0
  161. package/dist/flavors/plateau/index.d.ts +4 -0
  162. package/dist/flavors/plateau/index.js +97 -0
  163. package/dist/flavors/tgpp/index.d.ts +4 -0
  164. package/dist/flavors/tgpp/index.js +122 -0
  165. package/dist/flavors/un/index.d.ts +13 -0
  166. package/dist/flavors/un/index.js +90 -0
  167. package/dist/flavors/w3c/index.d.ts +14 -0
  168. package/dist/flavors/w3c/index.js +148 -0
  169. package/dist/flavors/xsf/index.d.ts +18 -0
  170. package/dist/flavors/xsf/index.js +65 -0
  171. package/dist/grammar/engine.d.ts +78 -0
  172. package/dist/grammar/engine.js +351 -0
  173. package/dist/model/attribute.d.ts +54 -0
  174. package/dist/model/attribute.js +53 -0
  175. package/dist/model/builder.d.ts +39 -0
  176. package/dist/model/builder.js +124 -0
  177. package/dist/model/component.d.ts +70 -0
  178. package/dist/model/component.js +170 -0
  179. package/dist/model/identifier.d.ts +83 -0
  180. package/dist/model/identifier.js +270 -0
  181. package/dist/model/urn-generator.d.ts +27 -0
  182. package/dist/model/urn-generator.js +91 -0
  183. package/package.json +1 -1
@@ -0,0 +1,802 @@
1
+ import { BaseIdentifier, registerType } from "../../model/identifier.js";
2
+ import { extendAttributes, keyValue } from "../../model/attribute.js";
3
+ import { PubidDate, Language, Iteration } from "../../model/component.js";
4
+ import { Component } from "../../model/component.js";
5
+ import { BaseUrnGenerator } from "../../model/urn-generator.js";
6
+ import { ISO_TYPED_STAGES } from "./stages.generated.js";
7
+ /**
8
+ * Port of lib/pubid/iso/identifiers/* on the unified model. The typed
9
+ * stage is the single source of truth for stage and doctype; the wire
10
+ * hash carries only the non-published stage CODE under "stage"
11
+ * (identifier.rb's stage_to_kv). number/part/subpart are plain strings;
12
+ * date is flat year/month/day; publisher serializes only when it is
13
+ * not the class default.
14
+ */
15
+ export function locateStage(abbr) {
16
+ const needle = abbr.trim().toUpperCase();
17
+ return ISO_TYPED_STAGES.find((s) => s.abbr.some((a) => a.toUpperCase() === needle));
18
+ }
19
+ export function locateType(typeKey) {
20
+ return ISO_TYPED_STAGES.filter((s) => s.typeKey === typeKey);
21
+ }
22
+ export function locateStageByCode(code) {
23
+ return ISO_TYPED_STAGES.find((s) => s.code === code);
24
+ }
25
+ export function publishedStage(typeKey) {
26
+ return ISO_TYPED_STAGES.find((s) => s.typeKey === typeKey && s.stageCode === "published");
27
+ }
28
+ /** Tokens for the parser, longest first (array_to_str semantics). */
29
+ export function stageTokens(typeKeys) {
30
+ const stages = typeKeys === undefined ? ISO_TYPED_STAGES : ISO_TYPED_STAGES.filter((s) => typeKeys.includes(s.typeKey));
31
+ const tokens = stages.flatMap((s) => s.abbr.filter((a) => a !== ""));
32
+ return [...new Set(tokens)].sort((a, b) => b.length - a.length);
33
+ }
34
+ /** TypedStage#abbreviation: long/short override, else abbr[0]; the
35
+ * parsed spelling (originalAbbr) decides long vs short via context. */
36
+ export function stageAbbr(entry, formatLong, originalAbbr) {
37
+ if (formatLong && entry.longAbbr !== undefined)
38
+ return entry.longAbbr;
39
+ if (!formatLong && entry.shortAbbr !== undefined)
40
+ return entry.shortAbbr;
41
+ return entry.abbr[0] ?? "";
42
+ }
43
+ /** The ISO Edition: number + original spelling ("Edition 13"). */
44
+ export class IsoEdition extends Component {
45
+ number;
46
+ original_text;
47
+ constructor(attrs) {
48
+ super();
49
+ this.number = attrs["number"];
50
+ this.original_text = attrs["original_text"];
51
+ }
52
+ render() {
53
+ return this.original_text ?? this.number ?? "";
54
+ }
55
+ toWire() {
56
+ return {
57
+ ...(this.number !== undefined ? { number: this.number } : {}),
58
+ ...(this.original_text !== undefined ? { original_text: this.original_text } : {}),
59
+ };
60
+ }
61
+ }
62
+ export class IsoIdentifier extends BaseIdentifier {
63
+ static attributes = extendAttributes(BaseIdentifier, {
64
+ number: { type: "string" },
65
+ part: { type: "string" },
66
+ subpart: { type: "string" },
67
+ stage_iteration: { type: Iteration },
68
+ date: { type: PubidDate },
69
+ edition: { type: IsoEdition },
70
+ languages: { type: Language, collection: true, initializeEmpty: true },
71
+ all_parts: { type: "boolean", default: false },
72
+ });
73
+ constructor(attrs = {}) {
74
+ super(attrs);
75
+ // Materialize the typed-stage state the way lutaml materializes
76
+ // attribute defaults: from the hash, else the class's published
77
+ // stage.
78
+ const self = this;
79
+ if (attrs["typedStageState"] !== undefined) {
80
+ self["typedStageState"] = attrs["typedStageState"];
81
+ }
82
+ else if (self["typedStageState"] === undefined) {
83
+ const pub = publishedStage(this.typeKey());
84
+ if (pub !== undefined)
85
+ self["typedStageState"] = { entry: pub, originalAbbr: pub.abbr[0] };
86
+ }
87
+ }
88
+ /** The class's type key (drives URN type component + class identity). */
89
+ typeKey() {
90
+ return this.constructor.typeKey;
91
+ }
92
+ root() {
93
+ const base = this["base"];
94
+ return base instanceof IsoIdentifier ? base.root() : this;
95
+ }
96
+ /** detect_stage_format_long: the parsed spelling picks long form. */
97
+ stageFormatLong() {
98
+ const ts = this.typedStageState;
99
+ if (ts === undefined)
100
+ return false;
101
+ if (ts.entry.longAbbr !== undefined && ts.originalAbbr?.startsWith(ts.entry.longAbbr))
102
+ return true;
103
+ if (ts.entry.longAbbr !== undefined && ts.originalAbbr?.includes("Directives"))
104
+ return true;
105
+ return false;
106
+ }
107
+ /** detect_language_code_format: single (E) vs iso (en). */
108
+ languageSingle() {
109
+ const first = this.languages?.[0];
110
+ if (first === undefined)
111
+ return false;
112
+ return first.originalCode !== undefined && first.originalCode.length === 1;
113
+ }
114
+ stageString() {
115
+ const ts = this.typedStageState;
116
+ if (ts === undefined)
117
+ return "";
118
+ return stageAbbr(ts.entry, this.stageFormatLong(), ts.originalAbbr);
119
+ }
120
+ /** Render with an EXPLICIT long-format flag (the supplement
121
+ * renderer propagates its own context to the base). */
122
+ renderWithFormat(formatLong) {
123
+ let result = "";
124
+ if (this.typeKey() === "iwa") {
125
+ const stage = this.typedStageState === undefined ? "" : stageAbbr(this.typedStageState.entry, formatLong);
126
+ if (stage !== "")
127
+ result += stage;
128
+ }
129
+ else {
130
+ const pub = this.publisher;
131
+ if (pub !== undefined) {
132
+ result += pub.render();
133
+ const stage = this.stageStringFor(formatLong);
134
+ if (stage !== "") {
135
+ const isGuide = this.typeKey() === "guide" && !(this instanceof IsoSupplementIdentifier);
136
+ const sep = isGuide || (pub.copublisher?.length ?? 0) > 0 ? " " : "/";
137
+ result += `${sep}${stage}`;
138
+ }
139
+ }
140
+ }
141
+ const num = this.numberPortion(true);
142
+ if (num !== "")
143
+ result += result === "" ? num : ` ${num}`;
144
+ result += this.languagePortion(this.languageSingle());
145
+ if (this.all_parts === true)
146
+ result += " (all parts)";
147
+ return result;
148
+ }
149
+ /** Ruby SupplementRenderer renders the base with the wrapper's
150
+ * detected context (stage_format_long propagates down the chain;
151
+ * with_date being non-nil pins it against re-detection — a nested
152
+ * amendment renders "AMD" under a "CD Cor" top but "Amd" under a
153
+ * "Cor." top). */
154
+ renderAsSupplementBase(long) {
155
+ return this.renderWithFormat(long);
156
+ }
157
+ stageStringFor(formatLong) {
158
+ const ts = this.typedStageState;
159
+ if (ts === undefined)
160
+ return "";
161
+ return stageAbbr(ts.entry, formatLong, ts.originalAbbr);
162
+ }
163
+ numberPortion(withDate) {
164
+ let result = this.number ?? "";
165
+ if (this.part !== undefined)
166
+ result += `-${this.part}`;
167
+ if (this.subpart !== undefined)
168
+ result += `-${this.subpart}`;
169
+ if (this.stage_iteration !== undefined)
170
+ result += `.${this.stage_iteration.render() ?? ""}`;
171
+ if (withDate && this.date !== undefined && this.date.present()) {
172
+ result += `:${this.date.render()}`;
173
+ }
174
+ return result;
175
+ }
176
+ languagePortion(single) {
177
+ if (this.languages === undefined || this.languages.length === 0)
178
+ return "";
179
+ const rendered = this.languages.map((l) => (single ? l.originalCode ?? l.code : l.code));
180
+ return `(${rendered.join(single ? "/" : ",")})`;
181
+ }
182
+ }
183
+ const dateTrio = () => [
184
+ {
185
+ wire: "year",
186
+ to: "date",
187
+ toWire: (m) => m["date"]?.year,
188
+ fromWire: (h) => h["year"] === undefined || h["year"] === null
189
+ ? undefined
190
+ : new PubidDate({
191
+ year: String(h["year"]),
192
+ month: h["month"] === undefined || h["month"] === null ? undefined : String(h["month"]),
193
+ day: h["day"] === undefined || h["day"] === null ? undefined : String(h["day"]),
194
+ }),
195
+ },
196
+ { wire: "month", to: "date", toWire: (m) => m["date"]?.month, fromWire: () => undefined },
197
+ { wire: "day", to: "date", toWire: (m) => m["date"]?.day, fromWire: () => undefined },
198
+ {
199
+ wire: "undated",
200
+ to: "date",
201
+ toWire: (m) => (m["date"]?.undated === true ? true : undefined),
202
+ fromWire: (h) => (h["undated"] === true ? new PubidDate({ undated: true }) : undefined),
203
+ },
204
+ ];
205
+ /** identifier.rb's base key_value block (the single-document whitelist). */
206
+ export const ISO_MAPPINGS = keyValue({ wire: "number", to: "number" }, { wire: "part", to: "part" }, { wire: "subpart", to: "subpart" }, {
207
+ wire: "stage_iteration",
208
+ to: "stage_iteration",
209
+ toWire: (m) => m["stage_iteration"]?.string,
210
+ fromWire: (h) => (h["stage_iteration"] === undefined || h["stage_iteration"] === null ? undefined : new Iteration({ string: String(h["stage_iteration"]) })),
211
+ }, ...dateTrio(), { wire: "edition", to: "edition" }, { wire: "languages", to: "languages" }, { wire: "all_parts", to: "all_parts" });
212
+ /** publisher/copublishers for publisher-carrying leaves. */
213
+ const publisherMappings = () => [
214
+ {
215
+ wire: "publisher",
216
+ to: "publisher",
217
+ toWire: (m) => {
218
+ const pub = m["publisher"];
219
+ if (pub === undefined)
220
+ return undefined;
221
+ if (pub.publisher === "ISO")
222
+ return undefined;
223
+ return pub.publisher;
224
+ },
225
+ fromWire: (h) => {
226
+ if ((h["publisher"] === undefined || h["publisher"] === null) && h["copublishers"] === undefined)
227
+ return undefined;
228
+ const cps = Array.isArray(h["copublishers"]) ? h["copublishers"].map(String) : [];
229
+ return new IsoPublisher({ publisher: h["publisher"] === undefined || h["publisher"] === null ? "ISO" : String(h["publisher"]), copublisher: cps });
230
+ },
231
+ },
232
+ {
233
+ wire: "copublishers",
234
+ to: "publisher",
235
+ toWire: (m) => {
236
+ const pub = m["publisher"];
237
+ const cp = pub?.copublisher;
238
+ return cp === undefined || cp.length === 0 ? undefined : cp;
239
+ },
240
+ // The "publisher" wire key is absent for the ISO default, so this
241
+ // mapping rebuilds the whole publisher (copublishers_from_kv
242
+ // mirrors Builder#parse on the Ruby side).
243
+ fromWire: (h) => {
244
+ if (h["copublishers"] === undefined || h["copublishers"] === null)
245
+ return undefined;
246
+ const cps = Array.isArray(h["copublishers"]) ? h["copublishers"].map(String) : [];
247
+ return new IsoPublisher({ publisher: h["publisher"] === undefined || h["publisher"] === null ? "ISO" : String(h["publisher"]), copublisher: cps });
248
+ },
249
+ },
250
+ ];
251
+ const stageMapping = () => ({
252
+ wire: "stage",
253
+ to: "typedStageState",
254
+ toWire: (m) => {
255
+ const ts = m["typedStageState"];
256
+ if (ts === undefined)
257
+ return undefined;
258
+ if (ts.entry.stageCode === "published")
259
+ return undefined;
260
+ return ts.entry.code;
261
+ },
262
+ fromWire: (h) => {
263
+ const code = h["stage"];
264
+ if (code === undefined || code === null || code === "")
265
+ return undefined;
266
+ const entry = locateStageByCode(String(code));
267
+ if (entry === undefined)
268
+ return undefined;
269
+ return { entry, originalAbbr: entry.abbr[0] };
270
+ },
271
+ });
272
+ /** The ISO Publisher component: "ISO/IEC/IEEE". */
273
+ export class IsoPublisher {
274
+ publisher;
275
+ copublisher;
276
+ constructor(attrs) {
277
+ this.publisher = attrs.publisher === undefined || attrs.publisher === null ? "ISO" : String(attrs.publisher);
278
+ this.copublisher = Array.isArray(attrs.copublisher) ? attrs.copublisher.map(String) : [];
279
+ }
280
+ render() {
281
+ if (this.copublisher === undefined || this.copublisher.length === 0)
282
+ return this.publisher;
283
+ return this.publisher + this.copublisher.map((cp) => `/${cp}`).join("");
284
+ }
285
+ }
286
+ /** Single documents (everything except supplements, TcDocument, Bundled). */
287
+ export class IsoSingleIdentifier extends IsoIdentifier {
288
+ static attributes = extendAttributes(IsoIdentifier, {
289
+ publisher: { type: IsoPublisher },
290
+ copublishers: { type: IsoPublisher, collection: true, initializeEmpty: true },
291
+ });
292
+ constructor(attrs = {}) {
293
+ super(attrs);
294
+ // The gem's default_publisher is nil on the IWA leaf ("IWA 1",
295
+ // not "ISO IWA 1"), so no publisher is materialized there.
296
+ const self = this;
297
+ if (self["publisher"] === undefined && this.typeKey() !== "iwa") {
298
+ self["publisher"] = new IsoPublisher({});
299
+ }
300
+ }
301
+ render() {
302
+ let result = "";
303
+ if (this.typeKey() === "iwa") {
304
+ const stage = this.stageString();
305
+ if (stage !== "")
306
+ result += stage;
307
+ }
308
+ else if (this.publisher !== undefined) {
309
+ result += this.publisher.render();
310
+ const stage = this.stageString();
311
+ if (stage !== "") {
312
+ const isGuide = this.typeKey() === "guide" && !(this instanceof IsoSupplementIdentifier);
313
+ const sep = isGuide || (this.publisher.copublisher?.length ?? 0) > 0 ? " " : "/";
314
+ result += `${sep}${stage}`;
315
+ }
316
+ }
317
+ const num = this.numberPortion(true);
318
+ if (num !== "")
319
+ result += result === "" ? num : ` ${num}`;
320
+ result += this.languagePortion(this.languageSingle());
321
+ if (this.all_parts === true)
322
+ result += " (all parts)";
323
+ return result;
324
+ }
325
+ }
326
+ // IWA identifiers have no implied publisher ("IWA 1", not "ISO IWA
327
+ // 1"), so an explicitly parsed "ISO" still emits on the wire — the
328
+ // leaf's default publisher is nil on the Ruby side. Built lazily:
329
+ // SINGLE_MAPPINGS is declared below.
330
+ let iwaMappings;
331
+ function isoClass(spec) {
332
+ const base = spec.supplement === true ? IsoSupplementIdentifier : spec.bundled === true ? IsoBundledBase : IsoSingleIdentifier;
333
+ class IsoConcrete extends base {
334
+ static polymorphicName = `pubid:iso:${spec.kind}`;
335
+ static typeKey = spec.typeKey;
336
+ static attributes = extendAttributes(base, {});
337
+ static mappings = spec.typeKey === "iwa"
338
+ ? (iwaMappings ??= SINGLE_MAPPINGS.map((m) => {
339
+ if (m.wire !== "publisher")
340
+ return m;
341
+ return {
342
+ wire: "publisher",
343
+ to: "publisher",
344
+ toWire: (mm) => mm["publisher"]?.publisher,
345
+ fromWire: (h) => {
346
+ if ((h["publisher"] === undefined || h["publisher"] === null) && h["copublishers"] === undefined)
347
+ return undefined;
348
+ const cps = Array.isArray(h["copublishers"]) ? h["copublishers"].map(String) : [];
349
+ return new IsoPublisher({ publisher: h["publisher"] === undefined || h["publisher"] === null ? "ISO" : String(h["publisher"]), copublisher: cps });
350
+ },
351
+ };
352
+ }))
353
+ : (spec.supplement === true ? SUPPLEMENT_MAPPINGS : SINGLE_MAPPINGS);
354
+ static urnGenerator = IsoUrnGenerator;
355
+ }
356
+ registerType(IsoConcrete);
357
+ return IsoConcrete;
358
+ }
359
+ class IsoUrnGenerator extends BaseUrnGenerator {
360
+ generate() {
361
+ const id = this.identifier;
362
+ if (id instanceof IsoDirectivesSupplement) {
363
+ if (id.base === undefined) {
364
+ const parts = ["urn", "iso", "doc"];
365
+ if (id.supplement_publisher !== undefined)
366
+ parts.push(id.supplement_publisher.toLowerCase());
367
+ parts.push("sup");
368
+ const d = urnDate(id);
369
+ if (d !== undefined)
370
+ parts.push(d);
371
+ return parts.join(":");
372
+ }
373
+ const parts = id.base.toUrn().split(":");
374
+ const sp = id.supplement_publisher ?? "";
375
+ if (/^JTC\s+(\d+)$/i.test(sp)) {
376
+ parts.push(...sp.toLowerCase().split(/\s+/));
377
+ parts.push("sup");
378
+ }
379
+ else {
380
+ parts.push("sup");
381
+ if (sp !== "")
382
+ parts.push(sp.toLowerCase());
383
+ }
384
+ const d = urnDate(id);
385
+ if (d !== undefined)
386
+ parts.push(d);
387
+ if (id.edition !== undefined && id.edition.number !== undefined)
388
+ parts.push(`ed-${id.edition.number}`);
389
+ return parts.join(":");
390
+ }
391
+ if (id instanceof IsoSupplementIdentifier)
392
+ return this.generateSupplementUrn(id);
393
+ if (id instanceof IsoTcDocument) {
394
+ const parts = ["urn:iso:doc"];
395
+ if (id.publisher !== undefined)
396
+ parts.push(id.publisher.publisher.toLowerCase());
397
+ if (id.tc_number !== undefined)
398
+ parts.push(`tc:${id.tc_number}`);
399
+ if (id.sc_number !== undefined)
400
+ parts.push(`sc-${id.sc_number}`);
401
+ if (id.wg_number !== undefined)
402
+ parts.push(`wg-${id.wg_number}`);
403
+ if (id.number !== undefined)
404
+ parts.push(id.number);
405
+ return parts.join(":");
406
+ }
407
+ if (id instanceof IsoDirectives) {
408
+ const parts = ["urn", "iso", "doc"];
409
+ const pubs = [id.publisher?.publisher ?? "ISO", ...(id.publisher?.copublisher ?? [])].map((p) => p.toLowerCase());
410
+ parts.push(pubs.join("-"));
411
+ if (id.subgroup !== undefined) {
412
+ const subgroupParts = id.subgroup.split(/\s+/);
413
+ if (subgroupParts[0] !== undefined)
414
+ parts.push(subgroupParts[0].toLowerCase());
415
+ if (subgroupParts[1] !== undefined)
416
+ parts.push(subgroupParts[1]);
417
+ }
418
+ parts.push("dir");
419
+ if (id.number !== undefined)
420
+ parts.push(id.number);
421
+ if (id.part !== undefined)
422
+ parts.push(id.part.toLowerCase());
423
+ if (id.date?.year !== undefined)
424
+ parts.push(id.date.year);
425
+ return parts.join(":");
426
+ }
427
+ if (id instanceof IsoBundledIdentifier) {
428
+ const parts = ["urn", ...(id.base_document?.toUrn() ?? "urn:iso:std:iso").split(":").slice(1)];
429
+ for (const supplement of id.supplements) {
430
+ parts.push(...supplement.toUrn().split(":").slice(3));
431
+ }
432
+ return parts.join(":");
433
+ }
434
+ return this.generateBaseUrn(id);
435
+ }
436
+ originator(id) {
437
+ if (id.publisher === undefined)
438
+ return "iso";
439
+ const publishers = [id.publisher.publisher, ...(id.publisher.copublisher ?? [])];
440
+ return publishers.map((p) => p.toLowerCase()).join("-");
441
+ }
442
+ typeComponent(id) {
443
+ const ts = id.typedStageState;
444
+ if (ts === undefined)
445
+ return undefined;
446
+ const typeKey = id.typeKey();
447
+ if (typeKey === "is")
448
+ return undefined;
449
+ const extended = TYPE_CODE_MAP[typeKey];
450
+ if (extended !== undefined)
451
+ return extended;
452
+ if (typeKey === "rec")
453
+ return "r";
454
+ return typeKey;
455
+ }
456
+ stageComponent(id) {
457
+ const ts = id.typedStageState;
458
+ if (ts === undefined)
459
+ return undefined;
460
+ const stageCode = ts.entry.stageCode;
461
+ if (stageCode === "published")
462
+ return undefined;
463
+ const typeKey = id.typeKey();
464
+ const combinedKey = typeKey !== "is" ? `${stageCode}${typeKey}` : stageCode;
465
+ const stageAbbrUrn = TYPED_STAGE_MAP[combinedKey] ?? TYPED_STAGE_MAP[stageCode];
466
+ if (stageAbbrUrn !== undefined) {
467
+ if (id.stage_iteration !== undefined)
468
+ return `${stageAbbrUrn}.${id.stage_iteration.render() ?? ""}`;
469
+ return stageAbbrUrn;
470
+ }
471
+ const harmonized = ts.entry.harmonized;
472
+ if (harmonized === undefined || harmonized.length === 0)
473
+ return undefined;
474
+ const first = harmonized[0];
475
+ if (first.startsWith("60.") && stageCode !== "prf")
476
+ return undefined;
477
+ let stagePart = stageCode === "prf" && id.stage_iteration !== undefined ? "stage-draft" : `stage-${first}`;
478
+ if (id.stage_iteration !== undefined && !(id instanceof IsoSupplementIdentifier)) {
479
+ stagePart += `.v${id.stage_iteration.render() ?? ""}`;
480
+ }
481
+ return stagePart;
482
+ }
483
+ generateBaseUrn(id) {
484
+ const parts = ["urn", "iso", "std", this.originator(id)];
485
+ const typeComp = this.typeComponent(id);
486
+ if (typeComp !== undefined)
487
+ parts.push(typeComp);
488
+ if (id.number !== undefined)
489
+ parts.push(id.number);
490
+ if (id.part !== undefined) {
491
+ let partComp = `-${id.part}`;
492
+ if (id.subpart !== undefined)
493
+ partComp += `-${id.subpart}`;
494
+ parts.push(partComp);
495
+ }
496
+ const stageComp = this.stageComponent(id);
497
+ if (stageComp !== undefined && id.all_parts !== true)
498
+ parts.push(stageComp);
499
+ if (id.edition !== undefined && id.edition.number !== undefined)
500
+ parts.push(`ed-${id.edition.number}`);
501
+ if (id.languages !== undefined && id.languages.length > 0) {
502
+ parts.push(id.languages.map((l) => l.code).join(","));
503
+ }
504
+ if (id.all_parts === true)
505
+ parts.push("ser");
506
+ return parts.join(":");
507
+ }
508
+ generateSupplementUrn(id) {
509
+ const chain = [];
510
+ let current = id;
511
+ while (current instanceof IsoSupplementIdentifier) {
512
+ chain.unshift(current);
513
+ current = current.base;
514
+ }
515
+ const baseId = current;
516
+ const parts = ["urn", "iso", "std"];
517
+ if (baseId !== undefined) {
518
+ parts.push(this.originator(baseId));
519
+ const typeComp = this.typeComponent(baseId);
520
+ if (typeComp !== undefined)
521
+ parts.push(typeComp);
522
+ if (baseId.number !== undefined)
523
+ parts.push(baseId.number);
524
+ if (baseId.part !== undefined) {
525
+ let partComp = `-${baseId.part}`;
526
+ if (baseId.subpart !== undefined)
527
+ partComp += `-${baseId.subpart}`;
528
+ parts.push(partComp);
529
+ }
530
+ const editions = [];
531
+ if (baseId.edition?.number !== undefined)
532
+ editions.push(`ed-${baseId.edition.number}`);
533
+ for (const supp of chain) {
534
+ if (supp.edition?.number !== undefined)
535
+ editions.push(`ed-${supp.edition.number}`);
536
+ }
537
+ parts.push(...editions);
538
+ const baseStageComp = this.stageComponent(baseId);
539
+ if (baseStageComp !== undefined) {
540
+ const supplementStages = chain.map((s) => this.stageComponent(s)).filter((s) => s !== undefined);
541
+ if (supplementStages.length === 0)
542
+ parts.push(baseStageComp);
543
+ else if (baseStageComp.startsWith("stage-10.") && !supplementStages.includes(baseStageComp))
544
+ parts.push(baseStageComp);
545
+ }
546
+ if (baseId.languages !== undefined && baseId.languages.length > 0) {
547
+ parts.push(baseId.languages.map((l) => l.code).join(","));
548
+ }
549
+ }
550
+ for (const supp of chain) {
551
+ const stageComp = this.stageComponent(supp);
552
+ if (stageComp !== undefined)
553
+ parts.push(stageComp);
554
+ parts.push(supp.typeKey() === "suppl" || supp.typeKey() === "add" ? "sup" : supp.typeKey());
555
+ const iter = supp.typeKey() === "suppl" || supp.stage_iteration === undefined ? undefined : supp.stage_iteration.render();
556
+ const d = urnDate(supp);
557
+ if (d !== undefined) {
558
+ parts.push(d);
559
+ if (supp.number !== undefined)
560
+ parts.push(iter !== undefined ? `v${supp.number}.${iter}` : `v${supp.number}`);
561
+ }
562
+ else {
563
+ if (supp.number !== undefined)
564
+ parts.push(supp.number);
565
+ parts.push(iter !== undefined ? `v1.${iter}` : "v1");
566
+ }
567
+ if (supp.languages !== undefined && supp.languages.length > 0) {
568
+ parts.push(supp.languages.map((l) => l.code).join(","));
569
+ }
570
+ }
571
+ if (id.all_parts === true)
572
+ parts.push("ser");
573
+ return parts.join(":");
574
+ }
575
+ }
576
+ const SINGLE_MAPPINGS = keyValue(...ISO_MAPPINGS, ...publisherMappings(), stageMapping());
577
+ /** Supplements carry the publisher of the document they supplement
578
+ * (SupplementIdentifier#publisher delegates to root). */
579
+ const supplementPublisherMappings = () => [
580
+ {
581
+ wire: "publisher",
582
+ to: "publisher",
583
+ toWire: (m) => {
584
+ const root = m.root?.();
585
+ const publisher = m["base"] !== undefined ? root?.publisher : m["publisher"];
586
+ if (publisher === undefined || publisher.publisher === "ISO")
587
+ return undefined;
588
+ return publisher.publisher;
589
+ },
590
+ fromWire: (h) => {
591
+ if ((h["publisher"] === undefined || h["publisher"] === null) && h["copublishers"] === undefined)
592
+ return undefined;
593
+ const cps = Array.isArray(h["copublishers"]) ? h["copublishers"].map(String) : [];
594
+ return new IsoPublisher({ publisher: h["publisher"] === undefined || h["publisher"] === null ? "ISO" : String(h["publisher"]), copublisher: cps });
595
+ },
596
+ },
597
+ {
598
+ wire: "copublishers",
599
+ to: "publisher",
600
+ toWire: (m) => {
601
+ const root = m.root?.();
602
+ const publisher = m["base"] !== undefined ? root?.publisher : m["publisher"];
603
+ const cp = publisher?.copublisher;
604
+ return cp === undefined || cp.length === 0 ? undefined : cp;
605
+ },
606
+ fromWire: (h) => {
607
+ if (h["copublishers"] === undefined || h["copublishers"] === null)
608
+ return undefined;
609
+ const cps = Array.isArray(h["copublishers"]) ? h["copublishers"].map(String) : [];
610
+ return new IsoPublisher({ publisher: h["publisher"] === undefined || h["publisher"] === null ? "ISO" : String(h["publisher"]), copublisher: cps });
611
+ },
612
+ },
613
+ ];
614
+ const SUPPLEMENT_MAPPINGS = keyValue(...ISO_MAPPINGS, ...supplementPublisherMappings(), stageMapping(), { wire: "base", to: "base" });
615
+ export class IsoSupplementIdentifier extends IsoSingleIdentifier {
616
+ static attributes = extendAttributes(IsoSingleIdentifier, {
617
+ base: { type: IsoIdentifier },
618
+ });
619
+ static mappings = SUPPLEMENT_MAPPINGS;
620
+ render() {
621
+ return this.renderSupplement(this.stageFormatLong());
622
+ }
623
+ renderAsSupplementBase(long) {
624
+ return this.renderSupplement(long);
625
+ }
626
+ renderSupplement(long) {
627
+ const base = this.base;
628
+ const baseStr = base === undefined ? "" : base.renderAsSupplementBase(long);
629
+ const ts = this.typedStageState;
630
+ const stage = ts === undefined ? "" : stageAbbr(ts.entry, long, ts.originalAbbr);
631
+ let result = `${baseStr}/${stage}`;
632
+ const num = this.numberPortion(true);
633
+ if (num !== "") {
634
+ if (!num.startsWith(":") && !stage.endsWith("."))
635
+ result += " ";
636
+ result += num;
637
+ }
638
+ result += this.languagePortion(this.languageSingle());
639
+ return result;
640
+ }
641
+ }
642
+ export class IsoBundledBase extends IsoSingleIdentifier {
643
+ }
644
+ // The 18 type-keyed leaves (bundled-identifier is separate).
645
+ const LEAF_SPECS = [
646
+ { kind: "international-standard", typeKey: "is" },
647
+ { kind: "international-standardized-profile", typeKey: "isp" },
648
+ { kind: "international-workshop-agreement", typeKey: "iwa" },
649
+ { kind: "technical-report", typeKey: "tr" },
650
+ { kind: "technical-specification", typeKey: "ts" },
651
+ { kind: "pas", typeKey: "pas" },
652
+ { kind: "guide", typeKey: "guide" },
653
+ { kind: "recommendation", typeKey: "rec" },
654
+ { kind: "amendment", typeKey: "amd", supplement: true },
655
+ { kind: "corrigendum", typeKey: "cor", supplement: true },
656
+ { kind: "supplement", typeKey: "suppl", supplement: true },
657
+ { kind: "addendum", typeKey: "add", supplement: true },
658
+ { kind: "extract", typeKey: "ext", supplement: true },
659
+ { kind: "data", typeKey: "data" },
660
+ { kind: "technology-trends-assessments", typeKey: "tta" },
661
+ ];
662
+ const LEAF_CLASSES = new Map(LEAF_SPECS.map((spec) => [spec.typeKey, isoClass(spec)]));
663
+ export function isoClassForType(typeKey) {
664
+ return LEAF_CLASSES.get(typeKey);
665
+ }
666
+ // --- Directives (+ subgroup) -------------------------------------------------
667
+ export class IsoDirectives extends IsoSingleIdentifier {
668
+ static polymorphicName = "pubid:iso:directives";
669
+ static typeKey = "dir";
670
+ static attributes = extendAttributes(IsoSingleIdentifier, {
671
+ subgroup: { type: "string" },
672
+ });
673
+ static mappings = keyValue(...SINGLE_MAPPINGS, {
674
+ wire: "subgroup",
675
+ to: "subgroup",
676
+ fromWire: (h) => {
677
+ const v = h["subgroup"];
678
+ if (v === undefined || v === null)
679
+ return undefined;
680
+ // The wire is a flat scalar since the gem flattened the
681
+ // { value: X } nesting; keep reading the old shape defensively.
682
+ if (typeof v === "object")
683
+ return String(v["value"] ?? "");
684
+ return String(v);
685
+ },
686
+ });
687
+ static urnGenerator = IsoUrnGenerator;
688
+ render() {
689
+ let head = this.publisher === undefined ? "" : this.publisher.render();
690
+ if (this.subgroup !== undefined)
691
+ head += ` ${this.subgroup}`;
692
+ // DirectivesRenderer pins the SHORT abbreviation regardless of the
693
+ // parsed spelling.
694
+ const abbr = this.typedStageState === undefined ? "" : stageAbbr(this.typedStageState.entry, false);
695
+ if (abbr !== "")
696
+ head += ` ${abbr}`;
697
+ let num = this.number ?? "";
698
+ if (this.part !== undefined)
699
+ num += ` ${this.part}`;
700
+ if (this.subpart !== undefined)
701
+ num += `-${this.subpart}`;
702
+ if (this.stage_iteration !== undefined)
703
+ num += `.${this.stage_iteration.render() ?? ""}`;
704
+ if (this.date !== undefined && this.date.present())
705
+ num += `:${this.date.render()}`;
706
+ if (num === "")
707
+ return head;
708
+ if (num.startsWith(":"))
709
+ return head + num;
710
+ return `${head} ${num}`;
711
+ }
712
+ }
713
+ registerType(IsoDirectives);
714
+ // --- Directives Supplement (+ supplement_publisher) --------------------------
715
+ export class IsoDirectivesSupplement extends IsoSupplementIdentifier {
716
+ static polymorphicName = "pubid:iso:directives-supplement";
717
+ static typeKey = "dir-sup";
718
+ static attributes = extendAttributes(IsoSupplementIdentifier, {
719
+ supplement_publisher: { type: "string" },
720
+ });
721
+ static mappings = keyValue(...ISO_MAPPINGS, stageMapping(), { wire: "base", to: "base" }, { wire: "publisher", to: "supplement_publisher" });
722
+ static urnGenerator = IsoUrnGenerator;
723
+ render() {
724
+ if (this.base !== undefined) {
725
+ let result = this.base.toHuman();
726
+ result += ` ${this.supplement_publisher ?? ""} SUP`;
727
+ if (this.date !== undefined && this.date.present())
728
+ result += `:${this.date.render()}`;
729
+ if (this.edition !== undefined && this.edition.number !== undefined)
730
+ result += ` Edition ${this.edition.number}`;
731
+ return result;
732
+ }
733
+ return `${this.supplement_publisher ?? ""} SUP${this.date !== undefined && this.date.present() ? `:${this.date.render()}` : ""}`;
734
+ }
735
+ }
736
+ registerType(IsoDirectivesSupplement);
737
+ // --- TC documents -------------------------------------------------------------
738
+ export class IsoTcDocument extends IsoIdentifier {
739
+ static polymorphicName = "pubid:iso:tc-document";
740
+ static typeKey = "tc";
741
+ static attributes = extendAttributes(IsoIdentifier, {
742
+ publisher: { type: IsoPublisher },
743
+ tc_type: { type: "string" },
744
+ tc_number: { type: "string" },
745
+ sc_type: { type: "string" },
746
+ sc_number: { type: "string" },
747
+ wg_type: { type: "string" },
748
+ wg_number: { type: "string" },
749
+ });
750
+ static mappings = keyValue({ wire: "tc_type", to: "tc_type" }, { wire: "tc_number", to: "tc_number" }, { wire: "sc_type", to: "sc_type" }, { wire: "sc_number", to: "sc_number" }, { wire: "wg_type", to: "wg_type" }, { wire: "wg_number", to: "wg_number" }, { wire: "number", to: "number" }, ...dateTrio(), { wire: "publisher", to: "publisher" });
751
+ static urnGenerator = IsoUrnGenerator;
752
+ render() {
753
+ let result = this.publisher === undefined ? "" : this.publisher.render();
754
+ if (this.tc_type !== undefined && this.tc_type !== "")
755
+ result += `/${this.tc_type} `;
756
+ if (this.tc_number !== undefined)
757
+ result += this.tc_number;
758
+ if (this.sc_type !== undefined && this.sc_number !== undefined)
759
+ result += `/${this.sc_type} ${this.sc_number}`;
760
+ if (this.wg_type !== undefined && this.wg_number !== undefined)
761
+ result += `/${this.wg_type} ${this.wg_number}`;
762
+ if (this.number !== undefined && this.number !== "")
763
+ result += ` N ${this.number}`;
764
+ if (this.date?.year !== undefined)
765
+ result += `:${this.date.render()}`;
766
+ return result;
767
+ }
768
+ }
769
+ registerType(IsoTcDocument);
770
+ // --- Bundled identifier ---------------------------------------------------------
771
+ export class IsoBundledIdentifier extends IsoIdentifier {
772
+ static polymorphicName = "pubid:iso:bundled-identifier";
773
+ static typeKey = "bundled";
774
+ static attributes = extendAttributes(IsoIdentifier, {
775
+ base_document: { type: IsoIdentifier },
776
+ supplements: { type: IsoIdentifier, collection: true, initializeEmpty: true },
777
+ });
778
+ static mappings = keyValue({ wire: "base", to: "base_document" }, { wire: "supplements", to: "supplements" });
779
+ static urnGenerator = IsoUrnGenerator;
780
+ render() {
781
+ const parts = [this.base_document?.toHuman() ?? ""];
782
+ for (const supplement of this.supplements) {
783
+ parts.push(`+ ${supplement.toHuman()}`);
784
+ }
785
+ return parts.join(" ");
786
+ }
787
+ }
788
+ registerType(IsoBundledIdentifier);
789
+ // ---------------------------------------------------------------------------
790
+ // URN generation (lib/pubid/iso/urn_generator.rb).
791
+ // ---------------------------------------------------------------------------
792
+ const TYPED_STAGE_MAP = {
793
+ wd: "WD", wds: "WDS", cd: "CD", cdv: "CDV", dis: "DIS", fdis: "FDIS",
794
+ pdam: "PDAM", dam: "DAM", fdamd: "FDAM", dcor: "DCOR", fdcor: "FDCOR",
795
+ cdts: "CDTS", dts: "DTS", fdts: "FDTS",
796
+ };
797
+ const TYPE_CODE_MAP = { dir: "dir", "dir-sup": "dir-sup", "iwa-sup": "iwa-sup" };
798
+ function urnDate(id) {
799
+ if (id.date === undefined || !id.date.present() || id.date.undated === true)
800
+ return undefined;
801
+ return id.date.year;
802
+ }