@nika-js/onlymap 0.7.6 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +3 -1
  3. package/dist/{LercDecode.es-sRuTJq5Y.js → LercDecode.es-DKhLh4TO.js} +1 -1
  4. package/dist/{basemap-BCGMmc2F.js → basemap-BjXMRr_M.js} +538 -502
  5. package/dist/basemap.d.ts +23 -0
  6. package/dist/cartograph/api.d.ts +45 -0
  7. package/dist/cartograph/atlas.d.ts +50 -0
  8. package/dist/cartograph/core-loader.d.ts +35 -0
  9. package/dist/cartograph/cvd.d.ts +106 -0
  10. package/dist/cartograph/element-base.d.ts +26 -0
  11. package/dist/cartograph/elements/om-atlas.d.ts +47 -0
  12. package/dist/cartograph/elements/om-cartograph.d.ts +76 -0
  13. package/dist/cartograph/elements/om-frame.d.ts +121 -0
  14. package/dist/cartograph/elements/om-graticule.d.ts +24 -0
  15. package/dist/cartograph/elements/om-image.d.ts +12 -0
  16. package/dist/cartograph/elements/om-legend.d.ts +16 -0
  17. package/dist/cartograph/elements/om-north.d.ts +11 -0
  18. package/dist/cartograph/elements/om-scalebar.d.ts +13 -0
  19. package/dist/cartograph/elements/om-shape.d.ts +16 -0
  20. package/dist/cartograph/elements/om-text.d.ts +9 -0
  21. package/dist/cartograph/georef.d.ts +126 -0
  22. package/dist/cartograph/graticule.d.ts +70 -0
  23. package/dist/cartograph/html-data.d.ts +27 -0
  24. package/dist/cartograph/index.d.ts +1 -0
  25. package/dist/cartograph/layout.d.ts +23 -0
  26. package/dist/cartograph/legend.d.ts +75 -0
  27. package/dist/cartograph/live-frame.d.ts +83 -0
  28. package/dist/cartograph/paint.d.ts +54 -0
  29. package/dist/cartograph/refs.d.ts +33 -0
  30. package/dist/cartograph/render.d.ts +64 -0
  31. package/dist/cartograph/scalebar.d.ts +91 -0
  32. package/dist/cartograph/schema.d.ts +38 -0
  33. package/dist/cartograph/standalone.d.ts +1 -0
  34. package/dist/cartograph/textlayout.d.ts +45 -0
  35. package/dist/cartograph/tokens.d.ts +45 -0
  36. package/dist/cartograph/url-actions.d.ts +26 -0
  37. package/dist/cartograph/validate.d.ts +38 -0
  38. package/dist/cartograph/zip.d.ts +22 -0
  39. package/dist/cartograph.css +1 -0
  40. package/dist/cartograph.js +2797 -0
  41. package/dist/cartograph.standalone.js +7669 -0
  42. package/dist/crs-DsDQ4Q4i.js +71 -0
  43. package/dist/download.d.ts +6 -0
  44. package/dist/elements/om-map.d.ts +2 -0
  45. package/dist/feature-access.d.ts +14 -0
  46. package/dist/field-access.d.ts +1 -10
  47. package/dist/{geoparquet-CK9IjEjH.js → geoparquet-D9pYDrCk.js} +1 -1
  48. package/dist/{index-CN_tn36D.js → index-BGQidVp5.js} +1 -1
  49. package/dist/{index-CIEJyv5x.js → index-BdKNZcs-.js} +1 -1
  50. package/dist/index-CcLC9jE5.js +4798 -0
  51. package/dist/{index-C1ZQGJxa.js → index-CqtubBZ4.js} +1 -1
  52. package/dist/{index-CNRYpb0x.js → index-D6R4z3Zs.js} +6296 -6203
  53. package/dist/{index-CW3bdfHB.js → index-Zm8MxpvR.js} +2 -2
  54. package/dist/index.d.ts +1 -1
  55. package/dist/{lerc-Bb2JZ92v.js → lerc-BdHcL8pi.js} +2 -2
  56. package/dist/onlymap.standalone.js +10777 -10648
  57. package/dist/onlymapjs.js +12 -11
  58. package/dist/{raster-DpYssEe7.js → raster-B7rPpOTP.js} +3 -3
  59. package/dist/{raster-pipeline-BVCB-0yq.js → raster-pipeline-X2-mnFQx.js} +1 -1
  60. package/dist/runtime-core.d.ts +42 -0
  61. package/dist/snapshot.d.ts +17 -0
  62. package/dist/units.d.ts +9 -0
  63. package/dist/version.d.ts +1 -1
  64. package/dist/{zarr-DNb4iqbL.js → zarr-BF-buFRB.js} +2 -2
  65. package/docs/cartograph.md +396 -0
  66. package/llms.txt +1 -0
  67. package/onlymapjs.html-data.json +978 -0
  68. package/package.json +17 -6
  69. package/skills/onlymapjs/SKILL.md +2 -2
  70. package/skills/onlymapjs/references/syntax.md +27 -2
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Cartograph vocabulary — the SINGLE SOURCE for which attributes each element
3
+ * accepts (spec: docs/cartograph.md; issue onlymap-js#41).
4
+ *
5
+ * This module is the RUNTIME half: attribute rosters, format and theme names,
6
+ * page presets, the inert-reserved map. The elements derive their
7
+ * `observedAttributes` from it and the validator checks against it.
8
+ *
9
+ * The human-readable half — every attribute's description, for editor
10
+ * IntelliSense — lives in ./html-data.ts and is NOT imported here, so
11
+ * documentation strings never ship in the runtime bundle. (The core makes the
12
+ * same split: src/index.ts never imports src/html-data.ts.) The html-data test
13
+ * asserts every attribute rostered here is described there, so the two halves
14
+ * cannot drift.
15
+ *
16
+ * PURITY RULE: data only — no DOM, no imports from the core entry.
17
+ */
18
+ /** The document format identifier carried by `<om-cartograph format=>`. */
19
+ export declare const CARTOGRAPH_FORMAT = "cartograph/2";
20
+ /** Built-in theme ids (ported 1:1 from NIKA's BUILTIN_THEMES — cartograph.css). */
21
+ export declare const CARTOGRAPH_THEMES: readonly ["default", "dark", "sepia", "blueprint", "minimal"];
22
+ /** Page presets, portrait mm. The runtime treats unknown `size` as A4; the validator flags it. */
23
+ export declare const PAGE_SIZE_NAMES: readonly ["A0", "A1", "A2", "A3", "A4", "A5", "Letter", "Legal"];
24
+ /**
25
+ * Reserved-but-unbuilt attributes, keyed attribute name → reason. Mirrors
26
+ * the core's INERT_RESERVED_ATTRS pattern (attribute-resolution.ts — which
27
+ * is layer-specific and untouched by the cartograph): the validator warns
28
+ * "has no effect: <reason>" instead of staying silent. Implementing one of
29
+ * these means deleting its entry in the same commit.
30
+ */
31
+ export declare const INERT_RESERVED_CARTOGRAPH_ATTRS: ReadonlyMap<string, string>;
32
+ /**
33
+ * Placement attributes shared by every placed element (everything except
34
+ * `<om-cartograph>` and `<om-atlas>`). Millimetres from the page's top-left.
35
+ */
36
+ export declare const PLACED_ATTR_NAMES: readonly ["id", "x", "y", "w", "h", "rotation", "z", "locked", "hidden"];
37
+ export declare const CARTOGRAPH_ELEMENT_ATTRS: Record<string, readonly string[]>;
38
+ export declare const CARTOGRAPH_TAG_NAMES: readonly string[];
@@ -0,0 +1 @@
1
+ export * from "./api";
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared text line-boxing — ONE wrapping implementation, used by both the DOM
3
+ * renderer and the canvas exporter.
4
+ *
5
+ * Why not let the browser wrap in the DOM and re-wrap independently on canvas:
6
+ * the two would disagree at the margins (different rounding, different
7
+ * measurement paths), so a PNG export and the printed PDF of the same page
8
+ * would break lines in different places. Computing the line boxes once and
9
+ * having both renderers draw THOSE gives parity by construction.
10
+ *
11
+ * Deliberately simple: greedy word wrap on whitespace, with a hard break for
12
+ * words longer than the line. No hyphenation, no bidi reordering — a
13
+ * cartograph title is a short phrase, not a paragraph of prose. When no text
14
+ * measurer is available (node, no canvas), `layoutText` returns null and
15
+ * callers fall back to natural flow.
16
+ */
17
+ export interface TextLine {
18
+ text: string;
19
+ /** Baseline offset from the block's top, in the same units the measurer uses. */
20
+ baselineY: number;
21
+ width: number;
22
+ }
23
+ export interface TextLayout {
24
+ lines: TextLine[];
25
+ lineHeight: number;
26
+ /** Widest line — callers use it for alignment and overflow checks. */
27
+ maxWidth: number;
28
+ }
29
+ export interface LayoutTextOptions {
30
+ text: string;
31
+ /** Available width in CSS px; Infinity disables wrapping. */
32
+ maxWidth: number;
33
+ fontSizePx: number;
34
+ lineHeightPx: number;
35
+ measure: (text: string) => number;
36
+ }
37
+ /**
38
+ * Wrap `text` into line boxes. Explicit newlines always break; runs of other
39
+ * whitespace collapse, matching how the DOM renders the same content.
40
+ */
41
+ export declare function layoutText({ text, maxWidth, fontSizePx, lineHeightPx, measure }: LayoutTextOptions): TextLayout;
42
+ /** A measurer backed by a 2D canvas, or null where none exists (node/SSR). */
43
+ export declare function canvasMeasurer(font: string): ((text: string) => number) | null;
44
+ /** Horizontal offset for a line inside a box, given the CSS text-align value. */
45
+ export declare function alignOffset(align: string, boxWidth: number, lineWidth: number): number;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * `{{token}}` substitution for cartograph text.
3
+ *
4
+ * SECURITY CONTRACT: substitution is TEXT-NODE ONLY. Token values come from
5
+ * map data (a feature's fields, via the atlas) and from authored attributes;
6
+ * routing them through innerHTML would make a GeoJSON property containing
7
+ * markup into live DOM on any page displaying a third-party cartograph. Every
8
+ * value lands in a text node's `data`, never parsed as HTML.
9
+ *
10
+ * Resolution order (design §3.4): atlas feature → frame → cartograph. Unknown
11
+ * tokens render literally and are reported by the validator, so a typo is
12
+ * visible on the page rather than silently blank.
13
+ */
14
+ export interface FrameTokenValues {
15
+ /** Representative-fraction denominator, formatted for print. */
16
+ scale?: string;
17
+ crs?: string;
18
+ }
19
+ export interface TokenContext {
20
+ /** Cartograph-level values: title, date, attribution, notes, … */
21
+ page: Record<string, string>;
22
+ /** Per-frame values, keyed by frame id — reached as {{frame.<id>.scale}}. */
23
+ frames?: Map<string, FrameTokenValues>;
24
+ /** The single frame bare {{scale}}/{{crs}} bind to, when the page has exactly one. */
25
+ soleFrameId?: string | null;
26
+ /** Atlas feature fields, reached as {{atlas.<field>}} (Phase 4). */
27
+ atlas?: Record<string, string>;
28
+ }
29
+ /** Resolve one token name, or undefined when nothing provides it. */
30
+ export declare function resolveToken(name: string, ctx: TokenContext): string | undefined;
31
+ export interface TokenResult {
32
+ text: string;
33
+ /** Token names nothing resolved — rendered literally, reported by the validator. */
34
+ unresolved: string[];
35
+ }
36
+ export declare function resolveTokens(template: string, ctx: TokenContext): TokenResult;
37
+ /** Every token name appearing in a template (for validation). */
38
+ export declare function tokensIn(template: string): string[];
39
+ /**
40
+ * Substitute tokens in every text node under `root`, in place. Returns the
41
+ * token names that went unresolved.
42
+ */
43
+ export declare function applyTokens(root: Node, ctx: TokenContext): string[];
44
+ /** Today's date in ISO form — the default `{{date}}` value. */
45
+ export declare function isoDate(now?: Date): string;
@@ -0,0 +1,26 @@
1
+ import type { OmCartographElement } from "./elements/om-cartograph";
2
+ /** How long to wait for frames and fonts before acting anyway. */
3
+ export declare const URL_ACTION_TIMEOUT_MS = 30000;
4
+ /**
5
+ * Resolves when every frame has settled and fonts are loaded — or when the
6
+ * timeout expires, which is deliberate: a dead raster URL must degrade to a
7
+ * page with a visible error placeholder, not hang forever with no output.
8
+ */
9
+ export declare function whenPageReady(page: Element, timeoutMs?: number): Promise<{
10
+ timedOut: boolean;
11
+ }>;
12
+ export interface UrlActionOptions {
13
+ /** Defaults to the page's own location. */
14
+ search?: string;
15
+ timeoutMs?: number;
16
+ }
17
+ /**
18
+ * Apply whatever the URL asks of this cartograph. Returns the action taken,
19
+ * or null when there was nothing to do (or the page did not opt in).
20
+ */
21
+ export declare function applyUrlActions(page: OmCartographElement, options?: UrlActionOptions): Promise<"print" | "export" | "cvd" | null>;
22
+ /**
23
+ * Install the triggers once the document is parsed. Called by the entry; a
24
+ * page with no `allow-url-actions` cartograph does nothing at all.
25
+ */
26
+ export declare function installUrlActions(): void;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Cartograph validation (spec: docs/cartograph.md; design §3.7).
3
+ *
4
+ * Returns the CORE validator's `ValidationResult` shape so a host folds
5
+ * cartograph diagnostics into agent tool results with exactly the code it
6
+ * already uses for map manifests. The types are `import type` only — erased at
7
+ * compile time — because src/validation.ts transitively imports every deck.gl
8
+ * layer package, and pulling that in would break the cartograph entry's
9
+ * lazy-core rule (the CI bundle gate would fail the build).
10
+ *
11
+ * SYNCHRONOUS AND HEADLESS by design: hosts validate on every agent write, so
12
+ * it must run in node over a parsed document with no element upgrade and no
13
+ * renderer. That is also why inline `<om-map>` manifests are NOT deep-validated
14
+ * here — delegating would require loading the core. Phase 2 adds an async
15
+ * `validateCartographDeep()` for hosts that already have the core loaded.
16
+ */
17
+ import type { ValidationResult } from "../validation";
18
+ /**
19
+ * Validate a parsed cartograph document (or a bare `<om-cartograph>` element).
20
+ */
21
+ export declare function validateCartograph(root: ParentNode): ValidationResult;
22
+ /** Validate a cartograph HTML string. Needs a DOM implementation for DOMParser. */
23
+ export declare function validateCartographString(html: string): ValidationResult;
24
+ /**
25
+ * Everything `validateCartograph` checks, PLUS the inline `<om-map>` manifests,
26
+ * delegated to the core validator.
27
+ *
28
+ * Separate and async because the core validator's import graph reaches every
29
+ * deck.gl layer package: pulling it into the synchronous path would break the
30
+ * lazy-core rule and load the whole map runtime just to check a document. Hosts
31
+ * that already have the core loaded (the NIKA editor) use this; hosts that
32
+ * validate on every agent write (a file-write hook, the QGIS plugin) use the
33
+ * sync form and stay cheap.
34
+ *
35
+ * Entries from an inline manifest are prefixed with their frame, so a host can
36
+ * tell "the cartograph is malformed" from "the map inside frame #main is".
37
+ */
38
+ export declare function validateCartographDeep(root: ParentNode): Promise<ValidationResult>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * A minimal ZIP writer (STORE method — no compression).
3
+ *
4
+ * An atlas export is N pages, and browsers block or prompt on a loop of N
5
+ * downloads, so the export has to hand back ONE file. PNGs are already
6
+ * deflate-compressed internally, so storing them uncompressed costs almost
7
+ * nothing and saves pulling a compression library into a bundle whose whole
8
+ * premise is staying small.
9
+ *
10
+ * Deliberately not a general zip implementation: no directories, no zip64, no
11
+ * unicode path extras beyond UTF-8 names with the language-encoding flag set.
12
+ */
13
+ export interface ZipFile {
14
+ name: string;
15
+ data: Blob | Uint8Array;
16
+ }
17
+ /**
18
+ * Build a ZIP archive. `modified` is a parameter so a caller that needs a
19
+ * byte-reproducible archive can pin it — the timestamp is otherwise the one
20
+ * part of the output that changes between runs.
21
+ */
22
+ export declare function createZip(files: readonly ZipFile[], modified?: Date): Promise<Blob>;
@@ -0,0 +1 @@
1
+ om-cartograph{--om-carto-bg: #fbf8fb;--om-carto-ink: #6d5b72;--om-carto-font: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--om-carto-title-ink: #2a1f2d;--om-carto-title-font: var(--om-carto-font);--om-carto-title-weight: 600;--om-carto-attr-ink: #8b7890;--om-carto-legend-bg: #fbf8fb;--om-carto-legend-border: #dfd0df;--om-carto-legend-title-ink: #2a1f2d;--om-carto-frame-stroke: #2a1f2d;--om-carto-frame-bg: #f1ebf1;--om-carto-compass-ink: #2a1f2d;--om-carto-scalebar-ink: #2a1f2d;--om-carto-shape-fill: #f0d9a5;--om-carto-shape-stroke: #2a1f2d;--om-carto-graticule-ink: #ffffff;display:block;position:relative;overflow:hidden;background:var(--om-carto-bg);color:var(--om-carto-ink);font-family:var(--om-carto-font);box-sizing:border-box}om-cartograph[theme=dark]{--om-carto-bg: #261a29;--om-carto-ink: #d7bfb5;--om-carto-title-ink: #f7ece6;--om-carto-attr-ink: #b996a6;--om-carto-legend-bg: #2f2134;--om-carto-legend-border: #4b3450;--om-carto-legend-title-ink: #f7ece6;--om-carto-frame-stroke: #4b3450;--om-carto-frame-bg: #2f2134;--om-carto-compass-ink: #f7ece6;--om-carto-scalebar-ink: #f7ece6;--om-carto-shape-fill: #3b2a41;--om-carto-shape-stroke: #f7ece6;--om-carto-graticule-ink: #ffffff}om-cartograph[theme=sepia]{--om-carto-bg: #f4ead5;--om-carto-ink: #3a2c1a;--om-carto-font: "Iowan Old Style", "Palatino Linotype", Palatino, "Hoefler Text", Georgia, serif;--om-carto-title-ink: #2a1f0e;--om-carto-title-weight: 700;--om-carto-attr-ink: #6b5638;--om-carto-legend-bg: #fbf4e3;--om-carto-legend-border: #a78a5a;--om-carto-legend-title-ink: #3a2c1a;--om-carto-frame-stroke: #5c4528;--om-carto-frame-bg: #e8dcc1;--om-carto-compass-ink: #5c4528;--om-carto-scalebar-ink: #3a2c1a;--om-carto-shape-fill: #e8dcc1;--om-carto-shape-stroke: #5c4528;--om-carto-graticule-ink: #5c4528}om-cartograph[theme=blueprint]{--om-carto-bg: #0d2e5c;--om-carto-ink: #cfe3ff;--om-carto-title-ink: #ffffff;--om-carto-attr-ink: #7fa6da;--om-carto-legend-bg: #11366b;--om-carto-legend-border: #5d8dc5;--om-carto-legend-title-ink: #ffffff;--om-carto-frame-stroke: #cfe3ff;--om-carto-frame-bg: #11366b;--om-carto-compass-ink: #cfe3ff;--om-carto-scalebar-ink: #cfe3ff;--om-carto-shape-fill: #11366b;--om-carto-shape-stroke: #cfe3ff;--om-carto-graticule-ink: #cfe3ff}om-cartograph[theme=minimal]{--om-carto-bg: #fafafa;--om-carto-ink: #444444;--om-carto-title-ink: #111111;--om-carto-title-weight: 500;--om-carto-attr-ink: #999999;--om-carto-legend-bg: #ffffff;--om-carto-legend-border: #e5e5e5;--om-carto-legend-title-ink: #222222;--om-carto-frame-stroke: #bbbbbb;--om-carto-frame-bg: #ffffff;--om-carto-compass-ink: #666666;--om-carto-scalebar-ink: #444444;--om-carto-shape-fill: #ffffff;--om-carto-shape-stroke: #999999;--om-carto-graticule-ink: #888888}om-text,om-frame,om-legend,om-scalebar,om-north,om-graticule,om-shape,om-image{display:block;position:absolute;box-sizing:border-box}om-text[hidden],om-cartograph [hidden]{display:none!important}om-legend-row{display:none!important}om-scalebar{color:var(--om-carto-scalebar-ink);font-family:var(--om-carto-font)}om-north{color:var(--om-carto-compass-ink);font-family:var(--om-carto-font)}om-graticule{color:var(--om-carto-graticule-ink)}om-legend{background:var(--om-carto-legend-bg);border:.2mm solid var(--om-carto-legend-border);color:var(--om-carto-ink)}om-frame{background:var(--om-carto-frame-bg);overflow:hidden}om-frame>img,om-image>img{display:block}om-frame>svg,om-scalebar>svg,om-north>svg,om-shape>svg,om-graticule>svg{display:block;overflow:visible}om-text[kind=title]{color:var(--om-carto-title-ink);font-family:var(--om-carto-title-font);font-weight:var(--om-carto-title-weight);font-size:18pt;line-height:1.2}om-text[kind=attribution]{color:var(--om-carto-attr-ink);font-size:6.5pt;line-height:1.4}om-text{font-size:10pt;line-height:1.4}@media print{[data-om-carto-screen-only]{display:none!important}om-cartograph{margin:0;box-shadow:none;filter:none!important}}om-cartograph:not(:defined){display:block;position:relative;min-height:240px;background:#fff;border:1px solid #d1d5db;color:#374151;font:14px/1.5 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;overflow:hidden}om-cartograph:not(:defined)>:not(om-text):not(om-frame):not(om-image):not(om-shape){display:none!important}om-cartograph:not(:defined) om-text{display:block;position:absolute}om-cartograph:not(:defined):after{content:"This cartograph requires JavaScript for its interactive map frames. Static content is shown as authored.";position:absolute;inset:auto 0 0;padding:8px 12px;font-size:11px;color:#6b7280;text-align:center;opacity:0;animation:om-carto-fallback-reveal .3s ease .4s forwards}@media(scripting:enabled){om-cartograph:not(:defined):after{content:"This cartograph is taking too long to load. Its JavaScript may be blocked or unreachable — check the connection, then reload the page.";animation-delay:4s}}@media(scripting:none){om-cartograph:not(:defined):after{opacity:1;animation:none}}@keyframes om-carto-fallback-reveal{to{opacity:1}}