@ng-native/components 0.18.1 → 0.19.0
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/markdown-blocks.js +16 -10
- package/dist/markdown-blocks.js.map +1 -1
- package/dist/text-input.d.ts +9 -3
- package/dist/text-input.js +11 -5
- package/dist/text-input.js.map +1 -1
- package/dist/virtual-list.d.ts +5 -0
- package/dist/virtual-list.js +15 -1
- package/dist/virtual-list.js.map +1 -1
- package/package.json +3 -3
package/dist/markdown-blocks.js
CHANGED
|
@@ -274,26 +274,32 @@ function share(previous, next) {
|
|
|
274
274
|
}
|
|
275
275
|
function shareArray(previous, next) {
|
|
276
276
|
const out = next.slice();
|
|
277
|
+
// Each pair is compared once: the passes below meet at the same position, and comparing a
|
|
278
|
+
// changed block again in each of them made a nested one cost three times as much a level.
|
|
279
|
+
const compared = new Set();
|
|
280
|
+
const shareAt = (was, at) => {
|
|
281
|
+
if (was === at) {
|
|
282
|
+
if (compared.has(at))
|
|
283
|
+
return out[at];
|
|
284
|
+
compared.add(at);
|
|
285
|
+
}
|
|
286
|
+
return (out[at] = share(previous[was], out[at]));
|
|
287
|
+
};
|
|
277
288
|
let start = 0;
|
|
278
289
|
while (start < out.length && start < previous.length) {
|
|
279
|
-
|
|
280
|
-
if (kept !== previous[start])
|
|
290
|
+
if (shareAt(start, start) !== previous[start])
|
|
281
291
|
break;
|
|
282
|
-
|
|
292
|
+
start++;
|
|
283
293
|
}
|
|
284
294
|
let end = 0;
|
|
285
295
|
while (end < out.length - start && end < previous.length - start) {
|
|
286
|
-
const at = out.length - 1 - end;
|
|
287
296
|
const was = previous.length - 1 - end;
|
|
288
|
-
|
|
289
|
-
if (kept !== previous[was])
|
|
297
|
+
if (shareAt(was, out.length - 1 - end) !== previous[was])
|
|
290
298
|
break;
|
|
291
|
-
out[at] = kept;
|
|
292
299
|
end++;
|
|
293
300
|
}
|
|
294
|
-
for (let i = start; i < out.length - end && i < previous.length - end; i++)
|
|
295
|
-
|
|
296
|
-
}
|
|
301
|
+
for (let i = start; i < out.length - end && i < previous.length - end; i++)
|
|
302
|
+
shareAt(i, i);
|
|
297
303
|
const same = out.length === previous.length && out.every((one, i) => one === previous[i]);
|
|
298
304
|
return same ? previous : out;
|
|
299
305
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-blocks.js","sourceRoot":"","sources":["../src/markdown-blocks.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAmEnD,IAAI,aAA8C,CAAC;AAEnD,+FAA+F;AAC/F,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;YAAE,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,MAAM,GAAG,uEAAuE,CAAC;AAEvF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAgB,EAAE,GAAY,EAAE,IAAa,EAAE,EAAE;QACnF,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;QAC1D,MAAM,IAAI,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAI,EAAE,EAAE,CAAC,CAAC;QAC1E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,QAAQ,IAAI,CAAC,IAAI,GAAG,MAAM,IAAI,IAAI,GAAG,MAAM,CAAC,CAAC;QAC/E,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AACrD,MAAM,MAAM,GAAG,uBAAuB,CAAC;AAEvC,qFAAqF;AACrF,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACpF,CAAC;AAED,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AACjE,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO,MAAM,KAAK,IAAI,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACrE,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,OAAO,MAAM,KAAK,IAAI,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC7C,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACnC,8FAA8F;IAC9F,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,GAAG,2DAA2D,CAAC;AAE/E,gGAAgG;AAChG,SAAS,MAAM,CAAC,KAAY;IAC1B,MAAM,IAAI,GAAa,KAAqB,CAAC,IAAI,CAAC;IAClD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChE,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAE/D,qDAAqD;AACrD,MAAM,UAAU,cAAc,CAAC,MAAwB;IACrD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,8FAA8F;AAC9F,MAAM,MAAM,GAAgE;IAC1E,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QACjB,MAAM,OAAO,GAAG,KAAuB,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAE,KAA0B,CAAC,MAAM,CAAC;IACpE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,KAAoB,CAAC;QAClC,OAAO,IAAI,CAAC,MAAM;YAChB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;YACzB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;QACrB,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,CAAE,KAA2B,CAAC,MAAM,CAAC,EAAE;KACtF;IACD,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAoB,CAAC,CAAC;IAC7C,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAE,KAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;IAChF,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC1B,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,KAAK,GAAG,KAAqB,CAAC;QACpC,OAAO;YACL;gBACE,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACxD,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;aACvE;SACF,CAAC;IACJ,CAAC;IACD,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAE,KAAqB,CAAC,IAAI,CAAC;IACrD,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE;IACf,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE;IACb,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE;CACnB,CAAC;AAEF,SAAS,KAAK,CAAC,KAAY;IACzB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,2FAA2F;AAC3F,SAAS,OAAO,CAAC,IAAY;IAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzC,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACpG,CAAC;AAED,SAAS,IAAI,CAAC,KAAkB;IAC9B,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QACpC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACvC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG;YAC1F,QAAQ,EAAE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;SACtC,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,MAAwB;IAC1C,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,IAAI,GAAG,GAAqB,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,GAAG,GAAG,EAAE,CAAC;IACX,CAAC,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3D,MAAM,GAAG,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,KAAK,EAAE,CAAC;QACR,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,cAAc,CAAE,KAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,KAAK,EAAE,CAAC;IACR,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CAAC,IAAsB;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,IAAI,EAAE,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACpD,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,OAAO,CAAC,MAAoC;IACnD,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;AACtD,CAAC;AAED,SAAS,QAAQ,CAAC,KAAY;IAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,IAA+B,CAAC;IACnD,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAE,KAAuB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,+FAA+F;AAC/F,MAAM,OAAO,GAAiE;IAC5E,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,KAAoB,CAAC;QAClC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAE,KAAuB,CAAC,IAAI,CAAC,CAAC;IACzD,MAAM,EAAE,QAAQ;IAChB,EAAE,EAAE,QAAQ;IACZ,GAAG,EAAE,QAAQ;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAG,KAAyB,CAAC,IAAI,EAAE,CAAC;IAC9E,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,KAAoB,CAAC;QAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC3D,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,QAAQ,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7D,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAE,KAAsB,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAG,KAAqB,CAAC,IAAI,EAAE,CAAC;IACtE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE;CACnB,CAAC;AAEF,SAAS,MAAM,CAAC,KAAY;IAC1B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9E,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,IAAI,GAAG,IAAI,OAAO,EAAkB,CAAC;AAC3C,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAoB;IAC3C,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,GAAG,KAAK,SAAS;QAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,QAA8C,EAC9C,IAA8B;IAE9B,OAAO,QAAQ,CAAC,CAAC,CAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,CAA8B,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/E,CAAC;AAED,SAAS,KAAK,CAAC,QAAiB,EAAE,IAAa;IAC7C,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC/F,IAAI,QAAQ,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjE,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,UAAU,CAAC,QAAQ,EAAE,IAAiB,CAAC,CAAC;IAC5E,OAAO,WAAW,CAAC,QAAmC,EAAE,IAA+B,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,UAAU,CAAC,QAA4B,EAAE,IAAwB;IACxE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IACzB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAChD,IAAI,IAAI,KAAK,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM;QACpC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IACtB,CAAC;IACD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,OAAO,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,KAAK,IAAI,GAAG,GAAG,QAAQ,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;QACjE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC;QAChC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3C,IAAI,IAAI,KAAK,QAAQ,CAAC,GAAG,CAAC;YAAE,MAAM;QAClC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QACf,GAAG,EAAE,CAAC;IACR,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3E,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1F,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;AAC/B,CAAC;AAED,SAAS,WAAW,CAClB,QAAiC,EACjC,IAA6B;IAE7B,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IACzD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjF,IAAI,IAAI,KAAK,GAAG;YAAE,IAAI,GAAG,KAAK,CAAC;QAC/B,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,IAAI,IAAI;QAAE,OAAO,QAAQ,CAAC;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,GAAG,KAAK,SAAS;QAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1C,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * Marked's tokens, turned into the blocks `<markdown>` draws: the entities decoded, the links and\n * images held to the schemes they may use, raw HTML made plain text, and an image lifted out of\n * its paragraph, since a `<text>` cannot hold one.\n *\n * Plain functions with no Angular in them, so the policy is the same wherever the tokens came from:\n * `marked.lexer` on the device, or a build step that lexed them ahead of time.\n */\nimport type { Token, Tokens } from 'marked';\nimport { HTML_ENTITIES } from './html-entities.ts';\n\n/** The elements a document is drawn with, by the HTML names the Markdown would have produced. */\nexport type MarkdownElement =\n | 'h1'\n | 'h2'\n | 'h3'\n | 'h4'\n | 'h5'\n | 'h6'\n | 'p'\n | 'blockquote'\n | 'ul'\n | 'ol'\n | 'li'\n | 'marker'\n | 'pre'\n | 'code'\n | 'strong'\n | 'em'\n | 'del'\n | 'a'\n | 'hr'\n | 'img'\n | 'table'\n | 'tr'\n | 'th'\n | 'td';\n\nexport type MarkdownInline =\n | { readonly kind: 'text'; readonly text: string }\n | { readonly kind: 'strong' | 'em' | 'del'; readonly children: readonly MarkdownInline[] }\n | { readonly kind: 'code'; readonly text: string }\n | {\n readonly kind: 'link';\n readonly href: string;\n readonly title: string | null;\n readonly children: readonly MarkdownInline[];\n };\n\nexport interface MarkdownListItem {\n readonly marker: string;\n readonly children: readonly MarkdownBlock[];\n}\n\nexport type MarkdownBlock =\n | {\n readonly kind: 'heading';\n readonly element: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n readonly children: readonly MarkdownInline[];\n }\n | { readonly kind: 'paragraph'; readonly children: readonly MarkdownInline[] }\n | { readonly kind: 'image'; readonly src: string; readonly alt: string }\n | { readonly kind: 'blockquote'; readonly children: readonly MarkdownBlock[] }\n | {\n readonly kind: 'list';\n readonly element: 'ul' | 'ol';\n readonly items: readonly MarkdownListItem[];\n }\n | { readonly kind: 'code'; readonly text: string }\n | { readonly kind: 'hr' }\n | {\n readonly kind: 'table';\n readonly header: readonly (readonly MarkdownInline[])[];\n readonly rows: readonly (readonly (readonly MarkdownInline[])[])[];\n };\n\nlet namedEntities: Map<string, string> | undefined;\n\n/** The character HTML names `name`, from its full table, built on the first name looked up. */\nfunction namedEntity(name: string): string | undefined {\n if (!namedEntities) {\n namedEntities = new Map();\n const pairs = HTML_ENTITIES.split(' ');\n for (let i = 0; i + 1 < pairs.length; i += 2) namedEntities.set(pairs[i]!, pairs[i + 1]!);\n }\n return namedEntities.get(name);\n}\n\nconst ENTITY = /&(?:#(\\d{1,7})|#[xX]([0-9a-fA-F]{1,6})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;\n\n/**\n * The text an HTML reader would show for `text`, in one pass so `&lt;` is `<` and not `<`.\n * A reference to no character, or to one outside Unicode, is the replacement character, as HTML\n * makes it; a name HTML does not have stays as written.\n */\nexport function decodeEntities(text: string): string {\n if (!text.includes('&')) return text;\n return text.replace(ENTITY, (whole, decimal?: string, hex?: string, name?: string) => {\n if (name !== undefined) return namedEntity(name) ?? whole;\n const code = decimal !== undefined ? Number(decimal) : parseInt(hex!, 16);\n const valid = code > 0 && code <= 0x10ffff && (code < 0xd800 || code > 0xdfff);\n return valid ? String.fromCodePoint(code) : '�';\n });\n}\n\n/**\n * What a URL parser ignores while it reads a scheme: the C0 controls and the space, and the C1\n * controls and DEL beside them. `java\\tscript:` is `javascript:` to the thing that opens it.\n */\nconst IGNORED_IN_SCHEME = /[\\u0000- \\u007f-\\u009f]/g;\nconst SCHEME = /^([a-z][a-z0-9+.-]*):/;\n\n/** The scheme `url` would be opened with, lowercased, or null for a relative one. */\nexport function schemeOf(url: string): string | null {\n return SCHEME.exec(url.replace(IGNORED_IN_SCHEME, '').toLowerCase())?.[1] ?? null;\n}\n\nconst LINK_SCHEMES = new Set(['http', 'https', 'mailto', 'tel']);\nconst IMAGE_SCHEMES = new Set(['http', 'https']);\n\n/**\n * A link's target if it may be followed: `http`, `https`, `mailto`, `tel`, or relative, which is\n * the app's to resolve. Anything else, `javascript:`, `data:`, `vbscript:` and `file:` among\n * them, is null, and the link is drawn as its text. The scheme is read after the trim, so\n * whitespace the trim strips cannot hide one.\n */\nexport function linkTarget(href: string): string | null {\n const target = href.trim();\n const scheme = schemeOf(target);\n return scheme === null || LINK_SCHEMES.has(scheme) ? target : null;\n}\n\n/** Whether `href` is absolute in a scheme a link may be followed to, and so is opened on press. */\nexport function opensOnPress(href: string): boolean {\n const scheme = schemeOf(href.trim());\n return scheme !== null && LINK_SCHEMES.has(scheme);\n}\n\n/**\n * An image's address if it may be loaded: `http`, `https`, or a picture written into the document\n * as a `data:` url of a raster type. A pasted screenshot arrives that way from a web editor, and\n * a native image only decodes such a picture: nothing in it runs. Any other `data:` url, an SVG\n * or HTML among them, is refused, as is every other scheme.\n */\nexport function imageSource(href: string): string | null {\n const source = href.trim();\n const scheme = schemeOf(source);\n if (scheme === null) return null;\n if (IMAGE_SCHEMES.has(scheme)) return source;\n if (scheme !== 'data') return null;\n // A native loader may not decode a url with whitespace in it, so a wrapped payload is joined.\n const joined = source.replace(/\\s+/g, '');\n return DATA_IMAGE.test(joined) ? joined : null;\n}\n\n/** A base64 `data:` url of a raster picture: PNG, JPEG, GIF or WebP. */\nconst DATA_IMAGE = /^data:image\\/(?:png|jpe?g|gif|webp);base64,[a-z0-9+/=]+$/i;\n\n/** A link's or an image's target with its entities decoded, or null when it is not a string. */\nfunction hrefOf(token: Token): string | null {\n const href: unknown = (token as Tokens.Link).href;\n return typeof href === 'string' ? decodeEntities(href) : null;\n}\n\nconst HEADINGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;\n\n/** The blocks a document of `tokens` is drawn as. */\nexport function markdownBlocks(tokens: readonly Token[]): MarkdownBlock[] {\n return tokens.flatMap(block);\n}\n\n/** What each kind of block token is drawn as. A kind not here is drawn as its source text. */\nconst BLOCKS: Readonly<Record<string, (token: Token) => MarkdownBlock[]>> = {\n heading: (token) => {\n const heading = token as Tokens.Heading;\n const depth = Math.min(Math.max(heading.depth, 1), 6);\n const children = trimmedEnd(inlines(heading.tokens));\n return [{ kind: 'heading', element: HEADINGS[depth - 1]!, children }];\n },\n paragraph: (token) => paragraphs((token as Tokens.Paragraph).tokens),\n text: (token) => {\n const text = token as Tokens.Text;\n return text.tokens\n ? paragraphs(text.tokens)\n : [{ kind: 'paragraph', children: [plain(softBreaks(text.text))] }];\n },\n blockquote: (token) => [\n { kind: 'blockquote', children: markdownBlocks((token as Tokens.Blockquote).tokens) },\n ],\n list: (token) => [list(token as Tokens.List)],\n code: (token) => [{ kind: 'code', text: indented((token as Tokens.Code).text) }],\n hr: () => [{ kind: 'hr' }],\n table: (token) => {\n const table = token as Tokens.Table;\n return [\n {\n kind: 'table',\n header: table.header.map((cell) => inlines(cell.tokens)),\n rows: table.rows.map((row) => row.map((cell) => inlines(cell.tokens))),\n },\n ];\n },\n html: (token) => literal((token as Tokens.HTML).text),\n space: () => [],\n def: () => [],\n checkbox: () => [],\n};\n\nfunction block(token: Token): MarkdownBlock[] {\n const draw = Object.hasOwn(BLOCKS, token.type) ? BLOCKS[token.type]! : null;\n return draw ? draw(token) : literal(token.raw ?? '');\n}\n\n/**\n * A code block's text with its first line's indent made of no-break spaces: a paragraph loses the\n * spaces at its start, and a block's indent is part of the code.\n */\nfunction indented(text: string): string {\n return text.replace(/^ +/, (spaces) => '\\u00a0'.repeat(spaces.length));\n}\n\n/** Text drawn as written, which is what raw HTML and a token nothing here knows become. */\nfunction literal(text: string): MarkdownBlock[] {\n const trimmed = text.replace(/\\n+$/, '');\n return trimmed.trim() ? [{ kind: 'paragraph', children: [{ kind: 'text', text: trimmed }] }] : [];\n}\n\nfunction list(token: Tokens.List): MarkdownBlock {\n const start = typeof token.start === 'number' ? token.start : 1;\n return {\n kind: 'list',\n element: token.ordered ? 'ol' : 'ul',\n items: token.items.map((item, index) => ({\n marker: item.task ? (item.checked ? '☑' : '☐') : token.ordered ? `${start + index}.` : '•',\n children: markdownBlocks(item.tokens),\n })),\n };\n}\n\n/**\n * A paragraph's runs, split around the images at its top level: an image is a block of its own,\n * and the text either side of it a paragraph each. An image whose address is refused, and one\n * inside a link or an emphasis, is its alt text instead.\n */\nfunction paragraphs(tokens: readonly Token[]): MarkdownBlock[] {\n const out: MarkdownBlock[] = [];\n let run: MarkdownInline[] = [];\n const flush = () => {\n if (run.some((one) => one.kind !== 'text' || one.text.trim())) {\n out.push({ kind: 'paragraph', children: trimmedEnd(run) });\n }\n run = [];\n };\n for (const token of tokens) {\n const href = token.type === 'image' ? hrefOf(token) : null;\n const src = href === null ? null : imageSource(href);\n if (src === null) {\n run.push(...inline(token));\n continue;\n }\n flush();\n out.push({ kind: 'image', src, alt: decodeEntities((token as Tokens.Image).text) });\n }\n flush();\n return out;\n}\n\n/**\n * Runs without the whitespace at their end, which a paragraph does not draw. The engine works out\n * that trim when a run changes, not when a run arrives after it, so a run that ended a streaming\n * paragraph and stops ending it would otherwise keep its trimmed space: `Run ` and then a code\n * span would read as one word.\n */\nfunction trimmedEnd(runs: MarkdownInline[]): MarkdownInline[] {\n const last = runs.at(-1);\n if (last?.kind !== 'text') return runs;\n const text = last.text.replace(/[ \\t\\n\\r\\f]+$/, '');\n if (text === last.text) return runs;\n return text ? [...runs.slice(0, -1), { kind: 'text', text }] : runs.slice(0, -1);\n}\n\nfunction inlines(tokens: readonly Token[] | undefined): MarkdownInline[] {\n return (tokens ?? []).flatMap(inline);\n}\n\n/**\n * Text with each line break the source wrapped it at made a space, as CommonMark reads a soft\n * break, with the spaces around it. A hard break is a `br` token of its own, and stays one.\n */\nfunction softBreaks(text: string): string {\n return text.replace(/ *\\n */g, ' ');\n}\n\nfunction plain(text: string): MarkdownInline {\n return { kind: 'text', text: decodeEntities(text) };\n}\n\nfunction emphasis(token: Token): MarkdownInline[] {\n const kind = token.type as 'strong' | 'em' | 'del';\n return [{ kind, children: inlines((token as Tokens.Strong).tokens) }];\n}\n\n/** What each kind of inline token is drawn as. A kind not here is drawn as its source text. */\nconst INLINES: Readonly<Record<string, (token: Token) => MarkdownInline[]>> = {\n text: (token) => {\n const text = token as Tokens.Text;\n return text.tokens ? inlines(text.tokens) : [plain(softBreaks(text.text))];\n },\n escape: (token) => [plain((token as Tokens.Escape).text)],\n strong: emphasis,\n em: emphasis,\n del: emphasis,\n codespan: (token) => [{ kind: 'code', text: (token as Tokens.Codespan).text }],\n br: () => [{ kind: 'text', text: '\\n' }],\n link: (token) => {\n const link = token as Tokens.Link;\n const children = inlines(link.tokens);\n const decoded = hrefOf(link);\n const href = decoded === null ? null : linkTarget(decoded);\n if (href === null) return children;\n const title = link.title ? decodeEntities(link.title) : null;\n return [{ kind: 'link', href, title, children }];\n },\n image: (token) => [plain((token as Tokens.Image).text)],\n html: (token) => [{ kind: 'text', text: (token as Tokens.HTML).text }],\n checkbox: () => [],\n};\n\nfunction inline(token: Token): MarkdownInline[] {\n const draw = Object.hasOwn(INLINES, token.type) ? INLINES[token.type]! : null;\n if (draw) return draw(token);\n return token.raw ? [{ kind: 'text', text: token.raw }] : [];\n}\n\nconst keys = new WeakMap<object, number>();\nlet lastKey = 0;\n\n/**\n * A key for `block` that stays the same while it is drawn: a block kept from the document before\n * keeps its own, and one {@link shareBlocks} made in place of an edited one takes that one's.\n */\nexport function blockKey(block: MarkdownBlock): number {\n let key = keys.get(block);\n if (key === undefined) keys.set(block, (key = ++lastKey));\n return key;\n}\n\n/**\n * `next`, with every part of it that equals the same part of `previous` replaced by that part, so\n * a block that did not change is the object drawn already and is not drawn again. The two are\n * matched from each end, so a block added or removed in the middle leaves those either side of it\n * kept; what is left between is matched by position.\n */\nexport function shareBlocks(\n previous: readonly MarkdownBlock[] | undefined,\n next: readonly MarkdownBlock[],\n): readonly MarkdownBlock[] {\n return previous ? (share(previous, next) as readonly MarkdownBlock[]) : next;\n}\n\nfunction share(previous: unknown, next: unknown): unknown {\n if (previous === next || typeof previous !== 'object' || typeof next !== 'object') return next;\n if (previous === null || next === null) return next;\n if (Array.isArray(previous) !== Array.isArray(next)) return next;\n if (Array.isArray(previous)) return shareArray(previous, next as unknown[]);\n return shareObject(previous as Record<string, unknown>, next as Record<string, unknown>);\n}\n\nfunction shareArray(previous: readonly unknown[], next: readonly unknown[]): readonly unknown[] {\n const out = next.slice();\n let start = 0;\n while (start < out.length && start < previous.length) {\n const kept = share(previous[start], out[start]);\n if (kept !== previous[start]) break;\n out[start++] = kept;\n }\n let end = 0;\n while (end < out.length - start && end < previous.length - start) {\n const at = out.length - 1 - end;\n const was = previous.length - 1 - end;\n const kept = share(previous[was], out[at]);\n if (kept !== previous[was]) break;\n out[at] = kept;\n end++;\n }\n for (let i = start; i < out.length - end && i < previous.length - end; i++) {\n out[i] = share(previous[i], out[i]);\n }\n const same = out.length === previous.length && out.every((one, i) => one === previous[i]);\n return same ? previous : out;\n}\n\nfunction shareObject(\n previous: Record<string, unknown>,\n next: Record<string, unknown>,\n): Record<string, unknown> {\n if (previous['kind'] !== next['kind']) return next;\n const names = Object.keys(next);\n let same = names.length === Object.keys(previous).length;\n const out: Record<string, unknown> = {};\n for (const name of names) {\n const was = previous[name];\n const kept = Object.hasOwn(previous, name) ? share(was, next[name]) : next[name];\n if (kept !== was) same = false;\n out[name] = kept;\n }\n if (same) return previous;\n const key = keys.get(previous);\n if (key !== undefined) keys.set(out, key);\n return out;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"markdown-blocks.js","sourceRoot":"","sources":["../src/markdown-blocks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Marked's tokens, turned into the blocks `<markdown>` draws: the entities decoded, the links and\n * images held to the schemes they may use, raw HTML made plain text, and an image lifted out of\n * its paragraph, since a `<text>` cannot hold one.\n *\n * Plain functions with no Angular in them, so the policy is the same wherever the tokens came from:\n * `marked.lexer` on the device, or a build step that lexed them ahead of time.\n */\nimport type { Token, Tokens } from 'marked';\nimport { HTML_ENTITIES } from './html-entities.ts';\n\n/** The elements a document is drawn with, by the HTML names the Markdown would have produced. */\nexport type MarkdownElement =\n | 'h1'\n | 'h2'\n | 'h3'\n | 'h4'\n | 'h5'\n | 'h6'\n | 'p'\n | 'blockquote'\n | 'ul'\n | 'ol'\n | 'li'\n | 'marker'\n | 'pre'\n | 'code'\n | 'strong'\n | 'em'\n | 'del'\n | 'a'\n | 'hr'\n | 'img'\n | 'table'\n | 'tr'\n | 'th'\n | 'td';\n\nexport type MarkdownInline =\n | { readonly kind: 'text'; readonly text: string }\n | { readonly kind: 'strong' | 'em' | 'del'; readonly children: readonly MarkdownInline[] }\n | { readonly kind: 'code'; readonly text: string }\n | {\n readonly kind: 'link';\n readonly href: string;\n readonly title: string | null;\n readonly children: readonly MarkdownInline[];\n };\n\nexport interface MarkdownListItem {\n readonly marker: string;\n readonly children: readonly MarkdownBlock[];\n}\n\nexport type MarkdownBlock =\n | {\n readonly kind: 'heading';\n readonly element: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n readonly children: readonly MarkdownInline[];\n }\n | { readonly kind: 'paragraph'; readonly children: readonly MarkdownInline[] }\n | { readonly kind: 'image'; readonly src: string; readonly alt: string }\n | { readonly kind: 'blockquote'; readonly children: readonly MarkdownBlock[] }\n | {\n readonly kind: 'list';\n readonly element: 'ul' | 'ol';\n readonly items: readonly MarkdownListItem[];\n }\n | { readonly kind: 'code'; readonly text: string }\n | { readonly kind: 'hr' }\n | {\n readonly kind: 'table';\n readonly header: readonly (readonly MarkdownInline[])[];\n readonly rows: readonly (readonly (readonly MarkdownInline[])[])[];\n };\n\nlet namedEntities: Map<string, string> | undefined;\n\n/** The character HTML names `name`, from its full table, built on the first name looked up. */\nfunction namedEntity(name: string): string | undefined {\n if (!namedEntities) {\n namedEntities = new Map();\n const pairs = HTML_ENTITIES.split(' ');\n for (let i = 0; i + 1 < pairs.length; i += 2) namedEntities.set(pairs[i]!, pairs[i + 1]!);\n }\n return namedEntities.get(name);\n}\n\nconst ENTITY = /&(?:#(\\d{1,7})|#[xX]([0-9a-fA-F]{1,6})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;\n\n/**\n * The text an HTML reader would show for `text`, in one pass so `&lt;` is `<` and not `<`.\n * A reference to no character, or to one outside Unicode, is the replacement character, as HTML\n * makes it; a name HTML does not have stays as written.\n */\nexport function decodeEntities(text: string): string {\n if (!text.includes('&')) return text;\n return text.replace(ENTITY, (whole, decimal?: string, hex?: string, name?: string) => {\n if (name !== undefined) return namedEntity(name) ?? whole;\n const code = decimal !== undefined ? Number(decimal) : parseInt(hex!, 16);\n const valid = code > 0 && code <= 0x10ffff && (code < 0xd800 || code > 0xdfff);\n return valid ? String.fromCodePoint(code) : '�';\n });\n}\n\n/**\n * What a URL parser ignores while it reads a scheme: the C0 controls and the space, and the C1\n * controls and DEL beside them. `java\\tscript:` is `javascript:` to the thing that opens it.\n */\nconst IGNORED_IN_SCHEME = /[\\u0000- \\u007f-\\u009f]/g;\nconst SCHEME = /^([a-z][a-z0-9+.-]*):/;\n\n/** The scheme `url` would be opened with, lowercased, or null for a relative one. */\nexport function schemeOf(url: string): string | null {\n return SCHEME.exec(url.replace(IGNORED_IN_SCHEME, '').toLowerCase())?.[1] ?? null;\n}\n\nconst LINK_SCHEMES = new Set(['http', 'https', 'mailto', 'tel']);\nconst IMAGE_SCHEMES = new Set(['http', 'https']);\n\n/**\n * A link's target if it may be followed: `http`, `https`, `mailto`, `tel`, or relative, which is\n * the app's to resolve. Anything else, `javascript:`, `data:`, `vbscript:` and `file:` among\n * them, is null, and the link is drawn as its text. The scheme is read after the trim, so\n * whitespace the trim strips cannot hide one.\n */\nexport function linkTarget(href: string): string | null {\n const target = href.trim();\n const scheme = schemeOf(target);\n return scheme === null || LINK_SCHEMES.has(scheme) ? target : null;\n}\n\n/** Whether `href` is absolute in a scheme a link may be followed to, and so is opened on press. */\nexport function opensOnPress(href: string): boolean {\n const scheme = schemeOf(href.trim());\n return scheme !== null && LINK_SCHEMES.has(scheme);\n}\n\n/**\n * An image's address if it may be loaded: `http`, `https`, or a picture written into the document\n * as a `data:` url of a raster type. A pasted screenshot arrives that way from a web editor, and\n * a native image only decodes such a picture: nothing in it runs. Any other `data:` url, an SVG\n * or HTML among them, is refused, as is every other scheme.\n */\nexport function imageSource(href: string): string | null {\n const source = href.trim();\n const scheme = schemeOf(source);\n if (scheme === null) return null;\n if (IMAGE_SCHEMES.has(scheme)) return source;\n if (scheme !== 'data') return null;\n // A native loader may not decode a url with whitespace in it, so a wrapped payload is joined.\n const joined = source.replace(/\\s+/g, '');\n return DATA_IMAGE.test(joined) ? joined : null;\n}\n\n/** A base64 `data:` url of a raster picture: PNG, JPEG, GIF or WebP. */\nconst DATA_IMAGE = /^data:image\\/(?:png|jpe?g|gif|webp);base64,[a-z0-9+/=]+$/i;\n\n/** A link's or an image's target with its entities decoded, or null when it is not a string. */\nfunction hrefOf(token: Token): string | null {\n const href: unknown = (token as Tokens.Link).href;\n return typeof href === 'string' ? decodeEntities(href) : null;\n}\n\nconst HEADINGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;\n\n/** The blocks a document of `tokens` is drawn as. */\nexport function markdownBlocks(tokens: readonly Token[]): MarkdownBlock[] {\n return tokens.flatMap(block);\n}\n\n/** What each kind of block token is drawn as. A kind not here is drawn as its source text. */\nconst BLOCKS: Readonly<Record<string, (token: Token) => MarkdownBlock[]>> = {\n heading: (token) => {\n const heading = token as Tokens.Heading;\n const depth = Math.min(Math.max(heading.depth, 1), 6);\n const children = trimmedEnd(inlines(heading.tokens));\n return [{ kind: 'heading', element: HEADINGS[depth - 1]!, children }];\n },\n paragraph: (token) => paragraphs((token as Tokens.Paragraph).tokens),\n text: (token) => {\n const text = token as Tokens.Text;\n return text.tokens\n ? paragraphs(text.tokens)\n : [{ kind: 'paragraph', children: [plain(softBreaks(text.text))] }];\n },\n blockquote: (token) => [\n { kind: 'blockquote', children: markdownBlocks((token as Tokens.Blockquote).tokens) },\n ],\n list: (token) => [list(token as Tokens.List)],\n code: (token) => [{ kind: 'code', text: indented((token as Tokens.Code).text) }],\n hr: () => [{ kind: 'hr' }],\n table: (token) => {\n const table = token as Tokens.Table;\n return [\n {\n kind: 'table',\n header: table.header.map((cell) => inlines(cell.tokens)),\n rows: table.rows.map((row) => row.map((cell) => inlines(cell.tokens))),\n },\n ];\n },\n html: (token) => literal((token as Tokens.HTML).text),\n space: () => [],\n def: () => [],\n checkbox: () => [],\n};\n\nfunction block(token: Token): MarkdownBlock[] {\n const draw = Object.hasOwn(BLOCKS, token.type) ? BLOCKS[token.type]! : null;\n return draw ? draw(token) : literal(token.raw ?? '');\n}\n\n/**\n * A code block's text with its first line's indent made of no-break spaces: a paragraph loses the\n * spaces at its start, and a block's indent is part of the code.\n */\nfunction indented(text: string): string {\n return text.replace(/^ +/, (spaces) => '\\u00a0'.repeat(spaces.length));\n}\n\n/** Text drawn as written, which is what raw HTML and a token nothing here knows become. */\nfunction literal(text: string): MarkdownBlock[] {\n const trimmed = text.replace(/\\n+$/, '');\n return trimmed.trim() ? [{ kind: 'paragraph', children: [{ kind: 'text', text: trimmed }] }] : [];\n}\n\nfunction list(token: Tokens.List): MarkdownBlock {\n const start = typeof token.start === 'number' ? token.start : 1;\n return {\n kind: 'list',\n element: token.ordered ? 'ol' : 'ul',\n items: token.items.map((item, index) => ({\n marker: item.task ? (item.checked ? '☑' : '☐') : token.ordered ? `${start + index}.` : '•',\n children: markdownBlocks(item.tokens),\n })),\n };\n}\n\n/**\n * A paragraph's runs, split around the images at its top level: an image is a block of its own,\n * and the text either side of it a paragraph each. An image whose address is refused, and one\n * inside a link or an emphasis, is its alt text instead.\n */\nfunction paragraphs(tokens: readonly Token[]): MarkdownBlock[] {\n const out: MarkdownBlock[] = [];\n let run: MarkdownInline[] = [];\n const flush = () => {\n if (run.some((one) => one.kind !== 'text' || one.text.trim())) {\n out.push({ kind: 'paragraph', children: trimmedEnd(run) });\n }\n run = [];\n };\n for (const token of tokens) {\n const href = token.type === 'image' ? hrefOf(token) : null;\n const src = href === null ? null : imageSource(href);\n if (src === null) {\n run.push(...inline(token));\n continue;\n }\n flush();\n out.push({ kind: 'image', src, alt: decodeEntities((token as Tokens.Image).text) });\n }\n flush();\n return out;\n}\n\n/**\n * Runs without the whitespace at their end, which a paragraph does not draw. The engine works out\n * that trim when a run changes, not when a run arrives after it, so a run that ended a streaming\n * paragraph and stops ending it would otherwise keep its trimmed space: `Run ` and then a code\n * span would read as one word.\n */\nfunction trimmedEnd(runs: MarkdownInline[]): MarkdownInline[] {\n const last = runs.at(-1);\n if (last?.kind !== 'text') return runs;\n const text = last.text.replace(/[ \\t\\n\\r\\f]+$/, '');\n if (text === last.text) return runs;\n return text ? [...runs.slice(0, -1), { kind: 'text', text }] : runs.slice(0, -1);\n}\n\nfunction inlines(tokens: readonly Token[] | undefined): MarkdownInline[] {\n return (tokens ?? []).flatMap(inline);\n}\n\n/**\n * Text with each line break the source wrapped it at made a space, as CommonMark reads a soft\n * break, with the spaces around it. A hard break is a `br` token of its own, and stays one.\n */\nfunction softBreaks(text: string): string {\n return text.replace(/ *\\n */g, ' ');\n}\n\nfunction plain(text: string): MarkdownInline {\n return { kind: 'text', text: decodeEntities(text) };\n}\n\nfunction emphasis(token: Token): MarkdownInline[] {\n const kind = token.type as 'strong' | 'em' | 'del';\n return [{ kind, children: inlines((token as Tokens.Strong).tokens) }];\n}\n\n/** What each kind of inline token is drawn as. A kind not here is drawn as its source text. */\nconst INLINES: Readonly<Record<string, (token: Token) => MarkdownInline[]>> = {\n text: (token) => {\n const text = token as Tokens.Text;\n return text.tokens ? inlines(text.tokens) : [plain(softBreaks(text.text))];\n },\n escape: (token) => [plain((token as Tokens.Escape).text)],\n strong: emphasis,\n em: emphasis,\n del: emphasis,\n codespan: (token) => [{ kind: 'code', text: (token as Tokens.Codespan).text }],\n br: () => [{ kind: 'text', text: '\\n' }],\n link: (token) => {\n const link = token as Tokens.Link;\n const children = inlines(link.tokens);\n const decoded = hrefOf(link);\n const href = decoded === null ? null : linkTarget(decoded);\n if (href === null) return children;\n const title = link.title ? decodeEntities(link.title) : null;\n return [{ kind: 'link', href, title, children }];\n },\n image: (token) => [plain((token as Tokens.Image).text)],\n html: (token) => [{ kind: 'text', text: (token as Tokens.HTML).text }],\n checkbox: () => [],\n};\n\nfunction inline(token: Token): MarkdownInline[] {\n const draw = Object.hasOwn(INLINES, token.type) ? INLINES[token.type]! : null;\n if (draw) return draw(token);\n return token.raw ? [{ kind: 'text', text: token.raw }] : [];\n}\n\nconst keys = new WeakMap<object, number>();\nlet lastKey = 0;\n\n/**\n * A key for `block` that stays the same while it is drawn: a block kept from the document before\n * keeps its own, and one {@link shareBlocks} made in place of an edited one takes that one's.\n */\nexport function blockKey(block: MarkdownBlock): number {\n let key = keys.get(block);\n if (key === undefined) keys.set(block, (key = ++lastKey));\n return key;\n}\n\n/**\n * `next`, with every part of it that equals the same part of `previous` replaced by that part, so\n * a block that did not change is the object drawn already and is not drawn again. The two are\n * matched from each end, so a block added or removed in the middle leaves those either side of it\n * kept; what is left between is matched by position.\n */\nexport function shareBlocks(\n previous: readonly MarkdownBlock[] | undefined,\n next: readonly MarkdownBlock[],\n): readonly MarkdownBlock[] {\n return previous ? (share(previous, next) as readonly MarkdownBlock[]) : next;\n}\n\nfunction share(previous: unknown, next: unknown): unknown {\n if (previous === next || typeof previous !== 'object' || typeof next !== 'object') return next;\n if (previous === null || next === null) return next;\n if (Array.isArray(previous) !== Array.isArray(next)) return next;\n if (Array.isArray(previous)) return shareArray(previous, next as unknown[]);\n return shareObject(previous as Record<string, unknown>, next as Record<string, unknown>);\n}\n\nfunction shareArray(previous: readonly unknown[], next: readonly unknown[]): readonly unknown[] {\n const out = next.slice();\n // Each pair is compared once: the passes below meet at the same position, and comparing a\n // changed block again in each of them made a nested one cost three times as much a level.\n const compared = new Set<number>();\n const shareAt = (was: number, at: number): unknown => {\n if (was === at) {\n if (compared.has(at)) return out[at];\n compared.add(at);\n }\n return (out[at] = share(previous[was], out[at]));\n };\n let start = 0;\n while (start < out.length && start < previous.length) {\n if (shareAt(start, start) !== previous[start]) break;\n start++;\n }\n let end = 0;\n while (end < out.length - start && end < previous.length - start) {\n const was = previous.length - 1 - end;\n if (shareAt(was, out.length - 1 - end) !== previous[was]) break;\n end++;\n }\n for (let i = start; i < out.length - end && i < previous.length - end; i++) shareAt(i, i);\n const same = out.length === previous.length && out.every((one, i) => one === previous[i]);\n return same ? previous : out;\n}\n\nfunction shareObject(\n previous: Record<string, unknown>,\n next: Record<string, unknown>,\n): Record<string, unknown> {\n if (previous['kind'] !== next['kind']) return next;\n const names = Object.keys(next);\n let same = names.length === Object.keys(previous).length;\n const out: Record<string, unknown> = {};\n for (const name of names) {\n const was = previous[name];\n const kept = Object.hasOwn(previous, name) ? share(was, next[name]) : next[name];\n if (kept !== was) same = false;\n out[name] = kept;\n }\n if (same) return previous;\n const key = keys.get(previous);\n if (key !== undefined) keys.set(out, key);\n return out;\n}\n"]}
|
package/dist/text-input.d.ts
CHANGED
|
@@ -21,9 +21,15 @@ export type SubmitBehavior = 'submit' | 'blurAndSubmit' | 'newline';
|
|
|
21
21
|
*
|
|
22
22
|
* The interesting part is the echo. A native text field owns state the user is actively
|
|
23
23
|
* changing, so JS and native disagree constantly. RN's protocol: native reports an `eventCount`
|
|
24
|
-
* with every change, JS passes the most recent one back
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* with every change, JS passes the most recent one back, and native ignores a `text` update whose
|
|
25
|
+
* count is stale, meaning the user has typed since. Without it, a controlled input fights the
|
|
26
|
+
* cursor and drops characters under fast typing.
|
|
27
|
+
*
|
|
28
|
+
* The engine commits the count as the `mostRecentEventCount` prop. Android takes the latest, as RN
|
|
29
|
+
* sends it; iOS takes 0 but where a multiline field's text style changes, since an echo with the
|
|
30
|
+
* current count replaces an empty field's first typed text there and drops the keystrokes queued
|
|
31
|
+
* behind it (see `echoedEventCount` in the engine). Text from code reaches iOS as the command
|
|
32
|
+
* below instead, which carries the count.
|
|
27
33
|
*
|
|
28
34
|
* The other direction is native holding text the app does not: a value set from code after the
|
|
29
35
|
* user has typed, or a keystroke the app refused or rewrote. It is controlled as RN's field is -
|
package/dist/text-input.js
CHANGED
|
@@ -19,9 +19,15 @@ import * as i0 from "@angular/core";
|
|
|
19
19
|
*
|
|
20
20
|
* The interesting part is the echo. A native text field owns state the user is actively
|
|
21
21
|
* changing, so JS and native disagree constantly. RN's protocol: native reports an `eventCount`
|
|
22
|
-
* with every change, JS passes the most recent one back
|
|
23
|
-
*
|
|
24
|
-
*
|
|
22
|
+
* with every change, JS passes the most recent one back, and native ignores a `text` update whose
|
|
23
|
+
* count is stale, meaning the user has typed since. Without it, a controlled input fights the
|
|
24
|
+
* cursor and drops characters under fast typing.
|
|
25
|
+
*
|
|
26
|
+
* The engine commits the count as the `mostRecentEventCount` prop. Android takes the latest, as RN
|
|
27
|
+
* sends it; iOS takes 0 but where a multiline field's text style changes, since an echo with the
|
|
28
|
+
* current count replaces an empty field's first typed text there and drops the keystrokes queued
|
|
29
|
+
* behind it (see `echoedEventCount` in the engine). Text from code reaches iOS as the command
|
|
30
|
+
* below instead, which carries the count.
|
|
25
31
|
*
|
|
26
32
|
* The other direction is native holding text the app does not: a value set from code after the
|
|
27
33
|
* user has typed, or a keystroke the app refused or rewrote. It is controlled as RN's field is -
|
|
@@ -308,7 +314,7 @@ export class TextInput extends ViewBase {
|
|
|
308
314
|
this.selectionReports.update((n) => n + 1);
|
|
309
315
|
}
|
|
310
316
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TextInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
311
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.0", type: TextInput, isStandalone: true, selector: "text-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, scrollEnabled: { classPropertyName: "scrollEnabled", publicName: "scrollEnabled", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, placeholderTextColor: { classPropertyName: "placeholderTextColor", publicName: "placeholderTextColor", isSignal: true, isRequired: false, transformFunction: null }, keyboardType: { classPropertyName: "keyboardType", publicName: "keyboardType", isSignal: true, isRequired: false, transformFunction: null }, returnKeyType: { classPropertyName: "returnKeyType", publicName: "returnKeyType", isSignal: true, isRequired: false, transformFunction: null }, submitBehavior: { classPropertyName: "submitBehavior", publicName: "submitBehavior", isSignal: true, isRequired: false, transformFunction: null }, secureTextEntry: { classPropertyName: "secureTextEntry", publicName: "secureTextEntry", isSignal: true, isRequired: false, transformFunction: null }, autoCapitalize: { classPropertyName: "autoCapitalize", publicName: "autoCapitalize", isSignal: true, isRequired: false, transformFunction: null }, autoCorrect: { classPropertyName: "autoCorrect", publicName: "autoCorrect", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, numberOfLines: { classPropertyName: "numberOfLines", publicName: "numberOfLines", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, selectionColor: { classPropertyName: "selectionColor", publicName: "selectionColor", isSignal: true, isRequired: false, transformFunction: null }, selectTextOnFocus: { classPropertyName: "selectTextOnFocus", publicName: "selectTextOnFocus", isSignal: true, isRequired: false, transformFunction: null }, caretHidden: { classPropertyName: "caretHidden", publicName: "caretHidden", isSignal: true, isRequired: false, transformFunction: null }, contextMenuHidden: { classPropertyName: "contextMenuHidden", publicName: "contextMenuHidden", isSignal: true, isRequired: false, transformFunction: null }, textAlign: { classPropertyName: "textAlign", publicName: "textAlign", isSignal: true, isRequired: false, transformFunction: null }, allowFontScaling: { classPropertyName: "allowFontScaling", publicName: "allowFontScaling", isSignal: true, isRequired: false, transformFunction: null }, maxFontSizeMultiplier: { classPropertyName: "maxFontSizeMultiplier", publicName: "maxFontSizeMultiplier", isSignal: true, isRequired: false, transformFunction: null }, inputAccessoryViewID: { classPropertyName: "inputAccessoryViewID", publicName: "inputAccessoryViewID", isSignal: true, isRequired: false, transformFunction: null }, clearButtonMode: { classPropertyName: "clearButtonMode", publicName: "clearButtonMode", isSignal: true, isRequired: false, transformFunction: null }, clearTextOnFocus: { classPropertyName: "clearTextOnFocus", publicName: "clearTextOnFocus", isSignal: true, isRequired: false, transformFunction: null }, enablesReturnKeyAutomatically: { classPropertyName: "enablesReturnKeyAutomatically", publicName: "enablesReturnKeyAutomatically", isSignal: true, isRequired: false, transformFunction: null }, keyboardAppearance: { classPropertyName: "keyboardAppearance", publicName: "keyboardAppearance", isSignal: true, isRequired: false, transformFunction: null }, passwordRules: { classPropertyName: "passwordRules", publicName: "passwordRules", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, smartInsertDelete: { classPropertyName: "smartInsertDelete", publicName: "smartInsertDelete", isSignal: true, isRequired: false, transformFunction: null }, dataDetectorTypes: { classPropertyName: "dataDetectorTypes", publicName: "dataDetectorTypes", isSignal: true, isRequired: false, transformFunction: null }, textContentType: { classPropertyName: "textContentType", publicName: "textContentType", isSignal: true, isRequired: false, transformFunction: null }, autoComplete: { classPropertyName: "autoComplete", publicName: "autoComplete", isSignal: true, isRequired: false, transformFunction: null }, underlineColorAndroid: { classPropertyName: "underlineColorAndroid", publicName: "underlineColorAndroid", isSignal: true, isRequired: false, transformFunction: null }, cursorColor: { classPropertyName: "cursorColor", publicName: "cursorColor", isSignal: true, isRequired: false, transformFunction: null }, selectionHandleColor: { classPropertyName: "selectionHandleColor", publicName: "selectionHandleColor", isSignal: true, isRequired: false, transformFunction: null }, textAlignVertical: { classPropertyName: "textAlignVertical", publicName: "textAlignVertical", isSignal: true, isRequired: false, transformFunction: null }, importantForAutofill: { classPropertyName: "importantForAutofill", publicName: "importantForAutofill", isSignal: true, isRequired: false, transformFunction: null }, showSoftInputOnFocus: { classPropertyName: "showSoftInputOnFocus", publicName: "showSoftInputOnFocus", isSignal: true, isRequired: false, transformFunction: null }, disableFullscreenUI: { classPropertyName: "disableFullscreenUI", publicName: "disableFullscreenUI", isSignal: true, isRequired: false, transformFunction: null }, inlineImageLeft: { classPropertyName: "inlineImageLeft", publicName: "inlineImageLeft", isSignal: true, isRequired: false, transformFunction: null }, inlineImagePadding: { classPropertyName: "inlineImagePadding", publicName: "inlineImagePadding", isSignal: true, isRequired: false, transformFunction: null }, textBreakStrategy: { classPropertyName: "textBreakStrategy", publicName: "textBreakStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changeText: "changeText", touch: "touch" }, host: { listeners: { "blur": "touch.emit()", "focus": "onFocus()", "change": "onNativeChange($event)", "selectionChange": "onNativeSelectionChange($event)" }, properties: { "text": "value()", "
|
|
317
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.0", type: TextInput, isStandalone: true, selector: "text-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, scrollEnabled: { classPropertyName: "scrollEnabled", publicName: "scrollEnabled", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, placeholderTextColor: { classPropertyName: "placeholderTextColor", publicName: "placeholderTextColor", isSignal: true, isRequired: false, transformFunction: null }, keyboardType: { classPropertyName: "keyboardType", publicName: "keyboardType", isSignal: true, isRequired: false, transformFunction: null }, returnKeyType: { classPropertyName: "returnKeyType", publicName: "returnKeyType", isSignal: true, isRequired: false, transformFunction: null }, submitBehavior: { classPropertyName: "submitBehavior", publicName: "submitBehavior", isSignal: true, isRequired: false, transformFunction: null }, secureTextEntry: { classPropertyName: "secureTextEntry", publicName: "secureTextEntry", isSignal: true, isRequired: false, transformFunction: null }, autoCapitalize: { classPropertyName: "autoCapitalize", publicName: "autoCapitalize", isSignal: true, isRequired: false, transformFunction: null }, autoCorrect: { classPropertyName: "autoCorrect", publicName: "autoCorrect", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, numberOfLines: { classPropertyName: "numberOfLines", publicName: "numberOfLines", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, selectionColor: { classPropertyName: "selectionColor", publicName: "selectionColor", isSignal: true, isRequired: false, transformFunction: null }, selectTextOnFocus: { classPropertyName: "selectTextOnFocus", publicName: "selectTextOnFocus", isSignal: true, isRequired: false, transformFunction: null }, caretHidden: { classPropertyName: "caretHidden", publicName: "caretHidden", isSignal: true, isRequired: false, transformFunction: null }, contextMenuHidden: { classPropertyName: "contextMenuHidden", publicName: "contextMenuHidden", isSignal: true, isRequired: false, transformFunction: null }, textAlign: { classPropertyName: "textAlign", publicName: "textAlign", isSignal: true, isRequired: false, transformFunction: null }, allowFontScaling: { classPropertyName: "allowFontScaling", publicName: "allowFontScaling", isSignal: true, isRequired: false, transformFunction: null }, maxFontSizeMultiplier: { classPropertyName: "maxFontSizeMultiplier", publicName: "maxFontSizeMultiplier", isSignal: true, isRequired: false, transformFunction: null }, inputAccessoryViewID: { classPropertyName: "inputAccessoryViewID", publicName: "inputAccessoryViewID", isSignal: true, isRequired: false, transformFunction: null }, clearButtonMode: { classPropertyName: "clearButtonMode", publicName: "clearButtonMode", isSignal: true, isRequired: false, transformFunction: null }, clearTextOnFocus: { classPropertyName: "clearTextOnFocus", publicName: "clearTextOnFocus", isSignal: true, isRequired: false, transformFunction: null }, enablesReturnKeyAutomatically: { classPropertyName: "enablesReturnKeyAutomatically", publicName: "enablesReturnKeyAutomatically", isSignal: true, isRequired: false, transformFunction: null }, keyboardAppearance: { classPropertyName: "keyboardAppearance", publicName: "keyboardAppearance", isSignal: true, isRequired: false, transformFunction: null }, passwordRules: { classPropertyName: "passwordRules", publicName: "passwordRules", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, smartInsertDelete: { classPropertyName: "smartInsertDelete", publicName: "smartInsertDelete", isSignal: true, isRequired: false, transformFunction: null }, dataDetectorTypes: { classPropertyName: "dataDetectorTypes", publicName: "dataDetectorTypes", isSignal: true, isRequired: false, transformFunction: null }, textContentType: { classPropertyName: "textContentType", publicName: "textContentType", isSignal: true, isRequired: false, transformFunction: null }, autoComplete: { classPropertyName: "autoComplete", publicName: "autoComplete", isSignal: true, isRequired: false, transformFunction: null }, underlineColorAndroid: { classPropertyName: "underlineColorAndroid", publicName: "underlineColorAndroid", isSignal: true, isRequired: false, transformFunction: null }, cursorColor: { classPropertyName: "cursorColor", publicName: "cursorColor", isSignal: true, isRequired: false, transformFunction: null }, selectionHandleColor: { classPropertyName: "selectionHandleColor", publicName: "selectionHandleColor", isSignal: true, isRequired: false, transformFunction: null }, textAlignVertical: { classPropertyName: "textAlignVertical", publicName: "textAlignVertical", isSignal: true, isRequired: false, transformFunction: null }, importantForAutofill: { classPropertyName: "importantForAutofill", publicName: "importantForAutofill", isSignal: true, isRequired: false, transformFunction: null }, showSoftInputOnFocus: { classPropertyName: "showSoftInputOnFocus", publicName: "showSoftInputOnFocus", isSignal: true, isRequired: false, transformFunction: null }, disableFullscreenUI: { classPropertyName: "disableFullscreenUI", publicName: "disableFullscreenUI", isSignal: true, isRequired: false, transformFunction: null }, inlineImageLeft: { classPropertyName: "inlineImageLeft", publicName: "inlineImageLeft", isSignal: true, isRequired: false, transformFunction: null }, inlineImagePadding: { classPropertyName: "inlineImagePadding", publicName: "inlineImagePadding", isSignal: true, isRequired: false, transformFunction: null }, textBreakStrategy: { classPropertyName: "textBreakStrategy", publicName: "textBreakStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changeText: "changeText", touch: "touch" }, host: { listeners: { "blur": "touch.emit()", "focus": "onFocus()", "change": "onNativeChange($event)", "selectionChange": "onNativeSelectionChange($event)" }, properties: { "text": "value()", "latestEventCount": "eventCount()", "multiline": "multiline()", "scrollEnabled": "scrollEnabled()", "editable": "resolvedEditable()", "accessibilityState": "accessibilityStateProp()", "attr.data-disabled": "disabled() ? '' : null", "attr.data-invalid": "invalid() ? '' : null", "attr.data-touched": "touched() ? '' : null", "placeholder": "placeholder()", "placeholderTextColor": "placeholderTextColor()", "keyboardType": "keyboardType()", "returnKeyType": "returnKeyType()", "submitBehavior": "resolvedSubmitBehavior()", "secureTextEntry": "secureTextEntry()", "autoCapitalize": "autoCapitalize()", "autoCorrect": "autoCorrect()", "autoFocus": "autoFocus()", "maxLength": "maxLength()", "numberOfLines": "numberOfLines()", "rows": "rows()", "selection": "resolvedSelection()", "selectionColor": "selectionColor()", "selectTextOnFocus": "selectTextOnFocus()", "caretHidden": "caretHidden()", "contextMenuHidden": "contextMenuHidden()", "textAlign": "textAlign()", "allowFontScaling": "allowFontScaling()", "maxFontSizeMultiplier": "maxFontSizeMultiplier()", "inputAccessoryViewID": "inputAccessoryViewID()", "clearButtonMode": "clearButtonMode()", "clearTextOnFocus": "clearTextOnFocus()", "enablesReturnKeyAutomatically": "enablesReturnKeyAutomatically()", "keyboardAppearance": "keyboardAppearance()", "passwordRules": "passwordRules()", "spellCheck": "spellCheck()", "smartInsertDelete": "smartInsertDelete()", "dataDetectorTypes": "dataDetectorTypes()", "textContentType": "textContentType()", "autoComplete": "autoComplete()", "underlineColorAndroid": "underlineColorAndroid()", "cursorColor": "resolvedCursorColor()", "selectionHandleColor": "resolvedSelectionHandleColor()", "textAlignVertical": "textAlignVertical()", "importantForAutofill": "importantForAutofill()", "showSoftInputOnFocus": "showSoftInputOnFocus()", "disableFullscreenUI": "disableFullscreenUI()", "inlineImageLeft": "inlineImageLeft()", "inlineImagePadding": "inlineImagePadding()", "textBreakStrategy": "textBreakStrategy()" } }, exportAs: ["textInput"], usesInheritance: true, usesOnChanges: true, ngImport: i0 });
|
|
312
318
|
}
|
|
313
319
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TextInput, decorators: [{
|
|
314
320
|
type: Directive,
|
|
@@ -317,7 +323,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
|
|
|
317
323
|
exportAs: 'textInput',
|
|
318
324
|
host: {
|
|
319
325
|
'[text]': 'value()',
|
|
320
|
-
'[
|
|
326
|
+
'[latestEventCount]': 'eventCount()',
|
|
321
327
|
'[multiline]': 'multiline()',
|
|
322
328
|
'[scrollEnabled]': 'scrollEnabled()',
|
|
323
329
|
'[editable]': 'resolvedEditable()',
|
package/dist/text-input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-input.js","sourceRoot":"","sources":["../src/text-input.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Directive,\n type SimpleChanges,\n afterRenderEffect,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport { Keyboard } from '@ng-native/device';\nimport type { NativeSyntheticEvent } from '@ng-native/fabric';\nimport { ControlledModel } from './controlled-model.ts';\nimport type { SelectionChangePayload, TextInputChangePayload } from './events.ts';\nimport { optionalBoolean, optionalNumber } from './transforms.ts';\nimport { ViewBase } from './view-base.ts';\n\nexport type KeyboardType =\n | 'default'\n | 'number-pad'\n | 'decimal-pad'\n | 'numeric'\n | 'email-address'\n | 'phone-pad'\n | 'url'\n | 'ascii-capable'\n | 'numbers-and-punctuation'\n | 'name-phone-pad'\n | 'twitter'\n | 'web-search'\n | 'visible-password';\nexport type ReturnKeyType =\n | 'done'\n | 'go'\n | 'next'\n | 'search'\n | 'send'\n | 'none'\n | 'previous'\n | 'default'\n | 'emergency-call'\n | 'google'\n | 'join'\n | 'route'\n | 'yahoo';\nexport type SubmitBehavior = 'submit' | 'blurAndSubmit' | 'newline';\n\n/**\n * A text field, wired for signal forms. Commits as `TextInput`, single or multi line by prop.\n *\n * `value` is a `model()`, which is all `FormValueControl<string>` requires, so binding it into a\n * form is `<text-input [formField]=\"f.name\" />` with no adapter class. The rest of the contract is\n * declared too, because Signal Forms only writes to inputs of those names: `disabled` and\n * `readonly` turn `editable` off, `invalid` and `touched` come out as `data-invalid` and\n * `data-touched` for a stylesheet, and `touch` fires from the native blur - there is no DOM one\n * for the form to hear instead. `(changeText)` carries\n * the new string alone, as RN's `onChangeText` does; the raw `(change)`, `(focus)`, `(blur)`,\n * `(submitEditing)`, `(endEditing)`, `(selectionChange)`, `(keyPress)`, `(contentSizeChange)`\n * and `(scroll)` are element events typed in `events.ts`.\n *\n * The interesting part is the echo. A native text field owns state the user is actively\n * changing, so JS and native disagree constantly. RN's protocol: native reports an `eventCount`\n * with every change, JS passes the most recent one back as a prop, and native ignores a `text`\n * update whose count is stale, meaning the user has typed since. Without it, a controlled input\n * fights the cursor and drops characters under fast typing.\n *\n * The other direction is native holding text the app does not: a value set from code after the\n * user has typed, or a keystroke the app refused or rewrote. It is controlled as RN's field is -\n * bind `value` and the app's value is what the field shows - so once each pass has rendered, the\n * field compares the model with the text native last reported and sends the difference as the\n * `setTextAndSelection` command. See `ControlledModel` for how a refusal reaches the model.\n * A value set that way is also measured again, since Fabric sizes the field from native state\n * that takes the new text only after measuring it: a composer cleared after sending shrinks.\n */\n@Directive({\n selector: 'text-input',\n exportAs: 'textInput',\n host: {\n '[text]': 'value()',\n '[mostRecentEventCount]': 'eventCount()',\n '[multiline]': 'multiline()',\n '[scrollEnabled]': 'scrollEnabled()',\n '[editable]': 'resolvedEditable()',\n // `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is\n // the one binding that keeps the announced state in step with it.\n '[accessibilityState]': 'accessibilityStateProp()',\n '[attr.data-disabled]': \"disabled() ? '' : null\",\n '[attr.data-invalid]': \"invalid() ? '' : null\",\n '[attr.data-touched]': \"touched() ? '' : null\",\n '(blur)': 'touch.emit()',\n '(focus)': 'onFocus()',\n '[placeholder]': 'placeholder()',\n '[placeholderTextColor]': 'placeholderTextColor()',\n '[keyboardType]': 'keyboardType()',\n '[returnKeyType]': 'returnKeyType()',\n '[submitBehavior]': 'resolvedSubmitBehavior()',\n '[secureTextEntry]': 'secureTextEntry()',\n '[autoCapitalize]': 'autoCapitalize()',\n '[autoCorrect]': 'autoCorrect()',\n '[autoFocus]': 'autoFocus()',\n '[maxLength]': 'maxLength()',\n '[numberOfLines]': 'numberOfLines()',\n '[rows]': 'rows()',\n '[selection]': 'resolvedSelection()',\n '[selectionColor]': 'selectionColor()',\n '[selectTextOnFocus]': 'selectTextOnFocus()',\n '[caretHidden]': 'caretHidden()',\n '[contextMenuHidden]': 'contextMenuHidden()',\n '[textAlign]': 'textAlign()',\n '[allowFontScaling]': 'allowFontScaling()',\n '[maxFontSizeMultiplier]': 'maxFontSizeMultiplier()',\n '[inputAccessoryViewID]': 'inputAccessoryViewID()',\n '[clearButtonMode]': 'clearButtonMode()',\n '[clearTextOnFocus]': 'clearTextOnFocus()',\n '[enablesReturnKeyAutomatically]': 'enablesReturnKeyAutomatically()',\n '[keyboardAppearance]': 'keyboardAppearance()',\n '[passwordRules]': 'passwordRules()',\n '[spellCheck]': 'spellCheck()',\n '[smartInsertDelete]': 'smartInsertDelete()',\n '[dataDetectorTypes]': 'dataDetectorTypes()',\n '[textContentType]': 'textContentType()',\n '[autoComplete]': 'autoComplete()',\n '[underlineColorAndroid]': 'underlineColorAndroid()',\n '[cursorColor]': 'resolvedCursorColor()',\n '[selectionHandleColor]': 'resolvedSelectionHandleColor()',\n '[textAlignVertical]': 'textAlignVertical()',\n '[importantForAutofill]': 'importantForAutofill()',\n '[showSoftInputOnFocus]': 'showSoftInputOnFocus()',\n '[disableFullscreenUI]': 'disableFullscreenUI()',\n '[inlineImageLeft]': 'inlineImageLeft()',\n '[inlineImagePadding]': 'inlineImagePadding()',\n '[textBreakStrategy]': 'textBreakStrategy()',\n '(change)': 'onNativeChange($event)',\n '(selectionChange)': 'onNativeSelectionChange($event)',\n },\n})\nexport class TextInput extends ViewBase {\n readonly value = model<string>('');\n /** The new text alone, on every native change. */\n readonly changeText = output<string>();\n /** Focus left the field. What Signal Forms marks a field touched from. */\n readonly touch = output<void>();\n\n /** Refuse input and announce as disabled. Wins over `editable`. */\n readonly disabled = input(undefined, { transform: optionalBoolean });\n /** Refuse input, though still announced as enabled. Wins over `editable`. */\n readonly readonly = input(undefined, { transform: optionalBoolean });\n /** Published as `data-invalid`; nothing native reads it. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Published as `data-touched`; nothing native reads it. */\n readonly touched = input(false, { transform: booleanAttribute });\n\n /** Allow more than one line. */\n readonly multiline = input(undefined, { transform: optionalBoolean });\n /** iOS: whether a multiline field scrolls its text; off, it grows with it instead. */\n readonly scrollEnabled = input(undefined, { transform: optionalBoolean });\n /** Set to false to make the field read-only. */\n readonly editable = input(undefined, { transform: optionalBoolean });\n /** Shown while the field is empty. */\n readonly placeholder = input<string>();\n readonly placeholderTextColor = input<string>();\n /** Which keyboard to show. */\n readonly keyboardType = input<KeyboardType>();\n /** The label on the return key. */\n readonly returnKeyType = input<ReturnKeyType>();\n /** What return does. Defaults to `blurAndSubmit` on one line and `newline` on many. */\n readonly submitBehavior = input<SubmitBehavior>();\n /** Hide what is typed, for passwords. */\n readonly secureTextEntry = input(undefined, { transform: optionalBoolean });\n /** When the keyboard capitalises. Defaults to `sentences`. */\n readonly autoCapitalize = input<'none' | 'sentences' | 'words' | 'characters'>();\n /** Auto-correct while typing. Defaults to true. */\n readonly autoCorrect = input(undefined, { transform: optionalBoolean });\n /** Focus the field as soon as it mounts. */\n readonly autoFocus = input(undefined, { transform: optionalBoolean });\n /** The most characters allowed, enforced natively so nothing flickers. */\n readonly maxLength = input(undefined, { transform: optionalNumber });\n /** Android: the height of a multiline field, in lines. */\n readonly numberOfLines = input(undefined, { transform: optionalNumber });\n /**\n * How many lines of its `line-height` a multiline field is tall, where nothing sets its height,\n * as a `<textarea rows>` is. Read by the engine, which sizes the field; never sent to native.\n */\n readonly rows = input(undefined, { transform: optionalNumber });\n /**\n * The selected range, or the caret when `end` is left out or equals `start`. Sent to native\n * whenever it differs from what native last had, so a caret the user moves goes back to it.\n */\n readonly selection = input<{ readonly start: number; readonly end?: number }>();\n readonly selectionColor = input<string>();\n /** Select everything on focus. */\n readonly selectTextOnFocus = input(undefined, { transform: optionalBoolean });\n readonly caretHidden = input(undefined, { transform: optionalBoolean });\n /** Disable the copy, paste and share menu. */\n readonly contextMenuHidden = input(undefined, { transform: optionalBoolean });\n readonly textAlign = input<'left' | 'center' | 'right'>();\n readonly allowFontScaling = input(undefined, { transform: optionalBoolean });\n readonly maxFontSizeMultiplier = input(undefined, { transform: optionalNumber });\n /** iOS: the `nativeID` of an `<input-accessory-view>` to dock above the keyboard. */\n readonly inputAccessoryViewID = input<string>();\n /** iOS: when the clear button shows. */\n readonly clearButtonMode = input<'never' | 'while-editing' | 'unless-editing' | 'always'>();\n /** iOS: empty the field on focus. */\n readonly clearTextOnFocus = input(undefined, { transform: optionalBoolean });\n /** iOS: disable the return key while the field is empty. */\n readonly enablesReturnKeyAutomatically = input(undefined, { transform: optionalBoolean });\n /** iOS: the keyboard's colour scheme. */\n readonly keyboardAppearance = input<'default' | 'light' | 'dark'>();\n /** iOS: rules for a generated password, in Apple's Password Rules syntax. */\n readonly passwordRules = input<string>();\n /** iOS: underline misspellings. Follows `autoCorrect` by default. */\n readonly spellCheck = input(undefined, { transform: optionalBoolean });\n /** iOS: add and remove spaces around pasted and deleted words. */\n readonly smartInsertDelete = input(undefined, { transform: optionalBoolean });\n /** iOS, multiline: turn phone numbers, links and addresses into taps. */\n readonly dataDetectorTypes = input<string | readonly string[]>();\n /** iOS: what the field holds, so the system can autofill it. */\n readonly textContentType = input<string>();\n /** Android: the autofill hint. */\n readonly autoComplete = input<string>();\n /**\n * Android: the underline colour, transparent by default.\n *\n * Not a taste call. Android's `EditText` carries the platform's own underline in its background\n * drawable, so a field with a border of its own draws two: the app's box, and a grey line\n * through it that turns blue on focus. React Native's `TextInput` defaults this prop to\n * `'transparent'` for exactly that reason, and this is that default rather than a new opinion.\n * Ignored on iOS, where the native field has no such chrome.\n */\n readonly underlineColorAndroid = input<string>('transparent');\n /** Android: the caret colour. Follows `selectionColor` by default, as RN's does. */\n readonly cursorColor = input<string>();\n /** Android: the selection handle colour. Follows `selectionColor` by default, as RN's does. */\n readonly selectionHandleColor = input<string>();\n /** Android: where text sits in a tall field. */\n readonly textAlignVertical = input<'auto' | 'top' | 'bottom' | 'center'>();\n /** Android: whether autofill may fill this field. */\n readonly importantForAutofill = input<\n 'auto' | 'no' | 'noExcludeDescendants' | 'yes' | 'yesExcludeDescendants'\n >();\n /** Android: set to false to focus without raising the keyboard. */\n readonly showSoftInputOnFocus = input(undefined, { transform: optionalBoolean });\n /** Android: keep the field in place in landscape rather than going full screen. */\n readonly disableFullscreenUI = input(undefined, { transform: optionalBoolean });\n /** Android: a drawable resource shown at the left of the field. */\n readonly inlineImageLeft = input<string>();\n readonly inlineImagePadding = input(undefined, { transform: optionalNumber });\n /** Android: the line-breaking strategy. */\n readonly textBreakStrategy = input<'simple' | 'highQuality' | 'balanced'>();\n\n protected readonly eventCount = signal(0);\n\n /** RN's normalised selection: an `end` left out is `start`, where iOS would read 0. */\n protected readonly resolvedSelection = computed(() => {\n const selection = this.selection();\n return selection\n ? { start: selection.start, end: selection.end ?? selection.start }\n : undefined;\n });\n\n // RN's Android defaults, checked against `undefined` as RN does rather than with `??`.\n protected readonly resolvedCursorColor = computed(() => {\n const color = this.cursorColor();\n return color === undefined ? this.selectionColor() : color;\n });\n protected readonly resolvedSelectionHandleColor = computed(() => {\n const color = this.selectionHandleColor();\n return color === undefined ? this.selectionColor() : color;\n });\n\n protected readonly resolvedEditable = computed(() =>\n this.disabled() || this.readonly() ? false : this.editable(),\n );\n\n protected override disabledForAccessibility(): boolean | undefined {\n return this.disabled();\n }\n\n protected readonly resolvedSubmitBehavior = computed(() => {\n const explicit = this.submitBehavior();\n // A single-line field has no line to add, so `newline` collapses to the default.\n if (explicit && (this.multiline() || explicit !== 'newline')) return explicit;\n return this.multiline() ? 'newline' : 'blurAndSubmit';\n });\n\n private readonly keyboard = inject(Keyboard);\n /** What native last reported, so a value set from code can be told from an echo. */\n private lastNativeText: string | null = null;\n /**\n * The selection native last had, sent or reported, so a bound one is sent only when it differs.\n * Unset to start with, so the first bound selection goes out too.\n */\n private lastSelection = { start: -1, end: -1 };\n /** Moved on every reported selection, so the bound one is compared with it again. */\n private readonly selectionReports = signal(0);\n private readonly control = new ControlledModel(this.value, 'value');\n\n constructor() {\n super();\n // RN's layout effect, keyed as RN keys it: the value, the selection, and the count every\n // native change moves on, so a refusal that leaves the value where it was is compared all the\n // same. After render rather than as an ordinary effect, because an accepted edit only reaches\n // the model during change detection, and comparing before it has would send the old text back.\n afterRenderEffect({ write: () => this.syncWithNative() });\n }\n\n override ngOnChanges(changes: SimpleChanges): void {\n super.ngOnChanges(changes);\n this.control.noteChanges(changes);\n }\n\n /**\n * With the keyboard already up, keep the field clear of it. UIKit scrolls a field clear as the\n * keyboard rises, not when focus moves from one field to another beneath it, which is what a\n * form's Next key does; native form screens keep the new field on screen either way.\n */\n protected onFocus(): void {\n const { height, screenY } = this.keyboard.metrics();\n if (height > 0 && screenY !== undefined)\n this.engine.reveal(this.node, { visibleBottom: screenY - this.keyboard.windowTop });\n }\n\n /** Bring the keyboard up on this field. A view command, so it reaches native directly. */\n focus(): void {\n this.engine.dispatchCommand(this.node, 'focus');\n }\n\n blur(): void {\n this.engine.dispatchCommand(this.node, 'blur');\n }\n\n /** Empty the field. */\n clear(): void {\n this.value.set('');\n }\n\n /** Move the caret, or select a range. */\n setSelection(start: number, end = start): void {\n this.engine.dispatchCommand(this.node, 'setTextAndSelection', [\n this.eventCount(),\n null,\n start,\n end,\n ]);\n }\n\n /** Whether this field currently has the keyboard. */\n isFocused(): boolean {\n return this.engine.focused === this.node;\n }\n\n protected onNativeChange(event: NativeSyntheticEvent<Partial<TextInputChangePayload>>): void {\n const native = event.nativeEvent;\n const text = native?.text ?? '';\n // Order matters, as it does in RN: the value first, the count last.\n this.lastNativeText = text;\n this.control.propose(text);\n this.eventCount.set(native?.eventCount ?? this.eventCount() + 1);\n this.changeText.emit(text);\n }\n\n /** Send native the text and selection it does not have, as one `setTextAndSelection`. */\n private syncWithNative(): void {\n const desired = this.value();\n const count = this.eventCount();\n const selection = this.resolvedSelection();\n this.selectionReports();\n const textChanged = this.lastNativeText !== null && this.lastNativeText !== desired;\n if (!textChanged && !this.differsFromNative(selection)) return;\n if (textChanged) this.lastNativeText = desired;\n if (selection) this.lastSelection = selection;\n // The `text` prop alone may be ignored as stale, so send it as a command with the count\n // native expects, and the text and bound selection as RN does whichever of them changed.\n this.engine.dispatchCommand(this.node, 'setTextAndSelection', [\n count,\n desired,\n selection?.start ?? -1,\n selection?.end ?? -1,\n ]);\n // Fabric sized the field for the text it had; see `HostEngine.remeasure`.\n if (textChanged) this.engine.remeasure(this.node);\n }\n\n /**\n * Whether a bound selection is not the one native last had. The prop alone does not move the\n * caret: Android has no `selection` prop, and iOS reads it only as the field appears or its\n * text is replaced.\n */\n private differsFromNative(selection: { start: number; end: number } | undefined): boolean {\n return (\n selection !== undefined &&\n (selection.start !== this.lastSelection.start || selection.end !== this.lastSelection.end)\n );\n }\n\n /** What native now has selected, which a bound selection that differs is sent over again. */\n protected onNativeSelectionChange(\n event: NativeSyntheticEvent<Partial<SelectionChangePayload>>,\n ): void {\n const selection = event.nativeEvent?.selection;\n if (!selection) return;\n this.lastSelection = { start: selection.start, end: selection.end };\n this.selectionReports.update((n) => n + 1);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"text-input.js","sourceRoot":"","sources":["../src/text-input.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Directive,\n type SimpleChanges,\n afterRenderEffect,\n booleanAttribute,\n computed,\n inject,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport { Keyboard } from '@ng-native/device';\nimport type { NativeSyntheticEvent } from '@ng-native/fabric';\nimport { ControlledModel } from './controlled-model.ts';\nimport type { SelectionChangePayload, TextInputChangePayload } from './events.ts';\nimport { optionalBoolean, optionalNumber } from './transforms.ts';\nimport { ViewBase } from './view-base.ts';\n\nexport type KeyboardType =\n | 'default'\n | 'number-pad'\n | 'decimal-pad'\n | 'numeric'\n | 'email-address'\n | 'phone-pad'\n | 'url'\n | 'ascii-capable'\n | 'numbers-and-punctuation'\n | 'name-phone-pad'\n | 'twitter'\n | 'web-search'\n | 'visible-password';\nexport type ReturnKeyType =\n | 'done'\n | 'go'\n | 'next'\n | 'search'\n | 'send'\n | 'none'\n | 'previous'\n | 'default'\n | 'emergency-call'\n | 'google'\n | 'join'\n | 'route'\n | 'yahoo';\nexport type SubmitBehavior = 'submit' | 'blurAndSubmit' | 'newline';\n\n/**\n * A text field, wired for signal forms. Commits as `TextInput`, single or multi line by prop.\n *\n * `value` is a `model()`, which is all `FormValueControl<string>` requires, so binding it into a\n * form is `<text-input [formField]=\"f.name\" />` with no adapter class. The rest of the contract is\n * declared too, because Signal Forms only writes to inputs of those names: `disabled` and\n * `readonly` turn `editable` off, `invalid` and `touched` come out as `data-invalid` and\n * `data-touched` for a stylesheet, and `touch` fires from the native blur - there is no DOM one\n * for the form to hear instead. `(changeText)` carries\n * the new string alone, as RN's `onChangeText` does; the raw `(change)`, `(focus)`, `(blur)`,\n * `(submitEditing)`, `(endEditing)`, `(selectionChange)`, `(keyPress)`, `(contentSizeChange)`\n * and `(scroll)` are element events typed in `events.ts`.\n *\n * The interesting part is the echo. A native text field owns state the user is actively\n * changing, so JS and native disagree constantly. RN's protocol: native reports an `eventCount`\n * with every change, JS passes the most recent one back, and native ignores a `text` update whose\n * count is stale, meaning the user has typed since. Without it, a controlled input fights the\n * cursor and drops characters under fast typing.\n *\n * The engine commits the count as the `mostRecentEventCount` prop. Android takes the latest, as RN\n * sends it; iOS takes 0 but where a multiline field's text style changes, since an echo with the\n * current count replaces an empty field's first typed text there and drops the keystrokes queued\n * behind it (see `echoedEventCount` in the engine). Text from code reaches iOS as the command\n * below instead, which carries the count.\n *\n * The other direction is native holding text the app does not: a value set from code after the\n * user has typed, or a keystroke the app refused or rewrote. It is controlled as RN's field is -\n * bind `value` and the app's value is what the field shows - so once each pass has rendered, the\n * field compares the model with the text native last reported and sends the difference as the\n * `setTextAndSelection` command. See `ControlledModel` for how a refusal reaches the model.\n * A value set that way is also measured again, since Fabric sizes the field from native state\n * that takes the new text only after measuring it: a composer cleared after sending shrinks.\n */\n@Directive({\n selector: 'text-input',\n exportAs: 'textInput',\n host: {\n '[text]': 'value()',\n '[latestEventCount]': 'eventCount()',\n '[multiline]': 'multiline()',\n '[scrollEnabled]': 'scrollEnabled()',\n '[editable]': 'resolvedEditable()',\n // `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is\n // the one binding that keeps the announced state in step with it.\n '[accessibilityState]': 'accessibilityStateProp()',\n '[attr.data-disabled]': \"disabled() ? '' : null\",\n '[attr.data-invalid]': \"invalid() ? '' : null\",\n '[attr.data-touched]': \"touched() ? '' : null\",\n '(blur)': 'touch.emit()',\n '(focus)': 'onFocus()',\n '[placeholder]': 'placeholder()',\n '[placeholderTextColor]': 'placeholderTextColor()',\n '[keyboardType]': 'keyboardType()',\n '[returnKeyType]': 'returnKeyType()',\n '[submitBehavior]': 'resolvedSubmitBehavior()',\n '[secureTextEntry]': 'secureTextEntry()',\n '[autoCapitalize]': 'autoCapitalize()',\n '[autoCorrect]': 'autoCorrect()',\n '[autoFocus]': 'autoFocus()',\n '[maxLength]': 'maxLength()',\n '[numberOfLines]': 'numberOfLines()',\n '[rows]': 'rows()',\n '[selection]': 'resolvedSelection()',\n '[selectionColor]': 'selectionColor()',\n '[selectTextOnFocus]': 'selectTextOnFocus()',\n '[caretHidden]': 'caretHidden()',\n '[contextMenuHidden]': 'contextMenuHidden()',\n '[textAlign]': 'textAlign()',\n '[allowFontScaling]': 'allowFontScaling()',\n '[maxFontSizeMultiplier]': 'maxFontSizeMultiplier()',\n '[inputAccessoryViewID]': 'inputAccessoryViewID()',\n '[clearButtonMode]': 'clearButtonMode()',\n '[clearTextOnFocus]': 'clearTextOnFocus()',\n '[enablesReturnKeyAutomatically]': 'enablesReturnKeyAutomatically()',\n '[keyboardAppearance]': 'keyboardAppearance()',\n '[passwordRules]': 'passwordRules()',\n '[spellCheck]': 'spellCheck()',\n '[smartInsertDelete]': 'smartInsertDelete()',\n '[dataDetectorTypes]': 'dataDetectorTypes()',\n '[textContentType]': 'textContentType()',\n '[autoComplete]': 'autoComplete()',\n '[underlineColorAndroid]': 'underlineColorAndroid()',\n '[cursorColor]': 'resolvedCursorColor()',\n '[selectionHandleColor]': 'resolvedSelectionHandleColor()',\n '[textAlignVertical]': 'textAlignVertical()',\n '[importantForAutofill]': 'importantForAutofill()',\n '[showSoftInputOnFocus]': 'showSoftInputOnFocus()',\n '[disableFullscreenUI]': 'disableFullscreenUI()',\n '[inlineImageLeft]': 'inlineImageLeft()',\n '[inlineImagePadding]': 'inlineImagePadding()',\n '[textBreakStrategy]': 'textBreakStrategy()',\n '(change)': 'onNativeChange($event)',\n '(selectionChange)': 'onNativeSelectionChange($event)',\n },\n})\nexport class TextInput extends ViewBase {\n readonly value = model<string>('');\n /** The new text alone, on every native change. */\n readonly changeText = output<string>();\n /** Focus left the field. What Signal Forms marks a field touched from. */\n readonly touch = output<void>();\n\n /** Refuse input and announce as disabled. Wins over `editable`. */\n readonly disabled = input(undefined, { transform: optionalBoolean });\n /** Refuse input, though still announced as enabled. Wins over `editable`. */\n readonly readonly = input(undefined, { transform: optionalBoolean });\n /** Published as `data-invalid`; nothing native reads it. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Published as `data-touched`; nothing native reads it. */\n readonly touched = input(false, { transform: booleanAttribute });\n\n /** Allow more than one line. */\n readonly multiline = input(undefined, { transform: optionalBoolean });\n /** iOS: whether a multiline field scrolls its text; off, it grows with it instead. */\n readonly scrollEnabled = input(undefined, { transform: optionalBoolean });\n /** Set to false to make the field read-only. */\n readonly editable = input(undefined, { transform: optionalBoolean });\n /** Shown while the field is empty. */\n readonly placeholder = input<string>();\n readonly placeholderTextColor = input<string>();\n /** Which keyboard to show. */\n readonly keyboardType = input<KeyboardType>();\n /** The label on the return key. */\n readonly returnKeyType = input<ReturnKeyType>();\n /** What return does. Defaults to `blurAndSubmit` on one line and `newline` on many. */\n readonly submitBehavior = input<SubmitBehavior>();\n /** Hide what is typed, for passwords. */\n readonly secureTextEntry = input(undefined, { transform: optionalBoolean });\n /** When the keyboard capitalises. Defaults to `sentences`. */\n readonly autoCapitalize = input<'none' | 'sentences' | 'words' | 'characters'>();\n /** Auto-correct while typing. Defaults to true. */\n readonly autoCorrect = input(undefined, { transform: optionalBoolean });\n /** Focus the field as soon as it mounts. */\n readonly autoFocus = input(undefined, { transform: optionalBoolean });\n /** The most characters allowed, enforced natively so nothing flickers. */\n readonly maxLength = input(undefined, { transform: optionalNumber });\n /** Android: the height of a multiline field, in lines. */\n readonly numberOfLines = input(undefined, { transform: optionalNumber });\n /**\n * How many lines of its `line-height` a multiline field is tall, where nothing sets its height,\n * as a `<textarea rows>` is. Read by the engine, which sizes the field; never sent to native.\n */\n readonly rows = input(undefined, { transform: optionalNumber });\n /**\n * The selected range, or the caret when `end` is left out or equals `start`. Sent to native\n * whenever it differs from what native last had, so a caret the user moves goes back to it.\n */\n readonly selection = input<{ readonly start: number; readonly end?: number }>();\n readonly selectionColor = input<string>();\n /** Select everything on focus. */\n readonly selectTextOnFocus = input(undefined, { transform: optionalBoolean });\n readonly caretHidden = input(undefined, { transform: optionalBoolean });\n /** Disable the copy, paste and share menu. */\n readonly contextMenuHidden = input(undefined, { transform: optionalBoolean });\n readonly textAlign = input<'left' | 'center' | 'right'>();\n readonly allowFontScaling = input(undefined, { transform: optionalBoolean });\n readonly maxFontSizeMultiplier = input(undefined, { transform: optionalNumber });\n /** iOS: the `nativeID` of an `<input-accessory-view>` to dock above the keyboard. */\n readonly inputAccessoryViewID = input<string>();\n /** iOS: when the clear button shows. */\n readonly clearButtonMode = input<'never' | 'while-editing' | 'unless-editing' | 'always'>();\n /** iOS: empty the field on focus. */\n readonly clearTextOnFocus = input(undefined, { transform: optionalBoolean });\n /** iOS: disable the return key while the field is empty. */\n readonly enablesReturnKeyAutomatically = input(undefined, { transform: optionalBoolean });\n /** iOS: the keyboard's colour scheme. */\n readonly keyboardAppearance = input<'default' | 'light' | 'dark'>();\n /** iOS: rules for a generated password, in Apple's Password Rules syntax. */\n readonly passwordRules = input<string>();\n /** iOS: underline misspellings. Follows `autoCorrect` by default. */\n readonly spellCheck = input(undefined, { transform: optionalBoolean });\n /** iOS: add and remove spaces around pasted and deleted words. */\n readonly smartInsertDelete = input(undefined, { transform: optionalBoolean });\n /** iOS, multiline: turn phone numbers, links and addresses into taps. */\n readonly dataDetectorTypes = input<string | readonly string[]>();\n /** iOS: what the field holds, so the system can autofill it. */\n readonly textContentType = input<string>();\n /** Android: the autofill hint. */\n readonly autoComplete = input<string>();\n /**\n * Android: the underline colour, transparent by default.\n *\n * Not a taste call. Android's `EditText` carries the platform's own underline in its background\n * drawable, so a field with a border of its own draws two: the app's box, and a grey line\n * through it that turns blue on focus. React Native's `TextInput` defaults this prop to\n * `'transparent'` for exactly that reason, and this is that default rather than a new opinion.\n * Ignored on iOS, where the native field has no such chrome.\n */\n readonly underlineColorAndroid = input<string>('transparent');\n /** Android: the caret colour. Follows `selectionColor` by default, as RN's does. */\n readonly cursorColor = input<string>();\n /** Android: the selection handle colour. Follows `selectionColor` by default, as RN's does. */\n readonly selectionHandleColor = input<string>();\n /** Android: where text sits in a tall field. */\n readonly textAlignVertical = input<'auto' | 'top' | 'bottom' | 'center'>();\n /** Android: whether autofill may fill this field. */\n readonly importantForAutofill = input<\n 'auto' | 'no' | 'noExcludeDescendants' | 'yes' | 'yesExcludeDescendants'\n >();\n /** Android: set to false to focus without raising the keyboard. */\n readonly showSoftInputOnFocus = input(undefined, { transform: optionalBoolean });\n /** Android: keep the field in place in landscape rather than going full screen. */\n readonly disableFullscreenUI = input(undefined, { transform: optionalBoolean });\n /** Android: a drawable resource shown at the left of the field. */\n readonly inlineImageLeft = input<string>();\n readonly inlineImagePadding = input(undefined, { transform: optionalNumber });\n /** Android: the line-breaking strategy. */\n readonly textBreakStrategy = input<'simple' | 'highQuality' | 'balanced'>();\n\n protected readonly eventCount = signal(0);\n\n /** RN's normalised selection: an `end` left out is `start`, where iOS would read 0. */\n protected readonly resolvedSelection = computed(() => {\n const selection = this.selection();\n return selection\n ? { start: selection.start, end: selection.end ?? selection.start }\n : undefined;\n });\n\n // RN's Android defaults, checked against `undefined` as RN does rather than with `??`.\n protected readonly resolvedCursorColor = computed(() => {\n const color = this.cursorColor();\n return color === undefined ? this.selectionColor() : color;\n });\n protected readonly resolvedSelectionHandleColor = computed(() => {\n const color = this.selectionHandleColor();\n return color === undefined ? this.selectionColor() : color;\n });\n\n protected readonly resolvedEditable = computed(() =>\n this.disabled() || this.readonly() ? false : this.editable(),\n );\n\n protected override disabledForAccessibility(): boolean | undefined {\n return this.disabled();\n }\n\n protected readonly resolvedSubmitBehavior = computed(() => {\n const explicit = this.submitBehavior();\n // A single-line field has no line to add, so `newline` collapses to the default.\n if (explicit && (this.multiline() || explicit !== 'newline')) return explicit;\n return this.multiline() ? 'newline' : 'blurAndSubmit';\n });\n\n private readonly keyboard = inject(Keyboard);\n /** What native last reported, so a value set from code can be told from an echo. */\n private lastNativeText: string | null = null;\n /**\n * The selection native last had, sent or reported, so a bound one is sent only when it differs.\n * Unset to start with, so the first bound selection goes out too.\n */\n private lastSelection = { start: -1, end: -1 };\n /** Moved on every reported selection, so the bound one is compared with it again. */\n private readonly selectionReports = signal(0);\n private readonly control = new ControlledModel(this.value, 'value');\n\n constructor() {\n super();\n // RN's layout effect, keyed as RN keys it: the value, the selection, and the count every\n // native change moves on, so a refusal that leaves the value where it was is compared all the\n // same. After render rather than as an ordinary effect, because an accepted edit only reaches\n // the model during change detection, and comparing before it has would send the old text back.\n afterRenderEffect({ write: () => this.syncWithNative() });\n }\n\n override ngOnChanges(changes: SimpleChanges): void {\n super.ngOnChanges(changes);\n this.control.noteChanges(changes);\n }\n\n /**\n * With the keyboard already up, keep the field clear of it. UIKit scrolls a field clear as the\n * keyboard rises, not when focus moves from one field to another beneath it, which is what a\n * form's Next key does; native form screens keep the new field on screen either way.\n */\n protected onFocus(): void {\n const { height, screenY } = this.keyboard.metrics();\n if (height > 0 && screenY !== undefined)\n this.engine.reveal(this.node, { visibleBottom: screenY - this.keyboard.windowTop });\n }\n\n /** Bring the keyboard up on this field. A view command, so it reaches native directly. */\n focus(): void {\n this.engine.dispatchCommand(this.node, 'focus');\n }\n\n blur(): void {\n this.engine.dispatchCommand(this.node, 'blur');\n }\n\n /** Empty the field. */\n clear(): void {\n this.value.set('');\n }\n\n /** Move the caret, or select a range. */\n setSelection(start: number, end = start): void {\n this.engine.dispatchCommand(this.node, 'setTextAndSelection', [\n this.eventCount(),\n null,\n start,\n end,\n ]);\n }\n\n /** Whether this field currently has the keyboard. */\n isFocused(): boolean {\n return this.engine.focused === this.node;\n }\n\n protected onNativeChange(event: NativeSyntheticEvent<Partial<TextInputChangePayload>>): void {\n const native = event.nativeEvent;\n const text = native?.text ?? '';\n // Order matters, as it does in RN: the value first, the count last.\n this.lastNativeText = text;\n this.control.propose(text);\n this.eventCount.set(native?.eventCount ?? this.eventCount() + 1);\n this.changeText.emit(text);\n }\n\n /** Send native the text and selection it does not have, as one `setTextAndSelection`. */\n private syncWithNative(): void {\n const desired = this.value();\n const count = this.eventCount();\n const selection = this.resolvedSelection();\n this.selectionReports();\n const textChanged = this.lastNativeText !== null && this.lastNativeText !== desired;\n if (!textChanged && !this.differsFromNative(selection)) return;\n if (textChanged) this.lastNativeText = desired;\n if (selection) this.lastSelection = selection;\n // The `text` prop alone may be ignored as stale, so send it as a command with the count\n // native expects, and the text and bound selection as RN does whichever of them changed.\n this.engine.dispatchCommand(this.node, 'setTextAndSelection', [\n count,\n desired,\n selection?.start ?? -1,\n selection?.end ?? -1,\n ]);\n // Fabric sized the field for the text it had; see `HostEngine.remeasure`.\n if (textChanged) this.engine.remeasure(this.node);\n }\n\n /**\n * Whether a bound selection is not the one native last had. The prop alone does not move the\n * caret: Android has no `selection` prop, and iOS reads it only as the field appears or its\n * text is replaced.\n */\n private differsFromNative(selection: { start: number; end: number } | undefined): boolean {\n return (\n selection !== undefined &&\n (selection.start !== this.lastSelection.start || selection.end !== this.lastSelection.end)\n );\n }\n\n /** What native now has selected, which a bound selection that differs is sent over again. */\n protected onNativeSelectionChange(\n event: NativeSyntheticEvent<Partial<SelectionChangePayload>>,\n ): void {\n const selection = event.nativeEvent?.selection;\n if (!selection) return;\n this.lastSelection = { start: selection.start, end: selection.end };\n this.selectionReports.update((n) => n + 1);\n }\n}\n"]}
|
package/dist/virtual-list.d.ts
CHANGED
|
@@ -456,6 +456,11 @@ export declare class VirtualList<T> extends ScrollViewProps {
|
|
|
456
456
|
/** A parked row for a slot that never drew, which only a slot taken and left in one pass is. */
|
|
457
457
|
private placeholder;
|
|
458
458
|
private recycledSlot;
|
|
459
|
+
/**
|
|
460
|
+
* Take an item's own parked row out as it comes back: its slot if it is of the type the item now
|
|
461
|
+
* is, and gone either way, or the window would hold its key twice.
|
|
462
|
+
*/
|
|
463
|
+
private unpark;
|
|
459
464
|
/**
|
|
460
465
|
* A row laid itself out; what `virtualListRow` calls. Only a row that sizes itself is measured,
|
|
461
466
|
* and a height that has not changed changes nothing.
|
package/dist/virtual-list.js
CHANGED
|
@@ -838,10 +838,24 @@ export class VirtualList extends ScrollViewProps {
|
|
|
838
838
|
if (held)
|
|
839
839
|
return held.slot;
|
|
840
840
|
const type = this.itemType()?.(item, index);
|
|
841
|
-
const slot = this.parked.get(type)?.pop()?.slot ?? this.nextSlot++;
|
|
841
|
+
const slot = this.unpark(key, type) ?? this.parked.get(type)?.pop()?.slot ?? this.nextSlot++;
|
|
842
842
|
this.recycled.set(key, { slot, type, row: null });
|
|
843
843
|
return slot;
|
|
844
844
|
}
|
|
845
|
+
/**
|
|
846
|
+
* Take an item's own parked row out as it comes back: its slot if it is of the type the item now
|
|
847
|
+
* is, and gone either way, or the window would hold its key twice.
|
|
848
|
+
*/
|
|
849
|
+
unpark(key, type) {
|
|
850
|
+
for (const [kind, pool] of this.parked) {
|
|
851
|
+
const at = pool.findIndex((row) => row.key === key);
|
|
852
|
+
if (at < 0)
|
|
853
|
+
continue;
|
|
854
|
+
const [row] = pool.splice(at, 1);
|
|
855
|
+
return kind === type ? row.slot : undefined;
|
|
856
|
+
}
|
|
857
|
+
return undefined;
|
|
858
|
+
}
|
|
845
859
|
/**
|
|
846
860
|
* A row laid itself out; what `virtualListRow` calls. Only a row that sizes itself is measured,
|
|
847
861
|
* and a height that has not changed changes nothing.
|
package/dist/virtual-list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtual-list.js","sourceRoot":"","sources":["../src/virtual-list.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n DestroyRef,\n Directive,\n ElementRef,\n TemplateRef,\n afterEveryRender,\n booleanAttribute,\n computed,\n contentChild,\n effect,\n inject,\n input,\n linkedSignal,\n output,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport {\n type HostNode,\n type NativeSyntheticEvent,\n type ScrollDrive,\n type ScrollRange,\n type StaticTransform,\n nativePlatform,\n pinnedRange,\n} from '@ng-native/fabric';\nimport { HeightIndex } from './height-index.ts';\nimport { type KeyboardShouldPersistTaps, dismissKeyboardOnTap } from './keyboard-taps.ts';\nimport { RefreshControl } from './refresh-control.ts';\nimport { STICKY_SETTLE_MS } from './sticky-headers.ts';\nimport { TemplateSlot } from './template-slot.ts';\nimport { ZeroSizeWarning, checksZeroSize, written } from './zero-size-warning.ts';\nimport { View } from './view.ts';\nimport { ScrollViewProps } from './scroll-view-props.ts';\nimport { numberOr } from './transforms.ts';\n\n/** One rendered row: the item, its index, and a stable style object for its slot. */\nexport interface VirtualRow<T> {\n readonly index: number;\n /**\n * A key that a row keeps while its item stays in the window, and that passes to a row arriving\n * once it has left. `track row.slot` recycles rows: the view of a row scrolling out is reused for\n * the one scrolling in, with only its bindings updated, rather than one destroyed and one created\n * each time. A slot follows its item, not its position, so an insert above the window moves no\n * row to another item.\n */\n readonly slot: number;\n /**\n * The item's identity, from `keyExtractor`, or the item itself without one. `track row.key`\n * gives each item a view of its own for as long as it is in the window and never recycles one,\n * which is what a row holding state of its own, or animating, needs.\n */\n readonly key: unknown;\n readonly item: T;\n readonly style: Record<string, unknown>;\n /**\n * A slot kept rendered but hidden, still bound to the last item it showed, so the next row of\n * its type to arrive reuses its views instead of building them. Always last in the window.\n */\n readonly parked?: true;\n}\n\n/**\n * Space around the rows, inside the scrolling content: one number for every side, or a side each,\n * as FlatList's `contentContainerStyle` padding.\n */\nexport type VirtualListPadding =\n | number\n | {\n readonly top?: number;\n readonly right?: number;\n readonly bottom?: number;\n readonly left?: number;\n };\n\n/** The padding on each side, in points. */\ninterface Edges {\n readonly top: number;\n readonly right: number;\n readonly bottom: number;\n readonly left: number;\n}\n\n/** A row height: one for every row, or one per item. */\nexport type VirtualItemHeight<T> = number | ((item: T, index: number) => number);\n\n/**\n * Keep what is on screen where it is when rows are added or removed before it, as\n * `ScrollView`'s `maintainVisibleContentPosition` does in React Native.\n */\nexport interface VirtualListVisiblePosition {\n /** Rows before this index are never what the position is held by. Defaults to 0. */\n readonly minIndexForVisible?: number;\n /**\n * Within this many points of the start, show what arrived instead of holding position: a feed\n * at its top scrolls to the new posts, a chat at its newest message follows the next one.\n */\n readonly autoscrollToTopThreshold?: number;\n}\n\n/** What a separator template is given: the rows either side of it, as FlatList's `leadingItem`. */\nexport interface VirtualListSeparatorContext<T> {\n readonly $implicit: T;\n readonly leadingItem: T;\n readonly trailingItem: T;\n readonly leadingIndex: number;\n}\n\n/**\n * Marks the template drawn between two rows: `<ng-template virtualListSeparator let-leading>`.\n * FlatList's `ItemSeparatorComponent`.\n */\n@Directive({ selector: 'ng-template[virtualListSeparator]' })\nexport class VirtualListSeparator<T = unknown> {\n readonly template = inject<TemplateRef<VirtualListSeparatorContext<T>>>(TemplateRef);\n\n static ngTemplateContextGuard<T>(\n _directive: VirtualListSeparator<T>,\n context: unknown,\n ): context is VirtualListSeparatorContext<T> {\n return true;\n }\n}\n\n/** One separator the list is drawing: its slot, and what its template is told. */\ninterface Gap<T> {\n readonly index: number;\n readonly style: Record<string, unknown>;\n readonly context: VirtualListSeparatorContext<T>;\n}\n\n/**\n * A parked slot: out of the flow, out of sight and out of reach, with its view kept to be used\n * again. Not `display: none`, which is an element with no view. A screen reader passes over a\n * view with no opacity, and `VirtualListRow` says so outright where a row uses it. Moved off the\n * list as well, since `pointer-events: none` is CSS's: something inside a row with a\n * `pointer-events` of its own would still take a touch where the row was left.\n */\nconst PARKED: Record<string, unknown> = Object.freeze({\n position: 'absolute',\n opacity: 0,\n pointerEvents: 'none',\n transform: 'translateX(-100000px)',\n});\n\n/** How many hidden slots of each row type are kept ready for reuse. */\nconst PARK_LIMIT = 6;\n\n/** The style of a row that sizes itself and needs nothing else: in flow, where it falls. */\nconst IN_FLOW: Record<string, unknown> = Object.freeze({});\n\n/** Points of drift below which a held position is left alone, as UIKit rounds to half-points. */\nconst HOLD_TOLERANCE = 0.5;\n\n/** The row a held position is held by: its key, and how far into it the viewport starts. */\ninterface Anchor<T> {\n readonly key: unknown;\n readonly within: number;\n /** The items the anchor was taken against, to look for a successor in if its row goes. */\n readonly items: readonly T[];\n readonly index: number;\n}\n\n/** What the window is built from: the visible row and the edges of what is rendered. */\ninterface Span {\n readonly first: number;\n readonly last: number;\n}\n\n/**\n * Windowed list: a native scroll view whose content is sized to the full list, with only the\n * visible slice rendered. Commits as `RCTScrollView`.\n *\n * RN's FlatList, SectionList and VirtualizedList are a large React component tree, and none of\n * it is reachable. This is the small equivalent. Angular's own `@for` does the rendering, so\n * tracking, reuse and destruction all behave normally, and the loop stays in the caller's\n * template:\n *\n * ```html\n * <virtual-list #list [items]=\"rows()\" [itemHeight]=\"44\" (endReached)=\"loadMore()\">\n * <text listHeader>Header</text>\n * @for (row of list.window(); track row.slot) {\n * <view [virtualListRow]=\"row\"><text>{{ row.item.label }}</text></view>\n * }\n * <text listFooter>Footer</text>\n * </virtual-list>\n * ```\n *\n * With `itemHeight`, every row's size is known up front and each is absolutely positioned at its\n * offset. Without it, rows size themselves, as a feed's posts and a chat's messages do: the window\n * is laid out in normal flow after a spacer standing in for the rows above it, so native places\n * every row correctly in the frame it first appears, and each row's layout tells the list its\n * height for sizing what is not rendered. Until a row has been measured it counts as\n * `estimatedItemHeight`. Measurements are kept by `keyExtractor`, so they follow their item across\n * inserts, removals and moves. `virtualListRow` on each row's view applies its style and reports\n * its layout; `[style]=\"row.style\"` still works for fixed heights, which need no measuring.\n *\n * Content marked `listHeader` and `listFooter` renders above and below the rows in normal flow,\n * as FlatList's header and footer components do. A `<refresh-control>` projects like any child.\n *\n * `<ng-template virtualListSeparator let-leading let-trailing=\"trailingItem\">` is drawn between\n * each pair of rows and not after the last, as FlatList's `ItemSeparatorComponent` is. It is drawn\n * inside the leading row's slot, at its trailing edge, so `itemHeight` includes it the way\n * `getItemLayout`'s `length` includes it in RN; a measured row has it drawn over its trailing edge\n * once its height is known. The slot it sits in lets touches through to the row underneath.\n *\n * `horizontal` swaps the axis: rows are placed by `left` and sized by `width`, and the offset is\n * read from `contentOffset.x`. `inverted` is a scale of -1 on the list and on each row, which is\n * how FlatList does it too - the list scrolls from the bottom and each row is flipped back the\n * right way up. The first item is the one at the bottom, so a chat passes its messages newest\n * first.\n *\n * `stickyIndices` pins a row to the leading edge while the rows under it scroll past, which is\n * FlatList's `stickyHeaderIndices` counted without the header. `stickyHeader` pins the\n * `listHeader` content the same way, FlatList's index 0 when it has a `ListHeaderComponent`, and\n * the first sticky row pushes it off as RN's sticky headers push each other. Neither is native:\n * RN's `ScrollView.js` translates a sticky child against the scroll offset in JavaScript, and a\n * row here follows the offset the same way while it is the current one - by its `top` when\n * absolutely positioned, by a transform when in flow.\n *\n * What is on screen stays on screen when a measured row above it turns out taller or shorter than\n * its estimate: the offset is corrected by the difference. `maintainVisibleContentPosition` does\n * the same for rows inserted or removed above it, which a feed receiving new posts and a chat\n * loading older messages above the ones being read both need.\n *\n * ponytail: viewability is `itemVisiblePercentThreshold` only: `minimumViewTime` and\n * `waitForInteraction` are timing policy on top of the same measurement, and nothing has needed\n * them. A separator is not told `highlighted`, which RN drives from the row's press state. A\n * sticky header follows the scroll a commit behind native, where RN's is on the native driver. A\n * held position is restored by a `scrollTo` after the commit, not in the mount as native\n * `maintainVisibleContentPosition` is, so a correction made mid-fling lands where the last scroll\n * event said the list was.\n */\n@Component({\n selector: 'virtual-list',\n exportAs: 'virtualList',\n imports: [TemplateSlot, View],\n // One content view holds the header, the rows and the footer, as ScrollView.js's content\n // container does: Android's ScrollView takes one child and throws on a second. It is never\n // collapsed, or Fabric would flatten it away and hand the scroll view all three again.\n // See ScrollView: the canvas carries only a height, so Fabric would flatten it away and drags\n // over the gaps between rows would not scroll. Separators come after the rows so they draw over\n // the slot they share. The spacer is there only when rows are in flow.\n // A refresh control comes first, as the scroll view's own child; see ScrollView.\n template: `\n <ng-content select=\"refresh-control\" />\n <view [style]=\"content()\" collapsable=\"false\">\n <view [style]=\"headerStyle()\" (layout)=\"onHeaderLayout($event)\"\n ><ng-content select=\"[listHeader]\"\n /></view>\n <view #rows [style]=\"canvas()\" collapsable=\"false\">\n @if (measuring()) {\n <view [style]=\"spacer()\"></view>\n }\n <ng-content />\n @if (separator(); as separator) {\n @for (gap of gaps(); track gap.index) {\n <view [style]=\"gap.style\"\n ><ng-container\n [templateSlot]=\"separator.template\"\n [templateSlotContext]=\"gap.context\"\n /></view>\n }\n }\n </view>\n <view [style]=\"footerStyle()\"><ng-content select=\"[listFooter]\" /></view>\n </view>\n `,\n host: {\n // ScrollView.js's `baseHorizontal`: a column would stack the header, canvas and footer, and\n // the canvas, holding only absolutely positioned rows, would have no height to give them. A\n // top-level prop, as on <scroll-view>, so the caller's own [style] still applies over it.\n '[flexDirection]': \"horizontal() ? 'row' : 'column'\",\n '[horizontal]': 'horizontal()',\n '[nestedScrollEnabled]': 'nestedScroll()',\n // A prop rather than `[style.transform]`: Angular stringifies a style binding, and a\n // transform is a list of objects. The engine flattens style into props anyway, so this is\n // where it would have ended up.\n '[transform]': 'flip()',\n '[scrollEventThrottle]': 'scrollEventThrottle()',\n '(scroll)': 'onScroll($event)',\n '(layout)': 'onLayout($event)',\n '(contentSizeChange)': 'onContentSize($event)',\n },\n})\nexport class VirtualList<T> extends ScrollViewProps {\n readonly items = input.required<readonly T[]>();\n /**\n * A fixed height, or a function for variable ones, when every row's size is known up front. The\n * function form builds a cumulative offset table and binary-searches it, which is what section\n * lists need: a header row and an item row are different heights, so uniform maths cannot place\n * them. Leave it unset for rows that size themselves.\n */\n readonly itemHeight = input<VirtualItemHeight<T>>();\n /**\n * What a row that sizes itself counts as until it has been measured. The closer it is, the more\n * honest the scroll bar is and the less a jump to an unmeasured row has to correct.\n */\n readonly estimatedItemHeight = input<VirtualItemHeight<T>>(50);\n /**\n * Space around the rows, inside the scrolling content. The leading side comes before the first\n * row and the trailing side after the last; the sides across the axis inset every row. The\n * header and footer sit outside it, as FlatList's do outside `contentContainerStyle`.\n */\n readonly contentPadding = input<VirtualListPadding>(0);\n /** Space between one row and the next, along the axis: not before the first or after the last. */\n readonly rowGap = input(0, { transform: numberOr(0) });\n /**\n * An item's identity, as FlatList's `keyExtractor`: what a measured height, a slot and a held\n * position follow across an insert. Without it an item is its own key, which is enough for items\n * that are replaced, not copied, when they change.\n */\n readonly keyExtractor = input<(item: T, index: number) => unknown>();\n /**\n * What kind of row an item is, when rows of different kinds share the list: a text post and a\n * photo post, a message and a date divider. A slot is only ever recycled into a row of the same\n * type, so its views are reused rather than torn down for another kind's, as UIKit's reuse\n * identifiers and FlashList's `getItemType` do.\n */\n readonly itemType = input<(item: T, index: number) => unknown>();\n /** Keep what is on screen still when rows are inserted or removed before it. */\n readonly maintainVisibleContentPosition = input<VirtualListVisiblePosition>();\n /** Rows rendered beyond each edge of the viewport, to cover fling gaps. */\n readonly overscan = input(4, { transform: numberOr(4) });\n /** How close to the end, in viewport heights, `(endReached)` fires. RN's default is 2. */\n readonly endReachedThreshold = input(2, { transform: numberOr(2) });\n\n /** Lay the rows out along x instead of y, and scroll that way. */\n readonly horizontal = input(false, { transform: booleanAttribute });\n /** Start at the end and scroll backwards, with every row flipped back the right way up. */\n readonly inverted = input(false, { transform: booleanAttribute });\n /**\n * Rows that pin to the leading edge while the ones under them scroll past. Ascending; a row is\n * pinned from the moment it would leave until the next sticky row pushes it off.\n */\n readonly stickyIndices = input<readonly number[]>([]);\n /** Pin the `listHeader` content to the leading edge until the first sticky row pushes it off. */\n readonly stickyHeader = input(false, { transform: booleanAttribute });\n /** What a tap in the list does while a text input has the keyboard up. See `ScrollView`. */\n readonly keyboardShouldPersistTaps = input<KeyboardShouldPersistTaps>('never');\n /** How much of a row must be on screen to count as viewable. RN's default is 0, meaning any. */\n readonly itemVisiblePercentThreshold = input(0, { transform: numberOr(0) });\n\n /**\n * The scroll position is within `endReachedThreshold` of the end: once per item count, and again\n * after the list has scrolled away from the end and come back.\n */\n readonly endReached = output<{ distanceFromEnd: number }>();\n\n /** Which rows are on screen, and what changed since last time. */\n readonly viewableItemsChanged = output<{\n viewable: readonly VirtualRow<T>[];\n entered: readonly number[];\n left: readonly number[];\n }>();\n\n private readonly viewport = signal(0);\n /** The leading edge of the viewport in content space, which sticky rows and viewability need. */\n private readonly offset = signal(0);\n private readonly headerHeight = signal(0);\n /** What native reported the content measures along the axis, once it has. */\n private contentSize = 0;\n /** The rows' own extent when native reported that, so a report for other rows is not used. */\n private contentSizeFor = -1;\n /** The item count `endReached` last fired for, cleared once the list is away from the end. */\n private endReachedFor = -1;\n\n /** Slot styles are cached so a scroll does not hand Fabric new prop objects for stable rows. */\n private readonly slots = new Map<number, Record<string, unknown>>();\n /** A separator's slot style, per row slot style, so it is as stable as the row's own. */\n private readonly gapStyles = new WeakMap<object, Record<string, unknown>>();\n /** The same for a measured row's separator, by key, while its place and size stay put. */\n private readonly measuredGaps = new Map<unknown, Record<string, unknown>>();\n\n protected readonly separator = contentChild<VirtualListSeparator<T>>(VirtualListSeparator);\n private readonly refreshControl = contentChild(RefreshControl);\n\n /** See ScrollView: inside Android's swipe layout the list must see a drag first. */\n protected readonly nestedScroll = computed(() =>\n nativePlatform() === 'android' && this.refreshControl() ? true : undefined,\n );\n\n /**\n * Whether native moves sticky rows. Each then stays at its own place in the list and native\n * translates it on every frame the list scrolls, as RN's `ScrollViewStickyHeader` does; a\n * translate committed from each scroll event lands a frame or more late, and on a fast fling\n * the row shudders and comes away from the edge.\n */\n private readonly nativeSticky = this.engine.drivesScroll;\n /** The offset once scrolling pauses, which the settled translate of a native-moved row is from. */\n private readonly settled = signal(0);\n private settleTimer: ReturnType<typeof setTimeout> | undefined;\n /** What native is moving, by row view, with the transform kept beside the translate. */\n private readonly drives = new Map<HostNode, { drive: ScrollDrive; statics: string }>();\n private readonly canvasView = viewChild.required('rows', { read: ElementRef });\n\n /** Whether the scroll offset is needed as a signal, which only pinning needs. */\n private readonly pinning = computed(() => this.stickyHeader() || this.stickyIndices().length > 0);\n\n /** Rows size themselves and are laid out in flow, rather than placed at a known offset. */\n readonly measuring = computed(() => this.itemHeight() === undefined);\n\n /** The padding on each side. */\n private readonly edges = computed<Edges>(() => {\n const padding = this.contentPadding();\n if (typeof padding === 'number') {\n return { top: padding, right: padding, bottom: padding, left: padding };\n }\n const { top = 0, right = 0, bottom = 0, left = 0 } = padding ?? {};\n return { top, right, bottom, left };\n });\n\n /** The padding before the first row, along the axis. */\n private readonly lead = computed(() =>\n this.horizontal() ? this.edges().left : this.edges().top,\n );\n\n /** The rows' insets across the axis, as the props that place an absolutely positioned row. */\n private readonly across = computed((): Record<string, number> => {\n const { top, right, bottom, left } = this.edges();\n return this.horizontal() ? { top, bottom } : { left, right };\n });\n\n /** Heights native has reported, by key. */\n private readonly measured = new Map<unknown, number>();\n /** Bumped when a measurement changes, which is what re-sizes the list. */\n private readonly measuredVersion = signal(0);\n\n /** Each item's key, or null when items are their own. */\n private readonly keys = computed<readonly unknown[] | null>(() => {\n const extract = this.keyExtractor();\n return extract ? this.items().map(extract) : null;\n });\n\n private keyAt(index: number): unknown {\n return this.keys()?.[index] ?? this.items()[index];\n }\n\n /**\n * Each row's size and where it starts, for variable heights; uniform rows need no index at all.\n * Built once per change of items. A measurement changes it in place and bumps\n * `measuredVersion`, which is what everything that reads it depends on, so a row laying out\n * costs a walk of the tree rather than a rebuild of every offset.\n */\n private readonly table = computed<HeightIndex | null>(() => {\n const height = this.itemHeight();\n if (typeof height === 'number') return null;\n\n // Each row's entry is its size and the gap after it, so where a row starts counts the gaps\n // before it without a second table.\n const gap = this.rowGap();\n const items = this.items();\n const sizes = new Float64Array(items.length);\n if (height) {\n for (let i = 0; i < items.length; i++) sizes[i] = height(items[i]!, i) + gap;\n return new HeightIndex(sizes);\n }\n const estimate = this.estimatedItemHeight();\n const keys = this.keys();\n for (let i = 0; i < items.length; i++) {\n const size =\n this.measured.get(keys ? keys[i] : items[i]) ??\n (typeof estimate === 'number' ? estimate : estimate(items[i]!, i));\n sizes[i] = size + gap;\n }\n return new HeightIndex(sizes);\n });\n\n /** Where each key is, so a measurement finds its row without a search. */\n private readonly indexOfKey = computed(() => {\n if (!this.measuring()) return null;\n const map = new Map<unknown, number>();\n (this.keys() ?? this.items()).forEach((key, index) => map.set(key, index));\n return map;\n });\n\n /** The index, with a dependency on its measurements for whoever is reading it. */\n private layout(): HeightIndex | null {\n const table = this.table();\n if (table) this.measuredVersion();\n return table;\n }\n\n /**\n * The list's own total extent along its axis: the padding at both ends, the rows, and a gap\n * between each two of them.\n */\n private readonly extent = computed(() => {\n const table = this.layout();\n const count = this.items().length;\n const rows = table ? table.total : count * this.stride();\n const { top, right, bottom, left } = this.edges();\n const padding = this.horizontal() ? left + right : top + bottom;\n return padding + (count ? rows - this.rowGap() : 0);\n });\n\n /** A fixed-height row and the gap after it. */\n private stride(): number {\n return (this.itemHeight() as number) + this.rowGap();\n }\n\n /** ScrollView.js's `contentContainerHorizontal`: the header, rows and footer side by side. */\n protected readonly content = computed(() =>\n this.horizontal() ? { flexDirection: 'row' } : undefined,\n );\n\n protected readonly canvas = computed(() =>\n this.horizontal() ? { width: this.extent(), flexDirection: 'row' } : { height: this.extent() },\n );\n\n /**\n * `scaleY: -1` on the list, and the same on every row.\n *\n * The list ends up scrolled from the far end with its rows in reverse, and the second flip puts\n * each row's own content back the right way up. It is what `FlatList` does, and it is why an\n * inverted list needs no reversed maths: the first item is at offset 0, which is the bottom.\n */\n protected readonly flip = computed<StaticTransform[] | undefined>(() => {\n if (!this.inverted()) return undefined;\n const scale: StaticTransform = this.horizontal() ? { scaleX: -1 } : { scaleY: -1 };\n return [scale];\n });\n\n /**\n * The flip as a style's transform: CSS text, which the engine turns into the list native reads.\n * A style binding validates its values as the DOM's, and warns on a list in development.\n */\n private readonly flipText = computed(() => {\n if (!this.inverted()) return undefined;\n return this.horizontal() ? 'scaleX(-1)' : 'scaleY(-1)';\n });\n\n /**\n * What places a row in flow: the gap after it and the padding across the axis, as margins, since\n * native lays the row out. Empty when there are none, so a plain list commits no margins.\n */\n private readonly flowSpacing = computed<Record<string, unknown>>(() => {\n const gap = this.rowGap();\n const { top, right, bottom, left } = this.edges();\n const spacing: Record<string, number> = this.horizontal()\n ? { marginRight: gap, marginTop: top, marginBottom: bottom }\n : { marginBottom: gap, marginLeft: left, marginRight: right };\n return Object.fromEntries(Object.entries(spacing).filter(([, value]) => value !== 0));\n });\n\n /** A row in flow, flipped back when the list is inverted. One object, so rows never re-clone. */\n private readonly flowStyle = computed(() => {\n const flip = this.flipText();\n const spacing = this.flowSpacing();\n if (!flip && Object.keys(spacing).length === 0) return IN_FLOW;\n return flip ? { ...spacing, transform: flip } : spacing;\n });\n\n /** Top of a row: the leading padding, and every row and gap before it. */\n private topOf(index: number): number {\n const table = this.layout();\n return this.lead() + (table ? table.topOf(index) : index * this.stride());\n }\n\n /** A row's own size, without the gap after it. */\n private heightOf(index: number): number {\n const table = this.layout();\n return table ? table.heightOf(index) - this.rowGap() : (this.itemHeight() as number);\n }\n\n /** First row whose bottom, or the gap after it, is past `y`. */\n private indexAt(y: number): number {\n const table = this.layout();\n const along = y - this.lead();\n if (!table) return Math.max(0, Math.floor(along / this.stride()));\n return table.indexAt(along);\n }\n\n // --- holding position -------------------------------------------------------------------\n\n /** The row the viewport's leading edge is in, taken at each scroll. */\n private anchor: Anchor<T> | null = null;\n /** The last offset seen. A field rather than a signal: reading it renders nothing. */\n private lastOffset = 0;\n /**\n * A correction to make once the commit that needs it is on its way to native: an offset in the\n * rows' own space, after the header, or the very start of the list.\n */\n private pendingScroll: { offset: number; animated: boolean } | 'start' | null = null;\n\n /** What moves the rows: which items, and where each one is. */\n private readonly placement = computed(() => ({\n items: this.items(),\n table: this.table(),\n version: this.measuredVersion(),\n }));\n\n /**\n * The first *visible* row, not the first rendered one, and not the raw scroll offset. A fling\n * produces a scroll event per frame, and setting a signal on each one costs a change-detection\n * pass even when the visible rows are identical. Deriving the index in the handler means most\n * scroll events change nothing and cost nothing.\n *\n * Linked to the rows' placement, because that is when the row on screen can move without the\n * user scrolling: an insert above it, or a row above it measuring differently from its estimate.\n * The index follows the anchored row there, and the offset follows it too.\n */\n private readonly visible = linkedSignal<\n { items: readonly T[]; table: HeightIndex | null; version: number },\n number\n >({\n source: this.placement,\n computation: (placement) => this.reanchor(placement.items),\n });\n\n /** Take the anchor at a row, keeping the viewport where it is. */\n private anchorAt(at: number, offset: number): void {\n const items = this.items();\n if (!items.length) {\n this.anchor = null;\n return;\n }\n const index = Math.min(at, items.length - 1);\n this.anchor = { key: this.keyAt(index), within: offset - this.topOf(index), items, index };\n }\n\n /**\n * Where the row on screen went when the rows moved under it, and the offset that keeps it where\n * the user left it. An insert or a removal is only held when the caller asked for it; a row\n * above measuring differently always is, since nothing the user did moved anything.\n */\n private reanchor(items: readonly T[]): number {\n const anchor = this.anchor;\n // Empty for a moment, as a filter typed through leaves it: the offset is kept for what comes.\n if (!items.length) return 0;\n if (!anchor) return this.atOffset();\n\n const index = this.heldIndex(anchor, items);\n if (index === 'start') return this.showStart();\n if (index < 0) return this.atOffset();\n const held = this.topOf(index) + anchor.within;\n if (Math.abs(held - this.lastOffset) > HOLD_TOLERANCE) {\n this.pendingScroll = { offset: held, animated: false };\n this.lastOffset = held;\n }\n this.anchor = { ...anchor, items, index };\n return index;\n }\n\n /**\n * The row under the offset native is still at, in rows that have just replaced the old ones, as\n * a filter replaces them. Native keeps its offset whatever the items became, so the window is\n * worked out from that, not from the old row's index, which in the new rows sits somewhere else.\n * When the new rows end before that offset, the list is scrolled back to their end: native\n * would otherwise stay scrolled past it, showing nothing until the next drag.\n */\n private atOffset(): number {\n const end = Math.max(0, this.extent() - this.viewport());\n if (this.viewport() > 0 && this.lastOffset > end + HOLD_TOLERANCE) {\n this.pendingScroll = { offset: end, animated: false };\n this.lastOffset = end;\n }\n const index = Math.max(0, Math.min(this.indexAt(this.lastOffset), this.items().length - 1));\n this.anchorAt(index, this.lastOffset);\n return index;\n }\n\n /**\n * The index to hold the viewport at, -1 to let it move, or the start of the list when an\n * insert lands within the autoscroll threshold of it.\n */\n private heldIndex(anchor: Anchor<T>, items: readonly T[]): number | 'start' {\n if (items === anchor.items) return anchor.index;\n const hold = this.maintainVisibleContentPosition();\n if (!hold) return -1;\n const threshold = hold.autoscrollToTopThreshold;\n if (threshold !== undefined && this.lastOffset <= threshold) return 'start';\n const index = this.successorOf(anchor, items);\n return index < (hold.minIndexForVisible ?? 0) ? -1 : index;\n }\n\n /** Scroll to what arrived at the start, rather than holding the viewport past it. */\n private showStart(): number {\n this.anchorAt(0, 0);\n if (this.lastOffset !== 0) this.pendingScroll = 'start';\n this.lastOffset = 0;\n return 0;\n }\n\n /**\n * The anchored row's new index, or the first row after it that survived when it did not. Only\n * the rows that were rendered are searched for a successor: past those the viewport has moved\n * on, and holding it by something off screen would be holding it by nothing the user saw.\n */\n private successorOf(anchor: Anchor<T>, items: readonly T[]): number {\n const keys = this.keys() ?? items;\n const index = keys.indexOf(anchor.key);\n if (index !== -1) return index;\n const extract = this.keyExtractor();\n const was = anchor.items;\n const limit = Math.min(was.length, anchor.index + this.overscan() * 4 + 1);\n for (let i = anchor.index + 1; i < limit; i++) {\n const successor = keys.indexOf(extract ? extract(was[i]!, i) : was[i]);\n if (successor !== -1) return successor;\n }\n return -1;\n }\n\n /** Make a queued correction, after the commit that moved the rows has gone to native. */\n private flushScroll(): void {\n const pending = this.pendingScroll;\n if (!pending) return;\n this.pendingScroll = null;\n if (pending === 'start') this.scrollToOffset({ offset: 0, animated: true });\n else this.scrollToOffset({ offset: this.headerHeight() + pending.offset, animated: false });\n }\n\n /** In development, a list with rows that stays at zero size; see `ZeroSizeWarning`. */\n private readonly zeroSize = checksZeroSize()\n ? new ZeroSizeWarning(\n () => written(this.node),\n () => !!this.horizontal(),\n )\n : null;\n\n constructor() {\n super();\n afterEveryRender(() => {\n this.flushScroll();\n if (this.nativeSticky) this.driveStickyRows();\n this.recheckItems();\n });\n const stop = dismissKeyboardOnTap(this.engine, this.node, () =>\n this.keyboardShouldPersistTaps(),\n );\n inject(DestroyRef).onDestroy(() => {\n stop();\n clearTimeout(this.settleTimer);\n this.zeroSize?.stop();\n for (const held of this.drives.values()) held.drive.stop();\n });\n if (this.zeroSize) this.checkZeroSize(this.zeroSize);\n }\n\n /** The items the end and viewability were last checked against after a render. */\n private checkedItems: readonly T[] | null = null;\n\n /**\n * New items can bring the end within reach or change what is on screen with no scroll: a list\n * shorter than its viewport, a page appended while at the end, a filter. Checked once the rows\n * they make are rendered, and only when they changed, so any other render costs a comparison.\n */\n private recheckItems(): void {\n const items = this.items();\n if (items === this.checkedItems) return;\n this.checkedItems = items;\n this.checkEnd(this.headerHeight() + this.lastOffset);\n this.announceViewable(this.lastOffset);\n }\n\n /** Whether the viewport has been laid out yet, so a zero in it is a measurement. */\n private viewportMeasured = false;\n\n /**\n * In development, rows that arrive in a list already measured at zero, or go from one, with no\n * new layout to say so: an update to `items` alone does not lay the viewport out again.\n */\n private checkZeroSize(warning: ZeroSizeWarning): void {\n effect(() => {\n const hasRows = this.items().length > 0;\n if (this.viewportMeasured) warning.laidOut(untracked(this.viewport), hasRows);\n });\n }\n\n // --- the window ---------------------------------------------------------------------------\n\n /** The rows to render, and the edges of the run they sit in. */\n private readonly span = computed<Span | null>(() => {\n const items = this.items();\n const viewport = this.viewport();\n const overscan = this.overscan();\n if (!items.length) return null;\n\n const visible = Math.min(this.visible(), items.length - 1);\n const first = Math.max(0, visible - overscan);\n // Before the first layout we have no viewport, so render a screen's worth optimistically\n // rather than nothing: an empty first frame is worse than a few extra rows.\n const budget = viewport > 0 ? viewport : this.heightOf(first) * overscan * 2;\n /*\n * Measured from the top of the first *visible* row, not the first rendered one.\n *\n * Anchoring it at `first` - which is already backed off by the overscan - spent the budget\n * on rows above the viewport, so the window ran out that far before the bottom of the\n * screen. The trailing `+ overscan` hid it whenever every row was the same height, because\n * then the rows added below happened to be worth exactly the rows wasted above. With mixed\n * heights they are not, and the list clips short of its own bottom.\n */\n const top = this.topOf(visible);\n\n let last = visible;\n while (last < items.length && this.topOf(last) < top + budget) last++;\n return { first, last: Math.min(items.length, last + overscan) };\n });\n\n readonly window = computed<VirtualRow<T>[]>(() => {\n const span = this.span();\n if (!span) return [];\n const rows = this.rowsFor(this.items(), span.first, span.last);\n this.trimParked();\n for (const pool of this.parked.values()) rows.push(...pool);\n // The cache exists for rows that stay in the window between scrolls; anything that has left\n // it is rebuilt if it comes back, so the map stays the size of the window, not of the list.\n for (const index of this.slots.keys()) {\n if (index < span.first || index >= span.last) this.slots.delete(index);\n }\n return rows;\n });\n\n /**\n * What stands in for the rows above the window when rows are in flow: their total extent, less\n * a pinned row's, which is rendered in flow ahead of the window.\n */\n protected readonly spacer = computed(() => {\n const span = this.span();\n let lead = span ? this.topOf(span.first) : 0;\n const pinned = this.pinnedIndex();\n if (span && pinned !== null && pinned < span.first) {\n lead = this.nativeSticky ? this.topOf(pinned) : lead - this.heightOf(pinned) - this.rowGap();\n }\n return this.horizontal() ? { width: Math.max(0, lead) } : { height: Math.max(0, lead) };\n });\n\n /** The rows from `first` up to `last`, and the pinned row above them if there is one. */\n private rowsFor(items: readonly T[], first: number, last: number): VirtualRow<T>[] {\n const rows: VirtualRow<T>[] = [];\n const pinned = this.pinnedIndex();\n const pinnedAbove = pinned !== null && pinned < first;\n this.releaseRecycled(first, last, pinnedAbove ? pinned : null);\n // The pinned row is on screen even when its own place in the list is not, which is the whole\n // point of it, so it is rendered whether or not the window reaches that far.\n if (pinnedAbove) {\n const key = this.keyAt(pinned);\n rows.push(\n this.hold({\n index: pinned,\n slot: this.recycledSlot(key, items[pinned]!, pinned),\n key,\n item: items[pinned]!,\n style: this.nativeSticky\n ? this.stickyStyle(pinned)\n : this.measuring()\n ? this.pinnedFlowStyle(this.topOf(first) - this.heightOf(pinned) - this.rowGap())\n : this.slotStyle(pinned, this.offset()),\n }),\n );\n }\n for (let index = first; index < last; index++) {\n const key = this.keyAt(index);\n rows.push(\n this.hold({\n index,\n slot: this.recycledSlot(key, items[index]!, index),\n key,\n item: items[index]!,\n style: this.styleFor(index, index === pinned),\n }),\n );\n }\n if (pinnedAbove && this.nativeSticky && this.measuring()) this.leadWindow(rows, pinned, first);\n return rows;\n }\n\n /**\n * A pinned row native moves stays at its own place, so the rows between it and the window are\n * made up before the window rather than after the row: new props on a view native is moving\n * put its transform back for a frame.\n */\n private leadWindow(rows: VirtualRow<T>[], pinned: number, first: number): void {\n const lead = rows[1];\n // The pinned row's own gap already follows it in flow.\n const between = this.topOf(first) - this.topOf(pinned) - this.heightOf(pinned) - this.rowGap();\n if (!lead || between <= 0) return;\n const margin = this.horizontal() ? 'marginLeft' : 'marginTop';\n rows[1] = this.hold({ ...lead, style: { ...lead.style, [margin]: between } });\n }\n\n private styleFor(index: number, pinned: boolean): Record<string, unknown> {\n if (this.nativeSticky && this.nextSticky().has(index)) return this.stickyStyle(index);\n if (this.measuring()) {\n return pinned ? this.pinnedFlowStyle(this.topOf(index)) : this.flowStyle();\n }\n return pinned ? this.slotStyle(index, this.offset()) : this.slotStyle(index);\n }\n\n /** A pinned row in flow, moved from where flow put it to the leading edge by a transform. */\n private pinnedFlowStyle(at: number): Record<string, unknown> {\n const shift = Math.max(0, this.offset() - at);\n const move = `${this.horizontal() ? 'translateX' : 'translateY'}(${shift}px)`;\n const flip = this.flipText();\n return { ...this.flowSpacing(), zIndex: 1, transform: flip ? `${move} ${flip}` : move };\n }\n\n /**\n * A sticky row native moves: at its own place, with the translate native had reached when\n * scrolling paused, so the props agree with what is on screen.\n */\n private stickyStyle(index: number): Record<string, unknown> {\n const horizontal = this.horizontal();\n const style: Record<string, unknown> = this.measuring()\n ? { ...this.flowSpacing() }\n : { ...this.slotStyle(index) };\n style['zIndex'] = 1;\n const top = this.topOf(index);\n const shift = Math.min(Math.max(0, this.settled() - top), this.stopOf(index) - top);\n const move = shift > 0 ? `${horizontal ? 'translateX' : 'translateY'}(${shift}px)` : '';\n const transform = [move, this.flipText() ?? ''].filter(Boolean).join(' ');\n if (transform) style['transform'] = transform;\n return style;\n }\n\n /** Each sticky row, and the one after it, which pushes it off. */\n private readonly nextSticky = computed(() => {\n const sticky = this.stickyIndices();\n return new Map(sticky.map((index, at) => [index, sticky[at + 1]]));\n });\n\n /** Where a sticky row stops, pushed off by the next: that row's top, less this row's size. */\n private stopOf(index: number): number {\n const next = this.nextSticky().get(index);\n return next === undefined ? Infinity : this.topOf(next) - this.heightOf(index);\n }\n\n /**\n * How native moves a rendered row, or null when it does not: along the scroll view's own\n * offset, which counts the header, from the row's top until the next sticky row pushes it off.\n */\n private stickyDrive(\n row: VirtualRow<T>,\n ): { range: ScrollRange; statics: readonly StaticTransform[] } | null {\n if (!this.nativeSticky || row.parked || !this.nextSticky().has(row.index)) return null;\n const header = this.headerHeight();\n const start = header + this.topOf(row.index);\n return {\n range: pinnedRange(start, header + this.stopOf(row.index)),\n statics: this.flip() ?? [],\n };\n }\n\n /**\n * Hand each rendered sticky row's view to native to move, and let go of the rest. The rows'\n * views are the canvas's element children in window order, after the spacer, which is how\n * `@for` over `window()` leaves them.\n */\n private driveStickyRows(): void {\n if (!this.pinning() && this.drives.size === 0) return;\n const canvas = this.canvasView().nativeElement as HostNode;\n const views = canvas.childList\n .filter((child) => child.nodeKind === 'element')\n .slice(this.measuring() ? 1 : 0);\n const axis = this.horizontal() ? 'x' : 'y';\n const live = new Set<HostNode>();\n this.window().forEach((row, at) => {\n const view = views[at];\n const next = this.stickyDrive(row);\n if (!view || !next) return;\n live.add(view);\n const statics = JSON.stringify(next.statics);\n const held = this.drives.get(view);\n if (held?.statics === statics) return held.drive.update(next.range);\n held?.drive.stop();\n const drive = this.engine.driveByScroll(view, this.node, axis, next.range, next.statics);\n if (drive) this.drives.set(view, { drive, statics });\n });\n for (const [view, held] of this.drives) {\n if (live.has(view)) continue;\n held.drive.stop();\n this.drives.delete(view);\n }\n }\n\n /** Which recycling slot each rendered item holds, by key: its type, and the row it last drew. */\n private readonly recycled = new Map<\n unknown,\n { slot: number; type: unknown; row: VirtualRow<T> | null }\n >();\n /** Slots that have left the window and are kept hidden, by the type of row that held them. */\n private readonly parked = new Map<unknown, VirtualRow<T>[]>();\n private nextSlot = 0;\n\n /** Note the row a slot is drawing, for parking it once it leaves. */\n private hold(row: VirtualRow<T>): VirtualRow<T> {\n const held = this.recycled.get(row.key);\n if (held) held.row = row;\n return row;\n }\n\n /**\n * Park the slots of the items that have left the window, for the items arriving.\n *\n * Parked rather than freed: a slot missing from the window is destroyed by `@for`, so a slot is\n * only reused if a row of its type arrives in the same pass as it left. Kept rendered and\n * hidden, it waits for the next row of its type however many passes later, which is what a\n * reuse queue of cells does in UIKit.\n */\n private releaseRecycled(first: number, last: number, pinned: number | null): void {\n const keep = new Set<unknown>();\n for (let index = first; index < last; index++) keep.add(this.keyAt(index));\n if (pinned !== null) keep.add(this.keyAt(pinned));\n for (const [key, held] of this.recycled) {\n if (keep.has(key)) continue;\n this.recycled.delete(key);\n let pool = this.parked.get(held.type);\n if (!pool) this.parked.set(held.type, (pool = []));\n pool.push({ ...(held.row ?? this.placeholder(key, held.slot)), parked: true, style: PARKED });\n }\n }\n\n /**\n * Keep a few hidden slots of each type once this pass has taken what it needs, dropping the\n * oldest: `@for` destroys the views of a slot that leaves the window for good.\n */\n private trimParked(): void {\n for (const pool of this.parked.values()) {\n if (pool.length > PARK_LIMIT) pool.splice(0, pool.length - PARK_LIMIT);\n }\n }\n\n /** A parked row for a slot that never drew, which only a slot taken and left in one pass is. */\n private placeholder(key: unknown, slot: number): VirtualRow<T> {\n return { index: -1, slot, key, item: this.items()[0]!, style: PARKED };\n }\n\n private recycledSlot(key: unknown, item: T, index: number): number {\n const held = this.recycled.get(key);\n if (held) return held.slot;\n const type = this.itemType()?.(item, index);\n const slot = this.parked.get(type)?.pop()?.slot ?? this.nextSlot++;\n this.recycled.set(key, { slot, type, row: null });\n return slot;\n }\n\n /**\n * A row laid itself out; what `virtualListRow` calls. Only a row that sizes itself is measured,\n * and a height that has not changed changes nothing.\n */\n measureRow(row: VirtualRow<T>, layout: { width?: number; height?: number } | undefined): void {\n if (!this.measuring() || !layout || row.parked) return;\n const size = this.horizontal() ? layout.width : layout.height;\n if (size === undefined || this.measured.get(row.key) === size) return;\n this.measured.set(row.key, size);\n this.forgetDeparted();\n const index = this.indexOfKey()?.get(row.key);\n if (index === undefined) return;\n this.table()?.set(index, size + this.rowGap());\n this.measuredVersion.update((version) => version + 1);\n }\n\n /**\n * A row handed a view native has laid out before. Native reports a layout only when a view's\n * frame differs from the last one it reported, so an item that lands where the view already was,\n * at the same size, is never measured; the view's last size is its own until native says\n * otherwise.\n */\n adoptRow(row: VirtualRow<T>, layout: { width?: number; height?: number }): void {\n if (!this.measured.has(row.key)) this.measureRow(row, layout);\n }\n\n /** Drop the measurements of items long gone, so churn cannot grow the map without bound. */\n private forgetDeparted(): void {\n const items = this.items();\n if (this.measured.size <= items.length * 2 + 64) return;\n const current = new Set(this.keys() ?? items);\n for (const key of this.measured.keys()) if (!current.has(key)) this.measured.delete(key);\n }\n\n /** A separator for every rendered row but the list's last, in its leading row's slot. */\n protected readonly gaps = computed<Gap<T>[]>(() => {\n if (!this.separator()) return [];\n const items = this.items();\n const gaps: Gap<T>[] = [];\n for (const row of this.window()) {\n if (row.parked || row.index >= items.length - 1) continue;\n const style = this.measuring() ? this.measuredGapStyle(row) : this.gapStyle(row);\n if (!style) continue;\n const trailingItem = items[row.index + 1]!;\n gaps.push({\n index: row.index,\n style,\n context: {\n $implicit: row.item,\n leadingItem: row.item,\n trailingItem,\n leadingIndex: row.index,\n },\n });\n }\n return gaps;\n });\n\n /** The row's own slot, laid out to put the separator at its trailing edge. */\n private gapStyle(row: VirtualRow<T>): Record<string, unknown> {\n let style = this.gapStyles.get(row.style);\n if (!style) {\n style = {\n ...row.style,\n flexDirection: this.horizontal() ? 'row' : 'column',\n justifyContent: 'flex-end',\n pointerEvents: 'box-none',\n };\n this.gapStyles.set(row.style, style);\n }\n return style;\n }\n\n /**\n * A measured row's slot, over the row itself: nothing until its height is known, since drawing\n * it at the estimate would put a line through the middle of a row that turns out taller.\n */\n private measuredGapStyle(row: VirtualRow<T>): Record<string, unknown> | null {\n if (!this.measured.has(row.key)) return null;\n const start = this.topOf(row.index);\n const size = this.heightOf(row.index);\n const horizontal = this.horizontal();\n const flip = this.flipText();\n const across = this.across();\n const cached = this.measuredGaps.get(row.key);\n const placed = horizontal\n ? { ...across, left: start, width: size, transform: flip }\n : { ...across, top: start, height: size, transform: flip };\n if (cached && holds(cached, placed)) return cached;\n const style: Record<string, unknown> = horizontal\n ? { position: 'absolute', ...across, left: start, width: size, flexDirection: 'row' }\n : { position: 'absolute', ...across, top: start, height: size };\n style['justifyContent'] = 'flex-end';\n style['pointerEvents'] = 'box-none';\n if (flip) style['transform'] = flip;\n this.measuredGaps.set(row.key, style);\n if (this.measuredGaps.size > 256) this.measuredGaps.clear();\n return style;\n }\n\n /**\n * The header's translation while it is pinned: the scroll position, held back at zero by an\n * overscroll and at the first sticky row, which pushes it off.\n */\n protected readonly headerStyle = computed(() => {\n const flip = this.flipText();\n if (!this.stickyHeader()) return flip ? { transform: flip } : undefined;\n const along = this.offset() + this.headerHeight();\n const first = this.stickyIndices()[0];\n const limit = first === undefined ? Infinity : this.topOf(first);\n const shift = Math.min(Math.max(0, along), limit);\n const move = shift > 0 ? `${this.horizontal() ? 'translateX' : 'translateY'}(${shift}px)` : '';\n const transform = [move, flip ?? ''].filter(Boolean).join(' ');\n return transform ? { zIndex: 1, transform } : { zIndex: 1 };\n });\n\n /**\n * The footer, flipped back like every row when the list is inverted, as FlatList inverts its\n * header and footer cells too; otherwise both read upside down.\n */\n protected readonly footerStyle = computed(() => {\n const flip = this.flipText();\n return flip ? { transform: flip } : undefined;\n });\n\n /**\n * The sticky row currently holding the leading edge: the last one at or before the offset.\n * Null when the list has scrolled back above the first of them.\n */\n private readonly pinnedIndex = computed<number | null>(() => {\n const sticky = this.stickyIndices();\n if (sticky.length === 0) return null;\n const offset = this.offset();\n\n let pinned: number | null = null;\n for (const index of sticky) {\n if (this.topOf(index) <= offset) pinned = index;\n else break;\n }\n return pinned;\n });\n\n /** Which rows are on screen far enough to count, by the caller's threshold. */\n private viewableAt(offset: number): number[] {\n const viewport = this.viewport();\n if (!viewport) return [];\n\n const threshold = this.itemVisiblePercentThreshold() / 100;\n const rows: number[] = [];\n for (const row of this.window()) {\n if (row.parked) continue;\n const start = this.topOf(row.index);\n const size = this.heightOf(row.index);\n const shown = Math.min(start + size, offset + viewport) - Math.max(start, offset);\n if (shown > 0 && shown >= size * threshold) rows.push(row.index);\n }\n return rows;\n }\n\n /** The last set announced, so the output fires on a change rather than on every frame. */\n private announced: number[] = [];\n /** The items the last set was announced from: new items are a change even at the same indices. */\n private announcedFrom: readonly T[] | null = null;\n\n /**\n * Announce a change in what is on screen.\n *\n * Deliberately not a `computed` over a signal offset. A fling produces a scroll event per\n * frame, and writing a signal on each one costs a change-detection pass whether or not anything\n * moved into view; comparing here costs an array walk over the window and emits only when the\n * set really changed.\n */\n private announceViewable(offset: number): void {\n const viewable = this.viewableAt(offset);\n const entered = viewable.filter((index) => !this.announced.includes(index));\n const left = this.announced.filter((index) => !viewable.includes(index));\n const items = this.items();\n const same = items === this.announcedFrom || viewable.length === 0;\n if (entered.length === 0 && left.length === 0 && same) return;\n\n this.announced = viewable;\n this.announcedFrom = items;\n this.viewableItemsChanged.emit({\n viewable: viewable.map((index) => {\n const key = this.keyAt(index);\n return {\n index,\n // What is viewable is in the window, so it holds a slot already.\n slot: this.recycled.get(key)?.slot ?? -1,\n key,\n item: items[index]!,\n style: this.styleFor(index, false),\n };\n }),\n entered,\n left,\n });\n }\n\n /**\n * Scroll so that a row is at the start of the viewport, less `viewOffset`. The window moves\n * there at once, and the row is held there while the rows around it are measured.\n */\n scrollToIndex(options: { index: number; animated?: boolean; viewOffset?: number }): void {\n const items = this.items();\n if (!items.length) return;\n const index = Math.max(0, Math.min(options.index, items.length - 1));\n const within = -(options.viewOffset ?? 0);\n const offset = this.topOf(index) + within;\n this.lastOffset = offset;\n this.anchor = { key: this.keyAt(index), within, items, index };\n this.visible.set(index);\n this.scrollToOffset({ offset: this.headerHeight() + offset, animated: options.animated });\n }\n\n /** Scroll to an offset along the list's own axis: x when it is horizontal, y otherwise. */\n scrollToOffset(options: { offset: number; animated?: boolean }): void {\n const { offset, animated = true } = options;\n const [x, y] = this.horizontal() ? [offset, 0] : [0, offset];\n this.engine.dispatchCommand(this.node, 'scrollTo', [x, y, animated]);\n }\n\n scrollToEnd(options: { animated?: boolean } = {}): void {\n this.engine.dispatchCommand(this.node, 'scrollToEnd', [options.animated ?? true]);\n }\n\n private slotStyle(index: number, pinnedAt?: number): Record<string, unknown> {\n const start = pinnedAt ?? this.topOf(index);\n const size = this.heightOf(index);\n const horizontal = this.horizontal();\n const key = horizontal ? 'left' : 'top';\n const extent = horizontal ? 'width' : 'height';\n\n const flip = this.flipText();\n const across = this.across();\n\n let style = this.slots.get(index);\n // The flip is part of the comparison because turning the list over changes every row, and a\n // cached slot would otherwise keep the orientation it was built with.\n const placed = { ...across, [extent]: size, [key]: start, transform: flip };\n const stale = !style || pinnedAt !== undefined || !holds(style, placed);\n\n if (stale) {\n style = horizontal\n ? { position: 'absolute', ...across, left: start, width: size }\n : { position: 'absolute', ...across, top: start, height: size };\n // A pinned row draws over the ones sliding under it; the transform is the row's half of\n // the inversion.\n if (pinnedAt !== undefined) style['zIndex'] = 1;\n if (flip) style['transform'] = flip;\n this.slots.set(index, style);\n return style;\n }\n return style!;\n }\n\n protected onScroll(\n event: NativeSyntheticEvent<{ contentOffset?: { x?: number; y?: number } }>,\n ): void {\n const contentOffset = event.nativeEvent?.contentOffset;\n const along = (this.horizontal() ? contentOffset?.x : contentOffset?.y) ?? 0;\n const content = along - this.headerHeight();\n\n // The first *visible* row, not the first rendered one. The overscan is applied where the\n // window is built, so that both edges can be measured from the same place.\n // Not clamped to the items: an input set in the same task as this event has not reached the\n // list yet, and the window clamps when it renders.\n const visible = this.indexAt(content);\n if (visible !== this.visible()) this.visible.set(visible);\n this.lastOffset = content;\n this.anchorAt(visible, content);\n // A pinned row follows the scroll continuously, so with sticky rows the offset has to be a\n // signal - and only then. Without them this stays a field, and a fling that moves no row in\n // or out of the window costs no change detection at all.\n if (this.pinning()) this.offset.set(content);\n if (this.nativeSticky && this.pinning()) this.settleAfterPause(content);\n this.checkEnd(along);\n this.announceViewable(content);\n }\n\n /** A pinned row's translate, settled once scrolling pauses: see `STICKY_SETTLE_MS`. */\n private settleAfterPause(content: number): void {\n clearTimeout(this.settleTimer);\n this.settleTimer = setTimeout(() => this.settled.set(content), STICKY_SETTLE_MS);\n }\n\n protected onLayout(\n event: NativeSyntheticEvent<{ layout?: { width?: number; height?: number } }>,\n ): void {\n const layout = event.nativeEvent?.layout;\n this.viewport.set((this.horizontal() ? layout?.width : layout?.height) ?? 0);\n this.viewportMeasured = true;\n this.zeroSize?.laidOut(this.viewport(), this.items().length > 0);\n this.checkEnd(this.headerHeight() + this.lastOffset);\n this.announceViewable(this.lastOffset);\n }\n\n /** The header's extent along the axis, which every row sits after. */\n protected onHeaderLayout(\n event: NativeSyntheticEvent<{ layout?: { width?: number; height?: number } }>,\n ): void {\n const layout = event.nativeEvent?.layout;\n const height = (this.horizontal() ? layout?.width : layout?.height) ?? 0;\n if (height === this.headerHeight()) return;\n this.headerHeight.set(height);\n this.holdPastHeader();\n }\n\n /**\n * The header grew or shrank - a typing indicator in a chat's, a banner in a feed's - and every\n * row moved with it. Held like an insert when the caller asked for that and the viewport is\n * past the header, among the rows; at the start the user is looking at the header, and it is\n * left to push the rows along. Made at once rather than after a render, because a layout arrives\n * outside change detection and nothing else may be about to render.\n */\n private holdPastHeader(): void {\n const hold = this.maintainVisibleContentPosition();\n if (!hold || this.lastOffset <= (hold.autoscrollToTopThreshold ?? 0)) return;\n this.scrollToOffset({ offset: this.headerHeight() + this.lastOffset, animated: false });\n }\n\n protected onContentSize(event: NativeSyntheticEvent<{ width?: number; height?: number }>): void {\n const size = event.nativeEvent;\n this.contentSize = (this.horizontal() ? size?.width : size?.height) ?? 0;\n this.contentSizeFor = this.extent();\n this.checkEnd(this.headerHeight() + this.lastOffset);\n }\n\n private checkEnd(y: number): void {\n const count = this.items().length;\n const viewport = this.viewport();\n if (!count || !viewport) return;\n // Native's size is for the rows it last laid out; until it reports for these, their own extent.\n const extent = this.extent();\n const reported = this.contentSizeFor === extent ? this.contentSize : 0;\n const total = reported || this.headerHeight() + extent;\n const distanceFromEnd = total - (y + viewport);\n // Away from the end again re-arms it, as React Native does, so a load that failed is retried\n // the next time the user comes back down.\n if (distanceFromEnd > this.endReachedThreshold() * viewport) {\n this.endReachedFor = -1;\n return;\n }\n if (this.endReachedFor === count) return;\n this.endReachedFor = count;\n this.endReached.emit({ distanceFromEnd });\n }\n}\n\n/** Whether a cached slot style already has every one of these props. */\nfunction holds(style: Record<string, unknown>, props: Record<string, unknown>): boolean {\n return Object.entries(props).every(([prop, value]) => style[prop] === value);\n}\n\n/**\n * Put on each row's view: `<view [virtualListRow]=\"row\">`. Applies the row's style, and reports\n * the row's layout to the list, which is how a list of rows that size themselves learns how tall\n * each one is.\n */\n@Directive({\n selector: '[virtualListRow]',\n host: {\n '[style]': 'row().style',\n // A parked row is not read out: see `PARKED`.\n '[attr.aria-hidden]': 'row().parked ? true : null',\n '(layout)': 'onLayout($event)',\n },\n})\nexport class VirtualListRow<T = unknown> {\n readonly row = input.required<VirtualRow<T>>({ alias: 'virtualListRow' });\n private readonly list = inject<VirtualList<T>>(VirtualList);\n /** The last layout native reported for this view, whichever item it held. */\n private layout: { width?: number; height?: number } | undefined;\n\n constructor() {\n effect(() => {\n const row = this.row();\n if (this.layout) untracked(() => this.list.adoptRow(row, this.layout!));\n });\n }\n\n protected onLayout(\n event: NativeSyntheticEvent<{ layout?: { width?: number; height?: number } }>,\n ): void {\n this.layout = event.nativeEvent?.layout ?? this.layout;\n this.list.measureRow(this.row(), event.nativeEvent?.layout);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"virtual-list.js","sourceRoot":"","sources":["../src/virtual-list.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,UAAU,EACV,SAAS,EACT,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,MAAM,EACN,KAAK,EACL,YAAY,EACZ,MAAM,EACN,MAAM,EACN,SAAS,EACT,SAAS,GACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAML,cAAc,EACd,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAkC,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;;AA0E3C;;;GAGG;AAEH,MAAM,OAAO,oBAAoB;IACtB,QAAQ,GAAG,MAAM,CAA8C,WAAW,CAAC,CAAC;IAErF,MAAM,CAAC,sBAAsB,CAC3B,UAAmC,EACnC,OAAgB;QAEhB,OAAO,IAAI,CAAC;IACd,CAAC;uGARU,oBAAoB;2FAApB,oBAAoB;;2FAApB,oBAAoB;kBADhC,SAAS;mBAAC,EAAE,QAAQ,EAAE,mCAAmC,EAAE;;AAmB5D;;;;;;GAMG;AACH,MAAM,MAAM,GAA4B,MAAM,CAAC,MAAM,CAAC;IACpD,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,MAAM;IACrB,SAAS,EAAE,uBAAuB;CACnC,CAAC,CAAC;AAEH,uEAAuE;AACvE,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB,4FAA4F;AAC5F,MAAM,OAAO,GAA4B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAE3D,iGAAiG;AACjG,MAAM,cAAc,GAAG,GAAG,CAAC;AAiB3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAqDH,MAAM,OAAO,WAAe,SAAQ,eAAe;IACxC,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAgB,CAAC;IAChD;;;;;OAKG;IACM,UAAU,GAAG,KAAK;8FAAwB,CAAC;IACpD;;;OAGG;IACM,mBAAmB,GAAG,KAAK,CAAuB,EAAE;4FAAC,CAAC;IAC/D;;;;OAIG;IACM,cAAc,GAAG,KAAK,CAAqB,CAAC;uFAAC,CAAC;IACvD,kGAAkG;IACzF,MAAM,GAAG,KAAK,CAAC,CAAC,8EAAI,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;IACvD;;;;OAIG;IACM,YAAY,GAAG,KAAK;gGAAuC,CAAC;IACrE;;;;;OAKG;IACM,QAAQ,GAAG,KAAK;4FAAuC,CAAC;IACjE,gFAAgF;IACvE,8BAA8B,GAAG,KAAK;kHAA8B,CAAC;IAC9E,2EAA2E;IAClE,QAAQ,GAAG,KAAK,CAAC,CAAC,gFAAI,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;IACzD,0FAA0F;IACjF,mBAAmB,GAAG,KAAK,CAAC,CAAC,2FAAI,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;IAEpE,kEAAkE;IACzD,UAAU,GAAG,KAAK,CAAC,KAAK,kFAAI,SAAS,EAAE,gBAAgB,GAAG,CAAC;IACpE,2FAA2F;IAClF,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,gBAAgB,GAAG,CAAC;IAClE;;;OAGG;IACM,aAAa,GAAG,KAAK,CAAoB,EAAE;sFAAC,CAAC;IACtD,iGAAiG;IACxF,YAAY,GAAG,KAAK,CAAC,KAAK,oFAAI,SAAS,EAAE,gBAAgB,GAAG,CAAC;IACtE,4FAA4F;IACnF,yBAAyB,GAAG,KAAK,CAA4B,OAAO;kGAAC,CAAC;IAC/E,gGAAgG;IACvF,2BAA2B,GAAG,KAAK,CAAC,CAAC,mGAAI,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;IAE5E;;;OAGG;IACM,UAAU,GAAG,MAAM,EAA+B,CAAC;IAE5D,kEAAkE;IACzD,oBAAoB,GAAG,MAAM,EAIlC,CAAC;IAEY,QAAQ,GAAG,MAAM,CAAC,CAAC;iFAAC,CAAC;IACtC,iGAAiG;IAChF,MAAM,GAAG,MAAM,CAAC,CAAC;+EAAC,CAAC;IACnB,YAAY,GAAG,MAAM,CAAC,CAAC;qFAAC,CAAC;IAC1C,6EAA6E;IACrE,WAAW,GAAG,CAAC,CAAC;IACxB,8FAA8F;IACtF,cAAc,GAAG,CAAC,CAAC,CAAC;IAC5B,8FAA8F;IACtF,aAAa,GAAG,CAAC,CAAC,CAAC;IAE3B,gGAAgG;IAC/E,KAAK,GAAG,IAAI,GAAG,EAAmC,CAAC;IACpE,yFAAyF;IACxE,SAAS,GAAG,IAAI,OAAO,EAAmC,CAAC;IAC5E,0FAA0F;IACzE,YAAY,GAAG,IAAI,GAAG,EAAoC,CAAC;IAEzD,SAAS,GAAG,YAAY,CAA0B,oBAAoB;kFAAC,CAAC;IAC1E,cAAc,GAAG,YAAY,CAAC,cAAc;uFAAC,CAAC;IAE/D,oFAAoF;IACjE,YAAY,GAAG,QAAQ,CAAC,GAAG,EAAE,CAC9C,cAAc,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;qFAC3E,CAAC;IAEF;;;;;OAKG;IACc,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;IACzD,mGAAmG;IAClF,OAAO,GAAG,MAAM,CAAC,CAAC;gFAAC,CAAC;IAC7B,WAAW,CAA4C;IAC/D,wFAAwF;IACvE,MAAM,GAAG,IAAI,GAAG,EAAqD,CAAC;IACtE,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,kFAAI,IAAI,EAAE,UAAU,GAAG,CAAC;IAE/E,iFAAiF;IAChE,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,GAAG,CAAC;gFAAC,CAAC;IAElG,2FAA2F;IAClF,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,SAAS;kFAAC,CAAC;IAErE,gCAAgC;IACf,KAAK,GAAG,QAAQ,CAAQ,GAAG,EAAE;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACtC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1E,CAAC;QACD,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QACnE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACtC,CAAC;8EAAC,CAAC;IAEH,wDAAwD;IACvC,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,CACpC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG;6EACzD,CAAC;IAEF,8FAA8F;IAC7E,MAAM,GAAG,QAAQ,CAAC,GAA2B,EAAE;QAC9D,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC/D,CAAC;+EAAC,CAAC;IAEH,2CAA2C;IAC1B,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;IACvD,0EAA0E;IACzD,eAAe,GAAG,MAAM,CAAC,CAAC;wFAAC,CAAC;IAE7C,yDAAyD;IACxC,IAAI,GAAG,QAAQ,CAA4B,GAAG,EAAE;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpD,CAAC;6EAAC,CAAC;IAEK,KAAK,CAAC,KAAa;QACzB,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IAED;;;;;OAKG;IACc,KAAK,GAAG,QAAQ,CAAqB,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE5C,2FAA2F;QAC3F,oCAAoC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;gBAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC;YAC7E,OAAO,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GACR,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC5C,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YACrE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC;QACxB,CAAC;QACD,OAAO,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;8EAAC,CAAC;IAEH,0EAA0E;IACzD,UAAU,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC1C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,IAAI,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAmB,CAAC;QACvC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAC3E,OAAO,GAAG,CAAC;IACb,CAAC;mFAAC,CAAC;IAEH,kFAAkF;IAC1E,MAAM;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK;YAAE,IAAI,CAAC,eAAe,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACc,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACzD,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC;QAChE,OAAO,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;+EAAC,CAAC;IAEH,+CAA+C;IACvC,MAAM;QACZ,OAAQ,IAAI,CAAC,UAAU,EAAa,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IACvD,CAAC;IAED,8FAA8F;IAC3E,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CACzC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS;gFACzD,CAAC;IAEiB,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,CACxC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;+EAC/F,CAAC;IAEF;;;;;;OAMG;IACgB,IAAI,GAAG,QAAQ,CAAgC,GAAG,EAAE;QACrE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO,SAAS,CAAC;QACvC,MAAM,KAAK,GAAoB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;QACnF,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;6EAAC,CAAC;IAEH;;;OAGG;IACc,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE;QACxC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO,SAAS,CAAC;QACvC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;IACzD,CAAC;iFAAC,CAAC;IAEH;;;OAGG;IACc,WAAW,GAAG,QAAQ,CAA0B,GAAG,EAAE;QACpE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAClD,MAAM,OAAO,GAA2B,IAAI,CAAC,UAAU,EAAE;YACvD,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE;YAC5D,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QAChE,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC;IACxF,CAAC;oFAAC,CAAC;IAEH,iGAAiG;IAChF,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAC/D,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAC1D,CAAC;kFAAC,CAAC;IAEH,0EAA0E;IAClE,KAAK,CAAC,KAAa;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,kDAAkD;IAC1C,QAAQ,CAAC,KAAa;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,UAAU,EAAa,CAAC;IACvF,CAAC;IAED,gEAAgE;IACxD,OAAO,CAAC,CAAS;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,2FAA2F;IAE3F,uEAAuE;IAC/D,MAAM,GAAqB,IAAI,CAAC;IACxC,sFAAsF;IAC9E,UAAU,GAAG,CAAC,CAAC;IACvB;;;OAGG;IACK,aAAa,GAA2D,IAAI,CAAC;IAErF,+DAA+D;IAC9C,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3C,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;QACnB,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE;KAChC,CAAC;kFAAC,CAAC;IAEJ;;;;;;;;;OASG;IACc,OAAO,GAAG,YAAY,8EAIrC,MAAM,EAAE,IAAI,CAAC,SAAS;QACtB,WAAW,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,GAC1D,CAAC;IAEH,kEAAkE;IAC1D,QAAQ,CAAC,EAAU,EAAE,MAAc;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC7F,CAAC;IAED;;;;OAIG;IACK,QAAQ,CAAC,KAAmB;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,8FAA8F;QAC9F,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,KAAK,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/C,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAC/C,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,cAAc,EAAE,CAAC;YACtD,IAAI,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;YACvD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACK,QAAQ;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzD,IAAI,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,GAAG,GAAG,GAAG,cAAc,EAAE,CAAC;YAClE,IAAI,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;YACtD,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACxB,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5F,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACK,SAAS,CAAC,MAAiB,EAAE,KAAmB;QACtD,IAAI,KAAK,KAAK,MAAM,CAAC,KAAK;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,8BAA8B,EAAE,CAAC;QACnD,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC,CAAC;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,wBAAwB,CAAC;QAChD,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,IAAI,SAAS;YAAE,OAAO,OAAO,CAAC;QAC5E,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,KAAK,GAAG,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7D,CAAC;IAED,qFAAqF;IAC7E,SAAS;QACf,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACpB,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC;YAAE,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QACxD,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpB,OAAO,CAAC,CAAC;IACX,CAAC;IAED;;;;OAIG;IACK,WAAW,CAAC,MAAiB,EAAE,KAAmB;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACvE,IAAI,SAAS,KAAK,CAAC,CAAC;gBAAE,OAAO,SAAS,CAAC;QACzC,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IAED,yFAAyF;IACjF,WAAW;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC;QACnC,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,OAAO,KAAK,OAAO;YAAE,IAAI,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;;YACvE,IAAI,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9F,CAAC;IAED,uFAAuF;IACtE,QAAQ,GAAG,cAAc,EAAE;QAC1C,CAAC,CAAC,IAAI,eAAe,CACjB,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EACxB,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAC1B;QACH,CAAC,CAAC,IAAI,CAAC;IAET;QACE,KAAK,EAAE,CAAC;QACR,gBAAgB,CAAC,GAAG,EAAE;YACpB,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,IAAI,IAAI,CAAC,YAAY;gBAAE,IAAI,CAAC,eAAe,EAAE,CAAC;YAC9C,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAC7D,IAAI,CAAC,yBAAyB,EAAE,CACjC,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE;YAChC,IAAI,EAAE,CAAC;YACP,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;YACtB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;gBAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7D,CAAC,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvD,CAAC;IAED,kFAAkF;IAC1E,YAAY,GAAwB,IAAI,CAAC;IAEjD;;;;OAIG;IACK,YAAY;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,KAAK,IAAI,CAAC,YAAY;YAAE,OAAO;QACxC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAED,oFAAoF;IAC5E,gBAAgB,GAAG,KAAK,CAAC;IAEjC;;;OAGG;IACK,aAAa,CAAC,OAAwB;QAC5C,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;YACxC,IAAI,IAAI,CAAC,gBAAgB;gBAAE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;IACL,CAAC;IAED,6FAA6F;IAE7F,gEAAgE;IAC/C,IAAI,GAAG,QAAQ,CAAc,GAAG,EAAE;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAE/B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC,CAAC;QAC9C,yFAAyF;QACzF,4EAA4E;QAC5E,MAAM,MAAM,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC;QAC7E;;;;;;;;WAQG;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEhC,IAAI,IAAI,GAAG,OAAO,CAAC;QACnB,OAAO,IAAI,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,MAAM;YAAE,IAAI,EAAE,CAAC;QACtE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC;IAClE,CAAC;6EAAC,CAAC;IAEM,MAAM,GAAG,QAAQ,CAAkB,GAAG,EAAE;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5D,4FAA4F;QAC5F,4FAA4F;QAC5F,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACtC,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;+EAAC,CAAC;IAEH;;;OAGG;IACgB,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAClC,IAAI,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YACnD,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC/F,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;IAC1F,CAAC;+EAAC,CAAC;IAEH,yFAAyF;IACjF,OAAO,CAAC,KAAmB,EAAE,KAAa,EAAE,IAAY;QAC9D,MAAM,IAAI,GAAoB,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,WAAW,GAAG,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,KAAK,CAAC;QACtD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,6FAA6F;QAC7F,6EAA6E;QAC7E,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI,CACP,IAAI,CAAC,IAAI,CAAC;gBACR,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAE,EAAE,MAAM,CAAC;gBACpD,GAAG;gBACH,IAAI,EAAE,KAAK,CAAC,MAAM,CAAE;gBACpB,KAAK,EAAE,IAAI,CAAC,YAAY;oBACtB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;oBAC1B,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE;wBAChB,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;wBACjF,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;aAC5C,CAAC,CACH,CAAC;QACJ,CAAC;QACD,KAAK,IAAI,KAAK,GAAG,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,CAAC,IAAI,CACP,IAAI,CAAC,IAAI,CAAC;gBACR,KAAK;gBACL,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAE,EAAE,KAAK,CAAC;gBAClD,GAAG;gBACH,IAAI,EAAE,KAAK,CAAC,KAAK,CAAE;gBACnB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC;aAC9C,CAAC,CACH,CAAC;QACJ,CAAC;QACD,IAAI,WAAW,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,SAAS,EAAE;YAAE,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACK,UAAU,CAAC,IAAqB,EAAE,MAAc,EAAE,KAAa;QACrE,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,uDAAuD;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC/F,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC;YAAE,OAAO;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;QAC9D,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IAChF,CAAC;IAEO,QAAQ,CAAC,KAAa,EAAE,MAAe;QAC7C,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACtF,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACrB,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/E,CAAC;IAED,6FAA6F;IACrF,eAAe,CAAC,EAAU;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,KAAK,CAAC;QAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1F,CAAC;IAED;;;OAGG;IACK,WAAW,CAAC,KAAa;QAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,KAAK,GAA4B,IAAI,CAAC,SAAS,EAAE;YACrD,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE;YAC3B,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;QACpF,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1E,IAAI,SAAS;YAAE,KAAK,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,kEAAkE;IACjD,UAAU,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;mFAAC,CAAC;IAEH,8FAA8F;IACtF,MAAM,CAAC,KAAa;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACjF,CAAC;IAED;;;OAGG;IACK,WAAW,CACjB,GAAkB;QAElB,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACvF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO;YACL,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1D,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;SAC3B,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,eAAe;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,aAAyB,CAAC;QAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS;aAC3B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC;aAC/C,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAY,CAAC;QACjC,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;YAChC,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;YACvB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;gBAAE,OAAO;YAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACf,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,IAAI,EAAE,OAAO,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YACzF,IAAI,KAAK;gBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QACH,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,iGAAiG;IAChF,QAAQ,GAAG,IAAI,GAAG,EAGhC,CAAC;IACJ,8FAA8F;IAC7E,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACtD,QAAQ,GAAG,CAAC,CAAC;IAErB,qEAAqE;IAC7D,IAAI,CAAC,GAAkB;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,IAAI;YAAE,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACzB,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;;;;;OAOG;IACK,eAAe,CAAC,KAAa,EAAE,IAAY,EAAE,MAAqB;QACxE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAW,CAAC;QAChC,KAAK,IAAI,KAAK,GAAG,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3E,IAAI,MAAM,KAAK,IAAI;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACxC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC,IAAI;gBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,UAAU;QAChB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,IAAI,IAAI,CAAC,MAAM,GAAG,UAAU;gBAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,gGAAgG;IACxF,WAAW,CAAC,GAAY,EAAE,IAAY;QAC5C,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACzE,CAAC;IAEO,YAAY,CAAC,GAAY,EAAE,IAAO,EAAE,KAAa;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7F,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACK,MAAM,CAAC,GAAY,EAAE,IAAa;QACxC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACvC,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;YACpD,IAAI,EAAE,GAAG,CAAC;gBAAE,SAAS;YACrB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACjC,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,GAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/C,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,GAAkB,EAAE,MAAuD;QACpF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;YAAE,OAAO;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;QAC9D,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,OAAO;QACtE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAChC,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IACxD,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,GAAkB,EAAE,MAA2C;QACtE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;IAED,4FAA4F;IACpF,cAAc;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE;YAAE,OAAO;QACxD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,CAAC;QAC9C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3F,CAAC;IAED,yFAAyF;IACtE,IAAI,GAAG,QAAQ,CAAW,GAAG,EAAE;QAChD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACjF,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC;gBACR,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,KAAK;gBACL,OAAO,EAAE;oBACP,SAAS,EAAE,GAAG,CAAC,IAAI;oBACnB,WAAW,EAAE,GAAG,CAAC,IAAI;oBACrB,YAAY;oBACZ,YAAY,EAAE,GAAG,CAAC,KAAK;iBACxB;aACF,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;6EAAC,CAAC;IAEH,8EAA8E;IACtE,QAAQ,CAAC,GAAkB;QACjC,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG;gBACN,GAAG,GAAG,CAAC,KAAK;gBACZ,aAAa,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;gBACnD,cAAc,EAAE,UAAU;gBAC1B,aAAa,EAAE,UAAU;aAC1B,CAAC;YACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACK,gBAAgB,CAAC,GAAkB;QACzC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,UAAU;YACvB,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;YAC1D,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC7D,IAAI,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;QACnD,MAAM,KAAK,GAA4B,UAAU;YAC/C,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;YACrF,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAClE,KAAK,CAAC,gBAAgB,CAAC,GAAG,UAAU,CAAC;QACrC,KAAK,CAAC,eAAe,CAAC,GAAG,UAAU,CAAC;QACpC,IAAI,IAAI;YAAE,KAAK,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;QACpC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,GAAG;YAAE,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACgB,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YAAE,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/F,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/D,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC9D,CAAC;oFAAC,CAAC;IAEH;;;OAGG;IACgB,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAChD,CAAC;oFAAC,CAAC;IAEH;;;OAGG;IACc,WAAW,GAAG,QAAQ,CAAgB,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAE7B,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM;gBAAE,MAAM,GAAG,KAAK,CAAC;;gBAC3C,MAAM;QACb,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;oFAAC,CAAC;IAEH,+EAA+E;IACvE,UAAU,CAAC,MAAc;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAC;QAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,2BAA2B,EAAE,GAAG,GAAG,CAAC;QAC3D,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,MAAM;gBAAE,SAAS;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAClF,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,SAAS;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0FAA0F;IAClF,SAAS,GAAa,EAAE,CAAC;IACjC,kGAAkG;IAC1F,aAAa,GAAwB,IAAI,CAAC;IAElD;;;;;;;OAOG;IACK,gBAAgB,CAAC,MAAc;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACzE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,aAAa,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;QACnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI;YAAE,OAAO;QAE9D,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;YAC7B,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC9B,OAAO;oBACL,KAAK;oBACL,iEAAiE;oBACjE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;oBACxC,GAAG;oBACH,IAAI,EAAE,KAAK,CAAC,KAAK,CAAE;oBACnB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;iBACnC,CAAC;YACJ,CAAC,CAAC;YACF,OAAO;YACP,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,OAAmE;QAC/E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC/D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,2FAA2F;IAC3F,cAAc,CAAC,OAA+C;QAC5D,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;QAC5C,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,WAAW,CAAC,UAAkC,EAAE;QAC9C,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC;IACpF,CAAC;IAEO,SAAS,CAAC,KAAa,EAAE,QAAiB;QAChD,MAAM,KAAK,GAAG,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACxC,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;QAE/C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAE7B,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClC,4FAA4F;QAC5F,sEAAsE;QACtE,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC5E,MAAM,KAAK,GAAG,CAAC,KAAK,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAExE,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,GAAG,UAAU;gBAChB,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;gBAC/D,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YAClE,wFAAwF;YACxF,iBAAiB;YACjB,IAAI,QAAQ,KAAK,SAAS;gBAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAChD,IAAI,IAAI;gBAAE,KAAK,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;YACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAM,CAAC;IAChB,CAAC;IAES,QAAQ,CAChB,KAA2E;QAE3E,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,EAAE,aAAa,CAAC;QACvD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7E,MAAM,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAE5C,yFAAyF;QACzF,2EAA2E;QAC3E,4FAA4F;QAC5F,mDAAmD;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAChC,2FAA2F;QAC3F,4FAA4F;QAC5F,yDAAyD;QACzD,IAAI,IAAI,CAAC,OAAO,EAAE;YAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,EAAE;YAAE,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACxE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,uFAAuF;IAC/E,gBAAgB,CAAC,OAAe;QACtC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAC,CAAC;IACnF,CAAC;IAES,QAAQ,CAChB,KAA6E;QAE7E,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAED,sEAAsE;IAC5D,cAAc,CACtB,KAA6E;QAE7E,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC;QACzC,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACzE,IAAI,MAAM,KAAK,IAAI,CAAC,YAAY,EAAE;YAAE,OAAO;QAC3C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAED;;;;;;OAMG;IACK,cAAc;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,8BAA8B,EAAE,CAAC;QACnD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,wBAAwB,IAAI,CAAC,CAAC;YAAE,OAAO;QAC7E,IAAI,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1F,CAAC;IAES,aAAa,CAAC,KAAgE;QACtF,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACzE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC;IAEO,QAAQ,CAAC,CAAS;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ;YAAE,OAAO;QAChC,gGAAgG;QAChG,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QACvE,MAAM,KAAK,GAAG,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE,GAAG,MAAM,CAAC;QACvD,MAAM,eAAe,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC/C,6FAA6F;QAC7F,0CAA0C;QAC1C,IAAI,eAAe,GAAG,IAAI,CAAC,mBAAmB,EAAE,GAAG,QAAQ,EAAE,CAAC;YAC5D,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,aAAa,KAAK,KAAK;YAAE,OAAO;QACzC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC;IAC5C,CAAC;uGAvlCU,WAAW;2FAAX,WAAW,01FAyF+C,oBAAoB,iGAC1C,cAAc,+IAmBI,UAAU,+FAtJjE;;;;;;;;;;;;;;;;;;;;;;;GAuBT,4DA/BS,YAAY,4GAAE,IAAI;;2FAiDjB,WAAW;kBApDvB,SAAS;mBAAC;oBACT,QAAQ,EAAE,cAAc;oBACxB,QAAQ,EAAE,aAAa;oBACvB,OAAO,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC;oBAC7B,yFAAyF;oBACzF,2FAA2F;oBAC3F,uFAAuF;oBACvF,8FAA8F;oBAC9F,gGAAgG;oBAChG,uEAAuE;oBACvE,iFAAiF;oBACjF,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;GAuBT;oBACD,IAAI,EAAE;wBACJ,4FAA4F;wBAC5F,4FAA4F;wBAC5F,0FAA0F;wBAC1F,iBAAiB,EAAE,iCAAiC;wBACpD,cAAc,EAAE,cAAc;wBAC9B,uBAAuB,EAAE,gBAAgB;wBACzC,qFAAqF;wBACrF,0FAA0F;wBAC1F,gCAAgC;wBAChC,aAAa,EAAE,QAAQ;wBACvB,uBAAuB,EAAE,uBAAuB;wBAChD,UAAU,EAAE,kBAAkB;wBAC9B,UAAU,EAAE,kBAAkB;wBAC9B,qBAAqB,EAAE,uBAAuB;qBAC/C;iBACF;i8DA0FsE,oBAAoB,gGAC1C,cAAc,qEAmBZ,MAAM,OAAE,EAAE,IAAI,EAAE,UAAU,EAAE;AA6+B/E,wEAAwE;AACxE,SAAS,KAAK,CAAC,KAA8B,EAAE,KAA8B;IAC3E,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AAUH,MAAM,OAAO,cAAc;IAChB,GAAG,GAAG,KAAK,CAAC,QAAQ,0EAAkB,KAAK,EAAE,gBAAgB,GAAG,CAAC;IACzD,IAAI,GAAG,MAAM,CAAiB,WAAW,CAAC,CAAC;IAC5D,6EAA6E;IACrE,MAAM,CAAkD;IAEhE;QACE,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,IAAI,IAAI,CAAC,MAAM;gBAAE,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,MAAO,CAAC,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC;IAES,QAAQ,CAChB,KAA6E;QAE7E,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;QACvD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC9D,CAAC;uGAlBU,cAAc;2FAAd,cAAc;;2FAAd,cAAc;kBAT1B,SAAS;mBAAC;oBACT,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE;wBACJ,SAAS,EAAE,aAAa;wBACxB,8CAA8C;wBAC9C,oBAAoB,EAAE,4BAA4B;wBAClD,UAAU,EAAE,kBAAkB;qBAC/B;iBACF","sourcesContent":["import {\n Component,\n DestroyRef,\n Directive,\n ElementRef,\n TemplateRef,\n afterEveryRender,\n booleanAttribute,\n computed,\n contentChild,\n effect,\n inject,\n input,\n linkedSignal,\n output,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport {\n type HostNode,\n type NativeSyntheticEvent,\n type ScrollDrive,\n type ScrollRange,\n type StaticTransform,\n nativePlatform,\n pinnedRange,\n} from '@ng-native/fabric';\nimport { HeightIndex } from './height-index.ts';\nimport { type KeyboardShouldPersistTaps, dismissKeyboardOnTap } from './keyboard-taps.ts';\nimport { RefreshControl } from './refresh-control.ts';\nimport { STICKY_SETTLE_MS } from './sticky-headers.ts';\nimport { TemplateSlot } from './template-slot.ts';\nimport { ZeroSizeWarning, checksZeroSize, written } from './zero-size-warning.ts';\nimport { View } from './view.ts';\nimport { ScrollViewProps } from './scroll-view-props.ts';\nimport { numberOr } from './transforms.ts';\n\n/** One rendered row: the item, its index, and a stable style object for its slot. */\nexport interface VirtualRow<T> {\n readonly index: number;\n /**\n * A key that a row keeps while its item stays in the window, and that passes to a row arriving\n * once it has left. `track row.slot` recycles rows: the view of a row scrolling out is reused for\n * the one scrolling in, with only its bindings updated, rather than one destroyed and one created\n * each time. A slot follows its item, not its position, so an insert above the window moves no\n * row to another item.\n */\n readonly slot: number;\n /**\n * The item's identity, from `keyExtractor`, or the item itself without one. `track row.key`\n * gives each item a view of its own for as long as it is in the window and never recycles one,\n * which is what a row holding state of its own, or animating, needs.\n */\n readonly key: unknown;\n readonly item: T;\n readonly style: Record<string, unknown>;\n /**\n * A slot kept rendered but hidden, still bound to the last item it showed, so the next row of\n * its type to arrive reuses its views instead of building them. Always last in the window.\n */\n readonly parked?: true;\n}\n\n/**\n * Space around the rows, inside the scrolling content: one number for every side, or a side each,\n * as FlatList's `contentContainerStyle` padding.\n */\nexport type VirtualListPadding =\n | number\n | {\n readonly top?: number;\n readonly right?: number;\n readonly bottom?: number;\n readonly left?: number;\n };\n\n/** The padding on each side, in points. */\ninterface Edges {\n readonly top: number;\n readonly right: number;\n readonly bottom: number;\n readonly left: number;\n}\n\n/** A row height: one for every row, or one per item. */\nexport type VirtualItemHeight<T> = number | ((item: T, index: number) => number);\n\n/**\n * Keep what is on screen where it is when rows are added or removed before it, as\n * `ScrollView`'s `maintainVisibleContentPosition` does in React Native.\n */\nexport interface VirtualListVisiblePosition {\n /** Rows before this index are never what the position is held by. Defaults to 0. */\n readonly minIndexForVisible?: number;\n /**\n * Within this many points of the start, show what arrived instead of holding position: a feed\n * at its top scrolls to the new posts, a chat at its newest message follows the next one.\n */\n readonly autoscrollToTopThreshold?: number;\n}\n\n/** What a separator template is given: the rows either side of it, as FlatList's `leadingItem`. */\nexport interface VirtualListSeparatorContext<T> {\n readonly $implicit: T;\n readonly leadingItem: T;\n readonly trailingItem: T;\n readonly leadingIndex: number;\n}\n\n/**\n * Marks the template drawn between two rows: `<ng-template virtualListSeparator let-leading>`.\n * FlatList's `ItemSeparatorComponent`.\n */\n@Directive({ selector: 'ng-template[virtualListSeparator]' })\nexport class VirtualListSeparator<T = unknown> {\n readonly template = inject<TemplateRef<VirtualListSeparatorContext<T>>>(TemplateRef);\n\n static ngTemplateContextGuard<T>(\n _directive: VirtualListSeparator<T>,\n context: unknown,\n ): context is VirtualListSeparatorContext<T> {\n return true;\n }\n}\n\n/** One separator the list is drawing: its slot, and what its template is told. */\ninterface Gap<T> {\n readonly index: number;\n readonly style: Record<string, unknown>;\n readonly context: VirtualListSeparatorContext<T>;\n}\n\n/**\n * A parked slot: out of the flow, out of sight and out of reach, with its view kept to be used\n * again. Not `display: none`, which is an element with no view. A screen reader passes over a\n * view with no opacity, and `VirtualListRow` says so outright where a row uses it. Moved off the\n * list as well, since `pointer-events: none` is CSS's: something inside a row with a\n * `pointer-events` of its own would still take a touch where the row was left.\n */\nconst PARKED: Record<string, unknown> = Object.freeze({\n position: 'absolute',\n opacity: 0,\n pointerEvents: 'none',\n transform: 'translateX(-100000px)',\n});\n\n/** How many hidden slots of each row type are kept ready for reuse. */\nconst PARK_LIMIT = 6;\n\n/** The style of a row that sizes itself and needs nothing else: in flow, where it falls. */\nconst IN_FLOW: Record<string, unknown> = Object.freeze({});\n\n/** Points of drift below which a held position is left alone, as UIKit rounds to half-points. */\nconst HOLD_TOLERANCE = 0.5;\n\n/** The row a held position is held by: its key, and how far into it the viewport starts. */\ninterface Anchor<T> {\n readonly key: unknown;\n readonly within: number;\n /** The items the anchor was taken against, to look for a successor in if its row goes. */\n readonly items: readonly T[];\n readonly index: number;\n}\n\n/** What the window is built from: the visible row and the edges of what is rendered. */\ninterface Span {\n readonly first: number;\n readonly last: number;\n}\n\n/**\n * Windowed list: a native scroll view whose content is sized to the full list, with only the\n * visible slice rendered. Commits as `RCTScrollView`.\n *\n * RN's FlatList, SectionList and VirtualizedList are a large React component tree, and none of\n * it is reachable. This is the small equivalent. Angular's own `@for` does the rendering, so\n * tracking, reuse and destruction all behave normally, and the loop stays in the caller's\n * template:\n *\n * ```html\n * <virtual-list #list [items]=\"rows()\" [itemHeight]=\"44\" (endReached)=\"loadMore()\">\n * <text listHeader>Header</text>\n * @for (row of list.window(); track row.slot) {\n * <view [virtualListRow]=\"row\"><text>{{ row.item.label }}</text></view>\n * }\n * <text listFooter>Footer</text>\n * </virtual-list>\n * ```\n *\n * With `itemHeight`, every row's size is known up front and each is absolutely positioned at its\n * offset. Without it, rows size themselves, as a feed's posts and a chat's messages do: the window\n * is laid out in normal flow after a spacer standing in for the rows above it, so native places\n * every row correctly in the frame it first appears, and each row's layout tells the list its\n * height for sizing what is not rendered. Until a row has been measured it counts as\n * `estimatedItemHeight`. Measurements are kept by `keyExtractor`, so they follow their item across\n * inserts, removals and moves. `virtualListRow` on each row's view applies its style and reports\n * its layout; `[style]=\"row.style\"` still works for fixed heights, which need no measuring.\n *\n * Content marked `listHeader` and `listFooter` renders above and below the rows in normal flow,\n * as FlatList's header and footer components do. A `<refresh-control>` projects like any child.\n *\n * `<ng-template virtualListSeparator let-leading let-trailing=\"trailingItem\">` is drawn between\n * each pair of rows and not after the last, as FlatList's `ItemSeparatorComponent` is. It is drawn\n * inside the leading row's slot, at its trailing edge, so `itemHeight` includes it the way\n * `getItemLayout`'s `length` includes it in RN; a measured row has it drawn over its trailing edge\n * once its height is known. The slot it sits in lets touches through to the row underneath.\n *\n * `horizontal` swaps the axis: rows are placed by `left` and sized by `width`, and the offset is\n * read from `contentOffset.x`. `inverted` is a scale of -1 on the list and on each row, which is\n * how FlatList does it too - the list scrolls from the bottom and each row is flipped back the\n * right way up. The first item is the one at the bottom, so a chat passes its messages newest\n * first.\n *\n * `stickyIndices` pins a row to the leading edge while the rows under it scroll past, which is\n * FlatList's `stickyHeaderIndices` counted without the header. `stickyHeader` pins the\n * `listHeader` content the same way, FlatList's index 0 when it has a `ListHeaderComponent`, and\n * the first sticky row pushes it off as RN's sticky headers push each other. Neither is native:\n * RN's `ScrollView.js` translates a sticky child against the scroll offset in JavaScript, and a\n * row here follows the offset the same way while it is the current one - by its `top` when\n * absolutely positioned, by a transform when in flow.\n *\n * What is on screen stays on screen when a measured row above it turns out taller or shorter than\n * its estimate: the offset is corrected by the difference. `maintainVisibleContentPosition` does\n * the same for rows inserted or removed above it, which a feed receiving new posts and a chat\n * loading older messages above the ones being read both need.\n *\n * ponytail: viewability is `itemVisiblePercentThreshold` only: `minimumViewTime` and\n * `waitForInteraction` are timing policy on top of the same measurement, and nothing has needed\n * them. A separator is not told `highlighted`, which RN drives from the row's press state. A\n * sticky header follows the scroll a commit behind native, where RN's is on the native driver. A\n * held position is restored by a `scrollTo` after the commit, not in the mount as native\n * `maintainVisibleContentPosition` is, so a correction made mid-fling lands where the last scroll\n * event said the list was.\n */\n@Component({\n selector: 'virtual-list',\n exportAs: 'virtualList',\n imports: [TemplateSlot, View],\n // One content view holds the header, the rows and the footer, as ScrollView.js's content\n // container does: Android's ScrollView takes one child and throws on a second. It is never\n // collapsed, or Fabric would flatten it away and hand the scroll view all three again.\n // See ScrollView: the canvas carries only a height, so Fabric would flatten it away and drags\n // over the gaps between rows would not scroll. Separators come after the rows so they draw over\n // the slot they share. The spacer is there only when rows are in flow.\n // A refresh control comes first, as the scroll view's own child; see ScrollView.\n template: `\n <ng-content select=\"refresh-control\" />\n <view [style]=\"content()\" collapsable=\"false\">\n <view [style]=\"headerStyle()\" (layout)=\"onHeaderLayout($event)\"\n ><ng-content select=\"[listHeader]\"\n /></view>\n <view #rows [style]=\"canvas()\" collapsable=\"false\">\n @if (measuring()) {\n <view [style]=\"spacer()\"></view>\n }\n <ng-content />\n @if (separator(); as separator) {\n @for (gap of gaps(); track gap.index) {\n <view [style]=\"gap.style\"\n ><ng-container\n [templateSlot]=\"separator.template\"\n [templateSlotContext]=\"gap.context\"\n /></view>\n }\n }\n </view>\n <view [style]=\"footerStyle()\"><ng-content select=\"[listFooter]\" /></view>\n </view>\n `,\n host: {\n // ScrollView.js's `baseHorizontal`: a column would stack the header, canvas and footer, and\n // the canvas, holding only absolutely positioned rows, would have no height to give them. A\n // top-level prop, as on <scroll-view>, so the caller's own [style] still applies over it.\n '[flexDirection]': \"horizontal() ? 'row' : 'column'\",\n '[horizontal]': 'horizontal()',\n '[nestedScrollEnabled]': 'nestedScroll()',\n // A prop rather than `[style.transform]`: Angular stringifies a style binding, and a\n // transform is a list of objects. The engine flattens style into props anyway, so this is\n // where it would have ended up.\n '[transform]': 'flip()',\n '[scrollEventThrottle]': 'scrollEventThrottle()',\n '(scroll)': 'onScroll($event)',\n '(layout)': 'onLayout($event)',\n '(contentSizeChange)': 'onContentSize($event)',\n },\n})\nexport class VirtualList<T> extends ScrollViewProps {\n readonly items = input.required<readonly T[]>();\n /**\n * A fixed height, or a function for variable ones, when every row's size is known up front. The\n * function form builds a cumulative offset table and binary-searches it, which is what section\n * lists need: a header row and an item row are different heights, so uniform maths cannot place\n * them. Leave it unset for rows that size themselves.\n */\n readonly itemHeight = input<VirtualItemHeight<T>>();\n /**\n * What a row that sizes itself counts as until it has been measured. The closer it is, the more\n * honest the scroll bar is and the less a jump to an unmeasured row has to correct.\n */\n readonly estimatedItemHeight = input<VirtualItemHeight<T>>(50);\n /**\n * Space around the rows, inside the scrolling content. The leading side comes before the first\n * row and the trailing side after the last; the sides across the axis inset every row. The\n * header and footer sit outside it, as FlatList's do outside `contentContainerStyle`.\n */\n readonly contentPadding = input<VirtualListPadding>(0);\n /** Space between one row and the next, along the axis: not before the first or after the last. */\n readonly rowGap = input(0, { transform: numberOr(0) });\n /**\n * An item's identity, as FlatList's `keyExtractor`: what a measured height, a slot and a held\n * position follow across an insert. Without it an item is its own key, which is enough for items\n * that are replaced, not copied, when they change.\n */\n readonly keyExtractor = input<(item: T, index: number) => unknown>();\n /**\n * What kind of row an item is, when rows of different kinds share the list: a text post and a\n * photo post, a message and a date divider. A slot is only ever recycled into a row of the same\n * type, so its views are reused rather than torn down for another kind's, as UIKit's reuse\n * identifiers and FlashList's `getItemType` do.\n */\n readonly itemType = input<(item: T, index: number) => unknown>();\n /** Keep what is on screen still when rows are inserted or removed before it. */\n readonly maintainVisibleContentPosition = input<VirtualListVisiblePosition>();\n /** Rows rendered beyond each edge of the viewport, to cover fling gaps. */\n readonly overscan = input(4, { transform: numberOr(4) });\n /** How close to the end, in viewport heights, `(endReached)` fires. RN's default is 2. */\n readonly endReachedThreshold = input(2, { transform: numberOr(2) });\n\n /** Lay the rows out along x instead of y, and scroll that way. */\n readonly horizontal = input(false, { transform: booleanAttribute });\n /** Start at the end and scroll backwards, with every row flipped back the right way up. */\n readonly inverted = input(false, { transform: booleanAttribute });\n /**\n * Rows that pin to the leading edge while the ones under them scroll past. Ascending; a row is\n * pinned from the moment it would leave until the next sticky row pushes it off.\n */\n readonly stickyIndices = input<readonly number[]>([]);\n /** Pin the `listHeader` content to the leading edge until the first sticky row pushes it off. */\n readonly stickyHeader = input(false, { transform: booleanAttribute });\n /** What a tap in the list does while a text input has the keyboard up. See `ScrollView`. */\n readonly keyboardShouldPersistTaps = input<KeyboardShouldPersistTaps>('never');\n /** How much of a row must be on screen to count as viewable. RN's default is 0, meaning any. */\n readonly itemVisiblePercentThreshold = input(0, { transform: numberOr(0) });\n\n /**\n * The scroll position is within `endReachedThreshold` of the end: once per item count, and again\n * after the list has scrolled away from the end and come back.\n */\n readonly endReached = output<{ distanceFromEnd: number }>();\n\n /** Which rows are on screen, and what changed since last time. */\n readonly viewableItemsChanged = output<{\n viewable: readonly VirtualRow<T>[];\n entered: readonly number[];\n left: readonly number[];\n }>();\n\n private readonly viewport = signal(0);\n /** The leading edge of the viewport in content space, which sticky rows and viewability need. */\n private readonly offset = signal(0);\n private readonly headerHeight = signal(0);\n /** What native reported the content measures along the axis, once it has. */\n private contentSize = 0;\n /** The rows' own extent when native reported that, so a report for other rows is not used. */\n private contentSizeFor = -1;\n /** The item count `endReached` last fired for, cleared once the list is away from the end. */\n private endReachedFor = -1;\n\n /** Slot styles are cached so a scroll does not hand Fabric new prop objects for stable rows. */\n private readonly slots = new Map<number, Record<string, unknown>>();\n /** A separator's slot style, per row slot style, so it is as stable as the row's own. */\n private readonly gapStyles = new WeakMap<object, Record<string, unknown>>();\n /** The same for a measured row's separator, by key, while its place and size stay put. */\n private readonly measuredGaps = new Map<unknown, Record<string, unknown>>();\n\n protected readonly separator = contentChild<VirtualListSeparator<T>>(VirtualListSeparator);\n private readonly refreshControl = contentChild(RefreshControl);\n\n /** See ScrollView: inside Android's swipe layout the list must see a drag first. */\n protected readonly nestedScroll = computed(() =>\n nativePlatform() === 'android' && this.refreshControl() ? true : undefined,\n );\n\n /**\n * Whether native moves sticky rows. Each then stays at its own place in the list and native\n * translates it on every frame the list scrolls, as RN's `ScrollViewStickyHeader` does; a\n * translate committed from each scroll event lands a frame or more late, and on a fast fling\n * the row shudders and comes away from the edge.\n */\n private readonly nativeSticky = this.engine.drivesScroll;\n /** The offset once scrolling pauses, which the settled translate of a native-moved row is from. */\n private readonly settled = signal(0);\n private settleTimer: ReturnType<typeof setTimeout> | undefined;\n /** What native is moving, by row view, with the transform kept beside the translate. */\n private readonly drives = new Map<HostNode, { drive: ScrollDrive; statics: string }>();\n private readonly canvasView = viewChild.required('rows', { read: ElementRef });\n\n /** Whether the scroll offset is needed as a signal, which only pinning needs. */\n private readonly pinning = computed(() => this.stickyHeader() || this.stickyIndices().length > 0);\n\n /** Rows size themselves and are laid out in flow, rather than placed at a known offset. */\n readonly measuring = computed(() => this.itemHeight() === undefined);\n\n /** The padding on each side. */\n private readonly edges = computed<Edges>(() => {\n const padding = this.contentPadding();\n if (typeof padding === 'number') {\n return { top: padding, right: padding, bottom: padding, left: padding };\n }\n const { top = 0, right = 0, bottom = 0, left = 0 } = padding ?? {};\n return { top, right, bottom, left };\n });\n\n /** The padding before the first row, along the axis. */\n private readonly lead = computed(() =>\n this.horizontal() ? this.edges().left : this.edges().top,\n );\n\n /** The rows' insets across the axis, as the props that place an absolutely positioned row. */\n private readonly across = computed((): Record<string, number> => {\n const { top, right, bottom, left } = this.edges();\n return this.horizontal() ? { top, bottom } : { left, right };\n });\n\n /** Heights native has reported, by key. */\n private readonly measured = new Map<unknown, number>();\n /** Bumped when a measurement changes, which is what re-sizes the list. */\n private readonly measuredVersion = signal(0);\n\n /** Each item's key, or null when items are their own. */\n private readonly keys = computed<readonly unknown[] | null>(() => {\n const extract = this.keyExtractor();\n return extract ? this.items().map(extract) : null;\n });\n\n private keyAt(index: number): unknown {\n return this.keys()?.[index] ?? this.items()[index];\n }\n\n /**\n * Each row's size and where it starts, for variable heights; uniform rows need no index at all.\n * Built once per change of items. A measurement changes it in place and bumps\n * `measuredVersion`, which is what everything that reads it depends on, so a row laying out\n * costs a walk of the tree rather than a rebuild of every offset.\n */\n private readonly table = computed<HeightIndex | null>(() => {\n const height = this.itemHeight();\n if (typeof height === 'number') return null;\n\n // Each row's entry is its size and the gap after it, so where a row starts counts the gaps\n // before it without a second table.\n const gap = this.rowGap();\n const items = this.items();\n const sizes = new Float64Array(items.length);\n if (height) {\n for (let i = 0; i < items.length; i++) sizes[i] = height(items[i]!, i) + gap;\n return new HeightIndex(sizes);\n }\n const estimate = this.estimatedItemHeight();\n const keys = this.keys();\n for (let i = 0; i < items.length; i++) {\n const size =\n this.measured.get(keys ? keys[i] : items[i]) ??\n (typeof estimate === 'number' ? estimate : estimate(items[i]!, i));\n sizes[i] = size + gap;\n }\n return new HeightIndex(sizes);\n });\n\n /** Where each key is, so a measurement finds its row without a search. */\n private readonly indexOfKey = computed(() => {\n if (!this.measuring()) return null;\n const map = new Map<unknown, number>();\n (this.keys() ?? this.items()).forEach((key, index) => map.set(key, index));\n return map;\n });\n\n /** The index, with a dependency on its measurements for whoever is reading it. */\n private layout(): HeightIndex | null {\n const table = this.table();\n if (table) this.measuredVersion();\n return table;\n }\n\n /**\n * The list's own total extent along its axis: the padding at both ends, the rows, and a gap\n * between each two of them.\n */\n private readonly extent = computed(() => {\n const table = this.layout();\n const count = this.items().length;\n const rows = table ? table.total : count * this.stride();\n const { top, right, bottom, left } = this.edges();\n const padding = this.horizontal() ? left + right : top + bottom;\n return padding + (count ? rows - this.rowGap() : 0);\n });\n\n /** A fixed-height row and the gap after it. */\n private stride(): number {\n return (this.itemHeight() as number) + this.rowGap();\n }\n\n /** ScrollView.js's `contentContainerHorizontal`: the header, rows and footer side by side. */\n protected readonly content = computed(() =>\n this.horizontal() ? { flexDirection: 'row' } : undefined,\n );\n\n protected readonly canvas = computed(() =>\n this.horizontal() ? { width: this.extent(), flexDirection: 'row' } : { height: this.extent() },\n );\n\n /**\n * `scaleY: -1` on the list, and the same on every row.\n *\n * The list ends up scrolled from the far end with its rows in reverse, and the second flip puts\n * each row's own content back the right way up. It is what `FlatList` does, and it is why an\n * inverted list needs no reversed maths: the first item is at offset 0, which is the bottom.\n */\n protected readonly flip = computed<StaticTransform[] | undefined>(() => {\n if (!this.inverted()) return undefined;\n const scale: StaticTransform = this.horizontal() ? { scaleX: -1 } : { scaleY: -1 };\n return [scale];\n });\n\n /**\n * The flip as a style's transform: CSS text, which the engine turns into the list native reads.\n * A style binding validates its values as the DOM's, and warns on a list in development.\n */\n private readonly flipText = computed(() => {\n if (!this.inverted()) return undefined;\n return this.horizontal() ? 'scaleX(-1)' : 'scaleY(-1)';\n });\n\n /**\n * What places a row in flow: the gap after it and the padding across the axis, as margins, since\n * native lays the row out. Empty when there are none, so a plain list commits no margins.\n */\n private readonly flowSpacing = computed<Record<string, unknown>>(() => {\n const gap = this.rowGap();\n const { top, right, bottom, left } = this.edges();\n const spacing: Record<string, number> = this.horizontal()\n ? { marginRight: gap, marginTop: top, marginBottom: bottom }\n : { marginBottom: gap, marginLeft: left, marginRight: right };\n return Object.fromEntries(Object.entries(spacing).filter(([, value]) => value !== 0));\n });\n\n /** A row in flow, flipped back when the list is inverted. One object, so rows never re-clone. */\n private readonly flowStyle = computed(() => {\n const flip = this.flipText();\n const spacing = this.flowSpacing();\n if (!flip && Object.keys(spacing).length === 0) return IN_FLOW;\n return flip ? { ...spacing, transform: flip } : spacing;\n });\n\n /** Top of a row: the leading padding, and every row and gap before it. */\n private topOf(index: number): number {\n const table = this.layout();\n return this.lead() + (table ? table.topOf(index) : index * this.stride());\n }\n\n /** A row's own size, without the gap after it. */\n private heightOf(index: number): number {\n const table = this.layout();\n return table ? table.heightOf(index) - this.rowGap() : (this.itemHeight() as number);\n }\n\n /** First row whose bottom, or the gap after it, is past `y`. */\n private indexAt(y: number): number {\n const table = this.layout();\n const along = y - this.lead();\n if (!table) return Math.max(0, Math.floor(along / this.stride()));\n return table.indexAt(along);\n }\n\n // --- holding position -------------------------------------------------------------------\n\n /** The row the viewport's leading edge is in, taken at each scroll. */\n private anchor: Anchor<T> | null = null;\n /** The last offset seen. A field rather than a signal: reading it renders nothing. */\n private lastOffset = 0;\n /**\n * A correction to make once the commit that needs it is on its way to native: an offset in the\n * rows' own space, after the header, or the very start of the list.\n */\n private pendingScroll: { offset: number; animated: boolean } | 'start' | null = null;\n\n /** What moves the rows: which items, and where each one is. */\n private readonly placement = computed(() => ({\n items: this.items(),\n table: this.table(),\n version: this.measuredVersion(),\n }));\n\n /**\n * The first *visible* row, not the first rendered one, and not the raw scroll offset. A fling\n * produces a scroll event per frame, and setting a signal on each one costs a change-detection\n * pass even when the visible rows are identical. Deriving the index in the handler means most\n * scroll events change nothing and cost nothing.\n *\n * Linked to the rows' placement, because that is when the row on screen can move without the\n * user scrolling: an insert above it, or a row above it measuring differently from its estimate.\n * The index follows the anchored row there, and the offset follows it too.\n */\n private readonly visible = linkedSignal<\n { items: readonly T[]; table: HeightIndex | null; version: number },\n number\n >({\n source: this.placement,\n computation: (placement) => this.reanchor(placement.items),\n });\n\n /** Take the anchor at a row, keeping the viewport where it is. */\n private anchorAt(at: number, offset: number): void {\n const items = this.items();\n if (!items.length) {\n this.anchor = null;\n return;\n }\n const index = Math.min(at, items.length - 1);\n this.anchor = { key: this.keyAt(index), within: offset - this.topOf(index), items, index };\n }\n\n /**\n * Where the row on screen went when the rows moved under it, and the offset that keeps it where\n * the user left it. An insert or a removal is only held when the caller asked for it; a row\n * above measuring differently always is, since nothing the user did moved anything.\n */\n private reanchor(items: readonly T[]): number {\n const anchor = this.anchor;\n // Empty for a moment, as a filter typed through leaves it: the offset is kept for what comes.\n if (!items.length) return 0;\n if (!anchor) return this.atOffset();\n\n const index = this.heldIndex(anchor, items);\n if (index === 'start') return this.showStart();\n if (index < 0) return this.atOffset();\n const held = this.topOf(index) + anchor.within;\n if (Math.abs(held - this.lastOffset) > HOLD_TOLERANCE) {\n this.pendingScroll = { offset: held, animated: false };\n this.lastOffset = held;\n }\n this.anchor = { ...anchor, items, index };\n return index;\n }\n\n /**\n * The row under the offset native is still at, in rows that have just replaced the old ones, as\n * a filter replaces them. Native keeps its offset whatever the items became, so the window is\n * worked out from that, not from the old row's index, which in the new rows sits somewhere else.\n * When the new rows end before that offset, the list is scrolled back to their end: native\n * would otherwise stay scrolled past it, showing nothing until the next drag.\n */\n private atOffset(): number {\n const end = Math.max(0, this.extent() - this.viewport());\n if (this.viewport() > 0 && this.lastOffset > end + HOLD_TOLERANCE) {\n this.pendingScroll = { offset: end, animated: false };\n this.lastOffset = end;\n }\n const index = Math.max(0, Math.min(this.indexAt(this.lastOffset), this.items().length - 1));\n this.anchorAt(index, this.lastOffset);\n return index;\n }\n\n /**\n * The index to hold the viewport at, -1 to let it move, or the start of the list when an\n * insert lands within the autoscroll threshold of it.\n */\n private heldIndex(anchor: Anchor<T>, items: readonly T[]): number | 'start' {\n if (items === anchor.items) return anchor.index;\n const hold = this.maintainVisibleContentPosition();\n if (!hold) return -1;\n const threshold = hold.autoscrollToTopThreshold;\n if (threshold !== undefined && this.lastOffset <= threshold) return 'start';\n const index = this.successorOf(anchor, items);\n return index < (hold.minIndexForVisible ?? 0) ? -1 : index;\n }\n\n /** Scroll to what arrived at the start, rather than holding the viewport past it. */\n private showStart(): number {\n this.anchorAt(0, 0);\n if (this.lastOffset !== 0) this.pendingScroll = 'start';\n this.lastOffset = 0;\n return 0;\n }\n\n /**\n * The anchored row's new index, or the first row after it that survived when it did not. Only\n * the rows that were rendered are searched for a successor: past those the viewport has moved\n * on, and holding it by something off screen would be holding it by nothing the user saw.\n */\n private successorOf(anchor: Anchor<T>, items: readonly T[]): number {\n const keys = this.keys() ?? items;\n const index = keys.indexOf(anchor.key);\n if (index !== -1) return index;\n const extract = this.keyExtractor();\n const was = anchor.items;\n const limit = Math.min(was.length, anchor.index + this.overscan() * 4 + 1);\n for (let i = anchor.index + 1; i < limit; i++) {\n const successor = keys.indexOf(extract ? extract(was[i]!, i) : was[i]);\n if (successor !== -1) return successor;\n }\n return -1;\n }\n\n /** Make a queued correction, after the commit that moved the rows has gone to native. */\n private flushScroll(): void {\n const pending = this.pendingScroll;\n if (!pending) return;\n this.pendingScroll = null;\n if (pending === 'start') this.scrollToOffset({ offset: 0, animated: true });\n else this.scrollToOffset({ offset: this.headerHeight() + pending.offset, animated: false });\n }\n\n /** In development, a list with rows that stays at zero size; see `ZeroSizeWarning`. */\n private readonly zeroSize = checksZeroSize()\n ? new ZeroSizeWarning(\n () => written(this.node),\n () => !!this.horizontal(),\n )\n : null;\n\n constructor() {\n super();\n afterEveryRender(() => {\n this.flushScroll();\n if (this.nativeSticky) this.driveStickyRows();\n this.recheckItems();\n });\n const stop = dismissKeyboardOnTap(this.engine, this.node, () =>\n this.keyboardShouldPersistTaps(),\n );\n inject(DestroyRef).onDestroy(() => {\n stop();\n clearTimeout(this.settleTimer);\n this.zeroSize?.stop();\n for (const held of this.drives.values()) held.drive.stop();\n });\n if (this.zeroSize) this.checkZeroSize(this.zeroSize);\n }\n\n /** The items the end and viewability were last checked against after a render. */\n private checkedItems: readonly T[] | null = null;\n\n /**\n * New items can bring the end within reach or change what is on screen with no scroll: a list\n * shorter than its viewport, a page appended while at the end, a filter. Checked once the rows\n * they make are rendered, and only when they changed, so any other render costs a comparison.\n */\n private recheckItems(): void {\n const items = this.items();\n if (items === this.checkedItems) return;\n this.checkedItems = items;\n this.checkEnd(this.headerHeight() + this.lastOffset);\n this.announceViewable(this.lastOffset);\n }\n\n /** Whether the viewport has been laid out yet, so a zero in it is a measurement. */\n private viewportMeasured = false;\n\n /**\n * In development, rows that arrive in a list already measured at zero, or go from one, with no\n * new layout to say so: an update to `items` alone does not lay the viewport out again.\n */\n private checkZeroSize(warning: ZeroSizeWarning): void {\n effect(() => {\n const hasRows = this.items().length > 0;\n if (this.viewportMeasured) warning.laidOut(untracked(this.viewport), hasRows);\n });\n }\n\n // --- the window ---------------------------------------------------------------------------\n\n /** The rows to render, and the edges of the run they sit in. */\n private readonly span = computed<Span | null>(() => {\n const items = this.items();\n const viewport = this.viewport();\n const overscan = this.overscan();\n if (!items.length) return null;\n\n const visible = Math.min(this.visible(), items.length - 1);\n const first = Math.max(0, visible - overscan);\n // Before the first layout we have no viewport, so render a screen's worth optimistically\n // rather than nothing: an empty first frame is worse than a few extra rows.\n const budget = viewport > 0 ? viewport : this.heightOf(first) * overscan * 2;\n /*\n * Measured from the top of the first *visible* row, not the first rendered one.\n *\n * Anchoring it at `first` - which is already backed off by the overscan - spent the budget\n * on rows above the viewport, so the window ran out that far before the bottom of the\n * screen. The trailing `+ overscan` hid it whenever every row was the same height, because\n * then the rows added below happened to be worth exactly the rows wasted above. With mixed\n * heights they are not, and the list clips short of its own bottom.\n */\n const top = this.topOf(visible);\n\n let last = visible;\n while (last < items.length && this.topOf(last) < top + budget) last++;\n return { first, last: Math.min(items.length, last + overscan) };\n });\n\n readonly window = computed<VirtualRow<T>[]>(() => {\n const span = this.span();\n if (!span) return [];\n const rows = this.rowsFor(this.items(), span.first, span.last);\n this.trimParked();\n for (const pool of this.parked.values()) rows.push(...pool);\n // The cache exists for rows that stay in the window between scrolls; anything that has left\n // it is rebuilt if it comes back, so the map stays the size of the window, not of the list.\n for (const index of this.slots.keys()) {\n if (index < span.first || index >= span.last) this.slots.delete(index);\n }\n return rows;\n });\n\n /**\n * What stands in for the rows above the window when rows are in flow: their total extent, less\n * a pinned row's, which is rendered in flow ahead of the window.\n */\n protected readonly spacer = computed(() => {\n const span = this.span();\n let lead = span ? this.topOf(span.first) : 0;\n const pinned = this.pinnedIndex();\n if (span && pinned !== null && pinned < span.first) {\n lead = this.nativeSticky ? this.topOf(pinned) : lead - this.heightOf(pinned) - this.rowGap();\n }\n return this.horizontal() ? { width: Math.max(0, lead) } : { height: Math.max(0, lead) };\n });\n\n /** The rows from `first` up to `last`, and the pinned row above them if there is one. */\n private rowsFor(items: readonly T[], first: number, last: number): VirtualRow<T>[] {\n const rows: VirtualRow<T>[] = [];\n const pinned = this.pinnedIndex();\n const pinnedAbove = pinned !== null && pinned < first;\n this.releaseRecycled(first, last, pinnedAbove ? pinned : null);\n // The pinned row is on screen even when its own place in the list is not, which is the whole\n // point of it, so it is rendered whether or not the window reaches that far.\n if (pinnedAbove) {\n const key = this.keyAt(pinned);\n rows.push(\n this.hold({\n index: pinned,\n slot: this.recycledSlot(key, items[pinned]!, pinned),\n key,\n item: items[pinned]!,\n style: this.nativeSticky\n ? this.stickyStyle(pinned)\n : this.measuring()\n ? this.pinnedFlowStyle(this.topOf(first) - this.heightOf(pinned) - this.rowGap())\n : this.slotStyle(pinned, this.offset()),\n }),\n );\n }\n for (let index = first; index < last; index++) {\n const key = this.keyAt(index);\n rows.push(\n this.hold({\n index,\n slot: this.recycledSlot(key, items[index]!, index),\n key,\n item: items[index]!,\n style: this.styleFor(index, index === pinned),\n }),\n );\n }\n if (pinnedAbove && this.nativeSticky && this.measuring()) this.leadWindow(rows, pinned, first);\n return rows;\n }\n\n /**\n * A pinned row native moves stays at its own place, so the rows between it and the window are\n * made up before the window rather than after the row: new props on a view native is moving\n * put its transform back for a frame.\n */\n private leadWindow(rows: VirtualRow<T>[], pinned: number, first: number): void {\n const lead = rows[1];\n // The pinned row's own gap already follows it in flow.\n const between = this.topOf(first) - this.topOf(pinned) - this.heightOf(pinned) - this.rowGap();\n if (!lead || between <= 0) return;\n const margin = this.horizontal() ? 'marginLeft' : 'marginTop';\n rows[1] = this.hold({ ...lead, style: { ...lead.style, [margin]: between } });\n }\n\n private styleFor(index: number, pinned: boolean): Record<string, unknown> {\n if (this.nativeSticky && this.nextSticky().has(index)) return this.stickyStyle(index);\n if (this.measuring()) {\n return pinned ? this.pinnedFlowStyle(this.topOf(index)) : this.flowStyle();\n }\n return pinned ? this.slotStyle(index, this.offset()) : this.slotStyle(index);\n }\n\n /** A pinned row in flow, moved from where flow put it to the leading edge by a transform. */\n private pinnedFlowStyle(at: number): Record<string, unknown> {\n const shift = Math.max(0, this.offset() - at);\n const move = `${this.horizontal() ? 'translateX' : 'translateY'}(${shift}px)`;\n const flip = this.flipText();\n return { ...this.flowSpacing(), zIndex: 1, transform: flip ? `${move} ${flip}` : move };\n }\n\n /**\n * A sticky row native moves: at its own place, with the translate native had reached when\n * scrolling paused, so the props agree with what is on screen.\n */\n private stickyStyle(index: number): Record<string, unknown> {\n const horizontal = this.horizontal();\n const style: Record<string, unknown> = this.measuring()\n ? { ...this.flowSpacing() }\n : { ...this.slotStyle(index) };\n style['zIndex'] = 1;\n const top = this.topOf(index);\n const shift = Math.min(Math.max(0, this.settled() - top), this.stopOf(index) - top);\n const move = shift > 0 ? `${horizontal ? 'translateX' : 'translateY'}(${shift}px)` : '';\n const transform = [move, this.flipText() ?? ''].filter(Boolean).join(' ');\n if (transform) style['transform'] = transform;\n return style;\n }\n\n /** Each sticky row, and the one after it, which pushes it off. */\n private readonly nextSticky = computed(() => {\n const sticky = this.stickyIndices();\n return new Map(sticky.map((index, at) => [index, sticky[at + 1]]));\n });\n\n /** Where a sticky row stops, pushed off by the next: that row's top, less this row's size. */\n private stopOf(index: number): number {\n const next = this.nextSticky().get(index);\n return next === undefined ? Infinity : this.topOf(next) - this.heightOf(index);\n }\n\n /**\n * How native moves a rendered row, or null when it does not: along the scroll view's own\n * offset, which counts the header, from the row's top until the next sticky row pushes it off.\n */\n private stickyDrive(\n row: VirtualRow<T>,\n ): { range: ScrollRange; statics: readonly StaticTransform[] } | null {\n if (!this.nativeSticky || row.parked || !this.nextSticky().has(row.index)) return null;\n const header = this.headerHeight();\n const start = header + this.topOf(row.index);\n return {\n range: pinnedRange(start, header + this.stopOf(row.index)),\n statics: this.flip() ?? [],\n };\n }\n\n /**\n * Hand each rendered sticky row's view to native to move, and let go of the rest. The rows'\n * views are the canvas's element children in window order, after the spacer, which is how\n * `@for` over `window()` leaves them.\n */\n private driveStickyRows(): void {\n if (!this.pinning() && this.drives.size === 0) return;\n const canvas = this.canvasView().nativeElement as HostNode;\n const views = canvas.childList\n .filter((child) => child.nodeKind === 'element')\n .slice(this.measuring() ? 1 : 0);\n const axis = this.horizontal() ? 'x' : 'y';\n const live = new Set<HostNode>();\n this.window().forEach((row, at) => {\n const view = views[at];\n const next = this.stickyDrive(row);\n if (!view || !next) return;\n live.add(view);\n const statics = JSON.stringify(next.statics);\n const held = this.drives.get(view);\n if (held?.statics === statics) return held.drive.update(next.range);\n held?.drive.stop();\n const drive = this.engine.driveByScroll(view, this.node, axis, next.range, next.statics);\n if (drive) this.drives.set(view, { drive, statics });\n });\n for (const [view, held] of this.drives) {\n if (live.has(view)) continue;\n held.drive.stop();\n this.drives.delete(view);\n }\n }\n\n /** Which recycling slot each rendered item holds, by key: its type, and the row it last drew. */\n private readonly recycled = new Map<\n unknown,\n { slot: number; type: unknown; row: VirtualRow<T> | null }\n >();\n /** Slots that have left the window and are kept hidden, by the type of row that held them. */\n private readonly parked = new Map<unknown, VirtualRow<T>[]>();\n private nextSlot = 0;\n\n /** Note the row a slot is drawing, for parking it once it leaves. */\n private hold(row: VirtualRow<T>): VirtualRow<T> {\n const held = this.recycled.get(row.key);\n if (held) held.row = row;\n return row;\n }\n\n /**\n * Park the slots of the items that have left the window, for the items arriving.\n *\n * Parked rather than freed: a slot missing from the window is destroyed by `@for`, so a slot is\n * only reused if a row of its type arrives in the same pass as it left. Kept rendered and\n * hidden, it waits for the next row of its type however many passes later, which is what a\n * reuse queue of cells does in UIKit.\n */\n private releaseRecycled(first: number, last: number, pinned: number | null): void {\n const keep = new Set<unknown>();\n for (let index = first; index < last; index++) keep.add(this.keyAt(index));\n if (pinned !== null) keep.add(this.keyAt(pinned));\n for (const [key, held] of this.recycled) {\n if (keep.has(key)) continue;\n this.recycled.delete(key);\n let pool = this.parked.get(held.type);\n if (!pool) this.parked.set(held.type, (pool = []));\n pool.push({ ...(held.row ?? this.placeholder(key, held.slot)), parked: true, style: PARKED });\n }\n }\n\n /**\n * Keep a few hidden slots of each type once this pass has taken what it needs, dropping the\n * oldest: `@for` destroys the views of a slot that leaves the window for good.\n */\n private trimParked(): void {\n for (const pool of this.parked.values()) {\n if (pool.length > PARK_LIMIT) pool.splice(0, pool.length - PARK_LIMIT);\n }\n }\n\n /** A parked row for a slot that never drew, which only a slot taken and left in one pass is. */\n private placeholder(key: unknown, slot: number): VirtualRow<T> {\n return { index: -1, slot, key, item: this.items()[0]!, style: PARKED };\n }\n\n private recycledSlot(key: unknown, item: T, index: number): number {\n const held = this.recycled.get(key);\n if (held) return held.slot;\n const type = this.itemType()?.(item, index);\n const slot = this.unpark(key, type) ?? this.parked.get(type)?.pop()?.slot ?? this.nextSlot++;\n this.recycled.set(key, { slot, type, row: null });\n return slot;\n }\n\n /**\n * Take an item's own parked row out as it comes back: its slot if it is of the type the item now\n * is, and gone either way, or the window would hold its key twice.\n */\n private unpark(key: unknown, type: unknown): number | undefined {\n for (const [kind, pool] of this.parked) {\n const at = pool.findIndex((row) => row.key === key);\n if (at < 0) continue;\n const [row] = pool.splice(at, 1);\n return kind === type ? row!.slot : undefined;\n }\n return undefined;\n }\n\n /**\n * A row laid itself out; what `virtualListRow` calls. Only a row that sizes itself is measured,\n * and a height that has not changed changes nothing.\n */\n measureRow(row: VirtualRow<T>, layout: { width?: number; height?: number } | undefined): void {\n if (!this.measuring() || !layout || row.parked) return;\n const size = this.horizontal() ? layout.width : layout.height;\n if (size === undefined || this.measured.get(row.key) === size) return;\n this.measured.set(row.key, size);\n this.forgetDeparted();\n const index = this.indexOfKey()?.get(row.key);\n if (index === undefined) return;\n this.table()?.set(index, size + this.rowGap());\n this.measuredVersion.update((version) => version + 1);\n }\n\n /**\n * A row handed a view native has laid out before. Native reports a layout only when a view's\n * frame differs from the last one it reported, so an item that lands where the view already was,\n * at the same size, is never measured; the view's last size is its own until native says\n * otherwise.\n */\n adoptRow(row: VirtualRow<T>, layout: { width?: number; height?: number }): void {\n if (!this.measured.has(row.key)) this.measureRow(row, layout);\n }\n\n /** Drop the measurements of items long gone, so churn cannot grow the map without bound. */\n private forgetDeparted(): void {\n const items = this.items();\n if (this.measured.size <= items.length * 2 + 64) return;\n const current = new Set(this.keys() ?? items);\n for (const key of this.measured.keys()) if (!current.has(key)) this.measured.delete(key);\n }\n\n /** A separator for every rendered row but the list's last, in its leading row's slot. */\n protected readonly gaps = computed<Gap<T>[]>(() => {\n if (!this.separator()) return [];\n const items = this.items();\n const gaps: Gap<T>[] = [];\n for (const row of this.window()) {\n if (row.parked || row.index >= items.length - 1) continue;\n const style = this.measuring() ? this.measuredGapStyle(row) : this.gapStyle(row);\n if (!style) continue;\n const trailingItem = items[row.index + 1]!;\n gaps.push({\n index: row.index,\n style,\n context: {\n $implicit: row.item,\n leadingItem: row.item,\n trailingItem,\n leadingIndex: row.index,\n },\n });\n }\n return gaps;\n });\n\n /** The row's own slot, laid out to put the separator at its trailing edge. */\n private gapStyle(row: VirtualRow<T>): Record<string, unknown> {\n let style = this.gapStyles.get(row.style);\n if (!style) {\n style = {\n ...row.style,\n flexDirection: this.horizontal() ? 'row' : 'column',\n justifyContent: 'flex-end',\n pointerEvents: 'box-none',\n };\n this.gapStyles.set(row.style, style);\n }\n return style;\n }\n\n /**\n * A measured row's slot, over the row itself: nothing until its height is known, since drawing\n * it at the estimate would put a line through the middle of a row that turns out taller.\n */\n private measuredGapStyle(row: VirtualRow<T>): Record<string, unknown> | null {\n if (!this.measured.has(row.key)) return null;\n const start = this.topOf(row.index);\n const size = this.heightOf(row.index);\n const horizontal = this.horizontal();\n const flip = this.flipText();\n const across = this.across();\n const cached = this.measuredGaps.get(row.key);\n const placed = horizontal\n ? { ...across, left: start, width: size, transform: flip }\n : { ...across, top: start, height: size, transform: flip };\n if (cached && holds(cached, placed)) return cached;\n const style: Record<string, unknown> = horizontal\n ? { position: 'absolute', ...across, left: start, width: size, flexDirection: 'row' }\n : { position: 'absolute', ...across, top: start, height: size };\n style['justifyContent'] = 'flex-end';\n style['pointerEvents'] = 'box-none';\n if (flip) style['transform'] = flip;\n this.measuredGaps.set(row.key, style);\n if (this.measuredGaps.size > 256) this.measuredGaps.clear();\n return style;\n }\n\n /**\n * The header's translation while it is pinned: the scroll position, held back at zero by an\n * overscroll and at the first sticky row, which pushes it off.\n */\n protected readonly headerStyle = computed(() => {\n const flip = this.flipText();\n if (!this.stickyHeader()) return flip ? { transform: flip } : undefined;\n const along = this.offset() + this.headerHeight();\n const first = this.stickyIndices()[0];\n const limit = first === undefined ? Infinity : this.topOf(first);\n const shift = Math.min(Math.max(0, along), limit);\n const move = shift > 0 ? `${this.horizontal() ? 'translateX' : 'translateY'}(${shift}px)` : '';\n const transform = [move, flip ?? ''].filter(Boolean).join(' ');\n return transform ? { zIndex: 1, transform } : { zIndex: 1 };\n });\n\n /**\n * The footer, flipped back like every row when the list is inverted, as FlatList inverts its\n * header and footer cells too; otherwise both read upside down.\n */\n protected readonly footerStyle = computed(() => {\n const flip = this.flipText();\n return flip ? { transform: flip } : undefined;\n });\n\n /**\n * The sticky row currently holding the leading edge: the last one at or before the offset.\n * Null when the list has scrolled back above the first of them.\n */\n private readonly pinnedIndex = computed<number | null>(() => {\n const sticky = this.stickyIndices();\n if (sticky.length === 0) return null;\n const offset = this.offset();\n\n let pinned: number | null = null;\n for (const index of sticky) {\n if (this.topOf(index) <= offset) pinned = index;\n else break;\n }\n return pinned;\n });\n\n /** Which rows are on screen far enough to count, by the caller's threshold. */\n private viewableAt(offset: number): number[] {\n const viewport = this.viewport();\n if (!viewport) return [];\n\n const threshold = this.itemVisiblePercentThreshold() / 100;\n const rows: number[] = [];\n for (const row of this.window()) {\n if (row.parked) continue;\n const start = this.topOf(row.index);\n const size = this.heightOf(row.index);\n const shown = Math.min(start + size, offset + viewport) - Math.max(start, offset);\n if (shown > 0 && shown >= size * threshold) rows.push(row.index);\n }\n return rows;\n }\n\n /** The last set announced, so the output fires on a change rather than on every frame. */\n private announced: number[] = [];\n /** The items the last set was announced from: new items are a change even at the same indices. */\n private announcedFrom: readonly T[] | null = null;\n\n /**\n * Announce a change in what is on screen.\n *\n * Deliberately not a `computed` over a signal offset. A fling produces a scroll event per\n * frame, and writing a signal on each one costs a change-detection pass whether or not anything\n * moved into view; comparing here costs an array walk over the window and emits only when the\n * set really changed.\n */\n private announceViewable(offset: number): void {\n const viewable = this.viewableAt(offset);\n const entered = viewable.filter((index) => !this.announced.includes(index));\n const left = this.announced.filter((index) => !viewable.includes(index));\n const items = this.items();\n const same = items === this.announcedFrom || viewable.length === 0;\n if (entered.length === 0 && left.length === 0 && same) return;\n\n this.announced = viewable;\n this.announcedFrom = items;\n this.viewableItemsChanged.emit({\n viewable: viewable.map((index) => {\n const key = this.keyAt(index);\n return {\n index,\n // What is viewable is in the window, so it holds a slot already.\n slot: this.recycled.get(key)?.slot ?? -1,\n key,\n item: items[index]!,\n style: this.styleFor(index, false),\n };\n }),\n entered,\n left,\n });\n }\n\n /**\n * Scroll so that a row is at the start of the viewport, less `viewOffset`. The window moves\n * there at once, and the row is held there while the rows around it are measured.\n */\n scrollToIndex(options: { index: number; animated?: boolean; viewOffset?: number }): void {\n const items = this.items();\n if (!items.length) return;\n const index = Math.max(0, Math.min(options.index, items.length - 1));\n const within = -(options.viewOffset ?? 0);\n const offset = this.topOf(index) + within;\n this.lastOffset = offset;\n this.anchor = { key: this.keyAt(index), within, items, index };\n this.visible.set(index);\n this.scrollToOffset({ offset: this.headerHeight() + offset, animated: options.animated });\n }\n\n /** Scroll to an offset along the list's own axis: x when it is horizontal, y otherwise. */\n scrollToOffset(options: { offset: number; animated?: boolean }): void {\n const { offset, animated = true } = options;\n const [x, y] = this.horizontal() ? [offset, 0] : [0, offset];\n this.engine.dispatchCommand(this.node, 'scrollTo', [x, y, animated]);\n }\n\n scrollToEnd(options: { animated?: boolean } = {}): void {\n this.engine.dispatchCommand(this.node, 'scrollToEnd', [options.animated ?? true]);\n }\n\n private slotStyle(index: number, pinnedAt?: number): Record<string, unknown> {\n const start = pinnedAt ?? this.topOf(index);\n const size = this.heightOf(index);\n const horizontal = this.horizontal();\n const key = horizontal ? 'left' : 'top';\n const extent = horizontal ? 'width' : 'height';\n\n const flip = this.flipText();\n const across = this.across();\n\n let style = this.slots.get(index);\n // The flip is part of the comparison because turning the list over changes every row, and a\n // cached slot would otherwise keep the orientation it was built with.\n const placed = { ...across, [extent]: size, [key]: start, transform: flip };\n const stale = !style || pinnedAt !== undefined || !holds(style, placed);\n\n if (stale) {\n style = horizontal\n ? { position: 'absolute', ...across, left: start, width: size }\n : { position: 'absolute', ...across, top: start, height: size };\n // A pinned row draws over the ones sliding under it; the transform is the row's half of\n // the inversion.\n if (pinnedAt !== undefined) style['zIndex'] = 1;\n if (flip) style['transform'] = flip;\n this.slots.set(index, style);\n return style;\n }\n return style!;\n }\n\n protected onScroll(\n event: NativeSyntheticEvent<{ contentOffset?: { x?: number; y?: number } }>,\n ): void {\n const contentOffset = event.nativeEvent?.contentOffset;\n const along = (this.horizontal() ? contentOffset?.x : contentOffset?.y) ?? 0;\n const content = along - this.headerHeight();\n\n // The first *visible* row, not the first rendered one. The overscan is applied where the\n // window is built, so that both edges can be measured from the same place.\n // Not clamped to the items: an input set in the same task as this event has not reached the\n // list yet, and the window clamps when it renders.\n const visible = this.indexAt(content);\n if (visible !== this.visible()) this.visible.set(visible);\n this.lastOffset = content;\n this.anchorAt(visible, content);\n // A pinned row follows the scroll continuously, so with sticky rows the offset has to be a\n // signal - and only then. Without them this stays a field, and a fling that moves no row in\n // or out of the window costs no change detection at all.\n if (this.pinning()) this.offset.set(content);\n if (this.nativeSticky && this.pinning()) this.settleAfterPause(content);\n this.checkEnd(along);\n this.announceViewable(content);\n }\n\n /** A pinned row's translate, settled once scrolling pauses: see `STICKY_SETTLE_MS`. */\n private settleAfterPause(content: number): void {\n clearTimeout(this.settleTimer);\n this.settleTimer = setTimeout(() => this.settled.set(content), STICKY_SETTLE_MS);\n }\n\n protected onLayout(\n event: NativeSyntheticEvent<{ layout?: { width?: number; height?: number } }>,\n ): void {\n const layout = event.nativeEvent?.layout;\n this.viewport.set((this.horizontal() ? layout?.width : layout?.height) ?? 0);\n this.viewportMeasured = true;\n this.zeroSize?.laidOut(this.viewport(), this.items().length > 0);\n this.checkEnd(this.headerHeight() + this.lastOffset);\n this.announceViewable(this.lastOffset);\n }\n\n /** The header's extent along the axis, which every row sits after. */\n protected onHeaderLayout(\n event: NativeSyntheticEvent<{ layout?: { width?: number; height?: number } }>,\n ): void {\n const layout = event.nativeEvent?.layout;\n const height = (this.horizontal() ? layout?.width : layout?.height) ?? 0;\n if (height === this.headerHeight()) return;\n this.headerHeight.set(height);\n this.holdPastHeader();\n }\n\n /**\n * The header grew or shrank - a typing indicator in a chat's, a banner in a feed's - and every\n * row moved with it. Held like an insert when the caller asked for that and the viewport is\n * past the header, among the rows; at the start the user is looking at the header, and it is\n * left to push the rows along. Made at once rather than after a render, because a layout arrives\n * outside change detection and nothing else may be about to render.\n */\n private holdPastHeader(): void {\n const hold = this.maintainVisibleContentPosition();\n if (!hold || this.lastOffset <= (hold.autoscrollToTopThreshold ?? 0)) return;\n this.scrollToOffset({ offset: this.headerHeight() + this.lastOffset, animated: false });\n }\n\n protected onContentSize(event: NativeSyntheticEvent<{ width?: number; height?: number }>): void {\n const size = event.nativeEvent;\n this.contentSize = (this.horizontal() ? size?.width : size?.height) ?? 0;\n this.contentSizeFor = this.extent();\n this.checkEnd(this.headerHeight() + this.lastOffset);\n }\n\n private checkEnd(y: number): void {\n const count = this.items().length;\n const viewport = this.viewport();\n if (!count || !viewport) return;\n // Native's size is for the rows it last laid out; until it reports for these, their own extent.\n const extent = this.extent();\n const reported = this.contentSizeFor === extent ? this.contentSize : 0;\n const total = reported || this.headerHeight() + extent;\n const distanceFromEnd = total - (y + viewport);\n // Away from the end again re-arms it, as React Native does, so a load that failed is retried\n // the next time the user comes back down.\n if (distanceFromEnd > this.endReachedThreshold() * viewport) {\n this.endReachedFor = -1;\n return;\n }\n if (this.endReachedFor === count) return;\n this.endReachedFor = count;\n this.endReached.emit({ distanceFromEnd });\n }\n}\n\n/** Whether a cached slot style already has every one of these props. */\nfunction holds(style: Record<string, unknown>, props: Record<string, unknown>): boolean {\n return Object.entries(props).every(([prop, value]) => style[prop] === value);\n}\n\n/**\n * Put on each row's view: `<view [virtualListRow]=\"row\">`. Applies the row's style, and reports\n * the row's layout to the list, which is how a list of rows that size themselves learns how tall\n * each one is.\n */\n@Directive({\n selector: '[virtualListRow]',\n host: {\n '[style]': 'row().style',\n // A parked row is not read out: see `PARKED`.\n '[attr.aria-hidden]': 'row().parked ? true : null',\n '(layout)': 'onLayout($event)',\n },\n})\nexport class VirtualListRow<T = unknown> {\n readonly row = input.required<VirtualRow<T>>({ alias: 'virtualListRow' });\n private readonly list = inject<VirtualList<T>>(VirtualList);\n /** The last layout native reported for this view, whichever item it held. */\n private layout: { width?: number; height?: number } | undefined;\n\n constructor() {\n effect(() => {\n const row = this.row();\n if (this.layout) untracked(() => this.list.adoptRow(row, this.layout!));\n });\n }\n\n protected onLayout(\n event: NativeSyntheticEvent<{ layout?: { width?: number; height?: number } }>,\n ): void {\n this.layout = event.nativeEvent?.layout ?? this.layout;\n this.list.measureRow(this.row(), event.nativeEvent?.layout);\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-native/components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Angular Native's core components: view, text, image, pressable, scroll-view, virtual-list, text-input and the rest of React Native's set.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"access": "public"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@ng-native/device": "0.
|
|
65
|
-
"@ng-native/fabric": "0.
|
|
64
|
+
"@ng-native/device": "0.19.0",
|
|
65
|
+
"@ng-native/fabric": "0.19.0"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"@angular/core": "^22.0.0",
|