@intentius/behold 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -2
- package/README.md +12 -2
- package/demos.json +8 -0
- package/dist/cli.js +750 -132
- package/example-argo-estate/README.md +46 -0
- package/example-argo-estate/app-a/chant.config.ts +10 -0
- package/example-argo-estate/app-a/manifests/app.yaml +54 -0
- package/example-argo-estate/app-a/package.json +13 -0
- package/example-argo-estate/app-a/src/app.ts +35 -0
- package/example-argo-estate/app-a/tsconfig.json +1 -0
- package/example-argo-estate/app-b/chant.config.ts +9 -0
- package/example-argo-estate/app-b/manifests/app.yaml +54 -0
- package/example-argo-estate/app-b/package.json +13 -0
- package/example-argo-estate/app-b/src/app.ts +34 -0
- package/example-argo-estate/app-b/tsconfig.json +1 -0
- package/example-argo-estate/control-plane/chant.config.ts +14 -0
- package/example-argo-estate/control-plane/package.json +13 -0
- package/example-argo-estate/control-plane/src/argo.ts +69 -0
- package/example-argo-estate/control-plane/tsconfig.json +1 -0
- package/example-argo-estate/package-lock.json +1949 -0
- package/example-argo-estate/package.json +10 -0
- package/example-flux-estate/README.md +13 -8
- package/example-flux-estate/app-a/package.json +2 -2
- package/example-flux-estate/app-b/package.json +2 -2
- package/example-flux-estate/control-plane/package.json +2 -2
- package/example-flux-estate/control-plane/src/flux.ts +6 -0
- package/example-flux-estate/package-lock.json +17 -17
- package/example-k8s/README.md +16 -2
- package/example-k8s/base/deployment.yaml +21 -0
- package/example-k8s/base/kustomization.yaml +3 -0
- package/example-k8s/base/service.yaml +12 -0
- package/example-k8s/chant.config.ts +10 -0
- package/example-k8s/overlays/dev/kustomization.yaml +6 -0
- package/example-k8s/package-lock.json +18 -18
- package/example-k8s/package.json +3 -3
- package/example-writes/package-lock.json +14 -14
- package/example-writes/package.json +3 -3
- package/package.json +3 -2
- package/web/app.js +350 -22
- package/web/icons/cncf/argo.svg +1 -0
- package/web/icons/cncf/flux.svg +1 -0
- package/web/icons/cncf/helm.svg +1 -0
- package/web/icons/k8s/c-role.svg +1 -0
- package/web/icons/k8s/cm.svg +1 -0
- package/web/icons/k8s/crb.svg +1 -0
- package/web/icons/k8s/crd.svg +1 -0
- package/web/icons/k8s/cronjob.svg +1 -0
- package/web/icons/k8s/deploy.svg +1 -0
- package/web/icons/k8s/ds.svg +1 -0
- package/web/icons/k8s/ep.svg +1 -0
- package/web/icons/k8s/group.svg +1 -0
- package/web/icons/k8s/hpa.svg +1 -0
- package/web/icons/k8s/ing.svg +1 -0
- package/web/icons/k8s/job.svg +1 -0
- package/web/icons/k8s/limits.svg +1 -0
- package/web/icons/k8s/netpol.svg +1 -0
- package/web/icons/k8s/ns.svg +1 -0
- package/web/icons/k8s/pod.svg +1 -0
- package/web/icons/k8s/psp.svg +1 -0
- package/web/icons/k8s/pv.svg +1 -0
- package/web/icons/k8s/pvc.svg +1 -0
- package/web/icons/k8s/quota.svg +1 -0
- package/web/icons/k8s/rb.svg +1 -0
- package/web/icons/k8s/role.svg +1 -0
- package/web/icons/k8s/rs.svg +1 -0
- package/web/icons/k8s/sa.svg +1 -0
- package/web/icons/k8s/sc.svg +1 -0
- package/web/icons/k8s/secret.svg +1 -0
- package/web/icons/k8s/sts.svg +1 -0
- package/web/icons/k8s/svc.svg +1 -0
- package/web/icons/k8s/user.svg +1 -0
- package/web/icons/k8s/vol.svg +1 -0
- package/web/index.html +192 -84
- package/web/layout-store.js +118 -0
- package/web/layout-store.test.js +163 -0
- package/web/theme.js +58 -6
package/web/app.js
CHANGED
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
// renderPanelView never rewrites, so the select mounts once and survives re-renders).
|
|
11
11
|
import { initTheme, mountThemePicker, readableOn, colorForCategory, onThemeChange, getTokens } from "./theme.js";
|
|
12
12
|
import { initPanel, setPanelTab, togglePanelCollapsed, isPanelCollapsed } from "./panel.js";
|
|
13
|
+
// #228: the hand-layout delta store — everything about WHAT gets remembered and
|
|
14
|
+
// under which key. The pointer work and the SVG surgery stay here (see the
|
|
15
|
+
// "Hand layout" section below).
|
|
16
|
+
import { applicable, clearLayout, isEmpty, layoutKey, lensKeyOf, projectKeyOf, readLayout, setDelta, writeLayout } from "./layout-store.js";
|
|
13
17
|
initTheme();
|
|
14
18
|
initPanel();
|
|
15
19
|
mountThemePicker(document.getElementById("panel-theme"));
|
|
@@ -63,6 +67,39 @@ function recolorNodesByCategory(ir) {
|
|
|
63
67
|
}
|
|
64
68
|
onThemeChange(() => recolorNodesByCategory());
|
|
65
69
|
|
|
70
|
+
// #229, the one motion signature behold spends on data: a node whose drift
|
|
71
|
+
// `_status` CHANGED between two renders pulses once in the colour it just
|
|
72
|
+
// became. Node ids are stable across renders, so the diff is a single map
|
|
73
|
+
// compare — no extra fetch, no per-node bookkeeping. The first render seeds the
|
|
74
|
+
// map and pulses nothing (everything would "change"), and a lens switch that
|
|
75
|
+
// swaps the id set pulses nothing either, since only ids present in BOTH
|
|
76
|
+
// renders can have changed. The CSS keyframes + the reduced-motion guard live
|
|
77
|
+
// in index.html.
|
|
78
|
+
let lastStatusById = new Map();
|
|
79
|
+
function markStatusChanges(ir, statusVar) {
|
|
80
|
+
const prev = lastStatusById;
|
|
81
|
+
const next = new Map();
|
|
82
|
+
for (const n of ir.nodes) {
|
|
83
|
+
const s = n.attrs && n.attrs._status;
|
|
84
|
+
if (s) next.set(n.id, s);
|
|
85
|
+
}
|
|
86
|
+
lastStatusById = next;
|
|
87
|
+
if (!prev.size) return;
|
|
88
|
+
const svg = document.querySelector("#graph svg");
|
|
89
|
+
if (!svg) return;
|
|
90
|
+
for (const g of svg.querySelectorAll("[data-node-id]")) {
|
|
91
|
+
const id = g.getAttribute("data-node-id");
|
|
92
|
+
const now = next.get(id);
|
|
93
|
+
if (!now || prev.get(id) === undefined || prev.get(id) === now) continue;
|
|
94
|
+
// The pulse wears the NEW status's hue, read through whichever vocabulary
|
|
95
|
+
// this graph is painted in — a node going foreign glows yellow in the drift
|
|
96
|
+
// overlay; a component that rolled back glows red in the component view,
|
|
97
|
+
// where the same `warn` means something else entirely.
|
|
98
|
+
g.style.setProperty("--pulse", statusVar[now] || "var(--pending)");
|
|
99
|
+
g.classList.add("status-changed");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
66
103
|
// Static-export mode (`behold export`): the SPA runs off a pre-captured bundle
|
|
67
104
|
// with no backend. Detect the flag the export injects, load its manifest, and
|
|
68
105
|
// replay every read from `snapshots/` — the graph, zoom dial, radial, inspect,
|
|
@@ -141,7 +178,6 @@ function inspect(node) {
|
|
|
141
178
|
const section = (title) => {
|
|
142
179
|
const h = document.createElement("h3");
|
|
143
180
|
h.textContent = title;
|
|
144
|
-
h.style.cssText = "font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);margin:14px 0 6px";
|
|
145
181
|
panel.appendChild(h);
|
|
146
182
|
const dl = document.createElement("dl");
|
|
147
183
|
panel.appendChild(dl);
|
|
@@ -202,7 +238,6 @@ function inspect(node) {
|
|
|
202
238
|
if (isComposite) {
|
|
203
239
|
const h = document.createElement("h3");
|
|
204
240
|
h.textContent = `members · ${node.attrs.members}`;
|
|
205
|
-
h.style.cssText = "font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);margin:14px 0 6px";
|
|
206
241
|
panel.appendChild(h);
|
|
207
242
|
const loading = document.createElement("p");
|
|
208
243
|
loading.style.color = "var(--muted)";
|
|
@@ -354,7 +389,7 @@ function inspect(node) {
|
|
|
354
389
|
panel.appendChild(p);
|
|
355
390
|
return;
|
|
356
391
|
}
|
|
357
|
-
renderObserved(panel, j.observed, j.health); // #30 observed state + #26 health
|
|
392
|
+
renderObserved(panel, j.observed, j.health, j.healthDetail); // #30 observed state + #26/#226 health
|
|
358
393
|
renderDiff(panel, j.diff); // #27 — drift since snapshot
|
|
359
394
|
renderFieldDrift(panel, j.fieldDrift); // #87 — field-level (per-manager) drift
|
|
360
395
|
});
|
|
@@ -388,11 +423,10 @@ const HEALTH_COLOR = {
|
|
|
388
423
|
};
|
|
389
424
|
|
|
390
425
|
// Render a node's observed live state (#30) + health verdict (#26).
|
|
391
|
-
function renderObserved(panel, o, health) {
|
|
426
|
+
function renderObserved(panel, o, health, healthDetail) {
|
|
392
427
|
if (!o) return; // pending/foreign nodes have no observed record in the diff
|
|
393
428
|
const h = document.createElement("h3");
|
|
394
429
|
h.textContent = "observed";
|
|
395
|
-
h.style.cssText = "font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);margin:14px 0 6px";
|
|
396
430
|
panel.appendChild(h);
|
|
397
431
|
const dl = document.createElement("dl");
|
|
398
432
|
const add = (k, v, color) => {
|
|
@@ -405,7 +439,14 @@ function renderObserved(panel, o, health) {
|
|
|
405
439
|
};
|
|
406
440
|
// Health first — the "is it well?" verdict, distinct from drift. Absent when
|
|
407
441
|
// the substrate reports no status (not fabricated).
|
|
408
|
-
|
|
442
|
+
// #226: for an Argo Application or a Flux object the verdict comes from the
|
|
443
|
+
// controller's own conditions, and `healthDetail` is the sentence it read
|
|
444
|
+
// there — `Ready=False (BuildFailed)`, `health=Degraded, sync=OutOfSync`.
|
|
445
|
+
// Appended to the verdict rather than given its own row, because it is the
|
|
446
|
+
// same claim said precisely.
|
|
447
|
+
if (health && health !== "unknown") {
|
|
448
|
+
add("health", healthDetail ? `${health} — ${healthDetail}` : health, HEALTH_COLOR[health]);
|
|
449
|
+
}
|
|
409
450
|
if (o.type) add("type", o.type);
|
|
410
451
|
if (o.status) add("status", o.status, HEALTH_COLOR[health] || undefined);
|
|
411
452
|
if (o.physicalId) add("physical id", o.physicalId);
|
|
@@ -448,7 +489,6 @@ const DIFF_LABEL = {
|
|
|
448
489
|
function renderDiff(panel, diff) {
|
|
449
490
|
const h = document.createElement("h3");
|
|
450
491
|
h.textContent = "drift";
|
|
451
|
-
h.style.cssText = "font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);margin:14px 0 6px";
|
|
452
492
|
panel.appendChild(h);
|
|
453
493
|
if (!diff) {
|
|
454
494
|
const p = document.createElement("p");
|
|
@@ -466,7 +506,7 @@ function renderDiff(panel, diff) {
|
|
|
466
506
|
// this address makes that visible). Monospace so a request path scans.
|
|
467
507
|
if (diff.queried) {
|
|
468
508
|
const q = document.createElement("p");
|
|
469
|
-
q.
|
|
509
|
+
q.className = "queried"; // mono + muted, styled with the rest of the pane's scale
|
|
470
510
|
q.textContent = `queried: ${diff.queried} → ${diff.category === "missing" ? "not found" : "read failed"}`;
|
|
471
511
|
panel.appendChild(q);
|
|
472
512
|
}
|
|
@@ -539,7 +579,6 @@ function renderFieldDrift(panel, fieldDrift) {
|
|
|
539
579
|
if (!fieldDrift.drifted.length && !fieldDrift.accepted.length) return; // deep ran, nothing to report for this node
|
|
540
580
|
const h = document.createElement("h3");
|
|
541
581
|
h.textContent = "field ownership";
|
|
542
|
-
h.style.cssText = "font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);margin:14px 0 6px";
|
|
543
582
|
panel.appendChild(h);
|
|
544
583
|
const dl = document.createElement("dl");
|
|
545
584
|
for (const ch of fieldDrift.drifted) {
|
|
@@ -734,7 +773,7 @@ function renderPanelView() {
|
|
|
734
773
|
lanes.href = "/lanes";
|
|
735
774
|
lanes.textContent = "lanes →";
|
|
736
775
|
lanes.title = "The time-lanes view — captured frames of this graph over time";
|
|
737
|
-
lanes.style.cssText = "color:var(--pending);text-decoration:none;font-size:
|
|
776
|
+
lanes.style.cssText = "color:var(--pending);text-decoration:none;font-size:var(--t-body)";
|
|
738
777
|
row.appendChild(lanes);
|
|
739
778
|
tools.appendChild(row);
|
|
740
779
|
}
|
|
@@ -1210,7 +1249,7 @@ function renderDial() {
|
|
|
1210
1249
|
}
|
|
1211
1250
|
host.style.display = "flex";
|
|
1212
1251
|
const hint = document.createElement("span");
|
|
1213
|
-
hint.style.cssText = "font-size:
|
|
1252
|
+
hint.style.cssText = "font-size:var(--t-caption);color:var(--muted);align-self:center";
|
|
1214
1253
|
hint.textContent = "observe → reconcile → apply needs an environment — pick one in ⌘K (env: …)";
|
|
1215
1254
|
host.appendChild(hint);
|
|
1216
1255
|
// A pipeline run (#163) is env-less — its progress still belongs here.
|
|
@@ -1283,7 +1322,7 @@ function renderApplyPicker() {
|
|
|
1283
1322
|
wrap.style.gap = "6px";
|
|
1284
1323
|
const sel = document.createElement("select");
|
|
1285
1324
|
sel.style.cssText =
|
|
1286
|
-
"background:var(--
|
|
1325
|
+
"background:var(--well);color:var(--fg);border:1px solid var(--line);border-radius:var(--r-ctl);padding:3px 8px;font-size:var(--t-body)";
|
|
1287
1326
|
sel.add(new Option("all components", "all"));
|
|
1288
1327
|
for (const name of componentChoices) sel.add(new Option(applyOptionLabel(name), name));
|
|
1289
1328
|
const go = button("Apply →", "", () => {
|
|
@@ -1405,7 +1444,7 @@ function renderApplyProgress(state) {
|
|
|
1405
1444
|
const wrap = document.createElement("div");
|
|
1406
1445
|
wrap.style.cssText = "display:flex;flex-direction:column;gap:6px;width:100%;margin-top:4px";
|
|
1407
1446
|
const summary = document.createElement("div");
|
|
1408
|
-
summary.style.cssText = `font-size:
|
|
1447
|
+
summary.style.cssText = `font-size:var(--t-caption);color:${APPLY_STATUS_COLOR[state.status] || "var(--muted)"}`;
|
|
1409
1448
|
// A pipeline run (#163) reuses this whole panel — same shape, different
|
|
1410
1449
|
// executor — and says so instead of claiming to be an apply.
|
|
1411
1450
|
summary.textContent = `${state.kind || "apply"}: ${state.status}`;
|
|
@@ -1414,14 +1453,14 @@ function renderApplyProgress(state) {
|
|
|
1414
1453
|
const row = document.createElement("div");
|
|
1415
1454
|
row.style.cssText = "display:flex;align-items:center;gap:8px;flex-wrap:wrap";
|
|
1416
1455
|
const label = document.createElement("span");
|
|
1417
|
-
label.style.cssText = `font-size:
|
|
1456
|
+
label.style.cssText = `font-size:var(--t-caption);color:${APPLY_STATUS_COLOR[w.status] || "var(--muted)"};min-width:52px`;
|
|
1418
1457
|
label.textContent = `wave ${w.wave}`;
|
|
1419
1458
|
row.appendChild(label);
|
|
1420
1459
|
for (const cname of w.components) {
|
|
1421
1460
|
const c = (state.components || []).find((x) => x.component === cname) || { status: "pending" };
|
|
1422
1461
|
const color = APPLY_STATUS_COLOR[c.status] || "var(--muted)";
|
|
1423
1462
|
const chip = document.createElement("span");
|
|
1424
|
-
chip.style.cssText = `border:1px solid ${color};color:${color};border-radius:
|
|
1463
|
+
chip.style.cssText = `border:1px solid ${color};color:${color};border-radius:var(--r-ctl);padding:2px 8px;font-size:var(--t-caption)`;
|
|
1425
1464
|
const detail = [c.phase, c.step].filter(Boolean).join(" · ");
|
|
1426
1465
|
chip.textContent = `${cname}${detail ? " · " + detail : ""} (${c.status})`;
|
|
1427
1466
|
if (c.error) chip.title = c.error;
|
|
@@ -1657,6 +1696,7 @@ function render(ir, svg, m) {
|
|
|
1657
1696
|
// green — the SVG's own :root shadows behold's override within the graph subtree.
|
|
1658
1697
|
g.innerHTML = svg.replace(/:root\s*\{[^{}]*--pin-[^{}]*\}/g, "");
|
|
1659
1698
|
recolorNodesByCategory(ir); // #62: category-hued fills from the theme's full palette
|
|
1699
|
+
markStatusChanges(ir, componentStatus ? COMPONENT_STATUS_VAR : DRIFT_STATUS_VAR); // #229
|
|
1660
1700
|
const svgEl = g.querySelector("svg");
|
|
1661
1701
|
if (svgEl) {
|
|
1662
1702
|
// Drop pinhole's fixed pixel size so the viewBox drives sizing; behold then
|
|
@@ -1676,6 +1716,7 @@ function render(ir, svg, m) {
|
|
|
1676
1716
|
ensureBackToInfra(g);
|
|
1677
1717
|
wire(ir);
|
|
1678
1718
|
if (view.radial && !view.components && !view.logical) addRadialLabels(ir);
|
|
1719
|
+
applyLayout(); // #228: last, so the hand-placed deltas ride on top of every other pass
|
|
1679
1720
|
renderDial();
|
|
1680
1721
|
}
|
|
1681
1722
|
|
|
@@ -1833,6 +1874,11 @@ function ensureZoomControls(host) {
|
|
|
1833
1874
|
let py = 0;
|
|
1834
1875
|
host.addEventListener("mousedown", (e) => {
|
|
1835
1876
|
if (!vb) return;
|
|
1877
|
+
// #228: pan is the default on empty ground, but a node card (or a box's
|
|
1878
|
+
// title / resize handle) belongs to the layout drag — starting a pan too
|
|
1879
|
+
// would move the graph out from under the thing you grabbed. The layout
|
|
1880
|
+
// drag owns the panMoved latch for the rest of the gesture.
|
|
1881
|
+
if (layoutTargetOf(e)) return;
|
|
1836
1882
|
drag = true;
|
|
1837
1883
|
panMoved = false;
|
|
1838
1884
|
px = e.clientX;
|
|
@@ -1862,6 +1908,288 @@ function ensureZoomControls(host) {
|
|
|
1862
1908
|
});
|
|
1863
1909
|
}
|
|
1864
1910
|
|
|
1911
|
+
// --- Hand layout (#228): drag a node, resize a containment box -------------
|
|
1912
|
+
// dagre is a good first draft and a bad final layout. A pointer-drag on a card
|
|
1913
|
+
// writes a {dx,dy} for that `data-node-id`; a corner handle on a containment
|
|
1914
|
+
// box writes {dw,dh} (and its title drags the box). The deltas live in
|
|
1915
|
+
// localStorage per project + lens (web/layout-store.js) and are re-applied at
|
|
1916
|
+
// the end of every render(), so the graph underneath stays chant's and a
|
|
1917
|
+
// delta for a node that left the estate is simply not applied.
|
|
1918
|
+
//
|
|
1919
|
+
// What this does NOT do, said plainly rather than faked:
|
|
1920
|
+
// * a resized box does not reflow its children — that is dagre's job on the
|
|
1921
|
+
// next layout, and the reset control's tooltip says so;
|
|
1922
|
+
// * an edge touching a displaced node is redrawn as a STRAIGHT line between
|
|
1923
|
+
// its original anchor points, each shifted by its own node's delta. #228
|
|
1924
|
+
// accepts the straight-line fallback; spline re-routing is pinhole's job.
|
|
1925
|
+
// An edge with both ends where dagre put them keeps its bezier untouched.
|
|
1926
|
+
// * nothing is written to the server. The second tier of #228 (a
|
|
1927
|
+
// `.behold/layout.json` sidecar behind POST /api/layout, so a server-side
|
|
1928
|
+
// export honours the same deltas) is the follow-up half.
|
|
1929
|
+
let layoutIndex = null; // {nodes,boxes,edges} for the SVG currently on screen
|
|
1930
|
+
let layoutDeltas = {}; // the deltas in force for the current key
|
|
1931
|
+
let layoutDrag = null; // the gesture in flight
|
|
1932
|
+
let layoutWired = false;
|
|
1933
|
+
|
|
1934
|
+
/** The storage key for the project + lens on screen; null before /api/project lands. */
|
|
1935
|
+
function currentLayoutKey() {
|
|
1936
|
+
if (!projectInfo) return null;
|
|
1937
|
+
return layoutKey(projectKeyOf(projectInfo), lensKeyOf({ zoom: zoomValue(), radial: view.radial, stack: view.stack }));
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
/** First and last coordinate pair of a path `d` — pinhole's own edge anchors. */
|
|
1941
|
+
function pathAnchors(d) {
|
|
1942
|
+
const n = String(d || "").match(/-?\d*\.?\d+(?:e[-+]?\d+)?/gi);
|
|
1943
|
+
if (!n || n.length < 4) return null;
|
|
1944
|
+
return { sx: +n[0], sy: +n[1], ex: +n[n.length - 2], ey: +n[n.length - 1] };
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
/**
|
|
1948
|
+
* Wrap each containment box in a `<g data-layout-box>` and give it a corner
|
|
1949
|
+
* handle, once per rendered SVG.
|
|
1950
|
+
*
|
|
1951
|
+
* FRAGILE BY CONSTRUCTION, and knowingly so: pinhole's `Canvas.groupBox` emits
|
|
1952
|
+
* a bare `<rect rx=…>` immediately followed by its title `<text>`, as a direct
|
|
1953
|
+
* child of the `<svg>` — no group, no `data-group-id` to match on. So behold
|
|
1954
|
+
* matches the structure, exactly the way addGitlabWaveBadges already has to.
|
|
1955
|
+
* The discriminators: a positive `rx` (the two page-background rects have
|
|
1956
|
+
* none), a `<text>` as the next non-badge sibling, and svg-root parentage (a
|
|
1957
|
+
* card's rect lives inside `[data-node-id]`, an edge-label's inside its own
|
|
1958
|
+
* `<g>`). The real fix is upstream — a `data-group-id` on the box — and until
|
|
1959
|
+
* pinhole stamps one, prefer the attribute here the moment it exists.
|
|
1960
|
+
*/
|
|
1961
|
+
function wrapContainmentBoxes(svgEl) {
|
|
1962
|
+
const boxes = new Map();
|
|
1963
|
+
const handleSize = Math.max(12, Math.round((vbInit ? vbInit[2] : 1000) / 90));
|
|
1964
|
+
for (const rect of [...svgEl.children]) {
|
|
1965
|
+
if (rect.tagName.toLowerCase() !== "rect") continue;
|
|
1966
|
+
const x = parseFloat(rect.getAttribute("x"));
|
|
1967
|
+
const y = parseFloat(rect.getAttribute("y"));
|
|
1968
|
+
const w = parseFloat(rect.getAttribute("width"));
|
|
1969
|
+
const h = parseFloat(rect.getAttribute("height"));
|
|
1970
|
+
if (!(parseFloat(rect.getAttribute("rx")) > 0) || !(w > 0) || !(h > 0) || Number.isNaN(x) || Number.isNaN(y)) continue;
|
|
1971
|
+
// Collect rect → title, stepping over anything already stamped between
|
|
1972
|
+
// them (the GitLab wave badge), and bail at the next box or card.
|
|
1973
|
+
const members = [rect];
|
|
1974
|
+
let title = null;
|
|
1975
|
+
for (let el = rect.nextElementSibling; el; el = el.nextElementSibling) {
|
|
1976
|
+
const tag = el.tagName.toLowerCase();
|
|
1977
|
+
if (tag === "rect" || (tag === "g" && (el.hasAttribute("data-node-id") || el.hasAttribute("data-edge-from")))) break;
|
|
1978
|
+
members.push(el);
|
|
1979
|
+
if (tag === "text") {
|
|
1980
|
+
title = el;
|
|
1981
|
+
break;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
if (!title) continue;
|
|
1985
|
+
const id = `box:${(title.textContent || "").trim() || boxes.size}`;
|
|
1986
|
+
if (boxes.has(id)) continue;
|
|
1987
|
+
const g = document.createElementNS(SVGNS, "g");
|
|
1988
|
+
g.setAttribute("data-layout-box", id);
|
|
1989
|
+
rect.parentNode.insertBefore(g, rect);
|
|
1990
|
+
members.forEach((m) => g.appendChild(m));
|
|
1991
|
+
// The title doubles as the box's move handle — the interior stays pan
|
|
1992
|
+
// territory, which on a logical view is most of the canvas.
|
|
1993
|
+
title.setAttribute("data-layout-move", id);
|
|
1994
|
+
title.setAttribute("cursor", "move");
|
|
1995
|
+
const handle = document.createElementNS(SVGNS, "g");
|
|
1996
|
+
handle.setAttribute("data-layout-resize", id);
|
|
1997
|
+
handle.setAttribute("cursor", "nwse-resize");
|
|
1998
|
+
handle.setAttribute("opacity", "0"); // CSS reveals it on hover; a static export never shows it
|
|
1999
|
+
const grip = document.createElementNS(SVGNS, "rect");
|
|
2000
|
+
grip.setAttribute("width", String(handleSize));
|
|
2001
|
+
grip.setAttribute("height", String(handleSize));
|
|
2002
|
+
grip.setAttribute("rx", "3");
|
|
2003
|
+
grip.setAttribute("fill", "var(--focus)");
|
|
2004
|
+
const tip = document.createElementNS(SVGNS, "title");
|
|
2005
|
+
tip.textContent = "Drag to resize this box. Children don't move with it — that's the next layout's job.";
|
|
2006
|
+
handle.append(tip, grip);
|
|
2007
|
+
g.appendChild(handle);
|
|
2008
|
+
boxes.set(id, { g, rect, handle, x, y, w0: w, h0: h, size: handleSize });
|
|
2009
|
+
}
|
|
2010
|
+
return boxes;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
/** Park the corner handle at the box's current bottom-right. */
|
|
2014
|
+
function positionBoxHandle(b, w, h) {
|
|
2015
|
+
b.handle.setAttribute("transform", `translate(${b.x + w - b.size - 3}, ${b.y + h - b.size - 3})`);
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
/** Index the freshly rendered SVG: node groups, containment boxes, edge paths. */
|
|
2019
|
+
function indexLayout(svgEl) {
|
|
2020
|
+
const nodes = new Map();
|
|
2021
|
+
for (const el of svgEl.querySelectorAll("[data-node-id]")) {
|
|
2022
|
+
const id = el.getAttribute("data-node-id");
|
|
2023
|
+
if (!nodes.has(id)) nodes.set(id, { el, base: el.getAttribute("transform") || "" });
|
|
2024
|
+
}
|
|
2025
|
+
const edges = [];
|
|
2026
|
+
for (const g of svgEl.querySelectorAll("g[data-edge-from]")) {
|
|
2027
|
+
const paths = [...g.querySelectorAll("path")];
|
|
2028
|
+
if (!paths.length) continue;
|
|
2029
|
+
const d0 = paths[0].getAttribute("d");
|
|
2030
|
+
edges.push({ from: g.getAttribute("data-edge-from"), to: g.getAttribute("data-edge-to"), paths, d0, anchors: pathAnchors(d0) });
|
|
2031
|
+
}
|
|
2032
|
+
layoutIndex = { nodes, boxes: wrapContainmentBoxes(svgEl), edges };
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
/** Paint `layoutDeltas` onto the indexed SVG. Idempotent: always from the original. */
|
|
2036
|
+
function renderLayout() {
|
|
2037
|
+
if (!layoutIndex) return;
|
|
2038
|
+
for (const [id, n] of layoutIndex.nodes) {
|
|
2039
|
+
const d = layoutDeltas[id];
|
|
2040
|
+
const t = d && (d.dx || d.dy) ? `translate(${d.dx || 0}, ${d.dy || 0}) ${n.base}`.trim() : n.base;
|
|
2041
|
+
if (t) n.el.setAttribute("transform", t);
|
|
2042
|
+
else n.el.removeAttribute("transform");
|
|
2043
|
+
}
|
|
2044
|
+
for (const [id, b] of layoutIndex.boxes) {
|
|
2045
|
+
const d = layoutDeltas[id] || {};
|
|
2046
|
+
const w = Math.max(b.size * 3, b.w0 + (d.dw || 0));
|
|
2047
|
+
const h = Math.max(b.size * 3, b.h0 + (d.dh || 0));
|
|
2048
|
+
b.rect.setAttribute("width", String(w));
|
|
2049
|
+
b.rect.setAttribute("height", String(h));
|
|
2050
|
+
if (d.dx || d.dy) b.g.setAttribute("transform", `translate(${d.dx || 0}, ${d.dy || 0})`);
|
|
2051
|
+
else b.g.removeAttribute("transform");
|
|
2052
|
+
positionBoxHandle(b, w, h);
|
|
2053
|
+
}
|
|
2054
|
+
for (const e of layoutIndex.edges) {
|
|
2055
|
+
const a = layoutDeltas[e.from];
|
|
2056
|
+
const z = layoutDeltas[e.to];
|
|
2057
|
+
if ((!a && !z) || !e.anchors) {
|
|
2058
|
+
if (e.paths[0].getAttribute("d") !== e.d0) e.paths.forEach((p) => p.setAttribute("d", e.d0));
|
|
2059
|
+
continue;
|
|
2060
|
+
}
|
|
2061
|
+
const { sx, sy, ex, ey } = e.anchors;
|
|
2062
|
+
const d = `M ${sx + ((a && a.dx) || 0)} ${sy + ((a && a.dy) || 0)} L ${ex + ((z && z.dx) || 0)} ${ey + ((z && z.dy) || 0)}`;
|
|
2063
|
+
e.paths.forEach((p) => p.setAttribute("d", d));
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
/** Re-index the SVG, load this lens's deltas, paint them. Called from render(). */
|
|
2068
|
+
function applyLayout() {
|
|
2069
|
+
const svgEl = currentSvg();
|
|
2070
|
+
const host = document.getElementById("graph");
|
|
2071
|
+
if (!svgEl || !host) return;
|
|
2072
|
+
indexLayout(svgEl);
|
|
2073
|
+
const key = currentLayoutKey();
|
|
2074
|
+
// Stale ids are dropped on apply, not on write: a lens the user hasn't
|
|
2075
|
+
// opened in a while shouldn't have its deltas quietly deleted because this
|
|
2076
|
+
// render happened to be a different projection of the same estate.
|
|
2077
|
+
layoutDeltas = key ? applicable(readLayout(localStorage, key), [...layoutIndex.nodes.keys(), ...layoutIndex.boxes.keys()]) : {};
|
|
2078
|
+
renderLayout();
|
|
2079
|
+
ensureLayoutReset(host);
|
|
2080
|
+
ensureLayoutDrag(host);
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
/** The grabbable thing at or above `el`, if any. */
|
|
2084
|
+
function layoutTargetIn(el) {
|
|
2085
|
+
if (!el || typeof el.closest !== "function") return null;
|
|
2086
|
+
const resize = el.closest("[data-layout-resize]");
|
|
2087
|
+
if (resize) return { kind: "resize", id: resize.getAttribute("data-layout-resize") };
|
|
2088
|
+
const move = el.closest("[data-layout-move]");
|
|
2089
|
+
if (move) return { kind: "move", id: move.getAttribute("data-layout-move") };
|
|
2090
|
+
const node = el.closest("[data-node-id]");
|
|
2091
|
+
if (node) return { kind: "move", id: node.getAttribute("data-node-id") };
|
|
2092
|
+
return null;
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2095
|
+
/** What (if anything) a pointerdown grabbed. Also the pan handler's bail test. */
|
|
2096
|
+
function layoutTargetOf(e) {
|
|
2097
|
+
const direct = layoutTargetIn(e.target);
|
|
2098
|
+
if (direct) return direct;
|
|
2099
|
+
// An edge can swallow the grab: wireEdgeHighlight raises every edge on a
|
|
2100
|
+
// hovered card to the top of the SVG, and pinhole's 14-wide transparent
|
|
2101
|
+
// hit-path is anchored at the card's own centre — so by the time the pointer
|
|
2102
|
+
// is down, the edge you just lit is lying across the card you meant to move.
|
|
2103
|
+
// Look through the stack for the card underneath instead of giving up.
|
|
2104
|
+
if (!e.target || typeof e.target.closest !== "function" || !e.target.closest("g[data-edge-from]")) return null;
|
|
2105
|
+
for (const el of document.elementsFromPoint(e.clientX, e.clientY)) {
|
|
2106
|
+
const t = layoutTargetIn(el);
|
|
2107
|
+
if (t) return t;
|
|
2108
|
+
}
|
|
2109
|
+
return null;
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
/** Screen pixels → viewBox units at the current zoom. */
|
|
2113
|
+
function userPerPixel(svgEl) {
|
|
2114
|
+
const m = svgEl.getScreenCTM && svgEl.getScreenCTM();
|
|
2115
|
+
if (m && m.a && m.d) return { x: 1 / m.a, y: 1 / m.d };
|
|
2116
|
+
const r = svgEl.getBoundingClientRect();
|
|
2117
|
+
return vb && r.width && r.height ? { x: vb[2] / r.width, y: vb[3] / r.height } : { x: 1, y: 1 };
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
function ensureLayoutDrag(host) {
|
|
2121
|
+
if (layoutWired) return;
|
|
2122
|
+
layoutWired = true;
|
|
2123
|
+
host.addEventListener("pointerdown", (e) => {
|
|
2124
|
+
if (e.button !== 0 || !layoutIndex) return;
|
|
2125
|
+
const t = layoutTargetOf(e);
|
|
2126
|
+
if (!t || !currentSvg()) return;
|
|
2127
|
+
layoutDrag = { ...t, x0: e.clientX, y0: e.clientY, base: layoutDeltas[t.id] || {}, moved: false };
|
|
2128
|
+
// The same latch pan uses (wire()'s click-inspect bails on it): claim it on
|
|
2129
|
+
// grab so a drag is never also a click, and so the NEXT plain click on a
|
|
2130
|
+
// node isn't swallowed by a stale `true` from the gesture before it.
|
|
2131
|
+
panMoved = false;
|
|
2132
|
+
// Deliberately no preventDefault(): cancelling pointerdown suppresses the
|
|
2133
|
+
// compatibility mouse events, and click-inspect rides on those. The pan is
|
|
2134
|
+
// held off by its own guard instead, and the text selection a drag would
|
|
2135
|
+
// otherwise smear across the graph by `user-select: none` on the SVG.
|
|
2136
|
+
});
|
|
2137
|
+
window.addEventListener("pointermove", (e) => {
|
|
2138
|
+
if (!layoutDrag) return;
|
|
2139
|
+
const svgEl = currentSvg();
|
|
2140
|
+
if (!svgEl) return;
|
|
2141
|
+
const px = e.clientX - layoutDrag.x0;
|
|
2142
|
+
const py = e.clientY - layoutDrag.y0;
|
|
2143
|
+
if (!layoutDrag.moved && Math.abs(px) + Math.abs(py) <= 3) return;
|
|
2144
|
+
layoutDrag.moved = true;
|
|
2145
|
+
panMoved = true;
|
|
2146
|
+
const s = userPerPixel(svgEl);
|
|
2147
|
+
const dx = px * s.x;
|
|
2148
|
+
const dy = py * s.y;
|
|
2149
|
+
const b = layoutDrag.base;
|
|
2150
|
+
const next =
|
|
2151
|
+
layoutDrag.kind === "resize"
|
|
2152
|
+
? { dx: b.dx || 0, dy: b.dy || 0, dw: (b.dw || 0) + dx, dh: (b.dh || 0) + dy }
|
|
2153
|
+
: { dx: (b.dx || 0) + dx, dy: (b.dy || 0) + dy, dw: b.dw || 0, dh: b.dh || 0 };
|
|
2154
|
+
layoutDeltas = setDelta(layoutDeltas, layoutDrag.id, next);
|
|
2155
|
+
renderLayout();
|
|
2156
|
+
});
|
|
2157
|
+
window.addEventListener("pointerup", () => {
|
|
2158
|
+
if (!layoutDrag) return;
|
|
2159
|
+
const moved = layoutDrag.moved;
|
|
2160
|
+
layoutDrag = null;
|
|
2161
|
+
if (!moved) return;
|
|
2162
|
+
const key = currentLayoutKey();
|
|
2163
|
+
if (key) writeLayout(localStorage, key, layoutDeltas);
|
|
2164
|
+
ensureLayoutReset(document.getElementById("graph"));
|
|
2165
|
+
});
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
/** The "↺ layout" control beside ⤢ fit — shown only while something is hand-placed. */
|
|
2169
|
+
function ensureLayoutReset(host) {
|
|
2170
|
+
if (!host) return;
|
|
2171
|
+
let btn = document.getElementById("layout-reset");
|
|
2172
|
+
if (!btn || btn.parentElement !== host) {
|
|
2173
|
+
btn = document.createElement("button");
|
|
2174
|
+
btn.id = "layout-reset";
|
|
2175
|
+
btn.textContent = "↺ layout";
|
|
2176
|
+
btn.title =
|
|
2177
|
+
"Drop the hand-placed layout for this project + this lens and go back to dagre's. " +
|
|
2178
|
+
"(A resized box never reflows what's inside it — only the next layout does that.)";
|
|
2179
|
+
btn.addEventListener("click", (e) => {
|
|
2180
|
+
e.stopPropagation();
|
|
2181
|
+
const key = currentLayoutKey();
|
|
2182
|
+
if (key) clearLayout(localStorage, key);
|
|
2183
|
+
layoutDeltas = {};
|
|
2184
|
+
renderLayout();
|
|
2185
|
+
ensureLayoutReset(host);
|
|
2186
|
+
nowline("↺ layout reset — back to dagre's placement");
|
|
2187
|
+
});
|
|
2188
|
+
host.appendChild(btn);
|
|
2189
|
+
}
|
|
2190
|
+
btn.style.display = isEmpty(layoutDeltas) ? "none" : "";
|
|
2191
|
+
}
|
|
2192
|
+
|
|
1865
2193
|
// Precondition-failure codes (#72) → a short, human title for the entry/error
|
|
1866
2194
|
// screen below. Mirrors every `code` a read route's structured error can
|
|
1867
2195
|
// carry (src/server.ts RouteErrorCode: chant.ts's lint/not-installed/eval,
|
|
@@ -2238,7 +2566,7 @@ function showToast(msg, ok) {
|
|
|
2238
2566
|
}
|
|
2239
2567
|
const t = document.createElement("div");
|
|
2240
2568
|
const color = ok ? "var(--managed)" : "var(--degraded)";
|
|
2241
|
-
t.style.cssText = `background:var(--panel);color:var(--fg);border:1px solid ${color};border-left:4px solid ${color};border-radius:
|
|
2569
|
+
t.style.cssText = `background:var(--panel);color:var(--fg);border:1px solid ${color};border-left:4px solid ${color};border-radius:var(--r-ctl);padding:8px 12px;font-size:var(--t-body);box-shadow:0 6px 18px color-mix(in srgb, var(--shadow) 50%, transparent);cursor:pointer;white-space:pre-wrap`;
|
|
2242
2570
|
t.textContent = msg;
|
|
2243
2571
|
t.onclick = () => t.remove();
|
|
2244
2572
|
host.appendChild(t);
|
|
@@ -2319,7 +2647,7 @@ async function openRollback(btn) {
|
|
|
2319
2647
|
wrap.style.cssText = "display:flex;gap:6px;align-self:center";
|
|
2320
2648
|
const sel = document.createElement("select");
|
|
2321
2649
|
sel.style.cssText =
|
|
2322
|
-
"background:var(--
|
|
2650
|
+
"background:var(--well);color:var(--fg);border:1px solid var(--line);border-radius:var(--r-ctl);padding:4px 8px;font-size:var(--t-body);max-width:340px";
|
|
2323
2651
|
for (const c of commits) sel.add(new Option(`${c.sha} · ${c.subject} (${c.date})`, c.sha));
|
|
2324
2652
|
const go = button("Roll back →", "", () => {
|
|
2325
2653
|
const to = sel.value;
|
|
@@ -2363,7 +2691,7 @@ async function initActions() {
|
|
|
2363
2691
|
const pill = document.createElement("span");
|
|
2364
2692
|
pill.textContent = `● static snapshot${manifest && manifest.capturedAt ? " · " + manifest.capturedAt.slice(0, 16).replace("T", " ") : ""}`;
|
|
2365
2693
|
pill.title = "An exported, read-only snapshot — no live observe or deploy.";
|
|
2366
|
-
pill.style.cssText = "align-self:center;font-
|
|
2694
|
+
pill.style.cssText = "align-self:center;font:var(--t-caption)/1.4 var(--font-mono);color:var(--muted);border:1px solid var(--line);border-radius:var(--r-ctl);padding:2px 8px";
|
|
2367
2695
|
bar.appendChild(pill);
|
|
2368
2696
|
previewMode = true;
|
|
2369
2697
|
return; // nothing else in the bar is a read
|
|
@@ -2395,7 +2723,7 @@ async function initActions() {
|
|
|
2395
2723
|
local.emulators.map((e) => `${e.lexicon} ${e.name} @ ${e.endpoint}`).join("; ") +
|
|
2396
2724
|
". Deploys and the overlay observe them — no cloud creds.";
|
|
2397
2725
|
pill.style.cssText =
|
|
2398
|
-
"align-self:center;font-
|
|
2726
|
+
"align-self:center;font:var(--t-caption)/1.4 var(--font-mono);color:var(--managed);border:1px solid var(--managed);border-radius:var(--r-ctl);padding:2px 8px";
|
|
2399
2727
|
bar.appendChild(pill);
|
|
2400
2728
|
}
|
|
2401
2729
|
// Auto-sync banner (#29) — make an active self-heal loop visible, not silent.
|
|
@@ -2404,7 +2732,7 @@ async function initActions() {
|
|
|
2404
2732
|
pill.textContent = `⟳ auto-sync: ${autoSync}`;
|
|
2405
2733
|
pill.title = `On polled drift, behold triggers the ${autoSync === "apply" ? "ApplyOp (heal)" : "ReconcileOp (adopt)"}. Gated applies still wait for Approve.`;
|
|
2406
2734
|
pill.style.cssText =
|
|
2407
|
-
"align-self:center;font-
|
|
2735
|
+
"align-self:center;font:var(--t-caption)/1.4 var(--font-mono);color:var(--pending);border:1px solid var(--pending);border-radius:var(--r-ctl);padding:2px 8px";
|
|
2408
2736
|
bar.appendChild(pill);
|
|
2409
2737
|
}
|
|
2410
2738
|
opsApply = ops.find((o) => o.kind === "apply") ?? null;
|
|
@@ -2451,7 +2779,7 @@ async function initActions() {
|
|
|
2451
2779
|
// its deploy path is Apply all, not committed Ops).
|
|
2452
2780
|
if (ops.length === 0 && !previewMode && !opsInitialEnv) {
|
|
2453
2781
|
const hint = document.createElement("span");
|
|
2454
|
-
hint.style.cssText = "color:var(--muted);font-size:
|
|
2782
|
+
hint.style.cssText = "color:var(--muted);font-size:var(--t-caption);align-self:center";
|
|
2455
2783
|
hint.textContent = "no Ops — commit an *.op.ts (ApplyOp / ReconcileOp / any deploy Op) to act";
|
|
2456
2784
|
hint.title = "behold triggers committed Ops on your executor. Add one to enable Deploy / Adopt / Run.";
|
|
2457
2785
|
bar.appendChild(hint);
|
|
@@ -2520,7 +2848,7 @@ events.addEventListener("pr", (e) => {
|
|
|
2520
2848
|
slot.id = "pr-link";
|
|
2521
2849
|
slot.target = "_blank";
|
|
2522
2850
|
slot.rel = "noopener";
|
|
2523
|
-
slot.style.cssText = "color:var(--managed);text-decoration:none;font-size:
|
|
2851
|
+
slot.style.cssText = "color:var(--managed);text-decoration:none;font-size:var(--t-body);align-self:center";
|
|
2524
2852
|
document.getElementById("actions").after(slot);
|
|
2525
2853
|
}
|
|
2526
2854
|
slot.href = url;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" viewBox="0 0 581 747"><path id="cncf-argo-a" fill="#fff" d="M336.76 437.61c0 28.31-18.83 43.36-49.29 43.36-30.45 0-47.2-17.84-47.2-43.36 0 0 16.75 23.65 47.2 23.65 30.46 0 49.3-23.65 49.3-23.65Z"/><path fill="#E2F5FC" d="M290.5 547.98c148.47 0 268.84-120.45 268.84-269.04 0-148.58-120.37-269.03-268.84-269.03-148.47 0-268.84 120.45-268.84 269.03 0 148.59 120.37 269.04 268.84 269.04Z"/><path fill="#CDECF6" d="M290.5 504.04c121.36 0 219.74-98.45 219.74-219.9S411.86 64.24 290.5 64.24c-121.36 0-219.74 98.45-219.74 219.9s98.38 219.9 219.74 219.9Z"/><path fill="#fff" d="M208.31 91.51a12.98 12.98 0 1 0 0-25.96 12.98 12.98 0 0 0 0 25.96Zm-96.57 325.82a4.5 4.5 0 1 0 7.08-5.54c-87.8-112.21-37.15-257.65 62.5-314.74a4.5 4.5 0 0 0-4.47-7.8C73.23 148.6 20.03 300.12 111.74 417.33Z"/><path fill="#B5D2F3" d="M19.26 225.54a3.5 3.5 0 1 0-7 0h7Zm-7 105.38a3.5 3.5 0 1 0 7 0h-7Zm555.07-105.88a3.5 3.5 0 1 0-7 0h7Zm-7 105.38a3.5 3.5 0 1 0 7 0h-7ZM289.79 555.97c153.28 0 277.54-124.35 277.54-277.73h-7c0 149.52-121.13 270.73-270.54 270.73v7Zm277.54-277.73C567.33 124.84 443.07.5 289.79.5v7c149.41 0 270.54 121.21 270.54 270.74h7ZM289.79.5C136.51.5 12.26 124.85 12.26 278.24h7C19.26 128.7 140.38 7.5 289.79 7.5v-7ZM12.26 278.24c0 153.38 124.25 277.73 277.53 277.73v-7c-149.4 0-270.53-121.2-270.53-270.73h-7Zm0-52.7v105.38h7V225.54h-7Zm548.07-.5v105.38h7V225.04h-7Z"/><path fill="#B5D2F3" d="M21.66 225.73a10.84 10.84 0 1 0-21.66 0v106.43a10.84 10.84 0 1 0 21.66 0V225.73Zm559.34 0a10.84 10.84 0 1 0-21.66 0v106.43a10.84 10.84 0 1 0 21.66 0V225.73Z"/><path fill="#FE733E" d="M171.17 687.76c12.53-5.1 9.98-10.2 9.98-12.74l-6.1-92.55-5.37-46.3-8.12-289.07c0-68.6 50.73-132.72 127.3-132.72s130.76 61.71 130.88 132.77c-2.2 137.24-5.9 189.47-11.07 288.02-.63 13.47-2.38 33.86-2.96 46.32-2.88 61.66-6.14 91.87-6.14 93.53 0 2.55-2.54 7.64 9.98 12.74 12.52 5.1 41.46 11.71 41.46 13.33 0 1.6-48.89 0-48.89 0-28.02 0-28.02-20.98-28.02-26.07 0-5.1-7.64-92.6-7.64-92.6l-2.55 112.99c0 5.1 2.55 12.74 20.38 17.84 0 0 38.91 5.89 38.91 8.01 0 2.13-46.55 0-46.55 0-35.45 0-35.45-20.75-35.45-20.75l-7.64-92.6S331 700.5 331 713.24c0 9.99 1.73 17.63 29.54 22.73 13.43 3.73 40.54 8.35 40.54 10.2 0 1.85-61.86 0-61.86 0-33.11-2.55-36.24-25.5-36.24-25.5l-12.55-46.14-12.5 46.15s-5.09 22.94-38.2 25.49c0 0-56.17 1.85-56.17 0s22.5-5.99 36.81-10.2c19.36-5.69 29.55-12.74 29.55-22.73 0-12.74-2.55-105.35-2.55-105.35l-7.64 92.6s0 22.74-35.45 22.74c0 0-50.5.15-50.5-1.98 0-2.12 42.64-8 42.64-8 17.83-5.1 20.38-12.75 20.38-17.85l-2.55-113s-7.64 87.5-7.64 92.6c0 5.1 0 28.05-28.02 28.05 0 0-47.13-2.33-47.13-3.95 0-1.6 27.18-6.25 39.7-11.35Z"/><path fill="#FE6446" d="M169.68 536.16s-5.23 12.8-17.05 19.7c-11.81 6.9-25.51 9.14-38.4 10.84 0 0 17.72 8.87 39.39 6.9 13.58-1.1 19.28 2.36 21.42 8.87l-5.36-46.3Zm238.99-.99s7.63 12.8 19.45 19.7c11.82 6.9 25.51 9.15 38.4 10.85 0 0-17.72 8.87-39.38 6.9-13.58-1.1-19.29 2.35-21.43 8.87l2.96-46.32Z"/><path fill="#FE6446" d="m408.81 533 .99-16.02c-62.56 29.54-120.7 26.43-120.7 26.43s-58.49 2.45-119.92-26.57l.4 15.57s43.82 26.94 119.52 26.94c75.7 0 119.71-26.35 119.71-26.35Z" opacity=".3"/><path fill="#FEA777" d="M238.78 194.25a17.84 17.84 0 1 0-.01-35.67 17.84 17.84 0 0 0 .01 35.67Z" opacity=".5"/><path fill="#FE6B3C" d="M419.5 249.06s1.88-22.34-7.88-48.94c-26.77-73.01-92.56-87.71-128.02-85.64 0 0 50.28 23.76 52.61 99.8 1.06 33.72 1.06 34.78 1.06 34.78h82.23Z"/><use xlink:href="#cncf-argo-a"/><use xlink:href="#cncf-argo-a"/><path fill="#fff" d="M336.76 437.61c0 28.31-11.39 72.92-49.29 72.92s-47.2-47.4-47.2-72.92c0 0 0 43.36 47.2 43.36 51.62 0 49.3-43.36 49.3-43.36Z"/><path fill="#070909" d="M336.76 437.61c0 28.31-11.39 72.92-49.29 72.92s-47.2-47.4-47.2-72.92c0 0 0 43.36 47.2 43.36 51.62 0 49.3-43.36 49.3-43.36Z"/><path fill="#FE6446" d="M197.93 394.25a77.82 77.82 0 0 0 77.8-77.85c0-43-34.83-77.85-77.8-77.85a77.82 77.82 0 0 0-77.8 77.85c0 43 34.84 77.85 77.8 77.85Z"/><path fill="#fff" d="M197.73 378.32a60.94 60.94 0 0 0 60.92-60.96 60.94 60.94 0 0 0-60.92-60.97 60.94 60.94 0 0 0-60.92 60.97 60.94 60.94 0 0 0 60.92 60.96Z"/><path fill="#090B0B" d="M195.96 325.27a18.72 18.72 0 1 0-.01-37.44 18.72 18.72 0 0 0 .01 37.44Z"/><path fill="#FE6446" d="M381.1 394.25a77.82 77.82 0 0 0 77.79-77.85c0-43-34.83-77.85-77.8-77.85a77.82 77.82 0 0 0-77.79 77.85c0 43 34.83 77.85 77.8 77.85Z"/><path fill="#fff" d="M378 378.21a60.94 60.94 0 0 0 60.93-60.96A60.94 60.94 0 0 0 378 256.29a60.94 60.94 0 0 0-60.92 60.96A60.94 60.94 0 0 0 378 378.21Z"/><path fill="#090B0B" d="M379.13 325.27a18.72 18.72 0 1 0-.02-37.44 18.72 18.72 0 0 0 .01 37.44Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="48.00 -2.25 262.50 364.00"><defs><style>.cncf-flux-cls-1{fill:#326ce5}.cncf-flux-cls-3{fill:none}</style></defs><path d="M59.72393 97.77847a10.18251 10.18251 0 0 1 0-17.07393l114.0703-74.16023a10.18258 10.18258 0 0 1 11.10024 0l114.07029 74.16023a10.1825 10.1825 0 0 1 0 17.07394l-114.07029 74.16021a10.18254 10.18254 0 0 1-11.10024 0z" class="cncf-flux-cls-1"/><path fill="#c1d2f7" d="M197.35565 110.866h7.91277a6.00326 6.00326 0 0 0 5.19908-9.005l-25.92381-44.902a6.00355 6.00355 0 0 0-10.39838 0l-25.924 44.902a6.00326 6.00326 0 0 0 5.19905 9.005h7.913a6.0034 6.0034 0 0 1 6.00341 6.0034v51.2563l5.31037 3.45252a12.28743 12.28743 0 0 0 13.39445 0l5.31062-3.45252v-51.25628a6.0034 6.0034 0 0 1 6.0034-6.00341z"/><path d="M173.79348 353.27108a10.12828 10.12828 0 0 0 3.45643 1.402c-2.17549-1.2312-4.38727-2.37429-6.62269-3.46036zm-6.45667-161.19546l-11.3157 7.35661a110.993 110.993 0 0 0 11.31571 6.5997zm24.01537 23.71607c9.73858 3.11505 19.81317 5.64851 30.10973 8.18655 10.92032 2.69182 21.97355 5.42717 32.81792 9.00839l-35.41606-23.02482a215.88133 215.88133 0 0 1-27.51161-9.41007zm0 62.19159v.58577c0 2.56929-2.68787 4.65195-6.00338 4.65195h-12.00855c-3.31549 0-6.00338-2.08266-6.00338-4.65195v-6.60473c-24.90538-6.40209-49.87294-14.48506-70.85945-33.8211L81.94819 247.589c22.46761 22.0509 50.27893 28.93291 79.71441 36.1886 27.17852 6.69856 55.18051 13.65144 78.68557 33.44222l14.67907-9.54334c-18.53142-16.50431-40.40962-23.68778-63.67506-29.6932zm-98.03756 22.96639l38.90829 25.29525c20.06438 5.11336 40.20029 11.24773 58.311 23.36044l14.90023-9.687c-19.7518-13.6724-42.5505-19.3134-66.41889-25.197-15.28704-3.76779-30.83479-7.6166-45.70063-13.77169zm74.02219-82.25413a124.3199 124.3199 0 0 1-21.53392-12.62006l-14.80531 9.62521a124.54057 124.54057 0 0 0 36.33923 18.708zm51.41006 16.29412c-9.1062-2.24474-18.30362-4.52388-27.39469-7.29853v13.68209q5.051 1.2853 10.17672 2.53817c29.93438 7.37818 60.8879 15.00885 85.70767 39.82861.60979.60979 1.16261 1.23989 1.752 1.85715l9.97427-6.48445a10.10425 10.10425 0 0 0 3.47529-3.79928c-1.06644-1.17252-2.144-2.34132-3.28875-3.48612-22.58513-22.5853-50.66938-29.50856-80.40251-36.83764zm-19.93295 19.93298q-3.72217-.91747-7.46168-1.85484v13.20974c25.81676 6.56181 51.80263 14.68843 73.4551 35.04069l14.52114-9.44055c-.03854-.03875-.07256-.07916-.11131-.11792-22.58546-22.58524-50.66975-29.50848-80.40325-36.83712zm-31.47711-8.58681c-16.28-5.27813-32.11777-12.39682-46.344-24.13081l-14.68176 9.5451c17.87023 15.55727 38.7844 22.67266 61.02572 28.50068z" class="cncf-flux-cls-3"/><path d="M73.24049 254.95972c-.348-.348-.6585-.70949-.99967-1.05976l-12.51495 8.13648a10.16548 10.16548 0 0 0-1.64428 1.3968c1.05336 1.15677 2.11561 2.31024 3.24544 3.44 22.5852 22.58519 50.66968 29.50838 80.40322 36.83688 25.3425 6.24691 51.40113 12.71661 73.86454 29.60253l14.80574-9.62562c-20.86424-16.41993-45.53021-22.50891-71.45287-28.898-29.93385-7.37888-60.88738-15.00944-85.70717-39.82931z" class="cncf-flux-cls-3"/><path d="M218.86377 209.9618l-27.51159-17.886v8.4759a215.88 215.88 0 0 0 27.51159 9.4101zm-27.51159 5.82989v11.89938c9.09108 2.77471 18.28849 5.05388 27.39469 7.29853 29.73311 7.32909 57.81738 14.25232 80.40261 36.83773 1.14474 1.14474 2.22232 2.31354 3.28875 3.48611a10.19327 10.19327 0 0 0-3.4753-13.27711l-44.6831-29.04976c-10.84437-3.58121-21.89768-6.31656-32.81794-9.00838-10.29656-2.53799-20.37113-5.07145-30.10971-8.1865zm-24.01537-9.75969a110.99292 110.99292 0 0 1-11.31571-6.59969l-10.21821 6.6432a124.31932 124.31932 0 0 0 21.53392 12.62007zm34.19212 37.87941q-5.12528-1.26352-10.17673-2.53816v11.6946q3.73686.938 7.46168 1.85485c29.73352 7.32863 57.8178 14.25187 80.40318 36.83709.03876.03876.07277.07916.11132.11792l9.66023-6.28051c-.58945-.61726-1.14225-1.24733-1.752-1.85715-24.81978-24.81979-55.7733-32.45048-85.70768-39.82864zm-34.19212-9.50272a124.54057 124.54057 0 0 1-36.33923-18.708l-10.00473 6.50436c14.22612 11.734 30.06393 18.85268 46.344 24.1308zm0 25.84203c-22.24132-5.828-43.1555-12.94341-61.02572-28.5006l-9.8338 6.39315c20.98652 19.336 45.95407 27.41893 70.85947 33.8211zm24.01537 17.73256c23.26546 6.00539 45.14367 13.18886 63.67506 29.69312l9.78-6.35823c-21.65249-20.35225-47.63835-28.47893-73.45509-35.04068zM81.94813 247.589l-9.70729 6.311c.34117.35032.65166.71178.99967 1.05976 24.81977 24.81979 55.77329 32.45043 85.70706 39.82925 25.92266 6.38909 50.58863 12.47807 71.45288 28.898l9.94772-6.46724c-23.50506-19.79078-51.507-26.74365-78.68557-33.44222-29.43548-7.25569-57.2468-14.1377-79.71447-36.18855zM61.327 266.87321c-1.12983-1.12983-2.19209-2.28328-3.24545-3.44a10.1544 10.1544 0 0 0 1.64428 15.67957l33.5887 21.83694c14.86583 6.15509 30.41359 10.0039 45.70058 13.77166 23.8684 5.88357 46.66708 11.52464 66.4189 25.197l10.1606-6.6057c-22.46332-16.88587-48.522-23.35562-73.86447-29.60253-29.73343-7.32851-57.81791-14.25175-80.40314-36.83694zm109.30024 84.33948c2.2354 1.0861 4.44718 2.22919 6.62269 3.46036a10.16012 10.16012 0 0 0 7.64543-1.402l5.63858-3.66577c-18.11065-12.11266-38.24653-18.247-58.31095-23.36044z" class="cncf-flux-cls-1"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg id="cncf-helm-Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cncf-helm-cls-1{fill:#0f1689;}</style></defs><path class="cncf-helm-cls-1" d="M136.52938,121.13478c-.572-.54252-1.19462-1.12636-1.81-1.71761-12.61677-12.12115-22.38092-26.13637-28.279-42.702-1.65073-4.63637-2.89692-9.36515-2.67587-14.35871.021-.4739.01959-.94915.05226-1.42214.445-6.44594,4.75912-9.70322,11.05839-8.17669a27.325,27.325,0,0,1,5.73149,2.19653c6.89022,3.45538,12.5062,8.56359,17.67051,14.16571a112.52651,112.52651,0,0,1,21.722,33.42965,8.29635,8.29635,0,0,0,.38946.861c.07116.12855.22232.21282.55927.51883A176.357,176.357,0,0,1,241.968,79.06864c-.17651-.8761-.28195-1.54571-.44772-2.2a112.49436,112.49436,0,0,1-2.65292-36.95637,84.07478,84.07478,0,0,1,4.44444-21.76378,31.32555,31.32555,0,0,1,5.47651-10.17139,15.687,15.687,0,0,1,3.16336-2.82149,7.026,7.026,0,0,1,8.03255-.056,17.27854,17.27854,0,0,1,5.8402,6.73185A53.05435,53.05435,0,0,1,271.08657,26.508a112.50469,112.50469,0,0,1,2.12263,33.00356,95.59806,95.59806,0,0,1-3.49052,19.91081c7.12171,1.31193,14.20955,2.32869,21.1473,3.97713a186.37909,186.37909,0,0,1,20.44069,6.0033A188.31671,188.31671,0,0,1,331.0769,97.9721c6.34538,3.16433,12.38553,6.94066,18.71757,10.53829.20571-.433.50439-.94982.706-1.50212A108.65959,108.65959,0,0,1,383.40128,60.246a37.75787,37.75787,0,0,1,11.822-6.883,17.24558,17.24558,0,0,1,3.67827-.84512c6.264-.71729,8.89351,3.2244,9.35653,7.93183a29.94372,29.94372,0,0,1-.77381,10.35466A87.90551,87.90551,0,0,1,396.75426,95.492c-6.79016,10.97178-14.85015,20.85494-25.09307,28.83042-.30234.2354-.56784.51814-1.07988.99029a177.77993,177.77993,0,0,1,26.59293,30.88244,10.96227,10.96227,0,0,1-1.689.29762c-10.59546.015-21.1911-.01829-31.78622.04607a4.004,4.004,0,0,1-3.17246-1.69,147.87522,147.87522,0,0,0-88.17776-46.54846,143.35862,143.35862,0,0,0-30.27955-1.16923,146.40735,146.40735,0,0,0-82.53728,31.81054,140.06663,140.06663,0,0,0-16.97616,15.84186,4.72839,4.72839,0,0,1-3.86326,1.75742c-10.12056-.07028-20.24188-.035-30.36293-.03495h-2.15212c.618-2.408,6.84026-10.93786,13.88352-18.55281C125.31349,132.2744,130.87768,126.8839,136.52938,121.13478Z"/><path class="cncf-helm-cls-1" d="M394.52934,347.9123a176.63854,176.63854,0,0,1-23.97343,27.16338c.70941.59068,1.28594,1.07041,1.86212,1.55057A108.31456,108.31456,0,0,1,406.10131,424.772a34.61831,34.61831,0,0,1,2.202,14.42026,14.88544,14.88544,0,0,1-.74786,3.69206,7.20762,7.20762,0,0,1-8.15793,5.02308,22.23329,22.23329,0,0,1-6.76276-2.00629,51.23237,51.23237,0,0,1-9.18151-5.8151,107.59183,107.59183,0,0,1-32.936-46.7072c-.18746-.51334-.39218-1.0204-.72243-1.87691a194.65008,194.65008,0,0,1-25.01223,14.00774,181.66925,181.66925,0,0,1-26.6869,9.72442,187.55649,187.55649,0,0,1-28.3045,5.38805c.16807.84015.26446,1.5098.43745,2.15907a109.172,109.172,0,0,1,2.9708,36.44311,80.804,80.804,0,0,1-4.42286,22.4773,78.24971,78.24971,0,0,1-4.16475,8.74473,13.39,13.39,0,0,1-2.33865,2.97083c-3.98009,4.109-8.73225,4.144-12.61157-.07366a27.28012,27.28012,0,0,1-3.907-5.61776c-3.07685-5.77569-4.6604-12.056-5.791-18.46021a116.86329,116.86329,0,0,1-1.35893-26.465,94.4795,94.4795,0,0,1,2.88466-19.18513c.14009-.53269.268-1.0696.37134-1.61034.02629-.13754-.06342-.2973-.17067-.73825a176.12108,176.12108,0,0,1-80.96855-24.99386c-.40992.90921-.76206,1.67473-1.10168,2.44579a110.47729,110.47729,0,0,1-30.90112,41.42041,38.16071,38.16071,0,0,1-12.04706,6.95909,12.08987,12.08987,0,0,1-6.51516.70023,7.11858,7.11858,0,0,1-5.40329-4.4892c-1.41614-3.424-1.16526-6.985-.68438-10.51691a55.45267,55.45267,0,0,1,4.30768-14.25037A112.49985,112.49985,0,0,1,134.88761,380.779c.459-.43461.92981-.857,1.38087-1.29954a3.76029,3.76029,0,0,0,.36534-.65529,178.90466,178.90466,0,0,1-28.469-31.31672c.98458-.08018,1.64327-.18,2.30205-.1806,10.51436-.00976,21.029.02736,31.54284-.04358a4.70554,4.70554,0,0,1,3.70344,1.62615,146.94611,146.94611,0,0,0,39.40276,28.88494,139.94667,139.94667,0,0,0,49.70395,14.77367q70.68048,6.87067,121.59971-42.85452a7.64571,7.64571,0,0,1,5.99261-2.44347c9.80139.12121,19.60512.04986,29.408.04986h2.53353Z"/><path class="cncf-helm-cls-1" d="M350.73576,197.76167c2.78711,0,5.47037.18919,8.11487-.0501,2.9951-.271,5.139.8001,7.32354,2.81308,12.61275,11.62214,25.35732,23.10129,38.05863,34.62729.63855.57948,1.29039,1.14432,2.1101,1.8701.76445-.65718,1.48119-1.24318,2.16483-1.8655Q428.14636,217.27914,447.756,199.37a5.44772,5.44772,0,0,1,4.20358-1.64576c3.21888.13038,6.44673.03746,9.8412.03746V303.13036c-1.72309.50368-24.8756.60366-27.63911.0611v-53.362l-.53656-.25427c-9.01079,8.21784-18.0216,16.43564-27.23786,24.8408-9.22584-8.31119-18.34194-16.52347-27.458-24.73577l-.52449.19192c-.023,4.45359-.00774,8.90828-.01046,13.36233q-.00408,6.63942-.00058,13.27882v26.87211h-27.428C350.45161,301.61243,350.21289,203.72342,350.73576,197.76167Z"/><path class="cncf-helm-cls-1" d="M97.63436,197.88229h27.26325c.55054,1.75251.65821,102.97139.09469,105.525H97.70468c-.15021-6.70344-.04736-13.38394-.06622-20.06131-.01871-6.62261-.0041-13.24531-.0041-20.03958H63.84679V303.047c-2.05946.61518-25.33374.67417-27.64758.123V197.89436H63.73742v37.18876c1.96793.56844,30.92319.67339,33.872.12942.00818-2.97713.02-6.02646.024-9.0758q.0063-4.7433.00094-9.4866,0-4.625,0-9.25C97.63437,204.32179,97.63436,201.24346,97.63436,197.88229Z"/><path class="cncf-helm-cls-1" d="M157.5757,303.3683V198.1946c1.617-.52913,61.545-.73586,65.46219-.20457v22.41432c-.87869.063-1.7857.18341-2.69279.18454q-16.0086.01994-32.01725.00881l-2.96767,0v17.43353H218.7067V261.2229H185.65838c-.55339,1.98509-.70531,15.81681-.25622,19.64583.84488.05679,1.75.16952,2.6553.17059q16.00862.01863,32.01727.00822h2.96945V303.3683Z"/><path class="cncf-helm-cls-1" d="M254.28291,303.40855c-.50074-2.82232-.39948-103.60181.09747-105.51735h27.16208v77.76453c1.17173.06084,2.09122.14921,3.01077.15005q16.128.01468,32.2561.00658c.92562,0,1.85125,0,2.90733,0v27.59622Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="18.035334mm" height="17.500378mm" viewBox="0 0 18.035334 17.500378" version="1.1" id="k8s-c-role-svg13826" inkscape:version="0.91 r13725" sodipodi:docname="c-role.svg"><defs id="k8s-c-role-defs13820" /><g inkscape:label="Calque 1" inkscape:groupmode="layer" id="k8s-c-role-layer1" transform="translate(-0.99262638,-1.174181)"><g id="k8s-c-role-g70" transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)"><path inkscape:export-ydpi="250.55" inkscape:export-xdpi="250.55" inkscape:export-filename="new.png" inkscape:connector-curvature="0" id="k8s-c-role-path3055" d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z" style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path id="k8s-c-role-path3054-2-9" d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z" style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate" inkscape:connector-curvature="0" /></g><g id="k8s-c-role-g3341" transform="translate(0,0.28092246)"><ellipse id="k8s-c-role-ellipse7838-2" pointer-events="none" ry="0.50229818" rx="0.50633514" cy="9.9493122" cx="9.9282999" style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.12665248" /><path id="k8s-c-role-path7840-40" pointer-events="none" d="m 10.010926,5.8761701 -3.1080511,1.374181 0,2.0505009 c 0,1.901056 1.3247841,3.677988 3.1080511,4.109873 1.780734,-0.431885 3.106786,-2.208817 3.106786,-4.109873 l 0,-2.0505009 z m 1.645216,5.5182459 -3.291698,0 0,-2.7635579 0.472414,0 0,-0.301428 c 0,-0.650995 0.53194,-1.17914 1.189266,-1.17914 0.657327,0 1.189267,0.528145 1.189267,1.17914 l 0,0.301428 0.440751,0 z" inkscape:connector-curvature="0" style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.12665248" /><path id="k8s-c-role-path7836-7" pointer-events="none" d="m 9.9878259,7.5890498 c -0.393889,0.0014 -0.713053,0.317896 -0.713053,0.707987 l 0,0.296364 1.4273741,0 0,-0.301428 c -0.0038,-0.388828 -0.321698,-0.701659 -0.7143211,-0.702923 z" inkscape:connector-curvature="0" style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.12665248" /></g></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="18.035334mm" height="17.500378mm" viewBox="0 0 18.035334 17.500378" version="1.1" id="k8s-cm-svg13826" inkscape:version="0.91 r13725" sodipodi:docname="cm.svg"><defs id="k8s-cm-defs13820" /><g inkscape:label="Calque 1" inkscape:groupmode="layer" id="k8s-cm-layer1" transform="translate(-0.99262638,-1.174181)"><g id="k8s-cm-g70" transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)"><path inkscape:export-ydpi="250.55" inkscape:export-xdpi="250.55" inkscape:export-filename="new.png" inkscape:connector-curvature="0" id="k8s-cm-path3055" d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z" style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path id="k8s-cm-path3054-2-9" d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z" style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate" inkscape:connector-curvature="0" /></g><g id="k8s-cm-g3349" transform="translate(0.11778981,0.45794291)"><path inkscape:export-ydpi="376.57999" inkscape:export-xdpi="376.57999" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1" inkscape:connector-curvature="0" d="m 8.236948,6.2914262 5.825001,0" id="k8s-cm-path876" /><path inkscape:export-ydpi="376.57999" inkscape:export-xdpi="376.57999" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1" inkscape:connector-curvature="0" d="m 5.723058,6.2914262 1.45834,0" id="k8s-cm-path880" /><a id="k8s-cm-a3346"><path id="k8s-cm-path884" d="m 10.353619,8.4080928 3.70833,0" inkscape:connector-curvature="0" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1" inkscape:export-xdpi="376.57999" inkscape:export-ydpi="376.57999" /></a><path inkscape:export-ydpi="376.57999" inkscape:export-xdpi="376.57999" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1" inkscape:connector-curvature="0" d="m 7.839728,8.4080928 1.4583305,0" id="k8s-cm-path888" /><path inkscape:export-ydpi="376.57999" inkscape:export-xdpi="376.57999" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1" inkscape:connector-curvature="0" d="m 10.353619,10.52476 3.70833,0" id="k8s-cm-path892" /><path inkscape:export-ydpi="376.57999" inkscape:export-xdpi="376.57999" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1" inkscape:connector-curvature="0" d="m 7.839728,10.52476 1.4583305,0" id="k8s-cm-path896" /><path inkscape:export-ydpi="376.57999" inkscape:export-xdpi="376.57999" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1" inkscape:connector-curvature="0" d="m 8.236948,12.641428 5.825001,0" id="k8s-cm-path900" /><path inkscape:export-ydpi="376.57999" inkscape:export-xdpi="376.57999" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1" inkscape:connector-curvature="0" d="m 5.723058,12.641428 1.45834,0" id="k8s-cm-path904" /></g></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="18.035334mm" height="17.500378mm" viewBox="0 0 18.035334 17.500378" version="1.1" id="k8s-crb-svg13826" inkscape:version="0.91 r13725" sodipodi:docname="crb.svg"><defs id="k8s-crb-defs13820" /><g inkscape:label="Calque 1" inkscape:groupmode="layer" id="k8s-crb-layer1" transform="translate(-0.99262638,-1.174181)"><g id="k8s-crb-g70" transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)"><path inkscape:export-ydpi="250.55" inkscape:export-xdpi="250.55" inkscape:export-filename="new.png" inkscape:connector-curvature="0" id="k8s-crb-path3055" d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z" style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path id="k8s-crb-path3054-2-9" d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z" style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate" inkscape:connector-curvature="0" /></g><path id="k8s-crb-path8732" d="m 6.8821333,9.92437 c 0,-0.660388 0.53682,-1.197192 1.1972,-1.197192 l 1.5447698,0 0,-0.733764 -1.5447698,0 c -1.06589,0 -1.93095,0.865069 -1.93095,1.930956 0,1.065887 0.86506,1.930956 1.93095,1.930956 l 1.5447698,0 0,-0.733764 -1.5447698,0 c -0.66038,0 -1.1972,-0.536806 -1.1972,-1.197192 z m 1.5834,0.386191 3.0895197,0 0,-0.772382 -3.0895197,0 z m 3.4757197,-2.317147 -1.54477,0 0,0.733764 1.54477,0 c 0.66038,0 1.19718,0.536804 1.19718,1.197192 0,0.660386 -0.5368,1.197192 -1.19718,1.197192 l -1.54477,0 0,0.733764 1.54477,0 c 1.06589,0 1.93095,-0.865069 1.93095,-1.930956 0,-1.065887 -0.86506,-1.930956 -1.93095,-1.930956 z" inkscape:connector-curvature="0" style="fill:#ffffff;fill-opacity:1;stroke-width:0.3861911" /></g></svg>
|