From 7bec86289ceb16d761409798ba5761c82140a82f Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 1 Jul 2026 07:17:59 +0000 Subject: [PATCH] =?UTF-8?q?web:=20morph=20preserves=20the=20boost's=20inje?= =?UTF-8?q?cted=20sx-*=20attrs=20=E2=80=94=20fix=20edit-page=20swap=20clob?= =?UTF-8?q?bering=20#content?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported: logged in, go to an edit page, then press Home — nothing happens. Root cause (browser-DOM trace): a boosted nav home→post morphs a home footer into the post's "edit" link (morph reuses nodes positionally). morph-node's sync-attrs then STRIPS any attribute the old node has but the SERVER node lacks — which removes the boost's client-injected sx-swap="innerHTML" (the server never sends it). With sx-swap gone the swap defaults to outerHTML, so clicking edit REPLACES #content (the
) with the edit fragment's
(no id) — DOM trace: "sx-boost children [NAV, DIV#content]" → "[NAV, DIV]". #content is destroyed, so every later boosted nav (Home) fetches but has no swap target ("post-swap: root=nil") → nothing updates. Fix: sync-attrs no longer removes the boost's injected navigation attributes (sx-target / sx-swap / sx-push-url / sx-get / sx-select) when the new (server) node lacks them — they're identical across all boosted links, so a reused node keeps sx-swap="innerHTML" and the swap morphs #content's children instead of replacing #content. Recompiled the web stack. Pairs with a511b21d (fresh href) + 88f8b427 (SX-Redirect) — three facets of the morph-node-reuse problem (stale href, lost swap attr, guarded-redirect clobber). TEST-FIRST: added a 3rd boost-nav.spec.js case (LOGGED IN: home→post→edit, assert #content survives + Home works). Reproduced RED via DOM traces (#content count 0), GREEN after — on the ephemeral server AND live. No regressions: picker 3/3 + block-editor 1/1. Co-Authored-By: Claude Opus 4.8 --- lib/host/playwright/boost-nav.spec.js | 32 ++++++++++++++++++++++ lib/host/playwright/run-boost-nav-check.sh | 2 +- shared/static/wasm/sx/engine.sx | 14 +++++++++- shared/static/wasm/sx/engine.sxbc | 4 +-- web/engine.sx | 14 +++++++++- 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/lib/host/playwright/boost-nav.spec.js b/lib/host/playwright/boost-nav.spec.js index 028e522c..b0a5b54d 100644 --- a/lib/host/playwright/boost-nav.spec.js +++ b/lib/host/playwright/boost-nav.spec.js @@ -7,9 +7,19 @@ const { test, expect } = require('playwright/test'); const BASE = process.env.SX_TEST_URL || 'http://127.0.0.1:8914'; +const USER = process.env.SX_ADMIN_USER || 'admin'; +const PASS = process.env.SX_ADMIN_PASSWORD || 'letmein'; + async function waitReady(page) { await expect(page.locator('html[data-sx-ready="true"]')).toHaveCount(1, { timeout: 45000 }); } +async function login(page) { + await page.goto(BASE + '/login'); + await page.fill('input[name="username"]', USER); + await page.fill('input[name="password"]', PASS); + await page.click('button[type="submit"]'); + await page.waitForURL((u) => !u.pathname.startsWith('/login')); +} test.describe('boosted navigation (browser-only)', () => { test('a post link clicked AFTER a boosted nav navigates to the right target (not a stale home link)', async ({ page }) => { @@ -56,4 +66,26 @@ test.describe('boosted navigation (browser-only)', () => { await expect(page.locator('body')).toContainText('Posts', { timeout: 12000 }); expect(new URL(page.url()).pathname).toBe('/'); }); + + test('LOGGED IN: the Home nav works after a boosted nav to the edit page', async ({ page }) => { + test.setTimeout(90000); + await login(page); // authed session + await page.goto(BASE + '/'); + await waitReady(page); + // boosted nav home -> post -> edit (authed, so the real edit form swaps into #content) + await page.locator('a[href="/compose-demo/"]').first().click(); + await expect(page.locator('body')).toContainText('composition object', { timeout: 15000 }); + // the footer "edit" link (there's also a "no relations — add some" link to edit when authed) + await page.locator('a[href="/compose-demo/edit"]').last().click(); + await expect(page.locator('body')).toContainText('Edit:', { timeout: 15000 }); + expect(new URL(page.url()).pathname).toBe('/compose-demo/edit'); + // #content must SURVIVE the edit swap (an outerHTML swap would replace it, then no later + // nav can find a swap target — the reported "Home does nothing"). + expect(await page.locator('#content').count()).toBe(1); + // the persistent top-nav Home link must still work on the edit page. + await page.locator('nav a[href="/"]').first().click(); + await page.waitForTimeout(3000); + await expect(page.locator('body')).toContainText('Posts', { timeout: 12000 }); + expect(new URL(page.url()).pathname).toBe('/'); + }); }); diff --git a/lib/host/playwright/run-boost-nav-check.sh b/lib/host/playwright/run-boost-nav-check.sh index 2b7b5c3d..92f7e0af 100755 --- a/lib/host/playwright/run-boost-nav-check.sh +++ b/lib/host/playwright/run-boost-nav-check.sh @@ -43,7 +43,7 @@ echo "== server up ==" echo "== running Playwright ==" cp "$ROOT/$SPEC_SRC" "$SPEC_DST" cd "$PW_DIR" -SX_TEST_URL="http://127.0.0.1:$PORT" \ +SX_TEST_URL="http://127.0.0.1:$PORT" SX_ADMIN_USER="$USER" SX_ADMIN_PASSWORD="$PASS" \ node_modules/.bin/playwright test _boost-nav-check.spec.js --workers=1 \ --config tests/playwright/playwright.config.js RC=$? diff --git a/shared/static/wasm/sx/engine.sx b/shared/static/wasm/sx/engine.sx index 207abff3..df553473 100644 --- a/shared/static/wasm/sx/engine.sx +++ b/shared/static/wasm/sx/engine.sx @@ -468,7 +468,19 @@ (and (not (dom-has-attr? new-el aname)) (not (contains? reactive-attrs aname)) - (not (= aname "data-sx-reactive-attrs"))) + (not (= aname "data-sx-reactive-attrs")) + ;; PRESERVE the boost's client-injected navigation attributes. The boost + ;; (boost-descendants) sets sx-target/sx-swap/sx-push-url on links; the + ;; SERVER never sends them, so this removal loop would strip them when a + ;; morph reuses a node for a different link — leaving sx-swap unset, which + ;; defaults to outerHTML and REPLACES the swap target (#content), breaking + ;; every later nav. These are identical across all boosted links, so + ;; keeping them on a reused node is correct. + (not (= aname "sx-target")) + (not (= aname "sx-swap")) + (not (= aname "sx-push-url")) + (not (= aname "sx-get")) + (not (= aname "sx-select"))) (dom-remove-attr old-el aname)))) (dom-attr-list old-el))))) (define diff --git a/shared/static/wasm/sx/engine.sxbc b/shared/static/wasm/sx/engine.sxbc index e265a0bc..a38f3dbf 100644 --- a/shared/static/wasm/sx/engine.sxbc +++ b/shared/static/wasm/sx/engine.sxbc @@ -1,3 +1,3 @@ -(sxbc 1 "a10bcb1db96341ec" +(sxbc 1 "ccf6ced8e7318d6b" (code - :constants ("ENGINE_VERBS" "get" "post" "put" "delete" "patch" "list" "DEFAULT_SWAP" "outerHTML" "parse-time" {:upvalue-count 0 :arity 1 :constants ("nil?" 0 "ms" "ends-with?" "parse-int" "s" "" "replace" 1000) :bytecode (16 0 52 0 0 1 33 6 0 1 1 0 32 71 0 16 0 1 2 0 52 3 0 2 33 12 0 16 0 1 1 0 52 4 0 2 32 47 0 16 0 1 5 0 52 3 0 2 33 26 0 16 0 1 5 0 1 6 0 52 7 0 3 1 1 0 52 4 0 2 1 8 0 162 32 9 0 16 0 1 1 0 52 4 0 2 50)} "parse-trigger-spec" {:upvalue-count 0 :arity 1 :constants ("nil?" "," "split" {:upvalue-count 0 :arity 1 :constants ("nil?") :bytecode (16 0 52 0 0 1 167 50)} {:upvalue-count 0 :arity 1 :constants ("trim" " " "split" "empty?" "every" 2 ">=" "event" "modifiers" "interval" "parse-time" 1 "nth" "dict" {:upvalue-count 1 :arity 1 :constants ("once" "dict-set!" "changed" "delay:" "starts-with?" "delay" "parse-time" 6 "slice" "from:" "from" 5) :bytecode (16 0 1 0 0 164 33 13 0 18 0 1 0 0 3 52 1 0 3 32 94 0 16 0 1 2 0 164 33 13 0 18 0 1 2 0 3 52 1 0 3 32 72 0 16 0 1 3 0 52 4 0 2 33 26 0 18 0 1 5 0 20 6 0 16 0 1 7 0 52 8 0 2 48 1 52 1 0 3 32 34 0 16 0 1 9 0 52 4 0 2 33 21 0 18 0 1 10 0 16 0 1 11 0 52 8 0 2 52 1 0 3 32 1 0 2 50)} "for-each" "[" "index-of" 0 "filter" "slice" "dict-set!") :bytecode (16 0 52 0 0 1 1 1 0 52 2 0 2 17 1 16 1 52 3 0 1 33 4 0 2 32 178 0 16 1 169 1 4 0 164 6 33 11 0 5 16 1 168 1 5 0 52 6 0 2 33 37 0 1 7 0 1 4 0 1 8 0 1 9 0 20 10 0 16 1 1 11 0 52 12 0 2 48 1 52 13 0 2 52 13 0 4 32 116 0 52 13 0 0 17 2 51 14 0 1 2 16 1 170 52 15 0 2 5 16 1 169 17 3 16 3 1 16 0 52 17 0 2 17 4 16 4 1 18 0 52 6 0 2 33 55 0 16 2 1 19 0 16 3 16 4 1 11 0 160 16 3 168 1 11 0 161 52 20 0 3 52 21 0 3 5 1 7 0 16 3 1 18 0 16 4 52 20 0 3 1 8 0 16 2 52 13 0 4 32 14 0 1 7 0 16 3 1 8 0 16 2 52 13 0 4 50)} "map" "filter") :bytecode (16 0 52 0 0 1 33 4 0 2 32 27 0 16 0 1 1 0 52 2 0 2 17 1 51 3 0 51 4 0 16 1 52 5 0 2 52 6 0 2 50)} "default-trigger" {:upvalue-count 0 :arity 1 :constants ("form" "=" "event" "submit" "modifiers" "dict" "list" "input" "change" "select" "textarea" "click") :bytecode (16 0 6 1 0 0 52 1 0 2 33 25 0 5 1 2 0 1 3 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 32 130 0 6 1 7 0 52 1 0 2 33 25 0 5 1 2 0 1 8 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 32 94 0 6 1 9 0 52 1 0 2 33 25 0 5 1 2 0 1 8 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 32 58 0 6 1 10 0 52 1 0 2 33 25 0 5 1 2 0 1 8 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 32 22 0 5 1 2 0 1 11 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 50)} "get-verb-info" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 1 :arity 1 :constants ("dom-get-attr" "sx-" "str" "method" "upper" "url" "dict") :bytecode (20 0 0 18 0 1 1 0 16 0 52 2 0 2 48 2 17 1 16 1 33 21 0 1 3 0 16 0 52 4 0 1 1 5 0 16 1 52 6 0 4 32 1 0 2 50)} "ENGINE_VERBS" "some") :bytecode (51 0 0 1 0 20 1 0 52 2 0 2 50)} "build-request-headers" {:upvalue-count 0 :arity 2 :constants ("SX-Request" "true" "SX-Current-URL" "browser-location-href" "dict" "dom-get-attr" "sx-target" "SX-Target" "dict-set!" "dom-query" "script[data-components][data-hash]" "data-hash" "SX-Components-Hash" "sx-headers" "parse-header-value" {:upvalue-count 2 :arity 1 :constants ("get" "str" "dict-set!") :bytecode (18 0 16 0 18 1 16 0 52 0 0 2 52 1 0 1 52 2 0 3 50)} "keys" "for-each") :bytecode (1 0 0 1 1 0 1 2 0 20 3 0 48 0 52 4 0 4 17 2 20 5 0 16 0 1 6 0 48 2 17 3 16 3 33 14 0 16 2 1 7 0 16 3 52 8 0 3 32 1 0 2 5 20 5 0 20 9 0 1 10 0 48 1 1 11 0 48 2 17 3 16 3 33 14 0 16 2 1 12 0 16 3 52 8 0 3 32 1 0 2 5 20 5 0 16 0 1 13 0 48 2 17 3 16 3 33 38 0 20 14 0 16 3 48 1 17 4 16 4 33 20 0 51 15 0 1 2 1 4 16 4 52 16 0 1 52 17 0 2 32 1 0 2 32 1 0 2 5 16 2 50)} "process-response-headers" {:upvalue-count 0 :arity 1 :constants ("redirect" "SX-Redirect" "refresh" "SX-Refresh" "trigger" "SX-Trigger" "retarget" "SX-Retarget" "reswap" "SX-Reswap" "location" "SX-Location" "replace-url" "SX-Replace-Url" "trigger-swap" "SX-Trigger-After-Swap" "trigger-settle" "SX-Trigger-After-Settle" "content-type" "Content-Type" "cache-invalidate" "SX-Cache-Invalidate" "cache-update" "SX-Cache-Update" "dict") :bytecode (1 0 0 16 0 1 1 0 48 1 1 2 0 16 0 1 3 0 48 1 1 4 0 16 0 1 5 0 48 1 1 6 0 16 0 1 7 0 48 1 1 8 0 16 0 1 9 0 48 1 1 10 0 16 0 1 11 0 48 1 1 12 0 16 0 1 13 0 48 1 1 14 0 16 0 1 15 0 48 1 1 16 0 16 0 1 17 0 48 1 1 18 0 16 0 1 19 0 48 1 1 20 0 16 0 1 21 0 48 1 1 22 0 16 0 1 23 0 48 1 52 24 0 24 50)} "parse-swap-spec" {:upvalue-count 0 :arity 2 :constants ("DEFAULT_SWAP" " " "split" {:upvalue-count 1 :arity 1 :constants ("transition:true" "transition:false") :bytecode (16 0 1 0 0 164 33 6 0 3 19 0 32 16 0 16 0 1 1 0 164 33 6 0 4 19 0 32 1 0 2 50)} "for-each" "style" "transition" "dict") :bytecode (16 0 6 34 4 0 5 20 0 0 1 1 0 52 2 0 2 17 2 16 2 169 17 3 16 1 17 4 51 3 0 1 4 16 2 170 52 4 0 2 5 1 5 0 16 3 1 6 0 16 4 52 7 0 4 50)} "parse-retry-spec" {:upvalue-count 0 :arity 1 :constants ("nil?" ":" "split" "strategy" "start-ms" 1 "nth" 1000 "parse-int" "cap-ms" 2 30000 "dict") :bytecode (16 0 52 0 0 1 33 4 0 2 32 59 0 16 0 1 1 0 52 2 0 2 17 1 1 3 0 16 1 169 1 4 0 16 1 1 5 0 52 6 0 2 1 7 0 52 8 0 2 1 9 0 16 1 1 10 0 52 6 0 2 1 11 0 52 8 0 2 52 12 0 6 50)} "next-retry-ms" {:upvalue-count 0 :arity 2 :constants (2 "min") :bytecode (16 0 1 0 0 162 16 1 52 1 0 2 50)} "filter-params" {:upvalue-count 0 :arity 2 :constants ("nil?" "none" "list" "*" "not " "starts-with?" "trim" 4 "slice" "," "split" "map" {:upvalue-count 1 :arity 1 :constants ("contains?") :bytecode (18 0 16 0 169 52 0 0 2 167 50)} "filter" {:upvalue-count 1 :arity 1 :constants ("contains?") :bytecode (18 0 16 0 169 52 0 0 2 50)}) :bytecode (16 0 52 0 0 1 33 5 0 16 1 32 110 0 16 0 1 1 0 164 33 7 0 52 2 0 0 32 94 0 16 0 1 3 0 164 33 5 0 16 1 32 80 0 16 0 1 4 0 52 5 0 2 33 39 0 20 6 0 16 0 1 7 0 52 8 0 2 1 9 0 52 10 0 2 52 11 0 2 17 2 51 12 0 1 2 16 1 52 13 0 2 32 29 0 20 6 0 16 0 1 9 0 52 10 0 2 52 11 0 2 17 2 51 14 0 1 2 16 1 52 13 0 2 50)} "resolve-target" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-target" "=" "this" "closest" "dom-parent" "dom-query") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 2 52 2 0 2 33 6 0 5 16 0 32 47 0 6 1 3 0 52 2 0 2 33 6 0 5 16 0 32 30 0 6 1 4 0 52 2 0 2 33 11 0 5 20 5 0 16 0 49 1 32 8 0 5 20 6 0 16 1 49 1 50)} "apply-optimistic" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-optimistic" "nil?" "resolve-target" "target" "directive" "dict" "remove" "opacity" "dom-get-style" "dict-set!" "dom-set-style" "0" "pointer-events" "none" "disable" "disabled" "dom-get-prop" "dom-set-prop" "add-class:" "starts-with?" 10 "slice" "add-class" "dom-add-class") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 52 2 0 1 33 4 0 2 32 185 0 20 3 0 16 0 48 1 6 34 3 0 5 16 0 17 2 1 4 0 16 2 1 5 0 16 1 52 6 0 4 17 3 16 1 1 7 0 164 33 50 0 16 3 1 8 0 20 9 0 16 2 1 8 0 48 2 52 10 0 3 5 20 11 0 16 2 1 8 0 1 12 0 48 3 5 20 11 0 16 2 1 13 0 1 14 0 48 3 32 91 0 16 1 1 15 0 164 33 34 0 16 3 1 16 0 20 17 0 16 2 1 16 0 48 2 52 10 0 3 5 20 18 0 16 2 1 16 0 3 48 3 32 48 0 16 1 1 19 0 52 20 0 2 33 35 0 16 1 1 21 0 52 22 0 2 17 4 16 3 1 23 0 16 4 52 10 0 3 5 20 24 0 16 2 16 4 48 2 32 1 0 2 5 16 3 50)} "revert-optimistic" {:upvalue-count 0 :arity 1 :constants ("target" "get" "directive" "remove" "dom-set-style" "opacity" "" "pointer-events" "disable" "dom-set-prop" "disabled" "add-class" "dom-remove-class") :bytecode (16 0 33 147 0 16 0 1 0 0 52 1 0 2 17 1 16 0 1 2 0 52 1 0 2 17 2 16 2 1 3 0 164 33 44 0 20 4 0 16 1 1 5 0 16 0 1 5 0 52 1 0 2 6 34 4 0 5 1 6 0 48 3 5 20 4 0 16 1 1 7 0 1 6 0 49 3 32 69 0 16 2 1 8 0 164 33 28 0 20 9 0 16 1 1 10 0 16 0 1 10 0 52 1 0 2 6 34 2 0 5 4 49 3 32 32 0 16 0 1 11 0 52 1 0 2 33 19 0 20 12 0 16 1 16 0 1 11 0 52 1 0 2 49 2 32 1 0 2 32 1 0 2 50)} "find-oob-swaps" {:upvalue-count 0 :arity 1 :constants ("list" {:upvalue-count 2 :arity 1 :constants ("dom-query-all" "[" "]" "str" {:upvalue-count 2 :arity 1 :constants ("dom-get-attr" "outerHTML" "dom-id" "dom-remove-attr" "element" "swap-type" "target-id" "dict" "append!") :bytecode (20 0 0 16 0 18 0 48 2 6 34 4 0 5 1 1 0 17 1 20 2 0 16 0 48 1 17 2 20 3 0 16 0 18 0 48 2 5 16 2 33 28 0 18 1 1 4 0 16 0 1 5 0 16 1 1 6 0 16 2 52 7 0 6 52 8 0 2 32 1 0 2 50)} "for-each") :bytecode (20 0 0 18 0 1 1 0 16 0 1 2 0 52 3 0 3 48 2 17 1 51 4 0 1 0 0 1 16 1 52 5 0 2 50)} "sx-swap-oob" "hx-swap-oob" "for-each") :bytecode (52 0 0 0 17 1 51 1 0 1 0 1 1 1 2 0 1 3 0 52 0 0 2 52 4 0 2 5 16 1 50)} "morph-node" {:upvalue-count 0 :arity 2 :constants ("dom-has-attr?" "sx-preserve" "sx-ignore" "data-sx-island" "is-processed?" "island-hydrated" "dom-get-attr" "data-sx-state" "sync-attrs" "dispose-island" "hydrate-island" "morph-island-children" "dom-node-type" "dom-node-name" "dom-replace-child" "dom-parent" "dom-clone" 3 8 "dom-text-content" "dom-set-text-content" 1 "dispose-islands-in" "dom-is-active-element?" "dom-is-input-element?" "morph-children") :bytecode (20 0 0 16 0 1 1 0 48 2 6 34 11 0 5 20 0 0 16 0 1 2 0 48 2 33 4 0 2 32 167 1 20 0 0 16 0 1 3 0 48 2 6 33 52 0 5 20 4 0 16 0 1 5 0 48 2 6 33 37 0 5 20 0 0 16 1 1 3 0 48 2 6 33 22 0 5 20 6 0 16 0 1 3 0 48 2 20 6 0 16 1 1 3 0 48 2 164 33 80 0 20 6 0 16 0 1 7 0 48 2 17 2 20 6 0 16 1 1 7 0 48 2 17 3 20 8 0 16 0 16 1 48 2 5 16 3 6 33 7 0 5 16 2 16 3 164 167 33 18 0 20 9 0 16 0 48 1 5 20 10 0 16 0 49 1 32 9 0 20 11 0 16 0 16 1 49 2 32 18 1 20 12 0 16 0 48 1 20 12 0 16 1 48 1 164 167 6 34 17 0 5 20 13 0 16 0 48 1 20 13 0 16 1 48 1 164 167 33 25 0 20 14 0 20 15 0 16 0 48 1 20 16 0 16 1 3 48 2 16 0 49 3 32 209 0 20 12 0 16 0 48 1 1 17 0 164 6 34 12 0 5 20 12 0 16 0 48 1 1 18 0 164 33 40 0 20 19 0 16 0 48 1 20 19 0 16 1 48 1 164 167 33 17 0 20 20 0 16 0 20 19 0 16 1 48 1 49 2 32 1 0 2 32 139 0 20 12 0 16 0 48 1 1 21 0 164 33 124 0 20 0 0 16 0 1 3 0 48 2 6 33 38 0 5 20 0 0 16 1 1 3 0 48 2 6 33 23 0 5 20 6 0 16 0 1 3 0 48 2 20 6 0 16 1 1 3 0 48 2 164 167 33 18 0 20 9 0 16 0 48 1 5 20 22 0 16 0 48 1 32 1 0 2 5 20 8 0 16 0 16 1 48 2 5 20 23 0 16 0 48 1 6 33 8 0 5 20 24 0 16 0 48 1 167 33 12 0 20 25 0 16 0 16 1 49 2 32 1 0 2 32 1 0 2 50)} "sync-attrs" {:upvalue-count 0 :arity 2 :constants ("dom-get-attr" "data-sx-reactive-attrs" "" "empty?" "list" "," "split" {:upvalue-count 2 :arity 1 :constants (1 "nth" "dom-get-attr" "contains?" "dom-set-attr") :bytecode (16 0 169 17 1 16 0 1 0 0 52 1 0 2 17 2 20 2 0 18 0 16 1 48 2 16 2 164 167 6 33 10 0 5 18 1 16 1 52 3 0 2 167 33 14 0 20 4 0 18 0 16 1 16 2 49 3 32 1 0 2 50)} "dom-attr-list" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-has-attr?" "contains?" "data-sx-reactive-attrs" "dom-remove-attr") :bytecode (16 0 169 17 1 20 0 0 18 0 16 1 48 2 167 6 33 22 0 5 18 1 16 1 52 1 0 2 167 6 33 8 0 5 16 1 1 2 0 164 167 33 12 0 20 3 0 18 2 16 1 49 2 32 1 0 2 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 6 34 4 0 5 1 2 0 17 2 16 2 52 3 0 1 33 7 0 52 4 0 0 32 9 0 16 2 1 5 0 52 6 0 2 17 3 51 7 0 1 0 1 3 20 8 0 16 1 48 1 52 9 0 2 5 51 10 0 1 1 1 3 1 0 20 8 0 16 0 48 1 52 9 0 2 50)} "morph-children" {:upvalue-count 0 :arity 2 :constants ("dom-child-list" "dict" 0 {:upvalue-count 3 :arity 1 :constants ("dom-id" "empty?" "dict-set!" "inc") :bytecode (20 0 0 16 0 48 1 17 1 16 1 6 33 8 0 5 16 1 52 1 0 1 167 33 24 0 18 0 16 1 16 0 52 2 0 3 5 18 1 16 1 18 2 52 2 0 3 32 1 0 2 5 18 2 52 3 0 1 19 2 50)} "for-each" {:upvalue-count 6 :arity 1 :constants ("dom-id" "empty?" "dict-get" "nil?" "str" "dict-set!" "nth" "dom-insert-before" "morph-node" "inc" "dom-clone" "dom-append") :bytecode (20 0 0 16 0 48 1 17 1 16 1 6 33 8 0 5 16 1 52 1 0 1 167 33 5 0 16 1 32 1 0 2 17 2 16 2 33 11 0 18 0 16 2 52 2 0 2 32 1 0 2 17 3 16 3 6 33 8 0 5 16 3 52 3 0 1 167 33 115 0 18 1 16 2 52 2 0 2 17 4 16 4 33 16 0 18 2 16 4 52 4 0 1 3 52 5 0 3 32 1 0 2 5 18 3 18 4 168 165 6 33 13 0 5 16 3 18 4 18 3 52 6 0 2 164 167 33 33 0 20 7 0 18 5 16 3 18 3 18 4 168 165 33 11 0 18 4 18 3 52 6 0 2 32 1 0 2 48 3 32 1 0 2 5 20 8 0 16 3 16 0 48 2 5 18 3 52 9 0 1 19 3 32 123 0 18 3 18 4 168 165 33 99 0 18 4 18 3 52 6 0 2 17 4 20 0 0 16 4 48 1 17 5 16 5 6 33 16 0 5 16 5 52 1 0 1 167 6 33 4 0 5 16 2 167 33 20 0 20 7 0 18 5 20 10 0 16 0 3 48 2 16 4 49 3 32 32 0 18 2 18 3 52 4 0 1 3 52 5 0 3 5 20 8 0 16 4 16 0 48 2 5 18 3 52 9 0 1 19 3 32 15 0 20 11 0 18 5 20 10 0 16 0 3 48 2 49 2 50)} {:upvalue-count 3 :arity 1 :constants ("str" "dict-get" "nth" "dom-is-child-of?" "dom-has-attr?" "sx-preserve" "sx-ignore" "dom-remove-child") :bytecode (18 0 16 0 52 0 0 1 52 1 0 2 167 33 70 0 18 1 16 0 52 2 0 2 17 1 20 3 0 16 1 18 2 48 2 6 33 28 0 5 20 4 0 16 1 1 5 0 48 2 167 6 33 12 0 5 20 4 0 16 1 1 6 0 48 2 167 33 12 0 20 7 0 18 2 16 1 49 2 32 1 0 2 32 1 0 2 50)} "range") :bytecode (20 0 0 16 0 48 1 17 2 20 0 0 16 1 48 1 17 3 52 1 0 0 17 4 52 1 0 0 17 5 52 1 0 0 17 6 1 2 0 17 7 1 2 0 17 8 51 3 0 1 4 1 5 1 8 16 2 52 4 0 2 5 51 5 0 1 4 1 5 1 6 1 7 1 2 1 0 16 3 52 4 0 2 5 51 6 0 1 6 1 2 1 0 1 2 0 16 2 168 52 7 0 2 52 4 0 2 50)} "morph-island-children" {:upvalue-count 0 :arity 2 :constants ("dom-query-all" "[data-sx-lake]" "[data-sx-marsh]" "dict" {:upvalue-count 1 :arity 1 :constants ("dom-get-attr" "data-sx-lake" "dict-set!") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 13 0 18 0 16 1 16 0 52 2 0 3 32 1 0 2 50)} "for-each" {:upvalue-count 1 :arity 1 :constants ("dom-get-attr" "data-sx-marsh" "dict-set!") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 13 0 18 0 16 1 16 0 52 2 0 3 32 1 0 2 50)} {:upvalue-count 1 :arity 1 :constants ("dom-get-attr" "data-sx-lake" "dict-get" "sync-attrs" "morph-children") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 18 0 16 1 52 2 0 2 17 2 16 2 33 22 0 20 3 0 16 0 16 2 48 2 5 20 4 0 16 0 16 2 49 2 32 1 0 2 50)} {:upvalue-count 2 :arity 1 :constants ("dom-get-attr" "data-sx-marsh" "dict-get" "morph-marsh") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 18 0 16 1 52 2 0 2 17 2 16 2 33 14 0 20 3 0 16 0 16 2 18 1 49 3 32 1 0 2 50)} "process-signal-updates") :bytecode (20 0 0 16 0 1 1 0 48 2 17 2 20 0 0 16 1 1 1 0 48 2 17 3 20 0 0 16 0 1 2 0 48 2 17 4 20 0 0 16 1 1 2 0 48 2 17 5 52 3 0 0 17 6 52 3 0 0 17 7 51 4 0 1 6 16 3 52 5 0 2 5 51 6 0 1 7 16 5 52 5 0 2 5 51 7 0 1 6 16 2 52 5 0 2 5 51 8 0 1 7 1 0 16 4 52 5 0 2 5 20 9 0 16 1 49 1 50)} "morph-marsh" {:upvalue-count 0 :arity 3 :constants ("dom-get-data" "sx-marsh-transform" "sx-marsh-env" "dom-inner-html" "empty?" "parse" "list" "cek-call" "dispose-marsh-scope" "with-marsh-scope" {:upvalue-count 3 :arity 0 :constants ("render-to-dom" "dom-remove-children-after" "dom-append") :bytecode (20 0 0 18 0 18 1 2 48 3 17 0 20 1 0 18 2 2 48 2 5 20 2 0 18 2 16 0 49 2 50)} "sync-attrs" "morph-children") :bytecode (20 0 0 16 0 1 1 0 48 2 17 3 20 0 0 16 0 1 2 0 48 2 17 4 20 3 0 16 1 48 1 17 5 16 4 6 33 15 0 5 16 5 6 33 8 0 5 16 5 52 4 0 1 167 33 59 0 16 5 52 5 0 1 17 6 16 3 33 15 0 16 3 16 6 52 6 0 1 52 7 0 2 32 2 0 16 6 17 7 20 8 0 16 0 48 1 5 20 9 0 16 0 51 10 0 1 7 1 4 1 0 49 2 32 19 0 20 11 0 16 0 16 1 48 2 5 20 12 0 16 0 16 1 49 2 50)} "process-signal-updates" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "[data-sx-signal]" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "data-sx-signal" ":" "index-of" 0 "slice" 1 "json-parse" "reset!" "use-store" "dom-remove-attr") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 87 0 16 1 1 2 0 52 3 0 2 17 2 16 2 1 4 0 166 33 63 0 16 1 1 4 0 16 2 52 5 0 3 17 3 16 1 16 2 1 6 0 160 52 5 0 2 17 4 20 7 0 16 4 48 1 17 5 20 8 0 16 3 52 9 0 1 16 5 48 2 5 20 10 0 16 0 1 1 0 49 2 32 1 0 2 32 1 0 2 50)} "for-each") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 51 2 0 16 1 52 3 0 2 50)} "swap-dom-nodes" {:upvalue-count 0 :arity 3 :constants ("innerHTML" "=" "dom-is-fragment?" "morph-children" "dom-create-element" "div" "dom-append" "outerHTML" "dom-parent" "dom-clone" "dom-first-child" "dom-replace-child" "dom-next-sibling" "insert-remaining-siblings" "dom-remove-child" "afterend" "dom-insert-after" "beforeend" "afterbegin" "dom-prepend" "beforebegin" "dom-insert-before" "delete" "none") :bytecode (16 2 6 1 0 0 52 1 0 2 33 56 0 5 20 2 0 16 1 48 1 33 12 0 20 3 0 16 0 16 1 49 2 32 30 0 20 4 0 1 5 0 2 48 2 17 3 20 6 0 16 3 16 1 48 2 5 20 3 0 16 0 16 3 49 2 32 75 1 6 1 7 0 52 1 0 2 33 119 0 5 20 8 0 16 0 48 1 17 3 20 9 0 16 1 3 48 2 17 4 20 2 0 16 1 48 1 33 72 0 20 10 0 16 1 48 1 17 5 16 5 33 46 0 20 9 0 16 5 3 48 2 17 4 5 20 11 0 16 3 16 4 16 0 48 3 5 20 12 0 16 5 48 1 17 6 20 13 0 16 3 16 4 16 6 48 3 32 9 0 20 14 0 16 3 16 0 48 2 32 11 0 20 11 0 16 3 16 4 16 0 48 3 5 16 4 32 201 0 6 1 15 0 52 1 0 2 33 13 0 5 20 16 0 16 0 16 1 49 2 32 177 0 6 1 17 0 52 1 0 2 33 13 0 5 20 6 0 16 0 16 1 49 2 32 153 0 6 1 18 0 52 1 0 2 33 13 0 5 20 19 0 16 0 16 1 49 2 32 129 0 6 1 20 0 52 1 0 2 33 20 0 5 20 21 0 20 8 0 16 0 48 1 16 1 16 0 49 3 32 98 0 6 1 22 0 52 1 0 2 33 18 0 5 20 14 0 20 8 0 16 0 48 1 16 0 49 2 32 69 0 6 1 23 0 52 1 0 2 33 5 0 5 2 32 53 0 5 20 2 0 16 1 48 1 33 12 0 20 3 0 16 0 16 1 49 2 32 30 0 20 4 0 1 5 0 2 48 2 17 3 20 6 0 16 3 16 1 48 2 5 20 3 0 16 0 16 3 49 2 50)} "insert-remaining-siblings" {:upvalue-count 0 :arity 3 :constants ("dom-next-sibling" "dom-insert-after" "insert-remaining-siblings") :bytecode (16 2 33 33 0 20 0 0 16 2 48 1 17 3 20 1 0 16 1 16 2 48 2 5 20 2 0 16 0 16 2 16 3 49 3 32 1 0 2 50)} "swap-html-string" {:upvalue-count 0 :arity 3 :constants ("innerHTML" "=" "dom-set-inner-html" "outerHTML" "dom-parent" "dom-insert-adjacent-html" "afterend" "dom-remove-child" "beforeend" "afterbegin" "beforebegin" "delete" "none") :bytecode (16 2 6 1 0 0 52 1 0 2 33 13 0 5 20 2 0 16 0 16 1 49 2 32 212 0 6 1 3 0 52 1 0 2 33 38 0 5 20 4 0 16 0 48 1 17 3 20 5 0 16 0 1 6 0 16 1 48 3 5 20 7 0 16 3 16 0 48 2 5 16 3 32 163 0 6 1 6 0 52 1 0 2 33 16 0 5 20 5 0 16 0 1 6 0 16 1 49 3 32 136 0 6 1 8 0 52 1 0 2 33 16 0 5 20 5 0 16 0 1 8 0 16 1 49 3 32 109 0 6 1 9 0 52 1 0 2 33 16 0 5 20 5 0 16 0 1 9 0 16 1 49 3 32 82 0 6 1 10 0 52 1 0 2 33 16 0 5 20 5 0 16 0 1 10 0 16 1 49 3 32 55 0 6 1 11 0 52 1 0 2 33 18 0 5 20 7 0 20 4 0 16 0 48 1 16 0 49 2 32 26 0 6 1 12 0 52 1 0 2 33 5 0 5 2 32 10 0 5 20 2 0 16 0 16 1 49 2 50)} "handle-history" {:upvalue-count 0 :arity 3 :constants ("dom-get-attr" "sx-push-url" "sx-replace-url" "replace-url" "get" "browser-replace-state" "false" "save-scroll-position" "browser-push-state" "true") :bytecode (20 0 0 16 0 1 1 0 48 2 17 3 20 0 0 16 0 1 2 0 48 2 17 4 16 2 1 3 0 52 4 0 2 17 5 16 5 33 10 0 20 5 0 16 5 49 1 32 89 0 16 3 6 33 8 0 5 16 3 1 6 0 164 167 33 30 0 20 7 0 48 0 5 20 8 0 16 3 1 9 0 164 33 5 0 16 1 32 2 0 16 3 49 1 32 42 0 16 4 6 33 8 0 5 16 4 1 6 0 164 167 33 24 0 20 5 0 16 4 1 9 0 164 33 5 0 16 1 32 2 0 16 4 49 1 32 1 0 2 50)} "PRELOAD_TTL" 30000 "preload-cache-get" {:upvalue-count 0 :arity 2 :constants ("dict-get" "nil?" "now-ms" "timestamp" "get" "PRELOAD_TTL" "dict-delete!") :bytecode (16 0 16 1 52 0 0 2 17 2 16 2 52 1 0 1 33 4 0 2 32 46 0 20 2 0 48 0 16 2 1 3 0 52 4 0 2 161 20 5 0 166 33 13 0 16 0 16 1 52 6 0 2 5 2 32 11 0 16 0 16 1 52 6 0 2 5 16 2 50)} "preload-cache-set" {:upvalue-count 0 :arity 4 :constants ("text" "content-type" "timestamp" "now-ms" "dict" "dict-set!") :bytecode (16 0 16 1 1 0 0 16 2 1 1 0 16 3 1 2 0 20 3 0 48 0 52 4 0 6 52 5 0 3 50)} "classify-trigger" {:upvalue-count 0 :arity 1 :constants ("event" "get" "every" "=" "poll" "intersect" "load" "revealed") :bytecode (16 0 1 0 0 52 1 0 2 17 1 16 1 6 1 2 0 52 3 0 2 33 7 0 5 1 4 0 32 58 0 6 1 5 0 52 3 0 2 33 7 0 5 1 5 0 32 40 0 6 1 6 0 52 3 0 2 33 7 0 5 1 6 0 32 22 0 6 1 7 0 52 3 0 2 33 7 0 5 1 7 0 32 4 0 5 1 0 0 50)} "should-boost-link?" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "href" "#" "starts-with?" "javascript:" "mailto:" "browser-same-origin?" "dom-has-attr?" "sx-get" "sx-post" "sx-disable") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 33 101 0 5 16 1 1 2 0 52 3 0 2 167 6 33 86 0 5 16 1 1 4 0 52 3 0 2 167 6 33 71 0 5 16 1 1 5 0 52 3 0 2 167 6 33 56 0 5 20 6 0 16 1 48 1 6 33 44 0 5 20 7 0 16 0 1 8 0 48 2 167 6 33 28 0 5 20 7 0 16 0 1 9 0 48 2 167 6 33 12 0 5 20 7 0 16 0 1 10 0 48 2 167 50)} "should-boost-form?" {:upvalue-count 0 :arity 1 :constants ("dom-has-attr?" "sx-get" "sx-post" "sx-disable") :bytecode (20 0 0 16 0 1 1 0 48 2 167 6 33 28 0 5 20 0 0 16 0 1 2 0 48 2 167 6 33 12 0 5 20 0 0 16 0 1 3 0 48 2 167 50)} "parse-sse-swap" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-sse-swap" "message") :bytecode (20 0 0 16 0 1 1 0 48 2 6 34 4 0 5 1 2 0 50)} {:library (web engine) :op "import"}) :bytecode (1 1 0 1 2 0 1 3 0 1 4 0 1 5 0 52 6 0 5 128 0 0 5 1 8 0 128 7 0 5 51 10 0 128 9 0 5 51 12 0 128 11 0 5 51 14 0 128 13 0 5 51 16 0 128 15 0 5 51 18 0 128 17 0 5 51 20 0 128 19 0 5 51 22 0 128 21 0 5 51 24 0 128 23 0 5 51 26 0 128 25 0 5 51 28 0 128 27 0 5 51 30 0 128 29 0 5 51 32 0 128 31 0 5 51 34 0 128 33 0 5 51 36 0 128 35 0 5 51 38 0 128 37 0 5 51 40 0 128 39 0 5 51 42 0 128 41 0 5 51 44 0 128 43 0 5 51 46 0 128 45 0 5 51 48 0 128 47 0 5 51 50 0 128 49 0 5 51 52 0 128 51 0 5 51 54 0 128 53 0 5 51 56 0 128 55 0 5 1 58 0 128 57 0 5 51 60 0 128 59 0 5 51 62 0 128 61 0 5 51 64 0 128 63 0 5 51 66 0 128 65 0 5 51 68 0 128 67 0 5 51 70 0 128 69 0 5 1 71 0 112 50))) + :constants ("ENGINE_VERBS" "get" "post" "put" "delete" "patch" "list" "DEFAULT_SWAP" "outerHTML" "parse-time" {:upvalue-count 0 :arity 1 :constants ("nil?" 0 "ms" "ends-with?" "parse-int" "s" "" "replace" 1000) :bytecode (16 0 52 0 0 1 33 6 0 1 1 0 32 71 0 16 0 1 2 0 52 3 0 2 33 12 0 16 0 1 1 0 52 4 0 2 32 47 0 16 0 1 5 0 52 3 0 2 33 26 0 16 0 1 5 0 1 6 0 52 7 0 3 1 1 0 52 4 0 2 1 8 0 162 32 9 0 16 0 1 1 0 52 4 0 2 50)} "parse-trigger-spec" {:upvalue-count 0 :arity 1 :constants ("nil?" "," "split" {:upvalue-count 0 :arity 1 :constants ("nil?") :bytecode (16 0 52 0 0 1 167 50)} {:upvalue-count 0 :arity 1 :constants ("trim" " " "split" "empty?" "every" 2 ">=" "event" "modifiers" "interval" "parse-time" 1 "nth" "dict" {:upvalue-count 1 :arity 1 :constants ("once" "dict-set!" "changed" "delay:" "starts-with?" "delay" "parse-time" 6 "slice" "from:" "from" 5) :bytecode (16 0 1 0 0 164 33 13 0 18 0 1 0 0 3 52 1 0 3 32 94 0 16 0 1 2 0 164 33 13 0 18 0 1 2 0 3 52 1 0 3 32 72 0 16 0 1 3 0 52 4 0 2 33 26 0 18 0 1 5 0 20 6 0 16 0 1 7 0 52 8 0 2 48 1 52 1 0 3 32 34 0 16 0 1 9 0 52 4 0 2 33 21 0 18 0 1 10 0 16 0 1 11 0 52 8 0 2 52 1 0 3 32 1 0 2 50)} "for-each" "[" "index-of" 0 "filter" "slice" "dict-set!") :bytecode (16 0 52 0 0 1 1 1 0 52 2 0 2 17 1 16 1 52 3 0 1 33 4 0 2 32 178 0 16 1 169 1 4 0 164 6 33 11 0 5 16 1 168 1 5 0 52 6 0 2 33 37 0 1 7 0 1 4 0 1 8 0 1 9 0 20 10 0 16 1 1 11 0 52 12 0 2 48 1 52 13 0 2 52 13 0 4 32 116 0 52 13 0 0 17 2 51 14 0 1 2 16 1 170 52 15 0 2 5 16 1 169 17 3 16 3 1 16 0 52 17 0 2 17 4 16 4 1 18 0 52 6 0 2 33 55 0 16 2 1 19 0 16 3 16 4 1 11 0 160 16 3 168 1 11 0 161 52 20 0 3 52 21 0 3 5 1 7 0 16 3 1 18 0 16 4 52 20 0 3 1 8 0 16 2 52 13 0 4 32 14 0 1 7 0 16 3 1 8 0 16 2 52 13 0 4 50)} "map" "filter") :bytecode (16 0 52 0 0 1 33 4 0 2 32 27 0 16 0 1 1 0 52 2 0 2 17 1 51 3 0 51 4 0 16 1 52 5 0 2 52 6 0 2 50)} "default-trigger" {:upvalue-count 0 :arity 1 :constants ("form" "=" "event" "submit" "modifiers" "dict" "list" "input" "change" "select" "textarea" "click") :bytecode (16 0 6 1 0 0 52 1 0 2 33 25 0 5 1 2 0 1 3 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 32 130 0 6 1 7 0 52 1 0 2 33 25 0 5 1 2 0 1 8 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 32 94 0 6 1 9 0 52 1 0 2 33 25 0 5 1 2 0 1 8 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 32 58 0 6 1 10 0 52 1 0 2 33 25 0 5 1 2 0 1 8 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 32 22 0 5 1 2 0 1 11 0 1 4 0 52 5 0 0 52 5 0 4 52 6 0 1 50)} "get-verb-info" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 1 :arity 1 :constants ("dom-get-attr" "sx-" "str" "method" "upper" "url" "dict") :bytecode (20 0 0 18 0 1 1 0 16 0 52 2 0 2 48 2 17 1 16 1 33 21 0 1 3 0 16 0 52 4 0 1 1 5 0 16 1 52 6 0 4 32 1 0 2 50)} "ENGINE_VERBS" "some") :bytecode (51 0 0 1 0 20 1 0 52 2 0 2 50)} "build-request-headers" {:upvalue-count 0 :arity 2 :constants ("SX-Request" "true" "SX-Current-URL" "browser-location-href" "dict" "dom-get-attr" "sx-target" "SX-Target" "dict-set!" "dom-query" "script[data-components][data-hash]" "data-hash" "SX-Components-Hash" "sx-headers" "parse-header-value" {:upvalue-count 2 :arity 1 :constants ("get" "str" "dict-set!") :bytecode (18 0 16 0 18 1 16 0 52 0 0 2 52 1 0 1 52 2 0 3 50)} "keys" "for-each") :bytecode (1 0 0 1 1 0 1 2 0 20 3 0 48 0 52 4 0 4 17 2 20 5 0 16 0 1 6 0 48 2 17 3 16 3 33 14 0 16 2 1 7 0 16 3 52 8 0 3 32 1 0 2 5 20 5 0 20 9 0 1 10 0 48 1 1 11 0 48 2 17 3 16 3 33 14 0 16 2 1 12 0 16 3 52 8 0 3 32 1 0 2 5 20 5 0 16 0 1 13 0 48 2 17 3 16 3 33 38 0 20 14 0 16 3 48 1 17 4 16 4 33 20 0 51 15 0 1 2 1 4 16 4 52 16 0 1 52 17 0 2 32 1 0 2 32 1 0 2 5 16 2 50)} "process-response-headers" {:upvalue-count 0 :arity 1 :constants ("redirect" "SX-Redirect" "refresh" "SX-Refresh" "trigger" "SX-Trigger" "retarget" "SX-Retarget" "reswap" "SX-Reswap" "location" "SX-Location" "replace-url" "SX-Replace-Url" "trigger-swap" "SX-Trigger-After-Swap" "trigger-settle" "SX-Trigger-After-Settle" "content-type" "Content-Type" "cache-invalidate" "SX-Cache-Invalidate" "cache-update" "SX-Cache-Update" "dict") :bytecode (1 0 0 16 0 1 1 0 48 1 1 2 0 16 0 1 3 0 48 1 1 4 0 16 0 1 5 0 48 1 1 6 0 16 0 1 7 0 48 1 1 8 0 16 0 1 9 0 48 1 1 10 0 16 0 1 11 0 48 1 1 12 0 16 0 1 13 0 48 1 1 14 0 16 0 1 15 0 48 1 1 16 0 16 0 1 17 0 48 1 1 18 0 16 0 1 19 0 48 1 1 20 0 16 0 1 21 0 48 1 1 22 0 16 0 1 23 0 48 1 52 24 0 24 50)} "parse-swap-spec" {:upvalue-count 0 :arity 2 :constants ("DEFAULT_SWAP" " " "split" {:upvalue-count 1 :arity 1 :constants ("transition:true" "transition:false") :bytecode (16 0 1 0 0 164 33 6 0 3 19 0 32 16 0 16 0 1 1 0 164 33 6 0 4 19 0 32 1 0 2 50)} "for-each" "style" "transition" "dict") :bytecode (16 0 6 34 4 0 5 20 0 0 1 1 0 52 2 0 2 17 2 16 2 169 17 3 16 1 17 4 51 3 0 1 4 16 2 170 52 4 0 2 5 1 5 0 16 3 1 6 0 16 4 52 7 0 4 50)} "parse-retry-spec" {:upvalue-count 0 :arity 1 :constants ("nil?" ":" "split" "strategy" "start-ms" 1 "nth" 1000 "parse-int" "cap-ms" 2 30000 "dict") :bytecode (16 0 52 0 0 1 33 4 0 2 32 59 0 16 0 1 1 0 52 2 0 2 17 1 1 3 0 16 1 169 1 4 0 16 1 1 5 0 52 6 0 2 1 7 0 52 8 0 2 1 9 0 16 1 1 10 0 52 6 0 2 1 11 0 52 8 0 2 52 12 0 6 50)} "next-retry-ms" {:upvalue-count 0 :arity 2 :constants (2 "min") :bytecode (16 0 1 0 0 162 16 1 52 1 0 2 50)} "filter-params" {:upvalue-count 0 :arity 2 :constants ("nil?" "none" "list" "*" "not " "starts-with?" "trim" 4 "slice" "," "split" "map" {:upvalue-count 1 :arity 1 :constants ("contains?") :bytecode (18 0 16 0 169 52 0 0 2 167 50)} "filter" {:upvalue-count 1 :arity 1 :constants ("contains?") :bytecode (18 0 16 0 169 52 0 0 2 50)}) :bytecode (16 0 52 0 0 1 33 5 0 16 1 32 110 0 16 0 1 1 0 164 33 7 0 52 2 0 0 32 94 0 16 0 1 3 0 164 33 5 0 16 1 32 80 0 16 0 1 4 0 52 5 0 2 33 39 0 20 6 0 16 0 1 7 0 52 8 0 2 1 9 0 52 10 0 2 52 11 0 2 17 2 51 12 0 1 2 16 1 52 13 0 2 32 29 0 20 6 0 16 0 1 9 0 52 10 0 2 52 11 0 2 17 2 51 14 0 1 2 16 1 52 13 0 2 50)} "resolve-target" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-target" "=" "this" "closest" "dom-parent" "dom-query") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 2 52 2 0 2 33 6 0 5 16 0 32 47 0 6 1 3 0 52 2 0 2 33 6 0 5 16 0 32 30 0 6 1 4 0 52 2 0 2 33 11 0 5 20 5 0 16 0 49 1 32 8 0 5 20 6 0 16 1 49 1 50)} "apply-optimistic" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-optimistic" "nil?" "resolve-target" "target" "directive" "dict" "remove" "opacity" "dom-get-style" "dict-set!" "dom-set-style" "0" "pointer-events" "none" "disable" "disabled" "dom-get-prop" "dom-set-prop" "add-class:" "starts-with?" 10 "slice" "add-class" "dom-add-class") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 52 2 0 1 33 4 0 2 32 185 0 20 3 0 16 0 48 1 6 34 3 0 5 16 0 17 2 1 4 0 16 2 1 5 0 16 1 52 6 0 4 17 3 16 1 1 7 0 164 33 50 0 16 3 1 8 0 20 9 0 16 2 1 8 0 48 2 52 10 0 3 5 20 11 0 16 2 1 8 0 1 12 0 48 3 5 20 11 0 16 2 1 13 0 1 14 0 48 3 32 91 0 16 1 1 15 0 164 33 34 0 16 3 1 16 0 20 17 0 16 2 1 16 0 48 2 52 10 0 3 5 20 18 0 16 2 1 16 0 3 48 3 32 48 0 16 1 1 19 0 52 20 0 2 33 35 0 16 1 1 21 0 52 22 0 2 17 4 16 3 1 23 0 16 4 52 10 0 3 5 20 24 0 16 2 16 4 48 2 32 1 0 2 5 16 3 50)} "revert-optimistic" {:upvalue-count 0 :arity 1 :constants ("target" "get" "directive" "remove" "dom-set-style" "opacity" "" "pointer-events" "disable" "dom-set-prop" "disabled" "add-class" "dom-remove-class") :bytecode (16 0 33 147 0 16 0 1 0 0 52 1 0 2 17 1 16 0 1 2 0 52 1 0 2 17 2 16 2 1 3 0 164 33 44 0 20 4 0 16 1 1 5 0 16 0 1 5 0 52 1 0 2 6 34 4 0 5 1 6 0 48 3 5 20 4 0 16 1 1 7 0 1 6 0 49 3 32 69 0 16 2 1 8 0 164 33 28 0 20 9 0 16 1 1 10 0 16 0 1 10 0 52 1 0 2 6 34 2 0 5 4 49 3 32 32 0 16 0 1 11 0 52 1 0 2 33 19 0 20 12 0 16 1 16 0 1 11 0 52 1 0 2 49 2 32 1 0 2 32 1 0 2 50)} "find-oob-swaps" {:upvalue-count 0 :arity 1 :constants ("list" {:upvalue-count 2 :arity 1 :constants ("dom-query-all" "[" "]" "str" {:upvalue-count 2 :arity 1 :constants ("dom-get-attr" "outerHTML" "dom-id" "dom-remove-attr" "element" "swap-type" "target-id" "dict" "append!") :bytecode (20 0 0 16 0 18 0 48 2 6 34 4 0 5 1 1 0 17 1 20 2 0 16 0 48 1 17 2 20 3 0 16 0 18 0 48 2 5 16 2 33 28 0 18 1 1 4 0 16 0 1 5 0 16 1 1 6 0 16 2 52 7 0 6 52 8 0 2 32 1 0 2 50)} "for-each") :bytecode (20 0 0 18 0 1 1 0 16 0 1 2 0 52 3 0 3 48 2 17 1 51 4 0 1 0 0 1 16 1 52 5 0 2 50)} "sx-swap-oob" "hx-swap-oob" "for-each") :bytecode (52 0 0 0 17 1 51 1 0 1 0 1 1 1 2 0 1 3 0 52 0 0 2 52 4 0 2 5 16 1 50)} "morph-node" {:upvalue-count 0 :arity 2 :constants ("dom-has-attr?" "sx-preserve" "sx-ignore" "data-sx-island" "is-processed?" "island-hydrated" "dom-get-attr" "data-sx-state" "sync-attrs" "dispose-island" "hydrate-island" "morph-island-children" "dom-node-type" "dom-node-name" "dom-replace-child" "dom-parent" "dom-clone" 3 8 "dom-text-content" "dom-set-text-content" 1 "dispose-islands-in" "dom-is-active-element?" "dom-is-input-element?" "morph-children") :bytecode (20 0 0 16 0 1 1 0 48 2 6 34 11 0 5 20 0 0 16 0 1 2 0 48 2 33 4 0 2 32 167 1 20 0 0 16 0 1 3 0 48 2 6 33 52 0 5 20 4 0 16 0 1 5 0 48 2 6 33 37 0 5 20 0 0 16 1 1 3 0 48 2 6 33 22 0 5 20 6 0 16 0 1 3 0 48 2 20 6 0 16 1 1 3 0 48 2 164 33 80 0 20 6 0 16 0 1 7 0 48 2 17 2 20 6 0 16 1 1 7 0 48 2 17 3 20 8 0 16 0 16 1 48 2 5 16 3 6 33 7 0 5 16 2 16 3 164 167 33 18 0 20 9 0 16 0 48 1 5 20 10 0 16 0 49 1 32 9 0 20 11 0 16 0 16 1 49 2 32 18 1 20 12 0 16 0 48 1 20 12 0 16 1 48 1 164 167 6 34 17 0 5 20 13 0 16 0 48 1 20 13 0 16 1 48 1 164 167 33 25 0 20 14 0 20 15 0 16 0 48 1 20 16 0 16 1 3 48 2 16 0 49 3 32 209 0 20 12 0 16 0 48 1 1 17 0 164 6 34 12 0 5 20 12 0 16 0 48 1 1 18 0 164 33 40 0 20 19 0 16 0 48 1 20 19 0 16 1 48 1 164 167 33 17 0 20 20 0 16 0 20 19 0 16 1 48 1 49 2 32 1 0 2 32 139 0 20 12 0 16 0 48 1 1 21 0 164 33 124 0 20 0 0 16 0 1 3 0 48 2 6 33 38 0 5 20 0 0 16 1 1 3 0 48 2 6 33 23 0 5 20 6 0 16 0 1 3 0 48 2 20 6 0 16 1 1 3 0 48 2 164 167 33 18 0 20 9 0 16 0 48 1 5 20 22 0 16 0 48 1 32 1 0 2 5 20 8 0 16 0 16 1 48 2 5 20 23 0 16 0 48 1 6 33 8 0 5 20 24 0 16 0 48 1 167 33 12 0 20 25 0 16 0 16 1 49 2 32 1 0 2 32 1 0 2 50)} "sync-attrs" {:upvalue-count 0 :arity 2 :constants ("dom-get-attr" "data-sx-reactive-attrs" "" "empty?" "list" "," "split" {:upvalue-count 2 :arity 1 :constants (1 "nth" "dom-get-attr" "contains?" "dom-set-attr") :bytecode (16 0 169 17 1 16 0 1 0 0 52 1 0 2 17 2 20 2 0 18 0 16 1 48 2 16 2 164 167 6 33 10 0 5 18 1 16 1 52 3 0 2 167 33 14 0 20 4 0 18 0 16 1 16 2 49 3 32 1 0 2 50)} "dom-attr-list" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-has-attr?" "contains?" "data-sx-reactive-attrs" "sx-target" "sx-swap" "sx-push-url" "sx-get" "sx-select" "dom-remove-attr") :bytecode (16 0 169 17 1 20 0 0 18 0 16 1 48 2 167 6 33 82 0 5 18 1 16 1 52 1 0 2 167 6 33 68 0 5 16 1 1 2 0 164 167 6 33 56 0 5 16 1 1 3 0 164 167 6 33 44 0 5 16 1 1 4 0 164 167 6 33 32 0 5 16 1 1 5 0 164 167 6 33 20 0 5 16 1 1 6 0 164 167 6 33 8 0 5 16 1 1 7 0 164 167 33 12 0 20 8 0 18 2 16 1 49 2 32 1 0 2 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 6 34 4 0 5 1 2 0 17 2 16 2 52 3 0 1 33 7 0 52 4 0 0 32 9 0 16 2 1 5 0 52 6 0 2 17 3 51 7 0 1 0 1 3 20 8 0 16 1 48 1 52 9 0 2 5 51 10 0 1 1 1 3 1 0 20 8 0 16 0 48 1 52 9 0 2 50)} "morph-children" {:upvalue-count 0 :arity 2 :constants ("dom-child-list" "dict" 0 {:upvalue-count 3 :arity 1 :constants ("dom-id" "empty?" "dict-set!" "inc") :bytecode (20 0 0 16 0 48 1 17 1 16 1 6 33 8 0 5 16 1 52 1 0 1 167 33 24 0 18 0 16 1 16 0 52 2 0 3 5 18 1 16 1 18 2 52 2 0 3 32 1 0 2 5 18 2 52 3 0 1 19 2 50)} "for-each" {:upvalue-count 6 :arity 1 :constants ("dom-id" "empty?" "dict-get" "nil?" "str" "dict-set!" "nth" "dom-insert-before" "morph-node" "inc" "dom-clone" "dom-append") :bytecode (20 0 0 16 0 48 1 17 1 16 1 6 33 8 0 5 16 1 52 1 0 1 167 33 5 0 16 1 32 1 0 2 17 2 16 2 33 11 0 18 0 16 2 52 2 0 2 32 1 0 2 17 3 16 3 6 33 8 0 5 16 3 52 3 0 1 167 33 115 0 18 1 16 2 52 2 0 2 17 4 16 4 33 16 0 18 2 16 4 52 4 0 1 3 52 5 0 3 32 1 0 2 5 18 3 18 4 168 165 6 33 13 0 5 16 3 18 4 18 3 52 6 0 2 164 167 33 33 0 20 7 0 18 5 16 3 18 3 18 4 168 165 33 11 0 18 4 18 3 52 6 0 2 32 1 0 2 48 3 32 1 0 2 5 20 8 0 16 3 16 0 48 2 5 18 3 52 9 0 1 19 3 32 123 0 18 3 18 4 168 165 33 99 0 18 4 18 3 52 6 0 2 17 4 20 0 0 16 4 48 1 17 5 16 5 6 33 16 0 5 16 5 52 1 0 1 167 6 33 4 0 5 16 2 167 33 20 0 20 7 0 18 5 20 10 0 16 0 3 48 2 16 4 49 3 32 32 0 18 2 18 3 52 4 0 1 3 52 5 0 3 5 20 8 0 16 4 16 0 48 2 5 18 3 52 9 0 1 19 3 32 15 0 20 11 0 18 5 20 10 0 16 0 3 48 2 49 2 50)} {:upvalue-count 3 :arity 1 :constants ("str" "dict-get" "nth" "dom-is-child-of?" "dom-has-attr?" "sx-preserve" "sx-ignore" "dom-remove-child") :bytecode (18 0 16 0 52 0 0 1 52 1 0 2 167 33 70 0 18 1 16 0 52 2 0 2 17 1 20 3 0 16 1 18 2 48 2 6 33 28 0 5 20 4 0 16 1 1 5 0 48 2 167 6 33 12 0 5 20 4 0 16 1 1 6 0 48 2 167 33 12 0 20 7 0 18 2 16 1 49 2 32 1 0 2 32 1 0 2 50)} "range") :bytecode (20 0 0 16 0 48 1 17 2 20 0 0 16 1 48 1 17 3 52 1 0 0 17 4 52 1 0 0 17 5 52 1 0 0 17 6 1 2 0 17 7 1 2 0 17 8 51 3 0 1 4 1 5 1 8 16 2 52 4 0 2 5 51 5 0 1 4 1 5 1 6 1 7 1 2 1 0 16 3 52 4 0 2 5 51 6 0 1 6 1 2 1 0 1 2 0 16 2 168 52 7 0 2 52 4 0 2 50)} "morph-island-children" {:upvalue-count 0 :arity 2 :constants ("dom-query-all" "[data-sx-lake]" "[data-sx-marsh]" "dict" {:upvalue-count 1 :arity 1 :constants ("dom-get-attr" "data-sx-lake" "dict-set!") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 13 0 18 0 16 1 16 0 52 2 0 3 32 1 0 2 50)} "for-each" {:upvalue-count 1 :arity 1 :constants ("dom-get-attr" "data-sx-marsh" "dict-set!") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 13 0 18 0 16 1 16 0 52 2 0 3 32 1 0 2 50)} {:upvalue-count 1 :arity 1 :constants ("dom-get-attr" "data-sx-lake" "dict-get" "sync-attrs" "morph-children") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 18 0 16 1 52 2 0 2 17 2 16 2 33 22 0 20 3 0 16 0 16 2 48 2 5 20 4 0 16 0 16 2 49 2 32 1 0 2 50)} {:upvalue-count 2 :arity 1 :constants ("dom-get-attr" "data-sx-marsh" "dict-get" "morph-marsh") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 18 0 16 1 52 2 0 2 17 2 16 2 33 14 0 20 3 0 16 0 16 2 18 1 49 3 32 1 0 2 50)} "process-signal-updates") :bytecode (20 0 0 16 0 1 1 0 48 2 17 2 20 0 0 16 1 1 1 0 48 2 17 3 20 0 0 16 0 1 2 0 48 2 17 4 20 0 0 16 1 1 2 0 48 2 17 5 52 3 0 0 17 6 52 3 0 0 17 7 51 4 0 1 6 16 3 52 5 0 2 5 51 6 0 1 7 16 5 52 5 0 2 5 51 7 0 1 6 16 2 52 5 0 2 5 51 8 0 1 7 1 0 16 4 52 5 0 2 5 20 9 0 16 1 49 1 50)} "morph-marsh" {:upvalue-count 0 :arity 3 :constants ("dom-get-data" "sx-marsh-transform" "sx-marsh-env" "dom-inner-html" "empty?" "parse" "list" "cek-call" "dispose-marsh-scope" "with-marsh-scope" {:upvalue-count 3 :arity 0 :constants ("render-to-dom" "dom-remove-children-after" "dom-append") :bytecode (20 0 0 18 0 18 1 2 48 3 17 0 20 1 0 18 2 2 48 2 5 20 2 0 18 2 16 0 49 2 50)} "sync-attrs" "morph-children") :bytecode (20 0 0 16 0 1 1 0 48 2 17 3 20 0 0 16 0 1 2 0 48 2 17 4 20 3 0 16 1 48 1 17 5 16 4 6 33 15 0 5 16 5 6 33 8 0 5 16 5 52 4 0 1 167 33 59 0 16 5 52 5 0 1 17 6 16 3 33 15 0 16 3 16 6 52 6 0 1 52 7 0 2 32 2 0 16 6 17 7 20 8 0 16 0 48 1 5 20 9 0 16 0 51 10 0 1 7 1 4 1 0 49 2 32 19 0 20 11 0 16 0 16 1 48 2 5 20 12 0 16 0 16 1 49 2 50)} "process-signal-updates" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "[data-sx-signal]" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "data-sx-signal" ":" "index-of" 0 "slice" 1 "json-parse" "reset!" "use-store" "dom-remove-attr") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 87 0 16 1 1 2 0 52 3 0 2 17 2 16 2 1 4 0 166 33 63 0 16 1 1 4 0 16 2 52 5 0 3 17 3 16 1 16 2 1 6 0 160 52 5 0 2 17 4 20 7 0 16 4 48 1 17 5 20 8 0 16 3 52 9 0 1 16 5 48 2 5 20 10 0 16 0 1 1 0 49 2 32 1 0 2 32 1 0 2 50)} "for-each") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 51 2 0 16 1 52 3 0 2 50)} "swap-dom-nodes" {:upvalue-count 0 :arity 3 :constants ("innerHTML" "=" "dom-is-fragment?" "morph-children" "dom-create-element" "div" "dom-append" "outerHTML" "dom-parent" "dom-clone" "dom-first-child" "dom-replace-child" "dom-next-sibling" "insert-remaining-siblings" "dom-remove-child" "afterend" "dom-insert-after" "beforeend" "afterbegin" "dom-prepend" "beforebegin" "dom-insert-before" "delete" "none") :bytecode (16 2 6 1 0 0 52 1 0 2 33 56 0 5 20 2 0 16 1 48 1 33 12 0 20 3 0 16 0 16 1 49 2 32 30 0 20 4 0 1 5 0 2 48 2 17 3 20 6 0 16 3 16 1 48 2 5 20 3 0 16 0 16 3 49 2 32 75 1 6 1 7 0 52 1 0 2 33 119 0 5 20 8 0 16 0 48 1 17 3 20 9 0 16 1 3 48 2 17 4 20 2 0 16 1 48 1 33 72 0 20 10 0 16 1 48 1 17 5 16 5 33 46 0 20 9 0 16 5 3 48 2 17 4 5 20 11 0 16 3 16 4 16 0 48 3 5 20 12 0 16 5 48 1 17 6 20 13 0 16 3 16 4 16 6 48 3 32 9 0 20 14 0 16 3 16 0 48 2 32 11 0 20 11 0 16 3 16 4 16 0 48 3 5 16 4 32 201 0 6 1 15 0 52 1 0 2 33 13 0 5 20 16 0 16 0 16 1 49 2 32 177 0 6 1 17 0 52 1 0 2 33 13 0 5 20 6 0 16 0 16 1 49 2 32 153 0 6 1 18 0 52 1 0 2 33 13 0 5 20 19 0 16 0 16 1 49 2 32 129 0 6 1 20 0 52 1 0 2 33 20 0 5 20 21 0 20 8 0 16 0 48 1 16 1 16 0 49 3 32 98 0 6 1 22 0 52 1 0 2 33 18 0 5 20 14 0 20 8 0 16 0 48 1 16 0 49 2 32 69 0 6 1 23 0 52 1 0 2 33 5 0 5 2 32 53 0 5 20 2 0 16 1 48 1 33 12 0 20 3 0 16 0 16 1 49 2 32 30 0 20 4 0 1 5 0 2 48 2 17 3 20 6 0 16 3 16 1 48 2 5 20 3 0 16 0 16 3 49 2 50)} "insert-remaining-siblings" {:upvalue-count 0 :arity 3 :constants ("dom-next-sibling" "dom-insert-after" "insert-remaining-siblings") :bytecode (16 2 33 33 0 20 0 0 16 2 48 1 17 3 20 1 0 16 1 16 2 48 2 5 20 2 0 16 0 16 2 16 3 49 3 32 1 0 2 50)} "swap-html-string" {:upvalue-count 0 :arity 3 :constants ("innerHTML" "=" "dom-set-inner-html" "outerHTML" "dom-parent" "dom-insert-adjacent-html" "afterend" "dom-remove-child" "beforeend" "afterbegin" "beforebegin" "delete" "none") :bytecode (16 2 6 1 0 0 52 1 0 2 33 13 0 5 20 2 0 16 0 16 1 49 2 32 212 0 6 1 3 0 52 1 0 2 33 38 0 5 20 4 0 16 0 48 1 17 3 20 5 0 16 0 1 6 0 16 1 48 3 5 20 7 0 16 3 16 0 48 2 5 16 3 32 163 0 6 1 6 0 52 1 0 2 33 16 0 5 20 5 0 16 0 1 6 0 16 1 49 3 32 136 0 6 1 8 0 52 1 0 2 33 16 0 5 20 5 0 16 0 1 8 0 16 1 49 3 32 109 0 6 1 9 0 52 1 0 2 33 16 0 5 20 5 0 16 0 1 9 0 16 1 49 3 32 82 0 6 1 10 0 52 1 0 2 33 16 0 5 20 5 0 16 0 1 10 0 16 1 49 3 32 55 0 6 1 11 0 52 1 0 2 33 18 0 5 20 7 0 20 4 0 16 0 48 1 16 0 49 2 32 26 0 6 1 12 0 52 1 0 2 33 5 0 5 2 32 10 0 5 20 2 0 16 0 16 1 49 2 50)} "handle-history" {:upvalue-count 0 :arity 3 :constants ("dom-get-attr" "sx-push-url" "sx-replace-url" "replace-url" "get" "browser-replace-state" "false" "save-scroll-position" "browser-push-state" "true") :bytecode (20 0 0 16 0 1 1 0 48 2 17 3 20 0 0 16 0 1 2 0 48 2 17 4 16 2 1 3 0 52 4 0 2 17 5 16 5 33 10 0 20 5 0 16 5 49 1 32 89 0 16 3 6 33 8 0 5 16 3 1 6 0 164 167 33 30 0 20 7 0 48 0 5 20 8 0 16 3 1 9 0 164 33 5 0 16 1 32 2 0 16 3 49 1 32 42 0 16 4 6 33 8 0 5 16 4 1 6 0 164 167 33 24 0 20 5 0 16 4 1 9 0 164 33 5 0 16 1 32 2 0 16 4 49 1 32 1 0 2 50)} "PRELOAD_TTL" 30000 "preload-cache-get" {:upvalue-count 0 :arity 2 :constants ("dict-get" "nil?" "now-ms" "timestamp" "get" "PRELOAD_TTL" "dict-delete!") :bytecode (16 0 16 1 52 0 0 2 17 2 16 2 52 1 0 1 33 4 0 2 32 46 0 20 2 0 48 0 16 2 1 3 0 52 4 0 2 161 20 5 0 166 33 13 0 16 0 16 1 52 6 0 2 5 2 32 11 0 16 0 16 1 52 6 0 2 5 16 2 50)} "preload-cache-set" {:upvalue-count 0 :arity 4 :constants ("text" "content-type" "timestamp" "now-ms" "dict" "dict-set!") :bytecode (16 0 16 1 1 0 0 16 2 1 1 0 16 3 1 2 0 20 3 0 48 0 52 4 0 6 52 5 0 3 50)} "classify-trigger" {:upvalue-count 0 :arity 1 :constants ("event" "get" "every" "=" "poll" "intersect" "load" "revealed") :bytecode (16 0 1 0 0 52 1 0 2 17 1 16 1 6 1 2 0 52 3 0 2 33 7 0 5 1 4 0 32 58 0 6 1 5 0 52 3 0 2 33 7 0 5 1 5 0 32 40 0 6 1 6 0 52 3 0 2 33 7 0 5 1 6 0 32 22 0 6 1 7 0 52 3 0 2 33 7 0 5 1 7 0 32 4 0 5 1 0 0 50)} "should-boost-link?" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "href" "#" "starts-with?" "javascript:" "mailto:" "browser-same-origin?" "dom-has-attr?" "sx-get" "sx-post" "sx-disable") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 33 101 0 5 16 1 1 2 0 52 3 0 2 167 6 33 86 0 5 16 1 1 4 0 52 3 0 2 167 6 33 71 0 5 16 1 1 5 0 52 3 0 2 167 6 33 56 0 5 20 6 0 16 1 48 1 6 33 44 0 5 20 7 0 16 0 1 8 0 48 2 167 6 33 28 0 5 20 7 0 16 0 1 9 0 48 2 167 6 33 12 0 5 20 7 0 16 0 1 10 0 48 2 167 50)} "should-boost-form?" {:upvalue-count 0 :arity 1 :constants ("dom-has-attr?" "sx-get" "sx-post" "sx-disable") :bytecode (20 0 0 16 0 1 1 0 48 2 167 6 33 28 0 5 20 0 0 16 0 1 2 0 48 2 167 6 33 12 0 5 20 0 0 16 0 1 3 0 48 2 167 50)} "parse-sse-swap" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-sse-swap" "message") :bytecode (20 0 0 16 0 1 1 0 48 2 6 34 4 0 5 1 2 0 50)} {:library (web engine) :op "import"}) :bytecode (1 1 0 1 2 0 1 3 0 1 4 0 1 5 0 52 6 0 5 128 0 0 5 1 8 0 128 7 0 5 51 10 0 128 9 0 5 51 12 0 128 11 0 5 51 14 0 128 13 0 5 51 16 0 128 15 0 5 51 18 0 128 17 0 5 51 20 0 128 19 0 5 51 22 0 128 21 0 5 51 24 0 128 23 0 5 51 26 0 128 25 0 5 51 28 0 128 27 0 5 51 30 0 128 29 0 5 51 32 0 128 31 0 5 51 34 0 128 33 0 5 51 36 0 128 35 0 5 51 38 0 128 37 0 5 51 40 0 128 39 0 5 51 42 0 128 41 0 5 51 44 0 128 43 0 5 51 46 0 128 45 0 5 51 48 0 128 47 0 5 51 50 0 128 49 0 5 51 52 0 128 51 0 5 51 54 0 128 53 0 5 51 56 0 128 55 0 5 1 58 0 128 57 0 5 51 60 0 128 59 0 5 51 62 0 128 61 0 5 51 64 0 128 63 0 5 51 66 0 128 65 0 5 51 68 0 128 67 0 5 51 70 0 128 69 0 5 1 71 0 112 50))) diff --git a/web/engine.sx b/web/engine.sx index 207abff3..df553473 100644 --- a/web/engine.sx +++ b/web/engine.sx @@ -468,7 +468,19 @@ (and (not (dom-has-attr? new-el aname)) (not (contains? reactive-attrs aname)) - (not (= aname "data-sx-reactive-attrs"))) + (not (= aname "data-sx-reactive-attrs")) + ;; PRESERVE the boost's client-injected navigation attributes. The boost + ;; (boost-descendants) sets sx-target/sx-swap/sx-push-url on links; the + ;; SERVER never sends them, so this removal loop would strip them when a + ;; morph reuses a node for a different link — leaving sx-swap unset, which + ;; defaults to outerHTML and REPLACES the swap target (#content), breaking + ;; every later nav. These are identical across all boosted links, so + ;; keeping them on a reused node is correct. + (not (= aname "sx-target")) + (not (= aname "sx-swap")) + (not (= aname "sx-push-url")) + (not (= aname "sx-get")) + (not (= aname "sx-select"))) (dom-remove-attr old-el aname)))) (dom-attr-list old-el))))) (define