Rebuild sx-browser.js and OCaml sx_ref.ml
Regenerated from refactored spec: stdlib.sx library functions, evaluator decoupling, host FFI primitives. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
// =========================================================================
|
||||
|
||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||
var SX_VERSION = "2026-03-15T17:07:09Z";
|
||||
var SX_VERSION = "2026-03-16T09:43:09Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -581,10 +581,7 @@
|
||||
var dict_fn = PRIMITIVES["dict"];
|
||||
|
||||
// HTML rendering helpers
|
||||
function escapeHtml(s) {
|
||||
return String(s).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");
|
||||
}
|
||||
function escapeAttr(s) { return escapeHtml(s); }
|
||||
// escape-html and escape-attr are now library functions defined in render.sx
|
||||
function rawHtmlContent(r) { return r.html; }
|
||||
function makeRawHtml(s) { return { _raw: true, html: s }; }
|
||||
function sxExprSource(x) { return x && x.source ? x.source : String(x); }
|
||||
@@ -594,11 +591,93 @@
|
||||
function isSpecialForm(n) { return false; }
|
||||
function isHoForm(n) { return false; }
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Host FFI — the irreducible web platform primitives
|
||||
// All DOM/browser operations are built on these in web/lib/dom.sx
|
||||
// -----------------------------------------------------------------------
|
||||
PRIMITIVES["host-global"] = function(name) {
|
||||
if (typeof globalThis !== "undefined" && name in globalThis) return globalThis[name];
|
||||
if (typeof window !== "undefined" && name in window) return window[name];
|
||||
return NIL;
|
||||
};
|
||||
PRIMITIVES["host-get"] = function(obj, prop) {
|
||||
if (obj == null || obj === NIL) return NIL;
|
||||
var v = obj[prop];
|
||||
return v === undefined || v === null ? NIL : v;
|
||||
};
|
||||
PRIMITIVES["host-set!"] = function(obj, prop, val) {
|
||||
if (obj != null && obj !== NIL) obj[prop] = val === NIL ? null : val;
|
||||
};
|
||||
PRIMITIVES["host-call"] = function() {
|
||||
var obj = arguments[0], method = arguments[1];
|
||||
var args = [];
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var a = arguments[i];
|
||||
args.push(a === NIL ? null : a);
|
||||
}
|
||||
if (obj == null || obj === NIL) {
|
||||
// Global function call
|
||||
var fn = typeof globalThis !== "undefined" ? globalThis[method] : window[method];
|
||||
if (typeof fn === "function") return fn.apply(null, args);
|
||||
return NIL;
|
||||
}
|
||||
if (typeof obj[method] === "function") {
|
||||
try { return obj[method].apply(obj, args); }
|
||||
catch(e) { return NIL; }
|
||||
}
|
||||
return NIL;
|
||||
};
|
||||
PRIMITIVES["host-new"] = function() {
|
||||
var name = arguments[0];
|
||||
var args = Array.prototype.slice.call(arguments, 1).map(function(a) { return a === NIL ? null : a; });
|
||||
var Ctor = typeof globalThis !== "undefined" ? globalThis[name] : window[name];
|
||||
if (typeof Ctor !== "function") return NIL;
|
||||
// Support 0-4 args (covers all practical cases)
|
||||
switch (args.length) {
|
||||
case 0: return new Ctor();
|
||||
case 1: return new Ctor(args[0]);
|
||||
case 2: return new Ctor(args[0], args[1]);
|
||||
case 3: return new Ctor(args[0], args[1], args[2]);
|
||||
default: return new Ctor(args[0], args[1], args[2], args[3]);
|
||||
}
|
||||
};
|
||||
PRIMITIVES["host-callback"] = function(fn) {
|
||||
// Wrap SX function/lambda as a native JS callback
|
||||
if (typeof fn === "function") return fn;
|
||||
if (fn && fn._type === "lambda") {
|
||||
return function() {
|
||||
var a = Array.prototype.slice.call(arguments);
|
||||
return cekCall(fn, a);
|
||||
};
|
||||
}
|
||||
return function() {};
|
||||
};
|
||||
PRIMITIVES["host-typeof"] = function(obj) {
|
||||
if (obj == null || obj === NIL) return "nil";
|
||||
if (obj instanceof Element) return "element";
|
||||
if (obj instanceof Text) return "text";
|
||||
if (obj instanceof DocumentFragment) return "fragment";
|
||||
if (obj instanceof Document) return "document";
|
||||
if (obj instanceof Event) return "event";
|
||||
if (obj instanceof Promise) return "promise";
|
||||
if (obj instanceof AbortController) return "abort-controller";
|
||||
return typeof obj;
|
||||
};
|
||||
PRIMITIVES["host-await"] = function(promise, callback) {
|
||||
if (promise && typeof promise.then === "function") {
|
||||
var cb = typeof callback === "function" ? callback :
|
||||
(callback && callback._type === "lambda") ?
|
||||
function(v) { return cekCall(callback, [v]); } : function() {};
|
||||
promise.then(cb);
|
||||
}
|
||||
};
|
||||
|
||||
// processBindings and evalCond — now specced in render.sx, bootstrapped above
|
||||
|
||||
function isDefinitionForm(name) {
|
||||
return name === "define" || name === "defcomp" || name === "defmacro" ||
|
||||
name === "defstyle" || name === "defhandler";
|
||||
name === "defstyle" || name === "defhandler" ||
|
||||
name === "deftype" || name === "defeffect";
|
||||
}
|
||||
|
||||
function indexOf_(s, ch) {
|
||||
@@ -1009,6 +1088,22 @@ PRIMITIVES["scan"] = scan;
|
||||
return scan(kont, []); };
|
||||
PRIMITIVES["kont-capture-to-reactive-reset"] = kontCaptureToReactiveReset;
|
||||
|
||||
// *custom-special-forms*
|
||||
var _customSpecialForms = {};
|
||||
PRIMITIVES["*custom-special-forms*"] = _customSpecialForms;
|
||||
|
||||
// register-special-form!
|
||||
var registerSpecialForm = function(name, handler) { return dictSet(_customSpecialForms, name, handler); };
|
||||
PRIMITIVES["register-special-form!"] = registerSpecialForm;
|
||||
|
||||
// *render-check*
|
||||
var _renderCheck = NIL;
|
||||
PRIMITIVES["*render-check*"] = _renderCheck;
|
||||
|
||||
// *render-fn*
|
||||
var _renderFn = NIL;
|
||||
PRIMITIVES["*render-fn*"] = _renderFn;
|
||||
|
||||
// trampoline
|
||||
var trampoline = function(val) { return (function() {
|
||||
var result = val;
|
||||
@@ -1107,6 +1202,10 @@ PRIMITIVES["parse-keyword-args"] = parseKeywordArgs;
|
||||
var condScheme_p = function(clauses) { return isEvery(function(c) { return (isSxTruthy((typeOf(c) == "list")) && (len(c) == 2)); }, clauses); };
|
||||
PRIMITIVES["cond-scheme?"] = condScheme_p;
|
||||
|
||||
// is-else-clause?
|
||||
var isElseClause = function(test) { return sxOr((isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")), (isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else")))); };
|
||||
PRIMITIVES["is-else-clause?"] = isElseClause;
|
||||
|
||||
// sf-named-let
|
||||
var sfNamedLet = function(args, env) { return (function() {
|
||||
var loopName = symbolName(first(args));
|
||||
@@ -1247,58 +1346,6 @@ PRIMITIVES["sf-defmacro"] = sfDefmacro;
|
||||
})(); };
|
||||
PRIMITIVES["parse-macro-params"] = parseMacroParams;
|
||||
|
||||
// sf-defstyle
|
||||
var sfDefstyle = function(args, env) { return (function() {
|
||||
var nameSym = first(args);
|
||||
var value = trampoline(evalExpr(nth(args, 1), env));
|
||||
envBind(env, symbolName(nameSym), value);
|
||||
return value;
|
||||
})(); };
|
||||
PRIMITIVES["sf-defstyle"] = sfDefstyle;
|
||||
|
||||
// make-type-def
|
||||
var makeTypeDef = function(name, params, body) { return {"name": name, "params": params, "body": body}; };
|
||||
PRIMITIVES["make-type-def"] = makeTypeDef;
|
||||
|
||||
// normalize-type-body
|
||||
var normalizeTypeBody = function(body) { return (isSxTruthy(isNil(body)) ? "nil" : (isSxTruthy((typeOf(body) == "symbol")) ? symbolName(body) : (isSxTruthy((typeOf(body) == "string")) ? body : (isSxTruthy((typeOf(body) == "keyword")) ? keywordName(body) : (isSxTruthy((typeOf(body) == "dict")) ? mapDict(function(k, v) { return normalizeTypeBody(v); }, body) : (isSxTruthy((typeOf(body) == "list")) ? (isSxTruthy(isEmpty(body)) ? "any" : (function() {
|
||||
var head = first(body);
|
||||
return (function() {
|
||||
var headName = (isSxTruthy((typeOf(head) == "symbol")) ? symbolName(head) : (String(head)));
|
||||
return (isSxTruthy((headName == "union")) ? cons("or", map(normalizeTypeBody, rest(body))) : cons(headName, map(normalizeTypeBody, rest(body))));
|
||||
})();
|
||||
})()) : (String(body)))))))); };
|
||||
PRIMITIVES["normalize-type-body"] = normalizeTypeBody;
|
||||
|
||||
// sf-deftype
|
||||
var sfDeftype = function(args, env) { return (function() {
|
||||
var nameOrForm = first(args);
|
||||
var bodyExpr = nth(args, 1);
|
||||
var typeName = NIL;
|
||||
var typeParams = [];
|
||||
(isSxTruthy((typeOf(nameOrForm) == "symbol")) ? (typeName = symbolName(nameOrForm)) : (isSxTruthy((typeOf(nameOrForm) == "list")) ? ((typeName = symbolName(first(nameOrForm))), (typeParams = map(function(p) { return (isSxTruthy((typeOf(p) == "symbol")) ? symbolName(p) : (String(p))); }, rest(nameOrForm)))) : NIL));
|
||||
return (function() {
|
||||
var body = normalizeTypeBody(bodyExpr);
|
||||
var registry = (isSxTruthy(envHas(env, "*type-registry*")) ? envGet(env, "*type-registry*") : {});
|
||||
registry[typeName] = makeTypeDef(typeName, typeParams, body);
|
||||
envBind(env, "*type-registry*", registry);
|
||||
return NIL;
|
||||
})();
|
||||
})(); };
|
||||
PRIMITIVES["sf-deftype"] = sfDeftype;
|
||||
|
||||
// sf-defeffect
|
||||
var sfDefeffect = function(args, env) { return (function() {
|
||||
var effectName = (isSxTruthy((typeOf(first(args)) == "symbol")) ? symbolName(first(args)) : (String(first(args))));
|
||||
var registry = (isSxTruthy(envHas(env, "*effect-registry*")) ? envGet(env, "*effect-registry*") : []);
|
||||
if (isSxTruthy(!isSxTruthy(contains(registry, effectName)))) {
|
||||
registry.push(effectName);
|
||||
}
|
||||
envBind(env, "*effect-registry*", registry);
|
||||
return NIL;
|
||||
})(); };
|
||||
PRIMITIVES["sf-defeffect"] = sfDefeffect;
|
||||
|
||||
// qq-expand
|
||||
var qqExpand = function(template, env) { return (isSxTruthy(!isSxTruthy((typeOf(template) == "list"))) ? template : (isSxTruthy(isEmpty(template)) ? [] : (function() {
|
||||
var head = first(template);
|
||||
@@ -1425,10 +1472,10 @@ PRIMITIVES["step-eval"] = stepEval;
|
||||
var args = rest(expr);
|
||||
return (isSxTruthy(!isSxTruthy(sxOr((typeOf(head) == "symbol"), (typeOf(head) == "lambda"), (typeOf(head) == "list")))) ? (isSxTruthy(isEmpty(expr)) ? makeCekValue([], env, kont) : makeCekState(first(expr), env, kontPush(makeMapFrame(NIL, rest(expr), [], env), kont))) : (isSxTruthy((typeOf(head) == "symbol")) ? (function() {
|
||||
var name = symbolName(head);
|
||||
return (isSxTruthy((name == "if")) ? stepSfIf(args, env, kont) : (isSxTruthy((name == "when")) ? stepSfWhen(args, env, kont) : (isSxTruthy((name == "cond")) ? stepSfCond(args, env, kont) : (isSxTruthy((name == "case")) ? stepSfCase(args, env, kont) : (isSxTruthy((name == "and")) ? stepSfAnd(args, env, kont) : (isSxTruthy((name == "or")) ? stepSfOr(args, env, kont) : (isSxTruthy((name == "let")) ? stepSfLet(args, env, kont) : (isSxTruthy((name == "let*")) ? stepSfLet(args, env, kont) : (isSxTruthy((name == "lambda")) ? stepSfLambda(args, env, kont) : (isSxTruthy((name == "fn")) ? stepSfLambda(args, env, kont) : (isSxTruthy((name == "define")) ? stepSfDefine(args, env, kont) : (isSxTruthy((name == "defcomp")) ? makeCekValue(sfDefcomp(args, env), env, kont) : (isSxTruthy((name == "defisland")) ? makeCekValue(sfDefisland(args, env), env, kont) : (isSxTruthy((name == "defmacro")) ? makeCekValue(sfDefmacro(args, env), env, kont) : (isSxTruthy((name == "defstyle")) ? makeCekValue(sfDefstyle(args, env), env, kont) : (isSxTruthy((name == "defhandler")) ? makeCekValue(sfDefhandler(args, env), env, kont) : (isSxTruthy((name == "defpage")) ? makeCekValue(sfDefpage(args, env), env, kont) : (isSxTruthy((name == "defquery")) ? makeCekValue(sfDefquery(args, env), env, kont) : (isSxTruthy((name == "defaction")) ? makeCekValue(sfDefaction(args, env), env, kont) : (isSxTruthy((name == "deftype")) ? makeCekValue(sfDeftype(args, env), env, kont) : (isSxTruthy((name == "defeffect")) ? makeCekValue(sfDefeffect(args, env), env, kont) : (isSxTruthy((name == "begin")) ? stepSfBegin(args, env, kont) : (isSxTruthy((name == "do")) ? stepSfBegin(args, env, kont) : (isSxTruthy((name == "quote")) ? makeCekValue((isSxTruthy(isEmpty(args)) ? NIL : first(args)), env, kont) : (isSxTruthy((name == "quasiquote")) ? makeCekValue(qqExpand(first(args), env), env, kont) : (isSxTruthy((name == "->")) ? stepSfThreadFirst(args, env, kont) : (isSxTruthy((name == "set!")) ? stepSfSet(args, env, kont) : (isSxTruthy((name == "letrec")) ? makeCekValue(sfLetrec(args, env), env, kont) : (isSxTruthy((name == "reset")) ? stepSfReset(args, env, kont) : (isSxTruthy((name == "shift")) ? stepSfShift(args, env, kont) : (isSxTruthy((name == "deref")) ? stepSfDeref(args, env, kont) : (isSxTruthy((name == "scope")) ? stepSfScope(args, env, kont) : (isSxTruthy((name == "provide")) ? stepSfProvide(args, env, kont) : (isSxTruthy((name == "context")) ? stepSfContext(args, env, kont) : (isSxTruthy((name == "emit!")) ? stepSfEmit(args, env, kont) : (isSxTruthy((name == "emitted")) ? stepSfEmitted(args, env, kont) : (isSxTruthy((name == "dynamic-wind")) ? makeCekValue(sfDynamicWind(args, env), env, kont) : (isSxTruthy((name == "map")) ? stepHoMap(args, env, kont) : (isSxTruthy((name == "map-indexed")) ? stepHoMapIndexed(args, env, kont) : (isSxTruthy((name == "filter")) ? stepHoFilter(args, env, kont) : (isSxTruthy((name == "reduce")) ? stepHoReduce(args, env, kont) : (isSxTruthy((name == "some")) ? stepHoSome(args, env, kont) : (isSxTruthy((name == "every?")) ? stepHoEvery(args, env, kont) : (isSxTruthy((name == "for-each")) ? stepHoForEach(args, env, kont) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? (function() {
|
||||
return (isSxTruthy((name == "if")) ? stepSfIf(args, env, kont) : (isSxTruthy((name == "when")) ? stepSfWhen(args, env, kont) : (isSxTruthy((name == "cond")) ? stepSfCond(args, env, kont) : (isSxTruthy((name == "case")) ? stepSfCase(args, env, kont) : (isSxTruthy((name == "and")) ? stepSfAnd(args, env, kont) : (isSxTruthy((name == "or")) ? stepSfOr(args, env, kont) : (isSxTruthy((name == "let")) ? stepSfLet(args, env, kont) : (isSxTruthy((name == "let*")) ? stepSfLet(args, env, kont) : (isSxTruthy((name == "lambda")) ? stepSfLambda(args, env, kont) : (isSxTruthy((name == "fn")) ? stepSfLambda(args, env, kont) : (isSxTruthy((name == "define")) ? stepSfDefine(args, env, kont) : (isSxTruthy((name == "defcomp")) ? makeCekValue(sfDefcomp(args, env), env, kont) : (isSxTruthy((name == "defisland")) ? makeCekValue(sfDefisland(args, env), env, kont) : (isSxTruthy((name == "defmacro")) ? makeCekValue(sfDefmacro(args, env), env, kont) : (isSxTruthy((name == "begin")) ? stepSfBegin(args, env, kont) : (isSxTruthy((name == "do")) ? stepSfBegin(args, env, kont) : (isSxTruthy((name == "quote")) ? makeCekValue((isSxTruthy(isEmpty(args)) ? NIL : first(args)), env, kont) : (isSxTruthy((name == "quasiquote")) ? makeCekValue(qqExpand(first(args), env), env, kont) : (isSxTruthy((name == "->")) ? stepSfThreadFirst(args, env, kont) : (isSxTruthy((name == "set!")) ? stepSfSet(args, env, kont) : (isSxTruthy((name == "letrec")) ? makeCekValue(sfLetrec(args, env), env, kont) : (isSxTruthy((name == "reset")) ? stepSfReset(args, env, kont) : (isSxTruthy((name == "shift")) ? stepSfShift(args, env, kont) : (isSxTruthy((name == "deref")) ? stepSfDeref(args, env, kont) : (isSxTruthy((name == "scope")) ? stepSfScope(args, env, kont) : (isSxTruthy((name == "provide")) ? stepSfProvide(args, env, kont) : (isSxTruthy((name == "context")) ? stepSfContext(args, env, kont) : (isSxTruthy((name == "emit!")) ? stepSfEmit(args, env, kont) : (isSxTruthy((name == "emitted")) ? stepSfEmitted(args, env, kont) : (isSxTruthy((name == "dynamic-wind")) ? makeCekValue(sfDynamicWind(args, env), env, kont) : (isSxTruthy((name == "map")) ? stepHoMap(args, env, kont) : (isSxTruthy((name == "map-indexed")) ? stepHoMapIndexed(args, env, kont) : (isSxTruthy((name == "filter")) ? stepHoFilter(args, env, kont) : (isSxTruthy((name == "reduce")) ? stepHoReduce(args, env, kont) : (isSxTruthy((name == "some")) ? stepHoSome(args, env, kont) : (isSxTruthy((name == "every?")) ? stepHoEvery(args, env, kont) : (isSxTruthy((name == "for-each")) ? stepHoForEach(args, env, kont) : (isSxTruthy(dictHas(_customSpecialForms, name)) ? makeCekValue([get(_customSpecialForms, name), args, env], env, kont) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? (function() {
|
||||
var mac = envGet(env, name);
|
||||
return makeCekState(expandMacro(mac, args, env), env, kont);
|
||||
})() : (isSxTruthy((isSxTruthy(renderActiveP()) && isRenderExpr(expr))) ? makeCekValue(renderExpr(expr, env), env, kont) : stepEvalCall(head, args, env, kont)))))))))))))))))))))))))))))))))))))))))))))));
|
||||
})() : (isSxTruthy((isSxTruthy(_renderCheck) && _renderCheck(expr, env))) ? makeCekValue(_renderFn(expr, env), env, kont) : stepEvalCall(head, args, env, kont)))))))))))))))))))))))))))))))))))))))));
|
||||
})() : stepEvalCall(head, args, env, kont)));
|
||||
})(); };
|
||||
PRIMITIVES["step-eval-list"] = stepEvalList;
|
||||
@@ -1493,10 +1540,10 @@ PRIMITIVES["step-sf-or"] = stepSfOr;
|
||||
return (isSxTruthy(scheme_p) ? (isSxTruthy(isEmpty(args)) ? makeCekValue(NIL, env, kont) : (function() {
|
||||
var clause = first(args);
|
||||
var test = first(clause);
|
||||
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))), (isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")))) ? makeCekState(nth(clause, 1), env, kont) : makeCekState(test, env, kontPush(makeCondFrame(args, env, true), kont)));
|
||||
return (isSxTruthy(isElseClause(test)) ? makeCekState(nth(clause, 1), env, kont) : makeCekState(test, env, kontPush(makeCondFrame(args, env, true), kont)));
|
||||
})()) : (isSxTruthy((len(args) < 2)) ? makeCekValue(NIL, env, kont) : (function() {
|
||||
var test = first(args);
|
||||
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")), (isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))))) ? makeCekState(nth(args, 1), env, kont) : makeCekState(test, env, kontPush(makeCondFrame(args, env, false), kont)));
|
||||
return (isSxTruthy(isElseClause(test)) ? makeCekState(nth(args, 1), env, kont) : makeCekState(test, env, kontPush(makeCondFrame(args, env, false), kont)));
|
||||
})()));
|
||||
})(); };
|
||||
PRIMITIVES["step-sf-cond"] = stepSfCond;
|
||||
@@ -1774,13 +1821,13 @@ PRIMITIVES["step-ho-for-each"] = stepHoForEach;
|
||||
return (isSxTruthy(isEmpty(nextClauses)) ? makeCekValue(NIL, fenv, restK) : (function() {
|
||||
var nextClause = first(nextClauses);
|
||||
var nextTest = first(nextClause);
|
||||
return (isSxTruthy(sxOr((isSxTruthy((typeOf(nextTest) == "symbol")) && sxOr((symbolName(nextTest) == "else"), (symbolName(nextTest) == ":else"))), (isSxTruthy((typeOf(nextTest) == "keyword")) && (keywordName(nextTest) == "else")))) ? makeCekState(nth(nextClause, 1), fenv, restK) : makeCekState(nextTest, fenv, kontPush(makeCondFrame(nextClauses, fenv, true), restK)));
|
||||
return (isSxTruthy(isElseClause(nextTest)) ? makeCekState(nth(nextClause, 1), fenv, restK) : makeCekState(nextTest, fenv, kontPush(makeCondFrame(nextClauses, fenv, true), restK)));
|
||||
})());
|
||||
})()) : (isSxTruthy(value) ? makeCekState(nth(remaining, 1), fenv, restK) : (function() {
|
||||
var next = slice(remaining, 2);
|
||||
return (isSxTruthy((len(next) < 2)) ? makeCekValue(NIL, fenv, restK) : (function() {
|
||||
var nextTest = first(next);
|
||||
return (isSxTruthy(sxOr((isSxTruthy((typeOf(nextTest) == "keyword")) && (keywordName(nextTest) == "else")), (isSxTruthy((typeOf(nextTest) == "symbol")) && sxOr((symbolName(nextTest) == "else"), (symbolName(nextTest) == ":else"))))) ? makeCekState(nth(next, 1), fenv, restK) : makeCekState(nextTest, fenv, kontPush(makeCondFrame(next, fenv, false), restK)));
|
||||
return (isSxTruthy(isElseClause(nextTest)) ? makeCekState(nth(next, 1), fenv, restK) : makeCekState(nextTest, fenv, kontPush(makeCondFrame(next, fenv, false), restK)));
|
||||
})());
|
||||
})()));
|
||||
})() : (isSxTruthy((ft == "case")) ? (function() {
|
||||
@@ -1957,7 +2004,7 @@ PRIMITIVES["continue-with-call"] = continueWithCall;
|
||||
var sfCaseStepLoop = function(matchVal, clauses, env, kont) { return (isSxTruthy((len(clauses) < 2)) ? makeCekValue(NIL, env, kont) : (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"))))) ? makeCekState(body, env, kont) : (function() {
|
||||
return (isSxTruthy(isElseClause(test)) ? makeCekState(body, env, kont) : (function() {
|
||||
var testVal = trampoline(evalExpr(test, env));
|
||||
return (isSxTruthy((matchVal == testVal)) ? makeCekState(body, env, kont) : sfCaseStepLoop(matchVal, slice(clauses, 2), env, kont));
|
||||
})());
|
||||
@@ -1972,6 +2019,353 @@ PRIMITIVES["eval-expr-cek"] = evalExprCek;
|
||||
var trampolineCek = function(val) { return (isSxTruthy(isThunk(val)) ? evalExprCek(thunkExpr(val), thunkEnv(val)) : val); };
|
||||
PRIMITIVES["trampoline-cek"] = trampolineCek;
|
||||
|
||||
// eval-expr
|
||||
var evalExpr = function(expr, env) { return cekRun(makeCekState(expr, env, [])); };
|
||||
PRIMITIVES["eval-expr"] = evalExpr;
|
||||
|
||||
// trampoline
|
||||
var trampoline = function(val) { return (isSxTruthy(isThunk(val)) ? evalExpr(thunkExpr(val), thunkEnv(val)) : val); };
|
||||
PRIMITIVES["trampoline"] = trampoline;
|
||||
|
||||
|
||||
// === Transpiled from stdlib (library functions from former primitives) ===
|
||||
|
||||
// not
|
||||
var not = function(x) { return (isSxTruthy(x) ? false : true); };
|
||||
PRIMITIVES["not"] = not;
|
||||
|
||||
// !=
|
||||
var != = function(a, b) { return !isSxTruthy((a == b)); };
|
||||
PRIMITIVES["!="] = !=;
|
||||
|
||||
// <=
|
||||
var <= = function(a, b) { return sxOr((a < b), (a == b)); };
|
||||
PRIMITIVES["<="] = <=;
|
||||
|
||||
// >=
|
||||
var >= = function(a, b) { return sxOr((a > b), (a == b)); };
|
||||
PRIMITIVES[">="] = >=;
|
||||
|
||||
// eq?
|
||||
var eq_p = =;
|
||||
PRIMITIVES["eq?"] = eq_p;
|
||||
|
||||
// eqv?
|
||||
var eqv_p = =;
|
||||
PRIMITIVES["eqv?"] = eqv_p;
|
||||
|
||||
// equal?
|
||||
var equal_p = =;
|
||||
PRIMITIVES["equal?"] = equal_p;
|
||||
|
||||
// nil?
|
||||
var isNil = function(x) { return (typeOf(x) == "nil"); };
|
||||
PRIMITIVES["nil?"] = isNil;
|
||||
|
||||
// boolean?
|
||||
var boolean_p = function(x) { return (typeOf(x) == "boolean"); };
|
||||
PRIMITIVES["boolean?"] = boolean_p;
|
||||
|
||||
// number?
|
||||
var isNumber = function(x) { return (typeOf(x) == "number"); };
|
||||
PRIMITIVES["number?"] = isNumber;
|
||||
|
||||
// string?
|
||||
var isString = function(x) { return (typeOf(x) == "string"); };
|
||||
PRIMITIVES["string?"] = isString;
|
||||
|
||||
// list?
|
||||
var isList = function(x) { return (typeOf(x) == "list"); };
|
||||
PRIMITIVES["list?"] = isList;
|
||||
|
||||
// dict?
|
||||
var isDict = function(x) { return (typeOf(x) == "dict"); };
|
||||
PRIMITIVES["dict?"] = isDict;
|
||||
|
||||
// continuation?
|
||||
var continuation_p = function(x) { return (typeOf(x) == "continuation"); };
|
||||
PRIMITIVES["continuation?"] = continuation_p;
|
||||
|
||||
// zero?
|
||||
var isZero = function(n) { return (n == 0); };
|
||||
PRIMITIVES["zero?"] = isZero;
|
||||
|
||||
// odd?
|
||||
var isOdd = function(n) { return ((n % 2) == 1); };
|
||||
PRIMITIVES["odd?"] = isOdd;
|
||||
|
||||
// even?
|
||||
var isEven = function(n) { return ((n % 2) == 0); };
|
||||
PRIMITIVES["even?"] = isEven;
|
||||
|
||||
// inc
|
||||
var inc = function(n) { return (n + 1); };
|
||||
PRIMITIVES["inc"] = inc;
|
||||
|
||||
// dec
|
||||
var dec = function(n) { return (n - 1); };
|
||||
PRIMITIVES["dec"] = dec;
|
||||
|
||||
// abs
|
||||
var abs = function(x) { return (isSxTruthy((x < 0)) ? (-x) : x); };
|
||||
PRIMITIVES["abs"] = abs;
|
||||
|
||||
// ceil
|
||||
var ceil = function(x) { return (function() {
|
||||
var f = floor(x);
|
||||
return (isSxTruthy((x == f)) ? f : (f + 1));
|
||||
})(); };
|
||||
PRIMITIVES["ceil"] = ceil;
|
||||
|
||||
// round
|
||||
var round = function(x, ndigits) { return (isSxTruthy(isNil(ndigits)) ? floor((x + 0.5)) : (function() {
|
||||
var f = pow(10, ndigits);
|
||||
return (floor(((x * f) + 0.5)) / f);
|
||||
})()); };
|
||||
PRIMITIVES["round"] = round;
|
||||
|
||||
// min
|
||||
var min = function(a, b) { return (isSxTruthy((a < b)) ? a : b); };
|
||||
PRIMITIVES["min"] = min;
|
||||
|
||||
// max
|
||||
var max = function(a, b) { return (isSxTruthy((a > b)) ? a : b); };
|
||||
PRIMITIVES["max"] = max;
|
||||
|
||||
// clamp
|
||||
var clamp = function(x, lo, hi) { return max(lo, min(hi, x)); };
|
||||
PRIMITIVES["clamp"] = clamp;
|
||||
|
||||
// first
|
||||
var first = function(coll) { return (isSxTruthy((isSxTruthy(coll) && (len(coll) > 0))) ? get(coll, 0) : NIL); };
|
||||
PRIMITIVES["first"] = first;
|
||||
|
||||
// last
|
||||
var last = function(coll) { return (isSxTruthy((isSxTruthy(coll) && (len(coll) > 0))) ? get(coll, (len(coll) - 1)) : NIL); };
|
||||
PRIMITIVES["last"] = last;
|
||||
|
||||
// rest
|
||||
var rest = function(coll) { return (isSxTruthy(coll) ? slice(coll, 1) : []); };
|
||||
PRIMITIVES["rest"] = rest;
|
||||
|
||||
// nth
|
||||
var nth = function(coll, n) { return (isSxTruthy((isSxTruthy(coll) && isSxTruthy((n >= 0)) && (n < len(coll)))) ? get(coll, n) : NIL); };
|
||||
PRIMITIVES["nth"] = nth;
|
||||
|
||||
// empty?
|
||||
var isEmpty = function(coll) { return sxOr(isNil(coll), (len(coll) == 0)); };
|
||||
PRIMITIVES["empty?"] = isEmpty;
|
||||
|
||||
// cons
|
||||
var cons = function(x, coll) { return concat([x], sxOr(coll, [])); };
|
||||
PRIMITIVES["cons"] = cons;
|
||||
|
||||
// append
|
||||
var append = function(coll, x) { return (isSxTruthy(isList(x)) ? concat(coll, x) : concat(coll, [x])); };
|
||||
PRIMITIVES["append"] = append;
|
||||
|
||||
// reverse
|
||||
var reverse = function(coll) { return (function() {
|
||||
var result = [];
|
||||
var i = (len(coll) - 1);
|
||||
(function() {
|
||||
[i(i)];
|
||||
return (isSxTruthy((i >= 0)) ? (append_b(result, get(coll, i)), loop((i - 1))) : NIL);
|
||||
})();
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["reverse"] = reverse;
|
||||
|
||||
// flatten
|
||||
var flatten = function(coll) { return (function() {
|
||||
var result = [];
|
||||
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var x = _c[_i]; (isSxTruthy(isList(x)) ? forEach(function(y) { return append_b(result, y); }, x) : append_b(result, x)); } }
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["flatten"] = flatten;
|
||||
|
||||
// range
|
||||
var range = function(start, end, step) { return (function() {
|
||||
var s = (isSxTruthy(isNil(step)) ? 1 : step);
|
||||
var result = [];
|
||||
(function() {
|
||||
[i(start)];
|
||||
return (isSxTruthy((i < end)) ? (append_b(result, i), loop((i + s))) : NIL);
|
||||
})();
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["range"] = range;
|
||||
|
||||
// chunk-every
|
||||
var chunkEvery = function(coll, n) { return (function() {
|
||||
var result = [];
|
||||
var clen = len(coll);
|
||||
(function() {
|
||||
[i(0)];
|
||||
return (isSxTruthy((i < clen)) ? (append_b(result, slice(coll, i, min((i + n), clen))), loop((i + n))) : NIL);
|
||||
})();
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["chunk-every"] = chunkEvery;
|
||||
|
||||
// zip-pairs
|
||||
var zipPairs = function(coll) { return (function() {
|
||||
var result = [];
|
||||
var clen = len(coll);
|
||||
(function() {
|
||||
[i(0)];
|
||||
return (isSxTruthy((i < (clen - 1))) ? (append_b(result, [get(coll, i), get(coll, (i + 1))]), loop((i + 1))) : NIL);
|
||||
})();
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["zip-pairs"] = zipPairs;
|
||||
|
||||
// vals
|
||||
var vals = function(d) { return (function() {
|
||||
var result = [];
|
||||
{ var _c = keys(d); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; result.push(get(d, k)); } }
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["vals"] = vals;
|
||||
|
||||
// has-key?
|
||||
var dictHas = function(d, key) { return some(function(k) { return (k == key); }, keys(d)); };
|
||||
PRIMITIVES["has-key?"] = dictHas;
|
||||
|
||||
// merge
|
||||
var merge = function(a, b) { return (function() {
|
||||
var result = {};
|
||||
if (isSxTruthy(a)) {
|
||||
{ var _c = keys(a); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; result[k] = get(a, k); } }
|
||||
}
|
||||
if (isSxTruthy(b)) {
|
||||
{ var _c = keys(b); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; result[k] = get(b, k); } }
|
||||
}
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["merge"] = merge;
|
||||
|
||||
// assoc
|
||||
var assoc = function(d, key, val) { return (function() {
|
||||
var result = {};
|
||||
if (isSxTruthy(d)) {
|
||||
{ var _c = keys(d); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; result[k] = get(d, k); } }
|
||||
}
|
||||
result[key] = val;
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["assoc"] = assoc;
|
||||
|
||||
// dissoc
|
||||
var dissoc = function(d, key) { return (function() {
|
||||
var result = {};
|
||||
{ var _c = keys(d); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; if (isSxTruthy((k != key))) {
|
||||
result[k] = get(d, k);
|
||||
} } }
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["dissoc"] = dissoc;
|
||||
|
||||
// into
|
||||
var into = function(target, coll) { return (isSxTruthy(isList(target)) ? (isSxTruthy(isList(coll)) ? concat(coll, []) : (function() {
|
||||
var result = [];
|
||||
{ var _c = keys(coll); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; result.push([k, get(coll, k)]); } }
|
||||
return result;
|
||||
})()) : (isSxTruthy(isDict(target)) ? (function() {
|
||||
var result = {};
|
||||
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; if (isSxTruthy((isSxTruthy(isList(pair)) && (len(pair) >= 2)))) {
|
||||
result[get(pair, 0)] = get(pair, 1);
|
||||
} } }
|
||||
return result;
|
||||
})() : target)); };
|
||||
PRIMITIVES["into"] = into;
|
||||
|
||||
// upcase
|
||||
var upcase = upper;
|
||||
PRIMITIVES["upcase"] = upcase;
|
||||
|
||||
// downcase
|
||||
var downcase = lower;
|
||||
PRIMITIVES["downcase"] = downcase;
|
||||
|
||||
// string-length
|
||||
var stringLength = function(s) { return len(s); };
|
||||
PRIMITIVES["string-length"] = stringLength;
|
||||
|
||||
// substring
|
||||
var substring = function(s, start, end) { return slice(s, start, end); };
|
||||
PRIMITIVES["substring"] = substring;
|
||||
|
||||
// string-contains?
|
||||
var stringContains_p = function(s, needle) { return (indexOf_(s, needle) != -1); };
|
||||
PRIMITIVES["string-contains?"] = stringContains_p;
|
||||
|
||||
// starts-with?
|
||||
var startsWith = function(s, prefix) { return (indexOf_(s, prefix) == 0); };
|
||||
PRIMITIVES["starts-with?"] = startsWith;
|
||||
|
||||
// ends-with?
|
||||
var endsWith = function(s, suffix) { return (function() {
|
||||
var slen = len(s);
|
||||
var plen = len(suffix);
|
||||
return (isSxTruthy((slen < plen)) ? false : (slice(s, (slen - plen)) == suffix));
|
||||
})(); };
|
||||
PRIMITIVES["ends-with?"] = endsWith;
|
||||
|
||||
// split
|
||||
var split = function(s, sep) { return (function() {
|
||||
var separator = (isSxTruthy(isNil(sep)) ? " " : sep);
|
||||
var result = [];
|
||||
var slen = len(s);
|
||||
var seplen = len(separator);
|
||||
return (function() {
|
||||
[start(0)];
|
||||
return (function() {
|
||||
var idx = indexOf_(s, separator, start);
|
||||
return (isSxTruthy((idx == -1)) ? (append_b(result, slice(s, start)), result) : (append_b(result, slice(s, start, idx)), loop((idx + seplen))));
|
||||
})();
|
||||
})();
|
||||
})(); };
|
||||
PRIMITIVES["split"] = split;
|
||||
|
||||
// join
|
||||
var join = function(sep, coll) { return (function() {
|
||||
var result = "";
|
||||
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var x = _c[_i]; result = (isSxTruthy((result == "")) ? (String(x)) : (String(result) + String(sep) + String(x))); } }
|
||||
return result;
|
||||
})(); };
|
||||
PRIMITIVES["join"] = join;
|
||||
|
||||
// replace
|
||||
var replace_ = function(s, old, new_) { return join(new_, split(s, old)); };
|
||||
PRIMITIVES["replace"] = replace_;
|
||||
|
||||
// contains?
|
||||
var contains = function(coll, key) { return (isSxTruthy(isString(coll)) ? (indexOf_(coll, (String(key))) != -1) : (isSxTruthy(isDict(coll)) ? dictHas(coll, key) : (isSxTruthy(isList(coll)) ? some(function(x) { return (x == key); }, coll) : false))); };
|
||||
PRIMITIVES["contains?"] = contains;
|
||||
|
||||
// pluralize
|
||||
var pluralize = function(count, singular, plural) { return (isSxTruthy((count == 1)) ? sxOr(singular, "") : sxOr(plural, "s")); };
|
||||
PRIMITIVES["pluralize"] = pluralize;
|
||||
|
||||
// escape
|
||||
var escape = function(s) { return >((String(s)), replace_("&", "&"), replace_("<", "<"), replace_(">", ">"), replace_("\"", """), replace_("'", "'")); };
|
||||
PRIMITIVES["escape"] = escape;
|
||||
|
||||
// parse-datetime
|
||||
var parseDatetime = function(s) { return (isSxTruthy(s) ? (String(s)) : NIL); };
|
||||
PRIMITIVES["parse-datetime"] = parseDatetime;
|
||||
|
||||
// assert
|
||||
var assert = function(condition, message) { if (isSxTruthy(!isSxTruthy(condition))) {
|
||||
error(sxOr(message, "Assertion failed"));
|
||||
}
|
||||
return true; };
|
||||
PRIMITIVES["assert"] = assert;
|
||||
|
||||
|
||||
// === Transpiled from freeze (serializable state boundaries) ===
|
||||
|
||||
// freeze-registry
|
||||
var freezeRegistry = {};
|
||||
PRIMITIVES["freeze-registry"] = freezeRegistry;
|
||||
@@ -2039,6 +2433,9 @@ PRIMITIVES["freeze-to-sx"] = freezeToSx;
|
||||
})(); };
|
||||
PRIMITIVES["thaw-from-sx"] = thawFromSx;
|
||||
|
||||
|
||||
// === Transpiled from content (content-addressed computation) ===
|
||||
|
||||
// content-store
|
||||
var contentStore = {};
|
||||
PRIMITIVES["content-store"] = contentStore;
|
||||
@@ -2077,14 +2474,6 @@ PRIMITIVES["freeze-to-cid"] = freezeToCid;
|
||||
})(); };
|
||||
PRIMITIVES["thaw-from-cid"] = thawFromCid;
|
||||
|
||||
// eval-expr
|
||||
var evalExpr = function(expr, env) { return cekRun(makeCekState(expr, env, [])); };
|
||||
PRIMITIVES["eval-expr"] = evalExpr;
|
||||
|
||||
// trampoline
|
||||
var trampoline = function(val) { return (isSxTruthy(isThunk(val)) ? evalExpr(thunkExpr(val), thunkEnv(val)) : val); };
|
||||
PRIMITIVES["trampoline"] = trampoline;
|
||||
|
||||
|
||||
// === Transpiled from render (core) ===
|
||||
|
||||
@@ -2136,7 +2525,7 @@ PRIMITIVES["eval-cond"] = evalCond;
|
||||
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)));
|
||||
return (isSxTruthy(isElseClause(test)) ? body : (isSxTruthy(trampoline(evalExpr(test, env))) ? body : evalCondScheme(rest(clauses), env)));
|
||||
})()); };
|
||||
PRIMITIVES["eval-cond-scheme"] = evalCondScheme;
|
||||
|
||||
@@ -2144,7 +2533,7 @@ PRIMITIVES["eval-cond-scheme"] = evalCondScheme;
|
||||
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)));
|
||||
return (isSxTruthy(isElseClause(test)) ? body : (isSxTruthy(trampoline(evalExpr(test, env))) ? body : evalCondClojure(slice(clauses, 2), env)));
|
||||
})()); };
|
||||
PRIMITIVES["eval-cond-clojure"] = evalCondClojure;
|
||||
|
||||
@@ -2184,6 +2573,14 @@ PRIMITIVES["is-render-expr?"] = isRenderExpr;
|
||||
})(); }, keys(spreadDict)); };
|
||||
PRIMITIVES["merge-spread-attrs"] = mergeSpreadAttrs;
|
||||
|
||||
// escape-html
|
||||
var escapeHtml = function(s) { return >((String(s)), replace_("&", "&"), replace_("<", "<"), replace_(">", ">"), replace_("\"", """)); };
|
||||
PRIMITIVES["escape-html"] = escapeHtml;
|
||||
|
||||
// escape-attr
|
||||
var escapeAttr = function(s) { return escapeHtml(s); };
|
||||
PRIMITIVES["escape-attr"] = escapeAttr;
|
||||
|
||||
|
||||
// === Transpiled from parser ===
|
||||
|
||||
@@ -5781,6 +6178,11 @@ PRIMITIVES["resource"] = resource;
|
||||
_renderExprFn = function(expr, env) { return renderToDom(expr, env, null); };
|
||||
_renderMode = true; // Browser always evaluates in render context.
|
||||
|
||||
// Wire CEK render hooks — evaluator checks _renderCheck/_renderFn instead of
|
||||
// the old renderActiveP()/isRenderExpr()/renderExpr() triple.
|
||||
_renderCheck = function(expr, env) { return isRenderExpr(expr); };
|
||||
_renderFn = 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";
|
||||
|
||||
@@ -7235,9 +7637,11 @@ PRIMITIVES["resource"] = resource;
|
||||
if (hname === "map-indexed") return asyncRenderMapIndexed(expr, env, ns);
|
||||
if (hname === "for-each") return asyncRenderMap(expr, env, ns);
|
||||
|
||||
// define/defcomp/defmacro — eval for side effects
|
||||
// define/defcomp/defmacro and custom special forms — eval for side effects
|
||||
if (hname === "define" || hname === "defcomp" || hname === "defmacro" ||
|
||||
hname === "defstyle" || hname === "defhandler") {
|
||||
hname === "defstyle" || hname === "defhandler" ||
|
||||
hname === "deftype" || hname === "defeffect" ||
|
||||
(typeof _customSpecialForms !== "undefined" && _customSpecialForms[hname])) {
|
||||
trampoline(evalExpr(expr, env));
|
||||
return null;
|
||||
}
|
||||
@@ -7900,7 +8304,7 @@ PRIMITIVES["resource"] = resource;
|
||||
cekValue: cekValue,
|
||||
makeReactiveResetFrame: makeReactiveResetFrame,
|
||||
evalExpr: evalExpr,
|
||||
_version: "ref-2.0 (boot+dom+engine+html+orchestration+parser+sx, bootstrap-compiled)"
|
||||
_version: "ref-2.0 (boot+browser-lib+dom+dom-lib+engine+html+orchestration+parser+sx, bootstrap-compiled)"
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user