marko 6.0.39 → 6.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/debug/dom.js CHANGED
@@ -24,6 +24,7 @@ __export(dom_exports, {
24
24
  attrTag: () => attrTag,
25
25
  attrTags: () => attrTags,
26
26
  attrs: () => attrs,
27
+ attrsAndContent: () => attrsAndContent,
27
28
  attrsEvents: () => attrsEvents,
28
29
  awaitTag: () => awaitTag,
29
30
  classAttr: () => classAttr,
@@ -61,6 +62,7 @@ __export(dom_exports, {
61
62
  hoist: () => hoist,
62
63
  html: () => html,
63
64
  init: () => init,
65
+ insertContent: () => insertContent,
64
66
  intersection: () => intersection,
65
67
  lifecycle: () => lifecycle,
66
68
  localClosures: () => localClosures,
@@ -72,6 +74,7 @@ __export(dom_exports, {
72
74
  nodeRef: () => nodeRef,
73
75
  on: () => on,
74
76
  partialAttrs: () => partialAttrs,
77
+ partialAttrsAndContent: () => partialAttrsAndContent,
75
78
  props: () => props,
76
79
  register: () => register,
77
80
  registerBoundSignal: () => registerBoundSignal,
@@ -741,895 +744,930 @@ function parseHTML(html2, ns) {
741
744
  return parser.content || parser;
742
745
  }
743
746
 
744
- // src/dom/dom.ts
745
- function attr(element, name, value2) {
746
- setAttribute(element, name, normalizeAttrValue(value2));
747
+ // src/dom/scope.ts
748
+ function createScope($global, closestBranch) {
749
+ const scope = {
750
+ ___id: $global.___nextScopeId++,
751
+ ___creating: 1,
752
+ ___closestBranch: closestBranch,
753
+ $global
754
+ };
755
+ pendingScopes.push(scope);
756
+ return scope;
747
757
  }
748
- function setAttribute(element, name, value2) {
749
- if (element.getAttribute(name) != value2) {
750
- if (value2 === void 0) {
751
- element.removeAttribute(name);
752
- } else {
753
- element.setAttribute(name, value2);
754
- }
758
+ function skipScope(scope) {
759
+ return scope.$global.___nextScopeId++;
760
+ }
761
+ function findBranchWithKey(scope, key) {
762
+ let branch = scope.___closestBranch;
763
+ while (branch && !branch[key]) {
764
+ branch = branch.___parentBranch;
755
765
  }
766
+ return branch;
756
767
  }
757
- function classAttr(element, value2) {
758
- setAttribute(element, "class", classValue(value2) || void 0);
768
+ function destroyBranch(branch) {
769
+ branch.___parentBranch?.___branchScopes?.delete(branch);
770
+ destroyNestedBranches(branch);
759
771
  }
760
- function classItems(element, items) {
761
- for (const key in items) {
762
- classItem(element, key, items[key]);
763
- }
772
+ function destroyNestedBranches(branch) {
773
+ branch.___destroyed = 1;
774
+ branch.___branchScopes?.forEach(destroyNestedBranches);
775
+ branch.___abortScopes?.forEach((scope) => {
776
+ for (const id in scope.___abortControllers) {
777
+ scope.___abortControllers[id]?.abort();
778
+ }
779
+ });
764
780
  }
765
- function classItem(element, name, value2) {
766
- element.classList.toggle(name, !!value2);
781
+ function removeAndDestroyBranch(branch) {
782
+ destroyBranch(branch);
783
+ removeChildNodes(branch.___startNode, branch.___endNode);
767
784
  }
768
- function styleAttr(element, value2) {
769
- setAttribute(element, "style", styleValue(value2) || void 0);
785
+ function insertBranchBefore(branch, parentNode, nextSibling) {
786
+ insertChildNodes(
787
+ parentNode,
788
+ nextSibling,
789
+ branch.___startNode,
790
+ branch.___endNode
791
+ );
770
792
  }
771
- function styleItems(element, items) {
772
- for (const key in items) {
773
- styleItem(element, key, items[key]);
793
+ function tempDetachBranch(branch) {
794
+ const fragment = new DocumentFragment();
795
+ fragment.namespaceURI = branch.___startNode.parentNode.namespaceURI;
796
+ insertChildNodes(fragment, null, branch.___startNode, branch.___endNode);
797
+ }
798
+
799
+ // src/dom/schedule.ts
800
+ var runTask;
801
+ var isScheduled;
802
+ var channel;
803
+ function schedule() {
804
+ if (!isScheduled) {
805
+ if (true) {
806
+ if (console.createTask) {
807
+ const task = console.createTask("queue");
808
+ runTask = () => task.run(run);
809
+ } else {
810
+ runTask = run;
811
+ }
812
+ }
813
+ isScheduled = 1;
814
+ queueMicrotask(flushAndWaitFrame);
774
815
  }
775
816
  }
776
- function styleItem(element, name, value2) {
777
- element.style.setProperty(name, value2 || value2 === 0 ? value2 + "" : "");
817
+ function flushAndWaitFrame() {
818
+ if (true) {
819
+ runTask();
820
+ } else {
821
+ run();
822
+ }
823
+ requestAnimationFrame(triggerMacroTask);
778
824
  }
779
- function data(node, value2) {
780
- const normalizedValue = normalizeString(value2);
781
- if (node.data !== normalizedValue) {
782
- node.data = normalizedValue;
825
+ function triggerMacroTask() {
826
+ if (!channel) {
827
+ channel = new MessageChannel();
828
+ channel.port1.onmessage = () => {
829
+ isScheduled = 0;
830
+ if (true) {
831
+ const run2 = runTask;
832
+ runTask = void 0;
833
+ run2();
834
+ } else {
835
+ run();
836
+ }
837
+ };
783
838
  }
839
+ channel.port2.postMessage(0);
784
840
  }
785
- function textContent(node, value2) {
786
- const normalizedValue = normalizeString(value2);
787
- if (node.textContent !== normalizedValue) {
788
- node.textContent = normalizedValue;
841
+
842
+ // src/dom/signals.ts
843
+ function state(valueAccessor, fn) {
844
+ if (true) {
845
+ var id = +valueAccessor.slice(
846
+ valueAccessor.lastIndexOf("/") + 1
847
+ );
848
+ valueAccessor = valueAccessor.slice(
849
+ 0,
850
+ valueAccessor.lastIndexOf("/")
851
+ );
789
852
  }
853
+ const valueChangeAccessor = "TagVariableChange:" /* TagVariableChange */ + valueAccessor;
854
+ const update = (scope, value2) => {
855
+ if (scope[valueAccessor] !== value2) {
856
+ scope[valueAccessor] = value2;
857
+ fn(scope, value2);
858
+ }
859
+ };
860
+ return (scope, value2, valueChange) => {
861
+ if (rendering) {
862
+ if ((scope[valueChangeAccessor] = valueChange) && scope[valueAccessor] !== value2 || !(valueAccessor in scope)) {
863
+ scope[valueAccessor] = value2;
864
+ fn(scope, value2);
865
+ }
866
+ } else if (scope[valueChangeAccessor]) {
867
+ scope[valueChangeAccessor](value2);
868
+ } else {
869
+ schedule();
870
+ queueRender(
871
+ scope,
872
+ update,
873
+ true ? id : valueAccessor,
874
+ value2
875
+ );
876
+ }
877
+ return value2;
878
+ };
790
879
  }
791
- function attrs(scope, nodeAccessor, nextAttrs) {
792
- const el = scope[nodeAccessor];
793
- for (let i = el.attributes.length; i--; ) {
794
- const { name } = el.attributes.item(i);
795
- if (!(nextAttrs && (name in nextAttrs || hasAttrAlias(el, name, nextAttrs)))) {
796
- el.removeAttribute(name);
880
+ function value(valueAccessor, fn = () => {
881
+ }) {
882
+ return (scope, value2) => {
883
+ if (!(valueAccessor in scope) || scope[valueAccessor] !== value2) {
884
+ scope[valueAccessor] = value2;
885
+ fn(scope, value2);
797
886
  }
798
- }
799
- attrsInternal(scope, nodeAccessor, nextAttrs);
887
+ };
800
888
  }
801
- function hasAttrAlias(element, attr2, nextAttrs) {
802
- return attr2 === "checked" && element.tagName === "INPUT" && "checkedValue" in nextAttrs;
889
+ function intersection(id, fn, defaultPending = 1, scopeIdAccessor = /* @__KEY__ */ "___id") {
890
+ return (scope) => {
891
+ if (scope.___creating) {
892
+ if (scope[id] === void 0) {
893
+ scope[id] = defaultPending;
894
+ } else if (!--scope[id]) {
895
+ fn(scope);
896
+ }
897
+ } else {
898
+ queueRender(scope, fn, id, 0, scope[scopeIdAccessor]);
899
+ }
900
+ };
803
901
  }
804
- function partialAttrs(scope, nodeAccessor, nextAttrs, skip) {
805
- const el = scope[nodeAccessor];
806
- const partial = {};
807
- for (let i = el.attributes.length; i--; ) {
808
- const { name } = el.attributes.item(i);
809
- if (!skip[name] && !(nextAttrs && name in nextAttrs)) {
810
- el.removeAttribute(name);
902
+ function loopClosure(valueAccessor, ownerLoopNodeAccessor, fn) {
903
+ const childSignal = closure(valueAccessor, fn);
904
+ const loopScopeAccessor = "LoopScopeArray:" /* LoopScopeArray */ + ownerLoopNodeAccessor;
905
+ const loopScopeMapAccessor = "LoopScopeMap:" /* LoopScopeMap */ + ownerLoopNodeAccessor;
906
+ const ownerSignal = (ownerScope) => {
907
+ const scopes = ownerScope[loopScopeAccessor] ||= ownerScope[loopScopeMapAccessor] ? [...ownerScope[loopScopeMapAccessor].values()] : [];
908
+ const [firstScope] = scopes;
909
+ if (firstScope) {
910
+ queueRender(
911
+ ownerScope,
912
+ () => {
913
+ for (const scope of scopes) {
914
+ if (!scope.___creating && !scope.___destroyed) {
915
+ childSignal(scope);
916
+ }
917
+ }
918
+ },
919
+ -1,
920
+ 0,
921
+ firstScope.___id
922
+ );
923
+ }
924
+ };
925
+ ownerSignal._ = childSignal;
926
+ return ownerSignal;
927
+ }
928
+ function conditionalClosure(valueAccessor, ownerConditionalNodeAccessor, branch, fn) {
929
+ const childSignal = closure(valueAccessor, fn);
930
+ const scopeAccessor = "ConditionalScope:" /* ConditionalScope */ + ownerConditionalNodeAccessor;
931
+ const branchAccessor = "ConditionalRenderer:" /* ConditionalRenderer */ + ownerConditionalNodeAccessor;
932
+ const ownerSignal = (scope) => {
933
+ const ifScope = scope[scopeAccessor];
934
+ if (ifScope && !ifScope.___creating && scope[branchAccessor] === branch) {
935
+ queueRender(ifScope, childSignal, -1);
811
936
  }
937
+ };
938
+ ownerSignal._ = childSignal;
939
+ return ownerSignal;
940
+ }
941
+ function subscribeToScopeSet(ownerScope, accessor, scope) {
942
+ const subscribers = ownerScope[accessor] ||= /* @__PURE__ */ new Set();
943
+ if (!subscribers.has(scope)) {
944
+ subscribers.add(scope);
945
+ getAbortSignal(scope, -1).addEventListener(
946
+ "abort",
947
+ () => ownerScope[accessor].delete(scope)
948
+ );
812
949
  }
813
- for (const key in nextAttrs) {
814
- if (!skip[key]) partial[key] = nextAttrs[key];
950
+ }
951
+ function dynamicClosure(...closureSignals) {
952
+ const [{ ___scopeInstancesAccessor, ___signalIndexAccessor }] = closureSignals;
953
+ for (let i = closureSignals.length; i--; ) {
954
+ closureSignals[i].___index = i;
815
955
  }
816
- attrsInternal(scope, nodeAccessor, partial);
956
+ return (scope) => {
957
+ if (scope[___scopeInstancesAccessor]) {
958
+ for (const childScope of scope[___scopeInstancesAccessor]) {
959
+ if (!childScope.___creating) {
960
+ queueRender(
961
+ childScope,
962
+ closureSignals[childScope[___signalIndexAccessor]],
963
+ -1
964
+ );
965
+ }
966
+ }
967
+ }
968
+ };
817
969
  }
818
- function attrsInternal(scope, nodeAccessor, nextAttrs) {
819
- const el = scope[nodeAccessor];
820
- let events;
821
- let skip;
822
- switch (el.tagName) {
823
- case "INPUT":
824
- if ("checked" in nextAttrs || "checkedChange" in nextAttrs) {
825
- controllable_input_checked(
826
- scope,
827
- nodeAccessor,
828
- nextAttrs.checked,
829
- nextAttrs.checkedChange
830
- );
831
- } else if ("checkedValue" in nextAttrs || "checkedValueChange" in nextAttrs) {
832
- controllable_input_checkedValue(
833
- scope,
834
- nodeAccessor,
835
- nextAttrs.checkedValue,
836
- nextAttrs.checkedValueChange,
837
- nextAttrs.value
838
- );
839
- } else if ("value" in nextAttrs || "valueChange" in nextAttrs) {
840
- controllable_input_value(
841
- scope,
842
- nodeAccessor,
843
- nextAttrs.value,
844
- nextAttrs.valueChange
845
- );
846
- } else {
847
- break;
970
+ function dynamicClosureRead(valueAccessor, fn, getOwnerScope) {
971
+ const childSignal = closure(valueAccessor, fn, getOwnerScope);
972
+ const closureSignal = (scope) => {
973
+ scope[closureSignal.___signalIndexAccessor] = closureSignal.___index;
974
+ childSignal(scope);
975
+ subscribeToScopeSet(
976
+ getOwnerScope ? getOwnerScope(scope) : scope["_" /* Owner */],
977
+ closureSignal.___scopeInstancesAccessor,
978
+ scope
979
+ );
980
+ };
981
+ closureSignal.___scopeInstancesAccessor = "ClosureScopes:" /* ClosureScopes */ + valueAccessor;
982
+ closureSignal.___signalIndexAccessor = "ClosureSignalIndex:" /* ClosureSignalIndex */ + valueAccessor;
983
+ return closureSignal;
984
+ }
985
+ function closure(valueAccessor, fn, getOwnerScope) {
986
+ return (scope) => {
987
+ fn(
988
+ scope,
989
+ (getOwnerScope ? getOwnerScope(scope) : scope["_" /* Owner */])[valueAccessor]
990
+ );
991
+ };
992
+ }
993
+ function setTagVar(scope, childAccessor, tagVarSignal2) {
994
+ scope[childAccessor]["#TagVariable" /* TagVariable */] = (value2) => tagVarSignal2(scope, value2);
995
+ }
996
+ var tagVarSignal = (scope, value2) => scope["#TagVariable" /* TagVariable */]?.(value2);
997
+ function setTagVarChange(scope, changeHandler) {
998
+ scope["#TagVariableChange" /* TagVariableChange */] = changeHandler;
999
+ }
1000
+ var tagVarSignalChange = (scope, value2) => scope["#TagVariableChange" /* TagVariableChange */]?.(value2);
1001
+ var tagIdsByGlobal = /* @__PURE__ */ new WeakMap();
1002
+ function nextTagId({ $global }) {
1003
+ const id = tagIdsByGlobal.get($global) || 0;
1004
+ tagIdsByGlobal.set($global, id + 1);
1005
+ return "c" + $global.runtimeId + $global.renderId + id.toString(36);
1006
+ }
1007
+ function effect(id, fn) {
1008
+ register(id, fn);
1009
+ return (scope) => {
1010
+ queueEffect(scope, fn);
1011
+ };
1012
+ }
1013
+ function* traverseAllHoisted(scope, path, curIndex = path.length - 1) {
1014
+ if (scope) {
1015
+ if (Symbol.iterator in scope) {
1016
+ for (const s of scope instanceof Map ? scope.values() : scope) {
1017
+ yield* traverseAllHoisted(s, path, curIndex);
848
1018
  }
849
- skip = /^(?:value|checked(?:Value)?)(?:Change)?$/;
850
- break;
851
- case "SELECT":
852
- if ("value" in nextAttrs || "valueChange" in nextAttrs) {
853
- controllable_select_value(
854
- scope,
855
- nodeAccessor,
856
- nextAttrs.value,
857
- nextAttrs.valueChange
858
- );
859
- skip = /^value(?:Change)?$/;
1019
+ } else if (curIndex) {
1020
+ yield* traverseAllHoisted(scope[path[curIndex]], path, curIndex - 1);
1021
+ } else {
1022
+ yield scope[path[0]];
1023
+ }
1024
+ }
1025
+ }
1026
+ function hoist(...path) {
1027
+ return (scope) => {
1028
+ const getOne = (...args) => iterator().next().value(...args);
1029
+ const iterator = getOne[Symbol.iterator] = () => traverseAllHoisted(scope, path);
1030
+ return getOne;
1031
+ };
1032
+ }
1033
+
1034
+ // src/dom/walker.ts
1035
+ var walker = /* @__PURE__ */ document.createTreeWalker(document);
1036
+ function walk(startNode, walkCodes, branch) {
1037
+ walker.currentNode = startNode;
1038
+ walkInternal(0, walkCodes, branch);
1039
+ }
1040
+ function walkInternal(currentWalkIndex, walkCodes, scope) {
1041
+ let value2;
1042
+ let storedMultiplier = 0;
1043
+ let currentMultiplier = 0;
1044
+ let currentScopeIndex = 0;
1045
+ for (; currentWalkIndex < walkCodes.length; ) {
1046
+ value2 = walkCodes.charCodeAt(currentWalkIndex++);
1047
+ currentMultiplier = storedMultiplier;
1048
+ storedMultiplier = 0;
1049
+ if (value2 === 32 /* Get */) {
1050
+ const node = walker.currentNode;
1051
+ scope[true ? getDebugKey(currentScopeIndex, walker.currentNode) : currentScopeIndex] = node;
1052
+ scope["Getter:" /* Getter */ + (true ? getDebugKey(currentScopeIndex++, walker.currentNode) : currentScopeIndex++)] = () => node;
1053
+ } else if (value2 === 37 /* Replace */ || value2 === 49 /* DynamicTagWithVar */) {
1054
+ walker.currentNode.replaceWith(
1055
+ walker.currentNode = scope[true ? getDebugKey(currentScopeIndex++, "#text") : currentScopeIndex++] = new Text()
1056
+ );
1057
+ if (value2 === 49 /* DynamicTagWithVar */) {
1058
+ scope[true ? getDebugKey(currentScopeIndex++, "#scopeOffset") : currentScopeIndex++] = skipScope(scope);
860
1059
  }
861
- break;
862
- case "TEXTAREA":
863
- if ("value" in nextAttrs || "valueChange" in nextAttrs) {
864
- controllable_input_value(
865
- scope,
866
- nodeAccessor,
867
- nextAttrs.value,
868
- nextAttrs.valueChange
869
- );
870
- skip = /^value(?:Change)?$/;
1060
+ } else if (value2 === 38 /* EndChild */) {
1061
+ return currentWalkIndex;
1062
+ } else if (value2 === 47 /* BeginChild */ || value2 === 48 /* BeginChildWithVar */) {
1063
+ currentWalkIndex = walkInternal(
1064
+ currentWalkIndex,
1065
+ walkCodes,
1066
+ scope[true ? getDebugKey(currentScopeIndex++, "#childScope") : currentScopeIndex++] = createScope(scope.$global, scope.___closestBranch)
1067
+ );
1068
+ if (value2 === 48 /* BeginChildWithVar */) {
1069
+ scope[true ? getDebugKey(currentScopeIndex++, "#scopeOffset") : currentScopeIndex++] = skipScope(scope);
871
1070
  }
872
- break;
873
- case "DETAILS":
874
- case "DIALOG":
875
- if ("open" in nextAttrs || "openChange" in nextAttrs) {
876
- controllable_detailsOrDialog_open(
877
- scope,
878
- nodeAccessor,
879
- nextAttrs.open,
880
- nextAttrs.openChange
881
- );
882
- skip = /^open(?:Change)?$/;
1071
+ } else if (value2 < 91 /* NextEnd */ + 1) {
1072
+ value2 = 20 /* Next */ * currentMultiplier + value2 - 67 /* Next */;
1073
+ while (value2--) {
1074
+ walker.nextNode();
883
1075
  }
884
- break;
885
- }
886
- for (const name in nextAttrs) {
887
- const value2 = nextAttrs[name];
888
- switch (name) {
889
- case "class":
890
- classAttr(el, value2);
891
- break;
892
- case "style":
893
- styleAttr(el, value2);
894
- break;
895
- case "content":
896
- break;
897
- default: {
898
- if (isEventHandler(name)) {
899
- (events ||= scope["EventAttributes:" /* EventAttributes */ + nodeAccessor] = {})[getEventHandlerName(name)] = value2;
900
- } else if (!skip?.test(name)) {
901
- attr(el, name, value2);
902
- }
1076
+ } else if (value2 < 106 /* OverEnd */ + 1) {
1077
+ value2 = 10 /* Over */ * currentMultiplier + value2 - 97 /* Over */;
1078
+ while (value2--) {
1079
+ walker.nextSibling();
1080
+ }
1081
+ } else if (value2 < 116 /* OutEnd */ + 1) {
1082
+ value2 = 10 /* Out */ * currentMultiplier + value2 - 107 /* Out */;
1083
+ while (value2--) {
1084
+ walker.parentNode();
1085
+ }
1086
+ walker.nextSibling();
1087
+ } else {
1088
+ if (value2 < 117 /* Multiplier */ || value2 > 126 /* MultiplierEnd */) {
1089
+ throw new Error(`Unknown walk code: ${value2}`);
903
1090
  }
1091
+ storedMultiplier = currentMultiplier * 10 /* Multiplier */ + value2 - 117 /* Multiplier */;
904
1092
  }
905
1093
  }
906
1094
  }
907
- function attrsEvents(scope, nodeAccessor) {
908
- const el = scope[nodeAccessor];
909
- const events = scope["EventAttributes:" /* EventAttributes */ + nodeAccessor];
910
- switch (scope["ControlledType:" /* ControlledType */ + nodeAccessor]) {
911
- case 0 /* InputChecked */:
912
- controllable_input_checked_effect(scope, nodeAccessor);
913
- break;
914
- case 1 /* InputCheckedValue */:
915
- controllable_input_checkedValue_effect(scope, nodeAccessor);
916
- break;
917
- case 2 /* InputValue */:
918
- controllable_input_value_effect(scope, nodeAccessor);
919
- break;
920
- case 3 /* SelectValue */:
921
- controllable_select_value_effect(scope, nodeAccessor);
922
- break;
923
- case 4 /* DetailsOrDialogOpen */:
924
- controllable_detailsOrDialog_open_effect(scope, nodeAccessor);
925
- break;
926
- }
927
- for (const name in events) {
928
- on(el, name, events[name]);
1095
+ function getDebugKey(index, node) {
1096
+ if (typeof node === "string") {
1097
+ return `${node}/${index}`;
1098
+ } else if (node.nodeType === 3 /* Text */) {
1099
+ return `#text/${index}`;
1100
+ } else if (node.nodeType === 8 /* Comment */) {
1101
+ return `#comment/${index}`;
1102
+ } else if (node.nodeType === 1 /* Element */) {
1103
+ return `#${node.tagName.toLowerCase()}/${index}`;
929
1104
  }
1105
+ return index;
930
1106
  }
931
- function html(scope, value2, accessor) {
932
- const firstChild = scope[accessor];
933
- const parentNode = firstChild.parentNode;
934
- const lastChild = scope["DynamicPlaceholderLastChild:" /* DynamicPlaceholderLastChild */ + accessor] || firstChild;
935
- const newContent = parseHTML(
936
- value2 || value2 === 0 ? value2 + "" : "",
1107
+
1108
+ // src/dom/renderer.ts
1109
+ function createBranch($global, renderer, parentScope, parentNode) {
1110
+ const branch = createScope($global);
1111
+ const parentBranch = parentScope?.___closestBranch;
1112
+ branch["_" /* Owner */] = renderer.___owner || parentScope;
1113
+ branch.___closestBranch = branch;
1114
+ if (parentBranch) {
1115
+ branch.___parentBranch = parentBranch;
1116
+ (parentBranch.___branchScopes ||= /* @__PURE__ */ new Set()).add(branch);
1117
+ }
1118
+ if (true) {
1119
+ branch.___renderer = renderer;
1120
+ }
1121
+ renderer.___clone?.(
1122
+ branch,
937
1123
  parentNode.namespaceURI
938
1124
  );
939
- insertChildNodes(
940
- parentNode,
941
- firstChild,
942
- scope[accessor] = newContent.firstChild || newContent.appendChild(new Text()),
943
- scope["DynamicPlaceholderLastChild:" /* DynamicPlaceholderLastChild */ + accessor] = newContent.lastChild
944
- );
945
- removeChildNodes(firstChild, lastChild);
1125
+ return branch;
946
1126
  }
947
- function props(scope, nodeIndex, index) {
948
- const nextProps = scope[index];
949
- const prevProps = scope[index + "-"];
950
- const node = scope[nodeIndex];
951
- if (prevProps) {
952
- for (const name in prevProps) {
953
- if (!(name in nextProps)) {
954
- node[name] = void 0;
955
- }
956
- }
957
- }
958
- for (const name in nextProps) {
959
- node[name] = nextProps[name];
960
- }
961
- scope[index + "-"] = nextProps;
1127
+ function createAndSetupBranch($global, renderer, parentScope, parentNode) {
1128
+ return setupBranch(
1129
+ renderer,
1130
+ createBranch($global, renderer, parentScope, parentNode)
1131
+ );
962
1132
  }
963
- function normalizeAttrValue(value2) {
964
- if (value2 || value2 === 0) {
965
- return value2 === true ? "" : value2 + "";
1133
+ function setupBranch(renderer, branch) {
1134
+ if (renderer.___setup) {
1135
+ queueRender(branch, renderer.___setup, -1);
966
1136
  }
1137
+ return branch;
967
1138
  }
968
- function normalizeString(value2) {
969
- return value2 || value2 === 0 ? value2 + "" : "\u200D";
1139
+ function createContent(id, template, walks, setup, params, dynamicScopesAccessor) {
1140
+ walks = walks ? walks.replace(/[^\0-1]+$/, "") : "";
1141
+ setup = setup ? setup._ || setup : void 0;
1142
+ params ||= void 0;
1143
+ const clone = template ? (branch, ns) => {
1144
+ ((cloneCache[ns] ||= {})[template] ||= createCloneableHTML(
1145
+ template,
1146
+ ns
1147
+ ))(branch, walks);
1148
+ } : (branch) => {
1149
+ walk(
1150
+ branch.___startNode = branch.___endNode = new Text(),
1151
+ walks,
1152
+ branch
1153
+ );
1154
+ };
1155
+ return (owner) => {
1156
+ return {
1157
+ ___id: id,
1158
+ ___clone: clone,
1159
+ ___owner: owner,
1160
+ ___setup: setup,
1161
+ ___params: params,
1162
+ ___accessor: dynamicScopesAccessor
1163
+ };
1164
+ };
970
1165
  }
971
- function lifecycle(scope, index, thisObj) {
972
- const instance = scope[index];
973
- if (instance) {
974
- Object.assign(instance, thisObj);
975
- instance.onUpdate?.();
976
- } else {
977
- scope[index] = thisObj;
978
- thisObj.onMount?.();
979
- getAbortSignal(
980
- scope,
981
- "LifecycleAbortController:" /* LifecycleAbortController */ + index
982
- ).onabort = () => thisObj.onDestroy?.();
983
- }
1166
+ function registerContent(id, template, walks, setup, params, dynamicScopesAccessor) {
1167
+ return register(
1168
+ id,
1169
+ createContent(id, template, walks, setup, params, dynamicScopesAccessor)
1170
+ );
984
1171
  }
985
- function removeChildNodes(startNode, endNode) {
986
- const stop = endNode.nextSibling;
987
- let current = startNode;
988
- while (current !== stop) {
989
- const next = current.nextSibling;
990
- current.remove();
991
- current = next;
1172
+ function localClosures(renderer, closureFns) {
1173
+ const closureSignals = {};
1174
+ for (const key in closureFns) {
1175
+ closureSignals[key] = value(key, closureFns[key]);
992
1176
  }
1177
+ return (owner, closureValues) => {
1178
+ const instance = renderer(owner);
1179
+ instance.___localClosures = closureSignals;
1180
+ instance.___localClosureValues = closureValues;
1181
+ return instance;
1182
+ };
993
1183
  }
994
- function insertChildNodes(parentNode, referenceNode, startNode, endNode) {
995
- parentNode.insertBefore(toInsertNode(startNode, endNode), referenceNode);
1184
+ function createRenderer(template, walks, setup, params) {
1185
+ return createContent("", template, walks, setup, params)();
996
1186
  }
997
- function toInsertNode(startNode, endNode) {
998
- if (startNode === endNode) return startNode;
999
- const parent = new DocumentFragment();
1000
- const stop = endNode.nextSibling;
1001
- let current = startNode;
1002
- while (current !== stop) {
1003
- const next = current.nextSibling;
1004
- parent.appendChild(current);
1005
- current = next;
1006
- }
1007
- return parent;
1187
+ var cloneCache = {};
1188
+ function createCloneableHTML(html2, ns) {
1189
+ const { firstChild, lastChild } = parseHTML(html2, ns);
1190
+ const parent = document.createElementNS(ns, "t");
1191
+ insertChildNodes(parent, null, firstChild, lastChild);
1192
+ return firstChild === lastChild && firstChild.nodeType < 8 /* Comment */ ? (branch, walks) => {
1193
+ walk(
1194
+ branch.___startNode = branch.___endNode = firstChild.cloneNode(true),
1195
+ walks,
1196
+ branch
1197
+ );
1198
+ } : (branch, walks) => {
1199
+ const clone = parent.cloneNode(true);
1200
+ walk(clone.firstChild, walks, branch);
1201
+ branch.___startNode = clone.firstChild;
1202
+ branch.___endNode = clone.lastChild;
1203
+ };
1008
1204
  }
1009
1205
 
1010
- // src/dom/scope.ts
1011
- function createScope($global, closestBranch) {
1012
- const scope = {
1013
- ___id: $global.___nextScopeId++,
1014
- ___creating: 1,
1015
- ___closestBranch: closestBranch,
1016
- $global
1017
- };
1018
- pendingScopes.push(scope);
1019
- return scope;
1206
+ // src/dom/dom.ts
1207
+ function attr(element, name, value2) {
1208
+ setAttribute(element, name, normalizeAttrValue(value2));
1020
1209
  }
1021
- function skipScope(scope) {
1022
- return scope.$global.___nextScopeId++;
1210
+ function setAttribute(element, name, value2) {
1211
+ if (element.getAttribute(name) != value2) {
1212
+ if (value2 === void 0) {
1213
+ element.removeAttribute(name);
1214
+ } else {
1215
+ element.setAttribute(name, value2);
1216
+ }
1217
+ }
1023
1218
  }
1024
- function findBranchWithKey(scope, key) {
1025
- let branch = scope.___closestBranch;
1026
- while (branch && !branch[key]) {
1027
- branch = branch.___parentBranch;
1219
+ function classAttr(element, value2) {
1220
+ setAttribute(element, "class", classValue(value2) || void 0);
1221
+ }
1222
+ function classItems(element, items) {
1223
+ for (const key in items) {
1224
+ classItem(element, key, items[key]);
1028
1225
  }
1029
- return branch;
1030
1226
  }
1031
- function destroyBranch(branch) {
1032
- branch.___parentBranch?.___branchScopes?.delete(branch);
1033
- destroyNestedBranches(branch);
1227
+ function classItem(element, name, value2) {
1228
+ element.classList.toggle(name, !!value2);
1034
1229
  }
1035
- function destroyNestedBranches(branch) {
1036
- branch.___destroyed = 1;
1037
- branch.___branchScopes?.forEach(destroyNestedBranches);
1038
- branch.___abortScopes?.forEach((scope) => {
1039
- for (const id in scope.___abortControllers) {
1040
- scope.___abortControllers[id]?.abort();
1041
- }
1042
- });
1230
+ function styleAttr(element, value2) {
1231
+ setAttribute(element, "style", styleValue(value2) || void 0);
1043
1232
  }
1044
- function removeAndDestroyBranch(branch) {
1045
- destroyBranch(branch);
1046
- removeChildNodes(branch.___startNode, branch.___endNode);
1233
+ function styleItems(element, items) {
1234
+ for (const key in items) {
1235
+ styleItem(element, key, items[key]);
1236
+ }
1047
1237
  }
1048
- function insertBranchBefore(branch, parentNode, nextSibling) {
1049
- insertChildNodes(
1050
- parentNode,
1051
- nextSibling,
1052
- branch.___startNode,
1053
- branch.___endNode
1054
- );
1238
+ function styleItem(element, name, value2) {
1239
+ element.style.setProperty(name, value2 || value2 === 0 ? value2 + "" : "");
1055
1240
  }
1056
- function tempDetachBranch(branch) {
1057
- const fragment = new DocumentFragment();
1058
- fragment.namespaceURI = branch.___startNode.parentNode.namespaceURI;
1059
- insertChildNodes(fragment, null, branch.___startNode, branch.___endNode);
1241
+ function data(node, value2) {
1242
+ const normalizedValue = normalizeString(value2);
1243
+ if (node.data !== normalizedValue) {
1244
+ node.data = normalizedValue;
1245
+ }
1060
1246
  }
1061
-
1062
- // src/dom/reconcile.ts
1063
- var WRONG_POS = 2147483647;
1064
- function reconcile(parent, oldBranches, newBranches, afterReference) {
1065
- let oldStart = 0;
1066
- let newStart = 0;
1067
- let oldEnd = oldBranches.length - 1;
1068
- let newEnd = newBranches.length - 1;
1069
- let oldStartBranch = oldBranches[oldStart];
1070
- let newStartBranch = newBranches[newStart];
1071
- let oldEndBranch = oldBranches[oldEnd];
1072
- let newEndBranch = newBranches[newEnd];
1073
- let i;
1074
- let j;
1075
- let k;
1076
- let nextSibling;
1077
- let oldBranch;
1078
- let newBranch;
1079
- outer: {
1080
- while (oldStartBranch === newStartBranch) {
1081
- ++oldStart;
1082
- ++newStart;
1083
- if (oldStart > oldEnd || newStart > newEnd) {
1084
- break outer;
1085
- }
1086
- oldStartBranch = oldBranches[oldStart];
1087
- newStartBranch = newBranches[newStart];
1088
- }
1089
- while (oldEndBranch === newEndBranch) {
1090
- --oldEnd;
1091
- --newEnd;
1092
- if (oldStart > oldEnd || newStart > newEnd) {
1093
- break outer;
1094
- }
1095
- oldEndBranch = oldBranches[oldEnd];
1096
- newEndBranch = newBranches[newEnd];
1097
- }
1247
+ function textContent(node, value2) {
1248
+ const normalizedValue = normalizeString(value2);
1249
+ if (node.textContent !== normalizedValue) {
1250
+ node.textContent = normalizedValue;
1098
1251
  }
1099
- if (oldStart > oldEnd) {
1100
- if (newStart <= newEnd) {
1101
- k = newEnd + 1;
1102
- nextSibling = k < newBranches.length ? newBranches[k].___startNode : afterReference;
1103
- do {
1104
- insertBranchBefore(newBranches[newStart++], parent, nextSibling);
1105
- } while (newStart <= newEnd);
1252
+ }
1253
+ function attrs(scope, nodeAccessor, nextAttrs) {
1254
+ const el = scope[nodeAccessor];
1255
+ for (let i = el.attributes.length; i--; ) {
1256
+ const { name } = el.attributes.item(i);
1257
+ if (!(nextAttrs && (name in nextAttrs || hasAttrAlias(el, name, nextAttrs)))) {
1258
+ el.removeAttribute(name);
1106
1259
  }
1107
- } else if (newStart > newEnd) {
1108
- do {
1109
- removeAndDestroyBranch(oldBranches[oldStart++]);
1110
- } while (oldStart <= oldEnd);
1111
- } else {
1112
- const oldLength = oldEnd - oldStart + 1;
1113
- const newLength = newEnd - newStart + 1;
1114
- const aNullable = oldBranches;
1115
- const sources = new Array(newLength);
1116
- for (i = 0; i < newLength; ++i) {
1117
- sources[i] = -1;
1118
- }
1119
- let pos = 0;
1120
- let synced = 0;
1121
- const keyIndex = /* @__PURE__ */ new Map();
1122
- for (j = newStart; j <= newEnd; ++j) {
1123
- keyIndex.set(newBranches[j], j);
1124
- }
1125
- for (i = oldStart; i <= oldEnd && synced < newLength; ++i) {
1126
- oldBranch = oldBranches[i];
1127
- j = keyIndex.get(oldBranch);
1128
- if (j !== void 0) {
1129
- pos = pos > j ? WRONG_POS : j;
1130
- ++synced;
1131
- newBranch = newBranches[j];
1132
- sources[j - newStart] = i;
1133
- aNullable[i] = null;
1134
- }
1260
+ }
1261
+ attrsInternal(scope, nodeAccessor, nextAttrs);
1262
+ }
1263
+ function attrsAndContent(scope, nodeAccessor, nextAttrs) {
1264
+ attrs(scope, nodeAccessor, nextAttrs);
1265
+ insertContent(scope, nodeAccessor, nextAttrs?.content);
1266
+ }
1267
+ function hasAttrAlias(element, attr2, nextAttrs) {
1268
+ return attr2 === "checked" && element.tagName === "INPUT" && "checkedValue" in nextAttrs;
1269
+ }
1270
+ function partialAttrs(scope, nodeAccessor, nextAttrs, skip) {
1271
+ const el = scope[nodeAccessor];
1272
+ const partial = {};
1273
+ for (let i = el.attributes.length; i--; ) {
1274
+ const { name } = el.attributes.item(i);
1275
+ if (!skip[name] && !(nextAttrs && name in nextAttrs)) {
1276
+ el.removeAttribute(name);
1135
1277
  }
1136
- if (oldLength === oldBranches.length && synced === 0) {
1137
- for (; newStart < newLength; ++newStart) {
1138
- insertBranchBefore(newBranches[newStart], parent, afterReference);
1278
+ }
1279
+ for (const key in nextAttrs) {
1280
+ if (!skip[key]) partial[key] = nextAttrs[key];
1281
+ }
1282
+ attrsInternal(scope, nodeAccessor, partial);
1283
+ }
1284
+ function partialAttrsAndContent(scope, nodeAccessor, nextAttrs, skip) {
1285
+ partialAttrs(scope, nodeAccessor, nextAttrs, skip);
1286
+ insertContent(scope, nodeAccessor, nextAttrs?.content);
1287
+ }
1288
+ function attrsInternal(scope, nodeAccessor, nextAttrs) {
1289
+ const el = scope[nodeAccessor];
1290
+ let events;
1291
+ let skip;
1292
+ switch (el.tagName) {
1293
+ case "INPUT":
1294
+ if ("checked" in nextAttrs || "checkedChange" in nextAttrs) {
1295
+ controllable_input_checked(
1296
+ scope,
1297
+ nodeAccessor,
1298
+ nextAttrs.checked,
1299
+ nextAttrs.checkedChange
1300
+ );
1301
+ } else if ("checkedValue" in nextAttrs || "checkedValueChange" in nextAttrs) {
1302
+ controllable_input_checkedValue(
1303
+ scope,
1304
+ nodeAccessor,
1305
+ nextAttrs.checkedValue,
1306
+ nextAttrs.checkedValueChange,
1307
+ nextAttrs.value
1308
+ );
1309
+ } else if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1310
+ controllable_input_value(
1311
+ scope,
1312
+ nodeAccessor,
1313
+ nextAttrs.value,
1314
+ nextAttrs.valueChange
1315
+ );
1316
+ } else {
1317
+ break;
1139
1318
  }
1140
- for (; oldStart < oldLength; ++oldStart) {
1141
- removeAndDestroyBranch(oldBranches[oldStart]);
1319
+ skip = /^(?:value|checked(?:Value)?)(?:Change)?$/;
1320
+ break;
1321
+ case "SELECT":
1322
+ if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1323
+ controllable_select_value(
1324
+ scope,
1325
+ nodeAccessor,
1326
+ nextAttrs.value,
1327
+ nextAttrs.valueChange
1328
+ );
1329
+ skip = /^value(?:Change)?$/;
1142
1330
  }
1143
- } else {
1144
- i = oldLength - synced;
1145
- while (i > 0) {
1146
- oldBranch = aNullable[oldStart++];
1147
- if (oldBranch !== null) {
1148
- removeAndDestroyBranch(oldBranch);
1149
- i--;
1150
- }
1331
+ break;
1332
+ case "TEXTAREA":
1333
+ if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1334
+ controllable_input_value(
1335
+ scope,
1336
+ nodeAccessor,
1337
+ nextAttrs.value,
1338
+ nextAttrs.valueChange
1339
+ );
1340
+ skip = /^value(?:Change)?$/;
1151
1341
  }
1152
- if (pos === WRONG_POS) {
1153
- const seq = longestIncreasingSubsequence(sources);
1154
- j = seq.length - 1;
1155
- k = newBranches.length;
1156
- for (i = newLength - 1; i >= 0; --i) {
1157
- if (sources[i] === -1) {
1158
- pos = i + newStart;
1159
- newBranch = newBranches[pos++];
1160
- nextSibling = pos < k ? newBranches[pos].___startNode : afterReference;
1161
- insertBranchBefore(newBranch, parent, nextSibling);
1162
- } else {
1163
- if (j < 0 || i !== seq[j]) {
1164
- pos = i + newStart;
1165
- newBranch = newBranches[pos++];
1166
- nextSibling = pos < k ? newBranches[pos].___startNode : afterReference;
1167
- insertBranchBefore(newBranch, parent, nextSibling);
1168
- } else {
1169
- --j;
1170
- }
1171
- }
1172
- }
1173
- } else if (synced !== newLength) {
1174
- k = newBranches.length;
1175
- for (i = newLength - 1; i >= 0; --i) {
1176
- if (sources[i] === -1) {
1177
- pos = i + newStart;
1178
- newBranch = newBranches[pos++];
1179
- nextSibling = pos < k ? newBranches[pos].___startNode : afterReference;
1180
- insertBranchBefore(newBranch, parent, nextSibling);
1181
- }
1182
- }
1342
+ break;
1343
+ case "DETAILS":
1344
+ case "DIALOG":
1345
+ if ("open" in nextAttrs || "openChange" in nextAttrs) {
1346
+ controllable_detailsOrDialog_open(
1347
+ scope,
1348
+ nodeAccessor,
1349
+ nextAttrs.open,
1350
+ nextAttrs.openChange
1351
+ );
1352
+ skip = /^open(?:Change)?$/;
1183
1353
  }
1184
- }
1354
+ break;
1185
1355
  }
1186
- }
1187
- function longestIncreasingSubsequence(a) {
1188
- const p = a.slice();
1189
- const result = [0];
1190
- let u;
1191
- let v;
1192
- for (let i = 0, il = a.length; i < il; ++i) {
1193
- if (a[i] === -1) {
1194
- continue;
1195
- }
1196
- const j = result[result.length - 1];
1197
- if (a[j] < a[i]) {
1198
- p[i] = j;
1199
- result.push(i);
1200
- continue;
1201
- }
1202
- u = 0;
1203
- v = result.length - 1;
1204
- while (u < v) {
1205
- const c = (u + v) / 2 | 0;
1206
- if (a[result[c]] < a[i]) {
1207
- u = c + 1;
1208
- } else {
1209
- v = c;
1356
+ for (const name in nextAttrs) {
1357
+ const value2 = nextAttrs[name];
1358
+ switch (name) {
1359
+ case "class":
1360
+ classAttr(el, value2);
1361
+ break;
1362
+ case "style":
1363
+ styleAttr(el, value2);
1364
+ break;
1365
+ case "content": {
1366
+ break;
1210
1367
  }
1211
- }
1212
- if (a[i] < a[result[u]]) {
1213
- if (u > 0) {
1214
- p[i] = result[u - 1];
1368
+ default: {
1369
+ if (isEventHandler(name)) {
1370
+ (events ||= scope["EventAttributes:" /* EventAttributes */ + nodeAccessor] = {})[getEventHandlerName(name)] = value2;
1371
+ } else if (!skip?.test(name)) {
1372
+ attr(el, name, value2);
1373
+ }
1215
1374
  }
1216
- result[u] = i;
1217
1375
  }
1218
1376
  }
1219
- u = result.length;
1220
- v = result[u - 1];
1221
- while (u-- > 0) {
1222
- result[u] = v;
1223
- v = p[v];
1224
- }
1225
- return result;
1226
1377
  }
1227
-
1228
- // src/dom/schedule.ts
1229
- var runTask;
1230
- var isScheduled;
1231
- var channel;
1232
- function schedule() {
1233
- if (!isScheduled) {
1234
- if (true) {
1235
- if (console.createTask) {
1236
- const task = console.createTask("queue");
1237
- runTask = () => task.run(run);
1238
- } else {
1239
- runTask = run;
1240
- }
1378
+ function insertContent(scope, nodeAccessor, value2) {
1379
+ const content = normalizeClientRender(value2);
1380
+ const rendererAccessor = "ConditionalRenderer:" /* ConditionalRenderer */ + nodeAccessor;
1381
+ if (scope[rendererAccessor] !== (scope[rendererAccessor] = content?.___id)) {
1382
+ setConditionalRenderer(scope, nodeAccessor, content, createAndSetupBranch);
1383
+ if (content?.___accessor) {
1384
+ subscribeToScopeSet(
1385
+ content.___owner,
1386
+ content.___accessor,
1387
+ scope["ConditionalScope:" /* ConditionalScope */ + nodeAccessor]
1388
+ );
1241
1389
  }
1242
- isScheduled = 1;
1243
- queueMicrotask(flushAndWaitFrame);
1244
1390
  }
1245
1391
  }
1246
- function flushAndWaitFrame() {
1247
- if (true) {
1248
- runTask();
1249
- } else {
1250
- run();
1392
+ function attrsEvents(scope, nodeAccessor) {
1393
+ const el = scope[nodeAccessor];
1394
+ const events = scope["EventAttributes:" /* EventAttributes */ + nodeAccessor];
1395
+ switch (scope["ControlledType:" /* ControlledType */ + nodeAccessor]) {
1396
+ case 0 /* InputChecked */:
1397
+ controllable_input_checked_effect(scope, nodeAccessor);
1398
+ break;
1399
+ case 1 /* InputCheckedValue */:
1400
+ controllable_input_checkedValue_effect(scope, nodeAccessor);
1401
+ break;
1402
+ case 2 /* InputValue */:
1403
+ controllable_input_value_effect(scope, nodeAccessor);
1404
+ break;
1405
+ case 3 /* SelectValue */:
1406
+ controllable_select_value_effect(scope, nodeAccessor);
1407
+ break;
1408
+ case 4 /* DetailsOrDialogOpen */:
1409
+ controllable_detailsOrDialog_open_effect(scope, nodeAccessor);
1410
+ break;
1411
+ }
1412
+ for (const name in events) {
1413
+ on(el, name, events[name]);
1251
1414
  }
1252
- requestAnimationFrame(triggerMacroTask);
1253
1415
  }
1254
- function triggerMacroTask() {
1255
- if (!channel) {
1256
- channel = new MessageChannel();
1257
- channel.port1.onmessage = () => {
1258
- isScheduled = 0;
1259
- if (true) {
1260
- const run2 = runTask;
1261
- runTask = void 0;
1262
- run2();
1263
- } else {
1264
- run();
1265
- }
1266
- };
1267
- }
1268
- channel.port2.postMessage(0);
1416
+ function html(scope, value2, accessor) {
1417
+ const firstChild = scope[accessor];
1418
+ const parentNode = firstChild.parentNode;
1419
+ const lastChild = scope["DynamicPlaceholderLastChild:" /* DynamicPlaceholderLastChild */ + accessor] || firstChild;
1420
+ const newContent = parseHTML(
1421
+ value2 || value2 === 0 ? value2 + "" : "",
1422
+ parentNode.namespaceURI
1423
+ );
1424
+ insertChildNodes(
1425
+ parentNode,
1426
+ firstChild,
1427
+ scope[accessor] = newContent.firstChild || newContent.appendChild(new Text()),
1428
+ scope["DynamicPlaceholderLastChild:" /* DynamicPlaceholderLastChild */ + accessor] = newContent.lastChild
1429
+ );
1430
+ removeChildNodes(firstChild, lastChild);
1269
1431
  }
1270
-
1271
- // src/dom/signals.ts
1272
- function state(valueAccessor, fn) {
1273
- if (true) {
1274
- var id = +valueAccessor.slice(
1275
- valueAccessor.lastIndexOf("/") + 1
1276
- );
1277
- valueAccessor = valueAccessor.slice(
1278
- 0,
1279
- valueAccessor.lastIndexOf("/")
1280
- );
1281
- }
1282
- const valueChangeAccessor = "TagVariableChange:" /* TagVariableChange */ + valueAccessor;
1283
- const update = (scope, value2) => {
1284
- if (scope[valueAccessor] !== value2) {
1285
- scope[valueAccessor] = value2;
1286
- fn(scope, value2);
1287
- }
1288
- };
1289
- return (scope, value2, valueChange) => {
1290
- if (rendering) {
1291
- if ((scope[valueChangeAccessor] = valueChange) && scope[valueAccessor] !== value2 || !(valueAccessor in scope)) {
1292
- scope[valueAccessor] = value2;
1293
- fn(scope, value2);
1294
- }
1295
- } else if (scope[valueChangeAccessor]) {
1296
- scope[valueChangeAccessor](value2);
1297
- } else {
1298
- schedule();
1299
- queueRender(
1300
- scope,
1301
- update,
1302
- true ? id : valueAccessor,
1303
- value2
1432
+ function normalizeClientRender(value2) {
1433
+ const renderer = normalizeDynamicRenderer(value2);
1434
+ if (renderer) {
1435
+ if (renderer.___id) {
1436
+ return renderer;
1437
+ } else if (true) {
1438
+ throw new Error(
1439
+ `Invalid \`content\` attribute. Received ${typeof value2}`
1304
1440
  );
1305
1441
  }
1306
- return value2;
1307
- };
1308
- }
1309
- function value(valueAccessor, fn = () => {
1310
- }) {
1311
- return (scope, value2) => {
1312
- if (!(valueAccessor in scope) || scope[valueAccessor] !== value2) {
1313
- scope[valueAccessor] = value2;
1314
- fn(scope, value2);
1315
- }
1316
- };
1442
+ }
1317
1443
  }
1318
- function intersection(id, fn, defaultPending = 1, scopeIdAccessor = /* @__KEY__ */ "___id") {
1319
- return (scope) => {
1320
- if (scope.___creating) {
1321
- if (scope[id] === void 0) {
1322
- scope[id] = defaultPending;
1323
- } else if (!--scope[id]) {
1324
- fn(scope);
1444
+ function props(scope, nodeIndex, index) {
1445
+ const nextProps = scope[index];
1446
+ const prevProps = scope[index + "-"];
1447
+ const node = scope[nodeIndex];
1448
+ if (prevProps) {
1449
+ for (const name in prevProps) {
1450
+ if (!(name in nextProps)) {
1451
+ node[name] = void 0;
1325
1452
  }
1326
- } else {
1327
- queueRender(scope, fn, id, 0, scope[scopeIdAccessor]);
1328
- }
1329
- };
1330
- }
1331
- function loopClosure(valueAccessor, ownerLoopNodeAccessor, fn) {
1332
- const childSignal = closure(valueAccessor, fn);
1333
- const loopScopeAccessor = "LoopScopeArray:" /* LoopScopeArray */ + ownerLoopNodeAccessor;
1334
- const loopScopeMapAccessor = "LoopScopeMap:" /* LoopScopeMap */ + ownerLoopNodeAccessor;
1335
- const ownerSignal = (ownerScope) => {
1336
- const scopes = ownerScope[loopScopeAccessor] ||= ownerScope[loopScopeMapAccessor] ? [...ownerScope[loopScopeMapAccessor].values()] : [];
1337
- const [firstScope] = scopes;
1338
- if (firstScope) {
1339
- queueRender(
1340
- ownerScope,
1341
- () => {
1342
- for (const scope of scopes) {
1343
- if (!scope.___creating && !scope.___destroyed) {
1344
- childSignal(scope);
1345
- }
1346
- }
1347
- },
1348
- -1,
1349
- 0,
1350
- firstScope.___id
1351
- );
1352
- }
1353
- };
1354
- ownerSignal._ = childSignal;
1355
- return ownerSignal;
1356
- }
1357
- function conditionalClosure(valueAccessor, ownerConditionalNodeAccessor, branch, fn) {
1358
- const childSignal = closure(valueAccessor, fn);
1359
- const scopeAccessor = "ConditionalScope:" /* ConditionalScope */ + ownerConditionalNodeAccessor;
1360
- const branchAccessor = "ConditionalRenderer:" /* ConditionalRenderer */ + ownerConditionalNodeAccessor;
1361
- const ownerSignal = (scope) => {
1362
- const ifScope = scope[scopeAccessor];
1363
- if (ifScope && !ifScope.___creating && scope[branchAccessor] === branch) {
1364
- queueRender(ifScope, childSignal, -1);
1365
1453
  }
1366
- };
1367
- ownerSignal._ = childSignal;
1368
- return ownerSignal;
1369
- }
1370
- function subscribeToScopeSet(ownerScope, accessor, scope) {
1371
- const subscribers = ownerScope[accessor] ||= /* @__PURE__ */ new Set();
1372
- if (!subscribers.has(scope)) {
1373
- subscribers.add(scope);
1374
- getAbortSignal(scope, -1).addEventListener(
1375
- "abort",
1376
- () => ownerScope[accessor].delete(scope)
1377
- );
1378
1454
  }
1455
+ for (const name in nextProps) {
1456
+ node[name] = nextProps[name];
1457
+ }
1458
+ scope[index + "-"] = nextProps;
1379
1459
  }
1380
- function dynamicClosure(...closureSignals) {
1381
- const [{ ___scopeInstancesAccessor, ___signalIndexAccessor }] = closureSignals;
1382
- for (let i = closureSignals.length; i--; ) {
1383
- closureSignals[i].___index = i;
1460
+ function normalizeAttrValue(value2) {
1461
+ if (value2 || value2 === 0) {
1462
+ return value2 === true ? "" : value2 + "";
1384
1463
  }
1385
- return (scope) => {
1386
- if (scope[___scopeInstancesAccessor]) {
1387
- for (const childScope of scope[___scopeInstancesAccessor]) {
1388
- if (!childScope.___creating) {
1389
- queueRender(
1390
- childScope,
1391
- closureSignals[childScope[___signalIndexAccessor]],
1392
- -1
1393
- );
1394
- }
1395
- }
1396
- }
1397
- };
1398
1464
  }
1399
- function dynamicClosureRead(valueAccessor, fn, getOwnerScope) {
1400
- const childSignal = closure(valueAccessor, fn, getOwnerScope);
1401
- const closureSignal = (scope) => {
1402
- scope[closureSignal.___signalIndexAccessor] = closureSignal.___index;
1403
- childSignal(scope);
1404
- subscribeToScopeSet(
1405
- getOwnerScope ? getOwnerScope(scope) : scope["_" /* Owner */],
1406
- closureSignal.___scopeInstancesAccessor,
1407
- scope
1408
- );
1409
- };
1410
- closureSignal.___scopeInstancesAccessor = "ClosureScopes:" /* ClosureScopes */ + valueAccessor;
1411
- closureSignal.___signalIndexAccessor = "ClosureSignalIndex:" /* ClosureSignalIndex */ + valueAccessor;
1412
- return closureSignal;
1465
+ function normalizeString(value2) {
1466
+ return value2 || value2 === 0 ? value2 + "" : "\u200D";
1413
1467
  }
1414
- function closure(valueAccessor, fn, getOwnerScope) {
1415
- return (scope) => {
1416
- fn(
1468
+ function lifecycle(scope, index, thisObj) {
1469
+ const instance = scope[index];
1470
+ if (instance) {
1471
+ Object.assign(instance, thisObj);
1472
+ instance.onUpdate?.();
1473
+ } else {
1474
+ scope[index] = thisObj;
1475
+ thisObj.onMount?.();
1476
+ getAbortSignal(
1417
1477
  scope,
1418
- (getOwnerScope ? getOwnerScope(scope) : scope["_" /* Owner */])[valueAccessor]
1419
- );
1420
- };
1421
- }
1422
- function setTagVar(scope, childAccessor, tagVarSignal2) {
1423
- scope[childAccessor]["#TagVariable" /* TagVariable */] = (value2) => tagVarSignal2(scope, value2);
1424
- }
1425
- var tagVarSignal = (scope, value2) => scope["#TagVariable" /* TagVariable */]?.(value2);
1426
- function setTagVarChange(scope, changeHandler) {
1427
- scope["#TagVariableChange" /* TagVariableChange */] = changeHandler;
1478
+ "LifecycleAbortController:" /* LifecycleAbortController */ + index
1479
+ ).onabort = () => thisObj.onDestroy?.();
1480
+ }
1428
1481
  }
1429
- var tagVarSignalChange = (scope, value2) => scope["#TagVariableChange" /* TagVariableChange */]?.(value2);
1430
- var tagIdsByGlobal = /* @__PURE__ */ new WeakMap();
1431
- function nextTagId({ $global }) {
1432
- const id = tagIdsByGlobal.get($global) || 0;
1433
- tagIdsByGlobal.set($global, id + 1);
1434
- return "c" + $global.runtimeId + $global.renderId + id.toString(36);
1482
+ function removeChildNodes(startNode, endNode) {
1483
+ const stop = endNode.nextSibling;
1484
+ let current = startNode;
1485
+ while (current !== stop) {
1486
+ const next = current.nextSibling;
1487
+ current.remove();
1488
+ current = next;
1489
+ }
1435
1490
  }
1436
- function effect(id, fn) {
1437
- register(id, fn);
1438
- return (scope) => {
1439
- queueEffect(scope, fn);
1440
- };
1491
+ function insertChildNodes(parentNode, referenceNode, startNode, endNode) {
1492
+ parentNode.insertBefore(toInsertNode(startNode, endNode), referenceNode);
1441
1493
  }
1442
- function* traverseAllHoisted(scope, path, curIndex = path.length - 1) {
1443
- if (scope) {
1444
- if (Symbol.iterator in scope) {
1445
- for (const s of scope instanceof Map ? scope.values() : scope) {
1446
- yield* traverseAllHoisted(s, path, curIndex);
1447
- }
1448
- } else if (curIndex) {
1449
- yield* traverseAllHoisted(scope[path[curIndex]], path, curIndex - 1);
1450
- } else {
1451
- yield scope[path[0]];
1452
- }
1494
+ function toInsertNode(startNode, endNode) {
1495
+ if (startNode === endNode) return startNode;
1496
+ const parent = new DocumentFragment();
1497
+ const stop = endNode.nextSibling;
1498
+ let current = startNode;
1499
+ while (current !== stop) {
1500
+ const next = current.nextSibling;
1501
+ parent.appendChild(current);
1502
+ current = next;
1453
1503
  }
1454
- }
1455
- function hoist(...path) {
1456
- return (scope) => {
1457
- const getOne = (...args) => iterator().next().value(...args);
1458
- const iterator = getOne[Symbol.iterator] = () => traverseAllHoisted(scope, path);
1459
- return getOne;
1460
- };
1504
+ return parent;
1461
1505
  }
1462
1506
 
1463
- // src/dom/walker.ts
1464
- var walker = /* @__PURE__ */ document.createTreeWalker(document);
1465
- function walk(startNode, walkCodes, branch) {
1466
- walker.currentNode = startNode;
1467
- walkInternal(0, walkCodes, branch);
1468
- }
1469
- function walkInternal(currentWalkIndex, walkCodes, scope) {
1470
- let value2;
1471
- let storedMultiplier = 0;
1472
- let currentMultiplier = 0;
1473
- let currentScopeIndex = 0;
1474
- for (; currentWalkIndex < walkCodes.length; ) {
1475
- value2 = walkCodes.charCodeAt(currentWalkIndex++);
1476
- currentMultiplier = storedMultiplier;
1477
- storedMultiplier = 0;
1478
- if (value2 === 32 /* Get */) {
1479
- const node = walker.currentNode;
1480
- scope[true ? getDebugKey(currentScopeIndex, walker.currentNode) : currentScopeIndex] = node;
1481
- scope["Getter:" /* Getter */ + (true ? getDebugKey(currentScopeIndex++, walker.currentNode) : currentScopeIndex++)] = () => node;
1482
- } else if (value2 === 37 /* Replace */ || value2 === 49 /* DynamicTagWithVar */) {
1483
- walker.currentNode.replaceWith(
1484
- walker.currentNode = scope[true ? getDebugKey(currentScopeIndex++, "#text") : currentScopeIndex++] = new Text()
1485
- );
1486
- if (value2 === 49 /* DynamicTagWithVar */) {
1487
- scope[true ? getDebugKey(currentScopeIndex++, "#scopeOffset") : currentScopeIndex++] = skipScope(scope);
1507
+ // src/dom/reconcile.ts
1508
+ var WRONG_POS = 2147483647;
1509
+ function reconcile(parent, oldBranches, newBranches, afterReference) {
1510
+ let oldStart = 0;
1511
+ let newStart = 0;
1512
+ let oldEnd = oldBranches.length - 1;
1513
+ let newEnd = newBranches.length - 1;
1514
+ let oldStartBranch = oldBranches[oldStart];
1515
+ let newStartBranch = newBranches[newStart];
1516
+ let oldEndBranch = oldBranches[oldEnd];
1517
+ let newEndBranch = newBranches[newEnd];
1518
+ let i;
1519
+ let j;
1520
+ let k;
1521
+ let nextSibling;
1522
+ let oldBranch;
1523
+ let newBranch;
1524
+ outer: {
1525
+ while (oldStartBranch === newStartBranch) {
1526
+ ++oldStart;
1527
+ ++newStart;
1528
+ if (oldStart > oldEnd || newStart > newEnd) {
1529
+ break outer;
1488
1530
  }
1489
- } else if (value2 === 38 /* EndChild */) {
1490
- return currentWalkIndex;
1491
- } else if (value2 === 47 /* BeginChild */ || value2 === 48 /* BeginChildWithVar */) {
1492
- currentWalkIndex = walkInternal(
1493
- currentWalkIndex,
1494
- walkCodes,
1495
- scope[true ? getDebugKey(currentScopeIndex++, "#childScope") : currentScopeIndex++] = createScope(scope.$global, scope.___closestBranch)
1496
- );
1497
- if (value2 === 48 /* BeginChildWithVar */) {
1498
- scope[true ? getDebugKey(currentScopeIndex++, "#scopeOffset") : currentScopeIndex++] = skipScope(scope);
1531
+ oldStartBranch = oldBranches[oldStart];
1532
+ newStartBranch = newBranches[newStart];
1533
+ }
1534
+ while (oldEndBranch === newEndBranch) {
1535
+ --oldEnd;
1536
+ --newEnd;
1537
+ if (oldStart > oldEnd || newStart > newEnd) {
1538
+ break outer;
1499
1539
  }
1500
- } else if (value2 < 91 /* NextEnd */ + 1) {
1501
- value2 = 20 /* Next */ * currentMultiplier + value2 - 67 /* Next */;
1502
- while (value2--) {
1503
- walker.nextNode();
1540
+ oldEndBranch = oldBranches[oldEnd];
1541
+ newEndBranch = newBranches[newEnd];
1542
+ }
1543
+ }
1544
+ if (oldStart > oldEnd) {
1545
+ if (newStart <= newEnd) {
1546
+ k = newEnd + 1;
1547
+ nextSibling = k < newBranches.length ? newBranches[k].___startNode : afterReference;
1548
+ do {
1549
+ insertBranchBefore(newBranches[newStart++], parent, nextSibling);
1550
+ } while (newStart <= newEnd);
1551
+ }
1552
+ } else if (newStart > newEnd) {
1553
+ do {
1554
+ removeAndDestroyBranch(oldBranches[oldStart++]);
1555
+ } while (oldStart <= oldEnd);
1556
+ } else {
1557
+ const oldLength = oldEnd - oldStart + 1;
1558
+ const newLength = newEnd - newStart + 1;
1559
+ const aNullable = oldBranches;
1560
+ const sources = new Array(newLength);
1561
+ for (i = 0; i < newLength; ++i) {
1562
+ sources[i] = -1;
1563
+ }
1564
+ let pos = 0;
1565
+ let synced = 0;
1566
+ const keyIndex = /* @__PURE__ */ new Map();
1567
+ for (j = newStart; j <= newEnd; ++j) {
1568
+ keyIndex.set(newBranches[j], j);
1569
+ }
1570
+ for (i = oldStart; i <= oldEnd && synced < newLength; ++i) {
1571
+ oldBranch = oldBranches[i];
1572
+ j = keyIndex.get(oldBranch);
1573
+ if (j !== void 0) {
1574
+ pos = pos > j ? WRONG_POS : j;
1575
+ ++synced;
1576
+ newBranch = newBranches[j];
1577
+ sources[j - newStart] = i;
1578
+ aNullable[i] = null;
1504
1579
  }
1505
- } else if (value2 < 106 /* OverEnd */ + 1) {
1506
- value2 = 10 /* Over */ * currentMultiplier + value2 - 97 /* Over */;
1507
- while (value2--) {
1508
- walker.nextSibling();
1580
+ }
1581
+ if (oldLength === oldBranches.length && synced === 0) {
1582
+ for (; newStart < newLength; ++newStart) {
1583
+ insertBranchBefore(newBranches[newStart], parent, afterReference);
1509
1584
  }
1510
- } else if (value2 < 116 /* OutEnd */ + 1) {
1511
- value2 = 10 /* Out */ * currentMultiplier + value2 - 107 /* Out */;
1512
- while (value2--) {
1513
- walker.parentNode();
1585
+ for (; oldStart < oldLength; ++oldStart) {
1586
+ removeAndDestroyBranch(oldBranches[oldStart]);
1514
1587
  }
1515
- walker.nextSibling();
1516
1588
  } else {
1517
- if (value2 < 117 /* Multiplier */ || value2 > 126 /* MultiplierEnd */) {
1518
- throw new Error(`Unknown walk code: ${value2}`);
1589
+ i = oldLength - synced;
1590
+ while (i > 0) {
1591
+ oldBranch = aNullable[oldStart++];
1592
+ if (oldBranch !== null) {
1593
+ removeAndDestroyBranch(oldBranch);
1594
+ i--;
1595
+ }
1596
+ }
1597
+ if (pos === WRONG_POS) {
1598
+ const seq = longestIncreasingSubsequence(sources);
1599
+ j = seq.length - 1;
1600
+ k = newBranches.length;
1601
+ for (i = newLength - 1; i >= 0; --i) {
1602
+ if (sources[i] === -1) {
1603
+ pos = i + newStart;
1604
+ newBranch = newBranches[pos++];
1605
+ nextSibling = pos < k ? newBranches[pos].___startNode : afterReference;
1606
+ insertBranchBefore(newBranch, parent, nextSibling);
1607
+ } else {
1608
+ if (j < 0 || i !== seq[j]) {
1609
+ pos = i + newStart;
1610
+ newBranch = newBranches[pos++];
1611
+ nextSibling = pos < k ? newBranches[pos].___startNode : afterReference;
1612
+ insertBranchBefore(newBranch, parent, nextSibling);
1613
+ } else {
1614
+ --j;
1615
+ }
1616
+ }
1617
+ }
1618
+ } else if (synced !== newLength) {
1619
+ k = newBranches.length;
1620
+ for (i = newLength - 1; i >= 0; --i) {
1621
+ if (sources[i] === -1) {
1622
+ pos = i + newStart;
1623
+ newBranch = newBranches[pos++];
1624
+ nextSibling = pos < k ? newBranches[pos].___startNode : afterReference;
1625
+ insertBranchBefore(newBranch, parent, nextSibling);
1626
+ }
1627
+ }
1519
1628
  }
1520
- storedMultiplier = currentMultiplier * 10 /* Multiplier */ + value2 - 117 /* Multiplier */;
1521
1629
  }
1522
1630
  }
1523
1631
  }
1524
- function getDebugKey(index, node) {
1525
- if (typeof node === "string") {
1526
- return `${node}/${index}`;
1527
- } else if (node.nodeType === 3 /* Text */) {
1528
- return `#text/${index}`;
1529
- } else if (node.nodeType === 8 /* Comment */) {
1530
- return `#comment/${index}`;
1531
- } else if (node.nodeType === 1 /* Element */) {
1532
- return `#${node.tagName.toLowerCase()}/${index}`;
1533
- }
1534
- return index;
1535
- }
1536
-
1537
- // src/dom/renderer.ts
1538
- function createBranch($global, renderer, parentScope, parentNode) {
1539
- const branch = createScope($global);
1540
- const parentBranch = parentScope?.___closestBranch;
1541
- branch["_" /* Owner */] = renderer.___owner || parentScope;
1542
- branch.___closestBranch = branch;
1543
- if (parentBranch) {
1544
- branch.___parentBranch = parentBranch;
1545
- (parentBranch.___branchScopes ||= /* @__PURE__ */ new Set()).add(branch);
1546
- }
1547
- if (true) {
1548
- branch.___renderer = renderer;
1549
- }
1550
- renderer.___clone?.(
1551
- branch,
1552
- parentNode.namespaceURI
1553
- );
1554
- return branch;
1555
- }
1556
- function createAndSetupBranch($global, renderer, parentScope, parentNode) {
1557
- return setupBranch(
1558
- renderer,
1559
- createBranch($global, renderer, parentScope, parentNode)
1560
- );
1561
- }
1562
- function setupBranch(renderer, branch) {
1563
- if (renderer.___setup) {
1564
- queueRender(branch, renderer.___setup, -1);
1632
+ function longestIncreasingSubsequence(a) {
1633
+ const p = a.slice();
1634
+ const result = [0];
1635
+ let u;
1636
+ let v;
1637
+ for (let i = 0, il = a.length; i < il; ++i) {
1638
+ if (a[i] === -1) {
1639
+ continue;
1640
+ }
1641
+ const j = result[result.length - 1];
1642
+ if (a[j] < a[i]) {
1643
+ p[i] = j;
1644
+ result.push(i);
1645
+ continue;
1646
+ }
1647
+ u = 0;
1648
+ v = result.length - 1;
1649
+ while (u < v) {
1650
+ const c = (u + v) / 2 | 0;
1651
+ if (a[result[c]] < a[i]) {
1652
+ u = c + 1;
1653
+ } else {
1654
+ v = c;
1655
+ }
1656
+ }
1657
+ if (a[i] < a[result[u]]) {
1658
+ if (u > 0) {
1659
+ p[i] = result[u - 1];
1660
+ }
1661
+ result[u] = i;
1662
+ }
1565
1663
  }
1566
- return branch;
1567
- }
1568
- function createContent(id, template, walks, setup, params, dynamicScopesAccessor) {
1569
- walks = walks ? walks.replace(/[^\0-1]+$/, "") : "";
1570
- setup = setup ? setup._ || setup : void 0;
1571
- params ||= void 0;
1572
- const clone = template ? (branch, ns) => {
1573
- ((cloneCache[ns] ||= {})[template] ||= createCloneableHTML(
1574
- template,
1575
- ns
1576
- ))(branch, walks);
1577
- } : (branch) => {
1578
- walk(
1579
- branch.___startNode = branch.___endNode = new Text(),
1580
- walks,
1581
- branch
1582
- );
1583
- };
1584
- return (owner) => {
1585
- return {
1586
- ___id: id,
1587
- ___clone: clone,
1588
- ___owner: owner,
1589
- ___setup: setup,
1590
- ___params: params,
1591
- ___accessor: dynamicScopesAccessor
1592
- };
1593
- };
1594
- }
1595
- function registerContent(id, template, walks, setup, params, dynamicScopesAccessor) {
1596
- return register(
1597
- id,
1598
- createContent(id, template, walks, setup, params, dynamicScopesAccessor)
1599
- );
1600
- }
1601
- function localClosures(renderer, closureFns) {
1602
- const closureSignals = {};
1603
- for (const key in closureFns) {
1604
- closureSignals[key] = value(key, closureFns[key]);
1664
+ u = result.length;
1665
+ v = result[u - 1];
1666
+ while (u-- > 0) {
1667
+ result[u] = v;
1668
+ v = p[v];
1605
1669
  }
1606
- return (owner, closureValues) => {
1607
- const instance = renderer(owner);
1608
- instance.___localClosures = closureSignals;
1609
- instance.___localClosureValues = closureValues;
1610
- return instance;
1611
- };
1612
- }
1613
- function createRenderer(template, walks, setup, params) {
1614
- return createContent("", template, walks, setup, params)();
1615
- }
1616
- var cloneCache = {};
1617
- function createCloneableHTML(html2, ns) {
1618
- const { firstChild, lastChild } = parseHTML(html2, ns);
1619
- const parent = document.createElementNS(ns, "t");
1620
- insertChildNodes(parent, null, firstChild, lastChild);
1621
- return firstChild === lastChild && firstChild.nodeType < 8 /* Comment */ ? (branch, walks) => {
1622
- walk(
1623
- branch.___startNode = branch.___endNode = firstChild.cloneNode(true),
1624
- walks,
1625
- branch
1626
- );
1627
- } : (branch, walks) => {
1628
- const clone = parent.cloneNode(true);
1629
- walk(clone.firstChild, walks, branch);
1630
- branch.___startNode = clone.firstChild;
1631
- branch.___endNode = clone.lastChild;
1632
- };
1670
+ return result;
1633
1671
  }
1634
1672
 
1635
1673
  // src/dom/control-flow.ts