@trdrs/quickcharts 1.3.0 → 2.0.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/CHANGELOG.md +84 -0
- package/README.md +209 -200
- package/dist/adapters/rest.d.ts +3 -3
- package/dist/adapters/rest.js +2 -2
- package/dist/adapters/rest.js.map +1 -1
- package/dist/{ar-G7MVXRE4.js → ar-KSXQ2USS.js} +20 -20
- package/dist/ar-KSXQ2USS.js.map +1 -0
- package/dist/{assets-ySndlUS3.d.ts → assets-DOuBBsOp.d.ts} +50 -50
- package/dist/{ca_ES-EUSRU4VG.js → ca_ES-JG4FM55E.js} +20 -20
- package/dist/ca_ES-JG4FM55E.js.map +1 -0
- package/dist/{chunk-AA7XKXH4.js → chunk-6S6TO2N6.js} +33 -33
- package/dist/chunk-6S6TO2N6.js.map +1 -0
- package/dist/{chunk-KFBQSPNA.js → chunk-D3S26ARP.js} +2 -2
- package/dist/chunk-D3S26ARP.js.map +1 -0
- package/dist/{chunk-AKXIFHQN.js → chunk-KLPTCWA2.js} +1 -1
- package/dist/{chunk-AKXIFHQN.js.map → chunk-KLPTCWA2.js.map} +1 -1
- package/dist/{de-2SVTG25S.js → de-VSW2LHNF.js} +20 -20
- package/dist/de-VSW2LHNF.js.map +1 -0
- package/dist/drawings.d.ts +16 -16
- package/dist/drawings.js +12 -12
- package/dist/{es-UDHZM4W7.js → es-5ZXIPVOB.js} +20 -20
- package/dist/es-5ZXIPVOB.js.map +1 -0
- package/dist/feature-manifest.json +3 -3
- package/dist/{fr-35VN4G4S.js → fr-4F6DAWGD.js} +20 -20
- package/dist/fr-4F6DAWGD.js.map +1 -0
- package/dist/{he_IL-JPZMCURP.js → he_IL-B7PBQUEV.js} +20 -20
- package/dist/he_IL-B7PBQUEV.js.map +1 -0
- package/dist/{id_ID-XSTFHHJQ.js → id_ID-CYJRMXPC.js} +20 -20
- package/dist/id_ID-CYJRMXPC.js.map +1 -0
- package/dist/index.d.ts +167 -163
- package/dist/index.js +248 -237
- package/dist/index.js.map +1 -1
- package/dist/{it-EIY6JESQ.js → it-KTX4SG5P.js} +20 -20
- package/dist/it-KTX4SG5P.js.map +1 -0
- package/dist/{ja-42N4XRCW.js → ja-V7OURU5D.js} +20 -20
- package/dist/ja-V7OURU5D.js.map +1 -0
- package/dist/{ko-3VRPTIP3.js → ko-2RNEBYVE.js} +20 -20
- package/dist/ko-2RNEBYVE.js.map +1 -0
- package/dist/{ms_MY-SKN7O6M5.js → ms_MY-EY235E7Q.js} +20 -20
- package/dist/ms_MY-EY235E7Q.js.map +1 -0
- package/dist/{pl-TYARHCLT.js → pl-ADNVRP55.js} +20 -20
- package/dist/pl-ADNVRP55.js.map +1 -0
- package/dist/{pt-72IIFLL4.js → pt-OL2DR3DO.js} +20 -20
- package/dist/pt-OL2DR3DO.js.map +1 -0
- package/dist/quickcharts.css +97 -96
- package/dist/{resources-Ch8eA1Mw.d.ts → resources-Le6flcEn.d.ts} +3 -3
- package/dist/rest-openapi.json +11 -11
- package/dist/{ru-TPH4F7IB.js → ru-V6YFEPAF.js} +20 -20
- package/dist/ru-V6YFEPAF.js.map +1 -0
- package/dist/{sv-DC5RS67Z.js → sv-TORXQVE7.js} +20 -20
- package/dist/sv-TORXQVE7.js.map +1 -0
- package/dist/{th-I6H6AOZ3.js → th-K6SJSYSY.js} +20 -20
- package/dist/th-K6SJSYSY.js.map +1 -0
- package/dist/theme-manifest.json +10 -10
- package/dist/{tr-7FSUVCNW.js → tr-4AEM66KW.js} +20 -20
- package/dist/tr-4AEM66KW.js.map +1 -0
- package/dist/{vi-DLRPHLLH.js → vi-YU5XCEUU.js} +20 -20
- package/dist/vi-YU5XCEUU.js.map +1 -0
- package/dist/{zh-ZXIQBBEP.js → zh-QXKRYHU5.js} +20 -20
- package/dist/zh-QXKRYHU5.js.map +1 -0
- package/dist/{zh_TW-TYNUJU7U.js → zh_TW-AYPDKG4Q.js} +20 -20
- package/dist/zh_TW-AYPDKG4Q.js.map +1 -0
- package/package.json +1 -1
- package/dist/ar-G7MVXRE4.js.map +0 -1
- package/dist/ca_ES-EUSRU4VG.js.map +0 -1
- package/dist/chunk-AA7XKXH4.js.map +0 -1
- package/dist/chunk-KFBQSPNA.js.map +0 -1
- package/dist/de-2SVTG25S.js.map +0 -1
- package/dist/es-UDHZM4W7.js.map +0 -1
- package/dist/fr-35VN4G4S.js.map +0 -1
- package/dist/he_IL-JPZMCURP.js.map +0 -1
- package/dist/id_ID-XSTFHHJQ.js.map +0 -1
- package/dist/it-EIY6JESQ.js.map +0 -1
- package/dist/ja-42N4XRCW.js.map +0 -1
- package/dist/ko-3VRPTIP3.js.map +0 -1
- package/dist/ms_MY-SKN7O6M5.js.map +0 -1
- package/dist/pl-TYARHCLT.js.map +0 -1
- package/dist/pt-72IIFLL4.js.map +0 -1
- package/dist/ru-TPH4F7IB.js.map +0 -1
- package/dist/sv-DC5RS67Z.js.map +0 -1
- package/dist/th-I6H6AOZ3.js.map +0 -1
- package/dist/tr-7FSUVCNW.js.map +0 -1
- package/dist/vi-DLRPHLLH.js.map +0 -1
- package/dist/zh-ZXIQBBEP.js.map +0 -1
- package/dist/zh_TW-TYNUJU7U.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
drawingContextKey
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KLPTCWA2.js";
|
|
4
4
|
|
|
5
5
|
// src/resources.ts
|
|
6
6
|
var ResourceAbortError = class extends Error {
|
|
@@ -104,4 +104,4 @@ export {
|
|
|
104
104
|
ResourceAbortError,
|
|
105
105
|
memorySaveLoadAdapter
|
|
106
106
|
};
|
|
107
|
-
//# sourceMappingURL=chunk-
|
|
107
|
+
//# sourceMappingURL=chunk-D3S26ARP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/resources.ts"],"sourcesContent":["// SAVED RESOURCES — the revisioned, async persistence contract for the entities a chart names and\n// a viewer can lose: saved charts, layouts, drawing documents, and templates.\n//\n// The contract exists because a saved chart is shared, mutable, remote state. Two tabs, two\n// devices, or one slow save and one fast one all end at the same question: whose version wins?\n// A store that answers \"the last write\" silently destroys work. So every read hands back a\n// `ResourceRef` (a stable id plus an opaque revision token), every write states the revision it\n// believes it is replacing, and a write against a stale revision comes back as a typed `conflict`\n// carrying the current ref. The chart never resolves that by overwriting; it surfaces it.\n//\n// Three rules the shape enforces:\n// - The revision is OPAQUE. It is a token the host minted and the chart only ever echoes back.\n// No ordering, no arithmetic, no timestamp parsing; a host is free to use an ETag, a counter,\n// or a content hash.\n// - Every call takes an `AbortSignal`. A symbol switch, a closed dialog, or a fast retype must be\n// able to abandon in-flight work, and a late answer to an abandoned ask must never land.\n// - A successful write RETURNS the stored revision, so the caller's next write is conditional on\n// what the store actually holds rather than on what it hoped it wrote.\n//\n// A chart's, a layout's and a template's body is contractually OPAQUE to the store: no parsing, no\n// per-entity logic, so the chart can evolve those formats freely. The drawings family is the one\n// deliberate exception: its body is the structured document in `drawings/document.ts`, because\n// deletion tombstones, ordered groups and per-drawing ownership have to survive a merge between two\n// surfaces, and a merge cannot be performed over a string. Each drawing's own state stays opaque\n// inside its entry.\n//\n// Flat viewer preferences that need no entity identity are NOT here; they stay on `ChartStorage`,\n// the small settings port beside this one.\nimport type { DrawingResourceContext, DrawingsBody } from './drawings/document'\nimport { drawingContextKey } from './drawings/document'\n\n/** A resource's identity plus the exact version this reader saw. A write quotes it back. */\nexport interface ResourceRef {\n id: string\n /** Opaque to the chart: minted by the store, compared only for equality. */\n revision: string\n}\n\n/** What a write did. `ok` carries the ref the store now holds (and, where the store computes one,\n * the resulting metadata); `conflict` carries the ref that beat this write, so a caller can reload\n * and re-decide; `not-found` means the id is gone. */\nexport type WriteOutcome<T = void> =\n | { kind: 'ok'; ref: ResourceRef; value?: T }\n | { kind: 'conflict'; current: ResourceRef }\n | { kind: 'not-found' }\n\n/** One family of resources. `Meta` is the listing row a picker shows without fetching content\n * (it carries the row's ref, so a picker can delete or open a row without a second read); `Body`\n * is the stored document. */\nexport interface ResourceStore<Meta, Body> {\n /** Listing rows, metadata only. */\n list(signal?: AbortSignal): Promise<Meta[]>\n /** The stored document and the revision it was read at, or null when the id is unknown. */\n load(id: string, signal?: AbortSignal): Promise<{ ref: ResourceRef; body: Body } | null>\n /** Store a new document. The store mints the id; a create conflicts only where the store keys a\n * document by identity and one already stands there (a drawings context that holds a document, a\n * name already taken), and then it answers the ref that stands. */\n create(body: Body, signal?: AbortSignal): Promise<WriteOutcome<Meta>>\n /** Replace the document at `ref.id`, but only while it still stands at `ref.revision`. */\n update(ref: ResourceRef, body: Body, signal?: AbortSignal): Promise<WriteOutcome<Meta>>\n /** Delete the document at `ref.id`, but only while it still stands at `ref.revision`. */\n remove(ref: ResourceRef, signal?: AbortSignal): Promise<WriteOutcome<void>>\n}\n\n/** A saved chart's listing row. */\nexport interface ChartMeta extends ResourceRef {\n name: string\n symbol: string\n timeframe: string\n /** Last save, ms since epoch (server-stamped by real backends). */\n updatedAt: number\n}\n\n/** A saved chart. `content` is the chart's own serialized state, opaque to the store. */\nexport interface ChartBody {\n name: string\n symbol: string\n timeframe: string\n content: string\n}\n\n/** A saved multi-chart layout's listing row. `symbol` is the active chart's market as the chart\n * writes it (`symbolNames(...).mark`, such as `BTCUSDC`) and `timeframe` its timeframe token, both\n * as they stood at the last save, so a listing can say what each layout shows without opening it. A\n * store that does not keep them, or a layout saved before they were stated, leaves them out. */\nexport interface LayoutMeta extends ResourceRef {\n name: string\n symbol?: string\n timeframe?: string\n updatedAt: number\n}\n\n/** A saved multi-chart layout. `content` is the arrangement's serialized state, opaque to the store.\n * The widget states the listing's `symbol` and `timeframe` on every save; they are display text and\n * play no part in restoring the layout. */\nexport interface LayoutBody {\n name: string\n symbol?: string\n timeframe?: string\n content: string\n}\n\n/** A drawings document's listing row. A context holds at most one, so `list` returns zero rows or\n * one, and the ref is the store's handle on it. */\nexport interface DrawingsMeta extends ResourceRef {\n updatedAt: number\n}\n\nexport type TemplateKind = 'indicator' | 'drawing' | 'palette'\n\n/** A named template's listing row. `tool` scopes DRAWING templates to their tool (a trend-line\n * template is meaningless on a rectangle); indicator and palette templates carry no tool. */\nexport interface TemplateMeta extends ResourceRef {\n name: string\n tool?: string\n updatedAt: number\n}\n\nexport interface TemplateBody {\n name: string\n tool?: string\n content: string\n}\n\n/** The adapter a host implements: four resource families over one revisioned contract. Viewer\n * settings are deliberately absent; they belong to `ChartStorage`. */\nexport interface ChartSaveLoadAdapter {\n charts: ResourceStore<ChartMeta, ChartBody>\n layouts: ResourceStore<LayoutMeta, LayoutBody>\n /** The store for one drawing-resource context. Calling with an equal context returns an\n * equivalent store; `drawingContextKey` is the canonical way to compare two. */\n drawings(context: DrawingResourceContext): ResourceStore<DrawingsMeta, DrawingsBody>\n templates(kind: TemplateKind): ResourceStore<TemplateMeta, TemplateBody>\n}\n\n/** The error every store rejects with when its signal aborts. `name` is 'AbortError', which is what\n * callers branch on, and what `DOMException` uses, so a host may reject with either. */\nexport class ResourceAbortError extends Error {\n override readonly name = 'AbortError'\n constructor(message = 'the resource operation was aborted') {\n super(message)\n }\n}\n\n/* ── The in-memory reference implementation ────────────────────────────────────────────────────\n The shape's own proof and the fixture every consumer test mounts: revisions on every write,\n conflicts on a stale ref, not-found on a vanished id, and an abort that lands before any state\n changes. It persists nothing, so it is also the right adapter for SSR, an ephemeral embed, and\n the clean-room consumer. */\n\ninterface Record_<Body> {\n id: string\n revision: string\n body: Body\n updatedAt: number\n}\n\n/** An aborted signal REJECTS the returned promise rather than throwing out of the call, so every\n * caller handles abandonment on one path. */\nconst aborted = (signal: AbortSignal | undefined): Promise<never> | null =>\n signal?.aborted ? Promise.reject(new ResourceAbortError()) : null\n\nconst newId = (): string =>\n typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : `r${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`\n\n/** Options for {@link memorySaveLoadAdapter}: a clock, so a test can pin `updatedAt`. */\nexport interface MemoryResourcesOptions {\n now?: () => number\n}\n\nfunction memoryStore<Meta, Body>(\n metaOf: (record: Record_<Body>) => Meta,\n now: () => number,\n): ResourceStore<Meta, Body> {\n const rows = new Map<string, Record_<Body>>()\n let counter = 0\n const nextRevision = (): string => `rev-${++counter}`\n const refOf = (record: Record_<Body>): ResourceRef => ({ id: record.id, revision: record.revision })\n\n return {\n list(signal) {\n return aborted(signal) ?? Promise.resolve([...rows.values()].map(metaOf))\n },\n load(id, signal) {\n const stop = aborted(signal)\n if (stop) return stop\n const record = rows.get(id)\n return Promise.resolve(record ? { ref: refOf(record), body: record.body } : null)\n },\n create(body, signal) {\n const stop = aborted(signal)\n if (stop) return stop\n const record: Record_<Body> = { id: newId(), revision: nextRevision(), body, updatedAt: now() }\n rows.set(record.id, record)\n const outcome: WriteOutcome<Meta> = { kind: 'ok', ref: refOf(record), value: metaOf(record) }\n return Promise.resolve(outcome)\n },\n update(ref, body, signal) {\n const stop = aborted(signal)\n if (stop) return stop\n const record = rows.get(ref.id)\n if (!record) return Promise.resolve<WriteOutcome<Meta>>({ kind: 'not-found' })\n if (record.revision !== ref.revision) return Promise.resolve<WriteOutcome<Meta>>({ kind: 'conflict', current: refOf(record) })\n record.body = body\n record.revision = nextRevision()\n record.updatedAt = now()\n const outcome: WriteOutcome<Meta> = { kind: 'ok', ref: refOf(record), value: metaOf(record) }\n return Promise.resolve(outcome)\n },\n remove(ref, signal) {\n const stop = aborted(signal)\n if (stop) return stop\n const record = rows.get(ref.id)\n if (!record) return Promise.resolve<WriteOutcome<void>>({ kind: 'not-found' })\n if (record.revision !== ref.revision) return Promise.resolve<WriteOutcome<void>>({ kind: 'conflict', current: refOf(record) })\n rows.delete(ref.id)\n return Promise.resolve<WriteOutcome<void>>({ kind: 'ok', ref: refOf(record) })\n },\n }\n}\n\n/** An in-memory {@link ChartSaveLoadAdapter}. Each drawing context and each template kind gets its\n * own store, created on first ask and kept, so two calls for one context see the same document. */\nexport function memorySaveLoadAdapter(options?: MemoryResourcesOptions): ChartSaveLoadAdapter {\n const now = options?.now ?? (() => Date.now())\n const drawingStores = new Map<string, ResourceStore<DrawingsMeta, DrawingsBody>>()\n const templateStores = new Map<TemplateKind, ResourceStore<TemplateMeta, TemplateBody>>()\n\n return {\n charts: memoryStore<ChartMeta, ChartBody>(\n (r) => ({ id: r.id, revision: r.revision, name: r.body.name, symbol: r.body.symbol, timeframe: r.body.timeframe, updatedAt: r.updatedAt }),\n now,\n ),\n layouts: memoryStore<LayoutMeta, LayoutBody>(\n (r) => ({\n id: r.id,\n revision: r.revision,\n name: r.body.name,\n ...(r.body.symbol === undefined ? {} : { symbol: r.body.symbol }),\n ...(r.body.timeframe === undefined ? {} : { timeframe: r.body.timeframe }),\n updatedAt: r.updatedAt,\n }),\n now,\n ),\n drawings(context) {\n const key = drawingContextKey(context)\n let store = drawingStores.get(key)\n if (!store) {\n store = memoryStore<DrawingsMeta, DrawingsBody>((r) => ({ id: r.id, revision: r.revision, updatedAt: r.updatedAt }), now)\n drawingStores.set(key, store)\n }\n return store\n },\n templates(kind) {\n let store = templateStores.get(kind)\n if (!store) {\n store = memoryStore<TemplateMeta, TemplateBody>(\n (r) => ({ id: r.id, revision: r.revision, name: r.body.name, ...(r.body.tool === undefined ? {} : { tool: r.body.tool }), updatedAt: r.updatedAt }),\n now,\n )\n templateStores.set(kind, store)\n }\n return store\n },\n }\n}\n"],"mappings":";;;;;AAyIO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC1B,OAAO;AAAA,EACzB,YAAY,UAAU,sCAAsC;AAC1D,UAAM,OAAO;AAAA,EACf;AACF;AAiBA,IAAM,UAAU,CAAC,WACf,QAAQ,UAAU,QAAQ,OAAO,IAAI,mBAAmB,CAAC,IAAI;AAE/D,IAAM,QAAQ,MACZ,OAAO,WAAW,eAAe,OAAO,aAAa,OAAO,WAAW,IAAI,IAAI,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAOjJ,SAAS,YACP,QACA,KAC2B;AAC3B,QAAM,OAAO,oBAAI,IAA2B;AAC5C,MAAI,UAAU;AACd,QAAM,eAAe,MAAc,OAAO,EAAE,OAAO;AACnD,QAAM,QAAQ,CAAC,YAAwC,EAAE,IAAI,OAAO,IAAI,UAAU,OAAO,SAAS;AAElG,SAAO;AAAA,IACL,KAAK,QAAQ;AACX,aAAO,QAAQ,MAAM,KAAK,QAAQ,QAAQ,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC;AAAA,IAC1E;AAAA,IACA,KAAK,IAAI,QAAQ;AACf,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAM,QAAO;AACjB,YAAM,SAAS,KAAK,IAAI,EAAE;AAC1B,aAAO,QAAQ,QAAQ,SAAS,EAAE,KAAK,MAAM,MAAM,GAAG,MAAM,OAAO,KAAK,IAAI,IAAI;AAAA,IAClF;AAAA,IACA,OAAO,MAAM,QAAQ;AACnB,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAM,QAAO;AACjB,YAAM,SAAwB,EAAE,IAAI,MAAM,GAAG,UAAU,aAAa,GAAG,MAAM,WAAW,IAAI,EAAE;AAC9F,WAAK,IAAI,OAAO,IAAI,MAAM;AAC1B,YAAM,UAA8B,EAAE,MAAM,MAAM,KAAK,MAAM,MAAM,GAAG,OAAO,OAAO,MAAM,EAAE;AAC5F,aAAO,QAAQ,QAAQ,OAAO;AAAA,IAChC;AAAA,IACA,OAAO,KAAK,MAAM,QAAQ;AACxB,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAM,QAAO;AACjB,YAAM,SAAS,KAAK,IAAI,IAAI,EAAE;AAC9B,UAAI,CAAC,OAAQ,QAAO,QAAQ,QAA4B,EAAE,MAAM,YAAY,CAAC;AAC7E,UAAI,OAAO,aAAa,IAAI,SAAU,QAAO,QAAQ,QAA4B,EAAE,MAAM,YAAY,SAAS,MAAM,MAAM,EAAE,CAAC;AAC7H,aAAO,OAAO;AACd,aAAO,WAAW,aAAa;AAC/B,aAAO,YAAY,IAAI;AACvB,YAAM,UAA8B,EAAE,MAAM,MAAM,KAAK,MAAM,MAAM,GAAG,OAAO,OAAO,MAAM,EAAE;AAC5F,aAAO,QAAQ,QAAQ,OAAO;AAAA,IAChC;AAAA,IACA,OAAO,KAAK,QAAQ;AAClB,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAM,QAAO;AACjB,YAAM,SAAS,KAAK,IAAI,IAAI,EAAE;AAC9B,UAAI,CAAC,OAAQ,QAAO,QAAQ,QAA4B,EAAE,MAAM,YAAY,CAAC;AAC7E,UAAI,OAAO,aAAa,IAAI,SAAU,QAAO,QAAQ,QAA4B,EAAE,MAAM,YAAY,SAAS,MAAM,MAAM,EAAE,CAAC;AAC7H,WAAK,OAAO,IAAI,EAAE;AAClB,aAAO,QAAQ,QAA4B,EAAE,MAAM,MAAM,KAAK,MAAM,MAAM,EAAE,CAAC;AAAA,IAC/E;AAAA,EACF;AACF;AAIO,SAAS,sBAAsB,SAAwD;AAC5F,QAAM,MAAM,SAAS,QAAQ,MAAM,KAAK,IAAI;AAC5C,QAAM,gBAAgB,oBAAI,IAAuD;AACjF,QAAM,iBAAiB,oBAAI,IAA6D;AAExF,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,UAAU,MAAM,EAAE,KAAK,MAAM,QAAQ,EAAE,KAAK,QAAQ,WAAW,EAAE,KAAK,WAAW,WAAW,EAAE,UAAU;AAAA,MACxI;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,CAAC,OAAO;AAAA,QACN,IAAI,EAAE;AAAA,QACN,UAAU,EAAE;AAAA,QACZ,MAAM,EAAE,KAAK;AAAA,QACb,GAAI,EAAE,KAAK,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,OAAO;AAAA,QAC/D,GAAI,EAAE,KAAK,cAAc,SAAY,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,UAAU;AAAA,QACxE,WAAW,EAAE;AAAA,MACf;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,SAAS;AAChB,YAAM,MAAM,kBAAkB,OAAO;AACrC,UAAI,QAAQ,cAAc,IAAI,GAAG;AACjC,UAAI,CAAC,OAAO;AACV,gBAAQ,YAAwC,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,UAAU,WAAW,EAAE,UAAU,IAAI,GAAG;AACxH,sBAAc,IAAI,KAAK,KAAK;AAAA,MAC9B;AACA,aAAO;AAAA,IACT;AAAA,IACA,UAAU,MAAM;AACd,UAAI,QAAQ,eAAe,IAAI,IAAI;AACnC,UAAI,CAAC,OAAO;AACV,gBAAQ;AAAA,UACN,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,UAAU,MAAM,EAAE,KAAK,MAAM,GAAI,EAAE,KAAK,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,KAAK,GAAI,WAAW,EAAE,UAAU;AAAA,UACjJ;AAAA,QACF;AACA,uBAAe,IAAI,MAAM,KAAK;AAAA,MAChC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/drawings/document.ts"],"sourcesContent":["// The drawings DOCUMENT: the pure rules over the drawing-resource contract's document shape.\n//\n// Nothing here touches a chart, a store or a clock. That is deliberate: what a document means when\n// two surfaces write it, what a deletion does to it, and which of its entries are live are exactly\n// the questions that go wrong in a persistence layer, and they are all decidable from two values.\n//\n// Three rules the module enforces:\n// - A deletion is a TOMBSTONE, never an omission. Two charts hold the same document; if a\n// deletion were just a shorter list, the other chart's copy would put the row back on the next\n// merge, and a drawing the trader deleted would return after a save, a reconnect or a reload.\n// - A merge is not a last-write-wins overwrite. The stored document is the other surface's work\n// and wins by identity and by order; this surface's own additions follow it. Neither side\n// loses a row it made, and neither side resurrects a row the other buried.\n// - Deleting a GROUP deletes the grouping, not the drawings. The members survive, ungrouped, and\n// the group id can never come back.\n//\n// The document's own SHAPE lives here too, beside the rules, because the two only make sense\n// together: the resource contract in `resources.ts` names this the drawings family's body.\n\n/* ── The drawing-resource context ───────────────────────────────────────────────────────────────\n Where a drawings document lives, as a discriminated, versioned context rather than a pair of\n loose fields. The kind IS the sharing rule, so a reader never infers one from which fields\n happen to be set:\n\n chart-local one chart of one layout, on one symbol. Nothing is shared.\n layout-shared every chart of one layout, on one symbol.\n symbol-global every chart the host mounts, on one symbol.\n\n `version` is the context's own format, not the document's: a store keys its rows by the whole\n context, so a later kind or field arrives as a different key rather than as a silently widened\n old one. */\n\nexport const DRAWING_CONTEXT_VERSION = 1\n\nexport type DrawingContextKind = 'chart-local' | 'layout-shared' | 'symbol-global'\n\n/** One chart of one layout, on one symbol. */\nexport interface ChartLocalDrawingContext {\n version: typeof DRAWING_CONTEXT_VERSION\n kind: 'chart-local'\n /** The host's stable identity for the layout the chart is tiled in. */\n layoutId: string\n /** The chart's stable identity WITHIN that layout, so the document is found again after a\n * reload; a per-mount instance id would key a document nothing could ever read back. */\n chartId: string\n symbol: string\n}\n\n/** Every chart of one layout, on one symbol. */\nexport interface LayoutSharedDrawingContext {\n version: typeof DRAWING_CONTEXT_VERSION\n kind: 'layout-shared'\n layoutId: string\n symbol: string\n}\n\n/** Every chart the host mounts, on one symbol. */\nexport interface SymbolGlobalDrawingContext {\n version: typeof DRAWING_CONTEXT_VERSION\n kind: 'symbol-global'\n symbol: string\n}\n\nexport type DrawingResourceContext = ChartLocalDrawingContext | LayoutSharedDrawingContext | SymbolGlobalDrawingContext\n\n/** The drawings document format. Bumping this is the only reason a reader ever branches. */\nexport const DRAWING_DOCUMENT_VERSION = 1\n\n/** One drawing in a document. The ENVELOPE is structured so a restore is validated without parsing\n * the drawing itself: the id is stable for the drawing's life, `source` names what owns it (the\n * main series, or an indicator's own source), `pane` names where it is drawn, and `type` is its\n * tool. `state` is the drawing's own serialized form and is opaque to the document, the store and\n * the transport. */\nexport interface DrawingEntry {\n id: string\n /** The owning source: `main` for the chart's main series, else an indicator instance's id. */\n source: string\n /** The pane the drawing is drawn in: `main` for the price pane, else the pane owner's id. */\n pane: string\n type: string\n /** Opaque: nothing between the layer and the backend reads it. */\n state: unknown\n /** The group this drawing belongs to, when it belongs to one. */\n group?: string\n}\n\n/** A group of drawings. Membership is ORDERED and holds drawing ids, so a group survives a round\n * trip with its order intact rather than being rebuilt from however a document happened to list\n * its entries. */\nexport interface DrawingGroup {\n id: string\n name?: string\n members: readonly string[]\n}\n\n/** A deletion, kept. A document that listed only what survives lets a concurrent save, a reconnect\n * or a reload resurrect what the trader deleted: the other side still holds the row and a merge\n * takes it back. A tombstone says the deletion happened, and at which document revision, so the\n * merge drops it instead. */\nexport interface DrawingTombstone {\n kind: 'drawing' | 'group'\n id: string\n /** The document revision the deletion was stamped at. */\n at: number\n}\n\n/** One context's drawings document. `revision` is the DOCUMENT's own counter, which orders\n * tombstones and detects a stale apply; it is not the store's `ResourceRef.revision`, which stays\n * opaque and is the store's alone. */\nexport interface DrawingsBody {\n version: typeof DRAWING_DOCUMENT_VERSION\n context: DrawingResourceContext\n revision: number\n entries: readonly DrawingEntry[]\n groups: readonly DrawingGroup[]\n tombstones: readonly DrawingTombstone[]\n}\n\n\n/** The canonical key for a drawing-resource context: equal contexts key equally, and no two\n * different contexts collide. The parts join on an escaped null, which no symbol, layout id or\n * chart id carries, so a symbol ending in a separator cannot spell another context's key. The\n * kind and version lead, so a later kind is a different key rather than a widened old one. */\nexport function drawingContextKey(context: DrawingResourceContext): string {\n const parts: string[] = [String(context.version), context.kind]\n if (context.kind === 'chart-local') parts.push(context.layoutId, context.chartId)\n else if (context.kind === 'layout-shared') parts.push(context.layoutId)\n parts.push(context.symbol)\n return parts.join('\\u0000')\n}\n\n/** Whether two contexts name the same document. */\nexport const sameDrawingContext = (a: DrawingResourceContext, b: DrawingResourceContext): boolean => drawingContextKey(a) === drawingContextKey(b)\n\n/** A document with nothing in it, at revision 0: what a context that has never been written reads\n * as, so every caller works over a document rather than over a null. */\nexport function emptyDrawingDocument(context: DrawingResourceContext): DrawingsBody {\n return { version: DRAWING_DOCUMENT_VERSION, context, revision: 0, entries: [], groups: [], tombstones: [] }\n}\n\nconst tombstoneKey = (kind: DrawingTombstone['kind'], id: string): string => `${kind}\\u0000${id}`\n\n/** The tombstones of both documents, one per (kind, id), each at the later revision it was seen at. */\nfunction mergeTombstones(a: readonly DrawingTombstone[], b: readonly DrawingTombstone[]): DrawingTombstone[] {\n const byKey = new Map<string, DrawingTombstone>()\n for (const stone of [...a, ...b]) {\n const key = tombstoneKey(stone.kind, stone.id)\n const held = byKey.get(key)\n if (!held || stone.at > held.at) byKey.set(key, { kind: stone.kind, id: stone.id, at: stone.at })\n }\n return [...byKey.values()]\n}\n\nconst buriedSet = (tombstones: readonly DrawingTombstone[], kind: DrawingTombstone['kind']): Set<string> =>\n new Set(tombstones.filter((stone) => stone.kind === kind).map((stone) => stone.id))\n\n/** Whether a document buries this id. Package-internal, beside the rules it serves: the layer asks\n * it to tell a live entry from one whose group is gone. */\nexport const drawingBuried = (document: DrawingsBody, kind: DrawingTombstone['kind'], id: string): boolean =>\n document.tombstones.some((stone) => stone.kind === kind && stone.id === id)\n\n/** The entries a document actually holds: nothing buried, no duplicate id, and no membership of a\n * group that is gone (the drawing survives, its grouping does not). */\nexport function liveDrawingEntries(document: DrawingsBody): DrawingEntry[] {\n const buriedDrawings = buriedSet(document.tombstones, 'drawing')\n const groups = new Set(liveDrawingGroups(document).map((group) => group.id))\n const out: DrawingEntry[] = []\n const seen = new Set<string>()\n for (const entry of document.entries) {\n if (buriedDrawings.has(entry.id) || seen.has(entry.id)) continue\n seen.add(entry.id)\n out.push(entry.group !== undefined && !groups.has(entry.group) ? omitGroup(entry) : entry)\n }\n return out\n}\n\nconst omitGroup = (entry: DrawingEntry): DrawingEntry => {\n const { group: _buried, ...rest } = entry\n return rest\n}\n\n/** The groups a document actually holds: nothing buried, no duplicate id, and no member that is\n * buried or absent, so a group never names a drawing that is not there. */\nexport function liveDrawingGroups(document: DrawingsBody): DrawingGroup[] {\n const buriedGroups = buriedSet(document.tombstones, 'group')\n const buriedDrawings = buriedSet(document.tombstones, 'drawing')\n const present = new Set(document.entries.filter((entry) => !buriedDrawings.has(entry.id)).map((entry) => entry.id))\n const out: DrawingGroup[] = []\n const seen = new Set<string>()\n for (const group of document.groups) {\n if (buriedGroups.has(group.id) || seen.has(group.id)) continue\n seen.add(group.id)\n out.push({ ...group, members: group.members.filter((id) => present.has(id)) })\n }\n return out\n}\n\n/** Replace what a document holds and stamp the difference. Every id the document held and the next\n * state does not is buried at the new revision; every id that arrives is kept in the order it\n * arrives in. One verb, one revision bump, so a save can never write entries at one revision and\n * groups at another. */\nexport function reviseDrawingDocument(\n document: DrawingsBody,\n next: { entries?: readonly DrawingEntry[]; groups?: readonly DrawingGroup[] },\n): DrawingsBody {\n const revision = document.revision + 1\n const entries = next.entries ?? liveDrawingEntries(document)\n const groups = next.groups ?? liveDrawingGroups(document)\n const keptDrawings = new Set(entries.map((entry) => entry.id))\n const keptGroups = new Set(groups.map((group) => group.id))\n const buried: DrawingTombstone[] = []\n for (const entry of liveDrawingEntries(document)) if (!keptDrawings.has(entry.id)) buried.push({ kind: 'drawing', id: entry.id, at: revision })\n for (const group of liveDrawingGroups(document)) if (!keptGroups.has(group.id)) buried.push({ kind: 'group', id: group.id, at: revision })\n return {\n version: DRAWING_DOCUMENT_VERSION,\n context: document.context,\n revision,\n entries: [...entries],\n groups: [...groups],\n tombstones: mergeTombstones(document.tombstones, buried),\n }\n}\n\n/** Merge the document another surface wrote first with this surface's own. The stored rows win by\n * identity and keep the stored order, because they are what everyone else can already see; rows\n * only this surface holds follow, because they are work the other surface never saw. Every\n * deletion either side made survives the merge. The result's revision is past both, so the write\n * that carries it is the newer document by either side's counter. */\nexport function mergeDrawingDocuments(stored: DrawingsBody, mine: DrawingsBody): DrawingsBody {\n const tombstones = mergeTombstones(stored.tombstones, mine.tombstones)\n const buriedDrawings = buriedSet(tombstones, 'drawing')\n const buriedGroups = buriedSet(tombstones, 'group')\n\n const entries: DrawingEntry[] = []\n const seen = new Set<string>()\n for (const entry of [...stored.entries, ...mine.entries]) {\n if (seen.has(entry.id) || buriedDrawings.has(entry.id)) continue\n seen.add(entry.id)\n entries.push(entry.group !== undefined && buriedGroups.has(entry.group) ? omitGroup(entry) : entry)\n }\n\n const groups: DrawingGroup[] = []\n const byId = new Map<string, DrawingGroup>()\n for (const group of [...stored.groups, ...mine.groups]) {\n if (buriedGroups.has(group.id)) continue\n const held = byId.get(group.id)\n if (!held) {\n const row = { ...group, members: [...group.members] }\n byId.set(group.id, row)\n groups.push(row)\n continue\n }\n // One group written by both surfaces: the stored order stands and the members only this\n // surface knows about are appended, the same rule the entries follow.\n for (const id of group.members) if (!held.members.includes(id)) (held.members as string[]).push(id)\n }\n const present = new Set(entries.map((entry) => entry.id))\n\n return {\n version: DRAWING_DOCUMENT_VERSION,\n context: stored.context,\n revision: Math.max(stored.revision, mine.revision) + 1,\n entries,\n groups: groups.map((group) => ({ ...group, members: group.members.filter((id) => present.has(id)) })),\n tombstones,\n }\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null\n\nconst entryOf = (value: unknown): DrawingEntry | null => {\n if (!isRecord(value)) return null\n const { id, source, pane, type, group } = value\n if (typeof id !== 'string' || !id || typeof source !== 'string' || typeof pane !== 'string' || typeof type !== 'string') return null\n return { id, source, pane, type, state: value.state, ...(typeof group === 'string' ? { group } : {}) }\n}\n\nconst groupOf = (value: unknown): DrawingGroup | null => {\n if (!isRecord(value)) return null\n const { id, name, members } = value\n if (typeof id !== 'string' || !id || !Array.isArray(members)) return null\n return { id, ...(typeof name === 'string' ? { name } : {}), members: members.filter((m): m is string => typeof m === 'string') }\n}\n\n/** The context a payload states, when it states a whole one this build understands. */\nconst contextOf = (value: unknown): DrawingResourceContext | null => {\n if (!isRecord(value) || value.version !== DRAWING_CONTEXT_VERSION) return null\n const { kind, symbol, layoutId, chartId } = value\n if (typeof symbol !== 'string') return null\n if (kind === 'symbol-global') return { version: DRAWING_CONTEXT_VERSION, kind, symbol }\n if (typeof layoutId !== 'string') return null\n if (kind === 'layout-shared') return { version: DRAWING_CONTEXT_VERSION, kind, layoutId, symbol }\n if (kind === 'chart-local' && typeof chartId === 'string') return { version: DRAWING_CONTEXT_VERSION, kind, layoutId, chartId, symbol }\n return null\n}\n\nconst tombstoneOf = (value: unknown): DrawingTombstone | null => {\n if (!isRecord(value)) return null\n const { kind, id, at } = value\n if ((kind !== 'drawing' && kind !== 'group') || typeof id !== 'string' || !id) return null\n return { kind, id, at: typeof at === 'number' ? at : 0 }\n}\n\n/** Read whatever a transport handed back as a document for this context. TOTAL: a null, a string, a\n * wrong version, a junk row or a whole junk body reads as the empty document, never a throw, so a\n * host can hand the chart what its backend returned without guarding it first. The context is the\n * caller's, not the payload's: a document is identified by where it was read from, and a body\n * claiming another context is not merged into this one. */\nexport function parseDrawingDocument(value: unknown, context: DrawingResourceContext): DrawingsBody {\n const raw: unknown = typeof value === 'string' ? safeJson(value) : value\n if (!isRecord(raw) || raw.version !== DRAWING_DOCUMENT_VERSION) return emptyDrawingDocument(context)\n const stated = contextOf(raw.context)\n if (stated && !sameDrawingContext(stated, context)) return emptyDrawingDocument(context)\n return {\n version: DRAWING_DOCUMENT_VERSION,\n context,\n revision: typeof raw.revision === 'number' && Number.isFinite(raw.revision) ? raw.revision : 0,\n entries: Array.isArray(raw.entries) ? raw.entries.map(entryOf).filter((e): e is DrawingEntry => e !== null) : [],\n groups: Array.isArray(raw.groups) ? raw.groups.map(groupOf).filter((g): g is DrawingGroup => g !== null) : [],\n tombstones: Array.isArray(raw.tombstones) ? raw.tombstones.map(tombstoneOf).filter((t): t is DrawingTombstone => t !== null) : [],\n }\n}\n\nconst safeJson = (text: string): unknown => {\n try {\n return JSON.parse(text)\n } catch {\n return null\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/drawings/document.ts"],"sourcesContent":["// The drawings DOCUMENT: the pure rules over the drawing-resource contract's document shape.\n//\n// Nothing here touches a chart, a store or a clock. That is deliberate: what a document means when\n// two surfaces write it, what a deletion does to it, and which of its entries are live are exactly\n// the questions that go wrong in a persistence layer, and they are all decidable from two values.\n//\n// Three rules the module enforces:\n// - A deletion is a TOMBSTONE, never an omission. Two charts hold the same document; if a\n// deletion were just a shorter list, the other chart's copy would put the row back on the next\n// merge, and a drawing the viewer deleted would return after a save, a reconnect or a reload.\n// - A merge is not a last-write-wins overwrite. The stored document is the other surface's work\n// and wins by identity and by order; this surface's own additions follow it. Neither side\n// loses a row it made, and neither side resurrects a row the other buried.\n// - Deleting a GROUP deletes the grouping, not the drawings. The members survive, ungrouped, and\n// the group id can never come back.\n//\n// The document's own SHAPE lives here too, beside the rules, because the two only make sense\n// together: the resource contract in `resources.ts` names this the drawings family's body.\n\n/* ── The drawing-resource context ───────────────────────────────────────────────────────────────\n Where a drawings document lives, as a discriminated, versioned context rather than a pair of\n loose fields. The kind IS the sharing rule, so a reader never infers one from which fields\n happen to be set:\n\n chart-local one chart of one layout, on one symbol. Nothing is shared.\n layout-shared every chart of one layout, on one symbol.\n symbol-global every chart the host mounts, on one symbol.\n\n `version` is the context's own format, not the document's: a store keys its rows by the whole\n context, so a later kind or field arrives as a different key rather than as a silently widened\n old one. */\n\nexport const DRAWING_CONTEXT_VERSION = 1\n\nexport type DrawingContextKind = 'chart-local' | 'layout-shared' | 'symbol-global'\n\n/** One chart of one layout, on one symbol. */\nexport interface ChartLocalDrawingContext {\n version: typeof DRAWING_CONTEXT_VERSION\n kind: 'chart-local'\n /** The host's stable identity for the layout the chart is tiled in. */\n layoutId: string\n /** The chart's stable identity WITHIN that layout, so the document is found again after a\n * reload; a per-mount instance id would key a document nothing could ever read back. */\n chartId: string\n symbol: string\n}\n\n/** Every chart of one layout, on one symbol. */\nexport interface LayoutSharedDrawingContext {\n version: typeof DRAWING_CONTEXT_VERSION\n kind: 'layout-shared'\n layoutId: string\n symbol: string\n}\n\n/** Every chart the host mounts, on one symbol. */\nexport interface SymbolGlobalDrawingContext {\n version: typeof DRAWING_CONTEXT_VERSION\n kind: 'symbol-global'\n symbol: string\n}\n\nexport type DrawingResourceContext = ChartLocalDrawingContext | LayoutSharedDrawingContext | SymbolGlobalDrawingContext\n\n/** The drawings document format. Bumping this is the only reason a reader ever branches. */\nexport const DRAWING_DOCUMENT_VERSION = 1\n\n/** One drawing in a document. The ENVELOPE is structured so a restore is validated without parsing\n * the drawing itself: the id is stable for the drawing's life, `source` names what owns it (the\n * main series, or an indicator's own source), `pane` names where it is drawn, and `type` is its\n * tool. `state` is the drawing's own serialized form and is opaque to the document, the store and\n * the transport. */\nexport interface DrawingEntry {\n id: string\n /** The owning source: `main` for the chart's main series, else an indicator instance's id. */\n source: string\n /** The pane the drawing is drawn in: `main` for the price pane, else the pane owner's id. */\n pane: string\n type: string\n /** Opaque: nothing between the layer and the backend reads it. */\n state: unknown\n /** The group this drawing belongs to, when it belongs to one. */\n group?: string\n}\n\n/** A group of drawings. Membership is ORDERED and holds drawing ids, so a group survives a round\n * trip with its order intact rather than being rebuilt from however a document happened to list\n * its entries. */\nexport interface DrawingGroup {\n id: string\n name?: string\n members: readonly string[]\n}\n\n/** A deletion, kept. A document that listed only what survives lets a concurrent save, a reconnect\n * or a reload resurrect what the viewer deleted: the other side still holds the row and a merge\n * takes it back. A tombstone says the deletion happened, and at which document revision, so the\n * merge drops it instead. */\nexport interface DrawingTombstone {\n kind: 'drawing' | 'group'\n id: string\n /** The document revision the deletion was stamped at. */\n at: number\n}\n\n/** One context's drawings document. `revision` is the DOCUMENT's own counter, which orders\n * tombstones and detects a stale apply; it is not the store's `ResourceRef.revision`, which stays\n * opaque and is the store's alone. */\nexport interface DrawingsBody {\n version: typeof DRAWING_DOCUMENT_VERSION\n context: DrawingResourceContext\n revision: number\n entries: readonly DrawingEntry[]\n groups: readonly DrawingGroup[]\n tombstones: readonly DrawingTombstone[]\n}\n\n\n/** The canonical key for a drawing-resource context: equal contexts key equally, and no two\n * different contexts collide. The parts join on an escaped null, which no symbol, layout id or\n * chart id carries, so a symbol ending in a separator cannot spell another context's key. The\n * kind and version lead, so a later kind is a different key rather than a widened old one. */\nexport function drawingContextKey(context: DrawingResourceContext): string {\n const parts: string[] = [String(context.version), context.kind]\n if (context.kind === 'chart-local') parts.push(context.layoutId, context.chartId)\n else if (context.kind === 'layout-shared') parts.push(context.layoutId)\n parts.push(context.symbol)\n return parts.join('\\u0000')\n}\n\n/** Whether two contexts name the same document. */\nexport const sameDrawingContext = (a: DrawingResourceContext, b: DrawingResourceContext): boolean => drawingContextKey(a) === drawingContextKey(b)\n\n/** A document with nothing in it, at revision 0: what a context that has never been written reads\n * as, so every caller works over a document rather than over a null. */\nexport function emptyDrawingDocument(context: DrawingResourceContext): DrawingsBody {\n return { version: DRAWING_DOCUMENT_VERSION, context, revision: 0, entries: [], groups: [], tombstones: [] }\n}\n\nconst tombstoneKey = (kind: DrawingTombstone['kind'], id: string): string => `${kind}\\u0000${id}`\n\n/** The tombstones of both documents, one per (kind, id), each at the later revision it was seen at. */\nfunction mergeTombstones(a: readonly DrawingTombstone[], b: readonly DrawingTombstone[]): DrawingTombstone[] {\n const byKey = new Map<string, DrawingTombstone>()\n for (const stone of [...a, ...b]) {\n const key = tombstoneKey(stone.kind, stone.id)\n const held = byKey.get(key)\n if (!held || stone.at > held.at) byKey.set(key, { kind: stone.kind, id: stone.id, at: stone.at })\n }\n return [...byKey.values()]\n}\n\nconst buriedSet = (tombstones: readonly DrawingTombstone[], kind: DrawingTombstone['kind']): Set<string> =>\n new Set(tombstones.filter((stone) => stone.kind === kind).map((stone) => stone.id))\n\n/** Whether a document buries this id. Package-internal, beside the rules it serves: the layer asks\n * it to tell a live entry from one whose group is gone. */\nexport const drawingBuried = (document: DrawingsBody, kind: DrawingTombstone['kind'], id: string): boolean =>\n document.tombstones.some((stone) => stone.kind === kind && stone.id === id)\n\n/** The entries a document actually holds: nothing buried, no duplicate id, and no membership of a\n * group that is gone (the drawing survives, its grouping does not). */\nexport function liveDrawingEntries(document: DrawingsBody): DrawingEntry[] {\n const buriedDrawings = buriedSet(document.tombstones, 'drawing')\n const groups = new Set(liveDrawingGroups(document).map((group) => group.id))\n const out: DrawingEntry[] = []\n const seen = new Set<string>()\n for (const entry of document.entries) {\n if (buriedDrawings.has(entry.id) || seen.has(entry.id)) continue\n seen.add(entry.id)\n out.push(entry.group !== undefined && !groups.has(entry.group) ? omitGroup(entry) : entry)\n }\n return out\n}\n\nconst omitGroup = (entry: DrawingEntry): DrawingEntry => {\n const { group: _buried, ...rest } = entry\n return rest\n}\n\n/** The groups a document actually holds: nothing buried, no duplicate id, and no member that is\n * buried or absent, so a group never names a drawing that is not there. */\nexport function liveDrawingGroups(document: DrawingsBody): DrawingGroup[] {\n const buriedGroups = buriedSet(document.tombstones, 'group')\n const buriedDrawings = buriedSet(document.tombstones, 'drawing')\n const present = new Set(document.entries.filter((entry) => !buriedDrawings.has(entry.id)).map((entry) => entry.id))\n const out: DrawingGroup[] = []\n const seen = new Set<string>()\n for (const group of document.groups) {\n if (buriedGroups.has(group.id) || seen.has(group.id)) continue\n seen.add(group.id)\n out.push({ ...group, members: group.members.filter((id) => present.has(id)) })\n }\n return out\n}\n\n/** Replace what a document holds and stamp the difference. Every id the document held and the next\n * state does not is buried at the new revision; every id that arrives is kept in the order it\n * arrives in. One verb, one revision bump, so a save can never write entries at one revision and\n * groups at another. */\nexport function reviseDrawingDocument(\n document: DrawingsBody,\n next: { entries?: readonly DrawingEntry[]; groups?: readonly DrawingGroup[] },\n): DrawingsBody {\n const revision = document.revision + 1\n const entries = next.entries ?? liveDrawingEntries(document)\n const groups = next.groups ?? liveDrawingGroups(document)\n const keptDrawings = new Set(entries.map((entry) => entry.id))\n const keptGroups = new Set(groups.map((group) => group.id))\n const buried: DrawingTombstone[] = []\n for (const entry of liveDrawingEntries(document)) if (!keptDrawings.has(entry.id)) buried.push({ kind: 'drawing', id: entry.id, at: revision })\n for (const group of liveDrawingGroups(document)) if (!keptGroups.has(group.id)) buried.push({ kind: 'group', id: group.id, at: revision })\n return {\n version: DRAWING_DOCUMENT_VERSION,\n context: document.context,\n revision,\n entries: [...entries],\n groups: [...groups],\n tombstones: mergeTombstones(document.tombstones, buried),\n }\n}\n\n/** Merge the document another surface wrote first with this surface's own. The stored rows win by\n * identity and keep the stored order, because they are what everyone else can already see; rows\n * only this surface holds follow, because they are work the other surface never saw. Every\n * deletion either side made survives the merge. The result's revision is past both, so the write\n * that carries it is the newer document by either side's counter. */\nexport function mergeDrawingDocuments(stored: DrawingsBody, mine: DrawingsBody): DrawingsBody {\n const tombstones = mergeTombstones(stored.tombstones, mine.tombstones)\n const buriedDrawings = buriedSet(tombstones, 'drawing')\n const buriedGroups = buriedSet(tombstones, 'group')\n\n const entries: DrawingEntry[] = []\n const seen = new Set<string>()\n for (const entry of [...stored.entries, ...mine.entries]) {\n if (seen.has(entry.id) || buriedDrawings.has(entry.id)) continue\n seen.add(entry.id)\n entries.push(entry.group !== undefined && buriedGroups.has(entry.group) ? omitGroup(entry) : entry)\n }\n\n const groups: DrawingGroup[] = []\n const byId = new Map<string, DrawingGroup>()\n for (const group of [...stored.groups, ...mine.groups]) {\n if (buriedGroups.has(group.id)) continue\n const held = byId.get(group.id)\n if (!held) {\n const row = { ...group, members: [...group.members] }\n byId.set(group.id, row)\n groups.push(row)\n continue\n }\n // One group written by both surfaces: the stored order stands and the members only this\n // surface knows about are appended, the same rule the entries follow.\n for (const id of group.members) if (!held.members.includes(id)) (held.members as string[]).push(id)\n }\n const present = new Set(entries.map((entry) => entry.id))\n\n return {\n version: DRAWING_DOCUMENT_VERSION,\n context: stored.context,\n revision: Math.max(stored.revision, mine.revision) + 1,\n entries,\n groups: groups.map((group) => ({ ...group, members: group.members.filter((id) => present.has(id)) })),\n tombstones,\n }\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null\n\nconst entryOf = (value: unknown): DrawingEntry | null => {\n if (!isRecord(value)) return null\n const { id, source, pane, type, group } = value\n if (typeof id !== 'string' || !id || typeof source !== 'string' || typeof pane !== 'string' || typeof type !== 'string') return null\n return { id, source, pane, type, state: value.state, ...(typeof group === 'string' ? { group } : {}) }\n}\n\nconst groupOf = (value: unknown): DrawingGroup | null => {\n if (!isRecord(value)) return null\n const { id, name, members } = value\n if (typeof id !== 'string' || !id || !Array.isArray(members)) return null\n return { id, ...(typeof name === 'string' ? { name } : {}), members: members.filter((m): m is string => typeof m === 'string') }\n}\n\n/** The context a payload states, when it states a whole one this build understands. */\nconst contextOf = (value: unknown): DrawingResourceContext | null => {\n if (!isRecord(value) || value.version !== DRAWING_CONTEXT_VERSION) return null\n const { kind, symbol, layoutId, chartId } = value\n if (typeof symbol !== 'string') return null\n if (kind === 'symbol-global') return { version: DRAWING_CONTEXT_VERSION, kind, symbol }\n if (typeof layoutId !== 'string') return null\n if (kind === 'layout-shared') return { version: DRAWING_CONTEXT_VERSION, kind, layoutId, symbol }\n if (kind === 'chart-local' && typeof chartId === 'string') return { version: DRAWING_CONTEXT_VERSION, kind, layoutId, chartId, symbol }\n return null\n}\n\nconst tombstoneOf = (value: unknown): DrawingTombstone | null => {\n if (!isRecord(value)) return null\n const { kind, id, at } = value\n if ((kind !== 'drawing' && kind !== 'group') || typeof id !== 'string' || !id) return null\n return { kind, id, at: typeof at === 'number' ? at : 0 }\n}\n\n/** Read whatever a transport handed back as a document for this context. TOTAL: a null, a string, a\n * wrong version, a junk row or a whole junk body reads as the empty document, never a throw, so a\n * host can hand the chart what its backend returned without guarding it first. The context is the\n * caller's, not the payload's: a document is identified by where it was read from, and a body\n * claiming another context is not merged into this one. */\nexport function parseDrawingDocument(value: unknown, context: DrawingResourceContext): DrawingsBody {\n const raw: unknown = typeof value === 'string' ? safeJson(value) : value\n if (!isRecord(raw) || raw.version !== DRAWING_DOCUMENT_VERSION) return emptyDrawingDocument(context)\n const stated = contextOf(raw.context)\n if (stated && !sameDrawingContext(stated, context)) return emptyDrawingDocument(context)\n return {\n version: DRAWING_DOCUMENT_VERSION,\n context,\n revision: typeof raw.revision === 'number' && Number.isFinite(raw.revision) ? raw.revision : 0,\n entries: Array.isArray(raw.entries) ? raw.entries.map(entryOf).filter((e): e is DrawingEntry => e !== null) : [],\n groups: Array.isArray(raw.groups) ? raw.groups.map(groupOf).filter((g): g is DrawingGroup => g !== null) : [],\n tombstones: Array.isArray(raw.tombstones) ? raw.tombstones.map(tombstoneOf).filter((t): t is DrawingTombstone => t !== null) : [],\n }\n}\n\nconst safeJson = (text: string): unknown => {\n try {\n return JSON.parse(text)\n } catch {\n return null\n }\n}\n"],"mappings":";AAgCO,IAAM,0BAA0B;AAkChC,IAAM,2BAA2B;AAyDjC,SAAS,kBAAkB,SAAyC;AACzE,QAAM,QAAkB,CAAC,OAAO,QAAQ,OAAO,GAAG,QAAQ,IAAI;AAC9D,MAAI,QAAQ,SAAS,cAAe,OAAM,KAAK,QAAQ,UAAU,QAAQ,OAAO;AAAA,WACvE,QAAQ,SAAS,gBAAiB,OAAM,KAAK,QAAQ,QAAQ;AACtE,QAAM,KAAK,QAAQ,MAAM;AACzB,SAAO,MAAM,KAAK,IAAQ;AAC5B;AAGO,IAAM,qBAAqB,CAAC,GAA2B,MAAuC,kBAAkB,CAAC,MAAM,kBAAkB,CAAC;AAI1I,SAAS,qBAAqB,SAA+C;AAClF,SAAO,EAAE,SAAS,0BAA0B,SAAS,UAAU,GAAG,SAAS,CAAC,GAAG,QAAQ,CAAC,GAAG,YAAY,CAAC,EAAE;AAC5G;AAEA,IAAM,eAAe,CAAC,MAAgC,OAAuB,GAAG,IAAI,KAAS,EAAE;AAG/F,SAAS,gBAAgB,GAAgC,GAAoD;AAC3G,QAAM,QAAQ,oBAAI,IAA8B;AAChD,aAAW,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG;AAChC,UAAM,MAAM,aAAa,MAAM,MAAM,MAAM,EAAE;AAC7C,UAAM,OAAO,MAAM,IAAI,GAAG;AAC1B,QAAI,CAAC,QAAQ,MAAM,KAAK,KAAK,GAAI,OAAM,IAAI,KAAK,EAAE,MAAM,MAAM,MAAM,IAAI,MAAM,IAAI,IAAI,MAAM,GAAG,CAAC;AAAA,EAClG;AACA,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAC3B;AAEA,IAAM,YAAY,CAAC,YAAyC,SAC1D,IAAI,IAAI,WAAW,OAAO,CAAC,UAAU,MAAM,SAAS,IAAI,EAAE,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AAI7E,IAAM,gBAAgB,CAAC,UAAwB,MAAgC,OACpF,SAAS,WAAW,KAAK,CAAC,UAAU,MAAM,SAAS,QAAQ,MAAM,OAAO,EAAE;AAIrE,SAAS,mBAAmB,UAAwC;AACzE,QAAM,iBAAiB,UAAU,SAAS,YAAY,SAAS;AAC/D,QAAM,SAAS,IAAI,IAAI,kBAAkB,QAAQ,EAAE,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AAC3E,QAAM,MAAsB,CAAC;AAC7B,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,SAAS,SAAS,SAAS;AACpC,QAAI,eAAe,IAAI,MAAM,EAAE,KAAK,KAAK,IAAI,MAAM,EAAE,EAAG;AACxD,SAAK,IAAI,MAAM,EAAE;AACjB,QAAI,KAAK,MAAM,UAAU,UAAa,CAAC,OAAO,IAAI,MAAM,KAAK,IAAI,UAAU,KAAK,IAAI,KAAK;AAAA,EAC3F;AACA,SAAO;AACT;AAEA,IAAM,YAAY,CAAC,UAAsC;AACvD,QAAM,EAAE,OAAO,SAAS,GAAG,KAAK,IAAI;AACpC,SAAO;AACT;AAIO,SAAS,kBAAkB,UAAwC;AACxE,QAAM,eAAe,UAAU,SAAS,YAAY,OAAO;AAC3D,QAAM,iBAAiB,UAAU,SAAS,YAAY,SAAS;AAC/D,QAAM,UAAU,IAAI,IAAI,SAAS,QAAQ,OAAO,CAAC,UAAU,CAAC,eAAe,IAAI,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AAClH,QAAM,MAAsB,CAAC;AAC7B,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,SAAS,SAAS,QAAQ;AACnC,QAAI,aAAa,IAAI,MAAM,EAAE,KAAK,KAAK,IAAI,MAAM,EAAE,EAAG;AACtD,SAAK,IAAI,MAAM,EAAE;AACjB,QAAI,KAAK,EAAE,GAAG,OAAO,SAAS,MAAM,QAAQ,OAAO,CAAC,OAAO,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;AAAA,EAC/E;AACA,SAAO;AACT;AAMO,SAAS,sBACd,UACA,MACc;AACd,QAAM,WAAW,SAAS,WAAW;AACrC,QAAM,UAAU,KAAK,WAAW,mBAAmB,QAAQ;AAC3D,QAAM,SAAS,KAAK,UAAU,kBAAkB,QAAQ;AACxD,QAAM,eAAe,IAAI,IAAI,QAAQ,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AAC7D,QAAM,aAAa,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AAC1D,QAAM,SAA6B,CAAC;AACpC,aAAW,SAAS,mBAAmB,QAAQ,EAAG,KAAI,CAAC,aAAa,IAAI,MAAM,EAAE,EAAG,QAAO,KAAK,EAAE,MAAM,WAAW,IAAI,MAAM,IAAI,IAAI,SAAS,CAAC;AAC9I,aAAW,SAAS,kBAAkB,QAAQ,EAAG,KAAI,CAAC,WAAW,IAAI,MAAM,EAAE,EAAG,QAAO,KAAK,EAAE,MAAM,SAAS,IAAI,MAAM,IAAI,IAAI,SAAS,CAAC;AACzI,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,SAAS;AAAA,IAClB;AAAA,IACA,SAAS,CAAC,GAAG,OAAO;AAAA,IACpB,QAAQ,CAAC,GAAG,MAAM;AAAA,IAClB,YAAY,gBAAgB,SAAS,YAAY,MAAM;AAAA,EACzD;AACF;AAOO,SAAS,sBAAsB,QAAsB,MAAkC;AAC5F,QAAM,aAAa,gBAAgB,OAAO,YAAY,KAAK,UAAU;AACrE,QAAM,iBAAiB,UAAU,YAAY,SAAS;AACtD,QAAM,eAAe,UAAU,YAAY,OAAO;AAElD,QAAM,UAA0B,CAAC;AACjC,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,SAAS,CAAC,GAAG,OAAO,SAAS,GAAG,KAAK,OAAO,GAAG;AACxD,QAAI,KAAK,IAAI,MAAM,EAAE,KAAK,eAAe,IAAI,MAAM,EAAE,EAAG;AACxD,SAAK,IAAI,MAAM,EAAE;AACjB,YAAQ,KAAK,MAAM,UAAU,UAAa,aAAa,IAAI,MAAM,KAAK,IAAI,UAAU,KAAK,IAAI,KAAK;AAAA,EACpG;AAEA,QAAM,SAAyB,CAAC;AAChC,QAAM,OAAO,oBAAI,IAA0B;AAC3C,aAAW,SAAS,CAAC,GAAG,OAAO,QAAQ,GAAG,KAAK,MAAM,GAAG;AACtD,QAAI,aAAa,IAAI,MAAM,EAAE,EAAG;AAChC,UAAM,OAAO,KAAK,IAAI,MAAM,EAAE;AAC9B,QAAI,CAAC,MAAM;AACT,YAAM,MAAM,EAAE,GAAG,OAAO,SAAS,CAAC,GAAG,MAAM,OAAO,EAAE;AACpD,WAAK,IAAI,MAAM,IAAI,GAAG;AACtB,aAAO,KAAK,GAAG;AACf;AAAA,IACF;AAGA,eAAW,MAAM,MAAM,QAAS,KAAI,CAAC,KAAK,QAAQ,SAAS,EAAE,EAAG,CAAC,KAAK,QAAqB,KAAK,EAAE;AAAA,EACpG;AACA,QAAM,UAAU,IAAI,IAAI,QAAQ,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AAExD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,OAAO;AAAA,IAChB,UAAU,KAAK,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI;AAAA,IACrD;AAAA,IACA,QAAQ,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,OAAO,SAAS,MAAM,QAAQ,OAAO,CAAC,OAAO,QAAQ,IAAI,EAAE,CAAC,EAAE,EAAE;AAAA,IACpG;AAAA,EACF;AACF;AAEA,IAAM,WAAW,CAAC,UAAqD,OAAO,UAAU,YAAY,UAAU;AAE9G,IAAM,UAAU,CAAC,UAAwC;AACvD,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,EAAE,IAAI,QAAQ,MAAM,MAAM,MAAM,IAAI;AAC1C,MAAI,OAAO,OAAO,YAAY,CAAC,MAAM,OAAO,WAAW,YAAY,OAAO,SAAS,YAAY,OAAO,SAAS,SAAU,QAAO;AAChI,SAAO,EAAE,IAAI,QAAQ,MAAM,MAAM,OAAO,MAAM,OAAO,GAAI,OAAO,UAAU,WAAW,EAAE,MAAM,IAAI,CAAC,EAAG;AACvG;AAEA,IAAM,UAAU,CAAC,UAAwC;AACvD,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,EAAE,IAAI,MAAM,QAAQ,IAAI;AAC9B,MAAI,OAAO,OAAO,YAAY,CAAC,MAAM,CAAC,MAAM,QAAQ,OAAO,EAAG,QAAO;AACrE,SAAO,EAAE,IAAI,GAAI,OAAO,SAAS,WAAW,EAAE,KAAK,IAAI,CAAC,GAAI,SAAS,QAAQ,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,EAAE;AACjI;AAGA,IAAM,YAAY,CAAC,UAAkD;AACnE,MAAI,CAAC,SAAS,KAAK,KAAK,MAAM,YAAY,wBAAyB,QAAO;AAC1E,QAAM,EAAE,MAAM,QAAQ,UAAU,QAAQ,IAAI;AAC5C,MAAI,OAAO,WAAW,SAAU,QAAO;AACvC,MAAI,SAAS,gBAAiB,QAAO,EAAE,SAAS,yBAAyB,MAAM,OAAO;AACtF,MAAI,OAAO,aAAa,SAAU,QAAO;AACzC,MAAI,SAAS,gBAAiB,QAAO,EAAE,SAAS,yBAAyB,MAAM,UAAU,OAAO;AAChG,MAAI,SAAS,iBAAiB,OAAO,YAAY,SAAU,QAAO,EAAE,SAAS,yBAAyB,MAAM,UAAU,SAAS,OAAO;AACtI,SAAO;AACT;AAEA,IAAM,cAAc,CAAC,UAA4C;AAC/D,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,EAAE,MAAM,IAAI,GAAG,IAAI;AACzB,MAAK,SAAS,aAAa,SAAS,WAAY,OAAO,OAAO,YAAY,CAAC,GAAI,QAAO;AACtF,SAAO,EAAE,MAAM,IAAI,IAAI,OAAO,OAAO,WAAW,KAAK,EAAE;AACzD;AAOO,SAAS,qBAAqB,OAAgB,SAA+C;AAClG,QAAM,MAAe,OAAO,UAAU,WAAW,SAAS,KAAK,IAAI;AACnE,MAAI,CAAC,SAAS,GAAG,KAAK,IAAI,YAAY,yBAA0B,QAAO,qBAAqB,OAAO;AACnG,QAAM,SAAS,UAAU,IAAI,OAAO;AACpC,MAAI,UAAU,CAAC,mBAAmB,QAAQ,OAAO,EAAG,QAAO,qBAAqB,OAAO;AACvF,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA,UAAU,OAAO,IAAI,aAAa,YAAY,OAAO,SAAS,IAAI,QAAQ,IAAI,IAAI,WAAW;AAAA,IAC7F,SAAS,MAAM,QAAQ,IAAI,OAAO,IAAI,IAAI,QAAQ,IAAI,OAAO,EAAE,OAAO,CAAC,MAAyB,MAAM,IAAI,IAAI,CAAC;AAAA,IAC/G,QAAQ,MAAM,QAAQ,IAAI,MAAM,IAAI,IAAI,OAAO,IAAI,OAAO,EAAE,OAAO,CAAC,MAAyB,MAAM,IAAI,IAAI,CAAC;AAAA,IAC5G,YAAY,MAAM,QAAQ,IAAI,UAAU,IAAI,IAAI,WAAW,IAAI,WAAW,EAAE,OAAO,CAAC,MAA6B,MAAM,IAAI,IAAI,CAAC;AAAA,EAClI;AACF;AAEA,IAAM,WAAW,CAAC,SAA0B;AAC1C,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -6,8 +6,8 @@ var legend = {
|
|
|
6
6
|
"legend.close": "C",
|
|
7
7
|
"legend.change": "{change} ({percent}%)",
|
|
8
8
|
"legend.indicatorSettings": "Indikator-Einstellungen",
|
|
9
|
-
"legend.showRows": "
|
|
10
|
-
"legend.hideRows": "
|
|
9
|
+
"legend.showRows": "Indikatorzeilen anzeigen",
|
|
10
|
+
"legend.hideRows": "Indikatorzeilen ausblenden",
|
|
11
11
|
"legend.restorePane": "Bereich wiederherstellen",
|
|
12
12
|
"legend.collapsePane": "Bereich einklappen",
|
|
13
13
|
"legend.maximizePane": "Bereich maximieren",
|
|
@@ -160,11 +160,11 @@ var replay = {
|
|
|
160
160
|
"replay.speed": "Replay speed",
|
|
161
161
|
"replay.updatesPerSecond": { one: "{count} update per second", other: "{count} updates per second" },
|
|
162
162
|
"replay.oneUpdatePerSeconds": { one: "1 update per {count} second", other: "1 update per {count} seconds" },
|
|
163
|
-
"replay.
|
|
164
|
-
"replay.
|
|
165
|
-
"replay.
|
|
163
|
+
"replay.timeframe": "Update timeframe",
|
|
164
|
+
"replay.timeframeHelp": "How much time each replay update advances. Finer than the chart timeframe, each bar forms from real finer bars.",
|
|
165
|
+
"replay.timeframeNone": "No finer timeframe for this chart timeframe",
|
|
166
166
|
"replay.auto": "Auto",
|
|
167
|
-
"replay.
|
|
167
|
+
"replay.autoSelectTimeframe": "Auto select timeframe"
|
|
168
168
|
};
|
|
169
169
|
|
|
170
170
|
// src/i18n/de/inputs.ts
|
|
@@ -243,17 +243,17 @@ var layouts = {
|
|
|
243
243
|
"layouts.arrangement": "Chart arrangement",
|
|
244
244
|
"layouts.syncInLayout": "Sync in layout",
|
|
245
245
|
"layouts.syncSymbol": "Symbol",
|
|
246
|
-
"layouts.
|
|
246
|
+
"layouts.syncTimeframe": "Zeiteinheit",
|
|
247
247
|
"layouts.syncCrosshair": "Crosshair",
|
|
248
248
|
"layouts.syncTime": "Time",
|
|
249
249
|
"layouts.syncDateRange": "Date range",
|
|
250
250
|
"layouts.syncSymbolTip": "Symbol changes on all charts within the layout",
|
|
251
|
-
"layouts.
|
|
251
|
+
"layouts.syncTimeframeTip": "Die Zeiteinheit \xE4ndert sich in allen Charts des Layouts",
|
|
252
252
|
"layouts.syncCrosshairTip": "Crosshair is synced across all charts within the layout",
|
|
253
253
|
"layouts.syncTimeTip": "When a chart is clicked, all charts within the layout display the same point of time",
|
|
254
254
|
"layouts.syncDateRangeTip": "Date range changes on all charts within the layout",
|
|
255
255
|
"layouts.syncSymbolToggle": "Sync symbol",
|
|
256
|
-
"layouts.
|
|
256
|
+
"layouts.syncTimeframeToggle": "Zeiteinheit synchronisieren",
|
|
257
257
|
"layouts.syncCrosshairToggle": "Sync crosshair",
|
|
258
258
|
"layouts.syncTimeToggle": "Sync time",
|
|
259
259
|
"layouts.syncDateRangeToggle": "Sync date range",
|
|
@@ -285,7 +285,7 @@ var layouts = {
|
|
|
285
285
|
"layouts.loading": "Loading",
|
|
286
286
|
"layouts.emptyNone": "No saved layouts yet.",
|
|
287
287
|
"layouts.openLayoutRow": "Open layout\u2026",
|
|
288
|
-
"layouts.listingFacts": "{symbol}, {
|
|
288
|
+
"layouts.listingFacts": "{symbol}, {timeframe}",
|
|
289
289
|
"layouts.listingDated": "{facts} ({date})",
|
|
290
290
|
"layouts.dialogTitle": "Layouts",
|
|
291
291
|
"layouts.search": "Search",
|
|
@@ -414,7 +414,7 @@ var range = {
|
|
|
414
414
|
"range.oneYear": "1 Jahr",
|
|
415
415
|
"range.fiveYears": "5 Jahre",
|
|
416
416
|
"range.all": "Alle Daten",
|
|
417
|
-
"range.tip": "{range} \xB7 {
|
|
417
|
+
"range.tip": "{range} \xB7 {timeframe}-Balken",
|
|
418
418
|
"range.zoomIn": "Vergr\xF6\xDFern",
|
|
419
419
|
"range.zoomOut": "Verkleinern",
|
|
420
420
|
"range.scrollLeft": "Nach links scrollen",
|
|
@@ -580,7 +580,7 @@ var drawing = {
|
|
|
580
580
|
"drawing.more": "More",
|
|
581
581
|
"drawing.moreActions": "More drawing actions",
|
|
582
582
|
"drawing.visualOrder": "Visual order",
|
|
583
|
-
"drawing.
|
|
583
|
+
"drawing.visibilityOnTimeframes": "Visibility on timeframes",
|
|
584
584
|
"drawing.clone": "Clone",
|
|
585
585
|
"drawing.copy": "Copy",
|
|
586
586
|
"drawing.modifierControl": "Ctrl",
|
|
@@ -602,10 +602,10 @@ var drawing = {
|
|
|
602
602
|
"drawing.sendToBack": "Send to back",
|
|
603
603
|
"drawing.bringForward": "Bring forward",
|
|
604
604
|
"drawing.sendBackward": "Send backward",
|
|
605
|
-
"drawing.visCurrentAndAbove": "Current
|
|
606
|
-
"drawing.visCurrentAndBelow": "Current
|
|
607
|
-
"drawing.visCurrentOnly": "Current
|
|
608
|
-
"drawing.visAll": "All
|
|
605
|
+
"drawing.visCurrentAndAbove": "Current timeframe and above",
|
|
606
|
+
"drawing.visCurrentAndBelow": "Current timeframe and below",
|
|
607
|
+
"drawing.visCurrentOnly": "Current timeframe only",
|
|
608
|
+
"drawing.visAll": "All timeframes",
|
|
609
609
|
"drawing.saveTemplate": "Save drawing template",
|
|
610
610
|
"drawing.templateName": "Template name",
|
|
611
611
|
"drawing.save": "Save",
|
|
@@ -764,7 +764,7 @@ var drawing = {
|
|
|
764
764
|
"drawing.unitDays": "Days",
|
|
765
765
|
"drawing.unitWeeks": "Weeks",
|
|
766
766
|
"drawing.unitMonths": "Months",
|
|
767
|
-
"drawing.
|
|
767
|
+
"drawing.timeframePinnedNote": "A drawing stays on at least one timeframe, so it can always be reached again.",
|
|
768
768
|
"drawing.colorSwatch": "Color {hex}",
|
|
769
769
|
"drawing.customColor": "Custom color",
|
|
770
770
|
"drawing.saturationValue": "Saturation and brightness",
|
|
@@ -858,7 +858,7 @@ var command = {
|
|
|
858
858
|
"command.drawingBringForward": "Bring drawing forward",
|
|
859
859
|
"command.drawingSendBackward": "Send drawing backward",
|
|
860
860
|
"command.drawingHideSelected": "Hide drawing",
|
|
861
|
-
"command.drawingVisibility": "Drawing visibility on
|
|
861
|
+
"command.drawingVisibility": "Drawing visibility on timeframes",
|
|
862
862
|
"command.drawingSettings": "Drawing settings",
|
|
863
863
|
"command.drawingCommitEdit": "Apply drawing settings",
|
|
864
864
|
"command.drawingPlaceImage": "Place image",
|
|
@@ -882,7 +882,7 @@ var command = {
|
|
|
882
882
|
"command.replayStepBack": "Step back",
|
|
883
883
|
"command.replayGoLive": "Replay to the live edge",
|
|
884
884
|
"command.replaySpeed": "Replay speed",
|
|
885
|
-
"command.
|
|
885
|
+
"command.replayTimeframe": "Replay update timeframe",
|
|
886
886
|
"command.timeframeSet": "Timeframe",
|
|
887
887
|
"command.subsessionRegular": "Regular hours",
|
|
888
888
|
"command.subsessionExtended": "Extended hours",
|
|
@@ -1025,4 +1025,4 @@ var de_default = dict;
|
|
|
1025
1025
|
export {
|
|
1026
1026
|
de_default as default
|
|
1027
1027
|
};
|
|
1028
|
-
//# sourceMappingURL=de-
|
|
1028
|
+
//# sourceMappingURL=de-VSW2LHNF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/i18n/de/legend.ts","../src/i18n/de/tools.ts","../src/i18n/de/menu.ts","../src/i18n/de/replay.ts","../src/i18n/de/inputs.ts","../src/i18n/de/session.ts","../src/i18n/de/layouts.ts","../src/i18n/de/host.ts","../src/i18n/de/indicators.ts","../src/i18n/de/timeframe.ts","../src/i18n/de/timezone.ts","../src/i18n/de/range.ts","../src/i18n/de/status.ts","../src/i18n/de/search.ts","../src/i18n/de/drawing.ts","../src/i18n/de/command.ts","../src/i18n/de/chrome.ts","../src/i18n/de/history.ts","../src/i18n/de/picker.ts","../src/i18n/de/settings.ts","../src/i18n/de/toast.ts","../src/i18n/de/index.ts"],"sourcesContent":["import type { Translation } from '../runtime'\nimport type { legend as source } from '../en/legend'\n\nexport const legend: Translation<typeof source> = {\n 'legend.open': 'O',\n 'legend.high': 'H',\n 'legend.low': 'L',\n 'legend.close': 'C',\n 'legend.change': '{change} ({percent}%)',\n 'legend.indicatorSettings': 'Indikator-Einstellungen',\n 'legend.showRows': 'Indikatorzeilen anzeigen',\n 'legend.hideRows': 'Indikatorzeilen ausblenden',\n 'legend.restorePane': 'Bereich wiederherstellen',\n 'legend.collapsePane': 'Bereich einklappen',\n 'legend.maximizePane': 'Bereich maximieren',\n 'legend.showIndicator': 'Indikator anzeigen',\n 'legend.hideIndicator': 'Indikator ausblenden',\n 'legend.scaleNormal': 'Norm',\n 'legend.scaleLog': 'Log',\n 'legend.scalePercent': '%',\n 'legend.scaleIndexed': '100',\n 'legend.changeSymbol': 'Symbol wechseln',\n 'legend.removeCompare': 'Vergleich entfernen',\n 'legend.removeIndicator': 'Remove indicator',\n}\n","import type { Translation } from '../runtime'\nimport type { tools as source } from '../en/tools'\n\nexport const tools: Translation<typeof source> = {\n 'tool.trend_line': 'Trendlinie',\n 'tool.ray': 'Strahl',\n 'tool.info_line': 'Infolinie',\n 'tool.extended': 'Verlängerte Linie',\n 'tool.trend_angle': 'Trendwinkel',\n 'tool.horizontal_line': 'Horizontale Linie',\n 'tool.horizontal_ray': 'Horizontaler Strahl',\n 'tool.vertical_line': 'Vertikale Linie',\n 'tool.cross_line': 'Kreuzlinie',\n 'tool.arrow': 'Pfeil',\n 'tool.rectangle': 'Rechteck',\n 'tool.rotated_rectangle': 'Gedrehtes Rechteck',\n 'tool.ellipse': 'Ellipse',\n 'tool.circle': 'Kreis',\n 'tool.triangle': 'Dreieck',\n 'tool.arc': 'Bogen',\n 'tool.curve': 'Kurve',\n 'tool.double_curve': 'Doppelkurve',\n 'tool.regression_trend': 'Regressionstrend',\n 'tool.parallel_channel': 'Paralleler Kanal',\n 'tool.flat_top_bottom': 'Flacher Ober-/Unterrand',\n 'tool.disjoint_channel': 'Getrennter Kanal',\n 'tool.fib_retracement': 'Fib-Retracement',\n 'tool.fib_trend_ext': 'Trendbasierte Fib-Erweiterung',\n 'tool.fib_channel': 'Fib-Kanal',\n 'tool.fib_timezone': 'Fib-Zeitzone',\n 'tool.fib_speed_resist_fan': 'Fib-Geschwindigkeitswiderstandsfächer',\n 'tool.fib_trend_time': 'Trendbasierte Fib-Zeit',\n 'tool.fib_circles': 'Fib-Kreise',\n 'tool.fib_spiral': 'Fib-Spirale',\n 'tool.fib_speed_resist_arcs': 'Fib-Geschwindigkeitswiderstandsbögen',\n 'tool.fib_wedge': 'Fib-Keil',\n 'tool.pitchfan': 'Pitchfan',\n 'tool.pitchfork': 'Pitchfork',\n 'tool.schiff_pitchfork': 'Schiff-Pitchfork',\n 'tool.schiff_pitchfork_modified': 'Modifizierte Schiff-Pitchfork',\n 'tool.inside_pitchfork': 'Innere Pitchfork',\n 'tool.gannbox': 'Gann-Box',\n 'tool.gannbox_square': 'Gann-Quadrat',\n 'tool.gannbox_fixed': 'Gann-Quadrat fest',\n 'tool.gannbox_fan': 'Gann-Fächer',\n 'tool.xabcd_pattern': 'XABCD-Muster',\n 'tool.cypher_pattern': 'Cypher-Muster',\n 'tool.abcd_pattern': 'ABCD-Muster',\n 'tool.three_drives': 'Three-Drives-Muster',\n 'tool.triangle_pattern': 'Dreiecksmuster',\n 'tool.head_and_shoulders': 'Kopf-Schulter-Formation',\n 'tool.elliott_impulse_wave': 'Elliott-Impulswelle (12345)',\n 'tool.elliott_correction': 'Elliott-Korrektur (ABC)',\n 'tool.elliott_triangle_wave': 'Elliott-Dreieck (ABCDE)',\n 'tool.elliott_double_combo': 'Elliott-Doppelkombination (WXY)',\n 'tool.elliott_triple_combo': 'Elliott-Dreifachkombination (WXYXZ)',\n 'tool.cyclic_lines': 'Zyklische Linien',\n 'tool.time_cycles': 'Zeitzyklen',\n 'tool.sine_line': 'Sinuslinie',\n 'tool.long_position': 'Long-Position',\n 'tool.short_position': 'Short-Position',\n 'tool.forecast': 'Positionsprognose',\n 'tool.sector': 'Sektor',\n 'tool.bars_pattern': 'Balkenmuster',\n 'tool.ghost_feed': 'Ghost Feed',\n 'tool.anchored_vwap': 'Verankerter VWAP',\n 'tool.fixed_range_volume_profile': 'Volumenprofil fester Bereich',\n 'tool.anchored_volume_profile': 'Verankertes Volumenprofil',\n 'tool.image': 'Bild',\n 'tool.content_card': 'Inhaltskarte',\n 'tool.emoji': 'Emoji',\n 'tool.sticker': 'Sticker',\n 'tool.icon': 'Symbol',\n 'tool.text': 'Text',\n 'tool.note': 'Notiz',\n 'tool.comment': 'Kommentar',\n 'tool.callout': 'Sprechblase',\n 'tool.price_label': 'Preisetikett',\n 'tool.arrow_up': 'Pfeilmarke nach oben',\n 'tool.arrow_down': 'Pfeilmarke nach unten',\n 'tool.arrow_marker': 'Pfeilmarkierung',\n 'tool.flag': 'Flaggenmarke',\n 'tool.price_note': 'Preisnotiz',\n 'tool.pin': 'Pin',\n 'tool.signpost': 'Wegweiser',\n 'tool.table': 'Tabelle',\n 'tool.brush': 'Pinsel',\n 'tool.highlighter': 'Textmarker',\n 'tool.path': 'Pfad',\n 'tool.polyline': 'Polylinie',\n 'tool.price_range': 'Preisbereich',\n 'tool.date_range': 'Datumsbereich',\n 'tool.date_and_price_range': 'Datums- und Preisbereich',\n 'tool.measure': 'Messen',\n}\n","import type { Translation } from '../runtime'\nimport type { menu as source } from '../en/menu'\n\nexport const menu: Translation<typeof source> = {\n 'menu.resetView': 'Chartansicht zurücksetzen',\n 'menu.copyPrice': 'Preis {price} kopieren',\n 'menu.paste': 'Einfügen',\n 'menu.removeIndicators': { one: '{count} Indikator entfernen', other: '{count} Indikatoren entfernen' },\n 'menu.removeDrawings': { one: '{count} Zeichnung entfernen', other: '{count} Zeichnungen entfernen' },\n 'menu.settings': 'Einstellungen…',\n}\n","import type { Translation } from '../runtime'\nimport type { replay as source } from '../en/replay'\n\nexport const replay: Translation<typeof source> = {\n 'replay.watermark': 'Replay',\n 'replay.selectBar': 'Select bar',\n 'replay.selectDate': 'Select date',\n 'replay.selectStartingPoint': 'Select starting point',\n 'replay.startBar': 'Bar',\n 'replay.startDate': 'Date…',\n 'replay.startFirst': 'First available date',\n 'replay.startRandom': 'Random bar',\n 'replay.startDateField': 'Replay start date',\n 'replay.startTimeField': 'Replay start time (UTC, optional)',\n 'replay.dateMask': 'YYYY-MM-DD',\n 'replay.timeMask': 'HH:MM',\n 'replay.previousMonth': 'Previous month',\n 'replay.nextMonth': 'Next month',\n 'replay.cancel': 'Cancel',\n 'replay.select': 'Select',\n 'replay.weekdayMon': 'Mo',\n 'replay.weekdayTue': 'Tu',\n 'replay.weekdayWed': 'We',\n 'replay.weekdayThu': 'Th',\n 'replay.weekdayFri': 'Fr',\n 'replay.weekdaySat': 'Sa',\n 'replay.weekdaySun': 'Su',\n 'replay.stepBack': 'Einen Balken zurück',\n 'replay.play': 'Abspielen',\n 'replay.pause': 'Pause',\n 'replay.stepForward': 'Einen Balken vor',\n 'replay.goLiveTitle': 'Zum Live-Rand springen',\n 'replay.exit': 'Wiedergabe beenden',\n 'replay.speed': 'Replay speed',\n 'replay.updatesPerSecond': { one: '{count} update per second', other: '{count} updates per second' },\n 'replay.oneUpdatePerSeconds': { one: '1 update per {count} second', other: '1 update per {count} seconds' },\n 'replay.timeframe': 'Update timeframe',\n 'replay.timeframeHelp': 'How much time each replay update advances. Finer than the chart timeframe, each bar forms from real finer bars.',\n 'replay.timeframeNone': 'No finer timeframe for this chart timeframe',\n 'replay.auto': 'Auto',\n 'replay.autoSelectTimeframe': 'Auto select timeframe',\n}\n","import type { Translation } from '../runtime'\nimport type { inputs as source } from '../en/inputs'\n\nexport const inputs: Translation<typeof source> = {\n 'inputs.cancel': 'Abbrechen',\n 'inputs.apply': 'Übernehmen',\n}\n","import type { Translation } from '../runtime'\nimport type { session as source } from '../en/session'\n\nexport const session: Translation<typeof source> = {\n 'session.pre': 'Vorbörse',\n 'session.open': 'Markt geöffnet',\n 'session.extended': 'Extended hours',\n 'session.after': 'Nachbörse',\n 'session.closed': 'Markt geschlossen',\n}\n","import type { Translation } from '../runtime'\nimport type { layouts as source } from '../en/layouts'\n\nexport const layouts: Translation<typeof source> = {\n 'layout.s': 'Einzelchart',\n 'layout.2h': '2 Spalten',\n 'layout.2v': '2 Zeilen',\n 'layout.3h': '3 Spalten',\n 'layout.3v': '3 Zeilen',\n 'layout.3s': 'Groß links, 2 gestapelt rechts',\n 'layout.3r': '2 gestapelt links, groß rechts',\n 'layout.2_1': '2 oben, 1 unten',\n 'layout.1_2': '1 oben, 2 unten',\n 'layout.4': 'Raster 2 × 2',\n 'layout.4v': '4 Zeilen',\n 'layout.4h': '4 Spalten',\n 'layout.4s': 'Groß links, 3 gestapelt rechts',\n 'layout.4s_l': '3 gestapelt links, groß rechts',\n 'layout.1_3': '1 oben, 3 unten',\n 'layout.3_1': '3 oben, 1 unten',\n 'layout.2_2_l': '2 Spalten, 2 gestapelt rechts',\n 'layout.2_2_r': '2 gestapelt links, 2 Spalten',\n 'layout.2_2': '2 oben, 2 Zeilen über die ganze Breite darunter',\n 'layout.1_4': '1 oben, 4 unten',\n 'layout.5h': '5 Spalten',\n 'layout.5v': '5 Zeilen',\n 'layout.5s': 'Groß links, 4 gestapelt rechts',\n 'layout.5s_l': '4 gestapelt links, groß rechts',\n 'layout.2_3': '2 oben, 3 unten',\n 'layout.3_2': '3 oben, 2 unten',\n 'layout.4_1': '4 oben, 1 unten',\n 'layout.2_3_l': '2 Spalten, 3 gestapelt rechts',\n 'layout.2_3_r': '3 gestapelt links, 2 Spalten',\n 'layout.6': 'Raster 3 × 2',\n 'layout.6h': '6 Spalten',\n 'layout.6v': '6 Zeilen',\n 'layout.6c': 'Raster 2 × 3',\n 'layout.2_4': '2 oben, 4 unten',\n 'layout.4_2': '4 oben, 2 unten',\n 'layout.4_3': '4 oben, 3 unten',\n 'layout.7h': '7 Spalten',\n 'layout.7s': 'Groß links, 6 gestapelt rechts',\n 'layout.8': 'Raster 4 × 2',\n 'layout.8c': 'Raster 2 × 4',\n 'layout.8h': '8 Spalten',\n 'layout.8v': '8 Zeilen',\n 'layout.9s': 'Raster 3 × 3',\n 'layout.5_4': '5 oben, 4 unten',\n 'layout.9h': '9 Spalten',\n 'layout.9v': '9 Zeilen',\n 'layout.10c5': 'Raster 5 × 2',\n 'layout.10h': '10 Spalten',\n 'layout.10v': '10 Zeilen',\n 'layout.12c6': 'Raster 6 × 2',\n 'layout.12c4': 'Raster 4 × 3',\n 'layout.12h': '12 Spalten',\n 'layout.14c7': 'Raster 7 × 2',\n 'layout.16c8': 'Raster 8 × 2',\n 'layout.16c4': 'Raster 4 × 4',\n 'layouts.setup': 'Layout setup',\n 'layouts.arrangement': 'Chart arrangement',\n 'layouts.syncInLayout': 'Sync in layout',\n 'layouts.syncSymbol': 'Symbol',\n 'layouts.syncTimeframe': 'Zeiteinheit',\n 'layouts.syncCrosshair': 'Crosshair',\n 'layouts.syncTime': 'Time',\n 'layouts.syncDateRange': 'Date range',\n 'layouts.syncSymbolTip': 'Symbol changes on all charts within the layout',\n 'layouts.syncTimeframeTip': 'Die Zeiteinheit ändert sich in allen Charts des Layouts',\n 'layouts.syncCrosshairTip': 'Crosshair is synced across all charts within the layout',\n 'layouts.syncTimeTip': 'When a chart is clicked, all charts within the layout display the same point of time',\n 'layouts.syncDateRangeTip': 'Date range changes on all charts within the layout',\n 'layouts.syncSymbolToggle': 'Sync symbol',\n 'layouts.syncTimeframeToggle': 'Zeiteinheit synchronisieren',\n 'layouts.syncCrosshairToggle': 'Sync crosshair',\n 'layouts.syncTimeToggle': 'Sync time',\n 'layouts.syncDateRangeToggle': 'Sync date range',\n 'layouts.unnamed': 'Unnamed',\n 'layouts.unsavedChanges': 'Unsaved changes',\n 'layouts.allSaved': 'All changes saved',\n 'layouts.notSaving': 'Not saving until this is restored',\n 'layouts.manage': 'Manage layouts',\n 'layouts.saveLayout': 'Save layout',\n 'layouts.hintSave': '{modifier} + S',\n 'layouts.hintOpen': 'Dot',\n 'layouts.save': 'Save',\n 'layouts.autosave': 'Autosave',\n 'layouts.rename': 'Rename',\n 'layouts.copyOfName': '{name} copy',\n 'layouts.saveNewTitle': 'Save New Chart Layout',\n 'layouts.saveNewLabel': 'Enter a new chart layout name:',\n 'layouts.copyTitle': 'Make copy of chart layout',\n 'layouts.renameTitle': 'Rename chart layout',\n 'layouts.createTitle': 'Create layout',\n 'layouts.newLayoutName': 'New layout name',\n 'layouts.createPlaceholder': 'My layout',\n 'layouts.create': 'Create',\n 'layouts.makeCopyRow': 'Make a copy…',\n 'layouts.renameRow': 'Rename…',\n 'layouts.downloadDataRow': 'Download chart data',\n 'layouts.createNewRow': 'Create new layout…',\n 'layouts.recentlyUsed': 'Recently used',\n 'layouts.loading': 'Loading',\n 'layouts.emptyNone': 'No saved layouts yet.',\n 'layouts.openLayoutRow': 'Open layout…',\n 'layouts.listingFacts': '{symbol}, {timeframe}',\n 'layouts.listingDated': '{facts} ({date})',\n 'layouts.dialogTitle': 'Layouts',\n 'layouts.search': 'Search',\n 'layouts.columnName': 'Layout name',\n 'layouts.sortBy': 'Sort by layout name, date changed',\n 'layouts.sortNameAsc': 'Layout name (A to Z)',\n 'layouts.sortNameDesc': 'Layout name (Z to A)',\n 'layouts.sortModifiedAsc': 'Date modified (oldest first)',\n 'layouts.sortModifiedDesc': 'Date modified (newest first)',\n 'layouts.favorite': 'Add to favorites',\n 'layouts.unfavorite': 'Remove from favorites',\n 'layouts.noMatches': 'Nothing matches.',\n 'layouts.delete': 'Delete',\n 'layouts.deleteNamed': 'Delete {name}',\n 'layouts.deleteConfirm': 'Delete this chart layout?',\n 'layouts.deleteConfirmBody': 'Doing this will permanently delete your \"{name}\" layout.',\n 'layouts.cancel': 'Cancel',\n 'layouts.close': 'Close',\n 'layouts.errList': 'Could not load your saved layouts.',\n}\n","import type { Translation } from '../runtime'\nimport type { host as source } from '../en/host'\n\nexport const host: Translation<typeof source> = {\n 'host.noVolume': 'Kein Volumen von diesem Feed',\n 'host.saveConflict': 'Saved elsewhere since you opened it. Load the newer version before saving.',\n 'host.saveNotFound': 'This was deleted elsewhere. Save it again as new.',\n 'host.loadInvalid': 'This could not be opened. Nothing on screen changed.',\n 'host.loadUnavailable': 'Your saved work could not be reached. Nothing on screen changed.',\n 'host.loadNotRestored': 'This could not be opened, and what was on screen could not be put back. The chart is not saving until you open a saved chart or layout. Save a copy first to keep what is on screen.',\n 'host.notSaving': 'The chart is not saving. Open a saved chart or layout to start from a known state. Saving a copy keeps what is on screen, but the chart still will not save.',\n}\n","import type { Translation } from '../runtime'\nimport type { indicators as source } from '../en/indicators'\n\nexport const indicators: Translation<typeof source> = {\n 'indicator.smaName': 'Simple Moving Average',\n 'indicator.smaDescription': 'Smoothed average over a fixed window',\n 'indicator.emaName': 'Exponential Moving Average',\n 'indicator.emaDescription': 'Recency-weighted moving average',\n 'indicator.hmaName': 'Hull Moving Average',\n 'indicator.hmaDescription': 'Low-lag weighted moving average',\n 'indicator.vwmaName': 'Volume Weighted MA',\n 'indicator.vwmaDescription': 'Moving average weighted by volume',\n 'indicator.bollingerName': 'Bollinger Bands',\n 'indicator.bollingerDescription': 'SMA envelope at two standard deviations',\n 'indicator.donchianName': 'Donchian Channels',\n 'indicator.donchianDescription': 'Rolling highest-high and lowest-low channel',\n 'indicator.keltnerName': 'Keltner Channels',\n 'indicator.keltnerDescription': 'EMA midline with ATR-scaled bands',\n 'indicator.supertrendName': 'Supertrend',\n 'indicator.supertrendDescription': 'ATR trend band that flips with direction',\n 'indicator.psarName': 'Parabolic SAR',\n 'indicator.psarDescription': 'Stop-and-reverse trailing dots',\n 'indicator.rsiName': 'Relative Strength Index',\n 'indicator.rsiDescription': 'Momentum oscillator from 0 to 100',\n 'indicator.macdName': 'MACD',\n 'indicator.macdDescription': 'Moving Average Convergence Divergence',\n 'indicator.stochasticName': 'Stochastic Oscillator',\n 'indicator.stochasticDescription': '%K and %D momentum from 0 to 100',\n 'indicator.stochrsiName': 'Stochastic RSI',\n 'indicator.stochrsiDescription': 'Stochastic applied to the RSI series',\n 'indicator.adxName': 'Average Directional Index',\n 'indicator.adxDescription': 'Trend strength with +DI and -DI',\n 'indicator.atrName': 'Average True Range',\n 'indicator.atrDescription': 'Volatility: Wilder\\'s true-range average',\n 'indicator.cciName': 'Commodity Channel Index',\n 'indicator.cciDescription': 'Deviation from the typical-price average',\n 'indicator.williamsName': 'Williams %R',\n 'indicator.williamsDescription': 'Overbought and oversold momentum from -100 to 0',\n 'indicator.rocName': 'Rate of Change',\n 'indicator.rocDescription': 'Percent change over the period',\n 'indicator.momentumName': 'Momentum',\n 'indicator.momentumDescription': 'Price difference over the period',\n 'indicator.volumeName': 'Volume',\n 'indicator.volumeDescription': 'Per-bar traded volume histogram',\n 'indicator.vwapName': 'Volume Weighted Avg Price',\n 'indicator.vwapDescription': 'Cumulative volume-weighted average price',\n 'indicator.obvName': 'On-Balance Volume',\n 'indicator.obvDescription': 'Cumulative volume by close direction',\n 'indicator.mfiName': 'Money Flow Index',\n 'indicator.mfiDescription': 'Volume-weighted RSI from 0 to 100',\n}\n","import type { Translation } from '../runtime'\nimport type { timeframe as source } from '../en/timeframe'\n\nexport const timeframe: Translation<typeof source> = {\n 'timeframe.title': 'Zeiteinheit',\n 'timeframe.all': 'Alle Zeiteinheiten',\n 'timeframe.unitTicks': 'Ticks',\n 'timeframe.unitSeconds': 'Sekunden',\n 'timeframe.unitMinutes': 'Minuten',\n 'timeframe.unitHours': 'Stunden',\n 'timeframe.unitDays': 'Tage',\n 'timeframe.unitWeeks': 'Wochen',\n 'timeframe.unitMonths': 'Monate',\n 'timeframe.countTicks': { one: '{count} Tick', other: '{count} Ticks' },\n 'timeframe.countSeconds': { one: '{count} Sekunde', other: '{count} Sekunden' },\n 'timeframe.countMinutes': { one: '{count} Minute', other: '{count} Minuten' },\n 'timeframe.countHours': { one: '{count} Stunde', other: '{count} Stunden' },\n 'timeframe.countDays': { one: '{count} Tag', other: '{count} Tage' },\n 'timeframe.countWeeks': { one: '{count} Woche', other: '{count} Wochen' },\n 'timeframe.countMonths': { one: '{count} Monat', other: '{count} Monate' },\n 'timeframe.delete': '{timeframe} löschen',\n 'timeframe.save': '{timeframe} speichern',\n 'timeframe.exists': '{timeframe} existiert bereits',\n 'timeframe.custom': 'Eigene Zeiteinheit',\n 'timeframe.customCount': 'Anzahl der eigenen Zeiteinheit',\n 'timeframe.customUnit': 'Einheit der eigenen Zeiteinheit',\n 'timeframe.addCustom': 'Eigene Zeiteinheit hinzufügen',\n 'timeframe.increment': 'Erhöhen',\n 'timeframe.decrement': 'Verringern',\n}\n","import type { Translation } from '../runtime'\nimport type { timezone as source } from '../en/timezone'\n\nexport const timezone: Translation<typeof source> = {\n 'timezone.title': 'Zeitzone des Charts',\n 'timezone.exchange': 'Börse',\n}\n","import type { Translation } from '../runtime'\nimport type { range as source } from '../en/range'\n\nexport const range: Translation<typeof source> = {\n 'range.oneDay': '1 Tag',\n 'range.fiveDays': '5 Tage',\n 'range.oneMonth': '1 Monat',\n 'range.threeMonths': '3 Monate',\n 'range.sixMonths': '6 Monate',\n 'range.yearToDate': 'Seit Jahresbeginn',\n 'range.oneYear': '1 Jahr',\n 'range.fiveYears': '5 Jahre',\n 'range.all': 'Alle Daten',\n 'range.tip': '{range} · {timeframe}-Balken',\n 'range.zoomIn': 'Vergrößern',\n 'range.zoomOut': 'Verkleinern',\n 'range.scrollLeft': 'Nach links scrollen',\n 'range.scrollRight': 'Nach rechts scrollen',\n 'range.reset': 'Chartansicht zurücksetzen',\n 'range.maximizeChart': 'Maximize chart',\n 'range.restoreChart': 'Restore chart',\n}\n","import type { Translation } from '../runtime'\nimport type { status as source } from '../en/status'\n\nexport const status: Translation<typeof source> = {\n 'status.title': 'Marktstatus',\n 'status.unknownTitle': 'Sitzung unbekannt',\n 'status.unknown': 'Die Handelssitzung dieses Symbols steht noch nicht fest.',\n 'status.endOfDayTitle': 'End of day',\n 'status.endOfDay': 'Prices update once a day, after the session closes.',\n 'status.delayed': 'Prices are delayed.',\n 'status.delayedPair': '{status} {delay}',\n 'status.continuousTitle': 'Rund um die Uhr geöffnet',\n 'status.continuous': 'This market trades around the clock and never closes.',\n 'status.open': 'Der Markt ist für den regulären Handel geöffnet.',\n 'status.openCloses': 'Der Markt ist für den regulären Handel geöffnet. Schließt in {until}.',\n 'status.extended': 'Market is open for extended-hours trading.',\n 'status.extendedRegular': 'Market is open for extended-hours trading. Regular hours start in {until}.',\n 'status.extendedCloses': 'Market is open for extended-hours trading. Closes in {until}.',\n 'status.pre': 'Der Markt ist für den vorbörslichen Handel geöffnet.',\n 'status.preRegular': 'Der Markt ist für den vorbörslichen Handel geöffnet. Die regulären Zeiten beginnen in {until}.',\n 'status.after': 'Der Markt ist für den nachbörslichen Handel geöffnet.',\n 'status.afterEnds': 'Der Markt ist für den nachbörslichen Handel geöffnet. Endet in {until}.',\n 'status.closed': 'Der Markt ist geschlossen.',\n 'status.closedPre': 'Der Markt ist geschlossen. Die Vorbörse beginnt in {until}.',\n 'status.closedOpens': 'Der Markt ist geschlossen. Öffnet in {until}.',\n 'status.exchangeTimezone': 'Zeitzone der Börse: {zone}',\n 'status.durationDays': { one: '{count} Tag', other: '{count} Tagen' },\n 'status.durationHours': { one: '{count} Stunde', other: '{count} Stunden' },\n 'status.durationMinutes': { one: '{count} Minute', other: '{count} Minuten' },\n 'status.durationPair': '{major} {minor}',\n}\n","import type { Translation } from '../runtime'\nimport type { search as source } from '../en/search'\n\nexport const search: Translation<typeof source> = {\n 'search.title': 'Symbolsuche',\n 'search.compareTitle': 'Symbole vergleichen',\n 'search.changeSymbolTitle': 'Symbol wechseln',\n 'search.placeholder': 'Search symbol',\n 'search.clear': 'Leeren',\n 'search.close': 'Close',\n 'search.noMatches': 'No symbols match your criteria',\n 'search.loadingMore': 'Loading more',\n 'search.failed': 'Search failed.',\n 'search.results': 'Symbols',\n 'search.samePercent': 'Gleiche %-Skala',\n 'search.newScale': 'Neue Preisskala',\n 'search.newPane': 'Neuer Bereich',\n 'search.added': 'Hinzugefügte Symbole',\n 'search.recent': 'Zuletzt verwendete Symbole',\n 'search.addedMark': '{symbol} ist im Chart. Zum Entfernen klicken.',\n 'search.compareEmpty': 'No symbols here yet. Why not add some?',\n 'search.allClasses': 'All',\n 'search.classFilter': 'Asset class',\n 'search.opDivision': 'Division',\n 'search.opSubtraction': 'Subtraktion',\n 'search.opAddition': 'Addition',\n 'search.opMultiplication': 'Multiplikation',\n 'search.opExponentiation': 'Potenzierung',\n 'search.opReciprocal': 'Kehrwert',\n 'search.opsHide': 'Spread-Operatoren ausblenden',\n 'search.opsShow': 'Spread-Operatoren anzeigen',\n 'search.ops': 'Spread operators',\n}\n","import type { Translation } from '../runtime'\nimport type { drawing as source } from '../en/drawing'\n\nexport const drawing: Translation<typeof source> = {\n 'drawing.toolbar': 'Drawing tools',\n 'drawing.groupTrend': 'Trend tools',\n 'drawing.groupFibGann': 'Fibonacci & Gann',\n 'drawing.groupPatterns': 'Patterns',\n 'drawing.groupForecast': 'Forecast & measure',\n 'drawing.groupGlyphs': 'Emojis & stickers',\n 'drawing.shapes': 'Shapes',\n 'drawing.textNotes': 'Text & notes',\n 'drawing.groupMenu': '{group} menu',\n 'drawing.sectionLines': 'Lines',\n 'drawing.sectionChannels': 'Channels',\n 'drawing.sectionPitchforks': 'Pitchforks',\n 'drawing.sectionFibonacci': 'Fibonacci',\n 'drawing.sectionGann': 'Gann',\n 'drawing.sectionChartPatterns': 'Chart patterns',\n 'drawing.sectionElliott': 'Elliott waves',\n 'drawing.sectionCycles': 'Cycles',\n 'drawing.sectionForecasting': 'Forecasting',\n 'drawing.sectionVolumeBased': 'Volume based',\n 'drawing.sectionMeasures': 'Measures',\n 'drawing.sectionBrushes': 'Brushes',\n 'drawing.sectionArrows': 'Arrows',\n 'drawing.sectionContent': 'Content',\n 'drawing.sectionGlyphs': 'Emojis, stickers, icons',\n 'drawing.cursor': 'Cursor',\n 'drawing.cursorMenu': 'Cursor menu',\n 'drawing.cursorCross': 'Cross',\n 'drawing.cursorDot': 'Dot',\n 'drawing.cursorArrow': 'Arrow',\n 'drawing.cursorEraser': 'Eraser',\n 'drawing.measure': 'Measure',\n 'drawing.zoomIn': 'Zoom in',\n 'drawing.magnet': 'Magnet',\n 'drawing.magnetMenu': 'Magnet menu',\n 'drawing.magnetWeak': 'Weak magnet',\n 'drawing.magnetStrong': 'Strong magnet',\n 'drawing.stayInDrawingMode': 'Stay in drawing mode',\n 'drawing.lockAll': 'Lock all drawings',\n 'drawing.unlockAll': 'Unlock all drawings',\n 'drawing.hideMenu': 'Hide menu',\n 'drawing.hideDrawings': 'Hide drawings',\n 'drawing.showDrawings': 'Show drawings',\n 'drawing.hideIndicators': 'Hide indicators',\n 'drawing.showIndicators': 'Show indicators',\n 'drawing.hideAll': 'Hide all',\n 'drawing.showAll': 'Show all',\n 'drawing.syncLabel': 'Sync drawings across the layout',\n 'drawing.syncOnHelp': 'New drawings are replicated to all charts in the layout and shown when the same ticker is selected',\n 'drawing.syncOffHelp': 'New drawings stay on the chart that drew them',\n 'drawing.removeMenu': 'Remove menu',\n 'drawing.removeDrawings': 'Remove drawings',\n 'drawing.countDrawings': { one: '{count} drawing', other: '{count} drawings' },\n 'drawing.countIndicators': { one: '{count} indicator', other: '{count} indicators' },\n 'drawing.removeItems': 'Remove {items}',\n 'drawing.removeBoth': 'Remove {drawings} & {indicators}',\n 'drawing.nothingToRemove': 'Nothing to remove',\n 'drawing.alwaysRemoveLocked': 'Always remove locked drawings',\n 'drawing.favTools': 'Favorite drawing tools',\n 'drawing.favToolsBar': 'Favorite drawing tools toolbar',\n 'drawing.favAdd': 'Add {tool} to favorites',\n 'drawing.favRemove': 'Remove {tool} from favorites',\n 'drawing.moveToolbar': 'Move toolbar',\n 'drawing.moveFavoritesToolbar': 'Move favorites toolbar',\n 'drawing.settingsBar': 'Selected drawing',\n 'drawing.templates': 'Templates',\n 'drawing.drawingTemplates': 'Drawing templates',\n 'drawing.saveTemplateAs': 'Save drawing template as...',\n 'drawing.applyDefaultTemplate': 'Apply default drawing template',\n 'drawing.removeTemplateNamed': 'Remove template {name}',\n 'drawing.remove': 'Remove',\n 'drawing.addRowShort': '+ Row',\n 'drawing.addColumnShort': '+ Col',\n 'drawing.drawingColor': 'Drawing color',\n 'drawing.backgroundColor': 'Background color',\n 'drawing.thickness': 'Thickness',\n 'drawing.lineThickness': 'Line thickness',\n 'drawing.thicknessValue': 'Thickness {n}px',\n 'drawing.lineStyle': 'Line style',\n 'drawing.lineStyleValue': 'Line style {name}',\n 'drawing.lineSolid': 'Line',\n 'drawing.lineDashed': 'Dashed line',\n 'drawing.lineDotted': 'Dotted line',\n 'drawing.settings': 'Settings',\n 'drawing.drawingSettings': 'Drawing settings',\n 'drawing.lock': 'Lock',\n 'drawing.unlock': 'Unlock',\n 'drawing.lockDrawing': 'Lock drawing',\n 'drawing.unlockDrawing': 'Unlock drawing',\n 'drawing.deleteDrawing': 'Delete drawing',\n 'drawing.more': 'More',\n 'drawing.moreActions': 'More drawing actions',\n 'drawing.visualOrder': 'Visual order',\n 'drawing.visibilityOnTimeframes': 'Visibility on timeframes',\n 'drawing.clone': 'Clone',\n 'drawing.copy': 'Copy',\n 'drawing.modifierControl': 'Ctrl',\n 'drawing.modifierCommand': 'Cmd',\n 'drawing.hintClone': '{modifier} + Drag',\n 'drawing.hintCopy': '{modifier} + C',\n 'drawing.hintPaste': '{modifier} + V',\n 'drawing.deleteWithKey': 'Delete (Del)',\n 'drawing.statusDrawingsHidden': 'Drawings hidden',\n 'drawing.statusDrawingsShown': 'Drawings shown',\n 'drawing.statusIndicatorsHidden': 'Indicators hidden',\n 'drawing.statusIndicatorsShown': 'Indicators shown',\n 'drawing.statusAllHidden': 'Drawings and indicators hidden',\n 'drawing.statusAllShown': 'Drawings and indicators shown',\n 'drawing.statusAllLocked': 'All drawings locked',\n 'drawing.statusAllUnlocked': 'All drawings unlocked',\n 'drawing.hide': 'Hide',\n 'drawing.bringToFront': 'Bring to front',\n 'drawing.sendToBack': 'Send to back',\n 'drawing.bringForward': 'Bring forward',\n 'drawing.sendBackward': 'Send backward',\n 'drawing.visCurrentAndAbove': 'Current timeframe and above',\n 'drawing.visCurrentAndBelow': 'Current timeframe and below',\n 'drawing.visCurrentOnly': 'Current timeframe only',\n 'drawing.visAll': 'All timeframes',\n 'drawing.saveTemplate': 'Save drawing template',\n 'drawing.templateName': 'Template name',\n 'drawing.save': 'Save',\n 'drawing.deleteTemplateTitle': 'Delete this template?',\n 'drawing.deleteTemplateBody': 'Doing this will permanently delete your \"{name}\" drawing template.',\n 'drawing.settingsTitle': '{tool} settings',\n 'drawing.tabInputs': 'Inputs',\n 'drawing.tabStyle': 'Style',\n 'drawing.tabText': 'Text',\n 'drawing.tabTable': 'Table',\n 'drawing.tabCoordinates': 'Coordinates',\n 'drawing.tabVisibility': 'Visibility',\n 'drawing.template': 'Template',\n 'drawing.saveAs': 'Save as...',\n 'drawing.applyDefaults': 'Apply defaults',\n 'drawing.cancel': 'Cancel',\n 'drawing.ok': 'Ok',\n 'drawing.delete': 'Delete',\n 'drawing.close': 'Close',\n 'drawing.color': 'Color',\n 'drawing.rowLine': 'Line',\n 'drawing.background': 'Background',\n 'drawing.border': 'Border',\n 'drawing.profitColor': 'Target zone color',\n 'drawing.stopColor': 'Stop zone color',\n 'drawing.textColor': 'Text color',\n 'drawing.fontSize': 'Font size',\n 'drawing.size': 'Size',\n 'drawing.width': 'Width',\n 'drawing.opacity': 'Opacity',\n 'drawing.transparency': 'Transparency',\n 'drawing.label': 'Label',\n 'drawing.labels': 'Labels',\n 'drawing.left': 'Left',\n 'drawing.center': 'Center',\n 'drawing.right': 'Right',\n 'drawing.up': 'Up',\n 'drawing.down': 'Down',\n 'drawing.rowVisible': '{name} visible',\n 'drawing.leftEnd': 'Left end',\n 'drawing.rightEnd': 'Right end',\n 'drawing.lineEndNormal': 'Normal',\n 'drawing.lineEndArrow': 'Arrow',\n 'drawing.increase': 'Increase',\n 'drawing.decrease': 'Decrease',\n 'drawing.rangeFrom': 'From',\n 'drawing.rangeTo': 'To',\n 'drawing.pickColor': 'Pick a color',\n 'drawing.extend': 'Extend',\n 'drawing.extendNone': 'Don\\'t extend',\n 'drawing.extendLeft': 'Extend left',\n 'drawing.extendRight': 'Extend right',\n 'drawing.extendBoth': 'Extend both',\n 'drawing.extendLines': 'Extend lines',\n 'drawing.middlePoint': 'Middle point',\n 'drawing.middleLine': 'Middle line',\n 'drawing.priceLabel': 'Price label',\n 'drawing.priceLabels': 'Price labels',\n 'drawing.timeLabel': 'Time label',\n 'drawing.rowStyle': 'Style',\n 'drawing.variantOriginal': 'Original',\n 'drawing.variantSchiff': 'Schiff',\n 'drawing.variantModifiedSchiff': 'Modified Schiff',\n 'drawing.variantInside': 'Inside',\n 'drawing.sectionStats': 'Stats',\n 'drawing.priceChange': 'Price change',\n 'drawing.percentChange': 'Percent change',\n 'drawing.bars': 'Bars',\n 'drawing.dateTimeRange': 'Date/time range',\n 'drawing.volume': 'Volume',\n 'drawing.sectionInfo': 'Info',\n 'drawing.priceRange': 'Price range',\n 'drawing.barsRange': 'Bars range',\n 'drawing.angle': 'Angle',\n 'drawing.statsPosition': 'Stats position',\n 'drawing.direction': 'Direction',\n 'drawing.prices': 'Prices',\n 'drawing.levels': 'Levels',\n 'drawing.reverse': 'Reverse',\n 'drawing.fullCircles': 'Full circles',\n 'drawing.coeffsAsPercents': 'Coeffs as percents',\n 'drawing.glyph': 'Glyph',\n 'drawing.image': 'Image',\n 'drawing.replaceEllipsis': 'Replace...',\n 'drawing.chooseEllipsis': 'Choose...',\n 'drawing.link': 'Link',\n 'drawing.rowsLayout': 'Rows layout',\n 'drawing.rowsByNumber': 'Number of rows',\n 'drawing.ticksPerRow': 'Ticks per row',\n 'drawing.rowSize': 'Row size',\n 'drawing.upDown': 'Up/Down',\n 'drawing.total': 'Total',\n 'drawing.delta': 'Delta',\n 'drawing.valueAreaVolume': 'Value area volume',\n 'drawing.widthPercent': 'Width %',\n 'drawing.placement': 'Placement',\n 'drawing.upDownVolume': 'Up/Down volume',\n 'drawing.valueAreaUpDown': 'Value area up/down',\n 'drawing.pointOfControl': 'Point of control',\n 'drawing.valueAreaHigh': 'Value area high',\n 'drawing.valueAreaLow': 'Value area low',\n 'drawing.developingPoc': 'Developing PoC',\n 'drawing.developingVa': 'Developing VA',\n 'drawing.source': 'Source',\n 'drawing.mode': 'Mode',\n 'drawing.modeLineOpen': 'Line (Open)',\n 'drawing.modeLineHigh': 'Line (High)',\n 'drawing.modeLineLow': 'Line (Low)',\n 'drawing.modeLineClose': 'Line (Close)',\n 'drawing.modeLineHl2': 'Line (HL2)',\n 'drawing.mirrored': 'Mirrored',\n 'drawing.flipped': 'Flipped',\n 'drawing.target': 'Target',\n 'drawing.success': 'Success',\n 'drawing.failure': 'Failure',\n 'drawing.avgHl': 'Avg HL',\n 'drawing.variance': 'Variance',\n 'drawing.body': 'Body',\n 'drawing.borders': 'Borders',\n 'drawing.drawBorders': 'Draw borders',\n 'drawing.wick': 'Wick',\n 'drawing.drawWicks': 'Draw wicks',\n 'drawing.sectionDeviation': 'Deviation',\n 'drawing.upper': 'Upper',\n 'drawing.lower': 'Lower',\n 'drawing.useUpperDeviation': 'Use upper deviation',\n 'drawing.useLowerDeviation': 'Use lower deviation',\n 'drawing.risk': 'Risk',\n 'drawing.accountSize': 'Account size',\n 'drawing.lotSize': 'Lot size',\n 'drawing.leverage': 'Leverage',\n 'drawing.compactStatsMode': 'Compact stats mode',\n 'drawing.levelVisible': 'Level {value} visible',\n 'drawing.levelText': 'Level {value} text',\n 'drawing.removeLevel': 'Remove level {value}',\n 'drawing.addLevel': 'Add level',\n 'drawing.weight': 'Weight',\n 'drawing.bold': 'Bold',\n 'drawing.italic': 'Italic',\n 'drawing.addText': 'Add text',\n 'drawing.alignment': 'Alignment',\n 'drawing.textPlaceholder': 'Text',\n 'drawing.textEditor': 'Drawing text',\n 'drawing.headerRow': 'Header row',\n 'drawing.tableCell': 'Cell {row},{col}',\n 'drawing.addRow': 'Add row',\n 'drawing.removeRow': 'Remove row',\n 'drawing.addColumn': 'Add column',\n 'drawing.removeColumn': 'Remove column',\n 'drawing.coordBar': '#{n} (bar)',\n 'drawing.coordPriceBar': '#{n} (price, bar)',\n 'drawing.unitTicks': 'Ticks',\n 'drawing.unitSeconds': 'Seconds',\n 'drawing.unitMinutes': 'Minutes',\n 'drawing.unitHours': 'Hours',\n 'drawing.unitDays': 'Days',\n 'drawing.unitWeeks': 'Weeks',\n 'drawing.unitMonths': 'Months',\n 'drawing.timeframePinnedNote': 'A drawing stays on at least one timeframe, so it can always be reached again.',\n 'drawing.colorSwatch': 'Color {hex}',\n 'drawing.customColor': 'Custom color',\n 'drawing.saturationValue': 'Saturation and brightness',\n 'drawing.hue': 'Hue',\n 'drawing.hexColor': 'Hex color',\n 'drawing.add': 'Add',\n 'drawing.glyphPicker': 'Glyph picker',\n 'drawing.kindEmojis': 'Emojis',\n 'drawing.kindStickers': 'Stickers',\n 'drawing.kindIcons': 'Icons',\n 'drawing.recentlyUsed': 'Recently used',\n 'drawing.recentGlyph': 'Recent {glyph}',\n 'drawing.stickersSoon': 'No sticker set is installed.',\n 'drawing.glyphCatSmileys': 'Smileys & People',\n 'drawing.glyphCatNature': 'Animals & Nature',\n 'drawing.glyphCatFood': 'Food & Drink',\n 'drawing.glyphCatActivity': 'Activity',\n 'drawing.glyphCatTravel': 'Travel & Places',\n 'drawing.glyphCatObjects': 'Objects',\n 'drawing.glyphCatSymbols': 'Symbols',\n 'drawing.glyphCatFlags': 'Flags',\n 'drawing.glyphCatIconArrows': 'Arrows',\n 'drawing.glyphCatIconCurrency': 'Currency',\n 'drawing.glyphCatIconGestures': 'Gestures and smileys',\n 'drawing.glyphCatIconNature': 'Nature',\n 'drawing.glyphCatIconSpecial': 'Special',\n 'drawing.glyphCatIconSymbols': 'Symbols and flags',\n 'drawing.imageReading': 'Reading...',\n 'drawing.chooseImage': 'Choose image',\n 'drawing.imageFormats': 'JPG or PNG',\n 'drawing.imageMaxSize': 'Max size 2MB',\n 'drawing.imageDimensions': '{width} x {height}',\n 'drawing.imageErrorType': 'That file is not a JPG or PNG. Pick one of those two formats.',\n 'drawing.imageErrorSize': 'That image is {size}. The limit is 2MB.',\n 'drawing.imageErrorRead': 'That file could not be read. Try picking it again.',\n 'drawing.imageErrorDecode': 'That image could not be opened. It may be damaged.',\n}\n","import type { Translation } from '../runtime'\nimport type { command as source } from '../en/command'\n\nexport const command: Translation<typeof source> = {\n 'command.extension': 'Host command',\n 'command.viewReset': 'Reset view',\n 'command.viewGoLive': 'Go to the live edge',\n 'command.viewZoomIn': 'Zoom in',\n 'command.viewZoomOut': 'Zoom out',\n 'command.viewScrollLeft': 'Scroll back',\n 'command.viewScrollRight': 'Scroll forward',\n 'command.priceCopy': 'Copy price',\n 'command.symbolSet': 'Change symbol',\n 'command.styleCandles': 'Candles',\n 'command.styleHollow': 'Hollow candles',\n 'command.styleBars': 'Bars',\n 'command.styleLine': 'Line',\n 'command.styleArea': 'Area',\n 'command.styleBaseline': 'Baseline',\n 'command.styleStepline': 'Step line',\n 'command.appearanceApply': 'Chart appearance',\n 'command.appearanceReset': 'Reset defaults',\n 'command.scaleNormal': 'Regular price scale',\n 'command.scaleLog': 'Logarithmic price scale',\n 'command.scalePercent': 'Percentage price scale',\n 'command.scaleIndexed': 'Indexed price scale',\n 'command.historyUndo': 'Undo',\n 'command.historyRedo': 'Redo',\n 'command.indicatorAdd': 'Add indicator',\n 'command.indicatorUpdate': 'Update indicator',\n 'command.indicatorsRemoveAll': 'Remove indicators',\n 'command.indicatorRemove': 'Remove indicator',\n 'command.indicatorHide': 'Hide indicator',\n 'command.indicatorShow': 'Show indicator',\n 'command.drawingsRemoveAll': 'Remove drawings',\n 'command.drawingDeleteSelected': 'Delete selected drawing',\n 'command.drawingArm': 'Drawing tool',\n 'command.drawingCursor': 'Cursor mode',\n 'command.drawingMagnet': 'Magnet',\n 'command.drawingStayInMode': 'Stay in drawing mode',\n 'command.drawingLockAll': 'Lock all drawings',\n 'command.drawingHide': 'Hide drawings or indicators',\n 'command.drawingSync': 'Sync drawings across the layout',\n 'command.drawingRemoveLockedPolicy': 'Always remove locked drawings',\n 'command.drawingFavorite': 'Favorite drawing tool',\n 'command.drawingFavoritesBar': 'Favorite drawing tools toolbar',\n 'command.drawingStyle': 'Drawing style',\n 'command.drawingProps': 'Drawing properties',\n 'command.drawingLock': 'Lock drawing',\n 'command.drawingClone': 'Clone drawing',\n 'command.drawingCopy': 'Copy drawing',\n 'command.drawingPaste': 'Paste drawing',\n 'command.drawingBringToFront': 'Bring drawing to front',\n 'command.drawingSendToBack': 'Send drawing to back',\n 'command.drawingBringForward': 'Bring drawing forward',\n 'command.drawingSendBackward': 'Send drawing backward',\n 'command.drawingHideSelected': 'Hide drawing',\n 'command.drawingVisibility': 'Drawing visibility on timeframes',\n 'command.drawingSettings': 'Drawing settings',\n 'command.drawingCommitEdit': 'Apply drawing settings',\n 'command.drawingPlaceImage': 'Place image',\n 'command.drawingTemplateApply': 'Apply drawing template',\n 'command.drawingTemplateSave': 'Save drawing template',\n 'command.drawingTemplateRemove': 'Remove drawing template',\n 'command.drawingTableAddRow': 'Add table row',\n 'command.drawingTableAddColumn': 'Add table column',\n 'command.drawingCancel': 'Cancel drawing',\n 'command.compareOpen': 'Compare or add symbol',\n 'command.compareAdd': 'Add comparison',\n 'command.compareRemove': 'Remove comparison',\n 'command.compareVisible': 'Show or hide a comparison',\n 'command.compareChangeSymbol': 'Change compared symbol',\n 'command.replayStart': 'Start bar replay',\n 'command.replayStartFirst': 'Start bar replay at the first available date',\n 'command.replayExit': 'Exit bar replay',\n 'command.replayPlay': 'Play replay',\n 'command.replayPause': 'Pause replay',\n 'command.replayStepForward': 'Step forward',\n 'command.replayStepBack': 'Step back',\n 'command.replayGoLive': 'Replay to the live edge',\n 'command.replaySpeed': 'Replay speed',\n 'command.replayTimeframe': 'Replay update timeframe',\n 'command.timeframeSet': 'Timeframe',\n 'command.subsessionRegular': 'Regular hours',\n 'command.subsessionExtended': 'Extended hours',\n 'command.rangeSet': 'Date range',\n 'command.timezoneSet': 'Timezone',\n 'command.themeLight': 'Light theme',\n 'command.themeDark': 'Dark theme',\n 'command.themeToggle': 'Switch theme',\n 'command.themeSet': 'Set theme',\n 'command.localeSet': 'Language',\n 'command.fullscreenEnter': 'Fullscreen',\n 'command.fullscreenExit': 'Exit fullscreen',\n 'command.fullscreenToggle': 'Toggle fullscreen',\n 'command.imageCapture': 'Capture image',\n 'command.imageDownload': 'Download image',\n 'command.dataDownload': 'Download chart data',\n 'command.imageCopy': 'Copy image',\n 'command.layoutArrangement': 'Layout',\n 'command.layoutActive': 'Active chart',\n 'command.layoutSync': 'Chart synchronization',\n 'command.layoutActivateNext': 'Next chart in layout',\n 'command.layoutActivatePrevious': 'Previous chart in layout',\n 'command.layoutMaximize': 'Maximize or restore the active chart',\n 'command.layoutSave': 'Save layout',\n 'command.layoutRename': 'Rename layout',\n 'command.layoutLoad': 'Open layout',\n 'command.layoutOpen': 'Open layout…',\n 'command.layoutDelete': 'Delete layout',\n 'command.layoutCreate': 'Create new layout',\n 'command.layoutAutosave': 'Autosave layout',\n}\n","import type { Translation } from '../runtime'\nimport type { chrome as source } from '../en/chrome'\n\nexport const chrome: Translation<typeof source> = {\n 'chrome.topBar': 'Chart toolbar',\n 'chrome.bottomBar': 'Chart footer',\n 'chrome.symbolSearch': 'Search symbol',\n 'chrome.compare': 'Compare or add symbol',\n 'chrome.chartStyle': 'Chart style',\n 'chrome.indicators': 'Indicators',\n 'chrome.replay': 'Bar replay',\n 'chrome.replayChip': 'Replay',\n 'chrome.image': 'Chart image',\n 'chrome.session': 'Trading session',\n 'chrome.sessionsHeading': 'Sessions',\n 'chrome.navigation': 'Chart navigation',\n 'chrome.activeChart': '{symbol}, {timeframe}',\n}\n","import type { Translation } from '../runtime'\nimport type { history as source } from '../en/history'\n\nexport const history: Translation<typeof source> = {\n 'history.undoNamed': 'Undo {change}',\n 'history.redoNamed': 'Redo {change}',\n 'history.changeSymbol': 'symbol change',\n 'history.changeTimeframe': 'timeframe change',\n 'history.changeChartStyle': 'chart style change',\n 'history.changePriceScale': 'price scale change',\n 'history.changeAppearance': 'appearance change',\n 'history.changeAddCompare': 'add comparison',\n 'history.changeRemoveCompare': 'remove comparison',\n 'history.changeCompare': 'comparison change',\n 'history.changeAddIndicator': 'add indicator',\n 'history.changeRemoveIndicator': 'remove indicator',\n 'history.changeIndicator': 'indicator change',\n 'history.changeAddDrawing': 'add drawing',\n 'history.changeRemoveDrawing': 'remove drawing',\n 'history.changeDrawing': 'drawing change',\n}\n","import type { Translation } from '../runtime'\nimport type { picker as source } from '../en/picker'\n\nexport const picker: Translation<typeof source> = {\n 'picker.title': 'Indicators',\n 'picker.search': 'Search indicators',\n 'picker.noMatches': 'No matching indicators.',\n 'picker.collections': 'Indicator collections',\n 'picker.personal': 'Personal',\n 'picker.builtin': 'Built-in',\n 'picker.favorites': 'Favorites',\n 'picker.thousands': ' K',\n 'picker.name': 'Name',\n 'picker.author': 'Author',\n 'picker.favorite': 'Favorite {name}',\n 'picker.unfavorite': 'Unfavorite {name}',\n 'picker.loading': 'Loading indicators…',\n 'picker.unavailable': 'Indicator content is unavailable. Try again.',\n 'picker.actionFailed': 'The action could not be completed. Try again.',\n 'picker.add': 'Add {name}',\n 'picker.notPermitted': '{name} is not available here',\n}\n","import type { Translation } from '../runtime'\nimport type { settings as source } from '../en/settings'\n\nexport const settings: Translation<typeof source> = {\n 'settings.menu': 'Chart settings',\n 'settings.sectionAppearance': 'Appearance',\n 'settings.background': 'Background',\n 'settings.upCandles': 'Up candles',\n 'settings.downCandles': 'Down candles',\n 'settings.upBorders': 'Up borders',\n 'settings.downBorders': 'Down borders',\n 'settings.upWicks': 'Up wicks',\n 'settings.downWicks': 'Down wicks',\n 'settings.sectionDisplay': 'Display',\n 'settings.gridLines': 'Grid lines',\n 'settings.sessionShading': 'Session shading',\n 'settings.sectionScale': 'Price scale',\n 'settings.sectionTheme': 'Theme',\n 'settings.indicatorTitle': '{name} settings',\n 'settings.tabInputs': 'Inputs',\n 'settings.tabStyle': 'Style',\n 'settings.tabVisibility': 'Visibility',\n 'settings.plots': 'Plots',\n 'settings.levels': 'Levels',\n 'settings.fills': 'Fills',\n 'settings.colorOf': '{name} color',\n 'settings.lineWidthOf': '{name} line width',\n 'settings.lineStyleOf': '{name} line style',\n 'settings.visibleOf': 'Show {name}',\n 'settings.lineStyleSolid': 'Solid',\n 'settings.lineStyleDashed': 'Dashed',\n 'settings.lineStyleDotted': 'Dotted',\n 'settings.precision': 'Precision',\n 'settings.precisionDefault': 'Default',\n 'settings.labelsOnPriceScale': 'Labels on price scale',\n 'settings.showIndicator': 'Show this indicator',\n}\n","import type { Translation } from '../runtime'\nimport type { toast as source } from '../en/toast'\n\nexport const toast: Translation<typeof source> = {\n 'toast.dismiss': 'Dismiss',\n 'toast.feedUnavailable': 'No data for {symbol} from this feed.',\n 'toast.feedNoData': 'No data for {symbol} yet.',\n 'toast.imageCopyFallback': 'Could not copy the image. Saved a file instead.',\n 'toast.imageFailed': 'Could not capture the chart image.',\n 'toast.indicatorsNotCarried': { one: '{count} indicator in this saved chart is not available here and was left out.', other: '{count} indicators in this saved chart are not available here and were left out.' },\n}\n","import type { Translation } from '../runtime'\nimport type { en } from '../en'\nimport { legend } from './legend'\nimport { tools } from './tools'\nimport { menu } from './menu'\nimport { replay } from './replay'\nimport { inputs } from './inputs'\nimport { session } from './session'\nimport { layouts } from './layouts'\nimport { host } from './host'\nimport { indicators } from './indicators'\nimport { timeframe } from './timeframe'\nimport { timezone } from './timezone'\nimport { range } from './range'\nimport { status } from './status'\nimport { search } from './search'\nimport { drawing } from './drawing'\nimport { command } from './command'\nimport { chrome } from './chrome'\nimport { history } from './history'\nimport { picker } from './picker'\nimport { settings } from './settings'\nimport { toast } from './toast'\n\nconst dict: Translation<typeof en> = { ...legend, ...tools, ...menu, ...replay, ...inputs, ...session, ...layouts, ...host, ...indicators, ...timeframe, ...timezone, ...range, ...status, ...search, ...drawing, ...command, ...chrome, ...history, ...picker, ...settings, ...toast }\nexport default dict\n"],"mappings":"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","names":[]}
|
package/dist/drawings.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { T as ToolCategory, S as SerializedDrawing, D as DrawingStyle, A as Anchor, I as IDrawing, M as MagnetMode, C as ChartMessageKey } from './assets-
|
|
2
|
-
export { a as CURSOR_LABELS, b as CURSOR_MODES, c as ControlPoint, d as CursorMode, e as DEFAULT_DRAWING_PREFERENCES, f as DEFAULT_FAVORITES, g as DEFAULT_OPTIONS, h as DEFAULT_PRESET_NAME, i as DEFAULT_STYLE, j as DEFAULT_VISIBILITY, k as DRAWING_PREFERENCES_KEY, l as DrawingAssetPort, m as DrawingCounts, n as DrawingOptions, o as DrawingPreferences, p as DrawingState, q as DrawingTemplates, F as FavoritesPort, r as FavoritesPosition, s as FavoritesState, G as GlyphSourcePort, t as IMAGE_ACCEPT, u as IMAGE_ERROR_MESSAGES, v as IMAGE_MAX_BYTES, w as IMAGE_MAX_EDGE, x as IMAGE_TYPES, y as ImageAsset, z as ImageIntakeError, B as ImageIntakeResult,
|
|
3
|
-
export { a as ChartLocalDrawingContext, D as DRAWING_CONTEXT_VERSION, b as DRAWING_DOCUMENT_VERSION, c as DrawingContextKind, d as DrawingEntry, e as DrawingGroup, f as DrawingResourceContext, g as DrawingTombstone, h as DrawingsBody, L as LayoutSharedDrawingContext, R as ResourceRef, i as ResourceStore, S as SymbolGlobalDrawingContext, T as TemplateBody, j as TemplateMeta, W as WriteOutcome, k as drawingContextKey, l as emptyDrawingDocument, m as liveDrawingEntries, n as liveDrawingGroups, o as mergeDrawingDocuments, p as parseDrawingDocument, r as reviseDrawingDocument, s as sameDrawingContext } from './resources-
|
|
1
|
+
import { T as ToolCategory, S as SerializedDrawing, D as DrawingStyle, A as Anchor, I as IDrawing, M as MagnetMode, C as ChartMessageKey } from './assets-DOuBBsOp.js';
|
|
2
|
+
export { a as CURSOR_LABELS, b as CURSOR_MODES, c as ControlPoint, d as CursorMode, e as DEFAULT_DRAWING_PREFERENCES, f as DEFAULT_FAVORITES, g as DEFAULT_OPTIONS, h as DEFAULT_PRESET_NAME, i as DEFAULT_STYLE, j as DEFAULT_VISIBILITY, k as DRAWING_PREFERENCES_KEY, l as DrawingAssetPort, m as DrawingCounts, n as DrawingOptions, o as DrawingPreferences, p as DrawingState, q as DrawingTemplates, F as FavoritesPort, r as FavoritesPosition, s as FavoritesState, G as GlyphSourcePort, t as IMAGE_ACCEPT, u as IMAGE_ERROR_MESSAGES, v as IMAGE_MAX_BYTES, w as IMAGE_MAX_EDGE, x as IMAGE_TYPES, y as ImageAsset, z as ImageIntakeError, B as ImageIntakeResult, L as LineStyle, E as MAX_FAVORITE_TOOLS, O as OhlcBar, P as Point, R as RemoveRow, H as TRANSIENT_LABELS, J as TRANSIENT_TOOLS, K as TimeframeBucket, N as TimeframeContext, Q as TimeframeVisibility, U as ToolPreset, V as ToolTemplate, W as TransientTool, X as Viewport, Y as VisibilityPreset, Z as VisibilityRange, _ as checkImageFile, $ as clampFavoritesPosition, a0 as cursorButtonArmed, a1 as decodePreset, a2 as favoritesBarShown, a3 as fitScale, a4 as fittedSize, a5 as isFavorite, a6 as isTransientTool, a7 as magnetSnap, a8 as normalizeVisibility, a9 as parseDrawingPreferences, aa as parseTimeframeContext, ab as pruneFavorites, ac as removableDrawings, ad as removeRows, ae as serializeDrawingPreferences, af as snapToBar, ag as toggleFavorite, ah as toolAfterPlacement, ai as transientSurvives, aj as visibilityPreset, ak as visibleAt } from './assets-DOuBBsOp.js';
|
|
3
|
+
export { a as ChartLocalDrawingContext, D as DRAWING_CONTEXT_VERSION, b as DRAWING_DOCUMENT_VERSION, c as DrawingContextKind, d as DrawingEntry, e as DrawingGroup, f as DrawingResourceContext, g as DrawingTombstone, h as DrawingsBody, L as LayoutSharedDrawingContext, R as ResourceRef, i as ResourceStore, S as SymbolGlobalDrawingContext, T as TemplateBody, j as TemplateMeta, W as WriteOutcome, k as drawingContextKey, l as emptyDrawingDocument, m as liveDrawingEntries, n as liveDrawingGroups, o as mergeDrawingDocuments, p as parseDrawingDocument, r as reviseDrawingDocument, s as sameDrawingContext } from './resources-Le6flcEn.js';
|
|
4
4
|
import 'lightweight-charts';
|
|
5
5
|
|
|
6
6
|
/** The alpha carried by a color value (rgba's 4th component); opaque formats report 1. */
|
|
@@ -10,7 +10,7 @@ declare function withAlpha(color: string, alpha: number): string;
|
|
|
10
10
|
|
|
11
11
|
declare function primeImageBitmap(key: string, image: HTMLImageElement): void;
|
|
12
12
|
|
|
13
|
-
/** Display order of categories in the toolbar
|
|
13
|
+
/** Display order of categories in the drawing toolbar. */
|
|
14
14
|
declare const TOOL_CATEGORIES: readonly ToolCategory[];
|
|
15
15
|
|
|
16
16
|
/** Parse a persisted store document. Total: malformed input is an EMPTY store, a non-array or
|
|
@@ -35,7 +35,7 @@ interface DrawingTool {
|
|
|
35
35
|
readonly anchors: number;
|
|
36
36
|
/** Style overrides every new drawing of this tool starts with. */
|
|
37
37
|
readonly style?: Partial<DrawingStyle>;
|
|
38
|
-
/** The tool renders
|
|
38
|
+
/** The tool renders the viewer's text, so a host opens its text editor once placement completes. */
|
|
39
39
|
readonly hasText?: boolean;
|
|
40
40
|
readonly placement?: DrawingPlacement;
|
|
41
41
|
/** The tool snapshots the bars between its anchors when placement completes. */
|
|
@@ -68,8 +68,8 @@ declare function restoreDrawings(list: readonly SerializedDrawing[]): IDrawing[]
|
|
|
68
68
|
/** The two modes the menu offers. Off is reached by toggling, never by picking. */
|
|
69
69
|
declare const MAGNET_STRENGTHS: readonly Exclude<MagnetMode, 'off'>[];
|
|
70
70
|
declare const MAGNET_LABELS: Readonly<Record<Exclude<MagnetMode, 'off'>, ChartMessageKey>>;
|
|
71
|
-
/** The toolbar button. It is a plain on/off switch over the LAST strength the
|
|
72
|
-
*
|
|
71
|
+
/** The toolbar button. It is a plain on/off switch over the LAST strength the viewer chose, so a
|
|
72
|
+
* viewer who set strong gets strong back when they turn the magnet on again. */
|
|
73
73
|
declare function toggleMagnet(mode: MagnetMode, lastStrength?: Exclude<MagnetMode, 'off'>): MagnetMode;
|
|
74
74
|
/** A menu row. Picking the active strength releases the magnet; picking the other switches to it
|
|
75
75
|
* without a trip through off. */
|
|
@@ -78,15 +78,15 @@ declare function chooseMagnetStrength(mode: MagnetMode, strength: Exclude<Magnet
|
|
|
78
78
|
declare const magnetActive: (mode: MagnetMode) => boolean;
|
|
79
79
|
|
|
80
80
|
/** One heading inside a group's flyout and the tools under it. */
|
|
81
|
-
interface
|
|
81
|
+
interface DrawingToolbarSection {
|
|
82
82
|
label: ChartMessageKey;
|
|
83
83
|
tools: DrawingTool[];
|
|
84
84
|
}
|
|
85
85
|
/** One toolbar button: its stable id, its heading, and the sections its flyout shows. */
|
|
86
|
-
interface
|
|
86
|
+
interface DrawingToolbarGroup {
|
|
87
87
|
id: string;
|
|
88
88
|
label: ChartMessageKey;
|
|
89
|
-
sections:
|
|
89
|
+
sections: DrawingToolbarSection[];
|
|
90
90
|
}
|
|
91
91
|
/** The arrow marks ride with the plain arrow line in the shapes group's Arrows section. */
|
|
92
92
|
declare const ARROW_TYPES: readonly string[];
|
|
@@ -115,20 +115,20 @@ interface GroupPlan {
|
|
|
115
115
|
}
|
|
116
116
|
/** The toolbar's seven groups and their sections, in display order. This is the product decision the
|
|
117
117
|
* registry cannot express: which categories share a button, and where the moved types land. */
|
|
118
|
-
declare const
|
|
118
|
+
declare const DRAWING_TOOLBAR_PLAN: readonly GroupPlan[];
|
|
119
119
|
/** Build the toolbar from the tool catalog. An empty section and a group left with none are dropped,
|
|
120
120
|
* so a catalog trimmed by configuration never shows a button that opens on nothing. */
|
|
121
|
-
declare function
|
|
121
|
+
declare function buildDrawingToolbarGroups(catalog?: DrawingToolCatalog): DrawingToolbarGroup[];
|
|
122
122
|
/** Which group holds a tool, or null when no group shows it. The toolbar highlights that button while
|
|
123
123
|
* the tool is armed. */
|
|
124
|
-
declare function groupOfTool(groups: readonly
|
|
124
|
+
declare function groupOfTool(groups: readonly DrawingToolbarGroup[], type: string | null): string | null;
|
|
125
125
|
/** Each toolbar button wears its last-picked tool's glyph, so the toolbar keeps that face across
|
|
126
126
|
* reloads. This resolves the face: the remembered tool when the group still shows it, else the
|
|
127
127
|
* group's first tool, else null for a group whose tools carry no glyph. */
|
|
128
|
-
declare function
|
|
128
|
+
declare function drawingToolbarFaceOf(group: DrawingToolbarGroup, lastTools: Readonly<Record<string, string>>): string | null;
|
|
129
129
|
/** Remember the tool a group was last used to arm. Returns a NEW record, so a caller stores the
|
|
130
130
|
* result rather than mutating what it was handed. A tool no group shows changes nothing. */
|
|
131
|
-
declare function
|
|
131
|
+
declare function rememberDrawingToolbarTool(groups: readonly DrawingToolbarGroup[], lastTools: Readonly<Record<string, string>>, type: string): Record<string, string>;
|
|
132
132
|
|
|
133
133
|
/** The layers the eye itself owns, and `all`. */
|
|
134
134
|
type BuiltInHideMode = 'drawings' | 'indicators' | 'all';
|
|
@@ -234,4 +234,4 @@ declare const NO_DASH: ReadonlySet<string>;
|
|
|
234
234
|
* A tool listed here gets the Inputs tab; unlisted props stay on Style. */
|
|
235
235
|
declare const INPUT_PROPS: Record<string, readonly string[]>;
|
|
236
236
|
|
|
237
|
-
export { ARROW_TYPES, Anchor, BAR_ONLY_COORDS, BRUSH_TYPES, type BuiltInHideMode, CARD_TYPES, CHART_HIDE_LAYERS, CLONE_OFFSET_PX, DEFAULT_HIDE_STATE, type DrawingPlacement, DrawingStyle, type DrawingTool, type DrawingToolCatalog, FILLABLE, FONT_TOOLS, GLYPH_TYPES, HIDE_LABELS, type HideMode, type HideState, IDrawing, INERT_PROPS, INPUT_PROPS, LABELED_PATTERNS, MAGNET_LABELS, MAGNET_STRENGTHS, MagnetMode, NO_DASH, NO_LINE_DECOR, NO_STROKE, NO_STYLE_TAB,
|
|
237
|
+
export { ARROW_TYPES, Anchor, BAR_ONLY_COORDS, BRUSH_TYPES, type BuiltInHideMode, CARD_TYPES, CHART_HIDE_LAYERS, CLONE_OFFSET_PX, DEFAULT_HIDE_STATE, DRAWING_TOOLBAR_PLAN, type DrawingPlacement, DrawingStyle, type DrawingTool, type DrawingToolCatalog, type DrawingToolbarGroup, type DrawingToolbarSection, FILLABLE, FONT_TOOLS, GLYPH_TYPES, HIDE_LABELS, type HideMode, type HideState, IDrawing, INERT_PROPS, INPUT_PROPS, LABELED_PATTERNS, MAGNET_LABELS, MAGNET_STRENGTHS, MagnetMode, NO_DASH, NO_LINE_DECOR, NO_STROKE, NO_STYLE_TAB, SerializedDrawing, TOOL_CATEGORIES, type TextCommit, type TextEditTarget, ToolCategory, alphaOf, blanks, buildDrawingToolbarGroups, cancelText, chooseHideMode, chooseMagnetStrength, commitText, drawingToolbarFaceOf, drawingTools, groupOfTool, hideOrder, hideRowActive, isBuiltInHideMode, magnetActive, opensTextEditor, parseDrawingsStore, primeImageBitmap, rememberDrawingToolbarTool, restoreDrawings, serializeDrawingsStore, toggleHide, toggleMagnet, withAlpha };
|