${body}`;
+}
+
+function responseFor(state) {
+ const { intent, possibleDecision, choices, goals, futures } = state;
+ if (intent === 'urgent') return { title: 'Let’s make the immediate decision smaller.', body: 'You do not need to solve everything right now. I’ll help isolate the choice that matters first.' };
+ if (intent === 'foggy') return { title: 'You do not have to organize this first.', body: 'I’ll pull out what I can, show it back to you, and let you correct anything that is wrong.' };
+ if (intent === 'compare') return { title: 'I can help compare the paths you’re considering.', body: 'I’ll keep your wording visible and only treat confirmed items as part of the formal decision model.' };
+ if (intent === 'unknown') return { title: 'The missing information may be part of the decision.', body: 'I’ll show what appears unclear and help identify the smallest thing worth checking next.' };
+ if (possibleDecision) return { title: 'I can see a decision forming here.', body: 'I found a possible decision in your words. Nothing becomes a fact until you confirm it.' };
+ if (choices.length || goals.length || futures.length) return { title: 'Here’s what I can already see.', body: 'I found a few useful signals in what you wrote. Treat them as a draft, not as facts.' };
+ return { title: 'We can start from here.', body: 'I don’t need you to have a perfectly formed question. I’ll help turn this into a useful next step.' };
+}
+
+function render(root, state, focusSelector = '#universal-input') {
+ const response = responseFor(state);
+ const enough = Boolean(state.possibleDecision && state.choices.length >= 2 && state.goals.length >= 2 && state.futures.length >= 2);
+ const safeCount = DRAFT_TOPOLOGY_BOUNDS.strategies.max;
+ root.innerHTML = `
+
+ Frontier Decision Engine
+
Bring the whole mess.
+
You don’t need to know how to use FDE. Tell it what’s happening, and FDE will give you something useful back.
+
+
+
+
+ FDE
+
${escapeHtml(response.title)}
+
${escapeHtml(response.body)}
+
+
+
+
Anything is okay. Your text stays in this browser and is treated as input—not as verified evidence.
+
+
+
+
+
+
+
+
`;
+ root.querySelector('#universal-input')?.addEventListener('input', (event) => {
+ state.startingPoint = String(event.currentTarget.value || '').slice(0, RESCUE_MAX_INPUT_CHARS);
+ saveSession(state);
+ });
+ root.querySelector('#universal-refresh')?.addEventListener('click', () => {
+ const result = validateIntakeText(root.querySelector('#universal-input')?.value);
+ if (!result.ok) {
+ state.startingPoint = result.text;
+ state.next = result.error;
+ saveSession(state);
+ render(root, state, '#universal-input');
+ root.querySelector('#universal-status').textContent = result.error;
+ return;
+ }
+ Object.assign(state, draftFromInput(result.text));
+ state.next = state.choices.length || state.goals.length || state.futures.length
+ ? 'Review the draft surface. Confirm only what is actually true for your decision.'
+ : 'Tell FDE one more thing only if you want a more specific surface. You can also stop here.';
+ saveSession(state);
+ render(root, state, '#surface-title');
+ });
+ root.querySelector('#universal-clear')?.addEventListener('click', () => {
+ clearSession();
+ Object.assign(state, { startingPoint: '', intent: '', possibleDecision: '', choices: [], goals: [], futures: [], confidence: '', next: '' });
+ render(root, state);
+ });
+ root.querySelector('#universal-download')?.addEventListener('click', () => {
+ downloadText(safeFilename(state.possibleDecision || 'decision-surface', 'txt'), frameAsText(buildDecisionFrame({ startingPoint: state.startingPoint, decision: state.possibleDecision, goals: state.goals, choices: state.choices, futures: state.futures })));
+ });
+ root.querySelector('#universal-confirm')?.addEventListener('click', () => {
+ const decisionText = state.possibleDecision || state.startingPoint;
+ const decision = createGuidedDecisionCase({ objectiveCount: Math.min(4, Math.max(2, state.goals.length)), strategyCount: Math.min(3, Math.max(2, state.choices.length)), scenarioCount: Math.min(4, Math.max(2, state.futures.length)) });
+ decision.question = decisionText;
+ decision.title = decisionText.slice(0, 120);
+ state.goals.forEach((label, index) => { decision.objectives[index].label = label; });
+ state.choices.forEach((label, index) => { decision.strategies[index].label = label; });
+ state.futures.forEach((label, index) => { decision.scenarios[index].label = label; });
+ const saved = getBrowserStorage(globalThis);
+ if (saved?.getItem?.(DECISION_STORAGE_KEY)) {
+ state.next = 'A saved FDE decision exists in this browser. Open it from the Decision Lab before replacing it.';
+ render(root, state, '#universal-surface');
+ return;
+ }
+ const result = saveDecision(saved, decision, null);
+ if (!result.ok) {
+ root.querySelector('#universal-status').textContent = result.status;
+ return;
+ }
+ clearSession();
+ try { storage()?.setItem(CONTEXT_KEY, JSON.stringify({ version: 1, startingPoint: state.startingPoint })); } catch { /* optional */ }
+ try { storage()?.setItem('fde.universal.handoff', '1'); } catch { /* optional */ }
+ location.hash = '#/decision';
+ });
+ const focusTarget = root.querySelector(focusSelector);
+ if (focusSelector === '#surface-title') focusTarget?.focus({ preventScroll: true });
+}
+
+export function renderUniversalDecisionExperience(root) {
+ const restored = loadSession() || {};
+ const state = {
+ startingPoint: normalize(restored.startingPoint || ''), intent: restored.intent || '',
+ possibleDecision: restored.possibleDecision || '', choices: Array.isArray(restored.choices) ? restored.choices.slice(0, MAX_SUGGESTIONS.choices) : [],
+ goals: Array.isArray(restored.goals) ? restored.goals.slice(0, MAX_SUGGESTIONS.goals) : [],
+ futures: Array.isArray(restored.futures) ? restored.futures.slice(0, MAX_SUGGESTIONS.futures) : [],
+ confidence: restored.confidence || '', next: restored.next || '',
+ };
+ render(root, state, '#universal-title');
+}
From 43297cc09ec285d4a981e6554c3cff2ba761d2dc Mon Sep 17 00:00:00 2001
From: Bridge Node 7 <291729790+Bridge-Node-7@users.noreply.github.com>
Date: Wed, 26 Aug 2026 12:52:35 -0700
Subject: [PATCH 02/57] Add universal response surface styling
---
site/assets/universal-decision.css | 35 ++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 site/assets/universal-decision.css
diff --git a/site/assets/universal-decision.css b/site/assets/universal-decision.css
new file mode 100644
index 0000000..2d42a25
--- /dev/null
+++ b/site/assets/universal-decision.css
@@ -0,0 +1,35 @@
+:root{--surface-glow:rgba(117,214,255,.08);--surface-border:rgba(117,214,255,.18)}
+.universal-hero{max-width:900px;margin:clamp(3rem,9vw,6.5rem) auto 2.25rem;text-align:center}
+.universal-hero h1{margin:.55rem 0 .9rem;font-size:clamp(2.5rem,6vw,5.2rem);line-height:.98;letter-spacing:-.045em}
+.universal-subtitle{max-width:720px;margin:0 auto;color:var(--muted);font-size:clamp(1.05rem,2vw,1.3rem);line-height:1.65}
+.universal-layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(320px,.88fr);gap:1.25rem;align-items:start;margin-bottom:5rem}
+.universal-entry,.universal-surface{border:1px solid var(--line-strong);background:var(--surface);box-shadow:0 24px 70px rgba(0,0,0,.16);border-radius:24px}
+.universal-entry{padding:1.35rem}
+.universal-response{padding:1rem 1rem 1.05rem;border:1px solid var(--surface-border);background:var(--surface-glow);border-radius:18px;margin-bottom:1rem}
+.universal-response-kicker,.universal-card-label{display:block;font-size:.78rem;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:.4rem}
+.universal-response h2{margin:.1rem 0 .55rem;font-size:clamp(1.5rem,3vw,2.25rem);line-height:1.08}
+.universal-response p{margin:0;color:var(--muted);line-height:1.6}
+.universal-entry>label{display:block;font-weight:800;margin:.5rem 0 .55rem}
+#universal-input{width:100%;min-height:260px;resize:vertical;border-radius:18px;font:inherit;line-height:1.6}
+.universal-entry .help{margin:.6rem 0 1rem}
+.universal-actions{display:flex;gap:.65rem;flex-wrap:wrap;align-items:center}
+.universal-actions .primary{min-height:48px}
+.universal-status{min-height:1.4rem;margin-top:.65rem;color:var(--muted)}
+.universal-surface{position:sticky;top:1rem;overflow:hidden}
+.universal-surface-head{display:flex;justify-content:space-between;gap:1rem;align-items:start;padding:1.25rem;border-bottom:1px solid var(--line)}
+.universal-surface-head h2{margin:.15rem 0 0;font-size:1.5rem}
+.universal-badge{font-size:.74rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;padding:.35rem .55rem;border:1px solid var(--line-strong);border-radius:999px;color:var(--muted)}
+.universal-card{padding:1rem 1.25rem;border-bottom:1px solid var(--line)}
+.universal-list{list-style:none;margin:0;padding:0;display:grid;gap:.45rem}
+.universal-list li{display:flex;gap:.55rem;align-items:baseline;justify-content:space-between}
+.surface-value{overflow-wrap:anywhere}
+.surface-state{font-size:.72rem;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);white-space:nowrap}
+.universal-empty{margin:0;color:var(--muted)}
+.universal-next{margin:1rem;border:1px solid var(--line-strong);border-radius:18px;padding:1rem;background:var(--surface-glow)}
+.universal-next p{margin:.35rem 0 1rem;color:var(--muted);line-height:1.55}
+.universal-confirm-row{display:flex;gap:.55rem;flex-wrap:wrap}
+.universal-confirm-row button{min-height:44px}
+.universal-truth{padding:0 1.25rem 1.25rem;margin:0;color:var(--muted);font-size:.82rem;line-height:1.5}
+@media(max-width:900px){.universal-layout{grid-template-columns:1fr}.universal-surface{position:static;order:2}.universal-entry{order:1}.universal-hero{text-align:left}.universal-hero h1{max-width:700px}.universal-subtitle{margin:0}}
+@media(max-width:620px){.universal-entry,.universal-surface{border-radius:18px}.universal-actions,.universal-confirm-row{align-items:stretch;flex-direction:column}.universal-actions button,.universal-confirm-row button{width:100%}#universal-input{min-height:220px}.universal-hero{margin-top:2.5rem}}
+@media(forced-colors:active){.universal-entry,.universal-surface,.universal-response,.universal-next{box-shadow:none;border:1px solid CanvasText}.universal-badge{border-color:CanvasText}}
From e9206c9f994a29f6a437d4d0491b69cacf2f4b8b Mon Sep 17 00:00:00 2001
From: Bridge Node 7 <291729790+Bridge-Node-7@users.noreply.github.com>
Date: Wed, 26 Aug 2026 12:55:23 -0700
Subject: [PATCH 03/57] feat: add universal response decision surface
---
README.md | 50 +++---
docs/ARCHITECTURE.md | 61 ++++----
package.json | 5 +-
project-facts.json | 6 +-
site/assets/universal-decision.css | 4 +-
site/index.html | 7 +-
site/src/app.js | 50 +++---
site/src/universal-ui.js | 241 ++++++++---------------------
tests/universal-response.test.js | 32 ++++
9 files changed, 188 insertions(+), 268 deletions(-)
create mode 100644 tests/universal-response.test.js
diff --git a/README.md b/README.md
index cccf444..be3c809 100644
--- a/README.md
+++ b/README.md
@@ -1,66 +1,56 @@
# Frontier Decision Engine
-**Bring a messy situation. Find the decision. Test choices when useful. Keep the final judgment human-owned.**
+**Bring the whole mess. FDE gives you something useful back, helps make uncertainty visible, and keeps the final decision human-owned.**
[Open the live application](https://bridgenode7.com/frontier-decision-engine/)
-
+## Start with one input
-## Start with Decision Rescue
+The FDE front door now starts with one free-form input. Put down a problem, question, worry, idea, decision, or a complete mess. FDE responds immediately with a provisional Decision Surface showing only what can be safely organized from the words provided.
-Decision Rescue accepts ordinary language first. A visitor can put down what is happening, choose one useful next action, and build a Decision Frame without knowing decision-science terminology.
+The surface is a draft, not a hidden machine decision. Possible signals stay possible until a person confirms them. When enough explicit structure exists, the surface can continue into the deterministic Decision Lab. Otherwise, it offers a simple path to shape the missing pieces without pretending the missing information is known.
-FDE preserves what the person confirms and does not pretend browser JavaScript inferred evidence, probabilities, thresholds, scores, or a recommendation. A partial Decision Frame is a valid stopping point.
+The experience is designed around a simple rule: **every meaningful input receives a useful response, and questions are used only when human judgment is actually needed to move the decision forward.**
-Decision Rescue uses tab-scoped session storage so an accidental refresh can recover in-progress framing. It does not treat the original brain dump as model evidence. When a complete frame continues into the Decision Lab, existing browser-saved Lab work is never replaced without an explicit human choice.
+## Decision Surface
-## What the Decision Lab does
+The surface can show:
-- Frames the decision, goals, choices, and plausible futures.
-- Evaluates the same choices across explicit goals and named conditions.
-- Shows unmet goals, ties, incomplete outcomes, and vulnerabilities.
-- Keeps final selection, rationale, and next action human-owned.
-- Exports a portable decision file and a readable decision summary.
+- a possible decision;
+- choices mentioned explicitly;
+- things that may matter;
+- conditions that could change the answer; and
+- the smallest useful next step.
-Guided work supports 2–4 objectives, 2–3 choices, and 2–4 plausible futures. The minimum comparison is a real 2 × 2 × 2 model. FDE never fills missing analytical inputs on the person's behalf.
+This is deliberately conservative. The browser does not call a remote AI service, retrieve outside facts, invent probabilities, or promote provisional text into verified evidence.
-The included ready example is a **synthetic critical-material source-qualification case**. It does not describe or certify a real supplier, material, capacity, compliance status, or investment.
+## Decision Lab
-## Privacy and authority
+When a person confirms enough structure, FDE can hand the work into its existing deterministic comparison engine. Guided work supports 2–4 objectives, 2–3 choices, and 2–4 plausible futures. The minimum comparison is a true 2 × 2 × 2 model.
-The application is static and browser-local. It has no backend, account system, analytics, telemetry, cookies, or default upload endpoint.
+The comparison informs. A person decides.
-Browser storage is a convenience, not encrypted confidential storage. Do not enter information that requires an approved confidential or controlled-data environment.
+## Privacy and authority
-FDE provides decision support. It does not approve, authorize, certify, qualify, consent, or make an investment decision. The comparison informs; a person decides.
+The application is static and browser-local. It has no backend, account system, analytics, telemetry, cookies, remote AI provider, or default upload endpoint. Session recovery and browser autosave are convenience features, not encrypted confidential storage.
-## Run locally
-
-```bash
-node scripts/run-python.mjs -m http.server 8000 --directory site
-```
-
-Open `http://localhost:8000`.
+FDE provides decision support. It does not approve, authorize, certify, qualify, consent, or make an investment decision.
## Verify
Requirements: Node.js 22+, Python 3.11+, and Chromium or Google Chrome.
```bash
-node scripts/run-python.mjs -m pip install -r requirements-dev.txt
-node scripts/run-python.mjs -m playwright install chromium
npm ci --ignore-scripts --no-audit --no-fund
npm run check
```
-`npm run check` runs the repository's unit, version, integrity, browser, Decision Rescue, and release-closeout gates. Current generated counts and versions are recorded in [`project-facts.json`](project-facts.json).
-
## Documentation
- [Architecture](docs/ARCHITECTURE.md)
- [Methodology](docs/METHODOLOGY.md)
- [Privacy](docs/PRIVACY.md)
-- [Releases](docs/RELEASING.md)
+- [Releasing](docs/RELEASING.md)
## Project
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index 7197a15..de24b6c 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -2,55 +2,54 @@
Frontier Decision Engine is a static browser application served from `site/`. There is no backend or account service.
-## Runtime
+## Human-first runtime
-- Decision Rescue is the human-language front door.
-- Decision Lab is the structured six-stage comparison workflow.
-- The ranking engine is deterministic and runs in the browser.
-- Portable decision schemas remain versioned under `schemas/`.
-- Validation and release checks run from `scripts/` and GitHub Actions.
+The public root is a one-input response experience. A person can write a problem, question, worry, idea, decision, or incomplete thought without knowing decision-science vocabulary. FDE immediately returns a useful response and a provisional Decision Surface.
-## Human-first entry
+The Decision Surface can show:
-The root experience accepts bounded inert text and asks for the smallest useful human contribution next. It does not claim to understand arbitrary prose, retrieve external facts, infer evidence, assign probabilities, create scores, or recommend an action.
+- a possible decision;
+- choices mentioned explicitly;
+- things that may matter;
+- conditions that could change the answer; and
+- the most useful next step.
-A Decision Frame can remain incomplete and still be useful. Full comparison is available only after the person has confirmed a decision, at least two goals, two choices, and two plausible futures.
+Possible elements are not silently promoted into facts. The surface is a draft until a person confirms the information that belongs in the formal decision model.
-Guided comparison supports:
+## Minimum necessary human contribution
-- 2–4 objectives
-- 2–3 strategies
-- 2–4 scenarios
+FDE follows this interaction rule at the surface layer:
-The ready example remains a larger synthetic reference case. Missing thresholds, scores, modifiers, critical flags, and evidence stay missing until a person supplies them.
+> Continue without bothering the person when the system can proceed safely; otherwise ask for the smallest human contribution that materially advances the decision.
-## Browser storage
+No normal input is treated as a dead end. Empty, vague, messy, ambiguous, and non-decision input receive a useful orientation response rather than an error-only state.
-Decision Rescue uses tab-scoped session storage for accidental-refresh recovery. The original starting context remains context only and is not scored or promoted into model evidence.
+## Formal Decision Lab
-Decision Lab uses bounded browser autosave for in-progress structured work. If a browser draft already exists, Decision Rescue does not replace it silently; replacement requires an explicit human choice.
+Once enough explicit structure exists, the confirmed information is handed into the existing deterministic Decision Lab. Guided comparison supports 2–4 objectives, 2–3 strategies, and 2–4 scenarios. The minimum comparison is a true 2 × 2 × 2 model.
-Browser storage is not encrypted confidential storage. Local files are processed in the browser and are not uploaded by the default application.
+The comparison core is isolated from the surface layer so UX changes do not silently alter ranking semantics. Missing analytical values are not fabricated.
-## Decision result
+## Epistemic boundaries
-The engine evaluates explicit human-supplied inputs across the same named futures. It preserves honest outcomes including:
+The public experience separates:
-- a unique leader under the tested model;
-- tied leaders;
-- no acceptable strategy under declared boundaries; and
-- insufficient data.
+1. **You said** — the original human input.
+2. **FDE organized** — a provisional structure derived from safe, explicit textual patterns.
+3. **You confirmed** — information promoted into the formal model by a human.
+4. **FDE calculated** — deterministic output from confirmed model inputs.
+5. **You decided** — the human-owned choice, rationale, and next action.
-The result is advisory. A person selects the strategy and records the rationale and next action.
+The default runtime does not use a remote AI provider, retrieve external facts, infer evidence, assign probabilities, or make the final decision.
-## Compatibility
+## Browser storage
-Legacy completed decision schema `0.2.10` remains supported. Optional decision-semantics state uses schema `0.3.0`. The guided browser editor is intentionally bounded even though portable schemas may permit broader cases.
+The universal response surface uses bounded tab-scoped session storage for accidental-refresh recovery. Decision Lab uses bounded browser autosave for structured work. Browser storage is a convenience, not encrypted confidential storage.
-The deterministic ranking core is isolated from the human-entry layer so UX changes do not silently alter comparison semantics.
+## Privacy and security
-## Security and privacy boundaries
+The public application has no backend, account system, analytics, telemetry, cookies, remote AI provider, or default upload endpoint. User input is rendered as text, not executable markup. Local files remain in the browser unless the person explicitly downloads or shares them.
-The public runtime has no account system, analytics, telemetry, remote AI provider, or default upload endpoint. User-entered text is rendered as text rather than executable markup.
+## Long-term direction
-Generated visualizations and software calculations are not evidence. FDE does not provide legal approval, organizational authorization, certification, qualification, consent, or investment approval.
+The architecture intentionally leaves room for an optional assisted-understanding adapter and later Decision Memory without making either a dependency of the deterministic core. Any future semantic provider must produce provisional output that passes through the same human-confirmation boundary.
\ No newline at end of file
diff --git a/package.json b/package.json
index e367893..4d879bc 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"description": "Browser-local, human-governed decision support for choices under deep uncertainty.",
"scripts": {
"test": "node --test",
+ "test:universal": "node --test tests/universal-response.test.js",
"facts": "node scripts/generate-project-facts.mjs",
"facts:check": "node scripts/validate-project-facts.mjs",
"validate": "node scripts/run-python.mjs scripts/validate_repository.py",
@@ -18,8 +19,6 @@
"validate:version": "node scripts/run-python.mjs scripts/validate_version_integrity.py",
"test:closeout": "node scripts/run-python.mjs scripts/browser_closeout_regressions.py"
},
- "engines": {
- "node": ">=22"
- },
+ "engines": { "node": ">=22" },
"license": "Apache-2.0"
}
diff --git a/project-facts.json b/project-facts.json
index 71de019..397b3bd 100644
--- a/project-facts.json
+++ b/project-facts.json
@@ -5,8 +5,8 @@
"semanticDecision": "0.3.0",
"opvCase": "0.1.0"
},
- "testCount": 143,
- "discoveredHashRouteLiteralCount": 6,
+ "testCount": 147,
+ "discoveredHashRouteLiteralCount": 7,
"browserModes": [
"desktop-light",
"mobile-light",
@@ -16,7 +16,7 @@
"reflow-400-equivalent",
"forced-colors"
],
- "manifestEntryCount": 35,
+ "manifestEntryCount": 37,
"retainedReferenceArtifactItemCounts": {
"profiles/phenomena/profile.json": 5,
"site/data/experiences.json": 41,
diff --git a/site/assets/universal-decision.css b/site/assets/universal-decision.css
index 2d42a25..1ffa588 100644
--- a/site/assets/universal-decision.css
+++ b/site/assets/universal-decision.css
@@ -28,8 +28,8 @@
.universal-next{margin:1rem;border:1px solid var(--line-strong);border-radius:18px;padding:1rem;background:var(--surface-glow)}
.universal-next p{margin:.35rem 0 1rem;color:var(--muted);line-height:1.55}
.universal-confirm-row{display:flex;gap:.55rem;flex-wrap:wrap}
-.universal-confirm-row button{min-height:44px}
+.universal-confirm-row button,.universal-confirm-row .button{min-height:44px}
.universal-truth{padding:0 1.25rem 1.25rem;margin:0;color:var(--muted);font-size:.82rem;line-height:1.5}
@media(max-width:900px){.universal-layout{grid-template-columns:1fr}.universal-surface{position:static;order:2}.universal-entry{order:1}.universal-hero{text-align:left}.universal-hero h1{max-width:700px}.universal-subtitle{margin:0}}
-@media(max-width:620px){.universal-entry,.universal-surface{border-radius:18px}.universal-actions,.universal-confirm-row{align-items:stretch;flex-direction:column}.universal-actions button,.universal-confirm-row button{width:100%}#universal-input{min-height:220px}.universal-hero{margin-top:2.5rem}}
+@media(max-width:620px){.universal-entry,.universal-surface{border-radius:18px}.universal-actions,.universal-confirm-row{align-items:stretch;flex-direction:column}.universal-actions button,.universal-confirm-row button,.universal-confirm-row .button{width:100%}#universal-input{min-height:220px}.universal-hero{margin-top:2.5rem}}
@media(forced-colors:active){.universal-entry,.universal-surface,.universal-response,.universal-next{box-shadow:none;border:1px solid CanvasText}.universal-badge{border-color:CanvasText}}
diff --git a/site/index.html b/site/index.html
index e53e603..bdc673a 100644
--- a/site/index.html
+++ b/site/index.html
@@ -3,11 +3,11 @@
-
+
-
+
@@ -21,6 +21,7 @@
+
@@ -43,7 +44,7 @@