@formicoidea/labre-framework-cynefin 0.32.0 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions.js +8 -0
- package/dist/commands-manifest.d.ts +18 -0
- package/dist/commands-manifest.js +42 -0
- package/dist/cynefin/consts.js +49 -13
- package/dist/cynefin/element-renderer.js +4 -1
- package/dist/cynefin/toolbar/config.d.ts +5 -1
- package/dist/cynefin/toolbar/config.js +57 -7
- package/dist/estuarine/consts.d.ts +10 -3
- package/dist/estuarine/consts.js +41 -8
- package/dist/estuarine/element-renderer.d.ts +108 -2
- package/dist/estuarine/element-renderer.js +146 -43
- package/dist/estuarine/ghost-overlay.d.ts +134 -0
- package/dist/estuarine/ghost-overlay.js +277 -0
- package/dist/estuarine/nudges.d.ts +41 -0
- package/dist/estuarine/nudges.js +69 -0
- package/dist/estuarine/roles.d.ts +48 -0
- package/dist/estuarine/roles.js +28 -0
- package/dist/estuarine/toolbar/config.d.ts +6 -1
- package/dist/estuarine/toolbar/config.js +67 -8
- package/dist/templates/index.js +18 -2
- package/dist/toolbar/senior-button.js +4 -1
- package/dist/toolbar/senior-tool.js +1 -0
- package/dist/translations.d.ts +5 -0
- package/dist/translations.js +15 -2
- package/dist/view.js +49 -1
- package/package.json +7 -2
package/dist/actions.js
CHANGED
|
@@ -4,6 +4,7 @@ import { Bound } from '@formicoidea/labre-core/global/gfx';
|
|
|
4
4
|
import { GfxControllerIdentifier } from '@formicoidea/labre-core/std/gfx';
|
|
5
5
|
import { REF_H as CYN_H, REF_W as CYN_W } from './cynefin/consts.js';
|
|
6
6
|
import { HEX_FILL, HEX_SIZE, HEX_STROKE, HEX_VERTICES, REF_H as EST_H, REF_W as EST_W, } from './estuarine/consts.js';
|
|
7
|
+
import { ESTUARINE_ROLE } from './estuarine/roles.js';
|
|
7
8
|
/**
|
|
8
9
|
* Creation actions for the Cynefin / Estuarine toolbox — lifted out of
|
|
9
10
|
* `toolbar/menu.ts` by PF3. This is also the framework that emitted NO
|
|
@@ -38,6 +39,10 @@ export function createEstuarineMap(std) {
|
|
|
38
39
|
const { centerX, centerY } = gfx.viewport;
|
|
39
40
|
const id = gfx.surface.addElement({
|
|
40
41
|
type: 'estuarine',
|
|
42
|
+
// The map is this framework's ROOT INSTANCE: the role is what makes the
|
|
43
|
+
// Map quality checklist reachable on it (WS4). Cynefin's background gets
|
|
44
|
+
// none, on purpose — see `estuarine/roles.ts`.
|
|
45
|
+
role: ESTUARINE_ROLE.map,
|
|
41
46
|
xywh: new Bound(centerX - width / 2, centerY - height / 2, width, height).serialize(),
|
|
42
47
|
});
|
|
43
48
|
finish(gfx, id);
|
|
@@ -49,6 +54,9 @@ export function createConstraintHexagon(std) {
|
|
|
49
54
|
const { centerX: cx, centerY: cy } = gfx.viewport;
|
|
50
55
|
const id = gfx.surface.addElement({
|
|
51
56
|
type: 'shape',
|
|
57
|
+
// A hexagon is a plain polygon on the canvas: nothing about its geometry
|
|
58
|
+
// says "constraint". The role is the only place that does.
|
|
59
|
+
role: ESTUARINE_ROLE.constraint,
|
|
52
60
|
shapeType: 'polygon',
|
|
53
61
|
vertices: HEX_VERTICES,
|
|
54
62
|
filled: true,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ShortcutManifestEntry } from '@formicoidea/labre-core/std';
|
|
2
|
+
/**
|
|
3
|
+
* The Cynefin / Estuarine commands as SHORTCUT-MANIFEST rows — id, label, chord, scope,
|
|
4
|
+
* owner — and nothing else.
|
|
5
|
+
*
|
|
6
|
+
* DATA ONLY, and that is the whole point (`docs/adr/0008` § Packaging). A
|
|
7
|
+
* `CommandDescriptor` carries its `run`, so a host settings pane that imports
|
|
8
|
+
* the package entry to list names and chords drags the entire action graph —
|
|
9
|
+
* the import/export machinery, the surface and gfx deep paths — into its
|
|
10
|
+
* chunk. This module has type-only imports, so the published bundle exposes it
|
|
11
|
+
* as `./commands-manifest`: a few hundred bytes that reference nothing.
|
|
12
|
+
*
|
|
13
|
+
* GENERATED-SHAPED, hand-committed: `commands-manifest.unit.spec.ts` asserts
|
|
14
|
+
* row-for-row equality with `toShortcutManifestEntry` over {@link cynefinEstuarineCommands},
|
|
15
|
+
* so this file cannot drift from the commands it projects. Add a command and
|
|
16
|
+
* the test says exactly what to add here.
|
|
17
|
+
*/
|
|
18
|
+
export declare const cynefinEstuarineCommandsManifest: ShortcutManifestEntry[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Cynefin / Estuarine commands as SHORTCUT-MANIFEST rows — id, label, chord, scope,
|
|
3
|
+
* owner — and nothing else.
|
|
4
|
+
*
|
|
5
|
+
* DATA ONLY, and that is the whole point (`docs/adr/0008` § Packaging). A
|
|
6
|
+
* `CommandDescriptor` carries its `run`, so a host settings pane that imports
|
|
7
|
+
* the package entry to list names and chords drags the entire action graph —
|
|
8
|
+
* the import/export machinery, the surface and gfx deep paths — into its
|
|
9
|
+
* chunk. This module has type-only imports, so the published bundle exposes it
|
|
10
|
+
* as `./commands-manifest`: a few hundred bytes that reference nothing.
|
|
11
|
+
*
|
|
12
|
+
* GENERATED-SHAPED, hand-committed: `commands-manifest.unit.spec.ts` asserts
|
|
13
|
+
* row-for-row equality with `toShortcutManifestEntry` over {@link cynefinEstuarineCommands},
|
|
14
|
+
* so this file cannot drift from the commands it projects. Add a command and
|
|
15
|
+
* the test says exactly what to add here.
|
|
16
|
+
*/
|
|
17
|
+
export const cynefinEstuarineCommandsManifest = [
|
|
18
|
+
{
|
|
19
|
+
id: 'cynefin-estuarine.addCynefin',
|
|
20
|
+
owner: 'cynefin-estuarine',
|
|
21
|
+
labelKey: 'com.labre.commands.cynefin-estuarine.addCynefin',
|
|
22
|
+
labelFallback: 'Cynefin framework',
|
|
23
|
+
scope: 'edgeless',
|
|
24
|
+
defaultKeys: { mac: [], other: [] },
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'cynefin-estuarine.addEstuarineMap',
|
|
28
|
+
owner: 'cynefin-estuarine',
|
|
29
|
+
labelKey: 'com.labre.commands.cynefin-estuarine.addEstuarineMap',
|
|
30
|
+
labelFallback: 'Estuarine map',
|
|
31
|
+
scope: 'edgeless',
|
|
32
|
+
defaultKeys: { mac: [], other: [] },
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'cynefin-estuarine.addConstraintHexagon',
|
|
36
|
+
owner: 'cynefin-estuarine',
|
|
37
|
+
labelKey: 'com.labre.commands.cynefin-estuarine.addConstraintHexagon',
|
|
38
|
+
labelFallback: 'Hexagon node',
|
|
39
|
+
scope: 'edgeless',
|
|
40
|
+
defaultKeys: { mac: [], other: [] },
|
|
41
|
+
},
|
|
42
|
+
];
|
package/dist/cynefin/consts.js
CHANGED
|
@@ -19,7 +19,11 @@ export const COLORS = {
|
|
|
19
19
|
*/
|
|
20
20
|
export const DARK_BACK_PATHS = [
|
|
21
21
|
// Main arc: top segment (Complex|Complicated) then left segment (Complex|Chaotic)
|
|
22
|
-
[
|
|
22
|
+
[
|
|
23
|
+
'M 550.1 17 A 296 296 0 0 1 338 328.5 A 448.7 448.7 0 0 1 26 331',
|
|
24
|
+
15.5,
|
|
25
|
+
false,
|
|
26
|
+
],
|
|
23
27
|
// Thin "Confusion" arc sweeping down towards the cliff
|
|
24
28
|
['M 649 294 C 644 382, 588 462, 440 506', 5, false],
|
|
25
29
|
];
|
|
@@ -34,7 +38,11 @@ export const DARK_FRONT_PATHS = [
|
|
|
34
38
|
// Thick descending branch with the bottom elbow (right edge of the cliff)
|
|
35
39
|
['M 340 332 C 390 440, 437 525, 472 632 Q 479 658, 453 700', 15.5, true],
|
|
36
40
|
// Thin left line (left edge of the cliff)
|
|
37
|
-
[
|
|
41
|
+
[
|
|
42
|
+
'M 345 356 C 372 440, 408 540, 413 655 C 414 685, 412 710, 412 738',
|
|
43
|
+
4,
|
|
44
|
+
false,
|
|
45
|
+
],
|
|
38
46
|
];
|
|
39
47
|
/** Cliff hatching: [x1,y1,x2,y2], lineWidth 3. */
|
|
40
48
|
export const HATCHES = [
|
|
@@ -51,14 +59,30 @@ export const HATCHES = [
|
|
|
51
59
|
];
|
|
52
60
|
/** Dashed Complicated↔Clear boundary, as oriented square pavings: [x,y,size,rotateDeg]. */
|
|
53
61
|
export const DASH_RECTS = [
|
|
54
|
-
[511, 245, 13.8, 206.8],
|
|
55
|
-
[
|
|
56
|
-
[
|
|
57
|
-
[
|
|
58
|
-
[
|
|
59
|
-
[
|
|
60
|
-
[
|
|
61
|
-
[
|
|
62
|
+
[511, 245, 13.8, 206.8],
|
|
63
|
+
[530, 255.5, 13.7, 205.2],
|
|
64
|
+
[549.5, 265.5, 13.6, 203.5],
|
|
65
|
+
[569.5, 274.5, 13.5, 201.9],
|
|
66
|
+
[590, 282.5, 13.5, 200.2],
|
|
67
|
+
[610.5, 289.5, 13.4, 198.6],
|
|
68
|
+
[631, 296, 13.3, 196.9],
|
|
69
|
+
[673.5, 307, 13.2, 193.6],
|
|
70
|
+
[695, 311.5, 13.1, 192.0],
|
|
71
|
+
[716, 315.5, 13.0, 190.3],
|
|
72
|
+
[738, 319, 12.9, 188.7],
|
|
73
|
+
[759.5, 322, 12.8, 187.0],
|
|
74
|
+
[781, 324.5, 12.8, 185.4],
|
|
75
|
+
[803, 325.5, 12.7, 183.7],
|
|
76
|
+
[824.5, 326.5, 12.6, 182.1],
|
|
77
|
+
[846, 327.5, 12.5, 180.5],
|
|
78
|
+
[868, 327.5, 12.4, 178.8],
|
|
79
|
+
[889.5, 326.5, 12.3, 177.2],
|
|
80
|
+
[912, 325.5, 12.2, 175.5],
|
|
81
|
+
[933, 323.5, 12.1, 173.9],
|
|
82
|
+
[954.5, 321.5, 12.1, 172.2],
|
|
83
|
+
[976, 318, 12.0, 170.6],
|
|
84
|
+
[998, 314, 11.9, 168.9],
|
|
85
|
+
[1019, 310, 11.8, 167.3],
|
|
62
86
|
];
|
|
63
87
|
export const DOMAINS = [
|
|
64
88
|
{
|
|
@@ -82,7 +106,11 @@ export const DOMAINS = [
|
|
|
82
106
|
lines: [
|
|
83
107
|
{ lead: 'Sense', rest: ' the context with analytical methods', y: 71 },
|
|
84
108
|
{ lead: 'Analyse', rest: ' observations', y: 90 },
|
|
85
|
-
{
|
|
109
|
+
{
|
|
110
|
+
lead: 'Respond',
|
|
111
|
+
rest: ' by applying one of many good solutions',
|
|
112
|
+
y: 109,
|
|
113
|
+
},
|
|
86
114
|
],
|
|
87
115
|
},
|
|
88
116
|
{
|
|
@@ -92,7 +120,11 @@ export const DOMAINS = [
|
|
|
92
120
|
subheading: 'Un-ordered system',
|
|
93
121
|
sy: 609,
|
|
94
122
|
lines: [
|
|
95
|
-
{
|
|
123
|
+
{
|
|
124
|
+
lead: 'Act',
|
|
125
|
+
rest: ' on the context to stabilize (it or yourself)',
|
|
126
|
+
y: 627,
|
|
127
|
+
},
|
|
96
128
|
{ lead: 'Sense', rest: ' how the context reacts', y: 646 },
|
|
97
129
|
{ lead: 'Respond', rest: ' by re-acting', y: 665 },
|
|
98
130
|
],
|
|
@@ -106,7 +138,11 @@ export const DOMAINS = [
|
|
|
106
138
|
lines: [
|
|
107
139
|
{ lead: 'Sense', rest: ' the context with analytical methods', y: 627 },
|
|
108
140
|
{ lead: 'Categorize', rest: ' observations', y: 646 },
|
|
109
|
-
{
|
|
141
|
+
{
|
|
142
|
+
lead: 'Respond',
|
|
143
|
+
rest: ' by applying tried and true practices',
|
|
144
|
+
y: 665,
|
|
145
|
+
},
|
|
110
146
|
],
|
|
111
147
|
},
|
|
112
148
|
];
|
|
@@ -13,7 +13,10 @@ export const cynefin = (model, ctx, matrix) => {
|
|
|
13
13
|
const [, , w, h] = model.deserializedXYWH;
|
|
14
14
|
const cx = w / 2;
|
|
15
15
|
const cy = h / 2;
|
|
16
|
-
ctx.setTransform(matrix
|
|
16
|
+
ctx.setTransform(matrix
|
|
17
|
+
.translateSelf(cx, cy)
|
|
18
|
+
.rotateSelf(model.rotate)
|
|
19
|
+
.translateSelf(-cx, -cy));
|
|
17
20
|
const { s, ox, oy } = refScale(w, h, REF_W, REF_H);
|
|
18
21
|
ctx.translate(ox, oy);
|
|
19
22
|
ctx.scale(s, s);
|
|
@@ -1,27 +1,31 @@
|
|
|
1
|
-
import { type ToolbarContext } from '@formicoidea/labre-core/shared/services';
|
|
1
|
+
import { type ChromeWording, type ToolbarContext } from '@formicoidea/labre-core/shared/services';
|
|
2
2
|
import { type TemplateResult } from 'lit';
|
|
3
3
|
export declare const cynefinToolbarConfig: {
|
|
4
4
|
readonly actions: [{
|
|
5
5
|
id: string;
|
|
6
6
|
tooltip: string;
|
|
7
|
+
tooltipWording: ChromeWording | undefined;
|
|
7
8
|
icon: TemplateResult;
|
|
8
9
|
active(ctx: ToolbarContext): boolean;
|
|
9
10
|
run(ctx: ToolbarContext): void;
|
|
10
11
|
}, {
|
|
11
12
|
id: string;
|
|
12
13
|
tooltip: string;
|
|
14
|
+
tooltipWording: ChromeWording | undefined;
|
|
13
15
|
icon: TemplateResult;
|
|
14
16
|
active(ctx: ToolbarContext): boolean;
|
|
15
17
|
run(ctx: ToolbarContext): void;
|
|
16
18
|
}, {
|
|
17
19
|
id: string;
|
|
18
20
|
tooltip: string;
|
|
21
|
+
tooltipWording: ChromeWording | undefined;
|
|
19
22
|
icon: TemplateResult;
|
|
20
23
|
active(ctx: ToolbarContext): boolean;
|
|
21
24
|
run(ctx: ToolbarContext): void;
|
|
22
25
|
}, {
|
|
23
26
|
id: string;
|
|
24
27
|
tooltip: string;
|
|
28
|
+
tooltipWording: ChromeWording | undefined;
|
|
25
29
|
icon: TemplateResult;
|
|
26
30
|
active(ctx: ToolbarContext): boolean;
|
|
27
31
|
run(ctx: ToolbarContext): void;
|
|
@@ -1,16 +1,66 @@
|
|
|
1
1
|
import { EdgelessCRUDIdentifier } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import { CynefinElementModel } from '@formicoidea/labre-core/model';
|
|
3
|
-
import { ToolbarModuleExtension, } from '@formicoidea/labre-core/shared/services';
|
|
3
|
+
import { BOARD_RESIZE_TOGGLE, ToolbarModuleExtension, } from '@formicoidea/labre-core/shared/services';
|
|
4
4
|
import { BlockFlavourIdentifier } from '@formicoidea/labre-core/std';
|
|
5
5
|
import { html } from 'lit';
|
|
6
|
-
const ResizeIcon = html `<svg
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const ResizeIcon = html `<svg
|
|
7
|
+
width="24"
|
|
8
|
+
height="24"
|
|
9
|
+
viewBox="0 0 24 24"
|
|
10
|
+
fill="none"
|
|
11
|
+
stroke="currentColor"
|
|
12
|
+
stroke-width="1.6"
|
|
13
|
+
stroke-linecap="round"
|
|
14
|
+
stroke-linejoin="round"
|
|
15
|
+
>
|
|
16
|
+
<path d="M9 5H5v4M15 19h4v-4" />
|
|
17
|
+
<path d="M5 5l6 6M19 19l-6-6" />
|
|
18
|
+
</svg>`;
|
|
19
|
+
const TitlesIcon = html `<svg
|
|
20
|
+
width="24"
|
|
21
|
+
height="24"
|
|
22
|
+
viewBox="0 0 24 24"
|
|
23
|
+
fill="none"
|
|
24
|
+
stroke="currentColor"
|
|
25
|
+
stroke-width="1.6"
|
|
26
|
+
stroke-linecap="round"
|
|
27
|
+
stroke-linejoin="round"
|
|
28
|
+
>
|
|
29
|
+
<path d="M5 7h14M9 7v11" />
|
|
30
|
+
</svg>`;
|
|
31
|
+
const DescIcon = html `<svg
|
|
32
|
+
width="24"
|
|
33
|
+
height="24"
|
|
34
|
+
viewBox="0 0 24 24"
|
|
35
|
+
fill="none"
|
|
36
|
+
stroke="currentColor"
|
|
37
|
+
stroke-width="1.6"
|
|
38
|
+
stroke-linecap="round"
|
|
39
|
+
stroke-linejoin="round"
|
|
40
|
+
>
|
|
41
|
+
<path d="M5 8h14M5 12h14M5 16h9" />
|
|
42
|
+
</svg>`;
|
|
43
|
+
const LiminalIcon = html `<svg
|
|
44
|
+
width="24"
|
|
45
|
+
height="24"
|
|
46
|
+
viewBox="0 0 24 24"
|
|
47
|
+
fill="none"
|
|
48
|
+
stroke="currentColor"
|
|
49
|
+
stroke-width="1.6"
|
|
50
|
+
stroke-linecap="round"
|
|
51
|
+
stroke-linejoin="round"
|
|
52
|
+
>
|
|
53
|
+
<path d="M5 17 C9 6 15 6 19 7" />
|
|
54
|
+
</svg>`;
|
|
10
55
|
function booleanToggle(id, tooltip, icon, prop) {
|
|
11
56
|
return {
|
|
12
57
|
id,
|
|
13
|
-
tooltip,
|
|
58
|
+
tooltip: typeof tooltip === 'string' ? tooltip : tooltip[1],
|
|
59
|
+
// The declared wording, when the caller gave one instead of a literal:
|
|
60
|
+
// `combine` resolves it against the host's catalogue and writes it over
|
|
61
|
+
// the English default above, so a playground with no catalogue reads
|
|
62
|
+
// exactly what it read before (#183).
|
|
63
|
+
tooltipWording: typeof tooltip === 'string' ? undefined : tooltip,
|
|
14
64
|
icon,
|
|
15
65
|
active(ctx) {
|
|
16
66
|
const models = ctx.getSurfaceModelsByType(CynefinElementModel);
|
|
@@ -30,7 +80,7 @@ function booleanToggle(id, tooltip, icon, prop) {
|
|
|
30
80
|
}
|
|
31
81
|
export const cynefinToolbarConfig = {
|
|
32
82
|
actions: [
|
|
33
|
-
booleanToggle('a.toggle-resize',
|
|
83
|
+
booleanToggle('a.toggle-resize', BOARD_RESIZE_TOGGLE, ResizeIcon, 'resizeEnabled'),
|
|
34
84
|
booleanToggle('b.toggle-titles', 'Show / hide titles', TitlesIcon, 'showTitles'),
|
|
35
85
|
booleanToggle('c.toggle-descriptions', 'Show / hide explanatory text', DescIcon, 'showDescriptions'),
|
|
36
86
|
booleanToggle('d.toggle-liminal', 'Show / hide liminal line', LiminalIcon, 'showLiminalLine'),
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Visual constants for the Estuarine framework map, reproduced from the official
|
|
3
3
|
* SVG (viewBox 0 0 690 801). All geometry is authored in that fixed reference
|
|
4
|
-
* space
|
|
5
|
-
*
|
|
4
|
+
* space; the renderer reads every coordinate below as a RATIO of it and maps it
|
|
5
|
+
* onto the element's real width and height independently, so a stretched map
|
|
6
|
+
* gets a longer time axis and a taller energy axis rather than the same drawing
|
|
7
|
+
* letterboxed (see `EstuarineFit` in `./element-renderer.ts`). The e axis is
|
|
8
|
+
* vertical & double-headed (energy), the t axis horizontal & single-headed
|
|
6
9
|
* (time only flows one way).
|
|
7
10
|
*/
|
|
8
11
|
export declare const REF_W = 690;
|
|
@@ -33,7 +36,11 @@ export declare const T_AXIS: {
|
|
|
33
36
|
};
|
|
34
37
|
export declare const AXIS_WIDTH = 8;
|
|
35
38
|
/** Filled arrowhead triangles: [[tipX,tipY],[baseAX,baseAY],[baseBX,baseBY]]. */
|
|
36
|
-
export declare const ARROWHEADS: ReadonlyArray<readonly [
|
|
39
|
+
export declare const ARROWHEADS: ReadonlyArray<readonly [
|
|
40
|
+
readonly [number, number],
|
|
41
|
+
readonly [number, number],
|
|
42
|
+
readonly [number, number]
|
|
43
|
+
]>;
|
|
37
44
|
/** Liminal: green boundary rising gently then dipping at the right end. */
|
|
38
45
|
export declare const LIMINAL_PATH = "M 63 193 C 67 192, 78 189, 85 188 C 92 187, 100 186, 107 185 C 114 184, 122 183, 129 183 C 136 183, 144 183, 151 183 C 158 183, 166 183, 173 183 C 180 183, 188 184, 195 185 C 202 186, 210 188, 217 189 C 224 190, 232 192, 239 194 C 246 196, 254 198, 261 201 C 268 204, 276 207, 283 210 C 290 213, 298 217, 305 220 C 312 223, 320 226, 327 230 C 334 234, 342 238, 349 242 C 356 246, 364 250, 371 255 C 378 260, 386 264, 393 269 C 400 274, 408 278, 415 283 C 422 288, 430 292, 437 297 C 444 302, 451 306, 458 310 C 465 314, 473 319, 480 323 C 487 327, 495 332, 502 335 C 509 338, 517 341, 524 343 C 531 345, 539 348, 546 349 C 553 350, 561 350, 568 350 C 575 350, 583 348, 590 346 C 597 344, 605 340, 612 336 C 619 332, 626 325, 633 319 C 640 313, 648 302, 651 298 C 654 294, 654 295, 654 294";
|
|
39
46
|
export declare const LIMINAL_WIDTH = 4.5;
|
package/dist/estuarine/consts.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Visual constants for the Estuarine framework map, reproduced from the official
|
|
3
3
|
* SVG (viewBox 0 0 690 801). All geometry is authored in that fixed reference
|
|
4
|
-
* space
|
|
5
|
-
*
|
|
4
|
+
* space; the renderer reads every coordinate below as a RATIO of it and maps it
|
|
5
|
+
* onto the element's real width and height independently, so a stretched map
|
|
6
|
+
* gets a longer time axis and a taller energy axis rather than the same drawing
|
|
7
|
+
* letterboxed (see `EstuarineFit` in `./element-renderer.ts`). The e axis is
|
|
8
|
+
* vertical & double-headed (energy), the t axis horizontal & single-headed
|
|
6
9
|
* (time only flows one way).
|
|
7
10
|
*/
|
|
8
11
|
export const REF_W = 690;
|
|
@@ -26,9 +29,21 @@ export const T_AXIS = { y: 649, x1: 28, x2: 616 };
|
|
|
26
29
|
export const AXIS_WIDTH = 8;
|
|
27
30
|
/** Filled arrowhead triangles: [[tipX,tipY],[baseAX,baseAY],[baseBX,baseBY]]. */
|
|
28
31
|
export const ARROWHEADS = [
|
|
29
|
-
[
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
[
|
|
33
|
+
[43.5, 72],
|
|
34
|
+
[30, 100],
|
|
35
|
+
[57, 100],
|
|
36
|
+
], // e — top
|
|
37
|
+
[
|
|
38
|
+
[43.5, 785],
|
|
39
|
+
[30, 758],
|
|
40
|
+
[57, 758],
|
|
41
|
+
], // e — bottom
|
|
42
|
+
[
|
|
43
|
+
[643, 649],
|
|
44
|
+
[613, 636],
|
|
45
|
+
[613, 662],
|
|
46
|
+
], // t — right
|
|
32
47
|
];
|
|
33
48
|
/** Liminal: green boundary rising gently then dipping at the right end. */
|
|
34
49
|
export const LIMINAL_PATH = 'M 63 193 C 67 192, 78 189, 85 188 C 92 187, 100 186, 107 185 C 114 184, 122 183, 129 183 C 136 183, 144 183, 151 183 C 158 183, 166 183, 173 183 C 180 183, 188 184, 195 185 C 202 186, 210 188, 217 189 C 224 190, 232 192, 239 194 C 246 196, 254 198, 261 201 C 268 204, 276 207, 283 210 C 290 213, 298 217, 305 220 C 312 223, 320 226, 327 230 C 334 234, 342 238, 349 242 C 356 246, 364 250, 371 255 C 378 260, 386 264, 393 269 C 400 274, 408 278, 415 283 C 422 288, 430 292, 437 297 C 444 302, 451 306, 458 310 C 465 314, 473 319, 480 323 C 487 327, 495 332, 502 335 C 509 338, 517 341, 524 343 C 531 345, 539 348, 546 349 C 553 350, 561 350, 568 350 C 575 350, 583 348, 590 346 C 597 344, 605 340, 612 336 C 619 332, 626 325, 633 319 C 640 313, 648 302, 651 298 C 654 294, 654 295, 654 294';
|
|
@@ -41,9 +56,27 @@ export const VOLATILE_PATH = 'M 58 446 C 61 447, 70 451, 76 454 C 82 457, 88 462
|
|
|
41
56
|
export const VOLATILE_WIDTH = 5;
|
|
42
57
|
/** Uppercase legends: anchored centre, alphabetic baseline, with letter-spacing. */
|
|
43
58
|
export const LABELS = {
|
|
44
|
-
counterfactual: {
|
|
45
|
-
|
|
46
|
-
|
|
59
|
+
counterfactual: {
|
|
60
|
+
text: 'COUNTER FACTUAL',
|
|
61
|
+
x: 422,
|
|
62
|
+
y: 25,
|
|
63
|
+
size: 20,
|
|
64
|
+
color: COLORS.label,
|
|
65
|
+
},
|
|
66
|
+
liminal: {
|
|
67
|
+
text: 'LIMINAL',
|
|
68
|
+
x: 316,
|
|
69
|
+
y: 192,
|
|
70
|
+
size: 18,
|
|
71
|
+
color: COLORS.liminalLabel,
|
|
72
|
+
},
|
|
73
|
+
volatile: {
|
|
74
|
+
text: 'VOLATILE',
|
|
75
|
+
x: 219,
|
|
76
|
+
y: 783,
|
|
77
|
+
size: 20,
|
|
78
|
+
color: COLORS.volatile,
|
|
79
|
+
},
|
|
47
80
|
};
|
|
48
81
|
/** Italic Georgia axis letters (left-anchored, alphabetic baseline). */
|
|
49
82
|
export const AXIS_LABELS = {
|
|
@@ -1,11 +1,117 @@
|
|
|
1
1
|
import { type ElementRenderer } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import type { EstuarineElementModel } from '@formicoidea/labre-core/model';
|
|
3
|
+
/**
|
|
4
|
+
* The three reference curves are drawn as a permanent GHOST (PO arbitration,
|
|
5
|
+
* 26/08/2026): dashed, translucent, never solid again.
|
|
6
|
+
*
|
|
7
|
+
* The reasoning is what an Estuarine line IS. Liminal, Volatile and
|
|
8
|
+
* Counter-factual are not measurements — they are boundaries a group argues
|
|
9
|
+
* itself into, and the printed map is a support for that argument, not a
|
|
10
|
+
* verdict about where the boundary lies. A solid stroke made the tool's own
|
|
11
|
+
* curve look like the answer, and the group's negotiated line (drawn on top,
|
|
12
|
+
* with a brush or a connector) look like an annotation on it. Dashing the
|
|
13
|
+
* reference inverts that: the tool suggests, the group states.
|
|
14
|
+
*
|
|
15
|
+
* The toggles keep their meaning exactly — ON shows the ghost, OFF hides it.
|
|
16
|
+
* What changed is only how ON looks, plus the ~600 ms reveal animation the
|
|
17
|
+
* moment a toggle flips (see `./ghost-overlay.ts`), which exists so a line
|
|
18
|
+
* that comes back at 45 % opacity is still SEEN arriving.
|
|
19
|
+
*
|
|
20
|
+
* The legends stay solid. A label is a name, not a boundary.
|
|
21
|
+
*/
|
|
22
|
+
/** Dash pattern of the ghost, in reference-space units. */
|
|
23
|
+
export declare const GHOST_DASH: readonly number[];
|
|
24
|
+
/** Opacity of the permanent ghost. */
|
|
25
|
+
export declare const GHOST_ALPHA = 0.45;
|
|
26
|
+
/** Which `EstuarineElementModel` flag shows a given curve. */
|
|
27
|
+
export type EstuarineCurveVisibility = 'showLiminal' | 'showVolatile' | 'showCounterfactual';
|
|
28
|
+
export interface EstuarineCurve {
|
|
29
|
+
key: 'liminal' | 'volatile' | 'counterfactual';
|
|
30
|
+
path: Path2D;
|
|
31
|
+
color: string;
|
|
32
|
+
width: number;
|
|
33
|
+
visibleProp: EstuarineCurveVisibility;
|
|
34
|
+
}
|
|
35
|
+
export declare function estuarineCurves(): readonly EstuarineCurve[];
|
|
36
|
+
/**
|
|
37
|
+
* How the fixed 690 × 801 reference design maps onto an element of `w × h`.
|
|
38
|
+
*
|
|
39
|
+
* ## Why an Estuarine map STRETCHES (PO recette, 26/08/2026)
|
|
40
|
+
*
|
|
41
|
+
* It used to be fitted uniformly and letterboxed (`refScale`), so widening the
|
|
42
|
+
* background left the drawing at its authored proportions, centred, with short
|
|
43
|
+
* axes floating in empty margins. That is wrong for THIS frame, and the reason
|
|
44
|
+
* is what an Estuarine map is: a coordinate system. The e axis measures energy
|
|
45
|
+
* to change, the t axis measures time, and the three curves are the boundaries
|
|
46
|
+
* a group negotiates ACROSS that plane. Give the user more room and they mean
|
|
47
|
+
* "more plane" — a longer time axis, a taller energy axis — not "the same
|
|
48
|
+
* picture, bigger". So both directions follow the element independently.
|
|
49
|
+
*
|
|
50
|
+
* **Cynefin, right next door, deliberately keeps the uniform letterbox**: its
|
|
51
|
+
* background is a figurative drawing — a cliff, hand-drawn arcs, a hatched
|
|
52
|
+
* fall — and a figurative drawing has proportions that stretching would simply
|
|
53
|
+
* damage. Two frames, two answers, and the difference is not an oversight.
|
|
54
|
+
*
|
|
55
|
+
* ## The two factors
|
|
56
|
+
*
|
|
57
|
+
* `sx` / `sy` stretch positions and paths. `strokeScale` is the ISOTROPIC
|
|
58
|
+
* factor for everything that must not be deformed — stroke widths, arrowhead
|
|
59
|
+
* triangles, font sizes, letter-spacing — taken as the geometric mean of the
|
|
60
|
+
* two, the usual area-preserving stand-in for "one scale" when there are two.
|
|
61
|
+
*
|
|
62
|
+
* At the authored ratio `sx === sy`, so all three collapse to the single old
|
|
63
|
+
* factor and `ox`/`oy` were zero: a map that has not been stretched paints
|
|
64
|
+
* exactly the pixels it painted before this change.
|
|
65
|
+
*/
|
|
66
|
+
export interface EstuarineFit {
|
|
67
|
+
/** Reference x → element x. */
|
|
68
|
+
sx: number;
|
|
69
|
+
/** Reference y → element y. */
|
|
70
|
+
sy: number;
|
|
71
|
+
/** The one undeformed factor: widths, arrowheads, type. */
|
|
72
|
+
strokeScale: number;
|
|
73
|
+
/**
|
|
74
|
+
* `lineWidth` correction for a path stroked INSIDE the stretched space.
|
|
75
|
+
*
|
|
76
|
+
* Canvas transforms the pen along with the path, so under `scale(sx, sy)` a
|
|
77
|
+
* nominal width `L` paints somewhere between `L·sx` and `L·sy` depending on
|
|
78
|
+
* the direction of the segment. There is no exact single number for a curve
|
|
79
|
+
* that runs in every direction; we approximate the pen's effective widening
|
|
80
|
+
* by the ARITHMETIC mean of the two factors and divide it out, which lands
|
|
81
|
+
* the ghost on {@link strokeScale} on average and keeps it within the
|
|
82
|
+
* sx/sy spread everywhere else. Exactly `1` at the authored ratio.
|
|
83
|
+
*/
|
|
84
|
+
curveLineScale: number;
|
|
85
|
+
}
|
|
86
|
+
export declare function estuarineFit(w: number, h: number): EstuarineFit;
|
|
87
|
+
/**
|
|
88
|
+
* Put `ctx` into the map's STRETCHED reference space, where the authored
|
|
89
|
+
* geometry (a `Path2D` built from `./consts.ts`) lands on the element's real
|
|
90
|
+
* bounds in both directions.
|
|
91
|
+
*
|
|
92
|
+
* The single source of truth for that transform, and it has to stay single:
|
|
93
|
+
* the ghost overlay paints the very same curves one layer above and must land
|
|
94
|
+
* on them to the pixel. Everything that must NOT be stretched — axes,
|
|
95
|
+
* arrowheads, legends — is drawn outside it, in element coordinates, from the
|
|
96
|
+
* same {@link EstuarineFit}.
|
|
97
|
+
*/
|
|
98
|
+
export declare function applyEstuarineTransform(ctx: CanvasRenderingContext2D, w: number, h: number): EstuarineFit;
|
|
3
99
|
/**
|
|
4
100
|
* Canvas renderer for the Estuarine framework map — reproduces the official SVG:
|
|
5
101
|
* the e (vertical, double-headed) / t (horizontal, single-headed) axes and the
|
|
6
102
|
* three reference curves (Liminal / Volatile / Counter-factual), each with its
|
|
7
|
-
* legend and individually hideable.
|
|
8
|
-
*
|
|
103
|
+
* legend and individually hideable.
|
|
104
|
+
*
|
|
105
|
+
* Two spaces, and which one a mark belongs to is the whole design:
|
|
106
|
+
*
|
|
107
|
+
* - **Element coordinates**, entered by mapping each authored coordinate
|
|
108
|
+
* through {@link EstuarineFit} by hand (`ax` / `ay` below): the axes, their
|
|
109
|
+
* arrowheads and every word. Their POSITION follows the stretch — an axis
|
|
110
|
+
* ends where the map now ends — while their SHAPE does not, because a
|
|
111
|
+
* stretched arrowhead or a squashed letter is a defect, never a feature.
|
|
112
|
+
* - **Stretched reference space**, entered by {@link applyEstuarineTransform}:
|
|
113
|
+
* the three curves, which are boundaries across the plane and must cover
|
|
114
|
+
* whatever plane the user has made.
|
|
9
115
|
*/
|
|
10
116
|
export declare const estuarine: ElementRenderer<EstuarineElementModel>;
|
|
11
117
|
export declare const EstuarineRendererExtension: import("@formicoidea/labre-core/store").ExtensionType & {
|