@g9tm/syncdata 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/PARITY.md +71 -0
- package/README.md +71 -0
- package/THIRD-PARTY-NOTICES.md +31 -0
- package/dist/abstractions/digest.d.ts +27 -0
- package/dist/abstractions/digest.js +78 -0
- package/dist/abstractions/digest.js.map +1 -0
- package/dist/abstractions/enums.d.ts +42 -0
- package/dist/abstractions/enums.js +60 -0
- package/dist/abstractions/enums.js.map +1 -0
- package/dist/abstractions/errors.d.ts +72 -0
- package/dist/abstractions/errors.js +90 -0
- package/dist/abstractions/errors.js.map +1 -0
- package/dist/abstractions/guid.d.ts +24 -0
- package/dist/abstractions/guid.js +93 -0
- package/dist/abstractions/guid.js.map +1 -0
- package/dist/abstractions/key.d.ts +16 -0
- package/dist/abstractions/key.js +47 -0
- package/dist/abstractions/key.js.map +1 -0
- package/dist/abstractions/long.d.ts +103 -0
- package/dist/abstractions/long.js +351 -0
- package/dist/abstractions/long.js.map +1 -0
- package/dist/abstractions/parameters.d.ts +49 -0
- package/dist/abstractions/parameters.js +153 -0
- package/dist/abstractions/parameters.js.map +1 -0
- package/dist/brotli-js/decode.d.ts +8 -0
- package/dist/brotli-js/decode.js +2004 -0
- package/dist/brotli-js/decode.js.map +1 -0
- package/dist/brotli-js/index.d.ts +5 -0
- package/dist/brotli-js/index.js +19 -0
- package/dist/brotli-js/index.js.map +1 -0
- package/dist/client/engine.d.ts +110 -0
- package/dist/client/engine.js +1158 -0
- package/dist/client/engine.js.map +1 -0
- package/dist/client/model.d.ts +61 -0
- package/dist/client/model.js +154 -0
- package/dist/client/model.js.map +1 -0
- package/dist/client/progress.d.ts +101 -0
- package/dist/client/progress.js +251 -0
- package/dist/client/progress.js.map +1 -0
- package/dist/client/runs.d.ts +219 -0
- package/dist/client/runs.js +239 -0
- package/dist/client/runs.js.map +1 -0
- package/dist/client/storeTypes.d.ts +428 -0
- package/dist/client/storeTypes.js +256 -0
- package/dist/client/storeTypes.js.map +1 -0
- package/dist/client/transport.d.ts +19 -0
- package/dist/client/transport.js +2 -0
- package/dist/client/transport.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/abort.d.ts +21 -0
- package/dist/internal/abort.js +125 -0
- package/dist/internal/abort.js.map +1 -0
- package/dist/internal/base64.d.ts +8 -0
- package/dist/internal/base64.js +85 -0
- package/dist/internal/base64.js.map +1 -0
- package/dist/internal/dotnetFormat.d.ts +32 -0
- package/dist/internal/dotnetFormat.js +207 -0
- package/dist/internal/dotnetFormat.js.map +1 -0
- package/dist/internal/md5.d.ts +2 -0
- package/dist/internal/md5.js +97 -0
- package/dist/internal/md5.js.map +1 -0
- package/dist/internal/sha256.d.ts +20 -0
- package/dist/internal/sha256.js +153 -0
- package/dist/internal/sha256.js.map +1 -0
- package/dist/internal/utf8.d.ts +8 -0
- package/dist/internal/utf8.js +143 -0
- package/dist/internal/utf8.js.map +1 -0
- package/dist/node/index.d.ts +9 -0
- package/dist/node/index.js +35 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/sqliteDriver.d.ts +11 -0
- package/dist/node/sqliteDriver.js +252 -0
- package/dist/node/sqliteDriver.js.map +1 -0
- package/dist/protocol/dtos.d.ts +280 -0
- package/dist/protocol/dtos.js +33 -0
- package/dist/protocol/dtos.js.map +1 -0
- package/dist/protocol/protocol.d.ts +36 -0
- package/dist/protocol/protocol.js +63 -0
- package/dist/protocol/protocol.js.map +1 -0
- package/dist/protocol/rowBatch/columnLayout.d.ts +4 -0
- package/dist/protocol/rowBatch/columnLayout.js +309 -0
- package/dist/protocol/rowBatch/columnLayout.js.map +1 -0
- package/dist/protocol/rowBatch/format.d.ts +74 -0
- package/dist/protocol/rowBatch/format.js +163 -0
- package/dist/protocol/rowBatch/format.js.map +1 -0
- package/dist/protocol/rowBatch/reader.d.ts +119 -0
- package/dist/protocol/rowBatch/reader.js +459 -0
- package/dist/protocol/rowBatch/reader.js.map +1 -0
- package/dist/protocol/rowBatch/writer.d.ts +101 -0
- package/dist/protocol/rowBatch/writer.js +412 -0
- package/dist/protocol/rowBatch/writer.js.map +1 -0
- package/dist/protocol/wire.d.ts +32 -0
- package/dist/protocol/wire.js +329 -0
- package/dist/protocol/wire.js.map +1 -0
- package/dist/signalr/index.d.ts +2 -0
- package/dist/signalr/index.js +5 -0
- package/dist/signalr/index.js.map +1 -0
- package/dist/signalr/protocols.d.ts +17 -0
- package/dist/signalr/protocols.js +109 -0
- package/dist/signalr/protocols.js.map +1 -0
- package/dist/signalr/transport.d.ts +67 -0
- package/dist/signalr/transport.js +286 -0
- package/dist/signalr/transport.js.map +1 -0
- package/dist/sqlite/apply.d.ts +91 -0
- package/dist/sqlite/apply.js +657 -0
- package/dist/sqlite/apply.js.map +1 -0
- package/dist/sqlite/commands.d.ts +24 -0
- package/dist/sqlite/commands.js +167 -0
- package/dist/sqlite/commands.js.map +1 -0
- package/dist/sqlite/connection.d.ts +81 -0
- package/dist/sqlite/connection.js +322 -0
- package/dist/sqlite/connection.js.map +1 -0
- package/dist/sqlite/driver.d.ts +63 -0
- package/dist/sqlite/driver.js +9 -0
- package/dist/sqlite/driver.js.map +1 -0
- package/dist/sqlite/index.d.ts +6 -0
- package/dist/sqlite/index.js +7 -0
- package/dist/sqlite/index.js.map +1 -0
- package/dist/sqlite/internals.d.ts +63 -0
- package/dist/sqlite/internals.js +194 -0
- package/dist/sqlite/internals.js.map +1 -0
- package/dist/sqlite/options.d.ts +78 -0
- package/dist/sqlite/options.js +78 -0
- package/dist/sqlite/options.js.map +1 -0
- package/dist/sqlite/push.d.ts +9 -0
- package/dist/sqlite/push.js +272 -0
- package/dist/sqlite/push.js.map +1 -0
- package/dist/sqlite/query.d.ts +38 -0
- package/dist/sqlite/query.js +476 -0
- package/dist/sqlite/query.js.map +1 -0
- package/dist/sqlite/revocation.d.ts +28 -0
- package/dist/sqlite/revocation.js +337 -0
- package/dist/sqlite/revocation.js.map +1 -0
- package/dist/sqlite/sql.d.ts +60 -0
- package/dist/sqlite/sql.js +324 -0
- package/dist/sqlite/sql.js.map +1 -0
- package/dist/sqlite/store.d.ts +116 -0
- package/dist/sqlite/store.js +664 -0
- package/dist/sqlite/store.js.map +1 -0
- package/dist/sqlite/values.d.ts +29 -0
- package/dist/sqlite/values.js +288 -0
- package/dist/sqlite/values.js.map +1 -0
- package/dist/testing/index.d.ts +61 -0
- package/dist/testing/index.js +175 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +104 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/sqlite/apply.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAC1H,4HAA4H;AAC5H,EAAE;AACF,uHAAuH;AACvH,0HAA0H;AAC1H,0GAA0G;AAC1G,qHAAqH;AACrH,iEAAiE;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,sBAAsB,EAAqB,MAAM,yBAAyB,CAAC;AACxH,OAAO,EAAE,eAAe,EAAyE,MAAM,qBAAqB,CAAC;AAC7H,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAE,YAAY,EAAyB,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAA2B,MAAM,iBAAiB,CAAC;AAEhG,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAwC,MAAM,gBAAgB,CAAC;AAC3K,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,QAAQ,GAAG,6CAA6C,CAAC;AAC/D,MAAM,eAAe,GAAG,kEAAkE,CAAC;AAC3F,MAAM,IAAI,GAAG,gDAAgD,CAAC;AAE9D,2DAA2D;AAC3D,MAAM,OAAO,YAAY;IAmBvB,YAAY,UAA8B,EAAE,QAAyC,EAAE,cAAsB,EAAE,kBAA0B,EAAE,MAAoB;QAhBtJ,WAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAC7B,UAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAC1B,kBAAa,GAAG,IAAI,GAAG,EAAgD,CAAC;QACxE,aAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;QAC/C,oBAAe,GAAG,IAAI,GAAG,EAA6B,CAAC;QACvD,oBAAe,GAAoC,EAAE,CAAC;QAC/D,sFAAsF;QAC7E,oBAAe,GAAoC,EAAE,CAAC;QAC/D,SAAI,GAAG,CAAC,CAAC;QACT,eAAU,GAAG,KAAK,CAAC;QACF,iBAAY,GAAG,IAAI,GAAG,EAAU,CAAC;QACjC,eAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;QA6DvC,gBAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;QAvDvD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;QAClE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,QAAQ,CAAC,GAAW,EAAE,GAAW;QAC/B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,QAAQ,GAAG,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,GAAW;QAC9B,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,QAAQ,GAAG,GAAG,CAAC,CAAC;IAC5E,CAAC;IAED,QAAQ,CAAC,GAAW;QAClB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,eAAe,CAAC,KAAa;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC;IACrD,CAAC;IAED,UAAU,CAAC,KAAa,EAAE,GAAW;;QACnC,MAAM,IAAI,GAAG,MAAA,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,mCAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACrF,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC;IAED,uDAAuD;IACvD,KAAK,CAAC,KAAK,CAAC,MAAc,EAAE,MAA+C,EAAE,QAA2C;QACtH,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC;YAAE,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACnE,CAAC;IAED,kHAAkH;IAClH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;YAAE,OAAO;QACnC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,gFAAgF;QAChF,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,YAAY,CAAC,KAAa,EAAE,IAAY,EAAE,SAAiB;;QACzD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,MAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,mCAAI,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;QACtG,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QAC5C,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,MAAA,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,mCAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QAC9E,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IAID,iBAAiB;QACf,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;;YACpC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,MAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAI,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3F,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAqB,EACrB,UAA8B,EAC9B,OASC;;IAED,MAAM,UAAU,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,UAAU,EAAE,MAAA,OAAO,CAAC,QAAQ,mCAAI,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,sBAAsB,EAAE,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/J,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,OAAO,CAAC,aAAa;YAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC/E,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,GACR,OAAO,CAAC,kBAAkB,KAAK,IAAI,IAAI,OAAO,CAAC,kBAAkB,KAAK,SAAS;YAC7E,CAAC,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,8CAA8C,CAAC;YACxE,CAAC,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,iEAAiE,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACpI,KAAK,MAAM,CAAC,IAAI,IAAI;YAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvE,IAAI,OAAO,CAAC,oBAAoB,KAAK,IAAI,IAAI,OAAO,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;YACxF,MAAM,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,oBAAoB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACxH,CAAC;QACD,uHAAuH;QACvH,KAAK,MAAM,CAAC,IAAI,MAAM,UAAU,CAAC,KAAK,CAAC,+GAA+G,CAAC,EAAE,CAAC;YACxJ,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,UAAU,GAAG,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,KAAK,IAAI,CAAC;IAE5F,MAAM,WAAW,GAAG,wBAAwB,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACzF,MAAM,YAAY,GAAG,IAAI,GAAG,EAA4B,CAAC;IACzD,KAAK,MAAM,CAAC,IAAI,WAAW;QAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC;IACvE,KAAK,MAAM,MAAM,IAAI,MAAM,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC;QAC/D,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1F,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAA,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC7F,CAAC;IACD,KAAK,MAAM,QAAQ,IAAI,MAAA,OAAO,CAAC,SAAS,mCAAI,EAAE;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEhH,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC;IAC/C,WAAW,CAAC,YAAY,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;gBAAE,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClF,CAAC;aAAM,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YAChC,oHAAoH;YACpH,mGAAmG;YACnG,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,8FAA8F,CAAC,CAAC;YACpI,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5B,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC;oBAAE,SAAS;gBAC7C,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,eAAe;gBAAE,MAAM,UAAU,CAAC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5G,IAAI,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC;gBAAE,WAAW,CAAC,+BAA+B,GAAG,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,uBAAuB,GAAG,CAAC;QAAE,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAChI,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,oGAAoG;AACpG,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAqB;IAClD,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,IAAI,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,eAAe;YAAE,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtF,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC;QACnC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,cAAc,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;IACpE,CAAC;IACD,IAAI,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,eAAe;YAAE,MAAM,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1H,OAAO,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAC5B,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;AAC/E,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,gBAAgB,CAAC,KAAqB,EAAE,IAAY;IAClE,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACvD,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAChI,CAAC;AAED,+CAA+C;AAC/C,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAqB,EAAE,UAA8B;IAC7F,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,MAAM,UAAU,CAAC,KAAK,CAAC,qEAAqE,CAAC,EAAE,CAAC;QAC9G,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,wGAAwG;AACxG,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAqB,EAAE,UAA8B,EAAE,QAAgB,EAAE,GAAuC;IACzJ,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,MAAM,UAAU,CAAC,KAAK,CAAC,0DAA0D,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;YAAE,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtK,CAAC;AACH,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,mBAAmB,CAAC,IAAkB;;IACpD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC,QAAQ;YAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,MAAA,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,mCAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9G,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gGAAgG;AAChG,KAAK,UAAU,YAAY,CAAC,KAAqB,EAAE,OAAqB,EAAE,YAAiC;IACzG,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,KAAK,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAClD,IAAI,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,uBAAuB,IAAI,CAAC,KAAK;YAAE,SAAS;QACrE,IAAI,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,iBAAiB,KAAK,CAAC,MAAM,UAAU,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAChF,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,2BAA2B,CAAC;YACzD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,wBAAwB,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC;YAClI,IAAI,MAAM,IAAI,CAAC,IAAI,IAAI,GAAG,QAAQ,GAAG,MAAM,EAAE,CAAC;gBAC5C,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,sBAAsB,CAAC;gBAC5F,SAAS;YACX,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG,CACd,MAAM,UAAU,CAAC,KAAK,CACpB,uHAAuH;YACrH,iEAAiE,EACnE,EAAE,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,CAC9B,CACF,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,UAAU,CAAC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACzD,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACnC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;QACnF,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,oBAAoB,IAAI,gBAAgB,KAAK,CAAC,KAAK,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,mCAAmC,CAAC,CAAC;IACjJ,CAAC;AACH,CAAC;AAED,uHAAuH;AACvH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAAqB,EAAE,UAA8B;IAC5F,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,6BAA6B;QAAE,OAAO,IAAI,CAAC;IAC9D,IAAI,QAAQ,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAClG,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC;IACzE,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,UAAU,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IACrD,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,UAAU,CAAC,IAAI,CAAC,uBAAuB,GAAG,QAAQ,CAAC,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC;AAED,wCAAwC;AACxC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAqB,EAAE,OAAqB,EAAE,KAAiB,EAAE,eAA8B;;IAC9H,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;IACd,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,MAAM,GAAqB,gBAAgB,CAAC,MAAM,CAAC;IACvD,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAChE,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC;YACzB,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC;YACnC,MAAM,GAAG,MAAA,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,mCAAI,gBAAgB,CAAC,MAAM,CAAC;QAC5E,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC9I,OAAO,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU;YAAE,SAAS;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;QAChC,QAAQ,MAAM,CAAC,EAAE,EAAE,CAAC;YAClB,KAAK,aAAa,CAAC,MAAM;gBACvB,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC5F,MAAM;YACR,KAAK,aAAa,CAAC,QAAQ;gBACzB,MAAM,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;gBACnD,MAAM;YACR,KAAK,aAAa,CAAC,SAAS;gBAC1B,OAAO,MAAM,CAAC,OAAO,EAAE;oBAAE,MAAM,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC1F,MAAM;YACR,KAAK,aAAa,CAAC,OAAO;gBACxB,OAAO,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;oBACxB,IAAI,IAAI,IAAI,CAAC;wBAAE,MAAM,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,eAAyB,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;gBACtH,CAAC;gBACD,MAAM;QACV,CAAC;QACD,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,GAAG,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC;AAED,uGAAuG;AACvG,KAAK,UAAU,YAAY,CAAC,KAAqB,EAAE,OAAqB,EAAE,MAAwB,EAAE,KAAiB,EAAE,IAAY,EAAE,YAA2B;IAC9J,MAAM,OAAO,GAAI,KAAK,CAAC,UAAkC,CAAC,OAAO,CAAC;IAClE,IAAI,MAAM,CAAC,WAAW,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,IAAI,qBAAqB,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,mBAAmB,MAAM,CAAC,WAAW,aAAa,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC;IAC/I,CAAC;IACD,MAAM,OAAO,GAAoD,EAAE,CAAC;IACpE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACvB,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,oHAAoH;IACpH,2DAA2D;IAC3D,MAAM,SAAS,GACb,eAAe,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;QACrJ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YACjB,CAAC,CAAC,eAAe,KAAK,CAAC,SAAS,cAAc;YAC9C,CAAC,CAAC,eAAe,KAAK,CAAC,SAAS,mBAAmB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAClL,yHAAyH;IACzH,qGAAqG;IACrG,MAAM,OAAO,GACX,uHAAuH;QACvH,QAAQ;QACR,oBAAoB;QACpB,oIAAoI;QACpI,uDAAuD;QACvD,kKAAkK,CAAC;IACrK,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;IAExC,OAAO,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACvB,IAAI,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YAClD,IAAI,IAAI,IAAI,CAAC;gBAAE,MAAM,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YAC5E,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAiB,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QACpD,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7G,MAAM,UAAU,GAAG;YACjB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE;YAClC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,UAAU,CAAC,EAAE;YACvF,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,EAAE;SACrC,CAAC;QACF,IAAI,YAAY,KAAK,IAAI;YAAE,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,gFAAgF,EAAE,MAAM,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9K,IAAI,OAAO,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACpC,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,mDAAmD,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACxG,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,oEAAoE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,sBAAsB,CAAC,EAAE,CAAC,CAAC;QACnJ,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE;;YAC/D,MAAM,OAAO,GAAG,CAAC,MAAC,OAAO,CAAC,CAAC,CAAiB,CAAC,OAAO,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC/D,IAAI,CAAC,OAAO;gBAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC7C,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC;gBAAE,OAAO,CAAC,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACxF,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,IAAI,IAAI;YAAE,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;AACH,CAAC;AAED,qFAAqF;AACrF,KAAK,UAAU,aAAa,CAAC,KAAqB,EAAE,OAAqB,EAAE,MAAwB,EAAE,KAAiB;IACpH,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAE,KAAK,CAAC,UAAkC,CAAC,OAAO,CAAC,CAAC;IAC7F,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC;QAClD,OAAO,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAqD,EAAE,CAAC;IACrE,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IACH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,MAAM,GAAG,GAAG,UAAU,KAAK,CAAC,MAAM,QAAQ,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,SAAS,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACjK,OAAO,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACvB,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YAC9B,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAiB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAsB,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1J,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QAClC,IAAI,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;YAAE,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1E,OAAO,CAAC,IAAI,EAAE,CAAC;IACjB,CAAC;AACH,CAAC;AAED,wBAAwB;AACxB,KAAK,UAAU,cAAc,CAAC,OAAqB,EAAE,KAAiB,EAAE,GAAW,EAAE,OAAe;IAClG,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CACtC;QACE,EAAE,GAAG,EAAE,eAAe,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,SAAS,OAAO,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE;QACpG;YACE,GAAG,EAAE,yEAAyE,GAAG,QAAQ,GAAG,wEAAwE;YACpK,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC;SAClC;QACD,EAAE,GAAG,EAAE,0DAA0D,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;QAC7F,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;KAC1B,EACD,CAAC,OAAO,EAAE,EAAE;;QACV,IAAI,CAAC,MAAC,OAAO,CAAC,CAAC,CAAiB,CAAC,OAAO,mCAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YACnD,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;IACH,CAAC,CACF,CAAC;IACF,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,IAAI,IAAI;QAAE,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;AAClC,CAAC;AAED,mHAAmH;AACnH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,KAAqB,EACrB,OAAqB,EACrB,KAAiB,EACjB,GAAW,EACX,eAAuB,EACvB,IAAY,EACZ,SAAkB,EAClB,MAAwB;IAExB,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,4EAA4E,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAClJ,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,8IAA8I,EAAE;YAChK,EAAE,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE;YAC7B,EAAE,EAAE,KAAK,CAAC,GAAG;YACb,GAAG,EAAE,GAAG;SACT,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,iEAAiE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACzI,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1B,IAAI,MAAM,KAAK,gBAAgB,CAAC,MAAM,EAAE,CAAC;QACvC,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB;YAAE,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACnF,OAAO;IACT,CAAC;IACD,2HAA2H;IAC3H,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,mBAAmB,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAChJ,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,OAAO;QAAE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED,uBAAuB;AACvB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAqB,EAAE,KAAiB,EAAE,GAAW,EAAE,IAAY,EAAE,YAA2B;IAClI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,iFAAiF,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACjJ,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,iFAAiF,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;AACjL,CAAC;AAED,mGAAmG;AACnG,KAAK,UAAU,iBAAiB,CAAC,KAAqB,EAAE,UAA8B,EAAE,oBAA4B;IAClH,MAAM,IAAI,GAAmC,EAAE,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,MAAM,UAAU,CAAC,KAAK,CAAC,8CAA8C,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAChJ,MAAM,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAC3G,KAAK,MAAM,CAAC,IAAI,MAAM,UAAU,CAAC,KAAK,CAAC,+GAA+G,CAAC,EAAE,CAAC;QACxJ,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gHAAgH;AAChH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAqB,EACrB,KAAa,EACb,WAA4C,EAC5C,MAA8C,EAC9C,aAAgI,EAChI,MAAoB;IAEpB,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAC1B,OAAO,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;QACpC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC5D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACtD,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,eAAe,CAAC,gBAAgB,CAAC,eAAe,EAAE,mCAAmC,CAAC,CAAC;YAC9G,MAAM,SAAS,GAAG,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,iFAAiF,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAExK,kHAAkH;YAClH,yDAAyD;YACzD,MAAM,SAAS,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;YACrE,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACtD,IAAI,aAAa,GAAG,KAAK,CAAC;YAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,uBAAuB,GAAG,CAAC;gBAAE,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,aAAa,GAAG,aAAa,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAChK,MAAM,WAAW,GAAG,SAAS,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC;YAC5E,6DAA6D;YAC7D,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5G,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,mBAAmB,IAAI,CAAC,WAAW,CAAC;YAEhG,MAAM,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;YAClC,IAAI,YAAY,GAAG,CAAC,CAAC;YACrB,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,IAAI,WAAW,GAAG,SAAS,CAAC;YAE5B,uGAAuG;YACvG,GAAG,CAAC;gBACF,IAAI,MAAM,IAAI,MAAM,CAAC,OAAO;oBAAE,MAAM,YAAY,EAAE,CAAC;gBACnD,MAAM,KAAK,GAAa,EAAE,CAAC;gBAC3B,IAAI,KAAK,GAAG,IAAI,CAAC;gBACjB,OAAO,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;oBACzC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAW,CAAC,CAAC;oBACvC,IAAI,CAAC,WAAW;wBAAE,SAAS;oBAC3B,IAAI,CAAC,MAAM,cAAc,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,WAAW,IAAI,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;wBACpG,KAAK,EAAE,CAAC;wBACR,KAAK,GAAG,KAAK,CAAC;wBACd,MAAM;oBACR,CAAC;gBACH,CAAC;gBACD,IAAI,KAAK,CAAC,OAAO,CAAC,iBAAiB,GAAG,WAAW;oBAAE,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;gBAE5H,IAAI,OAAO,GAAwB,IAAI,CAAC;gBACxC,MAAM,aAAa,GAA8C,EAAE,CAAC;gBACpE,MAAM,UAAU,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;;oBACnD,OAAO,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE;wBAC5C,QAAQ,EAAE,WAAW;wBACrB,SAAS,EAAE,MAAM,CAAC,SAAS;wBAC3B,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY;wBAC/C,oBAAoB,EAAE,MAAM,CAAC,aAAa;wBAC1C,aAAa;wBACb,YAAY;wBACZ,MAAM;qBACP,CAAC,CAAC;oBACH,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;wBAC7B,IAAI,MAAM,IAAI,MAAM,CAAC,OAAO;4BAAE,MAAM,YAAY,EAAE,CAAC;wBACnD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,+EAA+E,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;wBAClJ,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;wBACpB,IAAI,CAAC,GAAG;4BAAE,SAAS;wBACnB,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;wBACvB,IAAI,CAAC,CAAC,OAAO,YAAY,WAAW,CAAC;4BAAE,SAAS;wBAChD,MAAM,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACvG,CAAC;oBAED,IAAI,KAAK,EAAE,CAAC;wBACV,0HAA0H;wBAC1H,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;4BACzC,MAAM,MAAM,GACV,qJAAqJ,CAAC;4BACxJ,MAAM,MAAM,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,cAAc,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;4BACpH,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gCAChF,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;gCACtB,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,sBAAsB,EAAE,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,MAAA,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,mCAAI,IAAI,EAAE,CAAC,CAAC;4BAC9H,CAAC;iCAAM,CAAC;gCACN,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;gCACtB,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;4BACxC,CAAC;wBACH,CAAC;wBACD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;4BACxC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;4BACrD,IAAI,CAAC,KAAK;gCAAE,SAAS;4BACrB,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;4BAC3C,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO;gCAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC;oCAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;4BAC9H,MAAM,UAAU,CAAC,IAAI,CAAC,yDAAyD,EAAE,EAAE,EAAE,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;4BAC/H,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;wBACxC,CAAC;oBACH,CAAC;oBAED,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;oBACxB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;wBAAE,MAAM,UAAU,CAAC,IAAI,CAAC,qDAAqD,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC1I,IAAI,KAAK;wBAAE,MAAM,UAAU,CAAC,IAAI,CAAC,6CAA6C,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;gBACjG,CAAC,CAAC,CAAC;gBAEH,MAAM,OAAO,GAAG,OAAkC,CAAC;gBACnD,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,aAAa;oBAAE,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;gBAC5E,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;gBAC7B,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC5B,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAG,YAAY,CAAC,CAAC;gBAC5B,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YACtJ,CAAC,QAAQ,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE;YAEnC,KAAK,CAAC,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;YACnD,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,sBAAsB,YAAY,YAAY,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC1K,MAAM,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;YAC1D,OAAO,KAAK,CAAC;QACf,CAAC;gBAAS,CAAC;YACT,IAAI,OAAO;gBAAE,MAAM,OAAO,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC;IAC1B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,UAA8B,EAAE,KAAa,EAAE,KAAe;IAC1F,OAAO,QAAQ,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,iFAAiF,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACrK,CAAC;AAED,8HAA8H;AAC9H,KAAK,UAAU,kBAAkB,CAAC,KAAqB,EAAE,UAA8B,EAAE,WAAmB;IAC1G,IAAI,KAAK,CAAC,OAAO,CAAC,oBAAoB,IAAI,CAAC,IAAI,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,oBAAoB;QAAE,OAAO;IACxG,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QACxE,IAAI,QAAQ,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK;YAAE,OAAO;QAC7F,MAAM,UAAU,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACvE,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1C,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,qCAAqC,WAAW,uDAAuD,CAAC,CAAC;YACrI,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,MAAM,UAAU,CAAC,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,sDAAsD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9I,CAAC;AACH,CAAC;AAED,6BAA6B;AAC7B,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAqB,EACrB,eAAuB,EACvB,KAA0B,EAC1B,aAAoC,EACpC,iBAAoC,EACpC,WAA8B,EAC9B,MAAwB,EACxB,MAAoB;IAEpB,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,IAAI,0BAA0B,CAAC,CAAC;IAC3E,OAAO,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;QACpC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC5D,IAAI,CAAC;YACH,OAAO,MAAM,UAAU,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;gBAC1D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC/E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;gBAC9C,KAAK,MAAM,KAAK,IAAI,aAAa;oBAAE,MAAM,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;gBAC5F,MAAM,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;gBAChE,IAAI,YAAY,EAAE,CAAC;oBACjB,KAAK,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;wBACpC,MAAM,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;wBAC7G,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;oBACnC,CAAC;oBACD,KAAK,MAAM,GAAG,IAAI,WAAW;wBAAE,MAAM,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBAC/I,CAAC;gBACD,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACxB,OAAO,OAAO,CAAC,MAAM,CAAC;YACxB,CAAC,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,OAAO;gBAAE,MAAM,OAAO,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC","sourcesContent":["// Twin of G9SyncData.Client.Sqlite/G9CSqliteSyncStore.Apply.cs: the apply engine shared by pulls, reconciliation and push\n// results. It runs inside one write transaction with g9_ctx.applying = 1, so capture triggers ignore library writes (D-03).\n//\n// Bridge cost shapes the TypeScript form: on Lynx every driver call is a native round trip, so the row path queues its\n// statements and runs them in batches, and the per-row decisions the .NET store makes from a statement's result happen in\n// SQL instead — the metadata upsert reads changes() of the row upsert before it, and the clock moves with\n// `UPDATE g9_clock … WHERE changes() > 0` right after. The rows, metadata and clock end up exactly as the .NET store\n// leaves them (the parity tests compare both stores' databases).\nimport { G9EMoveOutPolicy } from '../abstractions/enums.js';\nimport { G9SyncErrorCodes, G9SyncException } from '../abstractions/errors.js';\nimport { G9Long } from '../abstractions/long.js';\nimport { delay } from '../internal/abort.js';\nimport { G9ApplyReport, G9ERevocationReason, REASON_TABLE_NOT_EMPTY, type G9ApplySlice } from '../client/storeTypes.js';\nimport { G9EPullPartKind, type G9DtBackfillRequest, type G9DtNegotiatedTable, type G9DtPullPlan } from '../protocol/dtos.js';\nimport { G9ERowBatchOp, G9RowBatchFormatError } from '../protocol/rowBatch/format.js';\nimport { openRowBatch, type G9RowBatchReader } from '../protocol/rowBatch/reader.js';\nimport { asNumber, asString, G9StatementBatch, type G9SqliteConnection } from './connection.js';\nimport type { G9SqlResult, G9SqlValue } from './driver.js';\nimport { findByServerName, keyValue, meta, nowMs, persistedJson, readPersistedDefinitions, readSubscriptions, type LocalTable, type StoreInternals } from './internals.js';\nimport { disposeReleasedRow, REVOKED_REJECTION_CODE } from './revocation.js';\nimport { bit, EPHEMERAL_SLOT, quote } from './sql.js';\nimport { frameValueToSql } from './values.js';\n\nconst NEXT_SEQ = '(SELECT seq FROM g9_clock WHERE id = 1) + 1';\nconst BUMP_IF_CHANGED = 'UPDATE g9_clock SET seq = seq + 1 WHERE id = 1 AND changes() > 0';\nconst BUMP = 'UPDATE g9_clock SET seq = seq + 1 WHERE id = 1';\n\n/** The state of one apply transaction (`ApplyContext`). */\nexport class ApplyContext {\n readonly connection: G9SqliteConnection;\n readonly batch: G9StatementBatch;\n readonly report = new G9ApplyReport();\n readonly dirty = new Set<string>();\n readonly subscriptions = new Map<string, { slot: number; ephemeral: boolean }>();\n readonly policies = new Map<string, G9EMoveOutPolicy>();\n readonly backfillColumns = new Map<number, readonly string[]>();\n readonly deferredIndexes: { name: string; sql: string }[] = [];\n /** Library triggers dropped for the apply, re-created from this SQL before commit. */\n readonly droppedTriggers: { name: string; sql: string }[] = [];\n rows = 0;\n hasRevoked = false;\n private readonly _dirtyTables = new Set<number>();\n private readonly _tableTime = new Map<string, number>();\n private readonly _progress: ((rows: number) => void) | null;\n private readonly _maxChangedKeys: number;\n private readonly _signal: AbortSignal | undefined;\n\n constructor(connection: G9SqliteConnection, progress: ((rows: number) => void) | null, maxChangedKeys: number, statementsPerBatch: number, signal?: AbortSignal) {\n this.connection = connection;\n this.batch = new G9StatementBatch(connection, statementsPerBatch);\n this._progress = progress;\n this._maxChangedKeys = maxChangedKeys;\n this._signal = signal;\n }\n\n addDirty(tid: number, key: string): void {\n this.dirty.add(tid + '\\u0000' + key);\n this._dirtyTables.add(tid);\n }\n\n isDirty(tid: number, key: string): boolean {\n return this._dirtyTables.has(tid) && this.dirty.has(tid + '\\u0000' + key);\n }\n\n hasDirty(tid: number): boolean {\n return this._dirtyTables.has(tid);\n }\n\n wantsChangedKey(table: string): boolean {\n const keys = this.report.changedKeys[table];\n return !keys || keys.length < this._maxChangedKeys;\n }\n\n addChanged(table: string, key: string): void {\n const keys = this.report.changedKeys[table] ?? (this.report.changedKeys[table] = []);\n if (keys.length < this._maxChangedKeys) keys.push(key);\n }\n\n tick(): void {\n this.rows++;\n if (this._progress && this.rows % 1000 === 0) this._progress(this.rows);\n }\n\n /** Queues a script; flushes when the batch is full. */\n async queue(script: string, params?: Parameters<G9StatementBatch['add']>[1], callback?: (results: G9SqlResult[]) => void): Promise<void> {\n if (this.batch.add(script, params, callback)) await this.flush();\n }\n\n /** Runs what is queued (before anything that reads, and at the end). Yields to the event loop between batches. */\n async flush(): Promise<void> {\n if (this.batch.count === 0) return;\n await this.batch.flush(this._signal);\n // Lynx: let the background thread breathe between bridge calls of a long apply.\n await delay(0);\n }\n\n addTableTime(table: string, rows: number, elapsedMs: number): void {\n this._tableTime.set(table.toLowerCase(), (this._tableTime.get(table.toLowerCase()) ?? 0) + elapsedMs);\n const diagnostics = this.report.diagnostics;\n diagnostics.rowsByTable[table] = (diagnostics.rowsByTable[table] ?? 0) + rows;\n this._tableNames.set(table.toLowerCase(), table);\n }\n\n private readonly _tableNames = new Map<string, string>();\n\n publishTableTimes(): void {\n this._tableTime.forEach((ms, lower) => {\n this.report.diagnostics.msByTable[this._tableNames.get(lower) ?? lower] = Math.floor(ms);\n });\n }\n}\n\n/**\n * Opens an apply and decides which rows it may not touch (`BeginApply`). `dirtyAfterSequence` narrows the protected set to\n * pending changes after it; `changedAfterSequence` widens it with every row changed after it (ADR-0046).\n */\nexport async function beginApply(\n store: StoreInternals,\n connection: G9SqliteConnection,\n options: {\n dirtyAfterSequence?: number | null;\n progress?: ((rows: number) => void) | null;\n backfills?: readonly G9DtBackfillRequest[];\n snapshotRows?: Map<number, number> | null;\n changedAfterSequence?: number | null;\n protectedRows?: { tid: number; key: string }[] | null;\n skipTriggers?: boolean;\n signal?: AbortSignal;\n },\n): Promise<ApplyContext> {\n await connection.exec('UPDATE g9_ctx SET applying = 1 WHERE id = 1');\n const context = new ApplyContext(connection, options.progress ?? null, store.options.maxChangedKeysPerTable, store.options.statementsPerBatch, options.signal);\n\n if (options.protectedRows) {\n for (const { tid, key } of options.protectedRows) context.addDirty(tid, key);\n } else {\n const rows =\n options.dirtyAfterSequence === null || options.dirtyAfterSequence === undefined\n ? await connection.query('SELECT tid, pk FROM g9_rows WHERE dirty <> 0')\n : await connection.query('SELECT tid, pk FROM g9_rows WHERE dirty <> 0 AND local_seq > $m', { $m: options.dirtyAfterSequence });\n for (const r of rows) context.addDirty(asNumber(r[0]), asString(r[1]));\n if (options.changedAfterSequence !== null && options.changedAfterSequence !== undefined) {\n await readRowsChangedAfter(store, connection, options.changedAfterSequence, (tid, key) => context.addDirty(tid, key));\n }\n // Rows touched by a command the server has not executed yet keep their optimistic state until its result settles them.\n for (const r of await connection.query('SELECT r.tid, r.pk FROM g9_command_rows r JOIN g9_commands c ON c.command_id = r.command_id WHERE c.state = 0')) {\n context.addDirty(asNumber(r[0]), asString(r[1]));\n }\n }\n\n context.hasRevoked = (await connection.scalar('SELECT 1 FROM g9_revoked LIMIT 1')) !== null;\n\n const definitions = readPersistedDefinitions(await meta(connection, 'definitions_json'));\n const policyByName = new Map<string, G9EMoveOutPolicy>();\n for (const d of definitions) policyByName.set(d.name, d.moveOutPolicy);\n for (const record of await readSubscriptions(connection, null)) {\n context.subscriptions.set(record.key, { slot: record.slot, ephemeral: record.ephemeral });\n context.policies.set(record.key, policyByName.get(record.name) ?? G9EMoveOutPolicy.Delete);\n }\n for (const backfill of options.backfills ?? []) context.backfillColumns.set(backfill.tableId, backfill.columns);\n\n const diagnostics = context.report.diagnostics;\n diagnostics.transactions = 1;\n if (store.options.skipTriggersDuringApply) {\n const foreign = await foreignTriggerNames(store, connection);\n if (foreign.length > 0) {\n for (const name of foreign.slice(0, 10)) diagnostics.foreignTriggers.push(name);\n } else if (options.skipTriggers) {\n // No SQLITE_DBCONFIG_ENABLE_TRIGGER through a driver: the library's own triggers leave for the apply and come back,\n // byte for byte, before the commit (PARITY.md). DDL is transactional: readers never see them gone.\n const rows = await connection.query(\"SELECT name, sql FROM sqlite_master WHERE type = 'trigger' AND sql IS NOT NULL ORDER BY name\");\n for (const r of rows) {\n const name = asString(r[0]);\n if (!isLibraryTrigger(store, name)) continue;\n context.droppedTriggers.push({ name, sql: asString(r[1]) });\n }\n for (const trigger of context.droppedTriggers) await connection.exec('DROP TRIGGER ' + quote(trigger.name));\n if (context.droppedTriggers.length > 0) diagnostics.transactionsWithTriggersSkipped = 1;\n }\n }\n if (options.snapshotRows && store.options.rebuildIndexesAfterRows > 0) await deferIndexes(store, context, options.snapshotRows);\n return context;\n}\n\n/** `EndApply`: rebuilds deferred indexes, re-creates dropped triggers, clears the applying flag. */\nexport async function endApply(context: ApplyContext): Promise<void> {\n await context.flush();\n if (context.deferredIndexes.length > 0) {\n const started = Date.now();\n for (const index of context.deferredIndexes) await context.connection.exec(index.sql);\n context.deferredIndexes.length = 0;\n context.report.diagnostics.indexRebuildMs += Date.now() - started;\n }\n if (context.droppedTriggers.length > 0) {\n for (const trigger of context.droppedTriggers) await context.connection.runStatements([{ sql: trigger.sql, params: [] }]);\n context.droppedTriggers.length = 0;\n }\n context.publishTableTimes();\n await context.connection.exec('UPDATE g9_ctx SET applying = 0 WHERE id = 1');\n}\n\n/** `g9_{table}_{ai|au|ad|ci|cu|cd}` for a table of the model. */\nexport function isLibraryTrigger(store: StoreInternals, name: string): boolean {\n const separator = name.lastIndexOf('_');\n if (separator <= 3 || name.slice(0, 3).toLowerCase() !== 'g9_') return false;\n const suffix = name.slice(separator + 1).toLowerCase();\n return ['ai', 'au', 'ad', 'ci', 'cu', 'cd'].indexOf(suffix) >= 0 && store.byLocal.has(name.slice(3, separator).toLowerCase());\n}\n\n/** The triggers the library did not create. */\nexport async function foreignTriggerNames(store: StoreInternals, connection: G9SqliteConnection): Promise<string[]> {\n const foreign: string[] = [];\n for (const r of await connection.query(\"SELECT name FROM sqlite_master WHERE type = 'trigger' ORDER BY name\")) {\n const name = asString(r[0]);\n if (!isLibraryTrigger(store, name)) foreign.push(name);\n }\n return foreign;\n}\n\n/** Rows changed after a sequence, table by table (`g9_rows_feed (tid, local_seq)` serves each read). */\nexport async function readRowsChangedAfter(store: StoreInternals, connection: G9SqliteConnection, sequence: number, add: (tid: number, key: string) => void): Promise<void> {\n for (const table of store.byLocal.values()) {\n for (const r of await connection.query('SELECT pk FROM g9_rows WHERE tid = $t AND local_seq > $c', { $t: table.tid, $c: sequence })) add(table.tid, asString(r[0]));\n }\n}\n\n/** Rows each table receives from snapshot parts of a plan, by server table id. */\nexport function snapshotRowsByTable(plan: G9DtPullPlan): Map<number, number> {\n const out = new Map<number, number>();\n for (const part of plan.parts) {\n if (part.kind === G9EPullPartKind.Snapshot) out.set(part.tableId, (out.get(part.tableId) ?? 0) + part.rows);\n }\n return out;\n}\n\n/** Drops the plain indexes of tables a large snapshot fills (`DeferIndexes`, ADR-0034/0058). */\nasync function deferIndexes(store: StoreInternals, context: ApplyContext, snapshotRows: Map<number, number>): Promise<void> {\n const connection = context.connection;\n for (const [serverTableId, rows] of Array.from(snapshotRows.entries())) {\n const table = store.byServerId.get(serverTableId);\n if (rows < store.options.rebuildIndexesAfterRows || !table) continue;\n if ((await connection.scalar(`SELECT 1 FROM ${table.quoted} LIMIT 1`)) !== null) {\n const growth = store.options.rebuildIndexesMinimumGrowth;\n const existing = growth > 0 ? asNumber(await connection.scalar(`SELECT count(*) FROM ${table.quoted}`)) : Number.MAX_SAFE_INTEGER;\n if (growth <= 0 || rows < existing * growth) {\n context.report.diagnostics.liveIndexReasons[table.model.localName] = REASON_TABLE_NOT_EMPTY;\n continue;\n }\n }\n const indexes = (\n await connection.query(\n \"SELECT m.name, m.sql FROM pragma_index_list($t) AS i JOIN sqlite_master AS m ON m.type = 'index' AND m.name = i.name \" +\n 'WHERE i.origin = \\'c\\' AND i.\"unique\" = 0 AND m.sql IS NOT NULL',\n { $t: table.model.localName },\n )\n ).map((r) => ({ name: asString(r[0]), sql: asString(r[1]) }));\n for (const index of indexes) {\n await connection.exec('DROP INDEX ' + quote(index.name));\n context.deferredIndexes.push(index);\n }\n if (indexes.length === 0) continue;\n context.report.diagnostics.deferredIndexes[table.model.localName] = indexes.length;\n store.log('debug', 20111, `G9SyncData loads ${rows} row(s) into ${table.model.localName}: ${indexes.length} index(es) rebuilt after the load`);\n }\n}\n\n/** `synchronous=NORMAL` while a transaction writes only server-derived data (WAL only); returns the restore action. */\nexport async function downloadDurability(store: StoreInternals, connection: G9SqliteConnection): Promise<(() => Promise<void>) | null> {\n if (!store.options.synchronousNormalForDownloads) return null;\n if (asString(await connection.scalar('PRAGMA journal_mode')).toLowerCase() !== 'wal') return null;\n const previous = asNumber(await connection.scalar('PRAGMA synchronous'));\n if (previous <= 1) return null;\n await connection.exec('PRAGMA synchronous = NORMAL');\n return async () => {\n await connection.exec('PRAGMA synchronous = ' + previous);\n };\n}\n\n/** Applies one frame (`ApplyFrame`). */\nexport async function applyFrame(store: StoreInternals, context: ApplyContext, frame: Uint8Array, subscriptionKey: string | null): Promise<void> {\n let slot = -1;\n let ephemeral = false;\n let policy: G9EMoveOutPolicy = G9EMoveOutPolicy.Delete;\n if (subscriptionKey !== null) {\n const subscription = context.subscriptions.get(subscriptionKey);\n if (subscription) {\n slot = subscription.slot;\n ephemeral = subscription.ephemeral;\n policy = context.policies.get(subscriptionKey) ?? G9EMoveOutPolicy.Delete;\n }\n }\n const reader = await openRowBatch(frame, { maxBodyBytes: store.options.maxDecodedFrameBytes, decompressor: store.options.frameDecompressor });\n while (reader.nextSection()) {\n const table = store.byServerId.get(reader.tableId);\n if (!table || !table.negotiated) continue;\n const started = Date.now();\n const rowsBefore = context.rows;\n switch (reader.op) {\n case G9ERowBatchOp.Upsert:\n await applyUpserts(store, context, reader, table, slot, ephemeral ? subscriptionKey : null);\n break;\n case G9ERowBatchOp.Backfill:\n await applyBackfill(store, context, reader, table);\n break;\n case G9ERowBatchOp.Tombstone:\n while (reader.readRow()) await applyTombstone(context, table, reader.key, reader.version);\n break;\n case G9ERowBatchOp.MoveOut:\n while (reader.readRow()) {\n if (slot >= 0) await moveOut(store, context, table, reader.key, subscriptionKey as string, slot, ephemeral, policy);\n }\n break;\n }\n context.addTableTime(table.model.localName, context.rows - rowsBefore, Date.now() - started);\n }\n}\n\n/** The download row path (`ApplyUpserts`): a guarded upsert and a metadata upsert per row, batched. */\nasync function applyUpserts(store: StoreInternals, context: ApplyContext, reader: G9RowBatchReader, table: LocalTable, slot: number, ephemeralKey: string | null): Promise<void> {\n const columns = (table.negotiated as G9DtNegotiatedTable).columns;\n if (reader.columnCount !== columns.length) {\n throw new G9RowBatchFormatError(`${table.model.localName}: the frame has ${reader.columnCount} columns, ${columns.length} were negotiated.`);\n }\n const targets: { name: string; type: number; frame: number }[] = [];\n columns.forEach((c, i) => {\n if (table.model.indexOf(c.name) >= 0) targets.push({ name: c.name, type: c.type, frame: i });\n });\n const membership = slot >= 0 ? bit(slot).toSqlValue() : 0;\n const names = targets.map((t) => quote(t.name));\n // The update half is guarded (ADR-0058): a row that already holds exactly these values is not rewritten. IS NOT, so\n // NULLs compare; excluded.* carries the column's affinity.\n const upsertSql =\n `INSERT INTO ${table.quoted} (${table.keyQuoted}${names.map((n) => ', ' + n).join('')}) VALUES (?1${names.map((_, i) => ', ?' + (i + 2)).join('')}) ` +\n (names.length === 0\n ? `ON CONFLICT(${table.keyQuoted}) DO NOTHING`\n : `ON CONFLICT(${table.keyQuoted}) DO UPDATE SET ${names.map((n) => n + ' = excluded.' + n).join(', ')} WHERE ${names.map((n) => n + ' IS NOT excluded.' + n).join(' OR ')}`);\n // One statement for both of the .NET store's metadata statements: when the row upsert just changed the row (changes() of\n // the statement before), the metadata is rewritten; otherwise only when the metadata itself differs.\n const metaSql =\n 'INSERT INTO g9_rows (tid, pk, server_ver, local_seq, subs, dirty, dirty_mask, rejected, deleted) VALUES (?1, ?2, ?3, ' +\n NEXT_SEQ +\n ', ?4, 0, 0, 0, 0) ' +\n 'ON CONFLICT(tid, pk) DO UPDATE SET server_ver = excluded.server_ver, local_seq = excluded.local_seq, subs = subs | excluded.subs, ' +\n 'dirty = 0, dirty_mask = 0, rejected = 0, deleted = 0 ' +\n 'WHERE changes() > 0 OR server_ver IS NOT excluded.server_ver OR (subs | excluded.subs) <> subs OR dirty <> 0 OR dirty_mask <> 0 OR rejected <> 0 OR deleted <> 0';\n const dirtyTable = context.hasDirty(table.tid);\n const localName = table.model.localName;\n\n while (reader.readRow()) {\n const key = reader.key;\n if (dirtyTable && context.isDirty(table.tid, key)) {\n if (slot >= 0) await addMembership(context, table, key, slot, ephemeralKey);\n context.report.skippedDirty++;\n context.tick();\n continue;\n }\n const values: G9SqlValue[] = [keyValue(table, key)];\n for (const target of targets) values.push(frameValueToSql(reader, target.frame, target.type, store.options));\n const statements = [\n { sql: upsertSql, params: values },\n { sql: metaSql, params: [table.tid, key, reader.versionLong.toSqlValue(), membership] },\n { sql: BUMP_IF_CHANGED, params: [] },\n ];\n if (ephemeralKey !== null) statements.push({ sql: 'INSERT OR IGNORE INTO g9_ephemeral_rows (sub_key, tid, pk) VALUES (?1, ?2, ?3)', params: [ephemeralKey, table.tid, key] });\n if (context.hasRevoked && slot >= 0) {\n statements.push({ sql: 'DELETE FROM g9_revoked WHERE tid = ?1 AND pk = ?2', params: [table.tid, key] });\n statements.push({ sql: 'DELETE FROM g9_rejections WHERE tid = ?1 AND pk = ?2 AND code = ?3', params: [table.tid, key, REVOKED_REJECTION_CODE] });\n }\n const full = context.batch.addStatements(statements, (results) => {\n const changed = ((results[0] as G9SqlResult).changes ?? 0) > 0;\n if (!changed) context.report.unchangedRows++;\n context.report.upserts++;\n if (changed && context.wantsChangedKey(localName)) context.addChanged(localName, key);\n });\n context.tick();\n if (full) await context.flush();\n }\n}\n\n/** `ApplyBackfill`: only the backfilled columns of rows the client already holds. */\nasync function applyBackfill(store: StoreInternals, context: ApplyContext, reader: G9RowBatchReader, table: LocalTable): Promise<void> {\n const names = context.backfillColumns.get((table.negotiated as G9DtNegotiatedTable).tableId);\n if (!names || names.length !== reader.columnCount) {\n while (reader.readRow()) {\n // skip\n }\n return;\n }\n const targets: { name: string; index: number; local: number }[] = [];\n names.forEach((name, i) => {\n const local = table.model.indexOf(name);\n if (local >= 0) targets.push({ name, index: i, local });\n });\n if (targets.length === 0) return;\n const sql = `UPDATE ${table.quoted} SET ${targets.map((t, i) => quote(t.name) + ' = ?' + (i + 1)).join(', ')} WHERE ${table.keyQuoted} = ?${targets.length + 1}`;\n while (reader.readRow()) {\n const key = reader.key;\n if (context.isDirty(table.tid, key)) {\n context.report.skippedDirty++;\n continue;\n }\n const params: G9SqlValue[] = targets.map((t) => frameValueToSql(reader, t.index, (table.model.columns[t.local] as { type: number }).type, store.options));\n params.push(keyValue(table, key));\n if (context.batch.addStatements([{ sql, params }])) await context.flush();\n context.tick();\n }\n}\n\n/** `ApplyTombstone`. */\nasync function applyTombstone(context: ApplyContext, table: LocalTable, key: string, version: number): Promise<void> {\n if (context.isDirty(table.tid, key)) {\n context.report.skippedDirty++;\n return;\n }\n const localName = table.model.localName;\n const full = context.batch.addStatements(\n [\n { sql: `DELETE FROM ${table.quoted} WHERE ${table.keyQuoted} = ?1`, params: [keyValue(table, key)] },\n {\n sql: 'UPDATE g9_rows SET deleted = 1, subs = 0, server_ver = ?1, local_seq = ' + NEXT_SEQ + ', dirty = 0, dirty_mask = 0 WHERE tid = ?2 AND pk = ?3 AND deleted = 0',\n params: [version, table.tid, key],\n },\n { sql: 'DELETE FROM g9_ephemeral_rows WHERE tid = ?1 AND pk = ?2', params: [table.tid, key] },\n { sql: BUMP, params: [] },\n ],\n (results) => {\n if (((results[0] as G9SqlResult).changes ?? 0) > 0) {\n context.report.deletes++;\n context.addChanged(localName, key);\n }\n },\n );\n context.tick();\n if (full) await context.flush();\n}\n\n/** `MoveOut`: drops the membership; with a Delete policy a row nobody holds goes through the revocation policy. */\nexport async function moveOut(\n store: StoreInternals,\n context: ApplyContext,\n table: LocalTable,\n key: string,\n subscriptionKey: string,\n slot: number,\n ephemeral: boolean,\n policy: G9EMoveOutPolicy,\n): Promise<void> {\n if (ephemeral) {\n context.batch.add('DELETE FROM g9_ephemeral_rows WHERE sub_key = $k AND tid = $t AND pk = $pk', { $k: subscriptionKey, $t: table.tid, $pk: key });\n context.batch.add('UPDATE g9_rows SET subs = subs & $n WHERE tid = $t AND pk = $pk AND NOT EXISTS (SELECT 1 FROM g9_ephemeral_rows WHERE tid = $t AND pk = $pk)', {\n $n: bit(EPHEMERAL_SLOT).not(),\n $t: table.tid,\n $pk: key,\n });\n } else {\n context.batch.add('UPDATE g9_rows SET subs = subs & $n WHERE tid = $t AND pk = $pk', { $n: bit(slot).not(), $t: table.tid, $pk: key });\n }\n context.report.moveOuts++;\n if (policy !== G9EMoveOutPolicy.Delete) {\n if (context.batch.count >= store.options.statementsPerBatch) await context.flush();\n return;\n }\n // No subscription holds it any more? The revocation policy decides (ADR-0026). It reads the row: run what is queued first.\n await context.flush();\n const removed = await disposeReleasedRow(store, context.connection, table, key, G9ERevocationReason.LeftScope, subscriptionKey, context.report);\n await context.connection.exec(BUMP);\n if (removed) context.addChanged(table.model.localName, key);\n}\n\n/** `AddMembership`. */\nexport async function addMembership(context: ApplyContext, table: LocalTable, key: string, slot: number, ephemeralKey: string | null): Promise<void> {\n context.batch.add('UPDATE g9_rows SET subs = subs | $b WHERE tid = $t AND pk = $pk AND deleted = 0', { $b: bit(slot), $t: table.tid, $pk: key });\n if (ephemeralKey !== null) context.batch.add('INSERT OR IGNORE INTO g9_ephemeral_rows (sub_key, tid, pk) VALUES ($k, $t, $pk)', { $k: ephemeralKey, $t: table.tid, $pk: key });\n}\n\n/** The rows an apply must not touch, read before the first slice commits (`ReadProtectedRows`). */\nasync function readProtectedRows(store: StoreInternals, connection: G9SqliteConnection, changedAfterSequence: number): Promise<{ tid: number; key: string }[]> {\n const rows: { tid: number; key: string }[] = [];\n for (const r of await connection.query('SELECT tid, pk FROM g9_rows WHERE dirty <> 0')) rows.push({ tid: asNumber(r[0]), key: asString(r[1]) });\n await readRowsChangedAfter(store, connection, changedAfterSequence, (tid, key) => rows.push({ tid, key }));\n for (const r of await connection.query('SELECT r.tid, r.pk FROM g9_command_rows r JOIN g9_commands c ON c.command_id = r.command_id WHERE c.state = 0')) {\n rows.push({ tid: asNumber(r[0]), key: asString(r[1]) });\n }\n return rows;\n}\n\n/** `ApplyStagedPullAsync`: atomic, or in committed slices (ADR-0053); cursors move only with the last slice. */\nexport async function applyStagedPull(\n store: StoreInternals,\n runId: string,\n rowsApplied: ((rows: number) => void) | null,\n slices: ((slice: G9ApplySlice) => void) | null,\n readStagedRun: (connection: G9SqliteConnection, runId: string) => Promise<import('../client/storeTypes.js').G9StagedPull | null>,\n signal?: AbortSignal,\n): Promise<G9ApplyReport> {\n store.ensureInitialized();\n return store.writeLock.run(async () => {\n const connection = store.writer();\n const restore = await downloadDurability(store, connection);\n try {\n const staged = await readStagedRun(connection, runId);\n if (!staged) throw new G9SyncException(G9SyncErrorCodes.LocalStoreError, 'The staged pull no longer exists.');\n const sequences = (await connection.query('SELECT seq FROM g9_stage WHERE run_id = $r AND payload IS NOT NULL ORDER BY seq', { $r: runId })).map((r) => asNumber(r[0]));\n\n // Slicing only pays for itself when someone is listening for the slices (ADR-0053); a LARGE snapshot stays in one\n // transaction with its indexes deferred (ADR-0056/0058).\n const sliceRows = slices === null ? 0 : store.options.applySliceRows;\n const snapshotRows = snapshotRowsByTable(staged.plan);\n let largeSnapshot = false;\n if (store.options.rebuildIndexesAfterRows > 0) snapshotRows.forEach((rows) => (largeSnapshot = largeSnapshot || rows >= store.options.rebuildIndexesAfterRows));\n const progressive = sliceRows > 0 && sequences.length > 1 && !largeSnapshot;\n // Read ONCE, before any slice commits (ADR-0046 + ADR-0053).\n const protectedRows = progressive ? await readProtectedRows(store, connection, staged.stageSequence) : null;\n const skipTriggers = staged.plan.totalRows >= store.options.skipTriggersMinRows && !progressive;\n\n const total = new G9ApplyReport();\n let appliedTotal = 0;\n let index = 0;\n const started = Date.now();\n let sliceBudget = sliceRows;\n\n // do/while: a pull with no payload chunks still writes its cursors and clears its stage, exactly once.\n do {\n if (signal && signal.aborted) throw cancellation();\n const slice: number[] = [];\n let final = true;\n for (; index < sequences.length; index++) {\n slice.push(sequences[index] as number);\n if (!progressive) continue;\n if ((await stagedRowCount(connection, runId, slice)) >= sliceBudget && index + 1 < sequences.length) {\n index++;\n final = false;\n break;\n }\n }\n if (store.options.applySliceRowsMax > sliceBudget) sliceBudget = Math.min(store.options.applySliceRowsMax, sliceBudget * 2);\n\n let context: ApplyContext | null = null;\n const syncedUpdates: { table: LocalTable; synced: string[] }[] = [];\n await connection.transaction('immediate', async () => {\n context = await beginApply(store, connection, {\n progress: rowsApplied,\n backfills: staged.backfills,\n snapshotRows: progressive ? null : snapshotRows,\n changedAfterSequence: staged.stageSequence,\n protectedRows,\n skipTriggers,\n signal,\n });\n for (const sequence of slice) {\n if (signal && signal.aborted) throw cancellation();\n const rows = await connection.query('SELECT payload, subscription_key FROM g9_stage WHERE run_id = $r AND seq = $s', { $r: runId, $s: sequence });\n const row = rows[0];\n if (!row) continue;\n const payload = row[0];\n if (!(payload instanceof ArrayBuffer)) continue;\n await applyFrame(store, context, new Uint8Array(payload), row[1] === null ? null : asString(row[1]));\n }\n\n if (final) {\n // Cursors move only here, and only when still the one the plan started from (ADR-0060; IS, a first pull plans from NULL).\n for (const cursor of staged.plan.cursors) {\n const update =\n 'UPDATE g9_subscriptions SET cursor = $c, definition_hash = $d, auth_hash = $a, state = 0, error_code = NULL, last_success_utc = $now WHERE key = $k';\n const params = { $c: cursor.cursor, $d: cursor.definitionHash, $a: cursor.authHash, $now: nowMs(), $k: cursor.key };\n if (Object.prototype.hasOwnProperty.call(staged.plannedFromCursors, cursor.key)) {\n await context.flush();\n await connection.exec(update + ' AND cursor IS $from', { ...params, $from: staged.plannedFromCursors[cursor.key] ?? null });\n } else {\n await context.flush();\n await connection.exec(update, params);\n }\n }\n for (const backfill of staged.backfills) {\n const table = store.byServerId.get(backfill.tableId);\n if (!table) continue;\n const synced = table.syncedColumns.slice();\n for (const column of backfill.columns) if (!synced.some((s) => s.toLowerCase() === column.toLowerCase())) synced.push(column);\n await connection.exec('UPDATE g9_tables SET synced_columns = $c WHERE tid = $t', { $c: persistedJson(synced), $t: table.tid });\n syncedUpdates.push({ table, synced });\n }\n }\n\n await endApply(context);\n if (slice.length > 0) await connection.exec('DELETE FROM g9_stage WHERE run_id = $r AND seq IN (' + slice.join(',') + ')', { $r: runId });\n if (final) await connection.exec('DELETE FROM g9_stage_runs WHERE run_id = $r', { $r: runId });\n });\n\n const applied = context as unknown as ApplyContext;\n for (const { table, synced } of syncedUpdates) table.syncedColumns = synced;\n appliedTotal += applied.rows;\n total.merge(applied.report);\n rowsApplied?.(appliedTotal);\n slices?.({ report: applied.report, rowsApplied: applied.rows, rowsAppliedTotal: appliedTotal, rowsPlanned: staged.plan.totalRows, isFinal: final });\n } while (index < sequences.length);\n\n total.diagnostics.elapsedMs = Date.now() - started;\n if (total.diagnostics.transactions > 0 && appliedTotal > 0) store.log('information', 20112, `G9SyncData applied ${appliedTotal} row(s): ${total.diagnostics.toString()}`);\n await maintainAfterApply(store, connection, appliedTotal);\n return total;\n } finally {\n if (restore) await restore();\n }\n });\n}\n\nfunction cancellation(): Error {\n const error = new Error('The operation was canceled.');\n error.name = 'AbortError';\n return error;\n}\n\nasync function stagedRowCount(connection: G9SqliteConnection, runId: string, slice: number[]): Promise<number> {\n return asNumber(await connection.scalar('SELECT coalesce(sum(row_count), 0) FROM g9_stage WHERE run_id = $r AND seq IN (' + slice.join(',') + ')', { $r: runId }));\n}\n\n/** Best-effort housekeeping after a large apply (`MaintainAfterApply`): planner statistics and one WAL checkpoint attempt. */\nasync function maintainAfterApply(store: StoreInternals, connection: G9SqliteConnection, appliedRows: number): Promise<void> {\n if (store.options.maintenanceAfterRows <= 0 || appliedRows < store.options.maintenanceAfterRows) return;\n try {\n await connection.exec('PRAGMA analysis_limit = 1000; PRAGMA optimize;');\n if (asString(await connection.scalar('PRAGMA journal_mode')).toLowerCase() !== 'wal') return;\n await connection.exec('PRAGMA busy_timeout = 250');\n try {\n const rows = await connection.query('PRAGMA wal_checkpoint(TRUNCATE)');\n if (rows[0] && asNumber(rows[0][0]) !== 0) {\n store.log('debug', 20113, `The WAL checkpoint after applying ${appliedRows} row(s) was blocked by a reader; the next one retries`);\n }\n } finally {\n await connection.exec('PRAGMA busy_timeout = ' + store.options.busyTimeoutMs);\n }\n } catch (error) {\n store.log('warning', 20114, `Maintenance after an apply failed and was skipped: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/** `ApplyReconcileAsync`. */\nexport async function applyReconcile(\n store: StoreInternals,\n subscriptionKey: string,\n table: G9DtNegotiatedTable,\n fetchedFrames: readonly Uint8Array[],\n addMembershipKeys: readonly string[],\n moveOutKeys: readonly string[],\n policy: G9EMoveOutPolicy,\n signal?: AbortSignal,\n): Promise<G9ApplyReport> {\n store.ensureInitialized();\n const local = findByServerName(store, table.name);\n if (!local) throw new RangeError(`'${table.name}' is not a synced table.`);\n return store.writeLock.run(async () => {\n const connection = store.writer();\n const restore = await downloadDurability(store, connection);\n try {\n return await connection.transaction('immediate', async () => {\n const context = await beginApply(store, connection, { backfills: [], signal });\n context.policies.set(subscriptionKey, policy);\n for (const frame of fetchedFrames) await applyFrame(store, context, frame, subscriptionKey);\n const subscription = context.subscriptions.get(subscriptionKey);\n if (subscription) {\n for (const key of addMembershipKeys) {\n await addMembership(context, local, key, subscription.slot, subscription.ephemeral ? subscriptionKey : null);\n context.report.membershipAdded++;\n }\n for (const key of moveOutKeys) await moveOut(store, context, local, key, subscriptionKey, subscription.slot, subscription.ephemeral, policy);\n }\n await endApply(context);\n return context.report;\n });\n } finally {\n if (restore) await restore();\n }\n });\n}\n\n/** For callers that need a G9Long bit as a bind value. */\nexport function bitValue(slot: number): G9Long {\n return bit(slot);\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { G9ELocalCommandState, type G9CommandRequest, type G9LocalCommand, type G9LocalCommandWriter } from '../client/storeTypes.js';
|
|
2
|
+
import { type G9DtCommand, type G9DtCommandResult } from '../protocol/dtos.js';
|
|
3
|
+
import { type G9SqliteConnection } from './connection.js';
|
|
4
|
+
import { type StoreInternals } from './internals.js';
|
|
5
|
+
/** `RecordCommand`. */
|
|
6
|
+
export declare function recordCommand(connection: G9SqliteConnection, request: G9CommandRequest): Promise<G9LocalCommand>;
|
|
7
|
+
/** From here until endCommandEffects, writes on this connection are the command's effects (command triggers). */
|
|
8
|
+
export declare function beginCommandEffects(connection: G9SqliteConnection, commandId: string): Promise<void>;
|
|
9
|
+
export declare function endCommandEffects(connection: G9SqliteConnection): Promise<void>;
|
|
10
|
+
/** The writer handed to `applyLocally` (`LocalCommandWriter`): parameters bind positionally as `$p0`, `$p1`, … */
|
|
11
|
+
export declare function localCommandWriter(connection: G9SqliteConnection): G9LocalCommandWriter;
|
|
12
|
+
/** `EnqueueCommandAsync` on the store's own connection. */
|
|
13
|
+
export declare function enqueueCommand(store: StoreInternals, request: G9CommandRequest, applyLocally: ((writer: G9LocalCommandWriter, signal?: AbortSignal) => Promise<void>) | null, signal?: AbortSignal): Promise<G9LocalCommand>;
|
|
14
|
+
export declare function getCommands(store: StoreInternals, state: G9ELocalCommandState | null, limit: number): Promise<G9LocalCommand[]>;
|
|
15
|
+
/** Pending commands for a push batch, with the rows each touched (`ReadPendingCommands`). */
|
|
16
|
+
export declare function readPendingCommands(store: StoreInternals, connection: G9SqliteConnection, inflightBatch: string | null, limit: number): Promise<G9DtCommand[]>;
|
|
17
|
+
/** Records server outcomes and releases the rows those commands protected (`CompleteCommands`). */
|
|
18
|
+
export declare function completeCommands(connection: G9SqliteConnection, results: readonly G9DtCommandResult[]): Promise<number>;
|
|
19
|
+
/**
|
|
20
|
+
* Records a command inside a transaction the APP owns on its own connection (the twin of the .NET overload taking the
|
|
21
|
+
* app's `sqlite3` handle): a SAVEPOINT of that transaction, so the command and the effects the app writes in
|
|
22
|
+
* `applyLocally` commit or roll back together with it. Without `tx` it is its own BEGIN IMMEDIATE transaction.
|
|
23
|
+
*/
|
|
24
|
+
export declare function enqueueCommandOnConnection(connection: G9SqliteConnection, request: G9CommandRequest, applyLocally: (() => Promise<void>) | null): Promise<G9LocalCommand>;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// Twin of G9SyncData.Client.Sqlite/G9CSqliteSyncStore.Commands.cs: the command outbox (ADR-0025). A command is recorded
|
|
2
|
+
// atomically with its local effects; while g9_ctx.applying = 2 the capture triggers stay silent and the command triggers
|
|
3
|
+
// record the touched rows instead; those rows are protected from pulls until the command's result settles them.
|
|
4
|
+
import { newGuid } from '../abstractions/guid.js';
|
|
5
|
+
import { G9Long } from '../abstractions/long.js';
|
|
6
|
+
import { G9ELocalCommandState, } from '../client/storeTypes.js';
|
|
7
|
+
import { G9ECommandStatus } from '../protocol/dtos.js';
|
|
8
|
+
import { asNumber, asOptionalString, asString, toSqlValue } from './connection.js';
|
|
9
|
+
import { byTid, meta, nowMs, setMeta } from './internals.js';
|
|
10
|
+
/** Completed commands are kept this long for the app to inspect, then deleted. */
|
|
11
|
+
const COMMAND_HISTORY_MS = 30 * 24 * 60 * 60 * 1000;
|
|
12
|
+
/** `RecordCommand`. */
|
|
13
|
+
export async function recordCommand(connection, request) {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
const sequence = Number((_a = (await meta(connection, 'next_command_seq'))) !== null && _a !== void 0 ? _a : '1');
|
|
16
|
+
await setMeta(connection, 'next_command_seq', String(sequence + 1));
|
|
17
|
+
const commandId = newGuid();
|
|
18
|
+
const created = nowMs();
|
|
19
|
+
const version = (_b = request.version) !== null && _b !== void 0 ? _b : 1;
|
|
20
|
+
await connection.exec('INSERT INTO g9_commands (command_id, seq, name, version, payload, created_utc, state) VALUES ($id, $seq, $name, $version, $payload, $created, 0)', { $id: commandId, $seq: sequence, $name: request.name, $version: version, $payload: request.payload, $created: created });
|
|
21
|
+
return {
|
|
22
|
+
commandId,
|
|
23
|
+
sequence,
|
|
24
|
+
name: request.name,
|
|
25
|
+
version,
|
|
26
|
+
payload: request.payload,
|
|
27
|
+
createdUtcMs: created,
|
|
28
|
+
state: G9ELocalCommandState.Pending,
|
|
29
|
+
code: null,
|
|
30
|
+
message: null,
|
|
31
|
+
result: null,
|
|
32
|
+
completedUtcMs: null,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** From here until endCommandEffects, writes on this connection are the command's effects (command triggers). */
|
|
36
|
+
export async function beginCommandEffects(connection, commandId) {
|
|
37
|
+
await connection.exec('UPDATE g9_ctx SET applying = 2, command_id = $id WHERE id = 1', { $id: commandId });
|
|
38
|
+
}
|
|
39
|
+
export async function endCommandEffects(connection) {
|
|
40
|
+
await connection.exec('UPDATE g9_ctx SET applying = 0, command_id = NULL WHERE id = 1');
|
|
41
|
+
}
|
|
42
|
+
/** The writer handed to `applyLocally` (`LocalCommandWriter`): parameters bind positionally as `$p0`, `$p1`, … */
|
|
43
|
+
export function localCommandWriter(connection) {
|
|
44
|
+
const bind = (args) => {
|
|
45
|
+
const params = {};
|
|
46
|
+
args.forEach((arg, i) => (params['$p' + i] = toSqlValue(arg instanceof G9Long || arg instanceof Uint8Array || typeof arg === 'boolean' ? arg : arg)));
|
|
47
|
+
return params;
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
execute: (sql, ...args) => connection.exec(sql, bind(args)),
|
|
51
|
+
scalar: (sql, ...args) => connection.scalar(sql, bind(args)),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** `EnqueueCommandAsync` on the store's own connection. */
|
|
55
|
+
export async function enqueueCommand(store, request, applyLocally, signal) {
|
|
56
|
+
if (!request || typeof request.name !== 'string' || request.name.trim() === '')
|
|
57
|
+
throw new TypeError('A command name is required.');
|
|
58
|
+
store.ensureInitialized();
|
|
59
|
+
return store.writeLock.run(() => store.writer().transaction('immediate', async () => {
|
|
60
|
+
const connection = store.writer();
|
|
61
|
+
const command = await recordCommand(connection, request);
|
|
62
|
+
if (applyLocally) {
|
|
63
|
+
await beginCommandEffects(connection, command.commandId);
|
|
64
|
+
await applyLocally(localCommandWriter(connection), signal);
|
|
65
|
+
await endCommandEffects(connection);
|
|
66
|
+
}
|
|
67
|
+
return command;
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
export async function getCommands(store, state, limit) {
|
|
71
|
+
store.ensureInitialized();
|
|
72
|
+
const rows = await store
|
|
73
|
+
.reader()
|
|
74
|
+
.query('SELECT command_id, seq, name, version, payload, created_utc, state, code, message, result, completed_utc FROM g9_commands ' +
|
|
75
|
+
(state === null ? '' : 'WHERE state = $state ') +
|
|
76
|
+
'ORDER BY seq DESC LIMIT $limit', state === null ? { $limit: Math.max(1, limit) } : { $state: state, $limit: Math.max(1, limit) });
|
|
77
|
+
return rows.map((r) => ({
|
|
78
|
+
commandId: asString(r[0]),
|
|
79
|
+
sequence: asNumber(r[1]),
|
|
80
|
+
name: asString(r[2]),
|
|
81
|
+
version: asNumber(r[3]),
|
|
82
|
+
payload: asString(r[4]),
|
|
83
|
+
createdUtcMs: asNumber(r[5]),
|
|
84
|
+
state: asNumber(r[6]),
|
|
85
|
+
code: asOptionalString(r[7]),
|
|
86
|
+
message: asOptionalString(r[8]),
|
|
87
|
+
result: asOptionalString(r[9]),
|
|
88
|
+
completedUtcMs: r[10] === null ? null : asNumber(r[10]),
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
/** Pending commands for a push batch, with the rows each touched (`ReadPendingCommands`). */
|
|
92
|
+
export async function readPendingCommands(store, connection, inflightBatch, limit) {
|
|
93
|
+
const rows = await connection.query('SELECT command_id, seq, name, version, payload, created_utc FROM g9_commands WHERE state = 0' +
|
|
94
|
+
// A retried batch carries exactly its own commands; a new batch takes every pending one.
|
|
95
|
+
(inflightBatch === null ? '' : ' AND batch_id = $inflight') +
|
|
96
|
+
' ORDER BY seq LIMIT $limit', inflightBatch === null ? { $limit: Math.max(1, limit) } : { $inflight: Number(inflightBatch), $limit: Math.max(1, limit) });
|
|
97
|
+
const commands = rows.map((r) => ({
|
|
98
|
+
commandId: asString(r[0]),
|
|
99
|
+
sequence: asNumber(r[1]),
|
|
100
|
+
name: asString(r[2]),
|
|
101
|
+
version: asNumber(r[3]),
|
|
102
|
+
payload: asString(r[4]),
|
|
103
|
+
createdUtcMs: asNumber(r[5]),
|
|
104
|
+
touched: [],
|
|
105
|
+
}));
|
|
106
|
+
for (const item of commands) {
|
|
107
|
+
for (const r of await connection.query('SELECT tid, pk FROM g9_command_rows WHERE command_id = $id', { $id: item.commandId })) {
|
|
108
|
+
const local = byTid(store, asNumber(r[0]));
|
|
109
|
+
if (!local || !local.negotiated)
|
|
110
|
+
continue;
|
|
111
|
+
item.touched.push({ tableId: local.negotiated.tableId, key: asString(r[1]) });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return commands;
|
|
115
|
+
}
|
|
116
|
+
/** Records server outcomes and releases the rows those commands protected (`CompleteCommands`). */
|
|
117
|
+
export async function completeCommands(connection, results) {
|
|
118
|
+
var _a, _b, _c;
|
|
119
|
+
let completed = 0;
|
|
120
|
+
const now = nowMs();
|
|
121
|
+
for (const result of results) {
|
|
122
|
+
const state = result.status === G9ECommandStatus.Ok ? G9ELocalCommandState.Ok : result.status === G9ECommandStatus.Superseded ? G9ELocalCommandState.Superseded : G9ELocalCommandState.Rejected;
|
|
123
|
+
completed += asNumber(await connection.scalar('UPDATE g9_commands SET state = $state, code = $code, message = $message, result = $result, completed_utc = $now WHERE command_id = $id AND state = 0 RETURNING 1', { $state: state, $code: (_a = result.code) !== null && _a !== void 0 ? _a : null, $message: (_b = result.message) !== null && _b !== void 0 ? _b : null, $result: (_c = result.result) !== null && _c !== void 0 ? _c : null, $now: now, $id: result.commandId }));
|
|
124
|
+
await connection.exec('DELETE FROM g9_command_rows WHERE command_id = $id', { $id: result.commandId });
|
|
125
|
+
}
|
|
126
|
+
await connection.exec('DELETE FROM g9_commands WHERE state <> 0 AND completed_utc < $cutoff', { $cutoff: now - COMMAND_HISTORY_MS });
|
|
127
|
+
return completed;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Records a command inside a transaction the APP owns on its own connection (the twin of the .NET overload taking the
|
|
131
|
+
* app's `sqlite3` handle): a SAVEPOINT of that transaction, so the command and the effects the app writes in
|
|
132
|
+
* `applyLocally` commit or roll back together with it. Without `tx` it is its own BEGIN IMMEDIATE transaction.
|
|
133
|
+
*/
|
|
134
|
+
export async function enqueueCommandOnConnection(connection, request, applyLocally) {
|
|
135
|
+
const owned = connection.tx === null;
|
|
136
|
+
if (owned)
|
|
137
|
+
await connection.begin('immediate');
|
|
138
|
+
else
|
|
139
|
+
await connection.exec('SAVEPOINT g9_command');
|
|
140
|
+
try {
|
|
141
|
+
const command = await recordCommand(connection, request);
|
|
142
|
+
if (applyLocally) {
|
|
143
|
+
await beginCommandEffects(connection, command.commandId);
|
|
144
|
+
await applyLocally();
|
|
145
|
+
await endCommandEffects(connection);
|
|
146
|
+
}
|
|
147
|
+
if (owned)
|
|
148
|
+
await connection.commit();
|
|
149
|
+
else
|
|
150
|
+
await connection.exec('RELEASE g9_command');
|
|
151
|
+
return command;
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
if (owned)
|
|
155
|
+
await connection.rollback();
|
|
156
|
+
else {
|
|
157
|
+
try {
|
|
158
|
+
await connection.exec('ROLLBACK TO g9_command; RELEASE g9_command');
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// the app's transaction is gone already
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/sqlite/commands.ts"],"names":[],"mappings":"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","sourcesContent":["// Twin of G9SyncData.Client.Sqlite/G9CSqliteSyncStore.Commands.cs: the command outbox (ADR-0025). A command is recorded\n// atomically with its local effects; while g9_ctx.applying = 2 the capture triggers stay silent and the command triggers\n// record the touched rows instead; those rows are protected from pulls until the command's result settles them.\nimport { newGuid } from '../abstractions/guid.js';\nimport { G9Long } from '../abstractions/long.js';\nimport {\n G9ELocalCommandState,\n type G9CommandRequest,\n type G9LocalCommand,\n type G9LocalCommandWriter,\n type G9LocalSqlArgument,\n} from '../client/storeTypes.js';\nimport { G9ECommandStatus, type G9DtCommand, type G9DtCommandResult } from '../protocol/dtos.js';\nimport { asNumber, asOptionalString, asString, toSqlValue, type G9SqliteConnection } from './connection.js';\nimport { byTid, meta, nowMs, setMeta, type StoreInternals } from './internals.js';\n\n/** Completed commands are kept this long for the app to inspect, then deleted. */\nconst COMMAND_HISTORY_MS = 30 * 24 * 60 * 60 * 1000;\n\n/** `RecordCommand`. */\nexport async function recordCommand(connection: G9SqliteConnection, request: G9CommandRequest): Promise<G9LocalCommand> {\n const sequence = Number((await meta(connection, 'next_command_seq')) ?? '1');\n await setMeta(connection, 'next_command_seq', String(sequence + 1));\n const commandId = newGuid();\n const created = nowMs();\n const version = request.version ?? 1;\n await connection.exec(\n 'INSERT INTO g9_commands (command_id, seq, name, version, payload, created_utc, state) VALUES ($id, $seq, $name, $version, $payload, $created, 0)',\n { $id: commandId, $seq: sequence, $name: request.name, $version: version, $payload: request.payload, $created: created },\n );\n return {\n commandId,\n sequence,\n name: request.name,\n version,\n payload: request.payload,\n createdUtcMs: created,\n state: G9ELocalCommandState.Pending,\n code: null,\n message: null,\n result: null,\n completedUtcMs: null,\n };\n}\n\n/** From here until endCommandEffects, writes on this connection are the command's effects (command triggers). */\nexport async function beginCommandEffects(connection: G9SqliteConnection, commandId: string): Promise<void> {\n await connection.exec('UPDATE g9_ctx SET applying = 2, command_id = $id WHERE id = 1', { $id: commandId });\n}\n\nexport async function endCommandEffects(connection: G9SqliteConnection): Promise<void> {\n await connection.exec('UPDATE g9_ctx SET applying = 0, command_id = NULL WHERE id = 1');\n}\n\n/** The writer handed to `applyLocally` (`LocalCommandWriter`): parameters bind positionally as `$p0`, `$p1`, … */\nexport function localCommandWriter(connection: G9SqliteConnection): G9LocalCommandWriter {\n const bind = (args: G9LocalSqlArgument[]) => {\n const params: { [name: string]: ReturnType<typeof toSqlValue> } = {};\n args.forEach((arg, i) => (params['$p' + i] = toSqlValue(arg instanceof G9Long || arg instanceof Uint8Array || typeof arg === 'boolean' ? arg : (arg as never))));\n return params;\n };\n return {\n execute: (sql, ...args) => connection.exec(sql, bind(args)),\n scalar: (sql, ...args) => connection.scalar(sql, bind(args)),\n };\n}\n\n/** `EnqueueCommandAsync` on the store's own connection. */\nexport async function enqueueCommand(\n store: StoreInternals,\n request: G9CommandRequest,\n applyLocally: ((writer: G9LocalCommandWriter, signal?: AbortSignal) => Promise<void>) | null,\n signal?: AbortSignal,\n): Promise<G9LocalCommand> {\n if (!request || typeof request.name !== 'string' || request.name.trim() === '') throw new TypeError('A command name is required.');\n store.ensureInitialized();\n return store.writeLock.run(() =>\n store.writer().transaction('immediate', async () => {\n const connection = store.writer();\n const command = await recordCommand(connection, request);\n if (applyLocally) {\n await beginCommandEffects(connection, command.commandId);\n await applyLocally(localCommandWriter(connection), signal);\n await endCommandEffects(connection);\n }\n return command;\n }),\n );\n}\n\nexport async function getCommands(store: StoreInternals, state: G9ELocalCommandState | null, limit: number): Promise<G9LocalCommand[]> {\n store.ensureInitialized();\n const rows = await store\n .reader()\n .query(\n 'SELECT command_id, seq, name, version, payload, created_utc, state, code, message, result, completed_utc FROM g9_commands ' +\n (state === null ? '' : 'WHERE state = $state ') +\n 'ORDER BY seq DESC LIMIT $limit',\n state === null ? { $limit: Math.max(1, limit) } : { $state: state, $limit: Math.max(1, limit) },\n );\n return rows.map((r) => ({\n commandId: asString(r[0]),\n sequence: asNumber(r[1]),\n name: asString(r[2]),\n version: asNumber(r[3]),\n payload: asString(r[4]),\n createdUtcMs: asNumber(r[5]),\n state: asNumber(r[6]) as G9ELocalCommandState,\n code: asOptionalString(r[7]),\n message: asOptionalString(r[8]),\n result: asOptionalString(r[9]),\n completedUtcMs: r[10] === null ? null : asNumber(r[10]),\n }));\n}\n\n/** Pending commands for a push batch, with the rows each touched (`ReadPendingCommands`). */\nexport async function readPendingCommands(store: StoreInternals, connection: G9SqliteConnection, inflightBatch: string | null, limit: number): Promise<G9DtCommand[]> {\n const rows = await connection.query(\n 'SELECT command_id, seq, name, version, payload, created_utc FROM g9_commands WHERE state = 0' +\n // A retried batch carries exactly its own commands; a new batch takes every pending one.\n (inflightBatch === null ? '' : ' AND batch_id = $inflight') +\n ' ORDER BY seq LIMIT $limit',\n inflightBatch === null ? { $limit: Math.max(1, limit) } : { $inflight: Number(inflightBatch), $limit: Math.max(1, limit) },\n );\n const commands: G9DtCommand[] = rows.map((r) => ({\n commandId: asString(r[0]),\n sequence: asNumber(r[1]),\n name: asString(r[2]),\n version: asNumber(r[3]),\n payload: asString(r[4]),\n createdUtcMs: asNumber(r[5]),\n touched: [],\n }));\n for (const item of commands) {\n for (const r of await connection.query('SELECT tid, pk FROM g9_command_rows WHERE command_id = $id', { $id: item.commandId })) {\n const local = byTid(store, asNumber(r[0]));\n if (!local || !local.negotiated) continue;\n item.touched.push({ tableId: local.negotiated.tableId, key: asString(r[1]) });\n }\n }\n return commands;\n}\n\n/** Records server outcomes and releases the rows those commands protected (`CompleteCommands`). */\nexport async function completeCommands(connection: G9SqliteConnection, results: readonly G9DtCommandResult[]): Promise<number> {\n let completed = 0;\n const now = nowMs();\n for (const result of results) {\n const state =\n result.status === G9ECommandStatus.Ok ? G9ELocalCommandState.Ok : result.status === G9ECommandStatus.Superseded ? G9ELocalCommandState.Superseded : G9ELocalCommandState.Rejected;\n completed += asNumber(\n await connection.scalar(\n 'UPDATE g9_commands SET state = $state, code = $code, message = $message, result = $result, completed_utc = $now WHERE command_id = $id AND state = 0 RETURNING 1',\n { $state: state, $code: result.code ?? null, $message: result.message ?? null, $result: result.result ?? null, $now: now, $id: result.commandId },\n ),\n );\n await connection.exec('DELETE FROM g9_command_rows WHERE command_id = $id', { $id: result.commandId });\n }\n await connection.exec('DELETE FROM g9_commands WHERE state <> 0 AND completed_utc < $cutoff', { $cutoff: now - COMMAND_HISTORY_MS });\n return completed;\n}\n\n/**\n * Records a command inside a transaction the APP owns on its own connection (the twin of the .NET overload taking the\n * app's `sqlite3` handle): a SAVEPOINT of that transaction, so the command and the effects the app writes in\n * `applyLocally` commit or roll back together with it. Without `tx` it is its own BEGIN IMMEDIATE transaction.\n */\nexport async function enqueueCommandOnConnection(\n connection: G9SqliteConnection,\n request: G9CommandRequest,\n applyLocally: (() => Promise<void>) | null,\n): Promise<G9LocalCommand> {\n const owned = connection.tx === null;\n if (owned) await connection.begin('immediate');\n else await connection.exec('SAVEPOINT g9_command');\n try {\n const command = await recordCommand(connection, request);\n if (applyLocally) {\n await beginCommandEffects(connection, command.commandId);\n await applyLocally();\n await endCommandEffects(connection);\n }\n if (owned) await connection.commit();\n else await connection.exec('RELEASE g9_command');\n return command;\n } catch (error) {\n if (owned) await connection.rollback();\n else {\n try {\n await connection.exec('ROLLBACK TO g9_command; RELEASE g9_command');\n } catch {\n // the app's transaction is gone already\n }\n }\n throw error;\n }\n}\n"]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { G9Long } from '../abstractions/long.js';
|
|
2
|
+
import { G9ELocalStoreFailure, type G9SyncLocalStoreFailure } from '../client/storeTypes.js';
|
|
3
|
+
import type { G9DriverStatement, G9SessionToken, G9SqlResult, G9SqlValue, G9SqliteDriver, G9TxToken } from './driver.js';
|
|
4
|
+
/** A parameter value the store binds. */
|
|
5
|
+
export type G9BindValue = G9SqlValue | boolean | G9Long | Uint8Array | undefined;
|
|
6
|
+
export type G9Params = {
|
|
7
|
+
[name: string]: G9BindValue;
|
|
8
|
+
};
|
|
9
|
+
/** A SQLite failure raised by the store, classified for the engine (twin of `G9CSqliteException`). */
|
|
10
|
+
export declare class G9SqliteStoreError extends Error implements G9SyncLocalStoreFailure {
|
|
11
|
+
/** The driver's error code (`busy`, `corrupt`, `full`, `constraint`, …). */
|
|
12
|
+
readonly driverCode: string;
|
|
13
|
+
/** SQLite's primary result code when the driver reported one. */
|
|
14
|
+
readonly sqliteCode: number | null;
|
|
15
|
+
constructor(message: string, driverCode: string, sqliteCode: number | null, cause?: unknown);
|
|
16
|
+
/** ADR-0068: corrupt (11/26), full (13), busy/locked (5/6). */
|
|
17
|
+
get localStoreFailure(): G9ELocalStoreFailure;
|
|
18
|
+
}
|
|
19
|
+
/** Converts a bind value to the driver's form. */
|
|
20
|
+
export declare function toSqlValue(value: G9BindValue): G9SqlValue;
|
|
21
|
+
interface Compiled {
|
|
22
|
+
statements: {
|
|
23
|
+
sql: string;
|
|
24
|
+
names: string[];
|
|
25
|
+
}[];
|
|
26
|
+
}
|
|
27
|
+
/** Splits a script and rewrites `$name` parameters (outside strings, identifiers and comments) to `?N`. */
|
|
28
|
+
export declare function compile(script: string): Compiled;
|
|
29
|
+
/** Statements of a script with their parameters bound by name. */
|
|
30
|
+
export declare function statementsOf(script: string, params?: G9Params): G9DriverStatement[];
|
|
31
|
+
/** An async mutex (the SemaphoreSlim(1, 1) twin). */
|
|
32
|
+
export declare class G9AsyncLock {
|
|
33
|
+
private _tail;
|
|
34
|
+
run<T>(action: () => Promise<T>): Promise<T>;
|
|
35
|
+
}
|
|
36
|
+
/** One driver session (a "connection") with the store's helpers. `tx` is the open transaction, if any. */
|
|
37
|
+
export declare class G9SqliteConnection {
|
|
38
|
+
readonly driver: G9SqliteDriver;
|
|
39
|
+
readonly session: G9SessionToken;
|
|
40
|
+
tx: G9TxToken | null;
|
|
41
|
+
constructor(driver: G9SqliteDriver, session: G9SessionToken);
|
|
42
|
+
/** Runs prepared driver statements in one bridge call. */
|
|
43
|
+
runStatements(statements: readonly G9DriverStatement[], signal?: AbortSignal): Promise<G9SqlResult[]>;
|
|
44
|
+
/** `ExecuteNonQuery`: the summed changes of every statement. */
|
|
45
|
+
exec(script: string, params?: G9Params): Promise<number>;
|
|
46
|
+
/** Rows of the first row-producing statement (statements before it run first, like ExecuteReader). */
|
|
47
|
+
query(script: string, params?: G9Params): Promise<(readonly G9SqlValue[])[]>;
|
|
48
|
+
/** First column of the first row, or null. */
|
|
49
|
+
scalar(script: string, params?: G9Params): Promise<G9SqlValue>;
|
|
50
|
+
/** `BEGIN IMMEDIATE` (or deferred) on this session. */
|
|
51
|
+
begin(mode?: 'deferred' | 'immediate'): Promise<void>;
|
|
52
|
+
commit(): Promise<void>;
|
|
53
|
+
rollback(): Promise<void>;
|
|
54
|
+
/** Runs `action` in a transaction: committed when it returns, rolled back when it throws (the `using var transaction` pattern). */
|
|
55
|
+
transaction<T>(mode: 'deferred' | 'immediate', action: () => Promise<T>): Promise<T>;
|
|
56
|
+
}
|
|
57
|
+
/** Collects statements and runs them in one driver call, handing each its result (the apply's batching). */
|
|
58
|
+
export declare class G9StatementBatch {
|
|
59
|
+
private readonly _connection;
|
|
60
|
+
private readonly _statements;
|
|
61
|
+
private readonly _callbacks;
|
|
62
|
+
private readonly _limit;
|
|
63
|
+
constructor(connection: G9SqliteConnection, limit?: number);
|
|
64
|
+
get count(): number;
|
|
65
|
+
/**
|
|
66
|
+
* Queues a script's statements; `callback` receives their results (in order) once the batch has run. Returns true when
|
|
67
|
+
* the batch is full and should be flushed.
|
|
68
|
+
*/
|
|
69
|
+
add(script: string, params?: G9Params, callback?: (results: G9SqlResult[]) => void): boolean;
|
|
70
|
+
/** Queues prepared statements. */
|
|
71
|
+
addStatements(statements: readonly G9DriverStatement[], callback?: (results: G9SqlResult[]) => void): boolean;
|
|
72
|
+
flush(signal?: AbortSignal): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
/** Reads an INTEGER cell as a number (an int64 tag rounds; the store's counters are far below 2^53). */
|
|
75
|
+
export declare function asNumber(value: G9SqlValue | undefined): number;
|
|
76
|
+
/** Reads an INTEGER cell exactly. */
|
|
77
|
+
export declare function asLong(value: G9SqlValue | undefined): G9Long;
|
|
78
|
+
/** Reads a TEXT cell (`GetString`: SQLite's text form of a number, as JavaScript prints it). */
|
|
79
|
+
export declare function asString(value: G9SqlValue | undefined): string;
|
|
80
|
+
export declare function asOptionalString(value: G9SqlValue | undefined): string | null;
|
|
81
|
+
export {};
|