@micheeeeel/yinyangapp 3.0.0 → 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 +3 -0
  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 +16 -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 +53 -13
  71. package/dist/types/components/view/YinYangDrawer.d.ts +139 -40
  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 +12 -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 +50 -0
  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 +13 -0
  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,47 @@
1
+ import type { KeyEventDefinition } from "../../../data/key-event-types";
2
+ import type { KeyEventActionEffects } from "../../../data/key-event-effects";
3
+ import type { ForceFieldLinkDetail } from "./types";
4
+ export declare const escapeEventHtml: (text: string) => string;
5
+ export type EventTargetBreakdown = {
6
+ id: string;
7
+ positional: number;
8
+ played: boolean;
9
+ effectText: string;
10
+ slotIndex?: number;
11
+ };
12
+ export declare const eventSignatureName: (event: KeyEventDefinition) => string;
13
+ /** Catalogue potential, or the parameter at the exact shared eligibility strength.
14
+ * These are labelled parameters, never fabricated additive deltas. */
15
+ export declare function eventSignatureDescription(event: KeyEventDefinition, strength?: number): string;
16
+ export declare function eventSignatureChipHtml(event: KeyEventDefinition): string;
17
+ export declare function eventEffectRows(effects: KeyEventActionEffects | undefined): {
18
+ event: KeyEventDefinition;
19
+ text: string;
20
+ strength: number;
21
+ }[];
22
+ export type EventEffectCardContext = {
23
+ baseDelta?: number;
24
+ comboDelta?: number;
25
+ stackItemId?: string;
26
+ detailRows?: ForceFieldLinkDetail[];
27
+ activeShield?: number;
28
+ activeShieldProtectedSign?: 1 | -1;
29
+ };
30
+ /** Cartes de modification dans le rail de l'action : même grammaire que
31
+ * les combos, avec les unités propres à chaque signature. Les badges de
32
+ * propagation/bouclier ne prétendent jamais être des deltas additionnables. */
33
+ export declare function eventEffectsCardsHtml(effects: KeyEventActionEffects | undefined, context?: EventEffectCardContext): string;
34
+ export declare function eventPropagationLabel(row: ForceFieldLinkDetail): string;
35
+ export declare function eventTargetsCardHtml(params: {
36
+ keyEvent: KeyEventDefinition;
37
+ targetedActions: Array<{
38
+ id: string;
39
+ name: string;
40
+ }>;
41
+ breakdowns?: EventTargetBreakdown[];
42
+ requiresAttr: string;
43
+ withinNextNAttr: string;
44
+ nameAttr: string;
45
+ itemIdAttr: string;
46
+ adverse: boolean;
47
+ }): string;
@@ -37,6 +37,10 @@ export type CometPlayOptions = {
37
37
  export declare class PropagationCometPlayer {
38
38
  private deps;
39
39
  private run;
40
+ /** Rappel de frame en attente et couche de la lecture en cours : `stop()`
41
+ * les retire tout de suite au lieu d'attendre la frame suivante. */
42
+ private pendingFrameId;
43
+ private pendingLayer;
40
44
  constructor(deps: PropagationCometPlayerDeps);
41
45
  private get cfg();
42
46
  /** Joue un ou plusieurs arbres (rafale). Retourne la durée de la lecture
@@ -38,8 +38,10 @@ export declare class PropagationVizLists {
38
38
  pool: readonly ForceFieldLinkDetail[];
39
39
  satellite: VizSatellite;
40
40
  blockColor?: string;
41
- /** Libellé d'une provenance (ex. nom de l'action pour son satellite). */
42
- labelOf?: (satellite: VizSatellite) => string | undefined;
41
+ /** Repère HTML ajouté après le nom d'un satellite (ex. icône de l'action
42
+ * sur le satellite où elle est jouée) — le nom, lui, reste celui du
43
+ * satellite : une ligne de liste désigne toujours un satellite. */
44
+ markOf?: (satellite: VizSatellite) => string | undefined;
43
45
  }): {
44
46
  html: string;
45
47
  count: number;
@@ -15,6 +15,7 @@ export type VizListEntry = {
15
15
  delta: number;
16
16
  edgeIds: string[];
17
17
  rationales: string[];
18
+ provenance: string[];
18
19
  };
19
20
  /** Arbre de trajet d'une comète : le satellite de départ, puis chaque
20
21
  * satellite atteint, embranchements compris. */
@@ -5,6 +5,7 @@ export interface ShieldGrant {
5
5
  oddId: string;
6
6
  cuttingIndex: number;
7
7
  shield: number;
8
+ protectedSign?: 1 | -1;
8
9
  /** Nom de l'action qui l'a créé — l'origine affichée au joueur. */
9
10
  label?: string;
10
11
  /** Item de pile qui l'a créé — cible du lien de la carte Bouclier. */
@@ -12,6 +13,7 @@ export interface ShieldGrant {
12
13
  }
13
14
  export interface ActiveShield {
14
15
  value: number;
16
+ protectedSign?: 1 | -1;
15
17
  originLabel?: string;
16
18
  originStackItemId?: string;
17
19
  }
@@ -25,7 +27,7 @@ export interface ShieldTargetRef {
25
27
  * un seul par satellite, le plus fort ; à valeur égale, le premier posé
26
28
  * reste l'origine (un bouclier plus faible ou égal ne remplace jamais).
27
29
  */
28
- export declare function resolveActiveShield(grants: ShieldGrant[], target: ShieldTargetRef): ActiveShield | undefined;
30
+ export declare function resolveActiveShield(grants: ShieldGrant[], target: ShieldTargetRef, protectedSign?: 1 | -1): ActiveShield | undefined;
29
31
  export type ShieldVerdict = "creates" | "replaces" | "ignored" | "unchanged";
30
32
  /**
31
33
  * Ce que ferait un bouclier `created` face au bouclier `active` déjà en
@@ -52,13 +54,14 @@ export interface AbsorptionBreakdown {
52
54
  applied: number;
53
55
  /** true si le bouclier a tout absorbé : le delta appliqué est 0, pas un gain. */
54
56
  boundedToZero: boolean;
57
+ protectedSign?: 1 | -1;
55
58
  }
56
59
  /**
57
60
  * @param absorption réduction rapportée par la projection pour ce satellite
58
61
  * @param directDelta delta effectif de l'action si elle vise ce satellite,
59
62
  * 0 sinon — permet de séparer direct et propagé.
60
63
  */
61
- export declare function buildAbsorptionBreakdown(absorption: Pick<ShieldAbsorption, "shield" | "aggregated" | "applied">, directDelta: number): AbsorptionBreakdown;
64
+ export declare function buildAbsorptionBreakdown(absorption: Pick<ShieldAbsorption, "shield" | "aggregated" | "applied" | "protectedSign">, directDelta: number): AbsorptionBreakdown;
62
65
  /** Lignes courtes du journal de résolution, dans l'ordre du pipeline. */
63
66
  export declare function absorptionSentences(b: AbsorptionBreakdown): string[];
64
67
  /** Carte « Bouclier » d'un bloc de l'ANALYSE : maillon additif entre les
@@ -73,6 +76,7 @@ export interface ShieldCardViewModel {
73
76
  /** Lignes de calcul, dans l'ordre du pipeline. */
74
77
  lines: string[];
75
78
  boundedToZero: boolean;
79
+ protectedSign?: 1 | -1;
76
80
  }
77
81
  /** undefined quand le bouclier n'a rien réduit dans ce bloc (contribution
78
82
  * positive, ou pas de bouclier) : pas de carte, la note du Bilan suffit. */
@@ -1,4 +1,4 @@
1
- import type { PropagationScope } from "../../../interfaces/IPropagationGraph";
1
+ import type { EventPropagationMetadata, PropagationScope } from "../../../interfaces/IPropagationGraph";
2
2
  /**
3
3
  * Une arrivée de propagation prête pour l'affichage : un saut du graphe
4
4
  * unifié, d'un satellite à un autre, issu d'une résolution précise.
@@ -20,6 +20,7 @@ export type ForceFieldLinkDetail = {
20
20
  * désigner une arrivée absente des lignes affichées (sautée dans une autre
21
21
  * facette) : la ligne est alors une racine pour cet affichage. */
22
22
  parentEdgeId?: string;
23
+ eventPropagation?: EventPropagationMetadata;
23
24
  scope: PropagationScope;
24
25
  fromComponentId: string;
25
26
  toComponentId: string;
@@ -3,6 +3,13 @@ import { YinYangInternalModel } from "../../../interfaces/IYinYangInternalModel"
3
3
  import { ChildrenOrbitEntry } from "../utils/childrenOrbit";
4
4
  import { ProjectedCuttingState } from "../actions/ActionProjectionService";
5
5
  export declare class ChildScoresDeltaRenderer {
6
+ private lastParams;
7
+ /**
8
+ * Frame d'orbite : chaque bloc de deltas déjà rendu glisse vers son
9
+ * nouvel ancrage par un simple `transform` sur son groupe (décalage par
10
+ * rapport à l'ancrage du dernier render), sans recréer textes ni voile.
11
+ */
12
+ followOrbit(): void;
6
13
  render(params: {
7
14
  orbitData: ChildrenOrbitEntry[];
8
15
  globalGroupNode: SVGGElement | null;
@@ -49,6 +49,15 @@ export declare class ComponentTitlePresenter {
49
49
  private deps;
50
50
  constructor(deps: ComponentTitlePresenterDeps);
51
51
  private getCurrentComponentTitle;
52
+ /** L'Événement Clé actif, s'il est issu de `component` — partagé par le
53
+ * titre en Facette et au repos. */
54
+ private getActiveKeyEventOf;
55
+ /** Au repos (Idle « facettes » / « tab ») : la hiérarchie du titre remonte
56
+ * d'un cran — l'objet racine en tête, le satellite-facette sélectionné
57
+ * (celui dont les bulles sont déployées) sur la ligne enfant, son
58
+ * Événement Clé actif au niveau suivant. Même rendu qu'une Facette
59
+ * ouverte (facette › satellite › action). */
60
+ private getIdleFacetteTitle;
52
61
  /** Second (et, le cas échéant, troisième) niveau du titre : libellé + couleur
53
62
  * ODD du satellite actif sous la facette courante (menu ouvert, ou
54
63
  * sélection en lecture seule — voir getActiveChildMeta), avec le libellé
@@ -80,6 +89,10 @@ export declare class ComponentTitlePresenter {
80
89
  * satellite line is cleared here rather than read from state mid-switch. */
81
90
  updateComponentTitleLabelImmediate(componentIndex: number): void;
82
91
  updateContextLabels(orbitData: ChildrenOrbitEntry[]): void;
92
+ /** Frame d'orbite (ForceFieldLifecycleController.updateOrbitFrame) :
93
+ * libellés, deltas et anneau de poids suivent les satellites. Le titre,
94
+ * la légende et les ghosts de bordure ne dépendent pas de l'angle. */
95
+ followOrbit(orbitData: ChildrenOrbitEntry[]): void;
83
96
  renderChildScoresDeltas(orbitData: ChildrenOrbitEntry[]): void;
84
97
  /** Re-syncs the weightDelta ghost/wave/pulse against the current
85
98
  * ViewInitializer settings (basePulseEnabled, ghostPulseDurationSec,
@@ -67,6 +67,12 @@ export declare class ContextLabelsRenderer {
67
67
  private componentLegendGroup;
68
68
  private lastParams;
69
69
  private _childLabelCache;
70
+ /** Rects écran du SVG et du titre pour updateTitleObstruction, relus au
71
+ * plus toutes les OBSTRUCTION_RECTS_TTL_MS pendant l'orbite : les lire à
72
+ * chaque frame, juste après les transforms des satellites, forçait un
73
+ * layout complet. */
74
+ private _obstructionRects;
75
+ private static readonly OBSTRUCTION_RECTS_TTL_MS;
70
76
  /** Crossfades du texte du titre (facette / satellite), indépendants pour
71
77
  * que le changement de l'un ne fasse pas clignoter l'autre. */
72
78
  private _titleCrossfadeTimers;
@@ -92,6 +98,16 @@ export declare class ContextLabelsRenderer {
92
98
  private static readonly SATELLITE_ROW_SPEC;
93
99
  private static readonly ACTION_ROW_SPEC;
94
100
  render(params: RenderContextLabelsParams): void;
101
+ /** Place le libellé court d'un satellite au meilleur endroit autour de
102
+ * son centre ; ne réécrit rien si rien n'a bougé depuis `cache`. */
103
+ private layoutChildLabel;
104
+ /**
105
+ * Frame d'orbite : les satellites ont bougé, rien d'autre. Recale chaque
106
+ * libellé déjà rendu (groupe + position du texte) et l'occultation du
107
+ * titre, sans data join ni réécriture du titre HTML, de la légende ou du
108
+ * contenu des libellés — tout cela ne change que par render().
109
+ */
110
+ followOrbit(orbitData: ChildrenOrbitEntry[]): void;
95
111
  clear(): void;
96
112
  setVisibilityOpacity(opacity: number): void;
97
113
  /**
@@ -18,6 +18,7 @@ export declare class WeightPreviewRingRenderer {
18
18
  private basePulseEnabled;
19
19
  private pulseDurationMs;
20
20
  private pulseMorphRatio;
21
+ private getChildRenderedCenter;
21
22
  render(params: {
22
23
  orbitData: ChildrenOrbitEntry[];
23
24
  globalGroupNode: SVGGElement | null;
@@ -40,6 +41,9 @@ export declare class WeightPreviewRingRenderer {
40
41
  pulseDurationMs: number;
41
42
  pulseMorphRatio: number;
42
43
  }): void;
44
+ /** Frame d'orbite : recentre fantômes et vagues sur leur satellite (les
45
+ * entrées sont les données liées aux cercles), sans data join. */
46
+ followOrbit(): void;
43
47
  /** Starts/stops per-satellite pulse state to match the current entry set
44
48
  * and basePulseEnabled flag, resetting any satellite's own scale back to
45
49
  * identity the moment it stops being targeted or pulsing is turned off —
@@ -49,6 +53,8 @@ export declare class WeightPreviewRingRenderer {
49
53
  private resetEntryTransform;
50
54
  private drawGhostCircles;
51
55
  private ensureLoop;
56
+ /** Fin de vie : coupe la boucle de pulsation. */
57
+ destroy(): void;
52
58
  private stopLoop;
53
59
  /** Breathes each pulsing satellite's own size out to its weightDelta
54
60
  * target and back, on a loop with a pause — same morph/reset/pause cycle
@@ -6,50 +6,83 @@ type ChildrenOrbitManagerDeps = {
6
6
  view: IYinYangView;
7
7
  getChildControllers: () => IYinYangController[];
8
8
  state: YinYangControllerState;
9
+ /** Rendu complet (menu, labels, panneaux, champ de force) : seulement
10
+ * quand l'état de l'orbite change (démarrage, arrêt, repos). */
9
11
  renderOppositeChildrenForceField: (orbitData: ChildrenOrbitEntry[]) => void;
12
+ /** Rendu par frame pendant que l'orbite tourne : uniquement ce qui suit
13
+ * la position des satellites (bulles, libellés, liens du champ de force). */
14
+ updateOrbitFrame: (orbitData: ChildrenOrbitEntry[]) => void;
10
15
  };
16
+ /**
17
+ * Orbite des satellites, jouée par le navigateur (PERF-18). Le mouvement est
18
+ * décrit en tronçons à accélération constante (`rotationMotion.ts`, ici en
19
+ * radians et rad/ms) ; chaque satellite reçoit une animation Web Animations
20
+ * par tronçon sur l'enveloppe d'orbite (`viewInitializer.orbitGroup`), calée
21
+ * sur `document.timeline` : le contenu du satellite n'est plus re-rasterisé.
22
+ *
23
+ * Ce qui suit les satellites (bulles, libellés, champ de force) reste en JS :
24
+ * une boucle par image recalcule l'angle sur la même horloge et le même
25
+ * modèle (`evaluateMotion`), d'où la même position que celle affichée.
26
+ * Les positions lues ailleurs passent par `getChildTranslation`, l'attribut
27
+ * `transform` n'étant plus à jour pendant le mouvement.
28
+ */
11
29
  export declare class ChildrenOrbitManager {
12
30
  private deps;
13
31
  private readonly orbitService;
14
32
  private cachedOrbitData;
15
- /** Temps de rampe (ms) courant pour l'accélération/décélération de la
16
- * boucle active — mémorisé pour que setSpeed() (vitesse changée en vol)
17
- * et la boucle elle-même s'y réfèrent sans avoir à le repasser partout. */
33
+ /** Temps de rampe (ms) courant pour l'accélération/décélération —
34
+ * mémorisé pour que setSpeed() (vitesse changée en vol) s'y réfère sans
35
+ * avoir à le repasser partout. */
18
36
  private rampMs;
19
- /** Vitesse angulaire instantanée (rad/ms, signée) — chasse la vitesse
20
- * cible (state.children.orbitSpeed, en rad/s) au rythme imposé par
21
- * rampMs. */
22
- private currentOmega;
23
- private lastTimestamp;
24
- /** Présent tant qu'un arrêt "retour à la position de base" est en cours :
25
- * l'orbite continue sa course pour s'arrêter exactement sur un multiple
26
- * de 2π (donc visuellement sur la position de base), plutôt que de couper
27
- * la vitesse puis sauter à angle 0. Même principe que AnimationsMngr :
28
- * `beginHomingStop` (mode "normal") décélère à taux constant, avec un tour
29
- * de plus si besoin de confort ; `beginFastHomingStop` (mode "Accéléré")
30
- * rejoint TOUJOURS le prochain passage par la position de base dans une
31
- * durée fixe choisie par l'utilisateur — voir `fastHomingStop.ts`. */
32
- private homeBrake?;
37
+ /** Mouvement en cours (vide à l'arrêt). Angles absolus, ajoutés à l'angle
38
+ * de base de chaque satellite. */
39
+ private motion;
40
+ /** Mouvement en cours = arrêt "retour à la position de base" : l'orbite
41
+ * continue sa course pour s'arrêter exactement sur un multiple de 2π,
42
+ * plutôt que de couper la vitesse puis sauter à angle 0. Même principe
43
+ * que AnimationsMngr : `beginHomingStop` (mode "normal") décélère à taux
44
+ * constant, avec un tour de plus si besoin de confort ;
45
+ * `beginFastHomingStop` (mode "Accéléré") rejoint TOUJOURS le prochain
46
+ * passage par la position de base dans une durée fixe choisie par
47
+ * l'utilisateur — voir `fastHomingStop.ts`. */
48
+ private homing;
49
+ /** Satellites et géométrie de la dernière pose (statique ou animée). */
50
+ private appliedOrbitData;
51
+ /** Angle de la dernière pose statique. */
52
+ private appliedAngle;
53
+ /** Animations posées, par enveloppe d'orbite. */
54
+ private tracks;
55
+ /** Satellites recréés pendant le mouvement : animations à reposer. */
56
+ private tracksStale;
33
57
  constructor(deps: ChildrenOrbitManagerDeps);
34
58
  invalidateCache(): void;
35
59
  buildOrbitData(): ChildrenOrbitEntry[];
60
+ /** Pose statique (orbite à l'arrêt ou au repos) et rendu complet. */
36
61
  applyTransforms(angleOffset: number, orbitData?: ChildrenOrbitEntry[]): void;
62
+ /** Translation affichée du satellite (repère du parent), y compris en
63
+ * plein mouvement : calculée à l'instant de l'image courante. */
64
+ getChildTranslation(controller: IYinYangController): {
65
+ x: number;
66
+ y: number;
67
+ };
68
+ private writeTranslations;
37
69
  setEnabled(isEnabled: boolean, rampMs?: number): void;
38
- /** Change la vitesse cible. Si une boucle est déjà active, elle relit
39
- * orbitSpeed à chaque frame et y converge au rythme de sa rampe en cours
40
- * (pas besoin de la redémarrer) — un changement de vitesse en vol est
41
- * donc lui aussi progressif plutôt que d'un coup. */
70
+ /** Change la vitesse cible : en vol, le mouvement repart de l'état
71
+ * courant et y converge au rythme de la rampe en cours — un changement
72
+ * de vitesse est donc lui aussi progressif plutôt que d'un coup. */
42
73
  setSpeed(speed: number): void;
43
74
  setRadiusScale(scale: number): void;
44
75
  /**
45
76
  * Démarre (ou modifie en vol) l'orbite. Avec `rampMs > 0`, la vitesse
46
- * angulaire part de sa valeur courante (0 si à l'arrêt) et chasse
47
- * progressivement `state.children.orbitSpeed` (relu à chaque frame — un
48
- * arrêt en cours de freinage repris ici ré-accélère en douceur depuis la
49
- * vitesse déjà atteinte). `rampMs` omis (0) → vitesse cible appliquée
77
+ * angulaire part de sa valeur courante (0 si à l'arrêt) et rejoint
78
+ * `state.children.orbitSpeed` à accélération constante — un arrêt en
79
+ * cours de freinage repris ici ré-accélère en douceur depuis la vitesse
80
+ * déjà atteinte. `rampMs` omis (0) → vitesse cible appliquée
50
81
  * instantanément, comportement historique.
51
82
  */
52
83
  start(_targetSpeed: number, rampMs?: number): void;
84
+ /** Fin de vie : coupe l'orbite sans rien écrire dans le DOM. */
85
+ destroy(): void;
53
86
  /**
54
87
  * Arrête l'orbite. Avec `rampMs > 0` et une orbite en cours, les satellites
55
88
  * continuent leur course et décélèrent à taux constant pour s'arrêter
@@ -68,6 +101,24 @@ export declare class ChildrenOrbitManager {
68
101
  private computeRemainingToZero;
69
102
  private beginHomingStop;
70
103
  private beginFastHomingStop;
104
+ /** Angle et vitesse à l'instant `now`, mouvement en cours ou non. */
105
+ private currentMotionState;
106
+ private play;
107
+ /**
108
+ * Image d'orbite en vol : les satellites sont déplacés par le navigateur ;
109
+ * ici, seulement ce qui les suit. Le temps de l'image (rAF) est celui de
110
+ * `document.timeline` : même angle que celui affiché.
111
+ */
112
+ private readonly onFrame;
113
+ /** (Re)pose une animation par tronçon sur l'enveloppe de chaque satellite. */
114
+ private syncTracks;
115
+ private cancelTracks;
116
+ private cancelFrameLoop;
117
+ /** Repos à `angle` : pose statique écrite AVANT de retirer les
118
+ * animations (même tâche, aucune image entre les deux). */
119
+ private settle;
71
120
  private finalizeStop;
121
+ /** Horloge des animations (temps de l'image courante). */
122
+ private now;
72
123
  }
73
124
  export {};
@@ -63,6 +63,8 @@ export declare class OddHighlightEffects {
63
63
  * rejouerait l'onde à chaque retour sur la sélection.
64
64
  */
65
65
  clear(keepOddMemory?: boolean): void;
66
+ /** Fin de vie : coupe la boucle et retire les couches. */
67
+ destroy(): void;
66
68
  private ensureLayer;
67
69
  private ensureLoop;
68
70
  private stopLoop;
@@ -47,8 +47,10 @@ export declare class OddViewManager {
47
47
  /** Satellite sélectionné (menu d'action ouvert) — il porte la même mise en
48
48
  * valeur que celle d'un ODD, mais resserrée sur lui seul. */
49
49
  private selectedChildKey;
50
- /** Aperçu transitoire au survol d'un item de la pile — prioritaire tant
51
- * qu'il dure, et sans effets de sélection. */
50
+ /** Satellite source d'un item de la pile — prioritaire tant qu'il dure.
51
+ * "soft" : aperçu au survol, sans effets de sélection. "full" : action en
52
+ * focus en STACK, même mise en lumière qu'un satellite sélectionné en
53
+ * RECHERCHE. */
52
54
  private stackPreviewKeys;
53
55
  /** Laquelle des deux sélections délibérées — un ODD, ou un satellite — est
54
56
  * la plus récente. Elles peuvent coexister (le menu d'un satellite reste
@@ -96,11 +98,13 @@ export declare class OddViewManager {
96
98
  * de visée + pings + onde de scan, et spikes énergisés avec leurs
97
99
  * comètes. */
98
100
  private syncFullHighlightEffects;
101
+ /** Fin de vie : coupe la boucle des effets de mise en valeur. */
102
+ destroy(): void;
99
103
  /** Relu à chaque frame par OddHighlightEffects : les satellites orbitent
100
104
  * sous les anneaux, et peuvent disparaître (satellites masqués, facette
101
105
  * changée) sans que la mise en valeur soit repassée. */
102
106
  private buildHighlightTargets;
103
- highlightOddByStackItemId(stackItemId: string | null): void;
107
+ highlightOddByStackItemId(stackItemId: string | null, intensity?: OddHighlightIntensity): void;
104
108
  cancelOddHighlight(): void;
105
109
  showOddInfo(oddId: string): void;
106
110
  showComposanteInfo(): void;
@@ -44,10 +44,24 @@ export declare const HALO_RING: Record<OddHighlightIntensity, {
44
44
  glowOpacity: number;
45
45
  }>;
46
46
  /** Satellite dont le menu d'action est ouvert : blanc pur et plus large, pour
47
- * ne pas se confondre avec un membre de l'ODD mis en valeur. */
48
- export declare const ACTIVE_CHILD_FILTER = "drop-shadow(0 0 12px rgba(255, 255, 255, 0.9)) brightness(1.1)";
47
+ * ne pas se confondre avec un membre de l'ODD mis en valeur. La lueur est
48
+ * l'anneau ACTIVE_CHILD_GLOW (voir setChildGlowRing), pas un drop-shadow :
49
+ * le satellite est en orbite, le flou serait recalculé à chaque image. */
50
+ export declare const ACTIVE_CHILD_FILTER = "brightness(1.1)";
49
51
  /** Survol direct d'un satellite — aperçu par-dessus tout le reste. */
50
- export declare const HOVERED_CHILD_FILTER = "brightness(1.3) drop-shadow(0 0 7px rgba(255,255,255,0.4))";
52
+ export declare const HOVERED_CHILD_FILTER = "brightness(1.3)";
53
+ /** Survol d'un satellite depuis l'arbre Recherche. */
54
+ export declare const SEARCH_HOVERED_CHILD_FILTER = "brightness(1.5)";
55
+ /** Lueur d'un satellite, équivalent de `drop-shadow(0 0 ${blur}px color)`
56
+ * (alpha compris dans `alpha`). */
57
+ export type ChildGlow = {
58
+ color: string;
59
+ blur: number;
60
+ alpha: number;
61
+ };
62
+ export declare const ACTIVE_CHILD_GLOW: readonly ChildGlow[];
63
+ export declare const HOVERED_CHILD_GLOW: readonly ChildGlow[];
64
+ export declare const SEARCH_HOVERED_CHILD_GLOW: readonly ChildGlow[];
51
65
  /** Aucun ODD mis en valeur et satellite ni actif ni survolé. */
52
66
  export declare const IDLE_CHILD_FILTER = "brightness(0.85)";
53
67
  /** Sans transition, l'extinction des non-membres se lit comme un
@@ -77,3 +91,31 @@ export declare function resolveChildFilter(params: {
77
91
  isPropagationTarget: boolean;
78
92
  highlight: ChildHighlightState;
79
93
  }): string;
94
+ /** Lueur d'état du satellite (actif), dans le même ordre de priorité que
95
+ * resolveChildFilter : seul le satellite actif hors mise en valeur d'ODD en
96
+ * a une — les membres ont leur anneau coloré (HALO_RING). */
97
+ export declare function resolveChildGlow(params: {
98
+ isMember: boolean;
99
+ isActiveChild: boolean;
100
+ highlight: ChildHighlightState;
101
+ }): readonly ChildGlow[] | null;
102
+ /**
103
+ * Pose (ou retire, `glows` null) l'anneau de lueur d'un satellite : des
104
+ * cercles concentriques translucides juste au-delà de son bord (voir
105
+ * glowHalo.glowStrokeLayers), dans son globalGroup — ils suivent donc son
106
+ * orbite sans aucun travail par image, là où un drop-shadow sur le groupe
107
+ * était recalculé à chaque déplacement.
108
+ */
109
+ export declare function setChildGlowRing(childController: {
110
+ view: {
111
+ viewInitializer: {
112
+ globalGroup: {
113
+ node: () => unknown;
114
+ };
115
+ positionX: number;
116
+ positionY: number;
117
+ borderOuterRadius: number;
118
+ borderInnerRadius: number;
119
+ };
120
+ };
121
+ }, glows: readonly ChildGlow[] | null): void;
@@ -83,9 +83,12 @@ type SearchPanelSynchronizerDeps = {
83
83
  x: number;
84
84
  y: number;
85
85
  } | null;
86
- /** Glisser guidé d'un prérequis : réaffiche dans le panneau STACK les
87
- * blocs de l'item de pile portant le combo. */
88
- showStackItemBlocksForDrag: (stackItemId: string) => void;
86
+ /** Affiche le combo source, ou l'action ciblée si le guide vient d'un événement. */
87
+ showStackItemBlocksForDrag: (stackItemId: string, action: {
88
+ actionId: string;
89
+ oddId: string;
90
+ cuttingIndex: number;
91
+ }) => void;
89
92
  /** Glisser guidé : aperçu en direct des cartes combo selon l'emplacement
90
93
  * survolé (restaure le contenu d'origine hors glisser guidé). */
91
94
  refreshGuidedComboPreview: () => void;
@@ -128,8 +131,8 @@ export declare class SearchPanelSynchronizer {
128
131
  * Cœur partagé du glisser-déposer vers la pile — entièrement générique
129
132
  * (ne connaît ni action ni Événement Clé), utilisé par startSearchActionDrag
130
133
  * (hiérarchie RECHERCHE), par ChildActionMenuController (bulle satellite du
131
- * diagramme) et par CoreEventMenuController (bulle Événement Clé du cercle
132
- * central) : chaque appelant fournit l'icône du fantôme de glisser et un
134
+ * diagramme) et par KeyEventMenuController (bulle Événement Clé d'un
135
+ * satellite-facette) : chaque appelant fournit l'icône du fantôme de glisser et un
133
136
  * `onDrop` qui sait construire l'item de pile approprié. Retourne `cleanup`
134
137
  * comme poignée d'annulation, pour permettre à un appelant de stopper
135
138
  * proprement un glisser en cours (ex. fermeture du menu radial en plein
@@ -8,7 +8,7 @@ type ControllerSettingsApplierDeps = {
8
8
  getOrbitData: () => ChildrenOrbitEntry[];
9
9
  updateContextLabels: (orbitData: ChildrenOrbitEntry[]) => void;
10
10
  updateChildActionMenu: (orbitData: ChildrenOrbitEntry[]) => void;
11
- updateCoreEventMenu: () => void;
11
+ updateKeyEventMenu: () => void;
12
12
  applyChildrenFitScale: () => void;
13
13
  clearForceFieldComputationState: () => void;
14
14
  renderOppositeChildrenForceField: () => void;
@@ -35,10 +35,10 @@ export declare class ControllerSettingsApplier {
35
35
  setOddLabelsCompact(compact: boolean): void;
36
36
  setChildActionMenuItemDistance(distance: number): void;
37
37
  setChildActionMenuItemScale(scale: number): void;
38
- setCoreEventMenuDistanceOffset(offset: number): void;
39
- setCoreEventMenuItemScale(scale: number): void;
38
+ setKeyEventMenuDistanceOffset(offset: number): void;
39
+ setKeyEventMenuItemScale(scale: number): void;
40
40
  setChildActionIconFontScale(scale: number): void;
41
- setCoreEventIconFontScale(scale: number): void;
41
+ setKeyEventIconFontScale(scale: number): void;
42
42
  setChildLabelMaxLines(lines: number): void;
43
43
  setOddLabelMaxLines(lines: number): void;
44
44
  setFacetteLabelFontScale(scale: number): void;
@@ -94,9 +94,9 @@ export declare class ControllerSession {
94
94
  cuttingIndex: number;
95
95
  forceOpen: boolean;
96
96
  } | null;
97
- /** Menu cœur à déployer à l'arrivée sur la facette (voir searchSetKeyEventMenuOpen). */
98
- pendingKeyEventMenuAfterSwitch: boolean;
99
- isCoreEventMenuOpen: boolean;
97
+ /** Facette dont le satellite-facette (Idle « facettes ») a ses bulles
98
+ * d'Événements Clés déployées, ou null. */
99
+ keyEventMenuFacetteId: string | null;
100
100
  /** Id de l'Événement Clé actuellement en aperçu (carte affichée), ou null. */
101
101
  activeKeyEventId: string | null;
102
102
  /** Quand vrai, le prochain appel à onShowDirectActionBlock est routé vers le panneau B. */
@@ -46,6 +46,16 @@ export type ControllerUiCallbacks = {
46
46
  * or when an ODD-level interaction deselects it — componentIndex lets the listener
47
47
  * restore its detail panel to the facette view rather than clearing it entirely. */
48
48
  onDiagramSatelliteDeselect?: (componentIndex: number) => void;
49
+ /** Vrai si au moins un panneau RECHERCHE est verrouillé (multi-blocs) : seul
50
+ * ce cas garde l'action active quand on sélectionne un autre satellite, pour
51
+ * en consulter la propagation dans le panneau suivant. */
52
+ isAnyRecherchePanelLocked?: () => boolean;
53
+ /** Vrai si un panneau RECHERCHE est verrouillé sur une action : elle reste
54
+ * l'action source du multi-blocs, aucune autre ne se sélectionne. */
55
+ isActionSelectionLocked?: () => boolean;
56
+ /** Clic sur une action alors que la sélection est verrouillée : `retry`
57
+ * rejoue ce clic une fois le panneau déverrouillé. */
58
+ onActionSelectionBlocked?: (retry: () => void) => void;
49
59
  /** Fired when the user clicks the current composante's border arc to hide its satellites. */
50
60
  onDiagramComposanteDeselect?: () => void;
51
61
  /** Vers le panneau Recherche quand la souris entre/sort d'un satellite dans le diagramme. */