@fasl-work/caos-app-shell 0.12.0 → 0.13.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/bin/caos-shell-gate.mjs +1 -1
- package/dist/chart.js +2 -2
- package/dist/{chunk-X6Y5CDUD.js → chunk-33WTUQ7Q.js} +5 -3
- package/dist/{chunk-DX36XRD5.js → chunk-YECZXGVG.js} +1 -1
- package/dist/index.d.ts +155 -57
- package/dist/index.js +1032 -212
- package/dist/{keys-CnvqkckF.d.ts → keys-DDQGijwQ.d.ts} +10 -4
- package/dist/keys.d.ts +1 -1
- package/dist/keys.js +1 -1
- package/gate/areas.mjs +230 -54
- package/gate/inpage.mjs +52 -10
- package/gate/run.mjs +33 -8
- package/gate/serve.mjs +6 -2
- package/package.json +1 -1
- package/reserved-classes.json +56 -18
- package/src/content/executive.schema.json +659 -141
- package/styles.css +37 -18
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { useThemeStore, useShellLang, useLangStore, SHELL_TOKENS, pick, useStageSize, NOT_AVAILABLE, formatTicks, formatNumber, NBSP } from './chunk-
|
|
2
|
-
export { NBSP, NOT_AVAILABLE, SCIENTIFIC_BELOW, SHELL_TOKENS, Stage, applyTheme, formatNumber, formatTicks, pick, readTheme, resolveToken, useFormat, useLangStore, useShellLang, useStageSize, useThemeStore, useThemeTokens } from './chunk-
|
|
3
|
-
|
|
1
|
+
import { useThemeStore, useShellLang, useLangStore, SHELL_TOKENS, pick, useStageSize, NOT_AVAILABLE, formatTicks, formatNumber, NBSP } from './chunk-YECZXGVG.js';
|
|
2
|
+
export { NBSP, NOT_AVAILABLE, SCIENTIFIC_BELOW, SHELL_TOKENS, Stage, applyTheme, formatNumber, formatTicks, pick, readTheme, resolveToken, useFormat, useLangStore, useShellLang, useStageSize, useThemeStore, useThemeTokens } from './chunk-YECZXGVG.js';
|
|
3
|
+
import { APP_ROUTE, LANDING_ROUTE } from './chunk-33WTUQ7Q.js';
|
|
4
|
+
export { APP_ROUTE, LANDING_ROUTE, LANG_STORAGE_KEY, STANDARD_ROUTES, THEME_BOOT_SCRIPT, THEME_STORAGE_KEY } from './chunk-33WTUQ7Q.js';
|
|
4
5
|
import { createContext, Component, useState, useRef, useId, useEffect, useCallback, useContext, useMemo, useLayoutEffect, Children } from 'react';
|
|
5
|
-
import { useInRouterContext, NavLink, useLocation } from 'react-router';
|
|
6
|
+
import { useInRouterContext, NavLink, useLocation, Navigate, Link } from 'react-router';
|
|
6
7
|
import { Sun, Moon, Languages, Boxes, CodeXml, Globe, Briefcase, Info } from 'lucide-react';
|
|
7
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
9
|
import katex from 'katex';
|
|
@@ -428,6 +429,11 @@ function Frame({ config, pathname, routed, children }) {
|
|
|
428
429
|
] }) }) })
|
|
429
430
|
] });
|
|
430
431
|
}
|
|
432
|
+
function Landing() {
|
|
433
|
+
const { pathname, search, hash } = useLocation();
|
|
434
|
+
const oldAppLink = pathname === "/" && (search !== "" || hash !== "");
|
|
435
|
+
return /* @__PURE__ */ jsx(Navigate, { to: `${oldAppLink ? APP_ROUTE : LANDING_ROUTE}${search}${hash}`, replace: true });
|
|
436
|
+
}
|
|
431
437
|
function WorkbenchShell({
|
|
432
438
|
brand,
|
|
433
439
|
routes,
|
|
@@ -1143,10 +1149,10 @@ var DOC_AREAS = {
|
|
|
1143
1149
|
"/experiments": ["question", "metrics", "protocol", "datasets"],
|
|
1144
1150
|
"/benchmark": ["results", "comparison", "robustness", "live", "provenance", "caveat"]
|
|
1145
1151
|
};
|
|
1146
|
-
function DocPage({ title, lede,
|
|
1152
|
+
function DocPage({ title, lede, floorWaivers, children }) {
|
|
1147
1153
|
const lang = useShellLang();
|
|
1148
1154
|
const waivers = (floorWaivers ?? []).map((w) => `${w.floor}: ${pick(w.reason, lang)}`).join("; ");
|
|
1149
|
-
return /* @__PURE__ */ jsxs("div", { className:
|
|
1155
|
+
return /* @__PURE__ */ jsxs("div", { className: "page-body wide prose caos-doc", "data-doc-page": "", "data-floor-waiver": waivers || void 0, children: [
|
|
1150
1156
|
/* @__PURE__ */ jsxs("div", { className: "page-head", children: [
|
|
1151
1157
|
/* @__PURE__ */ jsx("h1", { children: pick(title, lang) }),
|
|
1152
1158
|
/* @__PURE__ */ jsx("p", { className: "lede", children: lede })
|
|
@@ -1211,99 +1217,557 @@ function Stat({ value, unit, source }) {
|
|
|
1211
1217
|
var executive_schema_default = {
|
|
1212
1218
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1213
1219
|
$id: "https://github.com/fsantibanezleal/CAOS_APP_SHELL/blob/main/src/content/executive.schema.json",
|
|
1214
|
-
title: "CAOS executive view data, version
|
|
1215
|
-
description: "The one data file a CAOS product fills for the executive view of its Introduction (content/executive.json). Every text is { en, es }; nothing outside these fields is allowed. The writing limits (30 words per sentence,
|
|
1220
|
+
title: "CAOS executive view data, version 2.0.0",
|
|
1221
|
+
description: "The one data file a CAOS product fills for the executive view of its Introduction (content/executive.json): the industry's problem framed for a decision maker, general and never tied to a client or written as a pitch. Every text is { en, es }; nothing outside these fields is allowed. The floors are minimum and maximum counts of rows (minItems, maxItems). The writing limits (30 words per sentence, one sentence for key messages, captions, actions and the like, two for the key statement, at least 25 words in a paragraph, no equation, no inline citation, no promotional or client-bound wording), the 4 C's rule (exactly the 4 C's of FOUR_CS, in order, each c equal to its name), the owners that are roles of the current situation, the weights of the causes and the sources-by-id rules (every citation names a source, every source is cited, a source is an https link whose title and note cite no file) are checked by validateExecutive in executive.ts, on top of this structure.",
|
|
1216
1222
|
type: "object",
|
|
1217
1223
|
additionalProperties: false,
|
|
1218
|
-
required: [
|
|
1224
|
+
required: [
|
|
1225
|
+
"title",
|
|
1226
|
+
"key_statement",
|
|
1227
|
+
"headline_figures",
|
|
1228
|
+
"pain",
|
|
1229
|
+
"context",
|
|
1230
|
+
"situation",
|
|
1231
|
+
"trends",
|
|
1232
|
+
"proposal",
|
|
1233
|
+
"illustrations",
|
|
1234
|
+
"sources"
|
|
1235
|
+
],
|
|
1219
1236
|
properties: {
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1237
|
+
title: {
|
|
1238
|
+
$ref: "#/$defs/text",
|
|
1239
|
+
description: "The problem's title: the industry's problem, not a product name."
|
|
1240
|
+
},
|
|
1241
|
+
key_statement: {
|
|
1242
|
+
$ref: "#/$defs/text",
|
|
1243
|
+
description: "One or two sentences naming the pain and the direction proposed."
|
|
1244
|
+
},
|
|
1245
|
+
headline_figures: {
|
|
1246
|
+
type: "array",
|
|
1247
|
+
minItems: 2,
|
|
1248
|
+
maxItems: 3,
|
|
1249
|
+
description: "Two or three headline figures, each a short heading, one figure and its linked source.",
|
|
1250
|
+
items: {
|
|
1251
|
+
$ref: "#/$defs/figure"
|
|
1252
|
+
}
|
|
1253
|
+
},
|
|
1254
|
+
pain: {
|
|
1224
1255
|
type: "object",
|
|
1225
1256
|
additionalProperties: false,
|
|
1226
|
-
required: [
|
|
1257
|
+
required: [
|
|
1258
|
+
"key_message",
|
|
1259
|
+
"paragraphs",
|
|
1260
|
+
"bearers",
|
|
1261
|
+
"figures",
|
|
1262
|
+
"causes"
|
|
1263
|
+
],
|
|
1227
1264
|
properties: {
|
|
1228
|
-
|
|
1229
|
-
|
|
1265
|
+
key_message: {
|
|
1266
|
+
$ref: "#/$defs/text",
|
|
1267
|
+
description: "One line: what a reader who stops here takes away."
|
|
1268
|
+
},
|
|
1269
|
+
paragraphs: {
|
|
1270
|
+
type: "array",
|
|
1271
|
+
minItems: 2,
|
|
1272
|
+
maxItems: 3,
|
|
1273
|
+
description: "Two paragraphs (at least 25 words each): what goes wrong, for whom, how big.",
|
|
1274
|
+
items: {
|
|
1275
|
+
$ref: "#/$defs/text"
|
|
1276
|
+
}
|
|
1277
|
+
},
|
|
1278
|
+
bearers: {
|
|
1279
|
+
type: "array",
|
|
1280
|
+
minItems: 3,
|
|
1281
|
+
maxItems: 5,
|
|
1282
|
+
items: {
|
|
1283
|
+
type: "object",
|
|
1284
|
+
additionalProperties: false,
|
|
1285
|
+
required: [
|
|
1286
|
+
"who",
|
|
1287
|
+
"cost",
|
|
1288
|
+
"measure"
|
|
1289
|
+
],
|
|
1290
|
+
properties: {
|
|
1291
|
+
who: {
|
|
1292
|
+
$ref: "#/$defs/text",
|
|
1293
|
+
description: "Who bears it."
|
|
1294
|
+
},
|
|
1295
|
+
cost: {
|
|
1296
|
+
$ref: "#/$defs/text",
|
|
1297
|
+
description: "The cost in money, time, risk or harm."
|
|
1298
|
+
},
|
|
1299
|
+
measure: {
|
|
1300
|
+
$ref: "#/$defs/text",
|
|
1301
|
+
description: "How it is measured."
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
},
|
|
1306
|
+
figures: {
|
|
1307
|
+
type: "array",
|
|
1308
|
+
minItems: 2,
|
|
1309
|
+
maxItems: 4,
|
|
1310
|
+
description: "At least two sourced industry figures.",
|
|
1311
|
+
items: {
|
|
1312
|
+
$ref: "#/$defs/figure"
|
|
1313
|
+
}
|
|
1314
|
+
},
|
|
1315
|
+
causes: {
|
|
1316
|
+
type: "array",
|
|
1317
|
+
minItems: 3,
|
|
1318
|
+
maxItems: 5,
|
|
1319
|
+
description: "Three to five non-overlapping branches, weighted by size.",
|
|
1320
|
+
items: {
|
|
1321
|
+
type: "object",
|
|
1322
|
+
additionalProperties: false,
|
|
1323
|
+
required: [
|
|
1324
|
+
"cause",
|
|
1325
|
+
"weight"
|
|
1326
|
+
],
|
|
1327
|
+
properties: {
|
|
1328
|
+
cause: {
|
|
1329
|
+
$ref: "#/$defs/text",
|
|
1330
|
+
description: "One branch of the problem; branches do not overlap."
|
|
1331
|
+
},
|
|
1332
|
+
weight: {
|
|
1333
|
+
type: "integer",
|
|
1334
|
+
minimum: 1,
|
|
1335
|
+
maximum: 100,
|
|
1336
|
+
description: "The size of the branch as a percent of the whole; the weights add to at most 100."
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1230
1341
|
}
|
|
1231
1342
|
},
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1343
|
+
context: {
|
|
1344
|
+
type: "object",
|
|
1345
|
+
additionalProperties: false,
|
|
1346
|
+
required: [
|
|
1347
|
+
"key_message",
|
|
1348
|
+
"paragraphs",
|
|
1349
|
+
"setting",
|
|
1350
|
+
"forces",
|
|
1351
|
+
"evidence"
|
|
1352
|
+
],
|
|
1353
|
+
properties: {
|
|
1354
|
+
key_message: {
|
|
1355
|
+
$ref: "#/$defs/text",
|
|
1356
|
+
description: "One line: what a reader who stops here takes away."
|
|
1357
|
+
},
|
|
1358
|
+
paragraphs: {
|
|
1359
|
+
type: "array",
|
|
1360
|
+
minItems: 1,
|
|
1361
|
+
maxItems: 2,
|
|
1362
|
+
description: "One or two paragraphs (at least 25 words each).",
|
|
1363
|
+
items: {
|
|
1364
|
+
$ref: "#/$defs/text"
|
|
1365
|
+
}
|
|
1366
|
+
},
|
|
1367
|
+
setting: {
|
|
1368
|
+
$ref: "#/$defs/text",
|
|
1369
|
+
description: "The class of organisations, rules, data and technology the problem lives in."
|
|
1370
|
+
},
|
|
1371
|
+
forces: {
|
|
1372
|
+
type: "array",
|
|
1373
|
+
minItems: 3,
|
|
1374
|
+
maxItems: 4,
|
|
1375
|
+
items: {
|
|
1245
1376
|
type: "object",
|
|
1246
1377
|
additionalProperties: false,
|
|
1247
|
-
required: [
|
|
1378
|
+
required: [
|
|
1379
|
+
"force",
|
|
1380
|
+
"direction"
|
|
1381
|
+
],
|
|
1248
1382
|
properties: {
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1383
|
+
force: {
|
|
1384
|
+
$ref: "#/$defs/text",
|
|
1385
|
+
description: "A force that keeps the pain going."
|
|
1386
|
+
},
|
|
1387
|
+
direction: {
|
|
1388
|
+
$ref: "#/$defs/direction"
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
},
|
|
1393
|
+
evidence: {
|
|
1394
|
+
type: "array",
|
|
1395
|
+
minItems: 1,
|
|
1396
|
+
maxItems: 4,
|
|
1397
|
+
description: "At least one sourced rule or figure.",
|
|
1398
|
+
items: {
|
|
1399
|
+
type: "object",
|
|
1400
|
+
additionalProperties: false,
|
|
1401
|
+
required: [
|
|
1402
|
+
"statement",
|
|
1403
|
+
"source"
|
|
1404
|
+
],
|
|
1405
|
+
properties: {
|
|
1406
|
+
statement: {
|
|
1407
|
+
$ref: "#/$defs/text",
|
|
1408
|
+
description: "One sourced rule or figure."
|
|
1409
|
+
},
|
|
1410
|
+
source: {
|
|
1411
|
+
$ref: "#/$defs/sourceId"
|
|
1412
|
+
}
|
|
1252
1413
|
}
|
|
1253
1414
|
}
|
|
1254
1415
|
}
|
|
1255
1416
|
}
|
|
1256
1417
|
},
|
|
1257
|
-
|
|
1258
|
-
type: "
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1418
|
+
situation: {
|
|
1419
|
+
type: "object",
|
|
1420
|
+
additionalProperties: false,
|
|
1421
|
+
required: [
|
|
1422
|
+
"key_message",
|
|
1423
|
+
"roles",
|
|
1424
|
+
"interaction",
|
|
1425
|
+
"state_of_the_art",
|
|
1426
|
+
"status"
|
|
1427
|
+
],
|
|
1428
|
+
properties: {
|
|
1429
|
+
key_message: {
|
|
1430
|
+
$ref: "#/$defs/text",
|
|
1431
|
+
description: "One line: what a reader who stops here takes away."
|
|
1432
|
+
},
|
|
1433
|
+
roles: {
|
|
1434
|
+
type: "array",
|
|
1435
|
+
minItems: 3,
|
|
1436
|
+
maxItems: 5,
|
|
1437
|
+
items: {
|
|
1438
|
+
type: "object",
|
|
1439
|
+
additionalProperties: false,
|
|
1440
|
+
required: [
|
|
1441
|
+
"role",
|
|
1442
|
+
"decides",
|
|
1443
|
+
"needs"
|
|
1444
|
+
],
|
|
1445
|
+
properties: {
|
|
1446
|
+
role: {
|
|
1447
|
+
$ref: "#/$defs/text",
|
|
1448
|
+
description: "A role involved; a family of roles, never a person or an organisation."
|
|
1449
|
+
},
|
|
1450
|
+
decides: {
|
|
1451
|
+
$ref: "#/$defs/text",
|
|
1452
|
+
description: "What it decides."
|
|
1453
|
+
},
|
|
1454
|
+
needs: {
|
|
1455
|
+
$ref: "#/$defs/text",
|
|
1456
|
+
description: "What it needs."
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
},
|
|
1461
|
+
interaction: {
|
|
1462
|
+
$ref: "#/$defs/text",
|
|
1463
|
+
description: "One sentence on how the roles interact."
|
|
1464
|
+
},
|
|
1465
|
+
state_of_the_art: {
|
|
1466
|
+
type: "array",
|
|
1467
|
+
minItems: 3,
|
|
1468
|
+
maxItems: 5,
|
|
1469
|
+
items: {
|
|
1470
|
+
type: "object",
|
|
1471
|
+
additionalProperties: false,
|
|
1472
|
+
required: [
|
|
1473
|
+
"approach",
|
|
1474
|
+
"achieves",
|
|
1475
|
+
"falls_short",
|
|
1476
|
+
"source"
|
|
1477
|
+
],
|
|
1478
|
+
properties: {
|
|
1479
|
+
approach: {
|
|
1480
|
+
$ref: "#/$defs/text",
|
|
1481
|
+
description: "An approach in use, described fairly."
|
|
1482
|
+
},
|
|
1483
|
+
achieves: {
|
|
1484
|
+
$ref: "#/$defs/text",
|
|
1485
|
+
description: "What it achieves."
|
|
1486
|
+
},
|
|
1487
|
+
falls_short: {
|
|
1488
|
+
$ref: "#/$defs/text",
|
|
1489
|
+
description: "Where it falls short."
|
|
1490
|
+
},
|
|
1491
|
+
source: {
|
|
1492
|
+
$ref: "#/$defs/sourceId"
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
},
|
|
1497
|
+
status: {
|
|
1498
|
+
type: "object",
|
|
1499
|
+
additionalProperties: false,
|
|
1500
|
+
required: [
|
|
1501
|
+
"heading",
|
|
1502
|
+
"value",
|
|
1503
|
+
"unit",
|
|
1504
|
+
"date",
|
|
1505
|
+
"source"
|
|
1506
|
+
],
|
|
1507
|
+
properties: {
|
|
1508
|
+
heading: {
|
|
1509
|
+
$ref: "#/$defs/text"
|
|
1510
|
+
},
|
|
1511
|
+
value: {
|
|
1512
|
+
$ref: "#/$defs/text"
|
|
1513
|
+
},
|
|
1514
|
+
unit: {
|
|
1515
|
+
$ref: "#/$defs/text"
|
|
1516
|
+
},
|
|
1517
|
+
date: {
|
|
1518
|
+
$ref: "#/$defs/text",
|
|
1519
|
+
description: "The date of the figure."
|
|
1520
|
+
},
|
|
1521
|
+
source: {
|
|
1522
|
+
$ref: "#/$defs/sourceId"
|
|
1523
|
+
}
|
|
1524
|
+
},
|
|
1525
|
+
description: "One sourced status figure with its date."
|
|
1269
1526
|
}
|
|
1270
1527
|
}
|
|
1271
1528
|
},
|
|
1272
|
-
|
|
1273
|
-
type: "
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1529
|
+
trends: {
|
|
1530
|
+
type: "object",
|
|
1531
|
+
additionalProperties: false,
|
|
1532
|
+
required: [
|
|
1533
|
+
"key_message",
|
|
1534
|
+
"items"
|
|
1535
|
+
],
|
|
1536
|
+
properties: {
|
|
1537
|
+
key_message: {
|
|
1538
|
+
$ref: "#/$defs/text",
|
|
1539
|
+
description: "One line: what a reader who stops here takes away."
|
|
1540
|
+
},
|
|
1541
|
+
items: {
|
|
1542
|
+
type: "array",
|
|
1543
|
+
minItems: 3,
|
|
1544
|
+
maxItems: 5,
|
|
1545
|
+
items: {
|
|
1546
|
+
type: "object",
|
|
1547
|
+
additionalProperties: false,
|
|
1548
|
+
required: [
|
|
1549
|
+
"trend",
|
|
1550
|
+
"kind",
|
|
1551
|
+
"direction",
|
|
1552
|
+
"horizon",
|
|
1553
|
+
"signal",
|
|
1554
|
+
"effect",
|
|
1555
|
+
"confidence"
|
|
1556
|
+
],
|
|
1557
|
+
properties: {
|
|
1558
|
+
trend: {
|
|
1559
|
+
$ref: "#/$defs/text"
|
|
1560
|
+
},
|
|
1561
|
+
kind: {
|
|
1562
|
+
type: "string",
|
|
1563
|
+
enum: [
|
|
1564
|
+
"regulatory",
|
|
1565
|
+
"technological",
|
|
1566
|
+
"market",
|
|
1567
|
+
"practice"
|
|
1568
|
+
]
|
|
1569
|
+
},
|
|
1570
|
+
direction: {
|
|
1571
|
+
$ref: "#/$defs/direction"
|
|
1572
|
+
},
|
|
1573
|
+
horizon: {
|
|
1574
|
+
type: "string",
|
|
1575
|
+
enum: [
|
|
1576
|
+
"now",
|
|
1577
|
+
"two_years",
|
|
1578
|
+
"ten_years"
|
|
1579
|
+
]
|
|
1580
|
+
},
|
|
1581
|
+
signal: {
|
|
1582
|
+
type: "object",
|
|
1583
|
+
additionalProperties: false,
|
|
1584
|
+
required: [
|
|
1585
|
+
"statement",
|
|
1586
|
+
"source"
|
|
1587
|
+
],
|
|
1588
|
+
properties: {
|
|
1589
|
+
statement: {
|
|
1590
|
+
$ref: "#/$defs/text",
|
|
1591
|
+
description: "The sourced signal."
|
|
1592
|
+
},
|
|
1593
|
+
source: {
|
|
1594
|
+
$ref: "#/$defs/sourceId"
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
},
|
|
1598
|
+
effect: {
|
|
1599
|
+
$ref: "#/$defs/text",
|
|
1600
|
+
description: "Its effect on the roles of the current situation."
|
|
1601
|
+
},
|
|
1602
|
+
confidence: {
|
|
1603
|
+
type: "string",
|
|
1604
|
+
enum: [
|
|
1605
|
+
"low",
|
|
1606
|
+
"medium",
|
|
1607
|
+
"high"
|
|
1608
|
+
]
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
},
|
|
1615
|
+
proposal: {
|
|
1616
|
+
type: "object",
|
|
1617
|
+
additionalProperties: false,
|
|
1618
|
+
required: [
|
|
1619
|
+
"key_message",
|
|
1620
|
+
"paragraphs",
|
|
1621
|
+
"four_cs",
|
|
1622
|
+
"actions",
|
|
1623
|
+
"risks",
|
|
1624
|
+
"unknowns"
|
|
1625
|
+
],
|
|
1626
|
+
properties: {
|
|
1627
|
+
key_message: {
|
|
1628
|
+
$ref: "#/$defs/text",
|
|
1629
|
+
description: "One line: what a reader who stops here takes away."
|
|
1630
|
+
},
|
|
1631
|
+
paragraphs: {
|
|
1632
|
+
type: "array",
|
|
1633
|
+
minItems: 1,
|
|
1634
|
+
maxItems: 2,
|
|
1635
|
+
description: "The approach at the level of the problem, tied to its causes (at least 25 words each).",
|
|
1636
|
+
items: {
|
|
1637
|
+
$ref: "#/$defs/text"
|
|
1638
|
+
}
|
|
1639
|
+
},
|
|
1640
|
+
four_cs: {
|
|
1641
|
+
type: "array",
|
|
1642
|
+
minItems: 4,
|
|
1643
|
+
maxItems: 4,
|
|
1644
|
+
description: "Required: exactly 4 rows, the 4 C's of FOUR_CS in order (Choice, Context, Cost, Control), each c equal to the name in both languages.",
|
|
1645
|
+
items: {
|
|
1646
|
+
type: "object",
|
|
1647
|
+
additionalProperties: false,
|
|
1648
|
+
required: [
|
|
1649
|
+
"c",
|
|
1650
|
+
"applies"
|
|
1651
|
+
],
|
|
1652
|
+
properties: {
|
|
1653
|
+
c: {
|
|
1654
|
+
$ref: "#/$defs/text",
|
|
1655
|
+
description: "The C's name."
|
|
1656
|
+
},
|
|
1657
|
+
applies: {
|
|
1658
|
+
$ref: "#/$defs/text",
|
|
1659
|
+
description: "One sentence: what this C means for the proposal."
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
},
|
|
1664
|
+
actions: {
|
|
1665
|
+
type: "array",
|
|
1666
|
+
minItems: 3,
|
|
1667
|
+
maxItems: 6,
|
|
1668
|
+
items: {
|
|
1669
|
+
type: "object",
|
|
1670
|
+
additionalProperties: false,
|
|
1671
|
+
required: [
|
|
1672
|
+
"action",
|
|
1673
|
+
"owner",
|
|
1674
|
+
"horizon",
|
|
1675
|
+
"check"
|
|
1676
|
+
],
|
|
1677
|
+
properties: {
|
|
1678
|
+
action: {
|
|
1679
|
+
$ref: "#/$defs/text"
|
|
1680
|
+
},
|
|
1681
|
+
owner: {
|
|
1682
|
+
$ref: "#/$defs/text",
|
|
1683
|
+
description: "A role of the current situation, written as there."
|
|
1684
|
+
},
|
|
1685
|
+
horizon: {
|
|
1686
|
+
$ref: "#/$defs/text"
|
|
1687
|
+
},
|
|
1688
|
+
check: {
|
|
1689
|
+
$ref: "#/$defs/text",
|
|
1690
|
+
description: "How success is checked."
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
},
|
|
1695
|
+
risks: {
|
|
1696
|
+
type: "array",
|
|
1697
|
+
minItems: 1,
|
|
1698
|
+
maxItems: 4,
|
|
1699
|
+
items: {
|
|
1700
|
+
$ref: "#/$defs/text"
|
|
1701
|
+
}
|
|
1702
|
+
},
|
|
1703
|
+
unknowns: {
|
|
1704
|
+
type: "array",
|
|
1705
|
+
minItems: 1,
|
|
1706
|
+
maxItems: 4,
|
|
1707
|
+
items: {
|
|
1708
|
+
$ref: "#/$defs/text"
|
|
1709
|
+
}
|
|
1710
|
+
},
|
|
1711
|
+
handoff: {
|
|
1712
|
+
$ref: "#/$defs/text",
|
|
1713
|
+
description: "Optional: one closing line on the part of the problem the work explores."
|
|
1283
1714
|
}
|
|
1284
1715
|
}
|
|
1285
1716
|
},
|
|
1286
1717
|
illustrations: {
|
|
1287
1718
|
type: "object",
|
|
1288
1719
|
additionalProperties: false,
|
|
1289
|
-
required: [
|
|
1720
|
+
required: [
|
|
1721
|
+
"pain",
|
|
1722
|
+
"situation",
|
|
1723
|
+
"proposal"
|
|
1724
|
+
],
|
|
1290
1725
|
properties: {
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1726
|
+
pain: {
|
|
1727
|
+
$ref: "#/$defs/illustration"
|
|
1728
|
+
},
|
|
1729
|
+
situation: {
|
|
1730
|
+
$ref: "#/$defs/illustration"
|
|
1731
|
+
},
|
|
1732
|
+
proposal: {
|
|
1733
|
+
$ref: "#/$defs/illustration"
|
|
1734
|
+
}
|
|
1294
1735
|
}
|
|
1295
1736
|
},
|
|
1296
1737
|
sources: {
|
|
1297
1738
|
type: "array",
|
|
1298
1739
|
minItems: 1,
|
|
1299
|
-
description: "The
|
|
1740
|
+
description: "The sources, each a link; the notes are numbered in the order of first use. Every figure and every state-of-the-art or trend claim names one by id.",
|
|
1300
1741
|
items: {
|
|
1301
1742
|
type: "object",
|
|
1302
1743
|
additionalProperties: false,
|
|
1303
|
-
required: [
|
|
1744
|
+
required: [
|
|
1745
|
+
"id",
|
|
1746
|
+
"title",
|
|
1747
|
+
"url"
|
|
1748
|
+
],
|
|
1304
1749
|
properties: {
|
|
1305
|
-
|
|
1306
|
-
|
|
1750
|
+
id: {
|
|
1751
|
+
type: "string",
|
|
1752
|
+
pattern: "^[a-z0-9][a-z0-9-]*$",
|
|
1753
|
+
"x-pattern-message": "must be lower case letters, digits and hyphens",
|
|
1754
|
+
description: "The id the figures and claims cite."
|
|
1755
|
+
},
|
|
1756
|
+
title: {
|
|
1757
|
+
$ref: "#/$defs/text",
|
|
1758
|
+
description: "The publication, in plain words."
|
|
1759
|
+
},
|
|
1760
|
+
url: {
|
|
1761
|
+
type: "string",
|
|
1762
|
+
minLength: 1,
|
|
1763
|
+
pattern: "^https://[^\\s]+$",
|
|
1764
|
+
"x-pattern-message": "must be an https:// link (the page or document itself, no other scheme, no spaces)",
|
|
1765
|
+
description: "The https link to the page or document."
|
|
1766
|
+
},
|
|
1767
|
+
note: {
|
|
1768
|
+
$ref: "#/$defs/text",
|
|
1769
|
+
description: "Optional, at most one sentence, for example a page number. Never a file name or number."
|
|
1770
|
+
}
|
|
1307
1771
|
}
|
|
1308
1772
|
}
|
|
1309
1773
|
}
|
|
@@ -1312,54 +1776,125 @@ var executive_schema_default = {
|
|
|
1312
1776
|
text: {
|
|
1313
1777
|
type: "object",
|
|
1314
1778
|
additionalProperties: false,
|
|
1315
|
-
required: [
|
|
1779
|
+
required: [
|
|
1780
|
+
"en",
|
|
1781
|
+
"es"
|
|
1782
|
+
],
|
|
1316
1783
|
properties: {
|
|
1317
|
-
en: {
|
|
1318
|
-
|
|
1784
|
+
en: {
|
|
1785
|
+
type: "string",
|
|
1786
|
+
minLength: 1
|
|
1787
|
+
},
|
|
1788
|
+
es: {
|
|
1789
|
+
type: "string",
|
|
1790
|
+
minLength: 1
|
|
1791
|
+
}
|
|
1319
1792
|
}
|
|
1320
1793
|
},
|
|
1794
|
+
sourceId: {
|
|
1795
|
+
type: "string",
|
|
1796
|
+
minLength: 1,
|
|
1797
|
+
description: "The id of an entry of sources."
|
|
1798
|
+
},
|
|
1799
|
+
direction: {
|
|
1800
|
+
type: "string",
|
|
1801
|
+
enum: [
|
|
1802
|
+
"rising",
|
|
1803
|
+
"easing",
|
|
1804
|
+
"steady"
|
|
1805
|
+
],
|
|
1806
|
+
description: "Where the force or the trend is heading."
|
|
1807
|
+
},
|
|
1321
1808
|
figure: {
|
|
1322
1809
|
type: "object",
|
|
1323
1810
|
additionalProperties: false,
|
|
1324
|
-
required: [
|
|
1811
|
+
required: [
|
|
1812
|
+
"heading",
|
|
1813
|
+
"value",
|
|
1814
|
+
"unit",
|
|
1815
|
+
"source"
|
|
1816
|
+
],
|
|
1325
1817
|
properties: {
|
|
1326
|
-
|
|
1327
|
-
|
|
1818
|
+
heading: {
|
|
1819
|
+
$ref: "#/$defs/text",
|
|
1820
|
+
description: "A short heading."
|
|
1821
|
+
},
|
|
1822
|
+
value: {
|
|
1823
|
+
$ref: "#/$defs/text"
|
|
1824
|
+
},
|
|
1825
|
+
unit: {
|
|
1826
|
+
$ref: "#/$defs/text"
|
|
1827
|
+
},
|
|
1828
|
+
source: {
|
|
1829
|
+
$ref: "#/$defs/sourceId"
|
|
1830
|
+
}
|
|
1328
1831
|
}
|
|
1329
1832
|
},
|
|
1330
1833
|
illustration: {
|
|
1331
1834
|
type: "object",
|
|
1332
1835
|
additionalProperties: false,
|
|
1333
|
-
required: [
|
|
1836
|
+
required: [
|
|
1837
|
+
"file",
|
|
1838
|
+
"caption"
|
|
1839
|
+
],
|
|
1334
1840
|
properties: {
|
|
1335
1841
|
file: {
|
|
1336
1842
|
description: "The inline SVG: one path, or one path per language.",
|
|
1337
1843
|
anyOf: [
|
|
1338
|
-
{
|
|
1844
|
+
{
|
|
1845
|
+
type: "string",
|
|
1846
|
+
minLength: 1
|
|
1847
|
+
},
|
|
1339
1848
|
{
|
|
1340
1849
|
type: "object",
|
|
1341
1850
|
additionalProperties: false,
|
|
1342
|
-
required: [
|
|
1343
|
-
|
|
1851
|
+
required: [
|
|
1852
|
+
"en",
|
|
1853
|
+
"es"
|
|
1854
|
+
],
|
|
1855
|
+
properties: {
|
|
1856
|
+
en: {
|
|
1857
|
+
type: "string",
|
|
1858
|
+
minLength: 1
|
|
1859
|
+
},
|
|
1860
|
+
es: {
|
|
1861
|
+
type: "string",
|
|
1862
|
+
minLength: 1
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1344
1865
|
}
|
|
1345
1866
|
]
|
|
1346
1867
|
},
|
|
1347
|
-
caption: {
|
|
1868
|
+
caption: {
|
|
1869
|
+
$ref: "#/$defs/text",
|
|
1870
|
+
description: "One sentence saying what the reader should take from the illustration."
|
|
1871
|
+
}
|
|
1348
1872
|
}
|
|
1349
1873
|
}
|
|
1350
1874
|
}
|
|
1351
1875
|
};
|
|
1352
1876
|
|
|
1353
1877
|
// src/content/executive.ts
|
|
1354
|
-
var EXECUTIVE_SCHEMA_VERSION = "
|
|
1355
|
-
var FOUR_CS = [
|
|
1878
|
+
var EXECUTIVE_SCHEMA_VERSION = "2.0.0";
|
|
1879
|
+
var FOUR_CS = [
|
|
1880
|
+
{ name: { en: "Choice", es: "Elecci\xF3n" }, definition: { en: "flexibility across proprietary and open models.", es: "flexibilidad entre modelos propietarios y abiertos." } },
|
|
1881
|
+
{ name: { en: "Context", es: "Contexto" }, definition: { en: "AI grounded in business meaning, so decisions are accurate.", es: "IA anclada en el significado del negocio, para que las decisiones sean exactas." } },
|
|
1882
|
+
{ name: { en: "Cost", es: "Costo" }, definition: { en: "visibility of what the AI spends.", es: "visibilidad de lo que gasta la IA." } },
|
|
1883
|
+
{ name: { en: "Control", es: "Control" }, definition: { en: "one governance over data, models and agents.", es: "una sola gobernanza sobre datos, modelos y agentes." } }
|
|
1884
|
+
];
|
|
1356
1885
|
var EXEC_LIMITS = {
|
|
1357
1886
|
maxWords: 30,
|
|
1358
|
-
|
|
1887
|
+
/** The fewest words of a paragraph: no one-line sections, no restating the title. */
|
|
1888
|
+
minParagraphWords: 25,
|
|
1359
1889
|
/** An equation or a TeX marker: a dollar sign, `\(`, `\[` or a backslash command. */
|
|
1360
1890
|
equation: /\$|\\\(|\\\[|\\[a-zA-Z]+/,
|
|
1361
1891
|
/** An inline citation: `(Source`, `[1]`, `(ECB`, or a parenthesised author-year such as `(Smith et al., 2019)`. */
|
|
1362
|
-
citations: [/\(\s*Source/i, /\[\d+\]/, /\(\s*ECB/, /\(\w[^()]*\d{4}\)/]
|
|
1892
|
+
citations: [/\(\s*Source/i, /\[\d+\]/, /\(\s*ECB/, /\(\w[^()]*\d{4}\)/],
|
|
1893
|
+
/** A source that cites a file name or number in place of its link (a `.pdf` is allowed only beside a written-out https link). */
|
|
1894
|
+
fileCitations: [/\bfile\s*\d/i, /\barchivo\s*\d/i, /\.pdf\b/i, /\bPublished on\b/i],
|
|
1895
|
+
/** Promotional or client-bound wording (the view is general: never a client, never a pitch; Felipe 2026-10-13). Whole words, either case. */
|
|
1896
|
+
promotional: [/\bour\s+clients?\b/i, /\bnuestros?\s+clientes?\b/i, /\bcontact\s+us\b/i, /\bcontáctenos\b/i, /\bbuy\b/i, /\bcomprar\b/i, /\bprices?\b/i, /\bprecios?\b/i, /\boffers?\b/i, /\bofertas?\b/i]
|
|
1897
|
+
};
|
|
1363
1898
|
function sentencesOf(text) {
|
|
1364
1899
|
return text.split(/(?<=[.?!])\s+/).map((s) => s.trim()).filter(Boolean);
|
|
1365
1900
|
}
|
|
@@ -1386,12 +1921,21 @@ function check(value, rawNode, path, out) {
|
|
|
1386
1921
|
return;
|
|
1387
1922
|
}
|
|
1388
1923
|
const t2 = typeOf(value);
|
|
1389
|
-
|
|
1924
|
+
const wanted = node.type === "integer" ? "number" : node.type;
|
|
1925
|
+
if (node.type && t2 !== wanted) {
|
|
1390
1926
|
out.push({ path, message: `must be ${node.type === "object" ? "an object" : node.type === "array" ? "an array" : `a ${node.type}`}, not ${t2 === "undefined" ? "missing" : t2 === "array" ? "an array" : t2 === "object" ? "an object" : `a ${t2}`}` });
|
|
1391
1927
|
return;
|
|
1392
1928
|
}
|
|
1929
|
+
if (node.type === "integer" && !Number.isInteger(value)) out.push({ path, message: "must be a whole number" });
|
|
1930
|
+
if (typeof value === "number") {
|
|
1931
|
+
if (node.minimum !== void 0 && value < node.minimum) out.push({ path, message: `must be at least ${node.minimum}` });
|
|
1932
|
+
if (node.maximum !== void 0 && value > node.maximum) out.push({ path, message: `must be at most ${node.maximum}` });
|
|
1933
|
+
}
|
|
1934
|
+
if (node.enum && !node.enum.includes(value)) out.push({ path, message: `must be one of ${node.enum.join(", ")}` });
|
|
1393
1935
|
if (node.type === "string" && typeof value === "string" && node.minLength && value.trim().length < node.minLength) {
|
|
1394
1936
|
out.push({ path, message: "must not be empty" });
|
|
1937
|
+
} else if (node.type === "string" && typeof value === "string" && node.pattern && !new RegExp(node.pattern).test(value)) {
|
|
1938
|
+
out.push({ path, message: node["x-pattern-message"] ?? `must match ${node.pattern}` });
|
|
1395
1939
|
}
|
|
1396
1940
|
if (node.type === "array") {
|
|
1397
1941
|
const list = value;
|
|
@@ -1411,29 +1955,84 @@ function check(value, rawNode, path, out) {
|
|
|
1411
1955
|
}
|
|
1412
1956
|
}
|
|
1413
1957
|
}
|
|
1414
|
-
function
|
|
1415
|
-
const out = [
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
{
|
|
1419
|
-
{
|
|
1420
|
-
{
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
d.
|
|
1425
|
-
|
|
1426
|
-
|
|
1958
|
+
function executiveTextFields(d) {
|
|
1959
|
+
const out = [];
|
|
1960
|
+
const add = (path, text, sentences, minWords) => out.push({ path, text, sentences, minWords });
|
|
1961
|
+
const figure = (base, f) => {
|
|
1962
|
+
add(`${base}.heading`, f.heading);
|
|
1963
|
+
add(`${base}.value`, f.value);
|
|
1964
|
+
add(`${base}.unit`, f.unit);
|
|
1965
|
+
};
|
|
1966
|
+
add("title", d.title, 1);
|
|
1967
|
+
add("key_statement", d.key_statement, 2);
|
|
1968
|
+
d.headline_figures.forEach((f, i) => figure(`headline_figures[${i}]`, f));
|
|
1969
|
+
const { pain, context: context2, situation, trends, proposal } = d;
|
|
1970
|
+
add("pain.key_message", pain.key_message, 1);
|
|
1971
|
+
pain.paragraphs.forEach((p, i) => add(`pain.paragraphs[${i}]`, p, void 0, EXEC_LIMITS.minParagraphWords));
|
|
1972
|
+
pain.bearers.forEach((b, i) => {
|
|
1973
|
+
add(`pain.bearers[${i}].who`, b.who);
|
|
1974
|
+
add(`pain.bearers[${i}].cost`, b.cost);
|
|
1975
|
+
add(`pain.bearers[${i}].measure`, b.measure);
|
|
1976
|
+
});
|
|
1977
|
+
pain.figures.forEach((f, i) => figure(`pain.figures[${i}]`, f));
|
|
1978
|
+
pain.causes.forEach((c, i) => add(`pain.causes[${i}].cause`, c.cause));
|
|
1979
|
+
add("context.key_message", context2.key_message, 1);
|
|
1980
|
+
context2.paragraphs.forEach((p, i) => add(`context.paragraphs[${i}]`, p, void 0, EXEC_LIMITS.minParagraphWords));
|
|
1981
|
+
add("context.setting", context2.setting);
|
|
1982
|
+
context2.forces.forEach((f, i) => add(`context.forces[${i}].force`, f.force));
|
|
1983
|
+
context2.evidence.forEach((e, i) => add(`context.evidence[${i}].statement`, e.statement, 1));
|
|
1984
|
+
add("situation.key_message", situation.key_message, 1);
|
|
1985
|
+
situation.roles.forEach((r, i) => {
|
|
1986
|
+
add(`situation.roles[${i}].role`, r.role);
|
|
1987
|
+
add(`situation.roles[${i}].decides`, r.decides);
|
|
1988
|
+
add(`situation.roles[${i}].needs`, r.needs);
|
|
1989
|
+
});
|
|
1990
|
+
add("situation.interaction", situation.interaction, 1);
|
|
1991
|
+
situation.state_of_the_art.forEach((a, i) => {
|
|
1992
|
+
add(`situation.state_of_the_art[${i}].approach`, a.approach);
|
|
1993
|
+
add(`situation.state_of_the_art[${i}].achieves`, a.achieves);
|
|
1994
|
+
add(`situation.state_of_the_art[${i}].falls_short`, a.falls_short);
|
|
1995
|
+
});
|
|
1996
|
+
figure("situation.status", situation.status);
|
|
1997
|
+
add("situation.status.date", situation.status.date);
|
|
1998
|
+
add("trends.key_message", trends.key_message, 1);
|
|
1999
|
+
trends.items.forEach((t2, i) => {
|
|
2000
|
+
add(`trends.items[${i}].trend`, t2.trend);
|
|
2001
|
+
add(`trends.items[${i}].signal.statement`, t2.signal.statement, 1);
|
|
2002
|
+
add(`trends.items[${i}].effect`, t2.effect);
|
|
2003
|
+
});
|
|
2004
|
+
add("proposal.key_message", proposal.key_message, 1);
|
|
2005
|
+
proposal.paragraphs.forEach((p, i) => add(`proposal.paragraphs[${i}]`, p, void 0, EXEC_LIMITS.minParagraphWords));
|
|
2006
|
+
proposal.four_cs.forEach((c, i) => {
|
|
2007
|
+
add(`proposal.four_cs[${i}].c`, c.c);
|
|
2008
|
+
add(`proposal.four_cs[${i}].applies`, c.applies, 1);
|
|
2009
|
+
});
|
|
2010
|
+
proposal.actions.forEach((a, i) => {
|
|
2011
|
+
add(`proposal.actions[${i}].action`, a.action, 1);
|
|
2012
|
+
add(`proposal.actions[${i}].owner`, a.owner);
|
|
2013
|
+
add(`proposal.actions[${i}].horizon`, a.horizon);
|
|
2014
|
+
add(`proposal.actions[${i}].check`, a.check, 1);
|
|
1427
2015
|
});
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
2016
|
+
proposal.risks.forEach((r, i) => add(`proposal.risks[${i}]`, r, 1));
|
|
2017
|
+
proposal.unknowns.forEach((u, i) => add(`proposal.unknowns[${i}]`, u, 1));
|
|
2018
|
+
if (proposal.handoff) add("proposal.handoff", proposal.handoff, 1);
|
|
2019
|
+
for (const name of ["pain", "situation", "proposal"]) add(`illustrations.${name}.caption`, d.illustrations[name].caption, 1);
|
|
1431
2020
|
return out;
|
|
1432
2021
|
}
|
|
1433
|
-
function
|
|
1434
|
-
|
|
2022
|
+
function executiveCitations(d) {
|
|
2023
|
+
const out = [];
|
|
2024
|
+
d.headline_figures.forEach((f, i) => out.push({ path: `headline_figures[${i}].source`, source: f.source, tab: 0 }));
|
|
2025
|
+
d.pain.figures.forEach((f, i) => out.push({ path: `pain.figures[${i}].source`, source: f.source, tab: 1 }));
|
|
2026
|
+
d.context.evidence.forEach((e, i) => out.push({ path: `context.evidence[${i}].source`, source: e.source, tab: 2 }));
|
|
2027
|
+
d.situation.state_of_the_art.forEach((a, i) => out.push({ path: `situation.state_of_the_art[${i}].source`, source: a.source, tab: 3 }));
|
|
2028
|
+
out.push({ path: "situation.status.source", source: d.situation.status.source, tab: 3 });
|
|
2029
|
+
d.trends.items.forEach((t2, i) => out.push({ path: `trends.items[${i}].signal.source`, source: t2.signal.source, tab: 4 }));
|
|
2030
|
+
return out;
|
|
1435
2031
|
}
|
|
1436
|
-
function
|
|
2032
|
+
function sourceOrder(d) {
|
|
2033
|
+
return [...new Set(executiveCitations(d).map((c) => c.source))];
|
|
2034
|
+
}
|
|
2035
|
+
function writingProblems(text, maxSentences, minWords) {
|
|
1437
2036
|
const out = [];
|
|
1438
2037
|
const sentences = sentencesOf(text);
|
|
1439
2038
|
for (const s of sentences) {
|
|
@@ -1443,82 +2042,116 @@ function writingProblems(text, maxSentences) {
|
|
|
1443
2042
|
if (maxSentences !== void 0 && sentences.length > maxSentences) {
|
|
1444
2043
|
out.push(maxSentences === 1 ? `must be one sentence, has ${sentences.length}` : `has ${sentences.length} sentences; the limit is ${maxSentences}`);
|
|
1445
2044
|
}
|
|
2045
|
+
if (minWords !== void 0 && wordsIn(text) < minWords) out.push(`has ${wordsIn(text)} words; a paragraph needs at least ${minWords} (no one-line sections)`);
|
|
1446
2046
|
if (EXEC_LIMITS.equation.test(text)) out.push("holds an equation or a TeX marker; the executive view holds none");
|
|
1447
2047
|
if (EXEC_LIMITS.citations.some((re) => re.test(text))) out.push('holds an inline citation; give the source in "sources"');
|
|
2048
|
+
for (const re of EXEC_LIMITS.promotional) {
|
|
2049
|
+
const m = re.exec(text);
|
|
2050
|
+
if (m) out.push(`holds promotional or client-bound wording ("${m[0]}"); the executive view is general, never a client, never a pitch`);
|
|
2051
|
+
}
|
|
1448
2052
|
return out;
|
|
1449
2053
|
}
|
|
1450
|
-
function
|
|
1451
|
-
const fourCs = opts.fourCs ?? FOUR_CS;
|
|
2054
|
+
function sourceTextProblems(text, maxSentences) {
|
|
1452
2055
|
const out = [];
|
|
1453
|
-
const
|
|
1454
|
-
|
|
1455
|
-
|
|
2056
|
+
const sentences = sentencesOf(text);
|
|
2057
|
+
for (const sentence of sentences) {
|
|
2058
|
+
const n = wordsIn(sentence);
|
|
2059
|
+
if (n > EXEC_LIMITS.maxWords) out.push(`a sentence of ${n} words; the limit is ${EXEC_LIMITS.maxWords}`);
|
|
2060
|
+
}
|
|
2061
|
+
if (maxSentences !== void 0 && sentences.length > maxSentences) out.push(maxSentences === 1 ? `must be one sentence, has ${sentences.length}` : `has ${sentences.length} sentences; the limit is ${maxSentences}`);
|
|
2062
|
+
const written = /https?:\/\//i.test(text);
|
|
2063
|
+
for (const re of EXEC_LIMITS.fileCitations) {
|
|
2064
|
+
if (re.source.includes("pdf") && written) continue;
|
|
2065
|
+
const m = re.exec(text);
|
|
2066
|
+
if (m) out.push(`cites a file name or number in place of the link ("${m[0]}"); give the publication as the title and its https link as the url`);
|
|
2067
|
+
}
|
|
2068
|
+
return out;
|
|
2069
|
+
}
|
|
2070
|
+
var sameText = (a, b) => Boolean(a && b && a.en === b.en && a.es === b.es);
|
|
2071
|
+
function validateExecutive(data) {
|
|
2072
|
+
const out = [];
|
|
2073
|
+
check(data, ROOT, "", out);
|
|
2074
|
+
if (out.length > 0) return out;
|
|
1456
2075
|
const d = data;
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
2076
|
+
d.proposal.four_cs.forEach((r, i) => {
|
|
2077
|
+
const want = FOUR_CS[i].name;
|
|
2078
|
+
if (!sameText(r.c, want)) {
|
|
2079
|
+
out.push({ path: `proposal.four_cs[${i}].c`, message: `must be "${want.en}" in English and "${want.es}" in Spanish (the ${i + 1}${["st", "nd", "rd", "th"][i]} of the 4 C's, in Felipe's order); found "${r.c.en}" and "${r.c.es}"` });
|
|
2080
|
+
}
|
|
2081
|
+
});
|
|
2082
|
+
const total = d.pain.causes.reduce((sum, c) => sum + c.weight, 0);
|
|
2083
|
+
if (total > 100) out.push({ path: "pain.causes", message: `the weights add to ${total} percent; non-overlapping causes add to at most 100` });
|
|
2084
|
+
d.proposal.actions.forEach((a, i) => {
|
|
2085
|
+
if (!d.situation.roles.some((r) => sameText(r.role, a.owner))) {
|
|
2086
|
+
out.push({ path: `proposal.actions[${i}].owner`, message: `must be one of the roles of the current situation (${d.situation.roles.map((r) => `"${r.role.en}"`).join(", ")}), written the same in both languages` });
|
|
2087
|
+
}
|
|
2088
|
+
});
|
|
2089
|
+
for (const f of executiveTextFields(d)) {
|
|
2090
|
+
for (const lang of ["en", "es"]) {
|
|
2091
|
+
for (const m of writingProblems(f.text[lang], f.sentences, f.minWords)) out.push({ path: `${f.path}.${lang}`, message: m });
|
|
1469
2092
|
}
|
|
1470
2093
|
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
2094
|
+
const ids = /* @__PURE__ */ new Map();
|
|
2095
|
+
d.sources.forEach((s, i) => {
|
|
2096
|
+
if (ids.has(s.id)) out.push({ path: `sources[${i}].id`, message: `"${s.id}" is already the id of sources[${ids.get(s.id)}]` });
|
|
2097
|
+
else ids.set(s.id, i);
|
|
1475
2098
|
for (const lang of ["en", "es"]) {
|
|
1476
|
-
const
|
|
1477
|
-
if (
|
|
1478
|
-
|
|
2099
|
+
for (const m of sourceTextProblems(s.title[lang])) out.push({ path: `sources[${i}].title.${lang}`, message: m });
|
|
2100
|
+
if (s.note) for (const m of sourceTextProblems(s.note[lang], 1)) out.push({ path: `sources[${i}].note.${lang}`, message: m });
|
|
2101
|
+
}
|
|
2102
|
+
});
|
|
2103
|
+
const cited = /* @__PURE__ */ new Set();
|
|
2104
|
+
for (const c of executiveCitations(d)) {
|
|
2105
|
+
if (!ids.has(c.source)) {
|
|
2106
|
+
out.push({ path: c.path, message: `"${c.source}" is not the id of any source (the ids are ${[...ids.keys()].join(", ")})` });
|
|
2107
|
+
continue;
|
|
1479
2108
|
}
|
|
2109
|
+
cited.add(c.source);
|
|
1480
2110
|
}
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
full.sources.forEach((s, i) => {
|
|
1484
|
-
if (!wanted.includes(s.field)) out.push({ path: `sources[${i}].field`, message: `"${s.field}" is not a figure of this view (the figures are ${wanted.join(", ")})` });
|
|
1485
|
-
else if (seen.has(s.field)) out.push({ path: `sources[${i}].field`, message: `"${s.field}" already has a source` });
|
|
1486
|
-
seen.add(s.field);
|
|
2111
|
+
d.sources.forEach((s, i) => {
|
|
2112
|
+
if (!cited.has(s.id)) out.push({ path: `sources[${i}].id`, message: `"${s.id}" is cited by no figure or claim; every source backs a figure or a claim` });
|
|
1487
2113
|
});
|
|
1488
|
-
const missing = wanted.filter((f) => !seen.has(f));
|
|
1489
|
-
if (missing.length > 0) out.push({ path: "sources", message: `no source for ${missing.join(", ")}` });
|
|
1490
2114
|
return out;
|
|
1491
2115
|
}
|
|
1492
|
-
var
|
|
1493
|
-
{
|
|
1494
|
-
{
|
|
1495
|
-
{ en: "
|
|
1496
|
-
{
|
|
1497
|
-
|
|
1498
|
-
var SECTION_QUESTIONS = [
|
|
1499
|
-
{ en: "Built for a C-suite exec?", es: "\xBFPensado para un ejecutivo de primer nivel?" },
|
|
1500
|
-
{ en: "Outcomes, not a feature tour", es: "Resultados, no un recorrido de funciones" },
|
|
1501
|
-
{ en: "Value story, not features dump", es: "Historia de valor, no lista de funciones" },
|
|
1502
|
-
{ en: "Trust them in front of a CxO?", es: "\xBFConfiar\xEDa en ellos frente a un ejecutivo?" }
|
|
2116
|
+
var EXEC_SECTION_DEFS = [
|
|
2117
|
+
{ id: "pain", key: "pain", title: { en: "The pain", es: "El problema" } },
|
|
2118
|
+
{ id: "context", key: "context", title: { en: "The context", es: "El contexto" } },
|
|
2119
|
+
{ id: "situation", key: "situation", title: { en: "The current situation", es: "La situaci\xF3n actual" } },
|
|
2120
|
+
{ id: "trends", key: "trends", title: { en: "The trends", es: "Las tendencias" } },
|
|
2121
|
+
{ id: "proposal", key: "proposal", title: { en: "The proposal", es: "La propuesta" } }
|
|
1503
2122
|
];
|
|
1504
|
-
var
|
|
1505
|
-
|
|
1506
|
-
|
|
2123
|
+
var SECTION_TITLES = EXEC_SECTION_DEFS.map((d) => d.title);
|
|
2124
|
+
var ONWARD_LINKS = {
|
|
2125
|
+
technical: { en: "How the work explores this problem", es: "C\xF3mo explora el trabajo este problema" },
|
|
2126
|
+
app: { en: "Open the App", es: "Abrir la App" }
|
|
1507
2127
|
};
|
|
1508
|
-
function Question({ question, answer }) {
|
|
1509
|
-
return /* @__PURE__ */ jsxs("div", { className: "caos-qa", "data-qa": "", children: [
|
|
1510
|
-
/* @__PURE__ */ jsx("p", { className: "caos-qa-question", "data-question": "", children: question }),
|
|
1511
|
-
/* @__PURE__ */ jsx("div", { className: "caos-qa-answer", "data-answer": "", children: answer })
|
|
1512
|
-
] });
|
|
1513
|
-
}
|
|
1514
2128
|
var UI = {
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
2129
|
+
bearers: { en: "Who bears it", es: "Qui\xE9n lo soporta" },
|
|
2130
|
+
cost: { en: "Cost", es: "Costo" },
|
|
2131
|
+
measure: { en: "Measured by", es: "Se mide por" },
|
|
2132
|
+
causes: { en: "Where it comes from", es: "De d\xF3nde viene" },
|
|
2133
|
+
setting: { en: "Setting", es: "Entorno" },
|
|
2134
|
+
forces: { en: "What keeps it going", es: "Qu\xE9 lo mantiene" },
|
|
2135
|
+
evidence: { en: "Rules and figures", es: "Reglas y cifras" },
|
|
2136
|
+
roles: { en: "The roles involved", es: "Los roles involucrados" },
|
|
2137
|
+
decides: { en: "Decides", es: "Decide" },
|
|
2138
|
+
needs: { en: "Needs", es: "Necesita" },
|
|
2139
|
+
sota: { en: "How it is handled today", es: "C\xF3mo se maneja hoy" },
|
|
2140
|
+
achieves: { en: "Achieves", es: "Logra" },
|
|
2141
|
+
fallsShort: { en: "Falls short", es: "Se queda corto" },
|
|
2142
|
+
signal: { en: "Signal", es: "Se\xF1al" },
|
|
2143
|
+
effect: { en: "Effect on the roles", es: "Efecto en los roles" },
|
|
2144
|
+
confidence: { en: "Confidence", es: "Confianza" },
|
|
2145
|
+
fourCs: { en: "The 4 C's applied", es: "Las 4 C aplicadas" },
|
|
2146
|
+
actions: { en: "Actions", es: "Acciones" },
|
|
2147
|
+
owner: { en: "Owner", es: "Responsable" },
|
|
2148
|
+
horizon: { en: "When", es: "Cu\xE1ndo" },
|
|
2149
|
+
check: { en: "How we would know", es: "C\xF3mo lo sabremos" },
|
|
2150
|
+
risks: { en: "Risks", es: "Riesgos" },
|
|
2151
|
+
unknowns: { en: "What is still unknown", es: "Lo que a\xFAn se desconoce" },
|
|
1521
2152
|
sources: { en: "Sources", es: "Fuentes" },
|
|
2153
|
+
onward: { en: "Onward", es: "Continuar" },
|
|
2154
|
+
sections: { en: "The sections of the executive view", es: "Las secciones de la vista ejecutiva" },
|
|
1522
2155
|
source: { en: "Source", es: "Fuente" },
|
|
1523
2156
|
errorTitle: { en: "The executive view data is not valid", es: "Los datos de la vista ejecutiva no son v\xE1lidos" },
|
|
1524
2157
|
errorLead: {
|
|
@@ -1528,6 +2161,27 @@ var UI = {
|
|
|
1528
2161
|
loading: { en: "Loading the illustration", es: "Cargando la ilustraci\xF3n" },
|
|
1529
2162
|
missing: { en: "The illustration file did not load", es: "No carg\xF3 el archivo de la ilustraci\xF3n" }
|
|
1530
2163
|
};
|
|
2164
|
+
var DIRECTION = {
|
|
2165
|
+
rising: { en: "Rising", es: "En aumento" },
|
|
2166
|
+
easing: { en: "Easing", es: "Cediendo" },
|
|
2167
|
+
steady: { en: "Steady", es: "Estable" }
|
|
2168
|
+
};
|
|
2169
|
+
var KIND = {
|
|
2170
|
+
regulatory: { en: "Regulatory", es: "Regulatoria" },
|
|
2171
|
+
technological: { en: "Technological", es: "Tecnol\xF3gica" },
|
|
2172
|
+
market: { en: "Market", es: "De mercado" },
|
|
2173
|
+
practice: { en: "Practice", es: "De pr\xE1ctica" }
|
|
2174
|
+
};
|
|
2175
|
+
var HORIZON = {
|
|
2176
|
+
now: { en: "Now", es: "Ahora" },
|
|
2177
|
+
two_years: { en: "In two years", es: "En dos a\xF1os" },
|
|
2178
|
+
ten_years: { en: "In ten years", es: "En diez a\xF1os" }
|
|
2179
|
+
};
|
|
2180
|
+
var CONFIDENCE = {
|
|
2181
|
+
low: { en: "Low", es: "Baja" },
|
|
2182
|
+
medium: { en: "Medium", es: "Media" },
|
|
2183
|
+
high: { en: "High", es: "Alta" }
|
|
2184
|
+
};
|
|
1531
2185
|
var t = (text, lang) => text[lang];
|
|
1532
2186
|
function cleanSvg(text) {
|
|
1533
2187
|
const doc = new DOMParser().parseFromString(text, "image/svg+xml");
|
|
@@ -1589,20 +2243,28 @@ function Illustration({ name, spec, base, lang }) {
|
|
|
1589
2243
|
);
|
|
1590
2244
|
}
|
|
1591
2245
|
var Label = ({ children }) => /* @__PURE__ */ jsx("span", { className: "caos-exec-label", children });
|
|
1592
|
-
function Section({ n, lang, children }) {
|
|
2246
|
+
function Section({ n, lang, keyMessage, keyPath, children }) {
|
|
1593
2247
|
return /* @__PURE__ */ jsxs("section", { className: "caos-exec-section", "data-exec-section": n, "aria-label": t(SECTION_TITLES[n - 1], lang), children: [
|
|
1594
|
-
/* @__PURE__ */ jsx("
|
|
1595
|
-
/* @__PURE__ */ jsx("p", { className: "caos-exec-question", "data-exec-question": "", children: t(SECTION_QUESTIONS[n - 1], lang) }),
|
|
2248
|
+
/* @__PURE__ */ jsx("p", { className: "caos-exec-key", "data-exec-key-message": "", "data-exec-field": keyPath, children: t(keyMessage, lang) }),
|
|
1596
2249
|
children
|
|
1597
2250
|
] });
|
|
1598
2251
|
}
|
|
1599
|
-
function
|
|
1600
|
-
|
|
2252
|
+
function openSiblingTechnical(from) {
|
|
2253
|
+
const panel2 = from.closest('[role="tabpanel"]');
|
|
2254
|
+
const own = panel2?.getAttribute("aria-labelledby");
|
|
2255
|
+
const tab = own ? document.getElementById(own) : null;
|
|
2256
|
+
const target = tab?.closest('[role="tablist"]')?.querySelector('[role="tab"][data-tab="technical"]');
|
|
2257
|
+
target?.click();
|
|
2258
|
+
target?.focus();
|
|
2259
|
+
}
|
|
2260
|
+
function ExecutiveView({ data, base, onOpenTechnical }) {
|
|
2261
|
+
return /* @__PURE__ */ jsx(ExecutiveViewBody, { data, base, onOpenTechnical });
|
|
1601
2262
|
}
|
|
1602
|
-
function ExecutiveViewBody({ data, base = "/",
|
|
2263
|
+
function ExecutiveViewBody({ data, base = "/", lang: forced, open = 1, onOpenTechnical }) {
|
|
1603
2264
|
const stored = useShellLang();
|
|
1604
2265
|
const lang = forced ?? stored;
|
|
1605
|
-
const
|
|
2266
|
+
const routed = useInRouterContext();
|
|
2267
|
+
const problems = validateExecutive(data);
|
|
1606
2268
|
if (problems.length > 0) {
|
|
1607
2269
|
return /* @__PURE__ */ jsxs(
|
|
1608
2270
|
"div",
|
|
@@ -1627,77 +2289,235 @@ function ExecutiveViewBody({ data, base = "/", fourCs, lang: forced }) {
|
|
|
1627
2289
|
);
|
|
1628
2290
|
}
|
|
1629
2291
|
const d = data;
|
|
1630
|
-
const
|
|
1631
|
-
const
|
|
1632
|
-
const
|
|
1633
|
-
const Cite2 = ({
|
|
2292
|
+
const order = sourceOrder(d);
|
|
2293
|
+
const sourceOf = (id) => d.sources.find((s) => s.id === id);
|
|
2294
|
+
const note = (id) => order.indexOf(id) + 1;
|
|
2295
|
+
const Cite2 = ({ id }) => /* @__PURE__ */ jsx("sup", { className: "caos-exec-cite", children: /* @__PURE__ */ jsx("a", { href: `#exec-note-${note(id)}`, "aria-label": `${t(UI.source, lang)} ${note(id)}`, children: note(id) }) });
|
|
1634
2296
|
const field = (path, text) => /* @__PURE__ */ jsx("span", { "data-exec-field": path, children: t(text, lang) });
|
|
1635
|
-
|
|
1636
|
-
/* @__PURE__ */
|
|
1637
|
-
|
|
2297
|
+
const Figure2 = ({ f, path, kind }) => /* @__PURE__ */ jsxs("li", { className: "caos-exec-figure", "data-exec-item": kind, children: [
|
|
2298
|
+
/* @__PURE__ */ jsx(Label, { children: field(`${path}.heading`, f.heading) }),
|
|
2299
|
+
/* @__PURE__ */ jsx("strong", { className: "caos-exec-value", "data-exec-field": `${path}.value`, children: t(f.value, lang) }),
|
|
2300
|
+
" ",
|
|
2301
|
+
field(`${path}.unit`, f.unit),
|
|
2302
|
+
/* @__PURE__ */ jsx(Cite2, { id: f.source })
|
|
2303
|
+
] });
|
|
2304
|
+
const Paragraphs = ({ list, path }) => /* @__PURE__ */ jsx(Fragment, { children: list.map((p, i) => /* @__PURE__ */ jsx("p", { className: "caos-exec-paragraph", "data-exec-item": path, children: field(`${path}[${i}]`, p) }, i)) });
|
|
2305
|
+
const art = (name) => /* @__PURE__ */ jsx(Illustration, { name, spec: d.illustrations[name], base, lang });
|
|
2306
|
+
const enumLabel = (map, key) => t(map[key], lang);
|
|
2307
|
+
const bodies = [
|
|
2308
|
+
// 1. the pain
|
|
2309
|
+
/* @__PURE__ */ jsxs(Section, { n: 1, lang, keyMessage: d.pain.key_message, keyPath: "pain.key_message", children: [
|
|
2310
|
+
/* @__PURE__ */ jsx(Paragraphs, { list: d.pain.paragraphs, path: "pain.paragraphs" }),
|
|
2311
|
+
art("pain"),
|
|
2312
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-figures", children: d.pain.figures.map((f, i) => /* @__PURE__ */ jsx(Figure2, { f, path: `pain.figures[${i}]`, kind: "pain.figures" }, i)) }),
|
|
2313
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.bearers, lang) }),
|
|
2314
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-cards", children: d.pain.bearers.map((b, i) => /* @__PURE__ */ jsxs("li", { className: "caos-exec-card", "data-exec-item": "pain.bearers", children: [
|
|
2315
|
+
/* @__PURE__ */ jsx("strong", { children: field(`pain.bearers[${i}].who`, b.who) }),
|
|
1638
2316
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1639
|
-
/* @__PURE__ */ jsx(
|
|
1640
|
-
|
|
2317
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.cost, lang) }),
|
|
2318
|
+
" ",
|
|
2319
|
+
field(`pain.bearers[${i}].cost`, b.cost)
|
|
1641
2320
|
] }),
|
|
1642
2321
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1643
|
-
/* @__PURE__ */ jsx(
|
|
1644
|
-
|
|
2322
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.measure, lang) }),
|
|
2323
|
+
" ",
|
|
2324
|
+
field(`pain.bearers[${i}].measure`, b.measure)
|
|
1645
2325
|
] })
|
|
2326
|
+
] }, i)) }),
|
|
2327
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.causes, lang) }),
|
|
2328
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-causes", children: d.pain.causes.map((c, i) => /* @__PURE__ */ jsxs("li", { className: "caos-exec-cause", "data-exec-item": "pain.causes", "data-exec-weight": c.weight, children: [
|
|
2329
|
+
/* @__PURE__ */ jsxs("div", { className: "caos-exec-cause-head", children: [
|
|
2330
|
+
field(`pain.causes[${i}].cause`, c.cause),
|
|
2331
|
+
" ",
|
|
2332
|
+
/* @__PURE__ */ jsxs("strong", { className: "caos-exec-value", children: [
|
|
2333
|
+
c.weight,
|
|
2334
|
+
"%"
|
|
2335
|
+
] })
|
|
2336
|
+
] }),
|
|
2337
|
+
/* @__PURE__ */ jsx("div", { className: "caos-exec-bar", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { style: { width: `${c.weight}%` } }) })
|
|
2338
|
+
] }, i)) })
|
|
2339
|
+
] }, "pain"),
|
|
2340
|
+
// 2. the context
|
|
2341
|
+
/* @__PURE__ */ jsxs(Section, { n: 2, lang, keyMessage: d.context.key_message, keyPath: "context.key_message", children: [
|
|
2342
|
+
/* @__PURE__ */ jsx(Paragraphs, { list: d.context.paragraphs, path: "context.paragraphs" }),
|
|
2343
|
+
/* @__PURE__ */ jsxs("p", { className: "caos-exec-setting", children: [
|
|
2344
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.setting, lang) }),
|
|
2345
|
+
" ",
|
|
2346
|
+
field("context.setting", d.context.setting)
|
|
1646
2347
|
] }),
|
|
1647
|
-
/* @__PURE__ */ jsx("
|
|
1648
|
-
/* @__PURE__ */ jsx(
|
|
1649
|
-
|
|
1650
|
-
/* @__PURE__ */ jsx(
|
|
2348
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.forces, lang) }),
|
|
2349
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-cards", children: d.context.forces.map((f, i) => /* @__PURE__ */ jsxs("li", { className: "caos-exec-card", "data-exec-item": "context.forces", "data-exec-direction": f.direction, children: [
|
|
2350
|
+
field(`context.forces[${i}].force`, f.force),
|
|
2351
|
+
/* @__PURE__ */ jsx("span", { className: "caos-exec-badge", children: enumLabel(DIRECTION, f.direction) })
|
|
2352
|
+
] }, i)) }),
|
|
2353
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.evidence, lang) }),
|
|
2354
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-evidence", children: d.context.evidence.map((e, i) => /* @__PURE__ */ jsxs("li", { "data-exec-item": "context.evidence", children: [
|
|
2355
|
+
field(`context.evidence[${i}].statement`, e.statement),
|
|
2356
|
+
/* @__PURE__ */ jsx(Cite2, { id: e.source })
|
|
2357
|
+
] }, i)) })
|
|
2358
|
+
] }, "context"),
|
|
2359
|
+
// 3. the current situation
|
|
2360
|
+
/* @__PURE__ */ jsxs(Section, { n: 3, lang, keyMessage: d.situation.key_message, keyPath: "situation.key_message", children: [
|
|
2361
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.roles, lang) }),
|
|
2362
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-cards", children: d.situation.roles.map((r, i) => /* @__PURE__ */ jsxs("li", { className: "caos-exec-card", "data-exec-item": "situation.roles", children: [
|
|
2363
|
+
/* @__PURE__ */ jsx("strong", { children: field(`situation.roles[${i}].role`, r.role) }),
|
|
2364
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2365
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.decides, lang) }),
|
|
2366
|
+
" ",
|
|
2367
|
+
field(`situation.roles[${i}].decides`, r.decides)
|
|
2368
|
+
] }),
|
|
2369
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2370
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.needs, lang) }),
|
|
2371
|
+
" ",
|
|
2372
|
+
field(`situation.roles[${i}].needs`, r.needs)
|
|
2373
|
+
] })
|
|
2374
|
+
] }, i)) }),
|
|
2375
|
+
/* @__PURE__ */ jsx("p", { className: "caos-exec-interaction", children: field("situation.interaction", d.situation.interaction) }),
|
|
2376
|
+
art("situation"),
|
|
2377
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.sota, lang) }),
|
|
2378
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-cards", children: d.situation.state_of_the_art.map((a, i) => /* @__PURE__ */ jsxs("li", { className: "caos-exec-card", "data-exec-item": "situation.state_of_the_art", children: [
|
|
2379
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
2380
|
+
field(`situation.state_of_the_art[${i}].approach`, a.approach),
|
|
2381
|
+
/* @__PURE__ */ jsx(Cite2, { id: a.source })
|
|
2382
|
+
] }),
|
|
2383
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2384
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.achieves, lang) }),
|
|
2385
|
+
" ",
|
|
2386
|
+
field(`situation.state_of_the_art[${i}].achieves`, a.achieves)
|
|
2387
|
+
] }),
|
|
2388
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2389
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.fallsShort, lang) }),
|
|
2390
|
+
" ",
|
|
2391
|
+
field(`situation.state_of_the_art[${i}].falls_short`, a.falls_short)
|
|
2392
|
+
] })
|
|
2393
|
+
] }, i)) }),
|
|
2394
|
+
/* @__PURE__ */ jsxs("p", { className: "caos-exec-status", "data-exec-item": "situation.status", children: [
|
|
2395
|
+
/* @__PURE__ */ jsx(Label, { children: field("situation.status.heading", d.situation.status.heading) }),
|
|
1651
2396
|
" ",
|
|
1652
|
-
/* @__PURE__ */ jsx("strong", { className: "caos-exec-value", "data-exec-field": "
|
|
2397
|
+
/* @__PURE__ */ jsx("strong", { className: "caos-exec-value", "data-exec-field": "situation.status.value", children: t(d.situation.status.value, lang) }),
|
|
1653
2398
|
" ",
|
|
1654
|
-
field("
|
|
2399
|
+
field("situation.status.unit", d.situation.status.unit),
|
|
1655
2400
|
" ",
|
|
1656
2401
|
/* @__PURE__ */ jsx("span", { className: "caos-exec-sep", children: "\xB7" }),
|
|
1657
2402
|
" ",
|
|
1658
|
-
field("
|
|
1659
|
-
/* @__PURE__ */ jsx(Cite2, {
|
|
2403
|
+
field("situation.status.date", d.situation.status.date),
|
|
2404
|
+
/* @__PURE__ */ jsx(Cite2, { id: d.situation.status.source })
|
|
2405
|
+
] })
|
|
2406
|
+
] }, "situation"),
|
|
2407
|
+
// 4. the trends
|
|
2408
|
+
/* @__PURE__ */ jsx(Section, { n: 4, lang, keyMessage: d.trends.key_message, keyPath: "trends.key_message", children: /* @__PURE__ */ jsx("ul", { className: "caos-exec-cards", children: d.trends.items.map((it, i) => /* @__PURE__ */ jsxs("li", { className: "caos-exec-card", "data-exec-item": "trends.items", "data-exec-horizon": it.horizon, children: [
|
|
2409
|
+
/* @__PURE__ */ jsx("strong", { children: field(`trends.items[${i}].trend`, it.trend) }),
|
|
2410
|
+
/* @__PURE__ */ jsxs("div", { className: "caos-exec-badges", children: [
|
|
2411
|
+
/* @__PURE__ */ jsx("span", { className: "caos-exec-badge", children: enumLabel(KIND, it.kind) }),
|
|
2412
|
+
/* @__PURE__ */ jsx("span", { className: "caos-exec-badge", children: enumLabel(DIRECTION, it.direction) }),
|
|
2413
|
+
/* @__PURE__ */ jsx("span", { className: "caos-exec-badge", children: enumLabel(HORIZON, it.horizon) }),
|
|
2414
|
+
/* @__PURE__ */ jsxs("span", { className: "caos-exec-badge", children: [
|
|
2415
|
+
t(UI.confidence, lang),
|
|
2416
|
+
": ",
|
|
2417
|
+
enumLabel(CONFIDENCE, it.confidence)
|
|
2418
|
+
] })
|
|
2419
|
+
] }),
|
|
2420
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2421
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.signal, lang) }),
|
|
2422
|
+
" ",
|
|
2423
|
+
field(`trends.items[${i}].signal.statement`, it.signal.statement),
|
|
2424
|
+
/* @__PURE__ */ jsx(Cite2, { id: it.signal.source })
|
|
1660
2425
|
] }),
|
|
1661
|
-
/* @__PURE__ */
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
2426
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2427
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.effect, lang) }),
|
|
2428
|
+
" ",
|
|
2429
|
+
field(`trends.items[${i}].effect`, it.effect)
|
|
2430
|
+
] })
|
|
2431
|
+
] }, i)) }) }, "trends"),
|
|
2432
|
+
// 5. the proposal
|
|
2433
|
+
/* @__PURE__ */ jsxs(Section, { n: 5, lang, keyMessage: d.proposal.key_message, keyPath: "proposal.key_message", children: [
|
|
2434
|
+
/* @__PURE__ */ jsx(Paragraphs, { list: d.proposal.paragraphs, path: "proposal.paragraphs" }),
|
|
2435
|
+
art("proposal"),
|
|
2436
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.fourCs, lang) }),
|
|
2437
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-cs", children: d.proposal.four_cs.map((r, i) => /* @__PURE__ */ jsxs("li", { className: "caos-exec-card", "data-exec-c": i, "data-exec-item": "proposal.four_cs", children: [
|
|
2438
|
+
/* @__PURE__ */ jsx("strong", { "data-exec-field": `proposal.four_cs[${i}].c`, "data-exec-cname": "", children: t(FOUR_CS[i].name, lang) }),
|
|
2439
|
+
/* @__PURE__ */ jsx("small", { className: "caos-exec-cdef", "data-exec-cdef": "", children: t(FOUR_CS[i].definition, lang) }),
|
|
2440
|
+
/* @__PURE__ */ jsx("span", { children: field(`proposal.four_cs[${i}].applies`, r.applies) })
|
|
2441
|
+
] }, i)) }),
|
|
2442
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.actions, lang) }),
|
|
2443
|
+
/* @__PURE__ */ jsx("ol", { className: "caos-exec-actions", children: d.proposal.actions.map((a, i) => /* @__PURE__ */ jsxs("li", { className: "caos-exec-card", "data-exec-item": "proposal.actions", children: [
|
|
2444
|
+
/* @__PURE__ */ jsx("strong", { children: field(`proposal.actions[${i}].action`, a.action) }),
|
|
1667
2445
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1668
|
-
/* @__PURE__ */ jsx(Label, { children: t(UI.
|
|
2446
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.owner, lang) }),
|
|
1669
2447
|
" ",
|
|
1670
|
-
field(`
|
|
1671
|
-
] }),
|
|
1672
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1673
|
-
/* @__PURE__ */ jsx(Label, { children: t(UI.result, lang) }),
|
|
2448
|
+
field(`proposal.actions[${i}].owner`, a.owner),
|
|
1674
2449
|
" ",
|
|
1675
|
-
|
|
1676
|
-
] }),
|
|
1677
|
-
/* @__PURE__ */ jsxs("div", { className: "caos-exec-proof", children: [
|
|
1678
|
-
/* @__PURE__ */ jsx(Label, { children: t(UI.proof, lang) }),
|
|
2450
|
+
/* @__PURE__ */ jsx("span", { className: "caos-exec-sep", children: "\xB7" }),
|
|
1679
2451
|
" ",
|
|
1680
|
-
/* @__PURE__ */ jsx(
|
|
2452
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.horizon, lang) }),
|
|
1681
2453
|
" ",
|
|
1682
|
-
field(`
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
/* @__PURE__ */ jsx(
|
|
2454
|
+
field(`proposal.actions[${i}].horizon`, a.horizon)
|
|
2455
|
+
] }),
|
|
2456
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2457
|
+
/* @__PURE__ */ jsx(Label, { children: t(UI.check, lang) }),
|
|
2458
|
+
" ",
|
|
2459
|
+
field(`proposal.actions[${i}].check`, a.check)
|
|
1686
2460
|
] })
|
|
1687
|
-
] }, i)) })
|
|
2461
|
+
] }, i)) }),
|
|
2462
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.risks, lang) }),
|
|
2463
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-list", children: d.proposal.risks.map((r, i) => /* @__PURE__ */ jsx("li", { "data-exec-item": "proposal.risks", children: field(`proposal.risks[${i}]`, r) }, i)) }),
|
|
2464
|
+
/* @__PURE__ */ jsx("h3", { className: "caos-exec-sub", children: t(UI.unknowns, lang) }),
|
|
2465
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-list", children: d.proposal.unknowns.map((u, i) => /* @__PURE__ */ jsx("li", { "data-exec-item": "proposal.unknowns", children: field(`proposal.unknowns[${i}]`, u) }, i)) }),
|
|
2466
|
+
d.proposal.handoff && /* @__PURE__ */ jsx("p", { className: "caos-exec-handoff", children: field("proposal.handoff", d.proposal.handoff) })
|
|
2467
|
+
] }, "proposal")
|
|
2468
|
+
];
|
|
2469
|
+
return /* @__PURE__ */ jsxs("div", { className: "caos-exec", "data-executive-view": "", "data-executive-schema": EXECUTIVE_SCHEMA_VERSION, "data-executive-valid": "true", children: [
|
|
2470
|
+
/* @__PURE__ */ jsxs("header", { className: "caos-exec-landing", "data-exec-landing": "", children: [
|
|
2471
|
+
/* @__PURE__ */ jsx("h2", { className: "caos-exec-title", "data-exec-field": "title", children: t(d.title, lang) }),
|
|
2472
|
+
/* @__PURE__ */ jsx("p", { className: "caos-exec-statement", "data-exec-field": "key_statement", children: t(d.key_statement, lang) }),
|
|
2473
|
+
/* @__PURE__ */ jsx("ul", { className: "caos-exec-headline", children: d.headline_figures.map((f, i) => /* @__PURE__ */ jsx(Figure2, { f, path: `headline_figures[${i}]`, kind: "headline_figures" }, i)) })
|
|
1688
2474
|
] }),
|
|
1689
|
-
/* @__PURE__ */ jsx(
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
2475
|
+
/* @__PURE__ */ jsx("div", { className: "caos-exec-tabs", "data-exec-tabs": "", children: /* @__PURE__ */ jsx(
|
|
2476
|
+
SubTabs,
|
|
2477
|
+
{
|
|
2478
|
+
ariaLabel: t(UI.sections, lang),
|
|
2479
|
+
initial: EXEC_SECTION_DEFS[open - 1]?.id,
|
|
2480
|
+
tabs: EXEC_SECTION_DEFS.map((def, i) => ({ id: def.id, label: t(def.title, lang), content: bodies[i] }))
|
|
2481
|
+
}
|
|
2482
|
+
) }),
|
|
1695
2483
|
/* @__PURE__ */ jsxs("aside", { className: "caos-exec-notes-wrap", "aria-label": t(UI.sources, lang), children: [
|
|
1696
2484
|
/* @__PURE__ */ jsx("h3", { className: "caos-exec-notes-title", children: t(UI.sources, lang) }),
|
|
1697
|
-
/* @__PURE__ */ jsx("ol", { className: "caos-exec-notes", "data-exec-notes": "", children:
|
|
2485
|
+
/* @__PURE__ */ jsx("ol", { className: "caos-exec-notes", "data-exec-notes": "", children: order.map((id, i) => {
|
|
2486
|
+
const src = sourceOf(id);
|
|
2487
|
+
return /* @__PURE__ */ jsxs("li", { id: `exec-note-${i + 1}`, "data-exec-source": id, children: [
|
|
2488
|
+
/* @__PURE__ */ jsx("a", { href: src.url, target: "_blank", rel: "noopener noreferrer", "data-exec-source-title": "", children: t(src.title, lang) }),
|
|
2489
|
+
src.note && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2490
|
+
" ",
|
|
2491
|
+
/* @__PURE__ */ jsx("span", { className: "caos-exec-note-text", "data-exec-source-note": "", children: t(src.note, lang) })
|
|
2492
|
+
] })
|
|
2493
|
+
] }, id);
|
|
2494
|
+
}) })
|
|
2495
|
+
] }),
|
|
2496
|
+
/* @__PURE__ */ jsxs("nav", { className: "caos-exec-links", "data-exec-links": "", "aria-label": t(UI.onward, lang), children: [
|
|
2497
|
+
/* @__PURE__ */ jsx(
|
|
2498
|
+
"a",
|
|
2499
|
+
{
|
|
2500
|
+
href: "#technical",
|
|
2501
|
+
className: "caos-exec-link",
|
|
2502
|
+
"data-exec-link": "technical",
|
|
2503
|
+
onClick: (e) => {
|
|
2504
|
+
e.preventDefault();
|
|
2505
|
+
if (onOpenTechnical) onOpenTechnical();
|
|
2506
|
+
else openSiblingTechnical(e.currentTarget);
|
|
2507
|
+
},
|
|
2508
|
+
children: t(ONWARD_LINKS.technical, lang)
|
|
2509
|
+
}
|
|
2510
|
+
),
|
|
2511
|
+
routed ? /* @__PURE__ */ jsx(Link, { to: APP_ROUTE, className: "caos-exec-link", "data-exec-link": "app", children: t(ONWARD_LINKS.app, lang) }) : /* @__PURE__ */ jsx("a", { href: `${base}${APP_ROUTE.slice(1)}`, className: "caos-exec-link", "data-exec-link": "app", children: t(ONWARD_LINKS.app, lang) })
|
|
1698
2512
|
] })
|
|
1699
2513
|
] });
|
|
1700
2514
|
}
|
|
2515
|
+
function Question({ question, answer }) {
|
|
2516
|
+
return /* @__PURE__ */ jsxs("div", { className: "caos-qa", "data-qa": "", children: [
|
|
2517
|
+
/* @__PURE__ */ jsx("p", { className: "caos-qa-question", "data-question": "", children: question }),
|
|
2518
|
+
/* @__PURE__ */ jsx("div", { className: "caos-qa-answer", "data-answer": "", children: answer })
|
|
2519
|
+
] });
|
|
2520
|
+
}
|
|
1701
2521
|
function replaceQueryParam(param, value) {
|
|
1702
2522
|
if (typeof window === "undefined") return;
|
|
1703
2523
|
const next = withCaseParam(window.location.search, value, param);
|
|
@@ -2351,4 +3171,4 @@ function ViewsRow({ children, shares }) {
|
|
|
2351
3171
|
}) });
|
|
2352
3172
|
}
|
|
2353
3173
|
|
|
2354
|
-
export { AppShell, ArchitectureModal, BREAKPOINTS, BarChart, Callout, CaseSelector, CaseWorkbench, ChipGroup, CitationsProvider, Cite, DOC_AREAS, DocPage, DocReferences, DocRefsScope, DocSection, EXECUTIVE_SCHEMA_VERSION, Equation, ExecutiveView, FOUR_CS, Figure, FocusShell, Gauge, Glossary, InlineMath, Knob, LaneBadge, LanguageToggle, MAX_PEER_TABS, MAX_WORKBENCH_GROUPS, PanelBoundary, PlotCard, Question, Readout, ReferenceList, Refs, Stat, SubTabs, SurfacePage, TabGroups, Tabs, ThemeToggle, VariantBar, Verdict, ViewsRow, WorkbenchLayout, WorkbenchShell, WorkbenchStateContext, caseKind, caseTooltip, casesInSource, createVizLoop, firstAppearance, fitLabel, fontFamily, groupByCategory, isStale, makeStateKey, niceStep, niceTicks, readCaseParam, replaceQueryParam, sourcesPresent, textWidth, usePausedViz, useUrlView, useWorkbenchState, validateArchitectureConfig, validateExecutive, viewParamOf, widestLabel, withCaseParam };
|
|
3174
|
+
export { AppShell, ArchitectureModal, BREAKPOINTS, BarChart, Callout, CaseSelector, CaseWorkbench, ChipGroup, CitationsProvider, Cite, DOC_AREAS, DocPage, DocReferences, DocRefsScope, DocSection, EXECUTIVE_SCHEMA_VERSION, Equation, ExecutiveView, FOUR_CS, Figure, FocusShell, Gauge, Glossary, InlineMath, Knob, Landing, LaneBadge, LanguageToggle, MAX_PEER_TABS, MAX_WORKBENCH_GROUPS, PanelBoundary, PlotCard, Question, Readout, ReferenceList, Refs, Stat, SubTabs, SurfacePage, TabGroups, Tabs, ThemeToggle, VariantBar, Verdict, ViewsRow, WorkbenchLayout, WorkbenchShell, WorkbenchStateContext, caseKind, caseTooltip, casesInSource, createVizLoop, firstAppearance, fitLabel, fontFamily, groupByCategory, isStale, makeStateKey, niceStep, niceTicks, readCaseParam, replaceQueryParam, sourcesPresent, textWidth, usePausedViz, useUrlView, useWorkbenchState, validateArchitectureConfig, validateExecutive, viewParamOf, widestLabel, withCaseParam };
|