@zeey4d/react-native-gesture-engine 1.0.0 → 1.0.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/EventBus.ts","../src/core/types.ts","../src/input/TouchInputProvider.ts","../src/input/SensorInputProvider.ts","../src/input/HardwareInputProvider.ts","../src/input/CameraInputProvider.ts","../src/processing/NoiseFilter.ts","../src/processing/VelocityCalculator.ts","../src/processing/AngleDetector.ts","../src/processing/ThresholdNormalizer.ts","../src/processing/StreamBuffer.ts","../src/recognition/base/BaseRecognizer.ts","../src/recognition/discrete/TapRecognizer.ts","../src/recognition/discrete/DoubleTapRecognizer.ts","../src/recognition/continuous/PanRecognizer.ts","../src/recognition/continuous/PinchRecognizer.ts","../src/recognition/continuous/RotationRecognizer.ts","../src/recognition/spatial/EdgeSwipeRecognizer.ts","../src/recognition/spatial/CornerRecognizer.ts","../src/recognition/sensor/ShakeRecognizer.ts","../src/recognition/sensor/TiltRecognizer.ts","../src/recognition/sensor/WristFlickRecognizer.ts","../src/recognition/sequence/SequenceRecognizer.ts","../src/recognition/symbolic/SymbolRecognizer.ts","../src/conflict/GesturePriorityQueue.ts","../src/conflict/LockManager.ts","../src/conflict/ConflictResolver.ts","../src/actions/ActionDispatcher.ts","../src/actions/NavigationAction.ts","../src/actions/UITransformAction.ts","../src/actions/SystemAction.ts","../src/actions/CustomAction.ts","../src/feedback/HapticFeedback.ts","../src/feedback/VisualFeedback.ts","../src/feedback/AccessibilityFeedback.ts","../src/GestureEngine.ts","../src/hooks/useGestureEngine.ts","../src/hooks/useShakeGesture.ts","../src/hooks/useEdgeSwipe.ts","../src/hooks/useGestureSequence.ts"],"names":["InputType","TouchType","SensorType","CardinalDirection","RecognizerState","EventChannel","useRef","useEffect"],"mappings":";;;;;;;;;;AAqBO,IAAM,WAAN,MAAoC;AAAA,EAApC,WAAA,GAAA;AAEL;AAAA,IAAA,IAAA,CAAQ,SAAA,uBAAgB,GAAA,EAA0C;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUlE,EAAA,CAA2B,SAAY,OAAA,EAAsC;AAC3E,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA,EAAG;AAChC,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAA,kBAAS,IAAI,KAAK,CAAA;AAAA,IACvC;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA,CAAG,IAAI,OAAO,CAAA;AAGxC,IAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,OAAO,CAAA;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAA,CAA6B,SAAY,IAAA,EAAgC;AACvE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAC3C,IAAA,IAAI,CAAC,QAAA,EAAU;AAGf,IAAA,KAAA,MAAW,OAAA,IAAW,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC1C,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,MACd,SAAS,KAAA,EAAO;AAId,QAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,EAAS;AAC7C,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,OAAO,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAA4B,SAAY,OAAA,EAAgC;AACtE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,OAAO,CAAA;AAC3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,OAAO,OAAO,CAAA;AACvB,MAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,QAAA,IAAA,CAAK,SAAA,CAAU,OAAO,OAAO,CAAA;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AACF;;;AC3EO,IAAK,SAAA,qBAAAA,UAAAA,KAAL;AACL,EAAAA,WAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,WAAA,QAAA,CAAA,GAAS,QAAA;AACT,EAAAA,WAAA,UAAA,CAAA,GAAW,UAAA;AACX,EAAAA,WAAA,QAAA,CAAA,GAAS,QAAA;AAJC,EAAA,OAAAA,UAAAA;AAAA,CAAA,EAAA,SAAA,IAAA,EAAA;AAQL,IAAK,SAAA,qBAAAC,UAAAA,KAAL;AACL,EAAAA,WAAA,KAAA,CAAA,GAAM,KAAA;AACN,EAAAA,WAAA,KAAA,CAAA,GAAM,KAAA;AACN,EAAAA,WAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,WAAA,UAAA,CAAA,GAAW,UAAA;AAJD,EAAA,OAAAA,UAAAA;AAAA,CAAA,EAAA,SAAA,IAAA,EAAA;AAQL,IAAK,UAAA,qBAAAC,WAAAA,KAAL;AACL,EAAAA,YAAA,eAAA,CAAA,GAAgB,eAAA;AAChB,EAAAA,YAAA,WAAA,CAAA,GAAY,WAAA;AAFF,EAAA,OAAAA,WAAAA;AAAA,CAAA,EAAA,UAAA,IAAA,EAAA;AAiEL,IAAK,iBAAA,qBAAAC,kBAAAA,KAAL;AACL,EAAAA,mBAAA,IAAA,CAAA,GAAK,IAAA;AACL,EAAAA,mBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,mBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,mBAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,mBAAA,QAAA,CAAA,GAAS,SAAA;AACT,EAAAA,mBAAA,SAAA,CAAA,GAAU,UAAA;AACV,EAAAA,mBAAA,UAAA,CAAA,GAAW,WAAA;AACX,EAAAA,mBAAA,WAAA,CAAA,GAAY,YAAA;AACZ,EAAAA,mBAAA,MAAA,CAAA,GAAO,MAAA;AATG,EAAA,OAAAA,kBAAAA;AAAA,CAAA,EAAA,iBAAA,IAAA,EAAA;AAgDL,IAAK,eAAA,qBAAAC,gBAAAA,KAAL;AACL,EAAAA,iBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,iBAAA,UAAA,CAAA,GAAW,UAAA;AACX,EAAAA,iBAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,iBAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,iBAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,iBAAA,QAAA,CAAA,GAAS,QAAA;AACT,EAAAA,iBAAA,WAAA,CAAA,GAAY,WAAA;AAPF,EAAA,OAAAA,gBAAAA;AAAA,CAAA,EAAA,eAAA,IAAA,EAAA;AA4DL,IAAK,YAAA,qBAAAC,aAAAA,KAAL;AAEL,EAAAA,cAAA,UAAA,CAAA,GAAW,WAAA;AAEX,EAAAA,cAAA,kBAAA,CAAA,GAAmB,mBAAA;AAEnB,EAAAA,cAAA,oBAAA,CAAA,GAAqB,qBAAA;AAErB,EAAAA,cAAA,kBAAA,CAAA,GAAmB,mBAAA;AAEnB,EAAAA,cAAA,kBAAA,CAAA,GAAmB,mBAAA;AAVT,EAAA,OAAAA,aAAAA;AAAA,CAAA,EAAA,YAAA,IAAA,EAAA;AAmOL,SAAS,UAAA,GAAuB;AACrC,EAAA,OAAO,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,IAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AACpE;;;AC9YO,IAAM,qBAAN,MAAmD;AAAA,EAGxD,YAAoB,QAAA,EAAqB;AAArB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAFpB,IAAA,IAAA,CAAQ,SAAA,GAAY,KAAA;AAAA,EAEsB;AAAA,EAE1C,IAAI,QAAA,GAAoB;AACtB,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EACnB;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAA,EAQG;AACP,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AAErB,IAAA,MAAM,SAAA,GAAuB;AAAA,MAC3B,IAAA,EAAA,KAAA;AAAA,MACA,GAAG,IAAA,CAAK,CAAA;AAAA,MACR,GAAG,IAAA,CAAK,CAAA;AAAA,MACR,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,KAAA,EAAO,CAAA;AAAA,MACP,QAAA,EAAU,CAAA;AAAA,MACV,kBAAkB,IAAA,CAAK;AAAA,KACzB;AAEA,IAAA,IAAA,CAAK,UAAU,SAAS,CAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAA,EAAgE;AACpE,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AAErB,IAAA,MAAM,SAAA,GAAuB;AAAA,MAC3B,IAAA,EAAA,KAAA;AAAA,MACA,GAAG,IAAA,CAAK,CAAA;AAAA,MACR,GAAG,IAAA,CAAK,CAAA;AAAA,MACR,YAAA,EAAc,CAAA;AAAA,MACd,YAAA,EAAc,CAAA;AAAA,MACd,SAAA,EAAW,CAAA;AAAA,MACX,SAAA,EAAW,CAAA;AAAA,MACX,KAAA,EAAO,CAAA;AAAA,MACP,QAAA,EAAU,CAAA;AAAA,MACV,kBAAkB,IAAA,CAAK;AAAA,KACzB;AAEA,IAAA,IAAA,CAAK,UAAU,SAAS,CAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,IAAA,EAMC;AACP,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AAErB,IAAA,MAAM,SAAA,GAAuB;AAAA,MAC3B,IAAA,EAAA,OAAA;AAAA,MACA,GAAG,IAAA,CAAK,MAAA;AAAA,MACR,GAAG,IAAA,CAAK,MAAA;AAAA,MACR,YAAA,EAAc,CAAA;AAAA,MACd,YAAA,EAAc,CAAA;AAAA,MACd,SAAA,EAAW,CAAA;AAAA,MACX,WAAW,IAAA,CAAK,QAAA;AAAA,MAChB,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,QAAA,EAAU,CAAA;AAAA,MACV,kBAAkB,IAAA,CAAK;AAAA,KACzB;AAEA,IAAA,IAAA,CAAK,UAAU,SAAS,CAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,IAAA,EAMF;AACP,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AAErB,IAAA,MAAM,SAAA,GAAuB;AAAA,MAC3B,IAAA,EAAA,UAAA;AAAA,MACA,GAAG,IAAA,CAAK,OAAA;AAAA,MACR,GAAG,IAAA,CAAK,OAAA;AAAA,MACR,YAAA,EAAc,CAAA;AAAA,MACd,YAAA,EAAc,CAAA;AAAA,MACd,SAAA,EAAW,CAAA;AAAA,MACX,WAAW,IAAA,CAAK,QAAA;AAAA,MAChB,KAAA,EAAO,CAAA;AAAA,MACP,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,kBAAkB,IAAA,CAAK;AAAA,KACzB;AAEA,IAAA,IAAA,CAAK,UAAU,SAAS,CAAA;AAAA,EAC1B;AAAA;AAAA,EAGQ,UAAU,SAAA,EAA4B;AAC5C,IAAA,MAAM,KAAA,GAAoB;AAAA,MACxB,IAAI,UAAA,EAAW;AAAA,MACf,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB,SAAA,EAAA,OAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACR;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,iCAA4B,KAAK,CAAA;AAAA,EACjD;AACF;;;ACrJA,IAAI,aAAA;AACJ,IAAI,SAAA;AAEJ,SAAS,iBAAA,GAAoB;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,UAAQ,cAAc,CAAA;AACtC,IAAA,aAAA,GAAgB,OAAA,CAAQ,aAAA;AACxB,IAAA,SAAA,GAAY,OAAA,CAAQ,SAAA;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AAAA,EACF;AACF;AAWO,IAAM,sBAAN,MAAoD;AAAA,EAMzD,WAAA,CACU,QAAA,EACR,gBAAA,GAAmB,GAAA,EACnB;AAFQ,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AANV,IAAA,IAAA,CAAQ,SAAA,GAAY,KAAA;AACpB,IAAA,IAAA,CAAQ,iBAAA,GAA+C,IAAA;AACvD,IAAA,IAAA,CAAQ,gBAAA,GAA8C,IAAA;AAQpD,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,gBAAgB,CAAA;AACrD,IAAA,iBAAA,EAAkB;AAAA,EACpB;AAAA,EAEA,IAAI,QAAA,GAAoB;AACtB,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAI,KAAK,SAAA,EAAW;AACpB,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAEjB,IAAA,IAAI,CAAC,aAAA,IAAiB,CAAC,SAAA,EAAW;AAChC,MAAA,OAAA,CAAQ,KAAK,qEAAqE,CAAA;AAClF,MAAA;AAAA,IACF;AAGA,IAAA,aAAA,CAAc,iBAAA,CAAkB,KAAK,gBAAgB,CAAA;AACrD,IAAA,SAAA,CAAU,iBAAA,CAAkB,KAAK,gBAAgB,CAAA;AAGjD,IAAA,IAAA,CAAK,oBAAoB,aAAA,CAAc,WAAA;AAAA,MACrC,CAAC,IAAA,KAA8C;AAC7C,QAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AAErB,QAAA,MAAM,UAAA,GAAyB;AAAA,UAC7B,IAAA,EAAA,eAAA;AAAA,UACA,GAAG,IAAA,CAAK,CAAA;AAAA,UACR,GAAG,IAAA,CAAK,CAAA;AAAA,UACR,GAAG,IAAA,CAAK;AAAA,SACV;AAEA,QAAA,MAAM,KAAA,GAAoB;AAAA,UACxB,IAAI,UAAA,EAAW;AAAA,UACf,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,UACpB,SAAA,EAAA,QAAA;AAAA,UACA,IAAA,EAAM;AAAA,SACR;AAEA,QAAA,IAAA,CAAK,QAAA,CAAS,iCAA4B,KAAK,CAAA;AAAA,MACjD;AAAA,KACF;AAGA,IAAA,IAAA,CAAK,mBAAmB,SAAA,CAAU,WAAA;AAAA,MAChC,CAAC,IAAA,KAA8C;AAC7C,QAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AAErB,QAAA,MAAM,UAAA,GAAyB;AAAA,UAC7B,IAAA,EAAA,WAAA;AAAA,UACA,GAAG,IAAA,CAAK,CAAA;AAAA,UACR,GAAG,IAAA,CAAK,CAAA;AAAA,UACR,GAAG,IAAA,CAAK;AAAA,SACV;AAEA,QAAA,MAAM,KAAA,GAAoB;AAAA,UACxB,IAAI,UAAA,EAAW;AAAA,UACf,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,UACpB,SAAA,EAAA,QAAA;AAAA,UACA,IAAA,EAAM;AAAA,SACR;AAEA,QAAA,IAAA,CAAK,QAAA,CAAS,iCAA4B,KAAK,CAAA;AAAA,MACjD;AAAA,KACF;AAAA,EACF;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAEjB,IAAA,IAAI,KAAK,iBAAA,EAAmB;AAC1B,MAAA,IAAA,CAAK,kBAAkB,MAAA,EAAO;AAC9B,MAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,IAC3B;AAEA,IAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,MAAA,IAAA,CAAK,iBAAiB,MAAA,EAAO;AAC7B,MAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AAAA,IAC1B;AAAA,EACF;AACF;;;ACtHA,IAAI,kBAAA;AAEJ,SAAS,WAAA,GAAc;AACrB,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,GAAK,UAAQ,cAAc,CAAA;AACjC,IAAA,kBAAA,GAAqB,EAAA,CAAG,kBAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAcO,IAAM,wBAAN,MAAsD;AAAA,EAK3D,WAAA,CACU,QAAA,EACR,SAAA,GAAY,eAAA,EACZ;AAFQ,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AALV,IAAA,IAAA,CAAQ,SAAA,GAAY,KAAA;AACpB,IAAA,IAAA,CAAQ,YAAA,GAA0C,IAAA;AAOhD,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,WAAA,EAAY;AAAA,EACd;AAAA,EAEA,IAAI,QAAA,GAAoB;AACtB,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAI,KAAK,SAAA,EAAW;AACpB,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAEjB,IAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,eAAe,kBAAA,CAAmB,WAAA;AAAA,MACrC,IAAA,CAAK,SAAA;AAAA,MACL,CAAC,IAAA,KAAiD;AAChD,QAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AAErB,QAAA,MAAM,YAAA,GAA6B;AAAA,UACjC,KAAK,IAAA,CAAK,GAAA;AAAA,UACV,QAAQ,IAAA,CAAK;AAAA,SACf;AAEA,QAAA,MAAM,KAAA,GAAoB;AAAA,UACxB,IAAI,UAAA,EAAW;AAAA,UACf,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,UACpB,SAAA,EAAA,UAAA;AAAA,UACA,IAAA,EAAM;AAAA,SACR;AAEA,QAAA,IAAA,CAAK,QAAA,CAAS,iCAA4B,KAAK,CAAA;AAAA,MACjD;AAAA,KACF;AAAA,EACF;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAEjB,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,IAAA,CAAK,aAAa,MAAA,EAAO;AACzB,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,IACtB;AAAA,EACF;AACF;;;AC7EO,IAAM,sBAAN,MAAoD;AAAA;AAAA;AAAA,EAKzD,YAAoB,QAAA,EAAqB;AAArB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAJpB,IAAA,IAAA,CAAQ,SAAA,GAAY,KAAA;AAAA,EAIsB;AAAA,EAE1C,IAAI,QAAA,GAAoB;AACtB,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EAEnB;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAAA,EAEnB;AACF;;;ACpBO,IAAM,cAAN,MAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASvB,WAAA,CAAY,QAAQ,GAAA,EAAK;AARzB,IAAA,IAAA,CAAQ,YAAA,GAA2D,IAAA;AASjE,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAC,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,CAAQ,CAAA,EAAW,CAAA,EAAW,CAAA,EAAgD;AAC5E,IAAA,IAAI,IAAA,CAAK,iBAAiB,IAAA,EAAM;AAE9B,MAAA,IAAA,CAAK,YAAA,GAAe,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AAC9B,MAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AAAA,IACnB;AAEA,IAAA,MAAM,OAAO,IAAA,CAAK,YAAA;AAClB,IAAA,MAAM,QAAA,GAAW;AAAA,MACf,GAAG,IAAA,CAAK,KAAA,GAAQ,KAAK,CAAA,GAAI,IAAA,CAAK,SAAS,IAAA,CAAK,CAAA;AAAA,MAC5C,GAAG,IAAA,CAAK,KAAA,GAAQ,KAAK,CAAA,GAAI,IAAA,CAAK,SAAS,IAAA,CAAK,CAAA;AAAA,MAC5C,GAAG,IAAA,CAAK,KAAA,GAAQ,KAAK,CAAA,GAAI,IAAA,CAAK,SAAS,IAAA,CAAK;AAAA,KAC9C;AAEA,IAAA,IAAA,CAAK,YAAA,GAAe,QAAA;AACpB,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA,CAAS,CAAA,EAAW,CAAA,EAAW,CAAA,EAAgD;AAC7E,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,CAAA,EAAG,GAAG,CAAC,CAAA;AAChC,IAAA,OAAO;AAAA,MACL,CAAA,EAAG,IAAI,GAAA,CAAI,CAAA;AAAA,MACX,CAAA,EAAG,IAAI,GAAA,CAAI,CAAA;AAAA,MACX,CAAA,EAAG,IAAI,GAAA,CAAI;AAAA,KACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,KAAA,EAAqB;AAC5B,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAC,CAAA;AAAA,EAC7C;AACF;;;ACpEO,IAAM,qBAAN,MAAyB;AAAA,EAAzB,WAAA,GAAA;AACL,IAAA,IAAA,CAAQ,KAAA,GAAuB,IAAA;AAC/B,IAAA,IAAA,CAAQ,KAAA,GAAuB,IAAA;AAC/B,IAAA,IAAA,CAAQ,aAAA,GAA+B,IAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUvC,SAAA,CACE,CAAA,EACA,CAAA,EACA,SAAA,EAKA;AACA,IAAA,IAAI,IAAA,CAAK,UAAU,IAAA,IAAQ,IAAA,CAAK,UAAU,IAAA,IAAQ,IAAA,CAAK,kBAAkB,IAAA,EAAM;AAE7E,MAAA,IAAA,CAAK,KAAA,GAAQ,CAAA;AACb,MAAA,IAAA,CAAK,KAAA,GAAQ,CAAA;AACb,MAAA,IAAA,CAAK,aAAA,GAAgB,SAAA;AACrB,MAAA,OAAO,EAAE,SAAA,EAAW,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,UAAU,CAAA,EAAE;AAAA,IACnD;AAEA,IAAA,MAAM,EAAA,GAAK,YAAY,IAAA,CAAK,aAAA;AAG5B,IAAA,IAAI,MAAM,CAAA,EAAG;AACX,MAAA,OAAO,EAAE,SAAA,EAAW,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,UAAU,CAAA,EAAE;AAAA,IACnD;AAEA,IAAA,MAAM,EAAA,GAAK,IAAI,IAAA,CAAK,KAAA;AACpB,IAAA,MAAM,EAAA,GAAK,IAAI,IAAA,CAAK,KAAA;AAEpB,IAAA,MAAM,YAAY,EAAA,GAAK,EAAA;AACvB,IAAA,MAAM,YAAY,EAAA,GAAK,EAAA;AACvB,IAAA,MAAM,WAAW,IAAA,CAAK,IAAA,CAAK,SAAA,GAAY,SAAA,GAAY,YAAY,SAAS,CAAA;AAGxE,IAAA,IAAA,CAAK,KAAA,GAAQ,CAAA;AACb,IAAA,IAAA,CAAK,KAAA,GAAQ,CAAA;AACb,IAAA,IAAA,CAAK,aAAA,GAAgB,SAAA;AAErB,IAAA,OAAO,EAAE,SAAA,EAAW,SAAA,EAAW,QAAA,EAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AAAA,EACvB;AACF;;;ACrDO,IAAM,gBAAN,MAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzB,SAAA,CACE,IACA,EAAA,EAKA;AAEA,IAAA,IAAI,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,CAAA,EAAG;AACxB,MAAA,OAAO;AAAA,QACL,YAAA,EAAc,CAAA;AAAA,QACd,YAAA,EAAc,CAAA;AAAA,QACd,SAAA,EAAA,MAAA;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA;AACtC,IAAA,MAAM,YAAA,GAAgB,YAAA,GAAe,GAAA,GAAO,IAAA,CAAK,EAAA;AACjD,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,iBAAA,CAAkB,YAAY,CAAA;AAErD,IAAA,OAAO,EAAE,YAAA,EAAc,YAAA,EAAc,SAAA,EAAU;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBQ,kBAAkB,OAAA,EAAoC;AAE5D,IAAA,MAAM,CAAA,GAAI,OAAA;AAEV,IAAA,IAAI,CAAA,IAAK,KAAA,IAAS,CAAA,GAAI,IAAA,EAAM,OAAA,OAAA;AAC5B,IAAA,IAAI,CAAA,IAAK,IAAA,IAAQ,CAAA,GAAI,IAAA,EAAM,OAAA,YAAA;AAC3B,IAAA,IAAI,CAAA,IAAK,IAAA,IAAQ,CAAA,GAAI,KAAA,EAAO,OAAA,MAAA;AAC5B,IAAA,IAAI,CAAA,IAAK,KAAA,IAAS,CAAA,GAAI,KAAA,EAAO,OAAA,WAAA;AAC7B,IAAA,IAAI,CAAA,IAAK,KAAA,IAAS,CAAA,GAAI,MAAA,EAAQ,OAAA,MAAA;AAC9B,IAAA,IAAI,CAAA,IAAK,MAAA,IAAU,CAAA,GAAI,MAAA,EAAQ,OAAA,SAAA;AAC/B,IAAA,IAAI,CAAA,IAAK,MAAA,IAAU,CAAA,GAAI,KAAA,EAAO,OAAA,IAAA;AAC9B,IAAA,IAAI,CAAA,IAAK,KAAA,IAAS,CAAA,GAAI,KAAA,EAAO,OAAA,UAAA;AAE7B,IAAA,OAAA,MAAA;AAAA,EACF;AACF;;;AC/DO,IAAM,sBAAN,MAA0B;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ/B,WAAA,CAAY,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,CAAA,EAAG;AAC5B,IAAA,IAAI,OAAO,GAAA,EAAK;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,2BAAA,EAA8B,GAAG,CAAA,yBAAA,EAA4B,GAAG,CAAA,CAAA;AAAA,OAClE;AAAA,IACF;AACA,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,KAAA,EAAuB;AAC/B,IAAA,IAAI,KAAA,IAAS,IAAA,CAAK,GAAA,EAAK,OAAO,CAAA;AAC9B,IAAA,IAAI,KAAA,IAAS,IAAA,CAAK,GAAA,EAAK,OAAO,CAAA;AAC9B,IAAA,OAAA,CAAQ,KAAA,GAAQ,IAAA,CAAK,GAAA,KAAQ,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,CAAS,KAAa,GAAA,EAAmB;AACvC,IAAA,IAAI,OAAO,GAAA,EAAK;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,2BAAA,EAA8B,GAAG,CAAA,yBAAA,EAA4B,GAAG,CAAA,CAAA;AAAA,OAClE;AAAA,IACF;AACA,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,GAAiB;AACf,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,GAAiB;AACf,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AACF;;;ACnDO,IAAM,eAAN,MAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,EAWxB,WAAA,CAAY,QAAA,GAAW,GAAA,EAAK,QAAA,GAAW,EAAA,EAAI;AAT3C,IAAA,IAAA,CAAQ,IAAA,GAAO,CAAA;AACf,IAAA,IAAA,CAAQ,KAAA,GAAQ,CAAA;AASd,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,SAAS,IAAI,KAAA,CAAM,QAAQ,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,MAAA,EAA+B;AAElC,IAAA,MAAM,UAAA,GAAA,CAAc,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,SAAS,IAAA,CAAK,QAAA;AAEnD,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,IAAA,CAAK,QAAA,EAAU;AAEhC,MAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,GAAI,MAAA;AACzB,MAAA,IAAA,CAAK,IAAA,GAAA,CAAQ,IAAA,CAAK,IAAA,GAAO,CAAA,IAAK,IAAA,CAAK,QAAA;AAAA,IACrC,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA;AAC1B,MAAA,IAAA,CAAK,KAAA,EAAA;AAAA,IACP;AAGA,IAAA,IAAA,CAAK,UAAA,CAAW,OAAO,SAAS,CAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,GAA4B;AAC1B,IAAA,MAAM,SAA4B,EAAC;AACnC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,OAAO,CAAA,EAAA,EAAK;AACnC,MAAA,MAAM,KAAA,GAAA,CAAS,IAAA,CAAK,IAAA,GAAO,CAAA,IAAK,IAAA,CAAK,QAAA;AACrC,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA;AAChC,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAA,CAAO,KAAK,MAAM,CAAA;AAAA,MACpB;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,GAAiC;AAC/B,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,CAAA,EAAG,OAAO,IAAA;AAC7B,IAAA,MAAM,SAAS,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,KAAA,GAAQ,KAAK,IAAA,CAAK,QAAA;AAClD,IAAA,OAAO,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAA,GAAe;AACb,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,IAAI,CAAA;AACrB,IAAA,IAAA,CAAK,IAAA,GAAO,CAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,CAAA;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,gBAAA,EAAgC;AACjD,IAAA,MAAM,MAAA,GAAS,mBAAmB,IAAA,CAAK,QAAA;AAEvC,IAAA,OAAO,IAAA,CAAK,QAAQ,CAAA,EAAG;AACrB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA;AACpC,MAAA,IAAI,MAAA,IAAU,MAAA,CAAO,SAAA,GAAY,MAAA,EAAQ;AACvC,QAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AACzB,QAAA,IAAA,CAAK,IAAA,GAAA,CAAQ,IAAA,CAAK,IAAA,GAAO,CAAA,IAAK,IAAA,CAAK,QAAA;AACnC,QAAA,IAAA,CAAK,KAAA,EAAA;AAAA,MACP,CAAA,MAAO;AACL,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC9EO,IAAe,iBAAf,MAAqD;AAAA,EAU1D,WAAA,CACE,IAAA,EACA,QAAA,EACA,OAAA,GAII,EAAC,EACL;AAXF,IAAA,IAAA,CAAQ,MAAA,GAAA,MAAA;AAYN,IAAA,IAAA,CAAK,KAAK,UAAA,EAAW;AACrB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,GAAA;AACpC,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,WAAA,IAAe,KAAA;AAC1C,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,IAAA;AAAA,EACpC;AAAA,EAEA,IAAI,KAAA,GAAyB;AAC3B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAWA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,MAAA,GAAA,MAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,KAAA,EAAM;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,oBAAA,GAA6B;AACrC,IAAA,IAAI,KAAK,MAAA,KAAA,MAAA,aAAiC;AACxC,MAAA,IAAA,CAAK,MAAA,GAAA,UAAA;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,iBAAA,CAAkB,QAAA,GAA4B,EAAC,EAAS;AAChE,IAAA,IAAI,KAAK,MAAA,KAAA,UAAA,iBAAqC;AAC5C,MAAA,IAAA,CAAK,MAAA,GAAA,OAAA;AACL,MAAA,IAAA,CAAK,iBAAiB,QAAQ,CAAA;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,mBAAA,CAAoB,QAAA,GAA4B,EAAC,EAAS;AAClE,IAAA,IACE,IAAA,CAAK,MAAA,KAAA,OAAA,gBACL,IAAA,CAAK,MAAA,KAAA,SAAA,gBACL;AACA,MAAA,IAAA,CAAK,MAAA,GAAA,SAAA;AACL,MAAA,IAAA,CAAK,iBAAiB,QAAQ,CAAA;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,iBAAA,CAAkB,QAAA,GAA4B,EAAC,EAAS;AAChE,IAAA,IACE,IAAA,CAAK,MAAA,KAAA,OAAA,gBACL,IAAA,CAAK,MAAA,KAAA,SAAA,kBACL,KAAK,MAAA,KAAA,UAAA,iBACL;AACA,MAAA,IAAA,CAAK,MAAA,GAAA,OAAA;AACL,MAAA,IAAA,CAAK,iBAAiB,QAAQ,CAAA;AAE9B,MAAA,IAAA,CAAK,MAAA,GAAA,MAAA;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,kBAAA,GAA2B;AACnC,IAAA,IACE,IAAA,CAAK,MAAA,KAAA,UAAA,mBACL,IAAA,CAAK,MAAA,KAAA,OAAA,cACL;AACA,MAAA,IAAA,CAAK,MAAA,GAAA,QAAA;AAEL,MAAA,IAAA,CAAK,MAAA,GAAA,MAAA;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,qBAAA,GAA8B;AACtC,IAAA,IACE,IAAA,CAAK,MAAA,KAAA,OAAA,gBACL,IAAA,CAAK,MAAA,KAAA,SAAA,gBACL;AACA,MAAA,IAAA,CAAK,MAAA,GAAA,WAAA;AACL,MAAA,IAAA,CAAK,gBAAA,CAAiB,EAAE,CAAA;AACxB,MAAA,IAAA,CAAK,MAAA,GAAA,MAAA;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,QAAA,EAAiC;AACxD,IAAA,MAAM,KAAA,GAAsB;AAAA,MAC1B,IAAI,UAAA,EAAW;AAAA,MACf,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,OAAO,IAAA,CAAK,MAAA;AAAA,MACZ,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,aAAa,IAAA,CAAK,WAAA;AAAA,MAClB,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,qDAAsC,KAAK,CAAA;AAAA,EAC3D;AACF;;;AC9KO,IAAM,aAAA,GAAN,cAA4B,cAAA,CAAe;AAAA,EAOhD,WAAA,CAAY,QAAA,EAAqB,MAAA,GAA8B,EAAC,EAAG;AACjE,IAAA,KAAA,CAAM,OAAO,QAAA,EAAU;AAAA,MACrB,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AATH,IAAA,IAAA,CAAQ,SAAA,GAA2B,IAAA;AACnC,IAAA,IAAA,CAAQ,MAAA,GAAwB,IAAA;AAChC,IAAA,IAAA,CAAQ,MAAA,GAAwB,IAAA;AAQ9B,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,GAAA;AACzC,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,EAAA;AAAA,EAC3C;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,OAAA,cAA+B;AAE9C,IAAA,MAAM,YAAY,UAAA,CAAW,IAAA;AAC7B,IAAA,IAAI,SAAA,CAAU,IAAA,KAAA,KAAA,cAA0B,SAAA,CAAU,IAAA,KAAA,KAAA,YAAwB;AAG1E,IAAA,IAAI,UAAU,IAAA,KAAA,KAAA,YAAwB;AACpC,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,aAAa,EAAE,CAAA,EAAG,UAAU,CAAA,EAAG,CAAA,EAAG,UAAU,CAAA;AAAE,OAC/C,CAAA;AACD,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,aAAa,EAAE,CAAA,EAAG,UAAU,CAAA,EAAG,CAAA,EAAG,UAAU,CAAA;AAAE,OAC/C,CAAA;AACD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,IAAA,CAAK,cAAc,IAAA,EAAM;AAC3B,MAAA,IAAA,CAAK,YAAY,UAAA,CAAW,SAAA;AAC5B,MAAA,IAAA,CAAK,SAAS,SAAA,CAAU,CAAA;AACxB,MAAA,IAAA,CAAK,SAAS,SAAA,CAAU,CAAA;AACxB,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,UAAA,CAAW,SAAA,GAAY,IAAA,CAAK,SAAA;AAC5C,IAAA,MAAM,EAAA,GAAK,SAAA,CAAU,CAAA,IAAK,IAAA,CAAK,MAAA,IAAU,CAAA,CAAA;AACzC,IAAA,MAAM,EAAA,GAAK,SAAA,CAAU,CAAA,IAAK,IAAA,CAAK,MAAA,IAAU,CAAA,CAAA;AACzC,IAAA,MAAM,WAAW,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AAG5C,IAAA,IAAI,QAAA,GAAW,KAAK,WAAA,EAAa;AAC/B,MAAA,IAAA,CAAK,kBAAA,EAAmB;AACxB,MAAA,IAAA,CAAK,UAAA,EAAW;AAChB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,OAAA,GAAU,KAAK,WAAA,EAAa;AAC9B,MAAA,IAAA,CAAK,kBAAA,EAAmB;AACxB,MAAA,IAAA,CAAK,UAAA,EAAW;AAChB,MAAA;AAAA,IACF;AAGA,IAAA,IACE,IAAA,CAAK,GAAA,CAAI,SAAA,CAAU,SAAS,CAAA,GAAI,IAAA,IAChC,IAAA,CAAK,GAAA,CAAI,SAAA,CAAU,SAAS,CAAA,GAAI,IAAA,IAChC,UAAU,EAAA,EACV;AACA,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,WAAA,EAAa,EAAE,CAAA,EAAG,IAAA,CAAK,UAAU,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,MAAA,IAAU,CAAA;AAAE,OACzD,CAAA;AACD,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,aAAa,EAAE,CAAA,EAAG,UAAU,CAAA,EAAG,CAAA,EAAG,UAAU,CAAA;AAAE,OAC/C,CAAA;AACD,MAAA,IAAA,CAAK,UAAA,EAAW;AAAA,IAClB;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,KAAA,CAAM,KAAA,EAAM;AACZ,IAAA,IAAA,CAAK,UAAA,EAAW;AAAA,EAClB;AAAA,EAEQ,UAAA,GAAmB;AACzB,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,EAChB;AACF;;;AC7FO,IAAM,mBAAA,GAAN,cAAkC,cAAA,CAAe;AAAA,EAQtD,WAAA,CAAY,QAAA,EAAqB,MAAA,GAAoC,EAAC,EAAG;AACvE,IAAA,KAAA,CAAM,cAAc,QAAA,EAAU;AAAA,MAC5B,QAAA,EAAU,OAAO,QAAA,IAAY,CAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AAVH,IAAA,IAAA,CAAQ,YAAA,GAA8B,IAAA;AACtC,IAAA,IAAA,CAAQ,SAAA,GAA2B,IAAA;AACnC,IAAA,IAAA,CAAQ,SAAA,GAA2B,IAAA;AACnC,IAAA,IAAA,CAAQ,QAAA,GAAW,CAAA;AAQjB,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,GAAA;AACzC,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,EAAA;AAAA,EAC3C;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,OAAA,cAA+B;AAE9C,IAAA,MAAM,YAAY,UAAA,CAAW,IAAA;AAC7B,IAAA,IAAI,UAAU,IAAA,KAAA,KAAA,YAAwB;AAEtC,IAAA,MAAM,MAAM,UAAA,CAAW,SAAA;AAEvB,IAAA,IAAI,IAAA,CAAK,aAAa,CAAA,EAAG;AAEvB,MAAA,IAAA,CAAK,YAAA,GAAe,GAAA;AACpB,MAAA,IAAA,CAAK,YAAY,SAAA,CAAU,CAAA;AAC3B,MAAA,IAAA,CAAK,YAAY,SAAA,CAAU,CAAA;AAC3B,MAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAChB,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,aAAa,CAAA,EAAG;AACvB,MAAA,MAAM,OAAA,GAAU,GAAA,IAAO,IAAA,CAAK,YAAA,IAAgB,CAAA,CAAA;AAC5C,MAAA,MAAM,EAAA,GAAK,SAAA,CAAU,CAAA,IAAK,IAAA,CAAK,SAAA,IAAa,CAAA,CAAA;AAC5C,MAAA,MAAM,EAAA,GAAK,SAAA,CAAU,CAAA,IAAK,IAAA,CAAK,SAAA,IAAa,CAAA,CAAA;AAC5C,MAAA,MAAM,WAAW,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AAE5C,MAAA,IAAI,OAAA,IAAW,IAAA,CAAK,WAAA,IAAe,QAAA,IAAY,KAAK,WAAA,EAAa;AAE/D,QAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,UACrB,aAAa,EAAE,CAAA,EAAG,UAAU,CAAA,EAAG,CAAA,EAAG,UAAU,CAAA;AAAE,SAC/C,CAAA;AACD,QAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,UACrB,aAAa,EAAE,CAAA,EAAG,UAAU,CAAA,EAAG,CAAA,EAAG,UAAU,CAAA;AAAE,SAC/C,CAAA;AACD,QAAA,IAAA,CAAK,UAAA,EAAW;AAAA,MAClB,CAAA,MAAO;AAEL,QAAA,IAAA,CAAK,kBAAA,EAAmB;AACxB,QAAA,IAAA,CAAK,YAAA,GAAe,GAAA;AACpB,QAAA,IAAA,CAAK,YAAY,SAAA,CAAU,CAAA;AAC3B,QAAA,IAAA,CAAK,YAAY,SAAA,CAAU,CAAA;AAC3B,QAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAChB,QAAA,IAAA,CAAK,oBAAA,EAAqB;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,KAAA,CAAM,KAAA,EAAM;AACZ,IAAA,IAAA,CAAK,UAAA,EAAW;AAAA,EAClB;AAAA,EAEQ,UAAA,GAAmB;AACzB,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,IAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAAA,EAClB;AACF;;;AC7EO,IAAM,aAAA,GAAN,cAA4B,cAAA,CAAe;AAAA,EAGhD,WAAA,CAAY,QAAA,EAAqB,MAAA,GAA8B,EAAC,EAAG;AACjE,IAAA,KAAA,CAAM,OAAO,QAAA,EAAU;AAAA,MACrB,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AACD,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,EAAA;AAAA,EAC3C;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,OAAA,cAA+B;AAE9C,IAAA,MAAM,YAAY,UAAA,CAAW,IAAA;AAC7B,IAAA,IAAI,UAAU,IAAA,KAAA,KAAA,YAAwB;AAEtC,IAAA,MAAM,WAAA,GAAc;AAAA,MAClB,GAAG,SAAA,CAAU,YAAA;AAAA,MACb,GAAG,SAAA,CAAU;AAAA,KACf;AACA,IAAA,MAAM,WAAW,IAAA,CAAK,IAAA;AAAA,MACpB,YAAY,CAAA,GAAI,WAAA,CAAY,CAAA,GAAI,WAAA,CAAY,IAAI,WAAA,CAAY;AAAA,KAC9D;AAEA,IAAA,MAAM,QAAA,GAAW;AAAA,MACf,GAAG,SAAA,CAAU,SAAA;AAAA,MACb,GAAG,SAAA,CAAU;AAAA,KACf;AAGA,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,MAAA,IAAU,IAAA,CAAK,UAAU,UAAA,EAAY;AACtD,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,MAAA,IAAI,QAAA,IAAY,KAAK,WAAA,EAAa;AAChC,QAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,WAAA,EAAa,QAAA,EAAU,CAAA;AAAA,MAClD;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,OAAA,IAAW,IAAA,CAAK,UAAU,SAAA,EAAW;AAEtD,MAAA,IACE,IAAA,CAAK,GAAA,CAAI,SAAA,CAAU,SAAS,CAAA,GAAI,IAAA,IAChC,IAAA,CAAK,GAAA,CAAI,SAAA,CAAU,SAAS,CAAA,GAAI,IAAA,EAChC;AACA,QAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,WAAA,EAAa,QAAA,EAAU,CAAA;AAAA,MAClD,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,mBAAA,CAAoB,EAAE,WAAA,EAAa,QAAA,EAAU,CAAA;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACF;;;ACxDO,IAAM,eAAA,GAAN,cAA8B,cAAA,CAAe;AAAA,EAGlD,WAAA,CAAY,QAAA,EAAqB,MAAA,GAAgC,EAAC,EAAG;AACnE,IAAA,KAAA,CAAM,SAAS,QAAA,EAAU;AAAA,MACvB,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AACD,IAAA,IAAA,CAAK,QAAA,GAAW,OAAO,QAAA,IAAY,IAAA;AAAA,EACrC;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,OAAA,cAA+B;AAE9C,IAAA,MAAM,YAAY,UAAA,CAAW,IAAA;AAC7B,IAAA,IAAI,UAAU,IAAA,KAAA,OAAA,cAA0B;AAExC,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,SAAA,CAAU,QAAQ,CAAC,CAAA;AAE/C,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,MAAA,IAAU,IAAA,CAAK,UAAU,UAAA,EAAY;AACtD,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,MAAA,IAAI,UAAA,IAAc,KAAK,QAAA,EAAU;AAC/B,QAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,KAAA,EAAO,SAAA,CAAU,OAAO,CAAA;AAAA,MACnD;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,OAAA,IAAW,IAAA,CAAK,UAAU,SAAA,EAAW;AACtD,MAAA,IAAI,SAAA,CAAU,mBAAmB,CAAA,EAAG;AAClC,QAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,KAAA,EAAO,SAAA,CAAU,OAAO,CAAA;AAAA,MACnD,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,mBAAA,CAAoB,EAAE,KAAA,EAAO,SAAA,CAAU,OAAO,CAAA;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;;;ACvCO,IAAM,kBAAA,GAAN,cAAiC,cAAA,CAAe;AAAA,EAGrD,WAAA,CAAY,QAAA,EAAqB,MAAA,GAAmC,EAAC,EAAG;AACtE,IAAA,KAAA,CAAM,YAAY,QAAA,EAAU;AAAA,MAC1B,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AACD,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,IAAA;AAAA,EAC3C;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,OAAA,cAA+B;AAE9C,IAAA,MAAM,YAAY,UAAA,CAAW,IAAA;AAC7B,IAAA,IAAI,UAAU,IAAA,KAAA,UAAA,iBAA6B;AAE3C,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,SAAA,CAAU,QAAQ,CAAA;AAE/C,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,MAAA,IAAU,IAAA,CAAK,UAAU,UAAA,EAAY;AACtD,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,MAAA,IAAI,WAAA,IAAe,KAAK,WAAA,EAAa;AACnC,QAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,QAAA,EAAU,SAAA,CAAU,UAAU,CAAA;AAAA,MACzD;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,OAAA,IAAW,IAAA,CAAK,UAAU,SAAA,EAAW;AACtD,MAAA,IAAI,SAAA,CAAU,mBAAmB,CAAA,EAAG;AAClC,QAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,QAAA,EAAU,SAAA,CAAU,UAAU,CAAA;AAAA,MACzD,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,mBAAA,CAAoB,EAAE,QAAA,EAAU,SAAA,CAAU,UAAU,CAAA;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACF;;;AC/BO,IAAM,mBAAA,GAAN,cAAkC,cAAA,CAAe;AAAA,EAWtD,WAAA,CAAY,UAAqB,MAAA,EAAmC;AAClE,IAAA,KAAA,CAAM,CAAA,WAAA,EAAc,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,QAAA,EAAU;AAAA,MAC3C,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,IAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AATH,IAAA,IAAA,CAAQ,aAAA,GAAgB,KAAA;AACxB,IAAA,IAAA,CAAQ,MAAA,GAAwB,IAAA;AAChC,IAAA,IAAA,CAAQ,MAAA,GAAwB,IAAA;AAQ9B,IAAA,IAAA,CAAK,OAAO,MAAA,CAAO,IAAA;AACnB,IAAA,IAAA,CAAK,aAAA,GAAgB,OAAO,aAAA,IAAiB,EAAA;AAC7C,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,EAAA;AACzC,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,GAAA;AACzC,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,GAAA;AACzC,IAAA,IAAA,CAAK,YAAA,GAAe,OAAO,YAAA,IAAgB,GAAA;AAAA,EAC7C;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,OAAA,cAA+B;AAE9C,IAAA,MAAM,YAAY,UAAA,CAAW,IAAA;AAC7B,IAAA,IAAI,UAAU,IAAA,KAAA,KAAA,YAAwB;AAGtC,IAAA,IAAI,IAAA,CAAK,WAAW,IAAA,EAAM;AACxB,MAAA,IAAA,CAAK,SAAS,SAAA,CAAU,CAAA;AACxB,MAAA,IAAA,CAAK,SAAS,SAAA,CAAU,CAAA;AACxB,MAAA,IAAA,CAAK,gBAAgB,IAAA,CAAK,YAAA,CAAa,SAAA,CAAU,CAAA,EAAG,UAAU,CAAC,CAAA;AAE/D,MAAA,IAAI,KAAK,aAAA,EAAe;AACtB,QAAA,IAAA,CAAK,oBAAA,EAAqB;AAAA,MAC5B;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AAGzB,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,gBAAA,CAAiB,SAAS,CAAA;AACrD,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,gBAAA,CAAiB,SAAS,CAAA;AAErD,IAAA,IAAI,IAAA,CAAK,UAAU,UAAA,EAAY;AAE7B,MAAA,IAAI,aAAA,IAAiB,IAAA,CAAK,WAAA,IAAe,aAAA,IAAiB,KAAK,WAAA,EAAa;AAC1E,QAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,UACrB,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,WAAA,EAAa;AAAA,YACX,GAAG,SAAA,CAAU,YAAA;AAAA,YACb,GAAG,SAAA,CAAU;AAAA,WACf;AAAA,UACA,QAAA,EAAU;AAAA,YACR,GAAG,SAAA,CAAU,SAAA;AAAA,YACb,GAAG,SAAA,CAAU;AAAA;AACf,SACD,CAAA;AACD,QAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,UACrB,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,WAAA,EAAa;AAAA,YACX,GAAG,SAAA,CAAU,YAAA;AAAA,YACb,GAAG,SAAA,CAAU;AAAA,WACf;AAAA,UACA,QAAA,EAAU;AAAA,YACR,GAAG,SAAA,CAAU,SAAA;AAAA,YACb,GAAG,SAAA,CAAU;AAAA;AACf,SACD,CAAA;AACD,QAAA,IAAA,CAAK,UAAA,EAAW;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,KAAA,CAAM,KAAA,EAAM;AACZ,IAAA,IAAA,CAAK,UAAA,EAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAA,CAAa,GAAW,CAAA,EAAoB;AAClD,IAAA,QAAQ,KAAK,IAAA;AAAM,MACjB,KAAK,MAAA;AACH,QAAA,OAAO,KAAK,IAAA,CAAK,aAAA;AAAA,MACnB,KAAK,OAAA;AACH,QAAA,OAAO,CAAA,IAAK,IAAA,CAAK,WAAA,GAAc,IAAA,CAAK,aAAA;AAAA,MACtC,KAAK,KAAA;AACH,QAAA,OAAO,KAAK,IAAA,CAAK,aAAA;AAAA,MACnB,KAAK,QAAA;AACH,QAAA,OAAO,CAAA,IAAK,IAAA,CAAK,YAAA,GAAe,IAAA,CAAK,aAAA;AAAA;AACzC,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,SAAA,EAA8B;AACrD,IAAA,QAAQ,KAAK,IAAA;AAAM,MACjB,KAAK,MAAA;AACH,QAAA,OAAO,SAAA,CAAU,YAAA;AAAA;AAAA,MACnB,KAAK,OAAA;AACH,QAAA,OAAO,CAAC,SAAA,CAAU,YAAA;AAAA;AAAA,MACpB,KAAK,KAAA;AACH,QAAA,OAAO,SAAA,CAAU,YAAA;AAAA;AAAA,MACnB,KAAK,QAAA;AACH,QAAA,OAAO,CAAC,SAAA,CAAU,YAAA;AAAA;AACtB,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,SAAA,EAA8B;AACrD,IAAA,QAAQ,KAAK,IAAA;AAAM,MACjB,KAAK,MAAA;AACH,QAAA,OAAO,SAAA,CAAU,SAAA;AAAA,MACnB,KAAK,OAAA;AACH,QAAA,OAAO,CAAC,SAAA,CAAU,SAAA;AAAA,MACpB,KAAK,KAAA;AACH,QAAA,OAAO,SAAA,CAAU,SAAA;AAAA,MACnB,KAAK,QAAA;AACH,QAAA,OAAO,CAAC,SAAA,CAAU,SAAA;AAAA;AACtB,EACF;AAAA,EAEQ,UAAA,GAAmB;AACzB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,aAAA,GAAgB,KAAA;AAAA,EACvB;AACF;;;ACpJO,IAAM,gBAAA,GAAN,cAA+B,cAAA,CAAe;AAAA,EAUnD,WAAA,CAAY,UAAqB,MAAA,EAAgC;AAC/D,IAAA,KAAA,CAAM,CAAA,OAAA,EAAU,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,QAAA,EAAU;AAAA,MACzC,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,IAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AATH,IAAA,IAAA,CAAQ,eAAA,GAAkB,KAAA;AAC1B,IAAA,IAAA,CAAQ,MAAA,GAAwB,IAAA;AAChC,IAAA,IAAA,CAAQ,MAAA,GAAwB,IAAA;AAQ9B,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,IAAA,IAAA,CAAK,cAAA,GAAiB,OAAO,cAAA,IAAkB,EAAA;AAC/C,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,EAAA;AACzC,IAAA,IAAA,CAAK,WAAA,GAAc,OAAO,WAAA,IAAe,GAAA;AACzC,IAAA,IAAA,CAAK,YAAA,GAAe,OAAO,YAAA,IAAgB,GAAA;AAAA,EAC7C;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,OAAA,cAA+B;AAE9C,IAAA,MAAM,YAAY,UAAA,CAAW,IAAA;AAC7B,IAAA,IAAI,UAAU,IAAA,KAAA,KAAA,YAAwB;AAEtC,IAAA,IAAI,IAAA,CAAK,WAAW,IAAA,EAAM;AACxB,MAAA,IAAA,CAAK,SAAS,SAAA,CAAU,CAAA;AACxB,MAAA,IAAA,CAAK,SAAS,SAAA,CAAU,CAAA;AACxB,MAAA,IAAA,CAAK,kBAAkB,IAAA,CAAK,cAAA,CAAe,SAAA,CAAU,CAAA,EAAG,UAAU,CAAC,CAAA;AAEnE,MAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,QAAA,IAAA,CAAK,oBAAA,EAAqB;AAAA,MAC5B;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,KAAK,eAAA,EAAiB;AAE3B,IAAA,MAAM,WAAW,IAAA,CAAK,IAAA;AAAA,MACpB,SAAA,CAAU,YAAA,IAAgB,CAAA,GAAI,SAAA,CAAU,YAAA,IAAgB;AAAA,KAC1D;AAEA,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,UAAA,IAAc,QAAA,IAAY,KAAK,WAAA,EAAa;AAC7D,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,WAAA,EAAa;AAAA,UACX,GAAG,SAAA,CAAU,YAAA;AAAA,UACb,GAAG,SAAA,CAAU;AAAA;AACf,OACD,CAAA;AACD,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,WAAA,EAAa;AAAA,UACX,GAAG,SAAA,CAAU,YAAA;AAAA,UACb,GAAG,SAAA,CAAU;AAAA;AACf,OACD,CAAA;AACD,MAAA,IAAA,CAAK,UAAA,EAAW;AAAA,IAClB;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,KAAA,CAAM,KAAA,EAAM;AACZ,IAAA,IAAA,CAAK,UAAA,EAAW;AAAA,EAClB;AAAA,EAEQ,cAAA,CAAe,GAAW,CAAA,EAAoB;AACpD,IAAA,MAAM,OAAO,IAAA,CAAK,cAAA;AAClB,IAAA,QAAQ,KAAK,MAAA;AAAQ,MACnB,KAAK,UAAA;AACH,QAAA,OAAO,CAAA,IAAK,QAAQ,CAAA,IAAK,IAAA;AAAA,MAC3B,KAAK,WAAA;AACH,QAAA,OAAO,CAAA,IAAK,IAAA,CAAK,WAAA,GAAc,IAAA,IAAQ,CAAA,IAAK,IAAA;AAAA,MAC9C,KAAK,aAAA;AACH,QAAA,OAAO,CAAA,IAAK,IAAA,IAAQ,CAAA,IAAK,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,MAC/C,KAAK,cAAA;AACH,QAAA,OAAO,KAAK,IAAA,CAAK,WAAA,GAAc,IAAA,IAAQ,CAAA,IAAK,KAAK,YAAA,GAAe,IAAA;AAAA;AACpE,EACF;AAAA,EAEQ,UAAA,GAAmB;AACzB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AAAA,EACzB;AACF;;;ACjFO,IAAM,eAAA,GAAN,cAA8B,cAAA,CAAe;AAAA,EAQlD,WAAA,CAAY,QAAA,EAAqB,MAAA,GAAgC,EAAC,EAAG;AACnE,IAAA,KAAA,CAAM,SAAS,QAAA,EAAU;AAAA,MACvB,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AARH,IAAA,IAAA,CAAQ,mBAAA,GAAsB,CAAA;AAC9B,IAAA,IAAA,CAAQ,eAAA,GAAkB,CAAA;AAQxB,IAAA,IAAA,CAAK,SAAA,GAAY,OAAO,SAAA,IAAa,GAAA;AACrC,IAAA,IAAA,CAAK,kBAAA,GAAqB,OAAO,kBAAA,IAAsB,CAAA;AACvD,IAAA,IAAA,CAAK,UAAA,GAAa,OAAO,UAAA,IAAc,GAAA;AAAA,EACzC;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,QAAA,eAAgC;AAE/C,IAAA,MAAM,aAAa,UAAA,CAAW,IAAA;AAC9B,IAAA,IAAI,WAAW,IAAA,KAAA,eAAA,sBAAmC;AAGlD,IAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,KAAM,MAAA,CAAO,QAAA;AAG3B,IAAA,MAAM,SAAA,GAAY,KAAK,IAAA,CAAK,CAAA,GAAI,IAAI,CAAA,GAAI,CAAA,GAAI,IAAI,CAAC,CAAA;AAEjD,IAAA,IAAI,SAAA,IAAa,KAAK,SAAA,EAAW;AAC/B,MAAA,IAAA,CAAK,mBAAA,EAAA;AAEL,MAAA,IAAI,IAAA,CAAK,mBAAA,IAAuB,IAAA,CAAK,kBAAA,EAAoB;AACvD,QAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAGrB,QAAA,IAAI,GAAA,GAAM,IAAA,CAAK,eAAA,GAAkB,IAAA,CAAK,UAAA,EAAY;AAEhD,UAAA;AAAA,QACF;AAGA,QAAA,IAAA,CAAK,eAAA,GAAkB,GAAA;AACvB,QAAA,IAAA,CAAK,mBAAA,GAAsB,CAAA;AAE3B,QAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,QAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,SAAA,EAAW,CAAA;AACpC,QAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,SAAA,EAAW,CAAA;AAAA,MACtC;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,IAAA,CAAK,mBAAA,GAAsB,CAAA;AAAA,IAC7B;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,KAAA,CAAM,KAAA,EAAM;AACZ,IAAA,IAAA,CAAK,mBAAA,GAAsB,CAAA;AAAA,EAC7B;AACF;;;ACxEO,IAAM,cAAA,GAAN,cAA6B,cAAA,CAAe;AAAA,EAKjD,WAAA,CAAY,QAAA,EAAqB,MAAA,GAA+B,EAAC,EAAG;AAClE,IAAA,KAAA,CAAM,QAAQ,QAAA,EAAU;AAAA,MACtB,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AAPH,IAAA,IAAA,CAAQ,eAAA,GAAkB,CAAA;AAQxB,IAAA,IAAA,CAAK,aAAA,GAAgB,OAAO,aAAA,IAAiB,EAAA;AAC7C,IAAA,IAAA,CAAK,UAAA,GAAa,OAAO,UAAA,IAAc,GAAA;AAAA,EACzC;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,QAAA,eAAgC;AAE/C,IAAA,MAAM,aAAa,UAAA,CAAW,IAAA;AAC9B,IAAA,IAAI,WAAW,IAAA,KAAA,eAAA,sBAAmC;AAIlD,IAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE,GAAI,UAAA;AAKpB,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAC,CAAC,CAAA,IAAK,MAAM,IAAA,CAAK,EAAA,CAAA;AACpE,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAC,CAAC,CAAA,IAAK,MAAM,IAAA,CAAK,EAAA,CAAA;AAEnE,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,IAAI,CAAC,CAAA;AAExD,IAAA,IAAI,OAAA,IAAW,KAAK,aAAA,EAAe;AACjC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,MAAA,IAAI,GAAA,GAAM,IAAA,CAAK,eAAA,GAAkB,IAAA,CAAK,UAAA,EAAY;AAChD,QAAA;AAAA,MACF;AAEA,MAAA,IAAA,CAAK,eAAA,GAAkB,GAAA;AAEvB,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,IAAA,EAAM,EAAE,KAAA,EAAO,IAAA,EAAK;AAAA,QACpB,SAAA,EAAW;AAAA,OACZ,CAAA;AACD,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,IAAA,EAAM,EAAE,KAAA,EAAO,IAAA,EAAK;AAAA,QACpB,SAAA,EAAW;AAAA,OACZ,CAAA;AAAA,IACH;AAAA,EACF;AACF;;;ACvDO,IAAM,oBAAA,GAAN,cAAmC,cAAA,CAAe;AAAA,EAKvD,WAAA,CAAY,QAAA,EAAqB,MAAA,GAAqC,EAAC,EAAG;AACxE,IAAA,KAAA,CAAM,eAAe,QAAA,EAAU;AAAA,MAC7B,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AAPH,IAAA,IAAA,CAAQ,eAAA,GAAkB,CAAA;AAUxB,IAAA,IAAA,CAAK,wBAAA,GAAA,CACD,MAAA,CAAO,wBAAA,IAA4B,GAAA,IAAO,KAAK,EAAA,GAAM,GAAA;AACzD,IAAA,IAAA,CAAK,UAAA,GAAa,OAAO,UAAA,IAAc,GAAA;AAAA,EACzC;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,QAAA,eAAgC;AAE/C,IAAA,MAAM,aAAa,UAAA,CAAW,IAAA;AAC9B,IAAA,IAAI,WAAW,IAAA,KAAA,WAAA,kBAA+B;AAG9C,IAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,KAAM,MAAA,CAAO,QAAA;AAG3B,IAAA,MAAM,eAAA,GAAkB,KAAK,IAAA,CAAK,CAAA,GAAI,IAAI,CAAA,GAAI,CAAA,GAAI,IAAI,CAAC,CAAA;AAEvD,IAAA,IAAI,eAAA,IAAmB,KAAK,wBAAA,EAA0B;AACpD,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAErB,MAAA,IAAI,GAAA,GAAM,IAAA,CAAK,eAAA,GAAkB,IAAA,CAAK,UAAA,EAAY;AAChD,QAAA;AAAA,MACF;AAEA,MAAA,IAAA,CAAK,eAAA,GAAkB,GAAA;AAEvB,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,SAAA,EAAW,eAAA,IAAmB,GAAA,GAAM,IAAA,CAAK,EAAA;AAAA;AAAA,OAC1C,CAAA;AACD,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,SAAA,EAAW,eAAA,IAAmB,GAAA,GAAM,IAAA,CAAK,EAAA;AAAA,OAC1C,CAAA;AAAA,IACH;AAAA,EACF;AACF;;;ACtCO,IAAM,kBAAA,GAAN,cAAiC,cAAA,CAAe;AAAA,EAOrD,WAAA,CAAY,UAAqB,MAAA,EAAkC;AACjE,IAAA,MAAM,eAAe,CAAA,SAAA,EAAY,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAC1D,IAAA,KAAA,CAAM,cAAc,QAAA,EAAU;AAAA,MAC5B,QAAA,EAAU,OAAO,QAAA,IAAY,CAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AAVH,IAAA,IAAA,CAAQ,YAAA,GAAe,CAAA;AACvB,IAAA,IAAA,CAAQ,YAAA,GAAe,CAAA;AACvB,IAAA,IAAA,CAAQ,WAAA,GAAmC,IAAA;AASzC,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,QAAA;AACvB,IAAA,IAAA,CAAK,SAAA,GAAY,OAAO,SAAA,IAAa,GAAA;AAGrC,IAAA,IAAA,CAAK,mBAAA,EAAoB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,OAAA,EAAgC;AAAA,EAElD;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,KAAA,CAAM,KAAA,EAAM;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AACpB,IAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AAAA,EACtB;AAAA,EAES,OAAA,GAAgB;AACvB,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAA,CAAK,WAAA,EAAY;AACjB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AACA,IAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAA,GAA4B;AAClC,IAAA,IAAA,CAAK,WAAA,GAAc,KAAK,QAAA,CAAS,EAAA;AAAA,MAAA,qBAAA;AAAA,MAE/B,CAAC,KAAA,KAAwB;AACvB,QAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAGnB,QAAA,IAAI,MAAM,KAAA,KAAA,OAAA,cAAiC;AAG3C,QAAA,IAAI,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,WAAW,CAAA,EAAG;AAExC,QAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAGrB,QAAA,IAAI,KAAK,YAAA,GAAe,CAAA,IAAK,MAAM,IAAA,CAAK,YAAA,GAAe,KAAK,SAAA,EAAW;AACrE,UAAA,IAAA,CAAK,KAAA,EAAM;AAAA,QACb;AAGA,QAAA,MAAM,YAAA,GAAe,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,YAAY,CAAA;AACpD,QAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,UAAA,IAAA,CAAK,YAAA,EAAA;AACL,UAAA,IAAA,CAAK,YAAA,GAAe,GAAA;AAGpB,UAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ;AAE7C,YAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,YAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,CAAA;AACzB,YAAA,IAAA,CAAK,iBAAA,CAAkB,EAAE,CAAA;AACzB,YAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AACpB,YAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,KACF;AAAA,EACF;AACF;;;ACpFA,SAAS,sBAAA,CAAuB,IAAI,EAAA,EAAa;AAC/C,EAAA,MAAM,SAAkB,EAAC;AACzB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,KAAA,GAAS,CAAA,GAAI,IAAA,CAAK,EAAA,GAAK,CAAA,GAAK,CAAA;AAClC,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG,CAAA;AAAA,EACxD;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,wBAAA,GAAoC;AAC3C,EAAA,MAAM,MAAe,EAAC;AAEtB,EAAA,MAAM,QAAA,GAAoB;AAAA,IACxB,EAAE,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,CAAA,EAAE;AAAA,IACf,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AAAA,IACb,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA;AAAE,GACf;AACA,EAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,CAAA,EAAG,IAAA,EAAA,EAAQ;AACnC,IAAA,MAAM,IAAA,GAAO,SAAS,IAAI,CAAA;AAC1B,IAAA,MAAM,EAAA,GAAK,QAAA,CAAA,CAAU,IAAA,GAAO,CAAA,IAAK,CAAC,CAAA;AAClC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,MAAA,MAAM,IAAI,CAAA,GAAI,EAAA;AACd,MAAA,GAAA,CAAI,KAAK,EAAE,CAAA,EAAG,KAAK,CAAA,GAAA,CAAK,EAAA,CAAG,IAAI,IAAA,CAAK,CAAA,IAAK,CAAA,EAAG,CAAA,EAAG,KAAK,CAAA,GAAA,CAAK,EAAA,CAAG,IAAI,IAAA,CAAK,CAAA,IAAK,GAAG,CAAA;AAAA,IAC/E;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,qBAAA,GAAiC;AAExC,EAAA,MAAM,MAAe,EAAC;AACtB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,EAAA,EAAI,CAAA,EAAA,EAAK;AAC5B,IAAA,MAAM,IAAI,CAAA,GAAI,EAAA;AACd,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,CAAA,GAAI,KAAK,CAAA,EAAG,GAAA,GAAM,CAAA,GAAI,GAAA,EAAK,CAAA;AAAA,EAC3C;AACA,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,EAAA,EAAI,CAAA,EAAA,EAAK;AAC5B,IAAA,MAAM,IAAI,CAAA,GAAI,EAAA;AACd,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,GAAA,GAAM,CAAA,GAAI,KAAK,CAAA,EAAG,CAAA,GAAI,CAAA,GAAI,CAAA,EAAG,CAAA;AAAA,EAC7C;AACA,EAAA,OAAO,GAAA;AACT;AAEA,IAAM,iBAAA,GAA6C;AAAA,EACjD,QAAQ,sBAAA,EAAuB;AAAA,EAC/B,UAAU,wBAAA,EAAyB;AAAA,EACnC,OAAO,qBAAA;AACT,CAAA;AAEO,IAAM,gBAAA,GAAN,cAA+B,cAAA,CAAe;AAAA,EAQnD,WAAA,CAAY,QAAA,EAAqB,MAAA,GAAiC,EAAC,EAAG;AACpE,IAAA,KAAA,CAAM,UAAU,QAAA,EAAU;AAAA,MACxB,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,WAAA,EAAa,OAAO,WAAA,IAAe,KAAA;AAAA,MACnC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AAVH,IAAA,IAAA,CAAQ,cAAuB,EAAC;AAChC,IAAA,IAAA,CAAQ,SAAA,GAAY,KAAA;AACpB,IAAA,IAAA,CAAQ,aAAA,GAAgB,EAAA;AACxB,IAAA,IAAA,CAAQ,UAAA,GAAa,GAAA;AAQnB,IAAA,IAAA,CAAK,SAAA,GAAY,OAAO,SAAA,IAAa,iBAAA;AACrC,IAAA,IAAA,CAAK,aAAA,GAAgB,OAAO,aAAA,IAAiB,GAAA;AAAA,EAC/C;AAAA,EAEA,kBAAkB,MAAA,EAA+B;AAC/C,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AAEnB,IAAA,MAAM,EAAE,YAAW,GAAI,MAAA;AACvB,IAAA,IAAI,WAAW,SAAA,KAAA,OAAA,cAA+B;AAE9C,IAAA,MAAM,YAAY,UAAA,CAAW,IAAA;AAC7B,IAAA,IAAI,UAAU,IAAA,KAAA,KAAA,YAAwB;AAEtC,IAAA,MAAM,WAAW,IAAA,CAAK,IAAA;AAAA,MACpB,SAAA,CAAU,SAAA,IAAa,CAAA,GAAI,SAAA,CAAU,SAAA,IAAa;AAAA,KACpD;AAGA,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACnB,MAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,MAAA,IAAA,CAAK,cAAc,EAAC;AACpB,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAAA,IAC5B;AAGA,IAAA,IAAA,CAAK,WAAA,CAAY,KAAK,EAAE,CAAA,EAAG,UAAU,CAAA,EAAG,CAAA,EAAG,SAAA,CAAU,CAAA,EAAG,CAAA;AAGxD,IAAA,IAAI,QAAA,GAAW,IAAA,IAAQ,IAAA,CAAK,WAAA,CAAY,SAAS,EAAA,EAAI;AACnD,MAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AACjB,MAAA,IAAA,CAAK,SAAA,EAAU;AAAA,IACjB;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,KAAA,CAAM,KAAA,EAAM;AACZ,IAAA,IAAA,CAAK,cAAc,EAAC;AACpB,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAA,GAAkB;AACxB,IAAA,IAAI,IAAA,CAAK,WAAA,CAAY,MAAA,GAAS,EAAA,EAAI;AAChC,MAAA,IAAA,CAAK,kBAAA,EAAmB;AACxB,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,YAAY,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,WAAA,EAAa,KAAK,aAAa,CAAA;AAGpE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,SAAS,CAAA;AAC3C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,IAAI,SAAA,CAAU,CAAC,CAAA,CAAE,CAAA,EAAG,QAAA,CAAS,CAAA,GAAI,SAAA,CAAU,CAAC,EAAE,CAAC,CAAA;AACjF,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,SAAA,EAAW,CAAC,KAAK,CAAA;AAG/C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,KAAK,UAAU,CAAA;AAGpD,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,iBAAA,CAAkB,MAAM,CAAA;AAGhD,IAAA,IAAI,SAAA,GAAY,EAAA;AAChB,IAAA,IAAI,SAAA,GAAY,CAAA;AAEhB,IAAA,KAAA,MAAW,CAAC,MAAM,cAAc,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAA,EAAG;AAEnE,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,QAAA,CAAS,cAAA,EAAgB,KAAK,aAAa,CAAA;AACnE,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,UAAU,CAAA;AAC7C,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,IAAI,UAAA,CAAW,CAAC,CAAA,CAAE,CAAA,EAAG,SAAA,CAAU,CAAA,GAAI,UAAA,CAAW,CAAC,EAAE,CAAC,CAAA;AACtF,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,UAAA,EAAY,CAAC,MAAM,CAAA;AAClD,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,KAAK,UAAU,CAAA;AACtD,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,iBAAA,CAAkB,OAAO,CAAA;AAElD,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,YAAA,CAAa,UAAA,EAAY,WAAW,CAAA;AAC1D,MAAA,MAAM,eAAe,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,CAAC,IAAI,IAAA,CAAK,UAAA;AAC/C,MAAA,MAAM,KAAA,GAAQ,IAAI,QAAA,GAAW,YAAA;AAE7B,MAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,QAAA,SAAA,GAAY,KAAA;AACZ,QAAA,SAAA,GAAY,IAAA;AAAA,MACd;AAAA,IACF;AAEA,IAAA,IAAI,SAAA,IAAa,KAAK,aAAA,EAAe;AACnC,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,MAAA,EAAQ,SAAA;AAAA,QACR,UAAA,EAAY;AAAA,OACb,CAAA;AACD,MAAA,IAAA,CAAK,iBAAA,CAAkB;AAAA,QACrB,MAAA,EAAQ,SAAA;AAAA,QACR,UAAA,EAAY;AAAA,OACb,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,kBAAA,EAAmB;AAAA,IAC1B;AAEA,IAAA,IAAA,CAAK,cAAc,EAAC;AAAA,EACtB;AAAA;AAAA,EAIQ,QAAA,CAAS,QAAiB,CAAA,EAAoB;AACpD,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA;AAC1C,IAAA,MAAM,QAAA,GAAW,eAAe,CAAA,GAAI,CAAA,CAAA;AACpC,IAAA,MAAM,SAAA,GAAqB,CAAC,MAAA,CAAO,CAAC,CAAC,CAAA;AACrC,IAAA,IAAI,WAAA,GAAc,CAAA;AAElB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,MAAA,MAAM,CAAA,GAAI,KAAK,QAAA,CAAS,MAAA,CAAO,IAAI,CAAC,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA;AAEhD,MAAA,IAAI,WAAA,GAAc,KAAK,QAAA,EAAU;AAC/B,QAAA,MAAM,CAAA,GAAA,CAAK,WAAW,WAAA,IAAe,CAAA;AACrC,QAAA,MAAM,QAAA,GAAkB;AAAA,UACtB,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,CAAC,EAAE,CAAA,GAAI,CAAA,IAAK,MAAA,CAAO,CAAC,CAAA,CAAE,CAAA,GAAI,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,CAAE,CAAA,CAAA;AAAA,UACtD,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,CAAC,EAAE,CAAA,GAAI,CAAA,IAAK,MAAA,CAAO,CAAC,CAAA,CAAE,CAAA,GAAI,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,CAAE,CAAA;AAAA,SACxD;AACA,QAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AACvB,QAAA,MAAA,CAAO,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,QAAQ,CAAA;AAC5B,QAAA,WAAA,GAAc,CAAA;AAAA,MAChB,CAAA,MAAO;AACL,QAAA,WAAA,IAAe,CAAA;AAAA,MACjB;AAAA,IACF;AAGA,IAAA,OAAO,SAAA,CAAU,SAAS,CAAA,EAAG;AAC3B,MAAA,SAAA,CAAU,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAC,CAAA;AAAA,IAC1C;AAEA,IAAA,OAAO,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA;AAAA,EAC7B;AAAA,EAEQ,YAAY,MAAA,EAAwB;AAC1C,IAAA,IAAI,IAAA,GAAO,GAAG,IAAA,GAAO,CAAA;AACrB,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,IAAA,IAAQ,CAAA,CAAE,CAAA;AACV,MAAA,IAAA,IAAQ,CAAA,CAAE,CAAA;AAAA,IACZ;AACA,IAAA,OAAO,EAAE,GAAG,IAAA,GAAO,MAAA,CAAO,QAAQ,CAAA,EAAG,IAAA,GAAO,OAAO,MAAA,EAAO;AAAA,EAC5D;AAAA,EAEQ,QAAA,CAAS,QAAiB,KAAA,EAAwB;AACxD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AACxC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA;AAC1B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA;AAC1B,IAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACxB,CAAA,EAAA,CAAI,CAAA,CAAE,CAAA,GAAI,QAAA,CAAS,CAAA,IAAK,GAAA,GAAA,CAAO,CAAA,CAAE,CAAA,GAAI,QAAA,CAAS,CAAA,IAAK,GAAA,GAAM,QAAA,CAAS,CAAA;AAAA,MAClE,CAAA,EAAA,CAAI,CAAA,CAAE,CAAA,GAAI,QAAA,CAAS,CAAA,IAAK,GAAA,GAAA,CAAO,CAAA,CAAE,CAAA,GAAI,QAAA,CAAS,CAAA,IAAK,GAAA,GAAM,QAAA,CAAS;AAAA,KACpE,CAAE,CAAA;AAAA,EACJ;AAAA,EAEQ,OAAA,CAAQ,QAAiB,IAAA,EAAuB;AACtD,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AAClC,IAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,GAAO,EAAA,CAAG,IAAA;AACvB,IAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,GAAO,EAAA,CAAG,IAAA;AACvB,IAAA,IAAI,CAAA,KAAM,CAAA,IAAK,CAAA,KAAM,CAAA,EAAG,OAAO,MAAA;AAC/B,IAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACxB,CAAA,EAAI,CAAA,CAAE,CAAA,GAAI,IAAA,GAAQ,CAAA;AAAA,MAClB,CAAA,EAAI,CAAA,CAAE,CAAA,GAAI,IAAA,GAAQ;AAAA,KACpB,CAAE,CAAA;AAAA,EACJ;AAAA,EAEQ,kBAAkB,MAAA,EAA0B;AAClD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AACxC,IAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACxB,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,QAAA,CAAS,CAAA;AAAA,MAClB,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,QAAA,CAAS;AAAA,KACpB,CAAE,CAAA;AAAA,EACJ;AAAA,EAEQ,YAAY,MAAA,EAAiB;AACnC,IAAA,IAAI,OAAO,QAAA,EAAU,IAAA,GAAO,QAAA,EAAU,IAAA,GAAO,WAAW,IAAA,GAAO,CAAA,QAAA;AAC/D,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA;AACzB,MAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA;AACzB,MAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA;AACzB,MAAA,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAC,CAAA;AAAA,IAC3B;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAA,EAAK;AAAA,EAClC;AAAA,EAEQ,YAAA,CAAa,GAAY,CAAA,EAAoB;AACnD,IAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,MAAA,EAAQ,EAAE,MAAM,CAAA;AACvC,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,MAAA,KAAA,IAAS,KAAK,QAAA,CAAS,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,IACnC;AACA,IAAA,OAAO,KAAA,GAAQ,GAAA;AAAA,EACjB;AAAA,EAEQ,WAAW,MAAA,EAAyB;AAC1C,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,MAAA,KAAA,IAAS,IAAA,CAAK,SAAS,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IACjD;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,QAAA,CAAS,GAAU,CAAA,EAAkB;AAC3C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAA,CAAM,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,KAAM,CAAA,GAAA,CAAK,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,KAAM,CAAC,CAAA;AAAA,EACtD;AACF;;;ACpRO,IAAM,uBAAN,MAA2B;AAAA,EAA3B,WAAA,GAAA;AACL,IAAA,IAAA,CAAQ,OAAuB,EAAC;AAAA,EAAA;AAAA,EAEhC,IAAI,IAAA,GAAe;AACjB,IAAA,OAAO,KAAK,IAAA,CAAK,MAAA;AAAA,EACnB;AAAA,EAEA,OAAA,GAAmB;AACjB,IAAA,OAAO,IAAA,CAAK,KAAK,MAAA,KAAW,CAAA;AAAA,EAC9B;AAAA;AAAA,EAGA,OAAO,KAAA,EAA2B;AAChC,IAAA,IAAA,CAAK,IAAA,CAAK,KAAK,KAAK,CAAA;AACpB,IAAA,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AAAA,EACpC;AAAA;AAAA,EAGA,UAAA,GAAkC;AAChC,IAAA,IAAI,IAAA,CAAK,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACnC,IAAA,IAAI,KAAK,IAAA,CAAK,MAAA,KAAW,GAAG,OAAO,IAAA,CAAK,KAAK,GAAA,EAAI;AAEjD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AACvB,IAAA,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,KAAK,GAAA,EAAI;AAC7B,IAAA,IAAA,CAAK,WAAW,CAAC,CAAA;AACjB,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA,EAGA,IAAA,GAA4B;AAC1B,IAAA,OAAO,KAAK,IAAA,CAAK,MAAA,GAAS,IAAI,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA;AAAA,EAC/C;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,OAAO,EAAC;AAAA,EACf;AAAA;AAAA,EAGA,QAAA,GAA2B;AACzB,IAAA,MAAM,SAAyB,EAAC;AAChC,IAAA,OAAO,CAAC,IAAA,CAAK,OAAA,EAAQ,EAAG;AACtB,MAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,UAAA,EAAa,CAAA;AAAA,IAChC;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,SAAS,KAAA,EAAqB;AACpC,IAAA,OAAO,QAAQ,CAAA,EAAG;AAChB,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAA,CAAO,KAAA,GAAQ,KAAK,CAAC,CAAA;AAC9C,MAAA,IAAI,IAAA,CAAK,KAAK,WAAW,CAAA,CAAE,YAAY,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA,CAAE,QAAA,EAAU;AAClE,MAAA,CAAC,KAAK,IAAA,CAAK,WAAW,CAAA,EAAG,IAAA,CAAK,KAAK,KAAK,CAAC,CAAA,GAAI,CAAC,KAAK,IAAA,CAAK,KAAK,GAAG,IAAA,CAAK,IAAA,CAAK,WAAW,CAAC,CAAA;AACtF,MAAA,KAAA,GAAQ,WAAA;AAAA,IACV;AAAA,EACF;AAAA,EAEQ,WAAW,KAAA,EAAqB;AACtC,IAAA,MAAM,MAAA,GAAS,KAAK,IAAA,CAAK,MAAA;AACzB,IAAA,OAAO,IAAA,EAAM;AACX,MAAA,IAAI,QAAA,GAAW,KAAA;AACf,MAAA,MAAM,IAAA,GAAO,IAAI,KAAA,GAAQ,CAAA;AACzB,MAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,GAAQ,CAAA;AAE1B,MAAA,IAAI,IAAA,GAAO,MAAA,IAAU,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,CAAE,QAAA,GAAW,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,CAAE,QAAA,EAAU;AAC5E,QAAA,QAAA,GAAW,IAAA;AAAA,MACb;AACA,MAAA,IAAI,KAAA,GAAQ,MAAA,IAAU,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA,CAAE,QAAA,GAAW,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,CAAE,QAAA,EAAU;AAC9E,QAAA,QAAA,GAAW,KAAA;AAAA,MACb;AAEA,MAAA,IAAI,aAAa,KAAA,EAAO;AACxB,MAAA,CAAC,KAAK,IAAA,CAAK,QAAQ,CAAA,EAAG,IAAA,CAAK,KAAK,KAAK,CAAC,CAAA,GAAI,CAAC,KAAK,IAAA,CAAK,KAAK,GAAG,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAC,CAAA;AAChF,MAAA,KAAA,GAAQ,QAAA;AAAA,IACV;AAAA,EACF;AACF;;;AC1EO,IAAM,cAAN,MAAkB;AAAA,EAAlB,WAAA,GAAA;AAEL;AAAA,IAAA,IAAA,CAAQ,KAAA,uBAAY,GAAA,EAAoB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASxC,WAAA,CAAY,aAAqB,QAAA,EAA2B;AAC1D,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,WAAA,EAAa,QAAQ,CAAA;AACpC,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,WAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,KAAA,CAAM,OAAO,WAAW,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,QAAA,CAAS,aAAqB,QAAA,EAA2B;AACvD,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,YAAY,CAAA,IAAK,KAAK,KAAA,EAAO;AACjD,MAAA,IAAI,QAAA,KAAa,WAAA,IAAe,YAAA,IAAgB,QAAA,EAAU;AACxD,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,WAAA,EAA8B;AACpC,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,WAAW,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,eAAA,GAA0B;AAC5B,IAAA,OAAO,KAAK,KAAA,CAAM,IAAA;AAAA,EACpB;AACF;;;ACpDO,IAAM,mBAAN,MAAuB;AAAA,EAU5B,YAAY,QAAA,EAAqB;AANjC,IAAA,IAAA,CAAQ,WAAA,GAAmC,IAAA;AAG3C;AAAA,IAAA,IAAA,CAAQ,gBAAgC,EAAC;AACzC,IAAA,IAAA,CAAQ,mBAAA,GAAsB,KAAA;AAG5B,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAI,oBAAA,EAAqB;AAC9C,IAAA,IAAA,CAAK,WAAA,GAAc,IAAI,WAAA,EAAY;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,WAAA,GAAc,KAAK,QAAA,CAAS,EAAA;AAAA,MAAA,qBAAA;AAAA,MAE/B,CAAC,KAAA,KAAwB;AACvB,QAAA,IAAA,CAAK,aAAA,CAAc,KAAK,KAAK,CAAA;AAC7B,QAAA,IAAA,CAAK,kBAAA,EAAmB;AAAA,MAC1B;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAA,GAAa;AACX,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAA,CAAK,WAAA,EAAY;AACjB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AACA,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AACzB,IAAA,IAAA,CAAK,YAAY,QAAA,EAAS;AAC1B,IAAA,IAAA,CAAK,gBAAgB,EAAC;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAA,GAA2B;AACjC,IAAA,IAAI,KAAK,mBAAA,EAAqB;AAC9B,IAAA,IAAA,CAAK,mBAAA,GAAsB,IAAA;AAG3B,IAAA,OAAA,CAAQ,OAAA,EAAQ,CAAE,IAAA,CAAK,MAAM;AAC3B,MAAA,IAAA,CAAK,mBAAA,GAAsB,KAAA;AAC3B,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAA,GAAsB;AAE5B,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,aAAA,EAAe;AACtC,MAAA,IAAA,CAAK,aAAA,CAAc,OAAO,KAAK,CAAA;AAAA,IACjC;AACA,IAAA,IAAA,CAAK,gBAAgB,EAAC;AAGtB,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,aAAA,CAAc,QAAA,EAAS;AAEjD,IAAA,KAAA,MAAW,SAAS,YAAA,EAAc;AAEhC,MAAA,IAAI,MAAM,WAAA,EAAa;AACrB,QAAA,IAAI,MAAM,KAAA,KAAA,OAAA,cAAiC;AACzC,UAAA,IAAA,CAAK,WAAA,CAAY,WAAA,CAAY,KAAA,CAAM,IAAA,EAAM,MAAM,QAAQ,CAAA;AAAA,QACzD,WACE,KAAA,CAAM,KAAA,KAAA,OAAA,gBACN,KAAA,CAAM,KAAA,KAAA,WAAA,oBACN,MAAM,KAAA,KAAA,QAAA,eACN;AACA,UAAA,IAAA,CAAK,WAAA,CAAY,WAAA,CAAY,KAAA,CAAM,IAAI,CAAA;AAAA,QACzC;AAAA,MACF;AAGA,MAAA,IAAI,KAAK,WAAA,CAAY,QAAA,CAAS,MAAM,IAAA,EAAM,KAAA,CAAM,QAAQ,CAAA,EAAG;AAEzD,QAAA;AAAA,MACF;AAGA,MAAA,IAAA,CAAK,QAAA,CAAS,iDAAoC,KAAK,CAAA;AAAA,IACzD;AAAA,EACF;AAAA;AAAA,EAGA,cAAA,GAA8B;AAC5B,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AACF;;;AC1GO,IAAM,mBAAN,MAAuB;AAAA,EAK5B,YAAY,QAAA,EAAqB;AAJjC,IAAA,IAAA,CAAQ,SAAA,uBAAgB,GAAA,EAA8B;AAEtD,IAAA,IAAA,CAAQ,WAAA,GAAmC,IAAA;AAGzC,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,WAAA,GAAc,KAAK,QAAA,CAAS,EAAA;AAAA,MAAA,mBAAA;AAAA,MAE/B,CAAC,KAAA,KAAwB;AACvB,QAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,MACrB;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAA,GAAa;AACX,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,IAAA,CAAK,WAAA,EAAY;AACjB,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,CAAe,aAAqB,MAAA,EAA8B;AAChE,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,WAAW,CAAA,EAAG;AACpC,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,WAAA,EAAa,EAAE,CAAA;AAAA,IACpC;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,WAAW,CAAA,CAAG,KAAK,MAAM,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,CAAiB,aAAqB,QAAA,EAAwB;AAC5D,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,WAAW,CAAA;AAC9C,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,WAAW,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,QAAQ,CAAA;AAC9D,MAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,QAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,WAAA,EAAa,QAAQ,CAAA;AAAA,MAC1C,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,SAAA,CAAU,OAAO,WAAW,CAAA;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,GAAqB;AACnB,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAS,KAAA,EAA2B;AAC1C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,MAAM,IAAI,CAAA;AAC7C,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AAEtC,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAI;AACF,QAAA,MAAA,CAAO,QAAQ,KAAK,CAAA;AAAA,MACtB,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,CAAA,0CAAA,EAA6C,MAAA,CAAO,QAAQ,CAAA,aAAA,EAAgB,MAAM,IAAI,CAAA,CAAA,CAAA;AAAA,UACtF;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,QAAA,CAAS,iDAAoC,KAAK,CAAA;AAAA,EACzD;AACF;;;AC5FO,IAAM,mBAAN,MAAiD;AAAA,EAItD,WAAA,CAAY,UAAkB,QAAA,EAAyC;AACrE,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EAClB;AAAA,EAEA,QAAQ,KAAA,EAA2B;AACjC,IAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACrB;AACF;;;ACNO,IAAM,oBAAN,MAAkD;AAAA,EAIvD,WAAA,CAAY,UAAkB,SAAA,EAA0C;AACtE,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AAAA,EAEA,QAAQ,KAAA,EAA2B;AACjC,IAAA,IAAA,CAAK,UAAU,KAAK,CAAA;AAAA,EACtB;AACF;;;ACpBO,IAAM,eAAN,MAA6C;AAAA,EAIlD,WAAA,CAAY,UAAkB,QAAA,EAAyC;AACrE,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EAClB;AAAA,EAEA,QAAQ,KAAA,EAA2B;AACjC,IAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACrB;AACF;;;ACJO,IAAM,eAAN,MAA6C;AAAA,EAIlD,WAAA,CAAY,UAAkB,QAAA,EAAyC;AACrE,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EAClB;AAAA,EAEA,QAAQ,KAAA,EAA2B;AACjC,IAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACrB;AACF;;;ACrBA,IAAI,OAAA;AACJ,IAAI,SAAA;AAEJ,SAAS,WAAA,GAAc;AACrB,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,UAAQ,cAAc,CAAA;AAAA,EAClC,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,GAAK,UAAQ,cAAc,CAAA;AACjC,IAAA,SAAA,GAAY,EAAA,CAAG,SAAA;AAAA,EACjB,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAYO,IAAM,iBAAN,MAAkD;AAAA,EAKvD,WAAA,CAAY,UAAU,IAAA,EAAM;AAJ5B,IAAA,IAAA,CAAQ,YAAA,GAAe,KAAA;AACvB,IAAA,IAAA,CAAQ,oBAAA,GAAuB,KAAA;AAI7B,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,IAAA,WAAA,EAAY;AAEZ,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,IACtB,WAAW,SAAA,EAAW;AACpB,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,MAAA,IAAA,CAAK,oBAAA,GAAuB,IAAA;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,IAAI,WAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,gBAAgB,IAAA,CAAK,OAAA;AAAA,EACnC;AAAA,EAEA,QAAQ,KAAA,EAA2B;AACjC,IAAA,IAAI,CAAC,KAAK,WAAA,EAAa;AAGvB,IAAA,IACE,KAAA,CAAM,KAAA,KAAA,OAAA,gBACN,KAAA,CAAM,KAAA,KAAA,OAAA,cACN;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,KAAK,oBAAA,EAAsB;AAC7B,MAAA,SAAA,EAAW,QAAQ,EAAE,CAAA;AACrB,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,cAAc,KAAA,CAAM,IAAA;AAE1B,IAAA,IAAI,WAAA,CAAY,UAAA,CAAW,WAAW,CAAA,IAAK,gBAAgB,OAAA,EAAS;AAElE,MAAA,OAAA,EAAS,iBAAA,GAAoB,OAAA,CAAQ,wBAAA,EAA0B,OAAO,CAAA;AAAA,IACxE,CAAA,MAAA,IAAW,WAAA,KAAgB,KAAA,IAAS,WAAA,KAAgB,YAAA,EAAc;AAEhE,MAAA,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,mBAAA,EAAqB,KAAK,CAAA;AAAA,IAC3D,CAAA,MAAA,IAAW,YAAY,UAAA,CAAW,YAAY,KAAK,WAAA,CAAY,UAAA,CAAW,QAAQ,CAAA,EAAG;AAEnF,MAAA,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,mBAAA,EAAqB,MAAM,CAAA;AAAA,IAC5D,CAAA,MAAO;AAEL,MAAA,OAAA,EAAS,cAAA,IAAiB;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,WAAW,OAAA,EAAwB;AACjC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF;;;ACxEO,IAAM,iBAAN,MAAkD;AAAA,EAIvD,YAAY,QAAA,EAA0C;AAHtD,IAAA,IAAA,CAAQ,YAAA,GAAe,IAAA;AAIrB,IAAA,IAAA,CAAK,WAAW,QAAA,IAAY,IAAA;AAAA,EAC9B;AAAA,EAEA,IAAI,WAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,YAAA;AAAA,EACd;AAAA,EAEA,QAAQ,KAAA,EAA2B;AACjC,IAAA,IAAI,CAAC,IAAA,CAAK,YAAA,IAAgB,CAAC,KAAK,QAAA,EAAU;AAC1C,IAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,QAAA,EAA+C;AACzD,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EAClB;AACF;;;ACpCA,IAAI,iBAAA;AAEJ,SAAS,iBAAA,GAAoB;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,GAAK,UAAQ,cAAc,CAAA;AACjC,IAAA,iBAAA,GAAoB,EAAA,CAAG,iBAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAQO,IAAM,wBAAN,MAAyD;AAAA,EAI9D,WAAA,GAAc;AAHd,IAAA,IAAA,CAAQ,YAAA,GAAe,KAAA;AACvB,IAAA,IAAA,CAAQ,mBAAA,GAAgE,IAAA;AAGtE,IAAA,iBAAA,EAAkB;AAClB,IAAA,IAAA,CAAK,YAAA,GAAe,CAAC,CAAC,iBAAA,EAAmB,wBAAA;AAAA,EAC3C;AAAA,EAEA,IAAI,WAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,YAAA;AAAA,EACd;AAAA,EAEA,QAAQ,KAAA,EAA2B;AACjC,IAAA,IAAI,CAAC,KAAK,YAAA,EAAc;AAGxB,IAAA,IAAI,MAAM,KAAA,KAAA,OAAA,cAAiC;AAE3C,IAAA,MAAM,YAAA,GAAe,KAAK,mBAAA,GACtB,IAAA,CAAK,oBAAoB,KAAK,CAAA,GAC9B,IAAA,CAAK,mBAAA,CAAoB,KAAK,CAAA;AAElC,IAAA,iBAAA,CAAkB,yBAAyB,YAAY,CAAA;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB,OAAA,EAAgD;AACrE,IAAA,IAAA,CAAK,mBAAA,GAAsB,OAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,KAAA,EAA6B;AACvD,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAChB,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,MAAM,QAAQ,CAAA;AAEzB,IAAA,OAAO,qBAAqB,IAAI,CAAA,CAAA;AAAA,EAClC;AACF;;;ACxBO,IAAM,gBAAN,MAAoB;AAAA,EAkCzB,WAAA,CAAY,MAAA,GAA8B,EAAC,EAAG;AAhB9C;AAAA,IAAA,IAAA,CAAQ,cAA6B,EAAC;AAStC;AAAA,IAAA,IAAA,CAAQ,oBAAyC,EAAC;AAGlD;AAAA,IAAA,IAAA,CAAQ,UAAA,GAAa,KAAA;AACrB,IAAA,IAAA,CAAQ,gBAAA,GAAwC,IAAA;AAChD,IAAA,IAAA,CAAQ,mBAAA,GAA2C,IAAA;AAIjD,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,gBAAgB,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,MAAA,CAAO,kBAAkB,GAAG,CAAA;AAAA,MACzD,aAAA,EAAe,OAAO,aAAA,IAAiB,IAAA;AAAA,MACvC,KAAA,EAAO,OAAO,KAAA,IAAS,KAAA;AAAA,MACvB,WAAA,EAAa,OAAO,WAAA,IAAe,GAAA;AAAA,MACnC,YAAA,EAAc,OAAO,YAAA,IAAgB;AAAA,KACvC;AAGA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,QAAA,EAAS;AAG7B,IAAA,IAAA,CAAK,UAAA,GAAa,IAAI,kBAAA,CAAmB,IAAA,CAAK,QAAQ,CAAA;AACtD,IAAA,IAAA,CAAK,cAAc,IAAI,mBAAA;AAAA,MACrB,IAAA,CAAK,QAAA;AAAA,MACL,KAAK,MAAA,CAAO;AAAA,KACd;AAGA,IAAA,IAAA,CAAK,WAAA,GAAc,IAAI,WAAA,CAAY,GAAG,CAAA;AACtC,IAAA,IAAA,CAAK,iBAAA,GAAoB,IAAI,WAAA,CAAY,GAAG,CAAA;AAC5C,IAAA,IAAA,CAAK,YAAA,GAAe,IAAI,kBAAA,EAAmB;AAC3C,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAI,aAAA,EAAc;AACvC,IAAA,IAAA,CAAK,UAAA,GAAa,IAAI,mBAAA,CAAoB,CAAA,EAAG,EAAE,CAAA;AAC/C,IAAA,IAAA,CAAK,YAAA,GAAe,IAAI,YAAA,CAAa,GAAA,EAAK,EAAE,CAAA;AAG5C,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAI,gBAAA,CAAiB,IAAA,CAAK,QAAQ,CAAA;AAG1D,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAI,gBAAA,CAAiB,IAAA,CAAK,QAAQ,CAAA;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,SAAA,GAAqB;AACvB,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAI,KAAK,UAAA,EAAY;AACrB,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAGlB,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAK,QAAA,CAAS,EAAA;AAAA,MAAA,WAAA;AAAA,MAEpC,CAAC,KAAA,KAAsB,IAAA,CAAK,YAAA,CAAa,KAAK;AAAA,KAChD;AAGA,IAAA,IAAA,CAAK,mBAAA,GAAsB,KAAK,QAAA,CAAS,EAAA;AAAA,MAAA,mBAAA;AAAA,MAEvC,CAAC,KAAA,KAAwB;AACvB,QAAA,KAAA,MAAW,QAAA,IAAY,KAAK,iBAAA,EAAmB;AAC7C,UAAA,IAAI,SAAS,WAAA,EAAa;AACxB,YAAA,QAAA,CAAS,QAAQ,KAAK,CAAA;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,KACF;AAGA,IAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AACtB,IAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,IAAA,IAAA,CAAK,iBAAiB,KAAA,EAAM;AAC5B,IAAA,IAAA,CAAK,iBAAiB,KAAA,EAAM;AAE5B,IAAA,IAAI,IAAA,CAAK,OAAO,KAAA,EAAO;AACrB,MAAA,OAAA,CAAQ,GAAA,CAAI,sCAAA,EAAwC,IAAA,CAAK,MAAM,CAAA;AAAA,IACjE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAA,GAAa;AACX,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACtB,IAAA,IAAA,CAAK,UAAA,GAAa,KAAA;AAGlB,IAAA,IAAA,CAAK,WAAW,IAAA,EAAK;AACrB,IAAA,IAAA,CAAK,YAAY,IAAA,EAAK;AACtB,IAAA,IAAA,CAAK,iBAAiB,IAAA,EAAK;AAC3B,IAAA,IAAA,CAAK,iBAAiB,IAAA,EAAK;AAG3B,IAAA,IAAA,CAAK,gBAAA,IAAmB;AACxB,IAAA,IAAA,CAAK,mBAAA,IAAsB;AAC3B,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,IAAA,IAAA,CAAK,mBAAA,GAAsB,IAAA;AAG3B,IAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,IAAA,IAAA,CAAK,kBAAkB,KAAA,EAAM;AAC7B,IAAA,IAAA,CAAK,aAAa,KAAA,EAAM;AACxB,IAAA,IAAA,CAAK,aAAa,KAAA,EAAM;AAGxB,IAAA,KAAA,MAAW,UAAA,IAAc,KAAK,WAAA,EAAa;AACzC,MAAA,UAAA,CAAW,KAAA,EAAM;AAAA,IACnB;AAEA,IAAA,IAAI,IAAA,CAAK,OAAO,KAAA,EAAO;AACrB,MAAA,OAAA,CAAQ,IAAI,yBAAyB,CAAA;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,UAAA,EAA+B;AAChD,IAAA,IAAA,CAAK,WAAA,CAAY,KAAK,UAAU,CAAA;AAChC,IAAA,IAAI,IAAA,CAAK,OAAO,KAAA,EAAO;AACrB,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,uCAAA,EAA0C,UAAA,CAAW,IAAI,CAAA,CAAE,CAAA;AAAA,IACzE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB,YAAA,EAA4B;AAC/C,IAAA,MAAM,KAAA,GAAQ,KAAK,WAAA,CAAY,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,YAAY,CAAA;AACrE,IAAA,IAAI,UAAU,EAAA,EAAI;AAChB,MAAA,MAAM,CAAC,OAAO,CAAA,GAAI,KAAK,WAAA,CAAY,MAAA,CAAO,OAAO,CAAC,CAAA;AAClD,MAAA,OAAA,CAAQ,OAAA,EAAQ;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,CAAe,aAAqB,MAAA,EAA8B;AAChE,IAAA,IAAA,CAAK,gBAAA,CAAiB,cAAA,CAAe,WAAA,EAAa,MAAM,CAAA;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,QAAA,EAAmC;AAClD,IAAA,IAAA,CAAK,iBAAA,CAAkB,KAAK,QAAQ,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,GAAgC;AAC9B,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,WAAW,CAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,IAAA,EAAK;AACV,IAAA,KAAA,MAAW,UAAA,IAAc,KAAK,WAAA,EAAa;AACzC,MAAA,UAAA,CAAW,OAAA,EAAQ;AAAA,IACrB;AACA,IAAA,IAAA,CAAK,cAAc,EAAC;AACpB,IAAA,IAAA,CAAK,oBAAoB,EAAC;AAC1B,IAAA,IAAA,CAAK,iBAAiB,YAAA,EAAa;AACnC,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,aAAa,KAAA,EAAyB;AAC5C,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,cAAA;AAEJ,IAAA,IAAI,MAAM,SAAA,KAAA,OAAA,cAA+B;AACvC,MAAA,MAAM,QAAQ,KAAA,CAAM,IAAA;AAEpB,MAAA,QAAA,GAAW,KAAK,WAAA,CAAY,OAAA,CAAQ,MAAM,CAAA,EAAG,KAAA,CAAM,GAAG,CAAC,CAAA;AACvD,MAAA,cAAA,GAAiB,KAAK,YAAA,CAAa,SAAA;AAAA,QACjC,KAAA,CAAM,CAAA;AAAA,QACN,KAAA,CAAM,CAAA;AAAA,QACN,KAAA,CAAM;AAAA,OACR;AAAA,IACF,CAAA,MAAA,IAAW,MAAM,SAAA,KAAA,QAAA,eAAgC;AAC/C,MAAA,MAAM,SAAS,KAAA,CAAM,IAAA;AAErB,MAAA,QAAA,GAAW,IAAA,CAAK,kBAAkB,QAAA,CAAS,MAAA,CAAO,GAAG,MAAA,CAAO,CAAA,EAAG,OAAO,CAAC,CAAA;AACvE,MAAA,MAAM,YAAY,IAAA,CAAK,IAAA;AAAA,QACrB,SAAS,CAAA,IAAK,CAAA,GAAI,SAAS,CAAA,IAAK,CAAA,GAAI,SAAS,CAAA,IAAK;AAAA,OACpD;AACA,MAAA,cAAA,GAAiB,EAAE,WAAW,QAAA,CAAS,CAAA,EAAG,WAAW,QAAA,CAAS,CAAA,EAAG,UAAU,SAAA,EAAU;AAAA,IACvF,CAAA,MAAO;AAEL,MAAA,QAAA,GAAW,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AAC9B,MAAA,cAAA,GAAiB,EAAE,SAAA,EAAW,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,UAAU,CAAA,EAAE;AAAA,IAC7D;AAGA,IAAA,MAAM,KAAA,GAAQ,KAAK,aAAA,CAAc,SAAA;AAAA,MAC/B,cAAA,CAAe,SAAA;AAAA,MACf,cAAA,CAAe;AAAA,KACjB;AAGA,IAAA,MAAM,mBAAA,GAAsB,IAAA,CAAK,UAAA,CAAW,SAAA,CAAU,eAAe,QAAQ,CAAA;AAG7E,IAAA,MAAM,MAAA,GAA0B;AAAA,MAC9B,UAAA,EAAY,KAAA;AAAA,MACZ,UAAU,cAAA,CAAe,QAAA;AAAA,MACzB,WAAW,cAAA,CAAe,SAAA;AAAA,MAC1B,WAAW,cAAA,CAAe,SAAA;AAAA,MAC1B,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,mBAAA;AAAA,MACA,QAAA;AAAA,MACA,WAAW,KAAA,CAAM;AAAA,KACnB;AAGA,IAAA,IAAA,CAAK,YAAA,CAAa,KAAK,MAAM,CAAA;AAG7B,IAAA,IAAA,CAAK,QAAA,CAAS,iDAAoC,MAAM,CAAA;AAGxD,IAAA,KAAA,MAAW,UAAA,IAAc,KAAK,WAAA,EAAa;AACzC,MAAA,IAAI,WAAW,OAAA,EAAS;AACtB,QAAA,UAAA,CAAW,kBAAkB,MAAM,CAAA;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AACF;;;AC3QO,SAAS,gBAAA,CACd,MAAA,GAAiC,EAAC,EACV;AACxB,EAAA,MAAM,SAAA,GAAY,OAA6B,IAAI,CAAA;AACnD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAE5C,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,MAAM,MAAA,GAAS,IAAI,aAAA,CAAc;AAAA,MAC/B,gBAAgB,MAAA,CAAO,cAAA;AAAA,MACvB,eAAe,MAAA,CAAO,aAAA;AAAA,MACtB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,cAAc,MAAA,CAAO;AAAA,KACtB,CAAA;AAGD,IAAA,IAAI,OAAO,WAAA,EAAa;AACtB,MAAA,KAAA,MAAW,UAAA,IAAc,OAAO,WAAA,EAAa;AAC3C,QAAA,MAAA,CAAO,mBAAmB,UAAU,CAAA;AAAA,MACtC;AAAA,IACF;AAGA,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,KAAA,MAAW,CAAC,aAAa,OAAO,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA,EAAG;AACnE,QAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,UAAA,MAAA,CAAO,cAAA,CAAe,aAAa,MAAM,CAAA;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAGA,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,KAAA,MAAW,QAAA,IAAY,OAAO,QAAA,EAAU;AACtC,QAAA,MAAA,CAAO,iBAAiB,QAAQ,CAAA;AAAA,MAClC;AAAA,IACF;AAGA,IAAA,MAAA,CAAO,KAAA,EAAM;AACb,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,IAAA,UAAA,CAAW,IAAI,CAAA;AAGf,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,OAAA,EAAQ;AACf,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB,CAAA;AAAA,EAEF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACL,QAAQ,SAAA,CAAU,OAAA;AAAA,IAClB;AAAA,GACF;AACF;ACtEO,SAAS,gBAAgB,MAAA,EAAqC;AACnE,EAAA,MAAM,SAAA,GAAYC,OAA6B,IAAI,CAAA;AACnD,EAAA,MAAM,WAAA,GAAcA,MAAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AAGzC,EAAA,WAAA,CAAY,UAAU,MAAA,CAAO,OAAA;AAE7B,EAAAC,UAAU,MAAM;AACd,IAAA,MAAM,MAAA,GAAS,IAAI,aAAA,CAAc;AAAA,MAC/B,cAAA,EAAgB,OAAO,cAAA,IAAkB,GAAA;AAAA,MACzC,aAAA,EAAe,OAAO,aAAA,IAAiB;AAAA,KACxC,CAAA;AAGD,IAAA,MAAM,eAAA,GAAkB,IAAI,eAAA,CAAgB,MAAA,CAAO,QAAA,EAAU;AAAA,MAC3D,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,YAAY,MAAA,CAAO;AAAA,KACpB,CAAA;AACD,IAAA,MAAA,CAAO,mBAAmB,eAAe,CAAA;AAGzC,IAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa,gBAAA,EAAkB,MAAM;AACtD,MAAA,WAAA,CAAY,OAAA,EAAQ;AAAA,IACtB,CAAC,CAAA;AACD,IAAA,MAAA,CAAO,cAAA,CAAe,SAAS,MAAM,CAAA;AAGrC,IAAA,IAAI,MAAA,CAAO,kBAAkB,KAAA,EAAO;AAClC,MAAA,MAAA,CAAO,gBAAA,CAAiB,IAAI,cAAA,CAAe,IAAI,CAAC,CAAA;AAAA,IAClD;AAEA,IAAA,MAAA,CAAO,KAAA,EAAM;AACb,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAEpB,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,OAAA,EAAQ;AACf,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACtB,CAAA;AAAA,EAEF,CAAA,EAAG,CAAC,MAAA,CAAO,SAAA,EAAW,OAAO,UAAA,EAAY,MAAA,CAAO,cAAc,CAAC,CAAA;AACjE;ACtCO,SAAS,aAAa,MAAA,EAAkC;AAC7D,EAAA,MAAM,SAAA,GAAYD,OAA6B,IAAI,CAAA;AACnD,EAAA,MAAM,WAAA,GAAcA,MAAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AACzC,EAAA,WAAA,CAAY,UAAU,MAAA,CAAO,OAAA;AAE7B,EAAAC,UAAU,MAAM;AACd,IAAA,MAAM,MAAA,GAAS,IAAI,aAAA,CAAc;AAAA,MAC/B,aAAA,EAAe,OAAO,aAAA,IAAiB,IAAA;AAAA,MACvC,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,cAAc,MAAA,CAAO;AAAA,KACtB,CAAA;AAED,IAAA,MAAM,WAAA,GAAc,CAAA,WAAA,EAAc,MAAA,CAAO,IAAI,CAAA,CAAA;AAE7C,IAAA,MAAM,UAAA,GAAa,IAAI,mBAAA,CAAoB,MAAA,CAAO,QAAA,EAAU;AAAA,MAC1D,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,eAAe,MAAA,CAAO,aAAA;AAAA,MACtB,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,cAAc,MAAA,CAAO;AAAA,KACtB,CAAA;AACD,IAAA,MAAA,CAAO,mBAAmB,UAAU,CAAA;AAEpC,IAAA,MAAM,SAAS,IAAI,YAAA,CAAa,GAAG,WAAW,CAAA,SAAA,CAAA,EAAa,CAAC,KAAA,KAAU;AACpE,MAAA,WAAA,CAAY,QAAQ,KAAK,CAAA;AAAA,IAC3B,CAAC,CAAA;AACD,IAAA,MAAA,CAAO,cAAA,CAAe,aAAa,MAAM,CAAA;AAEzC,IAAA,IAAI,MAAA,CAAO,kBAAkB,KAAA,EAAO;AAClC,MAAA,MAAA,CAAO,gBAAA,CAAiB,IAAI,cAAA,CAAe,IAAI,CAAC,CAAA;AAAA,IAClD;AAEA,IAAA,MAAA,CAAO,KAAA,EAAM;AACb,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAEpB,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,OAAA,EAAQ;AACf,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACtB,CAAA;AAAA,EAEF,CAAA,EAAG,CAAC,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,aAAa,MAAA,CAAO,aAAA,EAAe,MAAA,CAAO,WAAW,CAAC,CAAA;AAChF;ACnDO,SAAS,mBAAmB,MAAA,EAAwC;AACzE,EAAA,MAAM,SAAA,GAAYD,OAA6B,IAAI,CAAA;AACnD,EAAA,MAAM,WAAA,GAAcA,MAAAA,CAAO,MAAA,CAAO,UAAU,CAAA;AAC5C,EAAA,WAAA,CAAY,UAAU,MAAA,CAAO,UAAA;AAE7B,EAAAC,UAAU,MAAM;AACd,IAAA,MAAM,MAAA,GAAS,IAAI,aAAA,CAAc;AAAA,MAC/B,aAAA,EAAe,OAAO,aAAA,IAAiB;AAAA,KACxC,CAAA;AAED,IAAA,MAAM,eAAe,CAAA,SAAA,EAAY,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAE1D,IAAA,MAAM,UAAA,GAAa,IAAI,kBAAA,CAAmB,MAAA,CAAO,QAAA,EAAU;AAAA,MACzD,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,WAAW,MAAA,CAAO;AAAA,KACnB,CAAA;AACD,IAAA,MAAA,CAAO,mBAAmB,UAAU,CAAA;AAEpC,IAAA,MAAM,SAAS,IAAI,YAAA,CAAa,CAAA,EAAG,YAAY,aAAa,MAAM;AAChE,MAAA,WAAA,CAAY,OAAA,EAAQ;AAAA,IACtB,CAAC,CAAA;AACD,IAAA,MAAA,CAAO,cAAA,CAAe,cAAc,MAAM,CAAA;AAE1C,IAAA,IAAI,MAAA,CAAO,kBAAkB,KAAA,EAAO;AAClC,MAAA,MAAA,CAAO,gBAAA,CAAiB,IAAI,cAAA,CAAe,IAAI,CAAC,CAAA;AAAA,IAClD;AAEA,IAAA,MAAA,CAAO,KAAA,EAAM;AACb,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAEpB,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,OAAA,EAAQ;AACf,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACtB,CAAA;AAAA,EAEF,CAAA,EAAG,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,GAAG,CAAA,EAAG,MAAA,CAAO,SAAS,CAAC,CAAA;AAClD","file":"index.mjs","sourcesContent":["// ─── EventBus ───────────────────────────────────────────────────────────────\r\n// Typed pub/sub system connecting all pipeline layers.\r\n// Provides compile-time safety: each channel maps to a specific payload type.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n EventChannel,\r\n EventChannelMap,\r\n EventHandler,\r\n IEventBus,\r\n} from './types';\r\n\r\n/**\r\n * Typed EventBus implementation.\r\n *\r\n * Design decisions:\r\n * - Lives outside the React tree to avoid unnecessary re-renders.\r\n * - Uses Map<channel, Set<handler>> for O(1) subscribe/unsubscribe.\r\n * - Generic channel parameter ensures type-safe emit/subscribe at compile time.\r\n * - `on()` returns an unsubscribe function for easy cleanup in useEffect.\r\n */\r\nexport class EventBus implements IEventBus {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private listeners = new Map<EventChannel, Set<EventHandler<any>>>();\r\n\r\n /**\r\n * Subscribe to a channel. Returns an unsubscribe function.\r\n *\r\n * @example\r\n * const unsub = bus.on(EventChannel.InputRaw, (event) => { ... });\r\n * // later:\r\n * unsub();\r\n */\r\n on<C extends EventChannel>(channel: C, handler: EventHandler<C>): () => void {\r\n if (!this.listeners.has(channel)) {\r\n this.listeners.set(channel, new Set());\r\n }\r\n this.listeners.get(channel)!.add(handler);\r\n\r\n // Return unsubscribe function for convenience (useEffect cleanup)\r\n return () => this.off(channel, handler);\r\n }\r\n\r\n /**\r\n * Emit data on a channel. All registered handlers are called synchronously.\r\n * The generic parameter ensures the data type matches the channel.\r\n */\r\n emit<C extends EventChannel>(channel: C, data: EventChannelMap[C]): void {\r\n const handlers = this.listeners.get(channel);\r\n if (!handlers) return;\r\n\r\n // Iterate over a copy to allow handlers to unsubscribe during emit\r\n for (const handler of Array.from(handlers)) {\r\n try {\r\n handler(data);\r\n } catch (error) {\r\n // Swallow handler errors to prevent one bad handler from\r\n // breaking the entire pipeline. In production, these should\r\n // be reported to an error tracking service.\r\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\r\n console.error(`[EventBus] Error in handler for ${channel}:`, error);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove a specific handler from a channel.\r\n */\r\n off<C extends EventChannel>(channel: C, handler: EventHandler<C>): void {\r\n const handlers = this.listeners.get(channel);\r\n if (handlers) {\r\n handlers.delete(handler);\r\n if (handlers.size === 0) {\r\n this.listeners.delete(channel);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove all handlers from all channels. Called during engine teardown.\r\n */\r\n clear(): void {\r\n this.listeners.clear();\r\n }\r\n}\r\n\r\n// Check if __DEV__ is defined (React Native global)\r\ndeclare const __DEV__: boolean | undefined;\r\n","// ─── Core Types ─────────────────────────────────────────────────────────────\r\n// All interfaces, enums, and type aliases for the gesture engine pipeline.\r\n// Each layer consumes and produces typed data objects connected via EventBus.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 1: Input Data Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Classification of input sources feeding into the pipeline */\r\nexport enum InputType {\r\n Touch = 'touch',\r\n Sensor = 'sensor',\r\n Hardware = 'hardware',\r\n Camera = 'camera',\r\n}\r\n\r\n/** Sub-type classification for touch inputs */\r\nexport enum TouchType {\r\n Pan = 'pan',\r\n Tap = 'tap',\r\n Pinch = 'pinch',\r\n Rotation = 'rotation',\r\n}\r\n\r\n/** Sub-type classification for sensor inputs */\r\nexport enum SensorType {\r\n Accelerometer = 'accelerometer',\r\n Gyroscope = 'gyroscope',\r\n}\r\n\r\n/** Normalized touch data emitted by TouchInputProvider */\r\nexport interface TouchData {\r\n /** Touch sub-type (pan, tap, pinch, rotation) */\r\n type: TouchType;\r\n /** Current X position in screen coordinates */\r\n x: number;\r\n /** Current Y position in screen coordinates */\r\n y: number;\r\n /** Translation from start point on X axis */\r\n translationX: number;\r\n /** Translation from start point on Y axis */\r\n translationY: number;\r\n /** Instantaneous velocity on X axis (px/ms) */\r\n velocityX: number;\r\n /** Instantaneous velocity on Y axis (px/ms) */\r\n velocityY: number;\r\n /** Scale factor for pinch gestures (1.0 = no scale) */\r\n scale: number;\r\n /** Rotation angle in radians for rotation gestures */\r\n rotation: number;\r\n /** Number of active touch points */\r\n numberOfPointers: number;\r\n}\r\n\r\n/** Sensor data emitted by SensorInputProvider */\r\nexport interface SensorData {\r\n type: SensorType;\r\n x: number;\r\n y: number;\r\n z: number;\r\n}\r\n\r\n/** Hardware input data (e.g., volume button presses) */\r\nexport interface HardwareData {\r\n /** Key identifier, e.g. 'volumeUp', 'volumeDown' */\r\n key: string;\r\n /** Press action: 'down' or 'up' */\r\n action: 'down' | 'up';\r\n}\r\n\r\n/**\r\n * Unified input event emitted by all providers on the InputRaw channel.\r\n * The `data` field is discriminated by `inputType`.\r\n */\r\nexport interface InputEvent {\r\n /** Unique event identifier */\r\n id: string;\r\n /** Timestamp in milliseconds (performance.now or Date.now) */\r\n timestamp: number;\r\n /** Source classification */\r\n inputType: InputType;\r\n /** Payload — shape depends on inputType */\r\n data: TouchData | SensorData | HardwareData;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 2: Processing Data Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Cardinal direction classification */\r\nexport enum CardinalDirection {\r\n Up = 'up',\r\n Down = 'down',\r\n Left = 'left',\r\n Right = 'right',\r\n UpLeft = 'up-left',\r\n UpRight = 'up-right',\r\n DownLeft = 'down-left',\r\n DownRight = 'down-right',\r\n None = 'none',\r\n}\r\n\r\n/**\r\n * Enriched data produced by the processing layer.\r\n * Combines raw input with computed velocity, angle, and normalized magnitude.\r\n */\r\nexport interface ProcessedSample {\r\n /** Reference to the original input event */\r\n inputEvent: InputEvent;\r\n /** Computed velocity magnitude (px/ms or g/ms) */\r\n velocity: number;\r\n /** Velocity on X axis */\r\n velocityX: number;\r\n /** Velocity on Y axis */\r\n velocityY: number;\r\n /** Direction angle in radians */\r\n angleRadians: number;\r\n /** Direction angle in degrees */\r\n angleDegrees: number;\r\n /** Cardinal direction classification */\r\n direction: CardinalDirection;\r\n /** Magnitude normalized to [0, 1] */\r\n normalizedMagnitude: number;\r\n /** Filtered data coordinates (noise-reduced) */\r\n filtered: { x: number; y: number; z: number };\r\n /** Processing timestamp */\r\n timestamp: number;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 3: Recognition Data Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * Recognizer state machine states.\r\n * Transitions: Idle → Possible → Began → Changed → Ended\r\n * ↘ Failed / Cancelled\r\n */\r\nexport enum RecognizerState {\r\n Idle = 'idle',\r\n Possible = 'possible',\r\n Began = 'began',\r\n Changed = 'changed',\r\n Ended = 'ended',\r\n Failed = 'failed',\r\n Cancelled = 'cancelled',\r\n}\r\n\r\n/** Additional metadata attached to gesture events */\r\nexport interface GestureMetadata {\r\n /** Translation amount for pan/swipe gestures */\r\n translation?: { x: number; y: number };\r\n /** Scale factor for pinch gestures */\r\n scale?: number;\r\n /** Rotation angle for rotation gestures */\r\n rotation?: number;\r\n /** Velocity at recognition time */\r\n velocity?: { x: number; y: number };\r\n /** Edge identifier for edge-swipe gestures */\r\n edge?: 'left' | 'right' | 'top' | 'bottom';\r\n /** Detected symbol name for symbol recognizer */\r\n symbol?: string;\r\n /** Confidence score [0, 1] for symbol recognizer */\r\n confidence?: number;\r\n /** Sensor magnitude for shake/tilt/flick gestures */\r\n magnitude?: number;\r\n /** Tilt angles */\r\n tilt?: { pitch: number; roll: number };\r\n /** Generic key-value bag for custom recognizers */\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Event emitted when a recognizer transitions state.\r\n * This is the primary output of Layer 3, consumed by conflict resolution and actions.\r\n */\r\nexport interface GestureEvent {\r\n /** Unique event identifier */\r\n id: string;\r\n /** Human-readable gesture name, e.g. 'tap', 'shake', 'edge-swipe-left' */\r\n name: string;\r\n /** Current recognizer state */\r\n state: RecognizerState;\r\n /** Recognizer priority (lower = higher priority) */\r\n priority: number;\r\n /** Whether this gesture is exclusive (blocks others) */\r\n isExclusive: boolean;\r\n /** Event timestamp */\r\n timestamp: number;\r\n /** Gesture-specific metadata */\r\n metadata: GestureMetadata;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 4: EventBus Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Named channels for the typed pub/sub EventBus */\r\nexport enum EventChannel {\r\n /** Raw input data from providers */\r\n InputRaw = 'input:raw',\r\n /** Processed samples with velocity, angle, normalization */\r\n ProcessingSample = 'processing:sample',\r\n /** Gesture recognition events (state transitions) */\r\n RecognitionGesture = 'recognition:gesture',\r\n /** Events that survived conflict resolution */\r\n ConflictResolved = 'conflict:resolved',\r\n /** Events after action dispatch */\r\n ActionDispatched = 'action:dispatched',\r\n}\r\n\r\n/** Compile-time mapping from channel to payload type */\r\nexport interface EventChannelMap {\r\n [EventChannel.InputRaw]: InputEvent;\r\n [EventChannel.ProcessingSample]: ProcessedSample;\r\n [EventChannel.RecognitionGesture]: GestureEvent;\r\n [EventChannel.ConflictResolved]: GestureEvent;\r\n [EventChannel.ActionDispatched]: GestureEvent;\r\n}\r\n\r\n/** Typed event handler */\r\nexport type EventHandler<C extends EventChannel> = (data: EventChannelMap[C]) => void;\r\n\r\n/** EventBus interface */\r\nexport interface IEventBus {\r\n on<C extends EventChannel>(channel: C, handler: EventHandler<C>): () => void;\r\n emit<C extends EventChannel>(channel: C, data: EventChannelMap[C]): void;\r\n off<C extends EventChannel>(channel: C, handler: EventHandler<C>): void;\r\n clear(): void;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 5: Layer Interfaces\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Interface for all input providers (Layer 1) */\r\nexport interface IInputProvider {\r\n /** Start emitting input events */\r\n start(): void;\r\n /** Stop emitting input events and clean up subscriptions */\r\n stop(): void;\r\n /** Whether the provider is currently active */\r\n readonly isActive: boolean;\r\n}\r\n\r\n/** Interface for all gesture recognizers (Layer 3) */\r\nexport interface IRecognizer {\r\n /** Unique recognizer identifier */\r\n readonly id: string;\r\n /** Human-readable name matching the GestureEvent.name field */\r\n readonly name: string;\r\n /** Priority: lower number = higher priority */\r\n readonly priority: number;\r\n /** If true, activating this gesture blocks lower-priority gestures */\r\n readonly isExclusive: boolean;\r\n /** Current state machine state */\r\n readonly state: RecognizerState;\r\n /** Enable/disable the recognizer at runtime */\r\n enabled: boolean;\r\n /** Feed a processed sample into the recognizer for evaluation */\r\n onProcessedSample(sample: ProcessedSample): void;\r\n /** Reset the recognizer to Idle state */\r\n reset(): void;\r\n /** Clean up resources */\r\n dispose(): void;\r\n}\r\n\r\n/** Interface for gesture actions (Layer 5) */\r\nexport interface IGestureAction {\r\n /** Unique action identifier */\r\n readonly actionId: string;\r\n /** Execute the action in response to a resolved gesture */\r\n execute(event: GestureEvent): void;\r\n}\r\n\r\n/** Interface for feedback providers (Layer 6) */\r\nexport interface IFeedbackProvider {\r\n /** Trigger feedback in response to a resolved gesture */\r\n trigger(event: GestureEvent): void;\r\n /** Whether this feedback type is supported on the current device */\r\n readonly isSupported: boolean;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 6: Configuration Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Configuration for the GestureEngine orchestrator */\r\nexport interface GestureEngineConfig {\r\n /** Sensor polling interval in ms (default 100 = 10Hz). Max 16 (~60Hz). */\r\n sensorInterval?: number;\r\n /** Enable haptic feedback (requires expo-haptics) */\r\n hapticEnabled?: boolean;\r\n /** Enable debug logging */\r\n debug?: boolean;\r\n /** Screen dimensions for edge detection */\r\n screenWidth?: number;\r\n /** Screen dimensions for edge detection */\r\n screenHeight?: number;\r\n}\r\n\r\n/** Configuration for recognizers */\r\nexport interface RecognizerConfig {\r\n /** Override the default priority */\r\n priority?: number;\r\n /** Override the default exclusive setting */\r\n isExclusive?: boolean;\r\n /** Whether the recognizer starts enabled */\r\n enabled?: boolean;\r\n}\r\n\r\n/** Tap recognizer specific config */\r\nexport interface TapRecognizerConfig extends RecognizerConfig {\r\n /** Maximum duration for a tap in ms (default 300) */\r\n maxDuration?: number;\r\n /** Maximum movement threshold in px (default 10) */\r\n maxDistance?: number;\r\n}\r\n\r\n/** Double-tap recognizer specific config */\r\nexport interface DoubleTapRecognizerConfig extends RecognizerConfig {\r\n /** Maximum time between taps in ms (default 300) */\r\n maxInterval?: number;\r\n /** Maximum movement between taps in px (default 30) */\r\n maxDistance?: number;\r\n}\r\n\r\n/** Pan recognizer specific config */\r\nexport interface PanRecognizerConfig extends RecognizerConfig {\r\n /** Minimum distance to activate in px (default 10) */\r\n minDistance?: number;\r\n}\r\n\r\n/** Pinch recognizer specific config */\r\nexport interface PinchRecognizerConfig extends RecognizerConfig {\r\n /** Minimum scale change to activate (default 0.05) */\r\n minScale?: number;\r\n}\r\n\r\n/** Rotation recognizer specific config */\r\nexport interface RotationRecognizerConfig extends RecognizerConfig {\r\n /** Minimum rotation in radians to activate (default 0.05) */\r\n minRotation?: number;\r\n}\r\n\r\n/** Edge-swipe recognizer specific config */\r\nexport interface EdgeSwipeRecognizerConfig extends RecognizerConfig {\r\n /** Edge to detect: 'left', 'right', 'top', 'bottom' */\r\n edge: 'left' | 'right' | 'top' | 'bottom';\r\n /** Width of the edge detection zone in px (default 30) */\r\n edgeZoneWidth?: number;\r\n /** Minimum swipe distance in px (default 50) */\r\n minDistance?: number;\r\n /** Minimum velocity in px/ms (default 0.3) */\r\n minVelocity?: number;\r\n /** Screen width in px */\r\n screenWidth?: number;\r\n /** Screen height in px */\r\n screenHeight?: number;\r\n}\r\n\r\n/** Corner recognizer specific config */\r\nexport interface CornerRecognizerConfig extends RecognizerConfig {\r\n /** Corner to detect */\r\n corner: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\r\n /** Size of the corner zone in px (default 50) */\r\n cornerZoneSize?: number;\r\n /** Minimum swipe distance in px (default 40) */\r\n minDistance?: number;\r\n /** Screen width in px */\r\n screenWidth?: number;\r\n /** Screen height in px */\r\n screenHeight?: number;\r\n}\r\n\r\n/** Shake recognizer specific config */\r\nexport interface ShakeRecognizerConfig extends RecognizerConfig {\r\n /** Acceleration threshold in g (default 1.5) */\r\n threshold?: number;\r\n /** Consecutive samples above threshold to trigger (default 2) */\r\n consecutiveSamples?: number;\r\n /** Cooldown period in ms (default 1000) */\r\n cooldownMs?: number;\r\n}\r\n\r\n/** Tilt recognizer specific config */\r\nexport interface TiltRecognizerConfig extends RecognizerConfig {\r\n /** Tilt angle threshold in degrees (default 30) */\r\n tiltThreshold?: number;\r\n /** Cooldown period in ms (default 500) */\r\n cooldownMs?: number;\r\n}\r\n\r\n/** Wrist-flick recognizer specific config */\r\nexport interface WristFlickRecognizerConfig extends RecognizerConfig {\r\n /** Angular velocity threshold in deg/s (default 150) */\r\n angularVelocityThreshold?: number;\r\n /** Cooldown in ms (default 800) */\r\n cooldownMs?: number;\r\n}\r\n\r\n/** Sequence recognizer specific config */\r\nexport interface SequenceRecognizerConfig extends RecognizerConfig {\r\n /** Ordered gesture names to match */\r\n sequence: string[];\r\n /** Max time between steps in ms (default 800) */\r\n timeoutMs?: number;\r\n}\r\n\r\n/** Symbol recognizer specific config */\r\nexport interface SymbolRecognizerConfig extends RecognizerConfig {\r\n /** Templates to match against: name → point array */\r\n templates?: Record<string, Array<{ x: number; y: number }>>;\r\n /** Minimum confidence score to accept (default 0.7) */\r\n minConfidence?: number;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 7: Utility Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Utility type to generate unique IDs */\r\nexport type UniqueId = string;\r\n\r\n/** Helper to create a unique ID */\r\nexport function generateId(): UniqueId {\r\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\r\n}\r\n","// ─── TouchInputProvider ─────────────────────────────────────────────────────\r\n// Wraps React Native Gesture Handler gestures and emits normalized TouchData\r\n// on the EventBus InputRaw channel for downstream processing.\r\n//\r\n// Design: This provider doesn't create gesture recognizers directly — instead\r\n// it provides a `createGesture()` method that returns a composed RNGH gesture\r\n// for use inside a GestureDetector. The callbacks emit InputEvents to the bus.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IInputProvider,\r\n IEventBus,\r\n EventChannel,\r\n InputType,\r\n TouchType,\r\n TouchData,\r\n InputEvent,\r\n generateId,\r\n} from '../core/types';\r\n\r\n/**\r\n * TouchInputProvider wraps RNGH pan/tap/pinch/rotation gestures\r\n * and normalizes their data into InputEvent objects.\r\n *\r\n * Usage:\r\n * - Call `start()` to enable event emission\r\n * - Use the gesture handler callbacks (onPan, onTap, etc.) inside\r\n * GestureDetector components\r\n * - Call `stop()` to disable emission\r\n */\r\nexport class TouchInputProvider implements IInputProvider {\r\n private _isActive = false;\r\n\r\n constructor(private eventBus: IEventBus) {}\r\n\r\n get isActive(): boolean {\r\n return this._isActive;\r\n }\r\n\r\n start(): void {\r\n this._isActive = true;\r\n }\r\n\r\n stop(): void {\r\n this._isActive = false;\r\n }\r\n\r\n /**\r\n * Called from RNGH Pan gesture callbacks.\r\n * Emits normalized TouchData with translation and velocity.\r\n */\r\n onPan(data: {\r\n x: number;\r\n y: number;\r\n translationX: number;\r\n translationY: number;\r\n velocityX: number;\r\n velocityY: number;\r\n numberOfPointers: number;\r\n }): void {\r\n if (!this._isActive) return;\r\n\r\n const touchData: TouchData = {\r\n type: TouchType.Pan,\r\n x: data.x,\r\n y: data.y,\r\n translationX: data.translationX,\r\n translationY: data.translationY,\r\n velocityX: data.velocityX,\r\n velocityY: data.velocityY,\r\n scale: 1,\r\n rotation: 0,\r\n numberOfPointers: data.numberOfPointers,\r\n };\r\n\r\n this.emitInput(touchData);\r\n }\r\n\r\n /**\r\n * Called from RNGH Tap gesture callbacks.\r\n */\r\n onTap(data: { x: number; y: number; numberOfPointers: number }): void {\r\n if (!this._isActive) return;\r\n\r\n const touchData: TouchData = {\r\n type: TouchType.Tap,\r\n x: data.x,\r\n y: data.y,\r\n translationX: 0,\r\n translationY: 0,\r\n velocityX: 0,\r\n velocityY: 0,\r\n scale: 1,\r\n rotation: 0,\r\n numberOfPointers: data.numberOfPointers,\r\n };\r\n\r\n this.emitInput(touchData);\r\n }\r\n\r\n /**\r\n * Called from RNGH Pinch gesture callbacks.\r\n */\r\n onPinch(data: {\r\n scale: number;\r\n focalX: number;\r\n focalY: number;\r\n velocity: number;\r\n numberOfPointers: number;\r\n }): void {\r\n if (!this._isActive) return;\r\n\r\n const touchData: TouchData = {\r\n type: TouchType.Pinch,\r\n x: data.focalX,\r\n y: data.focalY,\r\n translationX: 0,\r\n translationY: 0,\r\n velocityX: 0,\r\n velocityY: data.velocity,\r\n scale: data.scale,\r\n rotation: 0,\r\n numberOfPointers: data.numberOfPointers,\r\n };\r\n\r\n this.emitInput(touchData);\r\n }\r\n\r\n /**\r\n * Called from RNGH Rotation gesture callbacks.\r\n */\r\n onRotation(data: {\r\n rotation: number;\r\n anchorX: number;\r\n anchorY: number;\r\n velocity: number;\r\n numberOfPointers: number;\r\n }): void {\r\n if (!this._isActive) return;\r\n\r\n const touchData: TouchData = {\r\n type: TouchType.Rotation,\r\n x: data.anchorX,\r\n y: data.anchorY,\r\n translationX: 0,\r\n translationY: 0,\r\n velocityX: 0,\r\n velocityY: data.velocity,\r\n scale: 1,\r\n rotation: data.rotation,\r\n numberOfPointers: data.numberOfPointers,\r\n };\r\n\r\n this.emitInput(touchData);\r\n }\r\n\r\n /** Emit a normalized InputEvent onto the EventBus */\r\n private emitInput(touchData: TouchData): void {\r\n const event: InputEvent = {\r\n id: generateId(),\r\n timestamp: Date.now(),\r\n inputType: InputType.Touch,\r\n data: touchData,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.InputRaw, event);\r\n }\r\n}\r\n","// ─── SensorInputProvider ────────────────────────────────────────────────────\r\n// Subscribes to Accelerometer and Gyroscope from expo-sensors and emits\r\n// SensorData events on the EventBus. Supports configurable update intervals\r\n// and lazy initialization (only subscribes when start() is called).\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IInputProvider,\r\n IEventBus,\r\n EventChannel,\r\n InputType,\r\n SensorType,\r\n SensorData,\r\n InputEvent,\r\n generateId,\r\n} from '../core/types';\r\n\r\n// Lazy imports — expo-sensors is a peer dependency\r\nlet Accelerometer: any;\r\nlet Gyroscope: any;\r\n\r\nfunction loadSensorModules() {\r\n try {\r\n const sensors = require('expo-sensors');\r\n Accelerometer = sensors.Accelerometer;\r\n Gyroscope = sensors.Gyroscope;\r\n } catch {\r\n console.warn(\r\n '[GestureEngine] expo-sensors not found. SensorInputProvider will not function.',\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * SensorInputProvider subscribes to device accelerometer and gyroscope\r\n * and emits normalized SensorData events.\r\n *\r\n * Performance considerations:\r\n * - Default update interval is 100ms (10Hz) — configurable, capped at ~60Hz.\r\n * - Subscriptions are lazily created and cleaned up on stop().\r\n * - Data is emitted as-is; filtering happens in the Processing layer.\r\n */\r\nexport class SensorInputProvider implements IInputProvider {\r\n private _isActive = false;\r\n private accelSubscription: { remove(): void } | null = null;\r\n private gyroSubscription: { remove(): void } | null = null;\r\n private updateIntervalMs: number;\r\n\r\n constructor(\r\n private eventBus: IEventBus,\r\n updateIntervalMs = 100,\r\n ) {\r\n // Clamp to minimum 16ms (~60Hz) to prevent battery drain\r\n this.updateIntervalMs = Math.max(16, updateIntervalMs);\r\n loadSensorModules();\r\n }\r\n\r\n get isActive(): boolean {\r\n return this._isActive;\r\n }\r\n\r\n start(): void {\r\n if (this._isActive) return;\r\n this._isActive = true;\r\n\r\n if (!Accelerometer || !Gyroscope) {\r\n console.warn('[GestureEngine] Sensors unavailable. Skipping sensor subscriptions.');\r\n return;\r\n }\r\n\r\n // Configure update intervals\r\n Accelerometer.setUpdateInterval(this.updateIntervalMs);\r\n Gyroscope.setUpdateInterval(this.updateIntervalMs);\r\n\r\n // Subscribe to accelerometer\r\n this.accelSubscription = Accelerometer.addListener(\r\n (data: { x: number; y: number; z: number }) => {\r\n if (!this._isActive) return;\r\n\r\n const sensorData: SensorData = {\r\n type: SensorType.Accelerometer,\r\n x: data.x,\r\n y: data.y,\r\n z: data.z,\r\n };\r\n\r\n const event: InputEvent = {\r\n id: generateId(),\r\n timestamp: Date.now(),\r\n inputType: InputType.Sensor,\r\n data: sensorData,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.InputRaw, event);\r\n },\r\n );\r\n\r\n // Subscribe to gyroscope\r\n this.gyroSubscription = Gyroscope.addListener(\r\n (data: { x: number; y: number; z: number }) => {\r\n if (!this._isActive) return;\r\n\r\n const sensorData: SensorData = {\r\n type: SensorType.Gyroscope,\r\n x: data.x,\r\n y: data.y,\r\n z: data.z,\r\n };\r\n\r\n const event: InputEvent = {\r\n id: generateId(),\r\n timestamp: Date.now(),\r\n inputType: InputType.Sensor,\r\n data: sensorData,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.InputRaw, event);\r\n },\r\n );\r\n }\r\n\r\n stop(): void {\r\n this._isActive = false;\r\n\r\n if (this.accelSubscription) {\r\n this.accelSubscription.remove();\r\n this.accelSubscription = null;\r\n }\r\n\r\n if (this.gyroSubscription) {\r\n this.gyroSubscription.remove();\r\n this.gyroSubscription = null;\r\n }\r\n }\r\n}\r\n","// ─── HardwareInputProvider ──────────────────────────────────────────────────\r\n// Extensible stub for hardware button events (e.g., volume buttons on Android).\r\n// Uses DeviceEventEmitter to listen for native module events.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IInputProvider,\r\n IEventBus,\r\n EventChannel,\r\n InputType,\r\n HardwareData,\r\n InputEvent,\r\n generateId,\r\n} from '../core/types';\r\n\r\n// Lazy import — may not be available in all environments\r\nlet DeviceEventEmitter: any;\r\n\r\nfunction loadEmitter() {\r\n try {\r\n const rn = require('react-native');\r\n DeviceEventEmitter = rn.DeviceEventEmitter;\r\n } catch {\r\n // React Native not available (testing or web)\r\n }\r\n}\r\n\r\n/**\r\n * HardwareInputProvider listens for hardware button events on Android\r\n * via DeviceEventEmitter and emits them as InputEvents.\r\n *\r\n * Note: This requires a companion native module to forward volume button\r\n * events. Without one, this provider is effectively a no-op stub that\r\n * demonstrates the extensibility of the input layer.\r\n *\r\n * To extend for custom hardware events:\r\n * 1. Create a native module that emits 'onHardwareKey' events\r\n * 2. The event payload should contain { key: string, action: 'down' | 'up' }\r\n */\r\nexport class HardwareInputProvider implements IInputProvider {\r\n private _isActive = false;\r\n private subscription: { remove(): void } | null = null;\r\n private eventName: string;\r\n\r\n constructor(\r\n private eventBus: IEventBus,\r\n eventName = 'onHardwareKey',\r\n ) {\r\n this.eventName = eventName;\r\n loadEmitter();\r\n }\r\n\r\n get isActive(): boolean {\r\n return this._isActive;\r\n }\r\n\r\n start(): void {\r\n if (this._isActive) return;\r\n this._isActive = true;\r\n\r\n if (!DeviceEventEmitter) {\r\n return;\r\n }\r\n\r\n this.subscription = DeviceEventEmitter.addListener(\r\n this.eventName,\r\n (data: { key: string; action: 'down' | 'up' }) => {\r\n if (!this._isActive) return;\r\n\r\n const hardwareData: HardwareData = {\r\n key: data.key,\r\n action: data.action,\r\n };\r\n\r\n const event: InputEvent = {\r\n id: generateId(),\r\n timestamp: Date.now(),\r\n inputType: InputType.Hardware,\r\n data: hardwareData,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.InputRaw, event);\r\n },\r\n );\r\n }\r\n\r\n stop(): void {\r\n this._isActive = false;\r\n\r\n if (this.subscription) {\r\n this.subscription.remove();\r\n this.subscription = null;\r\n }\r\n }\r\n}\r\n","// ─── CameraInputProvider ────────────────────────────────────────────────────\r\n// Future-ready no-op stub implementing IInputProvider.\r\n// Placeholder for computer-vision-based gesture input (e.g., hand tracking).\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IInputProvider, IEventBus } from '../core/types';\r\n\r\n/**\r\n * CameraInputProvider is a future-ready stub for camera-based gesture input.\r\n *\r\n * When implemented, this would:\r\n * - Subscribe to a camera frame processing pipeline\r\n * - Run hand/pose detection models\r\n * - Emit InputEvents with detected gesture landmarks\r\n *\r\n * Currently a no-op — calling start()/stop() has no effect.\r\n */\r\nexport class CameraInputProvider implements IInputProvider {\r\n private _isActive = false;\r\n\r\n // EventBus stored for future use when camera input is implemented\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n constructor(private eventBus: IEventBus) {}\r\n\r\n get isActive(): boolean {\r\n return this._isActive;\r\n }\r\n\r\n start(): void {\r\n this._isActive = true;\r\n // Future: subscribe to camera frame pipeline\r\n }\r\n\r\n stop(): void {\r\n this._isActive = false;\r\n // Future: unsubscribe from camera frames\r\n }\r\n}\r\n","// ─── NoiseFilter ────────────────────────────────────────────────────────────\r\n// IIR (Infinite Impulse Response) low-pass and high-pass filters.\r\n// Low-pass removes jitter/noise; high-pass removes gravity component.\r\n// Configurable alpha controls filter responsiveness vs. smoothness.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * First-order IIR noise filter with both low-pass and high-pass modes.\r\n *\r\n * Low-pass: output = α * input + (1 - α) * previousOutput\r\n * - Smooths noisy signals (e.g., touch jitter)\r\n * - Higher alpha = more responsive but noisier\r\n *\r\n * High-pass: output = input - lowPass(input)\r\n * - Removes slowly-changing components (e.g., gravity from accelerometer)\r\n * - Isolates sudden movements (shakes, flicks)\r\n */\r\nexport class NoiseFilter {\r\n private lowPassState: { x: number; y: number; z: number } | null = null;\r\n private alpha: number;\r\n\r\n /**\r\n * @param alpha - Filter coefficient [0, 1]. Default 0.8.\r\n * - For low-pass: 0.1 = very smooth, 0.9 = barely filtered\r\n * - For high-pass: same alpha applied to the underlying low-pass\r\n */\r\n constructor(alpha = 0.8) {\r\n this.alpha = Math.max(0, Math.min(1, alpha));\r\n }\r\n\r\n /**\r\n * Apply low-pass filter. Removes high-frequency jitter.\r\n */\r\n lowPass(x: number, y: number, z: number): { x: number; y: number; z: number } {\r\n if (this.lowPassState === null) {\r\n // First sample — initialize state\r\n this.lowPassState = { x, y, z };\r\n return { x, y, z };\r\n }\r\n\r\n const prev = this.lowPassState;\r\n const filtered = {\r\n x: this.alpha * x + (1 - this.alpha) * prev.x,\r\n y: this.alpha * y + (1 - this.alpha) * prev.y,\r\n z: this.alpha * z + (1 - this.alpha) * prev.z,\r\n };\r\n\r\n this.lowPassState = filtered;\r\n return filtered;\r\n }\r\n\r\n /**\r\n * Apply high-pass filter. Removes low-frequency components (gravity).\r\n * Returns only the dynamic/transient part of the signal.\r\n */\r\n highPass(x: number, y: number, z: number): { x: number; y: number; z: number } {\r\n const low = this.lowPass(x, y, z);\r\n return {\r\n x: x - low.x,\r\n y: y - low.y,\r\n z: z - low.z,\r\n };\r\n }\r\n\r\n /**\r\n * Reset filter state. Call when starting a new gesture or after a pause.\r\n */\r\n reset(): void {\r\n this.lowPassState = null;\r\n }\r\n\r\n /**\r\n * Update alpha dynamically (e.g., for adaptive filtering).\r\n */\r\n setAlpha(alpha: number): void {\r\n this.alpha = Math.max(0, Math.min(1, alpha));\r\n }\r\n}\r\n","// ─── VelocityCalculator ─────────────────────────────────────────────────────\r\n// Computes velocity as Δposition / Δtime from sequential samples.\r\n// Handles edge cases: first sample, zero time delta, and NaN prevention.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Computes velocity from sequential position/time samples.\r\n * Velocity = (currentPosition - previousPosition) / (currentTime - previousTime)\r\n */\r\nexport class VelocityCalculator {\r\n private prevX: number | null = null;\r\n private prevY: number | null = null;\r\n private prevTimestamp: number | null = null;\r\n\r\n /**\r\n * Calculate velocity from a new position sample.\r\n *\r\n * @param x - Current X position\r\n * @param y - Current Y position\r\n * @param timestamp - Current timestamp in milliseconds\r\n * @returns Velocity components and magnitude\r\n */\r\n calculate(\r\n x: number,\r\n y: number,\r\n timestamp: number,\r\n ): {\r\n velocityX: number;\r\n velocityY: number;\r\n velocity: number;\r\n } {\r\n if (this.prevX === null || this.prevY === null || this.prevTimestamp === null) {\r\n // First sample — no velocity yet\r\n this.prevX = x;\r\n this.prevY = y;\r\n this.prevTimestamp = timestamp;\r\n return { velocityX: 0, velocityY: 0, velocity: 0 };\r\n }\r\n\r\n const dt = timestamp - this.prevTimestamp;\r\n\r\n // Guard against division by zero (simultaneous events)\r\n if (dt <= 0) {\r\n return { velocityX: 0, velocityY: 0, velocity: 0 };\r\n }\r\n\r\n const dx = x - this.prevX;\r\n const dy = y - this.prevY;\r\n\r\n const velocityX = dx / dt;\r\n const velocityY = dy / dt;\r\n const velocity = Math.sqrt(velocityX * velocityX + velocityY * velocityY);\r\n\r\n // Update state for next calculation\r\n this.prevX = x;\r\n this.prevY = y;\r\n this.prevTimestamp = timestamp;\r\n\r\n return { velocityX, velocityY, velocity };\r\n }\r\n\r\n /**\r\n * Reset state. Call when starting a new gesture.\r\n */\r\n reset(): void {\r\n this.prevX = null;\r\n this.prevY = null;\r\n this.prevTimestamp = null;\r\n }\r\n}\r\n","// ─── AngleDetector ──────────────────────────────────────────────────────────\r\n// Computes direction angle from X/Y components using Math.atan2.\r\n// Provides both radians and degrees, plus cardinal direction classification.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { CardinalDirection } from '../core/types';\r\n\r\n/**\r\n * Detects direction angle and classifies into cardinal directions.\r\n *\r\n * Coordinate system:\r\n * - 0° / 0 rad = right\r\n * - 90° / π/2 rad = down (screen coordinates, Y grows downward)\r\n * - 180° / π rad = left\r\n * - -90° / -π/2 rad = up\r\n */\r\nexport class AngleDetector {\r\n /**\r\n * Calculate angle from X/Y deltas.\r\n *\r\n * @param dx - Change in X (positive = right)\r\n * @param dy - Change in Y (positive = down in screen coords)\r\n * @returns Angle in radians, degrees, and cardinal direction\r\n */\r\n calculate(\r\n dx: number,\r\n dy: number,\r\n ): {\r\n angleRadians: number;\r\n angleDegrees: number;\r\n direction: CardinalDirection;\r\n } {\r\n // No movement — no direction\r\n if (dx === 0 && dy === 0) {\r\n return {\r\n angleRadians: 0,\r\n angleDegrees: 0,\r\n direction: CardinalDirection.None,\r\n };\r\n }\r\n\r\n const angleRadians = Math.atan2(dy, dx);\r\n const angleDegrees = (angleRadians * 180) / Math.PI;\r\n const direction = this.classifyDirection(angleDegrees);\r\n\r\n return { angleRadians, angleDegrees, direction };\r\n }\r\n\r\n /**\r\n * Classify angle (in degrees) into 8 cardinal directions.\r\n * Uses 45° sectors centered on each direction.\r\n *\r\n * Sectors (in screen coordinates where Y grows down):\r\n * Right: -22.5° to 22.5°\r\n * DownRight: 22.5° to 67.5°\r\n * Down: 67.5° to 112.5°\r\n * DownLeft: 112.5° to 157.5°\r\n * Left: 157.5° to 180° or -180° to -157.5°\r\n * UpLeft: -157.5° to -112.5°\r\n * Up: -112.5° to -67.5°\r\n * UpRight: -67.5° to -22.5°\r\n */\r\n private classifyDirection(degrees: number): CardinalDirection {\r\n // Normalize to [-180, 180]\r\n const d = degrees;\r\n\r\n if (d >= -22.5 && d < 22.5) return CardinalDirection.Right;\r\n if (d >= 22.5 && d < 67.5) return CardinalDirection.DownRight;\r\n if (d >= 67.5 && d < 112.5) return CardinalDirection.Down;\r\n if (d >= 112.5 && d < 157.5) return CardinalDirection.DownLeft;\r\n if (d >= 157.5 || d < -157.5) return CardinalDirection.Left;\r\n if (d >= -157.5 && d < -112.5) return CardinalDirection.UpLeft;\r\n if (d >= -112.5 && d < -67.5) return CardinalDirection.Up;\r\n if (d >= -67.5 && d < -22.5) return CardinalDirection.UpRight;\r\n\r\n return CardinalDirection.None;\r\n }\r\n}\r\n","// ─── ThresholdNormalizer ─────────────────────────────────────────────────────\r\n// Maps raw magnitude values to the [0, 1] range given min/max thresholds.\r\n// Values below min map to 0, above max map to 1, in between are linear.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Maps raw magnitudes to a normalized [0, 1] range with clamping.\r\n *\r\n * Formula: normalized = clamp((value - min) / (max - min), 0, 1)\r\n *\r\n * This is useful for turning raw sensor values (e.g., acceleration in g,\r\n * velocity in px/ms) into intensity values that can be used for feedback\r\n * or threshold comparison.\r\n */\r\nexport class ThresholdNormalizer {\r\n private min: number;\r\n private max: number;\r\n\r\n /**\r\n * @param min - Minimum threshold. Values at or below this map to 0.\r\n * @param max - Maximum threshold. Values at or above this map to 1.\r\n */\r\n constructor(min = 0, max = 1) {\r\n if (min >= max) {\r\n throw new Error(\r\n `[ThresholdNormalizer] min (${min}) must be less than max (${max})`,\r\n );\r\n }\r\n this.min = min;\r\n this.max = max;\r\n }\r\n\r\n /**\r\n * Normalize a raw value to [0, 1].\r\n */\r\n normalize(value: number): number {\r\n if (value <= this.min) return 0;\r\n if (value >= this.max) return 1;\r\n return (value - this.min) / (this.max - this.min);\r\n }\r\n\r\n /**\r\n * Update thresholds dynamically.\r\n */\r\n setRange(min: number, max: number): void {\r\n if (min >= max) {\r\n throw new Error(\r\n `[ThresholdNormalizer] min (${min}) must be less than max (${max})`,\r\n );\r\n }\r\n this.min = min;\r\n this.max = max;\r\n }\r\n\r\n /**\r\n * Get current min threshold.\r\n */\r\n getMin(): number {\r\n return this.min;\r\n }\r\n\r\n /**\r\n * Get current max threshold.\r\n */\r\n getMax(): number {\r\n return this.max;\r\n }\r\n}\r\n","// ─── StreamBuffer ───────────────────────────────────────────────────────────\r\n// Time-windowed ring buffer retaining ProcessedSample objects from the last\r\n// 300–500ms. Provides O(1) insertion and automatic eviction of stale entries.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample } from '../core/types';\r\n\r\n/**\r\n * Fixed-size ring buffer with time-based eviction.\r\n *\r\n * Design decisions:\r\n * - Uses a pre-allocated array with head/tail pointers for O(1) push.\r\n * - Evicts entries older than windowMs on each push (amortized O(1)).\r\n * - Capacity is generously sized (default 64) to handle burst input at 60Hz.\r\n * - getAll() returns samples in chronological order.\r\n */\r\nexport class StreamBuffer {\r\n private buffer: (ProcessedSample | null)[];\r\n private head = 0;\r\n private count = 0;\r\n private capacity: number;\r\n private windowMs: number;\r\n\r\n /**\r\n * @param windowMs - Time window in ms. Samples older than this are evicted. Default 400.\r\n * @param capacity - Maximum buffer size. Default 64 (~1 sec at 60Hz).\r\n */\r\n constructor(windowMs = 400, capacity = 64) {\r\n this.windowMs = windowMs;\r\n this.capacity = capacity;\r\n this.buffer = new Array(capacity).fill(null);\r\n }\r\n\r\n /**\r\n * Push a new sample. Automatically evicts stale samples.\r\n * O(1) amortized.\r\n */\r\n push(sample: ProcessedSample): void {\r\n // Write to current head position\r\n const writeIndex = (this.head + this.count) % this.capacity;\r\n\r\n if (this.count === this.capacity) {\r\n // Buffer full — overwrite oldest (advance head)\r\n this.buffer[this.head] = sample;\r\n this.head = (this.head + 1) % this.capacity;\r\n } else {\r\n this.buffer[writeIndex] = sample;\r\n this.count++;\r\n }\r\n\r\n // Evict stale samples from the head\r\n this.evictStale(sample.timestamp);\r\n }\r\n\r\n /**\r\n * Get all non-stale samples in chronological order.\r\n */\r\n getAll(): ProcessedSample[] {\r\n const result: ProcessedSample[] = [];\r\n for (let i = 0; i < this.count; i++) {\r\n const index = (this.head + i) % this.capacity;\r\n const sample = this.buffer[index];\r\n if (sample) {\r\n result.push(sample);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Get the most recent sample, or null if buffer is empty.\r\n */\r\n latest(): ProcessedSample | null {\r\n if (this.count === 0) return null;\r\n const index = (this.head + this.count - 1) % this.capacity;\r\n return this.buffer[index];\r\n }\r\n\r\n /**\r\n * Get the number of samples currently in the buffer.\r\n */\r\n size(): number {\r\n return this.count;\r\n }\r\n\r\n /**\r\n * Clear the buffer.\r\n */\r\n clear(): void {\r\n this.buffer.fill(null);\r\n this.head = 0;\r\n this.count = 0;\r\n }\r\n\r\n /**\r\n * Remove samples older than windowMs from the head.\r\n */\r\n private evictStale(currentTimestamp: number): void {\r\n const cutoff = currentTimestamp - this.windowMs;\r\n\r\n while (this.count > 0) {\r\n const sample = this.buffer[this.head];\r\n if (sample && sample.timestamp < cutoff) {\r\n this.buffer[this.head] = null;\r\n this.head = (this.head + 1) % this.capacity;\r\n this.count--;\r\n } else {\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n","// ─── BaseRecognizer ─────────────────────────────────────────────────────────\r\n// Abstract base class for all gesture recognizers with built-in state machine.\r\n// Implements IRecognizer and provides transition logic, EventBus integration,\r\n// and common lifecycle methods (reset, dispose).\r\n//\r\n// State transitions:\r\n// Idle → Possible → Began → Changed → Ended\r\n// ↘ Failed / Cancelled\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IRecognizer,\r\n IEventBus,\r\n RecognizerState,\r\n ProcessedSample,\r\n GestureEvent,\r\n GestureMetadata,\r\n EventChannel,\r\n generateId,\r\n} from '../../core/types';\r\n\r\n/**\r\n * Abstract base class for all gesture recognizers.\r\n *\r\n * Subclasses must implement:\r\n * - `onProcessedSample(sample)`: evaluate the sample and call transition methods\r\n *\r\n * The base class provides:\r\n * - State machine with validated transitions\r\n * - Automatic GestureEvent emission on state changes\r\n * - EventBus integration\r\n * - reset() and dispose() lifecycle methods\r\n */\r\nexport abstract class BaseRecognizer implements IRecognizer {\r\n readonly id: string;\r\n readonly name: string;\r\n readonly priority: number;\r\n readonly isExclusive: boolean;\r\n enabled: boolean;\r\n\r\n private _state: RecognizerState = RecognizerState.Idle;\r\n protected eventBus: IEventBus;\r\n\r\n constructor(\r\n name: string,\r\n eventBus: IEventBus,\r\n options: {\r\n priority?: number;\r\n isExclusive?: boolean;\r\n enabled?: boolean;\r\n } = {},\r\n ) {\r\n this.id = generateId();\r\n this.name = name;\r\n this.eventBus = eventBus;\r\n this.priority = options.priority ?? 100;\r\n this.isExclusive = options.isExclusive ?? false;\r\n this.enabled = options.enabled ?? true;\r\n }\r\n\r\n get state(): RecognizerState {\r\n return this._state;\r\n }\r\n\r\n /**\r\n * Must be implemented by subclasses.\r\n * Evaluate the incoming processed sample and trigger state transitions.\r\n */\r\n abstract onProcessedSample(sample: ProcessedSample): void;\r\n\r\n /**\r\n * Reset the recognizer to Idle state.\r\n */\r\n reset(): void {\r\n this._state = RecognizerState.Idle;\r\n }\r\n\r\n /**\r\n * Clean up resources. Override in subclasses for custom cleanup.\r\n */\r\n dispose(): void {\r\n this.reset();\r\n }\r\n\r\n // ─── Protected: state transition helpers ────────────────────────────\r\n\r\n /**\r\n * Transition to Possible state (gesture might be starting).\r\n */\r\n protected transitionToPossible(): void {\r\n if (this._state === RecognizerState.Idle) {\r\n this._state = RecognizerState.Possible;\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Began state and emit gesture event.\r\n * Only valid from Possible state.\r\n */\r\n protected transitionToBegan(metadata: GestureMetadata = {}): void {\r\n if (this._state === RecognizerState.Possible) {\r\n this._state = RecognizerState.Began;\r\n this.emitGestureEvent(metadata);\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Changed state and emit gesture event.\r\n * Only valid from Began or Changed state (continuous gestures).\r\n */\r\n protected transitionToChanged(metadata: GestureMetadata = {}): void {\r\n if (\r\n this._state === RecognizerState.Began ||\r\n this._state === RecognizerState.Changed\r\n ) {\r\n this._state = RecognizerState.Changed;\r\n this.emitGestureEvent(metadata);\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Ended state and emit gesture event.\r\n * Valid from Began, Changed, or Possible states.\r\n */\r\n protected transitionToEnded(metadata: GestureMetadata = {}): void {\r\n if (\r\n this._state === RecognizerState.Began ||\r\n this._state === RecognizerState.Changed ||\r\n this._state === RecognizerState.Possible\r\n ) {\r\n this._state = RecognizerState.Ended;\r\n this.emitGestureEvent(metadata);\r\n // Auto-reset to Idle after Ended\r\n this._state = RecognizerState.Idle;\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Failed state (gesture didn't match criteria).\r\n * Auto-resets to Idle.\r\n */\r\n protected transitionToFailed(): void {\r\n if (\r\n this._state === RecognizerState.Possible ||\r\n this._state === RecognizerState.Began\r\n ) {\r\n this._state = RecognizerState.Failed;\r\n // Auto-reset to Idle\r\n this._state = RecognizerState.Idle;\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Cancelled state (gesture was interrupted).\r\n * Auto-resets to Idle.\r\n */\r\n protected transitionToCancelled(): void {\r\n if (\r\n this._state === RecognizerState.Began ||\r\n this._state === RecognizerState.Changed\r\n ) {\r\n this._state = RecognizerState.Cancelled;\r\n this.emitGestureEvent({});\r\n this._state = RecognizerState.Idle;\r\n }\r\n }\r\n\r\n /**\r\n * Emit a GestureEvent on the RecognitionGesture channel.\r\n */\r\n private emitGestureEvent(metadata: GestureMetadata): void {\r\n const event: GestureEvent = {\r\n id: generateId(),\r\n name: this.name,\r\n state: this._state,\r\n priority: this.priority,\r\n isExclusive: this.isExclusive,\r\n timestamp: Date.now(),\r\n metadata,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.RecognitionGesture, event);\r\n }\r\n}\r\n","// ─── TapRecognizer ──────────────────────────────────────────────────────────\r\n// Detects single-tap gestures. A tap must:\r\n// 1. Start and end within maxDuration ms\r\n// 2. Not move more than maxDistance px from the start point\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, TapRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class TapRecognizer extends BaseRecognizer {\r\n private maxDuration: number;\r\n private maxDistance: number;\r\n private startTime: number | null = null;\r\n private startX: number | null = null;\r\n private startY: number | null = null;\r\n\r\n constructor(eventBus: IEventBus, config: TapRecognizerConfig = {}) {\r\n super('tap', eventBus, {\r\n priority: config.priority ?? 10,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.maxDuration = config.maxDuration ?? 300;\r\n this.maxDistance = config.maxDistance ?? 10;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Tap && touchData.type !== TouchType.Pan) return;\r\n\r\n // Handle tap type directly — RNGH fires onEnd for taps\r\n if (touchData.type === TouchType.Tap) {\r\n this.transitionToPossible();\r\n this.transitionToBegan({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n this.transitionToEnded({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n return;\r\n }\r\n\r\n // For pan-based tap detection: track motion to verify it's a tap\r\n if (this.startTime === null) {\r\n this.startTime = inputEvent.timestamp;\r\n this.startX = touchData.x;\r\n this.startY = touchData.y;\r\n this.transitionToPossible();\r\n return;\r\n }\r\n\r\n const elapsed = inputEvent.timestamp - this.startTime;\r\n const dx = touchData.x - (this.startX ?? 0);\r\n const dy = touchData.y - (this.startY ?? 0);\r\n const distance = Math.sqrt(dx * dx + dy * dy);\r\n\r\n // Too much movement — not a tap\r\n if (distance > this.maxDistance) {\r\n this.transitionToFailed();\r\n this.resetState();\r\n return;\r\n }\r\n\r\n // Duration exceeded — not a tap\r\n if (elapsed > this.maxDuration) {\r\n this.transitionToFailed();\r\n this.resetState();\r\n return;\r\n }\r\n\r\n // Velocity drops to near zero (finger lifted) — recognize as tap\r\n if (\r\n Math.abs(touchData.velocityX) < 0.01 &&\r\n Math.abs(touchData.velocityY) < 0.01 &&\r\n elapsed > 20\r\n ) {\r\n this.transitionToBegan({\r\n translation: { x: this.startX ?? 0, y: this.startY ?? 0 },\r\n });\r\n this.transitionToEnded({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n this.resetState();\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.resetState();\r\n }\r\n\r\n private resetState(): void {\r\n this.startTime = null;\r\n this.startX = null;\r\n this.startY = null;\r\n }\r\n}\r\n","// ─── DoubleTapRecognizer ────────────────────────────────────────────────────\r\n// Detects double-tap gestures. Two taps must occur within maxInterval ms\r\n// and within maxDistance px of each other.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, DoubleTapRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class DoubleTapRecognizer extends BaseRecognizer {\r\n private maxInterval: number;\r\n private maxDistance: number;\r\n private firstTapTime: number | null = null;\r\n private firstTapX: number | null = null;\r\n private firstTapY: number | null = null;\r\n private tapCount = 0;\r\n\r\n constructor(eventBus: IEventBus, config: DoubleTapRecognizerConfig = {}) {\r\n super('double-tap', eventBus, {\r\n priority: config.priority ?? 5,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.maxInterval = config.maxInterval ?? 300;\r\n this.maxDistance = config.maxDistance ?? 30;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Tap) return;\r\n\r\n const now = inputEvent.timestamp;\r\n\r\n if (this.tapCount === 0) {\r\n // First tap\r\n this.firstTapTime = now;\r\n this.firstTapX = touchData.x;\r\n this.firstTapY = touchData.y;\r\n this.tapCount = 1;\r\n this.transitionToPossible();\r\n return;\r\n }\r\n\r\n if (this.tapCount === 1) {\r\n const elapsed = now - (this.firstTapTime ?? 0);\r\n const dx = touchData.x - (this.firstTapX ?? 0);\r\n const dy = touchData.y - (this.firstTapY ?? 0);\r\n const distance = Math.sqrt(dx * dx + dy * dy);\r\n\r\n if (elapsed <= this.maxInterval && distance <= this.maxDistance) {\r\n // Second tap within bounds — double tap recognized\r\n this.transitionToBegan({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n this.transitionToEnded({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n this.resetState();\r\n } else {\r\n // Timed out or too far — treat this as a new first tap\r\n this.transitionToFailed();\r\n this.firstTapTime = now;\r\n this.firstTapX = touchData.x;\r\n this.firstTapY = touchData.y;\r\n this.tapCount = 1;\r\n this.transitionToPossible();\r\n }\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.resetState();\r\n }\r\n\r\n private resetState(): void {\r\n this.firstTapTime = null;\r\n this.firstTapX = null;\r\n this.firstTapY = null;\r\n this.tapCount = 0;\r\n }\r\n}\r\n","// ─── PanRecognizer ──────────────────────────────────────────────────────────\r\n// Continuous recognizer that emits Changed state with translation data\r\n// once the finger moves beyond a minimum threshold distance.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, PanRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class PanRecognizer extends BaseRecognizer {\r\n private minDistance: number;\r\n\r\n constructor(eventBus: IEventBus, config: PanRecognizerConfig = {}) {\r\n super('pan', eventBus, {\r\n priority: config.priority ?? 50,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.minDistance = config.minDistance ?? 10;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pan) return;\r\n\r\n const translation = {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n };\r\n const distance = Math.sqrt(\r\n translation.x * translation.x + translation.y * translation.y,\r\n );\r\n\r\n const velocity = {\r\n x: touchData.velocityX,\r\n y: touchData.velocityY,\r\n };\r\n\r\n // Check if we've moved enough to start recognizing\r\n if (this.state === 'idle' || this.state === 'possible') {\r\n this.transitionToPossible();\r\n if (distance >= this.minDistance) {\r\n this.transitionToBegan({ translation, velocity });\r\n }\r\n return;\r\n }\r\n\r\n // Continue emitting Changed events\r\n if (this.state === 'began' || this.state === 'changed') {\r\n // Detect end: velocity near zero and a brief pause\r\n if (\r\n Math.abs(touchData.velocityX) < 0.001 &&\r\n Math.abs(touchData.velocityY) < 0.001\r\n ) {\r\n this.transitionToEnded({ translation, velocity });\r\n } else {\r\n this.transitionToChanged({ translation, velocity });\r\n }\r\n }\r\n }\r\n}\r\n","// ─── PinchRecognizer ────────────────────────────────────────────────────────\r\n// Continuous recognizer for pinch/zoom gestures.\r\n// Emits Changed state with scale factor updates.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, PinchRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class PinchRecognizer extends BaseRecognizer {\r\n private minScale: number;\r\n\r\n constructor(eventBus: IEventBus, config: PinchRecognizerConfig = {}) {\r\n super('pinch', eventBus, {\r\n priority: config.priority ?? 40,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.minScale = config.minScale ?? 0.05;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pinch) return;\r\n\r\n const scaleDelta = Math.abs(touchData.scale - 1);\r\n\r\n if (this.state === 'idle' || this.state === 'possible') {\r\n this.transitionToPossible();\r\n if (scaleDelta >= this.minScale) {\r\n this.transitionToBegan({ scale: touchData.scale });\r\n }\r\n return;\r\n }\r\n\r\n if (this.state === 'began' || this.state === 'changed') {\r\n if (touchData.numberOfPointers < 2) {\r\n this.transitionToEnded({ scale: touchData.scale });\r\n } else {\r\n this.transitionToChanged({ scale: touchData.scale });\r\n }\r\n }\r\n }\r\n}\r\n","// ─── RotationRecognizer ─────────────────────────────────────────────────────\r\n// Continuous recognizer for two-finger rotation gestures.\r\n// Emits Changed state with rotation angle updates.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, RotationRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class RotationRecognizer extends BaseRecognizer {\r\n private minRotation: number;\r\n\r\n constructor(eventBus: IEventBus, config: RotationRecognizerConfig = {}) {\r\n super('rotation', eventBus, {\r\n priority: config.priority ?? 45,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.minRotation = config.minRotation ?? 0.05;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Rotation) return;\r\n\r\n const rotationAbs = Math.abs(touchData.rotation);\r\n\r\n if (this.state === 'idle' || this.state === 'possible') {\r\n this.transitionToPossible();\r\n if (rotationAbs >= this.minRotation) {\r\n this.transitionToBegan({ rotation: touchData.rotation });\r\n }\r\n return;\r\n }\r\n\r\n if (this.state === 'began' || this.state === 'changed') {\r\n if (touchData.numberOfPointers < 2) {\r\n this.transitionToEnded({ rotation: touchData.rotation });\r\n } else {\r\n this.transitionToChanged({ rotation: touchData.rotation });\r\n }\r\n }\r\n }\r\n}\r\n","// ─── EdgeSwipeRecognizer ────────────────────────────────────────────────────\r\n// Detects gestures that START within the edge zone of the screen.\r\n// Supports all 4 edges (left, right, top, bottom) with configurable:\r\n// - Edge zone width (default 30px)\r\n// - Minimum swipe distance (default 50px)\r\n// - Minimum velocity (default 0.3 px/ms)\r\n//\r\n// Emits GestureEvent with name 'edge-swipe-{left|right|top|bottom}'\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, TouchType, TouchData,\r\n IEventBus, EdgeSwipeRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class EdgeSwipeRecognizer extends BaseRecognizer {\r\n private edge: 'left' | 'right' | 'top' | 'bottom';\r\n private edgeZoneWidth: number;\r\n private minDistance: number;\r\n private minVelocity: number;\r\n private screenWidth: number;\r\n private screenHeight: number;\r\n private startedInEdge = false;\r\n private startX: number | null = null;\r\n private startY: number | null = null;\r\n\r\n constructor(eventBus: IEventBus, config: EdgeSwipeRecognizerConfig) {\r\n super(`edge-swipe-${config.edge}`, eventBus, {\r\n priority: config.priority ?? 20,\r\n isExclusive: config.isExclusive ?? true,\r\n enabled: config.enabled,\r\n });\r\n this.edge = config.edge;\r\n this.edgeZoneWidth = config.edgeZoneWidth ?? 30;\r\n this.minDistance = config.minDistance ?? 50;\r\n this.minVelocity = config.minVelocity ?? 0.3;\r\n this.screenWidth = config.screenWidth ?? 400;\r\n this.screenHeight = config.screenHeight ?? 800;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pan) return;\r\n\r\n // Track initial touch position to detect edge start\r\n if (this.startX === null) {\r\n this.startX = touchData.x;\r\n this.startY = touchData.y;\r\n this.startedInEdge = this.isInEdgeZone(touchData.x, touchData.y);\r\n\r\n if (this.startedInEdge) {\r\n this.transitionToPossible();\r\n }\r\n return;\r\n }\r\n\r\n // Ignore if gesture didn't start in the edge zone\r\n if (!this.startedInEdge) return;\r\n\r\n // Calculate swipe distance in the expected direction\r\n const swipeDistance = this.getSwipeDistance(touchData);\r\n const swipeVelocity = this.getSwipeVelocity(touchData);\r\n\r\n if (this.state === 'possible') {\r\n // Check if swipe conditions are met\r\n if (swipeDistance >= this.minDistance && swipeVelocity >= this.minVelocity) {\r\n this.transitionToBegan({\r\n edge: this.edge,\r\n translation: {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n },\r\n velocity: {\r\n x: touchData.velocityX,\r\n y: touchData.velocityY,\r\n },\r\n });\r\n this.transitionToEnded({\r\n edge: this.edge,\r\n translation: {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n },\r\n velocity: {\r\n x: touchData.velocityX,\r\n y: touchData.velocityY,\r\n },\r\n });\r\n this.resetState();\r\n }\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.resetState();\r\n }\r\n\r\n /**\r\n * Check if a point is within the configured edge zone.\r\n */\r\n private isInEdgeZone(x: number, y: number): boolean {\r\n switch (this.edge) {\r\n case 'left':\r\n return x <= this.edgeZoneWidth;\r\n case 'right':\r\n return x >= this.screenWidth - this.edgeZoneWidth;\r\n case 'top':\r\n return y <= this.edgeZoneWidth;\r\n case 'bottom':\r\n return y >= this.screenHeight - this.edgeZoneWidth;\r\n }\r\n }\r\n\r\n /**\r\n * Get the swipe distance along the expected axis.\r\n * Left/right edges → horizontal distance, top/bottom → vertical.\r\n */\r\n private getSwipeDistance(touchData: TouchData): number {\r\n switch (this.edge) {\r\n case 'left':\r\n return touchData.translationX; // positive = swiping right (from left edge)\r\n case 'right':\r\n return -touchData.translationX; // positive = swiping left (from right edge)\r\n case 'top':\r\n return touchData.translationY; // positive = swiping down (from top edge)\r\n case 'bottom':\r\n return -touchData.translationY; // positive = swiping up (from bottom edge)\r\n }\r\n }\r\n\r\n /**\r\n * Get the swipe velocity along the expected axis.\r\n */\r\n private getSwipeVelocity(touchData: TouchData): number {\r\n switch (this.edge) {\r\n case 'left':\r\n return touchData.velocityX;\r\n case 'right':\r\n return -touchData.velocityX;\r\n case 'top':\r\n return touchData.velocityY;\r\n case 'bottom':\r\n return -touchData.velocityY;\r\n }\r\n }\r\n\r\n private resetState(): void {\r\n this.startX = null;\r\n this.startY = null;\r\n this.startedInEdge = false;\r\n }\r\n}\r\n","// ─── CornerRecognizer ───────────────────────────────────────────────────────\r\n// Detects gestures that start from screen corners. Supports all 4 corners.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, TouchType, TouchData,\r\n IEventBus, CornerRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class CornerRecognizer extends BaseRecognizer {\r\n private corner: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\r\n private cornerZoneSize: number;\r\n private minDistance: number;\r\n private screenWidth: number;\r\n private screenHeight: number;\r\n private startedInCorner = false;\r\n private startX: number | null = null;\r\n private startY: number | null = null;\r\n\r\n constructor(eventBus: IEventBus, config: CornerRecognizerConfig) {\r\n super(`corner-${config.corner}`, eventBus, {\r\n priority: config.priority ?? 15,\r\n isExclusive: config.isExclusive ?? true,\r\n enabled: config.enabled,\r\n });\r\n this.corner = config.corner;\r\n this.cornerZoneSize = config.cornerZoneSize ?? 50;\r\n this.minDistance = config.minDistance ?? 40;\r\n this.screenWidth = config.screenWidth ?? 400;\r\n this.screenHeight = config.screenHeight ?? 800;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pan) return;\r\n\r\n if (this.startX === null) {\r\n this.startX = touchData.x;\r\n this.startY = touchData.y;\r\n this.startedInCorner = this.isInCornerZone(touchData.x, touchData.y);\r\n\r\n if (this.startedInCorner) {\r\n this.transitionToPossible();\r\n }\r\n return;\r\n }\r\n\r\n if (!this.startedInCorner) return;\r\n\r\n const distance = Math.sqrt(\r\n touchData.translationX ** 2 + touchData.translationY ** 2,\r\n );\r\n\r\n if (this.state === 'possible' && distance >= this.minDistance) {\r\n this.transitionToBegan({\r\n translation: {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n },\r\n });\r\n this.transitionToEnded({\r\n translation: {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n },\r\n });\r\n this.resetState();\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.resetState();\r\n }\r\n\r\n private isInCornerZone(x: number, y: number): boolean {\r\n const zone = this.cornerZoneSize;\r\n switch (this.corner) {\r\n case 'top-left':\r\n return x <= zone && y <= zone;\r\n case 'top-right':\r\n return x >= this.screenWidth - zone && y <= zone;\r\n case 'bottom-left':\r\n return x <= zone && y >= this.screenHeight - zone;\r\n case 'bottom-right':\r\n return x >= this.screenWidth - zone && y >= this.screenHeight - zone;\r\n }\r\n }\r\n\r\n private resetState(): void {\r\n this.startX = null;\r\n this.startY = null;\r\n this.startedInCorner = false;\r\n }\r\n}\r\n","// ─── ShakeRecognizer ────────────────────────────────────────────────────────\r\n// Detects device shake gestures from high-pass filtered accelerometer data.\r\n//\r\n// Algorithm:\r\n// 1. Consume ProcessedSamples with SensorType.Accelerometer\r\n// 2. Compute magnitude = √(x² + y² + z²) from filtered data\r\n// 3. Track consecutive samples above threshold (default 1.5g)\r\n// 4. When consecutiveSamples (default 2) are above threshold → trigger shake\r\n// 5. Enforce cooldown period (default 1000ms) to prevent rapid re-fires\r\n//\r\n// Emits GestureEvent with name: 'shake', metadata.magnitude\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, SensorType, SensorData,\r\n IEventBus, ShakeRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class ShakeRecognizer extends BaseRecognizer {\r\n private threshold: number;\r\n private consecutiveSamples: number;\r\n private cooldownMs: number;\r\n\r\n private aboveThresholdCount = 0;\r\n private lastTriggerTime = 0;\r\n\r\n constructor(eventBus: IEventBus, config: ShakeRecognizerConfig = {}) {\r\n super('shake', eventBus, {\r\n priority: config.priority ?? 30,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.threshold = config.threshold ?? 1.5;\r\n this.consecutiveSamples = config.consecutiveSamples ?? 2;\r\n this.cooldownMs = config.cooldownMs ?? 1000;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Sensor) return;\r\n\r\n const sensorData = inputEvent.data as SensorData;\r\n if (sensorData.type !== SensorType.Accelerometer) return;\r\n\r\n // Use high-pass filtered data (gravity removed) from the processing layer\r\n const { x, y, z } = sample.filtered;\r\n\r\n // Compute acceleration magnitude\r\n const magnitude = Math.sqrt(x * x + y * y + z * z);\r\n\r\n if (magnitude >= this.threshold) {\r\n this.aboveThresholdCount++;\r\n\r\n if (this.aboveThresholdCount >= this.consecutiveSamples) {\r\n const now = Date.now();\r\n\r\n // Check cooldown\r\n if (now - this.lastTriggerTime < this.cooldownMs) {\r\n // Still in cooldown — don't re-trigger\r\n return;\r\n }\r\n\r\n // Shake detected!\r\n this.lastTriggerTime = now;\r\n this.aboveThresholdCount = 0;\r\n\r\n this.transitionToPossible();\r\n this.transitionToBegan({ magnitude });\r\n this.transitionToEnded({ magnitude });\r\n }\r\n } else {\r\n // Below threshold — reset consecutive count\r\n this.aboveThresholdCount = 0;\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.aboveThresholdCount = 0;\r\n }\r\n}\r\n","// ─── TiltRecognizer ─────────────────────────────────────────────────────────\r\n// Detects device tilt from accelerometer data by computing pitch and roll\r\n// angles. Triggers when the tilt exceeds a configurable threshold.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, SensorType, SensorData,\r\n IEventBus, TiltRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class TiltRecognizer extends BaseRecognizer {\r\n private tiltThreshold: number;\r\n private cooldownMs: number;\r\n private lastTriggerTime = 0;\r\n\r\n constructor(eventBus: IEventBus, config: TiltRecognizerConfig = {}) {\r\n super('tilt', eventBus, {\r\n priority: config.priority ?? 35,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.tiltThreshold = config.tiltThreshold ?? 30;\r\n this.cooldownMs = config.cooldownMs ?? 500;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Sensor) return;\r\n\r\n const sensorData = inputEvent.data as SensorData;\r\n if (sensorData.type !== SensorType.Accelerometer) return;\r\n\r\n // Use raw (unfiltered) accelerometer data for tilt\r\n // since tilt is a sustained orientation, not a transient impulse\r\n const { x, y, z } = sensorData;\r\n\r\n // Compute pitch and roll from accelerometer\r\n // pitch = rotation around X axis (tilting forward/backward)\r\n // roll = rotation around Y axis (tilting left/right)\r\n const pitch = Math.atan2(y, Math.sqrt(x * x + z * z)) * (180 / Math.PI);\r\n const roll = Math.atan2(x, Math.sqrt(y * y + z * z)) * (180 / Math.PI);\r\n\r\n const maxTilt = Math.max(Math.abs(pitch), Math.abs(roll));\r\n\r\n if (maxTilt >= this.tiltThreshold) {\r\n const now = Date.now();\r\n\r\n if (now - this.lastTriggerTime < this.cooldownMs) {\r\n return;\r\n }\r\n\r\n this.lastTriggerTime = now;\r\n\r\n this.transitionToPossible();\r\n this.transitionToBegan({\r\n tilt: { pitch, roll },\r\n magnitude: maxTilt,\r\n });\r\n this.transitionToEnded({\r\n tilt: { pitch, roll },\r\n magnitude: maxTilt,\r\n });\r\n }\r\n }\r\n}\r\n","// ─── WristFlickRecognizer ───────────────────────────────────────────────────\r\n// Detects wrist flick gestures from gyroscope data.\r\n// A wrist flick is a rapid rotational movement detected via high angular\r\n// velocity on the gyroscope axes.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, SensorType, SensorData,\r\n IEventBus, WristFlickRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class WristFlickRecognizer extends BaseRecognizer {\r\n private angularVelocityThreshold: number;\r\n private cooldownMs: number;\r\n private lastTriggerTime = 0;\r\n\r\n constructor(eventBus: IEventBus, config: WristFlickRecognizerConfig = {}) {\r\n super('wrist-flick', eventBus, {\r\n priority: config.priority ?? 25,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n // Threshold in deg/s — gyroscope typically reports rad/s,\r\n // so we convert threshold to rad/s internally\r\n this.angularVelocityThreshold =\r\n ((config.angularVelocityThreshold ?? 150) * Math.PI) / 180;\r\n this.cooldownMs = config.cooldownMs ?? 800;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Sensor) return;\r\n\r\n const sensorData = inputEvent.data as SensorData;\r\n if (sensorData.type !== SensorType.Gyroscope) return;\r\n\r\n // Use filtered gyroscope data\r\n const { x, y, z } = sample.filtered;\r\n\r\n // Compute angular velocity magnitude (rad/s)\r\n const angularVelocity = Math.sqrt(x * x + y * y + z * z);\r\n\r\n if (angularVelocity >= this.angularVelocityThreshold) {\r\n const now = Date.now();\r\n\r\n if (now - this.lastTriggerTime < this.cooldownMs) {\r\n return;\r\n }\r\n\r\n this.lastTriggerTime = now;\r\n\r\n this.transitionToPossible();\r\n this.transitionToBegan({\r\n magnitude: angularVelocity * (180 / Math.PI), // Convert back to deg/s for metadata\r\n });\r\n this.transitionToEnded({\r\n magnitude: angularVelocity * (180 / Math.PI),\r\n });\r\n }\r\n }\r\n}\r\n","// ─── SequenceRecognizer ─────────────────────────────────────────────────────\r\n// Composes N recognizers in order with inter-step timeouts.\r\n//\r\n// Algorithm:\r\n// 1. Listen for GestureEvent objects on the RecognitionGesture channel\r\n// 2. When the next expected gesture name is detected (in Ended state),\r\n// advance the sequence index\r\n// 3. If the inter-step timeout (default 800ms) is exceeded, reset\r\n// 4. When all steps are matched, emit a 'sequence:{joined-names}' event\r\n//\r\n// Example: sequence: ['tap', 'tap', 'edge-swipe-right']\r\n// → emits 'sequence:tap>tap>edge-swipe-right' on completion\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IEventBus,\r\n EventChannel,\r\n GestureEvent,\r\n RecognizerState,\r\n ProcessedSample,\r\n SequenceRecognizerConfig,\r\n generateId,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class SequenceRecognizer extends BaseRecognizer {\r\n private sequence: string[];\r\n private timeoutMs: number;\r\n private currentIndex = 0;\r\n private lastStepTime = 0;\r\n private unsubscribe: (() => void) | null = null;\r\n\r\n constructor(eventBus: IEventBus, config: SequenceRecognizerConfig) {\r\n const sequenceName = `sequence:${config.sequence.join('>')}`;\r\n super(sequenceName, eventBus, {\r\n priority: config.priority ?? 1,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.sequence = config.sequence;\r\n this.timeoutMs = config.timeoutMs ?? 800;\r\n\r\n // Subscribe to gesture events to track the sequence\r\n this.subscribeToGestures();\r\n }\r\n\r\n /**\r\n * SequenceRecognizer doesn't use ProcessedSample — it listens\r\n * to GestureEvent objects on the EventBus instead.\r\n */\r\n onProcessedSample(_sample: ProcessedSample): void {\r\n // No-op — sequence recognition is event-driven, not sample-driven\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.currentIndex = 0;\r\n this.lastStepTime = 0;\r\n }\r\n\r\n override dispose(): void {\r\n if (this.unsubscribe) {\r\n this.unsubscribe();\r\n this.unsubscribe = null;\r\n }\r\n super.dispose();\r\n }\r\n\r\n /**\r\n * Subscribe to the RecognitionGesture channel to listen for\r\n * completed gestures and advance the sequence.\r\n */\r\n private subscribeToGestures(): void {\r\n this.unsubscribe = this.eventBus.on(\r\n EventChannel.RecognitionGesture,\r\n (event: GestureEvent) => {\r\n if (!this.enabled) return;\r\n\r\n // Only process ended gestures (completed gesture activations)\r\n if (event.state !== RecognizerState.Ended) return;\r\n\r\n // Don't match our own events to prevent infinite loops\r\n if (event.name.startsWith('sequence:')) return;\r\n\r\n const now = Date.now();\r\n\r\n // Check for timeout (reset if too much time between steps)\r\n if (this.currentIndex > 0 && now - this.lastStepTime > this.timeoutMs) {\r\n this.reset();\r\n }\r\n\r\n // Check if this event matches the expected next step\r\n const expectedName = this.sequence[this.currentIndex];\r\n if (event.name === expectedName) {\r\n this.currentIndex++;\r\n this.lastStepTime = now;\r\n\r\n // Check if sequence is complete\r\n if (this.currentIndex >= this.sequence.length) {\r\n // Sequence completed!\r\n this.transitionToPossible();\r\n this.transitionToBegan({});\r\n this.transitionToEnded({});\r\n this.currentIndex = 0;\r\n this.lastStepTime = 0;\r\n }\r\n }\r\n },\r\n );\r\n }\r\n}\r\n","// ─── SymbolRecognizer ───────────────────────────────────────────────────────\r\n// Basic $1 Unistroke Recognizer implementation for drawn shapes.\r\n// Recognizes drawn gestures by comparing against template point patterns.\r\n//\r\n// $1 Algorithm steps:\r\n// 1. Resample path to N equidistant points (default 64)\r\n// 2. Rotate to indicative angle (align first point → centroid to 0°)\r\n// 3. Scale to fit reference square\r\n// 4. Compare against templates using average point distance\r\n//\r\n// Built-in templates: circle, triangle, check, cross, rectangle\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, TouchType, TouchData,\r\n IEventBus, SymbolRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\ninterface Point {\r\n x: number;\r\n y: number;\r\n}\r\n\r\n// ─── Built-in symbol templates ────────────────────────────────────────────\r\n\r\nfunction generateCircleTemplate(n = 64): Point[] {\r\n const points: Point[] = [];\r\n for (let i = 0; i < n; i++) {\r\n const angle = (2 * Math.PI * i) / n;\r\n points.push({ x: Math.cos(angle), y: Math.sin(angle) });\r\n }\r\n return points;\r\n}\r\n\r\nfunction generateTriangleTemplate(): Point[] {\r\n const pts: Point[] = [];\r\n // Three sides of a triangle\r\n const vertices: Point[] = [\r\n { x: 0.5, y: 0 },\r\n { x: 1, y: 1 },\r\n { x: 0, y: 1 },\r\n ];\r\n for (let side = 0; side < 3; side++) {\r\n const from = vertices[side];\r\n const to = vertices[(side + 1) % 3];\r\n for (let i = 0; i < 21; i++) {\r\n const t = i / 20;\r\n pts.push({ x: from.x + (to.x - from.x) * t, y: from.y + (to.y - from.y) * t });\r\n }\r\n }\r\n return pts;\r\n}\r\n\r\nfunction generateCheckTemplate(): Point[] {\r\n // Checkmark: down-right then up-right\r\n const pts: Point[] = [];\r\n for (let i = 0; i <= 20; i++) {\r\n const t = i / 20;\r\n pts.push({ x: t * 0.4, y: 0.3 + t * 0.7 });\r\n }\r\n for (let i = 0; i <= 20; i++) {\r\n const t = i / 20;\r\n pts.push({ x: 0.4 + t * 0.6, y: 1 - t * 1 });\r\n }\r\n return pts;\r\n}\r\n\r\nconst DEFAULT_TEMPLATES: Record<string, Point[]> = {\r\n circle: generateCircleTemplate(),\r\n triangle: generateTriangleTemplate(),\r\n check: generateCheckTemplate(),\r\n};\r\n\r\nexport class SymbolRecognizer extends BaseRecognizer {\r\n private templates: Record<string, Point[]>;\r\n private minConfidence: number;\r\n private currentPath: Point[] = [];\r\n private isDrawing = false;\r\n private resampleCount = 64;\r\n private squareSize = 250;\r\n\r\n constructor(eventBus: IEventBus, config: SymbolRecognizerConfig = {}) {\r\n super('symbol', eventBus, {\r\n priority: config.priority ?? 60,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.templates = config.templates ?? DEFAULT_TEMPLATES;\r\n this.minConfidence = config.minConfidence ?? 0.7;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pan) return;\r\n\r\n const velocity = Math.sqrt(\r\n touchData.velocityX ** 2 + touchData.velocityY ** 2,\r\n );\r\n\r\n // Start tracking when finger moves\r\n if (!this.isDrawing) {\r\n this.isDrawing = true;\r\n this.currentPath = [];\r\n this.transitionToPossible();\r\n }\r\n\r\n // Record point\r\n this.currentPath.push({ x: touchData.x, y: touchData.y });\r\n\r\n // Detect end of stroke (velocity drops near zero)\r\n if (velocity < 0.01 && this.currentPath.length > 10) {\r\n this.isDrawing = false;\r\n this.recognize();\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.currentPath = [];\r\n this.isDrawing = false;\r\n }\r\n\r\n /**\r\n * Run the $1 recognizer against collected path points.\r\n */\r\n private recognize(): void {\r\n if (this.currentPath.length < 10) {\r\n this.transitionToFailed();\r\n return;\r\n }\r\n\r\n // Step 1: Resample\r\n const resampled = this.resample(this.currentPath, this.resampleCount);\r\n\r\n // Step 2: Rotate to indicative angle\r\n const centroid = this.getCentroid(resampled);\r\n const angle = Math.atan2(centroid.y - resampled[0].y, centroid.x - resampled[0].x);\r\n const rotated = this.rotateBy(resampled, -angle);\r\n\r\n // Step 3: Scale to square\r\n const scaled = this.scaleTo(rotated, this.squareSize);\r\n\r\n // Step 4: Translate to origin\r\n const translated = this.translateToOrigin(scaled);\r\n\r\n // Step 5: Match against templates\r\n let bestMatch = '';\r\n let bestScore = 0;\r\n\r\n for (const [name, templatePoints] of Object.entries(this.templates)) {\r\n // Process template the same way\r\n const tResampled = this.resample(templatePoints, this.resampleCount);\r\n const tCentroid = this.getCentroid(tResampled);\r\n const tAngle = Math.atan2(tCentroid.y - tResampled[0].y, tCentroid.x - tResampled[0].x);\r\n const tRotated = this.rotateBy(tResampled, -tAngle);\r\n const tScaled = this.scaleTo(tRotated, this.squareSize);\r\n const tTranslated = this.translateToOrigin(tScaled);\r\n\r\n const distance = this.pathDistance(translated, tTranslated);\r\n const halfDiagonal = 0.5 * Math.sqrt(2) * this.squareSize;\r\n const score = 1 - distance / halfDiagonal;\r\n\r\n if (score > bestScore) {\r\n bestScore = score;\r\n bestMatch = name;\r\n }\r\n }\r\n\r\n if (bestScore >= this.minConfidence) {\r\n this.transitionToBegan({\r\n symbol: bestMatch,\r\n confidence: bestScore,\r\n });\r\n this.transitionToEnded({\r\n symbol: bestMatch,\r\n confidence: bestScore,\r\n });\r\n } else {\r\n this.transitionToFailed();\r\n }\r\n\r\n this.currentPath = [];\r\n }\r\n\r\n // ─── $1 Unistroke helper functions ────────────────────────────────\r\n\r\n private resample(points: Point[], n: number): Point[] {\r\n const totalLength = this.pathLength(points);\r\n const interval = totalLength / (n - 1);\r\n const resampled: Point[] = [points[0]];\r\n let accumulated = 0;\r\n\r\n for (let i = 1; i < points.length; i++) {\r\n const d = this.distance(points[i - 1], points[i]);\r\n\r\n if (accumulated + d >= interval) {\r\n const t = (interval - accumulated) / d;\r\n const newPoint: Point = {\r\n x: points[i - 1].x + t * (points[i].x - points[i - 1].x),\r\n y: points[i - 1].y + t * (points[i].y - points[i - 1].y),\r\n };\r\n resampled.push(newPoint);\r\n points.splice(i, 0, newPoint);\r\n accumulated = 0;\r\n } else {\r\n accumulated += d;\r\n }\r\n }\r\n\r\n // Pad to n points if needed\r\n while (resampled.length < n) {\r\n resampled.push(points[points.length - 1]);\r\n }\r\n\r\n return resampled.slice(0, n);\r\n }\r\n\r\n private getCentroid(points: Point[]): Point {\r\n let sumX = 0, sumY = 0;\r\n for (const p of points) {\r\n sumX += p.x;\r\n sumY += p.y;\r\n }\r\n return { x: sumX / points.length, y: sumY / points.length };\r\n }\r\n\r\n private rotateBy(points: Point[], angle: number): Point[] {\r\n const centroid = this.getCentroid(points);\r\n const cos = Math.cos(angle);\r\n const sin = Math.sin(angle);\r\n return points.map((p) => ({\r\n x: (p.x - centroid.x) * cos - (p.y - centroid.y) * sin + centroid.x,\r\n y: (p.x - centroid.x) * sin + (p.y - centroid.y) * cos + centroid.y,\r\n }));\r\n }\r\n\r\n private scaleTo(points: Point[], size: number): Point[] {\r\n const bb = this.boundingBox(points);\r\n const w = bb.maxX - bb.minX;\r\n const h = bb.maxY - bb.minY;\r\n if (w === 0 || h === 0) return points;\r\n return points.map((p) => ({\r\n x: (p.x * size) / w,\r\n y: (p.y * size) / h,\r\n }));\r\n }\r\n\r\n private translateToOrigin(points: Point[]): Point[] {\r\n const centroid = this.getCentroid(points);\r\n return points.map((p) => ({\r\n x: p.x - centroid.x,\r\n y: p.y - centroid.y,\r\n }));\r\n }\r\n\r\n private boundingBox(points: Point[]) {\r\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\r\n for (const p of points) {\r\n minX = Math.min(minX, p.x);\r\n minY = Math.min(minY, p.y);\r\n maxX = Math.max(maxX, p.x);\r\n maxY = Math.max(maxY, p.y);\r\n }\r\n return { minX, minY, maxX, maxY };\r\n }\r\n\r\n private pathDistance(a: Point[], b: Point[]): number {\r\n const len = Math.min(a.length, b.length);\r\n let total = 0;\r\n for (let i = 0; i < len; i++) {\r\n total += this.distance(a[i], b[i]);\r\n }\r\n return total / len;\r\n }\r\n\r\n private pathLength(points: Point[]): number {\r\n let total = 0;\r\n for (let i = 1; i < points.length; i++) {\r\n total += this.distance(points[i - 1], points[i]);\r\n }\r\n return total;\r\n }\r\n\r\n private distance(a: Point, b: Point): number {\r\n return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);\r\n }\r\n}\r\n","// ─── GesturePriorityQueue ───────────────────────────────────────────────────\r\n// Min-heap sorted by priority value (lower = higher priority).\r\n// Used by ConflictResolver to process gestures in priority order.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { GestureEvent } from '../core/types';\r\n\r\n/**\r\n * Min-heap priority queue for GestureEvents.\r\n * Lower priority number = higher priority = processed first.\r\n *\r\n * Operations:\r\n * - insert: O(log n)\r\n * - extractMin: O(log n)\r\n * - peek: O(1)\r\n */\r\nexport class GesturePriorityQueue {\r\n private heap: GestureEvent[] = [];\r\n\r\n get size(): number {\r\n return this.heap.length;\r\n }\r\n\r\n isEmpty(): boolean {\r\n return this.heap.length === 0;\r\n }\r\n\r\n /** Insert a gesture event into the queue. O(log n). */\r\n insert(event: GestureEvent): void {\r\n this.heap.push(event);\r\n this.bubbleUp(this.heap.length - 1);\r\n }\r\n\r\n /** Extract and return the highest-priority (lowest priority number) event. O(log n). */\r\n extractMin(): GestureEvent | null {\r\n if (this.heap.length === 0) return null;\r\n if (this.heap.length === 1) return this.heap.pop()!;\r\n\r\n const min = this.heap[0];\r\n this.heap[0] = this.heap.pop()!;\r\n this.bubbleDown(0);\r\n return min;\r\n }\r\n\r\n /** Peek at the highest-priority event without removing it. O(1). */\r\n peek(): GestureEvent | null {\r\n return this.heap.length > 0 ? this.heap[0] : null;\r\n }\r\n\r\n /** Remove all events from the queue. */\r\n clear(): void {\r\n this.heap = [];\r\n }\r\n\r\n /** Drain the queue, returning all events in priority order. */\r\n drainAll(): GestureEvent[] {\r\n const result: GestureEvent[] = [];\r\n while (!this.isEmpty()) {\r\n result.push(this.extractMin()!);\r\n }\r\n return result;\r\n }\r\n\r\n private bubbleUp(index: number): void {\r\n while (index > 0) {\r\n const parentIndex = Math.floor((index - 1) / 2);\r\n if (this.heap[parentIndex].priority <= this.heap[index].priority) break;\r\n [this.heap[parentIndex], this.heap[index]] = [this.heap[index], this.heap[parentIndex]];\r\n index = parentIndex;\r\n }\r\n }\r\n\r\n private bubbleDown(index: number): void {\r\n const length = this.heap.length;\r\n while (true) {\r\n let smallest = index;\r\n const left = 2 * index + 1;\r\n const right = 2 * index + 2;\r\n\r\n if (left < length && this.heap[left].priority < this.heap[smallest].priority) {\r\n smallest = left;\r\n }\r\n if (right < length && this.heap[right].priority < this.heap[smallest].priority) {\r\n smallest = right;\r\n }\r\n\r\n if (smallest === index) break;\r\n [this.heap[smallest], this.heap[index]] = [this.heap[index], this.heap[smallest]];\r\n index = smallest;\r\n }\r\n }\r\n}\r\n","// ─── LockManager ────────────────────────────────────────────────────────────\r\n// Manages exclusive gesture locks. When an exclusive gesture activates,\r\n// it acquires a lock that blocks competing gestures at equal or lower priority.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * LockManager tracks which gestures currently hold exclusive locks.\r\n *\r\n * When an exclusive gesture fires:\r\n * 1. It calls acquireLock(name, priority)\r\n * 2. The ConflictResolver checks isLocked(name, priority) before allowing\r\n * other gestures to pass through\r\n * 3. Once the gesture ends, releaseLock(name) frees the slot\r\n *\r\n * Multiple locks can coexist (e.g., a high-priority lock + unrelated gestures).\r\n * A gesture is blocked if ANY active lock has higher or equal priority.\r\n */\r\nexport class LockManager {\r\n /** Active locks: gestureName → priority */\r\n private locks = new Map<string, number>();\r\n\r\n /**\r\n * Acquire an exclusive lock for a gesture.\r\n *\r\n * @param gestureName - The gesture acquiring the lock\r\n * @param priority - The priority level of the lock (lower = higher priority)\r\n * @returns true if the lock was acquired\r\n */\r\n acquireLock(gestureName: string, priority: number): boolean {\r\n this.locks.set(gestureName, priority);\r\n return true;\r\n }\r\n\r\n /**\r\n * Release the lock held by a gesture.\r\n */\r\n releaseLock(gestureName: string): void {\r\n this.locks.delete(gestureName);\r\n }\r\n\r\n /**\r\n * Check if a gesture with the given priority is blocked by any active lock.\r\n * A gesture is blocked if an active lock has higher or equal priority\r\n * (lower or equal priority number) and is not the same gesture.\r\n *\r\n * @param gestureName - The gesture to check\r\n * @param priority - The priority of the gesture to check\r\n * @returns true if the gesture is blocked\r\n */\r\n isLocked(gestureName: string, priority: number): boolean {\r\n for (const [lockName, lockPriority] of this.locks) {\r\n if (lockName !== gestureName && lockPriority <= priority) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Check if a specific gesture holds a lock.\r\n */\r\n hasLock(gestureName: string): boolean {\r\n return this.locks.has(gestureName);\r\n }\r\n\r\n /**\r\n * Clear all locks. Called during engine reset.\r\n */\r\n clearAll(): void {\r\n this.locks.clear();\r\n }\r\n\r\n /**\r\n * Get the number of active locks.\r\n */\r\n get activeLockCount(): number {\r\n return this.locks.size;\r\n }\r\n}\r\n","// ─── ConflictResolver ───────────────────────────────────────────────────────\r\n// Receives all GestureEvent objects from the RecognitionGesture channel,\r\n// applies priority ordering and exclusive/simultaneous rules, and emits\r\n// resolved events on the ConflictResolved channel.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IEventBus,\r\n EventChannel,\r\n GestureEvent,\r\n RecognizerState,\r\n} from '../core/types';\r\nimport { GesturePriorityQueue } from './GesturePriorityQueue';\r\nimport { LockManager } from './LockManager';\r\n\r\n/**\r\n * ConflictResolver processes gesture events through priority ordering\r\n * and exclusive locking to determine which gestures should be dispatched.\r\n *\r\n * Rules:\r\n * 1. Events are queued and processed in priority order (lower = first)\r\n * 2. If an exclusive gesture fires (Began state), it acquires a lock\r\n * 3. Locked gestures of equal or lower priority are blocked\r\n * 4. When an exclusive gesture ends, its lock is released\r\n * 5. Non-exclusive gestures pass through if not blocked\r\n */\r\nexport class ConflictResolver {\r\n private priorityQueue: GesturePriorityQueue;\r\n private lockManager: LockManager;\r\n private eventBus: IEventBus;\r\n private unsubscribe: (() => void) | null = null;\r\n\r\n // Buffer for batching events within a single tick\r\n private pendingEvents: GestureEvent[] = [];\r\n private processingScheduled = false;\r\n\r\n constructor(eventBus: IEventBus) {\r\n this.eventBus = eventBus;\r\n this.priorityQueue = new GesturePriorityQueue();\r\n this.lockManager = new LockManager();\r\n }\r\n\r\n /**\r\n * Start listening for gesture events and resolving conflicts.\r\n */\r\n start(): void {\r\n this.unsubscribe = this.eventBus.on(\r\n EventChannel.RecognitionGesture,\r\n (event: GestureEvent) => {\r\n this.pendingEvents.push(event);\r\n this.scheduleProcessing();\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Stop listening and clear all state.\r\n */\r\n stop(): void {\r\n if (this.unsubscribe) {\r\n this.unsubscribe();\r\n this.unsubscribe = null;\r\n }\r\n this.priorityQueue.clear();\r\n this.lockManager.clearAll();\r\n this.pendingEvents = [];\r\n }\r\n\r\n /**\r\n * Schedule conflict resolution for the next microtask.\r\n * This batches events that arrive in the same tick.\r\n */\r\n private scheduleProcessing(): void {\r\n if (this.processingScheduled) return;\r\n this.processingScheduled = true;\r\n\r\n // Use queueMicrotask for batching events within a single frame\r\n Promise.resolve().then(() => {\r\n this.processingScheduled = false;\r\n this.processEvents();\r\n });\r\n }\r\n\r\n /**\r\n * Process all pending events through priority queue and lock rules.\r\n */\r\n private processEvents(): void {\r\n // Step 1: Insert all pending events into the priority queue\r\n for (const event of this.pendingEvents) {\r\n this.priorityQueue.insert(event);\r\n }\r\n this.pendingEvents = [];\r\n\r\n // Step 2: Drain the queue in priority order and apply conflict rules\r\n const sortedEvents = this.priorityQueue.drainAll();\r\n\r\n for (const event of sortedEvents) {\r\n // Handle lock lifecycle for exclusive gestures\r\n if (event.isExclusive) {\r\n if (event.state === RecognizerState.Began) {\r\n this.lockManager.acquireLock(event.name, event.priority);\r\n } else if (\r\n event.state === RecognizerState.Ended ||\r\n event.state === RecognizerState.Cancelled ||\r\n event.state === RecognizerState.Failed\r\n ) {\r\n this.lockManager.releaseLock(event.name);\r\n }\r\n }\r\n\r\n // Check if this gesture is blocked by a higher-priority exclusive lock\r\n if (this.lockManager.isLocked(event.name, event.priority)) {\r\n // Blocked — skip this event\r\n continue;\r\n }\r\n\r\n // Event passes conflict resolution → emit on ConflictResolved channel\r\n this.eventBus.emit(EventChannel.ConflictResolved, event);\r\n }\r\n }\r\n\r\n /** Expose lock manager for testing */\r\n getLockManager(): LockManager {\r\n return this.lockManager;\r\n }\r\n}\r\n","// ─── ActionDispatcher ───────────────────────────────────────────────────────\r\n// Maps gesture names to arrays of IGestureAction instances.\r\n// Dispatches resolved gesture events to all registered actions.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IEventBus,\r\n EventChannel,\r\n GestureEvent,\r\n IGestureAction,\r\n} from '../core/types';\r\n\r\n/**\r\n * ActionDispatcher receives resolved gesture events and dispatches them\r\n * to registered action handlers.\r\n *\r\n * Actions are registered by gesture name. Multiple actions can be registered\r\n * for a single gesture (they all execute in registration order).\r\n */\r\nexport class ActionDispatcher {\r\n private actionMap = new Map<string, IGestureAction[]>();\r\n private eventBus: IEventBus;\r\n private unsubscribe: (() => void) | null = null;\r\n\r\n constructor(eventBus: IEventBus) {\r\n this.eventBus = eventBus;\r\n }\r\n\r\n /**\r\n * Start listening for resolved gesture events.\r\n */\r\n start(): void {\r\n this.unsubscribe = this.eventBus.on(\r\n EventChannel.ConflictResolved,\r\n (event: GestureEvent) => {\r\n this.dispatch(event);\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Stop listening.\r\n */\r\n stop(): void {\r\n if (this.unsubscribe) {\r\n this.unsubscribe();\r\n this.unsubscribe = null;\r\n }\r\n }\r\n\r\n /**\r\n * Register an action for a gesture name.\r\n */\r\n registerAction(gestureName: string, action: IGestureAction): void {\r\n if (!this.actionMap.has(gestureName)) {\r\n this.actionMap.set(gestureName, []);\r\n }\r\n this.actionMap.get(gestureName)!.push(action);\r\n }\r\n\r\n /**\r\n * Unregister a specific action from a gesture.\r\n */\r\n unregisterAction(gestureName: string, actionId: string): void {\r\n const actions = this.actionMap.get(gestureName);\r\n if (actions) {\r\n const filtered = actions.filter((a) => a.actionId !== actionId);\r\n if (filtered.length > 0) {\r\n this.actionMap.set(gestureName, filtered);\r\n } else {\r\n this.actionMap.delete(gestureName);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all registered actions.\r\n */\r\n clearActions(): void {\r\n this.actionMap.clear();\r\n }\r\n\r\n /**\r\n * Dispatch a gesture event to all matching registered actions.\r\n */\r\n private dispatch(event: GestureEvent): void {\r\n const actions = this.actionMap.get(event.name);\r\n if (!actions || actions.length === 0) return;\r\n\r\n for (const action of actions) {\r\n try {\r\n action.execute(event);\r\n } catch (error) {\r\n console.warn(\r\n `[ActionDispatcher] Error executing action ${action.actionId} for gesture ${event.name}:`,\r\n error,\r\n );\r\n }\r\n }\r\n\r\n // Emit on ActionDispatched channel for feedback layer\r\n this.eventBus.emit(EventChannel.ActionDispatched, event);\r\n }\r\n}\r\n","// ─── NavigationAction ───────────────────────────────────────────────────────\r\n// Triggers navigation actions (go back, push screen, etc.)\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IGestureAction, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * NavigationAction triggers navigation when a gesture is recognized.\r\n * Accepts a callback that receives the gesture event and can perform\r\n * any navigation logic (e.g., navigation.goBack()).\r\n */\r\nexport class NavigationAction implements IGestureAction {\r\n readonly actionId: string;\r\n private callback: (event: GestureEvent) => void;\r\n\r\n constructor(actionId: string, callback: (event: GestureEvent) => void) {\r\n this.actionId = actionId;\r\n this.callback = callback;\r\n }\r\n\r\n execute(event: GestureEvent): void {\r\n this.callback(event);\r\n }\r\n}\r\n","// ─── UITransformAction ──────────────────────────────────────────────────────\r\n// Applies Reanimated shared value transformations (scale, translate, rotate)\r\n// in response to gesture events.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IGestureAction, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * UITransformAction applies Reanimated transformations when a gesture fires.\r\n *\r\n * Accepts a callback where you can update shared values:\r\n * ```typescript\r\n * new UITransformAction('scale-on-pinch', (event) => {\r\n * scale.value = withSpring(event.metadata.scale ?? 1);\r\n * });\r\n * ```\r\n */\r\nexport class UITransformAction implements IGestureAction {\r\n readonly actionId: string;\r\n private transform: (event: GestureEvent) => void;\r\n\r\n constructor(actionId: string, transform: (event: GestureEvent) => void) {\r\n this.actionId = actionId;\r\n this.transform = transform;\r\n }\r\n\r\n execute(event: GestureEvent): void {\r\n this.transform(event);\r\n }\r\n}\r\n","// ─── SystemAction ───────────────────────────────────────────────────────────\r\n// System-level effects (e.g., toggle fullscreen, change orientation).\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IGestureAction, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * SystemAction performs system-level operations when a gesture fires.\r\n */\r\nexport class SystemAction implements IGestureAction {\r\n readonly actionId: string;\r\n private callback: (event: GestureEvent) => void;\r\n\r\n constructor(actionId: string, callback: (event: GestureEvent) => void) {\r\n this.actionId = actionId;\r\n this.callback = callback;\r\n }\r\n\r\n execute(event: GestureEvent): void {\r\n this.callback(event);\r\n }\r\n}\r\n","// ─── CustomAction ───────────────────────────────────────────────────────────\r\n// User-defined callback action. The most flexible action type — accepts\r\n// any callback to execute when a gesture is recognized.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IGestureAction, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * CustomAction wraps a user-defined callback.\r\n *\r\n * @example\r\n * ```typescript\r\n * const logAction = new CustomAction('log-shake', (event) => {\r\n * analytics.track('shake_gesture', { magnitude: event.metadata.magnitude });\r\n * });\r\n * ```\r\n */\r\nexport class CustomAction implements IGestureAction {\r\n readonly actionId: string;\r\n private callback: (event: GestureEvent) => void;\r\n\r\n constructor(actionId: string, callback: (event: GestureEvent) => void) {\r\n this.actionId = actionId;\r\n this.callback = callback;\r\n }\r\n\r\n execute(event: GestureEvent): void {\r\n this.callback(event);\r\n }\r\n}\r\n","// ─── HapticFeedback ─────────────────────────────────────────────────────────\r\n// Uses expo-haptics for impact/notification/selection haptics.\r\n// Falls back to react-native Vibration API if expo-haptics is unavailable.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IFeedbackProvider, GestureEvent, RecognizerState } from '../core/types';\r\n\r\n// Lazy imports — expo-haptics is an optional peer dependency\r\nlet Haptics: any;\r\nlet Vibration: any;\r\n\r\nfunction loadModules() {\r\n try {\r\n Haptics = require('expo-haptics');\r\n } catch {\r\n // expo-haptics not installed — fall back to Vibration\r\n }\r\n try {\r\n const rn = require('react-native');\r\n Vibration = rn.Vibration;\r\n } catch {\r\n // react-native not available (testing)\r\n }\r\n}\r\n\r\n/**\r\n * HapticFeedback triggers haptic responses when gestures are recognized.\r\n *\r\n * Supports three haptic types (via expo-haptics):\r\n * - Impact: for gesture activations (tap, swipe)\r\n * - Notification: for important events (shake, sequence complete)\r\n * - Selection: for continuous feedback (pan, rotation)\r\n *\r\n * Falls back to react-native Vibration API when expo-haptics is not installed.\r\n */\r\nexport class HapticFeedback implements IFeedbackProvider {\r\n private _isSupported = false;\r\n private useVibrationFallback = false;\r\n private enabled: boolean;\r\n\r\n constructor(enabled = true) {\r\n this.enabled = enabled;\r\n loadModules();\r\n\r\n if (Haptics) {\r\n this._isSupported = true;\r\n } else if (Vibration) {\r\n this._isSupported = true;\r\n this.useVibrationFallback = true;\r\n }\r\n }\r\n\r\n get isSupported(): boolean {\r\n return this._isSupported && this.enabled;\r\n }\r\n\r\n trigger(event: GestureEvent): void {\r\n if (!this.isSupported) return;\r\n\r\n // Only trigger on Began and Ended states to avoid spam\r\n if (\r\n event.state !== RecognizerState.Began &&\r\n event.state !== RecognizerState.Ended\r\n ) {\r\n return;\r\n }\r\n\r\n if (this.useVibrationFallback) {\r\n Vibration?.vibrate(50);\r\n return;\r\n }\r\n\r\n // Choose haptic type based on gesture\r\n const gestureName = event.name;\r\n\r\n if (gestureName.startsWith('sequence:') || gestureName === 'shake') {\r\n // Notification haptic for important events\r\n Haptics?.notificationAsync?.(Haptics.NotificationFeedbackType?.Success);\r\n } else if (gestureName === 'tap' || gestureName === 'double-tap') {\r\n // Light impact for taps\r\n Haptics?.impactAsync?.(Haptics.ImpactFeedbackStyle?.Light);\r\n } else if (gestureName.startsWith('edge-swipe') || gestureName.startsWith('corner')) {\r\n // Medium impact for spatial gestures\r\n Haptics?.impactAsync?.(Haptics.ImpactFeedbackStyle?.Medium);\r\n } else {\r\n // Selection for continuous gestures\r\n Haptics?.selectionAsync?.();\r\n }\r\n }\r\n\r\n setEnabled(enabled: boolean): void {\r\n this.enabled = enabled;\r\n }\r\n}\r\n","// ─── VisualFeedback ─────────────────────────────────────────────────────────\r\n// Triggers visual feedback via callbacks when gestures are recognized.\r\n// Designed to work with Reanimated shared value animations.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IFeedbackProvider, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * VisualFeedback invokes registered callbacks to trigger visual animations\r\n * when gestures are recognized.\r\n *\r\n * Typical usage: update Reanimated shared values in the callback.\r\n *\r\n * @example\r\n * ```typescript\r\n * const visual = new VisualFeedback((event) => {\r\n * opacity.value = withTiming(0.5, { duration: 100 });\r\n * scale.value = withSpring(0.95);\r\n * });\r\n * ```\r\n */\r\nexport class VisualFeedback implements IFeedbackProvider {\r\n private _isSupported = true;\r\n private callback: ((event: GestureEvent) => void) | null;\r\n\r\n constructor(callback?: (event: GestureEvent) => void) {\r\n this.callback = callback ?? null;\r\n }\r\n\r\n get isSupported(): boolean {\r\n return this._isSupported;\r\n }\r\n\r\n trigger(event: GestureEvent): void {\r\n if (!this._isSupported || !this.callback) return;\r\n this.callback(event);\r\n }\r\n\r\n /**\r\n * Update the visual feedback callback at runtime.\r\n */\r\n setCallback(callback: (event: GestureEvent) => void): void {\r\n this.callback = callback;\r\n }\r\n}\r\n","// ─── AccessibilityFeedback ──────────────────────────────────────────────────\r\n// Posts accessibility announcements when gestures are recognized.\r\n// Uses AccessibilityInfo.announceForAccessibility() from React Native.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IFeedbackProvider, GestureEvent, RecognizerState } from '../core/types';\r\n\r\n// Lazy import\r\nlet AccessibilityInfo: any;\r\n\r\nfunction loadAccessibility() {\r\n try {\r\n const rn = require('react-native');\r\n AccessibilityInfo = rn.AccessibilityInfo;\r\n } catch {\r\n // Not available\r\n }\r\n}\r\n\r\n/**\r\n * AccessibilityFeedback announces gesture events for screen reader users.\r\n *\r\n * Automatically generates human-readable announcements based on gesture names.\r\n * Custom announcement builders can be provided via setAnnouncementBuilder().\r\n */\r\nexport class AccessibilityFeedback implements IFeedbackProvider {\r\n private _isSupported = false;\r\n private announcementBuilder: ((event: GestureEvent) => string) | null = null;\r\n\r\n constructor() {\r\n loadAccessibility();\r\n this._isSupported = !!AccessibilityInfo?.announceForAccessibility;\r\n }\r\n\r\n get isSupported(): boolean {\r\n return this._isSupported;\r\n }\r\n\r\n trigger(event: GestureEvent): void {\r\n if (!this._isSupported) return;\r\n\r\n // Only announce on Ended state to avoid spam\r\n if (event.state !== RecognizerState.Ended) return;\r\n\r\n const announcement = this.announcementBuilder\r\n ? this.announcementBuilder(event)\r\n : this.defaultAnnouncement(event);\r\n\r\n AccessibilityInfo.announceForAccessibility(announcement);\r\n }\r\n\r\n /**\r\n * Set a custom function to build announcement strings.\r\n */\r\n setAnnouncementBuilder(builder: (event: GestureEvent) => string): void {\r\n this.announcementBuilder = builder;\r\n }\r\n\r\n /**\r\n * Generate a default human-readable announcement based on gesture name.\r\n */\r\n private defaultAnnouncement(event: GestureEvent): string {\r\n const name = event.name\r\n .replace(/-/g, ' ')\r\n .replace(/:/g, ' ')\r\n .replace(/>/g, ' then ');\r\n\r\n return `Gesture detected: ${name}`;\r\n }\r\n}\r\n","// ─── GestureEngine ──────────────────────────────────────────────────────────\r\n// Main orchestrator that wires all 6 layers together via the EventBus.\r\n//\r\n// Responsibilities:\r\n// 1. Creates and owns the EventBus\r\n// 2. Instantiates providers, processors, and conflict resolver\r\n// 3. Wires raw input → processing → recognition → conflict → action → feedback\r\n// 4. Provides a clean API: start(), stop(), registerRecognizer(), etc.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { EventBus } from './core/EventBus';\r\nimport {\r\n IEventBus,\r\n EventChannel,\r\n InputEvent,\r\n InputType,\r\n ProcessedSample,\r\n GestureEvent,\r\n GestureEngineConfig,\r\n IRecognizer,\r\n IGestureAction,\r\n IFeedbackProvider,\r\n TouchData,\r\n SensorData,\r\n CardinalDirection,\r\n generateId,\r\n} from './core/types';\r\nimport { TouchInputProvider } from './input/TouchInputProvider';\r\nimport { SensorInputProvider } from './input/SensorInputProvider';\r\nimport { NoiseFilter } from './processing/NoiseFilter';\r\nimport { VelocityCalculator } from './processing/VelocityCalculator';\r\nimport { AngleDetector } from './processing/AngleDetector';\r\nimport { ThresholdNormalizer } from './processing/ThresholdNormalizer';\r\nimport { StreamBuffer } from './processing/StreamBuffer';\r\nimport { ConflictResolver } from './conflict/ConflictResolver';\r\nimport { ActionDispatcher } from './actions/ActionDispatcher';\r\n\r\n/**\r\n * GestureEngine is the main orchestrator for the gesture pipeline.\r\n *\r\n * It connects all 6 layers:\r\n * Input → Processing → Recognition → Conflict → Action → Feedback\r\n *\r\n * All communication flows through the typed EventBus.\r\n */\r\nexport class GestureEngine {\r\n // ─── Core ──────────────────────────────────────────────────────────\r\n readonly eventBus: IEventBus;\r\n private config: Required<GestureEngineConfig>;\r\n\r\n // ─── Layer 1: Input ────────────────────────────────────────────────\r\n readonly touchInput: TouchInputProvider;\r\n readonly sensorInput: SensorInputProvider;\r\n\r\n // ─── Layer 2: Processing ───────────────────────────────────────────\r\n private noiseFilter: NoiseFilter;\r\n private sensorNoiseFilter: NoiseFilter;\r\n private velocityCalc: VelocityCalculator;\r\n private angleDetector: AngleDetector;\r\n private normalizer: ThresholdNormalizer;\r\n private streamBuffer: StreamBuffer;\r\n\r\n // ─── Layer 3: Recognition ──────────────────────────────────────────\r\n private recognizers: IRecognizer[] = [];\r\n\r\n // ─── Layer 4: Conflict Resolution ─────────────────────────────────\r\n private conflictResolver: ConflictResolver;\r\n\r\n // ─── Layer 5: Actions ──────────────────────────────────────────────\r\n private actionDispatcher: ActionDispatcher;\r\n\r\n // ─── Layer 6: Feedback ─────────────────────────────────────────────\r\n private feedbackProviders: IFeedbackProvider[] = [];\r\n\r\n // ─── State ─────────────────────────────────────────────────────────\r\n private _isRunning = false;\r\n private inputUnsubscribe: (() => void) | null = null;\r\n private feedbackUnsubscribe: (() => void) | null = null;\r\n\r\n constructor(config: GestureEngineConfig = {}) {\r\n // Merge with defaults\r\n this.config = {\r\n sensorInterval: Math.max(16, config.sensorInterval ?? 100),\r\n hapticEnabled: config.hapticEnabled ?? true,\r\n debug: config.debug ?? false,\r\n screenWidth: config.screenWidth ?? 400,\r\n screenHeight: config.screenHeight ?? 800,\r\n };\r\n\r\n // ─── Initialize core ──────────────────────────────────────────────\r\n this.eventBus = new EventBus();\r\n\r\n // ─── Initialize Layer 1: Input providers ──────────────────────────\r\n this.touchInput = new TouchInputProvider(this.eventBus);\r\n this.sensorInput = new SensorInputProvider(\r\n this.eventBus,\r\n this.config.sensorInterval,\r\n );\r\n\r\n // ─── Initialize Layer 2: Processing ───────────────────────────────\r\n this.noiseFilter = new NoiseFilter(0.8);\r\n this.sensorNoiseFilter = new NoiseFilter(0.2); // Lower alpha for high-pass on sensors\r\n this.velocityCalc = new VelocityCalculator();\r\n this.angleDetector = new AngleDetector();\r\n this.normalizer = new ThresholdNormalizer(0, 10);\r\n this.streamBuffer = new StreamBuffer(400, 64);\r\n\r\n // ─── Initialize Layer 4: Conflict Resolution ──────────────────────\r\n this.conflictResolver = new ConflictResolver(this.eventBus);\r\n\r\n // ─── Initialize Layer 5: Action Dispatcher ────────────────────────\r\n this.actionDispatcher = new ActionDispatcher(this.eventBus);\r\n }\r\n\r\n // ═══════════════════════════════════════════════════════════════════════\r\n // Public API\r\n // ═══════════════════════════════════════════════════════════════════════\r\n\r\n get isRunning(): boolean {\r\n return this._isRunning;\r\n }\r\n\r\n /**\r\n * Start the gesture engine. Activates all providers and wires the pipeline.\r\n */\r\n start(): void {\r\n if (this._isRunning) return;\r\n this._isRunning = true;\r\n\r\n // Wire Layer 1 → Layer 2 → Layer 3: raw input → processing → recognition\r\n this.inputUnsubscribe = this.eventBus.on(\r\n EventChannel.InputRaw,\r\n (event: InputEvent) => this.processInput(event),\r\n );\r\n\r\n // Wire Layer 6: feedback on action dispatch\r\n this.feedbackUnsubscribe = this.eventBus.on(\r\n EventChannel.ActionDispatched,\r\n (event: GestureEvent) => {\r\n for (const provider of this.feedbackProviders) {\r\n if (provider.isSupported) {\r\n provider.trigger(event);\r\n }\r\n }\r\n },\r\n );\r\n\r\n // Start all infrastructure\r\n this.touchInput.start();\r\n this.sensorInput.start();\r\n this.conflictResolver.start();\r\n this.actionDispatcher.start();\r\n\r\n if (this.config.debug) {\r\n console.log('[GestureEngine] Started with config:', this.config);\r\n }\r\n }\r\n\r\n /**\r\n * Stop the gesture engine. Cleans up all subscriptions and providers.\r\n */\r\n stop(): void {\r\n if (!this._isRunning) return;\r\n this._isRunning = false;\r\n\r\n // Stop providers\r\n this.touchInput.stop();\r\n this.sensorInput.stop();\r\n this.conflictResolver.stop();\r\n this.actionDispatcher.stop();\r\n\r\n // Unsubscribe pipeline wiring\r\n this.inputUnsubscribe?.();\r\n this.feedbackUnsubscribe?.();\r\n this.inputUnsubscribe = null;\r\n this.feedbackUnsubscribe = null;\r\n\r\n // Reset processors\r\n this.noiseFilter.reset();\r\n this.sensorNoiseFilter.reset();\r\n this.velocityCalc.reset();\r\n this.streamBuffer.clear();\r\n\r\n // Reset recognizers\r\n for (const recognizer of this.recognizers) {\r\n recognizer.reset();\r\n }\r\n\r\n if (this.config.debug) {\r\n console.log('[GestureEngine] Stopped');\r\n }\r\n }\r\n\r\n /**\r\n * Register a gesture recognizer with the engine.\r\n */\r\n registerRecognizer(recognizer: IRecognizer): void {\r\n this.recognizers.push(recognizer);\r\n if (this.config.debug) {\r\n console.log(`[GestureEngine] Registered recognizer: ${recognizer.name}`);\r\n }\r\n }\r\n\r\n /**\r\n * Unregister a recognizer by its ID.\r\n */\r\n unregisterRecognizer(recognizerId: string): void {\r\n const index = this.recognizers.findIndex((r) => r.id === recognizerId);\r\n if (index !== -1) {\r\n const [removed] = this.recognizers.splice(index, 1);\r\n removed.dispose();\r\n }\r\n }\r\n\r\n /**\r\n * Register an action for a gesture name.\r\n */\r\n registerAction(gestureName: string, action: IGestureAction): void {\r\n this.actionDispatcher.registerAction(gestureName, action);\r\n }\r\n\r\n /**\r\n * Register a feedback provider.\r\n */\r\n registerFeedback(provider: IFeedbackProvider): void {\r\n this.feedbackProviders.push(provider);\r\n }\r\n\r\n /**\r\n * Get all registered recognizers.\r\n */\r\n getRecognizers(): IRecognizer[] {\r\n return [...this.recognizers];\r\n }\r\n\r\n /**\r\n * Dispose the engine and clean up all resources.\r\n */\r\n dispose(): void {\r\n this.stop();\r\n for (const recognizer of this.recognizers) {\r\n recognizer.dispose();\r\n }\r\n this.recognizers = [];\r\n this.feedbackProviders = [];\r\n this.actionDispatcher.clearActions();\r\n this.eventBus.clear();\r\n }\r\n\r\n // ═══════════════════════════════════════════════════════════════════════\r\n // Pipeline: Input → Processing → Recognition\r\n // ═══════════════════════════════════════════════════════════════════════\r\n\r\n /**\r\n * Process a raw input event through Layer 2 (processing) and feed\r\n * the resulting ProcessedSample into Layer 3 (recognition).\r\n */\r\n private processInput(event: InputEvent): void {\r\n let filtered: { x: number; y: number; z: number };\r\n let velocityResult: { velocityX: number; velocityY: number; velocity: number };\r\n\r\n if (event.inputType === InputType.Touch) {\r\n const touch = event.data as TouchData;\r\n // Apply low-pass filter to touch coordinates\r\n filtered = this.noiseFilter.lowPass(touch.x, touch.y, 0);\r\n velocityResult = this.velocityCalc.calculate(\r\n touch.x,\r\n touch.y,\r\n event.timestamp,\r\n );\r\n } else if (event.inputType === InputType.Sensor) {\r\n const sensor = event.data as SensorData;\r\n // Apply high-pass filter to sensor data (remove gravity)\r\n filtered = this.sensorNoiseFilter.highPass(sensor.x, sensor.y, sensor.z);\r\n const magnitude = Math.sqrt(\r\n filtered.x ** 2 + filtered.y ** 2 + filtered.z ** 2,\r\n );\r\n velocityResult = { velocityX: filtered.x, velocityY: filtered.y, velocity: magnitude };\r\n } else {\r\n // Hardware/Camera — pass through\r\n filtered = { x: 0, y: 0, z: 0 };\r\n velocityResult = { velocityX: 0, velocityY: 0, velocity: 0 };\r\n }\r\n\r\n // Compute angle\r\n const angle = this.angleDetector.calculate(\r\n velocityResult.velocityX,\r\n velocityResult.velocityY,\r\n );\r\n\r\n // Normalize magnitude\r\n const normalizedMagnitude = this.normalizer.normalize(velocityResult.velocity);\r\n\r\n // Build processed sample\r\n const sample: ProcessedSample = {\r\n inputEvent: event,\r\n velocity: velocityResult.velocity,\r\n velocityX: velocityResult.velocityX,\r\n velocityY: velocityResult.velocityY,\r\n angleRadians: angle.angleRadians,\r\n angleDegrees: angle.angleDegrees,\r\n direction: angle.direction,\r\n normalizedMagnitude,\r\n filtered,\r\n timestamp: event.timestamp,\r\n };\r\n\r\n // Store in stream buffer\r\n this.streamBuffer.push(sample);\r\n\r\n // Emit on processing channel\r\n this.eventBus.emit(EventChannel.ProcessingSample, sample);\r\n\r\n // Feed into all recognizers (Layer 3)\r\n for (const recognizer of this.recognizers) {\r\n if (recognizer.enabled) {\r\n recognizer.onProcessedSample(sample);\r\n }\r\n }\r\n }\r\n}\r\n","// ─── useGestureEngine ───────────────────────────────────────────────────────\r\n// Main React hook that creates and manages a GestureEngine instance.\r\n// Lives outside the React tree render cycle for performance.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { GestureEngine } from '../GestureEngine';\r\nimport {\r\n GestureEngineConfig,\r\n IRecognizer,\r\n IGestureAction,\r\n IFeedbackProvider,\r\n} from '../core/types';\r\n\r\nexport interface UseGestureEngineConfig extends GestureEngineConfig {\r\n /**\r\n * Recognizer instances to register with the engine.\r\n * These are created outside the hook and passed in.\r\n */\r\n recognizers?: IRecognizer[];\r\n /**\r\n * Action mappings: gestureName → array of actions\r\n */\r\n actions?: Record<string, IGestureAction[]>;\r\n /**\r\n * Feedback providers to register\r\n */\r\n feedback?: IFeedbackProvider[];\r\n}\r\n\r\nexport interface UseGestureEngineResult {\r\n /** The GestureEngine instance */\r\n engine: GestureEngine | null;\r\n /** Whether the engine is initialized and running */\r\n isReady: boolean;\r\n}\r\n\r\n/**\r\n * React hook that creates, configures, and manages a GestureEngine lifecycle.\r\n *\r\n * The engine is created once on mount and disposed on unmount.\r\n * Uses useRef to keep the engine outside the React render cycle.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { engine, isReady } = useGestureEngine({\r\n * sensorInterval: 100,\r\n * hapticEnabled: true,\r\n * recognizers: [shakeRecognizer, edgeSwipeRecognizer],\r\n * actions: { 'shake': [myShakeAction] },\r\n * });\r\n * ```\r\n */\r\nexport function useGestureEngine(\r\n config: UseGestureEngineConfig = {},\r\n): UseGestureEngineResult {\r\n const engineRef = useRef<GestureEngine | null>(null);\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n useEffect(() => {\r\n // Create engine\r\n const engine = new GestureEngine({\r\n sensorInterval: config.sensorInterval,\r\n hapticEnabled: config.hapticEnabled,\r\n debug: config.debug,\r\n screenWidth: config.screenWidth,\r\n screenHeight: config.screenHeight,\r\n });\r\n\r\n // Register recognizers\r\n if (config.recognizers) {\r\n for (const recognizer of config.recognizers) {\r\n engine.registerRecognizer(recognizer);\r\n }\r\n }\r\n\r\n // Register actions\r\n if (config.actions) {\r\n for (const [gestureName, actions] of Object.entries(config.actions)) {\r\n for (const action of actions) {\r\n engine.registerAction(gestureName, action);\r\n }\r\n }\r\n }\r\n\r\n // Register feedback providers\r\n if (config.feedback) {\r\n for (const provider of config.feedback) {\r\n engine.registerFeedback(provider);\r\n }\r\n }\r\n\r\n // Start the engine\r\n engine.start();\r\n engineRef.current = engine;\r\n setIsReady(true);\r\n\r\n // Cleanup on unmount\r\n return () => {\r\n engine.dispose();\r\n engineRef.current = null;\r\n setIsReady(false);\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []); // Only run once on mount — config changes require remounting\r\n\r\n return {\r\n engine: engineRef.current,\r\n isReady,\r\n };\r\n}\r\n","// ─── useShakeGesture ────────────────────────────────────────────────────────\r\n// Convenience hook for shake detection. Creates a self-contained\r\n// GestureEngine with a ShakeRecognizer + CustomAction.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { useEffect, useRef } from 'react';\r\nimport { GestureEngine } from '../GestureEngine';\r\nimport { ShakeRecognizer } from '../recognition/sensor/ShakeRecognizer';\r\nimport { CustomAction } from '../actions/CustomAction';\r\nimport { HapticFeedback } from '../feedback/HapticFeedback';\r\nimport { EventBus } from '../core/EventBus';\r\n\r\nexport interface UseShakeGestureConfig {\r\n /** Acceleration threshold in g (default 1.5) */\r\n threshold?: number;\r\n /** Cooldown in ms (default 1000) */\r\n cooldownMs?: number;\r\n /** Callback when shake is detected */\r\n onShake: () => void;\r\n /** Enable haptic feedback (default true) */\r\n hapticEnabled?: boolean;\r\n /** Sensor polling interval in ms (default 100) */\r\n sensorInterval?: number;\r\n}\r\n\r\n/**\r\n * Convenience hook for shake gesture detection.\r\n *\r\n * Creates a minimal GestureEngine with just a ShakeRecognizer.\r\n * Ideal for simple use cases where you just need shake detection.\r\n *\r\n * @example\r\n * ```tsx\r\n * useShakeGesture({\r\n * threshold: 1.5,\r\n * cooldownMs: 1000,\r\n * onShake: () => console.log('Device shaken!'),\r\n * });\r\n * ```\r\n */\r\nexport function useShakeGesture(config: UseShakeGestureConfig): void {\r\n const engineRef = useRef<GestureEngine | null>(null);\r\n const callbackRef = useRef(config.onShake);\r\n\r\n // Keep callback ref current without re-creating the engine\r\n callbackRef.current = config.onShake;\r\n\r\n useEffect(() => {\r\n const engine = new GestureEngine({\r\n sensorInterval: config.sensorInterval ?? 100,\r\n hapticEnabled: config.hapticEnabled ?? true,\r\n });\r\n\r\n // Create shake recognizer\r\n const shakeRecognizer = new ShakeRecognizer(engine.eventBus, {\r\n threshold: config.threshold,\r\n cooldownMs: config.cooldownMs,\r\n });\r\n engine.registerRecognizer(shakeRecognizer);\r\n\r\n // Register action\r\n const action = new CustomAction('shake-callback', () => {\r\n callbackRef.current();\r\n });\r\n engine.registerAction('shake', action);\r\n\r\n // Add haptic feedback if enabled\r\n if (config.hapticEnabled !== false) {\r\n engine.registerFeedback(new HapticFeedback(true));\r\n }\r\n\r\n engine.start();\r\n engineRef.current = engine;\r\n\r\n return () => {\r\n engine.dispose();\r\n engineRef.current = null;\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [config.threshold, config.cooldownMs, config.sensorInterval]);\r\n}\r\n","// ─── useEdgeSwipe ───────────────────────────────────────────────────────────\r\n// Convenience hook for edge swipe detection.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { useEffect, useRef } from 'react';\r\nimport { GestureEngine } from '../GestureEngine';\r\nimport { EdgeSwipeRecognizer } from '../recognition/spatial/EdgeSwipeRecognizer';\r\nimport { CustomAction } from '../actions/CustomAction';\r\nimport { HapticFeedback } from '../feedback/HapticFeedback';\r\nimport { GestureEvent } from '../core/types';\r\n\r\nexport interface UseEdgeSwipeConfig {\r\n /** Edge to detect: 'left', 'right', 'top', 'bottom' */\r\n edge: 'left' | 'right' | 'top' | 'bottom';\r\n /** Minimum swipe distance in px (default 50) */\r\n minDistance?: number;\r\n /** Edge zone width in px (default 30) */\r\n edgeZoneWidth?: number;\r\n /** Minimum velocity in px/ms (default 0.3) */\r\n minVelocity?: number;\r\n /** Screen width in px */\r\n screenWidth?: number;\r\n /** Screen height in px */\r\n screenHeight?: number;\r\n /** Callback when edge swipe is detected */\r\n onSwipe: (event: GestureEvent) => void;\r\n /** Enable haptic feedback (default true) */\r\n hapticEnabled?: boolean;\r\n}\r\n\r\n/**\r\n * Convenience hook for edge swipe detection.\r\n *\r\n * @example\r\n * ```tsx\r\n * useEdgeSwipe({\r\n * edge: 'left',\r\n * minDistance: 50,\r\n * onSwipe: (event) => navigation.goBack(),\r\n * });\r\n * ```\r\n */\r\nexport function useEdgeSwipe(config: UseEdgeSwipeConfig): void {\r\n const engineRef = useRef<GestureEngine | null>(null);\r\n const callbackRef = useRef(config.onSwipe);\r\n callbackRef.current = config.onSwipe;\r\n\r\n useEffect(() => {\r\n const engine = new GestureEngine({\r\n hapticEnabled: config.hapticEnabled ?? true,\r\n screenWidth: config.screenWidth,\r\n screenHeight: config.screenHeight,\r\n });\r\n\r\n const gestureName = `edge-swipe-${config.edge}`;\r\n\r\n const recognizer = new EdgeSwipeRecognizer(engine.eventBus, {\r\n edge: config.edge,\r\n minDistance: config.minDistance,\r\n edgeZoneWidth: config.edgeZoneWidth,\r\n minVelocity: config.minVelocity,\r\n screenWidth: config.screenWidth,\r\n screenHeight: config.screenHeight,\r\n });\r\n engine.registerRecognizer(recognizer);\r\n\r\n const action = new CustomAction(`${gestureName}-callback`, (event) => {\r\n callbackRef.current(event);\r\n });\r\n engine.registerAction(gestureName, action);\r\n\r\n if (config.hapticEnabled !== false) {\r\n engine.registerFeedback(new HapticFeedback(true));\r\n }\r\n\r\n engine.start();\r\n engineRef.current = engine;\r\n\r\n return () => {\r\n engine.dispose();\r\n engineRef.current = null;\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [config.edge, config.minDistance, config.edgeZoneWidth, config.minVelocity]);\r\n}\r\n","// ─── useGestureSequence ─────────────────────────────────────────────────────\r\n// Convenience hook for gesture sequence detection.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { useEffect, useRef } from 'react';\r\nimport { GestureEngine } from '../GestureEngine';\r\nimport { SequenceRecognizer } from '../recognition/sequence/SequenceRecognizer';\r\nimport { CustomAction } from '../actions/CustomAction';\r\nimport { HapticFeedback } from '../feedback/HapticFeedback';\r\n\r\nexport interface UseGestureSequenceConfig {\r\n /** Ordered gesture names to match */\r\n sequence: string[];\r\n /** Max time between steps in ms (default 800) */\r\n timeoutMs?: number;\r\n /** Callback when sequence is completed */\r\n onComplete: () => void;\r\n /** Enable haptic feedback (default true) */\r\n hapticEnabled?: boolean;\r\n}\r\n\r\n/**\r\n * Convenience hook for gesture sequence detection.\r\n *\r\n * @example\r\n * ```tsx\r\n * useGestureSequence({\r\n * sequence: ['tap', 'tap', 'edge-swipe-right'],\r\n * timeoutMs: 800,\r\n * onComplete: () => console.log('Secret gesture unlocked!'),\r\n * });\r\n * ```\r\n */\r\nexport function useGestureSequence(config: UseGestureSequenceConfig): void {\r\n const engineRef = useRef<GestureEngine | null>(null);\r\n const callbackRef = useRef(config.onComplete);\r\n callbackRef.current = config.onComplete;\r\n\r\n useEffect(() => {\r\n const engine = new GestureEngine({\r\n hapticEnabled: config.hapticEnabled ?? true,\r\n });\r\n\r\n const sequenceName = `sequence:${config.sequence.join('>')}`;\r\n\r\n const recognizer = new SequenceRecognizer(engine.eventBus, {\r\n sequence: config.sequence,\r\n timeoutMs: config.timeoutMs,\r\n });\r\n engine.registerRecognizer(recognizer);\r\n\r\n const action = new CustomAction(`${sequenceName}-callback`, () => {\r\n callbackRef.current();\r\n });\r\n engine.registerAction(sequenceName, action);\r\n\r\n if (config.hapticEnabled !== false) {\r\n engine.registerFeedback(new HapticFeedback(true));\r\n }\r\n\r\n engine.start();\r\n engineRef.current = engine;\r\n\r\n return () => {\r\n engine.dispose();\r\n engineRef.current = null;\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [config.sequence.join(','), config.timeoutMs]);\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/core/EventBus.ts","../src/core/types.ts","../src/input/TouchInputProvider.ts","../src/input/SensorInputProvider.ts","../src/input/HardwareInputProvider.ts","../src/input/CameraInputProvider.ts","../src/processing/NoiseFilter.ts","../src/processing/VelocityCalculator.ts","../src/processing/AngleDetector.ts","../src/processing/ThresholdNormalizer.ts","../src/processing/StreamBuffer.ts","../src/recognition/base/BaseRecognizer.ts","../src/recognition/discrete/TapRecognizer.ts","../src/recognition/discrete/DoubleTapRecognizer.ts","../src/recognition/continuous/PanRecognizer.ts","../src/recognition/continuous/PinchRecognizer.ts","../src/recognition/continuous/RotationRecognizer.ts","../src/recognition/spatial/EdgeSwipeRecognizer.ts","../src/recognition/spatial/CornerRecognizer.ts","../src/recognition/sensor/ShakeRecognizer.ts","../src/recognition/sensor/TiltRecognizer.ts","../src/recognition/sensor/WristFlickRecognizer.ts","../src/recognition/sequence/SequenceRecognizer.ts","../src/recognition/symbolic/SymbolRecognizer.ts","../src/conflict/GesturePriorityQueue.ts","../src/conflict/LockManager.ts","../src/conflict/ConflictResolver.ts","../src/actions/ActionDispatcher.ts","../src/actions/NavigationAction.ts","../src/actions/UITransformAction.ts","../src/actions/SystemAction.ts","../src/actions/CustomAction.ts","../src/feedback/HapticFeedback.ts","../src/feedback/VisualFeedback.ts","../src/feedback/AccessibilityFeedback.ts","../src/GestureEngine.ts","../src/hooks/useGestureEngine.ts","../src/hooks/useShakeGesture.ts","../src/hooks/useEdgeSwipe.ts","../src/hooks/useGestureSequence.ts"],"names":["InputType","TouchType","SensorType","CardinalDirection","RecognizerState","EventChannel","useRef","useEffect"],"mappings":"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","file":"index.mjs","sourcesContent":["// ─── EventBus ───────────────────────────────────────────────────────────────\r\n// Typed pub/sub system connecting all pipeline layers.\r\n// Provides compile-time safety: each channel maps to a specific payload type.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n EventChannel,\r\n EventChannelMap,\r\n EventHandler,\r\n IEventBus,\r\n} from './types';\r\n\r\n/**\r\n * Typed EventBus implementation.\r\n *\r\n * Design decisions:\r\n * - Lives outside the React tree to avoid unnecessary re-renders.\r\n * - Uses Map<channel, Set<handler>> for O(1) subscribe/unsubscribe.\r\n * - Generic channel parameter ensures type-safe emit/subscribe at compile time.\r\n * - `on()` returns an unsubscribe function for easy cleanup in useEffect.\r\n */\r\nexport class EventBus implements IEventBus {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private listeners = new Map<EventChannel, Set<EventHandler<any>>>();\r\n\r\n /**\r\n * Subscribe to a channel. Returns an unsubscribe function.\r\n *\r\n * @example\r\n * const unsub = bus.on(EventChannel.InputRaw, (event) => { ... });\r\n * // later:\r\n * unsub();\r\n */\r\n on<C extends EventChannel>(channel: C, handler: EventHandler<C>): () => void {\r\n if (!this.listeners.has(channel)) {\r\n this.listeners.set(channel, new Set());\r\n }\r\n this.listeners.get(channel)!.add(handler);\r\n\r\n // Return unsubscribe function for convenience (useEffect cleanup)\r\n return () => this.off(channel, handler);\r\n }\r\n\r\n /**\r\n * Emit data on a channel. All registered handlers are called synchronously.\r\n * The generic parameter ensures the data type matches the channel.\r\n */\r\n emit<C extends EventChannel>(channel: C, data: EventChannelMap[C]): void {\r\n const handlers = this.listeners.get(channel);\r\n if (!handlers) return;\r\n\r\n // Iterate over a copy to allow handlers to unsubscribe during emit\r\n for (const handler of Array.from(handlers)) {\r\n try {\r\n handler(data);\r\n } catch (error) {\r\n // Swallow handler errors to prevent one bad handler from\r\n // breaking the entire pipeline. In production, these should\r\n // be reported to an error tracking service.\r\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\r\n console.error(`[EventBus] Error in handler for ${channel}:`, error);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove a specific handler from a channel.\r\n */\r\n off<C extends EventChannel>(channel: C, handler: EventHandler<C>): void {\r\n const handlers = this.listeners.get(channel);\r\n if (handlers) {\r\n handlers.delete(handler);\r\n if (handlers.size === 0) {\r\n this.listeners.delete(channel);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove all handlers from all channels. Called during engine teardown.\r\n */\r\n clear(): void {\r\n this.listeners.clear();\r\n }\r\n}\r\n\r\n// Check if __DEV__ is defined (React Native global)\r\ndeclare const __DEV__: boolean | undefined;\r\n","// ─── Core Types ─────────────────────────────────────────────────────────────\r\n// All interfaces, enums, and type aliases for the gesture engine pipeline.\r\n// Each layer consumes and produces typed data objects connected via EventBus.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 1: Input Data Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Classification of input sources feeding into the pipeline */\r\nexport enum InputType {\r\n Touch = 'touch',\r\n Sensor = 'sensor',\r\n Hardware = 'hardware',\r\n Camera = 'camera',\r\n}\r\n\r\n/** Sub-type classification for touch inputs */\r\nexport enum TouchType {\r\n Pan = 'pan',\r\n Tap = 'tap',\r\n Pinch = 'pinch',\r\n Rotation = 'rotation',\r\n}\r\n\r\n/** Sub-type classification for sensor inputs */\r\nexport enum SensorType {\r\n Accelerometer = 'accelerometer',\r\n Gyroscope = 'gyroscope',\r\n}\r\n\r\n/** Normalized touch data emitted by TouchInputProvider */\r\nexport interface TouchData {\r\n /** Touch sub-type (pan, tap, pinch, rotation) */\r\n type: TouchType;\r\n /** Current X position in screen coordinates */\r\n x: number;\r\n /** Current Y position in screen coordinates */\r\n y: number;\r\n /** Translation from start point on X axis */\r\n translationX: number;\r\n /** Translation from start point on Y axis */\r\n translationY: number;\r\n /** Instantaneous velocity on X axis (px/ms) */\r\n velocityX: number;\r\n /** Instantaneous velocity on Y axis (px/ms) */\r\n velocityY: number;\r\n /** Scale factor for pinch gestures (1.0 = no scale) */\r\n scale: number;\r\n /** Rotation angle in radians for rotation gestures */\r\n rotation: number;\r\n /** Number of active touch points */\r\n numberOfPointers: number;\r\n}\r\n\r\n/** Sensor data emitted by SensorInputProvider */\r\nexport interface SensorData {\r\n type: SensorType;\r\n x: number;\r\n y: number;\r\n z: number;\r\n}\r\n\r\n/** Hardware input data (e.g., volume button presses) */\r\nexport interface HardwareData {\r\n /** Key identifier, e.g. 'volumeUp', 'volumeDown' */\r\n key: string;\r\n /** Press action: 'down' or 'up' */\r\n action: 'down' | 'up';\r\n}\r\n\r\n/**\r\n * Unified input event emitted by all providers on the InputRaw channel.\r\n * The `data` field is discriminated by `inputType`.\r\n */\r\nexport interface InputEvent {\r\n /** Unique event identifier */\r\n id: string;\r\n /** Timestamp in milliseconds (performance.now or Date.now) */\r\n timestamp: number;\r\n /** Source classification */\r\n inputType: InputType;\r\n /** Payload — shape depends on inputType */\r\n data: TouchData | SensorData | HardwareData;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 2: Processing Data Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Cardinal direction classification */\r\nexport enum CardinalDirection {\r\n Up = 'up',\r\n Down = 'down',\r\n Left = 'left',\r\n Right = 'right',\r\n UpLeft = 'up-left',\r\n UpRight = 'up-right',\r\n DownLeft = 'down-left',\r\n DownRight = 'down-right',\r\n None = 'none',\r\n}\r\n\r\n/**\r\n * Enriched data produced by the processing layer.\r\n * Combines raw input with computed velocity, angle, and normalized magnitude.\r\n */\r\nexport interface ProcessedSample {\r\n /** Reference to the original input event */\r\n inputEvent: InputEvent;\r\n /** Computed velocity magnitude (px/ms or g/ms) */\r\n velocity: number;\r\n /** Velocity on X axis */\r\n velocityX: number;\r\n /** Velocity on Y axis */\r\n velocityY: number;\r\n /** Direction angle in radians */\r\n angleRadians: number;\r\n /** Direction angle in degrees */\r\n angleDegrees: number;\r\n /** Cardinal direction classification */\r\n direction: CardinalDirection;\r\n /** Magnitude normalized to [0, 1] */\r\n normalizedMagnitude: number;\r\n /** Filtered data coordinates (noise-reduced) */\r\n filtered: { x: number; y: number; z: number };\r\n /** Processing timestamp */\r\n timestamp: number;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 3: Recognition Data Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * Recognizer state machine states.\r\n * Transitions: Idle → Possible → Began → Changed → Ended\r\n * ↘ Failed / Cancelled\r\n */\r\nexport enum RecognizerState {\r\n Idle = 'idle',\r\n Possible = 'possible',\r\n Began = 'began',\r\n Changed = 'changed',\r\n Ended = 'ended',\r\n Failed = 'failed',\r\n Cancelled = 'cancelled',\r\n}\r\n\r\n/** Additional metadata attached to gesture events */\r\nexport interface GestureMetadata {\r\n /** Translation amount for pan/swipe gestures */\r\n translation?: { x: number; y: number };\r\n /** Scale factor for pinch gestures */\r\n scale?: number;\r\n /** Rotation angle for rotation gestures */\r\n rotation?: number;\r\n /** Velocity at recognition time */\r\n velocity?: { x: number; y: number };\r\n /** Edge identifier for edge-swipe gestures */\r\n edge?: 'left' | 'right' | 'top' | 'bottom';\r\n /** Detected symbol name for symbol recognizer */\r\n symbol?: string;\r\n /** Confidence score [0, 1] for symbol recognizer */\r\n confidence?: number;\r\n /** Sensor magnitude for shake/tilt/flick gestures */\r\n magnitude?: number;\r\n /** Tilt angles */\r\n tilt?: { pitch: number; roll: number };\r\n /** Generic key-value bag for custom recognizers */\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Event emitted when a recognizer transitions state.\r\n * This is the primary output of Layer 3, consumed by conflict resolution and actions.\r\n */\r\nexport interface GestureEvent {\r\n /** Unique event identifier */\r\n id: string;\r\n /** Human-readable gesture name, e.g. 'tap', 'shake', 'edge-swipe-left' */\r\n name: string;\r\n /** Current recognizer state */\r\n state: RecognizerState;\r\n /** Recognizer priority (lower = higher priority) */\r\n priority: number;\r\n /** Whether this gesture is exclusive (blocks others) */\r\n isExclusive: boolean;\r\n /** Event timestamp */\r\n timestamp: number;\r\n /** Gesture-specific metadata */\r\n metadata: GestureMetadata;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 4: EventBus Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Named channels for the typed pub/sub EventBus */\r\nexport enum EventChannel {\r\n /** Raw input data from providers */\r\n InputRaw = 'input:raw',\r\n /** Processed samples with velocity, angle, normalization */\r\n ProcessingSample = 'processing:sample',\r\n /** Gesture recognition events (state transitions) */\r\n RecognitionGesture = 'recognition:gesture',\r\n /** Events that survived conflict resolution */\r\n ConflictResolved = 'conflict:resolved',\r\n /** Events after action dispatch */\r\n ActionDispatched = 'action:dispatched',\r\n}\r\n\r\n/** Compile-time mapping from channel to payload type */\r\nexport interface EventChannelMap {\r\n [EventChannel.InputRaw]: InputEvent;\r\n [EventChannel.ProcessingSample]: ProcessedSample;\r\n [EventChannel.RecognitionGesture]: GestureEvent;\r\n [EventChannel.ConflictResolved]: GestureEvent;\r\n [EventChannel.ActionDispatched]: GestureEvent;\r\n}\r\n\r\n/** Typed event handler */\r\nexport type EventHandler<C extends EventChannel> = (data: EventChannelMap[C]) => void;\r\n\r\n/** EventBus interface */\r\nexport interface IEventBus {\r\n on<C extends EventChannel>(channel: C, handler: EventHandler<C>): () => void;\r\n emit<C extends EventChannel>(channel: C, data: EventChannelMap[C]): void;\r\n off<C extends EventChannel>(channel: C, handler: EventHandler<C>): void;\r\n clear(): void;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 5: Layer Interfaces\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Interface for all input providers (Layer 1) */\r\nexport interface IInputProvider {\r\n /** Start emitting input events */\r\n start(): void;\r\n /** Stop emitting input events and clean up subscriptions */\r\n stop(): void;\r\n /** Whether the provider is currently active */\r\n readonly isActive: boolean;\r\n}\r\n\r\n/** Interface for all gesture recognizers (Layer 3) */\r\nexport interface IRecognizer {\r\n /** Unique recognizer identifier */\r\n readonly id: string;\r\n /** Human-readable name matching the GestureEvent.name field */\r\n readonly name: string;\r\n /** Priority: lower number = higher priority */\r\n readonly priority: number;\r\n /** If true, activating this gesture blocks lower-priority gestures */\r\n readonly isExclusive: boolean;\r\n /** Current state machine state */\r\n readonly state: RecognizerState;\r\n /** Enable/disable the recognizer at runtime */\r\n enabled: boolean;\r\n /** Feed a processed sample into the recognizer for evaluation */\r\n onProcessedSample(sample: ProcessedSample): void;\r\n /** Reset the recognizer to Idle state */\r\n reset(): void;\r\n /** Clean up resources */\r\n dispose(): void;\r\n}\r\n\r\n/** Interface for gesture actions (Layer 5) */\r\nexport interface IGestureAction {\r\n /** Unique action identifier */\r\n readonly actionId: string;\r\n /** Execute the action in response to a resolved gesture */\r\n execute(event: GestureEvent): void;\r\n}\r\n\r\n/** Interface for feedback providers (Layer 6) */\r\nexport interface IFeedbackProvider {\r\n /** Trigger feedback in response to a resolved gesture */\r\n trigger(event: GestureEvent): void;\r\n /** Whether this feedback type is supported on the current device */\r\n readonly isSupported: boolean;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 6: Configuration Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Configuration for the GestureEngine orchestrator */\r\nexport interface GestureEngineConfig {\r\n /** Sensor polling interval in ms (default 100 = 10Hz). Max 16 (~60Hz). */\r\n sensorInterval?: number;\r\n /** Enable haptic feedback (requires expo-haptics) */\r\n hapticEnabled?: boolean;\r\n /** Enable debug logging */\r\n debug?: boolean;\r\n /** Screen dimensions for edge detection */\r\n screenWidth?: number;\r\n /** Screen dimensions for edge detection */\r\n screenHeight?: number;\r\n}\r\n\r\n/** Configuration for recognizers */\r\nexport interface RecognizerConfig {\r\n /** Override the default priority */\r\n priority?: number;\r\n /** Override the default exclusive setting */\r\n isExclusive?: boolean;\r\n /** Whether the recognizer starts enabled */\r\n enabled?: boolean;\r\n}\r\n\r\n/** Tap recognizer specific config */\r\nexport interface TapRecognizerConfig extends RecognizerConfig {\r\n /** Maximum duration for a tap in ms (default 300) */\r\n maxDuration?: number;\r\n /** Maximum movement threshold in px (default 10) */\r\n maxDistance?: number;\r\n}\r\n\r\n/** Double-tap recognizer specific config */\r\nexport interface DoubleTapRecognizerConfig extends RecognizerConfig {\r\n /** Maximum time between taps in ms (default 300) */\r\n maxInterval?: number;\r\n /** Maximum movement between taps in px (default 30) */\r\n maxDistance?: number;\r\n}\r\n\r\n/** Pan recognizer specific config */\r\nexport interface PanRecognizerConfig extends RecognizerConfig {\r\n /** Minimum distance to activate in px (default 10) */\r\n minDistance?: number;\r\n}\r\n\r\n/** Pinch recognizer specific config */\r\nexport interface PinchRecognizerConfig extends RecognizerConfig {\r\n /** Minimum scale change to activate (default 0.05) */\r\n minScale?: number;\r\n}\r\n\r\n/** Rotation recognizer specific config */\r\nexport interface RotationRecognizerConfig extends RecognizerConfig {\r\n /** Minimum rotation in radians to activate (default 0.05) */\r\n minRotation?: number;\r\n}\r\n\r\n/** Edge-swipe recognizer specific config */\r\nexport interface EdgeSwipeRecognizerConfig extends RecognizerConfig {\r\n /** Edge to detect: 'left', 'right', 'top', 'bottom' */\r\n edge: 'left' | 'right' | 'top' | 'bottom';\r\n /** Width of the edge detection zone in px (default 30) */\r\n edgeZoneWidth?: number;\r\n /** Minimum swipe distance in px (default 50) */\r\n minDistance?: number;\r\n /** Minimum velocity in px/ms (default 0.3) */\r\n minVelocity?: number;\r\n /** Screen width in px */\r\n screenWidth?: number;\r\n /** Screen height in px */\r\n screenHeight?: number;\r\n}\r\n\r\n/** Corner recognizer specific config */\r\nexport interface CornerRecognizerConfig extends RecognizerConfig {\r\n /** Corner to detect */\r\n corner: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\r\n /** Size of the corner zone in px (default 50) */\r\n cornerZoneSize?: number;\r\n /** Minimum swipe distance in px (default 40) */\r\n minDistance?: number;\r\n /** Screen width in px */\r\n screenWidth?: number;\r\n /** Screen height in px */\r\n screenHeight?: number;\r\n}\r\n\r\n/** Shake recognizer specific config */\r\nexport interface ShakeRecognizerConfig extends RecognizerConfig {\r\n /** Acceleration threshold in g (default 1.5) */\r\n threshold?: number;\r\n /** Consecutive samples above threshold to trigger (default 2) */\r\n consecutiveSamples?: number;\r\n /** Cooldown period in ms (default 1000) */\r\n cooldownMs?: number;\r\n}\r\n\r\n/** Tilt recognizer specific config */\r\nexport interface TiltRecognizerConfig extends RecognizerConfig {\r\n /** Tilt angle threshold in degrees (default 30) */\r\n tiltThreshold?: number;\r\n /** Cooldown period in ms (default 500) */\r\n cooldownMs?: number;\r\n}\r\n\r\n/** Wrist-flick recognizer specific config */\r\nexport interface WristFlickRecognizerConfig extends RecognizerConfig {\r\n /** Angular velocity threshold in deg/s (default 150) */\r\n angularVelocityThreshold?: number;\r\n /** Cooldown in ms (default 800) */\r\n cooldownMs?: number;\r\n}\r\n\r\n/** Sequence recognizer specific config */\r\nexport interface SequenceRecognizerConfig extends RecognizerConfig {\r\n /** Ordered gesture names to match */\r\n sequence: string[];\r\n /** Max time between steps in ms (default 800) */\r\n timeoutMs?: number;\r\n}\r\n\r\n/** Symbol recognizer specific config */\r\nexport interface SymbolRecognizerConfig extends RecognizerConfig {\r\n /** Templates to match against: name → point array */\r\n templates?: Record<string, Array<{ x: number; y: number }>>;\r\n /** Minimum confidence score to accept (default 0.7) */\r\n minConfidence?: number;\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n// Section 7: Utility Types\r\n// ═══════════════════════════════════════════════════════════════════════════════\r\n\r\n/** Utility type to generate unique IDs */\r\nexport type UniqueId = string;\r\n\r\n/** Helper to create a unique ID */\r\nexport function generateId(): UniqueId {\r\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\r\n}\r\n","// ─── TouchInputProvider ─────────────────────────────────────────────────────\r\n// Wraps React Native Gesture Handler gestures and emits normalized TouchData\r\n// on the EventBus InputRaw channel for downstream processing.\r\n//\r\n// Design: This provider doesn't create gesture recognizers directly — instead\r\n// it provides a `createGesture()` method that returns a composed RNGH gesture\r\n// for use inside a GestureDetector. The callbacks emit InputEvents to the bus.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IInputProvider,\r\n IEventBus,\r\n EventChannel,\r\n InputType,\r\n TouchType,\r\n TouchData,\r\n InputEvent,\r\n generateId,\r\n} from '../core/types';\r\nimport { Gesture, ComposedGesture } from 'react-native-gesture-handler';\r\n\r\n/**\r\n * TouchInputProvider wraps RNGH pan/tap/pinch/rotation gestures\r\n * and normalizes their data into InputEvent objects.\r\n *\r\n * Usage:\r\n * - Call `start()` to enable event emission\r\n * - Use the gesture handler callbacks (onPan, onTap, etc.) inside\r\n * GestureDetector components\r\n * - Call `stop()` to disable emission\r\n */\r\nexport class TouchInputProvider implements IInputProvider {\r\n private _isActive = false;\r\n /**\r\n * Extracted composed RNGH Gesture.\r\n * Consumers should wrap their app/screen in <GestureDetector gesture={gesture}>\r\n */\r\n public readonly gesture: ComposedGesture;\r\n\r\n constructor(private eventBus: IEventBus) {\r\n this.gesture = this.buildGesture();\r\n }\r\n\r\n get isActive(): boolean {\r\n return this._isActive;\r\n }\r\n\r\n start(): void {\r\n this._isActive = true;\r\n }\r\n\r\n stop(): void {\r\n this._isActive = false;\r\n }\r\n\r\n /**\r\n * Called from RNGH Pan gesture callbacks.\r\n * Emits normalized TouchData with translation and velocity.\r\n */\r\n onPan(data: {\r\n x: number;\r\n y: number;\r\n translationX: number;\r\n translationY: number;\r\n velocityX: number;\r\n velocityY: number;\r\n numberOfPointers: number;\r\n }): void {\r\n if (!this._isActive) return;\r\n\r\n const touchData: TouchData = {\r\n type: TouchType.Pan,\r\n x: data.x,\r\n y: data.y,\r\n translationX: data.translationX,\r\n translationY: data.translationY,\r\n velocityX: data.velocityX,\r\n velocityY: data.velocityY,\r\n scale: 1,\r\n rotation: 0,\r\n numberOfPointers: data.numberOfPointers,\r\n };\r\n\r\n this.emitInput(touchData);\r\n }\r\n\r\n /**\r\n * Called from RNGH Tap gesture callbacks.\r\n */\r\n onTap(data: { x: number; y: number; numberOfPointers: number }): void {\r\n if (!this._isActive) return;\r\n\r\n const touchData: TouchData = {\r\n type: TouchType.Tap,\r\n x: data.x,\r\n y: data.y,\r\n translationX: 0,\r\n translationY: 0,\r\n velocityX: 0,\r\n velocityY: 0,\r\n scale: 1,\r\n rotation: 0,\r\n numberOfPointers: data.numberOfPointers,\r\n };\r\n\r\n this.emitInput(touchData);\r\n }\r\n\r\n /**\r\n * Called from RNGH Pinch gesture callbacks.\r\n */\r\n onPinch(data: {\r\n scale: number;\r\n focalX: number;\r\n focalY: number;\r\n velocity: number;\r\n numberOfPointers: number;\r\n }): void {\r\n if (!this._isActive) return;\r\n\r\n const touchData: TouchData = {\r\n type: TouchType.Pinch,\r\n x: data.focalX,\r\n y: data.focalY,\r\n translationX: 0,\r\n translationY: 0,\r\n velocityX: 0,\r\n velocityY: data.velocity,\r\n scale: data.scale,\r\n rotation: 0,\r\n numberOfPointers: data.numberOfPointers,\r\n };\r\n\r\n this.emitInput(touchData);\r\n }\r\n\r\n /**\r\n * Called from RNGH Rotation gesture callbacks.\r\n */\r\n onRotation(data: {\r\n rotation: number;\r\n anchorX: number;\r\n anchorY: number;\r\n velocity: number;\r\n numberOfPointers: number;\r\n }): void {\r\n if (!this._isActive) return;\r\n\r\n const touchData: TouchData = {\r\n type: TouchType.Rotation,\r\n x: data.anchorX,\r\n y: data.anchorY,\r\n translationX: 0,\r\n translationY: 0,\r\n velocityX: 0,\r\n velocityY: data.velocity,\r\n scale: 1,\r\n rotation: data.rotation,\r\n numberOfPointers: data.numberOfPointers,\r\n };\r\n\r\n this.emitInput(touchData);\r\n }\r\n\r\n /** Emit a normalized InputEvent onto the EventBus */\r\n private emitInput(touchData: TouchData): void {\r\n const event: InputEvent = {\r\n id: generateId(),\r\n timestamp: Date.now(),\r\n inputType: InputType.Touch,\r\n data: touchData,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.InputRaw, event);\r\n }\r\n\r\n /**\r\n * Build the composed gesture.\r\n */\r\n private buildGesture(): ComposedGesture {\r\n const panGesture = Gesture.Pan()\r\n .onUpdate((e) => {\r\n this.onPan({\r\n x: e.x,\r\n y: e.y,\r\n translationX: e.translationX,\r\n translationY: e.translationY,\r\n velocityX: e.velocityX,\r\n velocityY: e.velocityY,\r\n numberOfPointers: e.numberOfPointers,\r\n });\r\n })\r\n .onEnd((e) => {\r\n this.onPan({\r\n x: e.x,\r\n y: e.y,\r\n translationX: e.translationX,\r\n translationY: e.translationY,\r\n velocityX: e.velocityX,\r\n velocityY: e.velocityY,\r\n numberOfPointers: e.numberOfPointers,\r\n });\r\n });\r\n\r\n const tapGesture = Gesture.Tap().onEnd((e) => {\r\n this.onTap({\r\n x: e.x,\r\n y: e.y,\r\n numberOfPointers: e.numberOfPointers,\r\n });\r\n });\r\n\r\n const pinchGesture = Gesture.Pinch()\r\n .onUpdate((e) => {\r\n this.onPinch({\r\n scale: e.scale,\r\n focalX: e.focalX,\r\n focalY: e.focalY,\r\n velocity: e.velocity,\r\n numberOfPointers: e.numberOfPointers,\r\n });\r\n })\r\n .onEnd((e) => {\r\n this.onPinch({\r\n scale: e.scale,\r\n focalX: e.focalX,\r\n focalY: e.focalY,\r\n velocity: e.velocity,\r\n numberOfPointers: e.numberOfPointers,\r\n });\r\n });\r\n\r\n const rotationGesture = Gesture.Rotation()\r\n .onUpdate((e) => {\r\n this.onRotation({\r\n rotation: e.rotation,\r\n anchorX: e.anchorX,\r\n anchorY: e.anchorY,\r\n velocity: e.velocity,\r\n numberOfPointers: e.numberOfPointers,\r\n });\r\n })\r\n .onEnd((e) => {\r\n this.onRotation({\r\n rotation: e.rotation,\r\n anchorX: e.anchorX,\r\n anchorY: e.anchorY,\r\n velocity: e.velocity,\r\n numberOfPointers: e.numberOfPointers,\r\n });\r\n });\r\n\r\n // Run them all simultaneously so we can capture any raw touch inputs\r\n return Gesture.Simultaneous(\r\n panGesture,\r\n tapGesture,\r\n pinchGesture,\r\n rotationGesture,\r\n );\r\n }\r\n}\r\n","// ─── SensorInputProvider ────────────────────────────────────────────────────\r\n// Subscribes to Accelerometer and Gyroscope from expo-sensors and emits\r\n// SensorData events on the EventBus. Supports configurable update intervals\r\n// and lazy initialization (only subscribes when start() is called).\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IInputProvider,\r\n IEventBus,\r\n EventChannel,\r\n InputType,\r\n SensorType,\r\n SensorData,\r\n InputEvent,\r\n generateId,\r\n} from '../core/types';\r\nimport { Accelerometer, Gyroscope } from 'expo-sensors';\r\n\r\n/**\r\n * SensorInputProvider subscribes to device accelerometer and gyroscope\r\n * and emits normalized SensorData events.\r\n *\r\n * Performance considerations:\r\n * - Default update interval is 100ms (10Hz) — configurable, capped at ~60Hz.\r\n * - Subscriptions are lazily created and cleaned up on stop().\r\n * - Data is emitted as-is; filtering happens in the Processing layer.\r\n */\r\nexport class SensorInputProvider implements IInputProvider {\r\n private _isActive = false;\r\n private accelSubscription: { remove(): void } | null = null;\r\n private gyroSubscription: { remove(): void } | null = null;\r\n private updateIntervalMs: number;\r\n\r\n constructor(\r\n private eventBus: IEventBus,\r\n updateIntervalMs = 100,\r\n ) {\r\n // Clamp to minimum 16ms (~60Hz) to prevent battery drain\r\n this.updateIntervalMs = Math.max(16, updateIntervalMs);\r\n }\r\n\r\n get isActive(): boolean {\r\n return this._isActive;\r\n }\r\n\r\n start(): void {\r\n if (this._isActive) return;\r\n this._isActive = true;\r\n\r\n if (!Accelerometer || !Gyroscope) {\r\n console.warn('[GestureEngine] Sensors unavailable. Skipping sensor subscriptions.');\r\n return;\r\n }\r\n\r\n // Configure update intervals\r\n Accelerometer.setUpdateInterval(this.updateIntervalMs);\r\n Gyroscope.setUpdateInterval(this.updateIntervalMs);\r\n\r\n // Subscribe to accelerometer\r\n this.accelSubscription = Accelerometer.addListener(\r\n (data: { x: number; y: number; z: number }) => {\r\n if (!this._isActive) return;\r\n\r\n const sensorData: SensorData = {\r\n type: SensorType.Accelerometer,\r\n x: data.x,\r\n y: data.y,\r\n z: data.z,\r\n };\r\n\r\n const event: InputEvent = {\r\n id: generateId(),\r\n timestamp: Date.now(),\r\n inputType: InputType.Sensor,\r\n data: sensorData,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.InputRaw, event);\r\n },\r\n );\r\n\r\n // Subscribe to gyroscope\r\n this.gyroSubscription = Gyroscope.addListener(\r\n (data: { x: number; y: number; z: number }) => {\r\n if (!this._isActive) return;\r\n\r\n const sensorData: SensorData = {\r\n type: SensorType.Gyroscope,\r\n x: data.x,\r\n y: data.y,\r\n z: data.z,\r\n };\r\n\r\n const event: InputEvent = {\r\n id: generateId(),\r\n timestamp: Date.now(),\r\n inputType: InputType.Sensor,\r\n data: sensorData,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.InputRaw, event);\r\n },\r\n );\r\n }\r\n\r\n stop(): void {\r\n this._isActive = false;\r\n\r\n if (this.accelSubscription) {\r\n this.accelSubscription.remove();\r\n this.accelSubscription = null;\r\n }\r\n\r\n if (this.gyroSubscription) {\r\n this.gyroSubscription.remove();\r\n this.gyroSubscription = null;\r\n }\r\n }\r\n}\r\n","// ─── HardwareInputProvider ──────────────────────────────────────────────────\r\n// Extensible stub for hardware button events (e.g., volume buttons on Android).\r\n// Uses DeviceEventEmitter to listen for native module events.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IInputProvider,\r\n IEventBus,\r\n EventChannel,\r\n InputType,\r\n HardwareData,\r\n InputEvent,\r\n generateId,\r\n} from '../core/types';\r\nimport { DeviceEventEmitter } from 'react-native';\r\n\r\n/**\r\n * HardwareInputProvider listens for hardware button events on Android\r\n * via DeviceEventEmitter and emits them as InputEvents.\r\n *\r\n * Note: This requires a companion native module to forward volume button\r\n * events. Without one, this provider is effectively a no-op stub that\r\n * demonstrates the extensibility of the input layer.\r\n *\r\n * To extend for custom hardware events:\r\n * 1. Create a native module that emits 'onHardwareKey' events\r\n * 2. The event payload should contain { key: string, action: 'down' | 'up' }\r\n */\r\nexport class HardwareInputProvider implements IInputProvider {\r\n private _isActive = false;\r\n private subscription: { remove(): void } | null = null;\r\n private eventName: string;\r\n\r\n constructor(\r\n private eventBus: IEventBus,\r\n eventName = 'onHardwareKey',\r\n ) {\r\n this.eventName = eventName;\r\n }\r\n\r\n get isActive(): boolean {\r\n return this._isActive;\r\n }\r\n\r\n start(): void {\r\n if (this._isActive) return;\r\n this._isActive = true;\r\n\r\n if (!DeviceEventEmitter) {\r\n return;\r\n }\r\n\r\n this.subscription = DeviceEventEmitter.addListener(\r\n this.eventName,\r\n (data: { key: string; action: 'down' | 'up' }) => {\r\n if (!this._isActive) return;\r\n\r\n const hardwareData: HardwareData = {\r\n key: data.key,\r\n action: data.action,\r\n };\r\n\r\n const event: InputEvent = {\r\n id: generateId(),\r\n timestamp: Date.now(),\r\n inputType: InputType.Hardware,\r\n data: hardwareData,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.InputRaw, event);\r\n },\r\n );\r\n }\r\n\r\n stop(): void {\r\n this._isActive = false;\r\n\r\n if (this.subscription) {\r\n this.subscription.remove();\r\n this.subscription = null;\r\n }\r\n }\r\n}\r\n","// ─── CameraInputProvider ────────────────────────────────────────────────────\r\n// Future-ready no-op stub implementing IInputProvider.\r\n// Placeholder for computer-vision-based gesture input (e.g., hand tracking).\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IInputProvider, IEventBus } from '../core/types';\r\n\r\n/**\r\n * CameraInputProvider is a future-ready stub for camera-based gesture input.\r\n *\r\n * When implemented, this would:\r\n * - Subscribe to a camera frame processing pipeline\r\n * - Run hand/pose detection models\r\n * - Emit InputEvents with detected gesture landmarks\r\n *\r\n * Currently a no-op — calling start()/stop() has no effect.\r\n */\r\nexport class CameraInputProvider implements IInputProvider {\r\n private _isActive = false;\r\n\r\n // EventBus stored for future use when camera input is implemented\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n constructor(private eventBus: IEventBus) {}\r\n\r\n get isActive(): boolean {\r\n return this._isActive;\r\n }\r\n\r\n start(): void {\r\n this._isActive = true;\r\n // Future: subscribe to camera frame pipeline\r\n }\r\n\r\n stop(): void {\r\n this._isActive = false;\r\n // Future: unsubscribe from camera frames\r\n }\r\n}\r\n","// ─── NoiseFilter ────────────────────────────────────────────────────────────\r\n// IIR (Infinite Impulse Response) low-pass and high-pass filters.\r\n// Low-pass removes jitter/noise; high-pass removes gravity component.\r\n// Configurable alpha controls filter responsiveness vs. smoothness.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * First-order IIR noise filter with both low-pass and high-pass modes.\r\n *\r\n * Low-pass: output = α * input + (1 - α) * previousOutput\r\n * - Smooths noisy signals (e.g., touch jitter)\r\n * - Higher alpha = more responsive but noisier\r\n *\r\n * High-pass: output = input - lowPass(input)\r\n * - Removes slowly-changing components (e.g., gravity from accelerometer)\r\n * - Isolates sudden movements (shakes, flicks)\r\n */\r\nexport class NoiseFilter {\r\n private lowPassState: { x: number; y: number; z: number } | null = null;\r\n private alpha: number;\r\n\r\n /**\r\n * @param alpha - Filter coefficient [0, 1]. Default 0.8.\r\n * - For low-pass: 0.1 = very smooth, 0.9 = barely filtered\r\n * - For high-pass: same alpha applied to the underlying low-pass\r\n */\r\n constructor(alpha = 0.8) {\r\n this.alpha = Math.max(0, Math.min(1, alpha));\r\n }\r\n\r\n /**\r\n * Apply low-pass filter. Removes high-frequency jitter.\r\n */\r\n lowPass(x: number, y: number, z: number): { x: number; y: number; z: number } {\r\n if (this.lowPassState === null) {\r\n // First sample — initialize state\r\n this.lowPassState = { x, y, z };\r\n return { x, y, z };\r\n }\r\n\r\n const prev = this.lowPassState;\r\n const filtered = {\r\n x: this.alpha * x + (1 - this.alpha) * prev.x,\r\n y: this.alpha * y + (1 - this.alpha) * prev.y,\r\n z: this.alpha * z + (1 - this.alpha) * prev.z,\r\n };\r\n\r\n this.lowPassState = filtered;\r\n return filtered;\r\n }\r\n\r\n /**\r\n * Apply high-pass filter. Removes low-frequency components (gravity).\r\n * Returns only the dynamic/transient part of the signal.\r\n */\r\n highPass(x: number, y: number, z: number): { x: number; y: number; z: number } {\r\n const low = this.lowPass(x, y, z);\r\n return {\r\n x: x - low.x,\r\n y: y - low.y,\r\n z: z - low.z,\r\n };\r\n }\r\n\r\n /**\r\n * Reset filter state. Call when starting a new gesture or after a pause.\r\n */\r\n reset(): void {\r\n this.lowPassState = null;\r\n }\r\n\r\n /**\r\n * Update alpha dynamically (e.g., for adaptive filtering).\r\n */\r\n setAlpha(alpha: number): void {\r\n this.alpha = Math.max(0, Math.min(1, alpha));\r\n }\r\n}\r\n","// ─── VelocityCalculator ─────────────────────────────────────────────────────\r\n// Computes velocity as Δposition / Δtime from sequential samples.\r\n// Handles edge cases: first sample, zero time delta, and NaN prevention.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Computes velocity from sequential position/time samples.\r\n * Velocity = (currentPosition - previousPosition) / (currentTime - previousTime)\r\n */\r\nexport class VelocityCalculator {\r\n private prevX: number | null = null;\r\n private prevY: number | null = null;\r\n private prevTimestamp: number | null = null;\r\n\r\n /**\r\n * Calculate velocity from a new position sample.\r\n *\r\n * @param x - Current X position\r\n * @param y - Current Y position\r\n * @param timestamp - Current timestamp in milliseconds\r\n * @returns Velocity components and magnitude\r\n */\r\n calculate(\r\n x: number,\r\n y: number,\r\n timestamp: number,\r\n ): {\r\n velocityX: number;\r\n velocityY: number;\r\n velocity: number;\r\n } {\r\n if (this.prevX === null || this.prevY === null || this.prevTimestamp === null) {\r\n // First sample — no velocity yet\r\n this.prevX = x;\r\n this.prevY = y;\r\n this.prevTimestamp = timestamp;\r\n return { velocityX: 0, velocityY: 0, velocity: 0 };\r\n }\r\n\r\n const dt = timestamp - this.prevTimestamp;\r\n\r\n // Guard against division by zero (simultaneous events)\r\n if (dt <= 0) {\r\n return { velocityX: 0, velocityY: 0, velocity: 0 };\r\n }\r\n\r\n const dx = x - this.prevX;\r\n const dy = y - this.prevY;\r\n\r\n const velocityX = dx / dt;\r\n const velocityY = dy / dt;\r\n const velocity = Math.sqrt(velocityX * velocityX + velocityY * velocityY);\r\n\r\n // Update state for next calculation\r\n this.prevX = x;\r\n this.prevY = y;\r\n this.prevTimestamp = timestamp;\r\n\r\n return { velocityX, velocityY, velocity };\r\n }\r\n\r\n /**\r\n * Reset state. Call when starting a new gesture.\r\n */\r\n reset(): void {\r\n this.prevX = null;\r\n this.prevY = null;\r\n this.prevTimestamp = null;\r\n }\r\n}\r\n","// ─── AngleDetector ──────────────────────────────────────────────────────────\r\n// Computes direction angle from X/Y components using Math.atan2.\r\n// Provides both radians and degrees, plus cardinal direction classification.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { CardinalDirection } from '../core/types';\r\n\r\n/**\r\n * Detects direction angle and classifies into cardinal directions.\r\n *\r\n * Coordinate system:\r\n * - 0° / 0 rad = right\r\n * - 90° / π/2 rad = down (screen coordinates, Y grows downward)\r\n * - 180° / π rad = left\r\n * - -90° / -π/2 rad = up\r\n */\r\nexport class AngleDetector {\r\n /**\r\n * Calculate angle from X/Y deltas.\r\n *\r\n * @param dx - Change in X (positive = right)\r\n * @param dy - Change in Y (positive = down in screen coords)\r\n * @returns Angle in radians, degrees, and cardinal direction\r\n */\r\n calculate(\r\n dx: number,\r\n dy: number,\r\n ): {\r\n angleRadians: number;\r\n angleDegrees: number;\r\n direction: CardinalDirection;\r\n } {\r\n // No movement — no direction\r\n if (dx === 0 && dy === 0) {\r\n return {\r\n angleRadians: 0,\r\n angleDegrees: 0,\r\n direction: CardinalDirection.None,\r\n };\r\n }\r\n\r\n const angleRadians = Math.atan2(dy, dx);\r\n const angleDegrees = (angleRadians * 180) / Math.PI;\r\n const direction = this.classifyDirection(angleDegrees);\r\n\r\n return { angleRadians, angleDegrees, direction };\r\n }\r\n\r\n /**\r\n * Classify angle (in degrees) into 8 cardinal directions.\r\n * Uses 45° sectors centered on each direction.\r\n *\r\n * Sectors (in screen coordinates where Y grows down):\r\n * Right: -22.5° to 22.5°\r\n * DownRight: 22.5° to 67.5°\r\n * Down: 67.5° to 112.5°\r\n * DownLeft: 112.5° to 157.5°\r\n * Left: 157.5° to 180° or -180° to -157.5°\r\n * UpLeft: -157.5° to -112.5°\r\n * Up: -112.5° to -67.5°\r\n * UpRight: -67.5° to -22.5°\r\n */\r\n private classifyDirection(degrees: number): CardinalDirection {\r\n // Normalize to [-180, 180]\r\n const d = degrees;\r\n\r\n if (d >= -22.5 && d < 22.5) return CardinalDirection.Right;\r\n if (d >= 22.5 && d < 67.5) return CardinalDirection.DownRight;\r\n if (d >= 67.5 && d < 112.5) return CardinalDirection.Down;\r\n if (d >= 112.5 && d < 157.5) return CardinalDirection.DownLeft;\r\n if (d >= 157.5 || d < -157.5) return CardinalDirection.Left;\r\n if (d >= -157.5 && d < -112.5) return CardinalDirection.UpLeft;\r\n if (d >= -112.5 && d < -67.5) return CardinalDirection.Up;\r\n if (d >= -67.5 && d < -22.5) return CardinalDirection.UpRight;\r\n\r\n return CardinalDirection.None;\r\n }\r\n}\r\n","// ─── ThresholdNormalizer ─────────────────────────────────────────────────────\r\n// Maps raw magnitude values to the [0, 1] range given min/max thresholds.\r\n// Values below min map to 0, above max map to 1, in between are linear.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Maps raw magnitudes to a normalized [0, 1] range with clamping.\r\n *\r\n * Formula: normalized = clamp((value - min) / (max - min), 0, 1)\r\n *\r\n * This is useful for turning raw sensor values (e.g., acceleration in g,\r\n * velocity in px/ms) into intensity values that can be used for feedback\r\n * or threshold comparison.\r\n */\r\nexport class ThresholdNormalizer {\r\n private min: number;\r\n private max: number;\r\n\r\n /**\r\n * @param min - Minimum threshold. Values at or below this map to 0.\r\n * @param max - Maximum threshold. Values at or above this map to 1.\r\n */\r\n constructor(min = 0, max = 1) {\r\n if (min >= max) {\r\n throw new Error(\r\n `[ThresholdNormalizer] min (${min}) must be less than max (${max})`,\r\n );\r\n }\r\n this.min = min;\r\n this.max = max;\r\n }\r\n\r\n /**\r\n * Normalize a raw value to [0, 1].\r\n */\r\n normalize(value: number): number {\r\n if (value <= this.min) return 0;\r\n if (value >= this.max) return 1;\r\n return (value - this.min) / (this.max - this.min);\r\n }\r\n\r\n /**\r\n * Update thresholds dynamically.\r\n */\r\n setRange(min: number, max: number): void {\r\n if (min >= max) {\r\n throw new Error(\r\n `[ThresholdNormalizer] min (${min}) must be less than max (${max})`,\r\n );\r\n }\r\n this.min = min;\r\n this.max = max;\r\n }\r\n\r\n /**\r\n * Get current min threshold.\r\n */\r\n getMin(): number {\r\n return this.min;\r\n }\r\n\r\n /**\r\n * Get current max threshold.\r\n */\r\n getMax(): number {\r\n return this.max;\r\n }\r\n}\r\n","// ─── StreamBuffer ───────────────────────────────────────────────────────────\r\n// Time-windowed ring buffer retaining ProcessedSample objects from the last\r\n// 300–500ms. Provides O(1) insertion and automatic eviction of stale entries.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample } from '../core/types';\r\n\r\n/**\r\n * Fixed-size ring buffer with time-based eviction.\r\n *\r\n * Design decisions:\r\n * - Uses a pre-allocated array with head/tail pointers for O(1) push.\r\n * - Evicts entries older than windowMs on each push (amortized O(1)).\r\n * - Capacity is generously sized (default 64) to handle burst input at 60Hz.\r\n * - getAll() returns samples in chronological order.\r\n */\r\nexport class StreamBuffer {\r\n private buffer: (ProcessedSample | null)[];\r\n private head = 0;\r\n private count = 0;\r\n private capacity: number;\r\n private windowMs: number;\r\n\r\n /**\r\n * @param windowMs - Time window in ms. Samples older than this are evicted. Default 400.\r\n * @param capacity - Maximum buffer size. Default 64 (~1 sec at 60Hz).\r\n */\r\n constructor(windowMs = 400, capacity = 64) {\r\n this.windowMs = windowMs;\r\n this.capacity = capacity;\r\n this.buffer = new Array(capacity).fill(null);\r\n }\r\n\r\n /**\r\n * Push a new sample. Automatically evicts stale samples.\r\n * O(1) amortized.\r\n */\r\n push(sample: ProcessedSample): void {\r\n // Write to current head position\r\n const writeIndex = (this.head + this.count) % this.capacity;\r\n\r\n if (this.count === this.capacity) {\r\n // Buffer full — overwrite oldest (advance head)\r\n this.buffer[this.head] = sample;\r\n this.head = (this.head + 1) % this.capacity;\r\n } else {\r\n this.buffer[writeIndex] = sample;\r\n this.count++;\r\n }\r\n\r\n // Evict stale samples from the head\r\n this.evictStale(sample.timestamp);\r\n }\r\n\r\n /**\r\n * Get all non-stale samples in chronological order.\r\n */\r\n getAll(): ProcessedSample[] {\r\n const result: ProcessedSample[] = [];\r\n for (let i = 0; i < this.count; i++) {\r\n const index = (this.head + i) % this.capacity;\r\n const sample = this.buffer[index];\r\n if (sample) {\r\n result.push(sample);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Get the most recent sample, or null if buffer is empty.\r\n */\r\n latest(): ProcessedSample | null {\r\n if (this.count === 0) return null;\r\n const index = (this.head + this.count - 1) % this.capacity;\r\n return this.buffer[index];\r\n }\r\n\r\n /**\r\n * Get the number of samples currently in the buffer.\r\n */\r\n size(): number {\r\n return this.count;\r\n }\r\n\r\n /**\r\n * Clear the buffer.\r\n */\r\n clear(): void {\r\n this.buffer.fill(null);\r\n this.head = 0;\r\n this.count = 0;\r\n }\r\n\r\n /**\r\n * Remove samples older than windowMs from the head.\r\n */\r\n private evictStale(currentTimestamp: number): void {\r\n const cutoff = currentTimestamp - this.windowMs;\r\n\r\n while (this.count > 0) {\r\n const sample = this.buffer[this.head];\r\n if (sample && sample.timestamp < cutoff) {\r\n this.buffer[this.head] = null;\r\n this.head = (this.head + 1) % this.capacity;\r\n this.count--;\r\n } else {\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n","// ─── BaseRecognizer ─────────────────────────────────────────────────────────\r\n// Abstract base class for all gesture recognizers with built-in state machine.\r\n// Implements IRecognizer and provides transition logic, EventBus integration,\r\n// and common lifecycle methods (reset, dispose).\r\n//\r\n// State transitions:\r\n// Idle → Possible → Began → Changed → Ended\r\n// ↘ Failed / Cancelled\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IRecognizer,\r\n IEventBus,\r\n RecognizerState,\r\n ProcessedSample,\r\n GestureEvent,\r\n GestureMetadata,\r\n EventChannel,\r\n generateId,\r\n} from '../../core/types';\r\n\r\n/**\r\n * Abstract base class for all gesture recognizers.\r\n *\r\n * Subclasses must implement:\r\n * - `onProcessedSample(sample)`: evaluate the sample and call transition methods\r\n *\r\n * The base class provides:\r\n * - State machine with validated transitions\r\n * - Automatic GestureEvent emission on state changes\r\n * - EventBus integration\r\n * - reset() and dispose() lifecycle methods\r\n */\r\nexport abstract class BaseRecognizer implements IRecognizer {\r\n readonly id: string;\r\n readonly name: string;\r\n readonly priority: number;\r\n readonly isExclusive: boolean;\r\n enabled: boolean;\r\n\r\n private _state: RecognizerState = RecognizerState.Idle;\r\n protected eventBus: IEventBus;\r\n\r\n constructor(\r\n name: string,\r\n eventBus: IEventBus,\r\n options: {\r\n priority?: number;\r\n isExclusive?: boolean;\r\n enabled?: boolean;\r\n } = {},\r\n ) {\r\n this.id = generateId();\r\n this.name = name;\r\n this.eventBus = eventBus;\r\n this.priority = options.priority ?? 100;\r\n this.isExclusive = options.isExclusive ?? false;\r\n this.enabled = options.enabled ?? true;\r\n }\r\n\r\n get state(): RecognizerState {\r\n return this._state;\r\n }\r\n\r\n /**\r\n * Must be implemented by subclasses.\r\n * Evaluate the incoming processed sample and trigger state transitions.\r\n */\r\n abstract onProcessedSample(sample: ProcessedSample): void;\r\n\r\n /**\r\n * Reset the recognizer to Idle state.\r\n */\r\n reset(): void {\r\n this._state = RecognizerState.Idle;\r\n }\r\n\r\n /**\r\n * Clean up resources. Override in subclasses for custom cleanup.\r\n */\r\n dispose(): void {\r\n this.reset();\r\n }\r\n\r\n // ─── Protected: state transition helpers ────────────────────────────\r\n\r\n /**\r\n * Transition to Possible state (gesture might be starting).\r\n */\r\n protected transitionToPossible(): void {\r\n if (this._state === RecognizerState.Idle) {\r\n this._state = RecognizerState.Possible;\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Began state and emit gesture event.\r\n * Only valid from Possible state.\r\n */\r\n protected transitionToBegan(metadata: GestureMetadata = {}): void {\r\n if (this._state === RecognizerState.Possible) {\r\n this._state = RecognizerState.Began;\r\n this.emitGestureEvent(metadata);\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Changed state and emit gesture event.\r\n * Only valid from Began or Changed state (continuous gestures).\r\n */\r\n protected transitionToChanged(metadata: GestureMetadata = {}): void {\r\n if (\r\n this._state === RecognizerState.Began ||\r\n this._state === RecognizerState.Changed\r\n ) {\r\n this._state = RecognizerState.Changed;\r\n this.emitGestureEvent(metadata);\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Ended state and emit gesture event.\r\n * Valid from Began, Changed, or Possible states.\r\n */\r\n protected transitionToEnded(metadata: GestureMetadata = {}): void {\r\n if (\r\n this._state === RecognizerState.Began ||\r\n this._state === RecognizerState.Changed ||\r\n this._state === RecognizerState.Possible\r\n ) {\r\n this._state = RecognizerState.Ended;\r\n this.emitGestureEvent(metadata);\r\n // Auto-reset to Idle after Ended\r\n this._state = RecognizerState.Idle;\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Failed state (gesture didn't match criteria).\r\n * Auto-resets to Idle.\r\n */\r\n protected transitionToFailed(): void {\r\n if (\r\n this._state === RecognizerState.Possible ||\r\n this._state === RecognizerState.Began\r\n ) {\r\n this._state = RecognizerState.Failed;\r\n // Auto-reset to Idle\r\n this._state = RecognizerState.Idle;\r\n }\r\n }\r\n\r\n /**\r\n * Transition to Cancelled state (gesture was interrupted).\r\n * Auto-resets to Idle.\r\n */\r\n protected transitionToCancelled(): void {\r\n if (\r\n this._state === RecognizerState.Began ||\r\n this._state === RecognizerState.Changed\r\n ) {\r\n this._state = RecognizerState.Cancelled;\r\n this.emitGestureEvent({});\r\n this._state = RecognizerState.Idle;\r\n }\r\n }\r\n\r\n /**\r\n * Emit a GestureEvent on the RecognitionGesture channel.\r\n */\r\n private emitGestureEvent(metadata: GestureMetadata): void {\r\n const event: GestureEvent = {\r\n id: generateId(),\r\n name: this.name,\r\n state: this._state,\r\n priority: this.priority,\r\n isExclusive: this.isExclusive,\r\n timestamp: Date.now(),\r\n metadata,\r\n };\r\n\r\n this.eventBus.emit(EventChannel.RecognitionGesture, event);\r\n }\r\n}\r\n","// ─── TapRecognizer ──────────────────────────────────────────────────────────\r\n// Detects single-tap gestures. A tap must:\r\n// 1. Start and end within maxDuration ms\r\n// 2. Not move more than maxDistance px from the start point\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, TapRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class TapRecognizer extends BaseRecognizer {\r\n private maxDuration: number;\r\n private maxDistance: number;\r\n private startTime: number | null = null;\r\n private startX: number | null = null;\r\n private startY: number | null = null;\r\n\r\n constructor(eventBus: IEventBus, config: TapRecognizerConfig = {}) {\r\n super('tap', eventBus, {\r\n priority: config.priority ?? 10,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.maxDuration = config.maxDuration ?? 300;\r\n this.maxDistance = config.maxDistance ?? 10;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Tap && touchData.type !== TouchType.Pan) return;\r\n\r\n // Handle tap type directly — RNGH fires onEnd for taps\r\n if (touchData.type === TouchType.Tap) {\r\n this.transitionToPossible();\r\n this.transitionToBegan({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n this.transitionToEnded({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n return;\r\n }\r\n\r\n // For pan-based tap detection: track motion to verify it's a tap\r\n if (this.startTime === null) {\r\n this.startTime = inputEvent.timestamp;\r\n this.startX = touchData.x;\r\n this.startY = touchData.y;\r\n this.transitionToPossible();\r\n return;\r\n }\r\n\r\n const elapsed = inputEvent.timestamp - this.startTime;\r\n const dx = touchData.x - (this.startX ?? 0);\r\n const dy = touchData.y - (this.startY ?? 0);\r\n const distance = Math.sqrt(dx * dx + dy * dy);\r\n\r\n // Too much movement — not a tap\r\n if (distance > this.maxDistance) {\r\n this.transitionToFailed();\r\n this.resetState();\r\n return;\r\n }\r\n\r\n // Duration exceeded — not a tap\r\n if (elapsed > this.maxDuration) {\r\n this.transitionToFailed();\r\n this.resetState();\r\n return;\r\n }\r\n\r\n // Velocity drops to near zero (finger lifted) — recognize as tap\r\n if (\r\n Math.abs(touchData.velocityX) < 0.01 &&\r\n Math.abs(touchData.velocityY) < 0.01 &&\r\n elapsed > 20\r\n ) {\r\n this.transitionToBegan({\r\n translation: { x: this.startX ?? 0, y: this.startY ?? 0 },\r\n });\r\n this.transitionToEnded({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n this.resetState();\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.resetState();\r\n }\r\n\r\n private resetState(): void {\r\n this.startTime = null;\r\n this.startX = null;\r\n this.startY = null;\r\n }\r\n}\r\n","// ─── DoubleTapRecognizer ────────────────────────────────────────────────────\r\n// Detects double-tap gestures. Two taps must occur within maxInterval ms\r\n// and within maxDistance px of each other.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, DoubleTapRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class DoubleTapRecognizer extends BaseRecognizer {\r\n private maxInterval: number;\r\n private maxDistance: number;\r\n private firstTapTime: number | null = null;\r\n private firstTapX: number | null = null;\r\n private firstTapY: number | null = null;\r\n private tapCount = 0;\r\n\r\n constructor(eventBus: IEventBus, config: DoubleTapRecognizerConfig = {}) {\r\n super('double-tap', eventBus, {\r\n priority: config.priority ?? 5,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.maxInterval = config.maxInterval ?? 300;\r\n this.maxDistance = config.maxDistance ?? 30;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Tap) return;\r\n\r\n const now = inputEvent.timestamp;\r\n\r\n if (this.tapCount === 0) {\r\n // First tap\r\n this.firstTapTime = now;\r\n this.firstTapX = touchData.x;\r\n this.firstTapY = touchData.y;\r\n this.tapCount = 1;\r\n this.transitionToPossible();\r\n return;\r\n }\r\n\r\n if (this.tapCount === 1) {\r\n const elapsed = now - (this.firstTapTime ?? 0);\r\n const dx = touchData.x - (this.firstTapX ?? 0);\r\n const dy = touchData.y - (this.firstTapY ?? 0);\r\n const distance = Math.sqrt(dx * dx + dy * dy);\r\n\r\n if (elapsed <= this.maxInterval && distance <= this.maxDistance) {\r\n // Second tap within bounds — double tap recognized\r\n this.transitionToBegan({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n this.transitionToEnded({\r\n translation: { x: touchData.x, y: touchData.y },\r\n });\r\n this.resetState();\r\n } else {\r\n // Timed out or too far — treat this as a new first tap\r\n this.transitionToFailed();\r\n this.firstTapTime = now;\r\n this.firstTapX = touchData.x;\r\n this.firstTapY = touchData.y;\r\n this.tapCount = 1;\r\n this.transitionToPossible();\r\n }\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.resetState();\r\n }\r\n\r\n private resetState(): void {\r\n this.firstTapTime = null;\r\n this.firstTapX = null;\r\n this.firstTapY = null;\r\n this.tapCount = 0;\r\n }\r\n}\r\n","// ─── PanRecognizer ──────────────────────────────────────────────────────────\r\n// Continuous recognizer that emits Changed state with translation data\r\n// once the finger moves beyond a minimum threshold distance.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, PanRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class PanRecognizer extends BaseRecognizer {\r\n private minDistance: number;\r\n\r\n constructor(eventBus: IEventBus, config: PanRecognizerConfig = {}) {\r\n super('pan', eventBus, {\r\n priority: config.priority ?? 50,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.minDistance = config.minDistance ?? 10;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pan) return;\r\n\r\n const translation = {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n };\r\n const distance = Math.sqrt(\r\n translation.x * translation.x + translation.y * translation.y,\r\n );\r\n\r\n const velocity = {\r\n x: touchData.velocityX,\r\n y: touchData.velocityY,\r\n };\r\n\r\n // Check if we've moved enough to start recognizing\r\n if (this.state === 'idle' || this.state === 'possible') {\r\n this.transitionToPossible();\r\n if (distance >= this.minDistance) {\r\n this.transitionToBegan({ translation, velocity });\r\n }\r\n return;\r\n }\r\n\r\n // Continue emitting Changed events\r\n if (this.state === 'began' || this.state === 'changed') {\r\n // Detect end: velocity near zero and a brief pause\r\n if (\r\n Math.abs(touchData.velocityX) < 0.001 &&\r\n Math.abs(touchData.velocityY) < 0.001\r\n ) {\r\n this.transitionToEnded({ translation, velocity });\r\n } else {\r\n this.transitionToChanged({ translation, velocity });\r\n }\r\n }\r\n }\r\n}\r\n","// ─── PinchRecognizer ────────────────────────────────────────────────────────\r\n// Continuous recognizer for pinch/zoom gestures.\r\n// Emits Changed state with scale factor updates.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, PinchRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class PinchRecognizer extends BaseRecognizer {\r\n private minScale: number;\r\n\r\n constructor(eventBus: IEventBus, config: PinchRecognizerConfig = {}) {\r\n super('pinch', eventBus, {\r\n priority: config.priority ?? 40,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.minScale = config.minScale ?? 0.05;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pinch) return;\r\n\r\n const scaleDelta = Math.abs(touchData.scale - 1);\r\n\r\n if (this.state === 'idle' || this.state === 'possible') {\r\n this.transitionToPossible();\r\n if (scaleDelta >= this.minScale) {\r\n this.transitionToBegan({ scale: touchData.scale });\r\n }\r\n return;\r\n }\r\n\r\n if (this.state === 'began' || this.state === 'changed') {\r\n if (touchData.numberOfPointers < 2) {\r\n this.transitionToEnded({ scale: touchData.scale });\r\n } else {\r\n this.transitionToChanged({ scale: touchData.scale });\r\n }\r\n }\r\n }\r\n}\r\n","// ─── RotationRecognizer ─────────────────────────────────────────────────────\r\n// Continuous recognizer for two-finger rotation gestures.\r\n// Emits Changed state with rotation angle updates.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { ProcessedSample, InputType, TouchType, TouchData, IEventBus, RotationRecognizerConfig } from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class RotationRecognizer extends BaseRecognizer {\r\n private minRotation: number;\r\n\r\n constructor(eventBus: IEventBus, config: RotationRecognizerConfig = {}) {\r\n super('rotation', eventBus, {\r\n priority: config.priority ?? 45,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.minRotation = config.minRotation ?? 0.05;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Rotation) return;\r\n\r\n const rotationAbs = Math.abs(touchData.rotation);\r\n\r\n if (this.state === 'idle' || this.state === 'possible') {\r\n this.transitionToPossible();\r\n if (rotationAbs >= this.minRotation) {\r\n this.transitionToBegan({ rotation: touchData.rotation });\r\n }\r\n return;\r\n }\r\n\r\n if (this.state === 'began' || this.state === 'changed') {\r\n if (touchData.numberOfPointers < 2) {\r\n this.transitionToEnded({ rotation: touchData.rotation });\r\n } else {\r\n this.transitionToChanged({ rotation: touchData.rotation });\r\n }\r\n }\r\n }\r\n}\r\n","// ─── EdgeSwipeRecognizer ────────────────────────────────────────────────────\r\n// Detects gestures that START within the edge zone of the screen.\r\n// Supports all 4 edges (left, right, top, bottom) with configurable:\r\n// - Edge zone width (default 30px)\r\n// - Minimum swipe distance (default 50px)\r\n// - Minimum velocity (default 0.3 px/ms)\r\n//\r\n// Emits GestureEvent with name 'edge-swipe-{left|right|top|bottom}'\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, TouchType, TouchData,\r\n IEventBus, EdgeSwipeRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class EdgeSwipeRecognizer extends BaseRecognizer {\r\n private edge: 'left' | 'right' | 'top' | 'bottom';\r\n private edgeZoneWidth: number;\r\n private minDistance: number;\r\n private minVelocity: number;\r\n private screenWidth: number;\r\n private screenHeight: number;\r\n private startedInEdge = false;\r\n private startX: number | null = null;\r\n private startY: number | null = null;\r\n\r\n constructor(eventBus: IEventBus, config: EdgeSwipeRecognizerConfig) {\r\n super(`edge-swipe-${config.edge}`, eventBus, {\r\n priority: config.priority ?? 20,\r\n isExclusive: config.isExclusive ?? true,\r\n enabled: config.enabled,\r\n });\r\n this.edge = config.edge;\r\n this.edgeZoneWidth = config.edgeZoneWidth ?? 30;\r\n this.minDistance = config.minDistance ?? 50;\r\n this.minVelocity = config.minVelocity ?? 0.3;\r\n this.screenWidth = config.screenWidth ?? 400;\r\n this.screenHeight = config.screenHeight ?? 800;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pan) return;\r\n\r\n // Track initial touch position to detect edge start\r\n if (this.startX === null) {\r\n this.startX = touchData.x;\r\n this.startY = touchData.y;\r\n this.startedInEdge = this.isInEdgeZone(touchData.x, touchData.y);\r\n\r\n if (this.startedInEdge) {\r\n this.transitionToPossible();\r\n }\r\n return;\r\n }\r\n\r\n // Ignore if gesture didn't start in the edge zone\r\n if (!this.startedInEdge) return;\r\n\r\n // Calculate swipe distance in the expected direction\r\n const swipeDistance = this.getSwipeDistance(touchData);\r\n const swipeVelocity = this.getSwipeVelocity(touchData);\r\n\r\n if (this.state === 'possible') {\r\n // Check if swipe conditions are met\r\n if (swipeDistance >= this.minDistance && swipeVelocity >= this.minVelocity) {\r\n this.transitionToBegan({\r\n edge: this.edge,\r\n translation: {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n },\r\n velocity: {\r\n x: touchData.velocityX,\r\n y: touchData.velocityY,\r\n },\r\n });\r\n this.transitionToEnded({\r\n edge: this.edge,\r\n translation: {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n },\r\n velocity: {\r\n x: touchData.velocityX,\r\n y: touchData.velocityY,\r\n },\r\n });\r\n this.resetState();\r\n }\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.resetState();\r\n }\r\n\r\n /**\r\n * Check if a point is within the configured edge zone.\r\n */\r\n private isInEdgeZone(x: number, y: number): boolean {\r\n switch (this.edge) {\r\n case 'left':\r\n return x <= this.edgeZoneWidth;\r\n case 'right':\r\n return x >= this.screenWidth - this.edgeZoneWidth;\r\n case 'top':\r\n return y <= this.edgeZoneWidth;\r\n case 'bottom':\r\n return y >= this.screenHeight - this.edgeZoneWidth;\r\n }\r\n }\r\n\r\n /**\r\n * Get the swipe distance along the expected axis.\r\n * Left/right edges → horizontal distance, top/bottom → vertical.\r\n */\r\n private getSwipeDistance(touchData: TouchData): number {\r\n switch (this.edge) {\r\n case 'left':\r\n return touchData.translationX; // positive = swiping right (from left edge)\r\n case 'right':\r\n return -touchData.translationX; // positive = swiping left (from right edge)\r\n case 'top':\r\n return touchData.translationY; // positive = swiping down (from top edge)\r\n case 'bottom':\r\n return -touchData.translationY; // positive = swiping up (from bottom edge)\r\n }\r\n }\r\n\r\n /**\r\n * Get the swipe velocity along the expected axis.\r\n */\r\n private getSwipeVelocity(touchData: TouchData): number {\r\n switch (this.edge) {\r\n case 'left':\r\n return touchData.velocityX;\r\n case 'right':\r\n return -touchData.velocityX;\r\n case 'top':\r\n return touchData.velocityY;\r\n case 'bottom':\r\n return -touchData.velocityY;\r\n }\r\n }\r\n\r\n private resetState(): void {\r\n this.startX = null;\r\n this.startY = null;\r\n this.startedInEdge = false;\r\n }\r\n}\r\n","// ─── CornerRecognizer ───────────────────────────────────────────────────────\r\n// Detects gestures that start from screen corners. Supports all 4 corners.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, TouchType, TouchData,\r\n IEventBus, CornerRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class CornerRecognizer extends BaseRecognizer {\r\n private corner: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\r\n private cornerZoneSize: number;\r\n private minDistance: number;\r\n private screenWidth: number;\r\n private screenHeight: number;\r\n private startedInCorner = false;\r\n private startX: number | null = null;\r\n private startY: number | null = null;\r\n\r\n constructor(eventBus: IEventBus, config: CornerRecognizerConfig) {\r\n super(`corner-${config.corner}`, eventBus, {\r\n priority: config.priority ?? 15,\r\n isExclusive: config.isExclusive ?? true,\r\n enabled: config.enabled,\r\n });\r\n this.corner = config.corner;\r\n this.cornerZoneSize = config.cornerZoneSize ?? 50;\r\n this.minDistance = config.minDistance ?? 40;\r\n this.screenWidth = config.screenWidth ?? 400;\r\n this.screenHeight = config.screenHeight ?? 800;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pan) return;\r\n\r\n if (this.startX === null) {\r\n this.startX = touchData.x;\r\n this.startY = touchData.y;\r\n this.startedInCorner = this.isInCornerZone(touchData.x, touchData.y);\r\n\r\n if (this.startedInCorner) {\r\n this.transitionToPossible();\r\n }\r\n return;\r\n }\r\n\r\n if (!this.startedInCorner) return;\r\n\r\n const distance = Math.sqrt(\r\n touchData.translationX ** 2 + touchData.translationY ** 2,\r\n );\r\n\r\n if (this.state === 'possible' && distance >= this.minDistance) {\r\n this.transitionToBegan({\r\n translation: {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n },\r\n });\r\n this.transitionToEnded({\r\n translation: {\r\n x: touchData.translationX,\r\n y: touchData.translationY,\r\n },\r\n });\r\n this.resetState();\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.resetState();\r\n }\r\n\r\n private isInCornerZone(x: number, y: number): boolean {\r\n const zone = this.cornerZoneSize;\r\n switch (this.corner) {\r\n case 'top-left':\r\n return x <= zone && y <= zone;\r\n case 'top-right':\r\n return x >= this.screenWidth - zone && y <= zone;\r\n case 'bottom-left':\r\n return x <= zone && y >= this.screenHeight - zone;\r\n case 'bottom-right':\r\n return x >= this.screenWidth - zone && y >= this.screenHeight - zone;\r\n }\r\n }\r\n\r\n private resetState(): void {\r\n this.startX = null;\r\n this.startY = null;\r\n this.startedInCorner = false;\r\n }\r\n}\r\n","// ─── ShakeRecognizer ────────────────────────────────────────────────────────\r\n// Detects device shake gestures from high-pass filtered accelerometer data.\r\n//\r\n// Algorithm:\r\n// 1. Consume ProcessedSamples with SensorType.Accelerometer\r\n// 2. Compute magnitude = √(x² + y² + z²) from filtered data\r\n// 3. Track consecutive samples above threshold (default 1.5g)\r\n// 4. When consecutiveSamples (default 2) are above threshold → trigger shake\r\n// 5. Enforce cooldown period (default 1000ms) to prevent rapid re-fires\r\n//\r\n// Emits GestureEvent with name: 'shake', metadata.magnitude\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, SensorType, SensorData,\r\n IEventBus, ShakeRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class ShakeRecognizer extends BaseRecognizer {\r\n private threshold: number;\r\n private consecutiveSamples: number;\r\n private cooldownMs: number;\r\n\r\n private aboveThresholdCount = 0;\r\n private lastTriggerTime = 0;\r\n\r\n constructor(eventBus: IEventBus, config: ShakeRecognizerConfig = {}) {\r\n super('shake', eventBus, {\r\n priority: config.priority ?? 30,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.threshold = config.threshold ?? 1.5;\r\n this.consecutiveSamples = config.consecutiveSamples ?? 2;\r\n this.cooldownMs = config.cooldownMs ?? 1000;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Sensor) return;\r\n\r\n const sensorData = inputEvent.data as SensorData;\r\n if (sensorData.type !== SensorType.Accelerometer) return;\r\n\r\n // Use high-pass filtered data (gravity removed) from the processing layer\r\n const { x, y, z } = sample.filtered;\r\n\r\n // Compute acceleration magnitude\r\n const magnitude = Math.sqrt(x * x + y * y + z * z);\r\n\r\n if (magnitude >= this.threshold) {\r\n this.aboveThresholdCount++;\r\n\r\n if (this.aboveThresholdCount >= this.consecutiveSamples) {\r\n const now = Date.now();\r\n\r\n // Check cooldown\r\n if (now - this.lastTriggerTime < this.cooldownMs) {\r\n // Still in cooldown — don't re-trigger\r\n return;\r\n }\r\n\r\n // Shake detected!\r\n this.lastTriggerTime = now;\r\n this.aboveThresholdCount = 0;\r\n\r\n this.transitionToPossible();\r\n this.transitionToBegan({ magnitude });\r\n this.transitionToEnded({ magnitude });\r\n }\r\n } else {\r\n // Below threshold — reset consecutive count\r\n this.aboveThresholdCount = 0;\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.aboveThresholdCount = 0;\r\n }\r\n}\r\n","// ─── TiltRecognizer ─────────────────────────────────────────────────────────\r\n// Detects device tilt from accelerometer data by computing pitch and roll\r\n// angles. Triggers when the tilt exceeds a configurable threshold.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, SensorType, SensorData,\r\n IEventBus, TiltRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class TiltRecognizer extends BaseRecognizer {\r\n private tiltThreshold: number;\r\n private cooldownMs: number;\r\n private lastTriggerTime = 0;\r\n\r\n constructor(eventBus: IEventBus, config: TiltRecognizerConfig = {}) {\r\n super('tilt', eventBus, {\r\n priority: config.priority ?? 35,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.tiltThreshold = config.tiltThreshold ?? 30;\r\n this.cooldownMs = config.cooldownMs ?? 500;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Sensor) return;\r\n\r\n const sensorData = inputEvent.data as SensorData;\r\n if (sensorData.type !== SensorType.Accelerometer) return;\r\n\r\n // Use raw (unfiltered) accelerometer data for tilt\r\n // since tilt is a sustained orientation, not a transient impulse\r\n const { x, y, z } = sensorData;\r\n\r\n // Compute pitch and roll from accelerometer\r\n // pitch = rotation around X axis (tilting forward/backward)\r\n // roll = rotation around Y axis (tilting left/right)\r\n const pitch = Math.atan2(y, Math.sqrt(x * x + z * z)) * (180 / Math.PI);\r\n const roll = Math.atan2(x, Math.sqrt(y * y + z * z)) * (180 / Math.PI);\r\n\r\n const maxTilt = Math.max(Math.abs(pitch), Math.abs(roll));\r\n\r\n if (maxTilt >= this.tiltThreshold) {\r\n const now = Date.now();\r\n\r\n if (now - this.lastTriggerTime < this.cooldownMs) {\r\n return;\r\n }\r\n\r\n this.lastTriggerTime = now;\r\n\r\n this.transitionToPossible();\r\n this.transitionToBegan({\r\n tilt: { pitch, roll },\r\n magnitude: maxTilt,\r\n });\r\n this.transitionToEnded({\r\n tilt: { pitch, roll },\r\n magnitude: maxTilt,\r\n });\r\n }\r\n }\r\n}\r\n","// ─── WristFlickRecognizer ───────────────────────────────────────────────────\r\n// Detects wrist flick gestures from gyroscope data.\r\n// A wrist flick is a rapid rotational movement detected via high angular\r\n// velocity on the gyroscope axes.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, SensorType, SensorData,\r\n IEventBus, WristFlickRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class WristFlickRecognizer extends BaseRecognizer {\r\n private angularVelocityThreshold: number;\r\n private cooldownMs: number;\r\n private lastTriggerTime = 0;\r\n\r\n constructor(eventBus: IEventBus, config: WristFlickRecognizerConfig = {}) {\r\n super('wrist-flick', eventBus, {\r\n priority: config.priority ?? 25,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n // Threshold in deg/s — gyroscope typically reports rad/s,\r\n // so we convert threshold to rad/s internally\r\n this.angularVelocityThreshold =\r\n ((config.angularVelocityThreshold ?? 150) * Math.PI) / 180;\r\n this.cooldownMs = config.cooldownMs ?? 800;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Sensor) return;\r\n\r\n const sensorData = inputEvent.data as SensorData;\r\n if (sensorData.type !== SensorType.Gyroscope) return;\r\n\r\n // Use filtered gyroscope data\r\n const { x, y, z } = sample.filtered;\r\n\r\n // Compute angular velocity magnitude (rad/s)\r\n const angularVelocity = Math.sqrt(x * x + y * y + z * z);\r\n\r\n if (angularVelocity >= this.angularVelocityThreshold) {\r\n const now = Date.now();\r\n\r\n if (now - this.lastTriggerTime < this.cooldownMs) {\r\n return;\r\n }\r\n\r\n this.lastTriggerTime = now;\r\n\r\n this.transitionToPossible();\r\n this.transitionToBegan({\r\n magnitude: angularVelocity * (180 / Math.PI), // Convert back to deg/s for metadata\r\n });\r\n this.transitionToEnded({\r\n magnitude: angularVelocity * (180 / Math.PI),\r\n });\r\n }\r\n }\r\n}\r\n","// ─── SequenceRecognizer ─────────────────────────────────────────────────────\r\n// Composes N recognizers in order with inter-step timeouts.\r\n//\r\n// Algorithm:\r\n// 1. Listen for GestureEvent objects on the RecognitionGesture channel\r\n// 2. When the next expected gesture name is detected (in Ended state),\r\n// advance the sequence index\r\n// 3. If the inter-step timeout (default 800ms) is exceeded, reset\r\n// 4. When all steps are matched, emit a 'sequence:{joined-names}' event\r\n//\r\n// Example: sequence: ['tap', 'tap', 'edge-swipe-right']\r\n// → emits 'sequence:tap>tap>edge-swipe-right' on completion\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IEventBus,\r\n EventChannel,\r\n GestureEvent,\r\n RecognizerState,\r\n ProcessedSample,\r\n SequenceRecognizerConfig,\r\n generateId,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\nexport class SequenceRecognizer extends BaseRecognizer {\r\n private sequence: string[];\r\n private timeoutMs: number;\r\n private currentIndex = 0;\r\n private lastStepTime = 0;\r\n private unsubscribe: (() => void) | null = null;\r\n\r\n constructor(eventBus: IEventBus, config: SequenceRecognizerConfig) {\r\n const sequenceName = `sequence:${config.sequence.join('>')}`;\r\n super(sequenceName, eventBus, {\r\n priority: config.priority ?? 1,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.sequence = config.sequence;\r\n this.timeoutMs = config.timeoutMs ?? 800;\r\n\r\n // Subscribe to gesture events to track the sequence\r\n this.subscribeToGestures();\r\n }\r\n\r\n /**\r\n * SequenceRecognizer doesn't use ProcessedSample — it listens\r\n * to GestureEvent objects on the EventBus instead.\r\n */\r\n onProcessedSample(_sample: ProcessedSample): void {\r\n // No-op — sequence recognition is event-driven, not sample-driven\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.currentIndex = 0;\r\n this.lastStepTime = 0;\r\n }\r\n\r\n override dispose(): void {\r\n if (this.unsubscribe) {\r\n this.unsubscribe();\r\n this.unsubscribe = null;\r\n }\r\n super.dispose();\r\n }\r\n\r\n /**\r\n * Subscribe to the RecognitionGesture channel to listen for\r\n * completed gestures and advance the sequence.\r\n */\r\n private subscribeToGestures(): void {\r\n this.unsubscribe = this.eventBus.on(\r\n EventChannel.RecognitionGesture,\r\n (event: GestureEvent) => {\r\n if (!this.enabled) return;\r\n\r\n // Only process ended gestures (completed gesture activations)\r\n if (event.state !== RecognizerState.Ended) return;\r\n\r\n // Don't match our own events to prevent infinite loops\r\n if (event.name.startsWith('sequence:')) return;\r\n\r\n const now = Date.now();\r\n\r\n // Check for timeout (reset if too much time between steps)\r\n if (this.currentIndex > 0 && now - this.lastStepTime > this.timeoutMs) {\r\n this.reset();\r\n }\r\n\r\n // Check if this event matches the expected next step\r\n const expectedName = this.sequence[this.currentIndex];\r\n if (event.name === expectedName) {\r\n this.currentIndex++;\r\n this.lastStepTime = now;\r\n\r\n // Check if sequence is complete\r\n if (this.currentIndex >= this.sequence.length) {\r\n // Sequence completed!\r\n this.transitionToPossible();\r\n this.transitionToBegan({});\r\n this.transitionToEnded({});\r\n this.currentIndex = 0;\r\n this.lastStepTime = 0;\r\n }\r\n }\r\n },\r\n );\r\n }\r\n}\r\n","// ─── SymbolRecognizer ───────────────────────────────────────────────────────\r\n// Basic $1 Unistroke Recognizer implementation for drawn shapes.\r\n// Recognizes drawn gestures by comparing against template point patterns.\r\n//\r\n// $1 Algorithm steps:\r\n// 1. Resample path to N equidistant points (default 64)\r\n// 2. Rotate to indicative angle (align first point → centroid to 0°)\r\n// 3. Scale to fit reference square\r\n// 4. Compare against templates using average point distance\r\n//\r\n// Built-in templates: circle, triangle, check, cross, rectangle\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n ProcessedSample, InputType, TouchType, TouchData,\r\n IEventBus, SymbolRecognizerConfig,\r\n} from '../../core/types';\r\nimport { BaseRecognizer } from '../base/BaseRecognizer';\r\n\r\ninterface Point {\r\n x: number;\r\n y: number;\r\n}\r\n\r\n// ─── Built-in symbol templates ────────────────────────────────────────────\r\n\r\nfunction generateCircleTemplate(n = 64): Point[] {\r\n const points: Point[] = [];\r\n for (let i = 0; i < n; i++) {\r\n const angle = (2 * Math.PI * i) / n;\r\n points.push({ x: Math.cos(angle), y: Math.sin(angle) });\r\n }\r\n return points;\r\n}\r\n\r\nfunction generateTriangleTemplate(): Point[] {\r\n const pts: Point[] = [];\r\n // Three sides of a triangle\r\n const vertices: Point[] = [\r\n { x: 0.5, y: 0 },\r\n { x: 1, y: 1 },\r\n { x: 0, y: 1 },\r\n ];\r\n for (let side = 0; side < 3; side++) {\r\n const from = vertices[side];\r\n const to = vertices[(side + 1) % 3];\r\n for (let i = 0; i < 21; i++) {\r\n const t = i / 20;\r\n pts.push({ x: from.x + (to.x - from.x) * t, y: from.y + (to.y - from.y) * t });\r\n }\r\n }\r\n return pts;\r\n}\r\n\r\nfunction generateCheckTemplate(): Point[] {\r\n // Checkmark: down-right then up-right\r\n const pts: Point[] = [];\r\n for (let i = 0; i <= 20; i++) {\r\n const t = i / 20;\r\n pts.push({ x: t * 0.4, y: 0.3 + t * 0.7 });\r\n }\r\n for (let i = 0; i <= 20; i++) {\r\n const t = i / 20;\r\n pts.push({ x: 0.4 + t * 0.6, y: 1 - t * 1 });\r\n }\r\n return pts;\r\n}\r\n\r\nconst DEFAULT_TEMPLATES: Record<string, Point[]> = {\r\n circle: generateCircleTemplate(),\r\n triangle: generateTriangleTemplate(),\r\n check: generateCheckTemplate(),\r\n};\r\n\r\nexport class SymbolRecognizer extends BaseRecognizer {\r\n private templates: Record<string, Point[]>;\r\n private minConfidence: number;\r\n private currentPath: Point[] = [];\r\n private isDrawing = false;\r\n private resampleCount = 64;\r\n private squareSize = 250;\r\n\r\n constructor(eventBus: IEventBus, config: SymbolRecognizerConfig = {}) {\r\n super('symbol', eventBus, {\r\n priority: config.priority ?? 60,\r\n isExclusive: config.isExclusive ?? false,\r\n enabled: config.enabled,\r\n });\r\n this.templates = config.templates ?? DEFAULT_TEMPLATES;\r\n this.minConfidence = config.minConfidence ?? 0.7;\r\n }\r\n\r\n onProcessedSample(sample: ProcessedSample): void {\r\n if (!this.enabled) return;\r\n\r\n const { inputEvent } = sample;\r\n if (inputEvent.inputType !== InputType.Touch) return;\r\n\r\n const touchData = inputEvent.data as TouchData;\r\n if (touchData.type !== TouchType.Pan) return;\r\n\r\n const velocity = Math.sqrt(\r\n touchData.velocityX ** 2 + touchData.velocityY ** 2,\r\n );\r\n\r\n // Start tracking when finger moves\r\n if (!this.isDrawing) {\r\n this.isDrawing = true;\r\n this.currentPath = [];\r\n this.transitionToPossible();\r\n }\r\n\r\n // Record point\r\n this.currentPath.push({ x: touchData.x, y: touchData.y });\r\n\r\n // Detect end of stroke (velocity drops near zero)\r\n if (velocity < 0.01 && this.currentPath.length > 10) {\r\n this.isDrawing = false;\r\n this.recognize();\r\n }\r\n }\r\n\r\n override reset(): void {\r\n super.reset();\r\n this.currentPath = [];\r\n this.isDrawing = false;\r\n }\r\n\r\n /**\r\n * Run the $1 recognizer against collected path points.\r\n */\r\n private recognize(): void {\r\n if (this.currentPath.length < 10) {\r\n this.transitionToFailed();\r\n return;\r\n }\r\n\r\n // Step 1: Resample\r\n const resampled = this.resample(this.currentPath, this.resampleCount);\r\n\r\n // Step 2: Rotate to indicative angle\r\n const centroid = this.getCentroid(resampled);\r\n const angle = Math.atan2(centroid.y - resampled[0].y, centroid.x - resampled[0].x);\r\n const rotated = this.rotateBy(resampled, -angle);\r\n\r\n // Step 3: Scale to square\r\n const scaled = this.scaleTo(rotated, this.squareSize);\r\n\r\n // Step 4: Translate to origin\r\n const translated = this.translateToOrigin(scaled);\r\n\r\n // Step 5: Match against templates\r\n let bestMatch = '';\r\n let bestScore = 0;\r\n\r\n for (const [name, templatePoints] of Object.entries(this.templates)) {\r\n // Process template the same way\r\n const tResampled = this.resample(templatePoints, this.resampleCount);\r\n const tCentroid = this.getCentroid(tResampled);\r\n const tAngle = Math.atan2(tCentroid.y - tResampled[0].y, tCentroid.x - tResampled[0].x);\r\n const tRotated = this.rotateBy(tResampled, -tAngle);\r\n const tScaled = this.scaleTo(tRotated, this.squareSize);\r\n const tTranslated = this.translateToOrigin(tScaled);\r\n\r\n const distance = this.pathDistance(translated, tTranslated);\r\n const halfDiagonal = 0.5 * Math.sqrt(2) * this.squareSize;\r\n const score = 1 - distance / halfDiagonal;\r\n\r\n if (score > bestScore) {\r\n bestScore = score;\r\n bestMatch = name;\r\n }\r\n }\r\n\r\n if (bestScore >= this.minConfidence) {\r\n this.transitionToBegan({\r\n symbol: bestMatch,\r\n confidence: bestScore,\r\n });\r\n this.transitionToEnded({\r\n symbol: bestMatch,\r\n confidence: bestScore,\r\n });\r\n } else {\r\n this.transitionToFailed();\r\n }\r\n\r\n this.currentPath = [];\r\n }\r\n\r\n // ─── $1 Unistroke helper functions ────────────────────────────────\r\n\r\n private resample(points: Point[], n: number): Point[] {\r\n const totalLength = this.pathLength(points);\r\n const interval = totalLength / (n - 1);\r\n const resampled: Point[] = [points[0]];\r\n let accumulated = 0;\r\n\r\n for (let i = 1; i < points.length; i++) {\r\n const d = this.distance(points[i - 1], points[i]);\r\n\r\n if (accumulated + d >= interval) {\r\n const t = (interval - accumulated) / d;\r\n const newPoint: Point = {\r\n x: points[i - 1].x + t * (points[i].x - points[i - 1].x),\r\n y: points[i - 1].y + t * (points[i].y - points[i - 1].y),\r\n };\r\n resampled.push(newPoint);\r\n points.splice(i, 0, newPoint);\r\n accumulated = 0;\r\n } else {\r\n accumulated += d;\r\n }\r\n }\r\n\r\n // Pad to n points if needed\r\n while (resampled.length < n) {\r\n resampled.push(points[points.length - 1]);\r\n }\r\n\r\n return resampled.slice(0, n);\r\n }\r\n\r\n private getCentroid(points: Point[]): Point {\r\n let sumX = 0, sumY = 0;\r\n for (const p of points) {\r\n sumX += p.x;\r\n sumY += p.y;\r\n }\r\n return { x: sumX / points.length, y: sumY / points.length };\r\n }\r\n\r\n private rotateBy(points: Point[], angle: number): Point[] {\r\n const centroid = this.getCentroid(points);\r\n const cos = Math.cos(angle);\r\n const sin = Math.sin(angle);\r\n return points.map((p) => ({\r\n x: (p.x - centroid.x) * cos - (p.y - centroid.y) * sin + centroid.x,\r\n y: (p.x - centroid.x) * sin + (p.y - centroid.y) * cos + centroid.y,\r\n }));\r\n }\r\n\r\n private scaleTo(points: Point[], size: number): Point[] {\r\n const bb = this.boundingBox(points);\r\n const w = bb.maxX - bb.minX;\r\n const h = bb.maxY - bb.minY;\r\n if (w === 0 || h === 0) return points;\r\n return points.map((p) => ({\r\n x: (p.x * size) / w,\r\n y: (p.y * size) / h,\r\n }));\r\n }\r\n\r\n private translateToOrigin(points: Point[]): Point[] {\r\n const centroid = this.getCentroid(points);\r\n return points.map((p) => ({\r\n x: p.x - centroid.x,\r\n y: p.y - centroid.y,\r\n }));\r\n }\r\n\r\n private boundingBox(points: Point[]) {\r\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\r\n for (const p of points) {\r\n minX = Math.min(minX, p.x);\r\n minY = Math.min(minY, p.y);\r\n maxX = Math.max(maxX, p.x);\r\n maxY = Math.max(maxY, p.y);\r\n }\r\n return { minX, minY, maxX, maxY };\r\n }\r\n\r\n private pathDistance(a: Point[], b: Point[]): number {\r\n const len = Math.min(a.length, b.length);\r\n let total = 0;\r\n for (let i = 0; i < len; i++) {\r\n total += this.distance(a[i], b[i]);\r\n }\r\n return total / len;\r\n }\r\n\r\n private pathLength(points: Point[]): number {\r\n let total = 0;\r\n for (let i = 1; i < points.length; i++) {\r\n total += this.distance(points[i - 1], points[i]);\r\n }\r\n return total;\r\n }\r\n\r\n private distance(a: Point, b: Point): number {\r\n return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);\r\n }\r\n}\r\n","// ─── GesturePriorityQueue ───────────────────────────────────────────────────\r\n// Min-heap sorted by priority value (lower = higher priority).\r\n// Used by ConflictResolver to process gestures in priority order.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { GestureEvent } from '../core/types';\r\n\r\n/**\r\n * Min-heap priority queue for GestureEvents.\r\n * Lower priority number = higher priority = processed first.\r\n *\r\n * Operations:\r\n * - insert: O(log n)\r\n * - extractMin: O(log n)\r\n * - peek: O(1)\r\n */\r\nexport class GesturePriorityQueue {\r\n private heap: GestureEvent[] = [];\r\n\r\n get size(): number {\r\n return this.heap.length;\r\n }\r\n\r\n isEmpty(): boolean {\r\n return this.heap.length === 0;\r\n }\r\n\r\n /** Insert a gesture event into the queue. O(log n). */\r\n insert(event: GestureEvent): void {\r\n this.heap.push(event);\r\n this.bubbleUp(this.heap.length - 1);\r\n }\r\n\r\n /** Extract and return the highest-priority (lowest priority number) event. O(log n). */\r\n extractMin(): GestureEvent | null {\r\n if (this.heap.length === 0) return null;\r\n if (this.heap.length === 1) return this.heap.pop()!;\r\n\r\n const min = this.heap[0];\r\n this.heap[0] = this.heap.pop()!;\r\n this.bubbleDown(0);\r\n return min;\r\n }\r\n\r\n /** Peek at the highest-priority event without removing it. O(1). */\r\n peek(): GestureEvent | null {\r\n return this.heap.length > 0 ? this.heap[0] : null;\r\n }\r\n\r\n /** Remove all events from the queue. */\r\n clear(): void {\r\n this.heap = [];\r\n }\r\n\r\n /** Drain the queue, returning all events in priority order. */\r\n drainAll(): GestureEvent[] {\r\n const result: GestureEvent[] = [];\r\n while (!this.isEmpty()) {\r\n result.push(this.extractMin()!);\r\n }\r\n return result;\r\n }\r\n\r\n private bubbleUp(index: number): void {\r\n while (index > 0) {\r\n const parentIndex = Math.floor((index - 1) / 2);\r\n if (this.heap[parentIndex].priority <= this.heap[index].priority) break;\r\n [this.heap[parentIndex], this.heap[index]] = [this.heap[index], this.heap[parentIndex]];\r\n index = parentIndex;\r\n }\r\n }\r\n\r\n private bubbleDown(index: number): void {\r\n const length = this.heap.length;\r\n while (true) {\r\n let smallest = index;\r\n const left = 2 * index + 1;\r\n const right = 2 * index + 2;\r\n\r\n if (left < length && this.heap[left].priority < this.heap[smallest].priority) {\r\n smallest = left;\r\n }\r\n if (right < length && this.heap[right].priority < this.heap[smallest].priority) {\r\n smallest = right;\r\n }\r\n\r\n if (smallest === index) break;\r\n [this.heap[smallest], this.heap[index]] = [this.heap[index], this.heap[smallest]];\r\n index = smallest;\r\n }\r\n }\r\n}\r\n","// ─── LockManager ────────────────────────────────────────────────────────────\r\n// Manages exclusive gesture locks. When an exclusive gesture activates,\r\n// it acquires a lock that blocks competing gestures at equal or lower priority.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * LockManager tracks which gestures currently hold exclusive locks.\r\n *\r\n * When an exclusive gesture fires:\r\n * 1. It calls acquireLock(name, priority)\r\n * 2. The ConflictResolver checks isLocked(name, priority) before allowing\r\n * other gestures to pass through\r\n * 3. Once the gesture ends, releaseLock(name) frees the slot\r\n *\r\n * Multiple locks can coexist (e.g., a high-priority lock + unrelated gestures).\r\n * A gesture is blocked if ANY active lock has higher or equal priority.\r\n */\r\nexport class LockManager {\r\n /** Active locks: gestureName → priority */\r\n private locks = new Map<string, number>();\r\n\r\n /**\r\n * Acquire an exclusive lock for a gesture.\r\n *\r\n * @param gestureName - The gesture acquiring the lock\r\n * @param priority - The priority level of the lock (lower = higher priority)\r\n * @returns true if the lock was acquired\r\n */\r\n acquireLock(gestureName: string, priority: number): boolean {\r\n this.locks.set(gestureName, priority);\r\n return true;\r\n }\r\n\r\n /**\r\n * Release the lock held by a gesture.\r\n */\r\n releaseLock(gestureName: string): void {\r\n this.locks.delete(gestureName);\r\n }\r\n\r\n /**\r\n * Check if a gesture with the given priority is blocked by any active lock.\r\n * A gesture is blocked if an active lock has higher or equal priority\r\n * (lower or equal priority number) and is not the same gesture.\r\n *\r\n * @param gestureName - The gesture to check\r\n * @param priority - The priority of the gesture to check\r\n * @returns true if the gesture is blocked\r\n */\r\n isLocked(gestureName: string, priority: number): boolean {\r\n for (const [lockName, lockPriority] of this.locks) {\r\n if (lockName !== gestureName && lockPriority <= priority) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Check if a specific gesture holds a lock.\r\n */\r\n hasLock(gestureName: string): boolean {\r\n return this.locks.has(gestureName);\r\n }\r\n\r\n /**\r\n * Clear all locks. Called during engine reset.\r\n */\r\n clearAll(): void {\r\n this.locks.clear();\r\n }\r\n\r\n /**\r\n * Get the number of active locks.\r\n */\r\n get activeLockCount(): number {\r\n return this.locks.size;\r\n }\r\n}\r\n","// ─── ConflictResolver ───────────────────────────────────────────────────────\r\n// Receives all GestureEvent objects from the RecognitionGesture channel,\r\n// applies priority ordering and exclusive/simultaneous rules, and emits\r\n// resolved events on the ConflictResolved channel.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IEventBus,\r\n EventChannel,\r\n GestureEvent,\r\n RecognizerState,\r\n} from '../core/types';\r\nimport { GesturePriorityQueue } from './GesturePriorityQueue';\r\nimport { LockManager } from './LockManager';\r\n\r\n/**\r\n * ConflictResolver processes gesture events through priority ordering\r\n * and exclusive locking to determine which gestures should be dispatched.\r\n *\r\n * Rules:\r\n * 1. Events are queued and processed in priority order (lower = first)\r\n * 2. If an exclusive gesture fires (Began state), it acquires a lock\r\n * 3. Locked gestures of equal or lower priority are blocked\r\n * 4. When an exclusive gesture ends, its lock is released\r\n * 5. Non-exclusive gestures pass through if not blocked\r\n */\r\nexport class ConflictResolver {\r\n private priorityQueue: GesturePriorityQueue;\r\n private lockManager: LockManager;\r\n private eventBus: IEventBus;\r\n private unsubscribe: (() => void) | null = null;\r\n\r\n // Buffer for batching events within a single tick\r\n private pendingEvents: GestureEvent[] = [];\r\n private processingScheduled = false;\r\n\r\n constructor(eventBus: IEventBus) {\r\n this.eventBus = eventBus;\r\n this.priorityQueue = new GesturePriorityQueue();\r\n this.lockManager = new LockManager();\r\n }\r\n\r\n /**\r\n * Start listening for gesture events and resolving conflicts.\r\n */\r\n start(): void {\r\n this.unsubscribe = this.eventBus.on(\r\n EventChannel.RecognitionGesture,\r\n (event: GestureEvent) => {\r\n this.pendingEvents.push(event);\r\n this.scheduleProcessing();\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Stop listening and clear all state.\r\n */\r\n stop(): void {\r\n if (this.unsubscribe) {\r\n this.unsubscribe();\r\n this.unsubscribe = null;\r\n }\r\n this.priorityQueue.clear();\r\n this.lockManager.clearAll();\r\n this.pendingEvents = [];\r\n }\r\n\r\n /**\r\n * Schedule conflict resolution for the next microtask.\r\n * This batches events that arrive in the same tick.\r\n */\r\n private scheduleProcessing(): void {\r\n if (this.processingScheduled) return;\r\n this.processingScheduled = true;\r\n\r\n // Use queueMicrotask for batching events within a single frame\r\n Promise.resolve().then(() => {\r\n this.processingScheduled = false;\r\n this.processEvents();\r\n });\r\n }\r\n\r\n /**\r\n * Process all pending events through priority queue and lock rules.\r\n */\r\n private processEvents(): void {\r\n // Step 1: Insert all pending events into the priority queue\r\n for (const event of this.pendingEvents) {\r\n this.priorityQueue.insert(event);\r\n }\r\n this.pendingEvents = [];\r\n\r\n // Step 2: Drain the queue in priority order and apply conflict rules\r\n const sortedEvents = this.priorityQueue.drainAll();\r\n\r\n for (const event of sortedEvents) {\r\n // Handle lock lifecycle for exclusive gestures\r\n if (event.isExclusive) {\r\n if (event.state === RecognizerState.Began) {\r\n this.lockManager.acquireLock(event.name, event.priority);\r\n } else if (\r\n event.state === RecognizerState.Ended ||\r\n event.state === RecognizerState.Cancelled ||\r\n event.state === RecognizerState.Failed\r\n ) {\r\n this.lockManager.releaseLock(event.name);\r\n }\r\n }\r\n\r\n // Check if this gesture is blocked by a higher-priority exclusive lock\r\n if (this.lockManager.isLocked(event.name, event.priority)) {\r\n // Blocked — skip this event\r\n continue;\r\n }\r\n\r\n // Event passes conflict resolution → emit on ConflictResolved channel\r\n this.eventBus.emit(EventChannel.ConflictResolved, event);\r\n }\r\n }\r\n\r\n /** Expose lock manager for testing */\r\n getLockManager(): LockManager {\r\n return this.lockManager;\r\n }\r\n}\r\n","// ─── ActionDispatcher ───────────────────────────────────────────────────────\r\n// Maps gesture names to arrays of IGestureAction instances.\r\n// Dispatches resolved gesture events to all registered actions.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport {\r\n IEventBus,\r\n EventChannel,\r\n GestureEvent,\r\n IGestureAction,\r\n} from '../core/types';\r\n\r\n/**\r\n * ActionDispatcher receives resolved gesture events and dispatches them\r\n * to registered action handlers.\r\n *\r\n * Actions are registered by gesture name. Multiple actions can be registered\r\n * for a single gesture (they all execute in registration order).\r\n */\r\nexport class ActionDispatcher {\r\n private actionMap = new Map<string, IGestureAction[]>();\r\n private eventBus: IEventBus;\r\n private unsubscribe: (() => void) | null = null;\r\n\r\n constructor(eventBus: IEventBus) {\r\n this.eventBus = eventBus;\r\n }\r\n\r\n /**\r\n * Start listening for resolved gesture events.\r\n */\r\n start(): void {\r\n this.unsubscribe = this.eventBus.on(\r\n EventChannel.ConflictResolved,\r\n (event: GestureEvent) => {\r\n this.dispatch(event);\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Stop listening.\r\n */\r\n stop(): void {\r\n if (this.unsubscribe) {\r\n this.unsubscribe();\r\n this.unsubscribe = null;\r\n }\r\n }\r\n\r\n /**\r\n * Register an action for a gesture name.\r\n */\r\n registerAction(gestureName: string, action: IGestureAction): void {\r\n if (!this.actionMap.has(gestureName)) {\r\n this.actionMap.set(gestureName, []);\r\n }\r\n this.actionMap.get(gestureName)!.push(action);\r\n }\r\n\r\n /**\r\n * Unregister a specific action from a gesture.\r\n */\r\n unregisterAction(gestureName: string, actionId: string): void {\r\n const actions = this.actionMap.get(gestureName);\r\n if (actions) {\r\n const filtered = actions.filter((a) => a.actionId !== actionId);\r\n if (filtered.length > 0) {\r\n this.actionMap.set(gestureName, filtered);\r\n } else {\r\n this.actionMap.delete(gestureName);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all registered actions.\r\n */\r\n clearActions(): void {\r\n this.actionMap.clear();\r\n }\r\n\r\n /**\r\n * Dispatch a gesture event to all matching registered actions.\r\n */\r\n private dispatch(event: GestureEvent): void {\r\n const actions = this.actionMap.get(event.name);\r\n if (!actions || actions.length === 0) return;\r\n\r\n for (const action of actions) {\r\n try {\r\n action.execute(event);\r\n } catch (error) {\r\n console.warn(\r\n `[ActionDispatcher] Error executing action ${action.actionId} for gesture ${event.name}:`,\r\n error,\r\n );\r\n }\r\n }\r\n\r\n // Emit on ActionDispatched channel for feedback layer\r\n this.eventBus.emit(EventChannel.ActionDispatched, event);\r\n }\r\n}\r\n","// ─── NavigationAction ───────────────────────────────────────────────────────\r\n// Triggers navigation actions (go back, push screen, etc.)\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IGestureAction, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * NavigationAction triggers navigation when a gesture is recognized.\r\n * Accepts a callback that receives the gesture event and can perform\r\n * any navigation logic (e.g., navigation.goBack()).\r\n */\r\nexport class NavigationAction implements IGestureAction {\r\n readonly actionId: string;\r\n private callback: (event: GestureEvent) => void;\r\n\r\n constructor(actionId: string, callback: (event: GestureEvent) => void) {\r\n this.actionId = actionId;\r\n this.callback = callback;\r\n }\r\n\r\n execute(event: GestureEvent): void {\r\n this.callback(event);\r\n }\r\n}\r\n","// ─── UITransformAction ──────────────────────────────────────────────────────\r\n// Applies Reanimated shared value transformations (scale, translate, rotate)\r\n// in response to gesture events.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IGestureAction, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * UITransformAction applies Reanimated transformations when a gesture fires.\r\n *\r\n * Accepts a callback where you can update shared values:\r\n * ```typescript\r\n * new UITransformAction('scale-on-pinch', (event) => {\r\n * scale.value = withSpring(event.metadata.scale ?? 1);\r\n * });\r\n * ```\r\n */\r\nexport class UITransformAction implements IGestureAction {\r\n readonly actionId: string;\r\n private transform: (event: GestureEvent) => void;\r\n\r\n constructor(actionId: string, transform: (event: GestureEvent) => void) {\r\n this.actionId = actionId;\r\n this.transform = transform;\r\n }\r\n\r\n execute(event: GestureEvent): void {\r\n this.transform(event);\r\n }\r\n}\r\n","// ─── SystemAction ───────────────────────────────────────────────────────────\r\n// System-level effects (e.g., toggle fullscreen, change orientation).\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IGestureAction, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * SystemAction performs system-level operations when a gesture fires.\r\n */\r\nexport class SystemAction implements IGestureAction {\r\n readonly actionId: string;\r\n private callback: (event: GestureEvent) => void;\r\n\r\n constructor(actionId: string, callback: (event: GestureEvent) => void) {\r\n this.actionId = actionId;\r\n this.callback = callback;\r\n }\r\n\r\n execute(event: GestureEvent): void {\r\n this.callback(event);\r\n }\r\n}\r\n","// ─── CustomAction ───────────────────────────────────────────────────────────\r\n// User-defined callback action. The most flexible action type — accepts\r\n// any callback to execute when a gesture is recognized.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IGestureAction, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * CustomAction wraps a user-defined callback.\r\n *\r\n * @example\r\n * ```typescript\r\n * const logAction = new CustomAction('log-shake', (event) => {\r\n * analytics.track('shake_gesture', { magnitude: event.metadata.magnitude });\r\n * });\r\n * ```\r\n */\r\nexport class CustomAction implements IGestureAction {\r\n readonly actionId: string;\r\n private callback: (event: GestureEvent) => void;\r\n\r\n constructor(actionId: string, callback: (event: GestureEvent) => void) {\r\n this.actionId = actionId;\r\n this.callback = callback;\r\n }\r\n\r\n execute(event: GestureEvent): void {\r\n this.callback(event);\r\n }\r\n}\r\n","// ─── HapticFeedback ─────────────────────────────────────────────────────────\r\n// Uses expo-haptics for impact/notification/selection haptics.\r\n// Falls back to react-native Vibration API if expo-haptics is unavailable.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IFeedbackProvider, GestureEvent, RecognizerState } from '../core/types';\r\nimport * as Haptics from 'expo-haptics';\r\nimport { Vibration } from 'react-native';\r\n\r\n/**\r\n * HapticFeedback triggers haptic responses when gestures are recognized.\r\n *\r\n * Supports three haptic types (via expo-haptics):\r\n * - Impact: for gesture activations (tap, swipe)\r\n * - Notification: for important events (shake, sequence complete)\r\n * - Selection: for continuous feedback (pan, rotation)\r\n *\r\n * Falls back to react-native Vibration API when expo-haptics is not installed.\r\n */\r\nexport class HapticFeedback implements IFeedbackProvider {\r\n private _isSupported = false;\r\n private useVibrationFallback = false;\r\n private enabled: boolean;\r\n\r\n constructor(enabled = true) {\r\n this.enabled = enabled;\r\n\r\n if (Haptics) {\r\n this._isSupported = true;\r\n } else if (Vibration) {\r\n this._isSupported = true;\r\n this.useVibrationFallback = true;\r\n }\r\n }\r\n\r\n get isSupported(): boolean {\r\n return this._isSupported && this.enabled;\r\n }\r\n\r\n trigger(event: GestureEvent): void {\r\n if (!this.isSupported) return;\r\n\r\n // Only trigger on Began and Ended states to avoid spam\r\n if (\r\n event.state !== RecognizerState.Began &&\r\n event.state !== RecognizerState.Ended\r\n ) {\r\n return;\r\n }\r\n\r\n if (this.useVibrationFallback) {\r\n Vibration?.vibrate(50);\r\n return;\r\n }\r\n\r\n // Choose haptic type based on gesture\r\n const gestureName = event.name;\r\n\r\n if (gestureName.startsWith('sequence:') || gestureName === 'shake') {\r\n // Notification haptic for important events\r\n Haptics?.notificationAsync?.(Haptics.NotificationFeedbackType?.Success);\r\n } else if (gestureName === 'tap' || gestureName === 'double-tap') {\r\n // Light impact for taps\r\n Haptics?.impactAsync?.(Haptics.ImpactFeedbackStyle?.Light);\r\n } else if (gestureName.startsWith('edge-swipe') || gestureName.startsWith('corner')) {\r\n // Medium impact for spatial gestures\r\n Haptics?.impactAsync?.(Haptics.ImpactFeedbackStyle?.Medium);\r\n } else {\r\n // Selection for continuous gestures\r\n Haptics?.selectionAsync?.();\r\n }\r\n }\r\n\r\n setEnabled(enabled: boolean): void {\r\n this.enabled = enabled;\r\n }\r\n}\r\n","// ─── VisualFeedback ─────────────────────────────────────────────────────────\r\n// Triggers visual feedback via callbacks when gestures are recognized.\r\n// Designed to work with Reanimated shared value animations.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IFeedbackProvider, GestureEvent } from '../core/types';\r\n\r\n/**\r\n * VisualFeedback invokes registered callbacks to trigger visual animations\r\n * when gestures are recognized.\r\n *\r\n * Typical usage: update Reanimated shared values in the callback.\r\n *\r\n * @example\r\n * ```typescript\r\n * const visual = new VisualFeedback((event) => {\r\n * opacity.value = withTiming(0.5, { duration: 100 });\r\n * scale.value = withSpring(0.95);\r\n * });\r\n * ```\r\n */\r\nexport class VisualFeedback implements IFeedbackProvider {\r\n private _isSupported = true;\r\n private callback: ((event: GestureEvent) => void) | null;\r\n\r\n constructor(callback?: (event: GestureEvent) => void) {\r\n this.callback = callback ?? null;\r\n }\r\n\r\n get isSupported(): boolean {\r\n return this._isSupported;\r\n }\r\n\r\n trigger(event: GestureEvent): void {\r\n if (!this._isSupported || !this.callback) return;\r\n this.callback(event);\r\n }\r\n\r\n /**\r\n * Update the visual feedback callback at runtime.\r\n */\r\n setCallback(callback: (event: GestureEvent) => void): void {\r\n this.callback = callback;\r\n }\r\n}\r\n","// ─── AccessibilityFeedback ──────────────────────────────────────────────────\r\n// Posts accessibility announcements when gestures are recognized.\r\n// Uses AccessibilityInfo.announceForAccessibility() from React Native.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { IFeedbackProvider, GestureEvent, RecognizerState } from '../core/types';\r\nimport { AccessibilityInfo } from 'react-native';\r\n\r\n/**\r\n * AccessibilityFeedback announces gesture events for screen reader users.\r\n *\r\n * Automatically generates human-readable announcements based on gesture names.\r\n * Custom announcement builders can be provided via setAnnouncementBuilder().\r\n */\r\nexport class AccessibilityFeedback implements IFeedbackProvider {\r\n private _isSupported = false;\r\n private announcementBuilder: ((event: GestureEvent) => string) | null = null;\r\n\r\n constructor() {\r\n this._isSupported = !!AccessibilityInfo?.announceForAccessibility;\r\n }\r\n\r\n get isSupported(): boolean {\r\n return this._isSupported;\r\n }\r\n\r\n trigger(event: GestureEvent): void {\r\n if (!this._isSupported) return;\r\n\r\n // Only announce on Ended state to avoid spam\r\n if (event.state !== RecognizerState.Ended) return;\r\n\r\n const announcement = this.announcementBuilder\r\n ? this.announcementBuilder(event)\r\n : this.defaultAnnouncement(event);\r\n\r\n AccessibilityInfo.announceForAccessibility(announcement);\r\n }\r\n\r\n /**\r\n * Set a custom function to build announcement strings.\r\n */\r\n setAnnouncementBuilder(builder: (event: GestureEvent) => string): void {\r\n this.announcementBuilder = builder;\r\n }\r\n\r\n /**\r\n * Generate a default human-readable announcement based on gesture name.\r\n */\r\n private defaultAnnouncement(event: GestureEvent): string {\r\n const name = event.name\r\n .replace(/-/g, ' ')\r\n .replace(/:/g, ' ')\r\n .replace(/>/g, ' then ');\r\n\r\n return `Gesture detected: ${name}`;\r\n }\r\n}\r\n","// ─── GestureEngine ──────────────────────────────────────────────────────────\r\n// Main orchestrator that wires all 6 layers together via the EventBus.\r\n//\r\n// Responsibilities:\r\n// 1. Creates and owns the EventBus\r\n// 2. Instantiates providers, processors, and conflict resolver\r\n// 3. Wires raw input → processing → recognition → conflict → action → feedback\r\n// 4. Provides a clean API: start(), stop(), registerRecognizer(), etc.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { EventBus } from './core/EventBus';\r\nimport {\r\n IEventBus,\r\n EventChannel,\r\n InputEvent,\r\n InputType,\r\n ProcessedSample,\r\n GestureEvent,\r\n GestureEngineConfig,\r\n IRecognizer,\r\n IGestureAction,\r\n IFeedbackProvider,\r\n TouchData,\r\n SensorData,\r\n CardinalDirection,\r\n generateId,\r\n} from './core/types';\r\nimport { TouchInputProvider } from './input/TouchInputProvider';\r\nimport { SensorInputProvider } from './input/SensorInputProvider';\r\nimport { NoiseFilter } from './processing/NoiseFilter';\r\nimport { VelocityCalculator } from './processing/VelocityCalculator';\r\nimport { AngleDetector } from './processing/AngleDetector';\r\nimport { ThresholdNormalizer } from './processing/ThresholdNormalizer';\r\nimport { StreamBuffer } from './processing/StreamBuffer';\r\nimport { ConflictResolver } from './conflict/ConflictResolver';\r\nimport { ActionDispatcher } from './actions/ActionDispatcher';\r\n\r\n/**\r\n * GestureEngine is the main orchestrator for the gesture pipeline.\r\n *\r\n * It connects all 6 layers:\r\n * Input → Processing → Recognition → Conflict → Action → Feedback\r\n *\r\n * All communication flows through the typed EventBus.\r\n */\r\nexport class GestureEngine {\r\n // ─── Core ──────────────────────────────────────────────────────────\r\n readonly eventBus: IEventBus;\r\n private config: Required<GestureEngineConfig>;\r\n\r\n // ─── Layer 1: Input ────────────────────────────────────────────────\r\n readonly touchInput: TouchInputProvider;\r\n readonly sensorInput: SensorInputProvider;\r\n\r\n // ─── Layer 2: Processing ───────────────────────────────────────────\r\n private noiseFilter: NoiseFilter;\r\n private sensorNoiseFilter: NoiseFilter;\r\n private velocityCalc: VelocityCalculator;\r\n private angleDetector: AngleDetector;\r\n private normalizer: ThresholdNormalizer;\r\n private streamBuffer: StreamBuffer;\r\n\r\n // ─── Layer 3: Recognition ──────────────────────────────────────────\r\n private recognizers: IRecognizer[] = [];\r\n\r\n // ─── Layer 4: Conflict Resolution ─────────────────────────────────\r\n private conflictResolver: ConflictResolver;\r\n\r\n // ─── Layer 5: Actions ──────────────────────────────────────────────\r\n private actionDispatcher: ActionDispatcher;\r\n\r\n // ─── Layer 6: Feedback ─────────────────────────────────────────────\r\n private feedbackProviders: IFeedbackProvider[] = [];\r\n\r\n // ─── State ─────────────────────────────────────────────────────────\r\n private _isRunning = false;\r\n private inputUnsubscribe: (() => void) | null = null;\r\n private feedbackUnsubscribe: (() => void) | null = null;\r\n\r\n constructor(config: GestureEngineConfig = {}) {\r\n // Merge with defaults\r\n this.config = {\r\n sensorInterval: Math.max(16, config.sensorInterval ?? 100),\r\n hapticEnabled: config.hapticEnabled ?? true,\r\n debug: config.debug ?? false,\r\n screenWidth: config.screenWidth ?? 400,\r\n screenHeight: config.screenHeight ?? 800,\r\n };\r\n\r\n // ─── Initialize core ──────────────────────────────────────────────\r\n this.eventBus = new EventBus();\r\n\r\n // ─── Initialize Layer 1: Input providers ──────────────────────────\r\n this.touchInput = new TouchInputProvider(this.eventBus);\r\n this.sensorInput = new SensorInputProvider(\r\n this.eventBus,\r\n this.config.sensorInterval,\r\n );\r\n\r\n // ─── Initialize Layer 2: Processing ───────────────────────────────\r\n this.noiseFilter = new NoiseFilter(0.8);\r\n this.sensorNoiseFilter = new NoiseFilter(0.2); // Lower alpha for high-pass on sensors\r\n this.velocityCalc = new VelocityCalculator();\r\n this.angleDetector = new AngleDetector();\r\n this.normalizer = new ThresholdNormalizer(0, 10);\r\n this.streamBuffer = new StreamBuffer(400, 64);\r\n\r\n // ─── Initialize Layer 4: Conflict Resolution ──────────────────────\r\n this.conflictResolver = new ConflictResolver(this.eventBus);\r\n\r\n // ─── Initialize Layer 5: Action Dispatcher ────────────────────────\r\n this.actionDispatcher = new ActionDispatcher(this.eventBus);\r\n }\r\n\r\n // ═══════════════════════════════════════════════════════════════════════\r\n // Public API\r\n // ═══════════════════════════════════════════════════════════════════════\r\n\r\n get isRunning(): boolean {\r\n return this._isRunning;\r\n }\r\n\r\n /**\r\n * Start the gesture engine. Activates all providers and wires the pipeline.\r\n */\r\n start(): void {\r\n if (this._isRunning) return;\r\n this._isRunning = true;\r\n\r\n // Wire Layer 1 → Layer 2 → Layer 3: raw input → processing → recognition\r\n this.inputUnsubscribe = this.eventBus.on(\r\n EventChannel.InputRaw,\r\n (event: InputEvent) => this.processInput(event),\r\n );\r\n\r\n // Wire Layer 6: feedback on action dispatch\r\n this.feedbackUnsubscribe = this.eventBus.on(\r\n EventChannel.ActionDispatched,\r\n (event: GestureEvent) => {\r\n for (const provider of this.feedbackProviders) {\r\n if (provider.isSupported) {\r\n provider.trigger(event);\r\n }\r\n }\r\n },\r\n );\r\n\r\n // Start all infrastructure\r\n this.touchInput.start();\r\n this.sensorInput.start();\r\n this.conflictResolver.start();\r\n this.actionDispatcher.start();\r\n\r\n if (this.config.debug) {\r\n console.log('[GestureEngine] Started with config:', this.config);\r\n }\r\n }\r\n\r\n /**\r\n * Stop the gesture engine. Cleans up all subscriptions and providers.\r\n */\r\n stop(): void {\r\n if (!this._isRunning) return;\r\n this._isRunning = false;\r\n\r\n // Stop providers\r\n this.touchInput.stop();\r\n this.sensorInput.stop();\r\n this.conflictResolver.stop();\r\n this.actionDispatcher.stop();\r\n\r\n // Unsubscribe pipeline wiring\r\n this.inputUnsubscribe?.();\r\n this.feedbackUnsubscribe?.();\r\n this.inputUnsubscribe = null;\r\n this.feedbackUnsubscribe = null;\r\n\r\n // Reset processors\r\n this.noiseFilter.reset();\r\n this.sensorNoiseFilter.reset();\r\n this.velocityCalc.reset();\r\n this.streamBuffer.clear();\r\n\r\n // Reset recognizers\r\n for (const recognizer of this.recognizers) {\r\n recognizer.reset();\r\n }\r\n\r\n if (this.config.debug) {\r\n console.log('[GestureEngine] Stopped');\r\n }\r\n }\r\n\r\n /**\r\n * Register a gesture recognizer with the engine.\r\n */\r\n registerRecognizer(recognizer: IRecognizer): void {\r\n this.recognizers.push(recognizer);\r\n if (this.config.debug) {\r\n console.log(`[GestureEngine] Registered recognizer: ${recognizer.name}`);\r\n }\r\n }\r\n\r\n /**\r\n * Unregister a recognizer by its ID.\r\n */\r\n unregisterRecognizer(recognizerId: string): void {\r\n const index = this.recognizers.findIndex((r) => r.id === recognizerId);\r\n if (index !== -1) {\r\n const [removed] = this.recognizers.splice(index, 1);\r\n removed.dispose();\r\n }\r\n }\r\n\r\n /**\r\n * Register an action for a gesture name.\r\n */\r\n registerAction(gestureName: string, action: IGestureAction): void {\r\n this.actionDispatcher.registerAction(gestureName, action);\r\n }\r\n\r\n /**\r\n * Register a feedback provider.\r\n */\r\n registerFeedback(provider: IFeedbackProvider): void {\r\n this.feedbackProviders.push(provider);\r\n }\r\n\r\n /**\r\n * Get all registered recognizers.\r\n */\r\n getRecognizers(): IRecognizer[] {\r\n return [...this.recognizers];\r\n }\r\n\r\n /**\r\n * Dispose the engine and clean up all resources.\r\n */\r\n dispose(): void {\r\n this.stop();\r\n for (const recognizer of this.recognizers) {\r\n recognizer.dispose();\r\n }\r\n this.recognizers = [];\r\n this.feedbackProviders = [];\r\n this.actionDispatcher.clearActions();\r\n this.eventBus.clear();\r\n }\r\n\r\n // ═══════════════════════════════════════════════════════════════════════\r\n // Pipeline: Input → Processing → Recognition\r\n // ═══════════════════════════════════════════════════════════════════════\r\n\r\n /**\r\n * Process a raw input event through Layer 2 (processing) and feed\r\n * the resulting ProcessedSample into Layer 3 (recognition).\r\n */\r\n private processInput(event: InputEvent): void {\r\n let filtered: { x: number; y: number; z: number };\r\n let velocityResult: { velocityX: number; velocityY: number; velocity: number };\r\n\r\n if (event.inputType === InputType.Touch) {\r\n const touch = event.data as TouchData;\r\n // Apply low-pass filter to touch coordinates\r\n filtered = this.noiseFilter.lowPass(touch.x, touch.y, 0);\r\n velocityResult = this.velocityCalc.calculate(\r\n touch.x,\r\n touch.y,\r\n event.timestamp,\r\n );\r\n } else if (event.inputType === InputType.Sensor) {\r\n const sensor = event.data as SensorData;\r\n // Apply high-pass filter to sensor data (remove gravity)\r\n filtered = this.sensorNoiseFilter.highPass(sensor.x, sensor.y, sensor.z);\r\n const magnitude = Math.sqrt(\r\n filtered.x ** 2 + filtered.y ** 2 + filtered.z ** 2,\r\n );\r\n velocityResult = { velocityX: filtered.x, velocityY: filtered.y, velocity: magnitude };\r\n } else {\r\n // Hardware/Camera — pass through\r\n filtered = { x: 0, y: 0, z: 0 };\r\n velocityResult = { velocityX: 0, velocityY: 0, velocity: 0 };\r\n }\r\n\r\n // Compute angle\r\n const angle = this.angleDetector.calculate(\r\n velocityResult.velocityX,\r\n velocityResult.velocityY,\r\n );\r\n\r\n // Normalize magnitude\r\n const normalizedMagnitude = this.normalizer.normalize(velocityResult.velocity);\r\n\r\n // Build processed sample\r\n const sample: ProcessedSample = {\r\n inputEvent: event,\r\n velocity: velocityResult.velocity,\r\n velocityX: velocityResult.velocityX,\r\n velocityY: velocityResult.velocityY,\r\n angleRadians: angle.angleRadians,\r\n angleDegrees: angle.angleDegrees,\r\n direction: angle.direction,\r\n normalizedMagnitude,\r\n filtered,\r\n timestamp: event.timestamp,\r\n };\r\n\r\n // Store in stream buffer\r\n this.streamBuffer.push(sample);\r\n\r\n // Emit on processing channel\r\n this.eventBus.emit(EventChannel.ProcessingSample, sample);\r\n\r\n // Feed into all recognizers (Layer 3)\r\n for (const recognizer of this.recognizers) {\r\n if (recognizer.enabled) {\r\n recognizer.onProcessedSample(sample);\r\n }\r\n }\r\n }\r\n}\r\n","// ─── useGestureEngine ───────────────────────────────────────────────────────\r\n// Main React hook that creates and manages a GestureEngine instance.\r\n// Lives outside the React tree render cycle for performance.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { GestureEngine } from '../GestureEngine';\r\nimport {\r\n GestureEngineConfig,\r\n IRecognizer,\r\n IGestureAction,\r\n IFeedbackProvider,\r\n} from '../core/types';\r\nimport { ComposedGesture } from 'react-native-gesture-handler';\r\n\r\nexport interface UseGestureEngineConfig extends GestureEngineConfig {\r\n /**\r\n * Recognizer instances to register with the engine.\r\n * These are created outside the hook and passed in.\r\n */\r\n recognizers?: IRecognizer[];\r\n /**\r\n * Action mappings: gestureName → array of actions\r\n */\r\n actions?: Record<string, IGestureAction[]>;\r\n /**\r\n * Feedback providers to register\r\n */\r\n feedback?: IFeedbackProvider[];\r\n}\r\n\r\nexport interface UseGestureEngineResult {\r\n /** The GestureEngine instance */\r\n engine: GestureEngine | null;\r\n /** Whether the engine is initialized and running */\r\n isReady: boolean;\r\n /**\r\n * RNGH Composed Gesture.\r\n * Pass this to `<GestureDetector gesture={gestures}>` to enable touch inputs.\r\n */\r\n gestures?: ComposedGesture;\r\n}\r\n\r\n/**\r\n * React hook that creates, configures, and manages a GestureEngine lifecycle.\r\n *\r\n * The engine is created once on mount and disposed on unmount.\r\n * Uses useRef to keep the engine outside the React render cycle.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { engine, isReady } = useGestureEngine({\r\n * sensorInterval: 100,\r\n * hapticEnabled: true,\r\n * recognizers: [shakeRecognizer, edgeSwipeRecognizer],\r\n * actions: { 'shake': [myShakeAction] },\r\n * });\r\n * ```\r\n */\r\nexport function useGestureEngine(\r\n config: UseGestureEngineConfig = {},\r\n): UseGestureEngineResult {\r\n const engineRef = useRef<GestureEngine | null>(null);\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n useEffect(() => {\r\n // Create engine\r\n const engine = new GestureEngine({\r\n sensorInterval: config.sensorInterval,\r\n hapticEnabled: config.hapticEnabled,\r\n debug: config.debug,\r\n screenWidth: config.screenWidth,\r\n screenHeight: config.screenHeight,\r\n });\r\n\r\n // Register recognizers\r\n if (config.recognizers) {\r\n for (const recognizer of config.recognizers) {\r\n engine.registerRecognizer(recognizer);\r\n }\r\n }\r\n\r\n // Register actions\r\n if (config.actions) {\r\n for (const [gestureName, actions] of Object.entries(config.actions)) {\r\n for (const action of actions) {\r\n engine.registerAction(gestureName, action);\r\n }\r\n }\r\n }\r\n\r\n // Register feedback providers\r\n if (config.feedback) {\r\n for (const provider of config.feedback) {\r\n engine.registerFeedback(provider);\r\n }\r\n }\r\n\r\n // Start the engine\r\n engine.start();\r\n engineRef.current = engine;\r\n setIsReady(true);\r\n\r\n // Cleanup on unmount\r\n return () => {\r\n engine.dispose();\r\n engineRef.current = null;\r\n setIsReady(false);\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []); // Only run once on mount — config changes require remounting\r\n\r\n return {\r\n engine: engineRef.current,\r\n isReady,\r\n gestures: engineRef.current?.touchInput.gesture,\r\n };\r\n}\r\n","// ─── useShakeGesture ────────────────────────────────────────────────────────\r\n// Convenience hook for shake detection. Creates a self-contained\r\n// GestureEngine with a ShakeRecognizer + CustomAction.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { useEffect, useRef } from 'react';\r\nimport { GestureEngine } from '../GestureEngine';\r\nimport { ShakeRecognizer } from '../recognition/sensor/ShakeRecognizer';\r\nimport { CustomAction } from '../actions/CustomAction';\r\nimport { HapticFeedback } from '../feedback/HapticFeedback';\r\nimport { EventBus } from '../core/EventBus';\r\n\r\nexport interface UseShakeGestureConfig {\r\n /** Acceleration threshold in g (default 1.5) */\r\n threshold?: number;\r\n /** Cooldown in ms (default 1000) */\r\n cooldownMs?: number;\r\n /** Callback when shake is detected */\r\n onShake: () => void;\r\n /** Enable haptic feedback (default true) */\r\n hapticEnabled?: boolean;\r\n /** Sensor polling interval in ms (default 100) */\r\n sensorInterval?: number;\r\n}\r\n\r\n/**\r\n * Convenience hook for shake gesture detection.\r\n *\r\n * Creates a minimal GestureEngine with just a ShakeRecognizer.\r\n * Ideal for simple use cases where you just need shake detection.\r\n *\r\n * @example\r\n * ```tsx\r\n * useShakeGesture({\r\n * threshold: 1.5,\r\n * cooldownMs: 1000,\r\n * onShake: () => console.log('Device shaken!'),\r\n * });\r\n * ```\r\n */\r\nexport function useShakeGesture(config: UseShakeGestureConfig): void {\r\n const engineRef = useRef<GestureEngine | null>(null);\r\n const callbackRef = useRef(config.onShake);\r\n\r\n // Keep callback ref current without re-creating the engine\r\n callbackRef.current = config.onShake;\r\n\r\n useEffect(() => {\r\n const engine = new GestureEngine({\r\n sensorInterval: config.sensorInterval ?? 100,\r\n hapticEnabled: config.hapticEnabled ?? true,\r\n });\r\n\r\n // Create shake recognizer\r\n const shakeRecognizer = new ShakeRecognizer(engine.eventBus, {\r\n threshold: config.threshold,\r\n cooldownMs: config.cooldownMs,\r\n });\r\n engine.registerRecognizer(shakeRecognizer);\r\n\r\n // Register action\r\n const action = new CustomAction('shake-callback', () => {\r\n callbackRef.current();\r\n });\r\n engine.registerAction('shake', action);\r\n\r\n // Add haptic feedback if enabled\r\n if (config.hapticEnabled !== false) {\r\n engine.registerFeedback(new HapticFeedback(true));\r\n }\r\n\r\n engine.start();\r\n engineRef.current = engine;\r\n\r\n return () => {\r\n engine.dispose();\r\n engineRef.current = null;\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [config.threshold, config.cooldownMs, config.sensorInterval]);\r\n}\r\n","// ─── useEdgeSwipe ───────────────────────────────────────────────────────────\r\n// Convenience hook for edge swipe detection.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { useEffect, useRef } from 'react';\r\nimport { GestureEngine } from '../GestureEngine';\r\nimport { EdgeSwipeRecognizer } from '../recognition/spatial/EdgeSwipeRecognizer';\r\nimport { CustomAction } from '../actions/CustomAction';\r\nimport { HapticFeedback } from '../feedback/HapticFeedback';\r\nimport { GestureEvent } from '../core/types';\r\n\r\nexport interface UseEdgeSwipeConfig {\r\n /** Edge to detect: 'left', 'right', 'top', 'bottom' */\r\n edge: 'left' | 'right' | 'top' | 'bottom';\r\n /** Minimum swipe distance in px (default 50) */\r\n minDistance?: number;\r\n /** Edge zone width in px (default 30) */\r\n edgeZoneWidth?: number;\r\n /** Minimum velocity in px/ms (default 0.3) */\r\n minVelocity?: number;\r\n /** Screen width in px */\r\n screenWidth?: number;\r\n /** Screen height in px */\r\n screenHeight?: number;\r\n /** Callback when edge swipe is detected */\r\n onSwipe: (event: GestureEvent) => void;\r\n /** Enable haptic feedback (default true) */\r\n hapticEnabled?: boolean;\r\n}\r\n\r\n/**\r\n * Convenience hook for edge swipe detection.\r\n *\r\n * @example\r\n * ```tsx\r\n * useEdgeSwipe({\r\n * edge: 'left',\r\n * minDistance: 50,\r\n * onSwipe: (event) => navigation.goBack(),\r\n * });\r\n * ```\r\n */\r\nexport function useEdgeSwipe(config: UseEdgeSwipeConfig): void {\r\n const engineRef = useRef<GestureEngine | null>(null);\r\n const callbackRef = useRef(config.onSwipe);\r\n callbackRef.current = config.onSwipe;\r\n\r\n useEffect(() => {\r\n const engine = new GestureEngine({\r\n hapticEnabled: config.hapticEnabled ?? true,\r\n screenWidth: config.screenWidth,\r\n screenHeight: config.screenHeight,\r\n });\r\n\r\n const gestureName = `edge-swipe-${config.edge}`;\r\n\r\n const recognizer = new EdgeSwipeRecognizer(engine.eventBus, {\r\n edge: config.edge,\r\n minDistance: config.minDistance,\r\n edgeZoneWidth: config.edgeZoneWidth,\r\n minVelocity: config.minVelocity,\r\n screenWidth: config.screenWidth,\r\n screenHeight: config.screenHeight,\r\n });\r\n engine.registerRecognizer(recognizer);\r\n\r\n const action = new CustomAction(`${gestureName}-callback`, (event) => {\r\n callbackRef.current(event);\r\n });\r\n engine.registerAction(gestureName, action);\r\n\r\n if (config.hapticEnabled !== false) {\r\n engine.registerFeedback(new HapticFeedback(true));\r\n }\r\n\r\n engine.start();\r\n engineRef.current = engine;\r\n\r\n return () => {\r\n engine.dispose();\r\n engineRef.current = null;\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [config.edge, config.minDistance, config.edgeZoneWidth, config.minVelocity]);\r\n}\r\n","// ─── useGestureSequence ─────────────────────────────────────────────────────\r\n// Convenience hook for gesture sequence detection.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nimport { useEffect, useRef } from 'react';\r\nimport { GestureEngine } from '../GestureEngine';\r\nimport { SequenceRecognizer } from '../recognition/sequence/SequenceRecognizer';\r\nimport { CustomAction } from '../actions/CustomAction';\r\nimport { HapticFeedback } from '../feedback/HapticFeedback';\r\n\r\nexport interface UseGestureSequenceConfig {\r\n /** Ordered gesture names to match */\r\n sequence: string[];\r\n /** Max time between steps in ms (default 800) */\r\n timeoutMs?: number;\r\n /** Callback when sequence is completed */\r\n onComplete: () => void;\r\n /** Enable haptic feedback (default true) */\r\n hapticEnabled?: boolean;\r\n}\r\n\r\n/**\r\n * Convenience hook for gesture sequence detection.\r\n *\r\n * @example\r\n * ```tsx\r\n * useGestureSequence({\r\n * sequence: ['tap', 'tap', 'edge-swipe-right'],\r\n * timeoutMs: 800,\r\n * onComplete: () => console.log('Secret gesture unlocked!'),\r\n * });\r\n * ```\r\n */\r\nexport function useGestureSequence(config: UseGestureSequenceConfig): void {\r\n const engineRef = useRef<GestureEngine | null>(null);\r\n const callbackRef = useRef(config.onComplete);\r\n callbackRef.current = config.onComplete;\r\n\r\n useEffect(() => {\r\n const engine = new GestureEngine({\r\n hapticEnabled: config.hapticEnabled ?? true,\r\n });\r\n\r\n const sequenceName = `sequence:${config.sequence.join('>')}`;\r\n\r\n const recognizer = new SequenceRecognizer(engine.eventBus, {\r\n sequence: config.sequence,\r\n timeoutMs: config.timeoutMs,\r\n });\r\n engine.registerRecognizer(recognizer);\r\n\r\n const action = new CustomAction(`${sequenceName}-callback`, () => {\r\n callbackRef.current();\r\n });\r\n engine.registerAction(sequenceName, action);\r\n\r\n if (config.hapticEnabled !== false) {\r\n engine.registerFeedback(new HapticFeedback(true));\r\n }\r\n\r\n engine.start();\r\n engineRef.current = engine;\r\n\r\n return () => {\r\n engine.dispose();\r\n engineRef.current = null;\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [config.sequence.join(','), config.timeoutMs]);\r\n}\r\n"]}