@weasel-js/routing 1.8.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/interactions/actions/activeToolContext.tsx","../src/interactions/actions/depRegistry.tsx","../src/interactions/dispatcher/useGestureDispatcher.tsx","../src/interactions/actions/ActionsProvider.tsx","../src/interactions/actions/inputScope.tsx","../src/interactions/actions/useOngoingAction.ts","../src/contributions/useContributions.ts","../src/tools/useTools.ts"],"names":["createContext","useMemo","jsx","useContext","useLatest","useEffect","useRef","useCallback","useStableByContent","sameList"],"mappings":";;;;;;;;AAoDO,IAAM,QAAA,GAAN,cAAuB,SAAA,CAAoB;AAAA,EACxC,KAAA;AAAA,EACA,KAAA,GAAkF,IAAA;AAAA,EAE1F,WAAA,CAAY,MAAA,EAAyB,QAAA,EAAmB,IAAA,EAAe,aAAA,EAA8B;AACnG,IAAA,KAAA,CAAM,QAAQ,QAAQ,CAAA;AAGtB,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,GACT,EAAE,MAAA,EAAQ,iBAAiB,MAAA,EAAQ,KAAA,EAAM,CAAE,KAAA,EAAO,MAAA,IAAU,IAAA,EAAM,WAAA,EAAa,IAAG,GAClF,IAAA;AAAA,EACN;AAAA;AAAA,EAGA,KAAA,GAAkB;AAChB,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,KAAA,EAAM,CAAE,OAAM,EAAG,IAAI,CAAA,CAAE,KAAA,EAAO,OAAO,CAAA;AAC1D,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEQ,OAAO,IAAA,EAAyC;AACtD,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,EAAM;AACzB,IAAA,IAAI,CAAC,MAAM,KAAA,EAAO;AAClB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAChC,IAAA,IAAI,OAAA,KAAY,MAAM,KAAA,EAAO;AAC7B,IAAA,KAAA,CAAM,KAAA,GAAQ,OAAA;AACd,IAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,EAChB;AAAA;AAAA,EAGA,QAAA,GAAmC;AACjC,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,EAAM;AACxB,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,EAAE,QAAQ,IAAA,EAAM,WAAA,EAAa,EAAC,EAAE;AAC5D,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA;AACpB,IAAA,IAAI,MAAA,IAAU,OAAO,IAAA,KAAS,IAAA,IAAQ,OAAO,KAAA,KAAU,KAAA,SAAc,MAAA,CAAO,GAAA;AAC5E,IAAA,MAAM,GAAA,GAA8B;AAAA,MAClC,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,WAAW,CAAC,EAAA,KAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAO,CAAA,CAAE,MAAA,KAAW,EAAA,GAAK,IAAI,EAAE,GAAG,CAAA,EAAG,MAAA,EAAQ,IAAK,CAAA;AAAA,MAClF,YAAY,CAAC,EAAA,KAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,aAAa,CAAC,GAAG,EAAE,WAAA,EAAa,EAAE,GAAE,CAAE,CAAA;AAAA,MACtF,WAAW,CAAC,EAAA,KACV,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM;AACjB,QAAA,MAAM,QAAQ,CAAA,CAAE,WAAA;AAChB,QAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,CAAA;AAC/B,QAAA,IAAI,EAAA,KAAO,MAAA,EAAW,OAAO,EAAE,GAAG,CAAA,EAAG,WAAA,EAAa,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,EAAE;AACrE,QAAA,MAAM,CAAA,GAAI,KAAA,CAAM,WAAA,CAAY,EAAE,CAAA;AAC9B,QAAA,OAAO,CAAA,KAAM,KAAK,CAAA,GAAI,EAAE,GAAG,CAAA,EAAG,WAAA,EAAa,CAAC,GAAG,KAAA,CAAM,MAAM,CAAA,EAAG,CAAC,GAAG,GAAG,KAAA,CAAM,MAAM,CAAA,GAAI,CAAC,CAAC,CAAA,EAAE;AAAA,MAC3F,CAAC;AAAA,KACL;AACA,IAAA,IAAA,CAAK,KAAA,GAAQ,EAAE,IAAA,EAAM,KAAA,EAAO,GAAA,EAAI;AAChC,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,SAAA,GAAY,CAAC,QAAA,KAAuC;AAClD,IAAA,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA;AAChC,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,IACrC,CAAA;AAAA,EACF,CAAA;AACF,CAAA;AAEA,IAAM,iBAAA,GAAoB,cAA+B,IAAI,CAAA;AAGtD,IAAM,qBAAA,GAAwB,iBAAA;AAY9B,SAAS,yBAAA,CAA0B;AAAA,EACxC,QAAA;AAAA,EACA,aAAA,GAAgB;AAClB,CAAA,EAAmC;AACjC,EAAA,MAAM,CAAC,IAAI,CAAA,GAAI,QAAA,CAAS,MAAM,IAAI,QAAA,CAAS,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,aAAa,CAAC,CAAA;AAC3E,EAAA,2BAAQ,iBAAA,CAAkB,QAAA,EAAlB,EAA2B,KAAA,EAAO,MAAO,QAAA,EAAS,CAAA;AAC5D;AAEA,SAAS,aAAa,IAAA,EAAsD;AAC1E,EAAA,MAAM,SAAA,GAAY,QAAQ,MAAM,IAAA,EAAM,aAAa,YAAA,EAAc,CAAC,IAAI,CAAC,CAAA;AACvE,EAAA,OAAO,oBAAA;AAAA,IACL,SAAA;AAAA,IACA,MAAM,IAAA,EAAM,QAAA,EAAS,IAAK,IAAA;AAAA,IAC1B,MAAM,IAAA,EAAM,QAAA,EAAS,IAAK;AAAA,GAC5B;AACF;AAEA,IAAM,YAAA,GAAe,MAAoB,MAAM;AAAC,CAAA;AAIzC,SAAS,oBAAA,GAA+C;AAC7D,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,UAAA,CAAW,iBAAiB,CAAC,CAAA;AACxD,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAQO,SAAS,4BAAA,GAA8D;AAC5E,EAAA,OAAO,YAAA,CAAa,UAAA,CAAW,iBAAiB,CAAC,CAAA;AACnD;AAOO,SAAS,+BAAA,CAAgC;AAAA,EAC9C;AACF,CAAA,EAEG;AACD,EAAA,MAAM,MAAA,GAAS,WAAW,iBAAiB,CAAA;AAC3C,EAAA,IAAI,MAAA,KAAW,IAAA,EAAM,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAS,CAAA;AACxC,EAAA,uBAAO,GAAA,CAAC,6BAA2B,QAAA,EAAS,CAAA;AAC9C;ACxKO,IAAM,kBAAA,GAAqBA,cAAkC,IAAI,CAAA;AAIjE,SAAS,mBAAA,CAAoB,EAAE,QAAA,EAAS,EAA4B;AACzE,EAAA,MAAM,QAAA,GAAWC,OAAAA,CAAQ,iBAAA,EAAmB,EAAE,CAAA;AAC9C,EAAA,uBAAOC,GAAAA,CAAC,kBAAA,CAAmB,UAAnB,EAA4B,KAAA,EAAO,UAAW,QAAA,EAAS,CAAA;AACjE;AAGO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,CAAA,GAAIC,WAAW,kBAAkB,CAAA;AACvC,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,MAAM,IAAI,MAAM,8HAA8H,CAAA;AAAA,EAChJ;AACA,EAAA,OAAO,CAAA;AACT;AAOO,SAAS,sBAAA,GAA6C;AAC3D,EAAA,OAAOA,WAAW,kBAAkB,CAAA;AACtC;AAKO,SAAS,YAAA,CAAgC,MAAS,MAAA,EAA4B;AACnF,EAAA,MAAM,WAAW,cAAA,EAAe;AAChC,EAAA,MAAM,SAAA,GAAY,UAAU,MAAM,CAAA;AAClC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAO,SAAS,QAAA,CAAS,IAAA,EAAM,MAAM,SAAA,CAAU,SAAS,CAAA;AAAA,EAC1D,CAAA,EAAG,CAAC,IAAA,EAAM,QAAA,EAAU,SAAS,CAAC,CAAA;AAChC;ACHA,IAAM,cAAA,GAAiB,iBAAA;AAWvB,SAAS,SAAS,CAAA,EAEhB;AACA,EAAA,OAAO;AAAA,IACL,GAAI,OAAO,CAAA,CAAE,QAAA,KAAa,QAAA,GAAW,EAAE,QAAA,EAAU,CAAA,CAAE,QAAA,EAAS,GAAI,EAAC;AAAA,IACjE,GAAI,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,GAAI,EAAC;AAAA,IACxD,GAAI,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,GAAI;AAAC,GAC1D;AACF;AAMA,IAAM,MAAA,GACJ,OAAO,SAAA,KAAc,WAAA,IACrB,MAAA,CAAO,IAAA;AAAA;AAAA;AAAA,EAGJ,SAAA,CAAoC,YAAY,SAAA,CAAU;AAC7D,CAAA;AAqDF,SAAS,YAAA,CACP,MACA,OAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,CAAC,IAAA,EAAM,MAAA,KAAW,MAAK,CAAE,QAAA,CAAS,MAAM,MAAM,CAAA;AAAA,IACxD,GAAA,EAAK,CAAoB,IAAA,KAAsC;AAC7D,MAAA,MAAM,GAAA,GAAM,OAAA,EAAQ,GAAI,IAAI,CAAA;AAC5B,MAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,GAAA;AAC9B,MAAA,OAAO,IAAA,EAAK,CAAE,GAAA,CAAI,IAAI,CAAA;AAAA,IACxB;AAAA,GACF;AACF;AA4PA,SAAS,0BACP,SAAA,EACwD;AACxD,EAAA,MAAM,GAAA,GAAM,CAAC,GAAG,SAAS,CAAA;AACzB,EAAA,IAAI,GAAA,CAAI,SAAS,CAAA,EAAG;AAClB,IAAA,OAAO,EAAE,UAAU,EAAE,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAE,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA,EAC/C;AAEA,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,MAAW,KAAK,GAAA,EAAK;AACnB,IAAA,IAAA,IAAQ,CAAA,CAAE,CAAA;AACV,IAAA,IAAA,IAAQ,CAAA,CAAE,CAAA;AAAA,EACZ;AACA,EAAA,MAAM,QAAA,GAAW,EAAE,CAAA,EAAG,IAAA,GAAO,IAAI,MAAA,EAAQ,CAAA,EAAG,IAAA,GAAO,GAAA,CAAI,MAAA,EAAO;AAE9D,EAAA,MAAM,KAAK,GAAA,CAAI,CAAC,EAAE,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA,CAAE,CAAA;AAC7B,EAAA,MAAM,KAAK,GAAA,CAAI,CAAC,EAAE,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA,CAAE,CAAA;AAC7B,EAAA,MAAM,SAAS,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AAC1C,EAAA,OAAO,EAAE,UAAU,MAAA,EAAO;AAC5B;AAeO,SAAS,qBAAqB,IAAA,EAAyC;AAC5E,EAAA,MAAM,EAAE,WAAW,OAAA,EAAS,WAAA,EAAa,UAAU,IAAA,EAAM,QAAA,GAAW,MAAM,YAAA,EAAc,cAAA,EAAgB,YAAY,aAAA,EAAe,aAAA,EAAe,eAAe,aAAA,EAAe,UAAA,EAAY,eAAe,KAAA,EAAO,QAAA,EAAU,WAAU,GAAI,IAAA;AAI1O,EAAA,MAAM,cAAA,GAAiB,UAAU,OAAA,KAAY,KAAA;AAC7C,EAAA,MAAM,YAAA,GAAe,UAAU,KAAA,KAAU,KAAA;AACzC,EAAA,MAAM,YAAA,GAAe,UAAU,KAAA,KAAU,KAAA;AACzC,EAAA,MAAM,kBAAA,GAAqB,UAAU,WAAA,KAAgB,KAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,UAAU,MAAA,KAAW,KAAA;AAC3C,EAAA,MAAM,gBAAA,GAAmBC,UAAU,aAAa,CAAA;AAChD,EAAA,MAAM,aAAa,oBAAA,EAAqB;AACxC,EAAA,MAAM,cAAc,cAAA,EAAe;AAInC,EAAA,MAAM,aAAA,GAAgB,OAA0B,IAAI,CAAA;AACpD,EAAA,IAAI,CAAC,cAAc,OAAA,EAAS;AAC1B,IAAA,aAAA,CAAc,OAAA,GAAU,iBAAiB,gBAAA,EAAiB;AAAA,EAC5D;AAMA,EAAA,MAAM,WAAA,GAAcA,UAAU,OAAO,CAAA;AACrC,EAAA,MAAM,SAASA,SAAAA,CAA6B;AAAA,IAC1C,OAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAc,UAAA,CAAW,MAAA;AAAA,IACzB,aAAa,UAAA,CAAW,WAAA;AAAA,IACxB,WAAA;AAAA,IACA,KAAA,EAAO;AAAA,GACR,CAAA;AAGD,EAAA,MAAM,gBAAgBA,SAAAA,CAAgC;AAAA,IACpD,EAAA,EAAI,IAAA;AAAA,IAAM,YAAY,aAAA,CAAc,OAAA;AAAA,IAAS,YAAA;AAAA,IAAc,cAAA;AAAA,IAAgB,aAAA;AAAA,IAC3E;AAAA,GACD,CAAA;AACD,EAAA,MAAM,QAAA,GAAWA,UAAU,KAAK,CAAA;AAGhC,EAAA,MAAM,cAAA,GAAiB,YAAY,MAAoB;AAAA,IACrD,cAAc,OAAA,CAAQ,UAAA;AAAA,IACtB,GAAA,CAAI,QAAA,CAAS,OAAA,EAAS,OAAA,EAAQ,IAAK,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU;AAAA,GAChE,EAAG,CAAC,aAAA,EAAe,QAAQ,CAAC,CAAA;AAC5B,EAAA,MAAM,gBAAA,GAAmBA,UAAU,aAAa,CAAA;AAChD,EAAA,MAAM,gBAAA,GAAmBA,UAAU,aAAa,CAAA;AAChD,EAAA,MAAM,YAAA,GAAeA,UAAU,SAAS,CAAA;AAMxC,EAAA,MAAM,YAAA,GAAe,OAA+D,IAAI,CAAA;AAQxF,EAAA,MAAM,YAAA,GAAe,MAAA,iBAA4B,IAAI,GAAA,EAAK,CAAA;AAC1D,EAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,UAAA,CAAW,MAAM,CAAA;AAC9C,EAAA,MAAM,cAAA,GAAiBA,UAAU,WAAW,CAAA;AAC5C,EAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,CAAC,EAAA,EAAY,IAAA,KAA8C;AAC3F,IAAA,MAAM,IAAA,GAAO,cAAA,CAAe,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AAC1C,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,MAAA,CAAO,IAAI,CAAA,EAAG;AAC5B,IAAA,MAAM,EAAA,GAAK,KAAK,IAAI,CAAA;AACpB,IAAA,IAAI,CAAC,EAAA,EAAI;AACT,IAAA,IAAI;AACF,MAAA,EAAA,CAAG,EAAE,OAAA,EAAS,IAAA,CAAK,WAAA,MAAiB,CAAA;AAAA,IACtC,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,MAAM,CAAA,cAAA,EAAiB,EAAE,CAAA,EAAA,EAAK,IAAI,UAAU,GAAG,CAAA;AAAA,IACzD;AAAA,EACF,CAAA,EAAG,CAAC,cAAc,CAAC,CAAA;AACnB,EAAAC,UAAU,MAAM;AACd,IAAA,MAAM,OAAO,YAAA,CAAa,OAAA;AAC1B,IAAA,MAAM,OAAO,IAAI,GAAA;AAAA,MACf,UAAA,CAAW,MAAA,KAAW,IAAA,GAAO,UAAA,CAAW,WAAA,GAAc,CAAC,UAAA,CAAW,MAAA,EAAQ,GAAG,UAAA,CAAW,WAAW;AAAA,KACrG;AACA,IAAA,YAAA,CAAa,OAAA,GAAU,IAAA;AACvB,IAAA,KAAA,MAAW,EAAA,IAAM,IAAA,EAAM,IAAI,CAAC,IAAA,CAAK,IAAI,EAAE,CAAA,EAAG,aAAA,CAAc,EAAA,EAAI,cAAc,CAAA;AAC1E,IAAA,IAAI,aAAA,CAAc,OAAA,KAAY,UAAA,CAAW,MAAA,EAAQ;AAC/C,MAAA,KAAA,MAAW,CAAA,IAAK,cAAA,EAAe,EAAG,CAAA,CAAE,UAAU,QAAQ,CAAA;AAAA,IACxD;AACA,IAAA,aAAA,CAAc,UAAU,UAAA,CAAW,MAAA;AACnC,IAAA,KAAA,MAAW,EAAA,IAAM,IAAA,EAAM,IAAI,CAAC,IAAA,CAAK,IAAI,EAAE,CAAA,EAAG,aAAA,CAAc,EAAA,EAAI,YAAY,CAAA;AAAA,EAC1E,CAAC,CAAA;AACD,EAAAA,SAAAA,CAAU,MAAM,MAAM;AACpB,IAAA,MAAM,OAAO,YAAA,CAAa,OAAA;AAC1B,IAAA,YAAA,CAAa,OAAA,uBAAc,GAAA,EAAI;AAC/B,IAAA,KAAA,MAAW,EAAA,IAAM,IAAA,EAAM,aAAA,CAAc,EAAA,EAAI,cAAc,CAAA;AAAA,EACzD,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AAElB,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,IAAI,QAAA,GAAW,KAAA;AAKf,IAAA,IAAI,QAAA,GAA0B,IAAA;AAG9B,IAAA,MAAM,SAAS,MAA4B;AACzC,MAAA,IAAI,QAAA,KAAa,IAAA,EAAM,OAAO,aAAA,CAAc,OAAA;AAC5C,MAAA,OAAO,QAAA,CAAS,OAAA,EAAS,OAAA,EAAQ,CAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,QAAQ,CAAA,IAC3D,aAAA,CAAc,OAAA;AAAA,IACrB,CAAA;AAIA,IAAA,MAAM,OAAA,GAAU,CAAC,SAAA,EAA0B,OAAA,EAAiB,OAAA,KAA0B;AACpF,MAAA,QAAA,GAAW,QAAA,CAAS,SAAS,QAAA,CAAS,EAAA,CAAG,WAAW,OAAA,EAAS,OAAO,EAAE,EAAA,IAAM,IAAA;AAAA,IAC9E,CAAA;AAEA,IAAA,MAAM,SAAA,GAAY,CAAC,SAAA,EAAmB,OAAA,EAAiB,OAAA,KAA0B;AAC/E,MAAA,QAAA,GAAW,QAAA,CAAS,SAAS,QAAA,CAAS,KAAA,CAAM,WAAW,OAAA,EAAS,OAAO,EAAE,EAAA,IAAM,IAAA;AAAA,IACjF,CAAA;AACA,IAAA,MAAM,YAAA,GAAe,CAAC,SAAA,KAA4B;AAChD,MAAA,QAAA,CAAS,OAAA,EAAS,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AAAA,IAC1C,CAAA;AAIA,IAAA,MAAM,aAAA,GAAgB,MAAkB,MAAA,EAAO,CAAE,UAAA;AAEjD,IAAA,MAAM,UAAA,GAAa,YAAA,CAAa,MAAM,MAAA,CAAO,OAAA,CAAQ,aAAa,MAAM,MAAA,EAAO,CAAE,IAAA,IAAQ,CAAA;AAGzF,IAAA,MAAM,aAAA,GAAgB,MACpB,MAAA,EAAO,CAAE,UAAA,IAAa;AACxB,IAAA,MAAM,SAAS,OAA0B;AAAA,MACvC,GAAG,MAAA,CAAO,OAAA;AAAA,MAAS,WAAA,EAAa,UAAA;AAAA,MAAY,UAAA,EAAY,aAAA;AAAA,MACxD,MAAA,EAAQ,QAAO,CAAE;AAAA,KACnB,CAAA;AACA,IAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AAQzB,IAAA,MAAM,OAAA,GAAU,CAAC,EAAA,EAAY,EAAA,KAAyC;AACpE,MAAA,MAAM,EAAA,GAAK,QAAO,CAAE,aAAA;AACpB,MAAA,OAAO,EAAA,GAAK,GAAG,EAAA,EAAI,EAAE,IAAI,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAG;AAAA,IAC1C,CAAA;AAYA,IAAA,MAAM,QAAA,GAAW,CAAC,EAAA,EAAgB,EAAA,KAA6C;AAC7E,MAAA,MAAM,CAAA,GAAI,MAAM,aAAA,EAAc;AAC9B,MAAA,MAAM,MAAA,GAAS,CAAA,CAAE,QAAA,EAAS,CAAE,IAAA;AAC5B,MAAA,MAAM,MAAA,GAAS,CAAA,CAAE,WAAA,CAAY,EAAA,EAAI,QAAQ,CAAA;AACzC,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,QAAA,EAAS,CAAE,IAAA;AAC3B,MAAA,IAAI,MAAA,GAAS,CAAA,IAAK,KAAA,GAAQ,CAAA,mBAAoB,OAAA,IAAU;AACxD,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAIA,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAoB;AACzC,IAAA,MAAM,cAAc,CAAC,CAAA,KAA6B,EAAE,IAAA,IAAQ,CAAA,CAAE,IAAI,WAAA,EAAY;AAK9E,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAyB;AAK1C,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA0D;AAC/E,MAAA,MAAM,IAAA,GAAO,QAAQ,qBAAA,EAAsB;AAC3C,MAAA,IAAI,CAAC,MAAM,OAAO,CAAA;AAClB,MAAA,MAAM,CAAC,GAAG,CAAC,CAAA,GAAI,mBAAmB,IAAA,EAAM,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA;AAChD,MAAA,OAAO,EAAE,GAAG,CAAA,EAAE;AAAA,IAChB,CAAA;AACA,IAAA,MAAM,eAAe,MAAM;AACzB,MAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAO,GAAI,yBAAA;AAAA,QAC3B,CAAC,GAAG,IAAA,CAAK,MAAA,EAAQ,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG;AAAA,OACrC;AACA,MAAA,OAAO,EAAE,QAAA,EAAU,aAAA,CAAc,QAAQ,GAAG,MAAA,EAAO;AAAA,IACrD,CAAA;AAKA,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,IAAI,UAAA,GAAa,CAAA;AACjB,IAAA,IAAI,aAAA,GAAgB,CAAA;AAEpB,IAAA,MAAM,WAAW,MAAY;AAC3B,MAAA,SAAA,GAAY,KAAA;AACZ,MAAA,UAAA,GAAa,CAAA;AACb,MAAA,aAAA,GAAgB,CAAA;AAAA,IAClB,CAAA;AAKA,IAAA,IAAI,eAAA,GAAkF,IAAA;AACtF,IAAA,MAAM,gBAAA,GAAmB,CAAA;AAKzB,IAAA,MAAM,eAAA,uBAAsB,GAAA,EAA2C;AAEvE,IAAA,MAAM,YAAA,GAAe,CAAC,SAAA,KAA6B;AACjD,MAAA,MAAM,KAAA,GAAQ,aAAa,OAAA,EAAS,KAAA;AACpC,MAAA,MAAM,CAAA,GAAI,OAAO,GAAA,EAAI;AACrB,MAAA,IAAI,CAAA,KAAM,cAAc,MAAA,IAAa,CAAA,CAAE,cAAc,SAAA,CAAA,EAAY,KAAA,CAAO,IAAI,IAAI,CAAA;AAAA,IAClF,CAAA;AAEA,IAAA,MAAM,eAAA,GAAkB,CAAC,SAAA,KAA4B;AACnD,MAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,GAAA,CAAI,SAAS,CAAA;AACvC,MAAA,IAAI,MAAM,MAAA,EAAW;AACnB,QAAA,YAAA,CAAa,CAAC,CAAA;AACd,QAAA,eAAA,CAAgB,OAAO,SAAS,CAAA;AAAA,MAClC;AACA,MAAA,YAAA,CAAa,SAAS,CAAA;AAAA,IACxB,CAAA;AAEA,IAAA,MAAM,qBAAqB,MAAY;AACrC,MAAA,KAAA,MAAW,CAAA,IAAK,eAAA,CAAgB,MAAA,EAAO,eAAgB,CAAC,CAAA;AACxD,MAAA,eAAA,CAAgB,KAAA,EAAM;AACtB,MAAA,YAAA,EAAa;AAAA,IACf,CAAA;AAEA,IAAA,MAAM,SAAA,GAAY,EAAA;AAKlB,IAAA,MAAM,eAAA,GAAkB,CAAC,IAAA,KAAkF;AACzG,MAAA,MAAM,MAAA,GAAS;AAAA,QACb,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,QACvE,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,QACvE,GAAI,KAAK,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAS,GAAI;AAAC,OACnE;AAEA,MAAA,MAAM,EAAA,GAAK,EAAE,CAAA,EAAG,IAAA,CAAK,MAAA,EAAQ,CAAA,EAAG,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,IAAA,CAAK,OAAA,EAAS,OAAA,EAAS,KAAK,OAAA,EAAQ;AAC1F,MAAA,OAAO;AAAA,QACL,WAAW,EAAE,IAAA,EAAM,aAAa,GAAG,EAAA,EAAI,GAAG,MAAA,EAAO;AAAA,QACjD,aAAa,EAAE,IAAA,EAAM,eAAe,GAAG,EAAA,EAAI,GAAG,MAAA;AAAO,OACvD;AAAA,IACF,CAAA;AAIA,IAAA,MAAM,kBAAA,GAAqB,CAAC,IAAA,KAAuC;AACjE,MAAA,MAAM,GAAA,GAAM,gBAAgB,IAAI,CAAA;AAChC,MAAA,MAAM,IAAI,aAAA,EAAc;AACxB,MAAA,OAAO,CAAA,CAAE,WAAA,CAAY,GAAA,CAAI,SAAA,EAAW,QAAQ,CAAA,KAAM,IAAA,IAC7C,CAAA,CAAE,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,MAAA,EAAQ,CAAA,KAAM,IAAA;AAAA,IACpD,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,SAAA,EAAmB,WAAA,KAA8B;AACtE,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA,EAAG,IAAA;AAClC,MAAA,YAAA,CAAa,SAAS,CAAA;AACtB,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,MAAM,GAAA,GAAM,gBAAgB,IAAI,CAAA;AAChC,MAAA,IAAI,MAAA,GAAS,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AACnC,MAAA,IAAI,MAAA,KAAW,WAAA,EAAa,MAAA,GAAS,QAAA,CAAS,IAAI,WAAW,CAAA;AAC7D,MAAA,IAAI,WAAW,SAAA,IAAa,YAAA,CAAa,OAAA,EAAS,OAAA,KAAY,UACtD,WAAA,KAAgB,OAAA,IAAW,WAAA,KAAgB,KAAA,CAAA,IAC5C,OAAO,SAAA,KAAc,WAAA,IAAe,OAAO,SAAA,CAAU,YAAY,UAAA,EAAY;AAClF,QAAA,SAAA,CAAU,QAAQ,SAAS,CAAA;AAAA,MAC7B;AAAA,IACF,CAAA;AAMA,IAAA,MAAM,mBAAA,GAAsB,GAAA;AAC5B,IAAA,MAAM,mBAAA,GAAsB,CAAA;AAM5B,IAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAqB;AACtC,MAAA,IAAI,CAAA,CAAE,gBAAA,IAAoB,gBAAA,CAAiB,CAAA,CAAE,MAAM,CAAA,EAAG;AAEtD,MAAA,IAAI,CAAC,WAAA,CAAY,OAAA,CAAQ,QAAA,EAAS,EAAG;AAQrC,MAAA,IAAI,EAAE,MAAA,IAAU,QAAA,CAAS,IAAI,WAAA,CAAY,CAAC,CAAC,CAAA,EAAG;AAC5C,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA;AAAA,MACF;AAOA,MAAA,MAAM,KAAA,GAAoB;AAAA,QACxB,IAAA,EAAM,KAAA;AAAA,QACN,KAAK,CAAA,CAAE,GAAA;AAAA,QACP,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,QAAQ,CAAA,CAAE;AAAA,OACZ;AACA,MAAA,MAAM,SAAA,GAAY,SAAS,KAAK,CAAA;AAMhC,MAAA,MAAM,MAAA,GAAqB;AAAA,QACzB,IAAA,EAAM,UAAA;AAAA,QACN,KAAK,CAAA,CAAE,GAAA;AAAA,QACP,KAAA,EAAO,MAAA;AAAA,QACP,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE;AAAA,OACd;AACA,MAAA,MAAM,UAAA,GAAa,SAAS,MAAM,CAAA;AAElC,MAAA,IAAI,eAAe,SAAA,EAAW;AAC5B,QAAA,QAAA,CAAS,GAAA,CAAI,WAAA,CAAY,CAAC,CAAA,EAAG,EAAE,GAAG,CAAA;AAAA,MACpC;AAEA,MAAA,IAAI,SAAA,KAAc,SAAA,IAAa,UAAA,KAAe,SAAA,EAAW;AACvD,QAAA,CAAA,CAAE,cAAA,EAAe;AAAA,MACnB;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAqB;AACpC,MAAA,MAAM,QAAA,GAAW,YAAY,CAAC,CAAA;AAC9B,MAAA,MAAM,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA;AACrC,MAAA,IAAI,YAAY,MAAA,EAAW;AAC3B,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,UAAA;AAAA,QACN,GAAA,EAAK,OAAA;AAAA,QACL,KAAA,EAAO,IAAA;AAAA,QACP,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE;AAAA,OACd;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AACX,MAAA,QAAA,CAAS,OAAO,QAAQ,CAAA;AAAA,IAC1B,CAAA;AAMA,IAAA,MAAM,eAAe,MAAM;AACzB,MAAA,QAAA,EAAS;AACT,MAAA,KAAA,MAAW,CAAA,IAAK,CAAC,GAAG,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAO;AACrD,MAAA,KAAA,MAAW,GAAA,IAAO,QAAA,CAAS,MAAA,EAAO,EAAG;AACnC,QAAA,MAAM,EAAA,GAAiB;AAAA,UACrB,IAAA,EAAM,UAAA;AAAA,UACN,GAAA;AAAA,UACA,KAAA,EAAO,IAAA;AAAA,UACP,MAAA,EAAQ,KAAA;AAAA,UACR,OAAA,EAAS,KAAA;AAAA,UACT,OAAA,EAAS,KAAA;AAAA,UACT,QAAA,EAAU;AAAA,SACZ;AACA,QAAA,QAAA,CAAS,EAAE,CAAA;AAAA,MACb;AACA,MAAA,QAAA,CAAS,KAAA,EAAM;AAAA,IACjB,CAAA;AAMA,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAkB;AACjC,MAAA,WAAA,CAAY,QAAQ,QAAA,EAAS;AAG7B,MAAA,IAAI,SAAA,IAAa,EAAE,OAAA,EAAS;AAC1B,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,QAAA;AAAA,MACF;AACA,MAAA,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAKlC,MAAA,MAAM,IAAA,GAAO,QAAQ,qBAAA,EAAsB;AAC3C,MAAA,MAAM,CAAC,MAAA,EAAQ,MAAM,CAAA,GAAI,IAAA,GACrB,mBAAmB,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA,GAC7C,CAAC,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACzB,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAC7C,MAAA,MAAM,UAAA,GAAa,MAAA,EAAO,CAAE,YAAA,GAAe,QAAQ,CAAA,IAAK,MAAA;AACxD,MAAA,MAAM,IAAA,GAAO,MAAA,EAAO,CAAE,cAAA,GAAiB,QAAQ,CAAA;AAC/C,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,OAAA;AAAA,QACN,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,OAAA,EAAS,MAAA;AAAA,QACT,OAAA,EAAS,MAAA;AAAA,QACT,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,MAAM,IAAA,KAAS,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,IAAA,EAAK,GAAI,EAAC;AAAA,QAC5D,GAAI,MAAM,IAAA,KAAS,MAAA,GAAY,EAAE,QAAA,EAAU,IAAA,CAAK,IAAA,EAAK,GAAI;AAAC,OAC5D;AACA,MAAA,MAAM,MAAA,GAAS,SAAS,EAAE,CAAA;AAG1B,MAAA,IAAI,WAAW,SAAA,EAAW;AACxB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,CAAA,CAAE,wBAAA,EAAyB;AAAA,MAC7B;AAAA,IACF,CAAA;AAMA,IAAA,MAAM,YAAA,GAAe,CAAC,CAAA,EAAU,KAAA,EAAe,QAAA,KAAiC;AAC9E,MAAA,MAAM,CAAA,GAAI,CAAA;AAIV,MAAA,MAAM,IAAA,GAAO,QAAQ,qBAAA,EAAsB;AAG3C,MAAA,MAAM,EAAA,GAAK,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,GAAW,CAAA,CAAE,OAAA,GAAW,IAAA,GAAO,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,KAAA,GAAQ,CAAA,GAAI,CAAA;AAC5F,MAAA,MAAM,EAAA,GAAK,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,GAAW,CAAA,CAAE,OAAA,GAAW,IAAA,GAAO,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,CAAA;AAC5F,MAAA,OAAA,CAAQ,IAAA,EAAM,IAAI,EAAE,CAAA;AACpB,MAAA,MAAM,CAAC,MAAA,EAAQ,MAAM,CAAA,GAAI,IAAA,GAAO,kBAAA,CAAmB,IAAA,EAAM,EAAA,EAAI,EAAE,CAAA,GAAI,CAAC,EAAA,EAAI,EAAE,CAAA;AAC1E,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,EAAA,EAAI,EAAE,CAAA;AAC/B,MAAA,MAAM,UAAA,GAAa,MAAA,EAAO,CAAE,YAAA,GAAe,QAAQ,CAAA,IAAK,MAAA;AACxD,MAAA,MAAM,IAAA,GAAO,MAAA,EAAO,CAAE,cAAA,GAAiB,QAAQ,CAAA;AAC/C,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,OAAA;AAAA,QACN,MAAA,EAAQ,EAAE,MAAA,KAAW,IAAA;AAAA,QACrB,OAAA,EAAS,EAAE,OAAA,KAAY,IAAA;AAAA,QACvB,OAAA,EAAS,EAAE,OAAA,KAAY,IAAA;AAAA,QACvB,QAAA,EAAU,EAAE,QAAA,KAAa,IAAA;AAAA,QACzB,KAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA,EAAS,MAAA;AAAA,QACT,OAAA,EAAS,MAAA;AAAA,QACT,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,MAAM,IAAA,KAAS,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,IAAA,EAAK,GAAI,EAAC;AAAA,QAC5D,GAAI,MAAM,IAAA,KAAS,MAAA,GAAY,EAAE,QAAA,EAAU,IAAA,CAAK,IAAA,EAAK,GAAI;AAAC,OAC5D;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,cAAA,GAAiB,CAAC,CAAA,KAAa;AACnC,MAAA,QAAA,EAAS;AAKT,MAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAClC,MAAA,IAAI,eAAc,CAAE,WAAA,CAAY,OAAO,MAAA,EAAQ,MAAM,IAAA,EAAM;AAC3D,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,CAAA,CAAE,cAAA,EAAe;AAAA,IACnB,CAAA;AAEA,IAAA,MAAM,eAAA,GAAkB,CAAC,CAAA,KAAa;AACpC,MAAA,MAAM,CAAA,GAAI,CAAA;AACV,MAAA,MAAM,KAAA,GAAQ,OAAO,CAAA,CAAE,KAAA,KAAU,YAAY,CAAA,CAAE,KAAA,GAAQ,CAAA,GAAI,CAAA,CAAE,KAAA,GAAQ,UAAA;AACrE,MAAA,MAAM,WAAW,OAAO,CAAA,CAAE,QAAA,KAAa,QAAA,GAAW,EAAE,QAAA,GAAW,aAAA;AAC/D,MAAA,MAAM,OAAO,KAAA,GAAQ,UAAA;AACrB,MAAA,MAAM,OAAO,QAAA,GAAW,aAAA;AACxB,MAAA,UAAA,GAAa,KAAA;AACb,MAAA,aAAA,GAAgB,QAAA;AAChB,MAAA,IAAI,SAAS,YAAA,CAAa,CAAA,EAAG,MAAM,IAAI,CAAC,MAAM,SAAA,EAAW;AACvD,QAAA,SAAA,GAAY,IAAA;AACZ,QAAA,CAAA,CAAE,cAAA,EAAe;AAAA,MACnB,WAAW,SAAA,EAAW;AAGpB,QAAA,CAAA,CAAE,cAAA,EAAe;AAAA,MACnB;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,YAAA,GAAe,CAAC,CAAA,KAAa;AACjC,MAAA,IAAI,SAAA,IAAa,cAAA,EAAe;AAChC,MAAA,QAAA,EAAS;AAAA,IACX,CAAA;AASA,IAAA,IAAI,kBAAA,GAAqB,KAAA;AACzB,IAAA,MAAM,mBAAA,GAAsB,CAAC,CAAA,KAAkB;AAC7C,MAAA,IAAI,CAAC,kBAAA,EAAoB;AACzB,MAAA,kBAAA,GAAqB,KAAA;AACrB,MAAA,CAAA,CAAE,cAAA,EAAe;AAAA,IACnB,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAoB;AACzC,MAAA,kBAAA,GAAqB,KAAA;AAErB,MAAA,WAAA,CAAY,QAAQ,QAAA,EAAS;AAS7B,MAAA,IAAA,CAAK,CAAA,CAAE,MAAA,IAAU,CAAA,MAAO,CAAA,EAAG;AAC3B,MAAA,IAAI,CAAC,MAAA,EAAQ;AAGb,MAAA,IAAI,iBAAA,CAAkB,CAAA,CAAE,MAAA,EAAQ,MAAM,CAAA,EAAG;AACzC,MAAA,SAAA,CAAU,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAE3C,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACtC,MAAA,MAAM,UAAA,GAAa,MAAA,EAAO,CAAE,YAAA,GAAe,CAAC,CAAA,IAAK,MAAA;AACjD,MAAA,MAAM,IAAA,GAAO,MAAA,EAAO,CAAE,cAAA,GAAiB,CAAC,CAAA;AACxC,MAAA,MAAM,aAAa,IAAA,EAAM,IAAA;AACzB,MAAA,MAAM,WAAW,IAAA,EAAM,IAAA;AACvB,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,aAAA;AAAA,QACN,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,WAAW,CAAA,CAAE,SAAA;AAAA,QACb,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,GAAG,SAAS,CAAC,CAAA;AAAA,QACb,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,KAAa;AAAC,OAC/C;AAMA,MAAA,IAAA,CAAK,GAAA,CAAI,EAAE,SAAA,EAAW;AAAA,QACpB,OAAA,EAAS,kBAAA,CAAmB,MAAA,EAAQ,CAAA,EAAG;AAAA,UACrC,MAAA,EAAQ,aAAA;AAAA,UACR,KAAA,EAAO,WAAA;AAAA,UACP,UAAU,MAAM;AAAE,YAAA,eAAA,CAAgB,EAAE,SAAS,CAAA;AAAA,UAAG;AAAA,SACjD,CAAA;AAAA,QACD,KAAK,EAAE,CAAA,EAAG,EAAE,OAAA,EAAS,CAAA,EAAG,EAAE,OAAA,EAAQ;AAAA;AAAA;AAAA,QAGlC,QAAA,EAAU,EAAE,EAAA,EAAI,OAAA,EAAS,EAAE,OAAA,EAAS,OAAA,EAAS,EAAE,OAAA,EAAQ;AAAA,QACvD,IAAA,EAAM;AAAA,UACJ,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,QAAQ,CAAA,CAAE,CAAA;AAAA,UACV,QAAQ,CAAA,CAAE,CAAA;AAAA,UACV,UAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,UAAU,CAAA,CAAE;AAAA;AACd,OACD,CAAA;AAYD,MAAA,IAAI,IAAA,CAAK,OAAO,CAAA,EAAG,QAAA,CAAS,EAAE,GAAG,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,CAAA;AAIrD,MAAA,IAAA,CAAK,CAAA,CAAE,gBAAgB,OAAA,IAAW,CAAA,CAAE,gBAAgB,KAAA,KAC7C,IAAA,CAAK,SAAS,CAAA,EAAG;AACtB,QAAA,eAAA,CAAgB,EAAE,SAAS,CAAA;AAC3B,QAAA,MAAM,QAAA,GAAW,YAAA,CAAa,OAAA,EAAS,QAAA,IAAY,aAAA;AACnD,QAAA,eAAA,CAAgB,GAAA;AAAA,UACd,CAAA,CAAE,SAAA;AAAA,UACF,WAAW,MAAM;AACf,YAAA,eAAA,CAAgB,MAAA,CAAO,EAAE,SAAS,CAAA;AAClC,YAAA,IAAI,QAAA,EAAU;AACd,YAAA,aAAA,CAAc,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,WAAW,CAAA;AAAA,UAC1C,GAAG,QAAQ;AAAA,SACb;AACA,QAAA,MAAM,KAAA,GAAQ,aAAa,OAAA,EAAS,KAAA;AACpC,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AAChC,QAAA,IAAI,SAAS,GAAA,EAAK;AAChB,UAAA,KAAA,CAAM,GAAA,CAAI;AAAA,YACR,WAAW,CAAA,CAAE,SAAA;AAAA,YACb,aAAa,CAAA,CAAE,WAAA;AAAA,YACf,QAAQ,EAAE,CAAA,EAAG,EAAE,OAAA,EAAS,CAAA,EAAG,EAAE,OAAA,EAAQ;AAAA,YACrC,KAAA,EAAO,cAAc,EAAE,CAAA,EAAG,EAAE,OAAA,EAAS,CAAA,EAAG,CAAA,CAAE,OAAA,EAAS,CAAA;AAAA,YACnD,OAAO,EAAE,CAAA,EAAG,EAAE,CAAA,EAAG,CAAA,EAAG,EAAE,CAAA,EAAE;AAAA,YACxB,MAAA,EAAQ,QAAO,CAAE,EAAA;AAAA,YACjB,SAAA,EAAW,YAAY,GAAA,EAAI;AAAA,YAC3B,QAAA;AAAA,YACA,KAAA,EAAO,kBAAA,CAAmB,GAAA,CAAI,IAAI;AAAA,WACnC,CAAA;AAAA,QACH;AAAA,MACF;AAGA,MAAA,IAAI,IAAA,CAAK,QAAQ,CAAA,EAAG;AAClB,QAAA,kBAAA,EAAmB;AAkBnB,QAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,MAAA,EAAO,IAAK,QAAA,GAAW,IAAA;AAE5C,QAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAO,GAAI,YAAA,EAAa;AAI1C,QAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,UAAA,eAAA,GAAkB,EAAE,SAAS,IAAA,CAAK,IAAA,EAAM,UAAU,EAAE,GAAG,UAAS,EAAE;AAAA,QACpE,CAAA,MAAO;AACL,UAAA,eAAA,CAAgB,UAAU,IAAA,CAAK,IAAA;AAAA,QACjC;AACA,QAAA,MAAM,EAAA,GAAiB;AAAA,UACrB,IAAA,EAAM,YAAA;AAAA,UACN,SAAS,IAAA,CAAK,IAAA;AAAA,UACd,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,UAAU,CAAA,CAAE,QAAA;AAAA,UACZ,QAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,QAAA,CAAS,EAAE,CAAA;AAAA,MACb;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAoB;AACzC,MAAA,OAAA,CAAQ,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACzC,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AAChC,MAAA,IAAI,GAAA,MAAS,GAAA,GAAM,EAAE,GAAG,CAAA,CAAE,OAAA,EAAS,CAAA,EAAG,CAAA,CAAE,OAAA,EAAQ;AAUhD,MAAA,MAAM,WAAW,GAAA,EAAK,QAAA;AACtB,MAAA,IAAI,OAAO,QAAA,EAAU;AACnB,QAAA,IAAI,iBAAA,CAAkB,QAAA,EAAU,CAAC,CAAA,EAAG;AAClC,UAAA,GAAA,CAAI,QAAA,GAAW,IAAA;AACf,UAAA,eAAA,CAAgB,EAAE,SAAS,CAAA;AAC3B,UAAA,QAAA,CAAS,SAAS,EAAE,CAAA;AAAA,QACtB;AAAA,MACF;AAKA,MAAA,MAAM,WAAA,GAAc,CAAA,WAAA,EAAc,IAAA,CAAK,IAAI,CAAA,CAAA;AAC3C,MAAA,IAAI,IAAA,CAAK,QAAQ,CAAA,IAAK,aAAA,GAAgB,QAAA,EAAS,CAAE,GAAA,CAAI,WAAW,CAAA,EAAG;AACjE,QAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAO,GAAI,YAAA,EAAa;AAC1C,QAAA,MAAM,IAAA,GAAmB;AAAA,UACvB,IAAA,EAAM,YAAA;AAAA,UACN,SAAS,IAAA,CAAK,IAAA;AAAA,UACd,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,UAAU,CAAA,CAAE,QAAA;AAAA,UACZ,QAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MAEf;AAEA,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACtC,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,aAAA;AAAA,QACN,WAAW,CAAA,CAAE,SAAA;AAAA,QACb,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,GAAG,SAAS,CAAC;AAAA,OACf;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AAEX,MAAA,SAAA,GAAY;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAC/B,QAAQ,CAAA,CAAE,MAAA;AAAA,QAAQ,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,UAAU,CAAA,CAAE;AAAA,OACxE;AACA,MAAA,kBAAA,EAAmB;AAAA,IACrB,CAAA;AA+BA,IAAA,IAAI,SAAA,GAGO,IAAA;AACX,IAAA,IAAI,gBAAA,GAAmB,KAAA;AACvB,IAAA,MAAM,mBAAmB,MAAM;AAC7B,MAAA,gBAAA,CAAiB,OAAA,IAAU,EAAG,WAAA,CAAY,IAAI,CAAA;AAC9C,MAAA,IAAI,oBAAoB,MAAA,EAAQ;AAC9B,QAAA,MAAA,CAAO,MAAM,MAAA,GAAS,EAAA;AACtB,QAAA,gBAAA,GAAmB,KAAA;AAAA,MACrB;AAAA,IACF,CAAA;AACA,IAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,KAA4B;AACpD,MAAA,MAAM,IAAA,GAAO,IAAA,KAAS,IAAA,GAAO,IAAA,GAAO,kBAAkB,IAAI,CAAA;AAC1D,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,MAAA,EAAQ;AACpB,QAAA,gBAAA,EAAiB;AACjB,QAAA;AAAA,MACF;AAIA,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,KAAS,SAAA,GAAY,IAAA,GAAO,IAAA;AACjD,MAAA,gBAAA,CAAiB,OAAA,IAAU,EAAG,WAAA,CAAY,OAAO,CAAA;AACjD,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,KAAS,KAAA,GAAQ,KAAK,GAAA,GAAM,MAAA;AAChD,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,gBAAA,EAAiB;AACjB,QAAA;AAAA,MACF;AACA,MAAA,MAAA,CAAO,MAAM,MAAA,GAAS,MAAA;AACtB,MAAA,gBAAA,GAAmB,IAAA;AAAA,IACrB,CAAA;AASA,IAAA,SAAS,kBAAA,GAA2B;AAClC,MAAA,MAAM,OAAA,GAAU,iBAAiB,OAAA,IAAU;AAC3C,MAAA,IAAI,CAAC,OAAA,EAAS,MAAA,MAAY,CAAC,MAAA,IAAU,CAAC,SAAA,EAAW;AACjD,MAAA,MAAM,CAAA,GAAI,OAAO,qBAAA,EAAsB;AACvC,MAAA,OAAA,CAAQ,UAAA,CAAW,UAAU,OAAA,GAAU,CAAA,CAAE,MAAM,SAAA,CAAU,OAAA,GAAU,EAAE,GAAG,CAAA;AAAA,IAC1E;AAEA,IAAA,SAAS,kBAAA,GAA2B;AAClC,MAAA,kBAAA,EAAmB;AACnB,MAAA,kBAAA,EAAmB;AAAA,IACrB;AAEA,IAAA,SAAS,kBAAA,GAA2B;AAClC,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,SAAA,EAAW;AAK3B,MAAA,IAAI,IAAA,CAAK,OAAO,CAAA,IAAK,aAAA,GAAgB,QAAA,EAAS,CAAE,OAAO,CAAA,EAAG;AACxD,QAAA,gBAAA,CAAiB,aAAA,EAAc,CAAE,cAAA,EAAgB,CAAA;AACjD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,CAAA,GAAI,SAAA;AAGV,MAAA,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAClC,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACtC,MAAA,MAAM,UAAA,GAAa,MAAA,EAAO,CAAE,YAAA,GAAe,CAAC,CAAA,IAAK,MAAA;AACjD,MAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,QAAA,gBAAA,CAAiB,WAAW,MAAM,CAAA;AAClC,QAAA;AAAA,MACF;AACA,MAAA,MAAM,SAAA,GAAY,MAAA,EAAO,CAAE,cAAA,GAAiB,CAAC,CAAA;AAC7C,MAAA,MAAM,aAAa,SAAA,EAAW,IAAA;AAC9B,MAAA,MAAM,WAAW,SAAA,EAAW,IAAA;AAC5B,MAAA,MAAM,KAAA,GAAQ;AAAA,QACZ,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,KAAa;AAAC,OAC/C;AACA,MAAA,MAAM,MAAM,MAAA,EAAO;AACnB,MAAA,MAAM,KAAA,GAAoB;AAAA,QACxB,IAAA,EAAM,aAAA;AAAA,QAAe,GAAG,CAAA,CAAE,CAAA;AAAA,QAAG,GAAG,CAAA,CAAE,CAAA;AAAA,QAAG,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,GAAG;AAAA,OAClF;AACA,MAAA,MAAM,IAAI,aAAA,EAAc;AACxB,MAAA,mBAAA,CAAoB,MAAM,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAC,CAAA;AAC/C,MAAA,MAAM,aAAa,CAAA,CAAE,WAAA,CAAY,KAAA,EAAO,GAAG,GAAG,MAAA,CAAO,MAAA;AAErD,MAAA,MAAM,MAAA,GAAS,UAAA,IAAc,aAAA,EAAc,CAAE,WAAA;AAAA,QAC3C,EAAE,IAAA,EAAM,OAAA,EAAS,CAAA,EAAG,CAAA,CAAE,GAAG,CAAA,EAAG,CAAA,CAAE,CAAA,EAAG,MAAA,EAAQ,EAAE,CAAA,EAAG,MAAA,EAAQ,CAAA,CAAE,CAAA,EAAG,GAAG,KAAA,EAAM;AAAA,QACpE;AAAA,SACC,MAAA,CAAO,MAAA;AACV,MAAA,gBAAA,CAAiB,UAAU,IAAI,CAAA;AAAA,IACjC;AAIA,IAAA,MAAM,0BAAA,GAA6B,CAAC,CAAA,KAAqB;AACvD,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,SAAA,GAAY;AAAA,QACV,GAAG,SAAA;AAAA,QACH,QAAQ,CAAA,CAAE,MAAA;AAAA,QAAQ,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,UAAU,CAAA,CAAE;AAAA,OACxE;AACA,MAAA,UAAA,CAAW,MAAM;AACf,QAAA,IAAI,CAAC,UAAU,kBAAA,EAAmB;AAAA,MACpC,GAAG,CAAC,CAAA;AAAA,IACN,CAAA;AAIA,IAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAAoB;AACvC,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,EAAG;AAC3B,MAAA,aAAA,CAAc,CAAC,CAAA;AAAA,IACjB,CAAA;AAEA,IAAA,MAAM,sBAAsB,MAAM;AAChC,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,MAAA,gBAAA,CAAiB,OAAA,MAAa,YAAA,EAAa;AAC3C,MAAA,gBAAA,EAAiB;AAAA,IACnB,CAAA;AAEA,IAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAAoB;AACvC,MAAA,OAAA,CAAQ,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACzC,MAAA,eAAA,CAAgB,EAAE,SAAS,CAAA;AAC3B,MAAA,MAAM,WAAW,IAAA,CAAK,IAAA;AAItB,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AAChC,MAAA,IAAA,CAAK,MAAA,CAAO,EAAE,SAAS,CAAA;AAOvB,MAAA,MAAM,mBAAA,GAAsB,KAAK,QAAA,IAAY,IAAA;AAO7C,MAAA,IAAI,QAAA,IAAY,CAAA,IAAK,IAAA,CAAK,IAAA,GAAO,CAAA,EAAG;AAClC,QAAA,MAAM,WAAA,GAAc,cAAc,QAAQ,CAAA,CAAA;AAC1C,QAAA,IAAI,eAAc,CAAE,QAAA,EAAS,CAAE,GAAA,CAAI,WAAW,CAAA,EAAG;AAO/C,UAAA,aAAA,EAAc,CAAE,UAAU,QAAQ,CAAA;AAAA,QACpC;AAEA,QAAA,MAAM,KAAA,GAAQ,eAAA;AACd,QAAA,IAAI,KAAA,EAAO;AAGT,UAAA,MAAM,QAAA,GAAW,aAAA;AAAA,YACf,yBAAA,CAA0B;AAAA,cACxB,GAAG,CAAC,GAAG,IAAA,CAAK,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG,CAAA;AAAA,cACtC,EAAE,CAAA,EAAG,CAAA,CAAE,OAAA,EAAS,CAAA,EAAG,EAAE,OAAA;AAAQ,aAC9B,CAAA,CAAE;AAAA,WACL;AACA,UAAA,MAAM,EAAA,GAAK,QAAA,CAAS,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,CAAA;AACvC,UAAA,MAAM,EAAA,GAAK,QAAA,CAAS,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,CAAA;AACvC,UAAA,IAAI,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,KAAK,gBAAA,EAAkB;AAC1C,YAAA,MAAM,GAAA,GAAkB;AAAA,cACtB,IAAA,EAAM,eAAA;AAAA,cACN,SAAS,KAAA,CAAM,OAAA;AAAA,cACf,QAAQ,CAAA,CAAE,MAAA;AAAA,cACV,SAAS,CAAA,CAAE,OAAA;AAAA,cACX,SAAS,CAAA,CAAE,OAAA;AAAA,cACX,UAAU,CAAA,CAAE;AAAA,aACd;AACA,YAAA,QAAA,CAAS,GAAG,CAAA;AAAA,UACd;AACA,UAAA,eAAA,GAAkB,IAAA;AAAA,QACpB;AAAA,MACF;AASA,MAAA,MAAM,eAAA,GAAkB,GAAA,GACnB,GAAA,CAAI,IAAA,CAAK,OAAA,KAAY,CAAA,CAAE,OAAA,IAAW,GAAA,CAAI,IAAA,CAAK,OAAA,KAAY,CAAA,CAAE,OAAA,GAC1D,IAAA;AACJ,MAAA,MAAM,eAAA,GACJ,aAAA,EAAc,CAAE,QAAA,EAAS,CAAE,IAAI,gBAAA,CAAiB,CAAA,CAAE,SAAS,CAAC,CAAA,IAAK,eAAA;AAEnE,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACxC,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,WAAA;AAAA,QACN,WAAW,CAAA,CAAE,SAAA;AAAA,QACb,GAAG,GAAA,CAAI,CAAA;AAAA,QACP,GAAG,GAAA,CAAI,CAAA;AAAA,QACP,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE;AAAA,OACd;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AAEX,MAAA,MAAM,OAAO,GAAA,EAAK,IAAA;AAalB,MAAA,IAAI,CAAC,eAAA,IAAmB,mBAAA,IAAuB,IAAA,EAAM;AACnD,QAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAC3C,QAAA,MAAM,OAAA,GAAsB;AAAA,UAC1B,IAAA,EAAM,OAAA;AAAA,UACN,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,UAAU,CAAA,CAAE,QAAA;AAAA,UACZ,GAAG,MAAA,CAAO,CAAA;AAAA,UACV,GAAG,MAAA,CAAO,CAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,UACvE,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,UACvE,GAAI,KAAK,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAS,GAAI;AAAC,SACnE;AACA,QAAA,QAAA,CAAS,OAAO,CAAA;AAOhB,QAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,QAAA,MAAM,OAAO,YAAA,CAAa,OAAA;AAC1B,QAAA,MAAM,EAAA,GAAK,CAAA,CAAE,OAAA,IAAW,IAAA,EAAM,OAAA,IAAW,CAAA,CAAA;AACzC,QAAA,MAAM,EAAA,GAAK,CAAA,CAAE,OAAA,IAAW,IAAA,EAAM,OAAA,IAAW,CAAA,CAAA;AACzC,QAAA,IAAI,IAAA,IAAQ,GAAA,GAAM,IAAA,CAAK,CAAA,GAAI,mBAAA,IAAuB,KAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA,GAAI,mBAAA,EAAqB;AAC1F,UAAA,MAAM,KAAA,GAAoB;AAAA,YACxB,IAAA,EAAM,aAAA;AAAA,YACN,QAAQ,CAAA,CAAE,MAAA;AAAA,YACV,QAAQ,CAAA,CAAE,MAAA;AAAA,YACV,SAAS,CAAA,CAAE,OAAA;AAAA,YACX,SAAS,CAAA,CAAE,OAAA;AAAA,YACX,UAAU,CAAA,CAAE,QAAA;AAAA,YACZ,GAAG,MAAA,CAAO,CAAA;AAAA,YACV,GAAG,MAAA,CAAO,CAAA;AAAA,YACV,SAAS,CAAA,CAAE,OAAA;AAAA,YACX,SAAS,CAAA,CAAE,OAAA;AAAA,YACX,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,YACvE,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,YACvE,GAAI,KAAK,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAS,GAAI;AAAC,WACnE;AAGA,UAAA,gBAAA,CAAiB,OAAA,GAAU,EAAE,CAAA,EAAG,MAAA,CAAO,GAAG,CAAA,EAAG,MAAA,CAAO,GAAG,CAAA;AACvD,UAAA,MAAM,OAAA,GAAU,QAAA,CAAS,KAAK,CAAA,KAAM,SAAA;AACpC,UAAA,kBAAA,GAAqB,OAAA,IAAW,iBAAiB,OAAA,KAAY,MAAA;AAC7D,UAAA,YAAA,CAAa,OAAA,GAAU,IAAA;AAAA,QACzB,CAAA,MAAO;AACL,UAAA,YAAA,CAAa,OAAA,GAAU,EAAE,CAAA,EAAG,GAAA,EAAK,SAAS,CAAA,CAAE,OAAA,EAAS,OAAA,EAAS,CAAA,CAAE,OAAA,EAAQ;AAAA,QAC1E;AAAA,MACF;AAIA,MAAA,YAAA,CAAa,EAAE,SAAS,CAAA;AAKxB,MAAA,SAAA,GAAY;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAC/B,QAAQ,CAAA,CAAE,MAAA;AAAA,QAAQ,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,UAAU,CAAA,CAAE;AAAA,OACxE;AACA,MAAA,UAAA,CAAW,MAAM;AACf,QAAA,IAAI,CAAC,UAAU,kBAAA,EAAmB;AAAA,MACpC,GAAG,CAAC,CAAA;AAAA,IACN,CAAA;AAOA,IAAA,MAAM,eAAA,GAAkB,CAAC,SAAA,KAAsB;AAG7C,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA;AAC9B,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,IAAA,CAAK,OAAO,SAAS,CAAA;AACrB,MAAA,OAAA,CAAQ,WAAW,GAAA,CAAI,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,IAAI,CAAC,CAAA;AACvC,MAAA,eAAA,CAAgB,SAAS,CAAA;AAGzB,MAAA,eAAA,GAAkB,IAAA;AAClB,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,eAAA;AAAA,QACN,SAAA;AAAA,QACA,MAAA,EAAQ,IAAI,IAAA,CAAK,MAAA;AAAA,QACjB,OAAA,EAAS,IAAI,IAAA,CAAK,OAAA;AAAA,QAClB,OAAA,EAAS,IAAI,IAAA,CAAK,OAAA;AAAA,QAClB,QAAA,EAAU,IAAI,IAAA,CAAK;AAAA,OACrB;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AACX,MAAA,YAAA,CAAa,SAAS,CAAA;AAAA,IACxB,CAAA;AAMA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAkB;AAEvC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAClC,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAGtC,MAAA,MAAM,UAAA,GAAa,MAAA,EAAO,CAAE,YAAA,GAAe,CAAC,CAAA,IAAK,MAAA;AACjD,MAAA,MAAM,QAAA,GAAW,MAAA,EAAO,CAAE,cAAA,GAAiB,CAAC,CAAA;AAC5C,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,aAAA;AAAA,QACN,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,UAAU,IAAA,KAAS,MAAA,GAAY,EAAE,UAAA,EAAY,QAAA,CAAS,IAAA,EAAK,GAAI,EAAC;AAAA,QACpE,GAAI,UAAU,IAAA,KAAS,MAAA,GAAY,EAAE,QAAA,EAAU,QAAA,CAAS,IAAA,EAAK,GAAI;AAAC,OACpE;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AAAA,IACb,CAAA;AAWA,IAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAiB;AACnC,MAAA,IAAI,CAAC,EAAE,YAAA,EAAc;AAErB,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,CAAA,CAAE,aAAa,UAAA,GAAa,MAAA;AAC5B,MAAA,MAAA,EAAQ,SAAA,CAAU,IAAI,cAAc,CAAA;AAAA,IACtC,CAAA;AAEA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,MAAA,EAAQ,SAAA,CAAU,OAAO,cAAc,CAAA;AAAA,IACzC,CAAA;AAMA,IAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAiB;AAC/B,MAAA,MAAA,EAAQ,SAAA,CAAU,OAAO,cAAc,CAAA;AACvC,MAAA,MAAM,KAAK,CAAA,CAAE,YAAA;AACb,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAClC,MAAA,MAAM,MAAA,GAAS,QAAO,CAAE,UAAA;AACxB,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAItC,MAAA,MAAM,IAAA,GAAO;AAAA,QACX,QAAQ,CAAA,CAAE,MAAA;AAAA,QAAQ,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,UAAU,CAAA,CAAE;AAAA,OACxE;AACA,MAAA,KAAK,qBAAA,CAAsB,EAAE,CAAA,CAAE,IAAA,CAAK,CAAC,KAAA,KAAU;AAC7C,QAAA,IAAI,QAAA,EAAU;AACd,QAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,QAAA,QAAA,CAAS;AAAA,UACP,IAAA,EAAM,MAAA;AAAA,UAAQ,KAAA;AAAA,UACd,GAAG,CAAA,CAAE,CAAA;AAAA,UAAG,GAAG,CAAA,CAAE,CAAA;AAAA,UAAG,SAAS,CAAA,CAAE,OAAA;AAAA,UAAS,SAAS,CAAA,CAAE,OAAA;AAAA,UAC/C,GAAG;AAAA,WACF,MAAM,CAAA;AAAA,MACX,CAAC,CAAA;AAAA,IACH,CAAA;AAEA,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAsB;AAGrC,MAAA,IAAI,gBAAA,CAAiB,CAAA,CAAE,MAAM,CAAA,EAAG;AAChC,MAAA,MAAM,KAAK,CAAA,CAAE,aAAA;AACb,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,MAAM,KAAA,GAAQ,uBAAuB,EAAE,CAAA;AACvC,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAKxB,MAAA,MAAM,SAAS,QAAA,CAAS;AAAA,QACtB,IAAA,EAAM,OAAA;AAAA,QAAS,KAAA;AAAA;AAAA,QAEf,MAAA,EAAQ,KAAA;AAAA,QAAO,OAAA,EAAS,KAAA;AAAA,QAAO,OAAA,EAAS,KAAA;AAAA,QAAO,QAAA,EAAU;AAAA,OAC1D,CAAA;AACD,MAAA,IAAI,MAAA,KAAW,SAAA,EAAW,CAAA,CAAE,cAAA,EAAe;AAAA,IAC7C,CAAA;AAMA,IAAA,MAAM,aAAa,QAAA,KAAa,OAAA;AAChC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,SAAA,EAAW,UAAU,CAAA;AACxD,MAAA,MAAA,CAAO,gBAAA,CAAiB,OAAA,EAAS,OAAA,EAAS,UAAU,CAAA;AAAA,IACtD;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,QAAQ,YAAY,CAAA;AAI5C,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,0BAA0B,CAAA;AAC7D,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,0BAA0B,CAAA;AAC3D,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,MAAA,EAAQ,gBAAA,CAAiB,gBAAgB,mBAAmB,CAAA;AAC5D,MAAA,MAAA,EAAQ,gBAAA,CAAiB,eAAe,aAAa,CAAA;AACrD,MAAA,MAAA,EAAQ,gBAAA,CAAiB,eAAe,WAAW,CAAA;AACnD,MAAA,MAAA,EAAQ,gBAAA,CAAiB,YAAY,mBAAmB,CAAA;AAAA,IAC1D;AACA,IAAA,IAAI,YAAA,EAAc,MAAA,EAAQ,gBAAA,CAAiB,OAAA,EAAS,OAAA,EAAS,EAAE,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,CAAA;AAC9F,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,MAAA,EAAQ,gBAAA,CAAiB,gBAAgB,cAAc,CAAA;AACvD,MAAA,MAAA,EAAQ,gBAAA,CAAiB,iBAAiB,eAAe,CAAA;AACzD,MAAA,MAAA,EAAQ,gBAAA,CAAiB,cAAc,YAAY,CAAA;AAAA,IACrD;AACA,IAAA,IAAI,kBAAA,EAAoB,MAAA,EAAQ,gBAAA,CAAiB,aAAA,EAAe,aAAa,CAAA;AAC7E,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,MAAA,EAAQ,gBAAA,CAAiB,aAAa,UAAU,CAAA;AAChD,MAAA,MAAA,EAAQ,gBAAA,CAAiB,YAAY,UAAU,CAAA;AAC/C,MAAA,MAAA,EAAQ,gBAAA,CAAiB,aAAa,WAAW,CAAA;AACjD,MAAA,MAAA,EAAQ,gBAAA,CAAiB,QAAQ,MAAM,CAAA;AACvC,MAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,OAAO,CAAA;AAAA,IAC1C;AAMA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,SAAA,EAAW,UAAU,CAAA;AAC3D,QAAA,MAAA,CAAO,mBAAA,CAAoB,OAAA,EAAS,OAAA,EAAS,UAAU,CAAA;AAAA,MACzD;AACA,MAAA,MAAA,CAAO,mBAAA,CAAoB,QAAQ,YAAY,CAAA;AAC/C,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,0BAA0B,CAAA;AAChE,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,0BAA0B,CAAA;AAC9D,MAAA,MAAA,EAAQ,mBAAA,CAAoB,gBAAgB,mBAAmB,CAAA;AAC/D,MAAA,MAAA,EAAQ,oBAAoB,OAAA,EAAS,OAAA,EAAS,EAAE,OAAA,EAAS,MAAM,CAAA;AAC/D,MAAA,MAAA,EAAQ,mBAAA,CAAoB,gBAAgB,cAAc,CAAA;AAC1D,MAAA,MAAA,EAAQ,mBAAA,CAAoB,iBAAiB,eAAe,CAAA;AAC5D,MAAA,MAAA,EAAQ,mBAAA,CAAoB,cAAc,YAAY,CAAA;AACtD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,eAAe,aAAa,CAAA;AACxD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,eAAe,WAAW,CAAA;AACtD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,YAAY,mBAAmB,CAAA;AAC3D,MAAA,MAAA,EAAQ,mBAAA,CAAoB,eAAe,aAAa,CAAA;AACxD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,aAAa,UAAU,CAAA;AACnD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,YAAY,UAAU,CAAA;AAClD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,aAAa,WAAW,CAAA;AACpD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AAC1C,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAG3C,MAAA,MAAA,EAAQ,SAAA,CAAU,OAAO,cAAc,CAAA;AACvC,MAAA,gBAAA,EAAiB;AACjB,MAAA,kBAAA,EAAmB;AACnB,MAAA,QAAA,GAAW,IAAA;AAGX,MAAA,KAAA,MAAW,KAAK,IAAA,CAAK,MAAA,EAAO,EAAG,CAAA,CAAE,QAAQ,MAAA,EAAO;AAChD,MAAA,IAAA,CAAK,KAAA,EAAM;AACX,MAAA,KAAA,MAAW,CAAA,IAAK,cAAA,EAAe,EAAG,CAAA,CAAE,UAAU,QAAQ,CAAA;AAAA,IACxD,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IAAC,OAAA;AAAA,IAAS,QAAA;AAAA,IAAU,SAAA;AAAA,IAAW,cAAA;AAAA,IAAgB,YAAA;AAAA,IAAc,YAAA;AAAA,IAAc,kBAAA;AAAA,IAAoB,aAAA;AAAA,IAChG,cAAA;AAAA,IAAgB,MAAA;AAAA,IAAQ,YAAA;AAAA,IAAc,gBAAA;AAAA,IAAkB,gBAAA;AAAA,IAAkB,WAAA;AAAA,IAAa,gBAAA;AAAA,IAAkB,aAAA;AAAA,IAAe;AAAA,GAAS,CAAA;AACrI;ACzpDO,IAAM,cAAA,GAAiBL,cAAsC,IAAI,CAAA;AAKxE,SAAS,OAAA,CAAQ,GAAW,CAAA,EAAgD;AAC1E,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,EAAC;AAChB,EAAA,IAAI,CAAA,CAAE,QAAA,EAAU,OAAO,qBAAA,CAAsB,GAAG,CAAC,CAAA;AACjD,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,CAAA,CAAE,GAAA,CAAI,WAAsB,CAAA;AAAA,IACvC,KAAA,EAAO,CAAA,CAAE,GAAA,CAAI,OAAkB,CAAA;AAAA,IAC/B,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,SAAoB,CAAA;AAAA,IACnC,IAAA,EAAM,CAAA,CAAE,GAAA,CAAI,MAAiB,CAAA;AAAA,IAC7B,UAAA,EAAY,CAAA,CAAE,GAAA,CAAI,YAAuB,CAAA;AAAA,IACzC,eAAA,EAAiB,CAAA,CAAE,GAAA,CAAI,iBAA4B;AAAA,GACrD;AACF;AAQO,IAAM,WAAA,GAAN,cAA0B,SAAA,CAAuB;AAAA,EAQtD,WAAA,CACE,MAAA,EACA,QAAA,EACiB,WAAA,EACjB;AACA,IAAA,KAAA,CAAM,QAAQ,QAAQ,CAAA;AAFL,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAGjB,IAAA,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,QAAA,EAAU,IAAI,CAAA;AAAA,EAC/B;AAAA,EAJmB,WAAA;AAAA,EAVF,OAAA,uBAAc,GAAA,EAAsB;AAAA,EACpC,KAAA,uBAAY,GAAA,EAAoB;AAAA,EAChC,cAA4B,EAAC;AAAA,EACtC,KAAA,GAAgF,IAAA;AAAA;AAAA,EAE/E,aAA6B,EAAC;AAAA,EAW/B,QAAQ,EAAA,EAAgC;AAC9C,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,KAAA,EAAM,EAAG;AAC5B,MAAA,IAAI,CAAA,CAAE,KAAA,CAAM,GAAA,CAAI,EAAE,GAAG,OAAO,MAAA;AAC5B,MAAA,MAAM,IAAI,CAAA,CAAE,OAAA,CAAQ,IAAI,EAAE,CAAA,EAAG,GAAG,EAAE,CAAA;AAClC,MAAA,IAAI,GAAG,OAAO,CAAA;AAAA,IAChB;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,QAAA,GAA8B;AACpC,IAAA,MAAM,IAAA,GAAO,KAAK,KAAA,EAAM;AACxB,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA;AACpB,IAAA,IAAI,MAAA,IAAU,MAAA,CAAO,OAAA,KAAY,IAAA,CAAK,IAAA,CAAK,WAAW,MAAA,CAAO,IAAA,KAAS,IAAA,EAAM,OAAO,MAAA,CAAO,IAAA;AAC1F,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAC5B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,KAAA,EAAM,EAAG,KAAA,MAAW,EAAA,IAAM,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAK,EAAG,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAC3E,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AACpB,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,EAAE,CAAA;AACzB,MAAA,IAAI,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA;AAAA,IACnB;AACA,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA;AAC9B,IAAA,IAAA,CAAK,QAAQ,EAAE,OAAA,EAAS,KAAK,IAAA,CAAK,OAAA,EAAS,MAAM,IAAA,EAAK;AACtD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEQ,IAAA,GAA2B;AACjC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,KAAA,EAAM,EAAG;AAC5B,MAAA,MAAM,CAAA,GAAI,EAAE,WAAA,EAAY;AACxB,MAAA,IAAI,GAAG,OAAO,CAAA;AAAA,IAChB;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEQ,UAAA,GAAgC;AACtC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,KAAA,EAAM,EAAG;AAC5B,MAAA,MAAM,CAAA,GAAI,CAAA,CAAE,WAAA,CAAY,EAAA,CAAG,EAAE,CAAA;AAC7B,MAAA,IAAI,GAAG,OAAO,CAAA;AAAA,IAChB;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAES,QAAA,GAAiB;AACxB,IAAA,KAAA,CAAM,QAAA,EAAS;AACf,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,UAAA,EAAY,CAAA,EAAE;AAAA,EACrC;AAAA,EAES,QAAA,GAA4B;AAAA,IACnC,QAAA,EAAU,CAAC,MAAA,KAAmB;AAC5B,MAAA,gBAAA,CAAiB,OAAO,EAAE,CAAA;AAC1B,MAAA,4BAAA,CAA6B,MAAM,CAAA;AACnC,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,OAAO,EAAE,CAAA;AACxC,MAAA,IAAI,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA;AAAA,gBAClB,OAAA,CAAQ,GAAA,CAAI,OAAO,EAAA,EAAI,CAAC,MAAM,CAAC,CAAA;AACzC,MAAA,IAAA,CAAK,OAAA,EAAQ;AACb,MAAA,IAAI,QAAA,GAAW,KAAA;AACf,MAAA,OAAO,MAAM;AACX,QAAA,IAAI,QAAA,EAAU;AACd,QAAA,QAAA,GAAW,IAAA;AACX,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,OAAO,EAAE,CAAA;AACtC,QAAA,IAAI,CAAC,GAAA,EAAK;AAGV,QAAA,MAAM,CAAA,GAAI,GAAA,CAAI,WAAA,CAAY,MAAM,CAAA;AAChC,QAAA,IAAI,MAAM,EAAA,EAAI;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAC,CAAA;AACf,QAAA,IAAI,IAAI,MAAA,KAAW,CAAA,OAAQ,OAAA,CAAQ,MAAA,CAAO,OAAO,EAAE,CAAA;AACnD,QAAA,IAAA,CAAK,OAAA,EAAQ;AAAA,MACf,CAAA;AAAA,IACF,CAAA;AAAA,IACA,UAAA,EAAY,CAAC,EAAA,KAAe;AAC1B,MAAA,IAAI,KAAK,OAAA,CAAQ,MAAA,CAAO,EAAE,CAAA,OAAQ,OAAA,EAAQ;AAAA,IAC5C,CAAA;AAAA,IACA,IAAA,EAAM,CAAC,EAAA,KAAe;AACpB,MAAA,IAAA,CAAK,KAAA,CAAM,IAAI,EAAA,EAAA,CAAK,IAAA,CAAK,MAAM,GAAA,CAAI,EAAE,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAChD,MAAA,IAAA,CAAK,OAAA,EAAQ;AACb,MAAA,IAAI,QAAA,GAAW,KAAA;AACf,MAAA,OAAO,MAAM;AACX,QAAA,IAAI,QAAA,EAAU;AACd,QAAA,QAAA,GAAW,IAAA;AACX,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AAC9B,QAAA,IAAI,SAAS,MAAA,EAAW;AACxB,QAAA,IAAI,OAAO,CAAA,EAAG,IAAA,CAAK,MAAM,GAAA,CAAI,EAAA,EAAI,OAAO,CAAC,CAAA;AAAA,aACpC,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,EAAE,CAAA;AACzB,QAAA,IAAA,CAAK,OAAA,EAAQ;AAAA,MACf,CAAA;AAAA,IACF,CAAA;AAAA,IACA,IAAA,EAAM,MAAM,IAAA,CAAK,QAAA,EAAS;AAAA,IAC1B,OAAA,EAAS,CAAC,EAAA,EAAY,MAAA,KAAqC;AACzD,MAAA,MAAM,IAAA,GAAO,KAAK,KAAA,EAAM;AACxB,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,EAAE,CAAA;AACzB,MAAA,IAAI,CAAC,GAAG,OAAO,KAAA;AACf,MAAA,IAAI;AACF,QAAA,IAAI,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,CAAQ,WAAW,WAAA,EAAa;AACjD,UAAA,CAAA,CAAE,OAAA,CAAQ,IAAI,OAAA,CAAQ,CAAA,EAAG,KAAK,IAAA,EAAM,GAAY,MAAM,CAAA;AAAA,QACxD;AAAA,MACF,SAAS,GAAA,EAAK;AACZ,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,EAAE,CAAA,OAAA,CAAA,EAAW,GAAG,CAAA;AAAA,MACnE;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAAA,IACA,SAAA,EAAW,CAAC,QAAA,KAAyB;AACnC,MAAA,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA;AAChC,MAAA,OAAO,MAAM;AACX,QAAA,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,MACrC,CAAA;AAAA,IACF,CAAA;AAAA,IACA,eAAe,CAAC,CAAA,KAAyB,SAAA,CAAU,IAAA,CAAK,aAAa,CAAC,CAAA;AAAA,IACtE,KAAA,EAAO,CAAC,EAAA,EAAY,MAAA,KAAqC;AACvD,MAAA,MAAM,IAAA,GAAO,KAAK,KAAA,EAAM;AACxB,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,EAAE,CAAA;AACzB,MAAA,MAAM,IAAA,GAAO,KAAK,UAAA,EAAW;AAC7B,MAAA,IAAI,CAAC,CAAA,IAAK,CAAC,IAAA,EAAM,OAAO,IAAA;AACxB,MAAA,OAAO,IAAA,CAAK,eAAe,EAAA,EAAI,OAAA,CAAQ,GAAG,IAAA,CAAK,IAAA,EAAM,CAAA,EAAY,MAAM,CAAA;AAAA,IACzE,CAAA;AAAA,IACA,QAAA,EAAU,MAAM,IAAA,CAAK,QAAA,EAAS;AAAA,IAC9B,QAAA,EAAU,MAAM,IAAA,CAAK,QAAA;AAAS,GAChC;AACF,CAAA;AAEA,IAAM,KAAA,uBAAY,OAAA,EAAsC;AAGjD,SAAS,cAAc,QAAA,EAAsD;AAClF,EAAA,OAAO,QAAA,GAAY,KAAA,CAAM,GAAA,CAAI,QAAQ,KAAK,IAAA,GAAQ,IAAA;AACpD;AAQO,SAAS,eAAA,CAAgB,EAAE,QAAA,EAAS,EAA0C;AAGnF,EAAA,MAAM,SAAS,sBAAA,EAAuB;AACtC,EAAA,MAAM,SAAA,GAAYI,UAA8B,MAAM,CAAA;AACtD,EAAA,MAAM,IAAA,GAAOH,OAAAA,CAAQ,MAAM,IAAI,WAAA,CAAY,IAAA,EAAM,IAAA,EAAM,MAAM,SAAA,CAAU,OAAO,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAC5F,EAAA,uBAAOC,IAAC,cAAA,CAAe,QAAA,EAAf,EAAwB,KAAA,EAAO,IAAA,CAAK,UAAW,QAAA,EAAS,CAAA;AAClE;AAOA,IAAM,UAAmB,MAAM;AAC7B,EAAA,IAAI;AACF,IAAA,OAAO,OAAA,CAAS,MAAA,CAAA,IAAA,CAAuD,GAAA,EAAK,GAAG,CAAA;AAAA,EACjF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF,CAAA,GAAG;AAMI,SAAS,kBAAA,GAA6C;AAC3D,EAAA,OAAOC,WAAW,cAAc,CAAA;AAClC;AASO,SAAS,UAAU,MAAA,EAAsB;AAC9C,EAAA,MAAM,MAAM,kBAAA,EAAmB;AAC/B,EAAAE,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,CAAA,WAAA,EAAc,OAAO,EAAE,CAAA,wGAAA;AAAA,SACzB;AAAA,MACF;AACA,MAAA;AAAA,IACF;AACA,IAAA,OAAO,GAAA,CAAI,SAAS,MAAM,CAAA;AAAA,EAC5B,CAAA,EAAG,CAAC,GAAA,EAAK,MAAM,CAAC,CAAA;AAClB;AC5NA,SAAS,QAAA,CACP,QAAA,EACA,QAAA,EACA,MAAA,EACM;AACN,EAAA,MAAM,gBAAgB,kBAAA,EAAmB;AACzC,EAAA,MAAM,aAAa,sBAAA,EAAuB;AAC1C,EAAA,MAAM,WAAA,GAAcF,WAAW,qBAAqB,CAAA;AACpD,EAAA,MAAM,EAAA,GAAK,MAAA,GAAS,MAAA,CAAO,OAAA,GAAU,cAAc,aAAa,CAAA;AAChE,EAAA,MAAM,EAAA,GAAK,MAAA,GAAS,MAAA,CAAO,IAAA,GAAO,UAAU,UAAU,CAAA;AACtD,EAAA,MAAM,EAAA,GAAK,MAAA,GAAS,MAAA,CAAO,KAAA,GAAQ,WAAA;AACnC,EAAA,MAAM,KAAA,GAAQF,QAAc,MAAM;AAChC,IAAA,MAAM,IAAA,GAAO,IAAI,OAAA,CAAQ,EAAA,EAAI,QAAQ,CAAA;AACrC,IAAA,MAAM,QAAQ,IAAI,QAAA,CAAS,EAAA,EAAI,QAAA,EAAU,UAAU,IAAI,CAAA;AACvD,IAAA,MAAM,UAAU,IAAI,WAAA,CAAY,IAAI,QAAA,EAAU,MAAM,KAAK,QAAQ,CAAA;AACjE,IAAA,OAAA,CAAQ,UAAA,CAAW,KAAK,MAAM,IAAA,CAAK,UAAS,EAAG,MAAM,KAAA,CAAM,QAAA,EAAU,CAAA;AACrE,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAM;AAAA,EAChC,GAAG,CAAC,EAAA,EAAI,IAAI,EAAA,EAAI,QAAA,EAAU,QAAQ,CAAC,CAAA;AACnC,EAAAI,UAAU,MAAM;AACd,IAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,CAAM,IAAA,CAAK,KAAA,EAAM,EAAG,KAAA,CAAM,KAAA,CAAM,KAAA,EAAM,EAAG,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AAC7E,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,MAAW,CAAA,IAAK,OAAO,CAAA,EAAE;AAAA,IAC3B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AACV,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,OAAA,CAAQ,EAAE,KAAA,EAAO,QAAA,EAAS,EAAuD;AACxF,EAAA,uBACEH,GAAAA,CAAC,kBAAA,CAAmB,QAAA,EAAnB,EAA4B,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,QAAA,EAC7C,QAAA,kBAAAA,GAAAA,CAAC,cAAA,CAAe,QAAA,EAAf,EAAwB,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,QAAA,EAC5C,QAAA,kBAAAA,GAAAA,CAAC,qBAAA,CAAsB,QAAA,EAAtB,EAA+B,KAAA,EAAO,KAAA,CAAM,KAAA,EAAQ,QAAA,EAAS,CAAA,EAChE,CAAA,EACF,CAAA;AAEJ;AAqBO,SAAS,UAAA,CAAW,EAAE,IAAA,EAAM,QAAA,EAAS,EAAkC;AAC5E,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,EAAO,IAAA,KAAS,QAAW,IAAI,CAAA;AACtD,EAAA,uBAAOA,GAAAA,CAAC,OAAA,EAAA,EAAQ,KAAA,EAAe,QAAA,EAAS,CAAA;AAC1C;AAOO,SAAS,OAAA,GAAgB;AAC9B,EAAA,OAAO,QAAA,CAAS,IAAA,EAAM,IAAA,EAAM,MAAS,CAAA;AACvC;AAcO,SAAS,IAAA,CAAK,EAAE,KAAA,EAAO,QAAA,EAAS,EAA4B;AACjE,EAAA,uBAAOA,GAAAA,CAAC,OAAA,EAAA,EAAQ,KAAA,EAAO,OAAQ,QAAA,EAAS,CAAA;AAC1C;ACjFO,SAAS,iBAAiB,QAAA,EAAiC;AAChE,EAAA,MAAM,MAAM,kBAAA,EAAmB;AAC/B,EAAA,MAAM,MAAA,GAASE,UAAkC,GAAG,CAAA;AACpD,EAAA,MAAM,KAAA,GAAQA,UAAU,QAAQ,CAAA;AAChC,EAAA,MAAM,OAAA,GAAUE,OAAgC,IAAI,CAAA;AAEpD,EAAA,MAAM,IAAA,GAAOL,QAAuB,MAAM;AACxC,IAAA,MAAM,GAAA,GAAM,CAAC,MAAA,KAAsC;AACjD,MAAA,MAAM,OAAO,OAAA,CAAQ,OAAA;AACrB,MAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,MAAA,IAAA,EAAM,IAAI,MAAM,CAAA;AAAA,IAClB,CAAA;AACA,IAAA,OAAO;AAAA,MACL,MAAM,MAAA,EAAQ;AACZ,QAAA,IAAI,OAAA,CAAQ,OAAA,EAAS,OAAA,CAAQ,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,aAC7C,OAAA,CAAQ,UAAU,MAAA,CAAO,OAAA,EAAS,MAAM,KAAA,CAAM,OAAA,EAAS,MAAM,CAAA,IAAK,IAAA;AAAA,MACzE,CAAA;AAAA,MACA,OAAO,MAAA,EAAQ;AACb,QAAA,IAAI,WAAW,MAAA,EAAW;AACxB,UAAA,IAAI,OAAA,CAAQ,OAAA,EAAS,OAAA,CAAQ,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,eAC7C,OAAA,CAAQ,UAAU,MAAA,CAAO,OAAA,EAAS,MAAM,KAAA,CAAM,OAAA,EAAS,MAAM,CAAA,IAAK,IAAA;AAAA,QACzE;AACA,QAAA,GAAA,CAAI,QAAQ,CAAA;AAAA,MACd,CAAA;AAAA,MACA,MAAA,GAAS;AACP,QAAA,GAAA,CAAI,QAAQ,CAAA;AAAA,MACd;AAAA,KACF;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,KAAK,CAAC,CAAA;AAElB,EAAAI,SAAAA,CAAU,MAAM,MAAM,IAAA,CAAK,QAAO,EAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AAErD,EAAA,OAAO,IAAA;AACT;ACLO,SAAS,iBACd,IAAA,EAC4B;AAC5B,EAAA,MAAM,MAAM,oBAAA,EAAqB;AACjC,EAAA,MAAM,kBAAkB,kBAAA,EAAmB;AAK3C,EAAA,MAAM,aAAA,GAAgBC,OAAiC,IAAI,CAAA;AAC3D,EAAA,MAAM,aAAA,GAAgB,cAAc,OAAA,IAAW,IAAA;AAC/C,EAAA,IAAI,aAAA,CAAc,OAAA,IAAW,IAAA,EAAM,aAAA,CAAc,OAAA,GAAU,EAAE,IAAA,EAAM,GAAA,CAAI,MAAA,KAAW,IAAA,IAAQ,IAAA,CAAK,OAAA,KAAY,IAAA,EAAK;AAChH,EAAAD,UAAU,MAAM;AACd,IAAA,MAAM,QAAQ,aAAA,CAAc,OAAA;AAC5B,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAClB,IAAA,KAAA,CAAM,IAAA,GAAO,KAAA;AACb,IAAA,GAAA,CAAI,SAAA,CAAU,KAAK,OAAO,CAAA;AAAA,EAG5B,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,OAAA,GAAU,aAAA,IAAiB,GAAA,CAAI,MAAA,KAAW,IAAA,IAAQ,KAAK,OAAA,KAAY,IAAA,GACrE,IAAA,CAAK,OAAA,GACL,GAAA,CAAI,MAAA;AAIR,EAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AACzD,EAAA,MAAM,UAAU,GAAA,CAAI,WAAA;AAEpB,EAAA,MAAM,UAAA,GAAaE,WAAAA,CAAY,CAAC,EAAA,KAAsB;AAAE,IAAA,GAAA,CAAI,UAAU,EAAE,CAAA;AAAA,EAAG,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAInF,EAAA,MAAM,QAAA,GAAWA,YAAY,MAAM;AACjC,IAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,OAAO,CAAA;AAClC,IAAA,MAAM,UAAoC,EAAC;AAC3C,IAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,MAAA,MAAM,QAAQ,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AAC7C,MAAA,IAAI,KAAA,IAAS,CAAC,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IAC3D;AACA,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IAClD;AACA,IAAA,OAAO;AAAA,MACL,OAAA;AAAA,MACA,KAAA,EAAO,EAAE,SAAA,EAAW,OAAA,EAAS,UAAA;AAAW,KAC1C;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,OAAA,EAAS,OAAO,CAAC,CAAA;AAE9B,EAAA,MAAM,cAAA,GAAiBA,YAAY,MAAuB;AACxD,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,QAAA,EAAS;AACpC,IAAA,OAAO,aAAA,CAAc,SAAS,KAAK,CAAA;AAAA,EACrC,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,MAAM,QAAA,GAAWA,WAAAA,CAAY,CAAC,QAAA,GAA4B,KAAA,KAAsB;AAC9E,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,QAAA,EAAS;AACpC,IAAA,MAAM,SAAqB,EAAC;AAC5B,IAAA,MAAM,SAAqB,EAAC;AAC5B,IAAA,MAAM,UAAsB,EAAC;AAC7B,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AACpB,MAAA,IAAA,CAAK,KAAA,CAAM,eAAA,IAAmB,KAAA,MAAW,QAAA,EAAU;AACnD,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,OAAO,IAAI,KAAA,CAAM,OAAA,GAAU,CAAC,KAAA,CAAM,OAAO,CAAA;AAC5E,MAAA,MAAM,KAAA,GAAQ,UAAU,KAAA,CAAM,EAAA,EAAI,MAAM,WAAA,IAAe,IAAI,KAAK,CAAA;AAChE,MAAA,IAAI,KAAA,KAAU,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,GAAG,MAAM,CAAA;AAAA,WAAA,IACpC,KAAA,KAAU,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,GAAG,MAAM,CAAA;AAAA,WAAA,IACzC,KAAA,KAAU,SAAA,EAAW,OAAA,CAAQ,IAAA,CAAK,GAAG,MAAM,CAAA;AAAA,IACtD;AACA,IAAA,OAAO,CAAC,GAAG,MAAA,EAAQ,GAAG,MAAA,EAAQ,GAAG,OAAO,CAAA;AAAA,EAC1C,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,gBAAA,CAAiB,OAAO,CAAA;AAWxB,EAAA,MAAM,kBAAA,GAAqBD,OAAgE,IAAI,CAAA;AAC/F,EAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAClD,EAAA,MAAM,gBAAgB,IAAA,CAAK,KAAA;AAC3B,EAAAD,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAM,EAAG;AACd,IAAA,MAAM,OAAO,kBAAA,CAAmB,OAAA;AAChC,IAAA,IAAI,IAAA,EAAM,GAAA,KAAQ,QAAA,IAAY,IAAA,CAAK,UAAU,aAAA,EAAe;AAC5D,IAAA,kBAAA,CAAmB,OAAA,GAAU,EAAE,GAAA,EAAK,QAAA,EAAU,OAAO,aAAA,EAAc;AAMnE,IAAA,MAAM,WAAqC,EAAC;AAC5C,IAAA,MAAM,UAAoC,EAAC;AAC3C,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,IAAI,KAAA,CAAM,WAAA,EAAa,KAAA,EAAO,QAAA,CAAS,KAAK,KAAK,CAAA;AACjD,MAAA,IAAI,KAAA,CAAM,aAAa,MAAA,IAAU,KAAA,CAAM,aAAa,OAAA,EAAS,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IACjF;AACA,IAAA,oBAAA,CAAqB;AAAA,MACnB,QAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA,EAAS,eAAA,EAAiB,IAAA,EAAK,IAAK,EAAC;AAAA,MACrC,GAAI,aAAA,GAAgB,EAAE,KAAA,EAAO,aAAA,CAAc,IAAA,EAAK,CAAE,GAAA,CAAI,YAAY,CAAA,EAAE,GAAI;AAAC,KAC1E,CAAA;AAAA,EACH,GAAG,CAAC,QAAA,EAAU,OAAA,EAAS,eAAA,EAAiB,aAAa,CAAC,CAAA;AAKtD,EAAA,OAAOJ,OAAAA;AAAA,IACL,OAAO,EAAE,OAAA,EAAS,OAAA,EAAS,UAAA,EAAY,gBAAgB,QAAA,EAAS,CAAA;AAAA,IAChE,CAAC,OAAA,EAAS,OAAA,EAAS,UAAA,EAAY,gBAAgB,QAAQ;AAAA,GACzD;AACF;AASO,SAAS,iBAAiB,OAAA,EAAiD;AAChF,EAAA,MAAM,kBAAkB,kBAAA,EAAmB;AAC3C,EAAA,MAAM,UAAA,GAAa,KAAK,SAAA,CAAU,OAAA,CAC/B,OAAO,CAAC,CAAA,KAAM,EAAE,WAAA,EAAa,OAAO,EACpC,GAAA,CAAI,CAAC,MAAM,CAAC,CAAA,CAAE,IAAI,CAAA,CAAE,WAAA,CAAY,OAAO,CAAC,CAAC,CAAA;AAC5C,EAAAI,UAAU,MAAM;AACd,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AACnC,IAAA,IAAI,CAAC,eAAA,IAAmB,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC5C,IAAA,MAAM,KAAA,GAAkC,KAAA,CAAM,GAAA,CAAI,CAAC,CAAC,MAAA,EAAQ,OAAO,CAAA,MACjE,EAAE,MAAA,EAAQ,GAAA,EAAK,aAAA,CAAc,OAAO,GAAE,CACvC,CAAA;AACD,IAAA,OAAO,gBAAgB,QAAA,CAAS,qBAAA,CAAsB,wBAAA,CAAyB,KAAK,CAAC,CAAC,CAAA;AAAA,EACxF,CAAA,EAAG,CAAC,eAAA,EAAiB,UAAU,CAAC,CAAA;AAClC;ACzIA,SAAS,WAAA,CAA6C,MAAS,IAAA,EAA6B;AAC1F,EAAA,MAAM,MAAA,GAAU,KAAK,GAAA,EAAgD,MAAA;AACrE,EAAA,MAAM,WAAA,GAA2B;AAAA,IAC/B,GAAG,IAAA,CAAK,WAAA;AAAA,IACR,CAAC,IAAI,GAAG,IAAA;AAAA,IACR,GAAI,MAAA,GAAS,EAAE,OAAA,EAAS,MAAA,KAAW;AAAC,GACtC;AACA,EAAA,OAAO,eAAA,CAAgB,KAAK,WAAA,EAAa,WAAW,IAAI,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,WAAA,EAAY;AACxF;AAEA,IAAM,aAA+B,EAAC;AAItC,SAAS,gBAAA,CACP,UACA,OAAA,EACwD;AACxD,EAAA,OAAOG,kBAAAA;AAAA,IACL,EAAE,QAAA,EAAU,OAAA,EAAS,OAAA,IAAW,UAAA,EAAW;AAAA,IAC3C,CAAC,CAAA,EAAG,CAAA,KAAM,UAAA,CAAW,CAAA,CAAE,QAAA,EAAU,CAAA,CAAE,QAAQ,CAAA,IAAKC,QAAAA,CAAS,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO;AAAA,GAC/E;AACF;AAEA,SAAS,UAAA,CAAc,GAAsB,CAAA,EAA+B;AAC1E,EAAA,MAAM,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA;AACxB,EAAA,IAAI,GAAG,MAAA,KAAW,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,QAAQ,OAAO,KAAA;AAChD,EAAA,OAAO,EAAA,CAAG,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,IAAK,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAC,CAAA;AAChD;AAEA,SAAS,eAAA,CAAgB,GAA4B,CAAA,EAAyB;AAC5E,EAAA,IAAI,CAAC,GAAG,OAAO,KAAA;AACf,EAAA,MAAM,IAAA,mBAAO,IAAI,GAAA,CAAI,CAAC,GAAG,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,GAAG,MAAA,CAAO,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA;AAC3D,EAAA,KAAA,MAAW,GAAA,IAAO,MAAM,IAAI,CAAA,CAAE,GAAG,CAAA,KAAM,CAAA,CAAE,GAAG,CAAA,EAAG,OAAO,KAAA;AACtD,EAAA,OAAO,IAAA;AACT;AAmBO,SAAS,SACd,IAAA,EACoB;AACpB,EAAA,MAAM,aAAA,GAAgB,KAAK,MAAA,IAAU,IAAA;AACrC,EAAA,IAAI,aAAA,KAAkB,IAAA,IAAQ,EAAE,aAAA,IAAiB,KAAK,QAAA,CAAA,EAAW;AAC/D,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,aAAa,CAAA,iBAAA,CAAmB,CAAA;AAAA,EACvE;AAEA,EAAA,MAAM,MAAM,oBAAA,EAAqB;AAKjC,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,IAAA,CAAK,QAAA,EAAU,KAAK,OAAO,CAAA;AAC5D,EAAA,MAAM,OAAA,GAAUR,QAAQ,MAAM;AAC5B,IAAA,MAAM,WAAgD,EAAC;AACvD,IAAA,KAAA,MAAW,CAAC,IAAI,IAAI,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACzD,MAAA,QAAA,CAAS,EAAE,CAAA,GAAI,WAAA,CAAY,IAAA,EAAM,OAAO,CAAA;AAAA,IAC1C;AACA,IAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,WAAA,CAAY,CAAA,EAAG,QAAQ,CAAC,CAAA;AACnE,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAoC;AACrD,IAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,GAAG,MAAA,CAAO,OAAO,QAAQ,CAAA,EAAG,GAAG,OAAO,CAAA,EAAG;AAC3D,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAC9B,MAAA,IAAI,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,EAAE,GAAG,IAAA,EAAM,WAAA,EAAa,EAAE,GAAG,KAAA,CAAM,WAAA,EAAa,GAAG,IAAA,CAAK,WAAA,IAAe,CAAA;AAAA,WAC/F,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,IAAI,CAAA;AAAA,IAC7B;AACA,IAAA,OAAO,EAAE,UAAU,OAAA,EAAS,OAAA,EAAS,CAAC,GAAG,IAAA,CAAK,MAAA,EAAQ,CAAA,EAAE;AAAA,EAC1D,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,gBAAgB,gBAAA,CAA2B;AAAA,IAC/C,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,OAAA,EAAS,aAAA;AAAA,IACT,GAAI,KAAK,KAAA,GAAQ,EAAE,OAAO,IAAA,CAAK,KAAA,KAAU;AAAC,GAC3C,CAAA;AAED,EAAA,MAAM,aAAA,GAAgB,GAAA,CAAI,WAAA,CAAY,EAAA,CAAG,EAAE,CAAA,IAAK,IAAA;AAIhD,EAAA,MAAM,UAAA,GAAaG,UAAU,OAAO,CAAA;AACpC,EAAA,MAAM,SAAA,GAAYA,SAAAA,CAAU,aAAA,CAAc,OAAO,CAAA;AACjD,EAAA,MAAM,SAAA,GAAYA,UAAU,aAAa,CAAA;AAEzC,EAAA,MAAM,aAAa,aAAA,CAAc,UAAA;AACjC,EAAA,MAAM,SAAA,GAAYG,WAAAA;AAAA,IAChB,CAAC,EAAA,KAAsB;AACrB,MAAA,IAAI,OAAO,IAAA,IAAQ,EAAE,EAAA,IAAM,UAAA,CAAW,QAAQ,QAAA,CAAA,EAAW;AACvD,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,YAAA,EAAe,EAAE,CAAA,iBAAA,CAAmB,CAAA;AAAA,MACtD;AACA,MAAA,IAAA,CAAK,OAAA,EAAS,SAAA,EAAW,SAAA,CAAU,OAAA,EAAS,UAAK,EAAE,CAAA;AACnD,MAAA,UAAA,CAAW,EAAE,CAAA;AAAA,IACf,CAAA;AAAA,IACA,CAAC,UAAA,EAAY,UAAA,EAAY,SAAS;AAAA,GACpC;AAEA,EAAA,MAAM,YAAA,GAAeA,WAAAA;AAAA,IACnB,CAAC,EAAA,KAAe;AACd,MAAA,IAAI,EAAE,EAAA,IAAM,UAAA,CAAW,OAAA,CAAQ,QAAA,CAAA,EAAW;AACxC,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,EAAE,CAAA,iBAAA,CAAmB,CAAA;AAAA,MACzD;AACA,MAAA,IAAA,CAAK,OAAA,EAAS,mBAAmB,EAAE,CAAA;AACnC,MAAA,GAAA,CAAI,WAAW,EAAE,CAAA;AAAA,IACnB,CAAA;AAAA,IACA,CAAC,KAAK,UAAU;AAAA,GAClB;AAEA,EAAA,MAAM,eAAA,GAAkBA,YAAY,MAAM;AACxC,IAAA,IAAI,UAAU,OAAA,EAAS,IAAA,CAAK,OAAA,EAAS,oBAAA,EAAsB,UAAU,OAAO,CAAA;AAC5E,IAAA,GAAA,CAAI,SAAA,EAAU;AAAA,EAChB,CAAA,EAAG,CAAC,GAAA,EAAK,SAAS,CAAC,CAAA;AAGnB,EAAA,MAAM,GAAA,GAAMA,WAAAA;AAAA,IACV,CAAC,EAAA,KACC,EAAA,IAAM,OAAA,CAAQ,QAAA,IACX,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAA;AAAA,IAC5C,CAAC,OAAO;AAAA,GACV;AAMA,EAAA,MAAM,SAAS,aAAA,CAAc,OAAA;AAC7B,EAAA,MAAM,oBAAoB,aAAA,CAAc,QAAA;AACxC,EAAA,OAAON,OAAAA;AAAA,IACL,OAAO;AAAA,MACL,MAAA;AAAA,MACA,SAAA;AAAA,MACA,aAAA;AAAA,MACA,YAAA;AAAA,MACA,eAAA;AAAA,MACA,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,GAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA,CAAC,QAAQ,SAAA,EAAW,aAAA,EAAe,cAAc,eAAA,EAAiB,GAAA,EAAK,mBAAmB,OAAO;AAAA,GACnG;AACF","file":"react.js","sourcesContent":["/**\n * ActiveToolContext — runtime selection state for tools.\n *\n * Holds the currently active tool id and a hotkey stack (tools held active\n * temporarily, e.g. space-for-hand). Read by the gesture dispatcher to\n * determine which tool's bindings are in scope; written by tool-switching\n * actions (`tool.activate`) and offhand hotkey actions (`tool.offhand`),\n * both parametric on `params.toolId`.\n *\n * The state hangs on the same scope tree as the actions and dep registries:\n * every canvas's input scope owns a tool of its own unless it joins a yoke,\n * and a provider above reads and writes the tool of the scope last used.\n */\n\nimport {\n createContext,\n useContext,\n useMemo,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from 'react';\nimport { ScopeNode } from './scopeNode';\n\n/** Which tool is active, plus the stack of tools temporarily held active by a\n * hotkey (space-for-hand and the like). The dispatcher reads this to decide\n * whose bindings are in scope. */\nexport interface ActiveToolContextValue {\n /** The focused tool's id, or `null` when no tool holds the active slot —\n * a canvas can run on ambient bindings alone. */\n active: string | null;\n hotkeyStack: string[];\n setActive(id: string | null): void;\n pushHotkey(id: string): void;\n /**\n * Disengage a hotkey-held tool. With `id`, removes that tool's own entry\n * wherever it now sits — holds do not have to come up in the order they went\n * down, and popping the top would disengage a tool whose key is still held.\n * With no id, pops the top.\n */\n popHotkey(id?: string): void;\n}\n\ninterface ToolState {\n active: string | null;\n hotkeyStack: string[];\n}\n\n/**\n * One node of the tool tree. A node that `owns` a tool holds its state; one\n * that does not — a scope inside a yoke — reads and writes its yoke's.\n */\nexport class ToolNode extends ScopeNode<ToolNode> {\n private state: ToolState | null;\n private value: { from: ToolNode; state: ToolState; out: ActiveToolContextValue } | null = null;\n\n constructor(parent: ToolNode | null, descends: boolean, owns: boolean, initialActive: string | null) {\n super(parent, descends);\n // A new scope starts on the tool in effect around it, so a tool a\n // consumer seeded above a canvas before it mounted is not lost.\n this.state = owns\n ? { active: initialActive ?? parent?.owner().state?.active ?? null, hotkeyStack: [] }\n : null;\n }\n\n /** The node whose tool a read here resolves to. */\n owner(): ToolNode {\n for (const n of this.start().chain()) if (n.state) return n;\n return this;\n }\n\n private update(next: (s: ToolState) => ToolState): void {\n const owner = this.owner();\n if (!owner.state) return;\n const updated = next(owner.state);\n if (updated === owner.state) return;\n owner.state = updated;\n owner.changed();\n }\n\n /** A stable value per owner and state, for `useSyncExternalStore`. */\n snapshot(): ActiveToolContextValue {\n const from = this.owner();\n const state = from.state ?? { active: null, hotkeyStack: [] };\n const cached = this.value;\n if (cached && cached.from === from && cached.state === state) return cached.out;\n const out: ActiveToolContextValue = {\n active: state.active,\n hotkeyStack: state.hotkeyStack,\n setActive: (id) => this.update((s) => (s.active === id ? s : { ...s, active: id })),\n pushHotkey: (id) => this.update((s) => ({ ...s, hotkeyStack: [...s.hotkeyStack, id] })),\n popHotkey: (id) =>\n this.update((s) => {\n const stack = s.hotkeyStack;\n if (stack.length === 0) return s;\n if (id === undefined) return { ...s, hotkeyStack: stack.slice(0, -1) };\n const i = stack.lastIndexOf(id);\n return i === -1 ? s : { ...s, hotkeyStack: [...stack.slice(0, i), ...stack.slice(i + 1)] };\n }),\n };\n this.value = { from, state, out };\n return out;\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.tree.listeners.add(listener);\n return () => {\n this.tree.listeners.delete(listener);\n };\n };\n}\n\nconst ActiveToolContext = createContext<ToolNode | null>(null);\n\n/** @internal The context `<InputScope>` and `<Yoke>` provide a tool node through. */\nexport const ActiveToolNodeContext = ActiveToolContext;\n\n/** Props for `<ActiveToolContextProvider>`. */\nexport interface ActiveToolContextProviderProps {\n children: ReactNode;\n /** Seeds the active slot, and wins over the first `useTools` call's\n * `active`. Omitted, the slot starts empty and that call seeds it. */\n initialActive?: string | null;\n}\n\n/** Provides root active-tool state. Every canvas below has a tool of its own;\n * reads and writes here reach the one last used. */\nexport function ActiveToolContextProvider({\n children,\n initialActive = null,\n}: ActiveToolContextProviderProps) {\n const [node] = useState(() => new ToolNode(null, true, true, initialActive));\n return <ActiveToolContext.Provider value={node}>{children}</ActiveToolContext.Provider>;\n}\n\nfunction useNodeValue(node: ToolNode | null): ActiveToolContextValue | null {\n const subscribe = useMemo(() => node?.subscribe ?? NO_SUBSCRIBE, [node]);\n return useSyncExternalStore(\n subscribe,\n () => node?.snapshot() ?? null,\n () => node?.snapshot() ?? null,\n );\n}\n\nconst NO_SUBSCRIBE = (): (() => void) => () => {};\n\n/** The active-tool state in scope. Throws outside a provider; use\n * `useOptionalActiveToolContext` where one is not guaranteed. */\nexport function useActiveToolContext(): ActiveToolContextValue {\n const value = useNodeValue(useContext(ActiveToolContext));\n if (value === null) {\n throw new Error(\n 'useActiveToolContext: no ActiveToolContextProvider in scope. Wrap your tree with <ActiveToolContextProvider> (typically inside <SceneCanvas>).',\n );\n }\n return value;\n}\n\n/**\n * Like `useActiveToolContext`, but returns `null` when no\n * `<ActiveToolContextProvider>` is in scope instead of throwing. Used by\n * `useStandardActions` to preserve its silent-no-op contract when no provider\n * is present.\n */\nexport function useOptionalActiveToolContext(): ActiveToolContextValue | null {\n return useNodeValue(useContext(ActiveToolContext));\n}\n\n/**\n * Conditional `<ActiveToolContextProvider>` wrapper. Mounts a provider only\n * when no parent provider is in scope — otherwise renders children unwrapped\n * so `<WeaselProvider>` defers to the host's existing scope.\n */\nexport function ActiveToolContextProviderIfRoot({\n children,\n}: {\n children: ReactNode;\n}) {\n const parent = useContext(ActiveToolContext);\n if (parent !== null) return <>{children}</>;\n return <ActiveToolContextProvider>{children}</ActiveToolContextProvider>;\n}\n","/** The React seam over the dep registry in `./depNode`: its provider and hooks. */\nimport {\n createContext, useContext, useEffect, useMemo,\n type ReactNode,\n} from 'react';\nimport type { DepSchema, DepName } from '../../index';\nimport { createDepRegistry, type DepRegistry } from './depNode';\nimport { useLatest } from '@weasel-js/react';\n\nexport type { DepSchema, DepName, DepRegistry };\nexport { DepNode, depNodeOf, createDepRegistry } from './depNode';\n\n/** @internal The context `<InputScope>` provides a scope's dep registry through. */\nexport const DepRegistryContext = createContext<DepRegistry | null>(null);\n\n/** Provides the dep registry for a canvas. `<SceneCanvas>` mounts one; a\n * consumer registering its own dep sources must be inside it. */\nexport function DepRegistryProvider({ children }: { children: ReactNode }) {\n const registry = useMemo(createDepRegistry, []);\n return <DepRegistryContext.Provider value={registry}>{children}</DepRegistryContext.Provider>;\n}\n\n/** The dep registry in scope. Throws outside a `<DepRegistryProvider>`. */\nexport function useDepRegistry(): DepRegistry {\n const r = useContext(DepRegistryContext);\n if (r === null) {\n throw new Error('useDepRegistry: no DepRegistryProvider in scope. Wrap your tree with <DepRegistryProvider> (typically inside <SceneCanvas>).');\n }\n return r;\n}\n\n/**\n * Like `useDepRegistry`, but returns `null` when no `<DepRegistryProvider>` is\n * in scope instead of throwing. Used by `useStandardActions` to preserve its\n * silent-no-op contract when neither provider is present.\n */\nexport function useOptionalDepRegistry(): DepRegistry | null {\n return useContext(DepRegistryContext);\n}\n\n/** Register a live source for `name` for the lifetime of the calling\n * component. The `source` thunk is called at dispatch time and should\n * return the latest value. */\nexport function useDepSource<K extends DepName>(name: K, source: () => DepSchema[K]) {\n const registry = useDepRegistry();\n const sourceRef = useLatest(source);\n useEffect(() => {\n return registry.register(name, () => sourceRef.current());\n }, [name, registry, sourceRef]);\n}\n","/**\n * useGestureDispatcher — React seam mounting the gesture dispatcher.\n *\n * Composes the input channels (window keydown/keyup, canvas wheel, WebKit\n * gesture events, canvas pointer events, multi-touch synthesized from\n * PointerEvents) and routes each\n * event to the dispatcher for the view it landed in — one view unless `views`\n * says otherwise. Reads ActiveToolContext + DepRegistry internally; consumer\n * passes the canvas ref, actions registry, and tools map.\n *\n * Side-effect only (returns void).\n *\n * See `docs/superpowers/specs/2026-05-16-registry-unification-design.md` § Q4.\n */\nimport { useCallback, useEffect, useRef } from 'react';\nimport type { RefObject } from 'react';\nimport { isEditableTarget } from '../keyHelpers';\nimport { useLatest } from '@weasel-js/react';\nimport { useActiveToolContext } from '../actions/activeToolContext';\nimport { useDepRegistry, type DepRegistry } from '../actions/depRegistry';\nimport type { DepName, DepSchema } from '../../index';\nimport type { ActionsRegistry } from '../actions/registry';\nimport type { AffordanceHit } from '../actions/invoker';\nimport { isTool } from '../../tools/types';\nimport type { Contribution } from '../../contributions/types';\nimport {\n createDispatcher, pointerGestureId, publishLiveDispatch, type Dispatcher, type DispatcherContext,\n} from './dispatcher';\nimport { isInControlWithin, pastDragThreshold } from '@weasel-js/gestures';\nimport { openPointerSession, type PointerSession } from '../pointerSession';\nimport { clientToCanvasRect } from '../../viewport/clientToCanvas';\nimport { itemsFromDataTransfer, itemsFromClipboardData } from '../../ingestion/ingestItems';\nimport type { InputEvent } from './matcher';\nimport { LONG_PRESS_MS, type LongPressOptions } from './longPressState';\nimport type { BodyTarget, BodyClassification } from '@weasel-js/gestures';\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport type { PaintedCursorState } from '@weasel-js/cursor';\nimport { resolveCursorTier } from '@weasel-js/cursor';\n\n// ---------------------------------------------------------------------------\n// Drop-over styling — class toggled on the canvas while an OS drag hovers it;\n// consumers style it. Not exported: the string is an observable public value\n// but the symbol is internal.\n// ---------------------------------------------------------------------------\n\n/** Class toggled on the canvas while an OS drag hovers it — consumers style it. */\nconst DROPOVER_CLASS = 'weasel-dropover';\n\n/**\n * Lift the stylus fields off a DOM `PointerEvent` onto the normalized\n * `InputEvent`. Kept as a spread-able partial so a synthetic event that\n * carries none of them stays free of `undefined`-valued keys.\n *\n * These ride the drag trail (`InvocationCtx.drag.points`) so pressure- and\n * tilt-aware actions — `insertAction`'s pencil kind today — can reach the\n * per-sample data without their own pointer plumbing.\n */\nfunction stylusOf(e: PointerEvent): {\n pressure?: number; tiltX?: number; tiltY?: number;\n} {\n return {\n ...(typeof e.pressure === 'number' ? { pressure: e.pressure } : {}),\n ...(typeof e.tiltX === 'number' ? { tiltX: e.tiltX } : {}),\n ...(typeof e.tiltY === 'number' ? { tiltY: e.tiltY } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Platform detection — module-level constant so it's stable across renders.\n// ---------------------------------------------------------------------------\n\nconst IS_MAC =\n typeof navigator !== 'undefined' &&\n /mac/i.test(\n // `||`, not `??`: jsdom (and some embedders) report an empty-string\n // platform, which is not nullish and would swallow the UA fallback.\n (navigator as { platform?: string }).platform || navigator.userAgent,\n );\n\n// ---------------------------------------------------------------------------\n// API\n// ---------------------------------------------------------------------------\n\n/**\n * Everything about handling an input event that depends on *which view* it\n * landed in: the dispatcher that runs it, and the three lookups that resolve\n * a client point against that view's camera.\n *\n * @internal One per view. The hook builds the `id: null` one from its flat\n * options; `views` supplies the rest, and the hook chooses between them per\n * event, so that it — and its listener set — still mounts exactly once.\n */\nexport interface DispatcherViewTarget {\n /** `null` is the root view — the whole canvas. Matches `ViewTarget.id`. */\n id: string | null;\n dispatcher: Dispatcher;\n affordanceAt: UseGestureDispatcherOptions['affordanceAt'];\n classifyTarget: UseGestureDispatcherOptions['classifyTarget'];\n clientToWorld: UseGestureDispatcherOptions['clientToWorld'];\n /**\n * The deps this view answers for itself — its camera, its selection, and\n * whatever else is per-view rather than per-canvas. Read per event; every\n * name it does not carry still resolves through the canvas registry.\n *\n * This is why a view does not get a `DepRegistryProvider` of its own. The\n * registry is where a consumer registers *sources*, and one per view would\n * fragment that: a consumer overriding `insert` would have to know how many\n * views exist and override each. An overlay keeps one place to register and\n * one authority per dep, with the view claiming only what is genuinely its.\n *\n * Without this a gesture inside a panel pans the whole canvas and selects\n * into the canvas's selection — correct coordinates alone do not make\n * routing correct.\n */\n deps?: () => Partial<DepSchema>;\n /**\n * This view's chrome-caps rule context, for the eligibility filter. The rule\n * table is the surface's, but a rule keyed on selection or the in-flight\n * action answers per view — so an action hidden in one panel must not\n * decline a gesture in another. `undefined` means \"nothing gates here\", the\n * same answer a surface with no mode registry gives.\n */\n getRuleCtx?: () => import('../../eligibility').RuleCtx | undefined;\n}\n\n/**\n * `base` with the routed view's own deps in front of it. Both sides are read\n * through thunks, so the result is stable for the life of a listener set while\n * still answering for whichever view the current event landed in.\n */\nfunction withViewDeps(\n base: () => DepRegistry,\n overlay: () => Partial<DepSchema> | undefined,\n): DepRegistry {\n return {\n register: (name, source) => base().register(name, source),\n get: <K extends DepName>(name: K): DepSchema[K] | undefined => {\n const own = overlay()?.[name];\n if (own !== undefined) return own as DepSchema[K];\n return base().get(name);\n },\n };\n}\n\n/**\n * The part of `features/viewports`' `ViewResolver` the dispatcher needs: which\n * view a client point belongs to, pinned to the view a gesture began in.\n *\n * @internal Structural on purpose — a `ViewResolver` satisfies it, and the\n * dispatcher stays free of the viewport module.\n */\nexport interface ViewIdResolver {\n begin(pointerId: number, clientX: number, clientY: number): { id: string | null };\n at(pointerId: number | null, clientX: number, clientY: number): { id: string | null };\n end(pointerId: number): void;\n}\n\n/** Per-channel switches for the listeners `useGestureDispatcher` attaches to\n * the canvas element. Omitted or `true` attaches the channel. */\nexport interface DispatcherChannels {\n /** `pointerdown`, hover `pointermove`, `pointerleave` — press, drag, click,\n * long-press, multi-touch and the hover-cursor pump. */\n pointer?: boolean;\n /** `wheel`. */\n wheel?: boolean;\n /** WebKit's `gesturestart` / `gesturechange` / `gestureend` — Safari's\n * trackpad pinch, dispatched as `pinch` events. */\n pinch?: boolean;\n /** `contextmenu`. Off leaves the browser's native menu in place. */\n contextMenu?: boolean;\n /** OS drop on the element plus `paste` on the window. Off leaves the\n * element a non-drop-target and stops `weasel-dropover` being applied. */\n ingest?: boolean;\n}\n\n/** Options for `useGestureDispatcher`: the element to listen on, the actions\n * and tools in play, and the hooks that turn raw DOM events into the world\n * coordinates and hit targets bindings match against. */\nexport interface UseGestureDispatcherOptions {\n /** Ref to the canvas element. Pointer/wheel/multitouch listeners attach here. */\n canvasRef: RefObject<HTMLElement | null>;\n /** Action registry (ActionsRegistry from registry.tsx). */\n actions: ActionsRegistry;\n /** Tool definitions keyed by id. Typically passes an empty Map. */\n entriesById: ReadonlyMap<string, Contribution<unknown>>;\n /** Default true. Set false to opt out of dispatcher wiring (e.g. demos that disable it). */\n enabled?: boolean;\n /**\n * Observer fired whenever the dispatcher synthesizes a double click, in\n * world coordinates. Runs BEFORE the event is dispatched and independently\n * of which binding (if any) handles it.\n *\n * This is deliberately not an Action. `<SceneCanvas onDoubleClick>` is a\n * notification — \"the user double-clicked, here's what they hit\" — and a\n * notification must not compete with behavior for the gesture. As a binding\n * it would lose to `enterPathEdit` on any body hit and silently never fire.\n * Routing it here keeps a single definition of \"double click\" (the point of\n * consolidating the kit's three detectors) without giving it\n * first-match-wins semantics it shouldn't have.\n */\n onDoubleClick?: (world: { x: number; y: number }) => void;\n /**\n * Default true. Set false to leave the window `keydown`/`keyup` listeners\n * unattached so keyboard-bound actions never dispatch — pointer, wheel, and\n * contextmenu channels stay live. `<SceneCanvas>` wires this to\n * `enableKeybindings`, so opting out of keybindings disables the modern\n * dispatcher key path as well as the legacy `useKeybindings` hook.\n *\n * Every dispatcher hears keys on `window`, and a keystroke one of them\n * claims — or anything else calls `preventDefault` on — is not dispatched by\n * the rest. `'first'` listens in the capture phase, so this dispatcher gets\n * the keystroke ahead of every dispatcher listening normally, whatever the\n * mount order: the shape for chrome that owns a key only when it can act.\n */\n keyboard?: boolean | 'first';\n /**\n * Optional affordance classifier. Called with the **world** coordinates of\n * the pointer — this hook applies the routed view's `clientToWorld` before\n * calling it, the same conversion that produces `InputEvent.x`/`y`, so a\n * consumer hit-tests in one space. Returns an `AffordanceHit` when the\n * pointer lands on a known affordance (resize handle, rotate handle, etc.)\n * or `null` when the pointer hit open canvas.\n *\n * The hit is packed into `InputEvent.pointerdown.affordance` and flows\n * through into `InvocationCtx.drag.affordance`. Action invokers that require\n * a specific affordance (e.g. `resizeAction` requires `handle:*`) use this\n * field as a guard in their `start` body.\n *\n * When omitted, `affordance` is always `undefined` — meaning only consumers\n * that explicitly wire a classifier get affordance-gated behavior.\n * `<SceneCanvas>` wires the full chrome→dispatcher bridge.\n */\n affordanceAt?: (worldPoint: { x: number; y: number }) => AffordanceHit | null;\n\n /**\n * Optional body classifier. Called on every pointerdown with the world-space\n * coordinates of the pointer. Its result is packed onto the event as\n * `bodyTarget` + `bodyKind`, which `matchTarget` reads to resolve the\n * string-form `TargetSpec` values in `Tool.bindings`.\n *\n * `body` is `'empty'` when nothing is under the pointer, `'selected-body'`\n * when the topmost hit belongs to the current selection, or\n * `'unselected-body'` when it belongs to a node that isn't selected. `kind`\n * is the hit node's semantic kind, when the scene can name it.\n *\n * When omitted, every body-derived target form (`'empty'`,\n * `'selected-body'`, `'unselected-body'`, `kind:<k>`, `kind:<k>:selected`)\n * never matches — bindings using those specs are silently skipped.\n * `<SceneCanvas>` wires this.\n *\n * World coordinates, on every path, for the same reason as `affordanceAt`.\n */\n classifyTarget?: (worldPoint: { x: number; y: number }) => BodyClassification;\n\n /**\n * Optional pre-created `Dispatcher`. When provided, this hook pumps events\n * into the supplied instance instead of creating its own. Lets a parent\n * scope (e.g. `<SceneCanvas>`) share one dispatcher between the gesture\n * mounter and other consumers (the preview-ghost layer).\n */\n dispatcher?: Dispatcher;\n\n /**\n * Converts a client-space pointer position (e.g. `e.clientX`, `e.clientY`)\n * to world-space coordinates. When supplied, every pointer/wheel event's\n * `x`/`y` is converted before the dispatcher builds `InvocationCtx.world`.\n *\n * Without this, `ctx.world` is populated with the raw client coords, which\n * silently breaks any action whose overlay/output uses absolute world\n * positions (marquee, lasso polyline, world-space affordances). Actions\n * that only read `drag.delta` are unaffected because client→world deltas\n * are equal at scale 1, but as soon as a consumer pans/zooms the view the\n * deltas diverge too.\n *\n * `<SceneCanvas>` always wires this via its canvas rect + current view.\n * Tests / harnesses without a view can omit it and continue passing raw\n * coordinates as before.\n */\n clientToWorld?: (clientX: number, clientY: number) => { x: number; y: number };\n\n /**\n * Invoked once per pump event (`pointermove`, `pointerup`, `pointercancel`,\n * `key-held` up-phase, `multitouch` move) when a dispatcher-side handle is\n * in flight. Lets the host canvas schedule a redraw so dispatcher-only\n * overlays (marquee, lasso, preview-ghost) repaint on each frame.\n *\n * Required because dispatcher actions don't go through the legacy\n * `tools.dispatcher.onGestureChange` redraw bump that ambient tool drags\n * relied on. Without it, the overlay layer's `draw` never runs between\n * pointerdown and pointerup, and the chrome flashes once at gesture start\n * and then sits frozen until the gesture ends.\n *\n * `<SceneCanvas>` wires this to the canvas's `requestRedraw`. Test\n * harnesses can omit it; their dispatchers won't paint between events but\n * that's already the test contract.\n */\n requestRedraw?: () => void;\n /**\n * The surface's painted-cursor channel, read live because the canvas handle\n * it lives on arrives a render after this hook runs.\n *\n * Given one, a cursor the CSS tier cannot express — sized in world units, or\n * past the size the browser drops the image at — is published here and drawn\n * by the painted-cursor layer instead. Without one, such a cursor resolves to\n * `none` and the pointer shows nothing.\n */\n paintedCursor?: () => PaintedCursorState | undefined;\n\n /** How touch and pen long-presses are timed, published and felt. */\n longPress?: LongPressOptions;\n\n /**\n * Thunk returning the live `RuleCtx` for the current frame. When supplied,\n * the dispatcher filters matched candidates by their declared\n * `Action.eligible` rule (omitted => always eligible). `<SceneCanvas>`\n * wires this; tests / harnesses without chrome-caps state can omit it.\n */\n getRuleCtx?: () => import('../../eligibility').RuleCtx | undefined;\n\n /**\n * Which of the canvas element's input channels to attach. Every one\n * defaults to `true`; naming a channel `false` leaves its listeners\n * unattached, so the element behaves as if the dispatcher were not there.\n *\n * A mount that binds two gestures should not also have to take the rest of\n * the pipeline's side effects: `contextMenu` suppresses the native menu\n * unconditionally, and `ingest` makes the element a valid drop target and\n * styles it while an OS drag hovers. `@weasel-js/labkit`'s loupe mounts on\n * a lab's own canvas host for a wheel and a held key, and turning the other\n * three off is what keeps right-click and file drops working there.\n *\n * The window keyboard channel is `keyboard` instead of an entry here,\n * because `<SceneCanvas enableKeybindings>` drives it.\n */\n channels?: DispatcherChannels;\n\n /**\n * Routing for a canvas hosting more than one view: the non-root dispatch\n * records to choose between, read fresh per event, and the resolver that\n * chooses. Omit for a single view — then every event runs on the record the\n * flat options above describe, which is what they are: view zero.\n *\n * A resolved id with no live record falls back to the root, so a view that\n * unmounts mid-gesture degrades instead of dropping the event.\n *\n * Keyboard and paste have no coordinates to resolve; they run on the view\n * the last coordinate-bearing event resolved to.\n *\n * @internal\n */\n views?: {\n targets: () => readonly DispatcherViewTarget[];\n resolver: ViewIdResolver;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** A pointer held on the canvas, and everything a press is synthesized from. */\ninterface HeldPointer {\n session: PointerSession;\n /** Latest screen position, for the multitouch centroid and spread. */\n pos: { x: number; y: number };\n /** The press, withheld from the dispatcher until movement crosses\n * `DRAG_THRESHOLD_PX`. Null once forwarded, or once multitouch claimed\n * the pointer — see the multi-pointer policy in `onPointerDown`. */\n buffered: { ev: InputEvent; clientX: number; clientY: number } | null;\n /** Press-time state replayed onto a synthesized click, long-press or\n * contextmenu, whose matchers resolve targets against it. */\n down: {\n target: unknown;\n clientX: number;\n clientY: number;\n /** World-space press point, forwarded onto the synthesized click as\n * `pressX`/`pressY` — see `ClickEvent`. */\n worldX: number;\n worldY: number;\n affordance?: unknown;\n bodyTarget?: BodyTarget;\n bodyKind?: string;\n altKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n };\n}\n\n/**\n * Compute centroid and spread (distance between first two pointers) from\n * the active pointer positions. Returns a centroid of (0, 0) and spread\n * of 0 when fewer than 2 pointers are present.\n */\nfunction computeMultiTouchGeometry(\n positions: Iterable<{ x: number; y: number }>,\n): { centroid: { x: number; y: number }; spread: number } {\n const pts = [...positions];\n if (pts.length < 2) {\n return { centroid: { x: 0, y: 0 }, spread: 0 };\n }\n // Centroid across all active pointers.\n let sumX = 0;\n let sumY = 0;\n for (const p of pts) {\n sumX += p.x;\n sumY += p.y;\n }\n const centroid = { x: sumX / pts.length, y: sumY / pts.length };\n // Spread = distance between the first two pointers (primary pair).\n const dx = pts[1].x - pts[0].x;\n const dy = pts[1].y - pts[0].y;\n const spread = Math.sqrt(dx * dx + dy * dy);\n return { centroid, spread };\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\n/**\n * Attach the input pipeline to a canvas: DOM pointer, wheel, keyboard and\n * multitouch listeners in, normalized input events out, routed through the\n * dispatcher to whichever action a binding names.\n *\n * Everything it needs beyond its options — the active tool, the dep registry —\n * comes from context, so it must be mounted inside `<SceneCanvas>`'s\n * providers.\n */\nexport function useGestureDispatcher(opts: UseGestureDispatcherOptions): void {\n const { canvasRef, actions, entriesById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld, requestRedraw, paintedCursor, getRuleCtx, onDoubleClick, views, channels, longPress } = opts;\n // Read out as booleans, not the object: the attach effect depends on\n // them, and an inline `channels={{...}}` would re-bind every listener on\n // every render.\n const pointerChannel = channels?.pointer !== false;\n const wheelChannel = channels?.wheel !== false;\n const pinchChannel = channels?.pinch !== false;\n const contextMenuChannel = channels?.contextMenu !== false;\n const ingestChannel = channels?.ingest !== false;\n const onDoubleClickRef = useLatest(onDoubleClick);\n const activeTool = useActiveToolContext();\n const depRegistry = useDepRegistry();\n\n // Single dispatcher instance, stable across renders. When a `dispatcher`\n // is supplied via options, adopt it; otherwise create one lazily.\n const dispatcherRef = useRef<Dispatcher | null>(null);\n if (!dispatcherRef.current) {\n dispatcherRef.current = dispatcherOpt ?? createDispatcher();\n }\n\n // Stable ref to the latest context values so event listeners always see\n // current state without needing to re-register on every render.\n // No `getRuleCtx` here: eligibility is a per-view answer, so it rides on the\n // dispatch record and `ctxNow` installs the routed view's.\n const registryRef = useLatest(actions);\n const ctxRef = useLatest<DispatcherContext>({\n actions,\n depRegistry,\n activeToolId: activeTool.active,\n hotkeyStack: activeTool.hotkeyStack,\n entriesById,\n isMac: IS_MAC,\n });\n\n // The flat options are view zero.\n const rootTargetRef = useLatest<DispatcherViewTarget>({\n id: null, dispatcher: dispatcherRef.current, affordanceAt, classifyTarget, clientToWorld,\n getRuleCtx,\n });\n const viewsRef = useLatest(views);\n\n /** Every live dispatcher — what a cancel-everything has to reach. */\n const allDispatchers = useCallback((): Dispatcher[] => [\n rootTargetRef.current.dispatcher,\n ...(viewsRef.current?.targets() ?? []).map((t) => t.dispatcher),\n ], [rootTargetRef, viewsRef]);\n const requestRedrawRef = useLatest(requestRedraw);\n const paintedCursorRef = useLatest(paintedCursor);\n const longPressRef = useLatest(longPress);\n\n // Double-click synthesis state. Lives at hook level (not inside the effect)\n // so it survives effect re-runs — otherwise HMR / StrictMode / a transient\n // deps change resets it between the two clicks and the doubleclick never\n // fires.\n const lastClickRef = useRef<{ t: number; clientX: number; clientY: number } | null>(null);\n\n // Tool lifecycle. A tool is live while it holds the active slot or sits\n // in the hotkey stack; `onActivate` fires as it becomes live in either and\n // `onDeactivate` as it stops being live in both. A switch of the active\n // tool also cancels in-flight handles, so the new tool does not inherit a\n // live gesture — between the outgoing tools' cleanup and the incoming\n // tools' setup.\n const liveToolsRef = useRef<ReadonlySet<string>>(new Set());\n const prevActiveRef = useRef(activeTool.active);\n const entriesByIdRef = useLatest(entriesById);\n const fireLifecycle = useCallback((id: string, hook: 'onActivate' | 'onDeactivate'): void => {\n const tool = entriesByIdRef.current.get(id);\n if (!tool || !isTool(tool)) return;\n const fn = tool[hook];\n if (!fn) return;\n try {\n fn({ scratch: tool.initScratch?.() });\n } catch (err) {\n console.error(`weasel: tool \"${id}\".${hook} threw`, err);\n }\n }, [entriesByIdRef]);\n useEffect(() => {\n const prev = liveToolsRef.current;\n const next = new Set<string>(\n activeTool.active === null ? activeTool.hotkeyStack : [activeTool.active, ...activeTool.hotkeyStack],\n );\n liveToolsRef.current = next;\n for (const id of prev) if (!next.has(id)) fireLifecycle(id, 'onDeactivate');\n if (prevActiveRef.current !== activeTool.active) {\n for (const d of allDispatchers()) d.cancelAll('cancel');\n }\n prevActiveRef.current = activeTool.active;\n for (const id of next) if (!prev.has(id)) fireLifecycle(id, 'onActivate');\n });\n useEffect(() => () => {\n const live = liveToolsRef.current;\n liveToolsRef.current = new Set();\n for (const id of live) fireLifecycle(id, 'onDeactivate');\n }, [fireLifecycle]);\n\n useEffect(() => {\n if (!enabled) return;\n\n let disposed = false;\n\n // The view the current event belongs to, as an id rather than a record:\n // the record is rebuilt every render, so holding one across events would\n // dispatch through last render's lookups.\n let routedId: string | null = null;\n\n /** The dispatch record for the routed view. */\n const target = (): DispatcherViewTarget => {\n if (routedId === null) return rootTargetRef.current;\n return viewsRef.current?.targets().find((t) => t.id === routedId)\n ?? rootTargetRef.current;\n };\n\n /** Route an event with coordinates. `pointerId` is `null` for input with\n * nothing to capture — wheel, hover, contextmenu, drop. */\n const routeAt = (pointerId: number | null, clientX: number, clientY: number): void => {\n routedId = viewsRef.current?.resolver.at(pointerId, clientX, clientY).id ?? null;\n };\n /** Route a pointerdown, pinning the pointer to the view it landed in. */\n const routeDown = (pointerId: number, clientX: number, clientY: number): void => {\n routedId = viewsRef.current?.resolver.begin(pointerId, clientX, clientY).id ?? null;\n };\n const routeRelease = (pointerId: number): void => {\n viewsRef.current?.resolver.end(pointerId);\n };\n\n // Resolved per event, not bound once: the dispatcher an event runs on is\n // a property of the view it landed in.\n const dispatcherNow = (): Dispatcher => target().dispatcher;\n\n const routedDeps = withViewDeps(() => ctxRef.current.depRegistry, () => target().deps?.());\n // Eligibility is evaluated against the routed view's rule context, not the\n // surface's — same reason its deps are.\n const routedRuleCtx = (): ReturnType<NonNullable<DispatcherViewTarget['getRuleCtx']>> =>\n target().getRuleCtx?.();\n const ctxNow = (): DispatcherContext => ({\n ...ctxRef.current, depRegistry: routedDeps, getRuleCtx: routedRuleCtx,\n viewId: target().id,\n });\n const canvas = canvasRef.current;\n\n // Convert a client-space pointer position to world-space. When no\n // `clientToWorld` thunk is wired (legacy harnesses / tests), this is the\n // identity — preserves pre-fix behavior for callers that pass raw event\n // coords as if they were world. SceneCanvas always wires the thunk via\n // its canvas rect + current view, so `ctx.world` becomes real world coords\n // for areaSelect / lassoSelect / world-space affordance consumers.\n const toWorld = (cx: number, cy: number): { x: number; y: number } => {\n const fn = target().clientToWorld;\n return fn ? fn(cx, cy) : { x: cx, y: cy };\n };\n\n // Dispatch + bump the host canvas's redraw when any handle was in flight\n // before, during, or after the event. Without this, dispatcher-only\n // overlays (marquee, lasso) never repaint after their initial frame.\n // `before` captures the pre-event state so we redraw on the pump that\n // CLOSES a gesture (e.g. pointerup-with-no-remaining-handles still needs\n // to clear the overlay).\n //\n // `on` is for the one path that dispatches after its event has left the\n // stack (drop, whose items materialize async) — by then the routed view\n // is whatever moved under the cursor since.\n const dispatch = (ev: InputEvent, on?: Dispatcher): 'handled' | 'unhandled' => {\n const d = on ?? dispatcherNow();\n const before = d.inFlight().size;\n const result = d.handleInput(ev, ctxNow());\n const after = d.inFlight().size;\n if (before > 0 || after > 0) requestRedrawRef.current?.();\n return result;\n };\n\n // Held keys by physical key, mapped to the `key` they went down as: Shift\n // pressed mid-hold makes the keyup of an 'o' press report 'O'.\n const heldKeys = new Map<string, string>();\n const physicalKey = (e: KeyboardEvent): string => e.code || e.key.toLowerCase();\n\n // Every pointer currently held on the canvas, one `openPointerSession`\n // each. The session owns capture, pointer identity, teardown and the\n // three recovery rules; the record owns what the dispatcher synthesizes.\n const held = new Map<number, HeldPointer>();\n // Pinch anchors land in `zoomAt`, which measures from the canvas top-left,\n // so the centroid is converted here — the same step the wheel listener\n // takes for its own anchor. Client coords would drift the zoom by the\n // canvas's offset from the viewport.\n const toCanvasLocal = (p: { x: number; y: number }): { x: number; y: number } => {\n const rect = canvas?.getBoundingClientRect();\n if (!rect) return p;\n const [x, y] = clientToCanvasRect(rect, p.x, p.y);\n return { x, y };\n };\n const heldGeometry = () => {\n const { centroid, spread } = computeMultiTouchGeometry(\n [...held.values()].map((p) => p.pos),\n );\n return { centroid: toCanvasLocal(centroid), spread };\n };\n\n // Set on a `gesturestart` some binding claims, cleared on its end. `scale`\n // and `rotation` on a GestureEvent are cumulative from the start; these\n // hold the previous sample's so each dispatched `pinch` is a step.\n let pinchLive = false;\n let pinchScale = 1;\n let pinchRotation = 0;\n\n const endPinch = (): void => {\n pinchLive = false;\n pinchScale = 1;\n pinchRotation = 0;\n };\n\n // Tracks the start state of an active multitouch episode so we can\n // synthesize a `multitouchtap` event on release when the centroid hasn't\n // moved past the tap threshold. `fingers` records the peak count.\n let multiTouchStart: { fingers: number; centroid: { x: number; y: number } } | null = null;\n const TAP_THRESHOLD_PX = 8;\n\n // Long-press synthesis. Armed on pointerdown for touch/pen, cancelled by\n // movement past `DRAG_THRESHOLD_PX`, by release, by cancel, or by a second\n // pointer landing (so it can never fire mid-pinch).\n const longPressTimers = new Map<number, ReturnType<typeof setTimeout>>();\n\n const clearPending = (pointerId?: number): void => {\n const store = longPressRef.current?.state;\n const p = store?.get();\n if (p && (pointerId === undefined || p.pointerId === pointerId)) store!.set(null);\n };\n\n const cancelLongPress = (pointerId: number): void => {\n const t = longPressTimers.get(pointerId);\n if (t !== undefined) {\n clearTimeout(t);\n longPressTimers.delete(pointerId);\n }\n clearPending(pointerId);\n };\n\n const cancelAllLongPress = (): void => {\n for (const t of longPressTimers.values()) clearTimeout(t);\n longPressTimers.clear();\n clearPending();\n };\n\n const HAPTIC_MS = 15;\n\n /** Fire a synthesized long-press, falling back to contextmenu when the\n * long-press matched nothing. The fallback is what makes existing\n * `contextMenu` bindings reachable by touch with no consumer change. */\n const longPressEvents = (down: HeldPointer['down']): { longpress: InputEvent; contextmenu: InputEvent } => {\n const shared = {\n target: down.target,\n altKey: down.altKey,\n ctrlKey: down.ctrlKey,\n metaKey: down.metaKey,\n shiftKey: down.shiftKey,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n\n const at = { x: down.worldX, y: down.worldY, clientX: down.clientX, clientY: down.clientY };\n return {\n longpress: { kind: 'longpress', ...at, ...shared } as InputEvent,\n contextmenu: { kind: 'contextmenu', ...at, ...shared } as InputEvent,\n };\n };\n\n /** Whether holding `down` to the end would fire anything: the same two\n * dispatches `fireLongPress` makes, predicted without invoking. */\n const longPressWouldFire = (down: HeldPointer['down']): boolean => {\n const evs = longPressEvents(down);\n const d = dispatcherNow();\n return d.resolveOnly(evs.longpress, ctxNow()) !== null\n || d.resolveOnly(evs.contextmenu, ctxNow()) !== null;\n };\n\n const fireLongPress = (pointerId: number, pointerType: string): void => {\n const down = held.get(pointerId)?.down;\n clearPending(pointerId);\n if (!down) return;\n const evs = longPressEvents(down);\n let result = dispatch(evs.longpress);\n if (result === 'unhandled') result = dispatch(evs.contextmenu);\n if (result === 'handled' && longPressRef.current?.haptics !== false\n && (pointerType === 'touch' || pointerType === 'pen')\n && typeof navigator !== 'undefined' && typeof navigator.vibrate === 'function') {\n navigator.vibrate(HAPTIC_MS);\n }\n };\n\n // Double-click synthesis thresholds. 600ms matches the upper end of OS\n // double-click settings; 8px tolerates the natural drift of a real\n // mouse / trackpad between the two clicks. State (`lastClickRef`)\n // lives at hook level so it survives effect re-runs.\n const DOUBLE_CLICK_MAX_MS = 600;\n const DOUBLE_CLICK_MAX_PX = 8;\n\n // -----------------------------------------------------------------------\n // Window key listeners\n // -----------------------------------------------------------------------\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.defaultPrevented || isEditableTarget(e.target)) return;\n // Every dispatcher hears keys on window; only the active scope's act.\n if (!registryRef.current.isActive()) return;\n\n // Autorepeat for a key that's already engaged a key-held binding is\n // suppressed entirely — no dispatch (no trace flood) and the\n // browser default is blocked. Holding Space-for-hand otherwise\n // streamed an 'unhandled' immediate-`key` trace entry per repeat.\n // Autorepeat for a key that ISN'T held still dispatches normally,\n // so things like Cmd+= step-zoom keep auto-repeating.\n if (e.repeat && heldKeys.has(physicalKey(e))) {\n e.preventDefault();\n return;\n }\n\n // Dispatch both key and key-held forms unconditionally. The dispatcher\n // de-dupes naturally because each form uses a different gestureId and\n // different GestureSpec kind. `matchBest` returns 'unhandled' when no\n // binding matches the alternate form, so there's no double-fire risk.\n\n const keyEv: InputEvent = {\n kind: 'key',\n key: e.key,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n repeat: e.repeat,\n };\n const keyResult = dispatch(keyEv);\n\n // Always dispatch key-held DOWN, even on autorepeat. The dispatcher's\n // own defense returns 'handled' (no-op) when a handle is already in\n // flight for this gestureId, which both prevents start() re-invocation\n // and lets us preventDefault the repeat so the page doesn't react.\n const heldEv: InputEvent = {\n kind: 'key-held',\n key: e.key,\n phase: 'down',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n const heldResult = dispatch(heldEv);\n\n if (heldResult === 'handled') {\n heldKeys.set(physicalKey(e), e.key);\n }\n\n if (keyResult === 'handled' || heldResult === 'handled') {\n e.preventDefault();\n }\n };\n\n const onKeyUp = (e: KeyboardEvent) => {\n const physical = physicalKey(e);\n const downKey = heldKeys.get(physical);\n if (downKey === undefined) return;\n const ev: InputEvent = {\n kind: 'key-held',\n key: downKey,\n phase: 'up',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(ev);\n heldKeys.delete(physical);\n };\n\n // A window that loses focus never delivers the keyup, so without this every\n // in-flight key-held handle stays engaged until that key is pressed again.\n // Nor can a drag trust the release it may or may not see later, so every\n // held pointer is canceled — through its session, which reports once.\n const onWindowBlur = () => {\n endPinch();\n for (const p of [...held.values()]) p.session.cancel();\n for (const key of heldKeys.values()) {\n const ev: InputEvent = {\n kind: 'key-held',\n key,\n phase: 'up',\n altKey: false,\n ctrlKey: false,\n metaKey: false,\n shiftKey: false,\n };\n dispatch(ev);\n }\n heldKeys.clear();\n };\n\n // -----------------------------------------------------------------------\n // Canvas wheel listener\n // -----------------------------------------------------------------------\n\n const onWheel = (e: WheelEvent) => {\n registryRef.current.activate();\n // Safari can report one trackpad pinch as both a gesture stream and\n // ctrl+wheel. While a claimed gesture is live it is the only driver.\n if (pinchLive && e.ctrlKey) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n routeAt(null, e.clientX, e.clientY);\n // Convert client-space cursor to canvas-local: zoomAt() (and any other\n // wheel consumer of clientX/Y) anchors in canvas-top-left coords, not\n // viewport coords. Without this, anchored-wheel zoom drifts by the\n // canvas's offset from the viewport top-left.\n const rect = canvas?.getBoundingClientRect();\n const [localX, localY] = rect\n ? clientToCanvasRect(rect, e.clientX, e.clientY)\n : [e.clientX, e.clientY];\n const hitPoint = toWorld(e.clientX, e.clientY);\n const affordance = target().affordanceAt?.(hitPoint) ?? undefined;\n const body = target().classifyTarget?.(hitPoint);\n const ev: InputEvent = {\n kind: 'wheel',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n deltaX: e.deltaX,\n deltaY: e.deltaY,\n clientX: localX,\n clientY: localY,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(body?.body !== undefined ? { bodyTarget: body.body } : {}),\n ...(body?.kind !== undefined ? { bodyKind: body.kind } : {}),\n };\n const result = dispatch(ev);\n // A claimed wheel neither scrolls the page nor reaches the canvas's other listeners\n // (a host's camera would zoom under a loupe); capture phase lets this run first.\n if (result === 'handled') {\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n };\n\n // -----------------------------------------------------------------------\n // Canvas gesture listeners (WebKit trackpad pinch)\n // -----------------------------------------------------------------------\n\n const pinchEventOf = (e: Event, scale: number, rotation: number): InputEvent => {\n const g = e as Event & {\n clientX?: number; clientY?: number;\n altKey?: boolean; ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean;\n };\n const rect = canvas?.getBoundingClientRect();\n // A focal point is part of the WebKit shape; the canvas center stands\n // in for an embedder that leaves it off.\n const cx = typeof g.clientX === 'number' ? g.clientX : (rect ? rect.left + rect.width / 2 : 0);\n const cy = typeof g.clientY === 'number' ? g.clientY : (rect ? rect.top + rect.height / 2 : 0);\n routeAt(null, cx, cy);\n const [localX, localY] = rect ? clientToCanvasRect(rect, cx, cy) : [cx, cy];\n const hitPoint = toWorld(cx, cy);\n const affordance = target().affordanceAt?.(hitPoint) ?? undefined;\n const body = target().classifyTarget?.(hitPoint);\n return {\n kind: 'pinch',\n altKey: g.altKey === true,\n ctrlKey: g.ctrlKey === true,\n metaKey: g.metaKey === true,\n shiftKey: g.shiftKey === true,\n scale,\n rotation,\n clientX: localX,\n clientY: localY,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(body?.body !== undefined ? { bodyTarget: body.body } : {}),\n ...(body?.kind !== undefined ? { bodyKind: body.kind } : {}),\n };\n };\n\n const onGestureStart = (e: Event) => {\n endPinch();\n // Claimed up front, with a probe at unit scale: Safari starts its own\n // page zoom from an unprevented start, before any change arrives.\n // `direction`-filtered bindings cannot match a unit step, so they are\n // resolved per change instead and do not claim the start.\n const probe = pinchEventOf(e, 1, 0);\n if (dispatcherNow().resolveOnly(probe, ctxNow()) === null) return;\n pinchLive = true;\n e.preventDefault();\n };\n\n const onGestureChange = (e: Event) => {\n const g = e as Event & { scale?: number; rotation?: number };\n const scale = typeof g.scale === 'number' && g.scale > 0 ? g.scale : pinchScale;\n const rotation = typeof g.rotation === 'number' ? g.rotation : pinchRotation;\n const step = scale / pinchScale;\n const turn = rotation - pinchRotation;\n pinchScale = scale;\n pinchRotation = rotation;\n if (dispatch(pinchEventOf(e, step, turn)) === 'handled') {\n pinchLive = true;\n e.preventDefault();\n } else if (pinchLive) {\n // The start was claimed; letting one change through would hand the\n // rest of the pinch to Safari's page zoom mid-gesture.\n e.preventDefault();\n }\n };\n\n const onGestureEnd = (e: Event) => {\n if (pinchLive) e.preventDefault();\n endPinch();\n };\n\n // -----------------------------------------------------------------------\n // Canvas pointer listeners + multi-touch synthesis\n // -----------------------------------------------------------------------\n\n // A double click this dispatcher acted on is spent: the browser's own\n // `dblclick` that follows is marked handled, so a container that opens or\n // toggles on double-click (labkit's lightbox) leaves it alone.\n let claimedDoubleClick = false;\n const onNativeDoubleClick = (e: MouseEvent) => {\n if (!claimedDoubleClick) return;\n claimedDoubleClick = false;\n e.preventDefault();\n };\n\n const onPointerDown = (e: PointerEvent) => {\n claimedDoubleClick = false;\n // Any button makes this the scope chrome and keys reach.\n registryRef.current.activate();\n // Only the primary button drives gesture dispatch. `pointerdown` reports\n // `button === 0` for the left mouse button and for touch / pen contact;\n // secondary (right, `2`) and middle (`1`) mouse buttons are left for the\n // consumer's own tools (e.g. right-drag viewport pan) and the browser\n // context menu. Without this guard a right-drag is classified and routed\n // exactly like a left-drag — selecting + transforming under the cursor\n // instead of letting an ambient pan tool claim it. An absent `button`\n // (synthetic / programmatic events) counts as primary.\n if ((e.button ?? 0) !== 0) return;\n if (!canvas) return;\n // A button or field laid over the canvas handles its own press: opening a\n // session here would capture the pointer and retarget its click.\n if (isInControlWithin(e.target, canvas)) return;\n routeDown(e.pointerId, e.clientX, e.clientY);\n\n const w = toWorld(e.clientX, e.clientY);\n const affordance = target().affordanceAt?.(w) ?? undefined;\n const body = target().classifyTarget?.(w);\n const bodyTarget = body?.body;\n const bodyKind = body?.kind;\n const ev: InputEvent = {\n kind: 'pointerdown',\n target: e.target,\n pointerId: e.pointerId,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n ...stylusOf(e),\n ...(affordance !== undefined ? { affordance } : {}),\n ...(bodyTarget !== undefined ? { bodyTarget } : {}),\n ...(bodyKind !== undefined ? { bodyKind } : {}),\n };\n // The session owns the rest of this pointer: capture, the moves and the\n // release, and the three recovery rules for a release that never\n // arrives. A press on a pointer one is already open for cancels that\n // stale gesture before this handler runs — its `pointerdown` listener is\n // on the document, in the capture phase, ahead of this one on the canvas.\n held.set(e.pointerId, {\n session: openPointerSession(canvas, e, {\n onMove: onPointerMove,\n onEnd: onPointerUp,\n onCancel: () => { onPointerCancel(e.pointerId); },\n }),\n pos: { x: e.clientX, y: e.clientY },\n // Deferred until the first past-threshold pointermove: a bare\n // press-and-release should fire `click`, not start a drag action.\n buffered: { ev, clientX: e.clientX, clientY: e.clientY },\n down: {\n target: e.target,\n clientX: e.clientX,\n clientY: e.clientY,\n worldX: w.x,\n worldY: w.y,\n affordance,\n bodyTarget,\n bodyKind,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n },\n });\n\n // The press itself dispatches now, for bindings that must act while the\n // button is still down and before the gesture is classified (select\n // highlights the pressed node here). `matchSpec` routes the two copies\n // to disjoint spec kinds — `pointerDown` matches only this one, `drag`\n // only the buffered one — so a single press never fires both.\n //\n // Withheld once a second pointer is down: this press belongs to the\n // multitouch channel under the MULTI-POINTER POLICY below, which clears\n // the buffered copy for the same reason. Without this a pinch's second\n // finger ran `select.pick` and moved the selection under the gesture.\n if (held.size < 2) dispatch({ ...ev, stage: 'press' });\n\n // Arm long-press for touch / pen only, and only for a lone pointer —\n // a second finger means a multi-touch gesture, not a long-press.\n if ((e.pointerType === 'touch' || e.pointerType === 'pen')\n && held.size === 1) {\n cancelLongPress(e.pointerId);\n const duration = longPressRef.current?.duration ?? LONG_PRESS_MS;\n longPressTimers.set(\n e.pointerId,\n setTimeout(() => {\n longPressTimers.delete(e.pointerId);\n if (disposed) return;\n fireLongPress(e.pointerId, e.pointerType);\n }, duration),\n );\n const store = longPressRef.current?.state;\n const rec = held.get(e.pointerId);\n if (store && rec) {\n store.set({\n pointerId: e.pointerId,\n pointerType: e.pointerType as 'touch' | 'pen',\n client: { x: e.clientX, y: e.clientY },\n local: toCanvasLocal({ x: e.clientX, y: e.clientY }),\n world: { x: w.x, y: w.y },\n viewId: target().id,\n startedAt: performance.now(),\n duration,\n armed: longPressWouldFire(rec.down),\n });\n }\n }\n\n // Synthesize a multi-touch event when >= 2 pointers are active.\n if (held.size >= 2) {\n cancelAllLongPress();\n // MULTI-POINTER POLICY: the multitouch channel takes ownership of\n // every pointer that hasn't already committed to a gesture. Clearing\n // the buffered press is what enforces it — a claimed pointer opens no\n // drag handle on the next move, and synthesizes no click on release\n // (both of those read the buffer). The `multitouch-<fingers>` handle\n // and the `multitouchtap` synthesis below are the whole gesture.\n //\n // This used to hold by accident: `gestureIdFor` returned one key for\n // every pointer, so a second finger's press found the first's handle\n // in flight and no-oped. Per-pointer keying removes the accident, so\n // the policy has to be stated. Stating it is the improvement — a\n // pointer that is part of a pinch is not also dragging something.\n //\n // Note the asymmetry: a pointer that already opened a drag has no\n // buffer left to claim, so its gesture survives the second finger\n // landing. Yanking a drag out from under someone who rested a palm is\n // worse than letting it finish.\n for (const p of held.values()) p.buffered = null;\n\n const { centroid, spread } = heldGeometry();\n // Capture start state for tap synthesis. On the first 1→2 transition\n // we record the centroid; subsequent pointerdowns at higher finger\n // counts only bump the recorded peak fingers count.\n if (!multiTouchStart) {\n multiTouchStart = { fingers: held.size, centroid: { ...centroid } };\n } else {\n multiTouchStart.fingers = held.size;\n }\n const mt: InputEvent = {\n kind: 'multitouch',\n fingers: held.size,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n centroid,\n spread,\n };\n dispatch(mt);\n }\n };\n\n const onPointerMove = (e: PointerEvent) => {\n routeAt(e.pointerId, e.clientX, e.clientY);\n const rec = held.get(e.pointerId);\n if (rec) rec.pos = { x: e.clientX, y: e.clientY };\n\n // Threshold gate: if a pointerdown is buffered for this pointer and\n // the movement crossed the drag threshold, forward the buffered\n // pointerdown to the dispatcher BEFORE the pointermove. This is what\n // opens the ongoing drag handle (matching `kind: 'drag'` bindings);\n // subsequent pointermoves pump it via `onMove`. Sub-threshold\n // pointermoves are still forwarded so existing pump paths (e.g. other\n // in-flight handles) keep working, but they're no-ops when no handle\n // exists.\n const buffered = rec?.buffered;\n if (rec && buffered) {\n if (pastDragThreshold(buffered, e)) {\n rec.buffered = null;\n cancelLongPress(e.pointerId);\n dispatch(buffered.ev);\n }\n }\n\n // If a multitouch handle is in flight, synthesize a multitouch pump event\n // with the updated centroid + spread. The dispatcher routes this to the\n // handle's onMove (because the event carries centroid data).\n const mtGestureId = `multitouch-${held.size}`;\n if (held.size >= 2 && dispatcherNow().inFlight().has(mtGestureId)) {\n const { centroid, spread } = heldGeometry();\n const mtEv: InputEvent = {\n kind: 'multitouch',\n fingers: held.size,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n centroid,\n spread,\n };\n dispatch(mtEv);\n // Also dispatch the raw pointermove so single-pointer handles can coexist.\n }\n\n const w = toWorld(e.clientX, e.clientY);\n const ev: InputEvent = {\n kind: 'pointermove',\n pointerId: e.pointerId,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n ...stylusOf(e),\n };\n dispatch(ev);\n\n lastHover = {\n clientX: e.clientX, clientY: e.clientY,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n refreshHoverCursor();\n };\n\n // -----------------------------------------------------------------------\n // Hover-cursor pump\n // -----------------------------------------------------------------------\n //\n // On every idle pointermove (no pressed pointer, no in-flight handle),\n // resolve what sits under the pointer and write a cursor override\n // directly to `canvas.style.cursor`. Precedence:\n //\n // 1. Affordance hit declaring `AffordanceHit.cursor` (resize corners,\n // rotate ring) — the same `affordanceAt` hit-test pointerdown uses.\n // 2. The action a drag from here would route to (`resolveOnly`, the\n // same match walk pointerdown takes), when it declares\n // `Action.cursor` — e.g. `viewport.dragPan` → 'grab' over empty\n // canvas when pan would win the drag.\n // 3. Otherwise the action a click here would route to, when it\n // declares one — e.g. Alt over a path segment in path-edit mode.\n // 4. No override — clear the inline style so the active tool's\n // React-managed `Tool.cursor` (the implicit base) shows through.\n //\n // Mid-gesture the pump stands down; the tool-cursor pipeline\n // (function-form `Tool.cursor` re-resolving on `gestureTick`) owns the\n // cursor there. The override is an inline style on purpose: clearing it\n // restores the React-managed base without effect churn.\n //\n // `lastHover` lets modifier keydown/keyup refresh the prediction without\n // pointer movement (a held Space re-routes the drag to the hand tool).\n // That refresh is deferred a tick so React can commit the hotkey-stack /\n // active-tool state the key event just changed — `ctxRef` is only\n // rewritten on commit.\n let lastHover: {\n clientX: number; clientY: number;\n altKey: boolean; ctrlKey: boolean; metaKey: boolean; shiftKey: boolean;\n } | null = null;\n let cursorOverridden = false;\n const clearHoverCursor = () => {\n paintedCursorRef.current?.()?.setOverride(null);\n if (cursorOverridden && canvas) {\n canvas.style.cursor = '';\n cursorOverridden = false;\n }\n };\n const applyHoverCursor = (spec: CursorSpec | null) => {\n const tier = spec === null ? null : resolveCursorTier(spec);\n if (!tier || !canvas) {\n clearHoverCursor();\n return;\n }\n // A painted cursor is two writes, not one: the native cursor gets out of\n // the way and the layer is told what to draw. Doing only the first is a\n // pointer with no cursor at all.\n const painted = tier.kind === 'painted' ? tier : null;\n paintedCursorRef.current?.()?.setOverride(painted);\n const cursor = tier.kind === 'css' ? tier.css : 'none';\n if (!cursor) {\n clearHoverCursor();\n return;\n }\n canvas.style.cursor = cursor;\n cursorOverridden = true;\n };\n /**\n * Where the painted-cursor layer should draw, in canvas-local CSS px.\n *\n * Pushed after the cursor has been resolved, not before: on the move that\n * first selects a painted cursor, a position written ahead of the decision\n * is discarded and the glyph does not appear until the next move. Guarded\n * on `active()`, so an ordinary CSS cursor costs no layout read per move.\n */\n function pushPaintedPointer(): void {\n const painted = paintedCursorRef.current?.();\n if (!painted?.active() || !canvas || !lastHover) return;\n const r = canvas.getBoundingClientRect();\n painted.setPointer(lastHover.clientX - r.left, lastHover.clientY - r.top);\n }\n\n function refreshHoverCursor(): void {\n resolveHoverCursor();\n pushPaintedPointer();\n }\n\n function resolveHoverCursor(): void {\n if (!canvas || !lastHover) return;\n // Mid-gesture the prediction is meaningless — what matters is what the\n // gesture IS. An in-flight action's `activeCursor` wins; with none\n // declared the override clears and the active tool's `Tool.cursor`\n // shows through, as before.\n if (held.size > 0 || dispatcherNow().inFlight().size > 0) {\n applyHoverCursor(dispatcherNow().inFlightCursor());\n return;\n }\n const h = lastHover;\n // Idle: re-resolve. Mid-gesture the branch above already returned, so a\n // pinned pointer is never unpinned by a hover refresh.\n routeAt(null, h.clientX, h.clientY);\n const w = toWorld(h.clientX, h.clientY);\n const affordance = target().affordanceAt?.(w) ?? undefined;\n if (affordance?.cursor) {\n applyHoverCursor(affordance.cursor);\n return;\n }\n const hoverBody = target().classifyTarget?.(w);\n const bodyTarget = hoverBody?.body;\n const bodyKind = hoverBody?.kind;\n const where = {\n altKey: h.altKey,\n ctrlKey: h.ctrlKey,\n metaKey: h.metaKey,\n shiftKey: h.shiftKey,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(bodyTarget !== undefined ? { bodyTarget } : {}),\n ...(bodyKind !== undefined ? { bodyKind } : {}),\n };\n const ctx = ctxNow();\n const press: InputEvent = {\n kind: 'pointerdown', x: w.x, y: w.y, clientX: h.clientX, clientY: h.clientY, ...where,\n };\n const d = dispatcherNow();\n publishLiveDispatch(() => d.explain(press, ctx));\n const dragCursor = d.resolveOnly(press, ctx)?.action.cursor;\n // A drag's hint first; failing that, what a click here would do.\n const cursor = dragCursor ?? dispatcherNow().resolveOnly(\n { kind: 'click', x: w.x, y: w.y, pressX: w.x, pressY: w.y, ...where },\n ctx,\n )?.action.cursor;\n applyHoverCursor(cursor ?? null);\n }\n /** Modifier/hotkey changes re-route the predicted drag without pointer\n * movement. Refresh after a tick so the key event's React state\n * (hotkey stack, active tool) has committed into `ctxRef`. */\n const scheduleHoverCursorRefresh = (e: KeyboardEvent) => {\n if (!lastHover) return;\n lastHover = {\n ...lastHover,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n setTimeout(() => {\n if (!disposed) refreshHoverCursor();\n }, 0);\n };\n // A held pointer's moves arrive through its session, which keeps seeing\n // them once the pointer has left the canvas or the canvas is gone. The\n // canvas listener is left with the hover half.\n const onHoverMove = (e: PointerEvent) => {\n if (held.has(e.pointerId)) return;\n onPointerMove(e);\n };\n\n const onHoverPointerLeave = () => {\n lastHover = null;\n publishLiveDispatch(null);\n paintedCursorRef.current?.()?.clearPointer();\n clearHoverCursor();\n };\n\n const onPointerUp = (e: PointerEvent) => {\n routeAt(e.pointerId, e.clientX, e.clientY);\n cancelLongPress(e.pointerId);\n const prevSize = held.size;\n // The record outlives the map entry: everything below is synthesized\n // from the press, and reads it after this pointer has stopped counting\n // towards `held.size`.\n const rec = held.get(e.pointerId);\n held.delete(e.pointerId);\n\n // A press still buffered never crossed the drag threshold — the\n // dispatcher never saw it, so no drag handle is in flight and this\n // release is a click. Crossing the threshold clears the buffer whether\n // or not a drag binding matched, which makes this the authoritative\n // \"did the pointer move?\" signal for click synthesis.\n const staysUnderThreshold = rec?.buffered != null;\n\n // When pointer count drops below 2, commit any in-flight multitouch handle\n // and (if the centroid never moved past the tap threshold) synthesize a\n // `multitouchtap` event carrying the peak fingers count.\n // The gestureId is keyed by the PREVIOUS size (before this pointer was removed)\n // because that was the handle's finger count when it was opened.\n if (prevSize >= 2 && held.size < 2) {\n const mtGestureId = `multitouch-${prevSize}`;\n if (dispatcherNow().inFlight().has(mtGestureId)) {\n // Synthesize a pointerup for the multitouch gesture — dispatcher needs\n // a pointerup to route to onEnd, but multitouch handles are keyed by\n // finger count, not by pointer. We use cancelAll to safely commit all\n // in-flight handles of this gesture; only the multitouch handle\n // should be active (see the multi-pointer policy in onPointerDown).\n // Use 'commit' because this is a natural lift (not a cancel).\n dispatcherNow().cancelAll('commit');\n }\n // Synthesize a tap if the centroid hasn't moved past threshold.\n const start = multiTouchStart;\n if (start) {\n // Final centroid uses the pointer positions BEFORE this pointer was\n // removed — it is already out of `held`, so add it back in.\n const centroid = toCanvasLocal(\n computeMultiTouchGeometry([\n ...[...held.values()].map((p) => p.pos),\n { x: e.clientX, y: e.clientY },\n ]).centroid,\n );\n const dx = centroid.x - start.centroid.x;\n const dy = centroid.y - start.centroid.y;\n if (Math.hypot(dx, dy) <= TAP_THRESHOLD_PX) {\n const tap: InputEvent = {\n kind: 'multitouchtap',\n fingers: start.fingers,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(tap);\n }\n multiTouchStart = null;\n }\n }\n\n // Check whether a drag handle is in-flight BEFORE sending pointerup.\n // If THIS pointer's handle is in-flight AND the pointer moved between\n // down and up, this is the end of a real drag — pump it and don't\n // synthesize a click. If no handle is in-flight, or the handle was\n // opened but the pointer never moved (sub-threshold \"tap\" that an\n // over-broad ambient drag binding accepted), we still synthesize a\n // click so click-specific bindings (e.g. clearSelection on empty) fire.\n const movedDuringDrag = rec\n ? (rec.down.clientX !== e.clientX || rec.down.clientY !== e.clientY)\n : true;\n const hadDragInFlight =\n dispatcherNow().inFlight().has(pointerGestureId(e.pointerId)) && movedDuringDrag;\n\n const wUp = toWorld(e.clientX, e.clientY);\n const ev: InputEvent = {\n kind: 'pointerup',\n pointerId: e.pointerId,\n x: wUp.x,\n y: wUp.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(ev);\n\n const down = rec?.down;\n\n // Synthesize a click when the pointer neither opened a drag handle nor\n // travelled past the drag threshold. Carry the `bodyTarget` from the\n // pointerdown so click specs with string-form targets ('empty',\n // 'selected-body') match.\n //\n // The threshold half of that test is load-bearing for any tool that\n // binds `click` but not `drag`: without it, dragging clear across the\n // canvas and releasing synthesized a click, because \"no drag handle\n // opened\" was the only condition. `ClickSpec` documents itself as\n // \"pointerdown + pointerup without movement past the threshold\" — this\n // is the code finally agreeing with it.\n if (!hadDragInFlight && staysUnderThreshold && down) {\n const wClick = toWorld(e.clientX, e.clientY);\n const clickEv: InputEvent = {\n kind: 'click',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n x: wClick.x,\n y: wClick.y,\n clientX: e.clientX,\n clientY: e.clientY,\n pressX: down.worldX,\n pressY: down.worldY,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n dispatch(clickEv);\n\n // Double-click synthesis: emit a `doubleclick` event AFTER the\n // second click when two clicks land within DOUBLE_CLICK_MAX_MS and\n // DOUBLE_CLICK_MAX_PX. Reset the tracker after a successful\n // doubleclick so a third click doesn't compose another one\n // (triple-click semantics are not modeled).\n const now = Date.now();\n const prev = lastClickRef.current;\n const dx = e.clientX - (prev?.clientX ?? 0);\n const dy = e.clientY - (prev?.clientY ?? 0);\n if (prev && now - prev.t < DOUBLE_CLICK_MAX_MS && Math.hypot(dx, dy) < DOUBLE_CLICK_MAX_PX) {\n const dblEv: InputEvent = {\n kind: 'doubleclick',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n x: wClick.x,\n y: wClick.y,\n clientX: e.clientX,\n clientY: e.clientY,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n // Notify observers first — see `onDoubleClick`'s doc for why this\n // is not modeled as a binding.\n onDoubleClickRef.current?.({ x: wClick.x, y: wClick.y });\n const handled = dispatch(dblEv) === 'handled';\n claimedDoubleClick = handled || onDoubleClickRef.current !== undefined;\n lastClickRef.current = null;\n } else {\n lastClickRef.current = { t: now, clientX: e.clientX, clientY: e.clientY };\n }\n }\n\n // Every synthesized event this release produces has been dispatched, so\n // the pointer's view can be unpinned.\n routeRelease(e.pointerId);\n\n // Re-resolve the hover cursor at the release point — deferred a tick\n // so any state the up/click actions changed (selection, active tool)\n // has committed before prediction reruns.\n lastHover = {\n clientX: e.clientX, clientY: e.clientY,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n setTimeout(() => {\n if (!disposed) refreshHoverCursor();\n }, 0);\n };\n\n // Every way a gesture ends without a release: the browser cancelling the\n // pointer, capture going away, a press proving the tracked one had already\n // ended. The session decides which of those happened; the dispatcher\n // treats them alike, and reads the press's own modifiers because a cancel\n // carries none of its own.\n const onPointerCancel = (pointerId: number) => {\n // On teardown every session is cancelled at once; `cancelAll` ends those\n // gestures, so re-entering dispatch here would end them twice.\n if (disposed) return;\n const rec = held.get(pointerId);\n if (!rec) return;\n held.delete(pointerId);\n routeAt(pointerId, rec.pos.x, rec.pos.y);\n cancelLongPress(pointerId);\n // Drop any pending multitouch-tap start state — a cancel means we should\n // not synthesize a tap on the subsequent up.\n multiTouchStart = null;\n const ev: InputEvent = {\n kind: 'pointercancel',\n pointerId,\n altKey: rec.down.altKey,\n ctrlKey: rec.down.ctrlKey,\n metaKey: rec.down.metaKey,\n shiftKey: rec.down.shiftKey,\n };\n dispatch(ev);\n routeRelease(pointerId);\n };\n\n // -----------------------------------------------------------------------\n // Canvas contextmenu listener (right-click)\n // -----------------------------------------------------------------------\n\n const onContextMenu = (e: MouseEvent) => {\n // Suppress native menu so tools/actions own the right-click UX.\n e.preventDefault();\n routeAt(null, e.clientX, e.clientY);\n const w = toWorld(e.clientX, e.clientY);\n // A secondary button never reaches `onPointerDown`, so unlike click and\n // long-press there is no press to replay the classification from.\n const affordance = target().affordanceAt?.(w) ?? undefined;\n const menuBody = target().classifyTarget?.(w);\n const ev: InputEvent = {\n kind: 'contextmenu',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(menuBody?.body !== undefined ? { bodyTarget: menuBody.body } : {}),\n ...(menuBody?.kind !== undefined ? { bodyKind: menuBody.kind } : {}),\n };\n dispatch(ev);\n };\n\n // -----------------------------------------------------------------------\n // External-content ingestion: OS drop on the canvas, paste on window.\n // Items are materialized DURING the event (DataTransfer is only live on\n // the event stack); dispatch happens when materialization resolves.\n // -----------------------------------------------------------------------\n\n // Attached to both dragover and dragenter: cancelling dragenter (WHATWG)\n // guarantees the element stays the active drop target and shows the copy\n // cursor on entry rather than waiting for the first dragover tick.\n const onDragOver = (e: DragEvent) => {\n if (!e.dataTransfer) return;\n // preventDefault is what makes the canvas a valid drop target.\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n canvas?.classList.add(DROPOVER_CLASS);\n };\n\n const onDragLeave = () => {\n canvas?.classList.remove(DROPOVER_CLASS);\n };\n\n // No stopPropagation: handled-ness is only known after the async\n // materialization microtask, so a conditional stop (wheel-style) is\n // impossible; an unconditional one would swallow drops the kit doesn't\n // dispatch. Callers that need exclusivity should gate on the action result.\n const onDrop = (e: DragEvent) => {\n canvas?.classList.remove(DROPOVER_CLASS);\n const dt = e.dataTransfer;\n if (!dt) return;\n e.preventDefault();\n routeAt(null, e.clientX, e.clientY);\n const dropOn = target().dispatcher;\n const w = toWorld(e.clientX, e.clientY);\n // Real modifiers forwarded (Option-drag is a copy-drag on macOS); the\n // kit ingest binding declares all modifiers optional, so they can't\n // block the default route — but a consumer binding may key on them.\n const base = {\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n void itemsFromDataTransfer(dt).then((items) => {\n if (disposed) return;\n if (items.length === 0) return;\n dispatch({\n kind: 'drop', items,\n x: w.x, y: w.y, clientX: e.clientX, clientY: e.clientY,\n ...base,\n }, dropOn);\n });\n };\n\n const onPaste = (e: ClipboardEvent) => {\n // Text-editing surfaces (inputs, the text-edit overlay) own their own\n // paste — never steal it for scene ingestion.\n if (isEditableTarget(e.target)) return;\n const cd = e.clipboardData;\n if (!cd) return;\n const items = itemsFromClipboardData(cd);\n if (items.length === 0) return;\n // Wheel's shape: dispatch first, suppress the default only when a\n // binding claimed it. Clipboard items materialize synchronously, so\n // unlike `onDrop` the result is known while `preventDefault` is still\n // honored — and a paste no binding wanted stays the page's to handle.\n const result = dispatch({\n kind: 'paste', items,\n // ClipboardEvent carries no modifier state.\n altKey: false, ctrlKey: false, metaKey: false, shiftKey: false,\n });\n if (result === 'handled') e.preventDefault();\n };\n\n // -----------------------------------------------------------------------\n // Attach\n // -----------------------------------------------------------------------\n\n const keyCapture = keyboard === 'first';\n if (keyboard) {\n window.addEventListener('keydown', onKeyDown, keyCapture);\n window.addEventListener('keyup', onKeyUp, keyCapture);\n }\n window.addEventListener('blur', onWindowBlur);\n // Hover-cursor refresh on modifier/hotkey changes — separate listeners\n // (not folded into onKeyDown/onKeyUp) so the pump also tracks modifiers\n // when `keyboard: false` disables gesture key dispatch.\n window.addEventListener('keydown', scheduleHoverCursorRefresh);\n window.addEventListener('keyup', scheduleHoverCursorRefresh);\n if (pointerChannel) {\n canvas?.addEventListener('pointerleave', onHoverPointerLeave);\n canvas?.addEventListener('pointerdown', onPointerDown);\n canvas?.addEventListener('pointermove', onHoverMove);\n canvas?.addEventListener('dblclick', onNativeDoubleClick);\n }\n if (wheelChannel) canvas?.addEventListener('wheel', onWheel, { passive: false, capture: true });\n if (pinchChannel) {\n canvas?.addEventListener('gesturestart', onGestureStart);\n canvas?.addEventListener('gesturechange', onGestureChange);\n canvas?.addEventListener('gestureend', onGestureEnd);\n }\n if (contextMenuChannel) canvas?.addEventListener('contextmenu', onContextMenu);\n if (ingestChannel) {\n canvas?.addEventListener('dragenter', onDragOver);\n canvas?.addEventListener('dragover', onDragOver);\n canvas?.addEventListener('dragleave', onDragLeave);\n canvas?.addEventListener('drop', onDrop);\n window.addEventListener('paste', onPaste);\n }\n\n // -----------------------------------------------------------------------\n // Cleanup\n // -----------------------------------------------------------------------\n\n return () => {\n if (keyboard) {\n window.removeEventListener('keydown', onKeyDown, keyCapture);\n window.removeEventListener('keyup', onKeyUp, keyCapture);\n }\n window.removeEventListener('blur', onWindowBlur);\n window.removeEventListener('keydown', scheduleHoverCursorRefresh);\n window.removeEventListener('keyup', scheduleHoverCursorRefresh);\n canvas?.removeEventListener('pointerleave', onHoverPointerLeave);\n canvas?.removeEventListener('wheel', onWheel, { capture: true });\n canvas?.removeEventListener('gesturestart', onGestureStart);\n canvas?.removeEventListener('gesturechange', onGestureChange);\n canvas?.removeEventListener('gestureend', onGestureEnd);\n canvas?.removeEventListener('pointerdown', onPointerDown);\n canvas?.removeEventListener('pointermove', onHoverMove);\n canvas?.removeEventListener('dblclick', onNativeDoubleClick);\n canvas?.removeEventListener('contextmenu', onContextMenu);\n canvas?.removeEventListener('dragenter', onDragOver);\n canvas?.removeEventListener('dragover', onDragOver);\n canvas?.removeEventListener('dragleave', onDragLeave);\n canvas?.removeEventListener('drop', onDrop);\n window.removeEventListener('paste', onPaste);\n // Detach is unconditional: a channel turned off mid-life must still\n // have whatever it attached while it was on taken back off.\n canvas?.classList.remove(DROPOVER_CLASS);\n clearHoverCursor();\n cancelAllLongPress();\n disposed = true;\n // `disposed` first: the sessions' cancels must not re-enter dispatch on\n // the way out, and `cancelAll` below is what ends the gestures.\n for (const p of held.values()) p.session.cancel();\n held.clear();\n for (const d of allDispatchers()) d.cancelAll('cancel');\n };\n }, [enabled, keyboard, canvasRef, pointerChannel, wheelChannel, pinchChannel, contextMenuChannel, ingestChannel,\n allDispatchers, ctxRef, longPressRef, onDoubleClickRef, paintedCursorRef, registryRef, requestRedrawRef, rootTargetRef, viewsRef]);\n}\n","/**\n * @experimental\n * The React half of the actions registry: the context, the tree node that\n * owns each id → descriptor stack, the providers that mount nodes, and the two\n * hooks. The store contract it implements is in `registry.ts`.\n */\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { Action } from './action';\nimport { useLatest } from '@weasel-js/react';\nimport {\n useOptionalDepRegistry,\n type DepRegistry,\n type DepName,\n} from './depRegistry';\nimport { buildDepsFromRequires } from './buildDeps';\nimport type { Dispatcher } from '../dispatcher/dispatcher';\nimport { validateActionId, validateActionDefaultBinding, type ActionsRegistry } from './registry';\nimport { pushOwner, ScopeNode } from './scopeNode';\n\n/** @internal Provided by `<ActionsProvider>`, `<InputScope>` and `<Yoke>`. */\nexport const ActionsContext = createContext<ActionsRegistry | null>(null);\n\n/** The deps an action is invoked with: its declared `requires` when it has\n * one, the legacy fixed bag otherwise. The fixed bag has no `applyOps`, so an\n * action that needs the consumer's history must declare it. */\nfunction depsFor(a: Action, r: DepRegistry | null): Record<string, unknown> {\n if (!r) return {};\n if (a.requires) return buildDepsFromRequires(a, r) as Record<string, unknown>;\n return {\n selection: r.get('selection' as DepName),\n scene: r.get('scene' as DepName),\n history: r.get('history' as DepName),\n view: r.get('view' as DepName),\n activeTool: r.get('activeTool' as DepName),\n booleansAdapter: r.get('booleansAdapter' as DepName),\n };\n}\n\n/**\n * One node of the actions tree: the actions registered at it, over its\n * parent's. Each id holds a stack of registrants, newest live, so a displaced\n * registrant is restored when the one above it leaves. Every read the registry\n * answers — `list`, `trigger`, `begin` — starts at the node's leaf.\n */\nexport class ActionsNode extends ScopeNode<ActionsNode> {\n private readonly actions = new Map<string, Action[]>();\n private readonly muted = new Map<string, number>();\n private readonly dispatchers: Dispatcher[] = [];\n private cache: { version: number; leaf: ActionsNode; list: readonly Action[] } | null = null;\n /** Called on `activate`, so a scope's dep and tool nodes move with it. */\n readonly onActivate: (() => void)[] = [];\n\n constructor(\n parent: ActionsNode | null,\n descends: boolean,\n private readonly contextDeps: () => DepRegistry | null,\n ) {\n super(parent, descends);\n NODES.set(this.registry, this);\n }\n\n private resolve(id: string): Action | undefined {\n for (const n of this.chain()) {\n if (n.muted.has(id)) return undefined;\n const a = n.actions.get(id)?.at(-1);\n if (a) return a;\n }\n return undefined;\n }\n\n private snapshot(): readonly Action[] {\n const leaf = this.start();\n const cached = this.cache;\n if (cached && cached.version === this.tree.version && cached.leaf === leaf) return cached.list;\n const ids = new Set<string>();\n for (const n of leaf.chain()) for (const id of n.actions.keys()) ids.add(id);\n const out: Action[] = [];\n for (const id of ids) {\n const a = leaf.resolve(id);\n if (a) out.push(a);\n }\n const list = Object.freeze(out);\n this.cache = { version: this.tree.version, leaf, list };\n return list;\n }\n\n private deps(): DepRegistry | null {\n for (const n of this.chain()) {\n const r = n.contextDeps();\n if (r) return r;\n }\n return null;\n }\n\n private dispatcher(): Dispatcher | null {\n for (const n of this.chain()) {\n const d = n.dispatchers.at(-1);\n if (d) return d;\n }\n return null;\n }\n\n override activate(): void {\n super.activate();\n for (const f of this.onActivate) f();\n }\n\n readonly registry: ActionsRegistry = {\n register: (action: Action) => {\n validateActionId(action.id);\n validateActionDefaultBinding(action);\n const stack = this.actions.get(action.id);\n if (stack) stack.push(action);\n else this.actions.set(action.id, [action]);\n this.changed();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const cur = this.actions.get(action.id);\n if (!cur) return;\n // Our own entry, wherever it now sits: a registrant that was already\n // displaced must take itself out without disturbing the one above it.\n const i = cur.lastIndexOf(action);\n if (i === -1) return;\n cur.splice(i, 1);\n if (cur.length === 0) this.actions.delete(action.id);\n this.changed();\n };\n },\n unregister: (id: string) => {\n if (this.actions.delete(id)) this.changed();\n },\n mute: (id: string) => {\n this.muted.set(id, (this.muted.get(id) ?? 0) + 1);\n this.changed();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const held = this.muted.get(id);\n if (held === undefined) return;\n if (held > 1) this.muted.set(id, held - 1);\n else this.muted.delete(id);\n this.changed();\n };\n },\n list: () => this.snapshot(),\n trigger: (id: string, params?: Record<string, unknown>) => {\n const leaf = this.start();\n const a = leaf.resolve(id);\n if (!a) return false;\n try {\n if (a.invoker && a.invoker.timing === 'immediate') {\n a.invoker.run(depsFor(a, leaf.deps()) as never, params);\n }\n } catch (err) {\n console.error(`weasel ActionsRegistry: action \"${id}\" threw`, err);\n }\n return true;\n },\n subscribe: (listener: () => void) => {\n this.tree.listeners.add(listener);\n return () => {\n this.tree.listeners.delete(listener);\n };\n },\n setDispatcher: (d: Dispatcher | null) => pushOwner(this.dispatchers, d),\n begin: (id: string, params?: Record<string, unknown>) => {\n const leaf = this.start();\n const a = leaf.resolve(id);\n const disp = leaf.dispatcher();\n if (!a || !disp) return null;\n return disp.beginUiOngoing(id, depsFor(a, leaf.deps()) as never, params);\n },\n activate: () => this.activate(),\n isActive: () => this.isActive(),\n };\n}\n\nconst NODES = new WeakMap<ActionsRegistry, ActionsNode>();\n\n/** The tree node behind `registry`, when it is one of ours. */\nexport function actionsNodeOf(registry: ActionsRegistry | null): ActionsNode | null {\n return registry ? (NODES.get(registry) ?? null) : null;\n}\n\n/**\n * @experimental\n * Mounts a root `ActionsRegistry` for its lifetime. Children call\n * `useActionsRegistry()` or `useAction()` to participate. Mounts no input\n * listener of its own — the gesture dispatcher owns input.\n */\nexport function ActionsProvider({ children }: { children: ReactNode }): ReactElement {\n // `trigger` consults the dep registry in scope, so actions can be fired\n // imperatively from ActionBar / palette callers.\n const depReg = useOptionalDepRegistry();\n const depRegRef = useLatest<DepRegistry | null>(depReg);\n const node = useMemo(() => new ActionsNode(null, true, () => depRegRef.current), [depRegRef]);\n return <ActionsContext.Provider value={node.registry}>{children}</ActionsContext.Provider>;\n}\n\n/**\n * `import.meta.env.DEV` read through a cast — core must not depend on a\n * bundler's ambient augmentation (`vite/client`) to compile. Mirrors the same\n * cast in SceneCanvas.tsx, dispatcher.ts and buildDeps.ts.\n */\nconst IS_DEV: boolean = (() => {\n try {\n return Boolean((import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV);\n } catch {\n return false;\n }\n})();\n\n/**\n * @experimental\n * Returns the `ActionsRegistry` in scope, or `null` when there is none.\n */\nexport function useActionsRegistry(): ActionsRegistry | null {\n return useContext(ActionsContext);\n}\n\n/**\n * @experimental\n * Register an `Action` for the lifetime of the calling component. No-op (with\n * a dev-only warning) when no `ActionsProvider` is in scope. Re-registers on\n * `action` reference change (consumers should memoize stable identities to\n * avoid churn).\n */\nexport function useAction(action: Action): void {\n const reg = useActionsRegistry();\n useEffect(() => {\n if (!reg) {\n if (IS_DEV) {\n console.warn(\n `useAction(\"${action.id}\"): no <ActionsProvider> is in scope, so the action was not registered and its bindings will never fire.`,\n );\n }\n return;\n }\n return reg.register(action);\n }, [reg, action]);\n}\n","/**\n * @experimental\n * Input scopes and yokes: the tiers between a root registry and a canvas.\n * Design: docs/proposals/2026-09-27-input-scopes.md.\n */\nimport { useContext, useEffect, useMemo, type ReactElement, type ReactNode } from 'react';\nimport { ActionsContext, ActionsNode, actionsNodeOf, useActionsRegistry } from './ActionsProvider';\nimport { DepNode, DepRegistryContext, depNodeOf, useOptionalDepRegistry } from './depRegistry';\nimport { ActiveToolNodeContext, ToolNode } from './activeToolContext';\n\n/**\n * @experimental\n * Canvases that share input on purpose: the active tool, the gesture in\n * flight, history and yoke-wide actions. Made once with `useYoke()` where the\n * sharing is decided, and passed to each canvas that joins it (`yoke={yoke}`)\n * and to `<Yoke value={yoke}>` around anything else that should reach it — a\n * toolbar, say. The members can sit anywhere in the tree: the handle, not the\n * tree, says who shares.\n */\nexport interface Yoke {\n /** @internal */\n readonly actions: ActionsNode;\n /** @internal */\n readonly deps: DepNode;\n /** @internal */\n readonly tools: ToolNode;\n}\n\n/** The three nodes of a tier, under `parent`'s or the ones in scope, with\n * activation carried across all three. */\nfunction useNodes(\n descends: boolean,\n ownsTool: boolean,\n parent: Yoke | undefined,\n): Yoke {\n const parentActions = useActionsRegistry();\n const parentDeps = useOptionalDepRegistry();\n const parentTools = useContext(ActiveToolNodeContext);\n const pa = parent ? parent.actions : actionsNodeOf(parentActions);\n const pd = parent ? parent.deps : depNodeOf(parentDeps);\n const pt = parent ? parent.tools : parentTools;\n const nodes = useMemo<Yoke>(() => {\n const deps = new DepNode(pd, descends);\n const tools = new ToolNode(pt, descends, ownsTool, null);\n const actions = new ActionsNode(pa, descends, () => deps.registry);\n actions.onActivate.push(() => deps.activate(), () => tools.activate());\n return { actions, deps, tools };\n }, [pa, pd, pt, descends, ownsTool]);\n useEffect(() => {\n const leave = [nodes.deps.mount(), nodes.tools.mount(), nodes.actions.mount()];\n return () => {\n for (const f of leave) f();\n };\n }, [nodes]);\n return nodes;\n}\n\nfunction Provide({ nodes, children }: { nodes: Yoke; children: ReactNode }): ReactElement {\n return (\n <DepRegistryContext.Provider value={nodes.deps.registry}>\n <ActionsContext.Provider value={nodes.actions.registry}>\n <ActiveToolNodeContext.Provider value={nodes.tools}>{children}</ActiveToolNodeContext.Provider>\n </ActionsContext.Provider>\n </DepRegistryContext.Provider>\n );\n}\n\n/** Props for `<InputScope>`. */\nexport interface InputScopeProps {\n /** The yoke this scope joins. Omitted, it sits under the registries in\n * scope and keeps a tool of its own. */\n yoke?: Yoke;\n children: ReactNode;\n}\n\n/**\n * @experimental\n * One canvas's input: actions, deps and a tool of its own, under whichever\n * registries are in scope (or its yoke's). What the canvas registers stays\n * here; what it looks up is answered here first, then by the tiers above.\n * With nothing in scope it is a root.\n *\n * Chrome above calls `trigger` / `begin` / `useActiveToolContext` on its own\n * registries, and those reach the active scope: the one last activated — by a\n * pointerdown or wheel — or the newest where none has been.\n */\nexport function InputScope({ yoke, children }: InputScopeProps): ReactElement {\n const nodes = useNodes(false, yoke === undefined, yoke);\n return <Provide nodes={nodes}>{children}</Provide>;\n}\n\n/**\n * @experimental\n * Make a yoke for canvases to join, under the registries in scope where it is\n * called. It lives as long as the calling component.\n */\nexport function useYoke(): Yoke {\n return useNodes(true, true, undefined);\n}\n\n/** Props for `<Yoke>`. */\nexport interface YokeProps {\n value: Yoke;\n children: ReactNode;\n}\n\n/**\n * @experimental\n * Put `value` in scope for what is not a canvas — a toolbar, a status bar — so\n * its actions, deps and tool reads reach the yoke and, through it, the member\n * canvas last used.\n */\nexport function Yoke({ value, children }: YokeProps): ReactElement {\n return <Provide nodes={value}>{children}</Provide>;\n}\n","import { useEffect, useMemo, useRef } from 'react';\nimport { useActionsRegistry } from './ActionsProvider';\nimport type { ActionsRegistry, UiOngoingControl } from './registry';\nimport { useLatest } from '@weasel-js/react';\n\n/**\n * One UI control's hold on an ongoing action — the handle a color picker, a\n * slider or a swatch drives the action through, the way a drag drives one\n * through a gesture.\n *\n * - `input(params)` opens the action on the first call and moves it on every\n * later one: the live preview.\n * - `commit(params?)` moves it to `params`, if given, and ends it as one\n * undoable edit. With nothing open, a commit carrying params is a whole edit\n * on its own — a click on a swatch, a switch of paint kind.\n * - `cancel()` ends an open edit without keeping it.\n *\n * All three are no-ops when no action is reachable, so a control renders the\n * same with or without a canvas in scope.\n */\nexport interface OngoingAction {\n input(params: Record<string, unknown>): void;\n commit(params?: Record<string, unknown>): void;\n cancel(): void;\n}\n\n/**\n * Drive the ongoing action `actionId` from a UI control: {@link OngoingAction}.\n *\n * An edit left open when the control unmounts, or when `actionId` changes, is\n * committed — it is what the user was looking at when the control went away.\n * The returned object is stable for the life of the component.\n */\nexport function useOngoingAction(actionId: string): OngoingAction {\n const reg = useActionsRegistry();\n const regRef = useLatest<ActionsRegistry | null>(reg);\n const idRef = useLatest(actionId);\n const ctrlRef = useRef<UiOngoingControl | null>(null);\n\n const edit = useMemo<OngoingAction>(() => {\n const end = (reason: 'commit' | 'cancel'): void => {\n const ctrl = ctrlRef.current;\n ctrlRef.current = null;\n ctrl?.end(reason);\n };\n return {\n input(params) {\n if (ctrlRef.current) ctrlRef.current.update(params);\n else ctrlRef.current = regRef.current?.begin(idRef.current, params) ?? null;\n },\n commit(params) {\n if (params !== undefined) {\n if (ctrlRef.current) ctrlRef.current.update(params);\n else ctrlRef.current = regRef.current?.begin(idRef.current, params) ?? null;\n }\n end('commit');\n },\n cancel() {\n end('cancel');\n },\n };\n }, [regRef, idRef]);\n\n useEffect(() => () => edit.commit(), [edit, actionId]);\n\n return edit;\n}\n","// src/contributions/useContributions.ts\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { activeModeOf, type ModeRegistry } from '@weasel-js/modes';\nimport type { ScopedBinding } from '../interactions/dispatcher/matcher';\nimport { useActiveToolContext } from '../interactions/actions/activeToolContext';\nimport { useActionsRegistry } from '../interactions/actions/ActionsProvider';\nimport {\n buildToolOffhandBindings,\n makeToolOffhandAction,\n offhandKeyFor,\n type ToolOffhandBindingSpec,\n} from '../interactions/actions/toolOffhand';\nimport { reportRouteConflicts } from '../tools/routing/reflection/conflicts';\nimport type { HotkeyTrigger } from './types';\nimport { scopeBindings } from './assemble';\nimport { liveScope } from './eligibility';\nimport type { Contribution, OverlayPosition } from './types';\nimport { isDev } from '../devFlag';\nimport { sameList, useStableByContent } from '@weasel-js/react';\nimport type { KernelOverlay } from '../index';\n\n/** Options for {@link useContributions}. */\nexport interface UseContributionsOptions<TOverlay = KernelOverlay> {\n /** Every registry entry, in declaration order. Order decides which of two\n * same-specificity bindings in one scope tier wins. */\n entries: readonly Contribution<TOverlay>[];\n /** Desired focused entry id, or `null` for none. First-mount-wins against\n * the shared `ActiveToolContext` — see `useTools` for the full semantics. */\n focused: string | null;\n /** The modes the canvas can be in. The dev-time route-conflict check reads\n * them to decide whether two gated actions can ever compete; without a\n * registry it checks against the kit's `DEFAULT_MODES`. */\n modes?: ModeRegistry;\n}\n\n/** The assembled registry {@link useContributions} returns. */\nexport interface ContributionsApi<TOverlay = KernelOverlay> {\n /** Every entry, as passed in. */\n entries: readonly Contribution<TOverlay>[];\n /** Currently focused entry id, or `null` when nothing is focused. */\n focused: string | null;\n /** Focus an entry, or pass `null` to focus none. Writes through to the\n * shared `ActiveToolContext`. */\n setFocused: (id: string | null) => void;\n /** Every live binding, tiered by the declaring entry's eligibility. */\n scopedBindings(): ScopedBinding[];\n /** Overlays of every live entry declaring `position`, ordered active, then\n * hotkey, then ambient. */\n overlays(position?: OverlayPosition): TOverlay[];\n}\n\n/**\n * Assembles one registry: every entry's bindings and overlays, each tiered by\n * what the entry declares about its own eligibility rather than by which\n * argument a consumer passed it in.\n *\n * Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /\n * `<SceneCanvas>`, which mount one internally): focus and held-key state live\n * in the context so the gesture dispatcher and every sibling caller read the\n * same source of truth.\n */\nexport function useContributions<TOverlay = KernelOverlay>(\n opts: UseContributionsOptions<TOverlay>,\n): ContributionsApi<TOverlay> {\n const ctx = useActiveToolContext();\n const actionsRegistry = useActionsRegistry();\n\n // First-mount sync: if the context's slot is still unseeded and the caller\n // wants a tool, push it. Captured at first render; the setState runs in a\n // post-commit effect so it never updates state during render.\n const firstMountRef = useRef<{ sync: boolean } | null>(null);\n const isFirstRender = firstMountRef.current == null;\n if (firstMountRef.current == null) firstMountRef.current = { sync: ctx.active === null && opts.focused !== null };\n useEffect(() => {\n const first = firstMountRef.current;\n if (!first?.sync) return;\n first.sync = false;\n ctx.setActive(opts.focused);\n // First-mount sync only — deliberately runs once after mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const focused = isFirstRender && ctx.active === null && opts.focused !== null\n ? opts.focused\n : ctx.active;\n\n // Consumers commonly rebuild the entry list every render; identity follows\n // its contents, so everything keyed on it below changes only when they do.\n const entries = useStableByContent(opts.entries, sameList);\n const engaged = ctx.hotkeyStack;\n\n const setFocused = useCallback((id: string | null) => { ctx.setActive(id); }, [ctx]);\n\n /** Live eligibility state, plus the entries ordered so that hotkey-engaged\n * ones come first — stack order breaks ties within the hotkey tier. */\n const snapshot = useCallback(() => {\n const engagedIds = new Set(engaged);\n const ordered: Contribution<TOverlay>[] = [];\n for (const id of engaged) {\n const entry = entries.find((e) => e.id === id);\n if (entry && !ordered.includes(entry)) ordered.push(entry);\n }\n for (const entry of entries) {\n if (!ordered.includes(entry)) ordered.push(entry);\n }\n return {\n ordered,\n state: { focusedId: focused, engagedIds },\n };\n }, [entries, focused, engaged]);\n\n const scopedBindings = useCallback((): ScopedBinding[] => {\n const { ordered, state } = snapshot();\n return scopeBindings(ordered, state);\n }, [snapshot]);\n\n const overlays = useCallback((position: OverlayPosition = 'top'): TOverlay[] => {\n const { ordered, state } = snapshot();\n const active: TOverlay[] = [];\n const hotkey: TOverlay[] = [];\n const ambient: TOverlay[] = [];\n for (const entry of ordered) {\n if (!entry.overlay) continue;\n if ((entry.overlayPosition ?? 'top') !== position) continue;\n const layers = Array.isArray(entry.overlay) ? entry.overlay : [entry.overlay];\n const scope = liveScope(entry.id, entry.eligibility ?? {}, state);\n if (scope === 'active') active.push(...layers);\n else if (scope === 'hotkey') hotkey.push(...layers);\n else if (scope === 'ambient') ambient.push(...layers);\n }\n return [...active, ...hotkey, ...ambient];\n }, [snapshot]);\n\n useOffhandAction(entries);\n\n // Route-conflict check. Two entries declaring the same (phase, gesture, arg,\n // target, modifiers) tuple in one scope are resolved by declaration order and\n // almost certainly not as either author intended. This is where the entry set\n // is assembled, so this is where it looks.\n //\n // Dev-only, and deduped on a signature of the entry set: the check walks\n // every binding of every entry, and consumers usually rebuild the entry list\n // each render. Actions are read inside the effect, after the registrations\n // that ran in child effects have landed.\n const lastConflictSigRef = useRef<{ sig: string; modes: ModeRegistry | undefined } | null>(null);\n const entrySig = entries.map((e) => e.id).join(',');\n const modesRegistry = opts.modes;\n useEffect(() => {\n if (!isDev()) return;\n const last = lastConflictSigRef.current;\n if (last?.sig === entrySig && last.modes === modesRegistry) return;\n lastConflictSigRef.current = { sig: entrySig, modes: modesRegistry };\n // An entry can be in both buckets and usually is: every tool `defineTool`\n // builds declares `focus: true`, and an ambient one carries `always: true`\n // on top of that. Sorting on \"not focus-eligible\" put ambient tools in the\n // registry bucket, which is never compared against itself — registry tools\n // take turns in the active slot — so ambient-vs-ambient went unreported.\n const registry: Contribution<TOverlay>[] = [];\n const ambient: Contribution<TOverlay>[] = [];\n for (const entry of entries) {\n if (entry.eligibility?.focus) registry.push(entry);\n if (entry.eligibility?.always || entry.eligibility?.claimed) ambient.push(entry);\n }\n reportRouteConflicts({\n registry,\n ambient,\n actions: actionsRegistry?.list() ?? [],\n ...(modesRegistry ? { modes: modesRegistry.list().map(activeModeOf) } : {}),\n });\n }, [entrySig, entries, actionsRegistry, modesRegistry]);\n\n // Memoized so consumers using the result as an effect dep don't see identity\n // churn every render — which loops infinitely when the consumer setStates\n // from inside such an effect.\n return useMemo(\n () => ({ entries, focused, setFocused, scopedBindings, overlays }),\n [entries, focused, setFocused, scopedBindings, overlays],\n );\n}\n\n/**\n * Registers the consolidated `tool.offhand` action for every entry declaring\n * an `offhand` trigger, into the nearest `<ActionsProvider>`; its invoker\n * reads `params.toolId` off the matched binding. `useContributions` calls it,\n * and so does any host that assembles its entries above its own provider —\n * `<SceneCanvas>` does — since a null registry here registers nothing.\n */\nexport function useOffhandAction(entries: readonly Contribution<unknown>[]): void {\n const actionsRegistry = useActionsRegistry();\n const offhandSig = JSON.stringify(entries\n .filter((e) => e.eligibility?.offhand)\n .map((e) => [e.id, e.eligibility.offhand]));\n useEffect(() => {\n const pairs = JSON.parse(offhandSig) as [string, HotkeyTrigger][];\n if (!actionsRegistry || pairs.length === 0) return;\n const specs: ToolOffhandBindingSpec[] = pairs.map(([toolId, trigger]) => (\n { toolId, key: offhandKeyFor(trigger) }\n ));\n return actionsRegistry.register(makeToolOffhandAction(buildToolOffhandBindings(specs)));\n }, [actionsRegistry, offhandSig]);\n}\n","// src/tools/useTools.ts\nimport { useCallback, useMemo } from 'react';\nimport type { ModeRegistry } from '@weasel-js/modes';\nimport { dlog } from '../dlog';\nimport type { AnyTool, AnyToolOf } from './types';\nimport type { HotkeyTrigger } from '../contributions/types';\nimport { useActiveToolContext } from '../interactions/actions/activeToolContext';\nimport { useContributions } from '../contributions/useContributions';\nimport type { Contribution, Eligibility, OverlayPosition } from '../contributions/types';\nimport type { KernelOverlay } from '../index';\nimport { sameList, useLatest, useStableByContent } from '@weasel-js/react';\n\n/** Options for `useTools`: which tools exist, which one starts active, and\n * which run continuously regardless of the active one. */\nexport interface UseToolsOptions<TOverlay = KernelOverlay> {\n /** Initial active-slot tool id, which must exist in `registry`. Omit, or\n * pass `null`, for no active tool: only hotkey and ambient bindings run. */\n active?: string | null;\n /** Tools eligible for the active slot or hotkey slot. The keys are the\n * tool ids; the values are the tool records. A tool with `hotkey` set\n * is wired into the hotkey slot whenever the engagement state matches. */\n registry: Record<string, AnyToolOf<TOverlay>>;\n /** Always-on entries — tools or other contributions, live regardless of\n * the active slot. */\n ambient?: readonly Contribution<TOverlay>[];\n /** The modes the canvas can be in, read by the dev-time route-conflict\n * check; without a registry it checks against the kit's `DEFAULT_MODES`. */\n modes?: ModeRegistry;\n}\n\n/** The tool registry's runtime surface: which tool is active, which is\n * temporarily held by a hotkey, and how to change either. */\nexport interface ToolsApi<TOverlay = KernelOverlay> {\n /** Current active-slot tool id, or `null` when no tool is active. */\n active: string | null;\n /** Set the active-slot tool, or `null` to clear it. The gesture dispatcher\n * watches the active tool and cancels any in-flight handle itself. */\n setActive: (id: string | null) => void;\n /** Currently hotkey-engaged tool id (or `null`). Derived as the top of\n * the hotkey stack for backwards compat with the pre-stack API. */\n hotkeyEngaged: string | null;\n /** Engage a hotkey-slot tool by id. */\n engageHotkey: (id: string) => void;\n /** Disengage the hotkey-slot tool, if any. */\n disengageHotkey: () => void;\n /** All always-on entries, in registration order. */\n ambient: readonly Contribution<TOverlay>[];\n /** Full registry — for userland UI (palette buttons, etc.). */\n registry: Readonly<Record<string, AnyToolOf<TOverlay>>>;\n /** Returns true if a tool with the given id is in the registry or ambient list. */\n has(id: string): boolean;\n /** All overlay layers from currently-engaged tools (active slot, hotkey\n * slot if engaged, all ambient slot tools) that declare `position`.\n * Filters out tools with no `overlay` field. Order: active, then hotkey\n * (if engaged), then ambient (registration order). */\n getActiveOverlays(position?: OverlayPosition): TOverlay[];\n}\n\n/** The slot a caller passed a tool in, restated as declared eligibility.\n * `ToolDef.hotkey` becomes `offhand` — it is the same declaration, read off\n * the authored form via the `def` reflection handle. A tool that already\n * declares what its slot implies is returned as-is: `ToolsApi.registry`\n * hands back the objects the caller passed, and consumers compare identity. */\nfunction declareSlot<T extends Contribution<unknown>>(tool: T, slot: 'focus' | 'always'): T {\n const hotkey = (tool.def as { hotkey?: HotkeyTrigger } | undefined)?.hotkey;\n const eligibility: Eligibility = {\n ...tool.eligibility,\n [slot]: true,\n ...(hotkey ? { offhand: hotkey } : {}),\n };\n return sameEligibility(tool.eligibility, eligibility) ? tool : { ...tool, eligibility };\n}\n\nconst NO_AMBIENT: readonly never[] = [];\n\n/** `registry` and `ambient` as last passed, kept by identity for as long as\n * every tool in them is the same object under the same id. */\nfunction useStableSources<T extends AnyTool, A extends Contribution<unknown>>(\n registry: Record<string, T>,\n ambient: readonly A[] | undefined,\n): { registry: Record<string, T>; ambient: readonly A[] } {\n return useStableByContent(\n { registry, ambient: ambient ?? NO_AMBIENT },\n (a, b) => sameRecord(a.registry, b.registry) && sameList(a.ambient, b.ambient),\n );\n}\n\nfunction sameRecord<T>(a: Record<string, T>, b: Record<string, T>): boolean {\n const ak = Object.keys(a);\n if (ak.length !== Object.keys(b).length) return false;\n return ak.every((k) => k in b && a[k] === b[k]);\n}\n\nfunction sameEligibility(a: Eligibility | undefined, b: Eligibility): boolean {\n if (!a) return false;\n const keys = new Set([...Object.keys(a), ...Object.keys(b)]) as Set<keyof Eligibility>;\n for (const key of keys) if (a[key] !== b[key]) return false;\n return true;\n}\n\n/**\n * Manages the active tool and hotkey slot.\n *\n * A thin shim over {@link useContributions}: the `registry` / `ambient`\n * arguments are restated as declared eligibility (`focus` / `always`), and\n * assembly happens in one place for tools and non-tool contributions alike.\n *\n * Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /\n * `<SceneCanvas>`, which mount one internally) in scope: active/hotkey state\n * lives in the context so the gesture dispatcher and any sibling\n * `useTools` calls all read the same source of truth.\n *\n * **First-mount-wins semantics**: if the context's slot is unseeded (no\n * `initialActive`, nothing set yet) on first mount, `useTools` pushes\n * `opts.active` to the context. Subsequent mounts respect whatever the\n * context currently holds (the first caller wins).\n */\nexport function useTools<TOverlay = KernelOverlay>(\n opts: UseToolsOptions<TOverlay>,\n): ToolsApi<TOverlay> {\n const initialActive = opts.active ?? null;\n if (initialActive !== null && !(initialActive in opts.registry)) {\n throw new Error(`useTools: active \"${initialActive}\" not in registry`);\n }\n\n const ctx = useActiveToolContext();\n\n // Rebuilt when the tools themselves change, not the objects holding them:\n // callers commonly pass `opts.registry` / `opts.ambient` as literals made\n // every render, while a tool redefined under an existing id must replace it.\n const sources = useStableSources(opts.registry, opts.ambient);\n const slotted = useMemo(() => {\n const registry: Record<string, AnyToolOf<TOverlay>> = {};\n for (const [id, tool] of Object.entries(sources.registry)) {\n registry[id] = declareSlot(tool, 'focus');\n }\n const ambient = sources.ambient.map((t) => declareSlot(t, 'always'));\n const byId = new Map<string, Contribution<TOverlay>>();\n for (const tool of [...Object.values(registry), ...ambient]) {\n const prior = byId.get(tool.id);\n if (prior) byId.set(tool.id, { ...tool, eligibility: { ...prior.eligibility, ...tool.eligibility } });\n else byId.set(tool.id, tool);\n }\n return { registry, ambient, entries: [...byId.values()] };\n }, [sources]);\n\n const contributions = useContributions<TOverlay>({\n entries: slotted.entries,\n focused: initialActive,\n ...(opts.modes ? { modes: opts.modes } : {}),\n });\n\n const hotkeyEngaged = ctx.hotkeyStack.at(-1) ?? null;\n\n // Refs so the memoized callbacks below see latest values without\n // re-creating themselves.\n const slottedRef = useLatest(slotted);\n const activeRef = useLatest(contributions.focused);\n const hotkeyRef = useLatest(hotkeyEngaged);\n\n const setFocused = contributions.setFocused;\n const setActive = useCallback(\n (id: string | null) => {\n if (id !== null && !(id in slottedRef.current.registry)) {\n throw new Error(`setActive: \"${id}\" not in registry`);\n }\n dlog('tools', 'active:', activeRef.current, '→', id);\n setFocused(id);\n },\n [setFocused, slottedRef, activeRef],\n );\n\n const engageHotkey = useCallback(\n (id: string) => {\n if (!(id in slottedRef.current.registry)) {\n throw new Error(`engageHotkey: \"${id}\" not in registry`);\n }\n dlog('tools', 'hotkey engaged:', id);\n ctx.pushHotkey(id);\n },\n [ctx, slottedRef],\n );\n\n const disengageHotkey = useCallback(() => {\n if (hotkeyRef.current) dlog('tools', 'hotkey disengaged:', hotkeyRef.current);\n ctx.popHotkey();\n }, [ctx, hotkeyRef]);\n\n // May be called while rendering, so it reads this render's tools, not a ref.\n const has = useCallback(\n (id: string): boolean =>\n id in slotted.registry\n || slotted.ambient.some((t) => t.id === id),\n [slotted],\n );\n\n // Memoize the returned ToolsApi so consumers using `tools` as a dep (e.g.\n // SceneCanvas's `onToolsCreated` useEffect) don't see identity churn on\n // every render — which otherwise loops infinitely when the consumer\n // setStates from inside `onToolsCreated`.\n const active = contributions.focused;\n const getActiveOverlays = contributions.overlays;\n return useMemo(\n () => ({\n active,\n setActive,\n hotkeyEngaged,\n engageHotkey,\n disengageHotkey,\n ambient: slotted.ambient,\n registry: slotted.registry,\n has,\n getActiveOverlays,\n }),\n [active, setActive, hotkeyEngaged, engageHotkey, disengageHotkey, has, getActiveOverlays, slotted],\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/interactions/actions/activeToolContext.tsx","../src/interactions/actions/depRegistry.tsx","../src/interactions/dispatcher/useGestureDispatcher.tsx","../src/interactions/actions/ActionsProvider.tsx","../src/interactions/actions/inputScope.tsx","../src/interactions/actions/useOngoingAction.ts","../src/contributions/useContributions.ts","../src/tools/useTools.ts"],"names":["createContext","useState","jsx","useContext","useLatest","useEffect","useMemo","useRef","useCallback","useStableByContent","sameList"],"mappings":"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","file":"react.js","sourcesContent":["/**\n * ActiveToolContext — runtime selection state for tools.\n *\n * Holds the currently active tool id and a hotkey stack (tools held active\n * temporarily, e.g. space-for-hand). Read by the gesture dispatcher to\n * determine which tool's bindings are in scope; written by tool-switching\n * actions (`tool.activate`) and offhand hotkey actions (`tool.offhand`),\n * both parametric on `params.toolId`.\n *\n * The state hangs on the same scope tree as the actions and dep registries:\n * every canvas's input scope owns a tool of its own unless it joins a yoke,\n * and a provider above reads and writes the tool of the scope last used.\n */\n\nimport {\n createContext,\n useContext,\n useMemo,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from 'react';\nimport { ScopeNode } from './scopeNode';\n\n/** Which tool is active, plus the stack of tools temporarily held active by a\n * hotkey (space-for-hand and the like). The dispatcher reads this to decide\n * whose bindings are in scope. */\nexport interface ActiveToolContextValue {\n /** The focused tool's id, or `null` when no tool holds the active slot —\n * a canvas can run on ambient bindings alone. */\n active: string | null;\n hotkeyStack: string[];\n setActive(id: string | null): void;\n pushHotkey(id: string): void;\n /**\n * Disengage a hotkey-held tool. With `id`, removes that tool's own entry\n * wherever it now sits — holds do not have to come up in the order they went\n * down, and popping the top would disengage a tool whose key is still held.\n * With no id, pops the top.\n */\n popHotkey(id?: string): void;\n}\n\ninterface ToolState {\n active: string | null;\n hotkeyStack: string[];\n}\n\n/**\n * One node of the tool tree. A node that `owns` a tool holds its state; one\n * that does not — a scope inside a yoke — reads and writes its yoke's.\n */\nexport class ToolNode extends ScopeNode<ToolNode> {\n private state: ToolState | null;\n private value: { from: ToolNode; state: ToolState; out: ActiveToolContextValue } | null = null;\n\n constructor(parent: ToolNode | null, descends: boolean, owns: boolean, initialActive: string | null) {\n super(parent, descends);\n // A new scope starts on the tool in effect around it, so a tool a\n // consumer seeded above a canvas before it mounted is not lost.\n this.state = owns\n ? { active: initialActive ?? parent?.owner().state?.active ?? null, hotkeyStack: [] }\n : null;\n }\n\n /** The node whose tool a read here resolves to. */\n owner(): ToolNode {\n for (const n of this.start().chain()) if (n.state) return n;\n return this;\n }\n\n private update(next: (s: ToolState) => ToolState): void {\n const owner = this.owner();\n if (!owner.state) return;\n const updated = next(owner.state);\n if (updated === owner.state) return;\n owner.state = updated;\n owner.changed();\n }\n\n /** A stable value per owner and state, for `useSyncExternalStore`. */\n snapshot(): ActiveToolContextValue {\n const from = this.owner();\n const state = from.state ?? { active: null, hotkeyStack: [] };\n const cached = this.value;\n if (cached && cached.from === from && cached.state === state) return cached.out;\n const out: ActiveToolContextValue = {\n active: state.active,\n hotkeyStack: state.hotkeyStack,\n setActive: (id) => this.update((s) => (s.active === id ? s : { ...s, active: id })),\n pushHotkey: (id) => this.update((s) => ({ ...s, hotkeyStack: [...s.hotkeyStack, id] })),\n popHotkey: (id) =>\n this.update((s) => {\n const stack = s.hotkeyStack;\n if (stack.length === 0) return s;\n if (id === undefined) return { ...s, hotkeyStack: stack.slice(0, -1) };\n const i = stack.lastIndexOf(id);\n return i === -1 ? s : { ...s, hotkeyStack: [...stack.slice(0, i), ...stack.slice(i + 1)] };\n }),\n };\n this.value = { from, state, out };\n return out;\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.tree.listeners.add(listener);\n return () => {\n this.tree.listeners.delete(listener);\n };\n };\n}\n\nconst ActiveToolContext = createContext<ToolNode | null>(null);\n\n/** @internal The context `<InputScope>` and `<Yoke>` provide a tool node through. */\nexport const ActiveToolNodeContext = ActiveToolContext;\n\n/** Props for `<ActiveToolContextProvider>`. */\nexport interface ActiveToolContextProviderProps {\n children: ReactNode;\n /** Seeds the active slot, and wins over the first `useTools` call's\n * `active`. Omitted, the slot starts empty and that call seeds it. */\n initialActive?: string | null;\n}\n\n/** Provides root active-tool state. Every canvas below has a tool of its own;\n * reads and writes here reach the one last used. */\nexport function ActiveToolContextProvider({\n children,\n initialActive = null,\n}: ActiveToolContextProviderProps) {\n const [node] = useState(() => new ToolNode(null, true, true, initialActive));\n return <ActiveToolContext.Provider value={node}>{children}</ActiveToolContext.Provider>;\n}\n\nfunction useNodeValue(node: ToolNode | null): ActiveToolContextValue | null {\n const subscribe = useMemo(() => node?.subscribe ?? NO_SUBSCRIBE, [node]);\n return useSyncExternalStore(\n subscribe,\n () => node?.snapshot() ?? null,\n () => node?.snapshot() ?? null,\n );\n}\n\nconst NO_SUBSCRIBE = (): (() => void) => () => {};\n\n/** The active-tool state in scope. Throws outside a provider; use\n * `useOptionalActiveToolContext` where one is not guaranteed. */\nexport function useActiveToolContext(): ActiveToolContextValue {\n const value = useNodeValue(useContext(ActiveToolContext));\n if (value === null) {\n throw new Error(\n 'useActiveToolContext: no ActiveToolContextProvider in scope. Wrap your tree with <ActiveToolContextProvider> (typically inside <SceneCanvas>).',\n );\n }\n return value;\n}\n\n/**\n * Like `useActiveToolContext`, but returns `null` when no\n * `<ActiveToolContextProvider>` is in scope instead of throwing. Used by\n * `useStandardActions` to preserve its silent-no-op contract when no provider\n * is present.\n */\nexport function useOptionalActiveToolContext(): ActiveToolContextValue | null {\n return useNodeValue(useContext(ActiveToolContext));\n}\n\n/**\n * Conditional `<ActiveToolContextProvider>` wrapper. Mounts a provider only\n * when no parent provider is in scope — otherwise renders children unwrapped\n * so `<WeaselProvider>` defers to the host's existing scope.\n */\nexport function ActiveToolContextProviderIfRoot({\n children,\n}: {\n children: ReactNode;\n}) {\n const parent = useContext(ActiveToolContext);\n if (parent !== null) return <>{children}</>;\n return <ActiveToolContextProvider>{children}</ActiveToolContextProvider>;\n}\n","/** The React seam over the dep registry in `./depNode`: its provider and hooks. */\nimport {\n createContext, useContext, useEffect, useState,\n type ReactNode,\n} from 'react';\nimport type { DepSchema, DepName } from '../../index';\nimport { createDepRegistry, type DepRegistry } from './depNode';\nimport { useLatest } from '@weasel-js/react';\n\nexport type { DepSchema, DepName, DepRegistry };\nexport { DepNode, depNodeOf, createDepRegistry } from './depNode';\n\n/** @internal The context `<InputScope>` provides a scope's dep registry through. */\nexport const DepRegistryContext = createContext<DepRegistry | null>(null);\n\n/** Provides the dep registry for a canvas. `<SceneCanvas>` mounts one; a\n * consumer registering its own dep sources must be inside it. */\nexport function DepRegistryProvider({ children }: { children: ReactNode }) {\n const [registry] = useState(createDepRegistry);\n return <DepRegistryContext.Provider value={registry}>{children}</DepRegistryContext.Provider>;\n}\n\n/** The dep registry in scope. Throws outside a `<DepRegistryProvider>`. */\nexport function useDepRegistry(): DepRegistry {\n const r = useContext(DepRegistryContext);\n if (r === null) {\n throw new Error('useDepRegistry: no DepRegistryProvider in scope. Wrap your tree with <DepRegistryProvider> (typically inside <SceneCanvas>).');\n }\n return r;\n}\n\n/**\n * Like `useDepRegistry`, but returns `null` when no `<DepRegistryProvider>` is\n * in scope instead of throwing. Used by `useStandardActions` to preserve its\n * silent-no-op contract when neither provider is present.\n */\nexport function useOptionalDepRegistry(): DepRegistry | null {\n return useContext(DepRegistryContext);\n}\n\n/** Register a live source for `name` for the lifetime of the calling\n * component. The `source` thunk is called at dispatch time and should\n * return the latest value. */\nexport function useDepSource<K extends DepName>(name: K, source: () => DepSchema[K]) {\n const registry = useDepRegistry();\n const sourceRef = useLatest(source);\n useEffect(() => {\n return registry.register(name, () => sourceRef.current());\n }, [name, registry, sourceRef]);\n}\n","/**\n * useGestureDispatcher — React seam mounting the gesture dispatcher.\n *\n * Composes the input channels (window keydown/keyup, canvas wheel, WebKit\n * gesture events, canvas pointer events, multi-touch synthesized from\n * PointerEvents) and routes each\n * event to the dispatcher for the view it landed in — one view unless `views`\n * says otherwise. Reads ActiveToolContext + DepRegistry internally; consumer\n * passes the canvas ref, actions registry, and tools map.\n *\n * Side-effect only (returns void).\n *\n * See `docs/superpowers/specs/2026-05-16-registry-unification-design.md` § Q4.\n */\nimport { useCallback, useEffect, useRef } from 'react';\nimport type { RefObject } from 'react';\nimport { isEditableTarget } from '../keyHelpers';\nimport { useLatest } from '@weasel-js/react';\nimport { useActiveToolContext } from '../actions/activeToolContext';\nimport { useDepRegistry, type DepRegistry } from '../actions/depRegistry';\nimport type { DepName, DepSchema } from '../../index';\nimport type { ActionsRegistry } from '../actions/registry';\nimport type { AffordanceHit } from '../actions/invoker';\nimport { isTool } from '../../tools/types';\nimport type { Contribution } from '../../contributions/types';\nimport {\n createDispatcher, pointerGestureId, publishLiveDispatch, type Dispatcher, type DispatcherContext,\n} from './dispatcher';\nimport { isInControlWithin, pastDragThreshold } from '@weasel-js/gestures';\nimport { openPointerSession, type PointerSession } from '../pointerSession';\nimport { clientToCanvasRect } from '../../viewport/clientToCanvas';\nimport { itemsFromDataTransfer, itemsFromClipboardData } from '../../ingestion/ingestItems';\nimport type { InputEvent } from './matcher';\nimport { LONG_PRESS_MS, type LongPressOptions } from './longPressState';\nimport type { BodyTarget, BodyClassification } from '@weasel-js/gestures';\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport type { PaintedCursorState } from '@weasel-js/cursor';\nimport { resolveCursorTier } from '@weasel-js/cursor';\n\n// ---------------------------------------------------------------------------\n// Drop-over styling — class toggled on the canvas while an OS drag hovers it;\n// consumers style it. Not exported: the string is an observable public value\n// but the symbol is internal.\n// ---------------------------------------------------------------------------\n\n/** Class toggled on the canvas while an OS drag hovers it — consumers style it. */\nconst DROPOVER_CLASS = 'weasel-dropover';\n\n/**\n * Lift the stylus fields off a DOM `PointerEvent` onto the normalized\n * `InputEvent`. Kept as a spread-able partial so a synthetic event that\n * carries none of them stays free of `undefined`-valued keys.\n *\n * These ride the drag trail (`InvocationCtx.drag.points`) so pressure- and\n * tilt-aware actions — `insertAction`'s pencil kind today — can reach the\n * per-sample data without their own pointer plumbing.\n */\nfunction stylusOf(e: PointerEvent): {\n pressure?: number; tiltX?: number; tiltY?: number;\n} {\n return {\n ...(typeof e.pressure === 'number' ? { pressure: e.pressure } : {}),\n ...(typeof e.tiltX === 'number' ? { tiltX: e.tiltX } : {}),\n ...(typeof e.tiltY === 'number' ? { tiltY: e.tiltY } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Platform detection — module-level constant so it's stable across renders.\n// ---------------------------------------------------------------------------\n\nconst IS_MAC =\n typeof navigator !== 'undefined' &&\n /mac/i.test(\n // `||`, not `??`: jsdom (and some embedders) report an empty-string\n // platform, which is not nullish and would swallow the UA fallback.\n (navigator as { platform?: string }).platform || navigator.userAgent,\n );\n\n// ---------------------------------------------------------------------------\n// API\n// ---------------------------------------------------------------------------\n\n/**\n * Everything about handling an input event that depends on *which view* it\n * landed in: the dispatcher that runs it, and the three lookups that resolve\n * a client point against that view's camera.\n *\n * @internal One per view. The hook builds the `id: null` one from its flat\n * options; `views` supplies the rest, and the hook chooses between them per\n * event, so that it — and its listener set — still mounts exactly once.\n */\nexport interface DispatcherViewTarget {\n /** `null` is the root view — the whole canvas. Matches `ViewTarget.id`. */\n id: string | null;\n dispatcher: Dispatcher;\n affordanceAt: UseGestureDispatcherOptions['affordanceAt'];\n classifyTarget: UseGestureDispatcherOptions['classifyTarget'];\n clientToWorld: UseGestureDispatcherOptions['clientToWorld'];\n /**\n * The deps this view answers for itself — its camera, its selection, and\n * whatever else is per-view rather than per-canvas. Read per event; every\n * name it does not carry still resolves through the canvas registry.\n *\n * This is why a view does not get a `DepRegistryProvider` of its own. The\n * registry is where a consumer registers *sources*, and one per view would\n * fragment that: a consumer overriding `insert` would have to know how many\n * views exist and override each. An overlay keeps one place to register and\n * one authority per dep, with the view claiming only what is genuinely its.\n *\n * Without this a gesture inside a panel pans the whole canvas and selects\n * into the canvas's selection — correct coordinates alone do not make\n * routing correct.\n */\n deps?: () => Partial<DepSchema>;\n /**\n * This view's chrome-caps rule context, for the eligibility filter. The rule\n * table is the surface's, but a rule keyed on selection or the in-flight\n * action answers per view — so an action hidden in one panel must not\n * decline a gesture in another. `undefined` means \"nothing gates here\", the\n * same answer a surface with no mode registry gives.\n */\n getRuleCtx?: () => import('../../eligibility').RuleCtx | undefined;\n}\n\n/**\n * `base` with the routed view's own deps in front of it. Both sides are read\n * through thunks, so the result is stable for the life of a listener set while\n * still answering for whichever view the current event landed in.\n */\nfunction withViewDeps(\n base: () => DepRegistry,\n overlay: () => Partial<DepSchema> | undefined,\n): DepRegistry {\n return {\n register: (name, source) => base().register(name, source),\n get: <K extends DepName>(name: K): DepSchema[K] | undefined => {\n const own = overlay()?.[name];\n if (own !== undefined) return own as DepSchema[K];\n return base().get(name);\n },\n };\n}\n\n/**\n * The part of `features/viewports`' `ViewResolver` the dispatcher needs: which\n * view a client point belongs to, pinned to the view a gesture began in.\n *\n * @internal Structural on purpose — a `ViewResolver` satisfies it, and the\n * dispatcher stays free of the viewport module.\n */\nexport interface ViewIdResolver {\n begin(pointerId: number, clientX: number, clientY: number): { id: string | null };\n at(pointerId: number | null, clientX: number, clientY: number): { id: string | null };\n end(pointerId: number): void;\n}\n\n/** Per-channel switches for the listeners `useGestureDispatcher` attaches to\n * the canvas element. Omitted or `true` attaches the channel. */\nexport interface DispatcherChannels {\n /** `pointerdown`, hover `pointermove`, `pointerleave` — press, drag, click,\n * long-press, multi-touch and the hover-cursor pump. */\n pointer?: boolean;\n /** `wheel`. */\n wheel?: boolean;\n /** WebKit's `gesturestart` / `gesturechange` / `gestureend` — Safari's\n * trackpad pinch, dispatched as `pinch` events. */\n pinch?: boolean;\n /** `contextmenu`. Off leaves the browser's native menu in place. */\n contextMenu?: boolean;\n /** OS drop on the element plus `paste` on the window. Off leaves the\n * element a non-drop-target and stops `weasel-dropover` being applied. */\n ingest?: boolean;\n}\n\n/** Options for `useGestureDispatcher`: the element to listen on, the actions\n * and tools in play, and the hooks that turn raw DOM events into the world\n * coordinates and hit targets bindings match against. */\nexport interface UseGestureDispatcherOptions {\n /** Ref to the canvas element. Pointer/wheel/multitouch listeners attach here. */\n canvasRef: RefObject<HTMLElement | null>;\n /** Action registry (ActionsRegistry from registry.tsx). */\n actions: ActionsRegistry;\n /** Tool definitions keyed by id. Typically passes an empty Map. */\n entriesById: ReadonlyMap<string, Contribution<unknown>>;\n /** Default true. Set false to opt out of dispatcher wiring (e.g. demos that disable it). */\n enabled?: boolean;\n /**\n * Observer fired whenever the dispatcher synthesizes a double click, in\n * world coordinates. Runs BEFORE the event is dispatched and independently\n * of which binding (if any) handles it.\n *\n * This is deliberately not an Action. `<SceneCanvas onDoubleClick>` is a\n * notification — \"the user double-clicked, here's what they hit\" — and a\n * notification must not compete with behavior for the gesture. As a binding\n * it would lose to `enterPathEdit` on any body hit and silently never fire.\n * Routing it here keeps a single definition of \"double click\" (the point of\n * consolidating the kit's three detectors) without giving it\n * first-match-wins semantics it shouldn't have.\n */\n onDoubleClick?: (world: { x: number; y: number }) => void;\n /**\n * Observer fired on every synthesized click, in world coordinates — an\n * observer for the same reason as `onDoubleClick`. Unlike it, this runs\n * AFTER the click is dispatched, so whatever the click's binding changed\n * (a pick, say) is already readable.\n */\n onClick?: (world: { x: number; y: number }) => void;\n /**\n * Default true. Set false to leave the window `keydown`/`keyup` listeners\n * unattached so keyboard-bound actions never dispatch — pointer, wheel, and\n * contextmenu channels stay live. `<SceneCanvas>` wires this to\n * `enableKeybindings`, so opting out of keybindings disables the modern\n * dispatcher key path as well as the legacy `useKeybindings` hook.\n *\n * Every dispatcher hears keys on `window`, and a keystroke one of them\n * claims — or anything else calls `preventDefault` on — is not dispatched by\n * the rest. `'first'` listens in the capture phase, so this dispatcher gets\n * the keystroke ahead of every dispatcher listening normally, whatever the\n * mount order: the shape for chrome that owns a key only when it can act.\n */\n keyboard?: boolean | 'first';\n /**\n * Optional affordance classifier. Called with the **world** coordinates of\n * the pointer — this hook applies the routed view's `clientToWorld` before\n * calling it, the same conversion that produces `InputEvent.x`/`y`, so a\n * consumer hit-tests in one space. Returns an `AffordanceHit` when the\n * pointer lands on a known affordance (resize handle, rotate handle, etc.)\n * or `null` when the pointer hit open canvas.\n *\n * The hit is packed into `InputEvent.pointerdown.affordance` and flows\n * through into `InvocationCtx.drag.affordance`. Action invokers that require\n * a specific affordance (e.g. `resizeAction` requires `handle:*`) use this\n * field as a guard in their `start` body.\n *\n * When omitted, `affordance` is always `undefined` — meaning only consumers\n * that explicitly wire a classifier get affordance-gated behavior.\n * `<SceneCanvas>` wires the full chrome→dispatcher bridge.\n */\n affordanceAt?: (worldPoint: { x: number; y: number }) => AffordanceHit | null;\n\n /**\n * Optional body classifier. Called on every pointerdown with the world-space\n * coordinates of the pointer. Its result is packed onto the event as\n * `bodyTarget` + `bodyKind`, which `matchTarget` reads to resolve the\n * string-form `TargetSpec` values in `Tool.bindings`.\n *\n * `body` is `'empty'` when nothing is under the pointer, `'selected-body'`\n * when the topmost hit belongs to the current selection, or\n * `'unselected-body'` when it belongs to a node that isn't selected. `kind`\n * is the hit node's semantic kind, when the scene can name it.\n *\n * When omitted, every body-derived target form (`'empty'`,\n * `'selected-body'`, `'unselected-body'`, `kind:<k>`, `kind:<k>:selected`)\n * never matches — bindings using those specs are silently skipped.\n * `<SceneCanvas>` wires this.\n *\n * World coordinates, on every path, for the same reason as `affordanceAt`.\n */\n classifyTarget?: (worldPoint: { x: number; y: number }) => BodyClassification;\n\n /**\n * Optional pre-created `Dispatcher`. When provided, this hook pumps events\n * into the supplied instance instead of creating its own. Lets a parent\n * scope (e.g. `<SceneCanvas>`) share one dispatcher between the gesture\n * mounter and other consumers (the preview-ghost layer).\n */\n dispatcher?: Dispatcher;\n\n /**\n * Converts a client-space pointer position (e.g. `e.clientX`, `e.clientY`)\n * to world-space coordinates. When supplied, every pointer/wheel event's\n * `x`/`y` is converted before the dispatcher builds `InvocationCtx.world`.\n *\n * Without this, `ctx.world` is populated with the raw client coords, which\n * silently breaks any action whose overlay/output uses absolute world\n * positions (marquee, lasso polyline, world-space affordances). Actions\n * that only read `drag.delta` are unaffected because client→world deltas\n * are equal at scale 1, but as soon as a consumer pans/zooms the view the\n * deltas diverge too.\n *\n * `<SceneCanvas>` always wires this via its canvas rect + current view.\n * Tests / harnesses without a view can omit it and continue passing raw\n * coordinates as before.\n */\n clientToWorld?: (clientX: number, clientY: number) => { x: number; y: number };\n\n /**\n * Invoked once per pump event (`pointermove`, `pointerup`, `pointercancel`,\n * `key-held` up-phase, `multitouch` move) when a dispatcher-side handle is\n * in flight. Lets the host canvas schedule a redraw so dispatcher-only\n * overlays (marquee, lasso, preview-ghost) repaint on each frame.\n *\n * Required because dispatcher actions don't go through the legacy\n * `tools.dispatcher.onGestureChange` redraw bump that ambient tool drags\n * relied on. Without it, the overlay layer's `draw` never runs between\n * pointerdown and pointerup, and the chrome flashes once at gesture start\n * and then sits frozen until the gesture ends.\n *\n * `<SceneCanvas>` wires this to the canvas's `requestRedraw`. Test\n * harnesses can omit it; their dispatchers won't paint between events but\n * that's already the test contract.\n */\n requestRedraw?: () => void;\n /**\n * The surface's painted-cursor channel, read live because the canvas handle\n * it lives on arrives a render after this hook runs.\n *\n * Given one, a cursor the CSS tier cannot express — sized in world units, or\n * past the size the browser drops the image at — is published here and drawn\n * by the painted-cursor layer instead. Without one, such a cursor resolves to\n * `none` and the pointer shows nothing.\n */\n paintedCursor?: () => PaintedCursorState | undefined;\n\n /** How touch and pen long-presses are timed, published and felt. */\n longPress?: LongPressOptions;\n\n /**\n * Thunk returning the live `RuleCtx` for the current frame. When supplied,\n * the dispatcher filters matched candidates by their declared\n * `Action.eligible` rule (omitted => always eligible). `<SceneCanvas>`\n * wires this; tests / harnesses without chrome-caps state can omit it.\n */\n getRuleCtx?: () => import('../../eligibility').RuleCtx | undefined;\n\n /**\n * Which of the canvas element's input channels to attach. Every one\n * defaults to `true`; naming a channel `false` leaves its listeners\n * unattached, so the element behaves as if the dispatcher were not there.\n *\n * A mount that binds two gestures should not also have to take the rest of\n * the pipeline's side effects: `contextMenu` suppresses the native menu\n * unconditionally, and `ingest` makes the element a valid drop target and\n * styles it while an OS drag hovers. `@weasel-js/labkit`'s loupe mounts on\n * a lab's own canvas host for a wheel and a held key, and turning the other\n * three off is what keeps right-click and file drops working there.\n *\n * The window keyboard channel is `keyboard` instead of an entry here,\n * because `<SceneCanvas enableKeybindings>` drives it.\n */\n channels?: DispatcherChannels;\n\n /**\n * Routing for a canvas hosting more than one view: the non-root dispatch\n * records to choose between, read fresh per event, and the resolver that\n * chooses. Omit for a single view — then every event runs on the record the\n * flat options above describe, which is what they are: view zero.\n *\n * A resolved id with no live record falls back to the root, so a view that\n * unmounts mid-gesture degrades instead of dropping the event.\n *\n * Keyboard and paste have no coordinates to resolve; they run on the view\n * the last coordinate-bearing event resolved to.\n *\n * @internal\n */\n views?: {\n targets: () => readonly DispatcherViewTarget[];\n resolver: ViewIdResolver;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** A pointer held on the canvas, and everything a press is synthesized from. */\ninterface HeldPointer {\n session: PointerSession;\n /** Latest screen position, for the multitouch centroid and spread. */\n pos: { x: number; y: number };\n /** The press, withheld from the dispatcher until movement crosses\n * `DRAG_THRESHOLD_PX`. Null once forwarded, or once multitouch claimed\n * the pointer — see the multi-pointer policy in `onPointerDown`. */\n buffered: { ev: InputEvent; clientX: number; clientY: number } | null;\n /** Press-time state replayed onto a synthesized click, long-press or\n * contextmenu, whose matchers resolve targets against it. */\n down: {\n target: unknown;\n clientX: number;\n clientY: number;\n /** World-space press point, forwarded onto the synthesized click as\n * `pressX`/`pressY` — see `ClickEvent`. */\n worldX: number;\n worldY: number;\n affordance?: unknown;\n bodyTarget?: BodyTarget;\n bodyKind?: string;\n altKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n };\n}\n\n/**\n * Compute centroid and spread (distance between first two pointers) from\n * the active pointer positions. Returns a centroid of (0, 0) and spread\n * of 0 when fewer than 2 pointers are present.\n */\nfunction computeMultiTouchGeometry(\n positions: Iterable<{ x: number; y: number }>,\n): { centroid: { x: number; y: number }; spread: number } {\n const pts = [...positions];\n if (pts.length < 2) {\n return { centroid: { x: 0, y: 0 }, spread: 0 };\n }\n // Centroid across all active pointers.\n let sumX = 0;\n let sumY = 0;\n for (const p of pts) {\n sumX += p.x;\n sumY += p.y;\n }\n const centroid = { x: sumX / pts.length, y: sumY / pts.length };\n // Spread = distance between the first two pointers (primary pair).\n const dx = pts[1].x - pts[0].x;\n const dy = pts[1].y - pts[0].y;\n const spread = Math.sqrt(dx * dx + dy * dy);\n return { centroid, spread };\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\n/**\n * Attach the input pipeline to a canvas: DOM pointer, wheel, keyboard and\n * multitouch listeners in, normalized input events out, routed through the\n * dispatcher to whichever action a binding names.\n *\n * Everything it needs beyond its options — the active tool, the dep registry —\n * comes from context, so it must be mounted inside `<SceneCanvas>`'s\n * providers.\n */\nexport function useGestureDispatcher(opts: UseGestureDispatcherOptions): void {\n const { canvasRef, actions, entriesById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld, requestRedraw, paintedCursor, getRuleCtx, onClick, onDoubleClick, views, channels, longPress } = opts;\n // Read out as booleans, not the object: the attach effect depends on\n // them, and an inline `channels={{...}}` would re-bind every listener on\n // every render.\n const pointerChannel = channels?.pointer !== false;\n const wheelChannel = channels?.wheel !== false;\n const pinchChannel = channels?.pinch !== false;\n const contextMenuChannel = channels?.contextMenu !== false;\n const ingestChannel = channels?.ingest !== false;\n const onClickRef = useLatest(onClick);\n const onDoubleClickRef = useLatest(onDoubleClick);\n const activeTool = useActiveToolContext();\n const depRegistry = useDepRegistry();\n\n // Single dispatcher instance, stable across renders. When a `dispatcher`\n // is supplied via options, adopt it; otherwise create one lazily.\n const dispatcherRef = useRef<Dispatcher | null>(null);\n if (!dispatcherRef.current) {\n dispatcherRef.current = dispatcherOpt ?? createDispatcher();\n }\n\n // Stable ref to the latest context values so event listeners always see\n // current state without needing to re-register on every render.\n // No `getRuleCtx` here: eligibility is a per-view answer, so it rides on the\n // dispatch record and `ctxNow` installs the routed view's.\n const registryRef = useLatest(actions);\n const ctxRef = useLatest<DispatcherContext>({\n actions,\n depRegistry,\n activeToolId: activeTool.active,\n hotkeyStack: activeTool.hotkeyStack,\n entriesById,\n isMac: IS_MAC,\n });\n\n // The flat options are view zero.\n const rootTargetRef = useLatest<DispatcherViewTarget>({\n id: null, dispatcher: dispatcherRef.current, affordanceAt, classifyTarget, clientToWorld,\n getRuleCtx,\n });\n const viewsRef = useLatest(views);\n\n /** Every live dispatcher — what a cancel-everything has to reach. */\n const allDispatchers = useCallback((): Dispatcher[] => [\n rootTargetRef.current.dispatcher,\n ...(viewsRef.current?.targets() ?? []).map((t) => t.dispatcher),\n ], [rootTargetRef, viewsRef]);\n const requestRedrawRef = useLatest(requestRedraw);\n const paintedCursorRef = useLatest(paintedCursor);\n const longPressRef = useLatest(longPress);\n\n // Double-click synthesis state. Lives at hook level (not inside the effect)\n // so it survives effect re-runs — otherwise HMR / StrictMode / a transient\n // deps change resets it between the two clicks and the doubleclick never\n // fires.\n const lastClickRef = useRef<{ t: number; clientX: number; clientY: number } | null>(null);\n\n // Tool lifecycle. A tool is live while it holds the active slot or sits\n // in the hotkey stack; `onActivate` fires as it becomes live in either and\n // `onDeactivate` as it stops being live in both. A switch of the active\n // tool also cancels in-flight handles, so the new tool does not inherit a\n // live gesture — between the outgoing tools' cleanup and the incoming\n // tools' setup.\n const liveToolsRef = useRef<ReadonlySet<string>>(new Set());\n const prevActiveRef = useRef(activeTool.active);\n const entriesByIdRef = useLatest(entriesById);\n const fireLifecycle = useCallback((id: string, hook: 'onActivate' | 'onDeactivate'): void => {\n const tool = entriesByIdRef.current.get(id);\n if (!tool || !isTool(tool)) return;\n const fn = tool[hook];\n if (!fn) return;\n try {\n fn({ scratch: tool.initScratch?.() });\n } catch (err) {\n console.error(`weasel: tool \"${id}\".${hook} threw`, err);\n }\n }, [entriesByIdRef]);\n useEffect(() => {\n const prev = liveToolsRef.current;\n const next = new Set<string>(\n activeTool.active === null ? activeTool.hotkeyStack : [activeTool.active, ...activeTool.hotkeyStack],\n );\n liveToolsRef.current = next;\n for (const id of prev) if (!next.has(id)) fireLifecycle(id, 'onDeactivate');\n if (prevActiveRef.current !== activeTool.active) {\n for (const d of allDispatchers()) d.cancelAll('cancel');\n }\n prevActiveRef.current = activeTool.active;\n for (const id of next) if (!prev.has(id)) fireLifecycle(id, 'onActivate');\n });\n useEffect(() => () => {\n const live = liveToolsRef.current;\n liveToolsRef.current = new Set();\n for (const id of live) fireLifecycle(id, 'onDeactivate');\n }, [fireLifecycle]);\n\n useEffect(() => {\n if (!enabled) return;\n\n let disposed = false;\n\n // The view the current event belongs to, as an id rather than a record:\n // the record is rebuilt every render, so holding one across events would\n // dispatch through last render's lookups.\n let routedId: string | null = null;\n\n /** The dispatch record for the routed view. */\n const target = (): DispatcherViewTarget => {\n if (routedId === null) return rootTargetRef.current;\n return viewsRef.current?.targets().find((t) => t.id === routedId)\n ?? rootTargetRef.current;\n };\n\n /** Route an event with coordinates. `pointerId` is `null` for input with\n * nothing to capture — wheel, hover, contextmenu, drop. */\n const routeAt = (pointerId: number | null, clientX: number, clientY: number): void => {\n routedId = viewsRef.current?.resolver.at(pointerId, clientX, clientY).id ?? null;\n };\n /** Route a pointerdown, pinning the pointer to the view it landed in. */\n const routeDown = (pointerId: number, clientX: number, clientY: number): void => {\n routedId = viewsRef.current?.resolver.begin(pointerId, clientX, clientY).id ?? null;\n };\n const routeRelease = (pointerId: number): void => {\n viewsRef.current?.resolver.end(pointerId);\n };\n\n // Resolved per event, not bound once: the dispatcher an event runs on is\n // a property of the view it landed in.\n const dispatcherNow = (): Dispatcher => target().dispatcher;\n\n const routedDeps = withViewDeps(() => ctxRef.current.depRegistry, () => target().deps?.());\n // Eligibility is evaluated against the routed view's rule context, not the\n // surface's — same reason its deps are.\n const routedRuleCtx = (): ReturnType<NonNullable<DispatcherViewTarget['getRuleCtx']>> =>\n target().getRuleCtx?.();\n const ctxNow = (): DispatcherContext => ({\n ...ctxRef.current, depRegistry: routedDeps, getRuleCtx: routedRuleCtx,\n viewId: target().id,\n });\n const canvas = canvasRef.current;\n\n // Convert a client-space pointer position to world-space. When no\n // `clientToWorld` thunk is wired (legacy harnesses / tests), this is the\n // identity — preserves pre-fix behavior for callers that pass raw event\n // coords as if they were world. SceneCanvas always wires the thunk via\n // its canvas rect + current view, so `ctx.world` becomes real world coords\n // for areaSelect / lassoSelect / world-space affordance consumers.\n const toWorld = (cx: number, cy: number): { x: number; y: number } => {\n const fn = target().clientToWorld;\n return fn ? fn(cx, cy) : { x: cx, y: cy };\n };\n\n // Dispatch + bump the host canvas's redraw when any handle was in flight\n // before, during, or after the event. Without this, dispatcher-only\n // overlays (marquee, lasso) never repaint after their initial frame.\n // `before` captures the pre-event state so we redraw on the pump that\n // CLOSES a gesture (e.g. pointerup-with-no-remaining-handles still needs\n // to clear the overlay).\n //\n // `on` is for the one path that dispatches after its event has left the\n // stack (drop, whose items materialize async) — by then the routed view\n // is whatever moved under the cursor since.\n const dispatch = (ev: InputEvent, on?: Dispatcher): 'handled' | 'unhandled' => {\n const d = on ?? dispatcherNow();\n const before = d.inFlight().size;\n const result = d.handleInput(ev, ctxNow());\n const after = d.inFlight().size;\n if (before > 0 || after > 0) requestRedrawRef.current?.();\n return result;\n };\n\n // Held keys by physical key, mapped to the `key` they went down as: Shift\n // pressed mid-hold makes the keyup of an 'o' press report 'O'.\n const heldKeys = new Map<string, string>();\n const physicalKey = (e: KeyboardEvent): string => e.code || e.key.toLowerCase();\n\n // Every pointer currently held on the canvas, one `openPointerSession`\n // each. The session owns capture, pointer identity, teardown and the\n // three recovery rules; the record owns what the dispatcher synthesizes.\n const held = new Map<number, HeldPointer>();\n // Pinch anchors land in `zoomAt`, which measures from the canvas top-left,\n // so the centroid is converted here — the same step the wheel listener\n // takes for its own anchor. Client coords would drift the zoom by the\n // canvas's offset from the viewport.\n const toCanvasLocal = (p: { x: number; y: number }): { x: number; y: number } => {\n const rect = canvas?.getBoundingClientRect();\n if (!rect) return p;\n const [x, y] = clientToCanvasRect(rect, p.x, p.y);\n return { x, y };\n };\n const heldGeometry = () => {\n const { centroid, spread } = computeMultiTouchGeometry(\n [...held.values()].map((p) => p.pos),\n );\n return { centroid: toCanvasLocal(centroid), spread };\n };\n\n // Set on a `gesturestart` some binding claims, cleared on its end. `scale`\n // and `rotation` on a GestureEvent are cumulative from the start; these\n // hold the previous sample's so each dispatched `pinch` is a step.\n let pinchLive = false;\n let pinchScale = 1;\n let pinchRotation = 0;\n\n const endPinch = (): void => {\n pinchLive = false;\n pinchScale = 1;\n pinchRotation = 0;\n };\n\n // Tracks the start state of an active multitouch episode so we can\n // synthesize a `multitouchtap` event on release when the centroid hasn't\n // moved past the tap threshold. `fingers` records the peak count.\n let multiTouchStart: { fingers: number; centroid: { x: number; y: number } } | null = null;\n const TAP_THRESHOLD_PX = 8;\n\n // Long-press synthesis. Armed on pointerdown for touch/pen, cancelled by\n // movement past `DRAG_THRESHOLD_PX`, by release, by cancel, or by a second\n // pointer landing (so it can never fire mid-pinch).\n const longPressTimers = new Map<number, ReturnType<typeof setTimeout>>();\n\n const clearPending = (pointerId?: number): void => {\n const store = longPressRef.current?.state;\n const p = store?.get();\n if (p && (pointerId === undefined || p.pointerId === pointerId)) store!.set(null);\n };\n\n const cancelLongPress = (pointerId: number): void => {\n const t = longPressTimers.get(pointerId);\n if (t !== undefined) {\n clearTimeout(t);\n longPressTimers.delete(pointerId);\n }\n clearPending(pointerId);\n };\n\n const cancelAllLongPress = (): void => {\n for (const t of longPressTimers.values()) clearTimeout(t);\n longPressTimers.clear();\n clearPending();\n };\n\n const HAPTIC_MS = 15;\n\n /** Fire a synthesized long-press, falling back to contextmenu when the\n * long-press matched nothing. The fallback is what makes existing\n * `contextMenu` bindings reachable by touch with no consumer change. */\n const longPressEvents = (down: HeldPointer['down']): { longpress: InputEvent; contextmenu: InputEvent } => {\n const shared = {\n target: down.target,\n altKey: down.altKey,\n ctrlKey: down.ctrlKey,\n metaKey: down.metaKey,\n shiftKey: down.shiftKey,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n\n const at = { x: down.worldX, y: down.worldY, clientX: down.clientX, clientY: down.clientY };\n return {\n longpress: { kind: 'longpress', ...at, ...shared } as InputEvent,\n contextmenu: { kind: 'contextmenu', ...at, ...shared } as InputEvent,\n };\n };\n\n /** Whether holding `down` to the end would fire anything: the same two\n * dispatches `fireLongPress` makes, predicted without invoking. */\n const longPressWouldFire = (down: HeldPointer['down']): boolean => {\n const evs = longPressEvents(down);\n const d = dispatcherNow();\n return d.resolveOnly(evs.longpress, ctxNow()) !== null\n || d.resolveOnly(evs.contextmenu, ctxNow()) !== null;\n };\n\n const fireLongPress = (pointerId: number, pointerType: string): void => {\n const down = held.get(pointerId)?.down;\n clearPending(pointerId);\n if (!down) return;\n const evs = longPressEvents(down);\n let result = dispatch(evs.longpress);\n if (result === 'unhandled') result = dispatch(evs.contextmenu);\n if (result === 'handled' && longPressRef.current?.haptics !== false\n && (pointerType === 'touch' || pointerType === 'pen')\n && typeof navigator !== 'undefined' && typeof navigator.vibrate === 'function') {\n navigator.vibrate(HAPTIC_MS);\n }\n };\n\n // Double-click synthesis thresholds. 600ms matches the upper end of OS\n // double-click settings; 8px tolerates the natural drift of a real\n // mouse / trackpad between the two clicks. State (`lastClickRef`)\n // lives at hook level so it survives effect re-runs.\n const DOUBLE_CLICK_MAX_MS = 600;\n const DOUBLE_CLICK_MAX_PX = 8;\n\n // -----------------------------------------------------------------------\n // Window key listeners\n // -----------------------------------------------------------------------\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.defaultPrevented || isEditableTarget(e.target)) return;\n // Every dispatcher hears keys on window; only the active scope's act.\n if (!registryRef.current.isActive()) return;\n\n // Autorepeat for a key that's already engaged a key-held binding is\n // suppressed entirely — no dispatch (no trace flood) and the\n // browser default is blocked. Holding Space-for-hand otherwise\n // streamed an 'unhandled' immediate-`key` trace entry per repeat.\n // Autorepeat for a key that ISN'T held still dispatches normally,\n // so things like Cmd+= step-zoom keep auto-repeating.\n if (e.repeat && heldKeys.has(physicalKey(e))) {\n e.preventDefault();\n return;\n }\n\n // Dispatch both key and key-held forms unconditionally. The dispatcher\n // de-dupes naturally because each form uses a different gestureId and\n // different GestureSpec kind. `matchBest` returns 'unhandled' when no\n // binding matches the alternate form, so there's no double-fire risk.\n\n const keyEv: InputEvent = {\n kind: 'key',\n key: e.key,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n repeat: e.repeat,\n };\n const keyResult = dispatch(keyEv);\n\n // Always dispatch key-held DOWN, even on autorepeat. The dispatcher's\n // own defense returns 'handled' (no-op) when a handle is already in\n // flight for this gestureId, which both prevents start() re-invocation\n // and lets us preventDefault the repeat so the page doesn't react.\n const heldEv: InputEvent = {\n kind: 'key-held',\n key: e.key,\n phase: 'down',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n const heldResult = dispatch(heldEv);\n\n if (heldResult === 'handled') {\n heldKeys.set(physicalKey(e), e.key);\n }\n\n if (keyResult === 'handled' || heldResult === 'handled') {\n e.preventDefault();\n }\n };\n\n const onKeyUp = (e: KeyboardEvent) => {\n const physical = physicalKey(e);\n const downKey = heldKeys.get(physical);\n if (downKey === undefined) return;\n const ev: InputEvent = {\n kind: 'key-held',\n key: downKey,\n phase: 'up',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(ev);\n heldKeys.delete(physical);\n };\n\n // A window that loses focus never delivers the keyup, so without this every\n // in-flight key-held handle stays engaged until that key is pressed again.\n // Nor can a drag trust the release it may or may not see later, so every\n // held pointer is canceled — through its session, which reports once.\n const onWindowBlur = () => {\n endPinch();\n for (const p of [...held.values()]) p.session.cancel();\n for (const key of heldKeys.values()) {\n const ev: InputEvent = {\n kind: 'key-held',\n key,\n phase: 'up',\n altKey: false,\n ctrlKey: false,\n metaKey: false,\n shiftKey: false,\n };\n dispatch(ev);\n }\n heldKeys.clear();\n };\n\n // -----------------------------------------------------------------------\n // Canvas wheel listener\n // -----------------------------------------------------------------------\n\n const onWheel = (e: WheelEvent) => {\n registryRef.current.activate();\n // Safari can report one trackpad pinch as both a gesture stream and\n // ctrl+wheel. While a claimed gesture is live it is the only driver.\n if (pinchLive && e.ctrlKey) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n routeAt(null, e.clientX, e.clientY);\n // Convert client-space cursor to canvas-local: zoomAt() (and any other\n // wheel consumer of clientX/Y) anchors in canvas-top-left coords, not\n // viewport coords. Without this, anchored-wheel zoom drifts by the\n // canvas's offset from the viewport top-left.\n const rect = canvas?.getBoundingClientRect();\n const [localX, localY] = rect\n ? clientToCanvasRect(rect, e.clientX, e.clientY)\n : [e.clientX, e.clientY];\n const hitPoint = toWorld(e.clientX, e.clientY);\n const affordance = target().affordanceAt?.(hitPoint) ?? undefined;\n const body = target().classifyTarget?.(hitPoint);\n const ev: InputEvent = {\n kind: 'wheel',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n deltaX: e.deltaX,\n deltaY: e.deltaY,\n clientX: localX,\n clientY: localY,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(body?.body !== undefined ? { bodyTarget: body.body } : {}),\n ...(body?.kind !== undefined ? { bodyKind: body.kind } : {}),\n };\n const result = dispatch(ev);\n // A claimed wheel neither scrolls the page nor reaches the canvas's other listeners\n // (a host's camera would zoom under a loupe); capture phase lets this run first.\n if (result === 'handled') {\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n };\n\n // -----------------------------------------------------------------------\n // Canvas gesture listeners (WebKit trackpad pinch)\n // -----------------------------------------------------------------------\n\n const pinchEventOf = (e: Event, scale: number, rotation: number): InputEvent => {\n const g = e as Event & {\n clientX?: number; clientY?: number;\n altKey?: boolean; ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean;\n };\n const rect = canvas?.getBoundingClientRect();\n // A focal point is part of the WebKit shape; the canvas center stands\n // in for an embedder that leaves it off.\n const cx = typeof g.clientX === 'number' ? g.clientX : (rect ? rect.left + rect.width / 2 : 0);\n const cy = typeof g.clientY === 'number' ? g.clientY : (rect ? rect.top + rect.height / 2 : 0);\n routeAt(null, cx, cy);\n const [localX, localY] = rect ? clientToCanvasRect(rect, cx, cy) : [cx, cy];\n const hitPoint = toWorld(cx, cy);\n const affordance = target().affordanceAt?.(hitPoint) ?? undefined;\n const body = target().classifyTarget?.(hitPoint);\n return {\n kind: 'pinch',\n altKey: g.altKey === true,\n ctrlKey: g.ctrlKey === true,\n metaKey: g.metaKey === true,\n shiftKey: g.shiftKey === true,\n scale,\n rotation,\n clientX: localX,\n clientY: localY,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(body?.body !== undefined ? { bodyTarget: body.body } : {}),\n ...(body?.kind !== undefined ? { bodyKind: body.kind } : {}),\n };\n };\n\n const onGestureStart = (e: Event) => {\n endPinch();\n // Claimed up front, with a probe at unit scale: Safari starts its own\n // page zoom from an unprevented start, before any change arrives.\n // `direction`-filtered bindings cannot match a unit step, so they are\n // resolved per change instead and do not claim the start.\n const probe = pinchEventOf(e, 1, 0);\n if (dispatcherNow().resolveOnly(probe, ctxNow()) === null) return;\n pinchLive = true;\n e.preventDefault();\n };\n\n const onGestureChange = (e: Event) => {\n const g = e as Event & { scale?: number; rotation?: number };\n const scale = typeof g.scale === 'number' && g.scale > 0 ? g.scale : pinchScale;\n const rotation = typeof g.rotation === 'number' ? g.rotation : pinchRotation;\n const step = scale / pinchScale;\n const turn = rotation - pinchRotation;\n pinchScale = scale;\n pinchRotation = rotation;\n if (dispatch(pinchEventOf(e, step, turn)) === 'handled') {\n pinchLive = true;\n e.preventDefault();\n } else if (pinchLive) {\n // The start was claimed; letting one change through would hand the\n // rest of the pinch to Safari's page zoom mid-gesture.\n e.preventDefault();\n }\n };\n\n const onGestureEnd = (e: Event) => {\n if (pinchLive) e.preventDefault();\n endPinch();\n };\n\n // -----------------------------------------------------------------------\n // Canvas pointer listeners + multi-touch synthesis\n // -----------------------------------------------------------------------\n\n // A double click this dispatcher acted on is spent: the browser's own\n // `dblclick` that follows is marked handled, so a container that opens or\n // toggles on double-click (labkit's lightbox) leaves it alone.\n let claimedDoubleClick = false;\n const onNativeDoubleClick = (e: MouseEvent) => {\n if (!claimedDoubleClick) return;\n claimedDoubleClick = false;\n e.preventDefault();\n };\n\n const onPointerDown = (e: PointerEvent) => {\n claimedDoubleClick = false;\n // Any button makes this the scope chrome and keys reach.\n registryRef.current.activate();\n // Only the primary button drives gesture dispatch. `pointerdown` reports\n // `button === 0` for the left mouse button and for touch / pen contact;\n // secondary (right, `2`) and middle (`1`) mouse buttons are left for the\n // consumer's own tools (e.g. right-drag viewport pan) and the browser\n // context menu. Without this guard a right-drag is classified and routed\n // exactly like a left-drag — selecting + transforming under the cursor\n // instead of letting an ambient pan tool claim it. An absent `button`\n // (synthetic / programmatic events) counts as primary.\n if ((e.button ?? 0) !== 0) return;\n if (!canvas) return;\n // A button or field laid over the canvas handles its own press: opening a\n // session here would capture the pointer and retarget its click.\n if (isInControlWithin(e.target, canvas)) return;\n routeDown(e.pointerId, e.clientX, e.clientY);\n\n const w = toWorld(e.clientX, e.clientY);\n const affordance = target().affordanceAt?.(w) ?? undefined;\n const body = target().classifyTarget?.(w);\n const bodyTarget = body?.body;\n const bodyKind = body?.kind;\n const ev: InputEvent = {\n kind: 'pointerdown',\n target: e.target,\n pointerId: e.pointerId,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n ...stylusOf(e),\n ...(affordance !== undefined ? { affordance } : {}),\n ...(bodyTarget !== undefined ? { bodyTarget } : {}),\n ...(bodyKind !== undefined ? { bodyKind } : {}),\n };\n // The session owns the rest of this pointer: capture, the moves and the\n // release, and the three recovery rules for a release that never\n // arrives. A press on a pointer one is already open for cancels that\n // stale gesture before this handler runs — its `pointerdown` listener is\n // on the document, in the capture phase, ahead of this one on the canvas.\n held.set(e.pointerId, {\n session: openPointerSession(canvas, e, {\n onMove: onPointerMove,\n onEnd: onPointerUp,\n onCancel: () => { onPointerCancel(e.pointerId); },\n }),\n pos: { x: e.clientX, y: e.clientY },\n // Deferred until the first past-threshold pointermove: a bare\n // press-and-release should fire `click`, not start a drag action.\n buffered: { ev, clientX: e.clientX, clientY: e.clientY },\n down: {\n target: e.target,\n clientX: e.clientX,\n clientY: e.clientY,\n worldX: w.x,\n worldY: w.y,\n affordance,\n bodyTarget,\n bodyKind,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n },\n });\n\n // The press itself dispatches now, for bindings that must act while the\n // button is still down and before the gesture is classified (select\n // highlights the pressed node here). `matchSpec` routes the two copies\n // to disjoint spec kinds — `pointerDown` matches only this one, `drag`\n // only the buffered one — so a single press never fires both.\n //\n // Withheld once a second pointer is down: this press belongs to the\n // multitouch channel under the MULTI-POINTER POLICY below, which clears\n // the buffered copy for the same reason. Without this a pinch's second\n // finger ran `select.pick` and moved the selection under the gesture.\n if (held.size < 2) dispatch({ ...ev, stage: 'press' });\n\n // Arm long-press for touch / pen only, and only for a lone pointer —\n // a second finger means a multi-touch gesture, not a long-press.\n if ((e.pointerType === 'touch' || e.pointerType === 'pen')\n && held.size === 1) {\n cancelLongPress(e.pointerId);\n const duration = longPressRef.current?.duration ?? LONG_PRESS_MS;\n longPressTimers.set(\n e.pointerId,\n setTimeout(() => {\n longPressTimers.delete(e.pointerId);\n if (disposed) return;\n fireLongPress(e.pointerId, e.pointerType);\n }, duration),\n );\n const store = longPressRef.current?.state;\n const rec = held.get(e.pointerId);\n if (store && rec) {\n store.set({\n pointerId: e.pointerId,\n pointerType: e.pointerType as 'touch' | 'pen',\n client: { x: e.clientX, y: e.clientY },\n local: toCanvasLocal({ x: e.clientX, y: e.clientY }),\n world: { x: w.x, y: w.y },\n viewId: target().id,\n startedAt: performance.now(),\n duration,\n armed: longPressWouldFire(rec.down),\n });\n }\n }\n\n // Synthesize a multi-touch event when >= 2 pointers are active.\n if (held.size >= 2) {\n cancelAllLongPress();\n // MULTI-POINTER POLICY: the multitouch channel takes ownership of\n // every pointer that hasn't already committed to a gesture. Clearing\n // the buffered press is what enforces it — a claimed pointer opens no\n // drag handle on the next move, and synthesizes no click on release\n // (both of those read the buffer). The `multitouch-<fingers>` handle\n // and the `multitouchtap` synthesis below are the whole gesture.\n //\n // This used to hold by accident: `gestureIdFor` returned one key for\n // every pointer, so a second finger's press found the first's handle\n // in flight and no-oped. Per-pointer keying removes the accident, so\n // the policy has to be stated. Stating it is the improvement — a\n // pointer that is part of a pinch is not also dragging something.\n //\n // Note the asymmetry: a pointer that already opened a drag has no\n // buffer left to claim, so its gesture survives the second finger\n // landing. Yanking a drag out from under someone who rested a palm is\n // worse than letting it finish.\n for (const p of held.values()) p.buffered = null;\n\n const { centroid, spread } = heldGeometry();\n // Capture start state for tap synthesis. On the first 1→2 transition\n // we record the centroid; subsequent pointerdowns at higher finger\n // counts only bump the recorded peak fingers count.\n if (!multiTouchStart) {\n multiTouchStart = { fingers: held.size, centroid: { ...centroid } };\n } else {\n multiTouchStart.fingers = held.size;\n }\n const mt: InputEvent = {\n kind: 'multitouch',\n fingers: held.size,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n centroid,\n spread,\n };\n dispatch(mt);\n }\n };\n\n const onPointerMove = (e: PointerEvent) => {\n routeAt(e.pointerId, e.clientX, e.clientY);\n const rec = held.get(e.pointerId);\n if (rec) rec.pos = { x: e.clientX, y: e.clientY };\n\n // Threshold gate: if a pointerdown is buffered for this pointer and\n // the movement crossed the drag threshold, forward the buffered\n // pointerdown to the dispatcher BEFORE the pointermove. This is what\n // opens the ongoing drag handle (matching `kind: 'drag'` bindings);\n // subsequent pointermoves pump it via `onMove`. Sub-threshold\n // pointermoves are still forwarded so existing pump paths (e.g. other\n // in-flight handles) keep working, but they're no-ops when no handle\n // exists.\n const buffered = rec?.buffered;\n if (rec && buffered) {\n if (pastDragThreshold(buffered, e)) {\n rec.buffered = null;\n cancelLongPress(e.pointerId);\n dispatch(buffered.ev);\n }\n }\n\n // If a multitouch handle is in flight, synthesize a multitouch pump event\n // with the updated centroid + spread. The dispatcher routes this to the\n // handle's onMove (because the event carries centroid data).\n const mtGestureId = `multitouch-${held.size}`;\n if (held.size >= 2 && dispatcherNow().inFlight().has(mtGestureId)) {\n const { centroid, spread } = heldGeometry();\n const mtEv: InputEvent = {\n kind: 'multitouch',\n fingers: held.size,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n centroid,\n spread,\n };\n dispatch(mtEv);\n // Also dispatch the raw pointermove so single-pointer handles can coexist.\n }\n\n const w = toWorld(e.clientX, e.clientY);\n const ev: InputEvent = {\n kind: 'pointermove',\n pointerId: e.pointerId,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n ...stylusOf(e),\n };\n dispatch(ev);\n\n lastHover = {\n clientX: e.clientX, clientY: e.clientY,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n refreshHoverCursor();\n };\n\n // -----------------------------------------------------------------------\n // Hover-cursor pump\n // -----------------------------------------------------------------------\n //\n // On every idle pointermove (no pressed pointer, no in-flight handle),\n // resolve what sits under the pointer and write a cursor override\n // directly to `canvas.style.cursor`. Precedence:\n //\n // 1. Affordance hit declaring `AffordanceHit.cursor` (resize corners,\n // rotate ring) — the same `affordanceAt` hit-test pointerdown uses.\n // 2. The action a drag from here would route to (`resolveOnly`, the\n // same match walk pointerdown takes), when it declares\n // `Action.cursor` — e.g. `viewport.dragPan` → 'grab' over empty\n // canvas when pan would win the drag.\n // 3. Otherwise the action a click here would route to, when it\n // declares one — e.g. Alt over a path segment in path-edit mode.\n // 4. No override — clear the inline style so the active tool's\n // React-managed `Tool.cursor` (the implicit base) shows through.\n //\n // Mid-gesture the pump stands down; the tool-cursor pipeline\n // (function-form `Tool.cursor` re-resolving on `gestureTick`) owns the\n // cursor there. The override is an inline style on purpose: clearing it\n // restores the React-managed base without effect churn.\n //\n // `lastHover` lets modifier keydown/keyup refresh the prediction without\n // pointer movement (a held Space re-routes the drag to the hand tool).\n // That refresh is deferred a tick so React can commit the hotkey-stack /\n // active-tool state the key event just changed — `ctxRef` is only\n // rewritten on commit.\n let lastHover: {\n clientX: number; clientY: number;\n altKey: boolean; ctrlKey: boolean; metaKey: boolean; shiftKey: boolean;\n } | null = null;\n let cursorOverridden = false;\n const clearHoverCursor = () => {\n paintedCursorRef.current?.()?.setOverride(null);\n if (cursorOverridden && canvas) {\n canvas.style.cursor = '';\n cursorOverridden = false;\n }\n };\n const applyHoverCursor = (spec: CursorSpec | null) => {\n const tier = spec === null ? null : resolveCursorTier(spec);\n if (!tier || !canvas) {\n clearHoverCursor();\n return;\n }\n // A painted cursor is two writes, not one: the native cursor gets out of\n // the way and the layer is told what to draw. Doing only the first is a\n // pointer with no cursor at all.\n const painted = tier.kind === 'painted' ? tier : null;\n paintedCursorRef.current?.()?.setOverride(painted);\n const cursor = tier.kind === 'css' ? tier.css : 'none';\n if (!cursor) {\n clearHoverCursor();\n return;\n }\n canvas.style.cursor = cursor;\n cursorOverridden = true;\n };\n /**\n * Where the painted-cursor layer should draw, in canvas-local CSS px.\n *\n * Pushed after the cursor has been resolved, not before: on the move that\n * first selects a painted cursor, a position written ahead of the decision\n * is discarded and the glyph does not appear until the next move. Guarded\n * on `active()`, so an ordinary CSS cursor costs no layout read per move.\n */\n function pushPaintedPointer(): void {\n const painted = paintedCursorRef.current?.();\n if (!painted?.active() || !canvas || !lastHover) return;\n const r = canvas.getBoundingClientRect();\n painted.setPointer(lastHover.clientX - r.left, lastHover.clientY - r.top);\n }\n\n function refreshHoverCursor(): void {\n resolveHoverCursor();\n pushPaintedPointer();\n }\n\n function resolveHoverCursor(): void {\n if (!canvas || !lastHover) return;\n // Mid-gesture the prediction is meaningless — what matters is what the\n // gesture IS. An in-flight action's `activeCursor` wins; with none\n // declared the override clears and the active tool's `Tool.cursor`\n // shows through, as before.\n if (held.size > 0 || dispatcherNow().inFlight().size > 0) {\n applyHoverCursor(dispatcherNow().inFlightCursor());\n return;\n }\n const h = lastHover;\n // Idle: re-resolve. Mid-gesture the branch above already returned, so a\n // pinned pointer is never unpinned by a hover refresh.\n routeAt(null, h.clientX, h.clientY);\n const w = toWorld(h.clientX, h.clientY);\n const affordance = target().affordanceAt?.(w) ?? undefined;\n if (affordance?.cursor) {\n applyHoverCursor(affordance.cursor);\n return;\n }\n const hoverBody = target().classifyTarget?.(w);\n const bodyTarget = hoverBody?.body;\n const bodyKind = hoverBody?.kind;\n const where = {\n altKey: h.altKey,\n ctrlKey: h.ctrlKey,\n metaKey: h.metaKey,\n shiftKey: h.shiftKey,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(bodyTarget !== undefined ? { bodyTarget } : {}),\n ...(bodyKind !== undefined ? { bodyKind } : {}),\n };\n const ctx = ctxNow();\n const press: InputEvent = {\n kind: 'pointerdown', x: w.x, y: w.y, clientX: h.clientX, clientY: h.clientY, ...where,\n };\n const d = dispatcherNow();\n publishLiveDispatch(() => d.explain(press, ctx));\n const dragCursor = d.resolveOnly(press, ctx)?.action.cursor;\n // A drag's hint first; failing that, what a click here would do.\n const cursor = dragCursor ?? dispatcherNow().resolveOnly(\n { kind: 'click', x: w.x, y: w.y, pressX: w.x, pressY: w.y, ...where },\n ctx,\n )?.action.cursor;\n applyHoverCursor(cursor ?? null);\n }\n /** Modifier/hotkey changes re-route the predicted drag without pointer\n * movement. Refresh after a tick so the key event's React state\n * (hotkey stack, active tool) has committed into `ctxRef`. */\n const scheduleHoverCursorRefresh = (e: KeyboardEvent) => {\n if (!lastHover) return;\n lastHover = {\n ...lastHover,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n setTimeout(() => {\n if (!disposed) refreshHoverCursor();\n }, 0);\n };\n // A held pointer's moves arrive through its session, which keeps seeing\n // them once the pointer has left the canvas or the canvas is gone. The\n // canvas listener is left with the hover half.\n const onHoverMove = (e: PointerEvent) => {\n if (held.has(e.pointerId)) return;\n onPointerMove(e);\n };\n\n const onHoverPointerLeave = () => {\n lastHover = null;\n publishLiveDispatch(null);\n paintedCursorRef.current?.()?.clearPointer();\n clearHoverCursor();\n };\n\n const onPointerUp = (e: PointerEvent) => {\n routeAt(e.pointerId, e.clientX, e.clientY);\n cancelLongPress(e.pointerId);\n const prevSize = held.size;\n // The record outlives the map entry: everything below is synthesized\n // from the press, and reads it after this pointer has stopped counting\n // towards `held.size`.\n const rec = held.get(e.pointerId);\n held.delete(e.pointerId);\n\n // A press still buffered never crossed the drag threshold — the\n // dispatcher never saw it, so no drag handle is in flight and this\n // release is a click. Crossing the threshold clears the buffer whether\n // or not a drag binding matched, which makes this the authoritative\n // \"did the pointer move?\" signal for click synthesis.\n const staysUnderThreshold = rec?.buffered != null;\n\n // When pointer count drops below 2, commit any in-flight multitouch handle\n // and (if the centroid never moved past the tap threshold) synthesize a\n // `multitouchtap` event carrying the peak fingers count.\n // The gestureId is keyed by the PREVIOUS size (before this pointer was removed)\n // because that was the handle's finger count when it was opened.\n if (prevSize >= 2 && held.size < 2) {\n const mtGestureId = `multitouch-${prevSize}`;\n if (dispatcherNow().inFlight().has(mtGestureId)) {\n // Synthesize a pointerup for the multitouch gesture — dispatcher needs\n // a pointerup to route to onEnd, but multitouch handles are keyed by\n // finger count, not by pointer. We use cancelAll to safely commit all\n // in-flight handles of this gesture; only the multitouch handle\n // should be active (see the multi-pointer policy in onPointerDown).\n // Use 'commit' because this is a natural lift (not a cancel).\n dispatcherNow().cancelAll('commit');\n }\n // Synthesize a tap if the centroid hasn't moved past threshold.\n const start = multiTouchStart;\n if (start) {\n // Final centroid uses the pointer positions BEFORE this pointer was\n // removed — it is already out of `held`, so add it back in.\n const centroid = toCanvasLocal(\n computeMultiTouchGeometry([\n ...[...held.values()].map((p) => p.pos),\n { x: e.clientX, y: e.clientY },\n ]).centroid,\n );\n const dx = centroid.x - start.centroid.x;\n const dy = centroid.y - start.centroid.y;\n if (Math.hypot(dx, dy) <= TAP_THRESHOLD_PX) {\n const tap: InputEvent = {\n kind: 'multitouchtap',\n fingers: start.fingers,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(tap);\n }\n multiTouchStart = null;\n }\n }\n\n // Check whether a drag handle is in-flight BEFORE sending pointerup.\n // If THIS pointer's handle is in-flight AND the pointer moved between\n // down and up, this is the end of a real drag — pump it and don't\n // synthesize a click. If no handle is in-flight, or the handle was\n // opened but the pointer never moved (sub-threshold \"tap\" that an\n // over-broad ambient drag binding accepted), we still synthesize a\n // click so click-specific bindings (e.g. clearSelection on empty) fire.\n const movedDuringDrag = rec\n ? (rec.down.clientX !== e.clientX || rec.down.clientY !== e.clientY)\n : true;\n const hadDragInFlight =\n dispatcherNow().inFlight().has(pointerGestureId(e.pointerId)) && movedDuringDrag;\n\n const wUp = toWorld(e.clientX, e.clientY);\n const ev: InputEvent = {\n kind: 'pointerup',\n pointerId: e.pointerId,\n x: wUp.x,\n y: wUp.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(ev);\n\n const down = rec?.down;\n\n // Synthesize a click when the pointer neither opened a drag handle nor\n // travelled past the drag threshold. Carry the `bodyTarget` from the\n // pointerdown so click specs with string-form targets ('empty',\n // 'selected-body') match.\n //\n // The threshold half of that test is load-bearing for any tool that\n // binds `click` but not `drag`: without it, dragging clear across the\n // canvas and releasing synthesized a click, because \"no drag handle\n // opened\" was the only condition. `ClickSpec` documents itself as\n // \"pointerdown + pointerup without movement past the threshold\" — this\n // is the code finally agreeing with it.\n if (!hadDragInFlight && staysUnderThreshold && down) {\n const wClick = toWorld(e.clientX, e.clientY);\n const clickEv: InputEvent = {\n kind: 'click',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n x: wClick.x,\n y: wClick.y,\n clientX: e.clientX,\n clientY: e.clientY,\n pressX: down.worldX,\n pressY: down.worldY,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n dispatch(clickEv);\n onClickRef.current?.({ x: wClick.x, y: wClick.y });\n\n // Double-click synthesis: emit a `doubleclick` event AFTER the\n // second click when two clicks land within DOUBLE_CLICK_MAX_MS and\n // DOUBLE_CLICK_MAX_PX. Reset the tracker after a successful\n // doubleclick so a third click doesn't compose another one\n // (triple-click semantics are not modeled).\n const now = Date.now();\n const prev = lastClickRef.current;\n const dx = e.clientX - (prev?.clientX ?? 0);\n const dy = e.clientY - (prev?.clientY ?? 0);\n if (prev && now - prev.t < DOUBLE_CLICK_MAX_MS && Math.hypot(dx, dy) < DOUBLE_CLICK_MAX_PX) {\n const dblEv: InputEvent = {\n kind: 'doubleclick',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n x: wClick.x,\n y: wClick.y,\n clientX: e.clientX,\n clientY: e.clientY,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n // Notify observers first — see `onDoubleClick`'s doc for why this\n // is not modeled as a binding.\n onDoubleClickRef.current?.({ x: wClick.x, y: wClick.y });\n const handled = dispatch(dblEv) === 'handled';\n claimedDoubleClick = handled || onDoubleClickRef.current !== undefined;\n lastClickRef.current = null;\n } else {\n lastClickRef.current = { t: now, clientX: e.clientX, clientY: e.clientY };\n }\n }\n\n // Every synthesized event this release produces has been dispatched, so\n // the pointer's view can be unpinned.\n routeRelease(e.pointerId);\n\n // Re-resolve the hover cursor at the release point — deferred a tick\n // so any state the up/click actions changed (selection, active tool)\n // has committed before prediction reruns.\n lastHover = {\n clientX: e.clientX, clientY: e.clientY,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n setTimeout(() => {\n if (!disposed) refreshHoverCursor();\n }, 0);\n };\n\n // Every way a gesture ends without a release: the browser cancelling the\n // pointer, capture going away, a press proving the tracked one had already\n // ended. The session decides which of those happened; the dispatcher\n // treats them alike, and reads the press's own modifiers because a cancel\n // carries none of its own.\n const onPointerCancel = (pointerId: number) => {\n // On teardown every session is cancelled at once; `cancelAll` ends those\n // gestures, so re-entering dispatch here would end them twice.\n if (disposed) return;\n const rec = held.get(pointerId);\n if (!rec) return;\n held.delete(pointerId);\n routeAt(pointerId, rec.pos.x, rec.pos.y);\n cancelLongPress(pointerId);\n // Drop any pending multitouch-tap start state — a cancel means we should\n // not synthesize a tap on the subsequent up.\n multiTouchStart = null;\n const ev: InputEvent = {\n kind: 'pointercancel',\n pointerId,\n altKey: rec.down.altKey,\n ctrlKey: rec.down.ctrlKey,\n metaKey: rec.down.metaKey,\n shiftKey: rec.down.shiftKey,\n };\n dispatch(ev);\n routeRelease(pointerId);\n };\n\n // -----------------------------------------------------------------------\n // Canvas contextmenu listener (right-click)\n // -----------------------------------------------------------------------\n\n const onContextMenu = (e: MouseEvent) => {\n // Suppress native menu so tools/actions own the right-click UX.\n e.preventDefault();\n routeAt(null, e.clientX, e.clientY);\n const w = toWorld(e.clientX, e.clientY);\n // A secondary button never reaches `onPointerDown`, so unlike click and\n // long-press there is no press to replay the classification from.\n const affordance = target().affordanceAt?.(w) ?? undefined;\n const menuBody = target().classifyTarget?.(w);\n const ev: InputEvent = {\n kind: 'contextmenu',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(menuBody?.body !== undefined ? { bodyTarget: menuBody.body } : {}),\n ...(menuBody?.kind !== undefined ? { bodyKind: menuBody.kind } : {}),\n };\n dispatch(ev);\n };\n\n // -----------------------------------------------------------------------\n // External-content ingestion: OS drop on the canvas, paste on window.\n // Items are materialized DURING the event (DataTransfer is only live on\n // the event stack); dispatch happens when materialization resolves.\n // -----------------------------------------------------------------------\n\n // Attached to both dragover and dragenter: cancelling dragenter (WHATWG)\n // guarantees the element stays the active drop target and shows the copy\n // cursor on entry rather than waiting for the first dragover tick.\n const onDragOver = (e: DragEvent) => {\n if (!e.dataTransfer) return;\n // preventDefault is what makes the canvas a valid drop target.\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n canvas?.classList.add(DROPOVER_CLASS);\n };\n\n const onDragLeave = () => {\n canvas?.classList.remove(DROPOVER_CLASS);\n };\n\n // No stopPropagation: handled-ness is only known after the async\n // materialization microtask, so a conditional stop (wheel-style) is\n // impossible; an unconditional one would swallow drops the kit doesn't\n // dispatch. Callers that need exclusivity should gate on the action result.\n const onDrop = (e: DragEvent) => {\n canvas?.classList.remove(DROPOVER_CLASS);\n const dt = e.dataTransfer;\n if (!dt) return;\n e.preventDefault();\n routeAt(null, e.clientX, e.clientY);\n const dropOn = target().dispatcher;\n const w = toWorld(e.clientX, e.clientY);\n // Real modifiers forwarded (Option-drag is a copy-drag on macOS); the\n // kit ingest binding declares all modifiers optional, so they can't\n // block the default route — but a consumer binding may key on them.\n const base = {\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n void itemsFromDataTransfer(dt).then((items) => {\n if (disposed) return;\n if (items.length === 0) return;\n dispatch({\n kind: 'drop', items,\n x: w.x, y: w.y, clientX: e.clientX, clientY: e.clientY,\n ...base,\n }, dropOn);\n });\n };\n\n const onPaste = (e: ClipboardEvent) => {\n // Text-editing surfaces (inputs, the text-edit overlay) own their own\n // paste — never steal it for scene ingestion.\n if (isEditableTarget(e.target)) return;\n const cd = e.clipboardData;\n if (!cd) return;\n const items = itemsFromClipboardData(cd);\n if (items.length === 0) return;\n // Wheel's shape: dispatch first, suppress the default only when a\n // binding claimed it. Clipboard items materialize synchronously, so\n // unlike `onDrop` the result is known while `preventDefault` is still\n // honored — and a paste no binding wanted stays the page's to handle.\n const result = dispatch({\n kind: 'paste', items,\n // ClipboardEvent carries no modifier state.\n altKey: false, ctrlKey: false, metaKey: false, shiftKey: false,\n });\n if (result === 'handled') e.preventDefault();\n };\n\n // -----------------------------------------------------------------------\n // Attach\n // -----------------------------------------------------------------------\n\n const keyCapture = keyboard === 'first';\n if (keyboard) {\n window.addEventListener('keydown', onKeyDown, keyCapture);\n window.addEventListener('keyup', onKeyUp, keyCapture);\n }\n window.addEventListener('blur', onWindowBlur);\n // Hover-cursor refresh on modifier/hotkey changes — separate listeners\n // (not folded into onKeyDown/onKeyUp) so the pump also tracks modifiers\n // when `keyboard: false` disables gesture key dispatch.\n window.addEventListener('keydown', scheduleHoverCursorRefresh);\n window.addEventListener('keyup', scheduleHoverCursorRefresh);\n if (pointerChannel) {\n canvas?.addEventListener('pointerleave', onHoverPointerLeave);\n canvas?.addEventListener('pointerdown', onPointerDown);\n canvas?.addEventListener('pointermove', onHoverMove);\n canvas?.addEventListener('dblclick', onNativeDoubleClick);\n }\n if (wheelChannel) canvas?.addEventListener('wheel', onWheel, { passive: false, capture: true });\n if (pinchChannel) {\n canvas?.addEventListener('gesturestart', onGestureStart);\n canvas?.addEventListener('gesturechange', onGestureChange);\n canvas?.addEventListener('gestureend', onGestureEnd);\n }\n if (contextMenuChannel) canvas?.addEventListener('contextmenu', onContextMenu);\n if (ingestChannel) {\n canvas?.addEventListener('dragenter', onDragOver);\n canvas?.addEventListener('dragover', onDragOver);\n canvas?.addEventListener('dragleave', onDragLeave);\n canvas?.addEventListener('drop', onDrop);\n window.addEventListener('paste', onPaste);\n }\n\n // -----------------------------------------------------------------------\n // Cleanup\n // -----------------------------------------------------------------------\n\n return () => {\n if (keyboard) {\n window.removeEventListener('keydown', onKeyDown, keyCapture);\n window.removeEventListener('keyup', onKeyUp, keyCapture);\n }\n window.removeEventListener('blur', onWindowBlur);\n window.removeEventListener('keydown', scheduleHoverCursorRefresh);\n window.removeEventListener('keyup', scheduleHoverCursorRefresh);\n canvas?.removeEventListener('pointerleave', onHoverPointerLeave);\n canvas?.removeEventListener('wheel', onWheel, { capture: true });\n canvas?.removeEventListener('gesturestart', onGestureStart);\n canvas?.removeEventListener('gesturechange', onGestureChange);\n canvas?.removeEventListener('gestureend', onGestureEnd);\n canvas?.removeEventListener('pointerdown', onPointerDown);\n canvas?.removeEventListener('pointermove', onHoverMove);\n canvas?.removeEventListener('dblclick', onNativeDoubleClick);\n canvas?.removeEventListener('contextmenu', onContextMenu);\n canvas?.removeEventListener('dragenter', onDragOver);\n canvas?.removeEventListener('dragover', onDragOver);\n canvas?.removeEventListener('dragleave', onDragLeave);\n canvas?.removeEventListener('drop', onDrop);\n window.removeEventListener('paste', onPaste);\n // Detach is unconditional: a channel turned off mid-life must still\n // have whatever it attached while it was on taken back off.\n canvas?.classList.remove(DROPOVER_CLASS);\n clearHoverCursor();\n cancelAllLongPress();\n disposed = true;\n // `disposed` first: the sessions' cancels must not re-enter dispatch on\n // the way out, and `cancelAll` below is what ends the gestures.\n for (const p of held.values()) p.session.cancel();\n held.clear();\n for (const d of allDispatchers()) d.cancelAll('cancel');\n };\n }, [enabled, keyboard, canvasRef, pointerChannel, wheelChannel, pinchChannel, contextMenuChannel, ingestChannel,\n allDispatchers, ctxRef, longPressRef, onClickRef, onDoubleClickRef, paintedCursorRef, registryRef, requestRedrawRef, rootTargetRef, viewsRef]);\n}\n","/**\n * @experimental\n * The React half of the actions registry: the context, the tree node that\n * owns each id → descriptor stack, the providers that mount nodes, and the two\n * hooks. The store contract it implements is in `registry.ts`.\n */\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { Action } from './action';\nimport { useLatest } from '@weasel-js/react';\nimport {\n useOptionalDepRegistry,\n type DepRegistry,\n type DepName,\n} from './depRegistry';\nimport { buildDepsFromRequires } from './buildDeps';\nimport type { Dispatcher } from '../dispatcher/dispatcher';\nimport { validateActionId, validateActionDefaultBinding, type ActionsRegistry } from './registry';\nimport { pushOwner, ScopeNode } from './scopeNode';\n\n/** @internal Provided by `<ActionsProvider>`, `<InputScope>` and `<Yoke>`. */\nexport const ActionsContext = createContext<ActionsRegistry | null>(null);\n\n/** The deps an action is invoked with: its declared `requires` when it has\n * one, the legacy fixed bag otherwise. The fixed bag has no `applyOps`, so an\n * action that needs the consumer's history must declare it. */\nfunction depsFor(a: Action, r: DepRegistry | null): Record<string, unknown> {\n if (!r) return {};\n if (a.requires) return buildDepsFromRequires(a, r) as Record<string, unknown>;\n return {\n selection: r.get('selection' as DepName),\n scene: r.get('scene' as DepName),\n history: r.get('history' as DepName),\n view: r.get('view' as DepName),\n activeTool: r.get('activeTool' as DepName),\n booleansAdapter: r.get('booleansAdapter' as DepName),\n };\n}\n\n/**\n * One node of the actions tree: the actions registered at it, over its\n * parent's. Each id holds a stack of registrants, newest live, so a displaced\n * registrant is restored when the one above it leaves. Every read the registry\n * answers — `list`, `trigger`, `begin` — starts at the node's leaf.\n */\nexport class ActionsNode extends ScopeNode<ActionsNode> {\n private readonly actions = new Map<string, Action[]>();\n private readonly muted = new Map<string, number>();\n private readonly dispatchers: Dispatcher[] = [];\n private cache: { version: number; leaf: ActionsNode; list: readonly Action[] } | null = null;\n /** Called on `activate`, so a scope's dep and tool nodes move with it. */\n readonly onActivate: (() => void)[] = [];\n\n constructor(\n parent: ActionsNode | null,\n descends: boolean,\n private readonly contextDeps: () => DepRegistry | null,\n ) {\n super(parent, descends);\n NODES.set(this.registry, this);\n }\n\n private resolve(id: string): Action | undefined {\n for (const n of this.chain()) {\n if (n.muted.has(id)) return undefined;\n const a = n.actions.get(id)?.at(-1);\n if (a) return a;\n }\n return undefined;\n }\n\n private snapshot(): readonly Action[] {\n const leaf = this.start();\n const cached = this.cache;\n if (cached && cached.version === this.tree.version && cached.leaf === leaf) return cached.list;\n const ids = new Set<string>();\n for (const n of leaf.chain()) for (const id of n.actions.keys()) ids.add(id);\n const out: Action[] = [];\n for (const id of ids) {\n const a = leaf.resolve(id);\n if (a) out.push(a);\n }\n const list = Object.freeze(out);\n this.cache = { version: this.tree.version, leaf, list };\n return list;\n }\n\n private deps(): DepRegistry | null {\n for (const n of this.chain()) {\n const r = n.contextDeps();\n if (r) return r;\n }\n return null;\n }\n\n private dispatcher(): Dispatcher | null {\n for (const n of this.chain()) {\n const d = n.dispatchers.at(-1);\n if (d) return d;\n }\n return null;\n }\n\n override activate(): void {\n super.activate();\n for (const f of this.onActivate) f();\n }\n\n readonly registry: ActionsRegistry = {\n register: (action: Action) => {\n validateActionId(action.id);\n validateActionDefaultBinding(action);\n const stack = this.actions.get(action.id);\n if (stack) stack.push(action);\n else this.actions.set(action.id, [action]);\n this.changed();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const cur = this.actions.get(action.id);\n if (!cur) return;\n // Our own entry, wherever it now sits: a registrant that was already\n // displaced must take itself out without disturbing the one above it.\n const i = cur.lastIndexOf(action);\n if (i === -1) return;\n cur.splice(i, 1);\n if (cur.length === 0) this.actions.delete(action.id);\n this.changed();\n };\n },\n unregister: (id: string) => {\n if (this.actions.delete(id)) this.changed();\n },\n mute: (id: string) => {\n this.muted.set(id, (this.muted.get(id) ?? 0) + 1);\n this.changed();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const held = this.muted.get(id);\n if (held === undefined) return;\n if (held > 1) this.muted.set(id, held - 1);\n else this.muted.delete(id);\n this.changed();\n };\n },\n list: () => this.snapshot(),\n trigger: (id: string, params?: Record<string, unknown>) => {\n const leaf = this.start();\n const a = leaf.resolve(id);\n if (!a) return false;\n try {\n if (a.invoker && a.invoker.timing === 'immediate') {\n a.invoker.run(depsFor(a, leaf.deps()) as never, params);\n }\n } catch (err) {\n console.error(`weasel ActionsRegistry: action \"${id}\" threw`, err);\n }\n return true;\n },\n subscribe: (listener: () => void) => {\n this.tree.listeners.add(listener);\n return () => {\n this.tree.listeners.delete(listener);\n };\n },\n setDispatcher: (d: Dispatcher | null) => pushOwner(this.dispatchers, d),\n begin: (id: string, params?: Record<string, unknown>) => {\n const leaf = this.start();\n const a = leaf.resolve(id);\n const disp = leaf.dispatcher();\n if (!a || !disp) return null;\n return disp.beginUiOngoing(id, depsFor(a, leaf.deps()) as never, params);\n },\n activate: () => this.activate(),\n isActive: () => this.isActive(),\n };\n}\n\nconst NODES = new WeakMap<ActionsRegistry, ActionsNode>();\n\n/** The tree node behind `registry`, when it is one of ours. */\nexport function actionsNodeOf(registry: ActionsRegistry | null): ActionsNode | null {\n return registry ? (NODES.get(registry) ?? null) : null;\n}\n\n/**\n * @experimental\n * Mounts a root `ActionsRegistry` for its lifetime. Children call\n * `useActionsRegistry()` or `useAction()` to participate. Mounts no input\n * listener of its own — the gesture dispatcher owns input.\n */\nexport function ActionsProvider({ children }: { children: ReactNode }): ReactElement {\n // `trigger` consults the dep registry in scope, so actions can be fired\n // imperatively from ActionBar / palette callers.\n const depReg = useOptionalDepRegistry();\n const depRegRef = useLatest<DepRegistry | null>(depReg);\n const node = useMemo(() => new ActionsNode(null, true, () => depRegRef.current), [depRegRef]);\n return <ActionsContext.Provider value={node.registry}>{children}</ActionsContext.Provider>;\n}\n\n/**\n * `import.meta.env.DEV` read through a cast — core must not depend on a\n * bundler's ambient augmentation (`vite/client`) to compile. Mirrors the same\n * cast in SceneCanvas.tsx, dispatcher.ts and buildDeps.ts.\n */\nconst IS_DEV: boolean = (() => {\n try {\n return Boolean((import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV);\n } catch {\n return false;\n }\n})();\n\n/**\n * @experimental\n * Returns the `ActionsRegistry` in scope, or `null` when there is none.\n */\nexport function useActionsRegistry(): ActionsRegistry | null {\n return useContext(ActionsContext);\n}\n\n/**\n * @experimental\n * Register an `Action` for the lifetime of the calling component. No-op (with\n * a dev-only warning) when no `ActionsProvider` is in scope. Re-registers on\n * `action` reference change (consumers should memoize stable identities to\n * avoid churn).\n */\nexport function useAction(action: Action): void {\n const reg = useActionsRegistry();\n useEffect(() => {\n if (!reg) {\n if (IS_DEV) {\n console.warn(\n `useAction(\"${action.id}\"): no <ActionsProvider> is in scope, so the action was not registered and its bindings will never fire.`,\n );\n }\n return;\n }\n return reg.register(action);\n }, [reg, action]);\n}\n","/**\n * @experimental\n * Input scopes and yokes: the tiers between a root registry and a canvas.\n * Design: docs/proposals/2026-09-27-input-scopes.md.\n */\nimport { useContext, useEffect, useMemo, type ReactElement, type ReactNode } from 'react';\nimport { ActionsContext, ActionsNode, actionsNodeOf, useActionsRegistry } from './ActionsProvider';\nimport { DepNode, DepRegistryContext, depNodeOf, useOptionalDepRegistry } from './depRegistry';\nimport { ActiveToolNodeContext, ToolNode } from './activeToolContext';\n\n/**\n * @experimental\n * Canvases that share input on purpose: the active tool, the gesture in\n * flight, history and yoke-wide actions. Made once with `useYoke()` where the\n * sharing is decided, and passed to each canvas that joins it (`yoke={yoke}`)\n * and to `<Yoke value={yoke}>` around anything else that should reach it — a\n * toolbar, say. The members can sit anywhere in the tree: the handle, not the\n * tree, says who shares.\n */\nexport interface Yoke {\n /** @internal */\n readonly actions: ActionsNode;\n /** @internal */\n readonly deps: DepNode;\n /** @internal */\n readonly tools: ToolNode;\n}\n\n/** The three nodes of a tier, under `parent`'s or the ones in scope, with\n * activation carried across all three. */\nfunction useNodes(\n descends: boolean,\n ownsTool: boolean,\n parent: Yoke | undefined,\n): Yoke {\n const parentActions = useActionsRegistry();\n const parentDeps = useOptionalDepRegistry();\n const parentTools = useContext(ActiveToolNodeContext);\n const pa = parent ? parent.actions : actionsNodeOf(parentActions);\n const pd = parent ? parent.deps : depNodeOf(parentDeps);\n const pt = parent ? parent.tools : parentTools;\n const nodes = useMemo<Yoke>(() => {\n const deps = new DepNode(pd, descends);\n const tools = new ToolNode(pt, descends, ownsTool, null);\n const actions = new ActionsNode(pa, descends, () => deps.registry);\n actions.onActivate.push(() => deps.activate(), () => tools.activate());\n return { actions, deps, tools };\n }, [pa, pd, pt, descends, ownsTool]);\n useEffect(() => {\n const leave = [nodes.deps.mount(), nodes.tools.mount(), nodes.actions.mount()];\n return () => {\n for (const f of leave) f();\n };\n }, [nodes]);\n return nodes;\n}\n\nfunction Provide({ nodes, children }: { nodes: Yoke; children: ReactNode }): ReactElement {\n return (\n <DepRegistryContext.Provider value={nodes.deps.registry}>\n <ActionsContext.Provider value={nodes.actions.registry}>\n <ActiveToolNodeContext.Provider value={nodes.tools}>{children}</ActiveToolNodeContext.Provider>\n </ActionsContext.Provider>\n </DepRegistryContext.Provider>\n );\n}\n\n/** Props for `<InputScope>`. */\nexport interface InputScopeProps {\n /** The yoke this scope joins. Omitted, it sits under the registries in\n * scope and keeps a tool of its own. */\n yoke?: Yoke;\n children: ReactNode;\n}\n\n/**\n * @experimental\n * One canvas's input: actions, deps and a tool of its own, under whichever\n * registries are in scope (or its yoke's). What the canvas registers stays\n * here; what it looks up is answered here first, then by the tiers above.\n * With nothing in scope it is a root.\n *\n * Chrome above calls `trigger` / `begin` / `useActiveToolContext` on its own\n * registries, and those reach the active scope: the one last activated — by a\n * pointerdown or wheel — or the newest where none has been.\n */\nexport function InputScope({ yoke, children }: InputScopeProps): ReactElement {\n const nodes = useNodes(false, yoke === undefined, yoke);\n return <Provide nodes={nodes}>{children}</Provide>;\n}\n\n/**\n * @experimental\n * Make a yoke for canvases to join, under the registries in scope where it is\n * called. It lives as long as the calling component.\n */\nexport function useYoke(): Yoke {\n return useNodes(true, true, undefined);\n}\n\n/** Props for `<Yoke>`. */\nexport interface YokeProps {\n value: Yoke;\n children: ReactNode;\n}\n\n/**\n * @experimental\n * Put `value` in scope for what is not a canvas — a toolbar, a status bar — so\n * its actions, deps and tool reads reach the yoke and, through it, the member\n * canvas last used.\n */\nexport function Yoke({ value, children }: YokeProps): ReactElement {\n return <Provide nodes={value}>{children}</Provide>;\n}\n","import { useEffect, useMemo, useRef } from 'react';\nimport { useActionsRegistry } from './ActionsProvider';\nimport type { ActionsRegistry, UiOngoingControl } from './registry';\nimport { useLatest } from '@weasel-js/react';\n\n/**\n * One UI control's hold on an ongoing action — the handle a color picker, a\n * slider or a swatch drives the action through, the way a drag drives one\n * through a gesture.\n *\n * - `input(params)` opens the action on the first call and moves it on every\n * later one: the live preview.\n * - `commit(params?)` moves it to `params`, if given, and ends it as one\n * undoable edit. With nothing open, a commit carrying params is a whole edit\n * on its own — a click on a swatch, a switch of paint kind.\n * - `cancel()` ends an open edit without keeping it.\n *\n * All three are no-ops when no action is reachable, so a control renders the\n * same with or without a canvas in scope.\n */\nexport interface OngoingAction {\n input(params: Record<string, unknown>): void;\n commit(params?: Record<string, unknown>): void;\n cancel(): void;\n}\n\n/**\n * Drive the ongoing action `actionId` from a UI control: {@link OngoingAction}.\n *\n * An edit left open when the control unmounts, or when `actionId` changes, is\n * committed — it is what the user was looking at when the control went away.\n * The returned object is stable for the life of the component.\n */\nexport function useOngoingAction(actionId: string): OngoingAction {\n const reg = useActionsRegistry();\n const regRef = useLatest<ActionsRegistry | null>(reg);\n const idRef = useLatest(actionId);\n const ctrlRef = useRef<UiOngoingControl | null>(null);\n\n const edit = useMemo<OngoingAction>(() => {\n const end = (reason: 'commit' | 'cancel'): void => {\n const ctrl = ctrlRef.current;\n ctrlRef.current = null;\n ctrl?.end(reason);\n };\n return {\n input(params) {\n if (ctrlRef.current) ctrlRef.current.update(params);\n else ctrlRef.current = regRef.current?.begin(idRef.current, params) ?? null;\n },\n commit(params) {\n if (params !== undefined) {\n if (ctrlRef.current) ctrlRef.current.update(params);\n else ctrlRef.current = regRef.current?.begin(idRef.current, params) ?? null;\n }\n end('commit');\n },\n cancel() {\n end('cancel');\n },\n };\n }, [regRef, idRef]);\n\n useEffect(() => () => edit.commit(), [edit, actionId]);\n\n return edit;\n}\n","// src/contributions/useContributions.ts\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { activeModeOf, type ModeRegistry } from '@weasel-js/modes';\nimport type { ScopedBinding } from '../interactions/dispatcher/matcher';\nimport { useActiveToolContext } from '../interactions/actions/activeToolContext';\nimport { useActionsRegistry } from '../interactions/actions/ActionsProvider';\nimport {\n buildToolOffhandBindings,\n makeToolOffhandAction,\n offhandKeyFor,\n type ToolOffhandBindingSpec,\n} from '../interactions/actions/toolOffhand';\nimport { reportRouteConflicts } from '../tools/routing/reflection/conflicts';\nimport type { HotkeyTrigger } from './types';\nimport { scopeBindings } from './assemble';\nimport { liveScope } from './eligibility';\nimport type { Contribution, OverlayPosition } from './types';\nimport { isDev } from '../devFlag';\nimport { sameList, useStableByContent } from '@weasel-js/react';\nimport type { KernelOverlay } from '../index';\n\n/** Options for {@link useContributions}. */\nexport interface UseContributionsOptions<TOverlay = KernelOverlay> {\n /** Every registry entry, in declaration order. Order decides which of two\n * same-specificity bindings in one scope tier wins. */\n entries: readonly Contribution<TOverlay>[];\n /** Desired focused entry id, or `null` for none. First-mount-wins against\n * the shared `ActiveToolContext` — see `useTools` for the full semantics. */\n focused: string | null;\n /** The modes the canvas can be in. The dev-time route-conflict check reads\n * them to decide whether two gated actions can ever compete; without a\n * registry it checks against the kit's `DEFAULT_MODES`. */\n modes?: ModeRegistry;\n}\n\n/** The assembled registry {@link useContributions} returns. */\nexport interface ContributionsApi<TOverlay = KernelOverlay> {\n /** Every entry, as passed in. */\n entries: readonly Contribution<TOverlay>[];\n /** Currently focused entry id, or `null` when nothing is focused. */\n focused: string | null;\n /** Focus an entry, or pass `null` to focus none. Writes through to the\n * shared `ActiveToolContext`. */\n setFocused: (id: string | null) => void;\n /** Every live binding, tiered by the declaring entry's eligibility. */\n scopedBindings(): ScopedBinding[];\n /** Overlays of every live entry declaring `position`, ordered active, then\n * hotkey, then ambient. */\n overlays(position?: OverlayPosition): TOverlay[];\n}\n\n/**\n * Assembles one registry: every entry's bindings and overlays, each tiered by\n * what the entry declares about its own eligibility rather than by which\n * argument a consumer passed it in.\n *\n * Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /\n * `<SceneCanvas>`, which mount one internally): focus and held-key state live\n * in the context so the gesture dispatcher and every sibling caller read the\n * same source of truth.\n */\nexport function useContributions<TOverlay = KernelOverlay>(\n opts: UseContributionsOptions<TOverlay>,\n): ContributionsApi<TOverlay> {\n const ctx = useActiveToolContext();\n const actionsRegistry = useActionsRegistry();\n\n // First-mount sync: if the context's slot is still unseeded and the caller\n // wants a tool, push it. Captured at first render; the setState runs in a\n // post-commit effect so it never updates state during render.\n const firstMountRef = useRef<{ sync: boolean } | null>(null);\n const isFirstRender = firstMountRef.current == null;\n if (firstMountRef.current == null) firstMountRef.current = { sync: ctx.active === null && opts.focused !== null };\n useEffect(() => {\n const first = firstMountRef.current;\n if (!first?.sync) return;\n first.sync = false;\n ctx.setActive(opts.focused);\n // First-mount sync only — deliberately runs once after mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const focused = isFirstRender && ctx.active === null && opts.focused !== null\n ? opts.focused\n : ctx.active;\n\n // Consumers commonly rebuild the entry list every render; identity follows\n // its contents, so everything keyed on it below changes only when they do.\n const entries = useStableByContent(opts.entries, sameList);\n const engaged = ctx.hotkeyStack;\n\n const setFocused = useCallback((id: string | null) => { ctx.setActive(id); }, [ctx]);\n\n /** Live eligibility state, plus the entries ordered so that hotkey-engaged\n * ones come first — stack order breaks ties within the hotkey tier. */\n const snapshot = useCallback(() => {\n const engagedIds = new Set(engaged);\n const ordered: Contribution<TOverlay>[] = [];\n for (const id of engaged) {\n const entry = entries.find((e) => e.id === id);\n if (entry && !ordered.includes(entry)) ordered.push(entry);\n }\n for (const entry of entries) {\n if (!ordered.includes(entry)) ordered.push(entry);\n }\n return {\n ordered,\n state: { focusedId: focused, engagedIds },\n };\n }, [entries, focused, engaged]);\n\n const scopedBindings = useCallback((): ScopedBinding[] => {\n const { ordered, state } = snapshot();\n return scopeBindings(ordered, state);\n }, [snapshot]);\n\n const overlays = useCallback((position: OverlayPosition = 'top'): TOverlay[] => {\n const { ordered, state } = snapshot();\n const active: TOverlay[] = [];\n const hotkey: TOverlay[] = [];\n const ambient: TOverlay[] = [];\n for (const entry of ordered) {\n if (!entry.overlay) continue;\n if ((entry.overlayPosition ?? 'top') !== position) continue;\n const layers = Array.isArray(entry.overlay) ? entry.overlay : [entry.overlay];\n const scope = liveScope(entry.id, entry.eligibility ?? {}, state);\n if (scope === 'active') active.push(...layers);\n else if (scope === 'hotkey') hotkey.push(...layers);\n else if (scope === 'ambient') ambient.push(...layers);\n }\n return [...active, ...hotkey, ...ambient];\n }, [snapshot]);\n\n useOffhandAction(entries);\n\n // Route-conflict check. Two entries declaring the same (phase, gesture, arg,\n // target, modifiers) tuple in one scope are resolved by declaration order and\n // almost certainly not as either author intended. This is where the entry set\n // is assembled, so this is where it looks.\n //\n // Dev-only, and deduped on a signature of the entry set: the check walks\n // every binding of every entry, and consumers usually rebuild the entry list\n // each render. Actions are read inside the effect, after the registrations\n // that ran in child effects have landed.\n const lastConflictSigRef = useRef<{ sig: string; modes: ModeRegistry | undefined } | null>(null);\n const entrySig = entries.map((e) => e.id).join(',');\n const modesRegistry = opts.modes;\n useEffect(() => {\n if (!isDev()) return;\n const last = lastConflictSigRef.current;\n if (last?.sig === entrySig && last.modes === modesRegistry) return;\n lastConflictSigRef.current = { sig: entrySig, modes: modesRegistry };\n // An entry can be in both buckets and usually is: every tool `defineTool`\n // builds declares `focus: true`, and an ambient one carries `always: true`\n // on top of that. Sorting on \"not focus-eligible\" put ambient tools in the\n // registry bucket, which is never compared against itself — registry tools\n // take turns in the active slot — so ambient-vs-ambient went unreported.\n const registry: Contribution<TOverlay>[] = [];\n const ambient: Contribution<TOverlay>[] = [];\n for (const entry of entries) {\n if (entry.eligibility?.focus) registry.push(entry);\n if (entry.eligibility?.always || entry.eligibility?.claimed) ambient.push(entry);\n }\n reportRouteConflicts({\n registry,\n ambient,\n actions: actionsRegistry?.list() ?? [],\n ...(modesRegistry ? { modes: modesRegistry.list().map(activeModeOf) } : {}),\n });\n }, [entrySig, entries, actionsRegistry, modesRegistry]);\n\n // Memoized so consumers using the result as an effect dep don't see identity\n // churn every render — which loops infinitely when the consumer setStates\n // from inside such an effect.\n return useMemo(\n () => ({ entries, focused, setFocused, scopedBindings, overlays }),\n [entries, focused, setFocused, scopedBindings, overlays],\n );\n}\n\n/**\n * Registers the consolidated `tool.offhand` action for every entry declaring\n * an `offhand` trigger, into the nearest `<ActionsProvider>`; its invoker\n * reads `params.toolId` off the matched binding. `useContributions` calls it,\n * and so does any host that assembles its entries above its own provider —\n * `<SceneCanvas>` does — since a null registry here registers nothing.\n */\nexport function useOffhandAction(entries: readonly Contribution<unknown>[]): void {\n const actionsRegistry = useActionsRegistry();\n const offhandSig = JSON.stringify(entries\n .filter((e) => e.eligibility?.offhand)\n .map((e) => [e.id, e.eligibility.offhand]));\n useEffect(() => {\n const pairs = JSON.parse(offhandSig) as [string, HotkeyTrigger][];\n if (!actionsRegistry || pairs.length === 0) return;\n const specs: ToolOffhandBindingSpec[] = pairs.map(([toolId, trigger]) => (\n { toolId, key: offhandKeyFor(trigger) }\n ));\n return actionsRegistry.register(makeToolOffhandAction(buildToolOffhandBindings(specs)));\n }, [actionsRegistry, offhandSig]);\n}\n","// src/tools/useTools.ts\nimport { useCallback, useMemo } from 'react';\nimport type { ModeRegistry } from '@weasel-js/modes';\nimport { dlog } from '../dlog';\nimport type { AnyTool, AnyToolOf } from './types';\nimport type { HotkeyTrigger } from '../contributions/types';\nimport { useActiveToolContext } from '../interactions/actions/activeToolContext';\nimport { useContributions } from '../contributions/useContributions';\nimport type { Contribution, Eligibility, OverlayPosition } from '../contributions/types';\nimport type { KernelOverlay } from '../index';\nimport { sameList, useLatest, useStableByContent } from '@weasel-js/react';\n\n/** Options for `useTools`: which tools exist, which one starts active, and\n * which run continuously regardless of the active one. */\nexport interface UseToolsOptions<TOverlay = KernelOverlay> {\n /** Initial active-slot tool id, which must exist in `registry`. Omit, or\n * pass `null`, for no active tool: only hotkey and ambient bindings run. */\n active?: string | null;\n /** Tools eligible for the active slot or hotkey slot. The keys are the\n * tool ids; the values are the tool records. A tool with `hotkey` set\n * is wired into the hotkey slot whenever the engagement state matches. */\n registry: Record<string, AnyToolOf<TOverlay>>;\n /** Always-on entries — tools or other contributions, live regardless of\n * the active slot. */\n ambient?: readonly Contribution<TOverlay>[];\n /** The modes the canvas can be in, read by the dev-time route-conflict\n * check; without a registry it checks against the kit's `DEFAULT_MODES`. */\n modes?: ModeRegistry;\n}\n\n/** The tool registry's runtime surface: which tool is active, which is\n * temporarily held by a hotkey, and how to change either. */\nexport interface ToolsApi<TOverlay = KernelOverlay> {\n /** Current active-slot tool id, or `null` when no tool is active. */\n active: string | null;\n /** Set the active-slot tool, or `null` to clear it. The gesture dispatcher\n * watches the active tool and cancels any in-flight handle itself. */\n setActive: (id: string | null) => void;\n /** Currently hotkey-engaged tool id (or `null`). Derived as the top of\n * the hotkey stack for backwards compat with the pre-stack API. */\n hotkeyEngaged: string | null;\n /** Engage a hotkey-slot tool by id. */\n engageHotkey: (id: string) => void;\n /** Disengage the hotkey-slot tool, if any. */\n disengageHotkey: () => void;\n /** All always-on entries, in registration order. */\n ambient: readonly Contribution<TOverlay>[];\n /** Full registry — for userland UI (palette buttons, etc.). */\n registry: Readonly<Record<string, AnyToolOf<TOverlay>>>;\n /** Returns true if a tool with the given id is in the registry or ambient list. */\n has(id: string): boolean;\n /** All overlay layers from currently-engaged tools (active slot, hotkey\n * slot if engaged, all ambient slot tools) that declare `position`.\n * Filters out tools with no `overlay` field. Order: active, then hotkey\n * (if engaged), then ambient (registration order). */\n getActiveOverlays(position?: OverlayPosition): TOverlay[];\n}\n\n/** The slot a caller passed a tool in, restated as declared eligibility.\n * `ToolDef.hotkey` becomes `offhand` — it is the same declaration, read off\n * the authored form via the `def` reflection handle. A tool that already\n * declares what its slot implies is returned as-is: `ToolsApi.registry`\n * hands back the objects the caller passed, and consumers compare identity. */\nfunction declareSlot<T extends Contribution<unknown>>(tool: T, slot: 'focus' | 'always'): T {\n const hotkey = (tool.def as { hotkey?: HotkeyTrigger } | undefined)?.hotkey;\n const eligibility: Eligibility = {\n ...tool.eligibility,\n [slot]: true,\n ...(hotkey ? { offhand: hotkey } : {}),\n };\n return sameEligibility(tool.eligibility, eligibility) ? tool : { ...tool, eligibility };\n}\n\nconst NO_AMBIENT: readonly never[] = [];\n\n/** `registry` and `ambient` as last passed, kept by identity for as long as\n * every tool in them is the same object under the same id. */\nfunction useStableSources<T extends AnyTool, A extends Contribution<unknown>>(\n registry: Record<string, T>,\n ambient: readonly A[] | undefined,\n): { registry: Record<string, T>; ambient: readonly A[] } {\n return useStableByContent(\n { registry, ambient: ambient ?? NO_AMBIENT },\n (a, b) => sameRecord(a.registry, b.registry) && sameList(a.ambient, b.ambient),\n );\n}\n\nfunction sameRecord<T>(a: Record<string, T>, b: Record<string, T>): boolean {\n const ak = Object.keys(a);\n if (ak.length !== Object.keys(b).length) return false;\n return ak.every((k) => k in b && a[k] === b[k]);\n}\n\nfunction sameEligibility(a: Eligibility | undefined, b: Eligibility): boolean {\n if (!a) return false;\n const keys = new Set([...Object.keys(a), ...Object.keys(b)]) as Set<keyof Eligibility>;\n for (const key of keys) if (a[key] !== b[key]) return false;\n return true;\n}\n\n/**\n * Manages the active tool and hotkey slot.\n *\n * A thin shim over {@link useContributions}: the `registry` / `ambient`\n * arguments are restated as declared eligibility (`focus` / `always`), and\n * assembly happens in one place for tools and non-tool contributions alike.\n *\n * Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /\n * `<SceneCanvas>`, which mount one internally) in scope: active/hotkey state\n * lives in the context so the gesture dispatcher and any sibling\n * `useTools` calls all read the same source of truth.\n *\n * **First-mount-wins semantics**: if the context's slot is unseeded (no\n * `initialActive`, nothing set yet) on first mount, `useTools` pushes\n * `opts.active` to the context. Subsequent mounts respect whatever the\n * context currently holds (the first caller wins).\n */\nexport function useTools<TOverlay = KernelOverlay>(\n opts: UseToolsOptions<TOverlay>,\n): ToolsApi<TOverlay> {\n const initialActive = opts.active ?? null;\n if (initialActive !== null && !(initialActive in opts.registry)) {\n throw new Error(`useTools: active \"${initialActive}\" not in registry`);\n }\n\n const ctx = useActiveToolContext();\n\n // Rebuilt when the tools themselves change, not the objects holding them:\n // callers commonly pass `opts.registry` / `opts.ambient` as literals made\n // every render, while a tool redefined under an existing id must replace it.\n const sources = useStableSources(opts.registry, opts.ambient);\n const slotted = useMemo(() => {\n const registry: Record<string, AnyToolOf<TOverlay>> = {};\n for (const [id, tool] of Object.entries(sources.registry)) {\n registry[id] = declareSlot(tool, 'focus');\n }\n const ambient = sources.ambient.map((t) => declareSlot(t, 'always'));\n const byId = new Map<string, Contribution<TOverlay>>();\n for (const tool of [...Object.values(registry), ...ambient]) {\n const prior = byId.get(tool.id);\n if (prior) byId.set(tool.id, { ...tool, eligibility: { ...prior.eligibility, ...tool.eligibility } });\n else byId.set(tool.id, tool);\n }\n return { registry, ambient, entries: [...byId.values()] };\n }, [sources]);\n\n const contributions = useContributions<TOverlay>({\n entries: slotted.entries,\n focused: initialActive,\n ...(opts.modes ? { modes: opts.modes } : {}),\n });\n\n const hotkeyEngaged = ctx.hotkeyStack.at(-1) ?? null;\n\n // Refs so the memoized callbacks below see latest values without\n // re-creating themselves.\n const slottedRef = useLatest(slotted);\n const activeRef = useLatest(contributions.focused);\n const hotkeyRef = useLatest(hotkeyEngaged);\n\n const setFocused = contributions.setFocused;\n const setActive = useCallback(\n (id: string | null) => {\n if (id !== null && !(id in slottedRef.current.registry)) {\n throw new Error(`setActive: \"${id}\" not in registry`);\n }\n dlog('tools', 'active:', activeRef.current, '→', id);\n setFocused(id);\n },\n [setFocused, slottedRef, activeRef],\n );\n\n const engageHotkey = useCallback(\n (id: string) => {\n if (!(id in slottedRef.current.registry)) {\n throw new Error(`engageHotkey: \"${id}\" not in registry`);\n }\n dlog('tools', 'hotkey engaged:', id);\n ctx.pushHotkey(id);\n },\n [ctx, slottedRef],\n );\n\n const disengageHotkey = useCallback(() => {\n if (hotkeyRef.current) dlog('tools', 'hotkey disengaged:', hotkeyRef.current);\n ctx.popHotkey();\n }, [ctx, hotkeyRef]);\n\n // May be called while rendering, so it reads this render's tools, not a ref.\n const has = useCallback(\n (id: string): boolean =>\n id in slotted.registry\n || slotted.ambient.some((t) => t.id === id),\n [slotted],\n );\n\n // Memoize the returned ToolsApi so consumers using `tools` as a dep (e.g.\n // SceneCanvas's `onToolsCreated` useEffect) don't see identity churn on\n // every render — which otherwise loops infinitely when the consumer\n // setStates from inside `onToolsCreated`.\n const active = contributions.focused;\n const getActiveOverlays = contributions.overlays;\n return useMemo(\n () => ({\n active,\n setActive,\n hotkeyEngaged,\n engageHotkey,\n disengageHotkey,\n ambient: slotted.ambient,\n registry: slotted.registry,\n has,\n getActiveOverlays,\n }),\n [active, setActive, hotkeyEngaged, engageHotkey, disengageHotkey, has, getActiveOverlays, slotted],\n );\n}\n"]}