@tellegen/svelte 0.1.2 → 0.3.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/README.md +46 -0
- package/dist/Sparkline.svelte.d.ts +0 -1
- package/dist/TellegenMap.svelte +328 -200
- package/dist/TellegenMap.svelte.d.ts +0 -1
- package/dist/TellegenProvider.svelte +4 -0
- package/dist/TellegenProvider.svelte.d.ts +0 -1
- package/dist/TellegenShell.svelte +19 -13
- package/dist/TellegenShell.svelte.d.ts +0 -1
- package/dist/TellegenViewer.svelte.d.ts +0 -1
- package/dist/api.d.ts +8 -2
- package/dist/api.js +6 -2
- package/dist/colors.d.ts +7 -8
- package/dist/colors.js +13 -13
- package/dist/components/AppFooter.svelte.d.ts +0 -1
- package/dist/components/AppHeader.svelte +27 -13
- package/dist/components/AppHeader.svelte.d.ts +0 -1
- package/dist/components/BindingLines.svelte +3 -6
- package/dist/components/BindingLines.svelte.d.ts +0 -1
- package/dist/components/BusPicker.svelte +8 -2
- package/dist/components/BusPicker.svelte.d.ts +0 -1
- package/dist/components/ControlPanel.svelte +106 -343
- package/dist/components/ControlPanel.svelte.d.ts +0 -1
- package/dist/components/DemandSlider.svelte +26 -8
- package/dist/components/DemandSlider.svelte.d.ts +0 -1
- package/dist/components/DiagramCanvas.svelte +486 -0
- package/dist/components/DiagramCanvas.svelte.d.ts +13 -0
- package/dist/components/DisplayControls.svelte +4 -2
- package/dist/components/DisplayControls.svelte.d.ts +0 -1
- package/dist/components/DropZone.svelte.d.ts +0 -1
- package/dist/components/FormulationSelector.svelte +8 -3
- package/dist/components/FormulationSelector.svelte.d.ts +0 -1
- package/dist/components/LocalCaseDetails.svelte +57 -44
- package/dist/components/LocalCaseDetails.svelte.d.ts +0 -1
- package/dist/components/McResults.svelte +365 -0
- package/dist/components/McResults.svelte.d.ts +11 -0
- package/dist/components/ModelDetails.svelte +230 -0
- package/dist/components/ModelDetails.svelte.d.ts +7 -0
- package/dist/components/MulticonductorDetails.svelte +227 -78
- package/dist/components/MulticonductorDetails.svelte.d.ts +0 -1
- package/dist/components/NetworkStats.svelte +20 -18
- package/dist/components/NetworkStats.svelte.d.ts +0 -1
- package/dist/components/NotificationCenter.svelte +243 -0
- package/dist/components/NotificationCenter.svelte.d.ts +3 -0
- package/dist/components/PanelCard.svelte +319 -0
- package/dist/components/PanelCard.svelte.d.ts +9 -0
- package/dist/components/PanelFrame.svelte +46 -0
- package/dist/components/PanelFrame.svelte.d.ts +16 -0
- package/dist/components/PanelHost.svelte +212 -0
- package/dist/components/PanelHost.svelte.d.ts +3 -0
- package/dist/components/PlacementCue.svelte.d.ts +0 -1
- package/dist/components/PowerFlowDetails.svelte +99 -0
- package/dist/components/PowerFlowDetails.svelte.d.ts +3 -0
- package/dist/components/RatingSlider.svelte +5 -9
- package/dist/components/RatingSlider.svelte.d.ts +0 -1
- package/dist/components/RestoreDefaultsButton.svelte.d.ts +0 -1
- package/dist/components/SavedNetworkDetails.svelte +214 -0
- package/dist/components/SavedNetworkDetails.svelte.d.ts +3 -0
- package/dist/components/SensitivityReadout.svelte +24 -16
- package/dist/components/SensitivityReadout.svelte.d.ts +0 -1
- package/dist/components/SizeLegend.svelte.d.ts +0 -1
- package/dist/components/SolveCard.svelte +46 -49
- package/dist/components/SolveCard.svelte.d.ts +0 -1
- package/dist/components/TopMovers.svelte +8 -3
- package/dist/components/TopMovers.svelte.d.ts +2 -18
- package/dist/components.d.ts +2 -1
- package/dist/components.js +2 -0
- package/dist/context.svelte.d.ts +0 -1
- package/dist/controller.svelte.d.ts +74 -41
- package/dist/controller.svelte.js +1095 -284
- package/dist/diagram-labels.d.ts +9 -0
- package/dist/diagram-labels.js +40 -0
- package/dist/display.d.ts +3 -8
- package/dist/display.js +31 -27
- package/dist/drop-classify.d.ts +5 -42
- package/dist/drop-classify.js +5 -78
- package/dist/drop-limits.d.ts +27 -0
- package/dist/drop-limits.js +83 -0
- package/dist/format.d.ts +0 -1
- package/dist/format.js +5 -4
- package/dist/index.d.ts +11 -7
- package/dist/index.js +8 -3
- package/dist/map-bounds.d.ts +5 -0
- package/dist/map-bounds.js +41 -0
- package/dist/map.d.ts +1 -2
- package/dist/map.js +1 -1
- package/dist/multiconductor.d.ts +11 -3
- package/dist/multiconductor.js +107 -14
- package/dist/notices.svelte.d.ts +29 -0
- package/dist/notices.svelte.js +82 -0
- package/dist/panels.svelte.d.ts +65 -0
- package/dist/panels.svelte.js +215 -0
- package/dist/state.svelte.d.ts +90 -24
- package/dist/state.svelte.js +94 -20
- package/dist/synthetic-layout.d.ts +0 -1
- package/dist/synthetic-layout.js +17 -2
- package/dist/transformer-icon.d.ts +0 -1
- package/dist/types.d.ts +0 -1
- package/package.json +28 -12
- package/dist/Sparkline.svelte.d.ts.map +0 -1
- package/dist/TellegenMap.svelte.d.ts.map +0 -1
- package/dist/TellegenProvider.svelte.d.ts.map +0 -1
- package/dist/TellegenShell.svelte.d.ts.map +0 -1
- package/dist/TellegenViewer.svelte.d.ts.map +0 -1
- package/dist/api.d.ts.map +0 -1
- package/dist/colors.d.ts.map +0 -1
- package/dist/components/AppFooter.svelte.d.ts.map +0 -1
- package/dist/components/AppHeader.svelte.d.ts.map +0 -1
- package/dist/components/BindingLines.svelte.d.ts.map +0 -1
- package/dist/components/BusPicker.svelte.d.ts.map +0 -1
- package/dist/components/ControlPanel.svelte.d.ts.map +0 -1
- package/dist/components/DemandSlider.svelte.d.ts.map +0 -1
- package/dist/components/DisplayControls.svelte.d.ts.map +0 -1
- package/dist/components/DropZone.svelte.d.ts.map +0 -1
- package/dist/components/FormulationSelector.svelte.d.ts.map +0 -1
- package/dist/components/LocalCaseDetails.svelte.d.ts.map +0 -1
- package/dist/components/MulticonductorDetails.svelte.d.ts.map +0 -1
- package/dist/components/NetworkStats.svelte.d.ts.map +0 -1
- package/dist/components/PlacementCue.svelte.d.ts.map +0 -1
- package/dist/components/RatingSlider.svelte.d.ts.map +0 -1
- package/dist/components/RestoreDefaultsButton.svelte.d.ts.map +0 -1
- package/dist/components/SensitivityReadout.svelte.d.ts.map +0 -1
- package/dist/components/SizeLegend.svelte.d.ts.map +0 -1
- package/dist/components/SolveCard.svelte.d.ts.map +0 -1
- package/dist/components/TopMovers.svelte.d.ts.map +0 -1
- package/dist/components.d.ts.map +0 -1
- package/dist/context.svelte.d.ts.map +0 -1
- package/dist/controller.svelte.d.ts.map +0 -1
- package/dist/display.d.ts.map +0 -1
- package/dist/drop-classify.d.ts.map +0 -1
- package/dist/format.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/map.d.ts.map +0 -1
- package/dist/multiconductor.d.ts.map +0 -1
- package/dist/state.svelte.d.ts.map +0 -1
- package/dist/study-package.d.ts +0 -9
- package/dist/study-package.d.ts.map +0 -1
- package/dist/study-package.js +0 -17
- package/dist/synthetic-layout.d.ts.map +0 -1
- package/dist/transformer-icon.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type PositionedLabel = {
|
|
2
|
+
id: number;
|
|
3
|
+
lon: number;
|
|
4
|
+
lat: number;
|
|
5
|
+
name?: string | null;
|
|
6
|
+
};
|
|
7
|
+
/** Place labels in screen pixels so zooming reveals equipment names as space opens. */
|
|
8
|
+
export declare function diagramLabels(buses: PositionedLabel[], scale: number, x: number, y: number, width: number, height: number, selected: number | null): Set<number>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Place labels in screen pixels so zooming reveals equipment names as space opens. */
|
|
2
|
+
export function diagramLabels(buses, scale, x, y, width, height, selected) {
|
|
3
|
+
const visible = new Set();
|
|
4
|
+
const cells = new Map();
|
|
5
|
+
const order = selected === null
|
|
6
|
+
? buses
|
|
7
|
+
: [
|
|
8
|
+
...buses.filter((bus) => bus.id === selected),
|
|
9
|
+
...buses.filter((bus) => bus.id !== selected)
|
|
10
|
+
];
|
|
11
|
+
for (const bus of order) {
|
|
12
|
+
const label = bus.name || String(bus.id);
|
|
13
|
+
const left = bus.lon * scale + x + 8;
|
|
14
|
+
const bottom = bus.lat * scale + y - 7;
|
|
15
|
+
const box = { left, bottom, right: left + label.length * 7 + 6, top: bottom - 16 };
|
|
16
|
+
if (box.right < 0 || box.left > width || box.bottom < 0 || box.top > height)
|
|
17
|
+
continue;
|
|
18
|
+
const keys = [];
|
|
19
|
+
let overlaps = false;
|
|
20
|
+
for (let col = Math.floor(Math.max(0, box.left) / 64); col <= Math.floor(Math.min(width, box.right) / 64); col++) {
|
|
21
|
+
for (let row = Math.floor(Math.max(0, box.top) / 64); row <= Math.floor(Math.min(height, box.bottom) / 64); row++) {
|
|
22
|
+
const key = `${col},${row}`;
|
|
23
|
+
keys.push(key);
|
|
24
|
+
if (cells
|
|
25
|
+
.get(key)
|
|
26
|
+
?.some((other) => box.left < other.right &&
|
|
27
|
+
box.right > other.left &&
|
|
28
|
+
box.top < other.bottom &&
|
|
29
|
+
box.bottom > other.top))
|
|
30
|
+
overlaps = true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (overlaps)
|
|
34
|
+
continue;
|
|
35
|
+
visible.add(bus.id);
|
|
36
|
+
for (const key of keys)
|
|
37
|
+
cells.set(key, [...(cells.get(key) ?? []), box]);
|
|
38
|
+
}
|
|
39
|
+
return visible;
|
|
40
|
+
}
|
package/dist/display.d.ts
CHANGED
|
@@ -10,14 +10,10 @@ export type DisplayOption = {
|
|
|
10
10
|
copy: string;
|
|
11
11
|
gradient: string;
|
|
12
12
|
};
|
|
13
|
-
/**
|
|
14
|
-
* LMP always, the DC phase angle under DC OPF, the relaxed |V| under SOCWR. Metadata
|
|
15
|
-
* only; call `displaySeriesFor` for one mode's per-bus values. Empty when unsolved. */
|
|
13
|
+
/** Variables present in the current result. Power flow has no LMP values. */
|
|
16
14
|
export declare function displayMetaFor(c: SolvableCase | null): DisplayOption[];
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* Empty when the case is unsolved. Single source for both the panel legend stats and
|
|
20
|
-
* the map node coloring, so the |V| transform stays in one place. */
|
|
15
|
+
/** Bus LMPs, voltage angles in radians, or voltage magnitudes in per unit.
|
|
16
|
+
* SOCWR supplies squared voltages, which are converted to magnitudes here. */
|
|
21
17
|
export declare function displaySeriesFor(c: SolvableCase | null, mode: DisplayMode): {
|
|
22
18
|
bus: number;
|
|
23
19
|
value: number;
|
|
@@ -28,4 +24,3 @@ export declare function caseDeltas(c: SolvableCase): DemandDeltas;
|
|
|
28
24
|
/** The committed branch rating deltas for a case (MW from base, keyed by branch).
|
|
29
25
|
* The rating counterpart of `caseDeltas`. */
|
|
30
26
|
export declare function caseRatings(c: SolvableCase): BranchRatingDeltas;
|
|
31
|
-
//# sourceMappingURL=display.d.ts.map
|
package/dist/display.js
CHANGED
|
@@ -1,45 +1,44 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { priceGradient } from './colors.js';
|
|
2
2
|
import { priceCopy } from './format.js';
|
|
3
3
|
import { CaseState } from './state.svelte.js';
|
|
4
|
-
/**
|
|
5
|
-
* LMP always, the DC phase angle under DC OPF, the relaxed |V| under SOCWR. Metadata
|
|
6
|
-
* only; call `displaySeriesFor` for one mode's per-bus values. Empty when unsolved. */
|
|
4
|
+
/** Variables present in the current result. Power flow has no LMP values. */
|
|
7
5
|
export function displayMetaFor(c) {
|
|
8
6
|
if (!c?.solution)
|
|
9
7
|
return [];
|
|
10
|
-
const options = [
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const options = [];
|
|
9
|
+
if (c.formulation !== 'acpf' && c.solution.prices.length > 0) {
|
|
10
|
+
options.push({
|
|
11
|
+
mode: 'price',
|
|
13
12
|
label: 'LMP',
|
|
14
|
-
unit: '
|
|
13
|
+
unit: 'objective units/MW',
|
|
15
14
|
copy: priceCopy(c.formulation),
|
|
16
|
-
gradient:
|
|
17
|
-
}
|
|
18
|
-
];
|
|
19
|
-
if (c.formulation === 'dcopf' && c.solution.va.length > 0) {
|
|
20
|
-
options.push({
|
|
21
|
-
mode: 'angle',
|
|
22
|
-
label: 'angle',
|
|
23
|
-
unit: 'rad',
|
|
24
|
-
copy: 'DC bus voltage phase angle from the current OPF solution.',
|
|
25
|
-
gradient: lmpGradient
|
|
15
|
+
gradient: priceGradient
|
|
26
16
|
});
|
|
27
17
|
}
|
|
28
|
-
if (c.
|
|
18
|
+
if (c.solution.vm?.length || c.solution.w.length > 0) {
|
|
29
19
|
options.push({
|
|
30
20
|
mode: 'voltage',
|
|
31
21
|
label: '|V|',
|
|
32
22
|
unit: 'pu',
|
|
33
|
-
copy:
|
|
34
|
-
|
|
23
|
+
copy: c.formulation === 'socwr'
|
|
24
|
+
? 'SOCWR voltage magnitude from the current relaxed solution.'
|
|
25
|
+
: 'Bus voltage magnitude from the current power-flow result.',
|
|
26
|
+
gradient: priceGradient
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (c.solution.va.length > 0) {
|
|
30
|
+
options.push({
|
|
31
|
+
mode: 'angle',
|
|
32
|
+
label: 'angle',
|
|
33
|
+
unit: 'rad',
|
|
34
|
+
copy: 'Bus voltage angle from the current result.',
|
|
35
|
+
gradient: priceGradient
|
|
35
36
|
});
|
|
36
37
|
}
|
|
37
38
|
return options;
|
|
38
39
|
}
|
|
39
|
-
/**
|
|
40
|
-
*
|
|
41
|
-
* Empty when the case is unsolved. Single source for both the panel legend stats and
|
|
42
|
-
* the map node coloring, so the |V| transform stays in one place. */
|
|
40
|
+
/** Bus LMPs, voltage angles in radians, or voltage magnitudes in per unit.
|
|
41
|
+
* SOCWR supplies squared voltages, which are converted to magnitudes here. */
|
|
43
42
|
export function displaySeriesFor(c, mode) {
|
|
44
43
|
const sol = c?.solution;
|
|
45
44
|
if (!sol)
|
|
@@ -47,9 +46,14 @@ export function displaySeriesFor(c, mode) {
|
|
|
47
46
|
if (mode === 'angle')
|
|
48
47
|
return sol.va;
|
|
49
48
|
if (mode === 'voltage') {
|
|
50
|
-
|
|
49
|
+
if (sol.vm?.length)
|
|
50
|
+
return sol.vm;
|
|
51
|
+
return sol.w.map((s) => ({
|
|
52
|
+
bus: s.bus,
|
|
53
|
+
value: Math.sqrt(Math.max(0, s.value))
|
|
54
|
+
}));
|
|
51
55
|
}
|
|
52
|
-
return sol.
|
|
56
|
+
return sol.prices.map((s) => ({ bus: s.bus, value: s.value }));
|
|
53
57
|
}
|
|
54
58
|
/** The committed demand deltas for a case (MW from base, keyed by bus). A backend
|
|
55
59
|
* case always carries a deltas map; a local case defaults to an empty one. */
|
package/dist/drop-classify.d.ts
CHANGED
|
@@ -1,48 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* the balanced `.m`/`.raw`/`.aux` via `formatOf` in the engine) is name-based;
|
|
4
|
-
* everything under `.json` is content-sniffed here so there is one place that
|
|
5
|
-
* decides package-vs-case and balanced-vs-multiconductor.
|
|
6
|
-
*
|
|
7
|
-
* The rules mirror the readers they feed:
|
|
8
|
-
* - a `.pio.json` package is recognized by its `schema` envelope field, then
|
|
9
|
-
* split by the authoritative `model_kind` (balanced restores a study;
|
|
10
|
-
* multiconductor is viewed);
|
|
11
|
-
* - a non-package document is distribution JSON, PMD when it carries the
|
|
12
|
-
* `data_model` marker and BMOPF otherwise (the same split
|
|
13
|
-
* `powerio_dist` uses for `.json`), except a GeoJSON FeatureCollection,
|
|
14
|
-
* which stays unrouted so the geo sidecar path keeps accepting it.
|
|
15
|
-
*
|
|
16
|
-
* Every function is total: malformed, truncated, or non-JSON input classifies
|
|
17
|
-
* as `not-json` rather than throwing. */
|
|
18
|
-
/** The schema URL prefix every `.pio.json` package envelope carries. */
|
|
19
|
-
export declare const PIO_PACKAGE_SCHEMA_PREFIX = "https://powerio.dev/schema/pio-package";
|
|
20
|
-
/** How a dropped JSON file should be ingested. */
|
|
21
|
-
export type JsonDropKind =
|
|
22
|
-
/** A saved balanced study package: restore the case, edits, and formulation. */
|
|
23
|
-
'balanced-package'
|
|
24
|
-
/** A package carrying a multiconductor payload: view it (no solve). */
|
|
25
|
-
| 'multiconductor-package'
|
|
26
|
-
/** A BMOPF JSON distribution case. */
|
|
27
|
-
| 'bmopf'
|
|
28
|
-
/** A PowerModelsDistribution ENGINEERING JSON case. */
|
|
29
|
-
| 'pmd'
|
|
30
|
-
/** Not JSON, or JSON we do not route (left to the generic error path). */
|
|
31
|
-
| 'not-json';
|
|
1
|
+
/** File name helpers for drop routing. JSON content classification lives in
|
|
2
|
+
* powerio's Rust/Wasm `classify_json_bytes` path, not in this TypeScript layer. */
|
|
32
3
|
/** The distribution format for a file recognized by extension, or null. Only
|
|
33
|
-
* `.dss` is name
|
|
34
|
-
*
|
|
4
|
+
* `.dss` is name routed; PMD and BMOPF share the `.json` extension and are
|
|
5
|
+
* classified by the engine. */
|
|
35
6
|
export declare function distExtensionFormat(name: string): 'dss' | null;
|
|
36
7
|
/** True for geographic sidecar files by extension (`.csv`, `.json`,
|
|
37
8
|
* `.geojson`). Routable `.json` content (packages, distribution documents) is
|
|
38
|
-
* consumed by
|
|
9
|
+
* consumed by the engine classifier before this applies; what remains parses
|
|
39
10
|
* through the engine's tolerant geo reader. */
|
|
40
11
|
export declare function isGeoFileName(name: string): boolean;
|
|
41
|
-
/** Whether `text` is a `.pio.json` package envelope, by its `schema` field. */
|
|
42
|
-
export declare function isPackageEnvelope(obj: Record<string, unknown> | null): boolean;
|
|
43
|
-
/** Classify a dropped JSON document into its ingest path. */
|
|
44
|
-
export declare function classifyJson(text: string): JsonDropKind;
|
|
45
|
-
/** Whether `text` is a saved study package (a balanced `.pio.json`). Kept for
|
|
46
|
-
* the study-restore path; multiconductor packages are viewed, not restored. */
|
|
47
|
-
export declare function isStudyPackageText(text: string): boolean;
|
|
48
|
-
//# sourceMappingURL=drop-classify.d.ts.map
|
package/dist/drop-classify.js
CHANGED
|
@@ -1,31 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* the balanced `.m`/`.raw`/`.aux` via `formatOf` in the engine) is name-based;
|
|
4
|
-
* everything under `.json` is content-sniffed here so there is one place that
|
|
5
|
-
* decides package-vs-case and balanced-vs-multiconductor.
|
|
6
|
-
*
|
|
7
|
-
* The rules mirror the readers they feed:
|
|
8
|
-
* - a `.pio.json` package is recognized by its `schema` envelope field, then
|
|
9
|
-
* split by the authoritative `model_kind` (balanced restores a study;
|
|
10
|
-
* multiconductor is viewed);
|
|
11
|
-
* - a non-package document is distribution JSON, PMD when it carries the
|
|
12
|
-
* `data_model` marker and BMOPF otherwise (the same split
|
|
13
|
-
* `powerio_dist` uses for `.json`), except a GeoJSON FeatureCollection,
|
|
14
|
-
* which stays unrouted so the geo sidecar path keeps accepting it.
|
|
15
|
-
*
|
|
16
|
-
* Every function is total: malformed, truncated, or non-JSON input classifies
|
|
17
|
-
* as `not-json` rather than throwing. */
|
|
18
|
-
/** The schema URL prefix every `.pio.json` package envelope carries. */
|
|
19
|
-
export const PIO_PACKAGE_SCHEMA_PREFIX = 'https://powerio.dev/schema/pio-package';
|
|
1
|
+
/** File name helpers for drop routing. JSON content classification lives in
|
|
2
|
+
* powerio's Rust/Wasm `classify_json_bytes` path, not in this TypeScript layer. */
|
|
20
3
|
/** The distribution format for a file recognized by extension, or null. Only
|
|
21
|
-
* `.dss` is name
|
|
22
|
-
*
|
|
4
|
+
* `.dss` is name routed; PMD and BMOPF share the `.json` extension and are
|
|
5
|
+
* classified by the engine. */
|
|
23
6
|
export function distExtensionFormat(name) {
|
|
24
7
|
return name.split('.').pop()?.toLowerCase() === 'dss' ? 'dss' : null;
|
|
25
8
|
}
|
|
26
9
|
/** True for geographic sidecar files by extension (`.csv`, `.json`,
|
|
27
10
|
* `.geojson`). Routable `.json` content (packages, distribution documents) is
|
|
28
|
-
* consumed by
|
|
11
|
+
* consumed by the engine classifier before this applies; what remains parses
|
|
29
12
|
* through the engine's tolerant geo reader. */
|
|
30
13
|
export function isGeoFileName(name) {
|
|
31
14
|
const dot = name.lastIndexOf('.');
|
|
@@ -34,59 +17,3 @@ export function isGeoFileName(name) {
|
|
|
34
17
|
const ext = name.slice(dot + 1).toLowerCase();
|
|
35
18
|
return ext === 'csv' || ext === 'json' || ext === 'geojson';
|
|
36
19
|
}
|
|
37
|
-
/** Parse `text` as JSON, returning the top-level object or null. */
|
|
38
|
-
function topLevelObject(text) {
|
|
39
|
-
let value;
|
|
40
|
-
try {
|
|
41
|
-
value = JSON.parse(text);
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
47
|
-
? value
|
|
48
|
-
: null;
|
|
49
|
-
}
|
|
50
|
-
/** Whether `text` is a `.pio.json` package envelope, by its `schema` field. */
|
|
51
|
-
export function isPackageEnvelope(obj) {
|
|
52
|
-
return typeof obj?.schema === 'string' && obj.schema.startsWith(PIO_PACKAGE_SCHEMA_PREFIX);
|
|
53
|
-
}
|
|
54
|
-
/** The package's model family. `model_kind` is authoritative and stored
|
|
55
|
-
* explicitly; fall back to the payload's own `model.kind` tag for a package
|
|
56
|
-
* written before the field existed. */
|
|
57
|
-
function packageModelKind(obj) {
|
|
58
|
-
const explicit = obj.model_kind;
|
|
59
|
-
if (explicit === 'balanced' || explicit === 'multiconductor')
|
|
60
|
-
return explicit;
|
|
61
|
-
const payloadKind = obj.model?.kind;
|
|
62
|
-
if (payloadKind === 'balanced' || payloadKind === 'multiconductor')
|
|
63
|
-
return payloadKind;
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
/** Classify a dropped JSON document into its ingest path. */
|
|
67
|
-
export function classifyJson(text) {
|
|
68
|
-
const obj = topLevelObject(text);
|
|
69
|
-
if (!obj)
|
|
70
|
-
return 'not-json';
|
|
71
|
-
if (isPackageEnvelope(obj)) {
|
|
72
|
-
const kind = packageModelKind(obj);
|
|
73
|
-
// A package with no readable kind is treated as balanced: that is the
|
|
74
|
-
// historical payload and the study-restore path fails closed on a
|
|
75
|
-
// non-balanced document anyway.
|
|
76
|
-
return kind === 'multiconductor' ? 'multiconductor-package' : 'balanced-package';
|
|
77
|
-
}
|
|
78
|
-
// A GeoJSON FeatureCollection saved as `.json` is coordinate data for the
|
|
79
|
-
// geo sidecar path, which accepted it before this classifier existed; leave
|
|
80
|
-
// it unrouted so it falls through.
|
|
81
|
-
if (Array.isArray(obj.features))
|
|
82
|
-
return 'not-json';
|
|
83
|
-
// Non-package JSON is a distribution document: PMD declares `data_model`,
|
|
84
|
-
// everything else is routed to BMOPF (which gives the precise parse error
|
|
85
|
-
// when it is neither).
|
|
86
|
-
return 'data_model' in obj ? 'pmd' : 'bmopf';
|
|
87
|
-
}
|
|
88
|
-
/** Whether `text` is a saved study package (a balanced `.pio.json`). Kept for
|
|
89
|
-
* the study-restore path; multiconductor packages are viewed, not restored. */
|
|
90
|
-
export function isStudyPackageText(text) {
|
|
91
|
-
return classifyJson(text) === 'balanced-package';
|
|
92
|
-
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Browser drop limits. Each accepted file is copied into JavaScript and worker/wasm
|
|
2
|
+
* memory, so the whole batch is checked before any file contents are read. */
|
|
3
|
+
export declare const MAX_DROP_FILES = 32;
|
|
4
|
+
export declare const MAX_DROP_FILE_BYTES: number;
|
|
5
|
+
export declare const MAX_DROP_TOTAL_BYTES: number;
|
|
6
|
+
type DropFileDescriptor = {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly size: number;
|
|
9
|
+
};
|
|
10
|
+
/** One-at-a-time admission for browser ingestion. A second drop is refused
|
|
11
|
+
* while the first still owns its release callback, so independently valid
|
|
12
|
+
* batches cannot queue enough worker copies to bypass the aggregate limit. */
|
|
13
|
+
export declare class DropBatchGate {
|
|
14
|
+
#private;
|
|
15
|
+
enter(): (() => void) | null;
|
|
16
|
+
}
|
|
17
|
+
/** Return bytes retained by an earlier routing pass, or read the file once when
|
|
18
|
+
* no retained buffer exists. Keeping this decision here makes the no-reread
|
|
19
|
+
* guarantee independently testable. */
|
|
20
|
+
export declare function readDropFileBytes(file: {
|
|
21
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
22
|
+
}, retained?: Uint8Array): Promise<Uint8Array>;
|
|
23
|
+
/** Validate and materialize an array-like browser file batch without calling
|
|
24
|
+
* `Array.from` first. The count and every declared byte size must be safe integers,
|
|
25
|
+
* and aggregate addition is guarded before it is performed. */
|
|
26
|
+
export declare function validateDropBatch<T extends DropFileDescriptor>(input: ArrayLike<T>): T[];
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** Browser drop limits. Each accepted file is copied into JavaScript and worker/wasm
|
|
2
|
+
* memory, so the whole batch is checked before any file contents are read. */
|
|
3
|
+
export const MAX_DROP_FILES = 32;
|
|
4
|
+
export const MAX_DROP_FILE_BYTES = 128 * 1024 * 1024;
|
|
5
|
+
export const MAX_DROP_TOTAL_BYTES = 128 * 1024 * 1024;
|
|
6
|
+
/** One-at-a-time admission for browser ingestion. A second drop is refused
|
|
7
|
+
* while the first still owns its release callback, so independently valid
|
|
8
|
+
* batches cannot queue enough worker copies to bypass the aggregate limit. */
|
|
9
|
+
export class DropBatchGate {
|
|
10
|
+
#active = false;
|
|
11
|
+
enter() {
|
|
12
|
+
if (this.#active)
|
|
13
|
+
return null;
|
|
14
|
+
this.#active = true;
|
|
15
|
+
let released = false;
|
|
16
|
+
return () => {
|
|
17
|
+
if (released)
|
|
18
|
+
return;
|
|
19
|
+
released = true;
|
|
20
|
+
this.#active = false;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Return bytes retained by an earlier routing pass, or read the file once when
|
|
25
|
+
* no retained buffer exists. Keeping this decision here makes the no-reread
|
|
26
|
+
* guarantee independently testable. */
|
|
27
|
+
export async function readDropFileBytes(file, retained) {
|
|
28
|
+
return retained ?? new Uint8Array(await file.arrayBuffer());
|
|
29
|
+
}
|
|
30
|
+
/** Validate and materialize an array-like browser file batch without calling
|
|
31
|
+
* `Array.from` first. The count and every declared byte size must be safe integers,
|
|
32
|
+
* and aggregate addition is guarded before it is performed. */
|
|
33
|
+
export function validateDropBatch(input) {
|
|
34
|
+
let length;
|
|
35
|
+
try {
|
|
36
|
+
length = input.length;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
throw new Error('the dropped file count is invalid');
|
|
40
|
+
}
|
|
41
|
+
if (typeof length !== 'number' || !Number.isSafeInteger(length) || length < 0) {
|
|
42
|
+
throw new Error('the dropped file count is invalid');
|
|
43
|
+
}
|
|
44
|
+
if (length > MAX_DROP_FILES) {
|
|
45
|
+
throw new Error(`drop at most ${MAX_DROP_FILES} files at a time`);
|
|
46
|
+
}
|
|
47
|
+
const files = [];
|
|
48
|
+
let totalBytes = 0;
|
|
49
|
+
for (let index = 0; index < length; index++) {
|
|
50
|
+
let file;
|
|
51
|
+
try {
|
|
52
|
+
file = input[index];
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
throw new Error(`dropped file ${index + 1} is invalid`);
|
|
56
|
+
}
|
|
57
|
+
if (!file || typeof file !== 'object') {
|
|
58
|
+
throw new Error(`dropped file ${index + 1} is invalid`);
|
|
59
|
+
}
|
|
60
|
+
let size;
|
|
61
|
+
let name;
|
|
62
|
+
try {
|
|
63
|
+
size = file.size;
|
|
64
|
+
name = file.name;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
throw new Error(`dropped file ${index + 1} is invalid`);
|
|
68
|
+
}
|
|
69
|
+
const label = typeof name === 'string' && name.length > 0 ? name : `dropped file ${index + 1}`;
|
|
70
|
+
if (typeof size !== 'number' || !Number.isSafeInteger(size) || size < 0) {
|
|
71
|
+
throw new Error(`${label} has an invalid file size`);
|
|
72
|
+
}
|
|
73
|
+
if (size > MAX_DROP_FILE_BYTES) {
|
|
74
|
+
throw new Error(`${label} exceeds the ${MAX_DROP_FILE_BYTES}-byte per-file limit`);
|
|
75
|
+
}
|
|
76
|
+
if (size > MAX_DROP_TOTAL_BYTES - totalBytes) {
|
|
77
|
+
throw new Error(`the dropped files exceed the ${MAX_DROP_TOTAL_BYTES}-byte total limit`);
|
|
78
|
+
}
|
|
79
|
+
totalBytes += size;
|
|
80
|
+
files.push(file);
|
|
81
|
+
}
|
|
82
|
+
return files;
|
|
83
|
+
}
|
package/dist/format.d.ts
CHANGED
|
@@ -27,4 +27,3 @@ export declare const fmt: Intl.NumberFormat;
|
|
|
27
27
|
export declare const signed: (v: number) => string;
|
|
28
28
|
export declare const signedExp: (v: number) => string;
|
|
29
29
|
export declare const displayFmt: (mode: DisplayMode, value: number) => string;
|
|
30
|
-
//# sourceMappingURL=format.d.ts.map
|
package/dist/format.js
CHANGED
|
@@ -10,9 +10,10 @@ export function formulationHint(id) {
|
|
|
10
10
|
return FORMULATIONS.find((f) => f.id === id)?.hint ?? id;
|
|
11
11
|
}
|
|
12
12
|
export function priceCopy(id) {
|
|
13
|
+
const definition = 'Locational marginal price (LMP): the change in the OPF objective for an additional MW at a bus, in objective units/MW.';
|
|
13
14
|
return id === 'socwr'
|
|
14
|
-
?
|
|
15
|
-
:
|
|
15
|
+
? `${definition} Prices come from the SOCWR relaxation. Select a bus to see their sensitivity.`
|
|
16
|
+
: `${definition} Select a bus to see its demand sensitivity.`;
|
|
16
17
|
}
|
|
17
18
|
export function splitName(name) {
|
|
18
19
|
const m = name.match(/^(.*?)\s*\((.*)\)$/);
|
|
@@ -22,7 +23,7 @@ export function solveMetaLabel(c) {
|
|
|
22
23
|
if ((c.iterations ?? []).length > 1)
|
|
23
24
|
return `${c.iterations?.length} iterations`;
|
|
24
25
|
if (c.solveBackend === 'clarabel-wasm-server-sensitivity')
|
|
25
|
-
return 'server
|
|
26
|
+
return 'server price sensitivity';
|
|
26
27
|
return c.solveBackend === 'rust-server' ? 'server solve' : 'browser solve';
|
|
27
28
|
}
|
|
28
29
|
export function rgbaCss([r, g, b, a]) {
|
|
@@ -46,4 +47,4 @@ export function extent(values) {
|
|
|
46
47
|
export const fmt = new Intl.NumberFormat('en-US', { maximumFractionDigits: 1 });
|
|
47
48
|
export const signed = (v) => `${v < 0 ? '−' : '+'}${fmt.format(Math.abs(v))}`;
|
|
48
49
|
export const signedExp = (v) => `${v < 0 ? '−' : '+'}${Math.abs(v).toExponential(2)}`;
|
|
49
|
-
export const displayFmt = (mode, value) => mode === '
|
|
50
|
+
export const displayFmt = (mode, value) => mode === 'price' ? fmt.format(value) : value.toFixed(3);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export { getNoticeCenter, errorNoticeTitle } from './notices.svelte.js';
|
|
2
|
+
export { default as ModelDetails } from './components/ModelDetails.svelte';
|
|
3
|
+
export { default as PanelFrame } from './components/PanelFrame.svelte';
|
|
4
|
+
export { getPanelLayout } from './panels.svelte.js';
|
|
5
|
+
export type { PanelSide, PanelPosition, PanelBounds } from './panels.svelte.js';
|
|
1
6
|
export { default as TellegenProvider } from './TellegenProvider.svelte';
|
|
2
7
|
export { default as TellegenShell } from './TellegenShell.svelte';
|
|
3
8
|
export { default as TellegenViewer } from './TellegenViewer.svelte';
|
|
@@ -6,16 +11,15 @@ export { DEFAULT_TELLEGEN_UI_CONFIG, getAppState, getController, getUiConfig, re
|
|
|
6
11
|
export { ApiError, createApiClient } from './api.js';
|
|
7
12
|
export { Controller, createController } from './controller.svelte.js';
|
|
8
13
|
export { AppState, CaseState, LocalCase, MulticonductorCase, createAppState } from './state.svelte.js';
|
|
9
|
-
export { attachmentColor, attachmentGlyph, edgeColor, edgeWidth, phaseColor, placeMultiView, buildGeographicView } from './multiconductor.js';
|
|
10
|
-
export {
|
|
14
|
+
export { attachmentColor, attachmentGlyph, edgeColor, edgeWidth, phaseColor, neutralTerminal, placeMultiView, buildGeographicView } from './multiconductor.js';
|
|
15
|
+
export { distExtensionFormat } from './drop-classify.js';
|
|
11
16
|
export { caseDeltas, caseRatings, displayMetaFor, displaySeriesFor } from './display.js';
|
|
12
|
-
export { DEFAULT_FORMULATION, FORMULATIONS, BrowserStudy, Study, capabilities, createStudy, errorText, formatOf, ingestCase, isDisplayFile, isPermanentEngineFailure, parseDisplay,
|
|
17
|
+
export { DEFAULT_FORMULATION, FORMULATIONS, BrowserStudy, Study, capabilities, createStudy, errorText, formatOf, classifyJson, ingestJsonDrop, ingestCase, isDisplayFile, isPermanentEngineFailure, parseDisplay, solveModule } from '@tellegen/engine';
|
|
13
18
|
export type { BranchRatingDeltas, CaseSummary, DemandDeltas, Network, NetworkBranch, NetworkBus, SensitivityColumn, Solution, SolveIteration, SolveStreamHandlers, TellegenApiClient, TellegenApiClientOptions } from './api.js';
|
|
14
19
|
export type { TellegenUiConfig, TellegenUiOptions } from './context.svelte.js';
|
|
15
20
|
export type { ControllerOptions } from './controller.svelte.js';
|
|
16
21
|
export type { DisplayOption } from './display.js';
|
|
17
|
-
export type { DemandRangeMode, DisplayMode, FallbackTarget, LocalCaseInit, LocalSubstations, MultiCaseSummary, MultiCoordsKind, SolvableCase, SolveBackend } from './state.svelte.js';
|
|
18
|
-
export type { JsonDropKind } from './drop-classify.js';
|
|
22
|
+
export type { CameraSnapshot, DiagramCameraSnapshot, DemandRangeMode, DisplayMode, FallbackTarget, LocalCaseInit, LocalSubstations, MultiCaseSummary, MultiCoordsKind, SolvableCase, StudyDisplaySnapshot, SolveBackend } from './state.svelte.js';
|
|
19
23
|
export type { MultiView, PlacedMultiBus, PlacedMultiEdge } from './multiconductor.js';
|
|
20
|
-
export type { CaseFileSummary, DistAttachmentKind, DistEdgeKind, DistGraph, DistGraphAttachment, DistGraphBus, DistGraphEdge, DisplayPreview, Formulation, IngestedCase, IngestedDistCase, SensTarget, Topology, TopologyBranch, TopologyBus } from '@tellegen/engine';
|
|
21
|
-
|
|
24
|
+
export type { CaseFileSummary, DistAttachmentKind, DistEdgeKind, DistGraph, DistGraphAttachment, DistGraphBus, DistGraphEdge, DisplayPreview, Formulation, IngestedCase, IngestedDistCase, IngestedJsonDrop, JsonDropClassification, JsonDropKind, CapacityPlanBusWeightJson, CapacityPlanIterationJson, CapacityPlanOutcomeJson, CapacityPlanRatingChangeJson, CapacityPlanResultSummaryJson, CapacityPlanSpecJson, ImplicitObjectiveJson, SensTarget, Topology, TopologyBranch, TopologyBus } from '@tellegen/engine';
|
|
25
|
+
export { default as McResults } from './components/McResults.svelte';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export { getNoticeCenter, errorNoticeTitle } from './notices.svelte.js';
|
|
2
|
+
export { default as ModelDetails } from './components/ModelDetails.svelte';
|
|
3
|
+
export { default as PanelFrame } from './components/PanelFrame.svelte';
|
|
4
|
+
export { getPanelLayout } from './panels.svelte.js';
|
|
1
5
|
export { default as TellegenProvider } from './TellegenProvider.svelte';
|
|
2
6
|
export { default as TellegenShell } from './TellegenShell.svelte';
|
|
3
7
|
export { default as TellegenViewer } from './TellegenViewer.svelte';
|
|
@@ -6,7 +10,8 @@ export { DEFAULT_TELLEGEN_UI_CONFIG, getAppState, getController, getUiConfig, re
|
|
|
6
10
|
export { ApiError, createApiClient } from './api.js';
|
|
7
11
|
export { Controller, createController } from './controller.svelte.js';
|
|
8
12
|
export { AppState, CaseState, LocalCase, MulticonductorCase, createAppState } from './state.svelte.js';
|
|
9
|
-
export { attachmentColor, attachmentGlyph, edgeColor, edgeWidth, phaseColor, placeMultiView, buildGeographicView } from './multiconductor.js';
|
|
10
|
-
export {
|
|
13
|
+
export { attachmentColor, attachmentGlyph, edgeColor, edgeWidth, phaseColor, neutralTerminal, placeMultiView, buildGeographicView } from './multiconductor.js';
|
|
14
|
+
export { distExtensionFormat } from './drop-classify.js';
|
|
11
15
|
export { caseDeltas, caseRatings, displayMetaFor, displaySeriesFor } from './display.js';
|
|
12
|
-
export { DEFAULT_FORMULATION, FORMULATIONS, BrowserStudy, Study, capabilities, createStudy, errorText, formatOf, ingestCase, isDisplayFile, isPermanentEngineFailure, parseDisplay,
|
|
16
|
+
export { DEFAULT_FORMULATION, FORMULATIONS, BrowserStudy, Study, capabilities, createStudy, errorText, formatOf, classifyJson, ingestJsonDrop, ingestCase, isDisplayFile, isPermanentEngineFailure, parseDisplay, solveModule } from '@tellegen/engine';
|
|
17
|
+
export { default as McResults } from './components/McResults.svelte';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type MapBounds = [[number, number], [number, number]];
|
|
2
|
+
/** Fold finite Web Mercator coordinates into map bounds. Invalid points are
|
|
3
|
+
* ignored so one malformed row cannot hide an otherwise usable network, and a
|
|
4
|
+
* single surviving point still yields a box `fitBounds` can frame. */
|
|
5
|
+
export declare function foldMapBounds(points: Iterable<readonly [number, number]>): MapBounds | null;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** Half-width given to an axis whose extent collapsed to a single value. A
|
|
2
|
+
* zero-span box makes `fitBounds` divide by zero, clamp to the map's maximum
|
|
3
|
+
* zoom, and slam the camera onto one point instead of framing it. */
|
|
4
|
+
const DEGENERATE_PAD_DEGREES = 0.005;
|
|
5
|
+
/** Fold finite Web Mercator coordinates into map bounds. Invalid points are
|
|
6
|
+
* ignored so one malformed row cannot hide an otherwise usable network, and a
|
|
7
|
+
* single surviving point still yields a box `fitBounds` can frame. */
|
|
8
|
+
export function foldMapBounds(points) {
|
|
9
|
+
let minLon = Infinity;
|
|
10
|
+
let minLat = Infinity;
|
|
11
|
+
let maxLon = -Infinity;
|
|
12
|
+
let maxLat = -Infinity;
|
|
13
|
+
for (const [lon, lat] of points) {
|
|
14
|
+
if (!Number.isFinite(lon) ||
|
|
15
|
+
!Number.isFinite(lat) ||
|
|
16
|
+
lon < -180 ||
|
|
17
|
+
lon > 180 ||
|
|
18
|
+
lat < -85.05 ||
|
|
19
|
+
lat > 85.05) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
minLon = Math.min(minLon, lon);
|
|
23
|
+
minLat = Math.min(minLat, lat);
|
|
24
|
+
maxLon = Math.max(maxLon, lon);
|
|
25
|
+
maxLat = Math.max(maxLat, lat);
|
|
26
|
+
}
|
|
27
|
+
if (!Number.isFinite(minLon) || !Number.isFinite(minLat))
|
|
28
|
+
return null;
|
|
29
|
+
if (minLon === maxLon) {
|
|
30
|
+
minLon -= DEGENERATE_PAD_DEGREES;
|
|
31
|
+
maxLon += DEGENERATE_PAD_DEGREES;
|
|
32
|
+
}
|
|
33
|
+
if (minLat === maxLat) {
|
|
34
|
+
minLat -= DEGENERATE_PAD_DEGREES;
|
|
35
|
+
maxLat += DEGENERATE_PAD_DEGREES;
|
|
36
|
+
}
|
|
37
|
+
return [
|
|
38
|
+
[minLon, minLat],
|
|
39
|
+
[maxLon, maxLat]
|
|
40
|
+
];
|
|
41
|
+
}
|
package/dist/map.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { ComponentProps } from 'svelte';
|
|
2
2
|
import TellegenMap from './TellegenMap.svelte';
|
|
3
3
|
export { default as TellegenMap } from './TellegenMap.svelte';
|
|
4
|
-
export { branchColor, branchWidth, busNeutral, busRadius,
|
|
4
|
+
export { branchColor, branchWidth, busNeutral, busRadius, priceColor, priceDomain, priceGradient, scalarDomain, sensColor, sensFlatColor, sensGradient, sensNeutral, sensitivityDomain } from './colors.js';
|
|
5
5
|
export { caseDeltas, displayMetaFor, displaySeriesFor } from './display.js';
|
|
6
6
|
export type { RGBA, SensitivityDomain } from './colors.js';
|
|
7
7
|
export type { DisplayOption } from './display.js';
|
|
8
8
|
export type TellegenMapProps = ComponentProps<typeof TellegenMap>;
|
|
9
|
-
//# sourceMappingURL=map.d.ts.map
|
package/dist/map.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import TellegenMap from './TellegenMap.svelte';
|
|
2
2
|
export { default as TellegenMap } from './TellegenMap.svelte';
|
|
3
|
-
export { branchColor, branchWidth, busNeutral, busRadius,
|
|
3
|
+
export { branchColor, branchWidth, busNeutral, busRadius, priceColor, priceDomain, priceGradient, scalarDomain, sensColor, sensFlatColor, sensGradient, sensNeutral, sensitivityDomain } from './colors.js';
|
|
4
4
|
export { caseDeltas, displayMetaFor, displaySeriesFor } from './display.js';
|
package/dist/multiconductor.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface PlacedMultiBus {
|
|
|
12
12
|
lat: number;
|
|
13
13
|
terminals: string[];
|
|
14
14
|
grounded: string[];
|
|
15
|
+
neutral_terminal?: string | null;
|
|
15
16
|
load_kw: number;
|
|
16
17
|
gen_kw: number;
|
|
17
18
|
has_source: boolean;
|
|
@@ -28,7 +29,7 @@ export interface PlacedMultiEdge {
|
|
|
28
29
|
conductors: [string, string][];
|
|
29
30
|
closed: boolean;
|
|
30
31
|
n_phases: number;
|
|
31
|
-
path: [
|
|
32
|
+
path: [number, number][];
|
|
32
33
|
}
|
|
33
34
|
/** The placed graph the map renders. */
|
|
34
35
|
export interface MultiView {
|
|
@@ -37,7 +38,11 @@ export interface MultiView {
|
|
|
37
38
|
}
|
|
38
39
|
/** Place a geographic graph: each bus's `xy` is `[longitude, latitude]` and
|
|
39
40
|
* drops straight onto the map. */
|
|
40
|
-
export declare function buildGeographicView(graph: DistGraph): MultiView;
|
|
41
|
+
export declare function buildGeographicView(graph: DistGraph, layer?: string): MultiView;
|
|
42
|
+
/** Retain native drawing positions; unpositioned buses receive a separate generated layout. */
|
|
43
|
+
export declare function buildDiagramView(graph: DistGraph, layer?: string): MultiView;
|
|
44
|
+
/** Numeric indices address drawing objects only; source identities remain on each object. */
|
|
45
|
+
export declare function multiDiagramNetwork(id: string, name: string, view: MultiView): import('./api.js').Network;
|
|
41
46
|
/** Place a non-geographic graph at a map `center`: fit the provided planar
|
|
42
47
|
* coordinates when the case carries them, otherwise fall back to the shared
|
|
43
48
|
* synthetic force layout. */
|
|
@@ -48,6 +53,10 @@ export declare function placeMultiView(graph: DistGraph, center: PlacementCenter
|
|
|
48
53
|
export declare function phaseColor(terminal: string): RGBA;
|
|
49
54
|
/** True when a terminal is a phase conductor (not a neutral/ground return). */
|
|
50
55
|
export declare function isPhaseTerminal(terminal: string): boolean;
|
|
56
|
+
/** Return the explicit neutral conductor in a terminal map. Other non-phase
|
|
57
|
+
* labels are left alone: an arbitrary terminal name is not evidence that the
|
|
58
|
+
* network has a usable neutral reference. */
|
|
59
|
+
export declare function neutralTerminal(terminals: string[], declared?: string | null): string | null;
|
|
51
60
|
/** Base color for an edge by kind and state. Lines are the warm gray of the
|
|
52
61
|
* single-phase branches; transformers are steel; a switch is amber when closed
|
|
53
62
|
* and a faded red when open. */
|
|
@@ -73,4 +82,3 @@ export declare function transformerMarks(edges: PlacedMultiEdge[]): TransformerM
|
|
|
73
82
|
export declare function attachmentColor(kind: DistAttachmentKind): RGBA;
|
|
74
83
|
/** A short glyph for an attachment kind, for the panel legend and badges. */
|
|
75
84
|
export declare function attachmentGlyph(kind: DistAttachmentKind): string;
|
|
76
|
-
//# sourceMappingURL=multiconductor.d.ts.map
|