@onlyworlds/sdk 4.69.0 → 4.71.0

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/AGENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # For AI agents using @onlyworlds/sdk
2
2
 
3
- **Current as of**: SDK **4.x** · schema-dist **v0.33.0-dist.49** (canonical 00.33.00).
3
+ **Current as of**: SDK **4.x** · schema-dist **v0.33.0-dist.57** (canonical 00.33.00).
4
4
  This line is asserted by `codegen:check` in CI — if the pin moves and this file is not
5
5
  re-read against it, the check fails rather than letting this document rot quietly.
6
6
 
@@ -94,6 +94,11 @@ against live data). The v1 surface (`OnlyWorldsClient`, the `ElementType` enum)
94
94
  first, UTF-8 name order, 1980 stamps) and holds only `world.json` and the folder's parts.
95
95
  Producers marked `"private": true` in `records/RECORDS.json` are left out whole unless
96
96
  `writeWorldFile(files, topDir, { includePrivateRecords: true })` (since 4.63.0; OW-8).
97
+ Element files marked `hidden: true` travel by default (a copy); a share passes
98
+ `{ includeHidden: false, report: r => r.hiddenLeftOut }` to leave them out whole and count
99
+ them (since 4.70.0; §4.8). Two names are one after OW-18's fold: NFC, then simple case
100
+ folding, both Unicode 15.1's from its own files (`nfc` since 4.71.0, `simpleCaseFold`), never
101
+ the runtime's `normalize`, whose Unicode is its ICU's (Node 22: 16.0).
97
102
  - World calendars (since 4.20.0): `worldCalendars(elements)` finds the elements carrying
98
103
  `atlas_calendar` (Atlas owns the field: read it, never write it); `resolveCalendarLens` picks
99
104
  one; `formatStep(config, step)` names a point on the world's integer time line, `parseDate`
package/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@ earlier history lives in git log only.
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [4.71.0] - 2026-10-24
9
+
10
+ ### Added
11
+
12
+ - **`nfc(text)`**: Normalization Form C as Unicode 15.1 defines it, built from Unicode's own `UnicodeData-15.1.0.txt` and `CompositionExclusions-15.1.0.txt` (schema-dist serial 57, OW Council #656), never the runtime's. It is the NFC half of OW-18's fold, beside `simpleCaseFold`, exported so a tool that compares names the way a world file does gets the same answer. This export is why the release is a minor, not 4.70.1.
13
+
14
+ ### Fixed
15
+
16
+ - **The world file's name check uses Unicode 15.1's NFC, not the runtime's** (folder spec §4.7, OW-18, ruled at serial 57). `readWorldFile` and `writeWorldFile` folded names with `String.prototype.normalize('NFC')`, which follows the runtime's ICU: Node 22's is Unicode 16.0, which composes 20 code points 15.1 leaves unassigned (Todhri, Tulu-Tigalari, Gurung Khema, Kirat Rai), so a name with U+11383 and one with U+11382 U+113C9 were refused as one name where the spec keeps two, and an older runtime could miss what 15.1 added. Both now fold with `nfc`. Where 15.1 and the runtime both assign a code point, nothing changes (Unicode's normalization stability): the set's 93 cases read the same either way. The tables are `src/nfc-tables.generated.ts`, made by `codegen/nfc_tables.mjs` from the vendored files.
17
+
18
+ ### Changed
19
+
20
+ - **Schema repinned to schema-dist `v0.33.0-dist.57`** (commit e21b867; same canonical 00.33.00; no schema file moved, `schema.json` and `presentation.json` unchanged, no generated type changed, `ONLYWORLDS_VERSION` still `'00.33.00'`; generated output moves only its source header and SCHEMA.md's line). Serials 50 to 57: the export fixture's world block is the World whole, with `origin` and `x_names` (50, 51); the review profile's reader rule, a reader that hands a world on leaves proposed elements out unless asked (52, 53); the folder lint takes `hidden` as a folder key (53); the checks profile's list case and reader rules 6 to 8 (54); the spine profile and its fixture (55, 56); the `.owworld` set at 93 zips, eight OW-18 NFC pairs with `UnicodeData-15.1.0.txt` and `CompositionExclusions-15.1.0.txt` beside `CaseFolding-15.1.0.txt` (57). None of the earlier 85 zips moved.
21
+ - Tests: the NFC against the two files for every code point (each composite composed back unless excluded, its mapping to the same NFC, each Hangul syllable from its jamo, each combining class by where ordering puts the mark), against the runtime wherever both assign a code point, and every code point 15.1 leaves unassigned left alone; U+11383 against U+11382 U+113C9 and U+16D68 against U+16D67 U+16D67 accepted as two names. The fixture count is the published 93. Four mutants (the runtime's `normalize` back in the fold, one exclusion dropped from the table, an unstable ordering, no Hangul LV+T), each red on its own line. Checked outside the repo against Unicode's `NormalizationTest-15.1.0.txt`: 19,074 lines, 0 disagreements.
22
+
23
+ ## [4.70.0] - 2026-10-23
24
+
25
+ ### Added
26
+
27
+ - **`writeWorldFile(files, topDir, { includeHidden: false })`** (folder spec §4.8, Skeld, OW Atlas h20 #11469): a world file is a copy, so an element file carrying the hidden mark travels byte for byte by default, as before. A tool making a file to hand to someone else passes `includeHidden: false`, and every `.json` file directly in a type folder of `elements/` or the legacy `spatial/` whose JSON has a top-level `hidden` (anything but absent, `null` or `false`, so `"true"` and `1` count, as the Python package's `is_hidden`) is left out whole. A file there that is not UTF-8 JSON, or not an object, is kept. Nothing else is rewritten: a visible element's link to a hidden one keeps its id. The two defaults differ on purpose: private records out unless asked, hidden kept unless the write is a share.
28
+ - **`report: (r: OwWriteWorldFileReport) => void`**, a `writeWorldFile` option: called once with `{ hiddenLeftOut }` after the archive is made and before it is returned, never on a refusal. The return stays the bytes. An `includeHidden` that is not a boolean, or a `report` that is not a function, is a `TypeError` before anything is written; both keys join the options fence.
29
+
30
+ ### Fixed
31
+
32
+ - **`draught`'s doc comment names `compact`** (4.69.0, keel #585), so the docs' generated reference row carries it.
33
+ - Tests: a hidden element file byte-identical by default and with `includeHidden: true`, the report 0; left out as a share, the report 1, every other file byte-identical; the legacy layout, `.JSON`, and a doubtful mark left out; not JSON, not UTF-8, not an object, a null or nested mark, a deeper file, a non-JSON file and the other parts kept; the same bytes for the same files either way; the report not called on a refusal; the fence. Watched failing with the leave-out turned into a keep (3 tests red), restored. The 85-case `.owworld` set unchanged.
34
+
8
35
  ## [4.69.0] - 2026-10-23
9
36
 
10
37
  ### Added
package/README.md CHANGED
@@ -293,12 +293,23 @@ The reader checks every entry before it inflates anything, and refuses the file
293
293
  | `marker` | a `mimetype` entry with other bytes than `WORLD_FILE_MEDIA_TYPE` (a marker is never required) |
294
294
  | `not_a_world`, `more_than_one` | no `world.json` with an `id`, two worlds, or a second `world.json` inside the world (one under `records/` is data) |
295
295
 
296
+ Two names are one when they match after NFC and then simple case folding, both as Unicode 15.1 defines them, from Unicode's own files built into the package (`nfc`, `simpleCaseFold`), never the runtime's Unicode: every reader, in any browser or Node version, joins the same names.
297
+
296
298
  Files beside the world's folder and archive junk (`__MACOSX`, `.DS_Store`) are ignored. The world's OnlyWorlds link and key (`world.json`'s `api`) never travel: both functions remove them. A tool's own folder (`.atlas/` and the like) comes back like any other file; pass `skip: path => …` to leave files out.
297
299
 
298
300
  The writer gives the same bytes for the same files: the `mimetype` marker first, then every entry in the UTF-8 order of its name, stamped 1980-01-01 00:00. It writes `world.json`, `elements/`, `spatial/`, `media/` and `records/`, and leaves any other file out. A tool's dot-folder you hand it travels too, which makes the file a private copy rather than a portable `.owworld`.
299
301
 
300
302
  `records/` travels byte for byte, except a producer's directory that `records/RECORDS.json` marks `"private": true`: that one is left out whole, and `RECORDS.json` itself travels unchanged, so the reader can see a producer was left out. Pass `writeWorldFile(files, topDir, { includePrivateRecords: true })` to carry private records too. A `RECORDS.json` that is not a JSON array of objects is refused with a `TypeError` unless you pass that option, since the writer cannot tell which records are private.
301
303
 
304
+ An element file marked hidden (`"hidden": true` at the top of its JSON, spec §4.8) travels byte for byte by default: a world file is a copy, also of your own world. When the file is a share, made to hand to someone else, pass `includeHidden: false`: every hidden file under `elements/<type>/` (or the old `spatial/<type>/`) is left out whole, and `report` tells you how many. Nothing else changes: a visible element's link to a hidden one keeps its id. A file there that is not JSON is kept.
305
+
306
+ ```typescript
307
+ let left = 0;
308
+ const share = writeWorldFile(files, topDir, { includeHidden: false, report: r => { left = r.hiddenLeftOut; } });
309
+ ```
310
+
311
+ The two defaults differ on purpose: private records stay out unless you ask, hidden elements stay in unless the write is a share.
312
+
302
313
  ## World calendars
303
314
 
304
315
  A world's time is an integer line (`time_range_current` is a point on it, and so is an Event's `start_date`). A calendar names its points: months, days, eras. Atlas keeps a calendar on an element (a Construct by convention) in its `atlas_calendar` field, and the SDK reads it with Atlas's own calendar code (since 4.20.0). Atlas owns that field and is its only writer; read it, never write it.
package/SCHEMA.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # OnlyWorlds Schema Reference
2
2
 
3
- **Source**: https://github.com/OnlyWorlds/schema-dist @ **v0.33.0-dist.49** — canonical schema **00.33.00**, published 2026-10-22.
3
+ **Source**: https://github.com/OnlyWorlds/schema-dist @ **v0.33.0-dist.57** — canonical schema **00.33.00**, published 2026-10-24.
4
4
 
5
5
  GENERATED from the canonical schema YAML — do not hand-edit (regenerate: `python codegen/generate_types.py`).
6
6
  Written for both humans and AI agents reading this package locally.
package/dist/index.d.ts CHANGED
@@ -3644,7 +3644,9 @@ declare class OwV2Client {
3644
3644
  * Character they can see; a player seat or a guest for its own Character only (another id is
3645
3645
  * 404). `asOf` is a filter on the elements' own dates, not time travel. A `cut` that is not
3646
3646
  * empty means the serving is partial (`cut.proposed` also counts proposed elements left out because
3647
- * the component was not named). Served `Cache-Control: private, no-store`.
3647
+ * the component was not named). `compact: true` leaves out every empty section and an empty `cut`,
3648
+ * the frame and every null kept, answered as `OwDraughtCompact` (keel #585). Served
3649
+ * `Cache-Control: private, no-store`.
3648
3650
  */
3649
3651
  draught(characterId: string, policy?: OwDraughtPolicy & {
3650
3652
  compact?: false;
@@ -4534,7 +4536,8 @@ declare function typeWord(world: object | null | undefined, type: string, opts?:
4534
4536
  * - `method` (OW-21): encrypted, or a method other than stored or deflate.
4535
4537
  * - `name` (OW-22): a Windows device name, a trailing dot or space, one of
4536
4538
  * `<>:"|?*` or a control character, a non-ASCII name without the UTF-8 flag.
4537
- * - `duplicate` (OW-17), `collision` (OW-18: NFC, then simple case folding).
4539
+ * - `duplicate` (OW-17), `collision` (OW-18: NFC, then simple case folding,
4540
+ * both Unicode 15.1's from its own files, never the runtime's).
4538
4541
  * - `too_many`, `too_big` (OW-14, OW-15): past the budget by count or declared
4539
4542
  * size, or an entry that inflates past the size it declares.
4540
4543
  * - `marker` (OW-6): a root `mimetype` entry with other bytes than the media
@@ -4550,7 +4553,8 @@ declare function typeWord(world: object | null | undefined, type: string, opts?:
4550
4553
  * 1980-01-01 00:00, in the UTF-8 byte order of its name, JSON deflated and
4551
4554
  * everything else stored. `records/` travels whole and byte-exact, except the
4552
4555
  * producers `records/RECORDS.json` marks private, left out whole unless the
4553
- * caller asks (OW-8, §4.5 rule 11).
4556
+ * caller asks (OW-8, §4.5 rule 11). Element files marked hidden travel too,
4557
+ * unless the caller says the file is a share (`includeHidden: false`, §4.8).
4554
4558
  *
4555
4559
  * A tool's own `.<tool>/` folder is the tool's (spec §4): the reader returns
4556
4560
  * it like any file (a caller leaves files out with `skip`), and the writer
@@ -4605,6 +4609,21 @@ interface OwWriteWorldFileOptions {
4605
4609
  * rule 11, OW-8). Left out or false, their directories are left out whole.
4606
4610
  */
4607
4611
  includePrivateRecords?: boolean;
4612
+ /**
4613
+ * Carry element files marked hidden (spec §4.8). Left out or true, they
4614
+ * travel byte for byte: a world file is a copy. Pass false when the file is
4615
+ * a share, made to hand to someone else: then every element file whose JSON
4616
+ * carries the hidden mark is left out whole, and `report` counts them. The
4617
+ * default is the opposite of `includePrivateRecords`'s on purpose.
4618
+ */
4619
+ includeHidden?: boolean;
4620
+ /** Called once with what the write left out, after the archive is made and before it is returned; never on a refusal. */
4621
+ report?: (report: OwWriteWorldFileReport) => void;
4622
+ }
4623
+ /** What `writeWorldFile` left out, handed to its `report` option. */
4624
+ interface OwWriteWorldFileReport {
4625
+ /** Element files left out for the hidden mark (`includeHidden: false`); 0 otherwise. */
4626
+ hiddenLeftOut: number;
4608
4627
  }
4609
4628
  /**
4610
4629
  * Write a world file under one top-level folder `topDir`: the `mimetype`
@@ -4624,8 +4643,19 @@ interface OwWriteWorldFileOptions {
4624
4643
  * to carry them; then the manifest is not read and every record travels. No
4625
4644
  * manifest, nothing is private.
4626
4645
  *
4646
+ * Element files marked hidden (spec §4.8) travel byte for byte by default: a
4647
+ * world file is a copy, also of a person's own world. A share is the offering
4648
+ * tool's question: pass `{ includeHidden: false }` for a file made to hand to
4649
+ * someone else, and every element file under `elements/<type>/` or
4650
+ * `spatial/<type>/` whose JSON carries a top-level `hidden` (anything but
4651
+ * absent, `null` or `false`) is left out whole. A file there that is not
4652
+ * JSON is kept. Nothing else is rewritten: a visible element's link to a
4653
+ * hidden one keeps its id, which then names no file. Pass
4654
+ * `report: r => …` to learn `r.hiddenLeftOut`, the count left out.
4655
+ *
4627
4656
  * Throws a `TypeError`, having written nothing, for an unknown option, an
4628
- * `includePrivateRecords` that is not a boolean, and (unless private records
4657
+ * `includePrivateRecords` or `includeHidden` that is not a boolean, a
4658
+ * `report` that is not a function, and (unless private records
4629
4659
  * are asked for) a `RECORDS.json` that is not a JSON array of objects or that
4630
4660
  * marks an entry private without a producer name. Refuses (`OwWorldFileError`)
4631
4661
  * an unsafe path or `topDir`, a duplicate path, a name some disk cannot hold,
@@ -4634,6 +4664,15 @@ interface OwWriteWorldFileOptions {
4634
4664
  */
4635
4665
  declare function writeWorldFile(files: OwWorldFileEntry[], topDir: string, opts?: OwWriteWorldFileOptions): Uint8Array;
4636
4666
 
4667
+ /**
4668
+ * Normalization Form C as Unicode 15.1's files define it (UAX #15:
4669
+ * canonical decomposition, canonical ordering, canonical composition), the
4670
+ * NFC OW-18 folds names with before simple case folding. A code point 15.1
4671
+ * leaves unassigned is left as it is, whatever the runtime's Unicode knows.
4672
+ * Lone surrogates pass through.
4673
+ */
4674
+ declare function nfc(text: string): string;
4675
+
4637
4676
  /**
4638
4677
  * World lookup: find the elements a plain-language question is about, in a
4639
4678
  * world held in memory, with no model and no network. Ported from Assembly's
@@ -5444,4 +5483,4 @@ declare class TokenResource {
5444
5483
  getEncryptionInfo(): Promise<EncryptionInfo>;
5445
5484
  }
5446
5485
 
5447
- export { AGENT_DOORS, ASK_LIMITS, type AccessKeyResponse, CALENDAR_FIELD, CALENDAR_SUPERTYPE, type CalendarConfig, type CalendarEra, type CalendarIntercalary, type CalendarMonths, type CalendarWeek, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementType, type EncryptionInfo, type EraDomain, FAMILY_COLORS, FAMILY_ORDER, FIELD_ACRONYMS, FIELD_SCHEMA, FILE_EXTENSIONS, type FieldInfo, type FieldType, GameTier, type ListParams, ONLYWORLDS_VERSION, type OwAccountWorld, type OwAgentJoined, type OwAllowance, OwApiError, type OwAskAnswer, type OwAskContext, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwCalendarElement, type OwChange, type OwChangeDelete, type OwChangeUpsert, type OwChangesPage, type OwClientConfig, type OwCreateAccountWorldInput, type OwCreatedAccountWorld, type OwCreatedWorldLink, type OwDeleteReason, type OwDraught, type OwDraughtCompact, type OwDraughtComponent, type OwDraughtItem, type OwDraughtPolicy, type OwElement, type OwElementBase, type OwErrorBody, type OwFileAddedBy, type OwFileDownload, type OwFileKind, type OwFileRow, type OwFileTicket, type OwFrontDoor, type OwHiddenRow, type OwJoinPreview, type OwJoined, type OwJoinedMembership, type OwKeyKind, type OwLinkEdit, type OwLookupElement, type OwLookupHit, type OwLookupLink, type OwLookupOptions, type OwLookupReason, type OwMe, type OwMediaTicket, type OwMember, type OwMemberRole, type OwMintedKey, type OwNamesMap, OwNetworkError, type OwPage, type OwPhotoOptions, type OwPhotoPlan, type OwPlayerJoined, OwPreconditionFailedError, type OwPreparedPhoto, type OwProposal, type OwProposalAccepted, type OwProposalConflict, type OwProposalList, type OwProposalQuery, type OwProposalState, type OwProposeInput, type OwProposed, OwProposedError, type OwProposedNewElement, type OwReadWorldFile, type OwReadWorldFileOptions, type OwRemovalTicket, type OwRemovedImage, type OwRenderOptions, type OwResyncReason, type OwReviewInput, type OwReviewed, type OwSeat, type OwSeatCreated, type OwSignInBegin, type OwSignInBegun, type OwSignInComplete, OwSignInError, type OwSignInReason, type OwSignInResult, type OwSignInStorage, type OwSignedIn, type OwSortAddToRow, type OwSortAnswer, type OwSortAskRow, type OwSortLinkRow, type OwSortMakeRow, type OwSortNote, type OwSortRef, type OwSortRow, OwStaleProposalError, type OwUploadedFile, type OwUploadedImage, OwV2Client, type OwWordPair, type OwWorldFileEntry, OwWorldFileError, type OwWorldFileReason, type OwWorldFileRow, type OwWorldFiles, type OwWorldIndex, type OwWorldLink, type OwWorldMeta, type OwWorldOrigin, type OwWorldProducer, type OwWorldProposalList, type OwWorldProposalQuery, type OwWorldProposalRow, type OwWorldPublicPage, type OwWorldSource, type OwWriteDoor, type OwWriteWorldFileOptions, PHOTO_MAX_BYTES, PHOTO_TYPES, PUBLIC_FIELDS, type ParseError, type ParseOptions, type ParseResult, ROOM_PAIRS, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type StepBreakdown, type TokenConsumeParams, type TokenConsumeResponse, TokenResource, type TokenStatus, type TokenTransport, WORLD_FILE_MAX_BYTES, WORLD_FILE_MAX_ENTRIES, WORLD_FILE_MEDIA_TYPE, type WorldCalendar, absYearForEraYear, absoluteYear, approxYearLength, base64url, breakdownStep, buildAskContext, buildWorldIndex, detectKeyKind, displayYear, elementColor, eraForStep, errorFromResponse, familyOf, fieldLabel, fileKindOf, floorDiv, floorMod, formatDuration, formatMidLabel, formatStep, formatYearLabel, getElementIcon, getElementLabel, isAgentDoor, isDemoKey, isKnownOf, isLeapYear, isParseError, isRoomElement, kindCanWrite, lookupWorld, monthStartSteps, parseDate, parseErrorEnvelope, pinExpectation, pkceChallenge, planPhoto, preparePhoto, readCalendarConfig, readCalendarValue, readWorldFile, renderElement, resolveCalendarLens, resolveEraDomains, simpleCaseFold, typeWord, validateCalendarConfig, weekdayForStep, worldCalendars, writeWorldFile, yearLength, yearStartStep };
5486
+ export { AGENT_DOORS, ASK_LIMITS, type AccessKeyResponse, CALENDAR_FIELD, CALENDAR_SUPERTYPE, type CalendarConfig, type CalendarEra, type CalendarIntercalary, type CalendarMonths, type CalendarWeek, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementType, type EncryptionInfo, type EraDomain, FAMILY_COLORS, FAMILY_ORDER, FIELD_ACRONYMS, FIELD_SCHEMA, FILE_EXTENSIONS, type FieldInfo, type FieldType, GameTier, type ListParams, ONLYWORLDS_VERSION, type OwAccountWorld, type OwAgentJoined, type OwAllowance, OwApiError, type OwAskAnswer, type OwAskContext, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwCalendarElement, type OwChange, type OwChangeDelete, type OwChangeUpsert, type OwChangesPage, type OwClientConfig, type OwCreateAccountWorldInput, type OwCreatedAccountWorld, type OwCreatedWorldLink, type OwDeleteReason, type OwDraught, type OwDraughtCompact, type OwDraughtComponent, type OwDraughtItem, type OwDraughtPolicy, type OwElement, type OwElementBase, type OwErrorBody, type OwFileAddedBy, type OwFileDownload, type OwFileKind, type OwFileRow, type OwFileTicket, type OwFrontDoor, type OwHiddenRow, type OwJoinPreview, type OwJoined, type OwJoinedMembership, type OwKeyKind, type OwLinkEdit, type OwLookupElement, type OwLookupHit, type OwLookupLink, type OwLookupOptions, type OwLookupReason, type OwMe, type OwMediaTicket, type OwMember, type OwMemberRole, type OwMintedKey, type OwNamesMap, OwNetworkError, type OwPage, type OwPhotoOptions, type OwPhotoPlan, type OwPlayerJoined, OwPreconditionFailedError, type OwPreparedPhoto, type OwProposal, type OwProposalAccepted, type OwProposalConflict, type OwProposalList, type OwProposalQuery, type OwProposalState, type OwProposeInput, type OwProposed, OwProposedError, type OwProposedNewElement, type OwReadWorldFile, type OwReadWorldFileOptions, type OwRemovalTicket, type OwRemovedImage, type OwRenderOptions, type OwResyncReason, type OwReviewInput, type OwReviewed, type OwSeat, type OwSeatCreated, type OwSignInBegin, type OwSignInBegun, type OwSignInComplete, OwSignInError, type OwSignInReason, type OwSignInResult, type OwSignInStorage, type OwSignedIn, type OwSortAddToRow, type OwSortAnswer, type OwSortAskRow, type OwSortLinkRow, type OwSortMakeRow, type OwSortNote, type OwSortRef, type OwSortRow, OwStaleProposalError, type OwUploadedFile, type OwUploadedImage, OwV2Client, type OwWordPair, type OwWorldFileEntry, OwWorldFileError, type OwWorldFileReason, type OwWorldFileRow, type OwWorldFiles, type OwWorldIndex, type OwWorldLink, type OwWorldMeta, type OwWorldOrigin, type OwWorldProducer, type OwWorldProposalList, type OwWorldProposalQuery, type OwWorldProposalRow, type OwWorldPublicPage, type OwWorldSource, type OwWriteDoor, type OwWriteWorldFileOptions, type OwWriteWorldFileReport, PHOTO_MAX_BYTES, PHOTO_TYPES, PUBLIC_FIELDS, type ParseError, type ParseOptions, type ParseResult, ROOM_PAIRS, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type StepBreakdown, type TokenConsumeParams, type TokenConsumeResponse, TokenResource, type TokenStatus, type TokenTransport, WORLD_FILE_MAX_BYTES, WORLD_FILE_MAX_ENTRIES, WORLD_FILE_MEDIA_TYPE, type WorldCalendar, absYearForEraYear, absoluteYear, approxYearLength, base64url, breakdownStep, buildAskContext, buildWorldIndex, detectKeyKind, displayYear, elementColor, eraForStep, errorFromResponse, familyOf, fieldLabel, fileKindOf, floorDiv, floorMod, formatDuration, formatMidLabel, formatStep, formatYearLabel, getElementIcon, getElementLabel, isAgentDoor, isDemoKey, isKnownOf, isLeapYear, isParseError, isRoomElement, kindCanWrite, lookupWorld, monthStartSteps, nfc, parseDate, parseErrorEnvelope, pinExpectation, pkceChallenge, planPhoto, preparePhoto, readCalendarConfig, readCalendarValue, readWorldFile, renderElement, resolveCalendarLens, resolveEraDomains, simpleCaseFold, typeWord, validateCalendarConfig, weekdayForStep, worldCalendars, writeWorldFile, yearLength, yearStartStep };
package/dist/index.js CHANGED
@@ -2957,6 +2957,118 @@ function getElementLabel(elementType) {
2957
2957
 
2958
2958
  // src/world-file.ts
2959
2959
  import { Inflate, inflateSync, zipSync } from "fflate";
2960
+
2961
+ // src/nfc-tables.generated.ts
2962
+ var NFC_CLASS_RUNS = "lc.l.6e,lx..6g,ly.4.64,m2..6g,m3..60,m4.5.64,m9.2.5m,mb.4.64,mf.2.5m,mh.b.64,ms.5.1,mx.4.64,n1.8.6e,n9..6o,na..6e,nb.3.64,ne.3.6e,nh.2.64,nk.3.6e,nn.4.64,nr..6e,ns..6g,nt.2.64,nv..6e,nw..6h,nx.2.6i,nz..6h,o0.2.6i,o2..6h,o3.d.6e,w3.5.6e,13l..64,13m.4.6e,13q..64,13r.3.6e,13u..66,13v..64,13w.6.6e,142.6.64,148.2.6e,14a..64,14b.2.6e,14d..66,14e..6c,14f..6e,14g..a,14h..b,14i..c,14j..d,14k..e,14l..f,14m..g,14n..h,14o..i,14p.2.j,14r..k,14s..l,14t..m,14v..n,14x..o,14y..p,150..6e,151..64,153..i,174.8.6e,17c..u,17d..v,17e..w,18r..r,18s..s,18t..t,18u..u,18v..v,18w..w,18x..x,18y..y,18z.2.6e,191.2.64,193.5.6e,198..64,199.2.6e,19b..64,19s..z,1cm.7.6e,1cv.4.6e,1cz..64,1d0..6e,1d3.2.6e,1d6..64,1d7.2.6e,1d9..64,1e9..10,1f4..6e,1f5..64,1f6.2.6e,1f8..64,1f9.2.6e,1fb.3.64,1fe..6e,1ff.2.64,1fh..6e,1fi..64,1fj.3.6e,1fm..64,1fn..6e,1fo..64,1fp..6e,1fq..64,1fr..6e,1fs..64,1ft.2.6e,1kb.7.6e,1ki..64,1kj..6e,1kt..64,1li.4.6e,1ln.9.6e,1lx.3.6e,1m1.5.6e,1nd.3.64,1p4..6e,1p5.3.64,1p8.4.6e,1qi.5.6e,1qn.5.64,1qs.e.6e,1r7..64,1r8.2.6e,1ra..64,1rb.2.6e,1rd..64,1re.3.6e,1rh.3.64,1rk..r,1rl..s,1rm..t,1rn.3.6e,1rq..64,1rr.2.6e,1rt.2.64,1rv.5.6e,1to..7,1u5..9,1u9..6e,1ua..64,1ub.2.6e,1x8..7,1xp..9,1z2..6e,20s..7,219..9,24c..7,24t..9,27w..7,28d..9,2bx..9,2f0..7,2fh..9,2fp..2c,2fq..2j,2ik..7,2j1..9,2m3.2.9,2ml..9,2q2..9,2t4.2.2v,2t6..9,2tk.4.2z,2wo.2.3a,2wq..9,2x4.4.3e,2zc.2.64,305..64,307..64,309..60,31t..3l,31u..3m,31w..3o,322.4.3m,328..3m,32a.2.6e,32c..9,32e.2.6e,346..64,37b..7,37d.2.9,39p..64,3tp.3.6e,4k4.2.9,4l0..9,4pe..9,4pp..6e,4vd..6c,4zd..66,4ze..6e,4zf..64,55j..6e,55k..64,57k..9,585.8.6e,58f..64,59s.5.6e,59x.6.64,5a3.2.6e,5a5..64,5a7.2.64,5a9.2.6e,5ab.2.64,5ad.5.6e,5ai..64,5aj.4.6e,5dg..7,5dw..9,5ez..6e,5f0..64,5f1.7.6e,5gq.2.9,5ie..7,5iq.2.9,5kn..7,5ow.3.6e,5p0..1,5p1.5.64,5p6.2.6e,5p8.4.64,5pc..6e,5pe.7.1,5pp..64,5pw..6e,5q0.2.6e,5vk.2.6e,5vm..64,5vn.7.6e,5vu..64,5vv.2.6e,5vx..6i,5vy..5y,5vz..64,5w0..5m,5w1.11.6e,5x2..6g,5x3.2.6c,5x5..64,5x6..62,5x7..6e,5x8..6h,5x9..64,5xa..6e,5xb..64,6hc.2.6e,6he.2.1,6hg.4.6e,6hk.3.1,6hn.2.6e,6ht..6e,6hx.2.1,6hz..6e,6i0..64,6i1..6e,6i2.2.1,6i4.4.64,6i8..6e,8vj.3.6e,8zj..9,928.w.6e,9ii..62,9ij..6c,9ik..6g,9il..66,9im.2.68,9ll.2.8,wvj..6e,wvo.a.6e,wwu.2.6e,wz4.2.6e,x6u..9,x7w..9,xc4..9,xcw.i.6e,xez.3.64,xg3..9,xir..7,xj4..9,xps..6e,xpu.2.6e,xpw..64,xpz.2.6e,xq6.2.6e,xq9..6e,xrq..9,xyl..9,1dlq..q,1e74.7.6e,1e7b.7.64,1e7i.2.6e,1eyl..64,1f4w..64,1f92.5.6e,1gjx..64,1gjz..6e,1gl4..6e,1gl5..1,1gl6..64,1glb..9,1gpx..6e,1gpy..64,1h5w.4.6e,1hgr.2.6e,1hj1.3.64,1hl2.2.64,1hl4.3.6e,1hl7..64,1hl8..6e,1hl9.4.64,1hmq..6e,1hmr..64,1hms..6e,1hmt..64,1hs6..9,1htc..9,1htr..9,1hvd..9,1hve..7,1hxc.3.6e,1hyr.2.9,1i0j..7,1i2o..9,1i2y..7,1i5x..9,1i5y..7,1iax..7,1iay..9,1id7.2.7,1idp..9,1iee.7.6e,1ieo.5.6e,1iki..9,1ikm..7,1ila..6e,1io2..9,1io3..7,1iv3..9,1iv4..7,1iyn..9,1j1y..9,1j1z..7,1j57..9,1jcp..9,1jcq..7,1jjx.2.9,1jk3..7,1jog..9,1jqs..9,1jrb..9,1jtl..9,1k5b..9,1kci..7,1kck.2.9,1kev..9,1kqp.2.9,1zow.5.1,1zqo.7.6e,20og.2.6,2ftq..1,2jxh.2.60,2jxj.3.1,2jxp..6a,2jxq.5.60,2jy3.8.64,2jyd.5.6e,2jyi.2.64,2jze.4.6e,2k3m.3.6e,2mtc.7.6e,2mtk.h.6e,2mu3.7.6e,2mub.2.6e,2mue.5.6e,2mxb..6e,2n1s.7.6e,2nce..6e,2ne4.4.6e,2nsc.2.6g,2nse..64,2nsf..6e,2ok0.7.64,2on8.6.6e,2one..7";
2963
+ var NFC_DECOMP = "5c.1t.lc,1.1t.ld,1.1t.le,1.1t.lf,1.1t.lk,1.1t.lm,2.1v.mf,1.1x.lc,1.1x.ld,1.1x.le,1.1x.lk,1.21.lc,1.21.ld,1.21.le,1.21.lk,2.26.lf,1.27.lc,1.27.ld,1.27.le,1.27.lf,1.27.lk,3.2d.lc,1.2d.ld,1.2d.le,1.2d.lk,1.2h.ld,3.2p.lc,1.2p.ld,1.2p.le,1.2p.lf,1.2p.lk,1.2p.lm,2.2r.mf,1.2t.lc,1.2t.ld,1.2t.le,1.2t.lk,1.2x.lc,1.2x.ld,1.2x.le,1.2x.lk,2.32.lf,1.33.lc,1.33.ld,1.33.le,1.33.lf,1.33.lk,3.39.lc,1.39.ld,1.39.le,1.39.lk,1.3d.ld,2.3d.lk,1.1t.lg,1.2p.lg,1.1t.li,1.2p.li,1.1t.mg,1.2p.mg,1.1v.ld,1.2r.ld,1.1v.le,1.2r.le,1.1v.lj,1.2r.lj,1.1v.lo,1.2r.lo,1.1w.lo,1.2s.lo,3.1x.lg,1.2t.lg,1.1x.li,1.2t.li,1.1x.lj,1.2t.lj,1.1x.mg,1.2t.mg,1.1x.lo,1.2t.lo,1.1z.le,1.2v.le,1.1z.li,1.2v.li,1.1z.lj,1.2v.lj,1.1z.mf,1.2v.mf,1.20.le,1.2w.le,3.21.lf,1.2x.lf,1.21.lg,1.2x.lg,1.21.li,1.2x.li,1.21.mg,1.2x.mg,1.21.lj,4.22.le,1.2y.le,1.23.mf,1.2z.mf,2.24.ld,1.30.ld,1.24.mf,1.30.mf,1.24.lo,1.30.lo,5.26.ld,1.32.ld,1.26.mf,1.32.mf,1.26.lo,1.32.lo,4.27.lg,1.33.lg,1.27.li,1.33.li,1.27.ln,1.33.ln,3.2a.ld,1.36.ld,1.2a.mf,1.36.mf,1.2a.lo,1.36.lo,1.2b.ld,1.37.ld,1.2b.le,1.37.le,1.2b.mf,1.37.mf,1.2b.lo,1.37.lo,1.2c.mf,1.38.mf,1.2c.lo,1.38.lo,3.2d.lf,1.39.lf,1.2d.lg,1.39.lg,1.2d.li,1.39.li,1.2d.lm,1.39.lm,1.2d.ln,1.39.ln,1.2d.mg,1.39.mg,1.2f.le,1.3b.le,1.2h.le,1.3d.le,1.2h.lk,1.2i.ld,1.3e.ld,1.2i.lj,1.3e.lj,1.2i.lo,1.3e.lo,y.27.m3,1.33.m3,e.2d.m3,1.39.m3,t.1t.lo,1.2p.lo,1.21.lo,1.2x.lo,1.27.lo,1.33.lo,1.2d.lo,1.39.lo,1.64.lg,1.70.lg,1.64.ld,1.70.ld,1.64.lo,1.70.lo,1.64.lc,1.70.lc,2.5g.lg,1.6c.lg,1.fa.lg,1.fb.lg,1.5i.lg,1.6e.lg,3.1z.lo,1.2v.lo,1.23.lo,1.2z.lo,1.27.mg,1.33.mg,1.dm.lg,1.dn.lg,1.c7.lo,1.ia.lo,1.2y.lo,4.1z.ld,1.2v.ld,3.26.lc,1.32.lc,1.5h.ld,1.6d.ld,1.5i.ld,1.6e.ld,1.60.ld,1.6w.ld,1.1t.lr,1.2p.lr,1.1t.lt,1.2p.lt,1.1x.lr,1.2t.lr,1.1x.lt,1.2t.lt,1.21.lr,1.2x.lr,1.21.lt,1.2x.lt,1.27.lr,1.33.lr,1.27.lt,1.33.lt,1.2a.lr,1.36.lr,1.2a.lt,1.36.lt,1.2d.lr,1.39.lr,1.2d.lt,1.39.lt,1.2b.me,1.37.me,1.2c.me,1.38.me,3.20.lo,1.2w.lo,7.1t.lj,1.2p.lj,1.1x.mf,1.2t.mf,1.5y.lg,1.6u.lg,1.5x.lg,1.6t.lg,1.27.lj,1.33.lj,1.fi.lg,1.fj.lg,1.2h.lg,1.3d.lg,7h.lc,1.ld,2.lv,1.lk.ld,1c.jd,a.1n,7.4o.ld,1.pd.ld,1.53,1.ph.ld,1.pj.ld,1.pl.ld,2.pr.ld,2.px.ld,1.q1.ld,1.qy.ld,q.pl.lk,1.px.lk,1.q9.ld,1.qd.ld,1.qf.ld,1.qh.ld,1.qz.ld,q.qh.lk,1.qt.lk,1.qn.ld,1.qt.ld,1.qx.ld,5.r6.ld,1.r6.lk,18.t1.lc,1.t1.lk,2.sz.ld,4.sm.lk,5.t6.ld,1.t4.lc,1.tf.li,b.t4.li,w.u0.li,n.tx.lc,1.tx.lk,2.tv.ld,4.uu.lk,5.u2.ld,1.u0.lc,1.ub.li,o.vo.lr,1.vp.lr,22.t2.li,1.ty.li,e.sw.li,1.ts.li,1.sw.lk,1.ts.lk,3.t1.li,1.tx.li,3.yg.lk,1.yh.lk,1.t2.lk,1.ty.lk,1.t3.lk,1.tz.lk,3.t4.lg,1.u0.lg,1.t4.lk,1.u0.lk,1.ta.lk,1.u6.lk,3.yw.lk,1.yx.lk,1.tp.lk,1.ul.lk,1.tf.lg,1.ub.lg,1.tf.lk,1.ub.lk,1.tf.ln,1.ub.ln,1.tj.lk,1.uf.lk,3.tn.lk,1.uj.lk,89.17r.18z,1.17r.190,1.18o.190,1.17r.191,1.18q.190,4a.1cl.190,2.1c1.190,h.1ci.190,gm.1t4.1to,8.1tc.1to,3.1tf.1to,10.1sl.1to,1.1sm.1to,1.1sn.1to,1.1ss.1to,1.1sx.1to,1.1sy.1to,1.1t7.1to,1.1tb.1to,30.1xj.1xa,1.1xj.1xz,g.1wh.1x8,1.1wi.1x8,2.1wv.1x8,2c.20i.20s,3.20o.20s,z.1zq.20s,1.1zr.20s,1.1zw.20s,3.20b.20s,6i.287.28m,3.287.27y,1.287.28n,g.275.27w,1.276.27w,1j.2aa.2c7,1i.2bq.2bi,1.2br.2bi,1.2bq.2c7,3g.2fa.2fq,3c.2in.2j9,7.2iu.2j9,1.2iu.2ja,2.2iu.2iq,1.2iy.2j9,3j.2me.2m6,1.2mf.2m6,1.2me.2mv,3y.2qh.2q2,2.2qh.2q7,1.2qk.2q2,1.2qh.2qn,9x.30i.33r,a.30s.33r,5.30x.33r,5.312.33r,5.317.33r,d.30g.33p,a.31t.31u,2.31t.31w,1.33m.328,2.33n.328,9.31t.328,i.32q.33r,a.330.33r,5.335.33r,5.33a.33r,5.33f.33r,d.32o.33p,31.36t.372,25c.5c5.5dh,2.5c7.5dh,2.5c9.5dh,2.5cb.5dh,2.5cd.5dh,4.5ch.5dh,15.5dm.5dh,2.5do.5dh,3.5dq.5dh,1.5dr.5dh,2.5du.5dh,jh.1t.md,1.2p.md,1.1u.lj,1.2q.lj,1.1u.mb,1.2q.mb,1.1u.mp,1.2q.mp,1.5j.ld,1.6f.ld,1.1w.lj,1.2s.lj,1.1w.mb,1.2s.mb,1.1w.mp,1.2s.mp,1.1w.mf,1.2s.mf,1.1w.ml,1.2s.ml,1.7m.lc,1.7n.lc,1.7m.ld,1.7n.ld,1.1x.ml,1.2t.ml,1.1x.mo,1.2t.mo,1.fc.li,1.fd.li,1.1y.lj,1.2u.lj,1.1z.lg,1.2v.lg,1.20.lj,1.2w.lj,1.20.mb,1.2w.mb,1.20.lk,1.2w.lk,1.20.mf,1.2w.mf,1.20.mm,1.2w.mm,1.21.mo,1.2x.mo,1.5r.ld,1.6n.ld,1.23.ld,1.2z.ld,1.23.mb,1.2z.mb,1.23.mp,1.2z.mp,1.24.mb,1.30.mb,1.5yu.lg,1.5yv.lg,1.24.mp,1.30.mp,1.24.ml,1.30.ml,1.25.ld,1.31.ld,1.25.lj,1.31.lj,1.25.mb,1.31.mb,1.26.lj,1.32.lj,1.26.mb,1.32.mb,1.26.mp,1.32.mp,1.26.ml,1.32.ml,1.5x.ld,1.6t.ld,1.5x.lk,1.6t.lk,1.98.lc,1.99.lc,1.98.ld,1.99.ld,1.28.ld,1.34.ld,1.28.lj,1.34.lj,1.2a.lj,1.36.lj,1.2a.mb,1.36.mb,1.5zu.lg,1.5zv.lg,1.2a.mp,1.36.mp,1.2b.lj,1.37.lj,1.2b.mb,1.37.mb,1.9m.lj,1.9n.lj,1.9s.lj,1.9t.lj,1.602.lj,1.603.lj,1.2c.lj,1.38.lj,1.2c.mb,1.38.mb,1.2c.mp,1.38.mp,1.2c.ml,1.38.ml,1.2d.mc,1.39.mc,1.2d.mo,1.39.mo,1.2d.ml,1.39.ml,1.a0.ld,1.a1.ld,1.a2.lk,1.a3.lk,1.2e.lf,1.3a.lf,1.2e.mb,1.3a.mb,1.2f.lc,1.3b.lc,1.2f.ld,1.3b.ld,1.2f.lk,1.3b.lk,1.2f.lj,1.3b.lj,1.2f.mb,1.3b.mb,1.2g.lj,1.3c.lj,1.2g.lk,1.3c.lk,1.2h.lj,1.3d.lj,1.2i.le,1.3e.le,1.2i.mb,1.3e.mb,1.2i.mp,1.3e.mp,1.2w.mp,1.38.lk,1.3b.lm,1.3d.lm,2.an.lj,5.1t.mb,1.2p.mb,1.1t.ll,1.2p.ll,1.5e.ld,1.6a.ld,1.5e.lc,1.6a.lc,1.5e.ll,1.6a.ll,1.5e.lf,1.6a.lf,1.61s.le,1.61t.le,1.76.ld,1.77.ld,1.76.lc,1.77.lc,1.76.ll,1.77.ll,1.76.lf,1.77.lf,1.61s.li,1.61t.li,1.1x.mb,1.2t.mb,1.1x.ll,1.2t.ll,1.1x.lf,1.2t.lf,1.5m.ld,1.6i.ld,1.5m.lc,1.6i.lc,1.5m.ll,1.6i.ll,1.5m.lf,1.6i.lf,1.62g.le,1.62h.le,1.21.ll,1.2x.ll,1.21.mb,1.2x.mb,1.27.mb,1.33.mb,1.27.ll,1.33.ll,1.5w.ld,1.6s.ld,1.5w.lc,1.6s.lc,1.5w.ll,1.6s.ll,1.5w.lf,1.6s.lf,1.630.le,1.631.le,1.bk.ld,1.bl.ld,1.bk.lc,1.bl.lc,1.bk.ll,1.bl.ll,1.bk.lf,1.bl.lf,1.bk.mb,1.bl.mb,1.2d.mb,1.39.mb,1.2d.ll,1.39.ll,1.bz.ld,1.c0.ld,1.bz.lc,1.c0.lc,1.bz.ll,1.c0.ll,1.bz.lf,1.c0.lf,1.bz.mb,1.c0.mb,1.2h.lc,1.3d.lc,1.2h.mb,1.3d.mb,1.2h.ll,1.3d.ll,1.2h.lf,1.3d.lf,7.q9.lv,1.q9.lw,1.64g.lc,1.64h.lc,1.64g.ld,1.64h.ld,1.64g.n6,1.64h.n6,1.pd.lv,1.pd.lw,1.64o.lc,1.64p.lc,1.64o.ld,1.64p.ld,1.64o.n6,1.64p.n6,1.qd.lv,1.qd.lw,1.64w.lc,1.64x.lc,1.64w.ld,1.64x.ld,3.ph.lv,1.ph.lw,1.654.lc,1.655.lc,1.654.ld,1.655.ld,3.qf.lv,1.qf.lw,1.65c.lc,1.65d.lc,1.65c.ld,1.65d.ld,1.65c.n6,1.65d.n6,1.pj.lv,1.pj.lw,1.65k.lc,1.65l.lc,1.65k.ld,1.65l.ld,1.65k.n6,1.65l.n6,1.qh.lv,1.qh.lw,1.65s.lc,1.65t.lc,1.65s.ld,1.65t.ld,1.65s.n6,1.65t.n6,1.pl.lv,1.pl.lw,1.660.lc,1.661.lc,1.660.ld,1.661.ld,1.660.n6,1.661.n6,1.qn.lv,1.qn.lw,1.668.lc,1.669.lc,1.668.ld,1.669.ld,3.pr.lv,1.pr.lw,1.66g.lc,1.66h.lc,1.66g.ld,1.66h.ld,3.qt.lv,1.qt.lw,1.66o.lc,1.66p.lc,1.66o.ld,1.66p.ld,1.66o.n6,1.66p.n6,2.px.lw,2.66x.lc,2.66x.ld,2.66x.n6,1.qx.lv,1.qx.lw,1.674.lc,1.675.lc,1.674.ld,1.675.ld,1.674.n6,1.675.n6,1.q1.lv,1.q1.lw,1.67c.lc,1.67d.lc,1.67c.ld,1.67d.ld,1.67c.n6,1.67d.n6,1.q9.lc,1.q4,1.qd.lc,1.q5,1.qf.lc,1.q6,1.qh.lc,1.q7,1.qn.lc,1.r0,1.qt.lc,1.r1,1.qx.lc,1.r2,3.64g.n9,1.64h.n9,1.64i.n9,1.64j.n9,1.64k.n9,1.64l.n9,1.64m.n9,1.64n.n9,1.64o.n9,1.64p.n9,1.64q.n9,1.64r.n9,1.64s.n9,1.64t.n9,1.64u.n9,1.64v.n9,1.65c.n9,1.65d.n9,1.65e.n9,1.65f.n9,1.65g.n9,1.65h.n9,1.65i.n9,1.65j.n9,1.65k.n9,1.65l.n9,1.65m.n9,1.65n.n9,1.65o.n9,1.65p.n9,1.65q.n9,1.65r.n9,1.674.n9,1.675.n9,1.676.n9,1.677.n9,1.678.n9,1.679.n9,1.67a.n9,1.67b.n9,1.67c.n9,1.67d.n9,1.67e.n9,1.67f.n9,1.67g.n9,1.67h.n9,1.67i.n9,1.67j.n9,1.q9.li,1.q9.lg,1.67k.n9,1.q9.n9,1.q4.n9,2.q9.n6,1.69i.n9,1.pd.li,1.pd.lg,1.pd.lc,1.p2,1.pd.n9,2.qh,3.4o.n6,1.67o.n9,1.qf.n9,1.q6.n9,2.qf.n6,1.69y.n9,1.ph.lc,1.p4,1.pj.lc,1.p5,1.pj.n9,1.69r.lc,1.69r.ld,1.69r.n6,1.qh.li,1.qh.lg,1.qy.lc,1.pc,3.qh.n6,1.qy.n6,1.pl.li,1.pl.lg,1.pl.lc,1.p6,2.6bi.lc,1.6bi.ld,1.6bi.n6,1.qt.li,1.qt.lg,1.qz.lc,1.q8,1.qp.lv,1.qp.lw,1.qt.n6,1.qz.n6,1.px.li,1.px.lg,1.px.lc,1.pa,1.pt.lw,1.4o.lc,1.p1,1.2o,3.67w.n9,1.qx.n9,1.r2.n9,2.qx.n6,1.6ba.n9,1.pr.lc,1.p8,1.q1.lc,1.pb,1.q1.n9,1.50,3.6bm,1.6bn,85.q1,4.23,1.5h,33.6mo.mw,1.6mq.mw,j.6ms.mw,v.6og.mw,1.6ok.mw,1.6oi.mw,1h.6pv.mw,5.6q0.mw,3.6q3.mw,o.6qr.mw,2.6qt.mw,r.6rg.mw,3.6rn.mw,3.6rp.mw,2.6rs.mw,n.1p.mw,2.6sh.mw,b.6rx.mw,1.1o.mw,1.1q.mw,1.6sk.mw,1.6sl.mw,3.6sy.mw,1.6sz.mw,3.6t2.mw,1.6t3.mw,7.6t6.mw,1.6t7.mw,3.6te.mw,1.6tf.mw,3.6ti.mw,1.6tj.mw,z.6ua.mw,1.6ug.mw,1.6uh.mw,1.6uj.mw,1d.6t8.mw,1.6t9.mw,1.6tt.mw,1.6tu.mw,7.6uq.mw,1.6ur.mw,1.6us.mw,1.6ut.mw,1o.9hk,1.9hl,1iq.8gt.mw,12o.9jf.9ll,2.9jh.9ll,2.9jj.9ll,2.9jl.9ll,2.9jn.9ll,2.9jp.9ll,2.9jr.9ll,2.9jt.9ll,2.9jv.9ll,2.9jx.9ll,2.9jz.9ll,2.9k1.9ll,3.9k4.9ll,2.9k6.9ll,2.9k8.9ll,7.9kf.9ll,1.9kf.9lm,2.9ki.9ll,1.9ki.9lm,2.9kl.9ll,1.9kl.9lm,2.9ko.9ll,1.9ko.9lm,2.9kr.9ll,1.9kr.9lm,n.9ja.9ll,a.9lp.9ll,e.9m3.9ll,2.9m5.9ll,2.9m7.9ll,2.9m9.9ll,2.9mb.9ll,2.9md.9ll,2.9mf.9ll,2.9mh.9ll,2.9mj.9ll,2.9ml.9ll,2.9mn.9ll,2.9mp.9ll,3.9ms.9ll,2.9mu.9ll,2.9mw.9ll,7.9n3.9ll,1.9n3.9lm,2.9n6.9ll,1.9n6.9lm,2.9n9.9ll,1.9n9.9lm,2.9nc.9ll,1.9nc.9lm,2.9nf.9ll,1.9nf.9lm,n.9ly.9ll,3.9nz.9ll,1.9o0.9ll,1.9o1.9ll,1.9o2.9ll,4.9od.9ll,13ia.rpk,1.kc4,1.s7e,1.rt4,1.lw1,1.fg2,1.gkl,1.vj0,1.vj0,1.hn5,1.ssx,1.gw7,1.hmw,1.jcm,1.ne1,1.p6t,1.qin,1.qt6,1.r20,1.sjz,1.kxu,1.ljv,1.mah,1.mvy,1.q4d,1.sq2,1.uep,1.fia,1.ghh,1.l50,1.mjf,1.qi5,1.v8e,1.ifk,1.m3v,1.qfh,1.r50,1.jih,1.pnc,1.qvz,1.iq2,1.kd3,1.lm2,1.mpo,1.slq,1.fpi,1.g53,1.gda,1.jwk,1.l3n,1.mj4,1.nhj,1.pa9,1.qh2,1.qjg,1.s1b,1.tv6,1.upb,1.v7e,1.nt8,1.nzz,1.otc,1.q15,1.t1g,1.vb3,1.rfa,1.hjz,1.iro,1.okg,1.pdq,1.mle,1.nuy,1.rsy,1.ttj,1.hjs,1.i8y,1.kyb,1.lp6,1.lxr,1.oq7,1.oxj,1.tor,1.gcy,1.pe3,1.g64,1.g5o,1.o4c,1.ou6,1.q29,1.tpx,1.rk0,1.jin,1.kxu,1.rge,1.fg9,1.i5j,1.iz6,1.mtj,1.n74,1.gev,1.nwb,1.fr3,1.iw9,1.ff1,1.lho,1.k1k,1.opu,1.gjn,1.hge,1.ni9,1.q4p,1.re2,1.la2,1.sds,1.lfs,1.jjy,1.put,1.jog,1.n6t,1.fji,1.g2x,1.g5l,1.kn5,1.oo7,1.prj,1.rf6,1.ssv,1.gdx,1.gn6,1.ho3,1.ir0,1.k3p,1.m4e,1.nxm,1.tkd,1.ui2,1.vbr,1.vda,1.gbf,1.kau,1.l87,1.sbm,1.ino,1.j9s,1.jcw,1.jve,1.lyb,1.mdl,1.n0p,1.o22,1.ovo,1.pdb,1.s9y,1.q9a,1.sgz,1.t3e,1.g7r,1.gbn,1.gql,1.ma0,1.r0i,1.re2,1.iq1,1.iyd,1.jnf,1.l9q,1.oji,1.mt1,1.fl0,1.h6h,1.i5j,1.iii,1.izg,1.muq,1.mzt,1.p7e,1.pc6,1.svo,1.tti,1.tvs,1.u1k,1.fpn,1.o1a,1.ss4,1.trs,1.j4x,1.fie,1.fyy,1.i5q,1.i7z,1.k2h,1.kxu,1.mha,1.ncy,1.q9o,1.sjg,1.vil,1.k94,1.tny,1.gax,1.kfv,1.kj7,1.lkx,1.luk,1.mx5,1.n6h,1.nsb,1.opc,1.u3i,1.g31,1.je6,1.tq0,1.fu3,1.ie1,1.lpm,1.sa2,1.ivf,1.j7o,1.kk7,1.mtj,1.tqe,1.g89,1.glr,1.i91,1.k5v,1.kem,1.ko8,1.lid,1.mx2,1.naa,1.p6h,1.r0v,1.r1d,1.sss,1.tsy,1.gfz,1.lve,1.gm5,1.mhc,1.n14,1.qgq,1.tr7,1.uvr,1.vbz,1.kgn,1.lor,1.pns,1.o97,1.obk,1.olu,1.mo0,1.m8p,1.riw,1.fk0,1.px2,1.g8q,1.g7b,1.ip2,1.jir,1.onq,1.i2t,1.ljy,1.kac,1.saj,1.qx8,1.tot,1.r63,1.iqb,1.g1s,1.gxs,3.hga,2.k8k,3.g66,1.mqy,1.ngq,1.ny4,1.nz2,1.nz9,1.o0f,1.tw6,1.on2,1.p8d,2.qhe,2.rg8,3.shk,1.sn1,4.u7j,1.u7w,1.u94,1.v5g,1.sm6,1.trr,1.fqm,1.fzb,1.g25,1.gcp,1.gdg,1.ggh,1.gwt,1.gzq,1.h2g,1.hfk,1.hig,1.i90,1.i9a,1.j2s,1.j8o,1.j9q,1.jci,1.k0f,1.k4i,1.k9d,1.kn9,1.lmf,1.lqy,1.lya,1.mem,1.mjv,1.mxu,1.ntd,1.ny6,1.nyh,1.nyg,1.nyo,1.nyu,1.nz1,1.o0d,1.o0e,1.o5c,1.o75,1.og0,1.ovo,1.ow9,1.oxt,1.p6a,1.pad,1.pnx,1.prt,1.prt,1.q53,1.r2o,1.r6e,1.rgh,1.ri1,1.rtf,1.ruw,1.sdy,1.shk,1.tsz,1.u0v,1.u2j,1.j1x,1.36cu,1.pp4,3.ffq,1.g51,1.g2w,1.fpc,1.g1x,1.g3k,1.gcn,1.ge2,1.gwt,1.gut,1.gwp,1.gyq,1.hga,1.hir,1.hms,1.hn8,1.huq,1.i08,1.iqa,1.iqh,1.iuh,1.iwd,1.j4o,1.j7y,1.j60,1.j9q,1.j8g,1.jci,1.jec,1.jpg,1.jrw,1.jte,1.k0m,1.k8k,1.kd3,1.kd7,1.keu,1.l89,1.la2,1.lkx,1.lwb,1.lvv,1.lya,1.m5a,1.mem,1.nmv,1.mk5,1.mnj,1.mqy,1.n01,1.n46,1.n5n,1.nbx,1.nbz,1.ngq,1.nh7,1.nhw,1.nka,1.nk0,1.nv0,1.o8h,1.og0,1.ol7,1.orf,1.ovo,1.p4u,1.pad,1.pxu,1.q27,1.qrd,1.r41,1.r5y,1.r6e,1.ren,1.rg8,1.rez,1.rgh,1.rge,1.rfx,1.ri1,1.rka,1.ruw,1.sag,1.sj6,1.srd,1.sxi,1.tq4,1.tsz,1.tw6,1.tzv,1.u0v,1.u17,1.u2j,1.umq,1.vj0,1.313e,1.3138,1.33dh,1.brx,1.cns,1.cop,1.39e1,1.3bgw,1.3i6r,1.vgj,1.vim,1w.15l.14k,2.16a.14n,b.161.14x,1.161.14y,1.1dmx.14x,1.1dmx.14y,1.15c.14n,1.15c.14o,1.15c.14s,1.15d.14s,1.15e.14s,1.15f.14s,1.15g.14s,1.15h.14s,1.15i.14s,2.15k.14s,1.15l.14s,1.15m.14s,1.15n.14s,1.15o.14s,2.15q.14s,2.15s.14s,1.15t.14s,2.15v.14s,1.15w.14s,2.15y.14s,1.15z.14s,1.160.14s,1.161.14s,1.162.14s,1.15h.14p,1.15d.14v,1.15n.14v,1.15w.14v,47g.1huh.1hve,2.1huj.1hve,f.1hut.1hve,3n.1hyp.1hyf,1.1hyq.1hyf,f0.1idj.1ida,1.1idj.1idz,a7.1int.1inu,1.1int.1ink,2.1int.1inx,70.1iuw.1iun,1.1iux.1iun,ot.1jjp.1jjk,10di.2jx3.2jxh,1.2jx4.2jxh,1.2jxb.2jxq,1.2jxb.2jxr,1.2jxb.2jxs,1.2jxb.2jxt,1.2jxb.2jxu,2f.2jzt.2jxh,1.2jzu.2jxh,1.2jzv.2jxq,1.2jzw.2jxq,1.2jzv.2jxr,1.2jzw.2jxr,1m4g.fgd,1.fg8,1.fgh,1.2tcy,1.fog,1.fqm,1.fqz,1.fsy,1.fwa,1.fx5,1.fzb,1.fyn,1.ae6,1.2ud6,1.g25,1.g2c,1.g2s,1.g3b,1.2u58,1.aex,1.g2v,1.g3x,1.2u6j,1.g47,1.g4k,1.fkc,1.g4s,1.g51,1.3ly7,1.g6t,1.g77,1.afz,1.g8r,1.g92,1.gaa,1.gaf,1.ahh,1.gcn,1.gcp,1.gdg,1.ge2,1.ged,1.gee,1.gev,1.gg9,1.ggh,1.ggq,1.ghf,1.ghp,1.ghr,1.ghr,1.ghr,1.2v58,1.m7k,1.gju,1.gkf,1.2vdv,1.gkr,1.gkx,1.gli,1.gpq,1.gmw,1.gnc,1.go8,1.gpu,1.gs6,1.gsw,1.gur,1.gv7,1.gw4,1.gw4,1.gwp,1.gx7,1.gxf,1.gxu,1.h7a,1.gzq,1.h7b,1.h1t,1.h2s,1.g7b,1.hke,1.hce,1.hdg,1.he5,1.haj,1.hf6,1.hf5,1.hik,1.2x9g,1.hki,1.hkn,1.hl2,1.hlm,1.hlu,1.hnm,1.2xm0,1.2xnu,1.hrg,1.hsr,1.ht3,1.hqw,1.huu,1.aum,1.av0,1.hzc,1.i0u,1.i0u,1.2y88,1.i4j,1.i54,1.i5j,1.i5v,1.2yhk,1.i67,1.i6e,1.itv,1.i76,1.ayp,1.i8w,1.i9a,1.ibk,1.ia5,1.2z1g,1.if7,1.2z1i,1.ige,1.igb,1.igs,1.ijl,1.ijm,1.b3j,1.ikd,1.ilk,1.im5,1.ind,1.b4y,1.2zr7,1.b5o,1.ipc,1.ipf,1.ipi,1.iq2,1.3pg2,1.iri,1.3035,1.3035,1.poh,1.isi,1.isi,1.b7r,1.335k,1.3cgq,1.iua,1.iuj,1.b8j,1.ivu,1.ix9,1.ixj,1.iyh,1.j29,1.bay,1.ba4,1.j2s,1.30t0,1.j47,1.j7s,1.j7w,1.j7y,1.j7w,1.j96,1.j9q,1.jaq,1.jac,1.jan,1.jby,1.jci,1.jcm,1.jdc,1.jdn,1.jfh,1.jht,1.jis,1.jm8,1.31n0,1.jlp,1.jjw,1.jmw,1.jnn,1.jqc,1.31td,1.js2,1.jph,1.jop,1.bhq,1.ju1,1.jum,1.jvh,1.juf,1.bjg,1.k0f,1.k18,1.32mi,1.k4j,1.kc8,1.k7d,1.bo9,1.k9d,1.bns,1.bms,1.g42,1.g45,1.kcg,1.k9o,1.pf1,1.deh,1.kd3,1.kd7,1.kdd,1.kf2,1.ker,1.33cz,1.bpl,1.kje,1.kg5,1.klu,1.kn9,1.33hp,1.kni,1.kkf,1.kr8,1.brx,1.ksi,1.kv7,1.kx6,1.l2g,1.33xf,1.l3v,1.bvc,1.l5t,1.34br,1.l78,1.bwu,1.l82,1.l9b,1.la2,1.la3,1.34p9,1.2yvf,1.34sa,1.le6,1.354s,1.lhb,1.lhp,1.lev,1.ljq,1.lku,1.lmf,1.lkx,1.lm1,1.lmg,1.lmt,1.357i,1.lkk,1.lrj,1.lta,1.c37,1.lvv,1.lvr,1.35jl,1.lq1,1.m0e,1.35ni,1.35ou,1.m2u,1.m61,1.m5a,1.m57,1.c5y,1.m6i,1.m7x,1.m7r,1.m99,1.2u5h,1.mdh,1.368z,1.mfw,1.36i3,1.mjs,1.mk5,1.mkw,1.36yw,1.mm8,1.mmt,1.3779,1.37dg,1.mt6,1.mtn,1.cdo,1.mud,1.ce0,1.ce0,1.myv,1.mzg,1.n01,1.n0l,1.n2i,1.cgr,1.n50,1.386u,1.n5q,1.389e,1.n74,1.2zrz,1.nbk,1.38v5,1.38vs,1.38zo,1.cn0,1.cnc,1.nhw,1.394j,1.394i,1.395l,1.396b,1.nj2,1.nj3,1.nj3,1.nka,1.cop,1.nm3,1.cp2,1.cra,1.39r1,1.nri,1.nt8,1.nv0,1.ctf,1.3a5i,1.nyu,1.3a8q,1.3a9x,1.o0f,1.o2z,1.cvj,1.o5c,1.o5m,1.o5r,1.3at8,1.3b1j,1.3b1j,1.oa6,1.d1e,1.3b8r,1.og6,1.og9,1.d2f,1.3beo,1.onm,1.d5s,1.oo8,1.oo3,1.oow,1.3c06,1.orn,1.d8h,1.ouf,1.ow2,1.oxx,1.d9w,1.3ciw,1.3cjr,1.dax,1.3cnt,1.p6i,1.3cqm,1.p79,1.pa2,1.pad,1.3d22,1.3d43,1.pcw,1.3d7s,1.pdc,1.33a7,1.ded,1.pf6,1.phf,1.dfv,1.pj2,1.hx1,1.3dlz,1.3dmd,1.33bn,1.33bw,1.poh,1.pok,1.sda,1.dij,1.psh,1.psb,1.pst,1.gc3,1.ptd,1.ptf,1.ptp,1.puu,1.3ebg,1.put,1.pwd,1.pyb,1.q0d,1.pwj,1.q0t,1.q1z,1.q53,1.pxv,1.q16,1.q18,1.q1o,1.3eie,1.3eqz,1.3emt,1.dnv,1.q9d,1.q9f,1.qae,1.3g0a,1.qck,1.3f3g,1.dp9,1.dpd,1.3f75,1.3ff6,1.dpn,1.qj4,1.qjg,1.qjr,1.qjt,1.qll,1.qko,1.qoe,1.qn6,1.qrd,1.qp4,1.qqz,1.qrq,1.dsn,1.qu9,1.qv5,1.dtl,1.qxs,1.qxv,1.3giv,1.r13,1.r1a,1.dv9,1.r22,1.aez,1.3gz2,1.3h46,1.dz2,1.dzb,1.rds,1.rfx,1.rka,1.rpx,1.3hrc,1.rsb,1.rsx,1.rvf,1.rxz,1.3i9b,1.2upw,1.s0b,1.rzw,1.s1c,1.2uvy,1.s7o,1.sag,1.3jki,1.3jl9,1.sk4,1.smp,1.snl,1.3ju6,1.snv,1.svs,1.t07,1.t08,1.sxo,1.t89,1.t91,1.3ksa,1.tjf,1.ej9,1.tkn,1.3l2v,1.eli,1.ts3,1.iia,1.tur,1.3ltx,1.3lzu,1.epa,1.epi,1.u00,1.3mdm,1.er6,1.3mhi,1.u17,1.u17,1.u21,1.3mpi,1.u76,1.eur,1.u95,1.ucn,1.ude,1.uf2,1.ez2,1.3nsg,1.umq,1.uv4,1.v0d,1.f66,1.f71,1.v3b,1.3owe,1.f7c,1.3oxx,1.3p5a,1.3p8x,1.vcr,1.f9y,1.veh,1.vem,1.vet,1.vf3,1.vfa,1.vgb,1.3pxc";
2964
+ var NFC_EXCLUDED = "1ug,1uh,1ui,1uj,1uk,1ul,1um,1un,1y4,1y5,1y7,20j,20m,21l,21m,21n,21q,28s,28t,30j,30t,30y,313,318,31l,31y,320,32r,331,336,33b,33g,33t,1dlp,1dlr,1dm2,1dm3,1dm4,1dm5,1dm6,1dm7,1dm8,1dm9,1dma,1dmb,1dmc,1dmd,1dme,1dmg,1dmh,1dmi,1dmj,1dmk,1dmm,1dmo,1dmp,1dmr,1dms,1dmu,1dmv,1dmw,1dmx,1dmy,1dmz,1dn0,1dn1,1dn2,8gs,2jxa,2jxb,2jxc,2jxd,2jxe,2jxf,2jxg,2jzv,2jzw,2jzx,2jzy,2jzz,2k00";
2965
+
2966
+ // src/nfc.ts
2967
+ var S_BASE = 44032;
2968
+ var L_BASE = 4352;
2969
+ var V_BASE = 4449;
2970
+ var T_BASE = 4519;
2971
+ var L_COUNT = 19;
2972
+ var V_COUNT = 21;
2973
+ var T_COUNT = 28;
2974
+ var N_COUNT = V_COUNT * T_COUNT;
2975
+ var S_COUNT = L_COUNT * N_COUNT;
2976
+ var tables = null;
2977
+ function load() {
2978
+ const ccc = /* @__PURE__ */ new Map();
2979
+ for (const run of NFC_CLASS_RUNS.split(",")) {
2980
+ const [start, count, cls] = run.split(".");
2981
+ const s = parseInt(start, 36);
2982
+ const n = count ? parseInt(count, 36) : 1;
2983
+ const c = parseInt(cls, 36);
2984
+ for (let k = 0; k < n; k++) ccc.set(s + k, c);
2985
+ }
2986
+ const raw = /* @__PURE__ */ new Map();
2987
+ let cp = 0;
2988
+ for (const entry of NFC_DECOMP.split(",")) {
2989
+ const [gap, ...to] = entry.split(".");
2990
+ cp += parseInt(gap, 36);
2991
+ raw.set(cp, to.map((t) => parseInt(t, 36)));
2992
+ }
2993
+ const excluded = new Set(NFC_EXCLUDED.split(",").map((t) => parseInt(t, 36)));
2994
+ const compose = /* @__PURE__ */ new Map();
2995
+ for (const [c, to] of raw) {
2996
+ if (to.length !== 2 || excluded.has(c) || ccc.has(c) || ccc.has(to[0])) continue;
2997
+ compose.set(to[0] * 1114112 + to[1], c);
2998
+ }
2999
+ const decomp = /* @__PURE__ */ new Map();
3000
+ const full = (c) => {
3001
+ const done = decomp.get(c);
3002
+ if (done) return done;
3003
+ const to = raw.get(c);
3004
+ if (!to) return [c];
3005
+ const out = to.flatMap(full);
3006
+ decomp.set(c, out);
3007
+ return out;
3008
+ };
3009
+ for (const c of raw.keys()) full(c);
3010
+ return { ccc, decomp, compose };
3011
+ }
3012
+ function nfc(text) {
3013
+ let plain = true;
3014
+ for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) >= 192) {
3015
+ plain = false;
3016
+ break;
3017
+ }
3018
+ if (plain) return text;
3019
+ const t = tables ?? (tables = load());
3020
+ const cls = (c) => t.ccc.get(c) ?? 0;
3021
+ const cps = [];
3022
+ for (const ch of text) {
3023
+ const c = ch.codePointAt(0);
3024
+ const s = c - S_BASE;
3025
+ if (s >= 0 && s < S_COUNT) {
3026
+ cps.push(L_BASE + Math.floor(s / N_COUNT), V_BASE + Math.floor(s % N_COUNT / T_COUNT));
3027
+ if (s % T_COUNT) cps.push(T_BASE + s % T_COUNT);
3028
+ } else {
3029
+ const d = t.decomp.get(c);
3030
+ if (d) cps.push(...d);
3031
+ else cps.push(c);
3032
+ }
3033
+ }
3034
+ for (let i = 1; i < cps.length; i++) {
3035
+ const c = cps[i];
3036
+ const k = cls(c);
3037
+ if (!k) continue;
3038
+ let j = i;
3039
+ while (j > 0 && cls(cps[j - 1]) > k) {
3040
+ cps[j] = cps[j - 1];
3041
+ j--;
3042
+ }
3043
+ cps[j] = c;
3044
+ }
3045
+ const out = [];
3046
+ let starter = -1;
3047
+ let last = 0;
3048
+ for (const c of cps) {
3049
+ const k = cls(c);
3050
+ if (starter >= 0 && (out.length - 1 === starter || last !== 0 && last < k)) {
3051
+ const a = out[starter];
3052
+ let composed;
3053
+ const l = a - L_BASE, v = c - V_BASE, s = a - S_BASE, tt = c - T_BASE;
3054
+ if (l >= 0 && l < L_COUNT && v >= 0 && v < V_COUNT) composed = S_BASE + (l * V_COUNT + v) * T_COUNT;
3055
+ else if (s >= 0 && s < S_COUNT && s % T_COUNT === 0 && tt > 0 && tt < T_COUNT) composed = a + tt;
3056
+ else composed = t.compose.get(a * 1114112 + c);
3057
+ if (composed !== void 0) {
3058
+ out[starter] = composed;
3059
+ continue;
3060
+ }
3061
+ }
3062
+ if (k === 0) starter = out.length;
3063
+ last = k;
3064
+ out.push(c);
3065
+ }
3066
+ let r = "";
3067
+ for (const c of out) r += String.fromCodePoint(c);
3068
+ return r;
3069
+ }
3070
+
3071
+ // src/world-file.ts
2960
3072
  var WORLD_FILE = "world.json";
2961
3073
  var MARKER_NAME = "mimetype";
2962
3074
  var WORLD_FILE_MEDIA_TYPE = "application/vnd.onlyworlds.world+zip";
@@ -3035,7 +3147,7 @@ function simpleCaseFold(text) {
3035
3147
  return out;
3036
3148
  }
3037
3149
  function foldName(name) {
3038
- return simpleCaseFold(name.normalize("NFC"));
3150
+ return simpleCaseFold(nfc(name));
3039
3151
  }
3040
3152
  function byCodePoint(a, b) {
3041
3153
  const n = Math.min(a.length, b.length);
@@ -3350,17 +3462,36 @@ function carried(path) {
3350
3462
  return !segs.some((s) => s.startsWith(".")) && !path.endsWith(".meta");
3351
3463
  }
3352
3464
  var STAMP = new Date(1980, 0, 1, 0, 0, 0);
3353
- var WRITE_OPTION_KEYS = ["includePrivateRecords"];
3465
+ var WRITE_OPTION_KEYS = ["includePrivateRecords", "includeHidden", "report"];
3354
3466
  var RECORDS_MANIFEST = "records/RECORDS.json";
3355
- function asksPrivate(opts) {
3356
- if (opts === void 0 || opts === null) return false;
3467
+ function writeOptions(opts) {
3468
+ if (opts === void 0 || opts === null) return { includePrivate: false, includeHidden: true };
3357
3469
  if (typeof opts !== "object") throw new TypeError(`writeWorldFile: options must be an object, such as { includePrivateRecords: true }. Nothing was written.`);
3358
3470
  refuseUnknownOptions("writeWorldFile", opts, WRITE_OPTION_KEYS, "Nothing was written.");
3359
- const asked = opts.includePrivateRecords;
3360
- if (asked !== void 0 && typeof asked !== "boolean") {
3361
- throw new TypeError(`writeWorldFile: includePrivateRecords must be true or false; got ${JSON.stringify(asked) ?? String(asked)}. Nothing was written.`);
3471
+ const o = opts;
3472
+ for (const key of ["includePrivateRecords", "includeHidden"]) {
3473
+ const asked = o[key];
3474
+ if (asked !== void 0 && typeof asked !== "boolean") {
3475
+ throw new TypeError(`writeWorldFile: ${key} must be true or false; got ${JSON.stringify(asked) ?? String(asked)}. Nothing was written.`);
3476
+ }
3362
3477
  }
3363
- return asked === true;
3478
+ if (o.report !== void 0 && typeof o.report !== "function") {
3479
+ throw new TypeError(`writeWorldFile: report must be a function; got ${JSON.stringify(o.report) ?? String(o.report)}. Nothing was written.`);
3480
+ }
3481
+ return { includePrivate: o.includePrivateRecords === true, includeHidden: o.includeHidden !== false, report: o.report };
3482
+ }
3483
+ function isHiddenElement(f) {
3484
+ const segs = f.path.split("/");
3485
+ if (segs.length !== 3 || segs[0] !== "elements" && segs[0] !== "spatial" || !/\.json$/i.test(segs[2])) return false;
3486
+ let doc;
3487
+ try {
3488
+ doc = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(f.data));
3489
+ } catch {
3490
+ return false;
3491
+ }
3492
+ if (doc === null || typeof doc !== "object" || Array.isArray(doc)) return false;
3493
+ const mark = doc.hidden;
3494
+ return mark !== void 0 && mark !== null && mark !== false;
3364
3495
  }
3365
3496
  function privateProducers(files) {
3366
3497
  const manifest = files.find((f) => f.path === RECORDS_MANIFEST);
@@ -3386,7 +3517,7 @@ function privateProducers(files) {
3386
3517
  return out;
3387
3518
  }
3388
3519
  function writeWorldFile(files, topDir, opts = {}) {
3389
- const includePrivate = asksPrivate(opts);
3520
+ const { includePrivate, includeHidden, report } = writeOptions(opts);
3390
3521
  if (pathFault(topDir) || topDir.includes("/")) throw new OwWorldFileError("unsafe_path");
3391
3522
  const seen = /* @__PURE__ */ new Set();
3392
3523
  for (const f of files) {
@@ -3399,7 +3530,15 @@ function writeWorldFile(files, topDir, opts = {}) {
3399
3530
  const segs = path.split("/");
3400
3531
  return segs.length > 2 && segs[0] === "records" && left.has(foldName(segs[1]));
3401
3532
  };
3402
- const kept = files.filter((f) => carried(f.path) && !inPrivate(f.path));
3533
+ let hiddenLeftOut = 0;
3534
+ const kept = files.filter((f) => {
3535
+ if (!carried(f.path) || inPrivate(f.path)) return false;
3536
+ if (!includeHidden && isHiddenElement(f)) {
3537
+ hiddenLeftOut++;
3538
+ return false;
3539
+ }
3540
+ return true;
3541
+ });
3403
3542
  if (!kept.some((f) => f.path === WORLD_FILE)) throw new OwWorldFileError("not_a_world");
3404
3543
  const keys = kept.map((f) => `${topDir}/${f.path}`);
3405
3544
  for (const key of keys) {
@@ -3416,7 +3555,9 @@ function writeWorldFile(files, topDir, opts = {}) {
3416
3555
  if (f.path === WORLD_FILE) data = withoutLink(data, parseWorld(data)).data;
3417
3556
  input[`${topDir}/${f.path}`] = [data, { level: /\.json$/i.test(f.path) ? 6 : 0, mtime: STAMP }];
3418
3557
  }
3419
- return zipSync(input);
3558
+ const zip = zipSync(input);
3559
+ report?.({ hiddenLeftOut });
3560
+ return zip;
3420
3561
  }
3421
3562
 
3422
3563
  // src/room.ts
@@ -4786,6 +4927,7 @@ export {
4786
4927
  kindCanWrite,
4787
4928
  lookupWorld,
4788
4929
  monthStartSteps,
4930
+ nfc,
4789
4931
  parseDate,
4790
4932
  parseErrorEnvelope,
4791
4933
  pinExpectation,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlyworlds/sdk",
3
- "version": "4.69.0",
3
+ "version": "4.71.0",
4
4
  "description": "TypeScript SDK for the OnlyWorlds API - build world-building applications with type safety",
5
5
  "type": "module",
6
6
  "exports": {