@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.
Files changed (140) hide show
  1. package/README.md +46 -0
  2. package/dist/Sparkline.svelte.d.ts +0 -1
  3. package/dist/TellegenMap.svelte +328 -200
  4. package/dist/TellegenMap.svelte.d.ts +0 -1
  5. package/dist/TellegenProvider.svelte +4 -0
  6. package/dist/TellegenProvider.svelte.d.ts +0 -1
  7. package/dist/TellegenShell.svelte +19 -13
  8. package/dist/TellegenShell.svelte.d.ts +0 -1
  9. package/dist/TellegenViewer.svelte.d.ts +0 -1
  10. package/dist/api.d.ts +8 -2
  11. package/dist/api.js +6 -2
  12. package/dist/colors.d.ts +7 -8
  13. package/dist/colors.js +13 -13
  14. package/dist/components/AppFooter.svelte.d.ts +0 -1
  15. package/dist/components/AppHeader.svelte +27 -13
  16. package/dist/components/AppHeader.svelte.d.ts +0 -1
  17. package/dist/components/BindingLines.svelte +3 -6
  18. package/dist/components/BindingLines.svelte.d.ts +0 -1
  19. package/dist/components/BusPicker.svelte +8 -2
  20. package/dist/components/BusPicker.svelte.d.ts +0 -1
  21. package/dist/components/ControlPanel.svelte +106 -343
  22. package/dist/components/ControlPanel.svelte.d.ts +0 -1
  23. package/dist/components/DemandSlider.svelte +26 -8
  24. package/dist/components/DemandSlider.svelte.d.ts +0 -1
  25. package/dist/components/DiagramCanvas.svelte +486 -0
  26. package/dist/components/DiagramCanvas.svelte.d.ts +13 -0
  27. package/dist/components/DisplayControls.svelte +4 -2
  28. package/dist/components/DisplayControls.svelte.d.ts +0 -1
  29. package/dist/components/DropZone.svelte.d.ts +0 -1
  30. package/dist/components/FormulationSelector.svelte +8 -3
  31. package/dist/components/FormulationSelector.svelte.d.ts +0 -1
  32. package/dist/components/LocalCaseDetails.svelte +57 -44
  33. package/dist/components/LocalCaseDetails.svelte.d.ts +0 -1
  34. package/dist/components/McResults.svelte +365 -0
  35. package/dist/components/McResults.svelte.d.ts +11 -0
  36. package/dist/components/ModelDetails.svelte +230 -0
  37. package/dist/components/ModelDetails.svelte.d.ts +7 -0
  38. package/dist/components/MulticonductorDetails.svelte +227 -78
  39. package/dist/components/MulticonductorDetails.svelte.d.ts +0 -1
  40. package/dist/components/NetworkStats.svelte +20 -18
  41. package/dist/components/NetworkStats.svelte.d.ts +0 -1
  42. package/dist/components/NotificationCenter.svelte +243 -0
  43. package/dist/components/NotificationCenter.svelte.d.ts +3 -0
  44. package/dist/components/PanelCard.svelte +319 -0
  45. package/dist/components/PanelCard.svelte.d.ts +9 -0
  46. package/dist/components/PanelFrame.svelte +46 -0
  47. package/dist/components/PanelFrame.svelte.d.ts +16 -0
  48. package/dist/components/PanelHost.svelte +212 -0
  49. package/dist/components/PanelHost.svelte.d.ts +3 -0
  50. package/dist/components/PlacementCue.svelte.d.ts +0 -1
  51. package/dist/components/PowerFlowDetails.svelte +99 -0
  52. package/dist/components/PowerFlowDetails.svelte.d.ts +3 -0
  53. package/dist/components/RatingSlider.svelte +5 -9
  54. package/dist/components/RatingSlider.svelte.d.ts +0 -1
  55. package/dist/components/RestoreDefaultsButton.svelte.d.ts +0 -1
  56. package/dist/components/SavedNetworkDetails.svelte +214 -0
  57. package/dist/components/SavedNetworkDetails.svelte.d.ts +3 -0
  58. package/dist/components/SensitivityReadout.svelte +24 -16
  59. package/dist/components/SensitivityReadout.svelte.d.ts +0 -1
  60. package/dist/components/SizeLegend.svelte.d.ts +0 -1
  61. package/dist/components/SolveCard.svelte +46 -49
  62. package/dist/components/SolveCard.svelte.d.ts +0 -1
  63. package/dist/components/TopMovers.svelte +8 -3
  64. package/dist/components/TopMovers.svelte.d.ts +2 -18
  65. package/dist/components.d.ts +2 -1
  66. package/dist/components.js +2 -0
  67. package/dist/context.svelte.d.ts +0 -1
  68. package/dist/controller.svelte.d.ts +74 -41
  69. package/dist/controller.svelte.js +1095 -284
  70. package/dist/diagram-labels.d.ts +9 -0
  71. package/dist/diagram-labels.js +40 -0
  72. package/dist/display.d.ts +3 -8
  73. package/dist/display.js +31 -27
  74. package/dist/drop-classify.d.ts +5 -42
  75. package/dist/drop-classify.js +5 -78
  76. package/dist/drop-limits.d.ts +27 -0
  77. package/dist/drop-limits.js +83 -0
  78. package/dist/format.d.ts +0 -1
  79. package/dist/format.js +5 -4
  80. package/dist/index.d.ts +11 -7
  81. package/dist/index.js +8 -3
  82. package/dist/map-bounds.d.ts +5 -0
  83. package/dist/map-bounds.js +41 -0
  84. package/dist/map.d.ts +1 -2
  85. package/dist/map.js +1 -1
  86. package/dist/multiconductor.d.ts +11 -3
  87. package/dist/multiconductor.js +107 -14
  88. package/dist/notices.svelte.d.ts +29 -0
  89. package/dist/notices.svelte.js +82 -0
  90. package/dist/panels.svelte.d.ts +65 -0
  91. package/dist/panels.svelte.js +215 -0
  92. package/dist/state.svelte.d.ts +90 -24
  93. package/dist/state.svelte.js +94 -20
  94. package/dist/synthetic-layout.d.ts +0 -1
  95. package/dist/synthetic-layout.js +17 -2
  96. package/dist/transformer-icon.d.ts +0 -1
  97. package/dist/types.d.ts +0 -1
  98. package/package.json +28 -12
  99. package/dist/Sparkline.svelte.d.ts.map +0 -1
  100. package/dist/TellegenMap.svelte.d.ts.map +0 -1
  101. package/dist/TellegenProvider.svelte.d.ts.map +0 -1
  102. package/dist/TellegenShell.svelte.d.ts.map +0 -1
  103. package/dist/TellegenViewer.svelte.d.ts.map +0 -1
  104. package/dist/api.d.ts.map +0 -1
  105. package/dist/colors.d.ts.map +0 -1
  106. package/dist/components/AppFooter.svelte.d.ts.map +0 -1
  107. package/dist/components/AppHeader.svelte.d.ts.map +0 -1
  108. package/dist/components/BindingLines.svelte.d.ts.map +0 -1
  109. package/dist/components/BusPicker.svelte.d.ts.map +0 -1
  110. package/dist/components/ControlPanel.svelte.d.ts.map +0 -1
  111. package/dist/components/DemandSlider.svelte.d.ts.map +0 -1
  112. package/dist/components/DisplayControls.svelte.d.ts.map +0 -1
  113. package/dist/components/DropZone.svelte.d.ts.map +0 -1
  114. package/dist/components/FormulationSelector.svelte.d.ts.map +0 -1
  115. package/dist/components/LocalCaseDetails.svelte.d.ts.map +0 -1
  116. package/dist/components/MulticonductorDetails.svelte.d.ts.map +0 -1
  117. package/dist/components/NetworkStats.svelte.d.ts.map +0 -1
  118. package/dist/components/PlacementCue.svelte.d.ts.map +0 -1
  119. package/dist/components/RatingSlider.svelte.d.ts.map +0 -1
  120. package/dist/components/RestoreDefaultsButton.svelte.d.ts.map +0 -1
  121. package/dist/components/SensitivityReadout.svelte.d.ts.map +0 -1
  122. package/dist/components/SizeLegend.svelte.d.ts.map +0 -1
  123. package/dist/components/SolveCard.svelte.d.ts.map +0 -1
  124. package/dist/components/TopMovers.svelte.d.ts.map +0 -1
  125. package/dist/components.d.ts.map +0 -1
  126. package/dist/context.svelte.d.ts.map +0 -1
  127. package/dist/controller.svelte.d.ts.map +0 -1
  128. package/dist/display.d.ts.map +0 -1
  129. package/dist/drop-classify.d.ts.map +0 -1
  130. package/dist/format.d.ts.map +0 -1
  131. package/dist/index.d.ts.map +0 -1
  132. package/dist/map.d.ts.map +0 -1
  133. package/dist/multiconductor.d.ts.map +0 -1
  134. package/dist/state.svelte.d.ts.map +0 -1
  135. package/dist/study-package.d.ts +0 -9
  136. package/dist/study-package.d.ts.map +0 -1
  137. package/dist/study-package.js +0 -17
  138. package/dist/synthetic-layout.d.ts.map +0 -1
  139. package/dist/transformer-icon.d.ts.map +0 -1
  140. package/dist/types.d.ts.map +0 -1
@@ -16,4 +16,3 @@ declare const SizeLegend: $$__sveltets_2_IsomorphicComponent<Record<string, neve
16
16
  }, {}, {}, string>;
17
17
  type SizeLegend = InstanceType<typeof SizeLegend>;
18
18
  export default SizeLegend;
19
- //# sourceMappingURL=SizeLegend.svelte.d.ts.map
@@ -1,56 +1,63 @@
1
1
  <script lang="ts">
2
- import { getController } from '../context.svelte.js';
2
+ import { getAppState, getController } from '../context.svelte.js';
3
3
  import { formulationLabel, solveMetaLabel } from '../format.js';
4
4
  import Sparkline from '../Sparkline.svelte';
5
+ import PanelFrame from './PanelFrame.svelte';
6
+ let open = $state(true);
5
7
 
6
8
  const ctrl = getController();
9
+ const app = getAppState();
10
+ const saved = $derived(app.studyView);
7
11
  const active = $derived(ctrl.activeSolvable);
8
- const iterations = $derived(active?.iterations ?? []);
12
+ const iterations = $derived(
13
+ saved
14
+ ? Array.isArray(saved.solution?.iterations)
15
+ ? saved.solution.iterations
16
+ : []
17
+ : (active?.iterations ?? [])
18
+ );
9
19
  </script>
10
20
 
11
- {#if active && (active.solving || active.solveMs != null)}
12
- <div class="solvecard">
13
- <div class="solvecard-head mono">
14
- <span><b>OPF solve</b></span>
21
+ {#if saved || (active && (active.solving || active.solveMs != null))}
22
+ <PanelFrame id="solver" title="Solver" side="right" order={10} width={320} bind:open>
23
+ <div class="solvecard">
24
+ <div class="solve-label mono">
25
+ {saved ? 'Saved result' : active?.formulation === 'acpf' ? 'Power flow' : 'OPF solve'}
26
+ </div>
27
+ {#if iterations.length > 1}
28
+ {#key iterations}
29
+ <Sparkline {iterations} />
30
+ {/key}
31
+ {/if}
32
+ {#if saved}
33
+ <div class="solve-meta mono dim">
34
+ <span class="solve-formulation">{formulationLabel(saved.formulation)}</span>
35
+ <span>{saved.solution?.status ?? 'Not solved'}</span>
36
+ <span>Saved state: {saved.label}</span>
37
+ </div>
38
+ {:else if active}
39
+ <div class="solve-meta mono dim">
40
+ <span class="solve-formulation">{formulationLabel(active.formulation)}</span>
41
+ <span>{solveMetaLabel(active)}</span>
42
+ {#if active.solveMs != null}<span>{active.solveMs} ms</span>{/if}
43
+ </div>
44
+ {#if active.solveBackend === 'rust-server' && active.solveFallbackReason}
45
+ <p class="fallback-reason mono dim" title={active.solveFallbackReason}>
46
+ fallback: {active.solveFallbackReason}
47
+ </p>
48
+ {/if}
49
+ {/if}
15
50
  </div>
16
- {#if iterations.length > 1}
17
- {#key iterations}
18
- <Sparkline {iterations} />
19
- {/key}
20
- {/if}
21
- <div class="solve-meta mono dim">
22
- <span class="solve-formulation">{formulationLabel(active.formulation)}</span>
23
- <span>{solveMetaLabel(active)}</span>
24
- {#if active.solveMs != null}<span>{active.solveMs} ms</span>{/if}
25
- </div>
26
- {#if active.solveBackend === 'rust-server' && active.solveFallbackReason}
27
- <p class="fallback-reason mono dim" title={active.solveFallbackReason}>
28
- fallback: {active.solveFallbackReason}
29
- </p>
30
- {/if}
31
- </div>
51
+ </PanelFrame>
32
52
  {/if}
33
53
 
34
54
  <style>
55
+ .solve-label {
56
+ font-size: 11px;
57
+ margin-bottom: 8px;
58
+ }
35
59
  .solvecard {
36
- position: absolute;
37
- top: 76px;
38
- right: 20px;
39
- z-index: 10;
40
- width: 300px;
41
60
  padding: 13px 15px 11px;
42
- background: var(--panel);
43
- border: 1px solid var(--line);
44
- border-radius: 3px;
45
- backdrop-filter: blur(6px);
46
- box-shadow: 0 4px 24px rgba(32, 36, 43, 0.08);
47
- animation: rise 0.3s ease-out both;
48
- }
49
-
50
- .solvecard-head {
51
- font-size: 10.5px;
52
- margin-bottom: 6px;
53
- white-space: nowrap;
54
61
  }
55
62
 
56
63
  .solve-meta {
@@ -72,14 +79,4 @@
72
79
  line-height: 1.35;
73
80
  overflow-wrap: anywhere;
74
81
  }
75
-
76
- @media (max-width: 760px) {
77
- .solvecard {
78
- /* just clear of the header's case tabs */
79
- top: 108px;
80
- left: auto;
81
- right: 10px;
82
- width: min(300px, calc(100% - 20px));
83
- }
84
- }
85
82
  </style>
@@ -1,4 +1,3 @@
1
1
  declare const SolveCard: import("svelte").Component<Record<string, never>, {}, "">;
2
2
  type SolveCard = ReturnType<typeof SolveCard>;
3
3
  export default SolveCard;
4
- //# sourceMappingURL=SolveCard.svelte.d.ts.map
@@ -3,15 +3,20 @@
3
3
  import { signedExp } from '../format.js';
4
4
 
5
5
  const ctrl = getController();
6
- const unitTitle =
7
- 'LMP is measured in $/MWh and demand is perturbed in MW, so dLMP/dd has units ($/MWh)/MW.';
6
+ const units = $derived(
7
+ (ctrl.selectedSensitivity?.units ?? '(objective units/MW)/MW').replaceAll(
8
+ 'objective_unit',
9
+ 'objective units'
10
+ )
11
+ );
12
+ const unitTitle = $derived(`LMP response per MW of demand, in ${units}.`);
8
13
  </script>
9
14
 
10
15
  <div class="movers-block">
11
16
  {#if !ctrl.previewing && ctrl.topMovers.length > 0}
12
17
  <table class="mono">
13
18
  <caption class="mono dim" title={unitTitle}>
14
- largest &Delta;LMP per MW demand <span class="unit">($/MWh)/MW</span>
19
+ largest LMP response <span class="unit">{units}</span>
15
20
  </caption>
16
21
  <tbody>
17
22
  {#each ctrl.topMovers as mover (mover.bus)}
@@ -1,19 +1,3 @@
1
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
- new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
- $$bindings?: Bindings;
4
- } & Exports;
5
- (internal: unknown, props: {
6
- $$events?: Events;
7
- $$slots?: Slots;
8
- }): Exports & {
9
- $set?: any;
10
- $on?: any;
11
- };
12
- z_$$bindings?: Bindings;
13
- }
14
- declare const TopMovers: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
- [evt: string]: CustomEvent<any>;
16
- }, {}, {}, string>;
17
- type TopMovers = InstanceType<typeof TopMovers>;
1
+ declare const TopMovers: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type TopMovers = ReturnType<typeof TopMovers>;
18
3
  export default TopMovers;
19
- //# sourceMappingURL=TopMovers.svelte.d.ts.map
@@ -1,3 +1,4 @@
1
+ export { default as ModelDetails } from './components/ModelDetails.svelte';
1
2
  export { default as AppFooter } from './components/AppFooter.svelte';
2
3
  export { default as AppHeader } from './components/AppHeader.svelte';
3
4
  export { default as BusPicker } from './components/BusPicker.svelte';
@@ -16,4 +17,4 @@ export { default as SizeLegend } from './components/SizeLegend.svelte';
16
17
  export { default as SolveCard } from './components/SolveCard.svelte';
17
18
  export { default as TopMovers } from './components/TopMovers.svelte';
18
19
  export { default as Sparkline } from './Sparkline.svelte';
19
- //# sourceMappingURL=components.d.ts.map
20
+ export { default as McResults } from './components/McResults.svelte';
@@ -1,3 +1,4 @@
1
+ export { default as ModelDetails } from './components/ModelDetails.svelte';
1
2
  export { default as AppFooter } from './components/AppFooter.svelte';
2
3
  export { default as AppHeader } from './components/AppHeader.svelte';
3
4
  export { default as BusPicker } from './components/BusPicker.svelte';
@@ -16,3 +17,4 @@ export { default as SizeLegend } from './components/SizeLegend.svelte';
16
17
  export { default as SolveCard } from './components/SolveCard.svelte';
17
18
  export { default as TopMovers } from './components/TopMovers.svelte';
18
19
  export { default as Sparkline } from './Sparkline.svelte';
20
+ export { default as McResults } from './components/McResults.svelte';
@@ -17,4 +17,3 @@ export declare const setUiConfig: (config: TellegenUiConfig) => TellegenUiConfig
17
17
  export declare const getAppState: () => AppState;
18
18
  export declare const getController: () => Controller;
19
19
  export declare const getUiConfig: () => TellegenUiConfig;
20
- //# sourceMappingURL=context.svelte.d.ts.map
@@ -1,15 +1,25 @@
1
1
  import { type TellegenApiClient } from './api.js';
2
2
  import type { BranchRatingDeltas, Network, NetworkBus, SensitivityColumn, Solution } from './api.js';
3
3
  import { CaseState, LocalCase, MulticonductorCase, type AppState, type DemandRangeMode, type SolvableCase } from './state.svelte.js';
4
- import { type BrowserStudy, type Formulation, type SensTarget } from '@tellegen/engine';
4
+ import { type EngineTransport, type McPfOptions, type McPfResult, type McStudySnapshot, type BrowserStudy, type Formulation, type PowerIoDiagnostic, type SensTarget } from '@tellegen/engine';
5
5
  /** A parsed geographic sidecar awaiting application: the canonical `.geo.json`
6
6
  * layer document from the engine's tolerant reader, its source file name, and
7
7
  * the reader's notes on records it could not use. */
8
8
  type GeoLayerFile = {
9
9
  name: string;
10
10
  layer: string;
11
- warnings: string[];
11
+ diagnostics: PowerIoDiagnostic[];
12
12
  };
13
+ type SavedCaseCapture = {
14
+ input: string;
15
+ solution?: string;
16
+ view?: import('@tellegen/engine').StudyView;
17
+ };
18
+ /** A lowered analysis row is view-only only when a current producer says so;
19
+ * absence keeps payloads from older compatible engine/server versions editable. */
20
+ export declare function isDisplayOnlyElement(element: {
21
+ editable?: boolean;
22
+ } | null | undefined): boolean;
13
23
  export type { SolvableCase };
14
24
  type DemandRangeAnchor = {
15
25
  caseId: string;
@@ -19,28 +29,32 @@ type DemandRangeAnchor = {
19
29
  export interface ControllerOptions {
20
30
  api?: TellegenApiClient;
21
31
  apiBase?: string;
32
+ mcTransport?: Pick<EngineTransport, 'solveMcModule' | 'applyMcGeo'> & Partial<Pick<EngineTransport, 'solveMcStudy' | 'applyMcStudyGeo' | 'createMcPfSession'>>;
22
33
  }
23
34
  export declare class Controller {
24
35
  app: AppState;
25
36
  api: TellegenApiClient;
37
+ mcTransport: Pick<EngineTransport, 'solveMcModule' | 'applyMcGeo'> & Partial<Pick<EngineTransport, 'solveMcStudy' | 'applyMcStudyGeo' | 'createMcPfSession'>>;
26
38
  abort: AbortController | null;
27
39
  sensitivity429Until: number;
28
40
  serverComputeOff: boolean;
29
41
  caseStudies: WeakMap<SolvableCase, {
30
42
  study: BrowserStudy;
31
- networkJson: string;
43
+ studyInputJson: string;
32
44
  formulation: Formulation;
33
45
  baseSolution: Solution;
34
46
  }>;
47
+ private detachedCaseCaptures;
35
48
  studyUnavailable: WeakMap<SolvableCase, string>;
36
49
  studyBuilds: WeakMap<SolvableCase, {
37
- networkJson: string;
50
+ studyInputJson: string;
38
51
  formulation: Formulation;
39
52
  token: object;
40
53
  promise: Promise<BrowserStudy | null>;
41
54
  }>;
42
55
  localSeq: number;
43
56
  loading: Promise<void> | null;
57
+ private readonly dropBatchGate;
44
58
  nearbyRangeAnchor: DemandRangeAnchor | null;
45
59
  hiddenDefaults: Set<string>;
46
60
  casesLoaded: boolean;
@@ -68,6 +82,7 @@ export declare class Controller {
68
82
  /** True when two selection targets name the same bus or branch. */
69
83
  sameTarget(a: SensTarget, b: SensTarget): boolean;
70
84
  isPerturbed(c: SolvableCase | null): boolean;
85
+ bumpRevision(c: SolvableCase): void;
71
86
  setNearbyRangeAnchor(c: SolvableCase, bus: number, delta?: number): void;
72
87
  beginBusSelection(c: SolvableCase, busId: number): {
73
88
  ac: AbortController;
@@ -84,12 +99,12 @@ export declare class Controller {
84
99
  rememberHiddenDefaultCase(id: string): void;
85
100
  localNetwork(c: LocalCase): Network | null;
86
101
  maybeStartLocalSolve(id: string): void;
87
- getStudy(c: SolvableCase, networkJson: string): Promise<BrowserStudy | null>;
88
- browserSensitivity(c: SolvableCase, networkJson: string, target: SensTarget): Promise<SensitivityColumn | null>;
102
+ getStudy(c: SolvableCase, studyInputJson: string): Promise<BrowserStudy | null>;
103
+ browserSensitivity(c: SolvableCase, studyInputJson: string, target: SensTarget): Promise<SensitivityColumn | null>;
89
104
  disposeStudy(c: SolvableCase): void;
90
105
  acceptSensitivity(c: SolvableCase, col: SensitivityColumn | null, target: SensTarget | null, sensitivitySeq?: number): void;
91
106
  finishSolve(c: SolvableCase, seq: number, target: SensTarget | null): void;
92
- ensureNetworkJson(c: SolvableCase): Promise<string | null>;
107
+ ensureStudyInputJson(c: SolvableCase): Promise<string | null>;
93
108
  previewDeltas(c: SolvableCase, bus: number, value: number): {
94
109
  [x: string]: number;
95
110
  [x: number]: number;
@@ -144,6 +159,7 @@ export declare class Controller {
144
159
  };
145
160
  sliderMin: number;
146
161
  sliderMax: number;
162
+ sliderDisabled: boolean;
147
163
  committedRating: number;
148
164
  ratingSliderValue: number;
149
165
  ratingBounds: {
@@ -184,7 +200,7 @@ export declare class Controller {
184
200
  placeLocalCase: (lon: number, lat: number) => Promise<void>;
185
201
  /** Write the case's on-screen layout into its network payload
186
202
  * (`Bus.location` with `synthetic` provenance — the engine also accepts
187
- * `manual`, which round trips through restored packages), so saves,
203
+ * `manual`, which round trips through saved PowerIO modules), so saves,
188
204
  * exports, and the `.geo.json` download carry it. Best effort: on an
189
205
  * engine failure the view still renders, only the layout's persistence is
190
206
  * lost. */
@@ -198,7 +214,7 @@ export declare class Controller {
198
214
  * wins on shared elements). The engine owns matching and the network becomes
199
215
  * the single owner of the coordinates: matched points land in
200
216
  * `Bus.location`, routes in `Branch.route`, and the refreshed
201
- * `network_json` replaces the case payload — so a saved package or export
217
+ * `module_json` replaces the case IR — so a saved module or export
202
218
  * carries exactly what is on screen. A live Study is synced the same way.
203
219
  * Throws when a layer matches nothing. */
204
220
  applyGeoLayers: (c: LocalCase, layers: GeoLayerFile[]) => Promise<void>;
@@ -206,10 +222,12 @@ export declare class Controller {
206
222
  * the case's network and view, provenance flips to the geographic source,
207
223
  * and the warnings panel gets the placement summary. */
208
224
  private adoptGeoPayload;
209
- /** Keep a live Study's base network in step with a geo change (locations
210
- * are metadata the model never reads, so nothing re-solves), and re-key its
211
- * cache entry so the next solve reuses it instead of rebuilding. */
212
- private syncCachedStudy;
225
+ /** Update an existing numerical Study after the base input receives geographic data. */
226
+ private syncStudyGeo;
227
+ private caseEditKey;
228
+ private localSidecarCopy;
229
+ private stageLocalSidecars;
230
+ private attachSidecarsToSelected;
213
231
  applyGeoLayersToExisting: (layers: GeoLayerFile[]) => Promise<void>;
214
232
  /** Ask the map to frame the selected branch and wait for the camera to land,
215
233
  * capped by FOCUS_SETTLE_CAP_MS and cut short by the selection's abort. */
@@ -225,7 +243,7 @@ export declare class Controller {
225
243
  * transient (a wasm chunk or case JSON fetch), so say what is known and keep
226
244
  * the retry meaningful. */
227
245
  private computeOffNotice;
228
- /** The one server ∂LMP/∂parameter request a selection may make: the
246
+ /** The one server nodal-value/parameter request a selection may make: the
229
247
  * reconciliation path when the browser Study produced no column for a DC OPF
230
248
  * case. Never retries on its own: a second request inside the same rate limit
231
249
  * window is a guaranteed rejection, and the retry button covers the user
@@ -260,32 +278,42 @@ export declare class Controller {
260
278
  commitDelta: (value: number) => void;
261
279
  finishDemandInput: (value: number) => void;
262
280
  resetCase: (c: SolvableCase) => void;
281
+ /** Rebuild the numerical Study for a selected calculation at the current demand. */
263
282
  changeFormulation: (c: SolvableCase, next: Formulation) => void;
264
283
  /** Parse dropped files in the browser via the powerio wasm module. Case
265
- * files (.m, .raw, .aux) become local networks; geographic files can
284
+ * files (.m, .raw, .aux, .epc, .pwb) become local networks; geographic files can
266
285
  * place those networks; a PowerWorld .pwd becomes a substation point
267
286
  * preview. Files run serially; nothing uploads. */
268
287
  ingestFiles: (files: FileList | File[]) => Promise<void>;
269
- /** Fill a coordinate-less case's positions from a co-dropped PowerWorld
270
- * `.pwd`: the display's substation points project to approximate
271
- * longitude/latitude and join onto buses through the `SubNum` extras key.
272
- * The first display that joins wins; one that matches nothing stays
273
- * available as its own preview entry, and the case stays placeable. */
288
+ private ingestFileBatch;
289
+ /** Apply co-dropped geographic data before a local case becomes active and
290
+ * starts solving. Without geographic data, let a coordinate-less case borrow
291
+ * the first matching PowerWorld display. A failed geographic join keeps the
292
+ * parsed case and returns the user-facing placement error. */
293
+ private prepareDroppedLocal;
294
+ /** Retain diagram geometry separately from the electrical case's geographic data. */
274
295
  private fillFromDisplaySibling;
275
- /** Route a dropped `.json` by its content: a saved study package restores
276
- * (`restored`), a multiconductor package or a BMOPF/PMD distribution
277
- * document views (`viewed`), `failed` means the content looked routable but
278
- * the engine rejected it (a fail-closed message is set), and `not-package`
279
- * falls through to the caller's geo/case handling. `drop-classify` is the
280
- * single owner of the classification. */
281
- private ingestJsonDrop;
296
+ setCaseDisplayMode: (c: LocalCase, mode: "geographic" | "diagram") => void;
297
+ /** Route a dropped `.json` by its content. Recognized payloads return without
298
+ * mutating case state so co-dropped sidecars can be applied first; unrouted
299
+ * content returns the bytes already read for the geographic fallback. */
300
+ private routeJsonDrop;
282
301
  /** Parse a dropped OpenDSS `.dss` file into a multiconductor viewing case.
283
302
  * Returns true when a case landed; a parse failure sets the panel error. */
284
303
  private ingestDistFile;
285
- /** Build a `MulticonductorCase` from an ingest payload and make it active.
286
- * Geographic cases place immediately; planar/synthetic cases enter placement
287
- * (a map click or "place on map") so the user picks their center. */
304
+ /** Retain parsed electrical inputs and draw each declared coordinate space directly. */
288
305
  private addMultiCase;
306
+ /** Compute terminal quantities only for the retained input and current case revision. */
307
+ solveMultiCase: (c: MulticonductorCase, options?: McPfOptions, signal?: AbortSignal) => Promise<McPfResult>;
308
+ /** Materialize the current retained operating point only when a portable
309
+ * snapshot is actually needed (save/export/geography). */
310
+ snapshotMultiCase: (c: MulticonductorCase) => Promise<McStudySnapshot>;
311
+ /** Apply coordinates atomically to the explicitly selected conductor-resolved case. */
312
+ applyMultiGeoLayers: (c: MulticonductorCase, layers: GeoLayerFile[]) => Promise<void>;
313
+ /** Stage an absolute load-branch P/Q edit and coalesce rapid UI changes into
314
+ * one retained-factor warm solve. */
315
+ queueMultiLoadPower: (c: MulticonductorCase, load: string, branch: number, p_w: number, q_var: number) => void;
316
+ private flushMultiLoadPowers;
289
317
  /** Make a multiconductor case active, framing it when it is placed. */
290
318
  activateMulti: (c: MulticonductorCase) => void;
291
319
  /** Select a bus in a multiconductor case: its terminal stack and incident
@@ -303,18 +331,24 @@ export declare class Controller {
303
331
  /** The unified map click-to-place: a pending multiconductor case takes the
304
332
  * click first, otherwise a pending local case does. */
305
333
  placeCase: (lon: number, lat: number) => void;
306
- /** Build a local case from a restored study package: the same shape a dropped case
307
- * takes, with the saved demand/rating deltas and formulation pre-applied. */
308
- private restoreLocalFromPackage;
334
+ projectStudyInput(input: string, layer?: string): Promise<Network>;
335
+ caseGeographyLayers(c: LocalCase): Promise<string[]>;
336
+ /** Capture a matching cached result without constructing or solving a model. */
337
+ captureSavedCase(c: SolvableCase): Promise<SavedCaseCapture>;
338
+ /** Build a local case from a balanced PowerIO ingest payload without activating
339
+ * it yet; co-dropped placement data is applied before the first solve. */
340
+ private localFromBalancedPayload;
309
341
  /** Build (or reuse) the case's Study and commit it at the current edit state, so a
310
342
  * save or export captures exactly what is on screen. Null (with an error set) when no
311
- * network or Study is available. */
312
- private syncedStudy;
313
- /** Save the active study as a `.pio.json` package and download it. */
314
- saveStudyPackage: (c: SolvableCase) => Promise<void>;
315
- /** Export the active study's committed state to `format` and download it. Returns the
316
- * writer's fidelity warnings so the caller can surface them. */
317
- exportStudyAs: (c: SolvableCase, format: string) => Promise<string[]>;
343
+ * PowerIO module or Study is available. */
344
+ syncedStudy: (c: SolvableCase) => Promise<BrowserStudy | null>;
345
+ /** Save the materialized case as a retained PowerIO module. */
346
+ saveCaseModule: (c: SolvableCase) => Promise<void>;
347
+ /** Save the exact DC OPF result with the materialized problem instance it solved. */
348
+ saveSolutionModule: (c: SolvableCase) => Promise<void>;
349
+ /** Export the active study's committed state to `format` and download it.
350
+ * Returns this output operation's structured diagnostics. */
351
+ exportCaseAs: (c: SolvableCase, format: string) => Promise<PowerIoDiagnostic[]>;
318
352
  /** A filesystem-safe base name for a downloaded case file. */
319
353
  private caseFileStem;
320
354
  setDemandRangeMode: (mode: DemandRangeMode) => void;
@@ -334,4 +368,3 @@ export declare class Controller {
334
368
  ratingSliderCurrent: () => number;
335
369
  }
336
370
  export declare function createController(app: AppState, options?: ControllerOptions): Controller;
337
- //# sourceMappingURL=controller.svelte.d.ts.map