@micheeeeel/yinyangapp 3.0.1 → 3.1.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 (110) hide show
  1. package/dist/bundle.css +1 -0
  2. package/dist/bundle.js +1 -2
  3. package/dist/types/adapters/yasuniCauseAdapter.d.ts +1 -1
  4. package/dist/types/adapters/yinYangAdapter.d.ts +7 -0
  5. package/dist/types/animations/AnimationsMngr.d.ts +69 -15
  6. package/dist/types/animations/FrameScheduler.d.ts +99 -0
  7. package/dist/types/animations/rotationMotion.d.ts +43 -0
  8. package/dist/types/api.d.ts +17 -2
  9. package/dist/types/benchmark/runner.d.ts +20 -0
  10. package/dist/types/benchmark/scenarios.d.ts +55 -6
  11. package/dist/types/components/controller/YinYangController.d.ts +104 -14
  12. package/dist/types/components/controller/action-stack/ActionStackController.d.ts +16 -1
  13. package/dist/types/components/controller/action-stack/ActionStackDragHandler.d.ts +4 -0
  14. package/dist/types/components/controller/action-stack/ActionStackManager.d.ts +13 -2
  15. package/dist/types/components/controller/action-stack/ActionStackState.d.ts +8 -5
  16. package/dist/types/components/controller/action-stack/StackFocusController.d.ts +8 -7
  17. package/dist/types/components/controller/action-stack/stackChromePalette.d.ts +20 -0
  18. package/dist/types/components/controller/actions/ActionProjectionService.d.ts +12 -1
  19. package/dist/types/components/controller/actions/ChildActionMenuController.d.ts +74 -32
  20. package/dist/types/components/controller/actions/KeyEventController.d.ts +78 -70
  21. package/dist/types/components/controller/actions/{CoreEventMenuController.d.ts → KeyEventMenuController.d.ts} +28 -33
  22. package/dist/types/components/controller/actions/radialItemMenu.d.ts +43 -5
  23. package/dist/types/components/controller/children/ChildInteractionController.d.ts +4 -0
  24. package/dist/types/components/controller/children/ChildrenBuilder.d.ts +3 -1
  25. package/dist/types/components/controller/children/ComponentSwitchCoordinator.d.ts +3 -1
  26. package/dist/types/components/controller/children/IdleFacettesController.d.ts +151 -0
  27. package/dist/types/components/controller/children/idleTabLayout.d.ts +95 -0
  28. package/dist/types/components/controller/children/idleTabMorph.d.ts +45 -0
  29. package/dist/types/components/controller/force-field/EventFieldLifecycleController.d.ts +14 -0
  30. package/dist/types/components/controller/force-field/EventFieldRenderer.d.ts +3 -3
  31. package/dist/types/components/controller/force-field/ForceFieldCanvasPainter.d.ts +99 -0
  32. package/dist/types/components/controller/force-field/ForceFieldComputationService.d.ts +9 -0
  33. package/dist/types/components/controller/force-field/ForceFieldDetailsPanel.d.ts +28 -57
  34. package/dist/types/components/controller/force-field/ForceFieldDetailsPresenter.d.ts +4 -1
  35. package/dist/types/components/controller/force-field/ForceFieldLifecycleController.d.ts +16 -1
  36. package/dist/types/components/controller/force-field/ForceFieldRenderer.d.ts +10 -18
  37. package/dist/types/components/controller/force-field/IncomingForceFieldService.d.ts +2 -2
  38. package/dist/types/components/controller/force-field/PropagationAnimator.d.ts +2 -0
  39. package/dist/types/components/controller/force-field/keyEventPresentation.d.ts +47 -0
  40. package/dist/types/components/controller/force-field/propagation-viz/PropagationCometPlayer.d.ts +4 -0
  41. package/dist/types/components/controller/force-field/propagation-viz/propagationVizLists.d.ts +4 -2
  42. package/dist/types/components/controller/force-field/propagation-viz/propagationVizModel.d.ts +1 -0
  43. package/dist/types/components/controller/force-field/shieldViewModel.d.ts +6 -2
  44. package/dist/types/components/controller/force-field/types.d.ts +2 -1
  45. package/dist/types/components/controller/labels/ChildScoresDeltaRenderer.d.ts +7 -0
  46. package/dist/types/components/controller/labels/ComponentTitlePresenter.d.ts +13 -0
  47. package/dist/types/components/controller/labels/ContextLabelsRenderer.d.ts +16 -0
  48. package/dist/types/components/controller/labels/WeightPreviewRingRenderer.d.ts +6 -0
  49. package/dist/types/components/controller/odd/ChildrenOrbitManager.d.ts +76 -25
  50. package/dist/types/components/controller/odd/OddHighlightEffects.d.ts +2 -0
  51. package/dist/types/components/controller/odd/OddViewManager.d.ts +7 -3
  52. package/dist/types/components/controller/odd/childHighlightStyles.d.ts +45 -3
  53. package/dist/types/components/controller/search/SearchPanelSynchronizer.d.ts +8 -5
  54. package/dist/types/components/controller/settings/ControllerSettingsApplier.d.ts +4 -4
  55. package/dist/types/components/controller/state/ControllerSession.d.ts +3 -3
  56. package/dist/types/components/controller/state/ControllerUiCallbacks.d.ts +10 -0
  57. package/dist/types/components/controller/state/YinYangControllerState.d.ts +20 -9
  58. package/dist/types/components/controller/types.d.ts +9 -2
  59. package/dist/types/components/controller/utils/actionCatalog.d.ts +1 -1
  60. package/dist/types/components/controller/utils/eventFieldTargets.d.ts +19 -13
  61. package/dist/types/components/controller/utils/keyEventPropagationContext.d.ts +4 -0
  62. package/dist/types/components/controller/utils/keyEventTargetBreakdowns.d.ts +4 -0
  63. package/dist/types/components/controller/utils/svgTransform.d.ts +16 -0
  64. package/dist/types/components/controls/VizControlsPanel.d.ts +3 -1
  65. package/dist/types/components/panel/PanelManager.d.ts +92 -22
  66. package/dist/types/components/search/GlobalSearchController.d.ts +13 -6
  67. package/dist/types/components/view/BorderDrawer.d.ts +40 -14
  68. package/dist/types/components/view/IdleTabGridDrawer.d.ts +15 -0
  69. package/dist/types/components/view/SpikeDrawer.d.ts +18 -0
  70. package/dist/types/components/view/ViewInitializer.d.ts +45 -7
  71. package/dist/types/components/view/YinYangDrawer.d.ts +132 -30
  72. package/dist/types/components/view/borderColorCycle.d.ts +76 -0
  73. package/dist/types/components/workspace/facetWeightRuleSetting.d.ts +10 -0
  74. package/dist/types/components/workspace/workspaceTemplate.d.ts +1 -1
  75. package/dist/types/config/animationConfig.d.ts +10 -1
  76. package/dist/types/data/adverse-action-planner.d.ts +3 -3
  77. package/dist/types/data/amplifier-engine.d.ts +6 -6
  78. package/dist/types/data/key-event-effects.d.ts +30 -0
  79. package/dist/types/data/key-event-eligibility.d.ts +24 -0
  80. package/dist/types/data/key-event-propagation.d.ts +13 -0
  81. package/dist/types/data/key-event-types.d.ts +48 -0
  82. package/dist/types/data/key-event-validation.d.ts +11 -0
  83. package/dist/types/data/stability-shield.d.ts +14 -0
  84. package/dist/types/data/yasuni_adverse_key_events.d.ts +1 -1
  85. package/dist/types/data/yasuni_cause.d.ts +7 -0
  86. package/dist/types/data/yasuni_key_events.d.ts +4 -60
  87. package/dist/types/interfaces/ICauseModel.d.ts +10 -1
  88. package/dist/types/interfaces/IGraphicsStrategy.d.ts +9 -2
  89. package/dist/types/interfaces/IPropagationGraph.d.ts +14 -0
  90. package/dist/types/interfaces/IViewData.d.ts +10 -0
  91. package/dist/types/interfaces/IYinYangController.d.ts +25 -7
  92. package/dist/types/interfaces/IYinYangInternalModel.d.ts +5 -0
  93. package/dist/types/main.d.ts +0 -1
  94. package/dist/types/utils/actionIconFit.d.ts +23 -0
  95. package/dist/types/utils/actionPropagation.d.ts +6 -4
  96. package/dist/types/utils/causeMetrics.d.ts +29 -11
  97. package/dist/types/utils/chainCardHeight.d.ts +87 -4
  98. package/dist/types/utils/collapseAnimation.d.ts +39 -0
  99. package/dist/types/utils/d3/D3GraphicsStrategy.d.ts +28 -5
  100. package/dist/types/utils/deltaChips.d.ts +0 -4
  101. package/dist/types/utils/exportControls.d.ts +8 -0
  102. package/dist/types/utils/facetWeightLabel.d.ts +6 -4
  103. package/dist/types/utils/facetteImages.d.ts +6 -0
  104. package/dist/types/utils/glowHalo.d.ts +74 -0
  105. package/dist/types/utils/hierBadge.d.ts +1 -1
  106. package/dist/types/utils/keyEventImages.d.ts +1 -1
  107. package/dist/types/utils/menuIconSize.d.ts +17 -0
  108. package/dist/types/utils/spreadAngles.d.ts +8 -0
  109. package/package.json +4 -1
  110. package/dist/bundle.js.LICENSE.txt +0 -1
@@ -0,0 +1,95 @@
1
+ export type IdleTabFacet = {
2
+ id: string;
3
+ label: string;
4
+ orientation: "yin" | "yang";
5
+ notion?: {
6
+ id: string;
7
+ name: string;
8
+ };
9
+ /** Ratio de taille du satellite (même calcul qu'en Idle « facettes »). */
10
+ sizeRatio: number;
11
+ };
12
+ export type IdleTabRect = {
13
+ x: number;
14
+ y: number;
15
+ width: number;
16
+ height: number;
17
+ };
18
+ export type IdleTabCell = IdleTabRect & {
19
+ facetId: string;
20
+ label: string;
21
+ orientation: "yin" | "yang";
22
+ /** Centre du satellite. */
23
+ satelliteCenter: {
24
+ x: number;
25
+ y: number;
26
+ };
27
+ /** Diamètre du satellite (minEdge, en pixels). */
28
+ satelliteDiameter: number;
29
+ /** Ligne de base du libellé de la facette. */
30
+ labelAnchor: {
31
+ x: number;
32
+ y: number;
33
+ };
34
+ /** La pastille de notion du groupe se pose sur le bord bas (sinon haut) :
35
+ * le libellé de la facette s'écarte alors vers l'intérieur. */
36
+ legendBottom: boolean;
37
+ /** La case borde-t-elle son groupe en haut / en bas (coins arrondis,
38
+ * libellé de la notion posé sur ce bord) ? */
39
+ groupEdges: {
40
+ top: boolean;
41
+ bottom: boolean;
42
+ };
43
+ /** Notion parente du groupe de la case, si elle en a une. */
44
+ notion?: {
45
+ id: string;
46
+ name: string;
47
+ };
48
+ };
49
+ export type IdleTabGroup = IdleTabRect & {
50
+ facetIds: string[];
51
+ /** Notion parente : son libellé se pose sur la bordure du groupe. */
52
+ notion?: {
53
+ id: string;
54
+ name: string;
55
+ };
56
+ /** Bordure qui porte le libellé de la notion (côté extérieur). */
57
+ legendSide: "top" | "bottom";
58
+ };
59
+ export type IdleTabLayout = {
60
+ columns: number;
61
+ rows: number;
62
+ cells: IdleTabCell[];
63
+ groups: IdleTabGroup[];
64
+ center: {
65
+ x: number;
66
+ y: number;
67
+ };
68
+ /** Rayon de l'illustration centrale réduite. */
69
+ centerRadius: number;
70
+ /** Taille de police des libellés de facette (px). */
71
+ labelFontSize: number;
72
+ };
73
+ export type IdleTabLayoutOptions = {
74
+ /** Coin haut-gauche de l'espace disponible (défaut : 0, 0). */
75
+ x?: number;
76
+ y?: number;
77
+ width: number;
78
+ height: number;
79
+ /** Marge autour de la grille. */
80
+ padding?: number;
81
+ /** Écart entre deux groupes voisins. */
82
+ gutter?: number;
83
+ };
84
+ type Unit = {
85
+ facets: IdleTabFacet[];
86
+ notion?: {
87
+ id: string;
88
+ name: string;
89
+ };
90
+ };
91
+ /** Facettes d'une même notion regroupées (ordre de première apparition),
92
+ * yin avant yang au sein d'un groupe. */
93
+ export declare function buildIdleTabUnits(facets: readonly IdleTabFacet[]): Unit[];
94
+ export declare function computeIdleTabLayout(facets: readonly IdleTabFacet[], options: IdleTabLayoutOptions): IdleTabLayout;
95
+ export {};
@@ -0,0 +1,45 @@
1
+ /** Centre et diamètre d'un satellite. */
2
+ export type MorphPoint = {
3
+ x: number;
4
+ y: number;
5
+ d: number;
6
+ };
7
+ export type MorphItem = {
8
+ /** Groupe enveloppe du satellite, qui porte la transformation. */
9
+ wrapper: SVGGElement;
10
+ /** Place radiale du satellite dans le repère du motif (avant réduction). */
11
+ base: MorphPoint;
12
+ /** Départ et arrivée, en pixels du SVG. */
13
+ from: MorphPoint;
14
+ to: MorphPoint;
15
+ };
16
+ type Center = {
17
+ x: number;
18
+ y: number;
19
+ };
20
+ /** Place à l'écran (pixels du SVG) d'un point du motif réduit à `scale`. */
21
+ export declare function toScreen(point: MorphPoint, scale: number, center: Center): MorphPoint;
22
+ /** Transformation de l'enveloppe qui amène le satellite de sa place
23
+ * radiale `base` à `screen`, le motif étant réduit à `scale`. */
24
+ export declare function wrapperTransform(base: MorphPoint, screen: MorphPoint, scale: number, center: Center): {
25
+ x: number;
26
+ y: number;
27
+ k: number;
28
+ transform: string;
29
+ };
30
+ /** Point entre `from` (t = 0) et `to` (t = 1), sur une trajectoire polaire
31
+ * autour de `center`. */
32
+ export declare function polarLerp(from: MorphPoint, to: MorphPoint, t: number, center: Center): MorphPoint;
33
+ /** Joue la bascule : échelle du motif de `fromScale` à `toScale` (posée par
34
+ * `applyScale`), chaque satellite de `from` à `to`. */
35
+ export declare function morphSatellites(options: {
36
+ /** Nœud qui porte la transition (le globalGroup du motif). */
37
+ node: SVGGElement;
38
+ center: Center;
39
+ fromScale: number;
40
+ toScale: number;
41
+ items: readonly MorphItem[];
42
+ durationMs: number;
43
+ applyScale: (scale: number) => void;
44
+ }): Promise<void>;
45
+ export {};
@@ -28,6 +28,18 @@ type EventFieldLifecycleControllerDeps = {
28
28
  center: Point | null;
29
29
  radius: number;
30
30
  };
31
+ /** Vrai en Idle « facettes » : le souffle relie alors le satellite-facette
32
+ * d'origine aux autres satellites-facettes atteints — pas de satellite de
33
+ * cutting à viser, et getComponentBorderTargetPoint résout chaque facette
34
+ * vers son satellite-facette. */
35
+ isIdleFacettesField: () => boolean;
36
+ /** Vrai pendant l'animation de changement de facette (clic sur un arc,
37
+ * navigation RECHERCHE ou pile) — voir refreshTargets. */
38
+ isComponentSwitching: () => boolean;
39
+ /** Vrai quand le champ est piloté par les événements cochés de la pile
40
+ * (mode STACK, aucun aperçu) : seuls les satellites réellement amplifiés
41
+ * sont alors visés (voir buildEventFieldTargets, stackEffects). */
42
+ isStackDrivenField: () => boolean;
31
43
  };
32
44
  /**
33
45
  * Cycle de vie du "Champ d'événement" (souffle cœur → satellites de
@@ -99,6 +111,8 @@ export declare class EventFieldLifecycleController {
99
111
  * frame par startEventFieldAnimation (orbite + pulsation). */
100
112
  private updateEventFieldVisual;
101
113
  private startEventFieldAnimation;
114
+ /** Fin de vie : coupe la boucle du champ d'événement. */
115
+ destroy(): void;
102
116
  private stopEventFieldAnimation;
103
117
  }
104
118
  export {};
@@ -7,8 +7,8 @@ export type Point = {
7
7
  * ce renderer ne fait que dessiner. */
8
8
  export type EventFieldRenderSegment = {
9
9
  end: Point;
10
- /** Bonus de score de l'Événement Clé — pilote l'épaisseur du souffle. */
11
- scoreBonus: number;
10
+ /** Intensité positionnelle commune aux cinq signatures — épaisseur du souffle. */
11
+ intensity: number;
12
12
  };
13
13
  /**
14
14
  * Chorégraphie du "Champ d'événement" : un souffle annulaire. Le cœur du
@@ -34,7 +34,7 @@ export declare class EventFieldRenderer {
34
34
  private coreHalo;
35
35
  /** setTimeout id du fondu de sortie en cours, ou null — voir hide(). */
36
36
  private _hideTimeoutId;
37
- /** requestAnimationFrame id de la rétraction géométrique en cours — voir retractGeometry(). */
37
+ /** Id frameScheduler de la rétraction géométrique en cours — voir retractGeometry(). */
38
38
  private _retractFrameId;
39
39
  hasActiveGroup(): boolean;
40
40
  ensureElements(params: {
@@ -0,0 +1,99 @@
1
+ type Point = {
2
+ x: number;
3
+ y: number;
4
+ };
5
+ export type StopData = Array<{
6
+ color: string;
7
+ opacity: number;
8
+ }>;
9
+ /** Un faisceau, tel que peint sur une image (repère du globalGroup). */
10
+ export type ForceFieldStroke = {
11
+ start: Point;
12
+ end: Point;
13
+ /** Extrémités des dégradés (énergie, comète, cœur). */
14
+ tail: Point;
15
+ head: Point;
16
+ /** Atténuation du faisceau (emphase de l'action en focus), 0..1. */
17
+ emphasis: number;
18
+ glow: {
19
+ color: string;
20
+ alpha: number;
21
+ baseWidth: number;
22
+ };
23
+ /** Cône d'aura : trapèze sur l'axe start → end, demi-largeurs aux deux bouts. */
24
+ cone: {
25
+ sourceHalf: number;
26
+ targetHalf: number;
27
+ fill: string;
28
+ opacity: number;
29
+ };
30
+ energy: {
31
+ stops: StopData;
32
+ width: number;
33
+ opacity: number;
34
+ dashOffset: number;
35
+ };
36
+ flow: {
37
+ width: number;
38
+ opacity: number;
39
+ dashOffset: number;
40
+ };
41
+ core: {
42
+ stops: StopData;
43
+ width: number;
44
+ opacity: number;
45
+ };
46
+ port: {
47
+ r: number;
48
+ width: number;
49
+ color: string;
50
+ opacity: number;
51
+ };
52
+ headAura: {
53
+ r: number;
54
+ fill: string;
55
+ opacity: number;
56
+ };
57
+ headCore: {
58
+ r: number;
59
+ opacity: number;
60
+ };
61
+ };
62
+ export declare const COMET_PERIOD: number;
63
+ export declare class ForceFieldCanvasPainter {
64
+ readonly globalGroup: SVGGElement;
65
+ private readonly host;
66
+ private readonly canvas;
67
+ private readonly ctx;
68
+ private readonly resizeObserver;
69
+ /** Coin haut-gauche de la zone peinte, en unités du globalGroup. */
70
+ private originX;
71
+ private originY;
72
+ /** Pixels du canvas par unité du globalGroup. */
73
+ private pxPerUnit;
74
+ /** Repère pour lequel la zone a été calée ; null = à recaler. */
75
+ private laidOutKey;
76
+ private readonly glowLayersByAlpha;
77
+ constructor(globalGroup: SVGGElement);
78
+ /** Repasse au-dessus des autres enfants du globalGroup. */
79
+ raise(): void;
80
+ /** Opacité de toute la couche, avec une transition CSS éventuelle. */
81
+ setOpacity(value: string, transition?: string): void;
82
+ remove(): void;
83
+ paint(strokes: readonly ForceFieldStroke[]): void;
84
+ private paintStroke;
85
+ /**
86
+ * Empreinte du repère de la zone peinte : transforms du globalGroup et de
87
+ * ses ancêtres jusqu'au <svg>, viewBox, densité d'écran. Quelques
88
+ * getAttribute par image, sans layout forcé ; la taille du <svg> est
89
+ * suivie à part (ResizeObserver).
90
+ */
91
+ private layoutKey;
92
+ private ensureLayout;
93
+ /** Cale la zone peinte sur le <svg> visible. Faux si pas encore mesurable. */
94
+ private layout;
95
+ private glowLayers;
96
+ private line;
97
+ private gradient;
98
+ }
99
+ export {};
@@ -1,8 +1,13 @@
1
+ import type { ActionStackItem } from "../action-stack/ActionStackState";
1
2
  import { YinYangInternalModel } from "../../../interfaces/IYinYangInternalModel";
2
3
  import type { CompiledPropagationGraph } from "../../../interfaces/IPropagationGraph";
3
4
  import { ChildrenOrbitEntry } from "../utils/childrenOrbit";
4
5
  import { ForceFieldLink, ForceFieldLinkDetail } from "./types";
5
6
  export declare class ForceFieldComputationService {
7
+ private readonly getEventContextItems;
8
+ constructor(getEventContextItems?: () => ActionStackItem[]);
9
+ eventContextCacheKey(): string;
10
+ private resolveDetails;
6
11
  build(params: {
7
12
  orbitData: ChildrenOrbitEntry[];
8
13
  sourceChildIndex: number;
@@ -15,6 +20,8 @@ export declare class ForceFieldComputationService {
15
20
  allComponents: YinYangInternalModel["components"] | undefined;
16
21
  actionDelta: number;
17
22
  propagationGraph: CompiledPropagationGraph;
23
+ eventContextItems?: ActionStackItem[];
24
+ actionItem?: ActionStackItem;
18
25
  }): {
19
26
  links: ForceFieldLink[];
20
27
  allLinkDetails: ForceFieldLinkDetail[];
@@ -31,6 +38,8 @@ export declare class ForceFieldComputationService {
31
38
  allComponents: YinYangInternalModel["components"] | undefined;
32
39
  actionDelta: number;
33
40
  propagationGraph: CompiledPropagationGraph;
41
+ eventContextItems?: ActionStackItem[];
42
+ actionItem?: ActionStackItem;
34
43
  }): {
35
44
  links: ForceFieldLink[];
36
45
  allLinkDetails: ForceFieldLinkDetail[];
@@ -1,9 +1,11 @@
1
+ import type { KeyEventActionEffects } from "../../../data/key-event-effects";
2
+ import { type EventTargetBreakdown } from "./keyEventPresentation";
1
3
  import { type CometPlayFn } from "./propagation-viz/propagationVizLists";
2
4
  import { YinYangComponentNode, YinYangInternalModel } from "../../../interfaces/IYinYangInternalModel";
3
5
  import { ForceFieldLink, ForceFieldLinkDetail } from "./types";
4
- import type { ComboResult } from "../../../data/combo-engine";
6
+ import { type ComboResult } from "../../../data/combo-engine";
5
7
  import { type AbsorptionBreakdown, type ActiveShield } from "./shieldViewModel";
6
- import type { AmplifierResult, AmplifierTargetBreakdown } from "../../../data/amplifier-engine";
8
+ import type { AmplifierResult } from "../../../data/amplifier-engine";
7
9
  import { type KeyEventDefinition } from "../../../data/yasuni_key_events";
8
10
  import type { Composante, ODD } from "../../../data/yasuni_cause";
9
11
  /** Contexte combo (backward) ou amplificateur (forward) transmis au clic
@@ -45,6 +47,7 @@ type ActionCumulativeBlockViewModel = {
45
47
  detailRows: ForceFieldLinkDetail[];
46
48
  comboResults?: ComboResult[];
47
49
  amplifierResults?: AmplifierResult[];
50
+ eventEffects?: KeyEventActionEffects;
48
51
  stackItemId?: string;
49
52
  color?: string;
50
53
  sequentialDetailPool?: ForceFieldLinkDetail[];
@@ -65,6 +68,10 @@ type ActionCumulativeBlockViewModel = {
65
68
  * contribution négative de ce bloc — direct, propagé, agrégé, absorbé,
66
69
  * appliqué (journal de résolution). */
67
70
  shieldAbsorption?: AbsorptionBreakdown;
71
+ directionalAbsorptions?: Array<{
72
+ active?: ActiveShield;
73
+ breakdown: AbsorptionBreakdown;
74
+ }>;
68
75
  };
69
76
  /** Bloc "keyEvent" : un Événement Clé joué, toujours affiché dès que sa
70
77
  * Facette d'origine correspond à celle affichée (voir YinYangController.
@@ -82,7 +89,7 @@ type KeyEventCumulativeBlockViewModel = {
82
89
  id: string;
83
90
  name: string;
84
91
  }>;
85
- breakdowns?: AmplifierTargetBreakdown[];
92
+ breakdowns?: EventTargetBreakdown[];
86
93
  };
87
94
  type CumulativeBlockViewModel = ActionCumulativeBlockViewModel | KeyEventCumulativeBlockViewModel;
88
95
  export declare class ForceFieldDetailsPanel {
@@ -134,6 +141,10 @@ export declare class ForceFieldDetailsPanel {
134
141
  /** Timer set during a user card interaction — prevents ResizeObserver from
135
142
  * running _applyAutoFitToGrids while a card is animating. */
136
143
  private _userInteractingTimer;
144
+ /** Observers posés sur les conteneurs de rails, et rappel de la montée des
145
+ * badges en cours : coupés par destroy(). */
146
+ private readonly _resizeObservers;
147
+ private _countUpFrameId;
137
148
  /** Set during a live-update _initCardRailState call. _applyAutoFitToGrids skips
138
149
  * this container until the timer fires (covering both the initial DOM-insertion
139
150
  * resize and the gs-block-open animation resize that follows). */
@@ -150,8 +161,6 @@ export declare class ForceFieldDetailsPanel {
150
161
  private _onDiagramElementHover?;
151
162
  /** Called when hovering a cumulative block — notifies the stack to highlight the matching item. */
152
163
  private _onStackItemHighlightCb?;
153
- /** Clic sur l'en-tête d'un bloc → action en focus (YinYangController). */
154
- private _onStackItemFocusCb?;
155
164
  private _onShieldOriginClickCb?;
156
165
  /** Miroir de state.forceField.focusedStackItemId — sert uniquement à
157
166
  * ré-appliquer .ff-block--focused après chaque innerHTML. */
@@ -202,6 +211,9 @@ export declare class ForceFieldDetailsPanel {
202
211
  * l'item de pile porteur, car la même action présente deux fois dans la
203
212
  * pile a deux cartes combo de même contenu mais d'ancres différentes. */
204
213
  private _getHighlightCardKey;
214
+ /** Repère d'une ligne Source : le satellite où l'action est jouée porte
215
+ * la petite icône de l'action (son nom en infobulle). */
216
+ private _actionSourceMarkHtml;
205
217
  /** Titre de carte, gabarit commun à toutes les cartes du rail : étiquette
206
218
  * de type facultative (couleur --card-accent de la carte) puis nom
207
219
  * lisible — l'information principale à lire. */
@@ -258,7 +270,7 @@ export declare class ForceFieldDetailsPanel {
258
270
  /**
259
271
  * Carte descriptive autonome d'un Événement Clé — affichée dans le
260
272
  * panneau Recherche quand l'utilisateur prévisualise l'événement lui-même
261
- * (1er clic sur une bulle du menu radial du cercle central), pas quand il
273
+ * (1er clic sur une bulle du menu radial du satellite-facette), pas quand il
262
274
  * amplifie une action (voir _buildAmplifierSectionHtml pour cette carte-là).
263
275
  * Reprend délibérément le langage visuel de la carte action "source" (voir
264
276
  * _renderChainCardHtml/isSourceCard) — illustration plein cadre — mais SANS
@@ -289,13 +301,12 @@ export declare class ForceFieldDetailsPanel {
289
301
  name: string;
290
302
  }>;
291
303
  /** Répartition par action ciblée (position dans la fenêtre, bonus
292
- * effectif déjà réduit) — absente en aperçu avant validation, où
293
- * l'événement n'a pas encore de slot depuis lequel compter une position.
294
- * Une entrée par targetedActions quand présente (voir
295
- * getAmplifierTargetBreakdown). */
296
- breakdowns?: AmplifierTargetBreakdown[];
297
- /** Id de l'item "keyEvent" actif dans la pile (absent en aperçu avant
298
- * validation) — active le clic "barres de gain par slot" sur la carte
304
+ * effectif déjà réduit) — bloc STACK seulement : absente en aperçu
305
+ * (RECHERCHE), où aucune position n'existe hors de la pile. En STACK,
306
+ * réduite aux actions cochées et amplifiées, comme targetedActions
307
+ * (voir buildKeyEventBlocksForComponent). */
308
+ breakdowns?: EventTargetBreakdown[];
309
+ /** Id de l'item "keyEvent" actif dans la pile (absent en aperçu) — active le clic "barres de gain par slot" sur la carte
299
310
  * et sa section d'actions ciblées (voir _attachComboHighlightHandlers),
300
311
  * même mécanisme que le clic sur une carte combo. */
301
312
  sourceItemId?: string;
@@ -304,49 +315,6 @@ export declare class ForceFieldDetailsPanel {
304
315
  html: string;
305
316
  attachHandlers: (container: HTMLElement) => void;
306
317
  };
307
- /**
308
- * Carte "actions ciblées" d'une source d'effet différé — la liste des
309
- * actions qu'un Événement Clé amplifie ("Actions amplifiées") ou qu'une
310
- * action adverse entrave ("Actions entravées"), avec pour chacune le seul
311
- * delta AJOUTÉ (ou retiré) par l'effet — pas le résultat final combiné au
312
- * delta de base de l'action, qui deviendrait faux dès qu'un combo entre
313
- * en jeu ailleurs sur la même action. Même grammaire que la chip de bonus
314
- * de la carte Événement Clé sœur (buildKeyEventChipsHtml) : rester simple
315
- * et lisible plutôt que reconstituer un calcul complet ici.
316
- *
317
- * Le bonus du catalogue est le PLAFOND — atteint seulement quand l'action
318
- * est jouée au pic de la fenêtre. Une fois la source placée (breakdowns
319
- * disponibles), chaque ligne affiche le bonus EFFECTIF (réduit selon la
320
- * position) plutôt que ce plafond nominal — sinon la chip mentirait sur ce
321
- * que l'action rapporte réellement. Sans breakdowns, le plafond reste la
322
- * meilleure estimation disponible.
323
- *
324
- * Porte le même jeu d'attributs data-keyevent-* que la carte source
325
- * (Événement Clé ou action adverse) pour que _attachComboHighlightHandlers
326
- * et _extractTagComboContext y lisent la fenêtre "en avant" : un clic
327
- * affiche les barres de gain par slot pour toute la fenêtre withinNextN.
328
- *
329
- * Badge et tableau repris à l'identique du gabarit carte combo (voir
330
- * _buildComboSectionHtml/_buildPrereqBreakdownHtml) plutôt qu'un format ad
331
- * hoc : le badge affiche le bonus/malus plafond du catalogue, accompagné
332
- * d'un chip de poids (même paire badge+chip que portait la carte source
333
- * avant que ces deltas n'emménagent ici, voir buildKeyEventCardHtml —
334
- * absent si l'effet ne touche pas le poids), et le tableau réutilise les
335
- * colonnes ff-pt-name/ff-pt-val de
336
- * .ff-combo-prereq-table (les noms passent à la ligne plutôt que d'exiger
337
- * une largeur de carte dérogatoire). Repliable comme n'importe quelle autre
338
- * carte de la famille (le garde-fou qui la forçait dépliée a été retiré de
339
- * _handleCardRailClick/_applyAutoFitToGrids) et précédée d'un séparateur
340
- * .ff-chain-separator — même traitement que la carte source vis-à-vis d'un
341
- * bloc combo/amplificateur, pour que ce bloc-ci ne fasse pas exception.
342
- */
343
- private _buildDelayedTargetsCardHtml;
344
- /** Badge et note de provenance d'un bloc action de la vue cumulative.
345
- * Seule une action propagée porte une note dans l'en-tête (le satellite
346
- * dont elle provient) : pour une action directe — adverse comprise — on
347
- * est déjà sur le satellite porteur, l'information serait redondante.
348
- * L'acteur d'origine d'une action adverse est rendu à part (`origin`),
349
- * dans le corps du bloc, pour ne pas concurrencer le nom. */
350
318
  private _pickActionBlockBadge;
351
319
  /** Ligne « Acteur : … » placée en tête du corps d'un bloc adverse (action
352
320
  * ou Événement) — remplace l'ancienne note d'en-tête. */
@@ -486,6 +454,9 @@ export declare class ForceFieldDetailsPanel {
486
454
  * re-runs the auto-fit measurement whenever the container changes size.
487
455
  */
488
456
  private _ensureResizeObserver;
457
+ /** Fin de vie : observers déconnectés, minuteries et montée des badges
458
+ * coupées. Le DOM du panneau appartient à l'hôte : non touché. */
459
+ destroy(): void;
489
460
  private _initCardRailState;
490
461
  private _handleCardRailClick;
491
462
  private _triggerHighlightFromCard;
@@ -531,7 +502,6 @@ export declare class ForceFieldDetailsPanel {
531
502
  /** Vrai si le panneau affiche actuellement le bloc « Effets cumulés » de cet
532
503
  * item de pile (le satellite/la facette porteuse est sélectionné). */
533
504
  hasBlockForStackItem(stackItemId: string): boolean;
534
- setStackItemFocusCallback(cb: (id: string | null) => void): void;
535
505
  /** Clic sur le nom de l'action d'origine dans une carte Bouclier. */
536
506
  setShieldOriginClickCallback(cb: (stackItemId: string) => void): void;
537
507
  /** Miroir du focus (source de vérité : YinYangController / state). */
@@ -692,6 +662,7 @@ export declare class ForceFieldDetailsPanel {
692
662
  allComponents?: YinYangComponentNode[];
693
663
  comboResults?: ComboResult[];
694
664
  amplifierResults?: AmplifierResult[];
665
+ eventEffects?: KeyEventActionEffects;
695
666
  stackItemId?: string;
696
667
  /** Bouclier de stabilité déjà actif sur le satellite ciblé (posé par
697
668
  * une action antérieure de la pile) — affiché sur la carte bilan et
@@ -20,7 +20,7 @@ export type ForceFieldDetailsPresenterDeps = {
20
20
  actionStackManager: ActionStackManager;
21
21
  applyOddStateForCutting: (oddId: string) => void;
22
22
  buildChildrenOrbitData: () => ChildrenOrbitEntry[];
23
- buildProjectionActionsFromStackItems: (items: ActionStackItem[]) => SequentialActionProjectionInput[];
23
+ buildProjectionActionsFromStackItems: (items: ActionStackItem[], eventContextItems?: ActionStackItem[]) => SequentialActionProjectionInput[];
24
24
  getChildControllers: () => IYinYangController[];
25
25
  childOddMap: Map<string, {
26
26
  oddId: string;
@@ -47,6 +47,9 @@ export type ForceFieldDetailsPresenterDeps = {
47
47
  export declare class ForceFieldDetailsPresenter {
48
48
  private deps;
49
49
  constructor(deps: ForceFieldDetailsPresenterDeps);
50
+ /** Action ciblée par un événement pendant son insertion depuis RECHERCHE.
51
+ * Les positions projetées servent au même moteur d'effets que le dépôt. */
52
+ renderGuidedActionPreview(preview: ActionStackItem, projected: ActionStackItem[] | null): void;
50
53
  /**
51
54
  * Construit le bloc d'action directe pour un emplacement connu (compId/oddId/cutIdx/actionId)
52
55
  * sans naviguer le diagramme, et fire le callback avec (compId, oddId, cutIdx, actionId, html, attachHandlers).
@@ -18,6 +18,12 @@ type ForceFieldLifecycleControllerDeps = {
18
18
  getAllComponents: () => YinYangInternalModel["components"] | undefined;
19
19
  updateChildActionMenu: (orbitData: ChildrenOrbitEntry[]) => void;
20
20
  updateContextLabels: (orbitData: ChildrenOrbitEntry[]) => void;
21
+ /** Frame d'orbite : bulles du menu radial et bulles détachées recalées
22
+ * sur leur satellite, sans data join ni transitions. */
23
+ followOrbitChildActionMenu: (orbitData: ChildrenOrbitEntry[]) => void;
24
+ /** Frame d'orbite : libellés, deltas et anneau de poids recalés, sans
25
+ * réécrire le titre, la légende ni les panneaux. */
26
+ followOrbitContextLabels: (orbitData: ChildrenOrbitEntry[]) => void;
21
27
  clearForceFieldDetails: () => void;
22
28
  renderForceFieldDetails: (linkIndex: number) => void;
23
29
  renderActionPropagationTable: () => void;
@@ -62,7 +68,16 @@ export declare class ForceFieldLifecycleController {
62
68
  invalidatePropagationCache(): void;
63
69
  private _buildPropCacheKey;
64
70
  renderOppositeChildrenForceField(orbitData?: ChildrenOrbitEntry[]): void;
65
- removeOppositeChildrenForceField(): void;
71
+ /**
72
+ * Frame d'orbite en vol (ChildrenOrbitManager) : les satellites viennent
73
+ * de bouger, rien d'autre n'a changé. Seule la géométrie qui dépend de
74
+ * leur position est recalée ; le champ de force est dessiné ici une seule
75
+ * fois, sa propre boucle se contentant alors d'avancer la phase.
76
+ */
77
+ updateOrbitFrame(orbitData: ChildrenOrbitEntry[]): void;
78
+ /** Fin de vie : coupe la boucle du champ de force. */
79
+ destroy(): void;
80
+ removeOppositeChildrenForceField(orbitData?: ChildrenOrbitEntry[]): void;
66
81
  private ensureForceFieldLinks;
67
82
  private updateForceFieldVisual;
68
83
  private startForceFieldAnimation;
@@ -6,13 +6,12 @@ type Point = {
6
6
  y: number;
7
7
  };
8
8
  export declare class ForceFieldRenderer {
9
- private forceFieldGroup;
10
- private forceFieldDefs;
9
+ /** Surface du champ de force ; null = aucun champ affiché. */
10
+ private painter;
11
11
  private forceFieldLayers;
12
- private readonly gradientPrefix;
13
12
  /** setTimeout id du fondu de sortie en cours, ou null — voir hide(). */
14
13
  private _hideTimeoutId;
15
- /** requestAnimationFrame id de la rétraction géométrique en cours — voir retractGeometry(). */
14
+ /** Id frameScheduler de la rétraction géométrique en cours — voir retractGeometry(). */
16
15
  private _retractFrameId;
17
16
  /** Horodatage du dernier updateVisual — updateVisual ne reçoit pas de Δt,
18
17
  * on le dérive ici pour le lissage de l'emphase. */
@@ -53,32 +52,25 @@ export declare class ForceFieldRenderer {
53
52
  getComponentBorderTargetPoint: (componentId: string) => Point | null;
54
53
  }): void;
55
54
  /**
56
- * Fondu de sortie : au lieu de retirer le groupe instantanément (clear()),
57
- * ramène son opacité à 0 sur fieldFadeOutDurationMs puis le retire
55
+ * Fondu de sortie : au lieu de retirer la surface instantanément (clear()),
56
+ * ramène son opacité à 0 sur fieldFadeOutDurationMs puis la retire
58
57
  * réellement — même grammaire de disparition que EventFieldRenderer.hide().
59
58
  * Idempotent : un appel alors qu'un fondu est déjà en cours ne fait rien de
60
59
  * plus (le clear() en attente suffit).
61
60
  */
62
61
  hide(): void;
63
62
  /**
64
- * Rétraction géométrique : anime chaque beam vers son point de départ,
63
+ * Rétraction géométrique : ramène chaque faisceau vers son point de départ,
65
64
  * inverse exact de la croissance animatedEnd de updateVisual (même
66
65
  * fonction d'accélération, lue à l'envers : d3.easeCubicOut(1 - t) au lieu
67
- * de d3.easeCubicOut(t)). Repart de _prevEndpoint — la géométrie du
68
- * dernier frame réellement rendu — donc ne dépend d'aucun state externe :
69
- * elle continue même si les liens qui l'ont produite sont nettoyés entre
66
+ * de d3.easeCubicOut(t)). Repart du dernier faisceau réellement peint, figé
67
+ * (respiration et comètes arrêtées), donc ne dépend d'aucun state externe :
68
+ * elle continue même si les liens qui l'ont produit sont nettoyés entre
70
69
  * temps (cas typique : clic sur l'arc de facette, qui déclenche hide()
71
70
  * puis, dans la foulée, la destruction des satellites source). Se déroule
72
- * en parallèle du fondu d'opacité du groupe (même durée, posé par hide()).
71
+ * en parallèle du fondu d'opacité (même durée, posé par hide()).
73
72
  */
74
73
  private retractGeometry;
75
74
  clear(): void;
76
- /**
77
- * Met à jour les coordonnées d'un gradient et, si stopData est fourni (cache miss),
78
- * les couleurs et opacités des stops.
79
- * Fix 1 : les offsets ne sont jamais réécrits (initialisés une seule fois dans createStops).
80
- * Fix 2 : stopData === null signifie que le cache couleur est valide — on n'écrit pas les stops.
81
- */
82
- private updateGradient;
83
75
  }
84
76
  export {};
@@ -8,10 +8,10 @@ import { ComponentTitlePresenter } from "../labels/ComponentTitlePresenter";
8
8
  import { ControllerSession } from "../state/ControllerSession";
9
9
  import { ForceFieldComputationService } from "./ForceFieldComputationService";
10
10
  export type IncomingForceFieldServiceDeps = {
11
- applyProjectedGhostFromStackItems: (items: ActionStackItem[]) => void;
11
+ applyProjectedGhostFromStackItems: (items: ActionStackItem[], eventContextItems?: ActionStackItem[]) => void;
12
12
  buildChildrenOrbitData: () => ChildrenOrbitEntry[];
13
13
  buildForceFieldSourceIndicesFromStackItems: (items: ActionStackItem[]) => number[];
14
- buildProjectionActionsFromStackItems: (items: ActionStackItem[]) => SequentialActionProjectionInput[];
14
+ buildProjectionActionsFromStackItems: (items: ActionStackItem[], eventContextItems?: ActionStackItem[]) => SequentialActionProjectionInput[];
15
15
  childOddMap: Map<string, {
16
16
  oddId: string;
17
17
  score: number;
@@ -44,6 +44,8 @@ export declare class PropagationAnimator {
44
44
  * le réglage se sente tout de suite. */
45
45
  setFocusPropagationLoopGapMs(ms: number): void;
46
46
  restartFocusPropagationLoop(): void;
47
+ /** Fin de vie : coupe la boucle de l'action en focus et la comète. */
48
+ destroy(): void;
47
49
  private stopFocusPropagationLoop;
48
50
  private _runFocusPropagationLoopPass;
49
51
  /** Joue une passe pour l'item ; retourne sa durée (0 si rien à jouer). */