Files
rose-ash/shared/static/scripts/sx-browser.js
giles 6772f1141f Register append! and dict-set! as proper primitives
Previously these mutating operations were internal helpers in the JS
bootstrapper but not declared in primitives.sx or registered in the
Python evaluator. Now properly specced and available in both hosts.

Removes mock injections from cache tests — they use real primitives.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 00:21:17 +00:00

3690 lines
169 KiB
JavaScript

/**
* sx-ref.js — Generated from reference SX evaluator specification.
*
* Bootstrap-compiled from shared/sx/ref/{eval,render,primitives}.sx
* Compare against hand-written sx.js for correctness verification.
*
* DO NOT EDIT — regenerate with: python bootstrap_js.py
*/
;(function(global) {
"use strict";
// =========================================================================
// Types
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-07T00:20:00Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
function Symbol(name) { this.name = name; }
Symbol.prototype.toString = function() { return this.name; };
Symbol.prototype._sym = true;
function Keyword(name) { this.name = name; }
Keyword.prototype.toString = function() { return ":" + this.name; };
Keyword.prototype._kw = true;
function Lambda(params, body, closure, name) {
this.params = params;
this.body = body;
this.closure = closure || {};
this.name = name || null;
}
Lambda.prototype._lambda = true;
function Component(name, params, hasChildren, body, closure) {
this.name = name;
this.params = params;
this.hasChildren = hasChildren;
this.body = body;
this.closure = closure || {};
}
Component.prototype._component = true;
function Macro(params, restParam, body, closure, name) {
this.params = params;
this.restParam = restParam;
this.body = body;
this.closure = closure || {};
this.name = name || null;
}
Macro.prototype._macro = true;
function Thunk(expr, env) { this.expr = expr; this.env = env; }
Thunk.prototype._thunk = true;
function RawHTML(html) { this.html = html; }
RawHTML.prototype._raw = true;
function StyleValue(className, declarations, mediaRules, pseudoRules, keyframes) {
this.className = className;
this.declarations = declarations || "";
this.mediaRules = mediaRules || [];
this.pseudoRules = pseudoRules || [];
this.keyframes = keyframes || [];
}
StyleValue.prototype._styleValue = true;
function isSym(x) { return x != null && x._sym === true; }
function isKw(x) { return x != null && x._kw === true; }
function merge() {
var out = {};
for (var i = 0; i < arguments.length; i++) {
var d = arguments[i];
if (d) for (var k in d) out[k] = d[k];
}
return out;
}
function sxOr() {
for (var i = 0; i < arguments.length; i++) {
if (isSxTruthy(arguments[i])) return arguments[i];
}
return arguments.length ? arguments[arguments.length - 1] : false;
}
// =========================================================================
// Platform interface — JS implementation
// =========================================================================
function typeOf(x) {
if (isNil(x)) return "nil";
if (typeof x === "number") return "number";
if (typeof x === "string") return "string";
if (typeof x === "boolean") return "boolean";
if (x._sym) return "symbol";
if (x._kw) return "keyword";
if (x._thunk) return "thunk";
if (x._lambda) return "lambda";
if (x._component) return "component";
if (x._macro) return "macro";
if (x._raw) return "raw-html";
if (x._styleValue) return "style-value";
if (typeof Node !== "undefined" && x instanceof Node) return "dom-node";
if (Array.isArray(x)) return "list";
if (typeof x === "object") return "dict";
return "unknown";
}
function symbolName(s) { return s.name; }
function keywordName(k) { return k.name; }
function makeSymbol(n) { return new Symbol(n); }
function makeKeyword(n) { return new Keyword(n); }
function makeLambda(params, body, env) { return new Lambda(params, body, merge(env)); }
function makeComponent(name, params, hasChildren, body, env) {
return new Component(name, params, hasChildren, body, merge(env));
}
function makeMacro(params, restParam, body, env, name) {
return new Macro(params, restParam, body, merge(env), name);
}
function makeThunk(expr, env) { return new Thunk(expr, env); }
function lambdaParams(f) { return f.params; }
function lambdaBody(f) { return f.body; }
function lambdaClosure(f) { return f.closure; }
function lambdaName(f) { return f.name; }
function setLambdaName(f, n) { f.name = n; }
function componentParams(c) { return c.params; }
function componentBody(c) { return c.body; }
function componentClosure(c) { return c.closure; }
function componentHasChildren(c) { return c.hasChildren; }
function componentName(c) { return c.name; }
function macroParams(m) { return m.params; }
function macroRestParam(m) { return m.restParam; }
function macroBody(m) { return m.body; }
function macroClosure(m) { return m.closure; }
function isThunk(x) { return x != null && x._thunk === true; }
function thunkExpr(t) { return t.expr; }
function thunkEnv(t) { return t.env; }
function isCallable(x) { return typeof x === "function" || (x != null && x._lambda === true); }
function isLambda(x) { return x != null && x._lambda === true; }
function isComponent(x) { return x != null && x._component === true; }
function isMacro(x) { return x != null && x._macro === true; }
function isStyleValue(x) { return x != null && x._styleValue === true; }
function styleValueClass(x) { return x.className; }
function styleValue_p(x) { return x != null && x._styleValue === true; }
function buildKeyframes(kfName, steps, env) {
// Platform implementation of defkeyframes
var parts = [];
for (var i = 0; i < steps.length; i++) {
var step = steps[i];
var selector = isSym(step[0]) ? step[0].name : String(step[0]);
var body = trampoline(evalExpr(step[1], env));
var decls = isStyleValue(body) ? body.declarations : String(body);
parts.push(selector + "{" + decls + "}");
}
var kfRule = "@keyframes " + kfName + "{" + parts.join("") + "}";
var cn = "sx-ref-kf-" + kfName;
var sv = new StyleValue(cn, "animation-name:" + kfName, [], [], [[kfName, kfRule]]);
env[kfName] = sv;
return sv;
}
function envHas(env, name) { return name in env; }
function envGet(env, name) { return env[name]; }
function envSet(env, name, val) { env[name] = val; }
function envExtend(env) { return merge(env); }
function envMerge(base, overlay) { return merge(base, overlay); }
function dictSet(d, k, v) { d[k] = v; return v; }
PRIMITIVES["dict-set!"] = dictSet;
function dictGet(d, k) { var v = d[k]; return v !== undefined ? v : NIL; }
// Render-expression detection — lets the evaluator delegate to the active adapter.
// Matches HTML tags, SVG tags, <>, raw!, ~components, html: prefix, custom elements.
function isRenderExpr(expr) {
if (!Array.isArray(expr) || !expr.length) return false;
var h = expr[0];
if (!h || !h._sym) return false;
var n = h.name;
return !!(n === "<>" || n === "raw!" ||
n.charAt(0) === "~" || n.indexOf("html:") === 0 ||
(typeof HTML_TAGS !== "undefined" && HTML_TAGS.indexOf(n) >= 0) ||
(typeof SVG_TAGS !== "undefined" && SVG_TAGS.indexOf(n) >= 0) ||
(n.indexOf("-") > 0 && expr.length > 1 && expr[1] && expr[1]._kw));
}
// Render dispatch — call the active adapter's render function.
// Set by each adapter when loaded; defaults to identity (no rendering).
var _renderExprFn = null;
function renderExpr(expr, env) {
if (_renderExprFn) return _renderExprFn(expr, env);
// No adapter loaded — just return the expression as-is
return expr;
}
function stripPrefix(s, prefix) {
return s.indexOf(prefix) === 0 ? s.slice(prefix.length) : s;
}
function error(msg) { throw new Error(msg); }
function inspect(x) { return JSON.stringify(x); }
// =========================================================================
// Primitives
// =========================================================================
var PRIMITIVES = {};
// core.arithmetic
PRIMITIVES["+"] = function() { var s = 0; for (var i = 0; i < arguments.length; i++) s += arguments[i]; return s; };
PRIMITIVES["-"] = function(a, b) { return arguments.length === 1 ? -a : a - b; };
PRIMITIVES["*"] = function() { var s = 1; for (var i = 0; i < arguments.length; i++) s *= arguments[i]; return s; };
PRIMITIVES["/"] = function(a, b) { return a / b; };
PRIMITIVES["mod"] = function(a, b) { return a % b; };
PRIMITIVES["inc"] = function(n) { return n + 1; };
PRIMITIVES["dec"] = function(n) { return n - 1; };
PRIMITIVES["abs"] = Math.abs;
PRIMITIVES["floor"] = Math.floor;
PRIMITIVES["ceil"] = Math.ceil;
PRIMITIVES["round"] = function(x, n) {
if (n === undefined || n === 0) return Math.round(x);
var f = Math.pow(10, n); return Math.round(x * f) / f;
};
PRIMITIVES["min"] = Math.min;
PRIMITIVES["max"] = Math.max;
PRIMITIVES["sqrt"] = Math.sqrt;
PRIMITIVES["pow"] = Math.pow;
PRIMITIVES["clamp"] = function(x, lo, hi) { return Math.max(lo, Math.min(hi, x)); };
// core.comparison
PRIMITIVES["="] = function(a, b) { return a === b; };
PRIMITIVES["!="] = function(a, b) { return a !== b; };
PRIMITIVES["<"] = function(a, b) { return a < b; };
PRIMITIVES[">"] = function(a, b) { return a > b; };
PRIMITIVES["<="] = function(a, b) { return a <= b; };
PRIMITIVES[">="] = function(a, b) { return a >= b; };
// core.logic
PRIMITIVES["not"] = function(x) { return !isSxTruthy(x); };
// core.predicates
PRIMITIVES["nil?"] = isNil;
PRIMITIVES["number?"] = function(x) { return typeof x === "number"; };
PRIMITIVES["string?"] = function(x) { return typeof x === "string"; };
PRIMITIVES["list?"] = Array.isArray;
PRIMITIVES["dict?"] = function(x) { return x !== null && typeof x === "object" && !Array.isArray(x) && !x._sym && !x._kw; };
PRIMITIVES["empty?"] = function(c) { return isNil(c) || (Array.isArray(c) ? c.length === 0 : typeof c === "string" ? c.length === 0 : Object.keys(c).length === 0); };
PRIMITIVES["contains?"] = function(c, k) {
if (typeof c === "string") return c.indexOf(String(k)) !== -1;
if (Array.isArray(c)) return c.indexOf(k) !== -1;
return k in c;
};
PRIMITIVES["odd?"] = function(n) { return n % 2 !== 0; };
PRIMITIVES["even?"] = function(n) { return n % 2 === 0; };
PRIMITIVES["zero?"] = function(n) { return n === 0; };
// core.strings
PRIMITIVES["str"] = function() {
var p = [];
for (var i = 0; i < arguments.length; i++) {
var v = arguments[i]; if (isNil(v)) continue; p.push(String(v));
}
return p.join("");
};
PRIMITIVES["upper"] = function(s) { return String(s).toUpperCase(); };
PRIMITIVES["lower"] = function(s) { return String(s).toLowerCase(); };
PRIMITIVES["trim"] = function(s) { return String(s).trim(); };
PRIMITIVES["split"] = function(s, sep) { return String(s).split(sep || " "); };
PRIMITIVES["join"] = function(sep, coll) { return coll.join(sep); };
PRIMITIVES["replace"] = function(s, old, nw) { return s.split(old).join(nw); };
PRIMITIVES["index-of"] = function(s, needle, from) { return String(s).indexOf(needle, from || 0); };
PRIMITIVES["starts-with?"] = function(s, p) { return String(s).indexOf(p) === 0; };
PRIMITIVES["ends-with?"] = function(s, p) { var str = String(s); return str.indexOf(p, str.length - p.length) !== -1; };
PRIMITIVES["slice"] = function(c, a, b) { return b !== undefined ? c.slice(a, b) : c.slice(a); };
PRIMITIVES["concat"] = function() {
var out = [];
for (var i = 0; i < arguments.length; i++) if (!isNil(arguments[i])) out = out.concat(arguments[i]);
return out;
};
// core.collections
PRIMITIVES["list"] = function() { return Array.prototype.slice.call(arguments); };
PRIMITIVES["dict"] = function() {
var d = {};
for (var i = 0; i < arguments.length - 1; i += 2) d[arguments[i]] = arguments[i + 1];
return d;
};
PRIMITIVES["range"] = function(a, b, step) {
var r = []; step = step || 1;
for (var i = a; step > 0 ? i < b : i > b; i += step) r.push(i);
return r;
};
PRIMITIVES["get"] = function(c, k, def) { var v = (c && c[k]); return v !== undefined ? v : (def !== undefined ? def : NIL); };
PRIMITIVES["len"] = function(c) { return Array.isArray(c) ? c.length : typeof c === "string" ? c.length : Object.keys(c).length; };
PRIMITIVES["first"] = function(c) { return c && c.length > 0 ? c[0] : NIL; };
PRIMITIVES["last"] = function(c) { return c && c.length > 0 ? c[c.length - 1] : NIL; };
PRIMITIVES["rest"] = function(c) { return c ? c.slice(1) : []; };
PRIMITIVES["nth"] = function(c, n) { return c && n >= 0 && n < c.length ? c[n] : NIL; };
PRIMITIVES["cons"] = function(x, c) { return [x].concat(c || []); };
PRIMITIVES["append"] = function(c, x) { return (c || []).concat([x]); };
PRIMITIVES["chunk-every"] = function(c, n) {
var r = []; for (var i = 0; i < c.length; i += n) r.push(c.slice(i, i + n)); return r;
};
PRIMITIVES["zip-pairs"] = function(c) {
var r = []; for (var i = 0; i < c.length - 1; i++) r.push([c[i], c[i + 1]]); return r;
};
// core.dict
PRIMITIVES["keys"] = function(d) { return Object.keys(d || {}); };
PRIMITIVES["vals"] = function(d) { var r = []; for (var k in d) r.push(d[k]); return r; };
PRIMITIVES["merge"] = function() {
var out = {};
for (var i = 0; i < arguments.length; i++) { var d = arguments[i]; if (d && !isNil(d)) for (var k in d) out[k] = d[k]; }
return out;
};
PRIMITIVES["assoc"] = function(d) {
var out = {}; if (d && !isNil(d)) for (var k in d) out[k] = d[k];
for (var i = 1; i < arguments.length - 1; i += 2) out[arguments[i]] = arguments[i + 1];
return out;
};
PRIMITIVES["dissoc"] = function(d) {
var out = {}; for (var k in d) out[k] = d[k];
for (var i = 1; i < arguments.length; i++) delete out[arguments[i]];
return out;
};
PRIMITIVES["into"] = function(target, coll) {
if (Array.isArray(target)) return Array.isArray(coll) ? coll.slice() : Object.entries(coll);
var r = {}; for (var i = 0; i < coll.length; i++) { var p = coll[i]; if (Array.isArray(p) && p.length >= 2) r[p[0]] = p[1]; }
return r;
};
// stdlib.format
PRIMITIVES["format-decimal"] = function(v, p) { return Number(v).toFixed(p || 2); };
PRIMITIVES["parse-int"] = function(v, d) { var n = parseInt(v, 10); return isNaN(n) ? (d || 0) : n; };
PRIMITIVES["format-date"] = function(s, fmt) {
if (!s) return "";
try {
var d = new Date(s);
if (isNaN(d.getTime())) return String(s);
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var short_months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
return fmt.replace(/%-d/g, d.getDate()).replace(/%d/g, ("0"+d.getDate()).slice(-2))
.replace(/%B/g, months[d.getMonth()]).replace(/%b/g, short_months[d.getMonth()])
.replace(/%Y/g, d.getFullYear()).replace(/%m/g, ("0"+(d.getMonth()+1)).slice(-2))
.replace(/%H/g, ("0"+d.getHours()).slice(-2)).replace(/%M/g, ("0"+d.getMinutes()).slice(-2));
} catch (e) { return String(s); }
};
PRIMITIVES["parse-datetime"] = function(s) { return s ? String(s) : NIL; };
// stdlib.text
PRIMITIVES["pluralize"] = function(n, s, p) {
if (s || (p && p !== "s")) return n == 1 ? (s || "") : (p || "s");
return n == 1 ? "" : "s";
};
PRIMITIVES["escape"] = function(s) {
return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;");
};
PRIMITIVES["strip-tags"] = function(s) { return String(s).replace(/<[^>]+>/g, ""); };
// stdlib.style
PRIMITIVES["css"] = function() {
var atoms = [];
for (var i = 0; i < arguments.length; i++) {
var a = arguments[i];
if (isNil(a) || a === false) continue;
atoms.push(isKw(a) ? a.name : String(a));
}
if (!atoms.length) return NIL;
return new StyleValue("sx-" + atoms.join("-"), atoms.join(";"), [], [], []);
};
PRIMITIVES["merge-styles"] = function() {
var valid = [];
for (var i = 0; i < arguments.length; i++) {
if (isStyleValue(arguments[i])) valid.push(arguments[i]);
}
if (!valid.length) return NIL;
if (valid.length === 1) return valid[0];
var allDecls = valid.map(function(v) { return v.declarations; }).join(";");
return new StyleValue("sx-merged", allDecls, [], [], []);
};
// stdlib.debug
PRIMITIVES["assert"] = function(cond, msg) {
if (!isSxTruthy(cond)) throw new Error("Assertion error: " + (msg || "Assertion failed"));
return true;
};
function isPrimitive(name) { return name in PRIMITIVES; }
function getPrimitive(name) { return PRIMITIVES[name]; }
// Higher-order helpers used by the transpiled code
function map(fn, coll) { return coll.map(fn); }
function mapIndexed(fn, coll) { return coll.map(function(item, i) { return fn(i, item); }); }
function filter(fn, coll) { return coll.filter(function(x) { return isSxTruthy(fn(x)); }); }
function reduce(fn, init, coll) {
var acc = init;
for (var i = 0; i < coll.length; i++) acc = fn(acc, coll[i]);
return acc;
}
function some(fn, coll) {
for (var i = 0; i < coll.length; i++) { var r = fn(coll[i]); if (isSxTruthy(r)) return r; }
return NIL;
}
function forEach(fn, coll) { for (var i = 0; i < coll.length; i++) fn(coll[i]); return NIL; }
function isEvery(fn, coll) {
for (var i = 0; i < coll.length; i++) { if (!isSxTruthy(fn(coll[i]))) return false; }
return true;
}
function mapDict(fn, d) { var r = {}; for (var k in d) r[k] = fn(k, d[k]); return r; }
// List primitives used directly by transpiled code
var len = PRIMITIVES["len"];
var first = PRIMITIVES["first"];
var last = PRIMITIVES["last"];
var rest = PRIMITIVES["rest"];
var nth = PRIMITIVES["nth"];
var cons = PRIMITIVES["cons"];
var append = PRIMITIVES["append"];
var isEmpty = PRIMITIVES["empty?"];
var contains = PRIMITIVES["contains?"];
var startsWith = PRIMITIVES["starts-with?"];
var slice = PRIMITIVES["slice"];
var concat = PRIMITIVES["concat"];
var str = PRIMITIVES["str"];
var join = PRIMITIVES["join"];
var keys = PRIMITIVES["keys"];
var get = PRIMITIVES["get"];
var assoc = PRIMITIVES["assoc"];
var range = PRIMITIVES["range"];
function zip(a, b) { var r = []; for (var i = 0; i < Math.min(a.length, b.length); i++) r.push([a[i], b[i]]); return r; }
function append_b(arr, x) { arr.push(x); return arr; }
PRIMITIVES["append!"] = append_b;
var apply = function(f, args) { return f.apply(null, args); };
// Additional primitive aliases used by adapter/engine transpiled code
var split = PRIMITIVES["split"];
var trim = PRIMITIVES["trim"];
var upper = PRIMITIVES["upper"];
var lower = PRIMITIVES["lower"];
var replace_ = function(s, old, nw) { return s.split(old).join(nw); };
var endsWith = PRIMITIVES["ends-with?"];
var parseInt_ = PRIMITIVES["parse-int"];
var dict_fn = PRIMITIVES["dict"];
// HTML rendering helpers
function escapeHtml(s) {
return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");
}
function escapeAttr(s) { return escapeHtml(s); }
function rawHtmlContent(r) { return r.html; }
function makeRawHtml(s) { return { _raw: true, html: s }; }
// Serializer
function serialize(val) {
if (isNil(val)) return "nil";
if (typeof val === "boolean") return val ? "true" : "false";
if (typeof val === "number") return String(val);
if (typeof val === "string") return '"' + val.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"';
if (isSym(val)) return val.name;
if (isKw(val)) return ":" + val.name;
if (Array.isArray(val)) return "(" + val.map(serialize).join(" ") + ")";
return String(val);
}
function isSpecialForm(n) { return n in {
"if":1,"when":1,"cond":1,"case":1,"and":1,"or":1,"let":1,"let*":1,
"lambda":1,"fn":1,"define":1,"defcomp":1,"defmacro":1,"defstyle":1,
"defkeyframes":1,"defhandler":1,"begin":1,"do":1,
"quote":1,"quasiquote":1,"->":1,"set!":1
}; }
function isHoForm(n) { return n in {
"map":1,"map-indexed":1,"filter":1,"reduce":1,"some":1,"every?":1,"for-each":1
}; }
// processBindings and evalCond — now specced in render.sx, bootstrapped above
function isDefinitionForm(name) {
return name === "define" || name === "defcomp" || name === "defmacro" ||
name === "defstyle" || name === "defkeyframes" || name === "defhandler";
}
function indexOf_(s, ch) {
return typeof s === "string" ? s.indexOf(ch) : -1;
}
function dictHas(d, k) { return d != null && k in d; }
function dictDelete(d, k) { delete d[k]; }
function forEachIndexed(fn, coll) {
for (var i = 0; i < coll.length; i++) fn(i, coll[i]);
return NIL;
}
// =========================================================================
// Platform interface — Parser
// =========================================================================
// Character classification derived from the grammar:
// ident-start → [a-zA-Z_~*+\-><=/!?&]
// ident-char → ident-start + [0-9.:\/\[\]#,]
var _identStartRe = /[a-zA-Z_~*+\-><=/!?&]/;
var _identCharRe = /[a-zA-Z0-9_~*+\-><=/!?.:&/\[\]#,]/;
function isIdentStart(ch) { return _identStartRe.test(ch); }
function isIdentChar(ch) { return _identCharRe.test(ch); }
function parseNumber(s) { return Number(s); }
function escapeString(s) {
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\t/g, "\\t");
}
function sxExprSource(e) { return typeof e === "string" ? e : String(e); }
// === Transpiled from eval ===
// trampoline
var trampoline = function(val) { return (function() {
var result = val;
return (isSxTruthy(isThunk(result)) ? trampoline(evalExpr(thunkExpr(result), thunkEnv(result))) : result);
})(); };
// eval-expr
var evalExpr = function(expr, env) { return (function() { var _m = typeOf(expr); if (_m == "number") return expr; if (_m == "string") return expr; if (_m == "boolean") return expr; if (_m == "nil") return NIL; if (_m == "symbol") return (function() {
var name = symbolName(expr);
return (isSxTruthy(envHas(env, name)) ? envGet(env, name) : (isSxTruthy(isPrimitive(name)) ? getPrimitive(name) : (isSxTruthy((name == "true")) ? true : (isSxTruthy((name == "false")) ? false : (isSxTruthy((name == "nil")) ? NIL : error((String("Undefined symbol: ") + String(name))))))));
})(); if (_m == "keyword") return keywordName(expr); if (_m == "dict") return mapDict(function(k, v) { return trampoline(evalExpr(v, env)); }, expr); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? [] : evalList(expr, env)); return expr; })(); };
// eval-list
var evalList = function(expr, env) { return (function() {
var head = first(expr);
var args = rest(expr);
return (isSxTruthy(!isSxTruthy(sxOr((typeOf(head) == "symbol"), (typeOf(head) == "lambda"), (typeOf(head) == "list")))) ? map(function(x) { return trampoline(evalExpr(x, env)); }, expr) : (isSxTruthy((typeOf(head) == "symbol")) ? (function() {
var name = symbolName(head);
return (isSxTruthy((name == "if")) ? sfIf(args, env) : (isSxTruthy((name == "when")) ? sfWhen(args, env) : (isSxTruthy((name == "cond")) ? sfCond(args, env) : (isSxTruthy((name == "case")) ? sfCase(args, env) : (isSxTruthy((name == "and")) ? sfAnd(args, env) : (isSxTruthy((name == "or")) ? sfOr(args, env) : (isSxTruthy((name == "let")) ? sfLet(args, env) : (isSxTruthy((name == "let*")) ? sfLet(args, env) : (isSxTruthy((name == "letrec")) ? sfLetrec(args, env) : (isSxTruthy((name == "lambda")) ? sfLambda(args, env) : (isSxTruthy((name == "fn")) ? sfLambda(args, env) : (isSxTruthy((name == "define")) ? sfDefine(args, env) : (isSxTruthy((name == "defcomp")) ? sfDefcomp(args, env) : (isSxTruthy((name == "defmacro")) ? sfDefmacro(args, env) : (isSxTruthy((name == "defstyle")) ? sfDefstyle(args, env) : (isSxTruthy((name == "defkeyframes")) ? sfDefkeyframes(args, env) : (isSxTruthy((name == "defhandler")) ? sfDefhandler(args, env) : (isSxTruthy((name == "defpage")) ? sfDefpage(args, env) : (isSxTruthy((name == "defquery")) ? sfDefquery(args, env) : (isSxTruthy((name == "defaction")) ? sfDefaction(args, env) : (isSxTruthy((name == "begin")) ? sfBegin(args, env) : (isSxTruthy((name == "do")) ? sfBegin(args, env) : (isSxTruthy((name == "quote")) ? sfQuote(args, env) : (isSxTruthy((name == "quasiquote")) ? sfQuasiquote(args, env) : (isSxTruthy((name == "->")) ? sfThreadFirst(args, env) : (isSxTruthy((name == "set!")) ? sfSetBang(args, env) : (isSxTruthy((name == "reset")) ? sfReset(args, env) : (isSxTruthy((name == "shift")) ? sfShift(args, env) : (isSxTruthy((name == "dynamic-wind")) ? sfDynamicWind(args, env) : (isSxTruthy((name == "map")) ? hoMap(args, env) : (isSxTruthy((name == "map-indexed")) ? hoMapIndexed(args, env) : (isSxTruthy((name == "filter")) ? hoFilter(args, env) : (isSxTruthy((name == "reduce")) ? hoReduce(args, env) : (isSxTruthy((name == "some")) ? hoSome(args, env) : (isSxTruthy((name == "every?")) ? hoEvery(args, env) : (isSxTruthy((name == "for-each")) ? hoForEach(args, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? (function() {
var mac = envGet(env, name);
return makeThunk(expandMacro(mac, args, env), env);
})() : (isSxTruthy(isRenderExpr(expr)) ? renderExpr(expr, env) : evalCall(head, args, env)))))))))))))))))))))))))))))))))))))));
})() : evalCall(head, args, env)));
})(); };
// eval-call
var evalCall = function(head, args, env) { return (function() {
var f = trampoline(evalExpr(head, env));
var evaluatedArgs = map(function(a) { return trampoline(evalExpr(a, env)); }, args);
return (isSxTruthy((isSxTruthy(isCallable(f)) && isSxTruthy(!isSxTruthy(isLambda(f))) && !isSxTruthy(isComponent(f)))) ? apply(f, evaluatedArgs) : (isSxTruthy(isLambda(f)) ? callLambda(f, evaluatedArgs, env) : (isSxTruthy(isComponent(f)) ? callComponent(f, args, env) : error((String("Not callable: ") + String(inspect(f)))))));
})(); };
// call-lambda
var callLambda = function(f, args, callerEnv) { return (function() {
var params = lambdaParams(f);
var local = envMerge(lambdaClosure(f), callerEnv);
return (isSxTruthy((len(args) != len(params))) ? error((String(sxOr(lambdaName(f), "lambda")) + String(" expects ") + String(len(params)) + String(" args, got ") + String(len(args)))) : (forEach(function(pair) { return envSet(local, first(pair), nth(pair, 1)); }, zip(params, args)), makeThunk(lambdaBody(f), local)));
})(); };
// call-component
var callComponent = function(comp, rawArgs, env) { return (function() {
var parsed = parseKeywordArgs(rawArgs, env);
var kwargs = first(parsed);
var children = nth(parsed, 1);
var local = envMerge(componentClosure(comp), env);
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; local[p] = sxOr(dictGet(kwargs, p), NIL); } }
if (isSxTruthy(componentHasChildren(comp))) {
local["children"] = children;
}
return makeThunk(componentBody(comp), local);
})(); };
// parse-keyword-args
var parseKeywordArgs = function(rawArgs, env) { return (function() {
var kwargs = {};
var children = [];
var i = 0;
reduce(function(state, arg) { return (function() {
var idx = get(state, "i");
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (idx + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((idx + 1) < len(rawArgs)))) ? (dictSet(kwargs, keywordName(arg), trampoline(evalExpr(nth(rawArgs, (idx + 1)), env))), assoc(state, "skip", true, "i", (idx + 1))) : (append_b(children, trampoline(evalExpr(arg, env))), assoc(state, "i", (idx + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, rawArgs);
return [kwargs, children];
})(); };
// sf-if
var sfIf = function(args, env) { return (function() {
var condition = trampoline(evalExpr(first(args), env));
return (isSxTruthy((isSxTruthy(condition) && !isSxTruthy(isNil(condition)))) ? makeThunk(nth(args, 1), env) : (isSxTruthy((len(args) > 2)) ? makeThunk(nth(args, 2), env) : NIL));
})(); };
// sf-when
var sfWhen = function(args, env) { return (function() {
var condition = trampoline(evalExpr(first(args), env));
return (isSxTruthy((isSxTruthy(condition) && !isSxTruthy(isNil(condition)))) ? (forEach(function(e) { return trampoline(evalExpr(e, env)); }, slice(args, 1, (len(args) - 1))), makeThunk(last(args), env)) : NIL);
})(); };
// sf-cond
var sfCond = function(args, env) { return (isSxTruthy((isSxTruthy((typeOf(first(args)) == "list")) && (len(first(args)) == 2))) ? sfCondScheme(args, env) : sfCondClojure(args, env)); };
// sf-cond-scheme
var sfCondScheme = function(clauses, env) { return (isSxTruthy(isEmpty(clauses)) ? NIL : (function() {
var clause = first(clauses);
var test = first(clause);
var body = nth(clause, 1);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))), (isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")))) ? makeThunk(body, env) : (isSxTruthy(trampoline(evalExpr(test, env))) ? makeThunk(body, env) : sfCondScheme(rest(clauses), env)));
})()); };
// sf-cond-clojure
var sfCondClojure = function(clauses, env) { return (isSxTruthy((len(clauses) < 2)) ? NIL : (function() {
var test = first(clauses);
var body = nth(clauses, 1);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")), (isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))))) ? makeThunk(body, env) : (isSxTruthy(trampoline(evalExpr(test, env))) ? makeThunk(body, env) : sfCondClojure(slice(clauses, 2), env)));
})()); };
// sf-case
var sfCase = function(args, env) { return (function() {
var matchVal = trampoline(evalExpr(first(args), env));
var clauses = rest(args);
return sfCaseLoop(matchVal, clauses, env);
})(); };
// sf-case-loop
var sfCaseLoop = function(matchVal, clauses, env) { return (isSxTruthy((len(clauses) < 2)) ? NIL : (function() {
var test = first(clauses);
var body = nth(clauses, 1);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")), (isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))))) ? makeThunk(body, env) : (isSxTruthy((matchVal == trampoline(evalExpr(test, env)))) ? makeThunk(body, env) : sfCaseLoop(matchVal, slice(clauses, 2), env)));
})()); };
// sf-and
var sfAnd = function(args, env) { return (isSxTruthy(isEmpty(args)) ? true : (function() {
var val = trampoline(evalExpr(first(args), env));
return (isSxTruthy(!isSxTruthy(val)) ? val : (isSxTruthy((len(args) == 1)) ? val : sfAnd(rest(args), env)));
})()); };
// sf-or
var sfOr = function(args, env) { return (isSxTruthy(isEmpty(args)) ? false : (function() {
var val = trampoline(evalExpr(first(args), env));
return (isSxTruthy(val) ? val : sfOr(rest(args), env));
})()); };
// sf-let
var sfLet = function(args, env) { return (isSxTruthy((typeOf(first(args)) == "symbol")) ? sfNamedLet(args, env) : (function() {
var bindings = first(args);
var body = rest(args);
var local = envExtend(env);
(isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? forEach(function(binding) { return (function() {
var vname = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : first(binding));
return envSet(local, vname, trampoline(evalExpr(nth(binding, 1), local)));
})(); }, bindings) : (function() {
var i = 0;
return reduce(function(acc, pairIdx) { return (function() {
var vname = (isSxTruthy((typeOf(nth(bindings, (pairIdx * 2))) == "symbol")) ? symbolName(nth(bindings, (pairIdx * 2))) : nth(bindings, (pairIdx * 2)));
var valExpr = nth(bindings, ((pairIdx * 2) + 1));
return envSet(local, vname, trampoline(evalExpr(valExpr, local)));
})(); }, NIL, range(0, (len(bindings) / 2)));
})());
{ var _c = slice(body, 0, (len(body) - 1)); for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; trampoline(evalExpr(e, local)); } }
return makeThunk(last(body), local);
})()); };
// sf-named-let
var sfNamedLet = function(args, env) { return (function() {
var loopName = symbolName(first(args));
var bindings = nth(args, 1);
var body = slice(args, 2);
var params = [];
var inits = [];
(isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? forEach(function(binding) { params.push((isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : first(binding)));
return append_b(inits, nth(binding, 1)); }, bindings) : reduce(function(acc, pairIdx) { return (append_b(params, (isSxTruthy((typeOf(nth(bindings, (pairIdx * 2))) == "symbol")) ? symbolName(nth(bindings, (pairIdx * 2))) : nth(bindings, (pairIdx * 2)))), append_b(inits, nth(bindings, ((pairIdx * 2) + 1)))); }, NIL, range(0, (len(bindings) / 2))));
return (function() {
var loopBody = (isSxTruthy((len(body) == 1)) ? first(body) : cons(makeSymbol("begin"), body));
var loopFn = makeLambda(params, loopBody, env);
loopFn.name = loopName;
lambdaClosure(loopFn)[loopName] = loopFn;
return (function() {
var initVals = map(function(e) { return trampoline(evalExpr(e, env)); }, inits);
return callLambda(loopFn, initVals, env);
})();
})();
})(); };
// sf-lambda
var sfLambda = function(args, env) { return (function() {
var paramsExpr = first(args);
var body = nth(args, 1);
var paramNames = map(function(p) { return (isSxTruthy((typeOf(p) == "symbol")) ? symbolName(p) : p); }, paramsExpr);
return makeLambda(paramNames, body, env);
})(); };
// sf-define
var sfDefine = function(args, env) { return (function() {
var nameSym = first(args);
var value = trampoline(evalExpr(nth(args, 1), env));
if (isSxTruthy((isSxTruthy(isLambda(value)) && isNil(lambdaName(value))))) {
value.name = symbolName(nameSym);
}
env[symbolName(nameSym)] = value;
return value;
})(); };
// sf-defcomp
var sfDefcomp = function(args, env) { return (function() {
var nameSym = first(args);
var paramsRaw = nth(args, 1);
var body = nth(args, 2);
var compName = stripPrefix(symbolName(nameSym), "~");
var parsed = parseCompParams(paramsRaw);
var params = first(parsed);
var hasChildren = nth(parsed, 1);
return (function() {
var comp = makeComponent(compName, params, hasChildren, body, env);
env[symbolName(nameSym)] = comp;
return comp;
})();
})(); };
// parse-comp-params
var parseCompParams = function(paramsExpr) { return (function() {
var params = [];
var hasChildren = false;
var inKey = false;
{ var _c = paramsExpr; for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; if (isSxTruthy((typeOf(p) == "symbol"))) {
(function() {
var name = symbolName(p);
return (isSxTruthy((name == "&key")) ? (inKey = true) : (isSxTruthy((name == "&rest")) ? (hasChildren = true) : (isSxTruthy((name == "&children")) ? (hasChildren = true) : (isSxTruthy(hasChildren) ? NIL : (isSxTruthy(inKey) ? append_b(params, name) : append_b(params, name))))));
})();
} } }
return [params, hasChildren];
})(); };
// sf-defmacro
var sfDefmacro = function(args, env) { return (function() {
var nameSym = first(args);
var paramsRaw = nth(args, 1);
var body = nth(args, 2);
var parsed = parseMacroParams(paramsRaw);
var params = first(parsed);
var restParam = nth(parsed, 1);
return (function() {
var mac = makeMacro(params, restParam, body, env, symbolName(nameSym));
env[symbolName(nameSym)] = mac;
return mac;
})();
})(); };
// parse-macro-params
var parseMacroParams = function(paramsExpr) { return (function() {
var params = [];
var restParam = NIL;
reduce(function(state, p) { return (isSxTruthy((isSxTruthy((typeOf(p) == "symbol")) && (symbolName(p) == "&rest"))) ? assoc(state, "in-rest", true) : (isSxTruthy(get(state, "in-rest")) ? ((restParam = (isSxTruthy((typeOf(p) == "symbol")) ? symbolName(p) : p)), state) : (append_b(params, (isSxTruthy((typeOf(p) == "symbol")) ? symbolName(p) : p)), state))); }, {["in-rest"]: false}, paramsExpr);
return [params, restParam];
})(); };
// sf-defstyle
var sfDefstyle = function(args, env) { return (function() {
var nameSym = first(args);
var value = trampoline(evalExpr(nth(args, 1), env));
env[symbolName(nameSym)] = value;
return value;
})(); };
// sf-defkeyframes
var sfDefkeyframes = function(args, env) { return (function() {
var kfName = symbolName(first(args));
var steps = rest(args);
return buildKeyframes(kfName, steps, env);
})(); };
// sf-begin
var sfBegin = function(args, env) { return (isSxTruthy(isEmpty(args)) ? NIL : (forEach(function(e) { return trampoline(evalExpr(e, env)); }, slice(args, 0, (len(args) - 1))), makeThunk(last(args), env))); };
// sf-quote
var sfQuote = function(args, env) { return (isSxTruthy(isEmpty(args)) ? NIL : first(args)); };
// sf-quasiquote
var sfQuasiquote = function(args, env) { return qqExpand(first(args), env); };
// qq-expand
var qqExpand = function(template, env) { return (isSxTruthy(!isSxTruthy((typeOf(template) == "list"))) ? template : (isSxTruthy(isEmpty(template)) ? [] : (function() {
var head = first(template);
return (isSxTruthy((isSxTruthy((typeOf(head) == "symbol")) && (symbolName(head) == "unquote"))) ? trampoline(evalExpr(nth(template, 1), env)) : reduce(function(result, item) { return (isSxTruthy((isSxTruthy((typeOf(item) == "list")) && isSxTruthy((len(item) == 2)) && isSxTruthy((typeOf(first(item)) == "symbol")) && (symbolName(first(item)) == "splice-unquote"))) ? (function() {
var spliced = trampoline(evalExpr(nth(item, 1), env));
return (isSxTruthy((typeOf(spliced) == "list")) ? concat(result, spliced) : (isSxTruthy(isNil(spliced)) ? result : append(result, spliced)));
})() : append(result, qqExpand(item, env))); }, [], template));
})())); };
// sf-thread-first
var sfThreadFirst = function(args, env) { return (function() {
var val = trampoline(evalExpr(first(args), env));
return reduce(function(result, form) { return (isSxTruthy((typeOf(form) == "list")) ? (function() {
var f = trampoline(evalExpr(first(form), env));
var restArgs = map(function(a) { return trampoline(evalExpr(a, env)); }, rest(form));
var allArgs = cons(result, restArgs);
return (isSxTruthy((isSxTruthy(isCallable(f)) && !isSxTruthy(isLambda(f)))) ? apply(f, allArgs) : (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, allArgs, env)) : error((String("-> form not callable: ") + String(inspect(f))))));
})() : (function() {
var f = trampoline(evalExpr(form, env));
return (isSxTruthy((isSxTruthy(isCallable(f)) && !isSxTruthy(isLambda(f)))) ? f(result) : (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, [result], env)) : error((String("-> form not callable: ") + String(inspect(f))))));
})()); }, val, rest(args));
})(); };
// sf-set!
var sfSetBang = function(args, env) { return (function() {
var name = symbolName(first(args));
var value = trampoline(evalExpr(nth(args, 1), env));
env[name] = value;
return value;
})(); };
// sf-letrec
var sfLetrec = function(args, env) { return (function() {
var bindings = first(args);
var body = rest(args);
var local = envExtend(env);
var names = [];
var valExprs = [];
(isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? forEach(function(binding) { return (function() {
var vname = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : first(binding));
names.push(vname);
valExprs.push(nth(binding, 1));
return envSet(local, vname, NIL);
})(); }, bindings) : reduce(function(acc, pairIdx) { return (function() {
var vname = (isSxTruthy((typeOf(nth(bindings, (pairIdx * 2))) == "symbol")) ? symbolName(nth(bindings, (pairIdx * 2))) : nth(bindings, (pairIdx * 2)));
var valExpr = nth(bindings, ((pairIdx * 2) + 1));
names.push(vname);
valExprs.push(valExpr);
return envSet(local, vname, NIL);
})(); }, NIL, range(0, (len(bindings) / 2))));
(function() {
var values = map(function(e) { return trampoline(evalExpr(e, local)); }, valExprs);
{ var _c = zip(names, values); for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; local[first(pair)] = nth(pair, 1); } }
return forEach(function(val) { return (isSxTruthy(isLambda(val)) ? forEach(function(n) { return envSet(lambdaClosure(val), n, envGet(local, n)); }, names) : NIL); }, values);
})();
{ var _c = slice(body, 0, (len(body) - 1)); for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; trampoline(evalExpr(e, local)); } }
return makeThunk(last(body), local);
})(); };
// sf-dynamic-wind
var sfDynamicWind = function(args, env) { return (function() {
var before = trampoline(evalExpr(first(args), env));
var body = trampoline(evalExpr(nth(args, 1), env));
var after = trampoline(evalExpr(nth(args, 2), env));
callThunk(before, env);
pushWind(before, after);
return (function() {
var result = callThunk(body, env);
popWind();
callThunk(after, env);
return result;
})();
})(); };
// expand-macro
var expandMacro = function(mac, rawArgs, env) { return (function() {
var local = envMerge(macroClosure(mac), env);
{ var _c = mapIndexed(function(i, p) { return [p, i]; }, macroParams(mac)); for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; local[first(pair)] = (isSxTruthy((nth(pair, 1) < len(rawArgs))) ? nth(rawArgs, nth(pair, 1)) : NIL); } }
if (isSxTruthy(macroRestParam(mac))) {
local[macroRestParam(mac)] = slice(rawArgs, len(macroParams(mac)));
}
return trampoline(evalExpr(macroBody(mac), local));
})(); };
// call-fn
var callFn = function(f, args, env) { return (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, args, env)) : (isSxTruthy(isCallable(f)) ? apply(f, args) : error((String("Not callable in HO form: ") + String(inspect(f)))))); };
// ho-map
var hoMap = function(args, env) { return (function() {
var f = trampoline(evalExpr(first(args), env));
var coll = trampoline(evalExpr(nth(args, 1), env));
return map(function(item) { return callFn(f, [item], env); }, coll);
})(); };
// ho-map-indexed
var hoMapIndexed = function(args, env) { return (function() {
var f = trampoline(evalExpr(first(args), env));
var coll = trampoline(evalExpr(nth(args, 1), env));
return mapIndexed(function(i, item) { return callFn(f, [i, item], env); }, coll);
})(); };
// ho-filter
var hoFilter = function(args, env) { return (function() {
var f = trampoline(evalExpr(first(args), env));
var coll = trampoline(evalExpr(nth(args, 1), env));
return filter(function(item) { return callFn(f, [item], env); }, coll);
})(); };
// ho-reduce
var hoReduce = function(args, env) { return (function() {
var f = trampoline(evalExpr(first(args), env));
var init = trampoline(evalExpr(nth(args, 1), env));
var coll = trampoline(evalExpr(nth(args, 2), env));
return reduce(function(acc, item) { return callFn(f, [acc, item], env); }, init, coll);
})(); };
// ho-some
var hoSome = function(args, env) { return (function() {
var f = trampoline(evalExpr(first(args), env));
var coll = trampoline(evalExpr(nth(args, 1), env));
return some(function(item) { return callFn(f, [item], env); }, coll);
})(); };
// ho-every
var hoEvery = function(args, env) { return (function() {
var f = trampoline(evalExpr(first(args), env));
var coll = trampoline(evalExpr(nth(args, 1), env));
return isEvery(function(item) { return callFn(f, [item], env); }, coll);
})(); };
// ho-for-each
var hoForEach = function(args, env) { return (function() {
var f = trampoline(evalExpr(first(args), env));
var coll = trampoline(evalExpr(nth(args, 1), env));
return forEach(function(item) { return callFn(f, [item], env); }, coll);
})(); };
// === Transpiled from render (core) ===
// HTML_TAGS
var HTML_TAGS = ["html", "head", "body", "title", "meta", "link", "script", "style", "noscript", "header", "nav", "main", "section", "article", "aside", "footer", "h1", "h2", "h3", "h4", "h5", "h6", "hgroup", "div", "p", "blockquote", "pre", "figure", "figcaption", "address", "details", "summary", "a", "span", "em", "strong", "small", "b", "i", "u", "s", "mark", "sub", "sup", "abbr", "cite", "code", "time", "br", "wbr", "hr", "ul", "ol", "li", "dl", "dt", "dd", "table", "thead", "tbody", "tfoot", "tr", "th", "td", "caption", "colgroup", "col", "form", "input", "textarea", "select", "option", "optgroup", "button", "label", "fieldset", "legend", "output", "datalist", "img", "video", "audio", "source", "picture", "canvas", "iframe", "svg", "math", "path", "circle", "ellipse", "rect", "line", "polyline", "polygon", "text", "tspan", "g", "defs", "use", "clipPath", "mask", "pattern", "linearGradient", "radialGradient", "stop", "filter", "feGaussianBlur", "feOffset", "feBlend", "feColorMatrix", "feComposite", "feMerge", "feMergeNode", "feTurbulence", "feComponentTransfer", "feFuncR", "feFuncG", "feFuncB", "feFuncA", "feDisplacementMap", "feFlood", "feImage", "feMorphology", "feSpecularLighting", "feDiffuseLighting", "fePointLight", "feSpotLight", "feDistantLight", "animate", "animateTransform", "foreignObject", "template", "slot", "dialog", "menu"];
// VOID_ELEMENTS
var VOID_ELEMENTS = ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"];
// BOOLEAN_ATTRS
var BOOLEAN_ATTRS = ["async", "autofocus", "autoplay", "checked", "controls", "default", "defer", "disabled", "formnovalidate", "hidden", "inert", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "selected"];
// definition-form?
var isDefinitionForm = function(name) { return sxOr((name == "define"), (name == "defcomp"), (name == "defmacro"), (name == "defstyle"), (name == "defkeyframes"), (name == "defhandler")); };
// parse-element-args
var parseElementArgs = function(args, env) { return (function() {
var attrs = {};
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var val = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
attrs[keywordName(arg)] = val;
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return [attrs, children];
})(); };
// render-attrs
var renderAttrs = function(attrs) { return join("", map(function(key) { return (function() {
var val = dictGet(attrs, key);
return (isSxTruthy((isSxTruthy(contains(BOOLEAN_ATTRS, key)) && val)) ? (String(" ") + String(key)) : (isSxTruthy((isSxTruthy(contains(BOOLEAN_ATTRS, key)) && !isSxTruthy(val))) ? "" : (isSxTruthy(isNil(val)) ? "" : (isSxTruthy((isSxTruthy((key == "style")) && isStyleValue(val))) ? (String(" class=\"") + String(styleValueClass(val)) + String("\"")) : (String(" ") + String(key) + String("=\"") + String(escapeAttr((String(val)))) + String("\""))))));
})(); }, keys(attrs))); };
// eval-cond
var evalCond = function(clauses, env) { return (isSxTruthy((isSxTruthy(!isSxTruthy(isEmpty(clauses))) && isSxTruthy((typeOf(first(clauses)) == "list")) && (len(first(clauses)) == 2))) ? evalCondScheme(clauses, env) : evalCondClojure(clauses, env)); };
// eval-cond-scheme
var evalCondScheme = function(clauses, env) { return (isSxTruthy(isEmpty(clauses)) ? NIL : (function() {
var clause = first(clauses);
var test = first(clause);
var body = nth(clause, 1);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))), (isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")))) ? body : (isSxTruthy(trampoline(evalExpr(test, env))) ? body : evalCondScheme(rest(clauses), env)));
})()); };
// eval-cond-clojure
var evalCondClojure = function(clauses, env) { return (isSxTruthy((len(clauses) < 2)) ? NIL : (function() {
var test = first(clauses);
var body = nth(clauses, 1);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")), (isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))))) ? body : (isSxTruthy(trampoline(evalExpr(test, env))) ? body : evalCondClojure(slice(clauses, 2), env)));
})()); };
// process-bindings
var processBindings = function(bindings, env) { return (function() {
var local = merge(env);
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(pair) == "list")) && (len(pair) >= 2)))) {
(function() {
var name = (isSxTruthy((typeOf(first(pair)) == "symbol")) ? symbolName(first(pair)) : (String(first(pair))));
return envSet(local, name, trampoline(evalExpr(nth(pair, 1), local)));
})();
} } }
return local;
})(); };
// === Transpiled from parser ===
// sx-parse
var sxParse = function(source) { return (function() {
var pos = 0;
var lenSrc = len(source);
var skipComment = function() { while(true) { if (isSxTruthy((isSxTruthy((pos < lenSrc)) && !isSxTruthy((nth(source, pos) == "\n"))))) { pos = (pos + 1);
continue; } else { return NIL; } } };
var skipWs = function() { while(true) { if (isSxTruthy((pos < lenSrc))) { { var ch = nth(source, pos);
if (isSxTruthy(sxOr((ch == " "), (ch == "\t"), (ch == "\n"), (ch == "\\r")))) { pos = (pos + 1);
continue; } else if (isSxTruthy((ch == ";"))) { pos = (pos + 1);
skipComment();
continue; } else { return NIL; } } } else { return NIL; } } };
var readString = function() { pos = (pos + 1);
return (function() {
var buf = "";
var readStrLoop = function() { while(true) { if (isSxTruthy((pos >= lenSrc))) { return error("Unterminated string"); } else { { var ch = nth(source, pos);
if (isSxTruthy((ch == "\""))) { pos = (pos + 1);
return NIL; } else if (isSxTruthy((ch == "\\"))) { pos = (pos + 1);
{ var esc = nth(source, pos);
buf = (String(buf) + String((isSxTruthy((esc == "n")) ? "\n" : (isSxTruthy((esc == "t")) ? "\t" : (isSxTruthy((esc == "r")) ? "\\r" : esc)))));
pos = (pos + 1);
continue; } } else { buf = (String(buf) + String(ch));
pos = (pos + 1);
continue; } } } } };
readStrLoop();
return buf;
})(); };
var readIdent = function() { return (function() {
var start = pos;
var readIdentLoop = function() { while(true) { if (isSxTruthy((isSxTruthy((pos < lenSrc)) && isIdentChar(nth(source, pos))))) { pos = (pos + 1);
continue; } else { return NIL; } } };
readIdentLoop();
return slice(source, start, pos);
})(); };
var readKeyword = function() { pos = (pos + 1);
return makeKeyword(readIdent()); };
var readNumber = function() { return (function() {
var start = pos;
if (isSxTruthy((isSxTruthy((pos < lenSrc)) && (nth(source, pos) == "-")))) {
pos = (pos + 1);
}
var readDigits = function() { while(true) { if (isSxTruthy((isSxTruthy((pos < lenSrc)) && (function() {
var c = nth(source, pos);
return (isSxTruthy((c >= "0")) && (c <= "9"));
})()))) { pos = (pos + 1);
continue; } else { return NIL; } } };
readDigits();
if (isSxTruthy((isSxTruthy((pos < lenSrc)) && (nth(source, pos) == ".")))) {
pos = (pos + 1);
readDigits();
}
if (isSxTruthy((isSxTruthy((pos < lenSrc)) && sxOr((nth(source, pos) == "e"), (nth(source, pos) == "E"))))) {
pos = (pos + 1);
if (isSxTruthy((isSxTruthy((pos < lenSrc)) && sxOr((nth(source, pos) == "+"), (nth(source, pos) == "-"))))) {
pos = (pos + 1);
}
readDigits();
}
return parseNumber(slice(source, start, pos));
})(); };
var readSymbol = function() { return (function() {
var name = readIdent();
return (isSxTruthy((name == "true")) ? true : (isSxTruthy((name == "false")) ? false : (isSxTruthy((name == "nil")) ? NIL : makeSymbol(name))));
})(); };
var readList = function(closeCh) { return (function() {
var items = [];
var readListLoop = function() { while(true) { skipWs();
if (isSxTruthy((pos >= lenSrc))) { return error("Unterminated list"); } else { if (isSxTruthy((nth(source, pos) == closeCh))) { pos = (pos + 1);
return NIL; } else { items.push(readExpr());
continue; } } } };
readListLoop();
return items;
})(); };
var readMap = function() { return (function() {
var result = {};
var readMapLoop = function() { while(true) { skipWs();
if (isSxTruthy((pos >= lenSrc))) { return error("Unterminated map"); } else { if (isSxTruthy((nth(source, pos) == "}"))) { pos = (pos + 1);
return NIL; } else { { var keyExpr = readExpr();
var keyStr = (isSxTruthy((typeOf(keyExpr) == "keyword")) ? keywordName(keyExpr) : (String(keyExpr)));
var valExpr = readExpr();
result[keyStr] = valExpr;
continue; } } } } };
readMapLoop();
return result;
})(); };
var readExpr = function() { skipWs();
return (isSxTruthy((pos >= lenSrc)) ? error("Unexpected end of input") : (function() {
var ch = nth(source, pos);
return (isSxTruthy((ch == "(")) ? ((pos = (pos + 1)), readList(")")) : (isSxTruthy((ch == "[")) ? ((pos = (pos + 1)), readList("]")) : (isSxTruthy((ch == "{")) ? ((pos = (pos + 1)), readMap()) : (isSxTruthy((ch == "\"")) ? readString() : (isSxTruthy((ch == ":")) ? readKeyword() : (isSxTruthy((ch == "`")) ? ((pos = (pos + 1)), [makeSymbol("quasiquote"), readExpr()]) : (isSxTruthy((ch == ",")) ? ((pos = (pos + 1)), (isSxTruthy((isSxTruthy((pos < lenSrc)) && (nth(source, pos) == "@"))) ? ((pos = (pos + 1)), [makeSymbol("splice-unquote"), readExpr()]) : [makeSymbol("unquote"), readExpr()])) : (isSxTruthy(sxOr((isSxTruthy((ch >= "0")) && (ch <= "9")), (isSxTruthy((ch == "-")) && isSxTruthy(((pos + 1) < lenSrc)) && (function() {
var nextCh = nth(source, (pos + 1));
return (isSxTruthy((nextCh >= "0")) && (nextCh <= "9"));
})()))) ? readNumber() : (isSxTruthy((isSxTruthy((ch == ".")) && isSxTruthy(((pos + 2) < lenSrc)) && isSxTruthy((nth(source, (pos + 1)) == ".")) && (nth(source, (pos + 2)) == "."))) ? ((pos = (pos + 3)), makeSymbol("...")) : (isSxTruthy(isIdentStart(ch)) ? readSymbol() : error((String("Unexpected character: ") + String(ch)))))))))))));
})()); };
return (function() {
var exprs = [];
var parseLoop = function() { while(true) { skipWs();
if (isSxTruthy((pos < lenSrc))) { exprs.push(readExpr());
continue; } else { return NIL; } } };
parseLoop();
return exprs;
})();
})(); };
// sx-serialize
var sxSerialize = function(val) { return (function() { var _m = typeOf(val); if (_m == "nil") return "nil"; if (_m == "boolean") return (isSxTruthy(val) ? "true" : "false"); if (_m == "number") return (String(val)); if (_m == "string") return (String("\"") + String(escapeString(val)) + String("\"")); if (_m == "symbol") return symbolName(val); if (_m == "keyword") return (String(":") + String(keywordName(val))); if (_m == "list") return (String("(") + String(join(" ", map(sxSerialize, val))) + String(")")); if (_m == "dict") return sxSerializeDict(val); if (_m == "sx-expr") return sxExprSource(val); return (String(val)); })(); };
// sx-serialize-dict
var sxSerializeDict = function(d) { return (String("{") + String(join(" ", reduce(function(acc, key) { return concat(acc, [(String(":") + String(key)), sxSerialize(dictGet(d, key))]); }, [], keys(d)))) + String("}")); };
// === Transpiled from adapter-html ===
// render-to-html
var renderToHtml = function(expr, env) { return (function() { var _m = typeOf(expr); if (_m == "nil") return ""; if (_m == "string") return escapeHtml(expr); if (_m == "number") return (String(expr)); if (_m == "boolean") return (isSxTruthy(expr) ? "true" : "false"); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? "" : renderListToHtml(expr, env)); if (_m == "symbol") return renderValueToHtml(trampoline(evalExpr(expr, env)), env); if (_m == "keyword") return escapeHtml(keywordName(expr)); if (_m == "raw-html") return rawHtmlContent(expr); return renderValueToHtml(trampoline(evalExpr(expr, env)), env); })(); };
// render-value-to-html
var renderValueToHtml = function(val, env) { return (function() { var _m = typeOf(val); if (_m == "nil") return ""; if (_m == "string") return escapeHtml(val); if (_m == "number") return (String(val)); if (_m == "boolean") return (isSxTruthy(val) ? "true" : "false"); if (_m == "list") return renderListToHtml(val, env); if (_m == "raw-html") return rawHtmlContent(val); if (_m == "style-value") return styleValueClass(val); return escapeHtml((String(val))); })(); };
// RENDER_HTML_FORMS
var RENDER_HTML_FORMS = ["if", "when", "cond", "case", "let", "let*", "begin", "do", "define", "defcomp", "defmacro", "defstyle", "defkeyframes", "defhandler", "map", "map-indexed", "filter", "for-each"];
// render-html-form?
var isRenderHtmlForm = function(name) { return contains(RENDER_HTML_FORMS, name); };
// render-list-to-html
var renderListToHtml = function(expr, env) { return (isSxTruthy(isEmpty(expr)) ? "" : (function() {
var head = first(expr);
return (isSxTruthy(!isSxTruthy((typeOf(head) == "symbol"))) ? join("", map(function(x) { return renderValueToHtml(x, env); }, expr)) : (function() {
var name = symbolName(head);
var args = rest(expr);
return (isSxTruthy((name == "<>")) ? join("", map(function(x) { return renderToHtml(x, env); }, args)) : (isSxTruthy((name == "raw!")) ? join("", map(function(x) { return (String(trampoline(evalExpr(x, env)))); }, args)) : (isSxTruthy(contains(HTML_TAGS, name)) ? renderHtmlElement(name, args, env) : (isSxTruthy(startsWith(name, "~")) ? (function() {
var val = envGet(env, name);
return (isSxTruthy(isComponent(val)) ? renderHtmlComponent(val, args, env) : (isSxTruthy(isMacro(val)) ? renderToHtml(expandMacro(val, args, env), env) : error((String("Unknown component: ") + String(name)))));
})() : (isSxTruthy(isRenderHtmlForm(name)) ? dispatchHtmlForm(name, expr, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? renderToHtml(expandMacro(envGet(env, name), args, env), env) : renderValueToHtml(trampoline(evalExpr(expr, env)), env)))))));
})());
})()); };
// dispatch-html-form
var dispatchHtmlForm = function(name, expr, env) { return (isSxTruthy((name == "if")) ? (function() {
var condVal = trampoline(evalExpr(nth(expr, 1), env));
return (isSxTruthy(condVal) ? renderToHtml(nth(expr, 2), env) : (isSxTruthy((len(expr) > 3)) ? renderToHtml(nth(expr, 3), env) : ""));
})() : (isSxTruthy((name == "when")) ? (isSxTruthy(!isSxTruthy(trampoline(evalExpr(nth(expr, 1), env)))) ? "" : join("", map(function(i) { return renderToHtml(nth(expr, i), env); }, range(2, len(expr))))) : (isSxTruthy((name == "cond")) ? (function() {
var branch = evalCond(rest(expr), env);
return (isSxTruthy(branch) ? renderToHtml(branch, env) : "");
})() : (isSxTruthy((name == "case")) ? renderToHtml(trampoline(evalExpr(expr, env)), env) : (isSxTruthy(sxOr((name == "let"), (name == "let*"))) ? (function() {
var local = processBindings(nth(expr, 1), env);
return join("", map(function(i) { return renderToHtml(nth(expr, i), local); }, range(2, len(expr))));
})() : (isSxTruthy(sxOr((name == "begin"), (name == "do"))) ? join("", map(function(i) { return renderToHtml(nth(expr, i), env); }, range(1, len(expr)))) : (isSxTruthy(isDefinitionForm(name)) ? (trampoline(evalExpr(expr, env)), "") : (isSxTruthy((name == "map")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
return join("", map(function(item) { return (isSxTruthy(isLambda(f)) ? renderLambdaHtml(f, [item], env) : renderToHtml(apply(f, [item]), env)); }, coll));
})() : (isSxTruthy((name == "map-indexed")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
return join("", mapIndexed(function(i, item) { return (isSxTruthy(isLambda(f)) ? renderLambdaHtml(f, [i, item], env) : renderToHtml(apply(f, [i, item]), env)); }, coll));
})() : (isSxTruthy((name == "filter")) ? renderToHtml(trampoline(evalExpr(expr, env)), env) : (isSxTruthy((name == "for-each")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
return join("", map(function(item) { return (isSxTruthy(isLambda(f)) ? renderLambdaHtml(f, [item], env) : renderToHtml(apply(f, [item]), env)); }, coll));
})() : renderValueToHtml(trampoline(evalExpr(expr, env)), env)))))))))))); };
// render-lambda-html
var renderLambdaHtml = function(f, args, env) { return (function() {
var local = envMerge(lambdaClosure(f), env);
forEachIndexed(function(i, p) { return envSet(local, p, nth(args, i)); }, lambdaParams(f));
return renderToHtml(lambdaBody(f), local);
})(); };
// render-html-component
var renderHtmlComponent = function(comp, args, env) { return (function() {
var kwargs = {};
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var val = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
kwargs[keywordName(arg)] = val;
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var local = envMerge(componentClosure(comp), env);
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; local[p] = (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL); } }
if (isSxTruthy(componentHasChildren(comp))) {
local["children"] = makeRawHtml(join("", map(function(c) { return renderToHtml(c, env); }, children)));
}
return renderToHtml(componentBody(comp), local);
})();
})(); };
// render-html-element
var renderHtmlElement = function(tag, args, env) { return (function() {
var parsed = parseElementArgs(args, env);
var attrs = first(parsed);
var children = nth(parsed, 1);
var isVoid = contains(VOID_ELEMENTS, tag);
return (String("<") + String(tag) + String(renderAttrs(attrs)) + String((isSxTruthy(isVoid) ? " />" : (String(">") + String(join("", map(function(c) { return renderToHtml(c, env); }, children))) + String("</") + String(tag) + String(">")))));
})(); };
// === Transpiled from adapter-sx ===
// render-to-sx
var renderToSx = function(expr, env) { return (function() {
var result = aser(expr, env);
return (isSxTruthy((typeOf(result) == "string")) ? result : serialize(result));
})(); };
// aser
var aser = function(expr, env) { return (function() { var _m = typeOf(expr); if (_m == "number") return expr; if (_m == "string") return expr; if (_m == "boolean") return expr; if (_m == "nil") return NIL; if (_m == "symbol") return (function() {
var name = symbolName(expr);
return (isSxTruthy(envHas(env, name)) ? envGet(env, name) : (isSxTruthy(isPrimitive(name)) ? getPrimitive(name) : (isSxTruthy((name == "true")) ? true : (isSxTruthy((name == "false")) ? false : (isSxTruthy((name == "nil")) ? NIL : error((String("Undefined symbol: ") + String(name))))))));
})(); if (_m == "keyword") return keywordName(expr); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? [] : aserList(expr, env)); return expr; })(); };
// aser-list
var aserList = function(expr, env) { return (function() {
var head = first(expr);
var args = rest(expr);
return (isSxTruthy(!isSxTruthy((typeOf(head) == "symbol"))) ? map(function(x) { return aser(x, env); }, expr) : (function() {
var name = symbolName(head);
return (isSxTruthy((name == "<>")) ? aserFragment(args, env) : (isSxTruthy(startsWith(name, "~")) ? aserCall(name, args, env) : (isSxTruthy(contains(HTML_TAGS, name)) ? aserCall(name, args, env) : (isSxTruthy(sxOr(isSpecialForm(name), isHoForm(name))) ? aserSpecial(name, expr, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? aser(expandMacro(envGet(env, name), args, env), env) : (function() {
var f = trampoline(evalExpr(head, env));
var evaledArgs = map(function(a) { return trampoline(evalExpr(a, env)); }, args);
return (isSxTruthy((isSxTruthy(isCallable(f)) && isSxTruthy(!isSxTruthy(isLambda(f))) && !isSxTruthy(isComponent(f)))) ? apply(f, evaledArgs) : (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, evaledArgs, env)) : (isSxTruthy(isComponent(f)) ? aserCall((String("~") + String(componentName(f))), args, env) : error((String("Not callable: ") + String(inspect(f)))))));
})())))));
})());
})(); };
// aser-fragment
var aserFragment = function(children, env) { return (function() {
var parts = filter(function(x) { return !isSxTruthy(isNil(x)); }, map(function(c) { return aser(c, env); }, children));
return (isSxTruthy(isEmpty(parts)) ? "" : (String("(<> ") + String(join(" ", map(serialize, parts))) + String(")")));
})(); };
// aser-call
var aserCall = function(name, args, env) { return (function() {
var parts = [name];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var val = aser(nth(args, (get(state, "i") + 1)), env);
if (isSxTruthy(!isSxTruthy(isNil(val)))) {
parts.push((String(":") + String(keywordName(arg))));
parts.push(serialize(val));
}
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (function() {
var val = aser(arg, env);
if (isSxTruthy(!isSxTruthy(isNil(val)))) {
parts.push(serialize(val));
}
return assoc(state, "i", (get(state, "i") + 1));
})()));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (String("(") + String(join(" ", parts)) + String(")"));
})(); };
// === Transpiled from adapter-dom ===
// SVG_NS
var SVG_NS = "http://www.w3.org/2000/svg";
// MATH_NS
var MATH_NS = "http://www.w3.org/1998/Math/MathML";
// render-to-dom
var renderToDom = function(expr, env, ns) { return (function() { var _m = typeOf(expr); if (_m == "nil") return createFragment(); if (_m == "boolean") return createFragment(); if (_m == "raw-html") return domParseHtml(rawHtmlContent(expr)); if (_m == "string") return createTextNode(expr); if (_m == "number") return createTextNode((String(expr))); if (_m == "symbol") return renderToDom(trampoline(evalExpr(expr, env)), env, ns); if (_m == "keyword") return createTextNode(keywordName(expr)); if (_m == "dom-node") return expr; if (_m == "dict") return createFragment(); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? createFragment() : renderDomList(expr, env, ns)); if (_m == "style-value") return createTextNode(styleValueClass(expr)); return createTextNode((String(expr))); })(); };
// render-dom-list
var renderDomList = function(expr, env, ns) { return (function() {
var head = first(expr);
return (isSxTruthy((typeOf(head) == "symbol")) ? (function() {
var name = symbolName(head);
var args = rest(expr);
return (isSxTruthy((name == "raw!")) ? renderDomRaw(args, env) : (isSxTruthy((name == "<>")) ? renderDomFragment(args, env, ns) : (isSxTruthy(startsWith(name, "html:")) ? renderDomElement(slice(name, 5), args, env, ns) : (isSxTruthy(isRenderDomForm(name)) ? (isSxTruthy((isSxTruthy(contains(HTML_TAGS, name)) && sxOr((isSxTruthy((len(args) > 0)) && (typeOf(first(args)) == "keyword")), ns))) ? renderDomElement(name, args, env, ns) : dispatchRenderForm(name, expr, env, ns)) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? renderToDom(expandMacro(envGet(env, name), args, env), env, ns) : (isSxTruthy(contains(HTML_TAGS, name)) ? renderDomElement(name, args, env, ns) : (isSxTruthy(startsWith(name, "~")) ? (function() {
var comp = envGet(env, name);
return (isSxTruthy(isComponent(comp)) ? renderDomComponent(comp, args, env, ns) : renderDomUnknownComponent(name));
})() : (isSxTruthy((isSxTruthy((indexOf_(name, "-") > 0)) && isSxTruthy((len(args) > 0)) && (typeOf(first(args)) == "keyword"))) ? renderDomElement(name, args, env, ns) : (isSxTruthy(ns) ? renderDomElement(name, args, env, ns) : renderToDom(trampoline(evalExpr(expr, env)), env, ns))))))))));
})() : (isSxTruthy(sxOr(isLambda(head), (typeOf(head) == "list"))) ? renderToDom(trampoline(evalExpr(expr, env)), env, ns) : (function() {
var frag = createFragment();
{ var _c = expr; for (var _i = 0; _i < _c.length; _i++) { var x = _c[_i]; domAppend(frag, renderToDom(x, env, ns)); } }
return frag;
})()));
})(); };
// render-dom-element
var renderDomElement = function(tag, args, env, ns) { return (function() {
var newNs = (isSxTruthy((tag == "svg")) ? SVG_NS : (isSxTruthy((tag == "math")) ? MATH_NS : ns));
var el = domCreateElement(tag, newNs);
var extraClass = NIL;
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var attrName = keywordName(arg);
var attrVal = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
(isSxTruthy(sxOr(isNil(attrVal), (attrVal == false))) ? NIL : (isSxTruthy((isSxTruthy((attrName == "style")) && isStyleValue(attrVal))) ? (extraClass = styleValueClass(attrVal)) : (isSxTruthy(contains(BOOLEAN_ATTRS, attrName)) ? (isSxTruthy(attrVal) ? domSetAttr(el, attrName, "") : NIL) : (isSxTruthy((attrVal == true)) ? domSetAttr(el, attrName, "") : domSetAttr(el, attrName, (String(attrVal)))))));
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : ((isSxTruthy(!isSxTruthy(contains(VOID_ELEMENTS, tag))) ? domAppend(el, renderToDom(arg, env, newNs)) : NIL), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
if (isSxTruthy(extraClass)) {
(function() {
var existing = domGetAttr(el, "class");
return domSetAttr(el, "class", (isSxTruthy(existing) ? (String(existing) + String(" ") + String(extraClass)) : extraClass));
})();
}
return el;
})(); };
// render-dom-component
var renderDomComponent = function(comp, args, env, ns) { return (function() {
var kwargs = {};
var children = [];
reduce(function(state, arg) { return (function() {
var skip = get(state, "skip");
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
var val = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
kwargs[keywordName(arg)] = val;
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
return (function() {
var local = envMerge(componentClosure(comp), env);
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; local[p] = (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL); } }
if (isSxTruthy(componentHasChildren(comp))) {
(function() {
var childFrag = createFragment();
{ var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; domAppend(childFrag, renderToDom(c, env, ns)); } }
return envSet(local, "children", childFrag);
})();
}
return renderToDom(componentBody(comp), local, ns);
})();
})(); };
// render-dom-fragment
var renderDomFragment = function(args, env, ns) { return (function() {
var frag = createFragment();
{ var _c = args; for (var _i = 0; _i < _c.length; _i++) { var x = _c[_i]; domAppend(frag, renderToDom(x, env, ns)); } }
return frag;
})(); };
// render-dom-raw
var renderDomRaw = function(args, env) { return (function() {
var frag = createFragment();
{ var _c = args; for (var _i = 0; _i < _c.length; _i++) { var arg = _c[_i]; (function() {
var val = trampoline(evalExpr(arg, env));
return (isSxTruthy((typeOf(val) == "string")) ? domAppend(frag, domParseHtml(val)) : (isSxTruthy((typeOf(val) == "dom-node")) ? domAppend(frag, domClone(val)) : (isSxTruthy(!isSxTruthy(isNil(val))) ? domAppend(frag, createTextNode((String(val)))) : NIL)));
})(); } }
return frag;
})(); };
// render-dom-unknown-component
var renderDomUnknownComponent = function(name) { return error((String("Unknown component: ") + String(name))); };
// RENDER_DOM_FORMS
var RENDER_DOM_FORMS = ["if", "when", "cond", "case", "let", "let*", "begin", "do", "define", "defcomp", "defmacro", "defstyle", "defkeyframes", "defhandler", "map", "map-indexed", "filter", "for-each"];
// render-dom-form?
var isRenderDomForm = function(name) { return contains(RENDER_DOM_FORMS, name); };
// dispatch-render-form
var dispatchRenderForm = function(name, expr, env, ns) { return (isSxTruthy((name == "if")) ? (function() {
var condVal = trampoline(evalExpr(nth(expr, 1), env));
return (isSxTruthy(condVal) ? renderToDom(nth(expr, 2), env, ns) : (isSxTruthy((len(expr) > 3)) ? renderToDom(nth(expr, 3), env, ns) : createFragment()));
})() : (isSxTruthy((name == "when")) ? (isSxTruthy(!isSxTruthy(trampoline(evalExpr(nth(expr, 1), env)))) ? createFragment() : (function() {
var frag = createFragment();
{ var _c = range(2, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), env, ns)); } }
return frag;
})()) : (isSxTruthy((name == "cond")) ? (function() {
var branch = evalCond(rest(expr), env);
return (isSxTruthy(branch) ? renderToDom(branch, env, ns) : createFragment());
})() : (isSxTruthy((name == "case")) ? renderToDom(trampoline(evalExpr(expr, env)), env, ns) : (isSxTruthy(sxOr((name == "let"), (name == "let*"))) ? (function() {
var local = processBindings(nth(expr, 1), env);
var frag = createFragment();
{ var _c = range(2, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), local, ns)); } }
return frag;
})() : (isSxTruthy(sxOr((name == "begin"), (name == "do"))) ? (function() {
var frag = createFragment();
{ var _c = range(1, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), env, ns)); } }
return frag;
})() : (isSxTruthy(isDefinitionForm(name)) ? (trampoline(evalExpr(expr, env)), createFragment()) : (isSxTruthy((name == "map")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
var frag = createFragment();
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var item = _c[_i]; (function() {
var val = (isSxTruthy(isLambda(f)) ? renderLambdaDom(f, [item], env, ns) : renderToDom(apply(f, [item]), env, ns));
return domAppend(frag, val);
})(); } }
return frag;
})() : (isSxTruthy((name == "map-indexed")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
var frag = createFragment();
forEachIndexed(function(i, item) { return (function() {
var val = (isSxTruthy(isLambda(f)) ? renderLambdaDom(f, [i, item], env, ns) : renderToDom(apply(f, [i, item]), env, ns));
return domAppend(frag, val);
})(); }, coll);
return frag;
})() : (isSxTruthy((name == "filter")) ? renderToDom(trampoline(evalExpr(expr, env)), env, ns) : (isSxTruthy((name == "for-each")) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var coll = trampoline(evalExpr(nth(expr, 2), env));
var frag = createFragment();
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var item = _c[_i]; (function() {
var val = (isSxTruthy(isLambda(f)) ? renderLambdaDom(f, [item], env, ns) : renderToDom(apply(f, [item]), env, ns));
return domAppend(frag, val);
})(); } }
return frag;
})() : renderToDom(trampoline(evalExpr(expr, env)), env, ns)))))))))))); };
// render-lambda-dom
var renderLambdaDom = function(f, args, env, ns) { return (function() {
var local = envMerge(lambdaClosure(f), env);
forEachIndexed(function(i, p) { return envSet(local, p, nth(args, i)); }, lambdaParams(f));
return renderToDom(lambdaBody(f), local, ns);
})(); };
// === Transpiled from engine ===
// ENGINE_VERBS
var ENGINE_VERBS = ["get", "post", "put", "delete", "patch"];
// DEFAULT_SWAP
var DEFAULT_SWAP = "outerHTML";
// parse-time
var parseTime = function(s) { return (isSxTruthy(isNil(s)) ? 0 : (isSxTruthy(endsWith(s, "ms")) ? parseInt_(s, 0) : (isSxTruthy(endsWith(s, "s")) ? (parseInt_(replace_(s, "s", ""), 0) * 1000) : parseInt_(s, 0)))); };
// parse-trigger-spec
var parseTriggerSpec = function(spec) { return (isSxTruthy(isNil(spec)) ? NIL : (function() {
var rawParts = split(spec, ",");
return filter(function(x) { return !isSxTruthy(isNil(x)); }, map(function(part) { return (function() {
var tokens = split(trim(part), " ");
return (isSxTruthy(isEmpty(tokens)) ? NIL : (isSxTruthy((isSxTruthy((first(tokens) == "every")) && (len(tokens) >= 2))) ? {["event"]: "every", ["modifiers"]: {["interval"]: parseTime(nth(tokens, 1))}} : (function() {
var mods = {};
{ var _c = rest(tokens); for (var _i = 0; _i < _c.length; _i++) { var tok = _c[_i]; (isSxTruthy((tok == "once")) ? dictSet(mods, "once", true) : (isSxTruthy((tok == "changed")) ? dictSet(mods, "changed", true) : (isSxTruthy(startsWith(tok, "delay:")) ? dictSet(mods, "delay", parseTime(slice(tok, 6))) : (isSxTruthy(startsWith(tok, "from:")) ? dictSet(mods, "from", slice(tok, 5)) : NIL)))); } }
return {["event"]: first(tokens), ["modifiers"]: mods};
})()));
})(); }, rawParts));
})()); };
// default-trigger
var defaultTrigger = function(tagName) { return (isSxTruthy((tagName == "FORM")) ? [{["event"]: "submit", ["modifiers"]: {}}] : (isSxTruthy(sxOr((tagName == "INPUT"), (tagName == "SELECT"), (tagName == "TEXTAREA"))) ? [{["event"]: "change", ["modifiers"]: {}}] : [{["event"]: "click", ["modifiers"]: {}}])); };
// get-verb-info
var getVerbInfo = function(el) { return some(function(verb) { return (function() {
var url = domGetAttr(el, (String("sx-") + String(verb)));
return (isSxTruthy(url) ? {["method"]: upper(verb), ["url"]: url} : NIL);
})(); }, ENGINE_VERBS); };
// build-request-headers
var buildRequestHeaders = function(el, loadedComponents, cssHash) { return (function() {
var headers = {["SX-Request"]: "true", ["SX-Current-URL"]: browserLocationHref()};
(function() {
var targetSel = domGetAttr(el, "sx-target");
return (isSxTruthy(targetSel) ? dictSet(headers, "SX-Target", targetSel) : NIL);
})();
if (isSxTruthy(!isSxTruthy(isEmpty(loadedComponents)))) {
headers["SX-Components"] = join(",", loadedComponents);
}
if (isSxTruthy(cssHash)) {
headers["SX-Css"] = cssHash;
}
(function() {
var extraH = domGetAttr(el, "sx-headers");
return (isSxTruthy(extraH) ? (function() {
var parsed = parseHeaderValue(extraH);
return (isSxTruthy(parsed) ? forEach(function(key) { return dictSet(headers, key, (String(get(parsed, key)))); }, keys(parsed)) : NIL);
})() : NIL);
})();
return headers;
})(); };
// process-response-headers
var processResponseHeaders = function(getHeader) { return {["redirect"]: getHeader("SX-Redirect"), ["refresh"]: getHeader("SX-Refresh"), ["trigger"]: getHeader("SX-Trigger"), ["retarget"]: getHeader("SX-Retarget"), ["reswap"]: getHeader("SX-Reswap"), ["location"]: getHeader("SX-Location"), ["replace-url"]: getHeader("SX-Replace-Url"), ["css-hash"]: getHeader("SX-Css-Hash"), ["trigger-swap"]: getHeader("SX-Trigger-After-Swap"), ["trigger-settle"]: getHeader("SX-Trigger-After-Settle"), ["content-type"]: getHeader("Content-Type")}; };
// parse-swap-spec
var parseSwapSpec = function(rawSwap, globalTransitions_p) { return (function() {
var parts = split(sxOr(rawSwap, DEFAULT_SWAP), " ");
var style = first(parts);
var useTransition = globalTransitions_p;
{ var _c = rest(parts); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; (isSxTruthy((p == "transition:true")) ? (useTransition = true) : (isSxTruthy((p == "transition:false")) ? (useTransition = false) : NIL)); } }
return {["style"]: style, ["transition"]: useTransition};
})(); };
// parse-retry-spec
var parseRetrySpec = function(retryAttr) { return (isSxTruthy(isNil(retryAttr)) ? NIL : (function() {
var parts = split(retryAttr, ":");
return {["strategy"]: first(parts), ["start-ms"]: parseInt_(nth(parts, 1), 1000), ["cap-ms"]: parseInt_(nth(parts, 2), 30000)};
})()); };
// next-retry-ms
var nextRetryMs = function(currentMs, capMs) { return min((currentMs * 2), capMs); };
// filter-params
var filterParams = function(paramsSpec, allParams) { return (isSxTruthy(isNil(paramsSpec)) ? allParams : (isSxTruthy((paramsSpec == "none")) ? [] : (isSxTruthy((paramsSpec == "*")) ? allParams : (isSxTruthy(startsWith(paramsSpec, "not ")) ? (function() {
var excluded = map(trim, split(slice(paramsSpec, 4), ","));
return filter(function(p) { return !isSxTruthy(contains(excluded, first(p))); }, allParams);
})() : (function() {
var allowed = map(trim, split(paramsSpec, ","));
return filter(function(p) { return contains(allowed, first(p)); }, allParams);
})())))); };
// resolve-target
var resolveTarget = function(el) { return (function() {
var sel = domGetAttr(el, "sx-target");
return (isSxTruthy(sxOr(isNil(sel), (sel == "this"))) ? el : (isSxTruthy((sel == "closest")) ? domParent(el) : domQuery(sel)));
})(); };
// apply-optimistic
var applyOptimistic = function(el) { return (function() {
var directive = domGetAttr(el, "sx-optimistic");
return (isSxTruthy(isNil(directive)) ? NIL : (function() {
var target = sxOr(resolveTarget(el), el);
var state = {["target"]: target, ["directive"]: directive};
(isSxTruthy((directive == "remove")) ? (dictSet(state, "opacity", domGetStyle(target, "opacity")), domSetStyle(target, "opacity", "0"), domSetStyle(target, "pointer-events", "none")) : (isSxTruthy((directive == "disable")) ? (dictSet(state, "disabled", domGetProp(target, "disabled")), domSetProp(target, "disabled", true)) : (isSxTruthy(startsWith(directive, "add-class:")) ? (function() {
var cls = slice(directive, 10);
state["add-class"] = cls;
return domAddClass(target, cls);
})() : NIL)));
return state;
})());
})(); };
// revert-optimistic
var revertOptimistic = function(state) { return (isSxTruthy(state) ? (function() {
var target = get(state, "target");
var directive = get(state, "directive");
return (isSxTruthy((directive == "remove")) ? (domSetStyle(target, "opacity", sxOr(get(state, "opacity"), "")), domSetStyle(target, "pointer-events", "")) : (isSxTruthy((directive == "disable")) ? domSetProp(target, "disabled", sxOr(get(state, "disabled"), false)) : (isSxTruthy(get(state, "add-class")) ? domRemoveClass(target, get(state, "add-class")) : NIL)));
})() : NIL); };
// find-oob-swaps
var findOobSwaps = function(container) { return (function() {
var results = [];
{ var _c = ["sx-swap-oob", "hx-swap-oob"]; for (var _i = 0; _i < _c.length; _i++) { var attr = _c[_i]; (function() {
var oobEls = domQueryAll(container, (String("[") + String(attr) + String("]")));
return forEach(function(oob) { return (function() {
var swapType = sxOr(domGetAttr(oob, attr), "outerHTML");
var targetId = domId(oob);
domRemoveAttr(oob, attr);
return (isSxTruthy(targetId) ? append_b(results, {["element"]: oob, ["swap-type"]: swapType, ["target-id"]: targetId}) : NIL);
})(); }, oobEls);
})(); } }
return results;
})(); };
// morph-node
var morphNode = function(oldNode, newNode) { return (isSxTruthy(sxOr(domHasAttr(oldNode, "sx-preserve"), domHasAttr(oldNode, "sx-ignore"))) ? NIL : (isSxTruthy(sxOr(!isSxTruthy((domNodeType(oldNode) == domNodeType(newNode))), !isSxTruthy((domNodeName(oldNode) == domNodeName(newNode))))) ? domReplaceChild(domParent(oldNode), domClone(newNode), oldNode) : (isSxTruthy(sxOr((domNodeType(oldNode) == 3), (domNodeType(oldNode) == 8))) ? (isSxTruthy(!isSxTruthy((domTextContent(oldNode) == domTextContent(newNode)))) ? domSetTextContent(oldNode, domTextContent(newNode)) : NIL) : (isSxTruthy((domNodeType(oldNode) == 1)) ? (syncAttrs(oldNode, newNode), (isSxTruthy(!isSxTruthy((isSxTruthy(domIsActiveElement(oldNode)) && domIsInputElement(oldNode)))) ? morphChildren(oldNode, newNode) : NIL)) : NIL)))); };
// sync-attrs
var syncAttrs = function(oldEl, newEl) { { var _c = domAttrList(newEl); for (var _i = 0; _i < _c.length; _i++) { var attr = _c[_i]; (function() {
var name = first(attr);
var val = nth(attr, 1);
return (isSxTruthy(!isSxTruthy((domGetAttr(oldEl, name) == val))) ? domSetAttr(oldEl, name, val) : NIL);
})(); } }
return forEach(function(attr) { return (isSxTruthy(!isSxTruthy(domHasAttr(newEl, first(attr)))) ? domRemoveAttr(oldEl, first(attr)) : NIL); }, domAttrList(oldEl)); };
// morph-children
var morphChildren = function(oldParent, newParent) { return (function() {
var oldKids = domChildList(oldParent);
var newKids = domChildList(newParent);
var oldById = reduce(function(acc, kid) { return (function() {
var id = domId(kid);
return (isSxTruthy(id) ? (dictSet(acc, id, kid), acc) : acc);
})(); }, {}, oldKids);
var oi = 0;
{ var _c = newKids; for (var _i = 0; _i < _c.length; _i++) { var newChild = _c[_i]; (function() {
var matchId = domId(newChild);
var matchById = (isSxTruthy(matchId) ? dictGet(oldById, matchId) : NIL);
return (isSxTruthy((isSxTruthy(matchById) && !isSxTruthy(isNil(matchById)))) ? ((isSxTruthy((isSxTruthy((oi < len(oldKids))) && !isSxTruthy((matchById == nth(oldKids, oi))))) ? domInsertBefore(oldParent, matchById, (isSxTruthy((oi < len(oldKids))) ? nth(oldKids, oi) : NIL)) : NIL), morphNode(matchById, newChild), (oi = (oi + 1))) : (isSxTruthy((oi < len(oldKids))) ? (function() {
var oldChild = nth(oldKids, oi);
return (isSxTruthy((isSxTruthy(domId(oldChild)) && !isSxTruthy(matchId))) ? domInsertBefore(oldParent, domClone(newChild), oldChild) : (morphNode(oldChild, newChild), (oi = (oi + 1))));
})() : domAppend(oldParent, domClone(newChild))));
})(); } }
return forEach(function(i) { return (isSxTruthy((i >= oi)) ? (function() {
var leftover = nth(oldKids, i);
return (isSxTruthy((isSxTruthy(domIsChildOf(leftover, oldParent)) && isSxTruthy(!isSxTruthy(domHasAttr(leftover, "sx-preserve"))) && !isSxTruthy(domHasAttr(leftover, "sx-ignore")))) ? domRemoveChild(oldParent, leftover) : NIL);
})() : NIL); }, range(oi, len(oldKids)));
})(); };
// swap-dom-nodes
var swapDomNodes = function(target, newNodes, strategy) { return (function() { var _m = strategy; if (_m == "innerHTML") return (isSxTruthy(domIsFragment(newNodes)) ? morphChildren(target, newNodes) : (function() {
var wrapper = domCreateElement("div", NIL);
domAppend(wrapper, newNodes);
return morphChildren(target, wrapper);
})()); if (_m == "outerHTML") return (function() {
var parent = domParent(target);
(isSxTruthy(domIsFragment(newNodes)) ? (function() {
var fc = domFirstChild(newNodes);
return (isSxTruthy(fc) ? (morphNode(target, fc), (function() {
var sib = domNextSibling(fc);
return insertRemainingSiblings(parent, target, sib);
})()) : domRemoveChild(parent, target));
})() : morphNode(target, newNodes));
return parent;
})(); if (_m == "afterend") return domInsertAfter(target, newNodes); if (_m == "beforeend") return domAppend(target, newNodes); if (_m == "afterbegin") return domPrepend(target, newNodes); if (_m == "beforebegin") return domInsertBefore(domParent(target), newNodes, target); if (_m == "delete") return domRemoveChild(domParent(target), target); if (_m == "none") return NIL; return (isSxTruthy(domIsFragment(newNodes)) ? morphChildren(target, newNodes) : (function() {
var wrapper = domCreateElement("div", NIL);
domAppend(wrapper, newNodes);
return morphChildren(target, wrapper);
})()); })(); };
// insert-remaining-siblings
var insertRemainingSiblings = function(parent, refNode, sib) { return (isSxTruthy(sib) ? (function() {
var next = domNextSibling(sib);
domInsertAfter(refNode, sib);
return insertRemainingSiblings(parent, sib, next);
})() : NIL); };
// swap-html-string
var swapHtmlString = function(target, html, strategy) { return (function() { var _m = strategy; if (_m == "innerHTML") return domSetInnerHtml(target, html); if (_m == "outerHTML") return (function() {
var parent = domParent(target);
domInsertAdjacentHtml(target, "afterend", html);
domRemoveChild(parent, target);
return parent;
})(); if (_m == "afterend") return domInsertAdjacentHtml(target, "afterend", html); if (_m == "beforeend") return domInsertAdjacentHtml(target, "beforeend", html); if (_m == "afterbegin") return domInsertAdjacentHtml(target, "afterbegin", html); if (_m == "beforebegin") return domInsertAdjacentHtml(target, "beforebegin", html); if (_m == "delete") return domRemoveChild(domParent(target), target); if (_m == "none") return NIL; return domSetInnerHtml(target, html); })(); };
// handle-history
var handleHistory = function(el, url, respHeaders) { return (function() {
var pushUrl = domGetAttr(el, "sx-push-url");
var replaceUrl = domGetAttr(el, "sx-replace-url");
var hdrReplace = get(respHeaders, "replace-url");
return (isSxTruthy(hdrReplace) ? browserReplaceState(hdrReplace) : (isSxTruthy((isSxTruthy(pushUrl) && !isSxTruthy((pushUrl == "false")))) ? browserPushState((isSxTruthy((pushUrl == "true")) ? url : pushUrl)) : (isSxTruthy((isSxTruthy(replaceUrl) && !isSxTruthy((replaceUrl == "false")))) ? browserReplaceState((isSxTruthy((replaceUrl == "true")) ? url : replaceUrl)) : NIL)));
})(); };
// PRELOAD_TTL
var PRELOAD_TTL = 30000;
// preload-cache-get
var preloadCacheGet = function(cache, url) { return (function() {
var entry = dictGet(cache, url);
return (isSxTruthy(isNil(entry)) ? NIL : (isSxTruthy(((nowMs() - get(entry, "timestamp")) > PRELOAD_TTL)) ? (dictDelete(cache, url), NIL) : (dictDelete(cache, url), entry)));
})(); };
// preload-cache-set
var preloadCacheSet = function(cache, url, text, contentType) { return dictSet(cache, url, {["text"]: text, ["content-type"]: contentType, ["timestamp"]: nowMs()}); };
// classify-trigger
var classifyTrigger = function(trigger) { return (function() {
var event = get(trigger, "event");
return (isSxTruthy((event == "every")) ? "poll" : (isSxTruthy((event == "intersect")) ? "intersect" : (isSxTruthy((event == "load")) ? "load" : (isSxTruthy((event == "revealed")) ? "revealed" : "event"))));
})(); };
// should-boost-link?
var shouldBoostLink = function(link) { return (function() {
var href = domGetAttr(link, "href");
return (isSxTruthy(href) && isSxTruthy(!isSxTruthy(startsWith(href, "#"))) && isSxTruthy(!isSxTruthy(startsWith(href, "javascript:"))) && isSxTruthy(!isSxTruthy(startsWith(href, "mailto:"))) && isSxTruthy(browserSameOrigin(href)) && isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-get"))) && isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-post"))) && !isSxTruthy(domHasAttr(link, "sx-disable")));
})(); };
// should-boost-form?
var shouldBoostForm = function(form) { return (isSxTruthy(!isSxTruthy(domHasAttr(form, "sx-get"))) && isSxTruthy(!isSxTruthy(domHasAttr(form, "sx-post"))) && !isSxTruthy(domHasAttr(form, "sx-disable"))); };
// parse-sse-swap
var parseSseSwap = function(el) { return sxOr(domGetAttr(el, "sx-sse-swap"), "message"); };
// === Transpiled from orchestration ===
// _preload-cache
var _preloadCache = {};
// _css-hash
var _cssHash = NIL;
// dispatch-trigger-events
var dispatchTriggerEvents = function(el, headerVal) { return (isSxTruthy(headerVal) ? (function() {
var parsed = tryParseJson(headerVal);
return (isSxTruthy(parsed) ? forEach(function(key) { return domDispatch(el, key, get(parsed, key)); }, keys(parsed)) : forEach(function(name) { return (function() {
var trimmed = trim(name);
return (isSxTruthy(!isSxTruthy(isEmpty(trimmed))) ? domDispatch(el, trimmed, {}) : NIL);
})(); }, split(headerVal, ",")));
})() : NIL); };
// init-css-tracking
var initCssTracking = function() { return (function() {
var meta = domQuery("meta[name=\"sx-css-classes\"]");
return (isSxTruthy(meta) ? (function() {
var content = domGetAttr(meta, "content");
return (isSxTruthy(content) ? (_cssHash = content) : NIL);
})() : NIL);
})(); };
// execute-request
var executeRequest = function(el, verbInfo, extraParams) { return (function() {
var info = sxOr(getVerbInfo(el), verbInfo);
return (isSxTruthy(isNil(info)) ? promiseResolve(NIL) : (function() {
var verb = get(info, "method");
var url = get(info, "url");
return (isSxTruthy((function() {
var media = domGetAttr(el, "sx-media");
return (isSxTruthy(media) && !isSxTruthy(browserMediaMatches(media)));
})()) ? promiseResolve(NIL) : (isSxTruthy((function() {
var confirmMsg = domGetAttr(el, "sx-confirm");
return (isSxTruthy(confirmMsg) && !isSxTruthy(browserConfirm(confirmMsg)));
})()) ? promiseResolve(NIL) : (function() {
var promptMsg = domGetAttr(el, "sx-prompt");
var promptVal = (isSxTruthy(promptMsg) ? browserPrompt(promptMsg) : NIL);
return (isSxTruthy((isSxTruthy(promptMsg) && isNil(promptVal))) ? promiseResolve(NIL) : (isSxTruthy(!isSxTruthy(validateForRequest(el))) ? promiseResolve(NIL) : doFetch(el, verb, verb, url, (isSxTruthy(promptVal) ? assoc(sxOr(extraParams, {}), "SX-Prompt", promptVal) : extraParams))));
})()));
})());
})(); };
// do-fetch
var doFetch = function(el, verb, method, url, extraParams) { return (function() {
var sync = domGetAttr(el, "sx-sync");
if (isSxTruthy((sync == "replace"))) {
abortPrevious(el);
}
return (function() {
var ctrl = newAbortController();
trackController(el, ctrl);
return (function() {
var bodyInfo = buildRequestBody(el, method, url);
var finalUrl = get(bodyInfo, "url");
var body = get(bodyInfo, "body");
var ct = get(bodyInfo, "content-type");
var headers = buildRequestHeaders(el, loadedComponentNames(), _cssHash);
var csrf = csrfToken();
if (isSxTruthy(extraParams)) {
{ var _c = keys(extraParams); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; headers[k] = get(extraParams, k); } }
}
if (isSxTruthy(ct)) {
headers["Content-Type"] = ct;
}
if (isSxTruthy(csrf)) {
headers["X-CSRFToken"] = csrf;
}
return (function() {
var cached = preloadCacheGet(_preloadCache, finalUrl);
var optimisticState = applyOptimistic(el);
var indicator = showIndicator(el);
var disabledElts = disableElements(el);
domAddClass(el, "sx-request");
domSetAttr(el, "aria-busy", "true");
domDispatch(el, "sx:beforeRequest", {["url"]: finalUrl, ["method"]: method});
return fetchRequest({["url"]: finalUrl, ["method"]: method, ["headers"]: headers, ["body"]: body, ["signal"]: controllerSignal(ctrl), ["cross-origin"]: isCrossOrigin(finalUrl), ["preloaded"]: cached}, function(respOk, status, getHeader, text) { return (clearLoadingState(el, indicator, disabledElts), revertOptimistic(optimisticState), (isSxTruthy(!isSxTruthy(respOk)) ? (domDispatch(el, "sx:responseError", {["status"]: status, ["text"]: text}), handleRetry(el, verb, method, finalUrl, extraParams)) : (domDispatch(el, "sx:afterRequest", {["status"]: status}), handleFetchSuccess(el, finalUrl, verb, extraParams, getHeader, text)))); }, function(err) { return (clearLoadingState(el, indicator, disabledElts), revertOptimistic(optimisticState), (isSxTruthy(!isSxTruthy(isAbortError(err))) ? domDispatch(el, "sx:requestError", {["error"]: err}) : NIL)); });
})();
})();
})();
})(); };
// handle-fetch-success
var handleFetchSuccess = function(el, url, verb, extraParams, getHeader, text) { return (function() {
var respHeaders = processResponseHeaders(getHeader);
(function() {
var newHash = get(respHeaders, "css-hash");
return (isSxTruthy(newHash) ? (_cssHash = newHash) : NIL);
})();
dispatchTriggerEvents(el, get(respHeaders, "trigger"));
return (isSxTruthy(get(respHeaders, "redirect")) ? browserNavigate(get(respHeaders, "redirect")) : (isSxTruthy(get(respHeaders, "refresh")) ? browserReload() : (isSxTruthy(get(respHeaders, "location")) ? fetchLocation(get(respHeaders, "location")) : (function() {
var targetEl = (isSxTruthy(get(respHeaders, "retarget")) ? domQuery(get(respHeaders, "retarget")) : resolveTarget(el));
var swapSpec = parseSwapSpec(sxOr(get(respHeaders, "reswap"), domGetAttr(el, "sx-swap")), domHasClass(domBody(), "sx-transitions"));
var swapStyle = get(swapSpec, "style");
var useTransition = get(swapSpec, "transition");
var ct = sxOr(get(respHeaders, "content-type"), "");
(isSxTruthy(contains(ct, "text/sx")) ? handleSxResponse(el, targetEl, text, swapStyle, useTransition) : handleHtmlResponse(el, targetEl, text, swapStyle, useTransition));
dispatchTriggerEvents(el, get(respHeaders, "trigger-swap"));
handleHistory(el, url, respHeaders);
if (isSxTruthy(get(respHeaders, "trigger-settle"))) {
setTimeout_(function() { return dispatchTriggerEvents(el, get(respHeaders, "trigger-settle")); }, 20);
}
return domDispatch(el, "sx:afterSwap", {["target"]: targetEl, ["swap"]: swapStyle});
})())));
})(); };
// handle-sx-response
var handleSxResponse = function(el, target, text, swapStyle, useTransition) { return (function() {
var cleaned = stripComponentScripts(text);
return (function() {
var final = extractResponseCss(cleaned);
return (function() {
var trimmed = trim(final);
return (isSxTruthy(!isSxTruthy(isEmpty(trimmed))) ? (function() {
var rendered = sxRender(trimmed);
var container = domCreateElement("div", NIL);
domAppend(container, rendered);
processOobSwaps(container, function(t, oob, s) { swapDomNodes(t, oob, s);
sxHydrate(t);
return processElements(t); });
return (function() {
var selectSel = domGetAttr(el, "sx-select");
var content = (isSxTruthy(selectSel) ? selectFromContainer(container, selectSel) : childrenToFragment(container));
return withTransition(useTransition, function() { swapDomNodes(target, content, swapStyle);
return postSwap(target); });
})();
})() : NIL);
})();
})();
})(); };
// handle-html-response
var handleHtmlResponse = function(el, target, text, swapStyle, useTransition) { return (function() {
var doc = domParseHtmlDocument(text);
return (isSxTruthy(doc) ? (function() {
var selectSel = domGetAttr(el, "sx-select");
return (isSxTruthy(selectSel) ? (function() {
var html = selectHtmlFromDoc(doc, selectSel);
return withTransition(useTransition, function() { swapHtmlString(target, html, swapStyle);
return postSwap(target); });
})() : (function() {
var container = domCreateElement("div", NIL);
domSetInnerHtml(container, domBodyInnerHtml(doc));
processOobSwaps(container, function(t, oob, s) { swapDomNodes(t, oob, s);
return postSwap(t); });
hoistHeadElements(container);
return withTransition(useTransition, function() { swapDomNodes(target, childrenToFragment(container), swapStyle);
return postSwap(target); });
})());
})() : NIL);
})(); };
// handle-retry
var handleRetry = function(el, verb, method, url, extraParams) { return (function() {
var retryAttr = domGetAttr(el, "sx-retry");
var spec = parseRetrySpec(retryAttr);
return (isSxTruthy(spec) ? (function() {
var currentMs = sxOr(domGetAttr(el, "data-sx-retry-ms"), get(spec, "start-ms"));
return (function() {
var ms = parseInt_(currentMs, get(spec, "start-ms"));
domSetAttr(el, "data-sx-retry-ms", (String(nextRetryMs(ms, get(spec, "cap-ms")))));
return setTimeout_(function() { return doFetch(el, verb, method, url, extraParams); }, ms);
})();
})() : NIL);
})(); };
// bind-triggers
var bindTriggers = function(el, verbInfo) { return (function() {
var triggers = sxOr(parseTriggerSpec(domGetAttr(el, "sx-trigger")), defaultTrigger(domTagName(el)));
return forEach(function(trigger) { return (function() {
var kind = classifyTrigger(trigger);
var mods = get(trigger, "modifiers");
return (isSxTruthy((kind == "poll")) ? setInterval_(function() { return executeRequest(el, NIL, NIL); }, get(mods, "interval")) : (isSxTruthy((kind == "intersect")) ? observeIntersection(el, function() { return executeRequest(el, NIL, NIL); }, false, get(mods, "delay")) : (isSxTruthy((kind == "load")) ? setTimeout_(function() { return executeRequest(el, NIL, NIL); }, sxOr(get(mods, "delay"), 0)) : (isSxTruthy((kind == "revealed")) ? observeIntersection(el, function() { return executeRequest(el, NIL, NIL); }, true, get(mods, "delay")) : (isSxTruthy((kind == "event")) ? bindEvent(el, get(trigger, "event"), mods, verbInfo) : NIL)))));
})(); }, triggers);
})(); };
// bind-event
var bindEvent = function(el, eventName, mods, verbInfo) { return (function() {
var timer = NIL;
var lastVal = NIL;
var listenTarget = (isSxTruthy(get(mods, "from")) ? domQuery(get(mods, "from")) : el);
return (isSxTruthy(listenTarget) ? domAddListener(listenTarget, eventName, function(e) { return (function() {
var shouldFire = true;
if (isSxTruthy(get(mods, "changed"))) {
(function() {
var val = elementValue(el);
return (isSxTruthy((val == lastVal)) ? (shouldFire = false) : (lastVal = val));
})();
}
return (isSxTruthy(shouldFire) ? ((isSxTruthy(sxOr((eventName == "submit"), (isSxTruthy((eventName == "click")) && domHasAttr(el, "href")))) ? preventDefault_(e) : NIL), (function() {
var isGetLink = (isSxTruthy((eventName == "click")) && isSxTruthy((get(verbInfo, "method") == "GET")) && isSxTruthy(domHasAttr(el, "href")) && !isSxTruthy(get(mods, "delay")));
var clientRouted = false;
if (isSxTruthy(isGetLink)) {
logInfo((String("sx:route trying ") + String(get(verbInfo, "url"))));
clientRouted = tryClientRoute(urlPathname(get(verbInfo, "url")), domGetAttr(el, "sx-target"));
}
return (isSxTruthy(clientRouted) ? (browserPushState(get(verbInfo, "url")), browserScrollTo(0, 0)) : ((isSxTruthy(isGetLink) ? logInfo((String("sx:route server fetch ") + String(get(verbInfo, "url")))) : NIL), (isSxTruthy(get(mods, "delay")) ? (clearTimeout_(timer), (timer = setTimeout_(function() { return executeRequest(el, verbInfo, NIL); }, get(mods, "delay")))) : executeRequest(el, verbInfo, NIL))));
})()) : NIL);
})(); }, (isSxTruthy(get(mods, "once")) ? {["once"]: true} : NIL)) : NIL);
})(); };
// post-swap
var postSwap = function(root) { activateScripts(root);
sxProcessScripts(root);
sxHydrate(root);
return processElements(root); };
// activate-scripts
var activateScripts = function(root) { return (isSxTruthy(root) ? (function() {
var scripts = domQueryAll(root, "script");
return forEach(function(dead) { return (isSxTruthy((isSxTruthy(!isSxTruthy(domHasAttr(dead, "data-components"))) && !isSxTruthy(domHasAttr(dead, "data-sx-activated")))) ? (function() {
var live = createScriptClone(dead);
domSetAttr(live, "data-sx-activated", "true");
return domReplaceChild(domParent(dead), live, dead);
})() : NIL); }, scripts);
})() : NIL); };
// process-oob-swaps
var processOobSwaps = function(container, swapFn) { return (function() {
var oobs = findOobSwaps(container);
return forEach(function(oob) { return (function() {
var targetId = get(oob, "target-id");
var target = domQueryById(targetId);
var oobEl = get(oob, "element");
var swapType = get(oob, "swap-type");
if (isSxTruthy(domParent(oobEl))) {
domRemoveChild(domParent(oobEl), oobEl);
}
return (isSxTruthy(target) ? swapFn(target, oobEl, swapType) : NIL);
})(); }, oobs);
})(); };
// hoist-head-elements
var hoistHeadElements = function(container) { { var _c = domQueryAll(container, "style[data-sx-css]"); for (var _i = 0; _i < _c.length; _i++) { var style = _c[_i]; if (isSxTruthy(domParent(style))) {
domRemoveChild(domParent(style), style);
}
domAppendToHead(style); } }
return forEach(function(link) { if (isSxTruthy(domParent(link))) {
domRemoveChild(domParent(link), link);
}
return domAppendToHead(link); }, domQueryAll(container, "link[rel=\"stylesheet\"]")); };
// process-boosted
var processBoosted = function(root) { return forEach(function(container) { return boostDescendants(container); }, domQueryAll(sxOr(root, domBody()), "[sx-boost]")); };
// boost-descendants
var boostDescendants = function(container) { return (function() {
var boostTarget = domGetAttr(container, "sx-boost");
{ var _c = domQueryAll(container, "a[href]"); for (var _i = 0; _i < _c.length; _i++) { var link = _c[_i]; if (isSxTruthy((isSxTruthy(!isSxTruthy(isProcessed(link, "boost"))) && shouldBoostLink(link)))) {
markProcessed(link, "boost");
if (isSxTruthy((isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-target"))) && isSxTruthy(boostTarget) && !isSxTruthy((boostTarget == "true"))))) {
domSetAttr(link, "sx-target", boostTarget);
}
if (isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-swap")))) {
domSetAttr(link, "sx-swap", "innerHTML");
}
if (isSxTruthy(!isSxTruthy(domHasAttr(link, "sx-push-url")))) {
domSetAttr(link, "sx-push-url", "true");
}
bindClientRouteLink(link, domGetAttr(link, "href"));
} } }
return forEach(function(form) { return (isSxTruthy((isSxTruthy(!isSxTruthy(isProcessed(form, "boost"))) && shouldBoostForm(form))) ? (markProcessed(form, "boost"), (function() {
var method = upper(sxOr(domGetAttr(form, "method"), "GET"));
var action = sxOr(domGetAttr(form, "action"), browserLocationHref());
if (isSxTruthy((isSxTruthy(!isSxTruthy(domHasAttr(form, "sx-target"))) && isSxTruthy(boostTarget) && !isSxTruthy((boostTarget == "true"))))) {
domSetAttr(form, "sx-target", boostTarget);
}
if (isSxTruthy(!isSxTruthy(domHasAttr(form, "sx-swap")))) {
domSetAttr(form, "sx-swap", "innerHTML");
}
return bindBoostForm(form, method, action);
})()) : NIL); }, domQueryAll(container, "form"));
})(); };
// _page-data-cache
var _pageDataCache = {};
// _page-data-cache-ttl
var _pageDataCacheTtl = 30000;
// page-data-cache-key
var pageDataCacheKey = function(pageName, params) { return (function() {
var base = pageName;
return (isSxTruthy(sxOr(isNil(params), isEmpty(keys(params)))) ? base : (function() {
var parts = [];
{ var _c = keys(params); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; parts.push((String(k) + String("=") + String(get(params, k)))); } }
return (String(base) + String(":") + String(join("&", parts)));
})());
})(); };
// page-data-cache-get
var pageDataCacheGet = function(cacheKey) { return (function() {
var entry = get(_pageDataCache, cacheKey);
return (isSxTruthy(isNil(entry)) ? NIL : (isSxTruthy(((nowMs() - get(entry, "ts")) > _pageDataCacheTtl)) ? (dictSet(_pageDataCache, cacheKey, NIL), NIL) : get(entry, "data")));
})(); };
// page-data-cache-set
var pageDataCacheSet = function(cacheKey, data) { return dictSet(_pageDataCache, cacheKey, {"data": data, "ts": nowMs()}); };
// swap-rendered-content
var swapRenderedContent = function(target, rendered, pathname) { return (domSetTextContent(target, ""), domAppend(target, rendered), hoistHeadElementsFull(target), processElements(target), sxHydrateElements(target), domDispatch(target, "sx:clientRoute", {["pathname"]: pathname}), logInfo((String("sx:route client ") + String(pathname)))); };
// resolve-route-target
var resolveRouteTarget = function(targetSel) { return (isSxTruthy((isSxTruthy(targetSel) && !isSxTruthy((targetSel == "true")))) ? domQuery(targetSel) : NIL); };
// try-client-route
var tryClientRoute = function(pathname, targetSel) { return (function() {
var match = findMatchingRoute(pathname, _pageRoutes);
return (isSxTruthy(isNil(match)) ? (logInfo((String("sx:route no match (") + String(len(_pageRoutes)) + String(" routes) ") + String(pathname))), false) : (function() {
var contentSrc = get(match, "content");
var closure = sxOr(get(match, "closure"), {});
var params = get(match, "params");
var pageName = get(match, "name");
return (isSxTruthy(sxOr(isNil(contentSrc), isEmpty(contentSrc))) ? (logWarn((String("sx:route no content for ") + String(pathname))), false) : (function() {
var target = resolveRouteTarget(targetSel);
return (isSxTruthy(isNil(target)) ? (logWarn((String("sx:route target not found: ") + String(targetSel))), false) : (isSxTruthy(get(match, "has-data")) ? (function() {
var cacheKey = pageDataCacheKey(pageName, params);
var cached = pageDataCacheGet(cacheKey);
return (isSxTruthy(cached) ? (function() {
var env = merge(closure, params, cached);
var rendered = tryEvalContent(contentSrc, env);
return (isSxTruthy(isNil(rendered)) ? (logWarn((String("sx:route cached eval failed for ") + String(pathname))), false) : (logInfo((String("sx:route client+cache ") + String(pathname))), swapRenderedContent(target, rendered, pathname), true));
})() : (logInfo((String("sx:route client+data ") + String(pathname))), resolvePageData(pageName, params, function(data) { pageDataCacheSet(cacheKey, data);
return (function() {
var env = merge(closure, params, data);
var rendered = tryEvalContent(contentSrc, env);
return (isSxTruthy(isNil(rendered)) ? logWarn((String("sx:route data eval failed for ") + String(pathname))) : swapRenderedContent(target, rendered, pathname));
})(); }), true));
})() : (function() {
var env = merge(closure, params);
var rendered = tryEvalContent(contentSrc, env);
return (isSxTruthy(isNil(rendered)) ? (logInfo((String("sx:route server (eval failed) ") + String(pathname))), false) : (swapRenderedContent(target, rendered, pathname), true));
})()));
})());
})());
})(); };
// bind-client-route-link
var bindClientRouteLink = function(link, href) { return bindClientRouteClick(link, href, function() { return bindBoostLink(link, href); }); };
// process-sse
var processSse = function(root) { return forEach(function(el) { return (isSxTruthy(!isSxTruthy(isProcessed(el, "sse"))) ? (markProcessed(el, "sse"), bindSse(el)) : NIL); }, domQueryAll(sxOr(root, domBody()), "[sx-sse]")); };
// bind-sse
var bindSse = function(el) { return (function() {
var url = domGetAttr(el, "sx-sse");
return (isSxTruthy(url) ? (function() {
var source = eventSourceConnect(url, el);
var eventName = parseSseSwap(el);
return eventSourceListen(source, eventName, function(data) { return bindSseSwap(el, data); });
})() : NIL);
})(); };
// bind-sse-swap
var bindSseSwap = function(el, data) { return (function() {
var target = resolveTarget(el);
var swapSpec = parseSwapSpec(domGetAttr(el, "sx-swap"), domHasClass(domBody(), "sx-transitions"));
var swapStyle = get(swapSpec, "style");
var useTransition = get(swapSpec, "transition");
var trimmed = trim(data);
return (isSxTruthy(!isSxTruthy(isEmpty(trimmed))) ? (isSxTruthy(startsWith(trimmed, "(")) ? (function() {
var rendered = sxRender(trimmed);
var container = domCreateElement("div", NIL);
domAppend(container, rendered);
return withTransition(useTransition, function() { swapDomNodes(target, childrenToFragment(container), swapStyle);
return postSwap(target); });
})() : withTransition(useTransition, function() { swapHtmlString(target, trimmed, swapStyle);
return postSwap(target); })) : NIL);
})(); };
// bind-inline-handlers
var bindInlineHandlers = function(root) { return forEach(function(el) { return forEach(function(attr) { return (function() {
var name = first(attr);
var body = nth(attr, 1);
return (isSxTruthy(startsWith(name, "sx-on:")) ? (function() {
var eventName = slice(name, 6);
return (isSxTruthy(!isSxTruthy(isProcessed(el, (String("on:") + String(eventName))))) ? (markProcessed(el, (String("on:") + String(eventName))), bindInlineHandler(el, eventName, body)) : NIL);
})() : NIL);
})(); }, domAttrList(el)); }, domQueryAll(sxOr(root, domBody()), "[sx-on\\:beforeRequest],[sx-on\\:afterRequest],[sx-on\\:afterSwap],[sx-on\\:afterSettle],[sx-on\\:load]")); };
// bind-preload-for
var bindPreloadFor = function(el) { return (function() {
var preloadAttr = domGetAttr(el, "sx-preload");
return (isSxTruthy(preloadAttr) ? (function() {
var info = getVerbInfo(el);
return (isSxTruthy(info) ? (function() {
var url = get(info, "url");
var headers = buildRequestHeaders(el, loadedComponentNames(), _cssHash);
var events = (isSxTruthy((preloadAttr == "mousedown")) ? ["mousedown", "touchstart"] : ["mouseover"]);
var debounceMs = (isSxTruthy((preloadAttr == "mousedown")) ? 0 : 100);
return bindPreload(el, events, debounceMs, function() { return doPreload(url, headers); });
})() : NIL);
})() : NIL);
})(); };
// do-preload
var doPreload = function(url, headers) { return (isSxTruthy(isNil(preloadCacheGet(_preloadCache, url))) ? fetchPreload(url, headers, _preloadCache) : NIL); };
// VERB_SELECTOR
var VERB_SELECTOR = (String("[sx-get],[sx-post],[sx-put],[sx-delete],[sx-patch]"));
// process-elements
var processElements = function(root) { (function() {
var els = domQueryAll(sxOr(root, domBody()), VERB_SELECTOR);
return forEach(function(el) { return (isSxTruthy(!isSxTruthy(isProcessed(el, "verb"))) ? (markProcessed(el, "verb"), processOne(el)) : NIL); }, els);
})();
processBoosted(root);
processSse(root);
return bindInlineHandlers(root); };
// process-one
var processOne = function(el) { return (function() {
var verbInfo = getVerbInfo(el);
return (isSxTruthy(verbInfo) ? (isSxTruthy(!isSxTruthy(domHasAttr(el, "sx-disable"))) ? (bindTriggers(el, verbInfo), bindPreloadFor(el)) : NIL) : NIL);
})(); };
// handle-popstate
var handlePopstate = function(scrollY) { return (function() {
var boostEl = domQuery("[sx-boost]");
var url = browserLocationHref();
return (isSxTruthy(boostEl) ? (function() {
var targetSel = domGetAttr(boostEl, "sx-boost");
var target = (isSxTruthy((isSxTruthy(targetSel) && !isSxTruthy((targetSel == "true")))) ? domQuery(targetSel) : NIL);
var pathname = urlPathname(url);
return (isSxTruthy(target) ? (isSxTruthy(tryClientRoute(pathname, targetSel)) ? browserScrollTo(0, scrollY) : (function() {
var headers = buildRequestHeaders(target, loadedComponentNames(), _cssHash);
return fetchAndRestore(target, url, headers, scrollY);
})()) : NIL);
})() : NIL);
})(); };
// engine-init
var engineInit = function() { return (initCssTracking(), sxProcessScripts(NIL), sxHydrate(NIL), processElements(NIL)); };
// === Transpiled from cssx ===
// _style-atoms
var _styleAtoms = {};
// _pseudo-variants
var _pseudoVariants = {};
// _responsive-breakpoints
var _responsiveBreakpoints = {};
// _style-keyframes
var _styleKeyframes = {};
// _arbitrary-patterns
var _arbitraryPatterns = [];
// _child-selector-prefixes
var _childSelectorPrefixes = [];
// _style-cache
var _styleCache = {};
// _injected-styles
var _injectedStyles = {};
// load-style-dict
var loadStyleDict = function(data) { _styleAtoms = sxOr(get(data, "a"), {});
_pseudoVariants = sxOr(get(data, "v"), {});
_responsiveBreakpoints = sxOr(get(data, "b"), {});
_styleKeyframes = sxOr(get(data, "k"), {});
_childSelectorPrefixes = sxOr(get(data, "c"), []);
_arbitraryPatterns = map(function(pair) { return {["re"]: compileRegex((String("^") + String(first(pair)) + String("$"))), ["tmpl"]: nth(pair, 1)}; }, sxOr(get(data, "p"), []));
return (_styleCache = {}); };
// split-variant
var splitVariant = function(atom) { return (function() {
var result = NIL;
{ var _c = keys(_responsiveBreakpoints); for (var _i = 0; _i < _c.length; _i++) { var bp = _c[_i]; if (isSxTruthy(isNil(result))) {
(function() {
var prefix = (String(bp) + String(":"));
return (isSxTruthy(startsWith(atom, prefix)) ? (function() {
var restAtom = slice(atom, len(prefix));
return (function() {
var innerMatch = NIL;
{ var _c = keys(_pseudoVariants); for (var _i = 0; _i < _c.length; _i++) { var pv = _c[_i]; if (isSxTruthy(isNil(innerMatch))) {
(function() {
var innerPrefix = (String(pv) + String(":"));
return (isSxTruthy(startsWith(restAtom, innerPrefix)) ? (innerMatch = [(String(bp) + String(":") + String(pv)), slice(restAtom, len(innerPrefix))]) : NIL);
})();
} } }
return (result = sxOr(innerMatch, [bp, restAtom]));
})();
})() : NIL);
})();
} } }
if (isSxTruthy(isNil(result))) {
{ var _c = keys(_pseudoVariants); for (var _i = 0; _i < _c.length; _i++) { var pv = _c[_i]; if (isSxTruthy(isNil(result))) {
(function() {
var prefix = (String(pv) + String(":"));
return (isSxTruthy(startsWith(atom, prefix)) ? (result = [pv, slice(atom, len(prefix))]) : NIL);
})();
} } }
}
return sxOr(result, [NIL, atom]);
})(); };
// resolve-atom
var resolveAtom = function(atom) { return (function() {
var decls = dictGet(_styleAtoms, atom);
return (isSxTruthy(!isSxTruthy(isNil(decls))) ? decls : (isSxTruthy(startsWith(atom, "animate-")) ? (function() {
var kfName = slice(atom, 8);
return (isSxTruthy(dictHas(_styleKeyframes, kfName)) ? (String("animation-name:") + String(kfName)) : NIL);
})() : (function() {
var matchResult = NIL;
{ var _c = _arbitraryPatterns; for (var _i = 0; _i < _c.length; _i++) { var pat = _c[_i]; if (isSxTruthy(isNil(matchResult))) {
(function() {
var m = regexMatch(get(pat, "re"), atom);
return (isSxTruthy(m) ? (matchResult = regexReplaceGroups(get(pat, "tmpl"), m)) : NIL);
})();
} } }
return matchResult;
})()));
})(); };
// is-child-selector-atom?
var isChildSelectorAtom = function(atom) { return some(function(prefix) { return startsWith(atom, prefix); }, _childSelectorPrefixes); };
// hash-style
var hashStyle = function(input) { return fnv1aHash(input); };
// resolve-style
var resolveStyle = function(atoms) { return (function() {
var key = join("\\0", atoms);
return (function() {
var cached = dictGet(_styleCache, key);
return (isSxTruthy(!isSxTruthy(isNil(cached))) ? cached : (function() {
var baseDecls = [];
var mediaRules = [];
var pseudoRules = [];
var kfNeeded = [];
{ var _c = atoms; for (var _i = 0; _i < _c.length; _i++) { var a = _c[_i]; if (isSxTruthy(a)) {
(function() {
var clean = (isSxTruthy(startsWith(a, ":")) ? slice(a, 1) : a);
return (function() {
var parts = splitVariant(clean);
return (function() {
var variant = first(parts);
var base = nth(parts, 1);
var decls = resolveAtom(base);
return (isSxTruthy(decls) ? ((isSxTruthy(startsWith(base, "animate-")) ? (function() {
var kfName = slice(base, 8);
return (isSxTruthy(dictHas(_styleKeyframes, kfName)) ? append_b(kfNeeded, [kfName, dictGet(_styleKeyframes, kfName)]) : NIL);
})() : NIL), (isSxTruthy(isNil(variant)) ? (isSxTruthy(isChildSelectorAtom(base)) ? append_b(pseudoRules, [">:not(:first-child)", decls]) : append_b(baseDecls, decls)) : (isSxTruthy(dictHas(_responsiveBreakpoints, variant)) ? append_b(mediaRules, [dictGet(_responsiveBreakpoints, variant), decls]) : (isSxTruthy(dictHas(_pseudoVariants, variant)) ? append_b(pseudoRules, [dictGet(_pseudoVariants, variant), decls]) : (function() {
var vparts = split(variant, ":");
var mediaPart = NIL;
var pseudoPart = NIL;
{ var _c = vparts; for (var _i = 0; _i < _c.length; _i++) { var vp = _c[_i]; (isSxTruthy(dictHas(_responsiveBreakpoints, vp)) ? (mediaPart = dictGet(_responsiveBreakpoints, vp)) : (isSxTruthy(dictHas(_pseudoVariants, vp)) ? (pseudoPart = dictGet(_pseudoVariants, vp)) : NIL)); } }
if (isSxTruthy(mediaPart)) {
mediaRules.push([mediaPart, decls]);
}
if (isSxTruthy(pseudoPart)) {
pseudoRules.push([pseudoPart, decls]);
}
return (isSxTruthy((isSxTruthy(isNil(mediaPart)) && isNil(pseudoPart))) ? append_b(baseDecls, decls) : NIL);
})())))) : NIL);
})();
})();
})();
} } }
return (function() {
var hashInput = join(";", baseDecls);
{ var _c = mediaRules; for (var _i = 0; _i < _c.length; _i++) { var mr = _c[_i]; hashInput = (String(hashInput) + String("@") + String(first(mr)) + String("{") + String(nth(mr, 1)) + String("}")); } }
{ var _c = pseudoRules; for (var _i = 0; _i < _c.length; _i++) { var pr = _c[_i]; hashInput = (String(hashInput) + String(first(pr)) + String("{") + String(nth(pr, 1)) + String("}")); } }
{ var _c = kfNeeded; for (var _i = 0; _i < _c.length; _i++) { var kf = _c[_i]; hashInput = (String(hashInput) + String(nth(kf, 1))); } }
return (function() {
var cn = (String("sx-") + String(hashStyle(hashInput)));
var sv = makeStyleValue_(cn, join(";", baseDecls), mediaRules, pseudoRules, kfNeeded);
_styleCache[key] = sv;
injectStyleValue(sv, atoms);
return sv;
})();
})();
})());
})();
})(); };
// merge-style-values
var mergeStyleValues = function(styles) { return (isSxTruthy((len(styles) == 1)) ? first(styles) : (function() {
var allDecls = [];
var allMedia = [];
var allPseudo = [];
var allKf = [];
{ var _c = styles; for (var _i = 0; _i < _c.length; _i++) { var sv = _c[_i]; if (isSxTruthy(styleValueDeclarations(sv))) {
allDecls.push(styleValueDeclarations(sv));
}
allMedia = concat(allMedia, styleValueMediaRules(sv));
allPseudo = concat(allPseudo, styleValuePseudoRules(sv));
allKf = concat(allKf, styleValueKeyframes_(sv)); } }
return (function() {
var hashInput = join(";", allDecls);
{ var _c = allMedia; for (var _i = 0; _i < _c.length; _i++) { var mr = _c[_i]; hashInput = (String(hashInput) + String("@") + String(first(mr)) + String("{") + String(nth(mr, 1)) + String("}")); } }
{ var _c = allPseudo; for (var _i = 0; _i < _c.length; _i++) { var pr = _c[_i]; hashInput = (String(hashInput) + String(first(pr)) + String("{") + String(nth(pr, 1)) + String("}")); } }
{ var _c = allKf; for (var _i = 0; _i < _c.length; _i++) { var kf = _c[_i]; hashInput = (String(hashInput) + String(nth(kf, 1))); } }
return (function() {
var cn = (String("sx-") + String(hashStyle(hashInput)));
var merged = makeStyleValue_(cn, join(";", allDecls), allMedia, allPseudo, allKf);
injectStyleValue(merged, []);
return merged;
})();
})();
})()); };
// === Transpiled from boot ===
// HEAD_HOIST_SELECTOR
var HEAD_HOIST_SELECTOR = "meta, title, link[rel='canonical'], script[type='application/ld+json']";
// hoist-head-elements-full
var hoistHeadElementsFull = function(root) { return (function() {
var els = domQueryAll(root, HEAD_HOIST_SELECTOR);
return forEach(function(el) { return (function() {
var tag = lower(domTagName(el));
return (isSxTruthy((tag == "title")) ? (setDocumentTitle(domTextContent(el)), domRemoveChild(domParent(el), el)) : (isSxTruthy((tag == "meta")) ? ((function() {
var name = domGetAttr(el, "name");
var prop = domGetAttr(el, "property");
if (isSxTruthy(name)) {
removeHeadElement((String("meta[name=\"") + String(name) + String("\"]")));
}
return (isSxTruthy(prop) ? removeHeadElement((String("meta[property=\"") + String(prop) + String("\"]"))) : NIL);
})(), domRemoveChild(domParent(el), el), domAppendToHead(el)) : (isSxTruthy((isSxTruthy((tag == "link")) && (domGetAttr(el, "rel") == "canonical"))) ? (removeHeadElement("link[rel=\"canonical\"]"), domRemoveChild(domParent(el), el), domAppendToHead(el)) : (domRemoveChild(domParent(el), el), domAppendToHead(el)))));
})(); }, els);
})(); };
// sx-mount
var sxMount = function(target, source, extraEnv) { return (function() {
var el = resolveMountTarget(target);
return (isSxTruthy(el) ? (function() {
var node = sxRenderWithEnv(source, extraEnv);
domSetTextContent(el, "");
domAppend(el, node);
hoistHeadElementsFull(el);
processElements(el);
return sxHydrateElements(el);
})() : NIL);
})(); };
// sx-hydrate-elements
var sxHydrateElements = function(root) { return (function() {
var els = domQueryAll(sxOr(root, domBody()), "[data-sx]");
return forEach(function(el) { return (isSxTruthy(!isSxTruthy(isProcessed(el, "hydrated"))) ? (markProcessed(el, "hydrated"), sxUpdateElement(el, NIL)) : NIL); }, els);
})(); };
// sx-update-element
var sxUpdateElement = function(el, newEnv) { return (function() {
var target = resolveMountTarget(el);
return (isSxTruthy(target) ? (function() {
var source = domGetAttr(target, "data-sx");
return (isSxTruthy(source) ? (function() {
var baseEnv = parseEnvAttr(target);
var env = mergeEnvs(baseEnv, newEnv);
return (function() {
var node = sxRenderWithEnv(source, env);
domSetTextContent(target, "");
domAppend(target, node);
return (isSxTruthy(newEnv) ? storeEnvAttr(target, baseEnv, newEnv) : NIL);
})();
})() : NIL);
})() : NIL);
})(); };
// sx-render-component
var sxRenderComponent = function(name, kwargs, extraEnv) { return (function() {
var fullName = (isSxTruthy(startsWith(name, "~")) ? name : (String("~") + String(name)));
return (function() {
var env = getRenderEnv(extraEnv);
var comp = envGet(env, fullName);
return (isSxTruthy(!isSxTruthy(isComponent(comp))) ? error((String("Unknown component: ") + String(fullName))) : (function() {
var callExpr = [makeSymbol(fullName)];
{ var _c = keys(kwargs); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; callExpr.push(makeKeyword(toKebab(k)));
callExpr.push(dictGet(kwargs, k)); } }
return renderToDom(callExpr, env, NIL);
})());
})();
})(); };
// process-sx-scripts
var processSxScripts = function(root) { return (function() {
var scripts = querySxScripts(root);
return forEach(function(s) { return (isSxTruthy(!isSxTruthy(isProcessed(s, "script"))) ? (markProcessed(s, "script"), (function() {
var text = domTextContent(s);
return (isSxTruthy(domHasAttr(s, "data-components")) ? processComponentScript(s, text) : (isSxTruthy(sxOr(isNil(text), isEmpty(trim(text)))) ? NIL : (isSxTruthy(domHasAttr(s, "data-mount")) ? (function() {
var mountSel = domGetAttr(s, "data-mount");
var target = domQuery(mountSel);
return (isSxTruthy(target) ? sxMount(target, text, NIL) : NIL);
})() : sxLoadComponents(text))));
})()) : NIL); }, scripts);
})(); };
// process-component-script
var processComponentScript = function(script, text) { return (function() {
var hash = domGetAttr(script, "data-hash");
return (isSxTruthy(isNil(hash)) ? (isSxTruthy((isSxTruthy(text) && !isSxTruthy(isEmpty(trim(text))))) ? sxLoadComponents(text) : NIL) : (function() {
var hasInline = (isSxTruthy(text) && !isSxTruthy(isEmpty(trim(text))));
(function() {
var cachedHash = localStorageGet("sx-components-hash");
return (isSxTruthy((cachedHash == hash)) ? (isSxTruthy(hasInline) ? (localStorageSet("sx-components-hash", hash), localStorageSet("sx-components-src", text), sxLoadComponents(text), logInfo("components: downloaded (cookie stale)")) : (function() {
var cached = localStorageGet("sx-components-src");
return (isSxTruthy(cached) ? (sxLoadComponents(cached), logInfo((String("components: cached (") + String(hash) + String(")")))) : (clearSxCompCookie(), browserReload()));
})()) : (isSxTruthy(hasInline) ? (localStorageSet("sx-components-hash", hash), localStorageSet("sx-components-src", text), sxLoadComponents(text), logInfo((String("components: downloaded (") + String(hash) + String(")")))) : (localStorageRemove("sx-components-hash"), localStorageRemove("sx-components-src"), clearSxCompCookie(), browserReload())));
})();
return setSxCompCookie(hash);
})());
})(); };
// init-style-dict
var initStyleDict = function() { return (function() {
var scripts = queryStyleScripts();
return forEach(function(s) { return (isSxTruthy(!isSxTruthy(isProcessed(s, "styles"))) ? (markProcessed(s, "styles"), (function() {
var text = domTextContent(s);
var hash = domGetAttr(s, "data-hash");
return (isSxTruthy(isNil(hash)) ? (isSxTruthy((isSxTruthy(text) && !isSxTruthy(isEmpty(trim(text))))) ? parseAndLoadStyleDict(text) : NIL) : (function() {
var hasInline = (isSxTruthy(text) && !isSxTruthy(isEmpty(trim(text))));
(function() {
var cachedHash = localStorageGet("sx-styles-hash");
return (isSxTruthy((cachedHash == hash)) ? (isSxTruthy(hasInline) ? (localStorageSet("sx-styles-src", text), parseAndLoadStyleDict(text), logInfo("styles: downloaded (cookie stale)")) : (function() {
var cached = localStorageGet("sx-styles-src");
return (isSxTruthy(cached) ? (parseAndLoadStyleDict(cached), logInfo((String("styles: cached (") + String(hash) + String(")")))) : (clearSxStylesCookie(), browserReload()));
})()) : (isSxTruthy(hasInline) ? (localStorageSet("sx-styles-hash", hash), localStorageSet("sx-styles-src", text), parseAndLoadStyleDict(text), logInfo((String("styles: downloaded (") + String(hash) + String(")")))) : (localStorageRemove("sx-styles-hash"), localStorageRemove("sx-styles-src"), clearSxStylesCookie(), browserReload())));
})();
return setSxStylesCookie(hash);
})());
})()) : NIL); }, scripts);
})(); };
// _page-routes
var _pageRoutes = [];
// process-page-scripts
var processPageScripts = function() { return (function() {
var scripts = queryPageScripts();
logInfo((String("pages: found ") + String(len(scripts)) + String(" script tags")));
{ var _c = scripts; for (var _i = 0; _i < _c.length; _i++) { var s = _c[_i]; if (isSxTruthy(!isSxTruthy(isProcessed(s, "pages")))) {
markProcessed(s, "pages");
(function() {
var text = domTextContent(s);
logInfo((String("pages: script text length=") + String((isSxTruthy(text) ? len(text) : 0))));
return (isSxTruthy((isSxTruthy(text) && !isSxTruthy(isEmpty(trim(text))))) ? (function() {
var pages = parse(text);
logInfo((String("pages: parsed ") + String(len(pages)) + String(" entries")));
return forEach(function(page) { return append_b(_pageRoutes, merge(page, {"parsed": parseRoutePattern(get(page, "path"))})); }, pages);
})() : logWarn("pages: script tag is empty"));
})();
} } }
return logInfo((String("pages: ") + String(len(_pageRoutes)) + String(" routes loaded")));
})(); };
// boot-init
var bootInit = function() { return (logInfo((String("sx-browser ") + String(SX_VERSION))), initCssTracking(), initStyleDict(), processPageScripts(), processSxScripts(NIL), sxHydrateElements(NIL), processElements(NIL)); };
// === Transpiled from router (client-side route matching) ===
// split-path-segments
var splitPathSegments = function(path) { return (function() {
var trimmed = (isSxTruthy(startsWith(path, "/")) ? slice(path, 1) : path);
return (function() {
var trimmed2 = (isSxTruthy((isSxTruthy(!isSxTruthy(isEmpty(trimmed))) && endsWith(trimmed, "/"))) ? slice(trimmed, 0, (len(trimmed) - 1)) : trimmed);
return (isSxTruthy(isEmpty(trimmed2)) ? [] : split(trimmed2, "/"));
})();
})(); };
// make-route-segment
var makeRouteSegment = function(seg) { return (isSxTruthy((isSxTruthy(startsWith(seg, "<")) && endsWith(seg, ">"))) ? (function() {
var paramName = slice(seg, 1, (len(seg) - 1));
return (function() {
var d = {};
d["type"] = "param";
d["value"] = paramName;
return d;
})();
})() : (function() {
var d = {};
d["type"] = "literal";
d["value"] = seg;
return d;
})()); };
// parse-route-pattern
var parseRoutePattern = function(pattern) { return (function() {
var segments = splitPathSegments(pattern);
return map(makeRouteSegment, segments);
})(); };
// match-route-segments
var matchRouteSegments = function(pathSegs, parsedSegs) { return (isSxTruthy(!isSxTruthy((len(pathSegs) == len(parsedSegs)))) ? NIL : (function() {
var params = {};
var matched = true;
forEachIndexed(function(i, parsedSeg) { return (isSxTruthy(matched) ? (function() {
var pathSeg = nth(pathSegs, i);
var segType = get(parsedSeg, "type");
return (isSxTruthy((segType == "literal")) ? (isSxTruthy(!isSxTruthy((pathSeg == get(parsedSeg, "value")))) ? (matched = false) : NIL) : (isSxTruthy((segType == "param")) ? dictSet(params, get(parsedSeg, "value"), pathSeg) : (matched = false)));
})() : NIL); }, parsedSegs);
return (isSxTruthy(matched) ? params : NIL);
})()); };
// match-route
var matchRoute = function(path, pattern) { return (function() {
var pathSegs = splitPathSegments(path);
var parsedSegs = parseRoutePattern(pattern);
return matchRouteSegments(pathSegs, parsedSegs);
})(); };
// find-matching-route
var findMatchingRoute = function(path, routes) { return (function() {
var pathSegs = splitPathSegments(path);
var result = NIL;
{ var _c = routes; for (var _i = 0; _i < _c.length; _i++) { var route = _c[_i]; if (isSxTruthy(isNil(result))) {
(function() {
var params = matchRouteSegments(pathSegs, get(route, "parsed"));
return (isSxTruthy(!isSxTruthy(isNil(params))) ? (function() {
var matched = merge(route, {});
matched["params"] = params;
return (result = matched);
})() : NIL);
})();
} } }
return result;
})(); };
// =========================================================================
// Platform interface — DOM adapter (browser-only)
// =========================================================================
var _hasDom = typeof document !== "undefined";
// Register DOM adapter as the render dispatch target for the evaluator.
_renderExprFn = function(expr, env) { return renderToDom(expr, env, null); };
var SVG_NS = "http://www.w3.org/2000/svg";
var MATH_NS = "http://www.w3.org/1998/Math/MathML";
function domCreateElement(tag, ns) {
if (!_hasDom) return null;
if (ns) return document.createElementNS(ns, tag);
return document.createElement(tag);
}
function createTextNode(s) {
return _hasDom ? document.createTextNode(s) : null;
}
function createFragment() {
return _hasDom ? document.createDocumentFragment() : null;
}
function domAppend(parent, child) {
if (parent && child) parent.appendChild(child);
}
function domPrepend(parent, child) {
if (parent && child) parent.insertBefore(child, parent.firstChild);
}
function domSetAttr(el, name, val) {
if (el && el.setAttribute) el.setAttribute(name, val);
}
function domGetAttr(el, name) {
if (!el || !el.getAttribute) return NIL;
var v = el.getAttribute(name);
return v === null ? NIL : v;
}
function domRemoveAttr(el, name) {
if (el && el.removeAttribute) el.removeAttribute(name);
}
function domHasAttr(el, name) {
return !!(el && el.hasAttribute && el.hasAttribute(name));
}
function domParseHtml(html) {
if (!_hasDom) return null;
var tpl = document.createElement("template");
tpl.innerHTML = html;
return tpl.content;
}
function domClone(node) {
return node && node.cloneNode ? node.cloneNode(true) : node;
}
function domParent(el) { return el ? el.parentNode : null; }
function domId(el) { return el && el.id ? el.id : NIL; }
function domNodeType(el) { return el ? el.nodeType : 0; }
function domNodeName(el) { return el ? el.nodeName : ""; }
function domTextContent(el) { return el ? el.textContent || el.nodeValue || "" : ""; }
function domSetTextContent(el, s) { if (el) { if (el.nodeType === 3 || el.nodeType === 8) el.nodeValue = s; else el.textContent = s; } }
function domIsFragment(el) { return el ? el.nodeType === 11 : false; }
function domIsChildOf(child, parent) { return !!(parent && child && child.parentNode === parent); }
function domIsActiveElement(el) { return _hasDom && el === document.activeElement; }
function domIsInputElement(el) {
if (!el || !el.tagName) return false;
var t = el.tagName;
return t === "INPUT" || t === "TEXTAREA" || t === "SELECT";
}
function domFirstChild(el) { return el ? el.firstChild : null; }
function domNextSibling(el) { return el ? el.nextSibling : null; }
function domChildList(el) {
if (!el || !el.childNodes) return [];
return Array.prototype.slice.call(el.childNodes);
}
function domAttrList(el) {
if (!el || !el.attributes) return [];
var r = [];
for (var i = 0; i < el.attributes.length; i++) {
r.push([el.attributes[i].name, el.attributes[i].value]);
}
return r;
}
function domInsertBefore(parent, node, ref) {
if (parent && node) parent.insertBefore(node, ref || null);
}
function domInsertAfter(ref, node) {
if (ref && ref.parentNode && node) {
ref.parentNode.insertBefore(node, ref.nextSibling);
}
}
function domRemoveChild(parent, child) {
if (parent && child && child.parentNode === parent) parent.removeChild(child);
}
function domReplaceChild(parent, newChild, oldChild) {
if (parent && newChild && oldChild) parent.replaceChild(newChild, oldChild);
}
function domSetInnerHtml(el, html) {
if (el) el.innerHTML = html;
}
function domInsertAdjacentHtml(el, pos, html) {
if (el && el.insertAdjacentHTML) el.insertAdjacentHTML(pos, html);
}
function domGetStyle(el, prop) {
return el && el.style ? el.style[prop] || "" : "";
}
function domSetStyle(el, prop, val) {
if (el && el.style) el.style[prop] = val;
}
function domGetProp(el, name) { return el ? el[name] : NIL; }
function domSetProp(el, name, val) { if (el) el[name] = val; }
function domAddClass(el, cls) {
if (el && el.classList) el.classList.add(cls);
}
function domRemoveClass(el, cls) {
if (el && el.classList) el.classList.remove(cls);
}
function domDispatch(el, name, detail) {
if (!_hasDom || !el) return false;
var evt = new CustomEvent(name, { bubbles: true, cancelable: true, detail: detail || {} });
return el.dispatchEvent(evt);
}
function domQuery(sel) {
return _hasDom ? document.querySelector(sel) : null;
}
function domQueryAll(root, sel) {
if (!root || !root.querySelectorAll) return [];
return Array.prototype.slice.call(root.querySelectorAll(sel));
}
function domTagName(el) { return el && el.tagName ? el.tagName : ""; }
// =========================================================================
// Platform interface — Engine pure logic (browser + node compatible)
// =========================================================================
function browserLocationHref() {
return typeof location !== "undefined" ? location.href : "";
}
function browserSameOrigin(url) {
try { return new URL(url, location.href).origin === location.origin; }
catch (e) { return true; }
}
function browserPushState(url) {
if (typeof history !== "undefined") {
try { history.pushState({ sxUrl: url, scrollY: typeof window !== "undefined" ? window.scrollY : 0 }, "", url); }
catch (e) {}
}
}
function browserReplaceState(url) {
if (typeof history !== "undefined") {
try { history.replaceState({ sxUrl: url, scrollY: typeof window !== "undefined" ? window.scrollY : 0 }, "", url); }
catch (e) {}
}
}
function nowMs() { return Date.now(); }
function parseHeaderValue(s) {
if (!s) return null;
try {
if (s.charAt(0) === "{" && s.charAt(1) === ":") return parse(s);
return JSON.parse(s);
} catch (e) { return null; }
}
// =========================================================================
// Platform interface — Orchestration (browser-only)
// =========================================================================
// --- Browser/Network ---
function browserNavigate(url) {
if (typeof location !== "undefined") location.assign(url);
}
function browserReload() {
if (typeof location !== "undefined") location.reload();
}
function browserScrollTo(x, y) {
if (typeof window !== "undefined") window.scrollTo(x, y);
}
function browserMediaMatches(query) {
if (typeof window === "undefined") return false;
return window.matchMedia(query).matches;
}
function browserConfirm(msg) {
if (typeof window === "undefined") return false;
return window.confirm(msg);
}
function browserPrompt(msg) {
if (typeof window === "undefined") return NIL;
var r = window.prompt(msg);
return r === null ? NIL : r;
}
function csrfToken() {
if (!_hasDom) return NIL;
var m = document.querySelector('meta[name="csrf-token"]');
return m ? m.getAttribute("content") : NIL;
}
function isCrossOrigin(url) {
try {
var h = new URL(url, location.href).hostname;
return h !== location.hostname &&
(h.indexOf(".rose-ash.com") >= 0 || h.indexOf(".localhost") >= 0);
} catch (e) { return false; }
}
// --- Promises ---
function promiseResolve(val) { return Promise.resolve(val); }
function promiseCatch(p, fn) { return p && p.catch ? p.catch(fn) : p; }
// --- Abort controllers ---
var _controllers = typeof WeakMap !== "undefined" ? new WeakMap() : null;
function abortPrevious(el) {
if (_controllers) {
var prev = _controllers.get(el);
if (prev) prev.abort();
}
}
function trackController(el, ctrl) {
if (_controllers) _controllers.set(el, ctrl);
}
function newAbortController() {
return typeof AbortController !== "undefined" ? new AbortController() : { signal: null, abort: function() {} };
}
function controllerSignal(ctrl) { return ctrl ? ctrl.signal : null; }
function isAbortError(err) { return err && err.name === "AbortError"; }
// --- Timers ---
function setTimeout_(fn, ms) { return setTimeout(fn, ms || 0); }
function setInterval_(fn, ms) { return setInterval(fn, ms || 1000); }
function clearTimeout_(id) { clearTimeout(id); }
function requestAnimationFrame_(fn) {
if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(fn);
else setTimeout(fn, 16);
}
// --- Fetch ---
function fetchRequest(config, successFn, errorFn) {
var opts = { method: config.method, headers: config.headers };
if (config.signal) opts.signal = config.signal;
if (config.body && config.method !== "GET") opts.body = config.body;
if (config["cross-origin"]) opts.credentials = "include";
var p = (config.preloaded && config.preloaded !== NIL)
? Promise.resolve({
ok: true, status: 200,
headers: new Headers({ "Content-Type": config.preloaded["content-type"] || "" }),
text: function() { return Promise.resolve(config.preloaded.text); }
})
: fetch(config.url, opts);
return p.then(function(resp) {
return resp.text().then(function(text) {
var getHeader = function(name) {
var v = resp.headers.get(name);
return v === null ? NIL : v;
};
return successFn(resp.ok, resp.status, getHeader, text);
});
}).catch(function(err) {
return errorFn(err);
});
}
function fetchLocation(headerVal) {
if (!_hasDom) return;
var locUrl = headerVal;
try { var obj = JSON.parse(headerVal); locUrl = obj.path || obj; } catch (e) {}
fetch(locUrl, { headers: { "SX-Request": "true" } }).then(function(r) {
return r.text().then(function(t) {
var main = document.getElementById("main-panel");
if (main) {
main.innerHTML = t;
postSwap(main);
try { history.pushState({ sxUrl: locUrl }, "", locUrl); } catch (e) {}
}
});
});
}
function fetchAndRestore(main, url, headers, scrollY) {
var opts = { headers: headers };
try {
var h = new URL(url, location.href).hostname;
if (h !== location.hostname &&
(h.indexOf(".rose-ash.com") >= 0 || h.indexOf(".localhost") >= 0)) {
opts.credentials = "include";
}
} catch (e) {}
fetch(url, opts).then(function(resp) {
return resp.text().then(function(text) {
text = stripComponentScripts(text);
text = extractResponseCss(text);
text = text.trim();
if (text.charAt(0) === "(") {
try {
var dom = sxRender(text);
var container = document.createElement("div");
container.appendChild(dom);
processOobSwaps(container, function(t, oob, s) {
swapDomNodes(t, oob, s);
sxHydrate(t);
processElements(t);
});
var newMain = container.querySelector("#main-panel");
morphChildren(main, newMain || container);
postSwap(main);
if (typeof window !== "undefined") window.scrollTo(0, scrollY || 0);
} catch (err) {
console.error("sx-ref popstate error:", err);
location.reload();
}
} else {
var parser = new DOMParser();
var doc = parser.parseFromString(text, "text/html");
var newMain = doc.getElementById("main-panel");
if (newMain) {
morphChildren(main, newMain);
postSwap(main);
if (typeof window !== "undefined") window.scrollTo(0, scrollY || 0);
} else {
location.reload();
}
}
});
}).catch(function() { location.reload(); });
}
function fetchPreload(url, headers, cache) {
fetch(url, { headers: headers }).then(function(resp) {
if (!resp.ok) return;
var ct = resp.headers.get("Content-Type") || "";
return resp.text().then(function(text) {
preloadCacheSet(cache, url, text, ct);
});
}).catch(function() { /* ignore */ });
}
// --- Request body building ---
function buildRequestBody(el, method, url) {
if (!_hasDom) return { body: null, url: url, "content-type": NIL };
var body = null;
var ct = NIL;
var finalUrl = url;
var isJson = el.getAttribute("sx-encoding") === "json";
if (method !== "GET") {
var form = el.closest("form") || (el.tagName === "FORM" ? el : null);
if (form) {
if (isJson) {
var fd = new FormData(form);
var obj = {};
fd.forEach(function(v, k) {
if (obj[k] !== undefined) {
if (!Array.isArray(obj[k])) obj[k] = [obj[k]];
obj[k].push(v);
} else { obj[k] = v; }
});
body = JSON.stringify(obj);
ct = "application/json";
} else {
body = new URLSearchParams(new FormData(form));
ct = "application/x-www-form-urlencoded";
}
}
}
// sx-params
var paramsSpec = el.getAttribute("sx-params");
if (paramsSpec && body instanceof URLSearchParams) {
if (paramsSpec === "none") {
body = new URLSearchParams();
} else if (paramsSpec.indexOf("not ") === 0) {
paramsSpec.substring(4).split(",").forEach(function(k) { body.delete(k.trim()); });
} else if (paramsSpec !== "*") {
var allowed = paramsSpec.split(",").map(function(s) { return s.trim(); });
var filtered = new URLSearchParams();
allowed.forEach(function(k) {
body.getAll(k).forEach(function(v) { filtered.append(k, v); });
});
body = filtered;
}
}
// sx-include
var includeSel = el.getAttribute("sx-include");
if (includeSel && method !== "GET") {
if (!body) body = new URLSearchParams();
document.querySelectorAll(includeSel).forEach(function(inp) {
if (inp.name) body.append(inp.name, inp.value);
});
}
// sx-vals
var valsAttr = el.getAttribute("sx-vals");
if (valsAttr) {
try {
var vals = valsAttr.charAt(0) === "{" && valsAttr.charAt(1) === ":" ? parse(valsAttr) : JSON.parse(valsAttr);
if (method === "GET") {
for (var vk in vals) finalUrl += (finalUrl.indexOf("?") >= 0 ? "&" : "?") + encodeURIComponent(vk) + "=" + encodeURIComponent(vals[vk]);
} else if (body instanceof URLSearchParams) {
for (var vk2 in vals) body.append(vk2, vals[vk2]);
} else if (!body) {
body = new URLSearchParams();
for (var vk3 in vals) body.append(vk3, vals[vk3]);
ct = "application/x-www-form-urlencoded";
}
} catch (e) {}
}
// GET form data → URL
if (method === "GET") {
var form2 = el.closest("form") || (el.tagName === "FORM" ? el : null);
if (form2) {
var qs = new URLSearchParams(new FormData(form2)).toString();
if (qs) finalUrl += (finalUrl.indexOf("?") >= 0 ? "&" : "?") + qs;
}
if ((el.tagName === "INPUT" || el.tagName === "SELECT" || el.tagName === "TEXTAREA") && el.name) {
finalUrl += (finalUrl.indexOf("?") >= 0 ? "&" : "?") + encodeURIComponent(el.name) + "=" + encodeURIComponent(el.value);
}
}
return { body: body, url: finalUrl, "content-type": ct };
}
// --- Loading state ---
function showIndicator(el) {
if (!_hasDom) return NIL;
var sel = el.getAttribute("sx-indicator");
var ind = sel ? (document.querySelector(sel) || el.closest(sel)) : null;
if (ind) { ind.classList.add("sx-request"); ind.style.display = ""; }
return ind || NIL;
}
function disableElements(el) {
if (!_hasDom) return [];
var sel = el.getAttribute("sx-disabled-elt");
if (!sel) return [];
var elts = Array.prototype.slice.call(document.querySelectorAll(sel));
elts.forEach(function(e) { e.disabled = true; });
return elts;
}
function clearLoadingState(el, indicator, disabledElts) {
el.classList.remove("sx-request");
el.removeAttribute("aria-busy");
if (indicator && !isNil(indicator)) {
indicator.classList.remove("sx-request");
indicator.style.display = "none";
}
if (disabledElts) {
for (var i = 0; i < disabledElts.length; i++) disabledElts[i].disabled = false;
}
}
// --- DOM extras ---
function domQueryById(id) {
return _hasDom ? document.getElementById(id) : null;
}
function domMatches(el, sel) {
return el && el.matches ? el.matches(sel) : false;
}
function domClosest(el, sel) {
return el && el.closest ? el.closest(sel) : null;
}
function domBody() {
return _hasDom ? document.body : null;
}
function domHasClass(el, cls) {
return el && el.classList ? el.classList.contains(cls) : false;
}
function domAppendToHead(el) {
if (_hasDom && document.head) document.head.appendChild(el);
}
function domParseHtmlDocument(text) {
if (!_hasDom) return null;
return new DOMParser().parseFromString(text, "text/html");
}
function domOuterHtml(el) {
return el ? el.outerHTML : "";
}
function domBodyInnerHtml(doc) {
return doc && doc.body ? doc.body.innerHTML : "";
}
// --- Events ---
function preventDefault_(e) { if (e && e.preventDefault) e.preventDefault(); }
function elementValue(el) { return el && el.value !== undefined ? el.value : NIL; }
function domAddListener(el, event, fn, opts) {
if (!el || !el.addEventListener) return;
var o = {};
if (opts && !isNil(opts)) {
if (opts.once || opts["once"]) o.once = true;
}
el.addEventListener(event, function(e) {
try { fn(e); } catch (err) { logInfo("EVENT ERROR: " + event + " " + (err && err.message ? err.message : err)); console.error("[sx-ref] event handler error:", event, err); }
}, o);
}
// --- Validation ---
function validateForRequest(el) {
if (!_hasDom) return true;
var attr = el.getAttribute("sx-validate");
if (attr === null) {
var vForm = el.closest("[sx-validate]");
if (vForm) attr = vForm.getAttribute("sx-validate");
}
if (attr === null) return true; // no validation configured
var form = el.tagName === "FORM" ? el : el.closest("form");
if (form && !form.reportValidity()) return false;
if (attr && attr !== "true" && attr !== "") {
var fn = window[attr];
if (typeof fn === "function" && !fn(el)) return false;
}
return true;
}
// --- View Transitions ---
function withTransition(enabled, fn) {
if (enabled && _hasDom && document.startViewTransition) {
document.startViewTransition(fn);
} else {
fn();
}
}
// --- IntersectionObserver ---
function observeIntersection(el, fn, once, delay) {
if (!_hasDom || !("IntersectionObserver" in window)) { fn(); return; }
var fired = false;
var d = isNil(delay) ? 0 : delay;
var obs = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (!entry.isIntersecting) return;
if (once && fired) return;
fired = true;
if (once) obs.unobserve(el);
if (d) setTimeout(fn, d); else fn();
});
});
obs.observe(el);
}
// --- EventSource ---
function eventSourceConnect(url, el) {
var source = new EventSource(url);
source.addEventListener("error", function() { domDispatch(el, "sx:sseError", {}); });
source.addEventListener("open", function() { domDispatch(el, "sx:sseOpen", {}); });
if (typeof MutationObserver !== "undefined") {
var obs = new MutationObserver(function() {
if (!document.body.contains(el)) { source.close(); obs.disconnect(); }
});
obs.observe(document.body, { childList: true, subtree: true });
}
return source;
}
function eventSourceListen(source, event, fn) {
source.addEventListener(event, function(e) { fn(e.data); });
}
// --- Boost bindings ---
function bindBoostLink(el, href) {
el.addEventListener("click", function(e) {
e.preventDefault();
executeRequest(el, { method: "GET", url: href }).then(function() {
try { history.pushState({ sxUrl: href, scrollY: window.scrollY }, "", href); } catch (err) {}
});
});
}
function bindBoostForm(form, method, action) {
form.addEventListener("submit", function(e) {
e.preventDefault();
executeRequest(form, { method: method, url: action }).then(function() {
try { history.pushState({ sxUrl: action, scrollY: window.scrollY }, "", action); } catch (err) {}
});
});
}
// --- Client-side route bindings ---
function bindClientRouteClick(link, href, fallbackFn) {
link.addEventListener("click", function(e) {
e.preventDefault();
var pathname = urlPathname(href);
if (tryClientRoute(pathname)) {
try { history.pushState({ sxUrl: href, scrollY: window.scrollY }, "", href); } catch (err) {}
if (typeof window !== "undefined") window.scrollTo(0, 0);
} else {
logInfo("sx:route server " + pathname);
executeRequest(link, { method: "GET", url: href }).then(function() {
try { history.pushState({ sxUrl: href, scrollY: window.scrollY }, "", href); } catch (err) {}
});
}
});
}
function tryEvalContent(source, env) {
try {
var merged = merge(componentEnv);
if (env && !isNil(env)) {
var ks = Object.keys(env);
for (var i = 0; i < ks.length; i++) merged[ks[i]] = env[ks[i]];
}
return sxRenderWithEnv(source, merged);
} catch (e) {
logInfo("sx:route eval miss: " + (e && e.message ? e.message : e));
return NIL;
}
}
function resolvePageData(pageName, params, callback) {
// Platform implementation: fetch page data via HTTP from /sx/data/ endpoint.
// The spec only knows about resolve-page-data(name, params, callback) —
// this function provides the concrete transport.
var url = "/sx/data/" + encodeURIComponent(pageName);
if (params && !isNil(params)) {
var qs = [];
var ks = Object.keys(params);
for (var i = 0; i < ks.length; i++) {
var v = params[ks[i]];
if (v !== null && v !== undefined && v !== NIL) {
qs.push(encodeURIComponent(ks[i]) + "=" + encodeURIComponent(v));
}
}
if (qs.length) url += "?" + qs.join("&");
}
var headers = { "SX-Request": "true" };
fetch(url, { headers: headers }).then(function(resp) {
if (!resp.ok) {
logWarn("sx:data resolve failed " + resp.status + " for " + pageName);
return;
}
return resp.text().then(function(text) {
try {
var exprs = parse(text);
var data = exprs.length === 1 ? exprs[0] : {};
callback(data || {});
} catch (e) {
logWarn("sx:data parse error for " + pageName + ": " + (e && e.message ? e.message : e));
}
});
}).catch(function(err) {
logWarn("sx:data resolve error for " + pageName + ": " + (err && err.message ? err.message : err));
});
}
function urlPathname(href) {
try {
return new URL(href, location.href).pathname;
} catch (e) {
// Fallback: strip query/hash
var idx = href.indexOf("?");
if (idx >= 0) href = href.substring(0, idx);
idx = href.indexOf("#");
if (idx >= 0) href = href.substring(0, idx);
return href;
}
}
// --- Inline handlers ---
function bindInlineHandler(el, eventName, body) {
el.addEventListener(eventName, new Function("event", body));
}
// --- Preload binding ---
function bindPreload(el, events, debounceMs, fn) {
var timer = null;
events.forEach(function(evt) {
el.addEventListener(evt, function() {
if (debounceMs) {
clearTimeout(timer);
timer = setTimeout(fn, debounceMs);
} else {
fn();
}
});
});
}
// --- Processing markers ---
var PROCESSED = "_sxBound";
function markProcessed(el, key) { el[PROCESSED + key] = true; }
function isProcessed(el, key) { return !!el[PROCESSED + key]; }
// --- Script cloning ---
function createScriptClone(dead) {
var live = document.createElement("script");
for (var i = 0; i < dead.attributes.length; i++)
live.setAttribute(dead.attributes[i].name, dead.attributes[i].value);
live.textContent = dead.textContent;
return live;
}
// --- SX API references ---
function sxRender(source) {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
if (SxObj && SxObj.render) return SxObj.render(source);
throw new Error("No SX renderer available");
}
function sxProcessScripts(root) {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
var r = (root && root !== NIL) ? root : undefined;
if (SxObj && SxObj.processScripts) SxObj.processScripts(r);
}
function sxHydrate(root) {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
var r = (root && root !== NIL) ? root : undefined;
if (SxObj && SxObj.hydrate) SxObj.hydrate(r);
}
function loadedComponentNames() {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
if (!SxObj) return [];
var env = SxObj.componentEnv || (SxObj.getEnv ? SxObj.getEnv() : {});
return Object.keys(env).filter(function(k) { return k.charAt(0) === "~"; });
}
// --- Response processing ---
function stripComponentScripts(text) {
var SxObj = typeof Sx !== "undefined" ? Sx : null;
return text.replace(/<script[^>]*type="text\/sx"[^>]*data-components[^>]*>([\s\S]*?)<\/script>/gi,
function(_, defs) { if (SxObj && SxObj.loadComponents) SxObj.loadComponents(defs); return ""; });
}
function extractResponseCss(text) {
if (!_hasDom) return text;
var target = document.getElementById("sx-css");
if (!target) return text;
return text.replace(/<style[^>]*data-sx-css[^>]*>([\s\S]*?)<\/style>/gi,
function(_, css) { target.textContent += css; return ""; });
}
function selectFromContainer(container, sel) {
var frag = document.createDocumentFragment();
sel.split(",").forEach(function(s) {
container.querySelectorAll(s.trim()).forEach(function(m) { frag.appendChild(m); });
});
return frag;
}
function childrenToFragment(container) {
var frag = document.createDocumentFragment();
while (container.firstChild) frag.appendChild(container.firstChild);
return frag;
}
function selectHtmlFromDoc(doc, sel) {
var parts = sel.split(",").map(function(s) { return s.trim(); });
var frags = [];
parts.forEach(function(s) {
doc.querySelectorAll(s).forEach(function(m) { frags.push(m.outerHTML); });
});
return frags.join("");
}
// --- Parsing ---
function tryParseJson(s) {
if (!s) return NIL;
try { return JSON.parse(s); } catch (e) { return NIL; }
}
// =========================================================================
// Platform interface — CSSX (style dictionary)
// =========================================================================
function fnv1aHash(input) {
var h = 0x811c9dc5;
for (var i = 0; i < input.length; i++) {
h ^= input.charCodeAt(i);
h = (h * 0x01000193) >>> 0;
}
return h.toString(16).padStart(8, "0").substring(0, 6);
}
function compileRegex(pattern) {
try { return new RegExp(pattern); } catch (e) { return null; }
}
function regexMatch(re, s) {
if (!re) return NIL;
var m = s.match(re);
return m ? Array.prototype.slice.call(m) : NIL;
}
function regexReplaceGroups(tmpl, match) {
var result = tmpl;
for (var j = 1; j < match.length; j++) {
result = result.split("{" + (j - 1) + "}").join(match[j]);
}
return result;
}
function makeStyleValue_(cn, decls, media, pseudo, kf) {
return new StyleValue(cn, decls || "", media || [], pseudo || [], kf || []);
}
function styleValueDeclarations(sv) { return sv.declarations; }
function styleValueMediaRules(sv) { return sv.mediaRules; }
function styleValuePseudoRules(sv) { return sv.pseudoRules; }
function styleValueKeyframes_(sv) { return sv.keyframes; }
function injectStyleValue(sv, atoms) {
if (_injectedStyles[sv.className]) return;
_injectedStyles[sv.className] = true;
if (!_hasDom) return;
var cssTarget = document.getElementById("sx-css");
if (!cssTarget) return;
var rules = [];
// Child-selector atoms are now routed to pseudoRules by the resolver
// with selector ">:not(:first-child)", so base declarations are always
// applied directly to the class.
if (sv.declarations) {
rules.push("." + sv.className + "{" + sv.declarations + "}");
}
for (var pi = 0; pi < sv.pseudoRules.length; pi++) {
var sel = sv.pseudoRules[pi][0], decls = sv.pseudoRules[pi][1];
if (sel.indexOf("&") >= 0) {
rules.push(sel.replace(/&/g, "." + sv.className) + "{" + decls + "}");
} else {
rules.push("." + sv.className + sel + "{" + decls + "}");
}
}
for (var mi = 0; mi < sv.mediaRules.length; mi++) {
rules.push("@media " + sv.mediaRules[mi][0] + "{." + sv.className + "{" + sv.mediaRules[mi][1] + "}}");
}
for (var ki = 0; ki < sv.keyframes.length; ki++) {
rules.push(sv.keyframes[ki][1]);
}
cssTarget.textContent += rules.join("");
}
// Replace stub css primitive with real CSSX implementation
PRIMITIVES["css"] = function() {
var atoms = [];
for (var i = 0; i < arguments.length; i++) {
var a = arguments[i];
if (isNil(a) || a === false) continue;
atoms.push(isKw(a) ? a.name : String(a));
}
if (!atoms.length) return NIL;
return resolveStyle(atoms);
};
PRIMITIVES["merge-styles"] = function() {
var valid = [];
for (var i = 0; i < arguments.length; i++) {
if (isStyleValue(arguments[i])) valid.push(arguments[i]);
}
if (!valid.length) return NIL;
if (valid.length === 1) return valid[0];
return mergeStyleValues(valid);
};
// =========================================================================
// Platform interface — Boot (mount, hydrate, scripts, cookies)
// =========================================================================
function resolveMountTarget(target) {
if (typeof target === "string") return _hasDom ? document.querySelector(target) : null;
return target;
}
function sxRenderWithEnv(source, extraEnv) {
var env = extraEnv ? merge(componentEnv, extraEnv) : componentEnv;
var exprs = parse(source);
if (!_hasDom) return null;
var frag = document.createDocumentFragment();
for (var i = 0; i < exprs.length; i++) {
var node = renderToDom(exprs[i], env, null);
if (node) frag.appendChild(node);
}
return frag;
}
function getRenderEnv(extraEnv) {
return extraEnv ? merge(componentEnv, extraEnv) : componentEnv;
}
function mergeEnvs(base, newEnv) {
return newEnv ? merge(componentEnv, base, newEnv) : merge(componentEnv, base);
}
function sxLoadComponents(text) {
try {
var exprs = parse(text);
for (var i = 0; i < exprs.length; i++) trampoline(evalExpr(exprs[i], componentEnv));
} catch (err) {
logParseError("loadComponents", text, err);
throw err;
}
}
function setDocumentTitle(s) {
if (_hasDom) document.title = s || "";
}
function removeHeadElement(sel) {
if (!_hasDom) return;
var old = document.head.querySelector(sel);
if (old) old.parentNode.removeChild(old);
}
function querySxScripts(root) {
if (!_hasDom) return [];
var r = (root && root !== NIL) ? root : document;
return Array.prototype.slice.call(
r.querySelectorAll('script[type="text/sx"]'));
}
function queryStyleScripts() {
if (!_hasDom) return [];
return Array.prototype.slice.call(
document.querySelectorAll('script[type="text/sx-styles"]'));
}
function queryPageScripts() {
if (!_hasDom) return [];
return Array.prototype.slice.call(
document.querySelectorAll('script[type="text/sx-pages"]'));
}
// --- localStorage ---
function localStorageGet(key) {
try { var v = localStorage.getItem(key); return v === null ? NIL : v; }
catch (e) { return NIL; }
}
function localStorageSet(key, val) {
try { localStorage.setItem(key, val); } catch (e) {}
}
function localStorageRemove(key) {
try { localStorage.removeItem(key); } catch (e) {}
}
// --- Cookies ---
function setSxCompCookie(hash) {
if (_hasDom) document.cookie = "sx-comp-hash=" + hash + ";path=/;max-age=31536000;SameSite=Lax";
}
function clearSxCompCookie() {
if (_hasDom) document.cookie = "sx-comp-hash=;path=/;max-age=0;SameSite=Lax";
}
function setSxStylesCookie(hash) {
if (_hasDom) document.cookie = "sx-styles-hash=" + hash + ";path=/;max-age=31536000;SameSite=Lax";
}
function clearSxStylesCookie() {
if (_hasDom) document.cookie = "sx-styles-hash=;path=/;max-age=0;SameSite=Lax";
}
// --- Env helpers ---
function parseEnvAttr(el) {
var attr = el && el.getAttribute ? el.getAttribute("data-sx-env") : null;
if (!attr) return {};
try { return JSON.parse(attr); } catch (e) { return {}; }
}
function storeEnvAttr(el, base, newEnv) {
var merged = merge(base, newEnv);
if (el && el.setAttribute) el.setAttribute("data-sx-env", JSON.stringify(merged));
}
function toKebab(s) { return s.replace(/_/g, "-"); }
// --- Logging ---
function logInfo(msg) {
if (typeof console !== "undefined") console.log("[sx-ref] " + msg);
}
function logWarn(msg) {
if (typeof console !== "undefined") console.warn("[sx-ref] " + msg);
}
function logParseError(label, text, err) {
if (typeof console === "undefined") return;
var msg = err && err.message ? err.message : String(err);
var colMatch = msg.match(/col (\d+)/);
var lineMatch = msg.match(/line (\d+)/);
if (colMatch && text) {
var errLine = lineMatch ? parseInt(lineMatch[1]) : 1;
var errCol = parseInt(colMatch[1]);
var lines = text.split("\n");
var pos = 0;
for (var i = 0; i < errLine - 1 && i < lines.length; i++) pos += lines[i].length + 1;
pos += errCol;
var ws = 80;
var start = Math.max(0, pos - ws);
var end = Math.min(text.length, pos + ws);
console.error("[sx-ref] " + label + ":", msg,
"\n around error (pos ~" + pos + "):",
"\n \u00ab" + text.substring(start, pos) + "\u26d4" + text.substring(pos, end) + "\u00bb");
} else {
console.error("[sx-ref] " + label + ":", msg);
}
}
function parseAndLoadStyleDict(text) {
try { loadStyleDict(JSON.parse(text)); }
catch (e) { if (typeof console !== "undefined") console.warn("[sx-ref] style dict parse error", e); }
}
// =========================================================================
// Post-transpilation fixups
// =========================================================================
// The reference spec's call-lambda only handles Lambda objects, but HO forms
// (map, reduce, etc.) may receive native primitives. Wrap to handle both.
var _rawCallLambda = callLambda;
callLambda = function(f, args, callerEnv) {
if (typeof f === "function") return f.apply(null, args);
return _rawCallLambda(f, args, callerEnv);
};
// Expose render functions as primitives so SX code can call them
if (typeof renderToHtml === "function") PRIMITIVES["render-to-html"] = renderToHtml;
if (typeof renderToSx === "function") PRIMITIVES["render-to-sx"] = renderToSx;
if (typeof aser === "function") PRIMITIVES["aser"] = aser;
if (typeof renderToDom === "function") PRIMITIVES["render-to-dom"] = renderToDom;
// Parser — compiled from parser.sx (see PLATFORM_PARSER_JS for ident char classes)
var parse = sxParse;
// =========================================================================
// Public API
// =========================================================================
var componentEnv = {};
function loadComponents(source) {
var exprs = parse(source);
for (var i = 0; i < exprs.length; i++) {
trampoline(evalExpr(exprs[i], componentEnv));
}
}
function render(source) {
if (!_hasDom) {
var exprs = parse(source);
var parts = [];
for (var i = 0; i < exprs.length; i++) parts.push(renderToHtml(exprs[i], merge(componentEnv)));
return parts.join("");
}
var exprs = parse(source);
var frag = document.createDocumentFragment();
for (var i = 0; i < exprs.length; i++) frag.appendChild(renderToDom(exprs[i], merge(componentEnv), null));
return frag;
}
function renderToString(source) {
var exprs = parse(source);
var parts = [];
for (var i = 0; i < exprs.length; i++) parts.push(renderToHtml(exprs[i], merge(componentEnv)));
return parts.join("");
}
var Sx = {
VERSION: "ref-2.0",
parse: parse,
parseAll: parse,
eval: function(expr, env) { return trampoline(evalExpr(expr, env || merge(componentEnv))); },
loadComponents: loadComponents,
render: render,
renderToString: renderToString,
serialize: serialize,
NIL: NIL,
Symbol: Symbol,
Keyword: Keyword,
isTruthy: isSxTruthy,
isNil: isNil,
componentEnv: componentEnv,
renderToHtml: function(expr, env) { return renderToHtml(expr, env || merge(componentEnv)); },
renderToSx: function(expr, env) { return renderToSx(expr, env || merge(componentEnv)); },
renderToDom: _hasDom ? function(expr, env, ns) { return renderToDom(expr, env || merge(componentEnv), ns || null); } : null,
parseTriggerSpec: typeof parseTriggerSpec === "function" ? parseTriggerSpec : null,
morphNode: typeof morphNode === "function" ? morphNode : null,
morphChildren: typeof morphChildren === "function" ? morphChildren : null,
swapDomNodes: typeof swapDomNodes === "function" ? swapDomNodes : null,
process: typeof processElements === "function" ? processElements : null,
executeRequest: typeof executeRequest === "function" ? executeRequest : null,
postSwap: typeof postSwap === "function" ? postSwap : null,
processScripts: typeof processSxScripts === "function" ? processSxScripts : null,
mount: typeof sxMount === "function" ? sxMount : null,
hydrate: typeof sxHydrateElements === "function" ? sxHydrateElements : null,
update: typeof sxUpdateElement === "function" ? sxUpdateElement : null,
renderComponent: typeof sxRenderComponent === "function" ? sxRenderComponent : null,
getEnv: function() { return componentEnv; },
init: typeof bootInit === "function" ? bootInit : null,
splitPathSegments: splitPathSegments,
parseRoutePattern: parseRoutePattern,
matchRoute: matchRoute,
findMatchingRoute: findMatchingRoute,
_version: "ref-2.0 (boot+cssx+dom+engine+html+orchestration+parser+sx, bootstrap-compiled)"
};
// --- Popstate listener ---
if (typeof window !== "undefined") {
window.addEventListener("popstate", function(e) {
handlePopstate(e && e.state ? e.state.scrollY || 0 : 0);
});
}
// --- Auto-init ---
if (typeof document !== "undefined") {
var _sxInit = function() { bootInit(); };
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", _sxInit);
} else {
_sxInit();
}
}
if (typeof module !== "undefined" && module.exports) module.exports = Sx;
else global.Sx = Sx;
})(typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : this);