shadow-claw 1.59.6 → 1.60.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/.well-known/mcp/server-card.json +1 -1
- package/.well-known/mcp.json +1 -1
- package/README.md +6 -2
- package/dist/cli/build/build.js +1 -1
- package/dist/cli/chunk-3C5izdQW.js +1 -0
- package/dist/cli/chunk-B-75h9gX.js +1 -0
- package/dist/cli/{chunk-C9o6lXP3.js → chunk-B7Kn-otm.js} +1 -1
- package/dist/cli/{chunk-YX32FcN7.js → chunk-BBczgswQ.js} +1 -1
- package/dist/cli/{chunk-DcNxjqH6.js → chunk-BE-lYWcn.js} +1 -1
- package/dist/cli/{chunk-DJqHK-qS.js → chunk-BECr0WxI.js} +11 -11
- package/dist/cli/chunk-BEz1PD1_.js +1 -0
- package/dist/cli/chunk-BLzI1Fp2.js +1 -0
- package/dist/cli/{chunk-yiVdvGCJ.js → chunk-BVSC1MNQ.js} +11 -11
- package/dist/cli/{chunk-CX2itile.js → chunk-BdWcep6o.js} +1 -1
- package/dist/cli/{chunk-DLde6nuO.js → chunk-BfTpnSS4.js} +1 -1
- package/dist/cli/{chunk-D2_eAO83.js → chunk-BgvqTf7w.js} +1 -1
- package/dist/cli/chunk-BwsJfUT3.js +1 -0
- package/dist/cli/{chunk--PFY91kE.js → chunk-C9b4b7c_.js} +1 -1
- package/dist/cli/{chunk-D3y7h9Xe.js → chunk-CAw9XYFe.js} +1 -1
- package/dist/cli/chunk-CFCcbFs2.js +396 -0
- package/dist/cli/{chunk-Cnjb8Usu.js → chunk-CTarF4FC.js} +1 -1
- package/dist/cli/{chunk-DM4xsTry.js → chunk-Cbq5hpjb.js} +4 -4
- package/dist/cli/chunk-CjTjKy_v.js +310 -0
- package/dist/cli/chunk-Cjyu4cr_.js +36 -0
- package/dist/cli/{chunk-DUGZPka_.js → chunk-ClMKygjZ.js} +1 -1
- package/dist/cli/chunk-Cppnq1KF.js +1 -0
- package/dist/cli/{chunk-DvemF16v.js → chunk-D9QCNFMO.js} +1 -1
- package/dist/cli/chunk-DB21BMqt.js +7 -0
- package/dist/cli/{chunk-_Vo-o_e3.js → chunk-DHoIWvCc.js} +1 -1
- package/dist/cli/chunk-DZEN9T5y.js +1 -0
- package/dist/cli/{chunk-5rLO4DWS.js → chunk-Dl14OyYO.js} +9 -9
- package/dist/cli/chunk-Dl_vv0dI.js +1 -0
- package/dist/cli/chunk-Dpmfhlyl.js +1 -0
- package/dist/cli/{chunk-BrR1DOBS.js → chunk-Du7Xtucq.js} +1 -1
- package/dist/cli/{chunk-Bc_weULz.js → chunk-DxcDFUi_.js} +1 -1
- package/dist/cli/{chunk-Dt7-hzJU.js → chunk-DyyEWbV7.js} +1 -1
- package/dist/cli/chunk-N0x3mXU0.js +1 -0
- package/dist/cli/{chunk-CGoE4llV.js → chunk-V-w0Bata.js} +1 -1
- package/dist/cli/{chunk-C8DBACtx.js → chunk-ZxDxSSn-.js} +1 -1
- package/dist/cli/chunk-lPvFUkd5.js +7 -0
- package/dist/cli/{chunk-Ctg5L55n.js → chunk-n5s-sCdU.js} +1 -1
- package/dist/cli/{chunk-Dw8GndPD.js → chunk-nD9VPVMq.js} +1 -1
- package/dist/cli/{chunk-Cq_kQohv.js → chunk-rFuy8aS_.js} +1 -1
- package/dist/cli/{chunk-Bq38OubR.js → chunk-wjM6JXWa.js} +1 -1
- package/dist/cli/{chunk-3wTukVof.js → chunk-zcES9rut.js} +1 -1
- package/dist/cli/cli.js +3 -3
- package/dist/headless-agent.js +2 -2
- package/dist/lib/{app-routes-DJdIjp2V.js → app-routes-BXiRvlNl.js} +7 -25
- package/dist/lib/{app-routes-DJdIjp2V.js.map → app-routes-BXiRvlNl.js.map} +1 -1
- package/dist/lib/{attachment-capabilities-Dbb-4ZP5.js → attachment-capabilities-BjkEPip8.js} +2 -2
- package/dist/lib/{attachment-capabilities-Dbb-4ZP5.js.map → attachment-capabilities-BjkEPip8.js.map} +1 -1
- package/dist/lib/{channel-Dlru5ofR.js → channel-DB77spML.js} +3 -3
- package/dist/lib/{channel-Dlru5ofR.js.map → channel-DB77spML.js.map} +1 -1
- package/dist/lib/{chat-template-BuuLY8l7.js → chat-template-DPEKGJhB.js} +2 -2
- package/dist/lib/{chat-template-BuuLY8l7.js.map → chat-template-DPEKGJhB.js.map} +1 -1
- package/dist/lib/{compact-context-BtR55YPU.js → compact-context-Q9t9aL1e.js} +19 -19
- package/dist/lib/{compact-context-BtR55YPU.js.map → compact-context-Q9t9aL1e.js.map} +1 -1
- package/dist/lib/components/common/shadow-claw-provider-model-picker.js +1 -1
- package/dist/lib/components/index.js +27 -27
- package/dist/lib/components/settings/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/settings/shadow-claw-git.js +1 -1
- package/dist/lib/components/settings/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
- package/dist/lib/components/settings/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
- package/dist/lib/components/settings/shadow-claw-notifications.js +1 -1
- package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
- package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw-a2ui.js +1 -1
- package/dist/lib/components/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/shadow-claw-channels.js +1 -1
- package/dist/lib/components/shadow-claw-chat.js +1 -1
- package/dist/lib/components/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/shadow-claw-conversations.js +1 -1
- package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
- package/dist/lib/components/shadow-claw-files.js +1 -1
- package/dist/lib/components/shadow-claw-git.js +1 -1
- package/dist/lib/components/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/shadow-claw-llm.js +1 -1
- package/dist/lib/components/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/shadow-claw-networking.js +1 -1
- package/dist/lib/components/shadow-claw-notifications.js +1 -1
- package/dist/lib/components/shadow-claw-page-header.js +1 -1
- package/dist/lib/components/shadow-claw-pages.js +1 -1
- package/dist/lib/components/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/shadow-claw-provider-model-picker.js +1 -1
- package/dist/lib/components/shadow-claw-settings.js +1 -1
- package/dist/lib/components/shadow-claw-storage.js +1 -1
- package/dist/lib/components/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/shadow-claw-tasks.js +1 -1
- package/dist/lib/components/shadow-claw-terminal.js +1 -1
- package/dist/lib/components/shadow-claw-tools.js +1 -1
- package/dist/lib/components/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw.js +1 -1
- package/dist/lib/{config-DxNI3TlW.js → config-BrHR97zt.js} +2 -2
- package/dist/lib/{config-DxNI3TlW.js.map → config-BrHR97zt.js.map} +1 -1
- package/dist/lib/{configure-peer-js-ChDhOZU4.js → configure-peer-js-CgFiwoxY.js} +3 -3
- package/dist/lib/{configure-peer-js-ChDhOZU4.js.map → configure-peer-js-CgFiwoxY.js.map} +1 -1
- package/dist/lib/{connections-DC4NZkJE.js → connections-C1FWsBsE.js} +2 -2
- package/dist/lib/{connections-DC4NZkJE.js.map → connections-C1FWsBsE.js.map} +1 -1
- package/dist/lib/content/build-attachment-content-blocks.d.ts +2 -0
- package/dist/lib/{credentials-5vpz0XPk.js → credentials-CZbngHXW.js} +2 -2
- package/dist/lib/{credentials-5vpz0XPk.js.map → credentials-CZbngHXW.js.map} +1 -1
- package/dist/lib/{discover-skills-CD0sKvAI.js → discover-skills-CXyaWHKi.js} +13 -13
- package/dist/lib/{discover-skills-CD0sKvAI.js.map → discover-skills-CXyaWHKi.js.map} +1 -1
- package/dist/lib/{download-group-file-Dk3qaxhJ.js → download-group-file-D0wgg10Q.js} +2 -2
- package/dist/lib/{download-group-file-Dk3qaxhJ.js.map → download-group-file-D0wgg10Q.js.map} +1 -1
- package/dist/lib/{file-viewer-B4pRW-_G.js → file-viewer-DOfvX6yy.js} +5 -5
- package/dist/lib/{file-viewer-B4pRW-_G.js.map → file-viewer-DOfvX6yy.js.map} +1 -1
- package/dist/lib/{get-or-create-subscriber-id-HCcgDEPz.js → get-or-create-subscriber-id-wyzaML7Z.js} +2 -2
- package/dist/lib/{get-or-create-subscriber-id-HCcgDEPz.js.map → get-or-create-subscriber-id-wyzaML7Z.js.map} +1 -1
- package/dist/lib/{git-B3Q1euc5.js → git-CogDRlEz.js} +5 -5
- package/dist/lib/{git-B3Q1euc5.js.map → git-CogDRlEz.js.map} +1 -1
- package/dist/lib/{iframe-bridge-scripts-D8iuFhUk.js → iframe-bridge-scripts-Dx825LLG.js} +2 -2
- package/dist/lib/{iframe-bridge-scripts-D8iuFhUk.js.map → iframe-bridge-scripts-Dx825LLG.js.map} +1 -1
- package/dist/lib/index.js +28 -28
- package/dist/lib/{init-chat-split-resize-B0ODULx9.js → init-chat-split-resize-Cc0bd2z9.js} +2 -2
- package/dist/lib/{init-chat-split-resize-B0ODULx9.js.map → init-chat-split-resize-Cc0bd2z9.js.map} +1 -1
- package/dist/lib/{init-control-plane-C1FRRmjC.js → init-control-plane-CEGdzgWX.js} +15 -15
- package/dist/lib/{init-control-plane-C1FRRmjC.js.map → init-control-plane-CEGdzgWX.js.map} +1 -1
- package/dist/lib/{invoke-agent-CzN7sVh-.js → invoke-agent-cac3gCsj.js} +11 -11
- package/dist/lib/{invoke-agent-CzN7sVh-.js.map → invoke-agent-cac3gCsj.js.map} +1 -1
- package/dist/lib/{markdown-mbNo7cV3.js → markdown--6vTAPEH.js} +2 -2
- package/dist/lib/{markdown-mbNo7cV3.js.map → markdown--6vTAPEH.js.map} +1 -1
- package/dist/lib/{mcp-reconnect-3T7yWGEY.js → mcp-reconnect-BeqQvNWO.js} +3 -3
- package/dist/lib/{mcp-reconnect-3T7yWGEY.js.map → mcp-reconnect-BeqQvNWO.js.map} +1 -1
- package/dist/lib/{model-ranking-DGNSWYwN.js → model-ranking-BhsJV7vb.js} +2 -2
- package/dist/lib/{model-ranking-DGNSWYwN.js.map → model-ranking-BhsJV7vb.js.map} +1 -1
- package/dist/lib/{move-group-entry-NMTJ59M9.js → move-group-entry-D8dptMg0.js} +5 -5
- package/dist/lib/{move-group-entry-NMTJ59M9.js.map → move-group-entry-D8dptMg0.js.map} +1 -1
- package/dist/lib/{orchestrator-B8FV1V7x.js → orchestrator-BBAwy9Nm.js} +24 -24
- package/dist/lib/{orchestrator-B8FV1V7x.js.map → orchestrator-BBAwy9Nm.js.map} +1 -1
- package/dist/lib/{orchestrator-i_QJ-o22.js → orchestrator-cRBe3lhq.js} +11 -11
- package/dist/lib/orchestrator-cRBe3lhq.js.map +1 -0
- package/dist/lib/{parse-path-DPCn-HwI.js → parse-path-BOHQP_IQ.js} +3 -3
- package/dist/lib/{parse-path-DPCn-HwI.js.map → parse-path-BOHQP_IQ.js.map} +1 -1
- package/dist/lib/{peerjs-z5zeioPV.js → peerjs-BLg8aGUj.js} +8 -8
- package/dist/lib/{peerjs-z5zeioPV.js.map → peerjs-BLg8aGUj.js.map} +1 -1
- package/dist/lib/{process-peer-query-param-CJp7w7AU.js → process-peer-query-param-BnsVnxzH.js} +5 -5
- package/dist/lib/{process-peer-query-param-CJp7w7AU.js.map → process-peer-query-param-BnsVnxzH.js.map} +1 -1
- package/dist/lib/{process-pending-shared-payloads-B6_TlBFA.js → process-pending-shared-payloads-DBZfZOOa.js} +4 -4
- package/dist/lib/{process-pending-shared-payloads-B6_TlBFA.js.map → process-pending-shared-payloads-DBZfZOOa.js.map} +1 -1
- package/dist/lib/{process-room-query-param-C3FFGGn6.js → process-room-query-param-B8EYg_-r.js} +4 -4
- package/dist/lib/{process-room-query-param-C3FFGGn6.js.map → process-room-query-param-B8EYg_-r.js.map} +1 -1
- package/dist/lib/{provider-DcQZypu5.js → provider-BC9KPI14.js} +3 -3
- package/dist/lib/{provider-DcQZypu5.js.map → provider-BC9KPI14.js.map} +1 -1
- package/dist/lib/{push-client-Cx5rMs6J.js → push-client-CAm6UMvE.js} +5 -5
- package/dist/lib/{push-client-Cx5rMs6J.js.map → push-client-CAm6UMvE.js.map} +1 -1
- package/dist/lib/{read-group-file-bytes-CXOG_YyM.js → read-group-file-bytes-UQIk1eJG.js} +2 -2
- package/dist/lib/{read-group-file-bytes-CXOG_YyM.js.map → read-group-file-bytes-UQIk1eJG.js.map} +1 -1
- package/dist/lib/{rooms-CwlkYLDU.js → rooms-Dzphx3rK.js} +2 -2
- package/dist/lib/{rooms-CwlkYLDU.js.map → rooms-Dzphx3rK.js.map} +1 -1
- package/dist/lib/{shadow-claw-DoQ7fgl5.js → shadow-claw-CGl8tXtG.js} +17 -20
- package/dist/lib/shadow-claw-CGl8tXtG.js.map +1 -0
- package/dist/lib/{shadow-claw-a2ui-Br6qJMs1.js → shadow-claw-a2ui-lG0vQbW8.js} +2 -2
- package/dist/lib/{shadow-claw-a2ui-Br6qJMs1.js.map → shadow-claw-a2ui-lG0vQbW8.js.map} +1 -1
- package/dist/lib/{shadow-claw-accounts-BTDILfWw.js → shadow-claw-accounts-CkqyCxwp.js} +3 -3
- package/dist/lib/{shadow-claw-accounts-BTDILfWw.js.map → shadow-claw-accounts-CkqyCxwp.js.map} +1 -1
- package/dist/lib/{shadow-claw-channel-config-IKiL34tI.js → shadow-claw-channel-config-BNIWCdsL.js} +4 -4
- package/dist/lib/{shadow-claw-channel-config-IKiL34tI.js.map → shadow-claw-channel-config-BNIWCdsL.js.map} +1 -1
- package/dist/lib/{shadow-claw-channels-JgEzuHWK.js → shadow-claw-channels-C2QSn4Ew.js} +3 -3
- package/dist/lib/{shadow-claw-channels-JgEzuHWK.js.map → shadow-claw-channels-C2QSn4Ew.js.map} +1 -1
- package/dist/lib/{shadow-claw-chat-SGUDT31r.js → shadow-claw-chat-Wx3y9y6c.js} +15 -15
- package/dist/lib/{shadow-claw-chat-SGUDT31r.js.map → shadow-claw-chat-Wx3y9y6c.js.map} +1 -1
- package/dist/lib/{shadow-claw-control-plane-CRWFZ3vD.js → shadow-claw-control-plane-D5E4cFGu.js} +7 -7
- package/dist/lib/{shadow-claw-control-plane-CRWFZ3vD.js.map → shadow-claw-control-plane-D5E4cFGu.js.map} +1 -1
- package/dist/lib/{shadow-claw-conversations-D23GJ7qo.js → shadow-claw-conversations-BtDv7GRW.js} +7 -7
- package/dist/lib/{shadow-claw-conversations-D23GJ7qo.js.map → shadow-claw-conversations-BtDv7GRW.js.map} +1 -1
- package/dist/lib/{shadow-claw-file-viewer-C1V8WTiU.js → shadow-claw-file-viewer-CG40kwWV.js} +10 -10
- package/dist/lib/{shadow-claw-file-viewer-C1V8WTiU.js.map → shadow-claw-file-viewer-CG40kwWV.js.map} +1 -1
- package/dist/lib/{shadow-claw-files-DN7irmE1.js → shadow-claw-files-BOUULrlX.js} +11 -11
- package/dist/lib/{shadow-claw-files-DN7irmE1.js.map → shadow-claw-files-BOUULrlX.js.map} +1 -1
- package/dist/lib/{shadow-claw-git-D-1oIh65.js → shadow-claw-git-BeHV73_9.js} +6 -6
- package/dist/lib/{shadow-claw-git-D-1oIh65.js.map → shadow-claw-git-BeHV73_9.js.map} +1 -1
- package/dist/lib/{shadow-claw-integrations-CZjnm7cM.js → shadow-claw-integrations-RZZ-m-Id.js} +4 -4
- package/dist/lib/{shadow-claw-integrations-CZjnm7cM.js.map → shadow-claw-integrations-RZZ-m-Id.js.map} +1 -1
- package/dist/lib/{shadow-claw-llm-4Gefh5FN.js → shadow-claw-llm-KONyWKZM.js} +9 -9
- package/dist/lib/{shadow-claw-llm-4Gefh5FN.js.map → shadow-claw-llm-KONyWKZM.js.map} +1 -1
- package/dist/lib/{shadow-claw-mcp-remote-B9ssb3YV.js → shadow-claw-mcp-remote-BKFROurv.js} +4 -4
- package/dist/lib/{shadow-claw-mcp-remote-B9ssb3YV.js.map → shadow-claw-mcp-remote-BKFROurv.js.map} +1 -1
- package/dist/lib/{shadow-claw-networking-BN5BB4hb.js → shadow-claw-networking-Diy3JJkc.js} +2 -2
- package/dist/lib/{shadow-claw-networking-BN5BB4hb.js.map → shadow-claw-networking-Diy3JJkc.js.map} +1 -1
- package/dist/lib/{shadow-claw-notifications-71KARtkY.js → shadow-claw-notifications-C-upPa-4.js} +3 -3
- package/dist/lib/{shadow-claw-notifications-71KARtkY.js.map → shadow-claw-notifications-C-upPa-4.js.map} +1 -1
- package/dist/lib/{shadow-claw-page-header-DMGO-TSe.js → shadow-claw-page-header-C_Qr3xZM.js} +2 -2
- package/dist/lib/{shadow-claw-page-header-DMGO-TSe.js.map → shadow-claw-page-header-C_Qr3xZM.js.map} +1 -1
- package/dist/lib/{shadow-claw-pages-BiRM6qiA.js → shadow-claw-pages-CfAjUKgd.js} +11 -11
- package/dist/lib/{shadow-claw-pages-BiRM6qiA.js.map → shadow-claw-pages-CfAjUKgd.js.map} +1 -1
- package/dist/lib/{shadow-claw-peerjs-BZu7jNSe.js → shadow-claw-peerjs-t4YibS9s.js} +6 -6
- package/dist/lib/{shadow-claw-peerjs-BZu7jNSe.js.map → shadow-claw-peerjs-t4YibS9s.js.map} +1 -1
- package/dist/lib/{shadow-claw-provider-model-picker-BXYXEobD.js → shadow-claw-provider-model-picker-B-Ct4yW-.js} +2 -2
- package/dist/lib/{shadow-claw-provider-model-picker-BXYXEobD.js.map → shadow-claw-provider-model-picker-B-Ct4yW-.js.map} +1 -1
- package/dist/lib/{shadow-claw-settings-CcT5EK08.js → shadow-claw-settings-Cg5V0e9g.js} +7 -7
- package/dist/lib/{shadow-claw-settings-CcT5EK08.js.map → shadow-claw-settings-Cg5V0e9g.js.map} +1 -1
- package/dist/lib/{shadow-claw-storage-eTOpbvpi.js → shadow-claw-storage-C7tCnsSG.js} +5 -5
- package/dist/lib/{shadow-claw-storage-eTOpbvpi.js.map → shadow-claw-storage-C7tCnsSG.js.map} +1 -1
- package/dist/lib/{shadow-claw-task-server-DFImTUbw.js → shadow-claw-task-server-BObsRdf8.js} +2 -2
- package/dist/lib/{shadow-claw-task-server-DFImTUbw.js.map → shadow-claw-task-server-BObsRdf8.js.map} +1 -1
- package/dist/lib/{shadow-claw-tasks-BjaxsmUx.js → shadow-claw-tasks-B2EEqrcY.js} +9 -9
- package/dist/lib/{shadow-claw-tasks-BjaxsmUx.js.map → shadow-claw-tasks-B2EEqrcY.js.map} +1 -1
- package/dist/lib/{shadow-claw-terminal-C-4wreFe.js → shadow-claw-terminal-DSHfO2b9.js} +2 -2
- package/dist/lib/{shadow-claw-terminal-C-4wreFe.js.map → shadow-claw-terminal-DSHfO2b9.js.map} +1 -1
- package/dist/lib/{shadow-claw-tools-COdrGZJk.js → shadow-claw-tools-DwPBADua.js} +7 -7
- package/dist/lib/{shadow-claw-tools-COdrGZJk.js.map → shadow-claw-tools-DwPBADua.js.map} +1 -1
- package/dist/lib/{shadow-claw-webvm-sxqVjO0L.js → shadow-claw-webvm-CY4qGaMB.js} +3 -3
- package/dist/lib/{shadow-claw-webvm-sxqVjO0L.js.map → shadow-claw-webvm-CY4qGaMB.js.map} +1 -1
- package/dist/lib/{sync-web-mcp-registration-D4hdUwtv.js → sync-web-mcp-registration-BiOZvW-R.js} +6 -6
- package/dist/lib/{sync-web-mcp-registration-D4hdUwtv.js.map → sync-web-mcp-registration-BiOZvW-R.js.map} +1 -1
- package/dist/lib/{system-prompt-DT_KeYaL.js → system-prompt-CxJ3Nx4c.js} +9 -8
- package/dist/lib/system-prompt-CxJ3Nx4c.js.map +1 -0
- package/dist/lib/{tools-Beuyh8y1.js → tools-B8OJ4sMF.js} +4 -4
- package/dist/lib/{tools-Beuyh8y1.js.map → tools-B8OJ4sMF.js.map} +1 -1
- package/dist/lib/{transformers-DydnReu4.js → transformers-BMURofG6.js} +2 -2
- package/dist/lib/{transformers-DydnReu4.js.map → transformers-BMURofG6.js.map} +1 -1
- package/dist/lib/{trusted-types-CfwZl_rr.js → trusted-types-HwsGS5Nj.js} +19 -17
- package/dist/lib/{trusted-types-CfwZl_rr.js.map → trusted-types-HwsGS5Nj.js.map} +1 -1
- package/dist/lib/{upload-group-file-BbBzjTcN.js → upload-group-file-CJpoNjEb.js} +3 -3
- package/dist/lib/{upload-group-file-BbBzjTcN.js.map → upload-group-file-CJpoNjEb.js.map} +1 -1
- package/dist/lib/utils/index.js +1 -1
- package/dist/lib/utils/namespaced-storage.js +1 -1
- package/dist/lib/utils/runtime-assets.js +1 -1
- package/dist/lib/utils/utils.js +1 -1
- package/dist/lib/{webmcp-DCfAFiIO.js → webmcp-BoMTvgmX.js} +3 -3
- package/dist/lib/{webmcp-DCfAFiIO.js.map → webmcp-BoMTvgmX.js.map} +1 -1
- package/dist/lib/{write-group-file-bytes-Ccn-VFUU.js → write-group-file-bytes-CNT7DqOZ.js} +3 -3
- package/dist/lib/{write-group-file-bytes-Ccn-VFUU.js.map → write-group-file-bytes-CNT7DqOZ.js.map} +1 -1
- package/dist/public/.well-known/mcp/server-card.json +1 -1
- package/dist/public/.well-known/mcp.json +1 -1
- package/dist/public/AGENTS.md +3 -1
- package/dist/public/README.md +6 -2
- package/dist/public/agent.worker.js +1 -1
- package/dist/public/attachment-capabilities-AdwXt3--.js +1 -0
- package/dist/public/{channel-BylT3rJC.js → channel-DIpDQekL.js} +1 -1
- package/dist/public/{chat-template-DPHJy7tr.js → chat-template-CXKs8lFR.js} +1 -1
- package/dist/public/compact-context-BQ2ZXoAc.js +5 -0
- package/dist/public/{compact-context-BINQh64w.js → compact-context-dHitmPsV.js} +2 -2
- package/dist/public/config-C16fFWtP.js +1 -0
- package/dist/public/{configure-peer-js-DChhcOfe.js → configure-peer-js-DV1rqvFX.js} +1 -1
- package/dist/public/{connections-CHaw0VqP.js → connections-Dxwj8yK_.js} +1 -1
- package/dist/public/{create-model-cache-fetch-DQebkoPL.js → create-model-cache-fetch-B0mSCEk6.js} +1 -1
- package/dist/public/{credentials-CgVqS119.js → credentials-CJUQ5Ep2.js} +1 -1
- package/dist/public/{custom-element-security-kiDhPfb8.js → custom-element-security-B2daIE5r.js} +2 -2
- package/dist/public/{discover-skills-Cvmx5I9V.js → discover-skills-BWJB8HUA.js} +6 -6
- package/dist/public/docs/architecture/overview.md +1 -1
- package/dist/public/docs/example/article/index.html +29 -30
- package/dist/public/docs/example/article.html +29 -30
- package/dist/public/docs/publishing/index.html +29 -30
- package/dist/public/docs/publishing.html +29 -30
- package/dist/public/docs/skill-creator/index.html +29 -30
- package/dist/public/docs/skill-creator.html +29 -30
- package/dist/public/docs/subsystems/attachment-capabilities.md +14 -1
- package/dist/public/docs/subsystems/cli.md +95 -51
- package/dist/public/docs/subsystems/pages.md +5 -0
- package/dist/public/{download-group-file-BapoRgfU.js → download-group-file-BkMH-JKi.js} +1 -1
- package/dist/public/e2e/README.md +1 -1
- package/dist/public/{e2e-bridge-C0g8vZKr.js → e2e-bridge-lP2qqiv3.js} +1 -1
- package/dist/public/get-group-dir-D--BiEyk.js +1 -0
- package/dist/public/{get-or-create-subscriber-id-GvRZYXwA.js → get-or-create-subscriber-id-jVHnQfbr.js} +1 -1
- package/dist/public/{git-CaAAZfVd.js → git-DjmQ16rm.js} +2 -2
- package/dist/public/{iframe-bridge-scripts-BnqtKhE4.js → iframe-bridge-scripts-CO0izGjW.js} +1 -1
- package/dist/public/index.html +29 -30
- package/dist/public/index.js +1 -1
- package/dist/public/{init-chat-split-resize-Btonoy8u.js → init-chat-split-resize-C8AqCCiK.js} +1 -1
- package/dist/public/init-control-plane-Ctz7FI8M.js +1 -0
- package/dist/public/{invoke-agent-B3Osw6K7.js → invoke-agent-C_geruwq.js} +1 -1
- package/dist/public/llms.txt +1 -1
- package/dist/public/main/index.html +29 -30
- package/dist/public/main/memory/index.html +29 -30
- package/dist/public/main/memory.html +29 -30
- package/dist/public/main.html +29 -30
- package/dist/public/{markdown-CPbU4r1U.js → markdown-CDSb5Hrl.js} +1 -1
- package/dist/public/{mcp-reconnect-CzROVsXG.js → mcp-reconnect-iPZPihwX.js} +1 -1
- package/dist/public/{memory-storage-BkoMlxOr.js → memory-storage-2m7KZ-aP.js} +1 -1
- package/dist/public/{model-ranking-CK0iBo3Z.js → model-ranking-BgOSaNIy.js} +1 -1
- package/dist/public/{move-group-entry-CTxoq7lw.js → move-group-entry-QQ9Hkk54.js} +1 -1
- package/dist/public/{orchestrator-BrDjQbGf.js → orchestrator-C1kaTltu.js} +2 -2
- package/dist/public/orchestrator-Li1UAsv7.js +63 -0
- package/dist/public/{peerjs-CgF4Iz5W.js → peerjs-DbBryE-9.js} +1 -1
- package/dist/public/{process-peer-query-param-BL2k0Hu-.js → process-peer-query-param-DQIgr3KL.js} +1 -1
- package/dist/public/{process-pending-shared-payloads-C1AgGvn8.js → process-pending-shared-payloads-Ctb-TFqB.js} +1 -1
- package/dist/public/{process-room-query-param-DM0QCq3_.js → process-room-query-param-F-XnIVoZ.js} +1 -1
- package/dist/public/provider-YPZmsuHR.js +1 -0
- package/dist/public/{push-client-DJEOz7bi.js → push-client-DRx9Eggz.js} +1 -1
- package/dist/public/{rooms-C6LXIJl4.js → rooms-BurBI7is.js} +1 -1
- package/dist/public/service-worker/init.js +1 -1
- package/dist/public/service-worker.js +1 -1
- package/dist/public/shadow-claw-Bg9AQ5x_.js +1176 -0
- package/dist/public/{shadow-claw-accounts--4hd_oCz.js → shadow-claw-accounts-B3mjYI0M.js} +1 -1
- package/dist/public/{shadow-claw-card-IbNlZAdK.js → shadow-claw-card-tcXRS1GF.js} +1 -1
- package/dist/public/{shadow-claw-channels-Vq_pPGa2.js → shadow-claw-channels-BiSfLvWv.js} +1 -1
- package/dist/public/{shadow-claw-chat-D7_GS25e.js → shadow-claw-chat-N5jMsXZZ.js} +3 -3
- package/dist/public/{shadow-claw-control-plane-WTMEV8_p.js → shadow-claw-control-plane-DFVe_Xdq.js} +2 -2
- package/dist/public/{shadow-claw-conversations-CLQgU1IT.js → shadow-claw-conversations-wAR06_ya.js} +1 -1
- package/dist/public/{shadow-claw-empty-state-D4CrFGsN.js → shadow-claw-empty-state-CnPm3NVM.js} +1 -1
- package/dist/public/{shadow-claw-file-viewer-BhqiqLWQ.js → shadow-claw-file-viewer-sZN_FCDW.js} +4 -4
- package/dist/public/{shadow-claw-files-senDiG9l.js → shadow-claw-files-CnvkCbd4.js} +2 -2
- package/dist/public/{shadow-claw-git-DOOCqY23.js → shadow-claw-git-BBHfClGk.js} +2 -2
- package/dist/public/{shadow-claw-integrations-Bsvc3Agq.js → shadow-claw-integrations-DvdBqzRJ.js} +1 -1
- package/dist/public/{shadow-claw-llm-actYICAk.js → shadow-claw-llm-YfohG519.js} +2 -2
- package/dist/public/{shadow-claw-mcp-remote-BYUgrK3v.js → shadow-claw-mcp-remote-BAVbf5pi.js} +1 -1
- package/dist/public/{shadow-claw-networking-Dk3p5Ny_.js → shadow-claw-networking-CZ4LWPW7.js} +1 -1
- package/dist/public/{shadow-claw-notifications-CzPAlay8.js → shadow-claw-notifications-BHwyREkG.js} +1 -1
- package/dist/public/{shadow-claw-page-header-CjJpVkyL.js → shadow-claw-page-header-De6Qf6eY.js} +1 -1
- package/dist/public/{shadow-claw-page-header-action-button-2DH5O1TD.js → shadow-claw-page-header-action-button-FSOhTc9z.js} +1 -1
- package/dist/public/{shadow-claw-pages-3r5I-wI8.js → shadow-claw-pages-D_oPyDca.js} +6 -6
- package/dist/public/{shadow-claw-pdf-viewer-BiCEwsoY.js → shadow-claw-pdf-viewer-CrU4wqRq.js} +1 -1
- package/dist/public/{shadow-claw-settings-DgB9RSZN.js → shadow-claw-settings-DkUhvxVr.js} +2 -2
- package/dist/public/{shadow-claw-storage-JB_43nd8.js → shadow-claw-storage-D0o56Tjw.js} +1 -1
- package/dist/public/{shadow-claw-task-server-oi5UIxdA.js → shadow-claw-task-server-4rkroO9K.js} +1 -1
- package/dist/public/{shadow-claw-tasks-CnyiOt81.js → shadow-claw-tasks-BdP7lmvu.js} +3 -3
- package/dist/public/{shadow-claw-terminal-BC3RynHt.js → shadow-claw-terminal-DVHX7Fsu.js} +1 -1
- package/dist/public/{shadow-claw-toast-YjG--2Za.js → shadow-claw-toast-B9Y9tSkW.js} +1 -1
- package/dist/public/{shadow-claw-tools-Bbwk4vlT.js → shadow-claw-tools-BwwY53Lr.js} +1 -1
- package/dist/public/{shadow-claw-webvm-HZqzl2H5.js → shadow-claw-webvm-CXGdkCNM.js} +1 -1
- package/dist/public/{sync-web-mcp-registration-BaH2nAP0.js → sync-web-mcp-registration-DVK_IhXZ.js} +1 -1
- package/dist/public/{system-prompt-Dck3N8T0.js → system-prompt-BmswoQwF.js} +2 -2
- package/dist/public/{tools-DHA1dK2I.js → tools-D-52Zmfc.js} +1 -1
- package/dist/public/{transformers-C-DuTM2K.js → transformers-CQ9ss9rD.js} +1 -1
- package/dist/public/{upload-group-file-Cejr3zo1.js → upload-group-file-A8kB7lvO.js} +1 -1
- package/dist/public/{webmcp-CMRtu57-.js → webmcp-DIUZjVF5.js} +1 -1
- package/dist/public/{workbox-92eae37e.js → workbox-e4022e15.js} +1 -1
- package/dist/public/{write-group-file-CmJuVQNO.js → write-group-file-R67DjJ-q.js} +1 -1
- package/dist/public/{write-group-file-bytes-Cejr3zo1.js → write-group-file-bytes-A8kB7lvO.js} +1 -1
- package/dist/public/{zip-reader-CuQ13eLe.js → zip-reader-JHoTbATw.js} +1 -1
- package/dist/server.js +6 -6
- package/package.json +1 -1
- package/dist/cli/chunk-2gZFafgY.js +0 -1
- package/dist/cli/chunk-BFziiMKt.js +0 -7
- package/dist/cli/chunk-BM3llsxb.js +0 -1
- package/dist/cli/chunk-BUNoeMKY.js +0 -36
- package/dist/cli/chunk-Bj5qFsDi.js +0 -7
- package/dist/cli/chunk-Bj95zm-y.js +0 -1
- package/dist/cli/chunk-BpyP-esT.js +0 -1
- package/dist/cli/chunk-CX696s3_.js +0 -1
- package/dist/cli/chunk-DRxCrCAA.js +0 -139
- package/dist/cli/chunk-DjbCHa0h.js +0 -1
- package/dist/cli/chunk-Ds5-K-9o.js +0 -1
- package/dist/cli/chunk-DsQhAF31.js +0 -1
- package/dist/cli/chunk-VM-dECyG.js +0 -1
- package/dist/cli/chunk-gvNsvav0.js +0 -225
- package/dist/cli/chunk-heu2xRw1.js +0 -1
- package/dist/lib/orchestrator-i_QJ-o22.js.map +0 -1
- package/dist/lib/shadow-claw-DoQ7fgl5.js.map +0 -1
- package/dist/lib/system-prompt-DT_KeYaL.js.map +0 -1
- package/dist/public/app-routes-V_-URXc5.js +0 -1
- package/dist/public/attachment-capabilities-B6ibLwQB.js +0 -1
- package/dist/public/compact-context-CX4H8V57.js +0 -5
- package/dist/public/config-C-YdSFZB.js +0 -1
- package/dist/public/get-group-dir-DL44kvqW.js +0 -1
- package/dist/public/init-control-plane-BoJijVtf.js +0 -1
- package/dist/public/orchestrator-CaUpEVkQ.js +0 -63
- package/dist/public/provider-DNIL4-Hw.js +0 -1
- package/dist/public/shadow-claw-DdgeYPg5.js +0 -1176
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-template-BuuLY8l7.js","names":[],"sources":["../../node_modules/@huggingface/jinja/dist/index.js","../../src/subsystems/providers/utils/chat-template.ts"],"sourcesContent":["var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => {\n __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n return value;\n};\n\n// src/lexer.ts\nvar TOKEN_TYPES = Object.freeze({\n Text: \"Text\",\n // The text between Jinja statements or expressions\n NumericLiteral: \"NumericLiteral\",\n // e.g., 123, 1.0\n StringLiteral: \"StringLiteral\",\n // 'string'\n Identifier: \"Identifier\",\n // Variables, functions, statements, booleans, etc.\n Equals: \"Equals\",\n // =\n OpenParen: \"OpenParen\",\n // (\n CloseParen: \"CloseParen\",\n // )\n OpenStatement: \"OpenStatement\",\n // {%\n CloseStatement: \"CloseStatement\",\n // %}\n OpenExpression: \"OpenExpression\",\n // {{\n CloseExpression: \"CloseExpression\",\n // }}\n OpenSquareBracket: \"OpenSquareBracket\",\n // [\n CloseSquareBracket: \"CloseSquareBracket\",\n // ]\n OpenCurlyBracket: \"OpenCurlyBracket\",\n // {\n CloseCurlyBracket: \"CloseCurlyBracket\",\n // }\n Comma: \"Comma\",\n // ,\n Dot: \"Dot\",\n // .\n Colon: \"Colon\",\n // :\n Pipe: \"Pipe\",\n // |\n CallOperator: \"CallOperator\",\n // ()\n AdditiveBinaryOperator: \"AdditiveBinaryOperator\",\n // + - ~\n MultiplicativeBinaryOperator: \"MultiplicativeBinaryOperator\",\n // * / // %\n ExponentiationBinaryOperator: \"ExponentiationBinaryOperator\",\n // **\n ComparisonBinaryOperator: \"ComparisonBinaryOperator\",\n // < > <= >= == !=\n UnaryOperator: \"UnaryOperator\",\n // ! - +\n Comment: \"Comment\"\n // {# ... #}\n});\nvar Token = class {\n /**\n * Constructs a new Token.\n * @param {string} value The raw value as seen inside the source code.\n * @param {TokenType} type The type of token.\n */\n constructor(value, type) {\n this.value = value;\n this.type = type;\n }\n};\nfunction isWord(char) {\n return /\\w/.test(char);\n}\nfunction isInteger(char) {\n return /[0-9]/.test(char);\n}\nfunction isWhitespace(char) {\n return /\\s/.test(char);\n}\nvar ORDERED_MAPPING_TABLE = [\n // Control sequences\n [\"{%\", TOKEN_TYPES.OpenStatement],\n [\"%}\", TOKEN_TYPES.CloseStatement],\n [\"{{\", TOKEN_TYPES.OpenExpression],\n [\"}}\", TOKEN_TYPES.CloseExpression],\n // Single character tokens\n [\"(\", TOKEN_TYPES.OpenParen],\n [\")\", TOKEN_TYPES.CloseParen],\n [\"{\", TOKEN_TYPES.OpenCurlyBracket],\n [\"}\", TOKEN_TYPES.CloseCurlyBracket],\n [\"[\", TOKEN_TYPES.OpenSquareBracket],\n [\"]\", TOKEN_TYPES.CloseSquareBracket],\n [\",\", TOKEN_TYPES.Comma],\n [\".\", TOKEN_TYPES.Dot],\n [\":\", TOKEN_TYPES.Colon],\n [\"|\", TOKEN_TYPES.Pipe],\n // Comparison operators\n [\"<=\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\">=\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\"==\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\"!=\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\"<\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\">\", TOKEN_TYPES.ComparisonBinaryOperator],\n // Arithmetic operators\n [\"+\", TOKEN_TYPES.AdditiveBinaryOperator],\n [\"-\", TOKEN_TYPES.AdditiveBinaryOperator],\n [\"~\", TOKEN_TYPES.AdditiveBinaryOperator],\n [\"**\", TOKEN_TYPES.ExponentiationBinaryOperator],\n // NOTE: must come before \"*\" so that \"**\" is matched first\n [\"*\", TOKEN_TYPES.MultiplicativeBinaryOperator],\n [\"//\", TOKEN_TYPES.MultiplicativeBinaryOperator],\n // NOTE: must come before \"/\" so that \"//\" is matched first\n [\"/\", TOKEN_TYPES.MultiplicativeBinaryOperator],\n [\"%\", TOKEN_TYPES.MultiplicativeBinaryOperator],\n // Assignment operator\n [\"=\", TOKEN_TYPES.Equals]\n];\nvar ESCAPE_CHARACTERS = /* @__PURE__ */ new Map([\n [\"n\", \"\\n\"],\n // New line\n [\"t\", \"\t\"],\n // Horizontal tab\n [\"r\", \"\\r\"],\n // Carriage return\n [\"b\", \"\\b\"],\n // Backspace\n [\"f\", \"\\f\"],\n // Form feed\n [\"v\", \"\\v\"],\n // Vertical tab\n [\"'\", \"'\"],\n // Single quote\n ['\"', '\"'],\n // Double quote\n [\"\\\\\", \"\\\\\"]\n // Backslash\n]);\nfunction preprocess(template, options = {}) {\n if (template.endsWith(\"\\n\")) {\n template = template.slice(0, -1);\n }\n if (options.lstrip_blocks) {\n template = template.replace(/^[ \\t]*({[#%-])/gm, \"$1\");\n }\n if (options.trim_blocks) {\n template = template.replace(/([#%-]})\\n/g, \"$1\");\n }\n return template.replace(\n /(\\s*){%(-?)\\s*(?:end)?generation\\s*(-?)%}(\\s*)/gs,\n (_, before, lstrip, rstrip, after) => (lstrip ? \"\" : before) + (rstrip ? \"\" : after)\n );\n}\nfunction tokenize(source, options = {}) {\n const tokens = [];\n const src = preprocess(source, options);\n let cursorPosition = 0;\n let curlyBracketDepth = 0;\n const consumeWhile = (predicate) => {\n let str = \"\";\n while (predicate(src[cursorPosition])) {\n if (src[cursorPosition] === \"\\\\\") {\n ++cursorPosition;\n if (cursorPosition >= src.length) {\n throw new SyntaxError(\"Unexpected end of input\");\n }\n const escaped = src[cursorPosition++];\n const unescaped = ESCAPE_CHARACTERS.get(escaped);\n if (unescaped === void 0) {\n throw new SyntaxError(`Unexpected escaped character: ${escaped}`);\n }\n str += unescaped;\n continue;\n }\n str += src[cursorPosition++];\n if (cursorPosition >= src.length) {\n throw new SyntaxError(\"Unexpected end of input\");\n }\n }\n return str;\n };\n const stripTrailingWhitespace = () => {\n const lastToken = tokens.at(-1);\n if (lastToken && lastToken.type === TOKEN_TYPES.Text) {\n lastToken.value = lastToken.value.trimEnd();\n if (lastToken.value === \"\") {\n tokens.pop();\n }\n }\n };\n const skipLeadingWhitespace = () => {\n while (cursorPosition < src.length && isWhitespace(src[cursorPosition])) {\n ++cursorPosition;\n }\n };\n main:\n while (cursorPosition < src.length) {\n const lastTokenType = tokens.at(-1)?.type;\n if (lastTokenType === void 0 || lastTokenType === TOKEN_TYPES.CloseStatement || lastTokenType === TOKEN_TYPES.CloseExpression || lastTokenType === TOKEN_TYPES.Comment) {\n let text = \"\";\n while (cursorPosition < src.length && // Keep going until we hit the next Jinja statement or expression\n !(src[cursorPosition] === \"{\" && (src[cursorPosition + 1] === \"%\" || src[cursorPosition + 1] === \"{\" || src[cursorPosition + 1] === \"#\"))) {\n text += src[cursorPosition++];\n }\n if (text.length > 0) {\n tokens.push(new Token(text, TOKEN_TYPES.Text));\n continue;\n }\n }\n if (src[cursorPosition] === \"{\" && src[cursorPosition + 1] === \"#\") {\n cursorPosition += 2;\n const stripBefore = src[cursorPosition] === \"-\";\n if (stripBefore) {\n ++cursorPosition;\n }\n let comment = \"\";\n while (src[cursorPosition] !== \"#\" || src[cursorPosition + 1] !== \"}\") {\n if (cursorPosition + 2 >= src.length) {\n throw new SyntaxError(\"Missing end of comment tag\");\n }\n comment += src[cursorPosition++];\n }\n const stripAfter = comment.endsWith(\"-\");\n if (stripAfter) {\n comment = comment.slice(0, -1);\n }\n if (stripBefore) {\n stripTrailingWhitespace();\n }\n tokens.push(new Token(comment, TOKEN_TYPES.Comment));\n cursorPosition += 2;\n if (stripAfter) {\n skipLeadingWhitespace();\n }\n continue;\n }\n if (src.slice(cursorPosition, cursorPosition + 3) === \"{%-\") {\n stripTrailingWhitespace();\n tokens.push(new Token(\"{%\", TOKEN_TYPES.OpenStatement));\n cursorPosition += 3;\n continue;\n }\n if (src.slice(cursorPosition, cursorPosition + 3) === \"{{-\") {\n stripTrailingWhitespace();\n tokens.push(new Token(\"{{\", TOKEN_TYPES.OpenExpression));\n curlyBracketDepth = 0;\n cursorPosition += 3;\n continue;\n }\n consumeWhile(isWhitespace);\n if (src.slice(cursorPosition, cursorPosition + 3) === \"-%}\") {\n tokens.push(new Token(\"%}\", TOKEN_TYPES.CloseStatement));\n cursorPosition += 3;\n skipLeadingWhitespace();\n continue;\n }\n if (src.slice(cursorPosition, cursorPosition + 3) === \"-}}\") {\n tokens.push(new Token(\"}}\", TOKEN_TYPES.CloseExpression));\n cursorPosition += 3;\n skipLeadingWhitespace();\n continue;\n }\n const char = src[cursorPosition];\n if (char === \"-\" || char === \"+\") {\n const lastTokenType2 = tokens.at(-1)?.type;\n if (lastTokenType2 === TOKEN_TYPES.Text || lastTokenType2 === void 0) {\n throw new SyntaxError(`Unexpected character: ${char}`);\n }\n switch (lastTokenType2) {\n case TOKEN_TYPES.Identifier:\n case TOKEN_TYPES.NumericLiteral:\n case TOKEN_TYPES.StringLiteral:\n case TOKEN_TYPES.CloseParen:\n case TOKEN_TYPES.CloseSquareBracket:\n break;\n default: {\n ++cursorPosition;\n let num = consumeWhile(isInteger);\n if (num.length > 0 && src[cursorPosition] === \".\" && isInteger(src[cursorPosition + 1])) {\n ++cursorPosition;\n const frac = consumeWhile(isInteger);\n num = `${num}.${frac}`;\n }\n tokens.push(\n new Token(`${char}${num}`, num.length > 0 ? TOKEN_TYPES.NumericLiteral : TOKEN_TYPES.UnaryOperator)\n );\n continue;\n }\n }\n }\n for (const [seq, type] of ORDERED_MAPPING_TABLE) {\n if (seq === \"}}\" && curlyBracketDepth > 0) {\n continue;\n }\n const slice2 = src.slice(cursorPosition, cursorPosition + seq.length);\n if (slice2 === seq) {\n tokens.push(new Token(seq, type));\n if (type === TOKEN_TYPES.OpenExpression) {\n curlyBracketDepth = 0;\n } else if (type === TOKEN_TYPES.OpenCurlyBracket) {\n ++curlyBracketDepth;\n } else if (type === TOKEN_TYPES.CloseCurlyBracket) {\n --curlyBracketDepth;\n }\n cursorPosition += seq.length;\n continue main;\n }\n }\n if (char === \"'\" || char === '\"') {\n ++cursorPosition;\n const str = consumeWhile((c) => c !== char);\n tokens.push(new Token(str, TOKEN_TYPES.StringLiteral));\n ++cursorPosition;\n continue;\n }\n if (isInteger(char)) {\n let num = consumeWhile(isInteger);\n if (tokens.at(-1)?.type !== TOKEN_TYPES.Dot && src[cursorPosition] === \".\" && isInteger(src[cursorPosition + 1])) {\n ++cursorPosition;\n const frac = consumeWhile(isInteger);\n num = `${num}.${frac}`;\n }\n tokens.push(new Token(num, TOKEN_TYPES.NumericLiteral));\n continue;\n }\n if (isWord(char)) {\n const word = consumeWhile(isWord);\n tokens.push(new Token(word, TOKEN_TYPES.Identifier));\n continue;\n }\n throw new SyntaxError(`Unexpected character: ${char}`);\n }\n return tokens;\n}\n\n// src/ast.ts\nvar Statement = class {\n type = \"Statement\";\n};\nvar Program = class extends Statement {\n constructor(body) {\n super();\n this.body = body;\n }\n type = \"Program\";\n};\nvar If = class extends Statement {\n constructor(test, body, alternate) {\n super();\n this.test = test;\n this.body = body;\n this.alternate = alternate;\n }\n type = \"If\";\n};\nvar For = class extends Statement {\n constructor(loopvar, iterable, body, defaultBlock) {\n super();\n this.loopvar = loopvar;\n this.iterable = iterable;\n this.body = body;\n this.defaultBlock = defaultBlock;\n }\n type = \"For\";\n};\nvar Break = class extends Statement {\n type = \"Break\";\n};\nvar Continue = class extends Statement {\n type = \"Continue\";\n};\nvar SetStatement = class extends Statement {\n constructor(assignee, value, body) {\n super();\n this.assignee = assignee;\n this.value = value;\n this.body = body;\n }\n type = \"Set\";\n};\nvar Macro = class extends Statement {\n constructor(name, args, body) {\n super();\n this.name = name;\n this.args = args;\n this.body = body;\n }\n type = \"Macro\";\n};\nvar Comment = class extends Statement {\n constructor(value) {\n super();\n this.value = value;\n }\n type = \"Comment\";\n};\nvar Expression = class extends Statement {\n type = \"Expression\";\n};\nvar MemberExpression = class extends Expression {\n constructor(object, property, computed) {\n super();\n this.object = object;\n this.property = property;\n this.computed = computed;\n }\n type = \"MemberExpression\";\n};\nvar CallExpression = class extends Expression {\n constructor(callee, args) {\n super();\n this.callee = callee;\n this.args = args;\n }\n type = \"CallExpression\";\n};\nvar Identifier = class extends Expression {\n /**\n * @param {string} value The name of the identifier\n */\n constructor(value) {\n super();\n this.value = value;\n }\n type = \"Identifier\";\n};\nvar Literal = class extends Expression {\n constructor(value) {\n super();\n this.value = value;\n }\n type = \"Literal\";\n};\nvar IntegerLiteral = class extends Literal {\n type = \"IntegerLiteral\";\n};\nvar FloatLiteral = class extends Literal {\n type = \"FloatLiteral\";\n};\nvar StringLiteral = class extends Literal {\n type = \"StringLiteral\";\n};\nvar ArrayLiteral = class extends Literal {\n type = \"ArrayLiteral\";\n};\nvar TupleLiteral = class extends Literal {\n type = \"TupleLiteral\";\n};\nvar ObjectLiteral = class extends Literal {\n type = \"ObjectLiteral\";\n};\nvar BinaryExpression = class extends Expression {\n constructor(operator, left, right) {\n super();\n this.operator = operator;\n this.left = left;\n this.right = right;\n }\n type = \"BinaryExpression\";\n};\nvar FilterExpression = class extends Expression {\n constructor(operand, filter) {\n super();\n this.operand = operand;\n this.filter = filter;\n }\n type = \"FilterExpression\";\n};\nvar FilterStatement = class extends Statement {\n constructor(filter, body) {\n super();\n this.filter = filter;\n this.body = body;\n }\n type = \"FilterStatement\";\n};\nvar SelectExpression = class extends Expression {\n constructor(lhs, test) {\n super();\n this.lhs = lhs;\n this.test = test;\n }\n type = \"SelectExpression\";\n};\nvar TestExpression = class extends Expression {\n constructor(operand, negate, test) {\n super();\n this.operand = operand;\n this.negate = negate;\n this.test = test;\n }\n type = \"TestExpression\";\n};\nvar UnaryExpression = class extends Expression {\n constructor(operator, argument) {\n super();\n this.operator = operator;\n this.argument = argument;\n }\n type = \"UnaryExpression\";\n};\nvar SliceExpression = class extends Expression {\n constructor(start = void 0, stop = void 0, step = void 0) {\n super();\n this.start = start;\n this.stop = stop;\n this.step = step;\n }\n type = \"SliceExpression\";\n};\nvar KeywordArgumentExpression = class extends Expression {\n constructor(key, value) {\n super();\n this.key = key;\n this.value = value;\n }\n type = \"KeywordArgumentExpression\";\n};\nvar SpreadExpression = class extends Expression {\n constructor(argument) {\n super();\n this.argument = argument;\n }\n type = \"SpreadExpression\";\n};\nvar KeywordSpreadExpression = class extends Expression {\n constructor(argument) {\n super();\n this.argument = argument;\n }\n type = \"KeywordSpreadExpression\";\n};\nvar CallStatement = class extends Statement {\n constructor(call, callerArgs, body) {\n super();\n this.call = call;\n this.callerArgs = callerArgs;\n this.body = body;\n }\n type = \"CallStatement\";\n};\nvar Ternary = class extends Expression {\n constructor(condition, trueExpr, falseExpr) {\n super();\n this.condition = condition;\n this.trueExpr = trueExpr;\n this.falseExpr = falseExpr;\n }\n type = \"Ternary\";\n};\n\n// src/parser.ts\nfunction parse(tokens) {\n const program = new Program([]);\n let current = 0;\n function expect(type, error) {\n const prev = tokens[current++];\n if (!prev || prev.type !== type) {\n throw new Error(`Parser Error: ${error}. ${prev.type} !== ${type}.`);\n }\n return prev;\n }\n function expectIdentifier(name) {\n if (!isIdentifier(name)) {\n throw new SyntaxError(`Expected ${name}`);\n }\n ++current;\n }\n function parseAny() {\n switch (tokens[current].type) {\n case TOKEN_TYPES.Comment:\n return new Comment(tokens[current++].value);\n case TOKEN_TYPES.Text:\n return parseText();\n case TOKEN_TYPES.OpenStatement:\n return parseJinjaStatement();\n case TOKEN_TYPES.OpenExpression:\n return parseJinjaExpression();\n default:\n throw new SyntaxError(`Unexpected token type: ${tokens[current].type}`);\n }\n }\n function is(...types) {\n return current + types.length <= tokens.length && types.every((type, i) => type === tokens[current + i].type);\n }\n function isStatement(...names) {\n return tokens[current]?.type === TOKEN_TYPES.OpenStatement && tokens[current + 1]?.type === TOKEN_TYPES.Identifier && names.includes(tokens[current + 1]?.value);\n }\n function isIdentifier(...names) {\n return current + names.length <= tokens.length && names.every((name, i) => tokens[current + i].type === \"Identifier\" && name === tokens[current + i].value);\n }\n function parseText() {\n return new StringLiteral(expect(TOKEN_TYPES.Text, \"Expected text token\").value);\n }\n function parseJinjaStatement() {\n expect(TOKEN_TYPES.OpenStatement, \"Expected opening statement token\");\n if (tokens[current].type !== TOKEN_TYPES.Identifier) {\n throw new SyntaxError(`Unknown statement, got ${tokens[current].type}`);\n }\n const name = tokens[current].value;\n let result;\n switch (name) {\n case \"set\":\n ++current;\n result = parseSetStatement();\n break;\n case \"if\":\n ++current;\n result = parseIfStatement();\n expect(TOKEN_TYPES.OpenStatement, \"Expected {% token\");\n expectIdentifier(\"endif\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected %} token\");\n break;\n case \"macro\":\n ++current;\n result = parseMacroStatement();\n expect(TOKEN_TYPES.OpenStatement, \"Expected {% token\");\n expectIdentifier(\"endmacro\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected %} token\");\n break;\n case \"for\":\n ++current;\n result = parseForStatement();\n expect(TOKEN_TYPES.OpenStatement, \"Expected {% token\");\n expectIdentifier(\"endfor\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected %} token\");\n break;\n case \"call\": {\n ++current;\n let callerArgs = null;\n if (is(TOKEN_TYPES.OpenParen)) {\n callerArgs = parseArgs(\"parameters\");\n }\n const callee = parsePrimaryExpression();\n if (callee.type !== \"Identifier\") {\n throw new SyntaxError(`Expected identifier following call statement`);\n }\n const callArgs = parseArgs(\"call\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const body = [];\n while (!isStatement(\"endcall\")) {\n body.push(parseAny());\n }\n expect(TOKEN_TYPES.OpenStatement, \"Expected '{%'\");\n expectIdentifier(\"endcall\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const callExpr = new CallExpression(callee, callArgs);\n result = new CallStatement(callExpr, callerArgs, body);\n break;\n }\n case \"break\":\n ++current;\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n result = new Break();\n break;\n case \"continue\":\n ++current;\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n result = new Continue();\n break;\n case \"filter\": {\n ++current;\n let filterNode = parsePrimaryExpression();\n if (filterNode instanceof Identifier && is(TOKEN_TYPES.OpenParen)) {\n filterNode = parseCallExpression(filterNode);\n }\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const filterBody = [];\n while (!isStatement(\"endfilter\")) {\n filterBody.push(parseAny());\n }\n expect(TOKEN_TYPES.OpenStatement, \"Expected '{%'\");\n expectIdentifier(\"endfilter\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected '%}'\");\n result = new FilterStatement(filterNode, filterBody);\n break;\n }\n default:\n throw new SyntaxError(`Unknown statement type: ${name}`);\n }\n return result;\n }\n function parseJinjaExpression() {\n expect(TOKEN_TYPES.OpenExpression, \"Expected opening expression token\");\n const result = parseExpression();\n expect(TOKEN_TYPES.CloseExpression, \"Expected closing expression token\");\n return result;\n }\n function parseSetStatement() {\n const left = parseExpressionSequence();\n let value = null;\n const body = [];\n if (is(TOKEN_TYPES.Equals)) {\n ++current;\n value = parseExpressionSequence();\n } else {\n expect(TOKEN_TYPES.CloseStatement, \"Expected %} token\");\n while (!isStatement(\"endset\")) {\n body.push(parseAny());\n }\n expect(TOKEN_TYPES.OpenStatement, \"Expected {% token\");\n expectIdentifier(\"endset\");\n }\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n return new SetStatement(left, value, body);\n }\n function parseIfStatement() {\n const test = parseExpression();\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const body = [];\n const alternate = [];\n while (!isStatement(\"elif\", \"else\", \"endif\")) {\n body.push(parseAny());\n }\n if (isStatement(\"elif\")) {\n ++current;\n ++current;\n const result = parseIfStatement();\n alternate.push(result);\n } else if (isStatement(\"else\")) {\n ++current;\n ++current;\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n while (!isStatement(\"endif\")) {\n alternate.push(parseAny());\n }\n }\n return new If(test, body, alternate);\n }\n function parseMacroStatement() {\n const name = parsePrimaryExpression();\n if (name.type !== \"Identifier\") {\n throw new SyntaxError(`Expected identifier following macro statement`);\n }\n const args = parseArgs(\"parameters\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const body = [];\n while (!isStatement(\"endmacro\")) {\n body.push(parseAny());\n }\n return new Macro(name, args, body);\n }\n function parseExpressionSequence(primary = false) {\n const fn = primary ? parsePrimaryExpression : parseExpression;\n const expressions = [fn()];\n const isTuple = is(TOKEN_TYPES.Comma);\n while (isTuple) {\n ++current;\n expressions.push(fn());\n if (!is(TOKEN_TYPES.Comma)) {\n break;\n }\n }\n return isTuple ? new TupleLiteral(expressions) : expressions[0];\n }\n function parseForStatement() {\n const loopVariable = parseExpressionSequence(true);\n if (!(loopVariable instanceof Identifier || loopVariable instanceof TupleLiteral)) {\n throw new SyntaxError(`Expected identifier/tuple for the loop variable, got ${loopVariable.type} instead`);\n }\n if (!isIdentifier(\"in\")) {\n throw new SyntaxError(\"Expected `in` keyword following loop variable\");\n }\n ++current;\n const iterable = parseExpression();\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const body = [];\n while (!isStatement(\"endfor\", \"else\")) {\n body.push(parseAny());\n }\n const alternative = [];\n if (isStatement(\"else\")) {\n ++current;\n ++current;\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n while (!isStatement(\"endfor\")) {\n alternative.push(parseAny());\n }\n }\n return new For(loopVariable, iterable, body, alternative);\n }\n function parseExpression() {\n return parseIfExpression();\n }\n function parseIfExpression() {\n const a = parseLogicalOrExpression();\n if (isIdentifier(\"if\")) {\n ++current;\n const test = parseLogicalOrExpression();\n if (isIdentifier(\"else\")) {\n ++current;\n const falseExpr = parseIfExpression();\n return new Ternary(test, a, falseExpr);\n } else {\n return new SelectExpression(a, test);\n }\n }\n return a;\n }\n function parseLogicalOrExpression() {\n let left = parseLogicalAndExpression();\n while (isIdentifier(\"or\")) {\n const operator = tokens[current];\n ++current;\n const right = parseLogicalAndExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseLogicalAndExpression() {\n let left = parseLogicalNegationExpression();\n while (isIdentifier(\"and\")) {\n const operator = tokens[current];\n ++current;\n const right = parseLogicalNegationExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseLogicalNegationExpression() {\n let right;\n while (isIdentifier(\"not\")) {\n const operator = tokens[current];\n ++current;\n const arg = parseLogicalNegationExpression();\n right = new UnaryExpression(operator, arg);\n }\n return right ?? parseComparisonExpression();\n }\n function parseComparisonExpression() {\n let left = parseAdditiveExpression();\n while (true) {\n let operator;\n if (isIdentifier(\"not\", \"in\")) {\n operator = new Token(\"not in\", TOKEN_TYPES.Identifier);\n current += 2;\n } else if (isIdentifier(\"in\")) {\n operator = tokens[current++];\n } else if (is(TOKEN_TYPES.ComparisonBinaryOperator)) {\n operator = tokens[current++];\n } else {\n break;\n }\n const right = parseAdditiveExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseAdditiveExpression() {\n let left = parseMultiplicativeExpression();\n while (is(TOKEN_TYPES.AdditiveBinaryOperator)) {\n const operator = tokens[current];\n ++current;\n const right = parseMultiplicativeExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseCallMemberExpression() {\n const member = parseMemberExpression(parsePrimaryExpression());\n if (is(TOKEN_TYPES.OpenParen)) {\n return parseCallExpression(member);\n }\n return member;\n }\n function parseCallExpression(callee) {\n let expression = new CallExpression(callee, parseArgs(\"call\"));\n expression = parseMemberExpression(expression);\n if (is(TOKEN_TYPES.OpenParen)) {\n expression = parseCallExpression(expression);\n }\n return expression;\n }\n function parseArgs(mode) {\n expect(TOKEN_TYPES.OpenParen, \"Expected opening parenthesis for arguments list\");\n const args = parseArgumentsList(mode);\n expect(TOKEN_TYPES.CloseParen, \"Expected closing parenthesis for arguments list\");\n return args;\n }\n function parseArgumentsList(mode) {\n const args = [];\n const parameterNames = /* @__PURE__ */ new Set();\n let sawKeywordOrDefault = false;\n let sawSpreadArgument = false;\n while (!is(TOKEN_TYPES.CloseParen)) {\n const isKeywordSpread = is(TOKEN_TYPES.ExponentiationBinaryOperator);\n const isPositionalSpread = is(TOKEN_TYPES.MultiplicativeBinaryOperator) && tokens[current].value === \"*\";\n if (mode === \"parameters\" && (isKeywordSpread || isPositionalSpread)) {\n throw new SyntaxError(\"Argument unpacking is not allowed in parameter declarations\");\n }\n if (isKeywordSpread) {\n ++current;\n args.push(new KeywordSpreadExpression(parseExpression()));\n if (is(TOKEN_TYPES.Comma)) {\n ++current;\n }\n if (!is(TOKEN_TYPES.CloseParen)) {\n throw new SyntaxError(\"Expected closing parenthesis: `**` must be applied to the final argument\");\n }\n break;\n }\n let argument;\n if (isPositionalSpread) {\n if (sawSpreadArgument) {\n throw new SyntaxError(\"Only one `*` argument unpacking is allowed\");\n }\n sawSpreadArgument = true;\n ++current;\n const expr = parseExpression();\n argument = new SpreadExpression(expr);\n } else {\n argument = parseExpression();\n if (is(TOKEN_TYPES.Equals)) {\n ++current;\n if (!(argument instanceof Identifier)) {\n throw new SyntaxError(\n mode === \"parameters\" ? \"Expected identifier for parameter declaration\" : \"Expected identifier for keyword argument\"\n );\n }\n const value = parseExpression();\n argument = new KeywordArgumentExpression(argument, value);\n }\n if (mode === \"parameters\") {\n if (!(argument instanceof Identifier || argument instanceof KeywordArgumentExpression)) {\n throw new SyntaxError(\"Expected identifier for parameter declaration\");\n }\n const parameterName = argument instanceof Identifier ? argument.value : argument.key.value;\n if (parameterNames.has(parameterName)) {\n throw new SyntaxError(`Duplicate parameter name: ${parameterName}`);\n }\n parameterNames.add(parameterName);\n }\n if (argument instanceof KeywordArgumentExpression) {\n sawKeywordOrDefault = true;\n } else if (sawKeywordOrDefault) {\n throw new SyntaxError(\n mode === \"call\" ? \"Positional arguments must come before keyword arguments\" : \"Non-default argument follows default argument\"\n );\n } else if (sawSpreadArgument) {\n throw new SyntaxError(\"Positional arguments must not follow `*` argument unpacking\");\n }\n }\n args.push(argument);\n if (is(TOKEN_TYPES.Comma)) {\n ++current;\n }\n }\n return args;\n }\n function parseMemberExpressionArgumentsList() {\n const slices = [];\n let isSlice = false;\n while (!is(TOKEN_TYPES.CloseSquareBracket)) {\n if (is(TOKEN_TYPES.Colon)) {\n slices.push(void 0);\n ++current;\n isSlice = true;\n } else {\n slices.push(parseExpression());\n if (is(TOKEN_TYPES.Colon)) {\n ++current;\n isSlice = true;\n }\n }\n }\n if (slices.length === 0) {\n throw new SyntaxError(`Expected at least one argument for member/slice expression`);\n }\n if (isSlice) {\n if (slices.length > 3) {\n throw new SyntaxError(`Expected 0-3 arguments for slice expression`);\n }\n return new SliceExpression(...slices);\n }\n return slices[0];\n }\n function parseMemberExpression(object) {\n while (is(TOKEN_TYPES.Dot) || is(TOKEN_TYPES.OpenSquareBracket)) {\n const operator = tokens[current];\n ++current;\n let property;\n const computed = operator.type === TOKEN_TYPES.OpenSquareBracket;\n if (computed) {\n property = parseMemberExpressionArgumentsList();\n expect(TOKEN_TYPES.CloseSquareBracket, \"Expected closing square bracket\");\n } else {\n property = parsePrimaryExpression();\n if (property.type !== \"Identifier\" && property.type !== \"IntegerLiteral\") {\n throw new SyntaxError(`Expected identifier or integer following dot operator`);\n }\n }\n object = new MemberExpression(object, property, computed);\n }\n return object;\n }\n function parseMultiplicativeExpression() {\n let left = parsePowerExpression();\n while (is(TOKEN_TYPES.MultiplicativeBinaryOperator)) {\n const operator = tokens[current++];\n const right = parsePowerExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parsePowerExpression() {\n let left = parseTestExpression();\n while (is(TOKEN_TYPES.ExponentiationBinaryOperator)) {\n const operator = tokens[current++];\n const right = parseTestExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseTestExpression() {\n let operand = parseFilterExpression();\n while (isIdentifier(\"is\")) {\n ++current;\n const negate = isIdentifier(\"not\");\n if (negate) {\n ++current;\n }\n const filter = parsePrimaryExpression();\n if (!(filter instanceof Identifier)) {\n throw new SyntaxError(`Expected identifier for the test`);\n }\n operand = new TestExpression(operand, negate, filter);\n }\n return operand;\n }\n function parseFilterExpression() {\n let operand = parseUnarySignExpression();\n while (is(TOKEN_TYPES.Pipe)) {\n ++current;\n let filter = parsePrimaryExpression();\n if (!(filter instanceof Identifier)) {\n throw new SyntaxError(`Expected identifier for the filter`);\n }\n if (is(TOKEN_TYPES.OpenParen)) {\n filter = parseCallExpression(filter);\n }\n operand = new FilterExpression(operand, filter);\n }\n return operand;\n }\n function parseUnarySignExpression() {\n const token = tokens[current];\n if (token && (token.type === TOKEN_TYPES.UnaryOperator || token.type === TOKEN_TYPES.AdditiveBinaryOperator) && (token.value === \"-\" || token.value === \"+\")) {\n const operator = tokens[current++];\n const argument = parseUnarySignExpression();\n return new UnaryExpression(operator, argument);\n }\n return parseCallMemberExpression();\n }\n function parsePrimaryExpression() {\n const token = tokens[current++];\n switch (token.type) {\n case TOKEN_TYPES.NumericLiteral: {\n const num = token.value;\n return num.includes(\".\") ? new FloatLiteral(Number(num)) : new IntegerLiteral(Number(num));\n }\n case TOKEN_TYPES.StringLiteral: {\n let value = token.value;\n while (is(TOKEN_TYPES.StringLiteral)) {\n value += tokens[current++].value;\n }\n return new StringLiteral(value);\n }\n case TOKEN_TYPES.Identifier:\n return new Identifier(token.value);\n case TOKEN_TYPES.OpenParen: {\n const expression = parseExpressionSequence();\n expect(TOKEN_TYPES.CloseParen, \"Expected closing parenthesis, got ${tokens[current].type} instead.\");\n return expression;\n }\n case TOKEN_TYPES.OpenSquareBracket: {\n const values = [];\n while (!is(TOKEN_TYPES.CloseSquareBracket)) {\n values.push(parseExpression());\n if (is(TOKEN_TYPES.Comma)) {\n ++current;\n }\n }\n ++current;\n return new ArrayLiteral(values);\n }\n case TOKEN_TYPES.OpenCurlyBracket: {\n const values = /* @__PURE__ */ new Map();\n while (!is(TOKEN_TYPES.CloseCurlyBracket)) {\n const key = parseExpression();\n expect(TOKEN_TYPES.Colon, \"Expected colon between key and value in object literal\");\n const value = parseExpression();\n values.set(key, value);\n if (is(TOKEN_TYPES.Comma)) {\n ++current;\n }\n }\n ++current;\n return new ObjectLiteral(values);\n }\n default:\n throw new SyntaxError(`Unexpected token: ${token.type}`);\n }\n }\n while (current < tokens.length) {\n program.body.push(parseAny());\n }\n return program;\n}\n\n// src/utils.ts\nfunction range(start, stop, step = 1) {\n if (stop === void 0) {\n stop = start;\n start = 0;\n }\n if (step === 0) {\n throw new Error(\"range() step must not be zero\");\n }\n const result = [];\n if (step > 0) {\n for (let i = start; i < stop; i += step) {\n result.push(i);\n }\n } else {\n for (let i = start; i > stop; i += step) {\n result.push(i);\n }\n }\n return result;\n}\nfunction slice(array, start, stop, step = 1) {\n const direction = Math.sign(step);\n if (direction >= 0) {\n start = (start ??= 0) < 0 ? Math.max(array.length + start, 0) : Math.min(start, array.length);\n stop = (stop ??= array.length) < 0 ? Math.max(array.length + stop, 0) : Math.min(stop, array.length);\n } else {\n start = (start ??= array.length - 1) < 0 ? Math.max(array.length + start, -1) : Math.min(start, array.length - 1);\n stop = (stop ??= -1) < -1 ? Math.max(array.length + stop, -1) : Math.min(stop, array.length - 1);\n }\n const result = [];\n for (let i = start; direction * i < direction * stop; i += step) {\n result.push(array[i]);\n }\n return result;\n}\nfunction titleCase(value) {\n return value.replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\nfunction strftime_now(format2) {\n return strftime(/* @__PURE__ */ new Date(), format2);\n}\nfunction strftime(date, format2) {\n const monthFormatterLong = new Intl.DateTimeFormat(void 0, { month: \"long\" });\n const monthFormatterShort = new Intl.DateTimeFormat(void 0, { month: \"short\" });\n const pad2 = (n) => n < 10 ? \"0\" + n : n.toString();\n return format2.replace(/%[YmdbBHM%]/g, (token) => {\n switch (token) {\n case \"%Y\":\n return date.getFullYear().toString();\n case \"%m\":\n return pad2(date.getMonth() + 1);\n case \"%d\":\n return pad2(date.getDate());\n case \"%b\":\n return monthFormatterShort.format(date);\n case \"%B\":\n return monthFormatterLong.format(date);\n case \"%H\":\n return pad2(date.getHours());\n case \"%M\":\n return pad2(date.getMinutes());\n case \"%%\":\n return \"%\";\n default:\n return token;\n }\n });\n}\nfunction escapeRegExp(s) {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\nfunction replace(str, oldvalue, newvalue, count) {\n if (count === 0) {\n return str;\n }\n let remaining = count == null || count < 0 ? Infinity : count;\n const pattern = oldvalue.length === 0 ? new RegExp(\"(?=)\", \"gu\") : new RegExp(escapeRegExp(oldvalue), \"gu\");\n return str.replaceAll(pattern, (match) => {\n if (remaining > 0) {\n --remaining;\n return newvalue;\n }\n return match;\n });\n}\n\n// src/runtime.ts\nvar BreakControl = class extends Error {\n};\nvar ContinueControl = class extends Error {\n};\nvar EMPTY_BUILTINS = /* @__PURE__ */ new Map();\nvar RuntimeValue = class {\n type = \"RuntimeValue\";\n value;\n /**\n * A collection of built-in functions for this type.\n */\n get builtins() {\n return EMPTY_BUILTINS;\n }\n /**\n * Creates a new RuntimeValue.\n */\n constructor(value = void 0) {\n this.value = value;\n }\n /**\n * Determines truthiness or falsiness of the runtime value.\n * This function should be overridden by subclasses if it has custom truthiness criteria.\n * @returns {BooleanValue} BooleanValue(true) if the value is truthy, BooleanValue(false) otherwise.\n */\n __bool__() {\n return new BooleanValue(!!this.value);\n }\n toString() {\n return String(this.value);\n }\n};\nvar IntegerValue = class extends RuntimeValue {\n type = \"IntegerValue\";\n};\nvar FloatValue = class extends RuntimeValue {\n type = \"FloatValue\";\n toString() {\n if (Object.is(this.value, -0)) {\n return \"-0.0\";\n }\n return this.value % 1 === 0 ? this.value.toFixed(1) : this.value.toString();\n }\n};\nvar StringValue = class extends RuntimeValue {\n type = \"StringValue\";\n _builtins;\n get builtins() {\n return this._builtins ??= /* @__PURE__ */ new Map([\n [\n \"upper\",\n new FunctionValue(() => {\n return new StringValue(this.value.toUpperCase());\n })\n ],\n [\n \"lower\",\n new FunctionValue(() => {\n return new StringValue(this.value.toLowerCase());\n })\n ],\n [\n \"strip\",\n new FunctionValue(() => {\n return new StringValue(this.value.trim());\n })\n ],\n [\n \"title\",\n new FunctionValue(() => {\n return new StringValue(titleCase(this.value));\n })\n ],\n [\n \"capitalize\",\n new FunctionValue(() => {\n return new StringValue(this.value.charAt(0).toUpperCase() + this.value.slice(1));\n })\n ],\n [\"length\", new IntegerValue(this.value.length)],\n [\n \"rstrip\",\n new FunctionValue(() => {\n return new StringValue(this.value.trimEnd());\n })\n ],\n [\n \"lstrip\",\n new FunctionValue(() => {\n return new StringValue(this.value.trimStart());\n })\n ],\n [\n \"startswith\",\n new FunctionValue((args) => {\n if (args.length === 0) {\n throw new Error(\"startswith() requires at least one argument\");\n }\n const pattern = args[0];\n if (pattern instanceof StringValue) {\n return new BooleanValue(this.value.startsWith(pattern.value));\n } else if (pattern instanceof ArrayValue) {\n for (const item of pattern.value) {\n if (!(item instanceof StringValue)) {\n throw new Error(\"startswith() tuple elements must be strings\");\n }\n if (this.value.startsWith(item.value)) {\n return new BooleanValue(true);\n }\n }\n return new BooleanValue(false);\n }\n throw new Error(\"startswith() argument must be a string or tuple of strings\");\n })\n ],\n [\n \"endswith\",\n new FunctionValue((args) => {\n if (args.length === 0) {\n throw new Error(\"endswith() requires at least one argument\");\n }\n const pattern = args[0];\n if (pattern instanceof StringValue) {\n return new BooleanValue(this.value.endsWith(pattern.value));\n } else if (pattern instanceof ArrayValue) {\n for (const item of pattern.value) {\n if (!(item instanceof StringValue)) {\n throw new Error(\"endswith() tuple elements must be strings\");\n }\n if (this.value.endsWith(item.value)) {\n return new BooleanValue(true);\n }\n }\n return new BooleanValue(false);\n }\n throw new Error(\"endswith() argument must be a string or tuple of strings\");\n })\n ],\n [\n \"split\",\n // follows Python's `str.split(sep=None, maxsplit=-1)` function behavior\n // https://docs.python.org/3.13/library/stdtypes.html#str.split\n new FunctionValue((args) => {\n const sep = args[0] ?? new NullValue();\n if (!(sep instanceof StringValue || sep instanceof NullValue)) {\n throw new Error(\"sep argument must be a string or null\");\n }\n const maxsplit = args[1] ?? new IntegerValue(-1);\n if (!(maxsplit instanceof IntegerValue)) {\n throw new Error(\"maxsplit argument must be a number\");\n }\n let result = [];\n if (sep instanceof NullValue) {\n const text = this.value.trimStart();\n for (const { 0: match, index } of text.matchAll(/\\S+/g)) {\n if (maxsplit.value !== -1 && result.length >= maxsplit.value && index !== void 0) {\n result.push(match + text.slice(index + match.length));\n break;\n }\n result.push(match);\n }\n } else {\n if (sep.value === \"\") {\n throw new Error(\"empty separator\");\n }\n result = this.value.split(sep.value);\n if (maxsplit.value !== -1 && result.length > maxsplit.value) {\n result.push(result.splice(maxsplit.value).join(sep.value));\n }\n }\n return new ArrayValue(result.map((part) => new StringValue(part)));\n })\n ],\n [\n \"replace\",\n new FunctionValue((args) => {\n if (args.length < 2) {\n throw new Error(\"replace() requires at least two arguments\");\n }\n const oldValue = args[0];\n const newValue = args[1];\n if (!(oldValue instanceof StringValue && newValue instanceof StringValue)) {\n throw new Error(\"replace() arguments must be strings\");\n }\n let count;\n if (args.length > 2) {\n if (args[2].type === \"KeywordArgumentsValue\") {\n count = args[2].value.get(\"count\") ?? new NullValue();\n } else {\n count = args[2];\n }\n } else {\n count = new NullValue();\n }\n if (!(count instanceof IntegerValue || count instanceof NullValue)) {\n throw new Error(\"replace() count argument must be a number or null\");\n }\n return new StringValue(replace(this.value, oldValue.value, newValue.value, count.value));\n })\n ]\n ]);\n }\n};\nvar BooleanValue = class extends RuntimeValue {\n type = \"BooleanValue\";\n};\nvar NON_ASCII_CHARS = /[\\x7f-\\uffff]/g;\nfunction makeAsciiSafe(str) {\n return str.replace(NON_ASCII_CHARS, (char) => \"\\\\u\" + char.charCodeAt(0).toString(16).padStart(4, \"0\"));\n}\nfunction toJSON(input, options = {}, depth = 0, convertUndefinedToNull = true) {\n const { indent = null, ensureAscii = false, separators = null, sortKeys = false } = options;\n let itemSeparator;\n let keySeparator;\n if (separators) {\n [itemSeparator, keySeparator] = separators;\n } else if (indent) {\n itemSeparator = \",\";\n keySeparator = \": \";\n } else {\n itemSeparator = \", \";\n keySeparator = \": \";\n }\n switch (input.type) {\n case \"NullValue\":\n return \"null\";\n case \"UndefinedValue\":\n return convertUndefinedToNull ? \"null\" : \"undefined\";\n case \"IntegerValue\":\n case \"FloatValue\":\n case \"BooleanValue\":\n return JSON.stringify(input.value);\n case \"StringValue\": {\n let result = JSON.stringify(input.value);\n if (ensureAscii) {\n result = makeAsciiSafe(result);\n }\n return result;\n }\n case \"ArrayValue\":\n case \"NamespaceValue\":\n case \"ObjectValue\": {\n const indentValue = indent ? \" \".repeat(indent) : \"\";\n const basePadding = \"\\n\" + indentValue.repeat(depth);\n const childrenPadding = basePadding + indentValue;\n if (input.type === \"ArrayValue\") {\n const core = input.value.map((x) => toJSON(x, options, depth + 1, convertUndefinedToNull));\n return indent ? `[${childrenPadding}${core.join(`${itemSeparator}${childrenPadding}`)}${basePadding}]` : `[${core.join(itemSeparator)}]`;\n } else {\n let entries = Array.from(input.value.entries());\n if (sortKeys) {\n entries = entries.sort(([a], [b]) => a.localeCompare(b));\n }\n const core = entries.map(([key, value]) => {\n let keyStr = JSON.stringify(key);\n if (ensureAscii) {\n keyStr = makeAsciiSafe(keyStr);\n }\n const v = `${keyStr}${keySeparator}${toJSON(value, options, depth + 1, convertUndefinedToNull)}`;\n return indent ? `${childrenPadding}${v}` : v;\n });\n return indent ? `{${core.join(itemSeparator)}${basePadding}}` : `{${core.join(itemSeparator)}}`;\n }\n }\n default:\n throw new Error(`Cannot convert to JSON: ${input.type}`);\n }\n}\nvar ObjectValue = class extends RuntimeValue {\n type = \"ObjectValue\";\n _builtins;\n /**\n * NOTE: necessary to override since all JavaScript arrays are considered truthy,\n * while only non-empty Python arrays are consider truthy.\n *\n * e.g.,\n * - JavaScript: {} && 5 -> 5\n * - Python: {} and 5 -> {}\n */\n __bool__() {\n return new BooleanValue(this.value.size > 0);\n }\n get builtins() {\n return this._builtins ??= /* @__PURE__ */ new Map([\n [\n \"get\",\n new FunctionValue(([key, defaultValue]) => {\n if (!(key instanceof StringValue)) {\n throw new Error(`Object key must be a string: got ${key.type}`);\n }\n return this.value.get(key.value) ?? defaultValue ?? new NullValue();\n })\n ],\n [\"items\", new FunctionValue(() => this.items())],\n [\"keys\", new FunctionValue(() => this.keys())],\n [\"values\", new FunctionValue(() => this.values())],\n [\n \"dictsort\",\n new FunctionValue((args) => {\n let kwargs = /* @__PURE__ */ new Map();\n const positionalArgs = args.filter((arg) => {\n if (arg instanceof KeywordArgumentsValue) {\n kwargs = arg.value;\n return false;\n }\n return true;\n });\n const caseSensitive = positionalArgs.at(0) ?? kwargs.get(\"case_sensitive\") ?? new BooleanValue(false);\n if (!(caseSensitive instanceof BooleanValue)) {\n throw new Error(\"case_sensitive must be a boolean\");\n }\n const by = positionalArgs.at(1) ?? kwargs.get(\"by\") ?? new StringValue(\"key\");\n if (!(by instanceof StringValue)) {\n throw new Error(\"by must be a string\");\n }\n if (![\"key\", \"value\"].includes(by.value)) {\n throw new Error(\"by must be either 'key' or 'value'\");\n }\n const reverse = positionalArgs.at(2) ?? kwargs.get(\"reverse\") ?? new BooleanValue(false);\n if (!(reverse instanceof BooleanValue)) {\n throw new Error(\"reverse must be a boolean\");\n }\n const items = Array.from(this.value.entries()).map(([key, value]) => new ArrayValue([new StringValue(key), value])).sort((a, b) => {\n const index = by.value === \"key\" ? 0 : 1;\n const aVal = a.value[index];\n const bVal = b.value[index];\n const result = compareRuntimeValues(aVal, bVal, caseSensitive.value);\n return reverse.value ? -result : result;\n });\n return new ArrayValue(items);\n })\n ]\n ]);\n }\n items() {\n return new ArrayValue(\n Array.from(this.value.entries()).map(([key, value]) => new ArrayValue([new StringValue(key), value]))\n );\n }\n keys() {\n return new ArrayValue(Array.from(this.value.keys()).map((key) => new StringValue(key)));\n }\n values() {\n return new ArrayValue(Array.from(this.value.values()));\n }\n toString() {\n return toJSON(this, {}, 0, false);\n }\n};\nvar KeywordArgumentsValue = class extends ObjectValue {\n type = \"KeywordArgumentsValue\";\n};\nvar NamespaceValue = class extends RuntimeValue {\n type = \"NamespaceValue\";\n toString() {\n return toJSON(this, {}, 0, false);\n }\n};\nvar ArrayValue = class extends RuntimeValue {\n type = \"ArrayValue\";\n _builtins;\n get builtins() {\n return this._builtins ??= /* @__PURE__ */ new Map([[\"length\", new IntegerValue(this.value.length)]]);\n }\n /**\n * NOTE: necessary to override since all JavaScript arrays are considered truthy,\n * while only non-empty Python arrays are consider truthy.\n *\n * e.g.,\n * - JavaScript: [] && 5 -> 5\n * - Python: [] and 5 -> []\n */\n __bool__() {\n return new BooleanValue(this.value.length > 0);\n }\n toString() {\n return toJSON(this, {}, 0, false);\n }\n};\nvar TupleValue = class extends ArrayValue {\n type = \"TupleValue\";\n};\nvar FunctionValue = class extends RuntimeValue {\n type = \"FunctionValue\";\n};\nvar NullValue = class extends RuntimeValue {\n type = \"NullValue\";\n};\nvar UndefinedValue = class extends RuntimeValue {\n type = \"UndefinedValue\";\n};\nfunction normalizeNamespaceEntry(pair) {\n let values;\n if (pair instanceof ArrayValue) {\n values = pair.value;\n } else if (pair instanceof StringValue) {\n values = Array.from(pair.value, (char) => new StringValue(char));\n }\n if (!values || values.length !== 2) {\n throw new Error(\"namespace expected an object or an iterable of [key, value] pairs\");\n }\n const [key, value] = values;\n if (!(key instanceof StringValue)) {\n throw new Error(\"namespace keys must be strings\");\n }\n return [key, value];\n}\nvar _Environment = class {\n constructor(parent) {\n this.parent = parent;\n }\n /**\n * The variables declared in this environment.\n */\n variables = /* @__PURE__ */ new Map([\n [\n \"namespace\",\n new FunctionValue((args) => {\n const positional = args.slice();\n let kwargs;\n if (positional.at(-1) instanceof KeywordArgumentsValue) {\n kwargs = positional.pop();\n }\n if (positional.length > 1) {\n throw new Error(`namespace expected at most 1 argument, got ${positional.length}`);\n }\n const entries = /* @__PURE__ */ new Map();\n if (positional.length === 1) {\n const source = positional[0];\n if (source instanceof ObjectValue) {\n for (const [key, value] of source.value) {\n entries.set(key, value);\n }\n } else if (source instanceof ArrayValue) {\n for (const pair of source.value) {\n const [key, value] = normalizeNamespaceEntry(pair);\n entries.set(key.value, value);\n }\n } else {\n throw new Error(`'${source.type}' object is not iterable`);\n }\n }\n if (kwargs) {\n for (const [key, value] of kwargs.value) {\n entries.set(key, value);\n }\n }\n return new NamespaceValue(entries);\n })\n ]\n ]);\n tests = _Environment.TESTS;\n /**\n * Set the value of a variable in the current environment.\n */\n set(name, value) {\n return this.declareVariable(name, convertToRuntimeValues(value));\n }\n declareVariable(name, value) {\n if (this.variables.has(name)) {\n throw new SyntaxError(`Variable already declared: ${name}`);\n }\n this.variables.set(name, value);\n return value;\n }\n // private assignVariable(name: string, value: AnyRuntimeValue): AnyRuntimeValue {\n // \tconst env = this.resolve(name);\n // \tenv.variables.set(name, value);\n // \treturn value;\n // }\n /**\n * Set variable in the current scope.\n * See https://jinja.palletsprojects.com/en/3.0.x/templates/#assignments for more information.\n */\n setVariable(name, value) {\n this.variables.set(name, value);\n return value;\n }\n /**\n * Resolve the environment in which the variable is declared.\n * @param {string} name The name of the variable.\n * @returns {Environment} The environment in which the variable is declared.\n */\n resolve(name) {\n if (this.variables.has(name)) {\n return this;\n }\n if (this.parent) {\n return this.parent.resolve(name);\n }\n throw new Error(`Unknown variable: ${name}`);\n }\n lookupVariable(name) {\n try {\n return this.resolve(name).variables.get(name) ?? new UndefinedValue();\n } catch {\n return new UndefinedValue();\n }\n }\n};\nvar Environment = _Environment;\n/**\n * The tests available in this environment.\n */\n__publicField(Environment, \"TESTS\", /* @__PURE__ */ new Map([\n [\"boolean\", (operand) => operand.type === \"BooleanValue\"],\n [\"callable\", (operand) => operand instanceof FunctionValue],\n [\n \"odd\",\n (operand) => {\n if (!(operand instanceof IntegerValue)) {\n throw new Error(`cannot odd on ${operand.type}`);\n }\n return operand.value % 2 !== 0;\n }\n ],\n [\n \"even\",\n (operand) => {\n if (!(operand instanceof IntegerValue)) {\n throw new Error(`cannot even on ${operand.type}`);\n }\n return operand.value % 2 === 0;\n }\n ],\n [\"false\", (operand) => operand.type === \"BooleanValue\" && !operand.value],\n [\"true\", (operand) => operand.type === \"BooleanValue\" && operand.value],\n [\"none\", (operand) => operand.type === \"NullValue\"],\n [\"string\", (operand) => operand.type === \"StringValue\"],\n [\"number\", (operand) => operand instanceof IntegerValue || operand instanceof FloatValue],\n [\"integer\", (operand) => operand instanceof IntegerValue],\n [\"iterable\", (operand) => operand.type === \"ArrayValue\" || operand.type === \"StringValue\"],\n [\"mapping\", (operand) => operand instanceof ObjectValue],\n [\n \"sequence\",\n (operand) => operand instanceof ArrayValue || operand instanceof ObjectValue || operand instanceof StringValue\n ],\n [\n \"lower\",\n (operand) => {\n const str = operand.value;\n return operand.type === \"StringValue\" && str === str.toLowerCase();\n }\n ],\n [\n \"upper\",\n (operand) => {\n const str = operand.value;\n return operand.type === \"StringValue\" && str === str.toUpperCase();\n }\n ],\n [\"none\", (operand) => operand.type === \"NullValue\"],\n [\"defined\", (operand) => operand.type !== \"UndefinedValue\"],\n [\"undefined\", (operand) => operand.type === \"UndefinedValue\"],\n [\"equalto\", (a, b) => a.value === b.value],\n [\"eq\", (a, b) => a.value === b.value]\n]));\nfunction setupGlobals(env) {\n env.set(\"false\", false);\n env.set(\"true\", true);\n env.set(\"none\", null);\n env.set(\"raise_exception\", (args) => {\n throw new Error(args);\n });\n env.set(\"range\", range);\n env.set(\"strftime_now\", strftime_now);\n env.set(\"True\", true);\n env.set(\"False\", false);\n env.set(\"None\", null);\n}\nfunction isAttributeContainer(value) {\n return value instanceof ObjectValue || value instanceof NamespaceValue;\n}\nfunction isNumericLikeValue(value) {\n return value instanceof IntegerValue || value instanceof FloatValue || value instanceof BooleanValue;\n}\nfunction getNumericValue(value) {\n return value instanceof BooleanValue ? Number(value.value) : value.value;\n}\nfunction getAttributeValue(item, attributePath) {\n const parts = attributePath.split(\".\");\n let value = item;\n for (const part of parts) {\n if (isAttributeContainer(value)) {\n value = value.value.get(part) ?? new UndefinedValue();\n } else if (value instanceof ArrayValue) {\n const index = parseInt(part, 10);\n if (!isNaN(index) && index >= 0 && index < value.value.length) {\n value = value.value[index];\n } else {\n return new UndefinedValue();\n }\n } else {\n return new UndefinedValue();\n }\n }\n return value;\n}\nfunction compareRuntimeValues(a, b, caseSensitive = false) {\n if (a instanceof NullValue && b instanceof NullValue) {\n return 0;\n }\n if (a instanceof NullValue || b instanceof NullValue) {\n throw new Error(`Cannot compare ${a.type} with ${b.type}`);\n }\n if (a instanceof UndefinedValue && b instanceof UndefinedValue) {\n return 0;\n }\n if (a instanceof UndefinedValue || b instanceof UndefinedValue) {\n throw new Error(`Cannot compare ${a.type} with ${b.type}`);\n }\n if (isNumericLikeValue(a) && isNumericLikeValue(b)) {\n const aNum = getNumericValue(a);\n const bNum = getNumericValue(b);\n return aNum < bNum ? -1 : aNum > bNum ? 1 : 0;\n }\n if (a.type !== b.type) {\n throw new Error(`Cannot compare different types: ${a.type} and ${b.type}`);\n }\n switch (a.type) {\n case \"StringValue\": {\n let aStr = a.value;\n let bStr = b.value;\n if (!caseSensitive) {\n aStr = aStr.toLowerCase();\n bStr = bStr.toLowerCase();\n }\n return aStr < bStr ? -1 : aStr > bStr ? 1 : 0;\n }\n default:\n throw new Error(`Cannot compare type: ${a.type}`);\n }\n}\nfunction getParameterDescriptor(argument) {\n if (argument.type === \"Identifier\") {\n return { name: argument.value };\n }\n const keywordArgument = argument;\n return { name: keywordArgument.key.value, defaultValue: keywordArgument.value };\n}\nfunction isSpecialMacroArgument(name) {\n return name === \"kwargs\" || name === \"varargs\";\n}\nfunction findAccessedSpecialMacroArguments(parameters, body) {\n const declared = /* @__PURE__ */ new Set();\n const accessed = /* @__PURE__ */ new Set();\n const declareName = (name) => {\n if (isSpecialMacroArgument(name)) {\n declared.add(name);\n }\n };\n const declareTarget = (target) => {\n if (target.type === \"Identifier\") {\n declareName(target.value);\n } else if (target.type === \"TupleLiteral\") {\n for (const item of target.value) {\n declareTarget(item);\n }\n }\n };\n const declareArgument = (argument) => {\n declareName(getParameterDescriptor(argument).name);\n };\n const visitArgumentDefaults = (args) => {\n for (const argument of args) {\n const parameter = getParameterDescriptor(argument);\n if (parameter.defaultValue) {\n visit(parameter.defaultValue);\n }\n }\n };\n const visitFilter = (filter) => {\n if (filter.type === \"CallExpression\") {\n visit(filter.args);\n }\n };\n const visit = (node) => {\n if (Array.isArray(node)) {\n for (const item of node) {\n visit(item);\n }\n return;\n }\n if (node instanceof Map) {\n for (const [key, value] of node) {\n visit(key);\n visit(value);\n }\n return;\n }\n if (!(node instanceof Statement)) {\n return;\n }\n switch (node.type) {\n case \"For\": {\n const statement = node;\n declareTarget(statement.loopvar);\n if (statement.iterable.type === \"SelectExpression\") {\n const iterable = statement.iterable;\n visit(iterable.lhs);\n visit(statement.body);\n visit(statement.defaultBlock);\n visit(iterable.test);\n return;\n }\n visit(statement.iterable);\n visit(statement.body);\n visit(statement.defaultBlock);\n return;\n }\n case \"Set\": {\n const statement = node;\n declareTarget(statement.assignee);\n visit(statement.value);\n visit(statement.body);\n return;\n }\n case \"Macro\": {\n const statement = node;\n for (const argument of statement.args) {\n declareArgument(argument);\n }\n visitArgumentDefaults(statement.args);\n visit(statement.body);\n return;\n }\n case \"CallStatement\": {\n const statement = node;\n visit(statement.call);\n for (const argument of statement.callerArgs ?? []) {\n declareArgument(argument);\n }\n visitArgumentDefaults(statement.callerArgs ?? []);\n visit(statement.body);\n return;\n }\n case \"FilterStatement\": {\n const statement = node;\n visit(statement.body);\n visitFilter(statement.filter);\n return;\n }\n case \"Identifier\": {\n const name = node.value;\n if (isSpecialMacroArgument(name) && !declared.has(name)) {\n accessed.add(name);\n }\n return;\n }\n case \"MemberExpression\": {\n const expression = node;\n visit(expression.object);\n if (expression.computed) {\n visit(expression.property);\n }\n return;\n }\n case \"FilterExpression\": {\n const expression = node;\n visit(expression.operand);\n visitFilter(expression.filter);\n return;\n }\n case \"TestExpression\":\n visit(node.operand);\n return;\n case \"SelectExpression\": {\n const expression = node;\n visit(expression.test);\n visit(expression.lhs);\n return;\n }\n case \"KeywordArgumentExpression\":\n visit(node.value);\n return;\n default:\n for (const child of Object.values(node)) {\n visit(child);\n }\n }\n };\n for (const parameter of parameters) {\n declareArgument(parameter);\n }\n visit(body);\n return accessed;\n}\nvar Interpreter = class {\n global;\n constructor(env) {\n this.global = env ?? new Environment();\n }\n /**\n * Run the program.\n */\n run(program) {\n return this.evaluate(program, this.global);\n }\n /**\n * Evaluates expressions following the binary operation type.\n */\n evaluateBinaryExpression(node, environment) {\n const left = this.evaluate(node.left, environment);\n switch (node.operator.value) {\n case \"and\":\n return left.__bool__().value ? this.evaluate(node.right, environment) : left;\n case \"or\":\n return left.__bool__().value ? left : this.evaluate(node.right, environment);\n }\n const right = this.evaluate(node.right, environment);\n switch (node.operator.value) {\n case \"==\":\n return new BooleanValue(left.value == right.value);\n case \"!=\":\n return new BooleanValue(left.value != right.value);\n }\n if (left instanceof UndefinedValue || right instanceof UndefinedValue) {\n if (right instanceof UndefinedValue && [\"in\", \"not in\"].includes(node.operator.value)) {\n return new BooleanValue(node.operator.value === \"not in\");\n }\n throw new Error(`Cannot perform operation ${node.operator.value} on undefined values`);\n } else if (left instanceof NullValue || right instanceof NullValue) {\n throw new Error(\"Cannot perform operation on null values\");\n } else if (node.operator.value === \"~\") {\n return new StringValue(left.value.toString() + right.value.toString());\n } else if (node.operator.value === \"**\" && isNumericLikeValue(left) && isNumericLikeValue(right)) {\n const a = getNumericValue(left);\n const b = getNumericValue(right);\n if (a === 0 && b < 0) {\n throw new Error(\"0.0 cannot be raised to a negative power\");\n }\n const result = a ** b;\n if (!Number.isFinite(result)) {\n throw new Error(\"Exponentiation result is not a finite real number\");\n }\n const isFloat = left instanceof FloatValue || right instanceof FloatValue || b < 0;\n return isFloat ? new FloatValue(result) : new IntegerValue(result);\n } else if ((left instanceof IntegerValue || left instanceof FloatValue) && (right instanceof IntegerValue || right instanceof FloatValue)) {\n const a = left.value, b = right.value;\n switch (node.operator.value) {\n case \"+\":\n case \"-\":\n case \"*\": {\n const res = node.operator.value === \"+\" ? a + b : node.operator.value === \"-\" ? a - b : a * b;\n const isFloat = left instanceof FloatValue || right instanceof FloatValue;\n return isFloat ? new FloatValue(res) : new IntegerValue(res);\n }\n case \"/\":\n return new FloatValue(a / b);\n case \"//\": {\n const res = Math.floor(a / b);\n const isFloat = left instanceof FloatValue || right instanceof FloatValue;\n return isFloat ? new FloatValue(res) : new IntegerValue(res);\n }\n case \"%\": {\n const rem = a % b;\n const isFloat = left instanceof FloatValue || right instanceof FloatValue;\n return isFloat ? new FloatValue(rem) : new IntegerValue(rem);\n }\n case \"<\":\n return new BooleanValue(a < b);\n case \">\":\n return new BooleanValue(a > b);\n case \">=\":\n return new BooleanValue(a >= b);\n case \"<=\":\n return new BooleanValue(a <= b);\n }\n } else if (left instanceof ArrayValue && right instanceof ArrayValue) {\n switch (node.operator.value) {\n case \"+\":\n return new ArrayValue(left.value.concat(right.value));\n }\n } else if (right instanceof ArrayValue) {\n const member = right.value.find((x) => x.value === left.value) !== void 0;\n switch (node.operator.value) {\n case \"in\":\n return new BooleanValue(member);\n case \"not in\":\n return new BooleanValue(!member);\n }\n }\n if (left instanceof StringValue || right instanceof StringValue) {\n switch (node.operator.value) {\n case \"+\":\n return new StringValue(left.value.toString() + right.value.toString());\n }\n }\n if (left instanceof StringValue && right instanceof StringValue) {\n switch (node.operator.value) {\n case \"in\":\n return new BooleanValue(right.value.includes(left.value));\n case \"not in\":\n return new BooleanValue(!right.value.includes(left.value));\n }\n }\n if (left instanceof StringValue && right instanceof ObjectValue) {\n switch (node.operator.value) {\n case \"in\":\n return new BooleanValue(right.value.has(left.value));\n case \"not in\":\n return new BooleanValue(!right.value.has(left.value));\n }\n }\n throw new SyntaxError(`Unknown operator \"${node.operator.value}\" between ${left.type} and ${right.type}`);\n }\n evaluateArguments(args, environment) {\n const positionalArguments = [];\n const keywordArguments = /* @__PURE__ */ new Map();\n const addKeywordArgument = (key, value) => {\n if (keywordArguments.has(key)) {\n throw new Error(`Got multiple values for keyword argument '${key}'`);\n }\n keywordArguments.set(key, value);\n };\n for (const argument of args) {\n if (argument.type === \"SpreadExpression\") {\n const spreadNode = argument;\n const val = this.evaluate(spreadNode.argument, environment);\n if (!(val instanceof ArrayValue)) {\n throw new Error(`Cannot unpack non-iterable type: ${val.type}`);\n }\n for (const item of val.value) {\n positionalArguments.push(item);\n }\n } else if (argument.type !== \"KeywordArgumentExpression\" && argument.type !== \"KeywordSpreadExpression\") {\n positionalArguments.push(this.evaluate(argument, environment));\n }\n }\n for (const argument of args) {\n if (argument.type === \"KeywordArgumentExpression\") {\n const kwarg = argument;\n addKeywordArgument(kwarg.key.value, this.evaluate(kwarg.value, environment));\n } else if (argument.type === \"KeywordSpreadExpression\") {\n const spreadNode = argument;\n const val = this.evaluate(spreadNode.argument, environment);\n if (!(val instanceof ObjectValue)) {\n throw new Error(`Argument after ** must be a mapping, not ${val.type}`);\n }\n for (const [key, value] of val.value) {\n addKeywordArgument(key, value);\n }\n }\n }\n return [positionalArguments, keywordArguments];\n }\n applyFilter(operand, filterNode, environment) {\n if (filterNode.type === \"Identifier\") {\n const filter = filterNode;\n if (filter.value === \"safe\") {\n return operand;\n }\n if (filter.value === \"tojson\") {\n return new StringValue(toJSON(operand, {}));\n }\n if (operand instanceof ArrayValue) {\n switch (filter.value) {\n case \"list\":\n return operand;\n case \"first\":\n return operand.value[0];\n case \"last\":\n return operand.value[operand.value.length - 1];\n case \"length\":\n return new IntegerValue(operand.value.length);\n case \"reverse\":\n return new ArrayValue(operand.value.slice().reverse());\n case \"sort\": {\n return new ArrayValue(operand.value.slice().sort((a, b) => compareRuntimeValues(a, b, false)));\n }\n case \"join\":\n return new StringValue(operand.value.map((x) => x.value).join(\"\"));\n case \"string\":\n return new StringValue(toJSON(operand, {}, 0, false));\n case \"unique\": {\n const seen = /* @__PURE__ */ new Set();\n const output = [];\n for (const item of operand.value) {\n if (!seen.has(item.value)) {\n seen.add(item.value);\n output.push(item);\n }\n }\n return new ArrayValue(output);\n }\n default:\n throw new Error(`Unknown ArrayValue filter: ${filter.value}`);\n }\n } else if (operand instanceof StringValue) {\n switch (filter.value) {\n case \"length\":\n case \"upper\":\n case \"lower\":\n case \"title\":\n case \"capitalize\": {\n const builtin = operand.builtins.get(filter.value);\n if (builtin instanceof FunctionValue) {\n return builtin.value(\n /* no arguments */\n [],\n environment\n );\n } else if (builtin instanceof IntegerValue) {\n return builtin;\n } else {\n throw new Error(`Unknown StringValue filter: ${filter.value}`);\n }\n }\n case \"trim\":\n return new StringValue(operand.value.trim());\n case \"indent\":\n return new StringValue(\n operand.value.split(\"\\n\").map(\n (x, i) => (\n // By default, don't indent the first line or empty lines\n i === 0 || x.length === 0 ? x : \" \" + x\n )\n ).join(\"\\n\")\n );\n case \"join\":\n case \"string\":\n return operand;\n case \"int\": {\n const val = parseInt(operand.value, 10);\n return new IntegerValue(isNaN(val) ? 0 : val);\n }\n case \"float\": {\n const val = parseFloat(operand.value);\n return new FloatValue(isNaN(val) ? 0 : val);\n }\n default:\n throw new Error(`Unknown StringValue filter: ${filter.value}`);\n }\n } else if (operand instanceof IntegerValue || operand instanceof FloatValue) {\n switch (filter.value) {\n case \"abs\":\n return operand instanceof IntegerValue ? new IntegerValue(Math.abs(operand.value)) : new FloatValue(Math.abs(operand.value));\n case \"int\":\n return new IntegerValue(Math.floor(operand.value));\n case \"float\":\n return new FloatValue(operand.value);\n case \"string\":\n return new StringValue(operand.toString());\n default:\n throw new Error(`Unknown NumericValue filter: ${filter.value}`);\n }\n } else if (operand instanceof ObjectValue) {\n switch (filter.value) {\n case \"items\":\n return new ArrayValue(\n Array.from(operand.value.entries()).map(([key, value]) => new ArrayValue([new StringValue(key), value]))\n );\n case \"length\":\n return new IntegerValue(operand.value.size);\n default: {\n const builtin = operand.builtins.get(filter.value);\n if (builtin) {\n if (builtin instanceof FunctionValue) {\n return builtin.value([], environment);\n }\n return builtin;\n }\n throw new Error(`Unknown ObjectValue filter: ${filter.value}`);\n }\n }\n } else if (operand instanceof BooleanValue) {\n switch (filter.value) {\n case \"bool\":\n return new BooleanValue(operand.value);\n case \"int\":\n return new IntegerValue(operand.value ? 1 : 0);\n case \"float\":\n return new FloatValue(operand.value ? 1 : 0);\n case \"string\":\n return new StringValue(operand.value ? \"true\" : \"false\");\n default:\n throw new Error(`Unknown BooleanValue filter: ${filter.value}`);\n }\n }\n throw new Error(`Cannot apply filter \"${filter.value}\" to type: ${operand.type}`);\n } else if (filterNode.type === \"CallExpression\") {\n const filter = filterNode;\n if (filter.callee.type !== \"Identifier\") {\n throw new Error(`Unknown filter: ${filter.callee.type}`);\n }\n const filterName = filter.callee.value;\n if (filterName === \"tojson\") {\n const [, kwargs] = this.evaluateArguments(filter.args, environment);\n const indent = kwargs.get(\"indent\") ?? new NullValue();\n if (!(indent instanceof IntegerValue || indent instanceof NullValue)) {\n throw new Error(\"If set, indent must be a number\");\n }\n const ensureAscii = kwargs.get(\"ensure_ascii\") ?? new BooleanValue(false);\n if (!(ensureAscii instanceof BooleanValue)) {\n throw new Error(\"If set, ensure_ascii must be a boolean\");\n }\n const sortKeys = kwargs.get(\"sort_keys\") ?? new BooleanValue(false);\n if (!(sortKeys instanceof BooleanValue)) {\n throw new Error(\"If set, sort_keys must be a boolean\");\n }\n const separatorsArg = kwargs.get(\"separators\") ?? new NullValue();\n let separators = null;\n if (separatorsArg instanceof ArrayValue || separatorsArg instanceof TupleValue) {\n if (separatorsArg.value.length !== 2) {\n throw new Error(\"separators must be a tuple of two strings\");\n }\n const [itemSep, keySep] = separatorsArg.value;\n if (!(itemSep instanceof StringValue) || !(keySep instanceof StringValue)) {\n throw new Error(\"separators must be a tuple of two strings\");\n }\n separators = [itemSep.value, keySep.value];\n } else if (!(separatorsArg instanceof NullValue)) {\n throw new Error(\"If set, separators must be a tuple of two strings\");\n }\n return new StringValue(\n toJSON(operand, {\n indent: indent.value,\n ensureAscii: ensureAscii.value,\n sortKeys: sortKeys.value,\n separators\n })\n );\n } else if (filterName === \"join\") {\n let value;\n if (operand instanceof StringValue) {\n value = Array.from(operand.value);\n } else if (operand instanceof ArrayValue) {\n value = operand.value.map((x) => x.value);\n } else {\n throw new Error(`Cannot apply filter \"${filterName}\" to type: ${operand.type}`);\n }\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const separator = args.at(0) ?? kwargs.get(\"separator\") ?? new StringValue(\"\");\n if (!(separator instanceof StringValue)) {\n throw new Error(\"separator must be a string\");\n }\n return new StringValue(value.join(separator.value));\n } else if (filterName === \"int\" || filterName === \"float\") {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const defaultValue = args.at(0) ?? kwargs.get(\"default\") ?? (filterName === \"int\" ? new IntegerValue(0) : new FloatValue(0));\n if (operand instanceof StringValue) {\n const val = filterName === \"int\" ? parseInt(operand.value, 10) : parseFloat(operand.value);\n return isNaN(val) ? defaultValue : filterName === \"int\" ? new IntegerValue(val) : new FloatValue(val);\n } else if (operand instanceof IntegerValue || operand instanceof FloatValue) {\n return operand;\n } else if (operand instanceof BooleanValue) {\n return filterName === \"int\" ? new IntegerValue(operand.value ? 1 : 0) : new FloatValue(operand.value ? 1 : 0);\n } else {\n throw new Error(`Cannot apply filter \"${filterName}\" to type: ${operand.type}`);\n }\n } else if (filterName === \"default\") {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const defaultValue = args[0] ?? new StringValue(\"\");\n const booleanValue = args[1] ?? kwargs.get(\"boolean\") ?? new BooleanValue(false);\n if (!(booleanValue instanceof BooleanValue)) {\n throw new Error(\"`default` filter flag must be a boolean\");\n }\n if (operand instanceof UndefinedValue || booleanValue.value && !operand.__bool__().value) {\n return defaultValue;\n }\n return operand;\n }\n if (operand instanceof ArrayValue) {\n switch (filterName) {\n case \"sort\": {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const reverse = args.at(0) ?? kwargs.get(\"reverse\") ?? new BooleanValue(false);\n if (!(reverse instanceof BooleanValue)) {\n throw new Error(\"reverse must be a boolean\");\n }\n const caseSensitive = args.at(1) ?? kwargs.get(\"case_sensitive\") ?? new BooleanValue(false);\n if (!(caseSensitive instanceof BooleanValue)) {\n throw new Error(\"case_sensitive must be a boolean\");\n }\n const attribute = args.at(2) ?? kwargs.get(\"attribute\") ?? new NullValue();\n if (!(attribute instanceof StringValue || attribute instanceof IntegerValue || attribute instanceof NullValue)) {\n throw new Error(\"attribute must be a string, integer, or null\");\n }\n const getSortValue = (item) => {\n if (attribute instanceof NullValue) {\n return item;\n }\n const attrPath = attribute instanceof IntegerValue ? String(attribute.value) : attribute.value;\n return getAttributeValue(item, attrPath);\n };\n return new ArrayValue(\n operand.value.slice().sort((a, b) => {\n const aVal = getSortValue(a);\n const bVal = getSortValue(b);\n const result = compareRuntimeValues(aVal, bVal, caseSensitive.value);\n return reverse.value ? -result : result;\n })\n );\n }\n case \"selectattr\":\n case \"rejectattr\": {\n const select = filterName === \"selectattr\";\n if (operand.value.some((item) => !isAttributeContainer(item))) {\n throw new Error(`\\`${filterName}\\` can only be applied to array of objects`);\n }\n if (filter.args.some((x) => x.type !== \"StringLiteral\")) {\n throw new Error(`arguments of \\`${filterName}\\` must be strings`);\n }\n const [attr, testName, value] = filter.args.map((x) => this.evaluate(x, environment));\n let testFunction;\n if (testName) {\n const test = environment.tests.get(testName.value);\n if (!test) {\n throw new Error(`Unknown test: ${testName.value}`);\n }\n testFunction = test;\n } else {\n testFunction = (...x) => x[0].__bool__().value;\n }\n const filtered = operand.value.filter((item) => {\n const a = item.value.get(attr.value);\n const result = a ? testFunction(a, value) : false;\n return select ? result : !result;\n });\n return new ArrayValue(filtered);\n }\n case \"map\": {\n const [, kwargs] = this.evaluateArguments(filter.args, environment);\n if (kwargs.has(\"attribute\")) {\n const attr = kwargs.get(\"attribute\");\n if (!(attr instanceof StringValue)) {\n throw new Error(\"attribute must be a string\");\n }\n const defaultValue = kwargs.get(\"default\");\n const mapped = operand.value.map((item) => {\n if (!isAttributeContainer(item)) {\n throw new Error(\"items in map must be an object\");\n }\n const value = getAttributeValue(item, attr.value);\n return value instanceof UndefinedValue ? defaultValue ?? new UndefinedValue() : value;\n });\n return new ArrayValue(mapped);\n } else {\n throw new Error(\"`map` expressions without `attribute` set are not currently supported.\");\n }\n }\n }\n throw new Error(`Unknown ArrayValue filter: ${filterName}`);\n } else if (operand instanceof StringValue) {\n switch (filterName) {\n case \"indent\": {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const width = args.at(0) ?? kwargs.get(\"width\") ?? new IntegerValue(4);\n if (!(width instanceof IntegerValue)) {\n throw new Error(\"width must be a number\");\n }\n const first = args.at(1) ?? kwargs.get(\"first\") ?? new BooleanValue(false);\n const blank = args.at(2) ?? kwargs.get(\"blank\") ?? new BooleanValue(false);\n const lines = operand.value.split(\"\\n\");\n const indent = \" \".repeat(width.value);\n const indented = lines.map(\n (x, i) => !first.value && i === 0 || !blank.value && x.length === 0 ? x : indent + x\n );\n return new StringValue(indented.join(\"\\n\"));\n }\n case \"replace\": {\n const replaceFn = operand.builtins.get(\"replace\");\n if (!(replaceFn instanceof FunctionValue)) {\n throw new Error(\"replace filter not available\");\n }\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n return replaceFn.value([...args, new KeywordArgumentsValue(kwargs)], environment);\n }\n }\n throw new Error(`Unknown StringValue filter: ${filterName}`);\n } else if (operand instanceof ObjectValue) {\n const builtin = operand.builtins.get(filterName);\n if (builtin && builtin instanceof FunctionValue) {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n if (kwargs.size > 0) {\n args.push(new KeywordArgumentsValue(kwargs));\n }\n return builtin.value(args, environment);\n }\n throw new Error(`Unknown ObjectValue filter: ${filterName}`);\n } else {\n throw new Error(`Cannot apply filter \"${filterName}\" to type: ${operand.type}`);\n }\n }\n throw new Error(`Unknown filter: ${filterNode.type}`);\n }\n /**\n * Evaluates expressions following the filter operation type.\n */\n evaluateFilterExpression(node, environment) {\n const operand = this.evaluate(node.operand, environment);\n return this.applyFilter(operand, node.filter, environment);\n }\n /**\n * Evaluates expressions following the test operation type.\n */\n evaluateTestExpression(node, environment) {\n const operand = this.evaluate(node.operand, environment);\n const test = environment.tests.get(node.test.value);\n if (!test) {\n throw new Error(`Unknown test: ${node.test.value}`);\n }\n const result = test(operand);\n return new BooleanValue(node.negate ? !result : result);\n }\n /**\n * Evaluates expressions following the select operation type.\n */\n evaluateSelectExpression(node, environment) {\n const predicate = this.evaluate(node.test, environment);\n if (!predicate.__bool__().value) {\n return new UndefinedValue();\n }\n return this.evaluate(node.lhs, environment);\n }\n /**\n * Evaluates expressions following the unary operation type.\n */\n evaluateUnaryExpression(node, environment) {\n const argument = this.evaluate(node.argument, environment);\n switch (node.operator.value) {\n case \"not\":\n return new BooleanValue(!argument.value);\n case \"+\":\n case \"-\": {\n const sign = node.operator.value === \"-\" ? -1 : 1;\n if (argument instanceof IntegerValue || argument instanceof FloatValue || argument instanceof BooleanValue) {\n const value = argument instanceof BooleanValue ? argument.value ? 1 : 0 : argument.value;\n const result = sign * value;\n return argument instanceof FloatValue ? new FloatValue(result) : new IntegerValue(result);\n }\n throw new SyntaxError(`Unknown operator \"${node.operator.value}\" for ${argument.type}`);\n }\n default:\n throw new SyntaxError(`Unknown operator: ${node.operator.value}`);\n }\n }\n evaluateTernaryExpression(node, environment) {\n const cond = this.evaluate(node.condition, environment);\n return cond.__bool__().value ? this.evaluate(node.trueExpr, environment) : this.evaluate(node.falseExpr, environment);\n }\n evalProgram(program, environment) {\n return this.evaluateBlock(program.body, environment);\n }\n evaluateBlock(statements, environment) {\n let result = \"\";\n for (const statement of statements) {\n const lastEvaluated = this.evaluate(statement, environment);\n if (lastEvaluated.type !== \"NullValue\" && lastEvaluated.type !== \"UndefinedValue\") {\n result += lastEvaluated.toString();\n }\n }\n return new StringValue(result);\n }\n evaluateIdentifier(node, environment) {\n return environment.lookupVariable(node.value);\n }\n evaluateCallExpression(expr, environment) {\n const [args, kwargs] = this.evaluateArguments(expr.args, environment);\n if (kwargs.size > 0) {\n args.push(new KeywordArgumentsValue(kwargs));\n }\n const fn = this.evaluate(expr.callee, environment);\n if (fn.type !== \"FunctionValue\") {\n throw new Error(`Cannot call something that is not a function: got ${fn.type}`);\n }\n return fn.value(args, environment);\n }\n evaluateSliceExpression(object, expr, environment) {\n if (!(object instanceof ArrayValue || object instanceof StringValue)) {\n throw new Error(\"Slice object must be an array or string\");\n }\n const start = this.evaluate(expr.start, environment);\n const stop = this.evaluate(expr.stop, environment);\n const step = this.evaluate(expr.step, environment);\n if (!(start instanceof IntegerValue || start instanceof UndefinedValue)) {\n throw new Error(\"Slice start must be numeric or undefined\");\n }\n if (!(stop instanceof IntegerValue || stop instanceof UndefinedValue)) {\n throw new Error(\"Slice stop must be numeric or undefined\");\n }\n if (!(step instanceof IntegerValue || step instanceof UndefinedValue)) {\n throw new Error(\"Slice step must be numeric or undefined\");\n }\n if (object instanceof ArrayValue) {\n return new ArrayValue(slice(object.value, start.value, stop.value, step.value));\n } else {\n return new StringValue(slice(Array.from(object.value), start.value, stop.value, step.value).join(\"\"));\n }\n }\n evaluateMemberExpression(expr, environment) {\n const object = this.evaluate(expr.object, environment);\n let property;\n if (expr.computed) {\n if (expr.property.type === \"SliceExpression\") {\n return this.evaluateSliceExpression(object, expr.property, environment);\n } else {\n property = this.evaluate(expr.property, environment);\n }\n } else if (expr.property.type === \"IntegerLiteral\") {\n property = new IntegerValue(expr.property.value);\n } else {\n property = new StringValue(expr.property.value);\n }\n let value;\n if (isAttributeContainer(object)) {\n if (!(property instanceof StringValue)) {\n throw new Error(`Cannot access property with non-string: got ${property.type}`);\n }\n value = object.value.get(property.value) ?? (object instanceof ObjectValue ? object.builtins.get(property.value) : void 0);\n } else if (object instanceof ArrayValue || object instanceof StringValue) {\n if (property instanceof IntegerValue) {\n value = object.value.at(property.value);\n if (object instanceof StringValue) {\n value = new StringValue(object.value.at(property.value));\n }\n } else if (property instanceof StringValue) {\n value = object.builtins.get(property.value);\n } else {\n throw new Error(`Cannot access property with non-string/non-number: got ${property.type}`);\n }\n } else {\n if (!(property instanceof StringValue)) {\n throw new Error(`Cannot access property with non-string: got ${property.type}`);\n }\n value = object.builtins.get(property.value);\n }\n return value instanceof RuntimeValue ? value : new UndefinedValue();\n }\n evaluateSet(node, environment) {\n const rhs = node.value ? this.evaluate(node.value, environment) : this.evaluateBlock(node.body, environment);\n if (node.assignee.type === \"Identifier\") {\n const variableName = node.assignee.value;\n environment.setVariable(variableName, rhs);\n } else if (node.assignee.type === \"TupleLiteral\") {\n const tuple = node.assignee;\n if (!(rhs instanceof ArrayValue)) {\n throw new Error(`Cannot unpack non-iterable type in set: ${rhs.type}`);\n }\n const arr = rhs.value;\n if (arr.length !== tuple.value.length) {\n throw new Error(`Too ${tuple.value.length > arr.length ? \"few\" : \"many\"} items to unpack in set`);\n }\n for (let i = 0; i < tuple.value.length; ++i) {\n const elem = tuple.value[i];\n if (elem.type !== \"Identifier\") {\n throw new Error(`Cannot unpack to non-identifier in set: ${elem.type}`);\n }\n environment.setVariable(elem.value, arr[i]);\n }\n } else if (node.assignee.type === \"MemberExpression\") {\n const member = node.assignee;\n const object = this.evaluate(member.object, environment);\n if (!(object instanceof NamespaceValue)) {\n throw new Error(\"cannot assign attribute on non-namespace object\");\n }\n if (member.property.type !== \"Identifier\") {\n throw new Error(\"Cannot assign to member with non-identifier property\");\n }\n object.value.set(member.property.value, rhs);\n } else {\n throw new Error(`Invalid LHS inside assignment expression: ${JSON.stringify(node.assignee)}`);\n }\n return new NullValue();\n }\n evaluateIf(node, environment) {\n const test = this.evaluate(node.test, environment);\n return this.evaluateBlock(test.__bool__().value ? node.body : node.alternate, environment);\n }\n evaluateFor(node, environment) {\n const scope = new Environment(environment);\n let test, iterable;\n if (node.iterable.type === \"SelectExpression\") {\n const select = node.iterable;\n iterable = this.evaluate(select.lhs, scope);\n test = select.test;\n } else {\n iterable = this.evaluate(node.iterable, scope);\n }\n if (!(iterable instanceof ArrayValue || iterable instanceof ObjectValue)) {\n throw new Error(`Expected iterable or object type in for loop: got ${iterable.type}`);\n }\n if (iterable instanceof ObjectValue) {\n iterable = iterable.keys();\n }\n const items = [];\n const scopeUpdateFunctions = [];\n for (let i = 0; i < iterable.value.length; ++i) {\n const loopScope = new Environment(scope);\n const current = iterable.value[i];\n let scopeUpdateFunction;\n if (node.loopvar.type === \"Identifier\") {\n scopeUpdateFunction = (scope2) => scope2.setVariable(node.loopvar.value, current);\n } else if (node.loopvar.type === \"TupleLiteral\") {\n const loopvar = node.loopvar;\n if (current.type !== \"ArrayValue\") {\n throw new Error(`Cannot unpack non-iterable type: ${current.type}`);\n }\n const c = current;\n if (loopvar.value.length !== c.value.length) {\n throw new Error(`Too ${loopvar.value.length > c.value.length ? \"few\" : \"many\"} items to unpack`);\n }\n scopeUpdateFunction = (scope2) => {\n for (let j = 0; j < loopvar.value.length; ++j) {\n if (loopvar.value[j].type !== \"Identifier\") {\n throw new Error(`Cannot unpack non-identifier type: ${loopvar.value[j].type}`);\n }\n scope2.setVariable(loopvar.value[j].value, c.value[j]);\n }\n };\n } else {\n throw new Error(`Invalid loop variable(s): ${node.loopvar.type}`);\n }\n if (test) {\n scopeUpdateFunction(loopScope);\n const testValue = this.evaluate(test, loopScope);\n if (!testValue.__bool__().value) {\n continue;\n }\n }\n items.push(current);\n scopeUpdateFunctions.push(scopeUpdateFunction);\n }\n let result = \"\";\n let noIteration = true;\n for (let i = 0; i < items.length; ++i) {\n const loop = /* @__PURE__ */ new Map([\n [\"index\", new IntegerValue(i + 1)],\n [\"index0\", new IntegerValue(i)],\n [\"revindex\", new IntegerValue(items.length - i)],\n [\"revindex0\", new IntegerValue(items.length - i - 1)],\n [\"first\", new BooleanValue(i === 0)],\n [\"last\", new BooleanValue(i === items.length - 1)],\n [\"length\", new IntegerValue(items.length)],\n [\"previtem\", i > 0 ? items[i - 1] : new UndefinedValue()],\n [\"nextitem\", i < items.length - 1 ? items[i + 1] : new UndefinedValue()]\n ]);\n scope.setVariable(\"loop\", new ObjectValue(loop));\n scopeUpdateFunctions[i](scope);\n try {\n const evaluated = this.evaluateBlock(node.body, scope);\n result += evaluated.value;\n } catch (err) {\n if (err instanceof ContinueControl) {\n continue;\n }\n if (err instanceof BreakControl) {\n break;\n }\n throw err;\n }\n noIteration = false;\n }\n if (noIteration) {\n const defaultEvaluated = this.evaluateBlock(node.defaultBlock, scope);\n result += defaultEvaluated.value;\n }\n return new StringValue(result);\n }\n /**\n * Bind every parameter name and special argument before evaluating defaults,\n * preventing unbound parameters from resolving in an outer scope.\n */\n bindMacroArguments(displayName, parameters, specialArguments, args, scope) {\n const positionalArguments = args.slice();\n let keywordArguments = /* @__PURE__ */ new Map();\n if (positionalArguments.at(-1) instanceof KeywordArgumentsValue) {\n keywordArguments = new Map(positionalArguments.pop().value);\n }\n const pendingDefaults = [];\n for (let i = 0; i < parameters.length; ++i) {\n const { name, defaultValue } = getParameterDescriptor(parameters[i]);\n let value = positionalArguments[i];\n if (value === void 0 && keywordArguments.has(name)) {\n value = keywordArguments.get(name);\n keywordArguments.delete(name);\n }\n if (value === void 0 && defaultValue !== void 0) {\n pendingDefaults.push([name, defaultValue]);\n }\n scope.setVariable(name, value ?? new UndefinedValue());\n }\n if (specialArguments.has(\"kwargs\")) {\n scope.setVariable(\"kwargs\", new ObjectValue(keywordArguments));\n } else if (keywordArguments.size > 0) {\n throw new Error(`macro ${displayName} takes no keyword argument '${keywordArguments.keys().next().value}'`);\n }\n if (specialArguments.has(\"varargs\")) {\n scope.setVariable(\"varargs\", new ArrayValue(positionalArguments.slice(parameters.length)));\n } else if (positionalArguments.length > parameters.length) {\n throw new Error(`macro ${displayName} takes not more than ${parameters.length} argument(s)`);\n }\n for (const [name, defaultValue] of pendingDefaults) {\n scope.setVariable(name, this.evaluate(defaultValue, scope));\n }\n }\n /**\n * See https://jinja.palletsprojects.com/en/3.1.x/templates/#macros for more information.\n */\n evaluateMacro(node, environment) {\n const specialArguments = findAccessedSpecialMacroArguments(node.args, node.body);\n environment.setVariable(\n node.name.value,\n new FunctionValue((args, scope) => {\n const macroScope = new Environment(scope);\n this.bindMacroArguments(`'${node.name.value}'`, node.args, specialArguments, args, macroScope);\n return this.evaluateBlock(node.body, macroScope);\n })\n );\n return new NullValue();\n }\n evaluateCallStatement(node, environment) {\n const parameters = node.callerArgs ?? [];\n const specialArguments = findAccessedSpecialMacroArguments(parameters, node.body);\n const callerFn = new FunctionValue((callerArguments) => {\n const callBlockEnv = new Environment(environment);\n this.bindMacroArguments(\"None\", parameters, specialArguments, callerArguments, callBlockEnv);\n return this.evaluateBlock(node.body, callBlockEnv);\n });\n const [macroArgs, macroKwargs] = this.evaluateArguments(node.call.args, environment);\n macroArgs.push(new KeywordArgumentsValue(macroKwargs));\n const fn = this.evaluate(node.call.callee, environment);\n if (fn.type !== \"FunctionValue\") {\n throw new Error(`Cannot call something that is not a function: got ${fn.type}`);\n }\n const newEnv = new Environment(environment);\n newEnv.setVariable(\"caller\", callerFn);\n return fn.value(macroArgs, newEnv);\n }\n evaluateFilterStatement(node, environment) {\n const rendered = this.evaluateBlock(node.body, environment);\n return this.applyFilter(rendered, node.filter, environment);\n }\n evaluate(statement, environment) {\n if (!statement) {\n return new UndefinedValue();\n }\n switch (statement.type) {\n case \"Program\":\n return this.evalProgram(statement, environment);\n case \"Set\":\n return this.evaluateSet(statement, environment);\n case \"If\":\n return this.evaluateIf(statement, environment);\n case \"For\":\n return this.evaluateFor(statement, environment);\n case \"Macro\":\n return this.evaluateMacro(statement, environment);\n case \"CallStatement\":\n return this.evaluateCallStatement(statement, environment);\n case \"Break\":\n throw new BreakControl();\n case \"Continue\":\n throw new ContinueControl();\n case \"IntegerLiteral\":\n return new IntegerValue(statement.value);\n case \"FloatLiteral\":\n return new FloatValue(statement.value);\n case \"StringLiteral\":\n return new StringValue(statement.value);\n case \"ArrayLiteral\":\n return new ArrayValue(statement.value.map((x) => this.evaluate(x, environment)));\n case \"TupleLiteral\":\n return new TupleValue(statement.value.map((x) => this.evaluate(x, environment)));\n case \"ObjectLiteral\": {\n const mapping = /* @__PURE__ */ new Map();\n for (const [key, value] of statement.value) {\n const evaluatedKey = this.evaluate(key, environment);\n if (!(evaluatedKey instanceof StringValue)) {\n throw new Error(`Object keys must be strings: got ${evaluatedKey.type}`);\n }\n mapping.set(evaluatedKey.value, this.evaluate(value, environment));\n }\n return new ObjectValue(mapping);\n }\n case \"Identifier\":\n return this.evaluateIdentifier(statement, environment);\n case \"CallExpression\":\n return this.evaluateCallExpression(statement, environment);\n case \"MemberExpression\":\n return this.evaluateMemberExpression(statement, environment);\n case \"UnaryExpression\":\n return this.evaluateUnaryExpression(statement, environment);\n case \"BinaryExpression\":\n return this.evaluateBinaryExpression(statement, environment);\n case \"FilterExpression\":\n return this.evaluateFilterExpression(statement, environment);\n case \"FilterStatement\":\n return this.evaluateFilterStatement(statement, environment);\n case \"TestExpression\":\n return this.evaluateTestExpression(statement, environment);\n case \"SelectExpression\":\n return this.evaluateSelectExpression(statement, environment);\n case \"Ternary\":\n return this.evaluateTernaryExpression(statement, environment);\n case \"Comment\":\n return new NullValue();\n default:\n throw new SyntaxError(`Unknown node type: ${statement.type}`);\n }\n }\n};\nfunction convertToRuntimeValues(input) {\n switch (typeof input) {\n case \"number\":\n return Number.isInteger(input) ? new IntegerValue(input) : new FloatValue(input);\n case \"string\":\n return new StringValue(input);\n case \"boolean\":\n return new BooleanValue(input);\n case \"undefined\":\n return new UndefinedValue();\n case \"object\":\n if (input === null) {\n return new NullValue();\n } else if (Array.isArray(input)) {\n return new ArrayValue(input.map(convertToRuntimeValues));\n } else {\n return new ObjectValue(\n new Map(Object.entries(input).map(([key, value]) => [key, convertToRuntimeValues(value)]))\n );\n }\n case \"function\":\n return new FunctionValue((args, _scope) => {\n const result = input(...args.map((x) => x.value)) ?? null;\n return convertToRuntimeValues(result);\n });\n default:\n throw new Error(`Cannot convert to runtime value: ${input}`);\n }\n}\n\n// src/format.ts\nvar NEWLINE = \"\\n\";\nvar OPEN_STATEMENT = \"{%- \";\nvar CLOSE_STATEMENT = \" -%}\";\nvar PRECEDENCE = Object.freeze({\n CONDITIONAL: 0,\n // a if b else c\n LOGICAL_OR: 1,\n // or\n LOGICAL_AND: 2,\n // and\n LOGICAL_NOT: 3,\n // not a\n COMPARISON: 4,\n // == != < <= > >= in, not in\n ADDITIVE: 5,\n // + -\n MULTIPLICATIVE: 6,\n // * / // %\n EXPONENTIATION: 7,\n // **\n TEST: 8,\n // is\n FILTER: 9,\n // |\n UNARY_SIGN: 10,\n // -a +a\n ATOM: 11\n // literals, identifiers, calls, member accesses\n});\nfunction getBinaryOperatorPrecedence(expr) {\n switch (expr.operator.type) {\n case \"ExponentiationBinaryOperator\":\n return PRECEDENCE.EXPONENTIATION;\n case \"MultiplicativeBinaryOperator\":\n return PRECEDENCE.MULTIPLICATIVE;\n case \"AdditiveBinaryOperator\":\n return PRECEDENCE.ADDITIVE;\n case \"ComparisonBinaryOperator\":\n return PRECEDENCE.COMPARISON;\n case \"Identifier\":\n if (expr.operator.value === \"and\") {\n return PRECEDENCE.LOGICAL_AND;\n }\n if (expr.operator.value === \"in\" || expr.operator.value === \"not in\") {\n return PRECEDENCE.COMPARISON;\n }\n return PRECEDENCE.LOGICAL_OR;\n }\n return PRECEDENCE.LOGICAL_OR;\n}\nfunction getPrecedence(node) {\n switch (node.type) {\n case \"SelectExpression\":\n case \"Ternary\":\n return PRECEDENCE.CONDITIONAL;\n case \"BinaryExpression\":\n return getBinaryOperatorPrecedence(node);\n case \"UnaryExpression\":\n return node.operator.value === \"not\" ? PRECEDENCE.LOGICAL_NOT : PRECEDENCE.UNARY_SIGN;\n case \"TestExpression\":\n return PRECEDENCE.TEST;\n case \"FilterExpression\":\n return PRECEDENCE.FILTER;\n default:\n return PRECEDENCE.ATOM;\n }\n}\nfunction formatOperand(node, minPrecedence) {\n const expr = formatExpression(node);\n return getPrecedence(node) < minPrecedence ? `(${expr})` : expr;\n}\nfunction format(program, indent = \"\t\") {\n const indentStr = typeof indent === \"number\" ? \" \".repeat(indent) : indent;\n const body = formatStatements(program.body, 0, indentStr);\n return body.replace(/\\n$/, \"\");\n}\nfunction createStatement(...text) {\n return OPEN_STATEMENT + text.join(\" \") + CLOSE_STATEMENT;\n}\nfunction formatStatements(stmts, depth, indentStr) {\n return stmts.map((stmt) => formatStatement(stmt, depth, indentStr)).join(NEWLINE);\n}\nfunction formatExpressionList(expressions) {\n return expressions.map((expression) => formatExpression(expression)).join(\", \");\n}\nfunction formatStatement(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n switch (node.type) {\n case \"Program\":\n return formatStatements(node.body, depth, indentStr);\n case \"If\":\n return formatIf(node, depth, indentStr);\n case \"For\":\n return formatFor(node, depth, indentStr);\n case \"Set\":\n return formatSet(node, depth, indentStr);\n case \"Macro\":\n return formatMacro(node, depth, indentStr);\n case \"Break\":\n return pad + createStatement(\"break\");\n case \"Continue\":\n return pad + createStatement(\"continue\");\n case \"CallStatement\":\n return formatCallStatement(node, depth, indentStr);\n case \"FilterStatement\":\n return formatFilterStatement(node, depth, indentStr);\n case \"Comment\":\n return pad + \"{# \" + node.value + \" #}\";\n default:\n return pad + \"{{- \" + formatExpression(node) + \" -}}\";\n }\n}\nfunction formatIf(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const clauses = [];\n let current = node;\n while (current) {\n clauses.push({ test: current.test, body: current.body });\n if (current.alternate.length === 1 && current.alternate[0].type === \"If\") {\n current = current.alternate[0];\n } else {\n break;\n }\n }\n let out = pad + createStatement(\"if\", formatExpression(clauses[0].test)) + NEWLINE + formatStatements(clauses[0].body, depth + 1, indentStr);\n for (let i = 1; i < clauses.length; ++i) {\n out += NEWLINE + pad + createStatement(\"elif\", formatExpression(clauses[i].test)) + NEWLINE + formatStatements(clauses[i].body, depth + 1, indentStr);\n }\n if (current && current.alternate.length > 0) {\n out += NEWLINE + pad + createStatement(\"else\") + NEWLINE + formatStatements(current.alternate, depth + 1, indentStr);\n }\n out += NEWLINE + pad + createStatement(\"endif\");\n return out;\n}\nfunction formatFor(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n let formattedIterable = \"\";\n if (node.iterable.type === \"SelectExpression\") {\n const n = node.iterable;\n formattedIterable = `${formatExpression(n.lhs)} if ${formatExpression(n.test)}`;\n } else {\n formattedIterable = formatExpression(node.iterable);\n }\n let out = pad + createStatement(\"for\", formatExpression(node.loopvar), \"in\", formattedIterable) + NEWLINE + formatStatements(node.body, depth + 1, indentStr);\n if (node.defaultBlock.length > 0) {\n out += NEWLINE + pad + createStatement(\"else\") + NEWLINE + formatStatements(node.defaultBlock, depth + 1, indentStr);\n }\n out += NEWLINE + pad + createStatement(\"endfor\");\n return out;\n}\nfunction formatSet(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const left = formatExpression(node.assignee);\n const right = node.value ? formatExpression(node.value) : \"\";\n const value = pad + createStatement(\"set\", `${left}${node.value ? \" = \" + right : \"\"}`);\n if (node.body.length === 0) {\n return value;\n }\n return value + NEWLINE + formatStatements(node.body, depth + 1, indentStr) + NEWLINE + pad + createStatement(\"endset\");\n}\nfunction formatMacro(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const args = formatExpressionList(node.args);\n return pad + createStatement(\"macro\", `${node.name.value}(${args})`) + NEWLINE + formatStatements(node.body, depth + 1, indentStr) + NEWLINE + pad + createStatement(\"endmacro\");\n}\nfunction formatCallStatement(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const params = node.callerArgs && node.callerArgs.length > 0 ? `(${formatExpressionList(node.callerArgs)})` : \"\";\n const callExpr = formatExpression(node.call);\n let out = pad + createStatement(`call${params}`, callExpr) + NEWLINE;\n out += formatStatements(node.body, depth + 1, indentStr) + NEWLINE;\n out += pad + createStatement(\"endcall\");\n return out;\n}\nfunction formatFilterStatement(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const spec = node.filter.type === \"Identifier\" ? node.filter.value : formatExpression(node.filter);\n let out = pad + createStatement(\"filter\", spec) + NEWLINE;\n out += formatStatements(node.body, depth + 1, indentStr) + NEWLINE;\n out += pad + createStatement(\"endfilter\");\n return out;\n}\nfunction formatExpression(node) {\n switch (node.type) {\n case \"SpreadExpression\": {\n const n = node;\n return `*${formatExpression(n.argument)}`;\n }\n case \"KeywordSpreadExpression\": {\n const n = node;\n return `**${formatExpression(n.argument)}`;\n }\n case \"Identifier\":\n return node.value;\n case \"IntegerLiteral\":\n return `${node.value}`;\n case \"FloatLiteral\": {\n const value = node.value;\n if (Object.is(value, -0)) {\n return \"-0.0\";\n }\n return value % 1 === 0 ? value.toFixed(1) : value.toString();\n }\n case \"StringLiteral\":\n return JSON.stringify(node.value);\n case \"BinaryExpression\": {\n const n = node;\n const thisPrecedence = getBinaryOperatorPrecedence(n);\n const left = formatOperand(n.left, thisPrecedence);\n const right = formatOperand(n.right, thisPrecedence + 1);\n return `${left} ${n.operator.value} ${right}`;\n }\n case \"UnaryExpression\": {\n const n = node;\n const operandPrecedence = n.argument.type === \"UnaryExpression\" ? getPrecedence(n) : PRECEDENCE.ATOM;\n return n.operator.value + (n.operator.value === \"not\" ? \" \" : \"\") + formatOperand(n.argument, operandPrecedence);\n }\n case \"CallExpression\": {\n const n = node;\n const args = formatExpressionList(n.args);\n return `${formatExpression(n.callee)}(${args})`;\n }\n case \"MemberExpression\": {\n const n = node;\n const obj = formatOperand(n.object, PRECEDENCE.ATOM);\n let prop = formatExpression(n.property);\n if (!n.computed && n.property.type !== \"Identifier\" && n.property.type !== \"IntegerLiteral\") {\n prop = `(${prop})`;\n }\n return n.computed ? `${obj}[${prop}]` : `${obj}.${prop}`;\n }\n case \"FilterExpression\": {\n const n = node;\n const operand = formatOperand(n.operand, PRECEDENCE.FILTER);\n if (n.filter.type === \"CallExpression\") {\n return `${operand} | ${formatExpression(n.filter)}`;\n }\n return `${operand} | ${n.filter.value}`;\n }\n case \"SelectExpression\": {\n const n = node;\n return `${formatOperand(n.lhs, PRECEDENCE.LOGICAL_OR)} if ${formatOperand(n.test, PRECEDENCE.LOGICAL_OR)}`;\n }\n case \"TestExpression\": {\n const n = node;\n return `${formatOperand(n.operand, PRECEDENCE.TEST)} is${n.negate ? \" not\" : \"\"} ${n.test.value}`;\n }\n case \"ArrayLiteral\":\n case \"TupleLiteral\": {\n const elems = formatExpressionList(node.value);\n const brackets = node.type === \"ArrayLiteral\" ? \"[]\" : \"()\";\n return `${brackets[0]}${elems}${brackets[1]}`;\n }\n case \"ObjectLiteral\": {\n const entries = Array.from(node.value.entries()).map(\n ([k, v]) => `${formatExpression(k)}: ${formatExpression(v)}`\n );\n return `{${entries.join(\", \")}}`;\n }\n case \"SliceExpression\": {\n const n = node;\n const s = n.start ? formatExpression(n.start) : \"\";\n const t = n.stop ? formatExpression(n.stop) : \"\";\n const st = n.step ? `:${formatExpression(n.step)}` : \"\";\n return `${s}:${t}${st}`;\n }\n case \"KeywordArgumentExpression\": {\n const n = node;\n return `${n.key.value}=${formatExpression(n.value)}`;\n }\n case \"Ternary\": {\n const n = node;\n return `${formatOperand(n.trueExpr, PRECEDENCE.LOGICAL_OR)} if ${formatOperand(\n n.condition,\n PRECEDENCE.LOGICAL_OR\n )} else ${formatOperand(n.falseExpr, PRECEDENCE.CONDITIONAL)}`;\n }\n default:\n throw new Error(`Unknown expression type: ${node.type}`);\n }\n}\n\n// src/index.ts\nvar Template = class {\n parsed;\n /**\n * @param {string} template The template string\n */\n constructor(template) {\n const tokens = tokenize(template, {\n lstrip_blocks: true,\n trim_blocks: true\n });\n this.parsed = parse(tokens);\n }\n render(items) {\n const env = new Environment();\n setupGlobals(env);\n if (items) {\n for (const [key, value] of Object.entries(items)) {\n env.set(key, value);\n }\n }\n const interpreter = new Interpreter(env);\n const result = interpreter.run(this.parsed);\n return result.value;\n }\n format(options) {\n return format(this.parsed, options?.indent || \"\t\");\n }\n};\nexport {\n Environment,\n Interpreter,\n Template,\n parse,\n tokenize\n};\n","import { Template } from \"@huggingface/jinja\";\nimport { modelRegistry } from \"../model-registry.js\";\nimport { createModelCacheFetch } from \"./create-model-cache-fetch.js\";\nimport { sanitizeToolParameters } from \"./parse-local-model-tool-call.js\";\n\nexport interface TokenizerConfig {\n chat_template?: string | Record<string, string>;\n bos_token?: string | { content: string };\n eos_token?: string | { content: string };\n pad_token?: string | { content: string };\n unk_token?: string | { content: string };\n [key: string]: any;\n}\n\nexport interface ChatMessage {\n role: \"system\" | \"user\" | \"assistant\" | \"model\" | \"tool\";\n content: string | any[];\n tool_calls?: any[];\n [key: string]: any;\n}\n\nexport interface NormalizedChatMessage {\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string;\n tool_calls?: any[];\n [key: string]: any;\n}\n\nexport interface RenderChatTemplateOptions {\n modelName?: string;\n template?: string | Record<string, string>;\n messages: any[];\n systemPrompt?: string;\n tools?: any[];\n documents?: any[];\n addGenerationPrompt?: boolean;\n bosToken?: string;\n eosToken?: string;\n padToken?: string;\n unkToken?: string;\n customFetch?: typeof fetch;\n}\n\n/**\n * Universal default ChatML template used when an uncached model is accessed offline\n * or when no model-specific Jinja template is available.\n */\nexport const DEFAULT_CHAT_TEMPLATE = `{%- for message in messages -%}\n{{- '<|im_start|>' + message.role + '\\n' + message.content + '<|im_end|>\\n' -}}\n{%- endfor -%}\n{%- if add_generation_prompt -%}\n{{- '<|im_start|>assistant\\n' -}}\n{%- endif -%}`;\n\nconst tokenizerConfigCache = new Map<string, TokenizerConfig>();\nconst compiledTemplateCache = new Map<string, Template>();\n\n/**\n * Clears in-memory tokenizer config and compiled template caches (primarily for tests).\n */\nexport function clearTokenizerConfigCache(): void {\n tokenizerConfigCache.clear();\n compiledTemplateCache.clear();\n}\n\n/**\n * Extract plain text string from a message content field (string or block array).\n */\nexport function extractContentText(content: any): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (!content) {\n return \"\";\n }\n if (Array.isArray(content)) {\n return content\n .map((block: any) => {\n if (!block) return \"\";\n if (typeof block === \"string\") return block;\n if (block.type === \"text\") return block.text || block.value || \"\";\n if (block.type === \"tool_use\") {\n return `[TOOL_CALL ${block.name}] ${JSON.stringify(block.input || {})}`;\n }\n if (block.type === \"tool_result\") {\n const res =\n typeof block.content === \"string\"\n ? block.content\n : JSON.stringify(block.content || \"\");\n return `[TOOL_RESULT ${block.tool_use_id || \"\"}] ${res}`;\n }\n if (block.type === \"attachment\") {\n return `[ATTACHMENT ${block.mediaType || \"file\"}] ${block.fileName || \"attachment\"}`;\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (typeof content === \"object\") {\n return JSON.stringify(content);\n }\n return String(content);\n}\n\n/**\n * Dynamically fetch tokenizer_config.json for a given model from Hugging Face or persistent CacheStorage.\n */\nexport async function fetchTokenizerConfig(\n modelName: string,\n customFetch?: typeof fetch,\n): Promise<TokenizerConfig | null> {\n const cleanModel = String(modelName || \"\").trim();\n if (!cleanModel) {\n return null;\n }\n\n if (tokenizerConfigCache.has(cleanModel)) {\n return tokenizerConfigCache.get(cleanModel)!;\n }\n\n const baseFetch =\n customFetch ||\n (typeof globalThis.fetch === \"function\"\n ? globalThis.fetch.bind(globalThis)\n : undefined);\n\n if (!baseFetch) {\n return null;\n }\n\n // Use disk-backed model cache fetch if no custom fetch function is explicitly passed\n const fetchFn = customFetch || createModelCacheFetch(baseFetch);\n const url = `https://huggingface.co/${encodeURI(cleanModel)}/resolve/main/tokenizer_config.json`;\n\n try {\n const res = await fetchFn(url);\n if (res.ok) {\n const config: TokenizerConfig = await res.json();\n if (config && typeof config === \"object\") {\n // If tokenizer_config.json does not contain chat_template, check for standalone chat_template.jinja\n if (!config.chat_template) {\n try {\n const jinjaUrl = `https://huggingface.co/${encodeURI(cleanModel)}/resolve/main/chat_template.jinja`;\n const jinjaRes = await fetchFn(jinjaUrl);\n if (jinjaRes.ok) {\n const jinjaText = await jinjaRes.text();\n if (jinjaText && jinjaText.trim()) {\n config.chat_template = jinjaText.trim();\n }\n }\n } catch {\n // Ignore standalone jinja fetch failures\n }\n }\n\n if (\n typeof config.model_max_length === \"number\" &&\n Number.isFinite(config.model_max_length) &&\n config.model_max_length > 0 &&\n config.model_max_length <= 2_097_152\n ) {\n const existing = modelRegistry.getModelInfo(cleanModel);\n modelRegistry.registerModelInfo(cleanModel, {\n contextWindow: config.model_max_length,\n maxOutput: existing?.maxOutput ?? null,\n ...(existing || {}),\n });\n }\n\n tokenizerConfigCache.set(cleanModel, config);\n return config;\n }\n }\n } catch (err) {\n // Network or parse error\n }\n\n return null;\n}\n\n/**\n * Map tools to the standard OpenAI/Transformers function format.\n */\nexport function mapToolsForChatTemplate(tools?: any[]): any[] | undefined {\n if (!tools || !Array.isArray(tools) || tools.length === 0) {\n return undefined;\n }\n\n return tools.map((t) => {\n if (t.type === \"function\" && t.function) {\n return {\n ...t,\n function: {\n ...t.function,\n parameters: sanitizeToolParameters(t.function.parameters),\n },\n };\n }\n return {\n type: \"function\",\n function: {\n name: t.name,\n description: t.description || \"\",\n parameters: sanitizeToolParameters(t.input_schema || t.parameters),\n },\n };\n });\n}\n\n/**\n * Normalizes messages to ensure compliance with strict chat template requirements:\n * 1. Consolidates system prompt into a single initial system message.\n * 2. Merges adjacent messages of identical role (e.g. consecutive user turns).\n * 3. Ensures strict user -> assistant -> user alternation.\n * 4. Ensures first turn after system is a user message.\n */\nexport function normalizeMessagesForChatTemplate(\n rawMessages: any[],\n systemPrompt?: string,\n): NormalizedChatMessage[] {\n let combinedSystemText = String(systemPrompt || \"\").trim();\n const nonSystem: NormalizedChatMessage[] = [];\n\n // Map known tool_call ids to their function names to resolve tool messages cleanly\n const toolCallNameById = new Map<string, string>();\n for (const msg of rawMessages) {\n if (msg?.tool_calls && Array.isArray(msg.tool_calls)) {\n for (const tc of msg.tool_calls) {\n const id = tc?.id || tc?.tool_call_id;\n const name = tc?.function?.name || tc?.name;\n if (id && name) {\n toolCallNameById.set(id, name);\n }\n }\n }\n if (Array.isArray(msg?.content)) {\n for (const b of msg.content) {\n if (b?.type === \"tool_use\" && b.id && b.name) {\n toolCallNameById.set(b.id, b.name);\n }\n }\n }\n }\n\n for (const msg of rawMessages) {\n if (!msg) continue;\n const rawRole = String(msg.role || \"user\").toLowerCase();\n const contentText = extractContentText(msg.content);\n\n if (rawRole === \"system\") {\n combinedSystemText = combinedSystemText\n ? `${combinedSystemText}\\n\\n${contentText}`\n : contentText;\n } else if (rawRole === \"tool\") {\n const resolvedName =\n msg.name ||\n (msg.tool_call_id\n ? toolCallNameById.get(msg.tool_call_id)\n : undefined) ||\n \"unknown\";\n nonSystem.push({\n role: \"tool\",\n content: contentText,\n ...(msg.tool_call_id ? { tool_call_id: msg.tool_call_id } : {}),\n name: resolvedName,\n });\n } else if (rawRole === \"assistant\" || rawRole === \"model\") {\n let toolCalls = msg.tool_calls;\n let textContent = contentText;\n\n if (Array.isArray(msg.content)) {\n const toolUseBlocks = msg.content.filter(\n (b: any) => b?.type === \"tool_use\",\n );\n if (toolUseBlocks.length > 0) {\n if (!toolCalls) {\n toolCalls = toolUseBlocks.map((b: any) => ({\n id: b.id || `call_${Math.random().toString(36).slice(2, 9)}`,\n type: \"function\",\n function: {\n name: b.name,\n arguments:\n typeof b.input === \"object\" && b.input !== null\n ? b.input\n : {},\n },\n }));\n }\n const textBlocks = msg.content.filter(\n (b: any) => b?.type !== \"tool_use\",\n );\n textContent = extractContentText(textBlocks);\n }\n }\n\n if (Array.isArray(toolCalls)) {\n toolCalls = toolCalls.map((tc: any) => {\n if (!tc || typeof tc !== \"object\") return tc;\n const fn = tc.function;\n if (\n fn &&\n typeof fn === \"object\" &&\n typeof fn.arguments === \"string\"\n ) {\n try {\n const parsedArgs = JSON.parse(fn.arguments);\n if (\n parsedArgs &&\n typeof parsedArgs === \"object\" &&\n !Array.isArray(parsedArgs)\n ) {\n return {\n ...tc,\n function: {\n ...fn,\n arguments: parsedArgs,\n },\n };\n }\n } catch {\n // Leave as string if not valid JSON\n }\n }\n return tc;\n });\n }\n nonSystem.push({\n role: \"assistant\",\n content: textContent,\n ...(toolCalls ? { tool_calls: toolCalls } : {}),\n });\n } else if (\n Array.isArray(msg.content) &&\n msg.content.some((b: any) => b?.type === \"tool_result\")\n ) {\n for (const b of msg.content) {\n if (b?.type === \"tool_result\") {\n const res =\n typeof b.content === \"string\"\n ? b.content\n : JSON.stringify(b.content || \"\");\n const resolvedName =\n b.name ||\n (b.tool_use_id ? toolCallNameById.get(b.tool_use_id) : undefined) ||\n \"unknown\";\n nonSystem.push({\n role: \"tool\",\n content: res,\n ...(b.tool_use_id ? { tool_call_id: b.tool_use_id } : {}),\n name: resolvedName,\n });\n } else {\n const nonToolText = extractContentText([b]);\n if (nonToolText) {\n nonSystem.push({ role: \"user\", content: nonToolText });\n }\n }\n }\n } else {\n nonSystem.push({ role: \"user\", content: contentText });\n }\n }\n\n // Merge consecutive messages with the same role\n const merged: NormalizedChatMessage[] = [];\n for (const msg of nonSystem) {\n if (\n merged.length > 0 &&\n merged[merged.length - 1].role === msg.role &&\n msg.role !== \"tool\"\n ) {\n const prev = merged[merged.length - 1];\n prev.content = prev.content\n ? `${prev.content}\\n\\n${msg.content}`\n : msg.content;\n if (msg.tool_calls) {\n prev.tool_calls = [...(prev.tool_calls || []), ...msg.tool_calls];\n }\n } else {\n merged.push({ ...msg });\n }\n }\n\n // If conversation starts with an assistant message, insert an initial user prompt\n if (merged.length > 0 && merged[0].role === \"assistant\") {\n merged.unshift({ role: \"user\", content: \"Hello\" });\n }\n\n // If conversation is completely empty, provide a default user turn\n if (merged.length === 0 && !combinedSystemText) {\n merged.push({ role: \"user\", content: \"Hello\" });\n }\n\n const result: NormalizedChatMessage[] = [];\n if (combinedSystemText) {\n result.push({ role: \"system\", content: combinedSystemText });\n }\n result.push(...merged);\n\n return result;\n}\n\n/**\n * Render dynamic Jinja2 chat template for messages, tools, and options.\n */\nexport async function renderChatTemplate(\n options: RenderChatTemplateOptions,\n): Promise<string> {\n const {\n modelName = \"\",\n messages,\n systemPrompt,\n tools,\n documents,\n addGenerationPrompt = true,\n customFetch,\n } = options;\n\n let templateStr: string | null = null;\n\n if (typeof options.template === \"string\") {\n templateStr = options.template;\n } else if (options.template && typeof options.template === \"object\") {\n if (tools && tools.length > 0 && \"tool_use\" in options.template) {\n templateStr = (options.template as Record<string, string>)[\"tool_use\"];\n } else if (\"default\" in options.template) {\n templateStr = (options.template as Record<string, string>)[\"default\"];\n }\n }\n\n let bosToken = options.bosToken;\n let eosToken = options.eosToken;\n\n if (!templateStr && modelName) {\n const config = await fetchTokenizerConfig(modelName, customFetch);\n if (config) {\n if (typeof config.chat_template === \"string\") {\n templateStr = config.chat_template;\n } else if (\n config.chat_template &&\n typeof config.chat_template === \"object\"\n ) {\n if (tools && tools.length > 0 && \"tool_use\" in config.chat_template) {\n templateStr = config.chat_template[\"tool_use\"];\n } else if (\"default\" in config.chat_template) {\n templateStr = config.chat_template[\"default\"];\n }\n }\n if (!bosToken && config.bos_token) {\n bosToken =\n typeof config.bos_token === \"string\"\n ? config.bos_token\n : config.bos_token.content;\n }\n if (!eosToken && config.eos_token) {\n eosToken =\n typeof config.eos_token === \"string\"\n ? config.eos_token\n : config.eos_token.content;\n }\n }\n }\n\n // Universal fallback template if still not found\n if (!templateStr) {\n templateStr = DEFAULT_CHAT_TEMPLATE;\n }\n\n const normalized = normalizeMessagesForChatTemplate(messages, systemPrompt);\n const mappedTools = mapToolsForChatTemplate(tools);\n\n let compiled = compiledTemplateCache.get(templateStr);\n if (!compiled) {\n compiled = new Template(templateStr);\n compiledTemplateCache.set(templateStr, compiled);\n }\n\n return compiled.render({\n messages: normalized,\n tools: mappedTools,\n documents: documents || null,\n add_generation_prompt: addGenerationPrompt,\n bos_token: bosToken || \"\",\n eos_token: eosToken || \"\",\n pad_token: options.padToken || \"\",\n unk_token: options.unkToken || \"\",\n });\n}\n"],"ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chat-template-DPEKGJhB.js","names":[],"sources":["../../node_modules/@huggingface/jinja/dist/index.js","../../src/subsystems/providers/utils/chat-template.ts"],"sourcesContent":["var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => {\n __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n return value;\n};\n\n// src/lexer.ts\nvar TOKEN_TYPES = Object.freeze({\n Text: \"Text\",\n // The text between Jinja statements or expressions\n NumericLiteral: \"NumericLiteral\",\n // e.g., 123, 1.0\n StringLiteral: \"StringLiteral\",\n // 'string'\n Identifier: \"Identifier\",\n // Variables, functions, statements, booleans, etc.\n Equals: \"Equals\",\n // =\n OpenParen: \"OpenParen\",\n // (\n CloseParen: \"CloseParen\",\n // )\n OpenStatement: \"OpenStatement\",\n // {%\n CloseStatement: \"CloseStatement\",\n // %}\n OpenExpression: \"OpenExpression\",\n // {{\n CloseExpression: \"CloseExpression\",\n // }}\n OpenSquareBracket: \"OpenSquareBracket\",\n // [\n CloseSquareBracket: \"CloseSquareBracket\",\n // ]\n OpenCurlyBracket: \"OpenCurlyBracket\",\n // {\n CloseCurlyBracket: \"CloseCurlyBracket\",\n // }\n Comma: \"Comma\",\n // ,\n Dot: \"Dot\",\n // .\n Colon: \"Colon\",\n // :\n Pipe: \"Pipe\",\n // |\n CallOperator: \"CallOperator\",\n // ()\n AdditiveBinaryOperator: \"AdditiveBinaryOperator\",\n // + - ~\n MultiplicativeBinaryOperator: \"MultiplicativeBinaryOperator\",\n // * / // %\n ExponentiationBinaryOperator: \"ExponentiationBinaryOperator\",\n // **\n ComparisonBinaryOperator: \"ComparisonBinaryOperator\",\n // < > <= >= == !=\n UnaryOperator: \"UnaryOperator\",\n // ! - +\n Comment: \"Comment\"\n // {# ... #}\n});\nvar Token = class {\n /**\n * Constructs a new Token.\n * @param {string} value The raw value as seen inside the source code.\n * @param {TokenType} type The type of token.\n */\n constructor(value, type) {\n this.value = value;\n this.type = type;\n }\n};\nfunction isWord(char) {\n return /\\w/.test(char);\n}\nfunction isInteger(char) {\n return /[0-9]/.test(char);\n}\nfunction isWhitespace(char) {\n return /\\s/.test(char);\n}\nvar ORDERED_MAPPING_TABLE = [\n // Control sequences\n [\"{%\", TOKEN_TYPES.OpenStatement],\n [\"%}\", TOKEN_TYPES.CloseStatement],\n [\"{{\", TOKEN_TYPES.OpenExpression],\n [\"}}\", TOKEN_TYPES.CloseExpression],\n // Single character tokens\n [\"(\", TOKEN_TYPES.OpenParen],\n [\")\", TOKEN_TYPES.CloseParen],\n [\"{\", TOKEN_TYPES.OpenCurlyBracket],\n [\"}\", TOKEN_TYPES.CloseCurlyBracket],\n [\"[\", TOKEN_TYPES.OpenSquareBracket],\n [\"]\", TOKEN_TYPES.CloseSquareBracket],\n [\",\", TOKEN_TYPES.Comma],\n [\".\", TOKEN_TYPES.Dot],\n [\":\", TOKEN_TYPES.Colon],\n [\"|\", TOKEN_TYPES.Pipe],\n // Comparison operators\n [\"<=\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\">=\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\"==\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\"!=\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\"<\", TOKEN_TYPES.ComparisonBinaryOperator],\n [\">\", TOKEN_TYPES.ComparisonBinaryOperator],\n // Arithmetic operators\n [\"+\", TOKEN_TYPES.AdditiveBinaryOperator],\n [\"-\", TOKEN_TYPES.AdditiveBinaryOperator],\n [\"~\", TOKEN_TYPES.AdditiveBinaryOperator],\n [\"**\", TOKEN_TYPES.ExponentiationBinaryOperator],\n // NOTE: must come before \"*\" so that \"**\" is matched first\n [\"*\", TOKEN_TYPES.MultiplicativeBinaryOperator],\n [\"//\", TOKEN_TYPES.MultiplicativeBinaryOperator],\n // NOTE: must come before \"/\" so that \"//\" is matched first\n [\"/\", TOKEN_TYPES.MultiplicativeBinaryOperator],\n [\"%\", TOKEN_TYPES.MultiplicativeBinaryOperator],\n // Assignment operator\n [\"=\", TOKEN_TYPES.Equals]\n];\nvar ESCAPE_CHARACTERS = /* @__PURE__ */ new Map([\n [\"n\", \"\\n\"],\n // New line\n [\"t\", \"\t\"],\n // Horizontal tab\n [\"r\", \"\\r\"],\n // Carriage return\n [\"b\", \"\\b\"],\n // Backspace\n [\"f\", \"\\f\"],\n // Form feed\n [\"v\", \"\\v\"],\n // Vertical tab\n [\"'\", \"'\"],\n // Single quote\n ['\"', '\"'],\n // Double quote\n [\"\\\\\", \"\\\\\"]\n // Backslash\n]);\nfunction preprocess(template, options = {}) {\n if (template.endsWith(\"\\n\")) {\n template = template.slice(0, -1);\n }\n if (options.lstrip_blocks) {\n template = template.replace(/^[ \\t]*({[#%-])/gm, \"$1\");\n }\n if (options.trim_blocks) {\n template = template.replace(/([#%-]})\\n/g, \"$1\");\n }\n return template.replace(\n /(\\s*){%(-?)\\s*(?:end)?generation\\s*(-?)%}(\\s*)/gs,\n (_, before, lstrip, rstrip, after) => (lstrip ? \"\" : before) + (rstrip ? \"\" : after)\n );\n}\nfunction tokenize(source, options = {}) {\n const tokens = [];\n const src = preprocess(source, options);\n let cursorPosition = 0;\n let curlyBracketDepth = 0;\n const consumeWhile = (predicate) => {\n let str = \"\";\n while (predicate(src[cursorPosition])) {\n if (src[cursorPosition] === \"\\\\\") {\n ++cursorPosition;\n if (cursorPosition >= src.length) {\n throw new SyntaxError(\"Unexpected end of input\");\n }\n const escaped = src[cursorPosition++];\n const unescaped = ESCAPE_CHARACTERS.get(escaped);\n if (unescaped === void 0) {\n throw new SyntaxError(`Unexpected escaped character: ${escaped}`);\n }\n str += unescaped;\n continue;\n }\n str += src[cursorPosition++];\n if (cursorPosition >= src.length) {\n throw new SyntaxError(\"Unexpected end of input\");\n }\n }\n return str;\n };\n const stripTrailingWhitespace = () => {\n const lastToken = tokens.at(-1);\n if (lastToken && lastToken.type === TOKEN_TYPES.Text) {\n lastToken.value = lastToken.value.trimEnd();\n if (lastToken.value === \"\") {\n tokens.pop();\n }\n }\n };\n const skipLeadingWhitespace = () => {\n while (cursorPosition < src.length && isWhitespace(src[cursorPosition])) {\n ++cursorPosition;\n }\n };\n main:\n while (cursorPosition < src.length) {\n const lastTokenType = tokens.at(-1)?.type;\n if (lastTokenType === void 0 || lastTokenType === TOKEN_TYPES.CloseStatement || lastTokenType === TOKEN_TYPES.CloseExpression || lastTokenType === TOKEN_TYPES.Comment) {\n let text = \"\";\n while (cursorPosition < src.length && // Keep going until we hit the next Jinja statement or expression\n !(src[cursorPosition] === \"{\" && (src[cursorPosition + 1] === \"%\" || src[cursorPosition + 1] === \"{\" || src[cursorPosition + 1] === \"#\"))) {\n text += src[cursorPosition++];\n }\n if (text.length > 0) {\n tokens.push(new Token(text, TOKEN_TYPES.Text));\n continue;\n }\n }\n if (src[cursorPosition] === \"{\" && src[cursorPosition + 1] === \"#\") {\n cursorPosition += 2;\n const stripBefore = src[cursorPosition] === \"-\";\n if (stripBefore) {\n ++cursorPosition;\n }\n let comment = \"\";\n while (src[cursorPosition] !== \"#\" || src[cursorPosition + 1] !== \"}\") {\n if (cursorPosition + 2 >= src.length) {\n throw new SyntaxError(\"Missing end of comment tag\");\n }\n comment += src[cursorPosition++];\n }\n const stripAfter = comment.endsWith(\"-\");\n if (stripAfter) {\n comment = comment.slice(0, -1);\n }\n if (stripBefore) {\n stripTrailingWhitespace();\n }\n tokens.push(new Token(comment, TOKEN_TYPES.Comment));\n cursorPosition += 2;\n if (stripAfter) {\n skipLeadingWhitespace();\n }\n continue;\n }\n if (src.slice(cursorPosition, cursorPosition + 3) === \"{%-\") {\n stripTrailingWhitespace();\n tokens.push(new Token(\"{%\", TOKEN_TYPES.OpenStatement));\n cursorPosition += 3;\n continue;\n }\n if (src.slice(cursorPosition, cursorPosition + 3) === \"{{-\") {\n stripTrailingWhitespace();\n tokens.push(new Token(\"{{\", TOKEN_TYPES.OpenExpression));\n curlyBracketDepth = 0;\n cursorPosition += 3;\n continue;\n }\n consumeWhile(isWhitespace);\n if (src.slice(cursorPosition, cursorPosition + 3) === \"-%}\") {\n tokens.push(new Token(\"%}\", TOKEN_TYPES.CloseStatement));\n cursorPosition += 3;\n skipLeadingWhitespace();\n continue;\n }\n if (src.slice(cursorPosition, cursorPosition + 3) === \"-}}\") {\n tokens.push(new Token(\"}}\", TOKEN_TYPES.CloseExpression));\n cursorPosition += 3;\n skipLeadingWhitespace();\n continue;\n }\n const char = src[cursorPosition];\n if (char === \"-\" || char === \"+\") {\n const lastTokenType2 = tokens.at(-1)?.type;\n if (lastTokenType2 === TOKEN_TYPES.Text || lastTokenType2 === void 0) {\n throw new SyntaxError(`Unexpected character: ${char}`);\n }\n switch (lastTokenType2) {\n case TOKEN_TYPES.Identifier:\n case TOKEN_TYPES.NumericLiteral:\n case TOKEN_TYPES.StringLiteral:\n case TOKEN_TYPES.CloseParen:\n case TOKEN_TYPES.CloseSquareBracket:\n break;\n default: {\n ++cursorPosition;\n let num = consumeWhile(isInteger);\n if (num.length > 0 && src[cursorPosition] === \".\" && isInteger(src[cursorPosition + 1])) {\n ++cursorPosition;\n const frac = consumeWhile(isInteger);\n num = `${num}.${frac}`;\n }\n tokens.push(\n new Token(`${char}${num}`, num.length > 0 ? TOKEN_TYPES.NumericLiteral : TOKEN_TYPES.UnaryOperator)\n );\n continue;\n }\n }\n }\n for (const [seq, type] of ORDERED_MAPPING_TABLE) {\n if (seq === \"}}\" && curlyBracketDepth > 0) {\n continue;\n }\n const slice2 = src.slice(cursorPosition, cursorPosition + seq.length);\n if (slice2 === seq) {\n tokens.push(new Token(seq, type));\n if (type === TOKEN_TYPES.OpenExpression) {\n curlyBracketDepth = 0;\n } else if (type === TOKEN_TYPES.OpenCurlyBracket) {\n ++curlyBracketDepth;\n } else if (type === TOKEN_TYPES.CloseCurlyBracket) {\n --curlyBracketDepth;\n }\n cursorPosition += seq.length;\n continue main;\n }\n }\n if (char === \"'\" || char === '\"') {\n ++cursorPosition;\n const str = consumeWhile((c) => c !== char);\n tokens.push(new Token(str, TOKEN_TYPES.StringLiteral));\n ++cursorPosition;\n continue;\n }\n if (isInteger(char)) {\n let num = consumeWhile(isInteger);\n if (tokens.at(-1)?.type !== TOKEN_TYPES.Dot && src[cursorPosition] === \".\" && isInteger(src[cursorPosition + 1])) {\n ++cursorPosition;\n const frac = consumeWhile(isInteger);\n num = `${num}.${frac}`;\n }\n tokens.push(new Token(num, TOKEN_TYPES.NumericLiteral));\n continue;\n }\n if (isWord(char)) {\n const word = consumeWhile(isWord);\n tokens.push(new Token(word, TOKEN_TYPES.Identifier));\n continue;\n }\n throw new SyntaxError(`Unexpected character: ${char}`);\n }\n return tokens;\n}\n\n// src/ast.ts\nvar Statement = class {\n type = \"Statement\";\n};\nvar Program = class extends Statement {\n constructor(body) {\n super();\n this.body = body;\n }\n type = \"Program\";\n};\nvar If = class extends Statement {\n constructor(test, body, alternate) {\n super();\n this.test = test;\n this.body = body;\n this.alternate = alternate;\n }\n type = \"If\";\n};\nvar For = class extends Statement {\n constructor(loopvar, iterable, body, defaultBlock) {\n super();\n this.loopvar = loopvar;\n this.iterable = iterable;\n this.body = body;\n this.defaultBlock = defaultBlock;\n }\n type = \"For\";\n};\nvar Break = class extends Statement {\n type = \"Break\";\n};\nvar Continue = class extends Statement {\n type = \"Continue\";\n};\nvar SetStatement = class extends Statement {\n constructor(assignee, value, body) {\n super();\n this.assignee = assignee;\n this.value = value;\n this.body = body;\n }\n type = \"Set\";\n};\nvar Macro = class extends Statement {\n constructor(name, args, body) {\n super();\n this.name = name;\n this.args = args;\n this.body = body;\n }\n type = \"Macro\";\n};\nvar Comment = class extends Statement {\n constructor(value) {\n super();\n this.value = value;\n }\n type = \"Comment\";\n};\nvar Expression = class extends Statement {\n type = \"Expression\";\n};\nvar MemberExpression = class extends Expression {\n constructor(object, property, computed) {\n super();\n this.object = object;\n this.property = property;\n this.computed = computed;\n }\n type = \"MemberExpression\";\n};\nvar CallExpression = class extends Expression {\n constructor(callee, args) {\n super();\n this.callee = callee;\n this.args = args;\n }\n type = \"CallExpression\";\n};\nvar Identifier = class extends Expression {\n /**\n * @param {string} value The name of the identifier\n */\n constructor(value) {\n super();\n this.value = value;\n }\n type = \"Identifier\";\n};\nvar Literal = class extends Expression {\n constructor(value) {\n super();\n this.value = value;\n }\n type = \"Literal\";\n};\nvar IntegerLiteral = class extends Literal {\n type = \"IntegerLiteral\";\n};\nvar FloatLiteral = class extends Literal {\n type = \"FloatLiteral\";\n};\nvar StringLiteral = class extends Literal {\n type = \"StringLiteral\";\n};\nvar ArrayLiteral = class extends Literal {\n type = \"ArrayLiteral\";\n};\nvar TupleLiteral = class extends Literal {\n type = \"TupleLiteral\";\n};\nvar ObjectLiteral = class extends Literal {\n type = \"ObjectLiteral\";\n};\nvar BinaryExpression = class extends Expression {\n constructor(operator, left, right) {\n super();\n this.operator = operator;\n this.left = left;\n this.right = right;\n }\n type = \"BinaryExpression\";\n};\nvar FilterExpression = class extends Expression {\n constructor(operand, filter) {\n super();\n this.operand = operand;\n this.filter = filter;\n }\n type = \"FilterExpression\";\n};\nvar FilterStatement = class extends Statement {\n constructor(filter, body) {\n super();\n this.filter = filter;\n this.body = body;\n }\n type = \"FilterStatement\";\n};\nvar SelectExpression = class extends Expression {\n constructor(lhs, test) {\n super();\n this.lhs = lhs;\n this.test = test;\n }\n type = \"SelectExpression\";\n};\nvar TestExpression = class extends Expression {\n constructor(operand, negate, test) {\n super();\n this.operand = operand;\n this.negate = negate;\n this.test = test;\n }\n type = \"TestExpression\";\n};\nvar UnaryExpression = class extends Expression {\n constructor(operator, argument) {\n super();\n this.operator = operator;\n this.argument = argument;\n }\n type = \"UnaryExpression\";\n};\nvar SliceExpression = class extends Expression {\n constructor(start = void 0, stop = void 0, step = void 0) {\n super();\n this.start = start;\n this.stop = stop;\n this.step = step;\n }\n type = \"SliceExpression\";\n};\nvar KeywordArgumentExpression = class extends Expression {\n constructor(key, value) {\n super();\n this.key = key;\n this.value = value;\n }\n type = \"KeywordArgumentExpression\";\n};\nvar SpreadExpression = class extends Expression {\n constructor(argument) {\n super();\n this.argument = argument;\n }\n type = \"SpreadExpression\";\n};\nvar KeywordSpreadExpression = class extends Expression {\n constructor(argument) {\n super();\n this.argument = argument;\n }\n type = \"KeywordSpreadExpression\";\n};\nvar CallStatement = class extends Statement {\n constructor(call, callerArgs, body) {\n super();\n this.call = call;\n this.callerArgs = callerArgs;\n this.body = body;\n }\n type = \"CallStatement\";\n};\nvar Ternary = class extends Expression {\n constructor(condition, trueExpr, falseExpr) {\n super();\n this.condition = condition;\n this.trueExpr = trueExpr;\n this.falseExpr = falseExpr;\n }\n type = \"Ternary\";\n};\n\n// src/parser.ts\nfunction parse(tokens) {\n const program = new Program([]);\n let current = 0;\n function expect(type, error) {\n const prev = tokens[current++];\n if (!prev || prev.type !== type) {\n throw new Error(`Parser Error: ${error}. ${prev.type} !== ${type}.`);\n }\n return prev;\n }\n function expectIdentifier(name) {\n if (!isIdentifier(name)) {\n throw new SyntaxError(`Expected ${name}`);\n }\n ++current;\n }\n function parseAny() {\n switch (tokens[current].type) {\n case TOKEN_TYPES.Comment:\n return new Comment(tokens[current++].value);\n case TOKEN_TYPES.Text:\n return parseText();\n case TOKEN_TYPES.OpenStatement:\n return parseJinjaStatement();\n case TOKEN_TYPES.OpenExpression:\n return parseJinjaExpression();\n default:\n throw new SyntaxError(`Unexpected token type: ${tokens[current].type}`);\n }\n }\n function is(...types) {\n return current + types.length <= tokens.length && types.every((type, i) => type === tokens[current + i].type);\n }\n function isStatement(...names) {\n return tokens[current]?.type === TOKEN_TYPES.OpenStatement && tokens[current + 1]?.type === TOKEN_TYPES.Identifier && names.includes(tokens[current + 1]?.value);\n }\n function isIdentifier(...names) {\n return current + names.length <= tokens.length && names.every((name, i) => tokens[current + i].type === \"Identifier\" && name === tokens[current + i].value);\n }\n function parseText() {\n return new StringLiteral(expect(TOKEN_TYPES.Text, \"Expected text token\").value);\n }\n function parseJinjaStatement() {\n expect(TOKEN_TYPES.OpenStatement, \"Expected opening statement token\");\n if (tokens[current].type !== TOKEN_TYPES.Identifier) {\n throw new SyntaxError(`Unknown statement, got ${tokens[current].type}`);\n }\n const name = tokens[current].value;\n let result;\n switch (name) {\n case \"set\":\n ++current;\n result = parseSetStatement();\n break;\n case \"if\":\n ++current;\n result = parseIfStatement();\n expect(TOKEN_TYPES.OpenStatement, \"Expected {% token\");\n expectIdentifier(\"endif\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected %} token\");\n break;\n case \"macro\":\n ++current;\n result = parseMacroStatement();\n expect(TOKEN_TYPES.OpenStatement, \"Expected {% token\");\n expectIdentifier(\"endmacro\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected %} token\");\n break;\n case \"for\":\n ++current;\n result = parseForStatement();\n expect(TOKEN_TYPES.OpenStatement, \"Expected {% token\");\n expectIdentifier(\"endfor\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected %} token\");\n break;\n case \"call\": {\n ++current;\n let callerArgs = null;\n if (is(TOKEN_TYPES.OpenParen)) {\n callerArgs = parseArgs(\"parameters\");\n }\n const callee = parsePrimaryExpression();\n if (callee.type !== \"Identifier\") {\n throw new SyntaxError(`Expected identifier following call statement`);\n }\n const callArgs = parseArgs(\"call\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const body = [];\n while (!isStatement(\"endcall\")) {\n body.push(parseAny());\n }\n expect(TOKEN_TYPES.OpenStatement, \"Expected '{%'\");\n expectIdentifier(\"endcall\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const callExpr = new CallExpression(callee, callArgs);\n result = new CallStatement(callExpr, callerArgs, body);\n break;\n }\n case \"break\":\n ++current;\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n result = new Break();\n break;\n case \"continue\":\n ++current;\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n result = new Continue();\n break;\n case \"filter\": {\n ++current;\n let filterNode = parsePrimaryExpression();\n if (filterNode instanceof Identifier && is(TOKEN_TYPES.OpenParen)) {\n filterNode = parseCallExpression(filterNode);\n }\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const filterBody = [];\n while (!isStatement(\"endfilter\")) {\n filterBody.push(parseAny());\n }\n expect(TOKEN_TYPES.OpenStatement, \"Expected '{%'\");\n expectIdentifier(\"endfilter\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected '%}'\");\n result = new FilterStatement(filterNode, filterBody);\n break;\n }\n default:\n throw new SyntaxError(`Unknown statement type: ${name}`);\n }\n return result;\n }\n function parseJinjaExpression() {\n expect(TOKEN_TYPES.OpenExpression, \"Expected opening expression token\");\n const result = parseExpression();\n expect(TOKEN_TYPES.CloseExpression, \"Expected closing expression token\");\n return result;\n }\n function parseSetStatement() {\n const left = parseExpressionSequence();\n let value = null;\n const body = [];\n if (is(TOKEN_TYPES.Equals)) {\n ++current;\n value = parseExpressionSequence();\n } else {\n expect(TOKEN_TYPES.CloseStatement, \"Expected %} token\");\n while (!isStatement(\"endset\")) {\n body.push(parseAny());\n }\n expect(TOKEN_TYPES.OpenStatement, \"Expected {% token\");\n expectIdentifier(\"endset\");\n }\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n return new SetStatement(left, value, body);\n }\n function parseIfStatement() {\n const test = parseExpression();\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const body = [];\n const alternate = [];\n while (!isStatement(\"elif\", \"else\", \"endif\")) {\n body.push(parseAny());\n }\n if (isStatement(\"elif\")) {\n ++current;\n ++current;\n const result = parseIfStatement();\n alternate.push(result);\n } else if (isStatement(\"else\")) {\n ++current;\n ++current;\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n while (!isStatement(\"endif\")) {\n alternate.push(parseAny());\n }\n }\n return new If(test, body, alternate);\n }\n function parseMacroStatement() {\n const name = parsePrimaryExpression();\n if (name.type !== \"Identifier\") {\n throw new SyntaxError(`Expected identifier following macro statement`);\n }\n const args = parseArgs(\"parameters\");\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const body = [];\n while (!isStatement(\"endmacro\")) {\n body.push(parseAny());\n }\n return new Macro(name, args, body);\n }\n function parseExpressionSequence(primary = false) {\n const fn = primary ? parsePrimaryExpression : parseExpression;\n const expressions = [fn()];\n const isTuple = is(TOKEN_TYPES.Comma);\n while (isTuple) {\n ++current;\n expressions.push(fn());\n if (!is(TOKEN_TYPES.Comma)) {\n break;\n }\n }\n return isTuple ? new TupleLiteral(expressions) : expressions[0];\n }\n function parseForStatement() {\n const loopVariable = parseExpressionSequence(true);\n if (!(loopVariable instanceof Identifier || loopVariable instanceof TupleLiteral)) {\n throw new SyntaxError(`Expected identifier/tuple for the loop variable, got ${loopVariable.type} instead`);\n }\n if (!isIdentifier(\"in\")) {\n throw new SyntaxError(\"Expected `in` keyword following loop variable\");\n }\n ++current;\n const iterable = parseExpression();\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n const body = [];\n while (!isStatement(\"endfor\", \"else\")) {\n body.push(parseAny());\n }\n const alternative = [];\n if (isStatement(\"else\")) {\n ++current;\n ++current;\n expect(TOKEN_TYPES.CloseStatement, \"Expected closing statement token\");\n while (!isStatement(\"endfor\")) {\n alternative.push(parseAny());\n }\n }\n return new For(loopVariable, iterable, body, alternative);\n }\n function parseExpression() {\n return parseIfExpression();\n }\n function parseIfExpression() {\n const a = parseLogicalOrExpression();\n if (isIdentifier(\"if\")) {\n ++current;\n const test = parseLogicalOrExpression();\n if (isIdentifier(\"else\")) {\n ++current;\n const falseExpr = parseIfExpression();\n return new Ternary(test, a, falseExpr);\n } else {\n return new SelectExpression(a, test);\n }\n }\n return a;\n }\n function parseLogicalOrExpression() {\n let left = parseLogicalAndExpression();\n while (isIdentifier(\"or\")) {\n const operator = tokens[current];\n ++current;\n const right = parseLogicalAndExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseLogicalAndExpression() {\n let left = parseLogicalNegationExpression();\n while (isIdentifier(\"and\")) {\n const operator = tokens[current];\n ++current;\n const right = parseLogicalNegationExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseLogicalNegationExpression() {\n let right;\n while (isIdentifier(\"not\")) {\n const operator = tokens[current];\n ++current;\n const arg = parseLogicalNegationExpression();\n right = new UnaryExpression(operator, arg);\n }\n return right ?? parseComparisonExpression();\n }\n function parseComparisonExpression() {\n let left = parseAdditiveExpression();\n while (true) {\n let operator;\n if (isIdentifier(\"not\", \"in\")) {\n operator = new Token(\"not in\", TOKEN_TYPES.Identifier);\n current += 2;\n } else if (isIdentifier(\"in\")) {\n operator = tokens[current++];\n } else if (is(TOKEN_TYPES.ComparisonBinaryOperator)) {\n operator = tokens[current++];\n } else {\n break;\n }\n const right = parseAdditiveExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseAdditiveExpression() {\n let left = parseMultiplicativeExpression();\n while (is(TOKEN_TYPES.AdditiveBinaryOperator)) {\n const operator = tokens[current];\n ++current;\n const right = parseMultiplicativeExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseCallMemberExpression() {\n const member = parseMemberExpression(parsePrimaryExpression());\n if (is(TOKEN_TYPES.OpenParen)) {\n return parseCallExpression(member);\n }\n return member;\n }\n function parseCallExpression(callee) {\n let expression = new CallExpression(callee, parseArgs(\"call\"));\n expression = parseMemberExpression(expression);\n if (is(TOKEN_TYPES.OpenParen)) {\n expression = parseCallExpression(expression);\n }\n return expression;\n }\n function parseArgs(mode) {\n expect(TOKEN_TYPES.OpenParen, \"Expected opening parenthesis for arguments list\");\n const args = parseArgumentsList(mode);\n expect(TOKEN_TYPES.CloseParen, \"Expected closing parenthesis for arguments list\");\n return args;\n }\n function parseArgumentsList(mode) {\n const args = [];\n const parameterNames = /* @__PURE__ */ new Set();\n let sawKeywordOrDefault = false;\n let sawSpreadArgument = false;\n while (!is(TOKEN_TYPES.CloseParen)) {\n const isKeywordSpread = is(TOKEN_TYPES.ExponentiationBinaryOperator);\n const isPositionalSpread = is(TOKEN_TYPES.MultiplicativeBinaryOperator) && tokens[current].value === \"*\";\n if (mode === \"parameters\" && (isKeywordSpread || isPositionalSpread)) {\n throw new SyntaxError(\"Argument unpacking is not allowed in parameter declarations\");\n }\n if (isKeywordSpread) {\n ++current;\n args.push(new KeywordSpreadExpression(parseExpression()));\n if (is(TOKEN_TYPES.Comma)) {\n ++current;\n }\n if (!is(TOKEN_TYPES.CloseParen)) {\n throw new SyntaxError(\"Expected closing parenthesis: `**` must be applied to the final argument\");\n }\n break;\n }\n let argument;\n if (isPositionalSpread) {\n if (sawSpreadArgument) {\n throw new SyntaxError(\"Only one `*` argument unpacking is allowed\");\n }\n sawSpreadArgument = true;\n ++current;\n const expr = parseExpression();\n argument = new SpreadExpression(expr);\n } else {\n argument = parseExpression();\n if (is(TOKEN_TYPES.Equals)) {\n ++current;\n if (!(argument instanceof Identifier)) {\n throw new SyntaxError(\n mode === \"parameters\" ? \"Expected identifier for parameter declaration\" : \"Expected identifier for keyword argument\"\n );\n }\n const value = parseExpression();\n argument = new KeywordArgumentExpression(argument, value);\n }\n if (mode === \"parameters\") {\n if (!(argument instanceof Identifier || argument instanceof KeywordArgumentExpression)) {\n throw new SyntaxError(\"Expected identifier for parameter declaration\");\n }\n const parameterName = argument instanceof Identifier ? argument.value : argument.key.value;\n if (parameterNames.has(parameterName)) {\n throw new SyntaxError(`Duplicate parameter name: ${parameterName}`);\n }\n parameterNames.add(parameterName);\n }\n if (argument instanceof KeywordArgumentExpression) {\n sawKeywordOrDefault = true;\n } else if (sawKeywordOrDefault) {\n throw new SyntaxError(\n mode === \"call\" ? \"Positional arguments must come before keyword arguments\" : \"Non-default argument follows default argument\"\n );\n } else if (sawSpreadArgument) {\n throw new SyntaxError(\"Positional arguments must not follow `*` argument unpacking\");\n }\n }\n args.push(argument);\n if (is(TOKEN_TYPES.Comma)) {\n ++current;\n }\n }\n return args;\n }\n function parseMemberExpressionArgumentsList() {\n const slices = [];\n let isSlice = false;\n while (!is(TOKEN_TYPES.CloseSquareBracket)) {\n if (is(TOKEN_TYPES.Colon)) {\n slices.push(void 0);\n ++current;\n isSlice = true;\n } else {\n slices.push(parseExpression());\n if (is(TOKEN_TYPES.Colon)) {\n ++current;\n isSlice = true;\n }\n }\n }\n if (slices.length === 0) {\n throw new SyntaxError(`Expected at least one argument for member/slice expression`);\n }\n if (isSlice) {\n if (slices.length > 3) {\n throw new SyntaxError(`Expected 0-3 arguments for slice expression`);\n }\n return new SliceExpression(...slices);\n }\n return slices[0];\n }\n function parseMemberExpression(object) {\n while (is(TOKEN_TYPES.Dot) || is(TOKEN_TYPES.OpenSquareBracket)) {\n const operator = tokens[current];\n ++current;\n let property;\n const computed = operator.type === TOKEN_TYPES.OpenSquareBracket;\n if (computed) {\n property = parseMemberExpressionArgumentsList();\n expect(TOKEN_TYPES.CloseSquareBracket, \"Expected closing square bracket\");\n } else {\n property = parsePrimaryExpression();\n if (property.type !== \"Identifier\" && property.type !== \"IntegerLiteral\") {\n throw new SyntaxError(`Expected identifier or integer following dot operator`);\n }\n }\n object = new MemberExpression(object, property, computed);\n }\n return object;\n }\n function parseMultiplicativeExpression() {\n let left = parsePowerExpression();\n while (is(TOKEN_TYPES.MultiplicativeBinaryOperator)) {\n const operator = tokens[current++];\n const right = parsePowerExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parsePowerExpression() {\n let left = parseTestExpression();\n while (is(TOKEN_TYPES.ExponentiationBinaryOperator)) {\n const operator = tokens[current++];\n const right = parseTestExpression();\n left = new BinaryExpression(operator, left, right);\n }\n return left;\n }\n function parseTestExpression() {\n let operand = parseFilterExpression();\n while (isIdentifier(\"is\")) {\n ++current;\n const negate = isIdentifier(\"not\");\n if (negate) {\n ++current;\n }\n const filter = parsePrimaryExpression();\n if (!(filter instanceof Identifier)) {\n throw new SyntaxError(`Expected identifier for the test`);\n }\n operand = new TestExpression(operand, negate, filter);\n }\n return operand;\n }\n function parseFilterExpression() {\n let operand = parseUnarySignExpression();\n while (is(TOKEN_TYPES.Pipe)) {\n ++current;\n let filter = parsePrimaryExpression();\n if (!(filter instanceof Identifier)) {\n throw new SyntaxError(`Expected identifier for the filter`);\n }\n if (is(TOKEN_TYPES.OpenParen)) {\n filter = parseCallExpression(filter);\n }\n operand = new FilterExpression(operand, filter);\n }\n return operand;\n }\n function parseUnarySignExpression() {\n const token = tokens[current];\n if (token && (token.type === TOKEN_TYPES.UnaryOperator || token.type === TOKEN_TYPES.AdditiveBinaryOperator) && (token.value === \"-\" || token.value === \"+\")) {\n const operator = tokens[current++];\n const argument = parseUnarySignExpression();\n return new UnaryExpression(operator, argument);\n }\n return parseCallMemberExpression();\n }\n function parsePrimaryExpression() {\n const token = tokens[current++];\n switch (token.type) {\n case TOKEN_TYPES.NumericLiteral: {\n const num = token.value;\n return num.includes(\".\") ? new FloatLiteral(Number(num)) : new IntegerLiteral(Number(num));\n }\n case TOKEN_TYPES.StringLiteral: {\n let value = token.value;\n while (is(TOKEN_TYPES.StringLiteral)) {\n value += tokens[current++].value;\n }\n return new StringLiteral(value);\n }\n case TOKEN_TYPES.Identifier:\n return new Identifier(token.value);\n case TOKEN_TYPES.OpenParen: {\n const expression = parseExpressionSequence();\n expect(TOKEN_TYPES.CloseParen, \"Expected closing parenthesis, got ${tokens[current].type} instead.\");\n return expression;\n }\n case TOKEN_TYPES.OpenSquareBracket: {\n const values = [];\n while (!is(TOKEN_TYPES.CloseSquareBracket)) {\n values.push(parseExpression());\n if (is(TOKEN_TYPES.Comma)) {\n ++current;\n }\n }\n ++current;\n return new ArrayLiteral(values);\n }\n case TOKEN_TYPES.OpenCurlyBracket: {\n const values = /* @__PURE__ */ new Map();\n while (!is(TOKEN_TYPES.CloseCurlyBracket)) {\n const key = parseExpression();\n expect(TOKEN_TYPES.Colon, \"Expected colon between key and value in object literal\");\n const value = parseExpression();\n values.set(key, value);\n if (is(TOKEN_TYPES.Comma)) {\n ++current;\n }\n }\n ++current;\n return new ObjectLiteral(values);\n }\n default:\n throw new SyntaxError(`Unexpected token: ${token.type}`);\n }\n }\n while (current < tokens.length) {\n program.body.push(parseAny());\n }\n return program;\n}\n\n// src/utils.ts\nfunction range(start, stop, step = 1) {\n if (stop === void 0) {\n stop = start;\n start = 0;\n }\n if (step === 0) {\n throw new Error(\"range() step must not be zero\");\n }\n const result = [];\n if (step > 0) {\n for (let i = start; i < stop; i += step) {\n result.push(i);\n }\n } else {\n for (let i = start; i > stop; i += step) {\n result.push(i);\n }\n }\n return result;\n}\nfunction slice(array, start, stop, step = 1) {\n const direction = Math.sign(step);\n if (direction >= 0) {\n start = (start ??= 0) < 0 ? Math.max(array.length + start, 0) : Math.min(start, array.length);\n stop = (stop ??= array.length) < 0 ? Math.max(array.length + stop, 0) : Math.min(stop, array.length);\n } else {\n start = (start ??= array.length - 1) < 0 ? Math.max(array.length + start, -1) : Math.min(start, array.length - 1);\n stop = (stop ??= -1) < -1 ? Math.max(array.length + stop, -1) : Math.min(stop, array.length - 1);\n }\n const result = [];\n for (let i = start; direction * i < direction * stop; i += step) {\n result.push(array[i]);\n }\n return result;\n}\nfunction titleCase(value) {\n return value.replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\nfunction strftime_now(format2) {\n return strftime(/* @__PURE__ */ new Date(), format2);\n}\nfunction strftime(date, format2) {\n const monthFormatterLong = new Intl.DateTimeFormat(void 0, { month: \"long\" });\n const monthFormatterShort = new Intl.DateTimeFormat(void 0, { month: \"short\" });\n const pad2 = (n) => n < 10 ? \"0\" + n : n.toString();\n return format2.replace(/%[YmdbBHM%]/g, (token) => {\n switch (token) {\n case \"%Y\":\n return date.getFullYear().toString();\n case \"%m\":\n return pad2(date.getMonth() + 1);\n case \"%d\":\n return pad2(date.getDate());\n case \"%b\":\n return monthFormatterShort.format(date);\n case \"%B\":\n return monthFormatterLong.format(date);\n case \"%H\":\n return pad2(date.getHours());\n case \"%M\":\n return pad2(date.getMinutes());\n case \"%%\":\n return \"%\";\n default:\n return token;\n }\n });\n}\nfunction escapeRegExp(s) {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\nfunction replace(str, oldvalue, newvalue, count) {\n if (count === 0) {\n return str;\n }\n let remaining = count == null || count < 0 ? Infinity : count;\n const pattern = oldvalue.length === 0 ? new RegExp(\"(?=)\", \"gu\") : new RegExp(escapeRegExp(oldvalue), \"gu\");\n return str.replaceAll(pattern, (match) => {\n if (remaining > 0) {\n --remaining;\n return newvalue;\n }\n return match;\n });\n}\n\n// src/runtime.ts\nvar BreakControl = class extends Error {\n};\nvar ContinueControl = class extends Error {\n};\nvar EMPTY_BUILTINS = /* @__PURE__ */ new Map();\nvar RuntimeValue = class {\n type = \"RuntimeValue\";\n value;\n /**\n * A collection of built-in functions for this type.\n */\n get builtins() {\n return EMPTY_BUILTINS;\n }\n /**\n * Creates a new RuntimeValue.\n */\n constructor(value = void 0) {\n this.value = value;\n }\n /**\n * Determines truthiness or falsiness of the runtime value.\n * This function should be overridden by subclasses if it has custom truthiness criteria.\n * @returns {BooleanValue} BooleanValue(true) if the value is truthy, BooleanValue(false) otherwise.\n */\n __bool__() {\n return new BooleanValue(!!this.value);\n }\n toString() {\n return String(this.value);\n }\n};\nvar IntegerValue = class extends RuntimeValue {\n type = \"IntegerValue\";\n};\nvar FloatValue = class extends RuntimeValue {\n type = \"FloatValue\";\n toString() {\n if (Object.is(this.value, -0)) {\n return \"-0.0\";\n }\n return this.value % 1 === 0 ? this.value.toFixed(1) : this.value.toString();\n }\n};\nvar StringValue = class extends RuntimeValue {\n type = \"StringValue\";\n _builtins;\n get builtins() {\n return this._builtins ??= /* @__PURE__ */ new Map([\n [\n \"upper\",\n new FunctionValue(() => {\n return new StringValue(this.value.toUpperCase());\n })\n ],\n [\n \"lower\",\n new FunctionValue(() => {\n return new StringValue(this.value.toLowerCase());\n })\n ],\n [\n \"strip\",\n new FunctionValue(() => {\n return new StringValue(this.value.trim());\n })\n ],\n [\n \"title\",\n new FunctionValue(() => {\n return new StringValue(titleCase(this.value));\n })\n ],\n [\n \"capitalize\",\n new FunctionValue(() => {\n return new StringValue(this.value.charAt(0).toUpperCase() + this.value.slice(1));\n })\n ],\n [\"length\", new IntegerValue(this.value.length)],\n [\n \"rstrip\",\n new FunctionValue(() => {\n return new StringValue(this.value.trimEnd());\n })\n ],\n [\n \"lstrip\",\n new FunctionValue(() => {\n return new StringValue(this.value.trimStart());\n })\n ],\n [\n \"startswith\",\n new FunctionValue((args) => {\n if (args.length === 0) {\n throw new Error(\"startswith() requires at least one argument\");\n }\n const pattern = args[0];\n if (pattern instanceof StringValue) {\n return new BooleanValue(this.value.startsWith(pattern.value));\n } else if (pattern instanceof ArrayValue) {\n for (const item of pattern.value) {\n if (!(item instanceof StringValue)) {\n throw new Error(\"startswith() tuple elements must be strings\");\n }\n if (this.value.startsWith(item.value)) {\n return new BooleanValue(true);\n }\n }\n return new BooleanValue(false);\n }\n throw new Error(\"startswith() argument must be a string or tuple of strings\");\n })\n ],\n [\n \"endswith\",\n new FunctionValue((args) => {\n if (args.length === 0) {\n throw new Error(\"endswith() requires at least one argument\");\n }\n const pattern = args[0];\n if (pattern instanceof StringValue) {\n return new BooleanValue(this.value.endsWith(pattern.value));\n } else if (pattern instanceof ArrayValue) {\n for (const item of pattern.value) {\n if (!(item instanceof StringValue)) {\n throw new Error(\"endswith() tuple elements must be strings\");\n }\n if (this.value.endsWith(item.value)) {\n return new BooleanValue(true);\n }\n }\n return new BooleanValue(false);\n }\n throw new Error(\"endswith() argument must be a string or tuple of strings\");\n })\n ],\n [\n \"split\",\n // follows Python's `str.split(sep=None, maxsplit=-1)` function behavior\n // https://docs.python.org/3.13/library/stdtypes.html#str.split\n new FunctionValue((args) => {\n const sep = args[0] ?? new NullValue();\n if (!(sep instanceof StringValue || sep instanceof NullValue)) {\n throw new Error(\"sep argument must be a string or null\");\n }\n const maxsplit = args[1] ?? new IntegerValue(-1);\n if (!(maxsplit instanceof IntegerValue)) {\n throw new Error(\"maxsplit argument must be a number\");\n }\n let result = [];\n if (sep instanceof NullValue) {\n const text = this.value.trimStart();\n for (const { 0: match, index } of text.matchAll(/\\S+/g)) {\n if (maxsplit.value !== -1 && result.length >= maxsplit.value && index !== void 0) {\n result.push(match + text.slice(index + match.length));\n break;\n }\n result.push(match);\n }\n } else {\n if (sep.value === \"\") {\n throw new Error(\"empty separator\");\n }\n result = this.value.split(sep.value);\n if (maxsplit.value !== -1 && result.length > maxsplit.value) {\n result.push(result.splice(maxsplit.value).join(sep.value));\n }\n }\n return new ArrayValue(result.map((part) => new StringValue(part)));\n })\n ],\n [\n \"replace\",\n new FunctionValue((args) => {\n if (args.length < 2) {\n throw new Error(\"replace() requires at least two arguments\");\n }\n const oldValue = args[0];\n const newValue = args[1];\n if (!(oldValue instanceof StringValue && newValue instanceof StringValue)) {\n throw new Error(\"replace() arguments must be strings\");\n }\n let count;\n if (args.length > 2) {\n if (args[2].type === \"KeywordArgumentsValue\") {\n count = args[2].value.get(\"count\") ?? new NullValue();\n } else {\n count = args[2];\n }\n } else {\n count = new NullValue();\n }\n if (!(count instanceof IntegerValue || count instanceof NullValue)) {\n throw new Error(\"replace() count argument must be a number or null\");\n }\n return new StringValue(replace(this.value, oldValue.value, newValue.value, count.value));\n })\n ]\n ]);\n }\n};\nvar BooleanValue = class extends RuntimeValue {\n type = \"BooleanValue\";\n};\nvar NON_ASCII_CHARS = /[\\x7f-\\uffff]/g;\nfunction makeAsciiSafe(str) {\n return str.replace(NON_ASCII_CHARS, (char) => \"\\\\u\" + char.charCodeAt(0).toString(16).padStart(4, \"0\"));\n}\nfunction toJSON(input, options = {}, depth = 0, convertUndefinedToNull = true) {\n const { indent = null, ensureAscii = false, separators = null, sortKeys = false } = options;\n let itemSeparator;\n let keySeparator;\n if (separators) {\n [itemSeparator, keySeparator] = separators;\n } else if (indent) {\n itemSeparator = \",\";\n keySeparator = \": \";\n } else {\n itemSeparator = \", \";\n keySeparator = \": \";\n }\n switch (input.type) {\n case \"NullValue\":\n return \"null\";\n case \"UndefinedValue\":\n return convertUndefinedToNull ? \"null\" : \"undefined\";\n case \"IntegerValue\":\n case \"FloatValue\":\n case \"BooleanValue\":\n return JSON.stringify(input.value);\n case \"StringValue\": {\n let result = JSON.stringify(input.value);\n if (ensureAscii) {\n result = makeAsciiSafe(result);\n }\n return result;\n }\n case \"ArrayValue\":\n case \"NamespaceValue\":\n case \"ObjectValue\": {\n const indentValue = indent ? \" \".repeat(indent) : \"\";\n const basePadding = \"\\n\" + indentValue.repeat(depth);\n const childrenPadding = basePadding + indentValue;\n if (input.type === \"ArrayValue\") {\n const core = input.value.map((x) => toJSON(x, options, depth + 1, convertUndefinedToNull));\n return indent ? `[${childrenPadding}${core.join(`${itemSeparator}${childrenPadding}`)}${basePadding}]` : `[${core.join(itemSeparator)}]`;\n } else {\n let entries = Array.from(input.value.entries());\n if (sortKeys) {\n entries = entries.sort(([a], [b]) => a.localeCompare(b));\n }\n const core = entries.map(([key, value]) => {\n let keyStr = JSON.stringify(key);\n if (ensureAscii) {\n keyStr = makeAsciiSafe(keyStr);\n }\n const v = `${keyStr}${keySeparator}${toJSON(value, options, depth + 1, convertUndefinedToNull)}`;\n return indent ? `${childrenPadding}${v}` : v;\n });\n return indent ? `{${core.join(itemSeparator)}${basePadding}}` : `{${core.join(itemSeparator)}}`;\n }\n }\n default:\n throw new Error(`Cannot convert to JSON: ${input.type}`);\n }\n}\nvar ObjectValue = class extends RuntimeValue {\n type = \"ObjectValue\";\n _builtins;\n /**\n * NOTE: necessary to override since all JavaScript arrays are considered truthy,\n * while only non-empty Python arrays are consider truthy.\n *\n * e.g.,\n * - JavaScript: {} && 5 -> 5\n * - Python: {} and 5 -> {}\n */\n __bool__() {\n return new BooleanValue(this.value.size > 0);\n }\n get builtins() {\n return this._builtins ??= /* @__PURE__ */ new Map([\n [\n \"get\",\n new FunctionValue(([key, defaultValue]) => {\n if (!(key instanceof StringValue)) {\n throw new Error(`Object key must be a string: got ${key.type}`);\n }\n return this.value.get(key.value) ?? defaultValue ?? new NullValue();\n })\n ],\n [\"items\", new FunctionValue(() => this.items())],\n [\"keys\", new FunctionValue(() => this.keys())],\n [\"values\", new FunctionValue(() => this.values())],\n [\n \"dictsort\",\n new FunctionValue((args) => {\n let kwargs = /* @__PURE__ */ new Map();\n const positionalArgs = args.filter((arg) => {\n if (arg instanceof KeywordArgumentsValue) {\n kwargs = arg.value;\n return false;\n }\n return true;\n });\n const caseSensitive = positionalArgs.at(0) ?? kwargs.get(\"case_sensitive\") ?? new BooleanValue(false);\n if (!(caseSensitive instanceof BooleanValue)) {\n throw new Error(\"case_sensitive must be a boolean\");\n }\n const by = positionalArgs.at(1) ?? kwargs.get(\"by\") ?? new StringValue(\"key\");\n if (!(by instanceof StringValue)) {\n throw new Error(\"by must be a string\");\n }\n if (![\"key\", \"value\"].includes(by.value)) {\n throw new Error(\"by must be either 'key' or 'value'\");\n }\n const reverse = positionalArgs.at(2) ?? kwargs.get(\"reverse\") ?? new BooleanValue(false);\n if (!(reverse instanceof BooleanValue)) {\n throw new Error(\"reverse must be a boolean\");\n }\n const items = Array.from(this.value.entries()).map(([key, value]) => new ArrayValue([new StringValue(key), value])).sort((a, b) => {\n const index = by.value === \"key\" ? 0 : 1;\n const aVal = a.value[index];\n const bVal = b.value[index];\n const result = compareRuntimeValues(aVal, bVal, caseSensitive.value);\n return reverse.value ? -result : result;\n });\n return new ArrayValue(items);\n })\n ]\n ]);\n }\n items() {\n return new ArrayValue(\n Array.from(this.value.entries()).map(([key, value]) => new ArrayValue([new StringValue(key), value]))\n );\n }\n keys() {\n return new ArrayValue(Array.from(this.value.keys()).map((key) => new StringValue(key)));\n }\n values() {\n return new ArrayValue(Array.from(this.value.values()));\n }\n toString() {\n return toJSON(this, {}, 0, false);\n }\n};\nvar KeywordArgumentsValue = class extends ObjectValue {\n type = \"KeywordArgumentsValue\";\n};\nvar NamespaceValue = class extends RuntimeValue {\n type = \"NamespaceValue\";\n toString() {\n return toJSON(this, {}, 0, false);\n }\n};\nvar ArrayValue = class extends RuntimeValue {\n type = \"ArrayValue\";\n _builtins;\n get builtins() {\n return this._builtins ??= /* @__PURE__ */ new Map([[\"length\", new IntegerValue(this.value.length)]]);\n }\n /**\n * NOTE: necessary to override since all JavaScript arrays are considered truthy,\n * while only non-empty Python arrays are consider truthy.\n *\n * e.g.,\n * - JavaScript: [] && 5 -> 5\n * - Python: [] and 5 -> []\n */\n __bool__() {\n return new BooleanValue(this.value.length > 0);\n }\n toString() {\n return toJSON(this, {}, 0, false);\n }\n};\nvar TupleValue = class extends ArrayValue {\n type = \"TupleValue\";\n};\nvar FunctionValue = class extends RuntimeValue {\n type = \"FunctionValue\";\n};\nvar NullValue = class extends RuntimeValue {\n type = \"NullValue\";\n};\nvar UndefinedValue = class extends RuntimeValue {\n type = \"UndefinedValue\";\n};\nfunction normalizeNamespaceEntry(pair) {\n let values;\n if (pair instanceof ArrayValue) {\n values = pair.value;\n } else if (pair instanceof StringValue) {\n values = Array.from(pair.value, (char) => new StringValue(char));\n }\n if (!values || values.length !== 2) {\n throw new Error(\"namespace expected an object or an iterable of [key, value] pairs\");\n }\n const [key, value] = values;\n if (!(key instanceof StringValue)) {\n throw new Error(\"namespace keys must be strings\");\n }\n return [key, value];\n}\nvar _Environment = class {\n constructor(parent) {\n this.parent = parent;\n }\n /**\n * The variables declared in this environment.\n */\n variables = /* @__PURE__ */ new Map([\n [\n \"namespace\",\n new FunctionValue((args) => {\n const positional = args.slice();\n let kwargs;\n if (positional.at(-1) instanceof KeywordArgumentsValue) {\n kwargs = positional.pop();\n }\n if (positional.length > 1) {\n throw new Error(`namespace expected at most 1 argument, got ${positional.length}`);\n }\n const entries = /* @__PURE__ */ new Map();\n if (positional.length === 1) {\n const source = positional[0];\n if (source instanceof ObjectValue) {\n for (const [key, value] of source.value) {\n entries.set(key, value);\n }\n } else if (source instanceof ArrayValue) {\n for (const pair of source.value) {\n const [key, value] = normalizeNamespaceEntry(pair);\n entries.set(key.value, value);\n }\n } else {\n throw new Error(`'${source.type}' object is not iterable`);\n }\n }\n if (kwargs) {\n for (const [key, value] of kwargs.value) {\n entries.set(key, value);\n }\n }\n return new NamespaceValue(entries);\n })\n ]\n ]);\n tests = _Environment.TESTS;\n /**\n * Set the value of a variable in the current environment.\n */\n set(name, value) {\n return this.declareVariable(name, convertToRuntimeValues(value));\n }\n declareVariable(name, value) {\n if (this.variables.has(name)) {\n throw new SyntaxError(`Variable already declared: ${name}`);\n }\n this.variables.set(name, value);\n return value;\n }\n // private assignVariable(name: string, value: AnyRuntimeValue): AnyRuntimeValue {\n // \tconst env = this.resolve(name);\n // \tenv.variables.set(name, value);\n // \treturn value;\n // }\n /**\n * Set variable in the current scope.\n * See https://jinja.palletsprojects.com/en/3.0.x/templates/#assignments for more information.\n */\n setVariable(name, value) {\n this.variables.set(name, value);\n return value;\n }\n /**\n * Resolve the environment in which the variable is declared.\n * @param {string} name The name of the variable.\n * @returns {Environment} The environment in which the variable is declared.\n */\n resolve(name) {\n if (this.variables.has(name)) {\n return this;\n }\n if (this.parent) {\n return this.parent.resolve(name);\n }\n throw new Error(`Unknown variable: ${name}`);\n }\n lookupVariable(name) {\n try {\n return this.resolve(name).variables.get(name) ?? new UndefinedValue();\n } catch {\n return new UndefinedValue();\n }\n }\n};\nvar Environment = _Environment;\n/**\n * The tests available in this environment.\n */\n__publicField(Environment, \"TESTS\", /* @__PURE__ */ new Map([\n [\"boolean\", (operand) => operand.type === \"BooleanValue\"],\n [\"callable\", (operand) => operand instanceof FunctionValue],\n [\n \"odd\",\n (operand) => {\n if (!(operand instanceof IntegerValue)) {\n throw new Error(`cannot odd on ${operand.type}`);\n }\n return operand.value % 2 !== 0;\n }\n ],\n [\n \"even\",\n (operand) => {\n if (!(operand instanceof IntegerValue)) {\n throw new Error(`cannot even on ${operand.type}`);\n }\n return operand.value % 2 === 0;\n }\n ],\n [\"false\", (operand) => operand.type === \"BooleanValue\" && !operand.value],\n [\"true\", (operand) => operand.type === \"BooleanValue\" && operand.value],\n [\"none\", (operand) => operand.type === \"NullValue\"],\n [\"string\", (operand) => operand.type === \"StringValue\"],\n [\"number\", (operand) => operand instanceof IntegerValue || operand instanceof FloatValue],\n [\"integer\", (operand) => operand instanceof IntegerValue],\n [\"iterable\", (operand) => operand.type === \"ArrayValue\" || operand.type === \"StringValue\"],\n [\"mapping\", (operand) => operand instanceof ObjectValue],\n [\n \"sequence\",\n (operand) => operand instanceof ArrayValue || operand instanceof ObjectValue || operand instanceof StringValue\n ],\n [\n \"lower\",\n (operand) => {\n const str = operand.value;\n return operand.type === \"StringValue\" && str === str.toLowerCase();\n }\n ],\n [\n \"upper\",\n (operand) => {\n const str = operand.value;\n return operand.type === \"StringValue\" && str === str.toUpperCase();\n }\n ],\n [\"none\", (operand) => operand.type === \"NullValue\"],\n [\"defined\", (operand) => operand.type !== \"UndefinedValue\"],\n [\"undefined\", (operand) => operand.type === \"UndefinedValue\"],\n [\"equalto\", (a, b) => a.value === b.value],\n [\"eq\", (a, b) => a.value === b.value]\n]));\nfunction setupGlobals(env) {\n env.set(\"false\", false);\n env.set(\"true\", true);\n env.set(\"none\", null);\n env.set(\"raise_exception\", (args) => {\n throw new Error(args);\n });\n env.set(\"range\", range);\n env.set(\"strftime_now\", strftime_now);\n env.set(\"True\", true);\n env.set(\"False\", false);\n env.set(\"None\", null);\n}\nfunction isAttributeContainer(value) {\n return value instanceof ObjectValue || value instanceof NamespaceValue;\n}\nfunction isNumericLikeValue(value) {\n return value instanceof IntegerValue || value instanceof FloatValue || value instanceof BooleanValue;\n}\nfunction getNumericValue(value) {\n return value instanceof BooleanValue ? Number(value.value) : value.value;\n}\nfunction getAttributeValue(item, attributePath) {\n const parts = attributePath.split(\".\");\n let value = item;\n for (const part of parts) {\n if (isAttributeContainer(value)) {\n value = value.value.get(part) ?? new UndefinedValue();\n } else if (value instanceof ArrayValue) {\n const index = parseInt(part, 10);\n if (!isNaN(index) && index >= 0 && index < value.value.length) {\n value = value.value[index];\n } else {\n return new UndefinedValue();\n }\n } else {\n return new UndefinedValue();\n }\n }\n return value;\n}\nfunction compareRuntimeValues(a, b, caseSensitive = false) {\n if (a instanceof NullValue && b instanceof NullValue) {\n return 0;\n }\n if (a instanceof NullValue || b instanceof NullValue) {\n throw new Error(`Cannot compare ${a.type} with ${b.type}`);\n }\n if (a instanceof UndefinedValue && b instanceof UndefinedValue) {\n return 0;\n }\n if (a instanceof UndefinedValue || b instanceof UndefinedValue) {\n throw new Error(`Cannot compare ${a.type} with ${b.type}`);\n }\n if (isNumericLikeValue(a) && isNumericLikeValue(b)) {\n const aNum = getNumericValue(a);\n const bNum = getNumericValue(b);\n return aNum < bNum ? -1 : aNum > bNum ? 1 : 0;\n }\n if (a.type !== b.type) {\n throw new Error(`Cannot compare different types: ${a.type} and ${b.type}`);\n }\n switch (a.type) {\n case \"StringValue\": {\n let aStr = a.value;\n let bStr = b.value;\n if (!caseSensitive) {\n aStr = aStr.toLowerCase();\n bStr = bStr.toLowerCase();\n }\n return aStr < bStr ? -1 : aStr > bStr ? 1 : 0;\n }\n default:\n throw new Error(`Cannot compare type: ${a.type}`);\n }\n}\nfunction getParameterDescriptor(argument) {\n if (argument.type === \"Identifier\") {\n return { name: argument.value };\n }\n const keywordArgument = argument;\n return { name: keywordArgument.key.value, defaultValue: keywordArgument.value };\n}\nfunction isSpecialMacroArgument(name) {\n return name === \"kwargs\" || name === \"varargs\";\n}\nfunction findAccessedSpecialMacroArguments(parameters, body) {\n const declared = /* @__PURE__ */ new Set();\n const accessed = /* @__PURE__ */ new Set();\n const declareName = (name) => {\n if (isSpecialMacroArgument(name)) {\n declared.add(name);\n }\n };\n const declareTarget = (target) => {\n if (target.type === \"Identifier\") {\n declareName(target.value);\n } else if (target.type === \"TupleLiteral\") {\n for (const item of target.value) {\n declareTarget(item);\n }\n }\n };\n const declareArgument = (argument) => {\n declareName(getParameterDescriptor(argument).name);\n };\n const visitArgumentDefaults = (args) => {\n for (const argument of args) {\n const parameter = getParameterDescriptor(argument);\n if (parameter.defaultValue) {\n visit(parameter.defaultValue);\n }\n }\n };\n const visitFilter = (filter) => {\n if (filter.type === \"CallExpression\") {\n visit(filter.args);\n }\n };\n const visit = (node) => {\n if (Array.isArray(node)) {\n for (const item of node) {\n visit(item);\n }\n return;\n }\n if (node instanceof Map) {\n for (const [key, value] of node) {\n visit(key);\n visit(value);\n }\n return;\n }\n if (!(node instanceof Statement)) {\n return;\n }\n switch (node.type) {\n case \"For\": {\n const statement = node;\n declareTarget(statement.loopvar);\n if (statement.iterable.type === \"SelectExpression\") {\n const iterable = statement.iterable;\n visit(iterable.lhs);\n visit(statement.body);\n visit(statement.defaultBlock);\n visit(iterable.test);\n return;\n }\n visit(statement.iterable);\n visit(statement.body);\n visit(statement.defaultBlock);\n return;\n }\n case \"Set\": {\n const statement = node;\n declareTarget(statement.assignee);\n visit(statement.value);\n visit(statement.body);\n return;\n }\n case \"Macro\": {\n const statement = node;\n for (const argument of statement.args) {\n declareArgument(argument);\n }\n visitArgumentDefaults(statement.args);\n visit(statement.body);\n return;\n }\n case \"CallStatement\": {\n const statement = node;\n visit(statement.call);\n for (const argument of statement.callerArgs ?? []) {\n declareArgument(argument);\n }\n visitArgumentDefaults(statement.callerArgs ?? []);\n visit(statement.body);\n return;\n }\n case \"FilterStatement\": {\n const statement = node;\n visit(statement.body);\n visitFilter(statement.filter);\n return;\n }\n case \"Identifier\": {\n const name = node.value;\n if (isSpecialMacroArgument(name) && !declared.has(name)) {\n accessed.add(name);\n }\n return;\n }\n case \"MemberExpression\": {\n const expression = node;\n visit(expression.object);\n if (expression.computed) {\n visit(expression.property);\n }\n return;\n }\n case \"FilterExpression\": {\n const expression = node;\n visit(expression.operand);\n visitFilter(expression.filter);\n return;\n }\n case \"TestExpression\":\n visit(node.operand);\n return;\n case \"SelectExpression\": {\n const expression = node;\n visit(expression.test);\n visit(expression.lhs);\n return;\n }\n case \"KeywordArgumentExpression\":\n visit(node.value);\n return;\n default:\n for (const child of Object.values(node)) {\n visit(child);\n }\n }\n };\n for (const parameter of parameters) {\n declareArgument(parameter);\n }\n visit(body);\n return accessed;\n}\nvar Interpreter = class {\n global;\n constructor(env) {\n this.global = env ?? new Environment();\n }\n /**\n * Run the program.\n */\n run(program) {\n return this.evaluate(program, this.global);\n }\n /**\n * Evaluates expressions following the binary operation type.\n */\n evaluateBinaryExpression(node, environment) {\n const left = this.evaluate(node.left, environment);\n switch (node.operator.value) {\n case \"and\":\n return left.__bool__().value ? this.evaluate(node.right, environment) : left;\n case \"or\":\n return left.__bool__().value ? left : this.evaluate(node.right, environment);\n }\n const right = this.evaluate(node.right, environment);\n switch (node.operator.value) {\n case \"==\":\n return new BooleanValue(left.value == right.value);\n case \"!=\":\n return new BooleanValue(left.value != right.value);\n }\n if (left instanceof UndefinedValue || right instanceof UndefinedValue) {\n if (right instanceof UndefinedValue && [\"in\", \"not in\"].includes(node.operator.value)) {\n return new BooleanValue(node.operator.value === \"not in\");\n }\n throw new Error(`Cannot perform operation ${node.operator.value} on undefined values`);\n } else if (left instanceof NullValue || right instanceof NullValue) {\n throw new Error(\"Cannot perform operation on null values\");\n } else if (node.operator.value === \"~\") {\n return new StringValue(left.value.toString() + right.value.toString());\n } else if (node.operator.value === \"**\" && isNumericLikeValue(left) && isNumericLikeValue(right)) {\n const a = getNumericValue(left);\n const b = getNumericValue(right);\n if (a === 0 && b < 0) {\n throw new Error(\"0.0 cannot be raised to a negative power\");\n }\n const result = a ** b;\n if (!Number.isFinite(result)) {\n throw new Error(\"Exponentiation result is not a finite real number\");\n }\n const isFloat = left instanceof FloatValue || right instanceof FloatValue || b < 0;\n return isFloat ? new FloatValue(result) : new IntegerValue(result);\n } else if ((left instanceof IntegerValue || left instanceof FloatValue) && (right instanceof IntegerValue || right instanceof FloatValue)) {\n const a = left.value, b = right.value;\n switch (node.operator.value) {\n case \"+\":\n case \"-\":\n case \"*\": {\n const res = node.operator.value === \"+\" ? a + b : node.operator.value === \"-\" ? a - b : a * b;\n const isFloat = left instanceof FloatValue || right instanceof FloatValue;\n return isFloat ? new FloatValue(res) : new IntegerValue(res);\n }\n case \"/\":\n return new FloatValue(a / b);\n case \"//\": {\n const res = Math.floor(a / b);\n const isFloat = left instanceof FloatValue || right instanceof FloatValue;\n return isFloat ? new FloatValue(res) : new IntegerValue(res);\n }\n case \"%\": {\n const rem = a % b;\n const isFloat = left instanceof FloatValue || right instanceof FloatValue;\n return isFloat ? new FloatValue(rem) : new IntegerValue(rem);\n }\n case \"<\":\n return new BooleanValue(a < b);\n case \">\":\n return new BooleanValue(a > b);\n case \">=\":\n return new BooleanValue(a >= b);\n case \"<=\":\n return new BooleanValue(a <= b);\n }\n } else if (left instanceof ArrayValue && right instanceof ArrayValue) {\n switch (node.operator.value) {\n case \"+\":\n return new ArrayValue(left.value.concat(right.value));\n }\n } else if (right instanceof ArrayValue) {\n const member = right.value.find((x) => x.value === left.value) !== void 0;\n switch (node.operator.value) {\n case \"in\":\n return new BooleanValue(member);\n case \"not in\":\n return new BooleanValue(!member);\n }\n }\n if (left instanceof StringValue || right instanceof StringValue) {\n switch (node.operator.value) {\n case \"+\":\n return new StringValue(left.value.toString() + right.value.toString());\n }\n }\n if (left instanceof StringValue && right instanceof StringValue) {\n switch (node.operator.value) {\n case \"in\":\n return new BooleanValue(right.value.includes(left.value));\n case \"not in\":\n return new BooleanValue(!right.value.includes(left.value));\n }\n }\n if (left instanceof StringValue && right instanceof ObjectValue) {\n switch (node.operator.value) {\n case \"in\":\n return new BooleanValue(right.value.has(left.value));\n case \"not in\":\n return new BooleanValue(!right.value.has(left.value));\n }\n }\n throw new SyntaxError(`Unknown operator \"${node.operator.value}\" between ${left.type} and ${right.type}`);\n }\n evaluateArguments(args, environment) {\n const positionalArguments = [];\n const keywordArguments = /* @__PURE__ */ new Map();\n const addKeywordArgument = (key, value) => {\n if (keywordArguments.has(key)) {\n throw new Error(`Got multiple values for keyword argument '${key}'`);\n }\n keywordArguments.set(key, value);\n };\n for (const argument of args) {\n if (argument.type === \"SpreadExpression\") {\n const spreadNode = argument;\n const val = this.evaluate(spreadNode.argument, environment);\n if (!(val instanceof ArrayValue)) {\n throw new Error(`Cannot unpack non-iterable type: ${val.type}`);\n }\n for (const item of val.value) {\n positionalArguments.push(item);\n }\n } else if (argument.type !== \"KeywordArgumentExpression\" && argument.type !== \"KeywordSpreadExpression\") {\n positionalArguments.push(this.evaluate(argument, environment));\n }\n }\n for (const argument of args) {\n if (argument.type === \"KeywordArgumentExpression\") {\n const kwarg = argument;\n addKeywordArgument(kwarg.key.value, this.evaluate(kwarg.value, environment));\n } else if (argument.type === \"KeywordSpreadExpression\") {\n const spreadNode = argument;\n const val = this.evaluate(spreadNode.argument, environment);\n if (!(val instanceof ObjectValue)) {\n throw new Error(`Argument after ** must be a mapping, not ${val.type}`);\n }\n for (const [key, value] of val.value) {\n addKeywordArgument(key, value);\n }\n }\n }\n return [positionalArguments, keywordArguments];\n }\n applyFilter(operand, filterNode, environment) {\n if (filterNode.type === \"Identifier\") {\n const filter = filterNode;\n if (filter.value === \"safe\") {\n return operand;\n }\n if (filter.value === \"tojson\") {\n return new StringValue(toJSON(operand, {}));\n }\n if (operand instanceof ArrayValue) {\n switch (filter.value) {\n case \"list\":\n return operand;\n case \"first\":\n return operand.value[0];\n case \"last\":\n return operand.value[operand.value.length - 1];\n case \"length\":\n return new IntegerValue(operand.value.length);\n case \"reverse\":\n return new ArrayValue(operand.value.slice().reverse());\n case \"sort\": {\n return new ArrayValue(operand.value.slice().sort((a, b) => compareRuntimeValues(a, b, false)));\n }\n case \"join\":\n return new StringValue(operand.value.map((x) => x.value).join(\"\"));\n case \"string\":\n return new StringValue(toJSON(operand, {}, 0, false));\n case \"unique\": {\n const seen = /* @__PURE__ */ new Set();\n const output = [];\n for (const item of operand.value) {\n if (!seen.has(item.value)) {\n seen.add(item.value);\n output.push(item);\n }\n }\n return new ArrayValue(output);\n }\n default:\n throw new Error(`Unknown ArrayValue filter: ${filter.value}`);\n }\n } else if (operand instanceof StringValue) {\n switch (filter.value) {\n case \"length\":\n case \"upper\":\n case \"lower\":\n case \"title\":\n case \"capitalize\": {\n const builtin = operand.builtins.get(filter.value);\n if (builtin instanceof FunctionValue) {\n return builtin.value(\n /* no arguments */\n [],\n environment\n );\n } else if (builtin instanceof IntegerValue) {\n return builtin;\n } else {\n throw new Error(`Unknown StringValue filter: ${filter.value}`);\n }\n }\n case \"trim\":\n return new StringValue(operand.value.trim());\n case \"indent\":\n return new StringValue(\n operand.value.split(\"\\n\").map(\n (x, i) => (\n // By default, don't indent the first line or empty lines\n i === 0 || x.length === 0 ? x : \" \" + x\n )\n ).join(\"\\n\")\n );\n case \"join\":\n case \"string\":\n return operand;\n case \"int\": {\n const val = parseInt(operand.value, 10);\n return new IntegerValue(isNaN(val) ? 0 : val);\n }\n case \"float\": {\n const val = parseFloat(operand.value);\n return new FloatValue(isNaN(val) ? 0 : val);\n }\n default:\n throw new Error(`Unknown StringValue filter: ${filter.value}`);\n }\n } else if (operand instanceof IntegerValue || operand instanceof FloatValue) {\n switch (filter.value) {\n case \"abs\":\n return operand instanceof IntegerValue ? new IntegerValue(Math.abs(operand.value)) : new FloatValue(Math.abs(operand.value));\n case \"int\":\n return new IntegerValue(Math.floor(operand.value));\n case \"float\":\n return new FloatValue(operand.value);\n case \"string\":\n return new StringValue(operand.toString());\n default:\n throw new Error(`Unknown NumericValue filter: ${filter.value}`);\n }\n } else if (operand instanceof ObjectValue) {\n switch (filter.value) {\n case \"items\":\n return new ArrayValue(\n Array.from(operand.value.entries()).map(([key, value]) => new ArrayValue([new StringValue(key), value]))\n );\n case \"length\":\n return new IntegerValue(operand.value.size);\n default: {\n const builtin = operand.builtins.get(filter.value);\n if (builtin) {\n if (builtin instanceof FunctionValue) {\n return builtin.value([], environment);\n }\n return builtin;\n }\n throw new Error(`Unknown ObjectValue filter: ${filter.value}`);\n }\n }\n } else if (operand instanceof BooleanValue) {\n switch (filter.value) {\n case \"bool\":\n return new BooleanValue(operand.value);\n case \"int\":\n return new IntegerValue(operand.value ? 1 : 0);\n case \"float\":\n return new FloatValue(operand.value ? 1 : 0);\n case \"string\":\n return new StringValue(operand.value ? \"true\" : \"false\");\n default:\n throw new Error(`Unknown BooleanValue filter: ${filter.value}`);\n }\n }\n throw new Error(`Cannot apply filter \"${filter.value}\" to type: ${operand.type}`);\n } else if (filterNode.type === \"CallExpression\") {\n const filter = filterNode;\n if (filter.callee.type !== \"Identifier\") {\n throw new Error(`Unknown filter: ${filter.callee.type}`);\n }\n const filterName = filter.callee.value;\n if (filterName === \"tojson\") {\n const [, kwargs] = this.evaluateArguments(filter.args, environment);\n const indent = kwargs.get(\"indent\") ?? new NullValue();\n if (!(indent instanceof IntegerValue || indent instanceof NullValue)) {\n throw new Error(\"If set, indent must be a number\");\n }\n const ensureAscii = kwargs.get(\"ensure_ascii\") ?? new BooleanValue(false);\n if (!(ensureAscii instanceof BooleanValue)) {\n throw new Error(\"If set, ensure_ascii must be a boolean\");\n }\n const sortKeys = kwargs.get(\"sort_keys\") ?? new BooleanValue(false);\n if (!(sortKeys instanceof BooleanValue)) {\n throw new Error(\"If set, sort_keys must be a boolean\");\n }\n const separatorsArg = kwargs.get(\"separators\") ?? new NullValue();\n let separators = null;\n if (separatorsArg instanceof ArrayValue || separatorsArg instanceof TupleValue) {\n if (separatorsArg.value.length !== 2) {\n throw new Error(\"separators must be a tuple of two strings\");\n }\n const [itemSep, keySep] = separatorsArg.value;\n if (!(itemSep instanceof StringValue) || !(keySep instanceof StringValue)) {\n throw new Error(\"separators must be a tuple of two strings\");\n }\n separators = [itemSep.value, keySep.value];\n } else if (!(separatorsArg instanceof NullValue)) {\n throw new Error(\"If set, separators must be a tuple of two strings\");\n }\n return new StringValue(\n toJSON(operand, {\n indent: indent.value,\n ensureAscii: ensureAscii.value,\n sortKeys: sortKeys.value,\n separators\n })\n );\n } else if (filterName === \"join\") {\n let value;\n if (operand instanceof StringValue) {\n value = Array.from(operand.value);\n } else if (operand instanceof ArrayValue) {\n value = operand.value.map((x) => x.value);\n } else {\n throw new Error(`Cannot apply filter \"${filterName}\" to type: ${operand.type}`);\n }\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const separator = args.at(0) ?? kwargs.get(\"separator\") ?? new StringValue(\"\");\n if (!(separator instanceof StringValue)) {\n throw new Error(\"separator must be a string\");\n }\n return new StringValue(value.join(separator.value));\n } else if (filterName === \"int\" || filterName === \"float\") {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const defaultValue = args.at(0) ?? kwargs.get(\"default\") ?? (filterName === \"int\" ? new IntegerValue(0) : new FloatValue(0));\n if (operand instanceof StringValue) {\n const val = filterName === \"int\" ? parseInt(operand.value, 10) : parseFloat(operand.value);\n return isNaN(val) ? defaultValue : filterName === \"int\" ? new IntegerValue(val) : new FloatValue(val);\n } else if (operand instanceof IntegerValue || operand instanceof FloatValue) {\n return operand;\n } else if (operand instanceof BooleanValue) {\n return filterName === \"int\" ? new IntegerValue(operand.value ? 1 : 0) : new FloatValue(operand.value ? 1 : 0);\n } else {\n throw new Error(`Cannot apply filter \"${filterName}\" to type: ${operand.type}`);\n }\n } else if (filterName === \"default\") {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const defaultValue = args[0] ?? new StringValue(\"\");\n const booleanValue = args[1] ?? kwargs.get(\"boolean\") ?? new BooleanValue(false);\n if (!(booleanValue instanceof BooleanValue)) {\n throw new Error(\"`default` filter flag must be a boolean\");\n }\n if (operand instanceof UndefinedValue || booleanValue.value && !operand.__bool__().value) {\n return defaultValue;\n }\n return operand;\n }\n if (operand instanceof ArrayValue) {\n switch (filterName) {\n case \"sort\": {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const reverse = args.at(0) ?? kwargs.get(\"reverse\") ?? new BooleanValue(false);\n if (!(reverse instanceof BooleanValue)) {\n throw new Error(\"reverse must be a boolean\");\n }\n const caseSensitive = args.at(1) ?? kwargs.get(\"case_sensitive\") ?? new BooleanValue(false);\n if (!(caseSensitive instanceof BooleanValue)) {\n throw new Error(\"case_sensitive must be a boolean\");\n }\n const attribute = args.at(2) ?? kwargs.get(\"attribute\") ?? new NullValue();\n if (!(attribute instanceof StringValue || attribute instanceof IntegerValue || attribute instanceof NullValue)) {\n throw new Error(\"attribute must be a string, integer, or null\");\n }\n const getSortValue = (item) => {\n if (attribute instanceof NullValue) {\n return item;\n }\n const attrPath = attribute instanceof IntegerValue ? String(attribute.value) : attribute.value;\n return getAttributeValue(item, attrPath);\n };\n return new ArrayValue(\n operand.value.slice().sort((a, b) => {\n const aVal = getSortValue(a);\n const bVal = getSortValue(b);\n const result = compareRuntimeValues(aVal, bVal, caseSensitive.value);\n return reverse.value ? -result : result;\n })\n );\n }\n case \"selectattr\":\n case \"rejectattr\": {\n const select = filterName === \"selectattr\";\n if (operand.value.some((item) => !isAttributeContainer(item))) {\n throw new Error(`\\`${filterName}\\` can only be applied to array of objects`);\n }\n if (filter.args.some((x) => x.type !== \"StringLiteral\")) {\n throw new Error(`arguments of \\`${filterName}\\` must be strings`);\n }\n const [attr, testName, value] = filter.args.map((x) => this.evaluate(x, environment));\n let testFunction;\n if (testName) {\n const test = environment.tests.get(testName.value);\n if (!test) {\n throw new Error(`Unknown test: ${testName.value}`);\n }\n testFunction = test;\n } else {\n testFunction = (...x) => x[0].__bool__().value;\n }\n const filtered = operand.value.filter((item) => {\n const a = item.value.get(attr.value);\n const result = a ? testFunction(a, value) : false;\n return select ? result : !result;\n });\n return new ArrayValue(filtered);\n }\n case \"map\": {\n const [, kwargs] = this.evaluateArguments(filter.args, environment);\n if (kwargs.has(\"attribute\")) {\n const attr = kwargs.get(\"attribute\");\n if (!(attr instanceof StringValue)) {\n throw new Error(\"attribute must be a string\");\n }\n const defaultValue = kwargs.get(\"default\");\n const mapped = operand.value.map((item) => {\n if (!isAttributeContainer(item)) {\n throw new Error(\"items in map must be an object\");\n }\n const value = getAttributeValue(item, attr.value);\n return value instanceof UndefinedValue ? defaultValue ?? new UndefinedValue() : value;\n });\n return new ArrayValue(mapped);\n } else {\n throw new Error(\"`map` expressions without `attribute` set are not currently supported.\");\n }\n }\n }\n throw new Error(`Unknown ArrayValue filter: ${filterName}`);\n } else if (operand instanceof StringValue) {\n switch (filterName) {\n case \"indent\": {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n const width = args.at(0) ?? kwargs.get(\"width\") ?? new IntegerValue(4);\n if (!(width instanceof IntegerValue)) {\n throw new Error(\"width must be a number\");\n }\n const first = args.at(1) ?? kwargs.get(\"first\") ?? new BooleanValue(false);\n const blank = args.at(2) ?? kwargs.get(\"blank\") ?? new BooleanValue(false);\n const lines = operand.value.split(\"\\n\");\n const indent = \" \".repeat(width.value);\n const indented = lines.map(\n (x, i) => !first.value && i === 0 || !blank.value && x.length === 0 ? x : indent + x\n );\n return new StringValue(indented.join(\"\\n\"));\n }\n case \"replace\": {\n const replaceFn = operand.builtins.get(\"replace\");\n if (!(replaceFn instanceof FunctionValue)) {\n throw new Error(\"replace filter not available\");\n }\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n return replaceFn.value([...args, new KeywordArgumentsValue(kwargs)], environment);\n }\n }\n throw new Error(`Unknown StringValue filter: ${filterName}`);\n } else if (operand instanceof ObjectValue) {\n const builtin = operand.builtins.get(filterName);\n if (builtin && builtin instanceof FunctionValue) {\n const [args, kwargs] = this.evaluateArguments(filter.args, environment);\n if (kwargs.size > 0) {\n args.push(new KeywordArgumentsValue(kwargs));\n }\n return builtin.value(args, environment);\n }\n throw new Error(`Unknown ObjectValue filter: ${filterName}`);\n } else {\n throw new Error(`Cannot apply filter \"${filterName}\" to type: ${operand.type}`);\n }\n }\n throw new Error(`Unknown filter: ${filterNode.type}`);\n }\n /**\n * Evaluates expressions following the filter operation type.\n */\n evaluateFilterExpression(node, environment) {\n const operand = this.evaluate(node.operand, environment);\n return this.applyFilter(operand, node.filter, environment);\n }\n /**\n * Evaluates expressions following the test operation type.\n */\n evaluateTestExpression(node, environment) {\n const operand = this.evaluate(node.operand, environment);\n const test = environment.tests.get(node.test.value);\n if (!test) {\n throw new Error(`Unknown test: ${node.test.value}`);\n }\n const result = test(operand);\n return new BooleanValue(node.negate ? !result : result);\n }\n /**\n * Evaluates expressions following the select operation type.\n */\n evaluateSelectExpression(node, environment) {\n const predicate = this.evaluate(node.test, environment);\n if (!predicate.__bool__().value) {\n return new UndefinedValue();\n }\n return this.evaluate(node.lhs, environment);\n }\n /**\n * Evaluates expressions following the unary operation type.\n */\n evaluateUnaryExpression(node, environment) {\n const argument = this.evaluate(node.argument, environment);\n switch (node.operator.value) {\n case \"not\":\n return new BooleanValue(!argument.value);\n case \"+\":\n case \"-\": {\n const sign = node.operator.value === \"-\" ? -1 : 1;\n if (argument instanceof IntegerValue || argument instanceof FloatValue || argument instanceof BooleanValue) {\n const value = argument instanceof BooleanValue ? argument.value ? 1 : 0 : argument.value;\n const result = sign * value;\n return argument instanceof FloatValue ? new FloatValue(result) : new IntegerValue(result);\n }\n throw new SyntaxError(`Unknown operator \"${node.operator.value}\" for ${argument.type}`);\n }\n default:\n throw new SyntaxError(`Unknown operator: ${node.operator.value}`);\n }\n }\n evaluateTernaryExpression(node, environment) {\n const cond = this.evaluate(node.condition, environment);\n return cond.__bool__().value ? this.evaluate(node.trueExpr, environment) : this.evaluate(node.falseExpr, environment);\n }\n evalProgram(program, environment) {\n return this.evaluateBlock(program.body, environment);\n }\n evaluateBlock(statements, environment) {\n let result = \"\";\n for (const statement of statements) {\n const lastEvaluated = this.evaluate(statement, environment);\n if (lastEvaluated.type !== \"NullValue\" && lastEvaluated.type !== \"UndefinedValue\") {\n result += lastEvaluated.toString();\n }\n }\n return new StringValue(result);\n }\n evaluateIdentifier(node, environment) {\n return environment.lookupVariable(node.value);\n }\n evaluateCallExpression(expr, environment) {\n const [args, kwargs] = this.evaluateArguments(expr.args, environment);\n if (kwargs.size > 0) {\n args.push(new KeywordArgumentsValue(kwargs));\n }\n const fn = this.evaluate(expr.callee, environment);\n if (fn.type !== \"FunctionValue\") {\n throw new Error(`Cannot call something that is not a function: got ${fn.type}`);\n }\n return fn.value(args, environment);\n }\n evaluateSliceExpression(object, expr, environment) {\n if (!(object instanceof ArrayValue || object instanceof StringValue)) {\n throw new Error(\"Slice object must be an array or string\");\n }\n const start = this.evaluate(expr.start, environment);\n const stop = this.evaluate(expr.stop, environment);\n const step = this.evaluate(expr.step, environment);\n if (!(start instanceof IntegerValue || start instanceof UndefinedValue)) {\n throw new Error(\"Slice start must be numeric or undefined\");\n }\n if (!(stop instanceof IntegerValue || stop instanceof UndefinedValue)) {\n throw new Error(\"Slice stop must be numeric or undefined\");\n }\n if (!(step instanceof IntegerValue || step instanceof UndefinedValue)) {\n throw new Error(\"Slice step must be numeric or undefined\");\n }\n if (object instanceof ArrayValue) {\n return new ArrayValue(slice(object.value, start.value, stop.value, step.value));\n } else {\n return new StringValue(slice(Array.from(object.value), start.value, stop.value, step.value).join(\"\"));\n }\n }\n evaluateMemberExpression(expr, environment) {\n const object = this.evaluate(expr.object, environment);\n let property;\n if (expr.computed) {\n if (expr.property.type === \"SliceExpression\") {\n return this.evaluateSliceExpression(object, expr.property, environment);\n } else {\n property = this.evaluate(expr.property, environment);\n }\n } else if (expr.property.type === \"IntegerLiteral\") {\n property = new IntegerValue(expr.property.value);\n } else {\n property = new StringValue(expr.property.value);\n }\n let value;\n if (isAttributeContainer(object)) {\n if (!(property instanceof StringValue)) {\n throw new Error(`Cannot access property with non-string: got ${property.type}`);\n }\n value = object.value.get(property.value) ?? (object instanceof ObjectValue ? object.builtins.get(property.value) : void 0);\n } else if (object instanceof ArrayValue || object instanceof StringValue) {\n if (property instanceof IntegerValue) {\n value = object.value.at(property.value);\n if (object instanceof StringValue) {\n value = new StringValue(object.value.at(property.value));\n }\n } else if (property instanceof StringValue) {\n value = object.builtins.get(property.value);\n } else {\n throw new Error(`Cannot access property with non-string/non-number: got ${property.type}`);\n }\n } else {\n if (!(property instanceof StringValue)) {\n throw new Error(`Cannot access property with non-string: got ${property.type}`);\n }\n value = object.builtins.get(property.value);\n }\n return value instanceof RuntimeValue ? value : new UndefinedValue();\n }\n evaluateSet(node, environment) {\n const rhs = node.value ? this.evaluate(node.value, environment) : this.evaluateBlock(node.body, environment);\n if (node.assignee.type === \"Identifier\") {\n const variableName = node.assignee.value;\n environment.setVariable(variableName, rhs);\n } else if (node.assignee.type === \"TupleLiteral\") {\n const tuple = node.assignee;\n if (!(rhs instanceof ArrayValue)) {\n throw new Error(`Cannot unpack non-iterable type in set: ${rhs.type}`);\n }\n const arr = rhs.value;\n if (arr.length !== tuple.value.length) {\n throw new Error(`Too ${tuple.value.length > arr.length ? \"few\" : \"many\"} items to unpack in set`);\n }\n for (let i = 0; i < tuple.value.length; ++i) {\n const elem = tuple.value[i];\n if (elem.type !== \"Identifier\") {\n throw new Error(`Cannot unpack to non-identifier in set: ${elem.type}`);\n }\n environment.setVariable(elem.value, arr[i]);\n }\n } else if (node.assignee.type === \"MemberExpression\") {\n const member = node.assignee;\n const object = this.evaluate(member.object, environment);\n if (!(object instanceof NamespaceValue)) {\n throw new Error(\"cannot assign attribute on non-namespace object\");\n }\n if (member.property.type !== \"Identifier\") {\n throw new Error(\"Cannot assign to member with non-identifier property\");\n }\n object.value.set(member.property.value, rhs);\n } else {\n throw new Error(`Invalid LHS inside assignment expression: ${JSON.stringify(node.assignee)}`);\n }\n return new NullValue();\n }\n evaluateIf(node, environment) {\n const test = this.evaluate(node.test, environment);\n return this.evaluateBlock(test.__bool__().value ? node.body : node.alternate, environment);\n }\n evaluateFor(node, environment) {\n const scope = new Environment(environment);\n let test, iterable;\n if (node.iterable.type === \"SelectExpression\") {\n const select = node.iterable;\n iterable = this.evaluate(select.lhs, scope);\n test = select.test;\n } else {\n iterable = this.evaluate(node.iterable, scope);\n }\n if (!(iterable instanceof ArrayValue || iterable instanceof ObjectValue)) {\n throw new Error(`Expected iterable or object type in for loop: got ${iterable.type}`);\n }\n if (iterable instanceof ObjectValue) {\n iterable = iterable.keys();\n }\n const items = [];\n const scopeUpdateFunctions = [];\n for (let i = 0; i < iterable.value.length; ++i) {\n const loopScope = new Environment(scope);\n const current = iterable.value[i];\n let scopeUpdateFunction;\n if (node.loopvar.type === \"Identifier\") {\n scopeUpdateFunction = (scope2) => scope2.setVariable(node.loopvar.value, current);\n } else if (node.loopvar.type === \"TupleLiteral\") {\n const loopvar = node.loopvar;\n if (current.type !== \"ArrayValue\") {\n throw new Error(`Cannot unpack non-iterable type: ${current.type}`);\n }\n const c = current;\n if (loopvar.value.length !== c.value.length) {\n throw new Error(`Too ${loopvar.value.length > c.value.length ? \"few\" : \"many\"} items to unpack`);\n }\n scopeUpdateFunction = (scope2) => {\n for (let j = 0; j < loopvar.value.length; ++j) {\n if (loopvar.value[j].type !== \"Identifier\") {\n throw new Error(`Cannot unpack non-identifier type: ${loopvar.value[j].type}`);\n }\n scope2.setVariable(loopvar.value[j].value, c.value[j]);\n }\n };\n } else {\n throw new Error(`Invalid loop variable(s): ${node.loopvar.type}`);\n }\n if (test) {\n scopeUpdateFunction(loopScope);\n const testValue = this.evaluate(test, loopScope);\n if (!testValue.__bool__().value) {\n continue;\n }\n }\n items.push(current);\n scopeUpdateFunctions.push(scopeUpdateFunction);\n }\n let result = \"\";\n let noIteration = true;\n for (let i = 0; i < items.length; ++i) {\n const loop = /* @__PURE__ */ new Map([\n [\"index\", new IntegerValue(i + 1)],\n [\"index0\", new IntegerValue(i)],\n [\"revindex\", new IntegerValue(items.length - i)],\n [\"revindex0\", new IntegerValue(items.length - i - 1)],\n [\"first\", new BooleanValue(i === 0)],\n [\"last\", new BooleanValue(i === items.length - 1)],\n [\"length\", new IntegerValue(items.length)],\n [\"previtem\", i > 0 ? items[i - 1] : new UndefinedValue()],\n [\"nextitem\", i < items.length - 1 ? items[i + 1] : new UndefinedValue()]\n ]);\n scope.setVariable(\"loop\", new ObjectValue(loop));\n scopeUpdateFunctions[i](scope);\n try {\n const evaluated = this.evaluateBlock(node.body, scope);\n result += evaluated.value;\n } catch (err) {\n if (err instanceof ContinueControl) {\n continue;\n }\n if (err instanceof BreakControl) {\n break;\n }\n throw err;\n }\n noIteration = false;\n }\n if (noIteration) {\n const defaultEvaluated = this.evaluateBlock(node.defaultBlock, scope);\n result += defaultEvaluated.value;\n }\n return new StringValue(result);\n }\n /**\n * Bind every parameter name and special argument before evaluating defaults,\n * preventing unbound parameters from resolving in an outer scope.\n */\n bindMacroArguments(displayName, parameters, specialArguments, args, scope) {\n const positionalArguments = args.slice();\n let keywordArguments = /* @__PURE__ */ new Map();\n if (positionalArguments.at(-1) instanceof KeywordArgumentsValue) {\n keywordArguments = new Map(positionalArguments.pop().value);\n }\n const pendingDefaults = [];\n for (let i = 0; i < parameters.length; ++i) {\n const { name, defaultValue } = getParameterDescriptor(parameters[i]);\n let value = positionalArguments[i];\n if (value === void 0 && keywordArguments.has(name)) {\n value = keywordArguments.get(name);\n keywordArguments.delete(name);\n }\n if (value === void 0 && defaultValue !== void 0) {\n pendingDefaults.push([name, defaultValue]);\n }\n scope.setVariable(name, value ?? new UndefinedValue());\n }\n if (specialArguments.has(\"kwargs\")) {\n scope.setVariable(\"kwargs\", new ObjectValue(keywordArguments));\n } else if (keywordArguments.size > 0) {\n throw new Error(`macro ${displayName} takes no keyword argument '${keywordArguments.keys().next().value}'`);\n }\n if (specialArguments.has(\"varargs\")) {\n scope.setVariable(\"varargs\", new ArrayValue(positionalArguments.slice(parameters.length)));\n } else if (positionalArguments.length > parameters.length) {\n throw new Error(`macro ${displayName} takes not more than ${parameters.length} argument(s)`);\n }\n for (const [name, defaultValue] of pendingDefaults) {\n scope.setVariable(name, this.evaluate(defaultValue, scope));\n }\n }\n /**\n * See https://jinja.palletsprojects.com/en/3.1.x/templates/#macros for more information.\n */\n evaluateMacro(node, environment) {\n const specialArguments = findAccessedSpecialMacroArguments(node.args, node.body);\n environment.setVariable(\n node.name.value,\n new FunctionValue((args, scope) => {\n const macroScope = new Environment(scope);\n this.bindMacroArguments(`'${node.name.value}'`, node.args, specialArguments, args, macroScope);\n return this.evaluateBlock(node.body, macroScope);\n })\n );\n return new NullValue();\n }\n evaluateCallStatement(node, environment) {\n const parameters = node.callerArgs ?? [];\n const specialArguments = findAccessedSpecialMacroArguments(parameters, node.body);\n const callerFn = new FunctionValue((callerArguments) => {\n const callBlockEnv = new Environment(environment);\n this.bindMacroArguments(\"None\", parameters, specialArguments, callerArguments, callBlockEnv);\n return this.evaluateBlock(node.body, callBlockEnv);\n });\n const [macroArgs, macroKwargs] = this.evaluateArguments(node.call.args, environment);\n macroArgs.push(new KeywordArgumentsValue(macroKwargs));\n const fn = this.evaluate(node.call.callee, environment);\n if (fn.type !== \"FunctionValue\") {\n throw new Error(`Cannot call something that is not a function: got ${fn.type}`);\n }\n const newEnv = new Environment(environment);\n newEnv.setVariable(\"caller\", callerFn);\n return fn.value(macroArgs, newEnv);\n }\n evaluateFilterStatement(node, environment) {\n const rendered = this.evaluateBlock(node.body, environment);\n return this.applyFilter(rendered, node.filter, environment);\n }\n evaluate(statement, environment) {\n if (!statement) {\n return new UndefinedValue();\n }\n switch (statement.type) {\n case \"Program\":\n return this.evalProgram(statement, environment);\n case \"Set\":\n return this.evaluateSet(statement, environment);\n case \"If\":\n return this.evaluateIf(statement, environment);\n case \"For\":\n return this.evaluateFor(statement, environment);\n case \"Macro\":\n return this.evaluateMacro(statement, environment);\n case \"CallStatement\":\n return this.evaluateCallStatement(statement, environment);\n case \"Break\":\n throw new BreakControl();\n case \"Continue\":\n throw new ContinueControl();\n case \"IntegerLiteral\":\n return new IntegerValue(statement.value);\n case \"FloatLiteral\":\n return new FloatValue(statement.value);\n case \"StringLiteral\":\n return new StringValue(statement.value);\n case \"ArrayLiteral\":\n return new ArrayValue(statement.value.map((x) => this.evaluate(x, environment)));\n case \"TupleLiteral\":\n return new TupleValue(statement.value.map((x) => this.evaluate(x, environment)));\n case \"ObjectLiteral\": {\n const mapping = /* @__PURE__ */ new Map();\n for (const [key, value] of statement.value) {\n const evaluatedKey = this.evaluate(key, environment);\n if (!(evaluatedKey instanceof StringValue)) {\n throw new Error(`Object keys must be strings: got ${evaluatedKey.type}`);\n }\n mapping.set(evaluatedKey.value, this.evaluate(value, environment));\n }\n return new ObjectValue(mapping);\n }\n case \"Identifier\":\n return this.evaluateIdentifier(statement, environment);\n case \"CallExpression\":\n return this.evaluateCallExpression(statement, environment);\n case \"MemberExpression\":\n return this.evaluateMemberExpression(statement, environment);\n case \"UnaryExpression\":\n return this.evaluateUnaryExpression(statement, environment);\n case \"BinaryExpression\":\n return this.evaluateBinaryExpression(statement, environment);\n case \"FilterExpression\":\n return this.evaluateFilterExpression(statement, environment);\n case \"FilterStatement\":\n return this.evaluateFilterStatement(statement, environment);\n case \"TestExpression\":\n return this.evaluateTestExpression(statement, environment);\n case \"SelectExpression\":\n return this.evaluateSelectExpression(statement, environment);\n case \"Ternary\":\n return this.evaluateTernaryExpression(statement, environment);\n case \"Comment\":\n return new NullValue();\n default:\n throw new SyntaxError(`Unknown node type: ${statement.type}`);\n }\n }\n};\nfunction convertToRuntimeValues(input) {\n switch (typeof input) {\n case \"number\":\n return Number.isInteger(input) ? new IntegerValue(input) : new FloatValue(input);\n case \"string\":\n return new StringValue(input);\n case \"boolean\":\n return new BooleanValue(input);\n case \"undefined\":\n return new UndefinedValue();\n case \"object\":\n if (input === null) {\n return new NullValue();\n } else if (Array.isArray(input)) {\n return new ArrayValue(input.map(convertToRuntimeValues));\n } else {\n return new ObjectValue(\n new Map(Object.entries(input).map(([key, value]) => [key, convertToRuntimeValues(value)]))\n );\n }\n case \"function\":\n return new FunctionValue((args, _scope) => {\n const result = input(...args.map((x) => x.value)) ?? null;\n return convertToRuntimeValues(result);\n });\n default:\n throw new Error(`Cannot convert to runtime value: ${input}`);\n }\n}\n\n// src/format.ts\nvar NEWLINE = \"\\n\";\nvar OPEN_STATEMENT = \"{%- \";\nvar CLOSE_STATEMENT = \" -%}\";\nvar PRECEDENCE = Object.freeze({\n CONDITIONAL: 0,\n // a if b else c\n LOGICAL_OR: 1,\n // or\n LOGICAL_AND: 2,\n // and\n LOGICAL_NOT: 3,\n // not a\n COMPARISON: 4,\n // == != < <= > >= in, not in\n ADDITIVE: 5,\n // + -\n MULTIPLICATIVE: 6,\n // * / // %\n EXPONENTIATION: 7,\n // **\n TEST: 8,\n // is\n FILTER: 9,\n // |\n UNARY_SIGN: 10,\n // -a +a\n ATOM: 11\n // literals, identifiers, calls, member accesses\n});\nfunction getBinaryOperatorPrecedence(expr) {\n switch (expr.operator.type) {\n case \"ExponentiationBinaryOperator\":\n return PRECEDENCE.EXPONENTIATION;\n case \"MultiplicativeBinaryOperator\":\n return PRECEDENCE.MULTIPLICATIVE;\n case \"AdditiveBinaryOperator\":\n return PRECEDENCE.ADDITIVE;\n case \"ComparisonBinaryOperator\":\n return PRECEDENCE.COMPARISON;\n case \"Identifier\":\n if (expr.operator.value === \"and\") {\n return PRECEDENCE.LOGICAL_AND;\n }\n if (expr.operator.value === \"in\" || expr.operator.value === \"not in\") {\n return PRECEDENCE.COMPARISON;\n }\n return PRECEDENCE.LOGICAL_OR;\n }\n return PRECEDENCE.LOGICAL_OR;\n}\nfunction getPrecedence(node) {\n switch (node.type) {\n case \"SelectExpression\":\n case \"Ternary\":\n return PRECEDENCE.CONDITIONAL;\n case \"BinaryExpression\":\n return getBinaryOperatorPrecedence(node);\n case \"UnaryExpression\":\n return node.operator.value === \"not\" ? PRECEDENCE.LOGICAL_NOT : PRECEDENCE.UNARY_SIGN;\n case \"TestExpression\":\n return PRECEDENCE.TEST;\n case \"FilterExpression\":\n return PRECEDENCE.FILTER;\n default:\n return PRECEDENCE.ATOM;\n }\n}\nfunction formatOperand(node, minPrecedence) {\n const expr = formatExpression(node);\n return getPrecedence(node) < minPrecedence ? `(${expr})` : expr;\n}\nfunction format(program, indent = \"\t\") {\n const indentStr = typeof indent === \"number\" ? \" \".repeat(indent) : indent;\n const body = formatStatements(program.body, 0, indentStr);\n return body.replace(/\\n$/, \"\");\n}\nfunction createStatement(...text) {\n return OPEN_STATEMENT + text.join(\" \") + CLOSE_STATEMENT;\n}\nfunction formatStatements(stmts, depth, indentStr) {\n return stmts.map((stmt) => formatStatement(stmt, depth, indentStr)).join(NEWLINE);\n}\nfunction formatExpressionList(expressions) {\n return expressions.map((expression) => formatExpression(expression)).join(\", \");\n}\nfunction formatStatement(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n switch (node.type) {\n case \"Program\":\n return formatStatements(node.body, depth, indentStr);\n case \"If\":\n return formatIf(node, depth, indentStr);\n case \"For\":\n return formatFor(node, depth, indentStr);\n case \"Set\":\n return formatSet(node, depth, indentStr);\n case \"Macro\":\n return formatMacro(node, depth, indentStr);\n case \"Break\":\n return pad + createStatement(\"break\");\n case \"Continue\":\n return pad + createStatement(\"continue\");\n case \"CallStatement\":\n return formatCallStatement(node, depth, indentStr);\n case \"FilterStatement\":\n return formatFilterStatement(node, depth, indentStr);\n case \"Comment\":\n return pad + \"{# \" + node.value + \" #}\";\n default:\n return pad + \"{{- \" + formatExpression(node) + \" -}}\";\n }\n}\nfunction formatIf(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const clauses = [];\n let current = node;\n while (current) {\n clauses.push({ test: current.test, body: current.body });\n if (current.alternate.length === 1 && current.alternate[0].type === \"If\") {\n current = current.alternate[0];\n } else {\n break;\n }\n }\n let out = pad + createStatement(\"if\", formatExpression(clauses[0].test)) + NEWLINE + formatStatements(clauses[0].body, depth + 1, indentStr);\n for (let i = 1; i < clauses.length; ++i) {\n out += NEWLINE + pad + createStatement(\"elif\", formatExpression(clauses[i].test)) + NEWLINE + formatStatements(clauses[i].body, depth + 1, indentStr);\n }\n if (current && current.alternate.length > 0) {\n out += NEWLINE + pad + createStatement(\"else\") + NEWLINE + formatStatements(current.alternate, depth + 1, indentStr);\n }\n out += NEWLINE + pad + createStatement(\"endif\");\n return out;\n}\nfunction formatFor(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n let formattedIterable = \"\";\n if (node.iterable.type === \"SelectExpression\") {\n const n = node.iterable;\n formattedIterable = `${formatExpression(n.lhs)} if ${formatExpression(n.test)}`;\n } else {\n formattedIterable = formatExpression(node.iterable);\n }\n let out = pad + createStatement(\"for\", formatExpression(node.loopvar), \"in\", formattedIterable) + NEWLINE + formatStatements(node.body, depth + 1, indentStr);\n if (node.defaultBlock.length > 0) {\n out += NEWLINE + pad + createStatement(\"else\") + NEWLINE + formatStatements(node.defaultBlock, depth + 1, indentStr);\n }\n out += NEWLINE + pad + createStatement(\"endfor\");\n return out;\n}\nfunction formatSet(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const left = formatExpression(node.assignee);\n const right = node.value ? formatExpression(node.value) : \"\";\n const value = pad + createStatement(\"set\", `${left}${node.value ? \" = \" + right : \"\"}`);\n if (node.body.length === 0) {\n return value;\n }\n return value + NEWLINE + formatStatements(node.body, depth + 1, indentStr) + NEWLINE + pad + createStatement(\"endset\");\n}\nfunction formatMacro(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const args = formatExpressionList(node.args);\n return pad + createStatement(\"macro\", `${node.name.value}(${args})`) + NEWLINE + formatStatements(node.body, depth + 1, indentStr) + NEWLINE + pad + createStatement(\"endmacro\");\n}\nfunction formatCallStatement(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const params = node.callerArgs && node.callerArgs.length > 0 ? `(${formatExpressionList(node.callerArgs)})` : \"\";\n const callExpr = formatExpression(node.call);\n let out = pad + createStatement(`call${params}`, callExpr) + NEWLINE;\n out += formatStatements(node.body, depth + 1, indentStr) + NEWLINE;\n out += pad + createStatement(\"endcall\");\n return out;\n}\nfunction formatFilterStatement(node, depth, indentStr) {\n const pad = indentStr.repeat(depth);\n const spec = node.filter.type === \"Identifier\" ? node.filter.value : formatExpression(node.filter);\n let out = pad + createStatement(\"filter\", spec) + NEWLINE;\n out += formatStatements(node.body, depth + 1, indentStr) + NEWLINE;\n out += pad + createStatement(\"endfilter\");\n return out;\n}\nfunction formatExpression(node) {\n switch (node.type) {\n case \"SpreadExpression\": {\n const n = node;\n return `*${formatExpression(n.argument)}`;\n }\n case \"KeywordSpreadExpression\": {\n const n = node;\n return `**${formatExpression(n.argument)}`;\n }\n case \"Identifier\":\n return node.value;\n case \"IntegerLiteral\":\n return `${node.value}`;\n case \"FloatLiteral\": {\n const value = node.value;\n if (Object.is(value, -0)) {\n return \"-0.0\";\n }\n return value % 1 === 0 ? value.toFixed(1) : value.toString();\n }\n case \"StringLiteral\":\n return JSON.stringify(node.value);\n case \"BinaryExpression\": {\n const n = node;\n const thisPrecedence = getBinaryOperatorPrecedence(n);\n const left = formatOperand(n.left, thisPrecedence);\n const right = formatOperand(n.right, thisPrecedence + 1);\n return `${left} ${n.operator.value} ${right}`;\n }\n case \"UnaryExpression\": {\n const n = node;\n const operandPrecedence = n.argument.type === \"UnaryExpression\" ? getPrecedence(n) : PRECEDENCE.ATOM;\n return n.operator.value + (n.operator.value === \"not\" ? \" \" : \"\") + formatOperand(n.argument, operandPrecedence);\n }\n case \"CallExpression\": {\n const n = node;\n const args = formatExpressionList(n.args);\n return `${formatExpression(n.callee)}(${args})`;\n }\n case \"MemberExpression\": {\n const n = node;\n const obj = formatOperand(n.object, PRECEDENCE.ATOM);\n let prop = formatExpression(n.property);\n if (!n.computed && n.property.type !== \"Identifier\" && n.property.type !== \"IntegerLiteral\") {\n prop = `(${prop})`;\n }\n return n.computed ? `${obj}[${prop}]` : `${obj}.${prop}`;\n }\n case \"FilterExpression\": {\n const n = node;\n const operand = formatOperand(n.operand, PRECEDENCE.FILTER);\n if (n.filter.type === \"CallExpression\") {\n return `${operand} | ${formatExpression(n.filter)}`;\n }\n return `${operand} | ${n.filter.value}`;\n }\n case \"SelectExpression\": {\n const n = node;\n return `${formatOperand(n.lhs, PRECEDENCE.LOGICAL_OR)} if ${formatOperand(n.test, PRECEDENCE.LOGICAL_OR)}`;\n }\n case \"TestExpression\": {\n const n = node;\n return `${formatOperand(n.operand, PRECEDENCE.TEST)} is${n.negate ? \" not\" : \"\"} ${n.test.value}`;\n }\n case \"ArrayLiteral\":\n case \"TupleLiteral\": {\n const elems = formatExpressionList(node.value);\n const brackets = node.type === \"ArrayLiteral\" ? \"[]\" : \"()\";\n return `${brackets[0]}${elems}${brackets[1]}`;\n }\n case \"ObjectLiteral\": {\n const entries = Array.from(node.value.entries()).map(\n ([k, v]) => `${formatExpression(k)}: ${formatExpression(v)}`\n );\n return `{${entries.join(\", \")}}`;\n }\n case \"SliceExpression\": {\n const n = node;\n const s = n.start ? formatExpression(n.start) : \"\";\n const t = n.stop ? formatExpression(n.stop) : \"\";\n const st = n.step ? `:${formatExpression(n.step)}` : \"\";\n return `${s}:${t}${st}`;\n }\n case \"KeywordArgumentExpression\": {\n const n = node;\n return `${n.key.value}=${formatExpression(n.value)}`;\n }\n case \"Ternary\": {\n const n = node;\n return `${formatOperand(n.trueExpr, PRECEDENCE.LOGICAL_OR)} if ${formatOperand(\n n.condition,\n PRECEDENCE.LOGICAL_OR\n )} else ${formatOperand(n.falseExpr, PRECEDENCE.CONDITIONAL)}`;\n }\n default:\n throw new Error(`Unknown expression type: ${node.type}`);\n }\n}\n\n// src/index.ts\nvar Template = class {\n parsed;\n /**\n * @param {string} template The template string\n */\n constructor(template) {\n const tokens = tokenize(template, {\n lstrip_blocks: true,\n trim_blocks: true\n });\n this.parsed = parse(tokens);\n }\n render(items) {\n const env = new Environment();\n setupGlobals(env);\n if (items) {\n for (const [key, value] of Object.entries(items)) {\n env.set(key, value);\n }\n }\n const interpreter = new Interpreter(env);\n const result = interpreter.run(this.parsed);\n return result.value;\n }\n format(options) {\n return format(this.parsed, options?.indent || \"\t\");\n }\n};\nexport {\n Environment,\n Interpreter,\n Template,\n parse,\n tokenize\n};\n","import { Template } from \"@huggingface/jinja\";\nimport { modelRegistry } from \"../model-registry.js\";\nimport { createModelCacheFetch } from \"./create-model-cache-fetch.js\";\nimport { sanitizeToolParameters } from \"./parse-local-model-tool-call.js\";\n\nexport interface TokenizerConfig {\n chat_template?: string | Record<string, string>;\n bos_token?: string | { content: string };\n eos_token?: string | { content: string };\n pad_token?: string | { content: string };\n unk_token?: string | { content: string };\n [key: string]: any;\n}\n\nexport interface ChatMessage {\n role: \"system\" | \"user\" | \"assistant\" | \"model\" | \"tool\";\n content: string | any[];\n tool_calls?: any[];\n [key: string]: any;\n}\n\nexport interface NormalizedChatMessage {\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string;\n tool_calls?: any[];\n [key: string]: any;\n}\n\nexport interface RenderChatTemplateOptions {\n modelName?: string;\n template?: string | Record<string, string>;\n messages: any[];\n systemPrompt?: string;\n tools?: any[];\n documents?: any[];\n addGenerationPrompt?: boolean;\n bosToken?: string;\n eosToken?: string;\n padToken?: string;\n unkToken?: string;\n customFetch?: typeof fetch;\n}\n\n/**\n * Universal default ChatML template used when an uncached model is accessed offline\n * or when no model-specific Jinja template is available.\n */\nexport const DEFAULT_CHAT_TEMPLATE = `{%- for message in messages -%}\n{{- '<|im_start|>' + message.role + '\\n' + message.content + '<|im_end|>\\n' -}}\n{%- endfor -%}\n{%- if add_generation_prompt -%}\n{{- '<|im_start|>assistant\\n' -}}\n{%- endif -%}`;\n\nconst tokenizerConfigCache = new Map<string, TokenizerConfig>();\nconst compiledTemplateCache = new Map<string, Template>();\n\n/**\n * Clears in-memory tokenizer config and compiled template caches (primarily for tests).\n */\nexport function clearTokenizerConfigCache(): void {\n tokenizerConfigCache.clear();\n compiledTemplateCache.clear();\n}\n\n/**\n * Extract plain text string from a message content field (string or block array).\n */\nexport function extractContentText(content: any): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (!content) {\n return \"\";\n }\n if (Array.isArray(content)) {\n return content\n .map((block: any) => {\n if (!block) return \"\";\n if (typeof block === \"string\") return block;\n if (block.type === \"text\") return block.text || block.value || \"\";\n if (block.type === \"tool_use\") {\n return `[TOOL_CALL ${block.name}] ${JSON.stringify(block.input || {})}`;\n }\n if (block.type === \"tool_result\") {\n const res =\n typeof block.content === \"string\"\n ? block.content\n : JSON.stringify(block.content || \"\");\n return `[TOOL_RESULT ${block.tool_use_id || \"\"}] ${res}`;\n }\n if (block.type === \"attachment\") {\n return `[ATTACHMENT ${block.mediaType || \"file\"}] ${block.fileName || \"attachment\"}`;\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (typeof content === \"object\") {\n return JSON.stringify(content);\n }\n return String(content);\n}\n\n/**\n * Dynamically fetch tokenizer_config.json for a given model from Hugging Face or persistent CacheStorage.\n */\nexport async function fetchTokenizerConfig(\n modelName: string,\n customFetch?: typeof fetch,\n): Promise<TokenizerConfig | null> {\n const cleanModel = String(modelName || \"\").trim();\n if (!cleanModel) {\n return null;\n }\n\n if (tokenizerConfigCache.has(cleanModel)) {\n return tokenizerConfigCache.get(cleanModel)!;\n }\n\n const baseFetch =\n customFetch ||\n (typeof globalThis.fetch === \"function\"\n ? globalThis.fetch.bind(globalThis)\n : undefined);\n\n if (!baseFetch) {\n return null;\n }\n\n // Use disk-backed model cache fetch if no custom fetch function is explicitly passed\n const fetchFn = customFetch || createModelCacheFetch(baseFetch);\n const url = `https://huggingface.co/${encodeURI(cleanModel)}/resolve/main/tokenizer_config.json`;\n\n try {\n const res = await fetchFn(url);\n if (res.ok) {\n const config: TokenizerConfig = await res.json();\n if (config && typeof config === \"object\") {\n // If tokenizer_config.json does not contain chat_template, check for standalone chat_template.jinja\n if (!config.chat_template) {\n try {\n const jinjaUrl = `https://huggingface.co/${encodeURI(cleanModel)}/resolve/main/chat_template.jinja`;\n const jinjaRes = await fetchFn(jinjaUrl);\n if (jinjaRes.ok) {\n const jinjaText = await jinjaRes.text();\n if (jinjaText && jinjaText.trim()) {\n config.chat_template = jinjaText.trim();\n }\n }\n } catch {\n // Ignore standalone jinja fetch failures\n }\n }\n\n if (\n typeof config.model_max_length === \"number\" &&\n Number.isFinite(config.model_max_length) &&\n config.model_max_length > 0 &&\n config.model_max_length <= 2_097_152\n ) {\n const existing = modelRegistry.getModelInfo(cleanModel);\n modelRegistry.registerModelInfo(cleanModel, {\n contextWindow: config.model_max_length,\n maxOutput: existing?.maxOutput ?? null,\n ...(existing || {}),\n });\n }\n\n tokenizerConfigCache.set(cleanModel, config);\n return config;\n }\n }\n } catch (err) {\n // Network or parse error\n }\n\n return null;\n}\n\n/**\n * Map tools to the standard OpenAI/Transformers function format.\n */\nexport function mapToolsForChatTemplate(tools?: any[]): any[] | undefined {\n if (!tools || !Array.isArray(tools) || tools.length === 0) {\n return undefined;\n }\n\n return tools.map((t) => {\n if (t.type === \"function\" && t.function) {\n return {\n ...t,\n function: {\n ...t.function,\n parameters: sanitizeToolParameters(t.function.parameters),\n },\n };\n }\n return {\n type: \"function\",\n function: {\n name: t.name,\n description: t.description || \"\",\n parameters: sanitizeToolParameters(t.input_schema || t.parameters),\n },\n };\n });\n}\n\n/**\n * Normalizes messages to ensure compliance with strict chat template requirements:\n * 1. Consolidates system prompt into a single initial system message.\n * 2. Merges adjacent messages of identical role (e.g. consecutive user turns).\n * 3. Ensures strict user -> assistant -> user alternation.\n * 4. Ensures first turn after system is a user message.\n */\nexport function normalizeMessagesForChatTemplate(\n rawMessages: any[],\n systemPrompt?: string,\n): NormalizedChatMessage[] {\n let combinedSystemText = String(systemPrompt || \"\").trim();\n const nonSystem: NormalizedChatMessage[] = [];\n\n // Map known tool_call ids to their function names to resolve tool messages cleanly\n const toolCallNameById = new Map<string, string>();\n for (const msg of rawMessages) {\n if (msg?.tool_calls && Array.isArray(msg.tool_calls)) {\n for (const tc of msg.tool_calls) {\n const id = tc?.id || tc?.tool_call_id;\n const name = tc?.function?.name || tc?.name;\n if (id && name) {\n toolCallNameById.set(id, name);\n }\n }\n }\n if (Array.isArray(msg?.content)) {\n for (const b of msg.content) {\n if (b?.type === \"tool_use\" && b.id && b.name) {\n toolCallNameById.set(b.id, b.name);\n }\n }\n }\n }\n\n for (const msg of rawMessages) {\n if (!msg) continue;\n const rawRole = String(msg.role || \"user\").toLowerCase();\n const contentText = extractContentText(msg.content);\n\n if (rawRole === \"system\") {\n combinedSystemText = combinedSystemText\n ? `${combinedSystemText}\\n\\n${contentText}`\n : contentText;\n } else if (rawRole === \"tool\") {\n const resolvedName =\n msg.name ||\n (msg.tool_call_id\n ? toolCallNameById.get(msg.tool_call_id)\n : undefined) ||\n \"unknown\";\n nonSystem.push({\n role: \"tool\",\n content: contentText,\n ...(msg.tool_call_id ? { tool_call_id: msg.tool_call_id } : {}),\n name: resolvedName,\n });\n } else if (rawRole === \"assistant\" || rawRole === \"model\") {\n let toolCalls = msg.tool_calls;\n let textContent = contentText;\n\n if (Array.isArray(msg.content)) {\n const toolUseBlocks = msg.content.filter(\n (b: any) => b?.type === \"tool_use\",\n );\n if (toolUseBlocks.length > 0) {\n if (!toolCalls) {\n toolCalls = toolUseBlocks.map((b: any) => ({\n id: b.id || `call_${Math.random().toString(36).slice(2, 9)}`,\n type: \"function\",\n function: {\n name: b.name,\n arguments:\n typeof b.input === \"object\" && b.input !== null\n ? b.input\n : {},\n },\n }));\n }\n const textBlocks = msg.content.filter(\n (b: any) => b?.type !== \"tool_use\",\n );\n textContent = extractContentText(textBlocks);\n }\n }\n\n if (Array.isArray(toolCalls)) {\n toolCalls = toolCalls.map((tc: any) => {\n if (!tc || typeof tc !== \"object\") return tc;\n const fn = tc.function;\n if (\n fn &&\n typeof fn === \"object\" &&\n typeof fn.arguments === \"string\"\n ) {\n try {\n const parsedArgs = JSON.parse(fn.arguments);\n if (\n parsedArgs &&\n typeof parsedArgs === \"object\" &&\n !Array.isArray(parsedArgs)\n ) {\n return {\n ...tc,\n function: {\n ...fn,\n arguments: parsedArgs,\n },\n };\n }\n } catch {\n // Leave as string if not valid JSON\n }\n }\n return tc;\n });\n }\n nonSystem.push({\n role: \"assistant\",\n content: textContent,\n ...(toolCalls ? { tool_calls: toolCalls } : {}),\n });\n } else if (\n Array.isArray(msg.content) &&\n msg.content.some((b: any) => b?.type === \"tool_result\")\n ) {\n for (const b of msg.content) {\n if (b?.type === \"tool_result\") {\n const res =\n typeof b.content === \"string\"\n ? b.content\n : JSON.stringify(b.content || \"\");\n const resolvedName =\n b.name ||\n (b.tool_use_id ? toolCallNameById.get(b.tool_use_id) : undefined) ||\n \"unknown\";\n nonSystem.push({\n role: \"tool\",\n content: res,\n ...(b.tool_use_id ? { tool_call_id: b.tool_use_id } : {}),\n name: resolvedName,\n });\n } else {\n const nonToolText = extractContentText([b]);\n if (nonToolText) {\n nonSystem.push({ role: \"user\", content: nonToolText });\n }\n }\n }\n } else {\n nonSystem.push({ role: \"user\", content: contentText });\n }\n }\n\n // Merge consecutive messages with the same role\n const merged: NormalizedChatMessage[] = [];\n for (const msg of nonSystem) {\n if (\n merged.length > 0 &&\n merged[merged.length - 1].role === msg.role &&\n msg.role !== \"tool\"\n ) {\n const prev = merged[merged.length - 1];\n prev.content = prev.content\n ? `${prev.content}\\n\\n${msg.content}`\n : msg.content;\n if (msg.tool_calls) {\n prev.tool_calls = [...(prev.tool_calls || []), ...msg.tool_calls];\n }\n } else {\n merged.push({ ...msg });\n }\n }\n\n // If conversation starts with an assistant message, insert an initial user prompt\n if (merged.length > 0 && merged[0].role === \"assistant\") {\n merged.unshift({ role: \"user\", content: \"Hello\" });\n }\n\n // If conversation is completely empty, provide a default user turn\n if (merged.length === 0 && !combinedSystemText) {\n merged.push({ role: \"user\", content: \"Hello\" });\n }\n\n const result: NormalizedChatMessage[] = [];\n if (combinedSystemText) {\n result.push({ role: \"system\", content: combinedSystemText });\n }\n result.push(...merged);\n\n return result;\n}\n\n/**\n * Render dynamic Jinja2 chat template for messages, tools, and options.\n */\nexport async function renderChatTemplate(\n options: RenderChatTemplateOptions,\n): Promise<string> {\n const {\n modelName = \"\",\n messages,\n systemPrompt,\n tools,\n documents,\n addGenerationPrompt = true,\n customFetch,\n } = options;\n\n let templateStr: string | null = null;\n\n if (typeof options.template === \"string\") {\n templateStr = options.template;\n } else if (options.template && typeof options.template === \"object\") {\n if (tools && tools.length > 0 && \"tool_use\" in options.template) {\n templateStr = (options.template as Record<string, string>)[\"tool_use\"];\n } else if (\"default\" in options.template) {\n templateStr = (options.template as Record<string, string>)[\"default\"];\n }\n }\n\n let bosToken = options.bosToken;\n let eosToken = options.eosToken;\n\n if (!templateStr && modelName) {\n const config = await fetchTokenizerConfig(modelName, customFetch);\n if (config) {\n if (typeof config.chat_template === \"string\") {\n templateStr = config.chat_template;\n } else if (\n config.chat_template &&\n typeof config.chat_template === \"object\"\n ) {\n if (tools && tools.length > 0 && \"tool_use\" in config.chat_template) {\n templateStr = config.chat_template[\"tool_use\"];\n } else if (\"default\" in config.chat_template) {\n templateStr = config.chat_template[\"default\"];\n }\n }\n if (!bosToken && config.bos_token) {\n bosToken =\n typeof config.bos_token === \"string\"\n ? config.bos_token\n : config.bos_token.content;\n }\n if (!eosToken && config.eos_token) {\n eosToken =\n typeof config.eos_token === \"string\"\n ? config.eos_token\n : config.eos_token.content;\n }\n }\n }\n\n // Universal fallback template if still not found\n if (!templateStr) {\n templateStr = DEFAULT_CHAT_TEMPLATE;\n }\n\n const normalized = normalizeMessagesForChatTemplate(messages, systemPrompt);\n const mappedTools = mapToolsForChatTemplate(tools);\n\n let compiled = compiledTemplateCache.get(templateStr);\n if (!compiled) {\n compiled = new Template(templateStr);\n compiledTemplateCache.set(templateStr, compiled);\n }\n\n return compiled.render({\n messages: normalized,\n tools: mappedTools,\n documents: documents || null,\n add_generation_prompt: addGenerationPrompt,\n bos_token: bosToken || \"\",\n eos_token: eosToken || \"\",\n pad_token: options.padToken || \"\",\n unk_token: options.unkToken || \"\",\n });\n}\n"],"ignoreList":[0],"mappings":"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"}
|