@fluidframework/merge-tree 2.31.0 → 2.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/client.d.ts +7 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +153 -44
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/mergeTree.d.ts +17 -5
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +188 -79
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +16 -18
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +6 -0
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/perspective.d.ts +9 -0
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +14 -1
- package/dist/perspective.js.map +1 -1
- package/dist/segmentInfos.d.ts +32 -4
- package/dist/segmentInfos.d.ts.map +1 -1
- package/dist/segmentInfos.js +3 -1
- package/dist/segmentInfos.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts +1 -0
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js +3 -0
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/test/beastTest.spec.js +5 -5
- package/dist/test/beastTest.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +3 -3
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.rollback.spec.js +17 -0
- package/dist/test/client.rollback.spec.js.map +1 -1
- package/dist/test/clientTestHelper.d.ts +100 -0
- package/dist/test/clientTestHelper.d.ts.map +1 -0
- package/dist/test/clientTestHelper.js +196 -0
- package/dist/test/clientTestHelper.js.map +1 -0
- package/dist/test/mergeTree.annotate.spec.js +12 -12
- package/dist/test/mergeTree.annotate.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +1 -1
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
- package/dist/test/obliterate.concurrent.spec.js +93 -90
- package/dist/test/obliterate.concurrent.spec.js.map +1 -1
- package/dist/test/obliterate.deltaCallback.spec.js +121 -116
- package/dist/test/obliterate.deltaCallback.spec.js.map +1 -1
- package/dist/test/obliterate.rangeExpansion.spec.js +29 -79
- package/dist/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/dist/test/obliterate.reconnect.spec.js +235 -58
- package/dist/test/obliterate.reconnect.spec.js.map +1 -1
- package/dist/test/testClient.js +1 -1
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testUtils.d.ts +13 -0
- package/dist/test/testUtils.d.ts.map +1 -1
- package/dist/test/testUtils.js +22 -1
- package/dist/test/testUtils.js.map +1 -1
- package/lib/client.d.ts +7 -1
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +155 -46
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/mergeTree.d.ts +17 -5
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +192 -83
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +16 -18
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +7 -1
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/perspective.d.ts +9 -0
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +12 -0
- package/lib/perspective.js.map +1 -1
- package/lib/segmentInfos.d.ts +32 -4
- package/lib/segmentInfos.d.ts.map +1 -1
- package/lib/segmentInfos.js +2 -1
- package/lib/segmentInfos.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts +1 -0
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js +3 -0
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/test/beastTest.spec.js +5 -5
- package/lib/test/beastTest.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +3 -3
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.rollback.spec.js +18 -1
- package/lib/test/client.rollback.spec.js.map +1 -1
- package/lib/test/clientTestHelper.d.ts +100 -0
- package/lib/test/clientTestHelper.d.ts.map +1 -0
- package/lib/test/clientTestHelper.js +192 -0
- package/lib/test/clientTestHelper.js.map +1 -0
- package/lib/test/mergeTree.annotate.spec.js +12 -12
- package/lib/test/mergeTree.annotate.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +1 -1
- package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
- package/lib/test/obliterate.concurrent.spec.js +93 -90
- package/lib/test/obliterate.concurrent.spec.js.map +1 -1
- package/lib/test/obliterate.deltaCallback.spec.js +121 -116
- package/lib/test/obliterate.deltaCallback.spec.js.map +1 -1
- package/lib/test/obliterate.rangeExpansion.spec.js +1 -51
- package/lib/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/lib/test/obliterate.reconnect.spec.js +236 -59
- package/lib/test/obliterate.reconnect.spec.js.map +1 -1
- package/lib/test/testClient.js +1 -1
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testUtils.d.ts +13 -0
- package/lib/test/testUtils.d.ts.map +1 -1
- package/lib/test/testUtils.js +20 -0
- package/lib/test/testUtils.js.map +1 -1
- package/package.json +19 -18
- package/src/client.ts +286 -55
- package/src/index.ts +1 -1
- package/src/mergeTree.ts +265 -98
- package/src/mergeTreeNodes.ts +24 -18
- package/src/perspective.ts +21 -0
- package/src/segmentInfos.ts +48 -6
- package/src/sortedSegmentSet.ts +4 -0
- package/dist/test/partialSyncHelper.d.ts +0 -42
- package/dist/test/partialSyncHelper.d.ts.map +0 -1
- package/dist/test/partialSyncHelper.js +0 -96
- package/dist/test/partialSyncHelper.js.map +0 -1
- package/dist/test/reconnectHelper.d.ts +0 -50
- package/dist/test/reconnectHelper.d.ts.map +0 -1
- package/dist/test/reconnectHelper.js +0 -106
- package/dist/test/reconnectHelper.js.map +0 -1
- package/lib/test/partialSyncHelper.d.ts +0 -42
- package/lib/test/partialSyncHelper.d.ts.map +0 -1
- package/lib/test/partialSyncHelper.js +0 -92
- package/lib/test/partialSyncHelper.js.map +0 -1
- package/lib/test/reconnectHelper.d.ts +0 -50
- package/lib/test/reconnectHelper.d.ts.map +0 -1
- package/lib/test/reconnectHelper.js +0 -102
- package/lib/test/reconnectHelper.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obliterate.rangeExpansion.spec.js","sourceRoot":"","sources":["../../src/test/obliterate.rangeExpansion.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,6CAA+C;AAE/C,0DAA2C;AAE3C,6DAA2D;AAE3D,SAAS,wBAAwB,CAAC,EAAE,MAAM,EAAE,YAAY,EAAsB;IAC7E,OAAO,GAAG,EAAE;QACX,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,MAAM,MAAM,GAAG,IAAI,wCAAmB,CAAC;YACtC,8BAA8B,EAAE,IAAI;SACpC,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE;YAClD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC;QACf,MAAM,CAAC,aAAa,EAAE,CAAC;QAEvB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC;AACH,CAAC;AAQD,SAAS,sBAAsB,CAAC,IAAwB;IACvD,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC;AACvD,CAAC;AACD,sBAAsB,CAAC,IAAI,GAAG,CAAC,IAAwB,EAAE,EAAE,CAC1D,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC;AACrD,sBAAsB,CAAC,IAAI,GAAG,CAAC,IAAwB,EAAE,EAAE,CAC1D,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC;AAErD,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC3B,sBAAsB,CAAC;QACtB,KAAK,EAAE,4BAA4B;QACnC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YACnC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACzF,gGAAgG;YAChG,yCAAyC;YACzC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACjC,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACzF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,YAAY,EAAE,OAAO;KACrB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,mDAAmD;QAC1D,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACxF,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACxF,2EAA2E;YAC3E,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;YACxC,kIAAkI;YAClI,mIAAmI;YACnI,yCAAyC;YACzC,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,MAAM,CAAC,aAAa,EAAE,CAAC;QACxB,CAAC;QACD,YAAY,EAAE,MAAM;KACpB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,yCAAyC;QAChD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,8EAA8E;YAC9E,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,YAAY,EAAE,aAAa;KAC3B,CAAC,CAAC;IACH,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;QACtD,sBAAsB,CAAC;YACtB,KAAK,EAAE,4BAA4B;YACnC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBACjC,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAC5B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC7B,CAAC;YACH,CAAC;YACD,YAAY,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,sBAAsB,CAAC;YACtB,KAAK,EAAE,0BAA0B;YACjC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBACjC,MAAM,CAAC,aAAa,EAAE,CAAC;gBACvB,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAC5B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC7B,CAAC;YACH,CAAC;YACD,YAAY,EAAE,IAAI;SAClB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACvE,sBAAsB,CAAC;YACtB,KAAK,EAAE,gCAAgC;YACvC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBACjC,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAC5B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC7B,CAAC;gBACF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YAChC,CAAC;YACD,YAAY,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,sBAAsB,CAAC;YACtB,KAAK,EAAE,gCAAgC;YACvC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBACjC,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAC5B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC7B,CAAC;gBACF,MAAM,CAAC,aAAa,EAAE,CAAC;gBACvB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YAChC,CAAC;YACD,YAAY,EAAE,KAAK;SACnB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,sBAAsB,CAAC;QACtB,KAAK,EAAE,kDAAkD;QACzD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAC7B,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAC7B,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,YAAY,EAAE,OAAO;KACrB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,kDAAkD;QACzD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YAClC,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAC7B,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAC7B,CAAC;QACH,CAAC;QACD,YAAY,EAAE,OAAO;KACrB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,kDAAkD;QACzD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAC7B,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAC7B,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,YAAY,EAAE,OAAO;KACrB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,kDAAkD;QACzD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YAClC,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAC7B,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAC7B,CAAC;QACH,CAAC;QACD,YAAY,EAAE,OAAO;KACrB,CAAC,CAAC;IACH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC5B,gFAAgF;QAChF,sBAAsB,CAAC,IAAI,CAAC;YAC3B,KAAK,EAAE,mDAAmD;YAC1D,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;gBACzC,MAAM,CAAC,aAAa,EAAE,CAAC;gBAEvB,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAC7B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC7B,CAAC;gBACF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YACpC,CAAC;YACD,YAAY,EAAE,aAAa;SAC3B,CAAC,CAAC;QACH,sBAAsB,CAAC;YACtB,KAAK,EAAE,oDAAoD;YAC3D,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;gBACzC,MAAM,CAAC,aAAa,EAAE,CAAC;gBAEvB,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAC5B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC7B,CAAC;gBACF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YACpC,CAAC;YACD,YAAY,EAAE,aAAa;SAC3B,CAAC,CAAC;QACH,gFAAgF;QAChF,sBAAsB,CAAC,IAAI,CAAC;YAC3B,KAAK,EAAE,iDAAiD;YACxD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;gBAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;gBACzC,MAAM,CAAC,aAAa,EAAE,CAAC;gBAEvB,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAC3D,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC9B,CAAC;gBACF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;YAC/D,CAAC;YACD,YAAY,EAAE,aAAa;SAC3B,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAClC,sBAAsB,CAAC;QACtB,KAAK,EAAE,uCAAuC;QAC9C,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,IAAI,GAAG,QAAQ,CAAC;YAEtB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YAChC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAC7B,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAC1C,CAAC;YACF,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAC7B,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAC1C,CAAC;QACH,CAAC;QACD,YAAY,EAAE,EAAE;KAChB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,sBAAsB;QAC7B,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,YAAY,EAAE,SAAS;KACvB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,iCAAiC;QACxC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/B,CAAC;QACD,YAAY,EAAE,SAAS;KACvB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,iDAAiD;QACxD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACxF,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/B,CAAC;QACD,YAAY,EAAE,QAAQ;KACtB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,+CAA+C;QACtD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/B,CAAC;QACD,YAAY,EAAE,SAAS;KACvB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,iDAAiD;QACxD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9B,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,YAAY,EAAE,SAAS;KACvB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,+CAA+C;QACtD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9B,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACzF,CAAC;QACD,YAAY,EAAE,QAAQ;KACtB,CAAC,CAAC;IAEH,6GAA6G;IAC7G,+GAA+G;IAC/G,gIAAgI;IAChI,sBAAsB,CAAC;QACtB,KAAK,EAAE,qDAAqD;QAC5D,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;YACxC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACxF,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YAC/B,MAAM,CAAC,aAAa,EAAE,CAAC;QACxB,CAAC;QACD,YAAY,EAAE,IAAI;KAClB,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;IAC/B,sBAAsB,CAAC;QACtB,KAAK,EAAE,mFAAmF;QAC1F,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,MAAM,EAAE,GAAG,MAAM,CAAC,oBAAoB,CACrC,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAC5B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAC5B,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,oBAAoB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACrC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,oDAAoD;YACpD,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,YAAY,EAAE,WAAW;KACzB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,mFAAmF;QAC1F,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,MAAM,EAAE,GAAG,MAAM,CAAC,oBAAoB,CACrC,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAC5B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAC5B,CAAC;YACF,oDAAoD;YACpD,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACjC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,oBAAoB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACtC,CAAC;QACD,YAAY,EAAE,WAAW;KACzB,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAClC;;;;;;;;;OASG;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,uDAAuD;QAC9D,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,2FAA2F;YAC3F,2FAA2F;YAC3F,0BAA0B;YAC1B,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACzF,uDAAuD;YACvD,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACjC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,YAAY,EAAE,UAAU;KACxB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,mDAAmD;QAC1D,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,kEAAkE;YAClE,kDAAkD;YAClD,yEAAyE;YACzE,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACjC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YAC/B,sCAAsC;YACtC,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACxF,kDAAkD;YAClD,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;YAC/B,wCAAwC;YACxC,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAC7B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC7B,CAAC;QACH,CAAC;QACD,YAAY,EAAE,IAAI;KAClB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,4CAA4C;QACnD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,yDAAyD;YACzD,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACzF,uDAAuD;YACvD,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACzF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACjC,wDAAwD;YACxD,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,YAAY,EAAE,UAAU;KACxB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,0CAA0C;QACjD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,yDAAyD;YACzD,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACzF,yDAAyD;YACzD,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAC7B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC7B,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,iBAAiB;YACnD,wDAAwD;YACxD,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,oBAAoB;QACvD,CAAC;QACD,YAAY,EAAE,UAAU;KACxB,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,8CAA8C;QACrD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,uDAAuD;YACvD,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,uDAAuD;YACvD,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAExF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,8BAA8B;YAChE,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,kCAAkC;YACpE,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;YACxD,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;YACxD,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;YAExD,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;QACD,YAAY,EAAE,aAAa;KAC3B,CAAC,CAAC;IACH,sBAAsB,CAAC;QACtB,KAAK,EAAE,4CAA4C;QACnD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,uDAAuD;YACvD,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,yDAAyD;YACzD,MAAM,CAAC,eAAe,CACrB,GAAG,EACH,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,EAC7B,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,uBAAI,CAAC,MAAM,EAAE,CAC7B,CAAC;YAEF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACjC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YAEjC,MAAM,CAAC,aAAa,EAAE,CAAC;YAEvB,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;YACxD,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;YACxD,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;YAExD,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;QACD,YAAY,EAAE,aAAa;KAC3B,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { Side } from \"../sequencePlace.js\";\n\nimport { ReconnectTestHelper } from \"./reconnectHelper.js\";\n\nfunction createObliterateTestBody({ action, expectedText }: ObliterateTestArgs): () => void {\n\treturn () => {\n\t\tconst events: number[] = [];\n\n\t\tconst helper = new ReconnectTestHelper({\n\t\t\tmergeTreeEnableSidedObliterate: true,\n\t\t});\n\t\thelper.clients.A.on(\"delta\", (opArgs, deltaArgs) => {\n\t\t\tevents.push(deltaArgs.operation);\n\t\t});\n\t\taction(helper);\n\t\thelper.processAllOps();\n\n\t\thelper.logger.validate({ baseText: expectedText });\n\t};\n}\n\ninterface ObliterateTestArgs {\n\ttitle: string;\n\taction: (helper: ReconnectTestHelper) => void;\n\texpectedText: string;\n}\n\nfunction itCorrectlyObliterates(args: ObliterateTestArgs): Mocha.Test {\n\treturn it(args.title, createObliterateTestBody(args));\n}\nitCorrectlyObliterates.skip = (args: ObliterateTestArgs) =>\n\tit.skip(args.title, createObliterateTestBody(args));\nitCorrectlyObliterates.only = (args: ObliterateTestArgs) =>\n\tit.only(args.title, createObliterateTestBody(args));\n\ndescribe(\"obliterate\", () => {\n\titCorrectlyObliterates({\n\t\ttitle: \"Obliterate adjacent insert\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"|ABC>\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 0, side: Side.After }, { pos: 4, side: Side.Before });\n\t\t\t// not concurrent to A's obliterate - ops on the same client are never concurrent to one another\n\t\t\t// because they are all sequenced locally\n\t\t\thelper.insertText(\"A\", 1, \"AAA\");\n\t\t\thelper.obliterateRange(\"B\", { pos: 0, side: Side.After }, { pos: 4, side: Side.Before });\n\t\t\thelper.insertText(\"B\", 1, \"BBB\");\n\t\t},\n\t\texpectedText: \"|BBB>\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"Obliterate adjacent insert followed by obliterate\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"0xx12345678\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 0, side: Side.After }, { pos: 2, side: Side.After });\n\t\t\thelper.obliterateRange(\"B\", { pos: 0, side: Side.After }, { pos: 2, side: Side.After });\n\t\t\t// B won the obliterate, so this segment should be obliterated on insertion\n\t\t\thelper.insertText(\"A\", 1, \"AAAAAAAAAA\");\n\t\t\t// Nonetheless, all clients should recognize that subsequent ops from A won't have realized this (until A's refSeq advances beyond\n\t\t\t// acking B's obliterate). At one point this caused 0xa3f because other clients didn't realize that the positions here still assume\n\t\t\t// existence of the 'AAAAAAAAAA' segment.\n\t\t\thelper.obliterateRange(\"A\", { pos: 6, side: Side.After }, { pos: 15, side: Side.After });\n\t\t\thelper.processAllOps();\n\t\t},\n\t\texpectedText: \"0678\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"does not obliterate non-adjacent insert\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\t// do not obliterate the XYZ - outside the obliterated range without expansion\n\t\t\thelper.insertText(\"B\", 0, \"XYZ\");\n\t\t},\n\t\texpectedText: \"XYZhe world\",\n\t});\n\tdescribe(\"removes prior insert from same client\", () => {\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"when the insert is unacked\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t);\n\t\t\t},\n\t\t\texpectedText: \"AC\",\n\t\t});\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"when the insert is acked\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\t\thelper.processAllOps();\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t);\n\t\t\t},\n\t\t\texpectedText: \"AC\",\n\t\t});\n\t});\n\n\tdescribe(\"does not remove subsequent insert from the same client\", () => {\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"when the obliterate is unacked\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.insertText(\"A\", 1, \"D\");\n\t\t\t},\n\t\t\texpectedText: \"ADC\",\n\t\t});\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"when the obliterate is unacked\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.processAllOps();\n\t\t\t\thelper.insertText(\"A\", 1, \"D\");\n\t\t\t},\n\t\t\texpectedText: \"ADC\",\n\t\t});\n\t});\n\n\titCorrectlyObliterates({\n\t\ttitle: \"obliterate, then insert at the end of the string\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"A\",\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t\t{ pos: 10, side: Side.After },\n\t\t\t);\n\t\t\thelper.insertText(\"B\", 10, \"123\");\n\t\t},\n\t\texpectedText: \"hello\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"insert, then obliterate at the end of the string\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\thelper.insertText(\"A\", 10, \"123\");\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t\t{ pos: 10, side: Side.After },\n\t\t\t);\n\t\t},\n\t\texpectedText: \"hello\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"obliterate, then insert at the end of the string\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"A\",\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t\t{ pos: 10, side: Side.After },\n\t\t\t);\n\t\t\thelper.insertText(\"B\", 10, \"123\");\n\t\t},\n\t\texpectedText: \"hello\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"insert, then obliterate at the end of the string\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\thelper.insertText(\"A\", 10, \"123\");\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t\t{ pos: 10, side: Side.After },\n\t\t\t);\n\t\t},\n\t\texpectedText: \"hello\",\n\t});\n\tdescribe(\"zero length\", () => {\n\t\t// TODO: #17785: Allow start and end to be used as obliteration range endpoints.\n\t\titCorrectlyObliterates.skip({\n\t\t\ttitle: \"zero length obliterate at the start of the string\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\t\thelper.processAllOps();\n\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: -1, side: Side.After },\n\t\t\t\t\t{ pos: 0, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.insertText(\"B\", 0, \"more \");\n\t\t\t},\n\t\t\texpectedText: \"hello world\",\n\t\t});\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"zero length obliterate in the middle of the string\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\t\thelper.processAllOps();\n\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 1, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.insertText(\"B\", 1, \"more \");\n\t\t\t},\n\t\t\texpectedText: \"hello world\",\n\t\t});\n\t\t// TODO: #17785: Allow start and end to be used as obliteration range endpoints.\n\t\titCorrectlyObliterates.skip({\n\t\t\ttitle: \"zero length obliterate at the end of the string\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\t\thelper.processAllOps();\n\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: helper.clients.A.getLength() - 1, side: Side.After },\n\t\t\t\t\t{ pos: -1, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.insertText(\"B\", helper.clients.B.getLength(), \" more\");\n\t\t\t},\n\t\t\texpectedText: \"hello world\",\n\t\t});\n\t});\n});\n\ndescribe(\"overlapping edits\", () => {\n\titCorrectlyObliterates({\n\t\ttitle: \"overlapping obliterate and obliterate\",\n\t\taction: (helper) => {\n\t\t\tconst text = \"abcdef\";\n\n\t\t\thelper.insertText(\"A\", 0, text);\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"A\",\n\t\t\t\t{ pos: 0, side: Side.Before },\n\t\t\t\t{ pos: text.length - 1, side: Side.After },\n\t\t\t);\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 0, side: Side.Before },\n\t\t\t\t{ pos: text.length - 1, side: Side.After },\n\t\t\t);\n\t\t},\n\t\texpectedText: \"\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"adjacent obliterates\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 3, side: Side.After });\n\t\t\thelper.obliterateRange(\"B\", { pos: 4, side: Side.Before }, { pos: 5, side: Side.After });\n\t\t},\n\t\texpectedText: \"heworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"remove within obliterated range\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 5, side: Side.After });\n\t\t\thelper.removeRange(\"B\", 3, 4);\n\t\t},\n\t\texpectedText: \"heworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"obliterate, then remove adjacent to range start\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 1, side: Side.After }, { pos: 5, side: Side.After });\n\t\t\thelper.removeRange(\"B\", 1, 2);\n\t\t},\n\t\texpectedText: \"hworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"obliterate, then remove adjacent to range end\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\thelper.removeRange(\"B\", 4, 6);\n\t\t},\n\t\texpectedText: \"heworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"remove, then obliterate adjacent to range start\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.removeRange(\"A\", 4, 6);\n\t\t\thelper.obliterateRange(\"B\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t},\n\t\texpectedText: \"heworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"remove, then obliterate adjacent to range end\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.removeRange(\"A\", 2, 4);\n\t\t\thelper.obliterateRange(\"B\", { pos: 3, side: Side.After }, { pos: 6, side: Side.After });\n\t\t},\n\t\texpectedText: \"heorld\",\n\t});\n\n\t// This test is somewhat arbitrary: it's a minimized fuzz test failure that ended up root-causing to an issue\n\t// in SortedSegmentSet (local references were not compared correctly when put at various offsets). We also have\n\t// more direct unit tests for that, but this is a good sanity check and adds some extra verification for concurrent obliterates.\n\titCorrectlyObliterates({\n\t\ttitle: \"overlapping obliterates with third client inserting\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"0123456789\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 7, side: Side.After }, { pos: 8, side: Side.After });\n\t\t\thelper.obliterateRange(\"C\", { pos: 1, side: Side.Before }, { pos: 8, side: Side.After });\n\t\t\thelper.insertText(\"B\", 5, \"V\");\n\t\t\thelper.processAllOps();\n\t\t},\n\t\texpectedText: \"09\",\n\t});\n});\n\ndescribe.skip(\"reconnect\", () => {\n\titCorrectlyObliterates({\n\t\ttitle: \"add text, disconnect, obliterate, reconnect, insert adjacent to obliterated range\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.disconnect([\"C\"]);\n\t\t\tconst op = helper.obliterateRangeLocal(\n\t\t\t\t\"C\",\n\t\t\t\t{ pos: 1, side: Side.After },\n\t\t\t\t{ pos: 4, side: Side.After },\n\t\t\t);\n\t\t\thelper.reconnect([\"C\"]);\n\t\t\thelper.submitDisconnectedOp(\"C\", op);\n\t\t\thelper.processAllOps();\n\t\t\t// inserting adjacent to the obliterated range start\n\t\t\thelper.insertText(\"A\", 2, \"123\");\n\t\t},\n\t\texpectedText: \"heo world\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"add text, disconnect, obliterate, insert adjacent to obliterated range, reconnect\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.disconnect([\"C\"]);\n\t\t\tconst op = helper.obliterateRangeLocal(\n\t\t\t\t\"C\",\n\t\t\t\t{ pos: 1, side: Side.After },\n\t\t\t\t{ pos: 4, side: Side.After },\n\t\t\t);\n\t\t\t// inserting adjacent to the obliterated range start\n\t\t\thelper.insertText(\"A\", 2, \"123\");\n\t\t\thelper.reconnect([\"C\"]);\n\t\t\thelper.submitDisconnectedOp(\"C\", op);\n\t\t},\n\t\texpectedText: \"heo world\",\n\t});\n});\n\ndescribe(\"sided obliterates\", () => {\n\t/**\n\t * All test cases will operate on the same numerical positions, but differ on their sidedness:\n\t * 1. A expand both endpoints, B expand neither endpoint = expand range on both endpoints\n\t * 2. A expand start endpoint, B expand end endpoint = either FWW/LWW\n\t * 3. A expand both endpoints, B expand start = expand range on both endpoints\n\t * 4. (similar to 3) A expand both endpoints, B expand end = expand range on both endpoints\n\t * 5. A expand neither endpoint, B expand start = expand start endpoint\n\t * 6. A expand neither endpoint, B expand end = expand end endpoint\n\t * before = 0, after = 1\n\t */\n\titCorrectlyObliterates({\n\t\ttitle: \"1. A expand both endpoints, B expand neither endpoint\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\t// in order to get the right behavior, the range needs to start after the previous position\n\t\t\t// if so, for a range ( 2, 4 ) itCorrectlyObliterates would need to be after 1 and before 5\n\t\t\t// h e( l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 1, side: Side.After }, { pos: 5, side: Side.Before });\n\t\t\t// [2, 4]: before 2, after 4 => h e [l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"B\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\thelper.insertText(\"C\", 2, \"123\");\n\t\t\thelper.insertText(\"C\", 8, \"456\");\n\t\t},\n\t\texpectedText: \"he world\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"2. A expand start endpoint, B expand end endpoint\",\n\t\taction: (helper) => {\n\t\t\t// currently this is the example from obliterate notation loop doc\n\t\t\t// TODO: translate this into same format as others\n\t\t\t// i think this gets difficult when the range to obliterate > 1 character\n\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.insertText(\"A\", 2, \"D\");\n\t\t\t// ( 1]: after 0, after 1 => A( B] D C\n\t\t\thelper.obliterateRange(\"A\", { pos: 0, side: Side.After }, { pos: 1, side: Side.After });\n\t\t\t// included in the range -- should get obliterated\n\t\t\thelper.insertText(\"B\", 1, \"E\");\n\t\t\t// [1 ): before 1, before 2 => A E [B )C\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 1, side: Side.Before },\n\t\t\t\t{ pos: 3, side: Side.Before },\n\t\t\t);\n\t\t},\n\t\texpectedText: \"AC\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"3. A expand both endpoints, B expand start\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\t// ( 2, 4 ): after 1, before 5 => h e( l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 1, side: Side.After }, { pos: 5, side: Side.Before });\n\t\t\t// ( 2, 4]: after 1, after 4 => h e( l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"B\", { pos: 2, side: Side.After }, { pos: 4, side: Side.Before });\n\t\t\thelper.insertText(\"C\", 2, \"123\");\n\t\t\t// for this to be interesting, might want to insert at 5\n\t\t\thelper.insertText(\"C\", 4, \"456\");\n\t\t},\n\t\texpectedText: \"he world\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"4. A expand both endpoints, B expand end\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\t// ( 2, 4 ): after 1, before 5 => h e( l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 1, side: Side.After }, { pos: 5, side: Side.Before });\n\t\t\t// [2, 4 ): before 2, before 5 => h e [l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t);\n\t\t\thelper.insertText(\"C\", 2, \"123\"); // he123llo world\n\t\t\t// for this to be interesting, might want to insert at 5\n\t\t\thelper.insertText(\"C\", 8, \"456\"); // he123llo456 world\n\t\t},\n\t\texpectedText: \"he world\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"5. A expand neither endpoint, B expand start\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\t// [2, 4]: before 2, after 4 => h e [l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\t// ( 2, 4]: after 1, after 4 => h e( l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"B\", { pos: 1, side: Side.After }, { pos: 4, side: Side.After });\n\n\t\t\thelper.insertText(\"C\", 2, \"123\"); // h e( 123 l l o] _ w o r l d\n\t\t\thelper.insertText(\"C\", 8, \"456\"); // h e( 123 l l o) 456 _ w o r l d\n\t\t\thelper.processAllOps();\n\n\t\t\tassert.equal(helper.clients.A.getText(), \"he456 world\");\n\t\t\tassert.equal(helper.clients.B.getText(), \"he456 world\");\n\t\t\tassert.equal(helper.clients.C.getText(), \"he456 world\");\n\n\t\t\thelper.logger.validate();\n\t\t},\n\t\texpectedText: \"he456 world\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"6. A expand neither endpoint, B expand end\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\t// [2, 4]: before 2, after 4 => h e [l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\t// [2, 4 ): before 2, before 5 => h e [l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t);\n\n\t\t\thelper.insertText(\"C\", 2, \"123\");\n\t\t\thelper.insertText(\"C\", 8, \"456\");\n\n\t\t\thelper.processAllOps();\n\n\t\t\tassert.equal(helper.clients.A.getText(), \"he123 world\");\n\t\t\tassert.equal(helper.clients.B.getText(), \"he123 world\");\n\t\t\tassert.equal(helper.clients.C.getText(), \"he123 world\");\n\n\t\t\thelper.logger.validate();\n\t\t},\n\t\texpectedText: \"he123 world\",\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"obliterate.rangeExpansion.spec.js","sourceRoot":"","sources":["../../src/test/obliterate.rangeExpansion.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { Side } from \"../sequencePlace.js\";\n\nimport { itCorrectlyObliterates } from \"./testUtils.js\";\n\ndescribe(\"obliterate\", () => {\n\titCorrectlyObliterates({\n\t\ttitle: \"Obliterate adjacent insert\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"|ABC>\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 0, side: Side.After }, { pos: 4, side: Side.Before });\n\t\t\t// not concurrent to A's obliterate - ops on the same client are never concurrent to one another\n\t\t\t// because they are all sequenced locally\n\t\t\thelper.insertText(\"A\", 1, \"AAA\");\n\t\t\thelper.obliterateRange(\"B\", { pos: 0, side: Side.After }, { pos: 4, side: Side.Before });\n\t\t\thelper.insertText(\"B\", 1, \"BBB\");\n\t\t},\n\t\texpectedText: \"|BBB>\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"Obliterate adjacent insert followed by obliterate\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"0xx12345678\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 0, side: Side.After }, { pos: 2, side: Side.After });\n\t\t\thelper.obliterateRange(\"B\", { pos: 0, side: Side.After }, { pos: 2, side: Side.After });\n\t\t\t// B won the obliterate, so this segment should be obliterated on insertion\n\t\t\thelper.insertText(\"A\", 1, \"AAAAAAAAAA\");\n\t\t\t// Nonetheless, all clients should recognize that subsequent ops from A won't have realized this (until A's refSeq advances beyond\n\t\t\t// acking B's obliterate). At one point this caused 0xa3f because other clients didn't realize that the positions here still assume\n\t\t\t// existence of the 'AAAAAAAAAA' segment.\n\t\t\thelper.obliterateRange(\"A\", { pos: 6, side: Side.After }, { pos: 15, side: Side.After });\n\t\t\thelper.processAllOps();\n\t\t},\n\t\texpectedText: \"0678\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"does not obliterate non-adjacent insert\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\t// do not obliterate the XYZ - outside the obliterated range without expansion\n\t\t\thelper.insertText(\"B\", 0, \"XYZ\");\n\t\t},\n\t\texpectedText: \"XYZhe world\",\n\t});\n\tdescribe(\"removes prior insert from same client\", () => {\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"when the insert is unacked\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t);\n\t\t\t},\n\t\t\texpectedText: \"AC\",\n\t\t});\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"when the insert is acked\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\t\thelper.processAllOps();\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t);\n\t\t\t},\n\t\t\texpectedText: \"AC\",\n\t\t});\n\t});\n\n\tdescribe(\"does not remove subsequent insert from the same client\", () => {\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"when the obliterate is unacked\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.insertText(\"A\", 1, \"D\");\n\t\t\t},\n\t\t\texpectedText: \"ADC\",\n\t\t});\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"when the obliterate is unacked\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.processAllOps();\n\t\t\t\thelper.insertText(\"A\", 1, \"D\");\n\t\t\t},\n\t\t\texpectedText: \"ADC\",\n\t\t});\n\t});\n\n\titCorrectlyObliterates({\n\t\ttitle: \"obliterate, then insert at the end of the string\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"A\",\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t\t{ pos: 10, side: Side.After },\n\t\t\t);\n\t\t\thelper.insertText(\"B\", 10, \"123\");\n\t\t},\n\t\texpectedText: \"hello\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"insert, then obliterate at the end of the string\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\thelper.insertText(\"A\", 10, \"123\");\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t\t{ pos: 10, side: Side.After },\n\t\t\t);\n\t\t},\n\t\texpectedText: \"hello\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"obliterate, then insert at the end of the string\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"A\",\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t\t{ pos: 10, side: Side.After },\n\t\t\t);\n\t\t\thelper.insertText(\"B\", 10, \"123\");\n\t\t},\n\t\texpectedText: \"hello\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"insert, then obliterate at the end of the string\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\thelper.insertText(\"A\", 10, \"123\");\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t\t{ pos: 10, side: Side.After },\n\t\t\t);\n\t\t},\n\t\texpectedText: \"hello\",\n\t});\n\tdescribe(\"zero length\", () => {\n\t\t// TODO: #17785: Allow start and end to be used as obliteration range endpoints.\n\t\titCorrectlyObliterates.skip({\n\t\t\ttitle: \"zero length obliterate at the start of the string\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\t\thelper.processAllOps();\n\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: -1, side: Side.After },\n\t\t\t\t\t{ pos: 0, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.insertText(\"B\", 0, \"more \");\n\t\t\t},\n\t\t\texpectedText: \"hello world\",\n\t\t});\n\t\titCorrectlyObliterates({\n\t\t\ttitle: \"zero length obliterate in the middle of the string\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\t\thelper.processAllOps();\n\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: 0, side: Side.After },\n\t\t\t\t\t{ pos: 1, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.insertText(\"B\", 1, \"more \");\n\t\t\t},\n\t\t\texpectedText: \"hello world\",\n\t\t});\n\t\t// TODO: #17785: Allow start and end to be used as obliteration range endpoints.\n\t\titCorrectlyObliterates.skip({\n\t\t\ttitle: \"zero length obliterate at the end of the string\",\n\t\t\taction: (helper) => {\n\t\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\t\thelper.processAllOps();\n\n\t\t\t\thelper.obliterateRange(\n\t\t\t\t\t\"A\",\n\t\t\t\t\t{ pos: helper.clients.A.getLength() - 1, side: Side.After },\n\t\t\t\t\t{ pos: -1, side: Side.Before },\n\t\t\t\t);\n\t\t\t\thelper.insertText(\"B\", helper.clients.B.getLength(), \" more\");\n\t\t\t},\n\t\t\texpectedText: \"hello world\",\n\t\t});\n\t});\n});\n\ndescribe(\"overlapping edits\", () => {\n\titCorrectlyObliterates({\n\t\ttitle: \"overlapping obliterate and obliterate\",\n\t\taction: (helper) => {\n\t\t\tconst text = \"abcdef\";\n\n\t\t\thelper.insertText(\"A\", 0, text);\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"A\",\n\t\t\t\t{ pos: 0, side: Side.Before },\n\t\t\t\t{ pos: text.length - 1, side: Side.After },\n\t\t\t);\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 0, side: Side.Before },\n\t\t\t\t{ pos: text.length - 1, side: Side.After },\n\t\t\t);\n\t\t},\n\t\texpectedText: \"\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"adjacent obliterates\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 3, side: Side.After });\n\t\t\thelper.obliterateRange(\"B\", { pos: 4, side: Side.Before }, { pos: 5, side: Side.After });\n\t\t},\n\t\texpectedText: \"heworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"remove within obliterated range\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 5, side: Side.After });\n\t\t\thelper.removeRange(\"B\", 3, 4);\n\t\t},\n\t\texpectedText: \"heworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"obliterate, then remove adjacent to range start\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 1, side: Side.After }, { pos: 5, side: Side.After });\n\t\t\thelper.removeRange(\"B\", 1, 2);\n\t\t},\n\t\texpectedText: \"hworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"obliterate, then remove adjacent to range end\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\thelper.removeRange(\"B\", 4, 6);\n\t\t},\n\t\texpectedText: \"heworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"remove, then obliterate adjacent to range start\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.removeRange(\"A\", 4, 6);\n\t\t\thelper.obliterateRange(\"B\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t},\n\t\texpectedText: \"heworld\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"remove, then obliterate adjacent to range end\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.removeRange(\"A\", 2, 4);\n\t\t\thelper.obliterateRange(\"B\", { pos: 3, side: Side.After }, { pos: 6, side: Side.After });\n\t\t},\n\t\texpectedText: \"heorld\",\n\t});\n\n\t// This test is somewhat arbitrary: it's a minimized fuzz test failure that ended up root-causing to an issue\n\t// in SortedSegmentSet (local references were not compared correctly when put at various offsets). We also have\n\t// more direct unit tests for that, but this is a good sanity check and adds some extra verification for concurrent obliterates.\n\titCorrectlyObliterates({\n\t\ttitle: \"overlapping obliterates with third client inserting\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"0123456789\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.obliterateRange(\"A\", { pos: 7, side: Side.After }, { pos: 8, side: Side.After });\n\t\t\thelper.obliterateRange(\"C\", { pos: 1, side: Side.Before }, { pos: 8, side: Side.After });\n\t\t\thelper.insertText(\"B\", 5, \"V\");\n\t\t\thelper.processAllOps();\n\t\t},\n\t\texpectedText: \"09\",\n\t});\n});\n\ndescribe(\"sided obliterates\", () => {\n\t/**\n\t * All test cases will operate on the same numerical positions, but differ on their sidedness:\n\t * 1. A expand both endpoints, B expand neither endpoint = expand range on both endpoints\n\t * 2. A expand start endpoint, B expand end endpoint = either FWW/LWW\n\t * 3. A expand both endpoints, B expand start = expand range on both endpoints\n\t * 4. (similar to 3) A expand both endpoints, B expand end = expand range on both endpoints\n\t * 5. A expand neither endpoint, B expand start = expand start endpoint\n\t * 6. A expand neither endpoint, B expand end = expand end endpoint\n\t * before = 0, after = 1\n\t */\n\titCorrectlyObliterates({\n\t\ttitle: \"1. A expand both endpoints, B expand neither endpoint\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\t\t\t// in order to get the right behavior, the range needs to start after the previous position\n\t\t\t// if so, for a range ( 2, 4 ) itCorrectlyObliterates would need to be after 1 and before 5\n\t\t\t// h e( l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 1, side: Side.After }, { pos: 5, side: Side.Before });\n\t\t\t// [2, 4]: before 2, after 4 => h e [l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"B\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\thelper.insertText(\"C\", 2, \"123\");\n\t\t\thelper.insertText(\"C\", 8, \"456\");\n\t\t},\n\t\texpectedText: \"he world\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"2. A expand start endpoint, B expand end endpoint\",\n\t\taction: (helper) => {\n\t\t\t// currently this is the example from obliterate notation loop doc\n\t\t\t// TODO: translate this into same format as others\n\t\t\t// i think this gets difficult when the range to obliterate > 1 character\n\t\t\thelper.insertText(\"A\", 0, \"ABC\");\n\t\t\thelper.processAllOps();\n\t\t\thelper.insertText(\"A\", 2, \"D\");\n\t\t\t// ( 1]: after 0, after 1 => A( B] D C\n\t\t\thelper.obliterateRange(\"A\", { pos: 0, side: Side.After }, { pos: 1, side: Side.After });\n\t\t\t// included in the range -- should get obliterated\n\t\t\thelper.insertText(\"B\", 1, \"E\");\n\t\t\t// [1 ): before 1, before 2 => A E [B )C\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 1, side: Side.Before },\n\t\t\t\t{ pos: 3, side: Side.Before },\n\t\t\t);\n\t\t},\n\t\texpectedText: \"AC\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"3. A expand both endpoints, B expand start\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\t// ( 2, 4 ): after 1, before 5 => h e( l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 1, side: Side.After }, { pos: 5, side: Side.Before });\n\t\t\t// ( 2, 4]: after 1, after 4 => h e( l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"B\", { pos: 2, side: Side.After }, { pos: 4, side: Side.Before });\n\t\t\thelper.insertText(\"C\", 2, \"123\");\n\t\t\t// for this to be interesting, might want to insert at 5\n\t\t\thelper.insertText(\"C\", 4, \"456\");\n\t\t},\n\t\texpectedText: \"he world\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"4. A expand both endpoints, B expand end\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\t// ( 2, 4 ): after 1, before 5 => h e( l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 1, side: Side.After }, { pos: 5, side: Side.Before });\n\t\t\t// [2, 4 ): before 2, before 5 => h e [l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t);\n\t\t\thelper.insertText(\"C\", 2, \"123\"); // he123llo world\n\t\t\t// for this to be interesting, might want to insert at 5\n\t\t\thelper.insertText(\"C\", 8, \"456\"); // he123llo456 world\n\t\t},\n\t\texpectedText: \"he world\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"5. A expand neither endpoint, B expand start\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\t// [2, 4]: before 2, after 4 => h e [l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\t// ( 2, 4]: after 1, after 4 => h e( l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"B\", { pos: 1, side: Side.After }, { pos: 4, side: Side.After });\n\n\t\t\thelper.insertText(\"C\", 2, \"123\"); // h e( 123 l l o] _ w o r l d\n\t\t\thelper.insertText(\"C\", 8, \"456\"); // h e( 123 l l o) 456 _ w o r l d\n\t\t\thelper.processAllOps();\n\n\t\t\tassert.equal(helper.clients.A.getText(), \"he456 world\");\n\t\t\tassert.equal(helper.clients.B.getText(), \"he456 world\");\n\t\t\tassert.equal(helper.clients.C.getText(), \"he456 world\");\n\n\t\t\thelper.logger.validate();\n\t\t},\n\t\texpectedText: \"he456 world\",\n\t});\n\titCorrectlyObliterates({\n\t\ttitle: \"6. A expand neither endpoint, B expand end\",\n\t\taction: (helper) => {\n\t\t\thelper.insertText(\"A\", 0, \"hello world\");\n\t\t\thelper.processAllOps();\n\n\t\t\t// [2, 4]: before 2, after 4 => h e [l l o] _ w o r l d\n\t\t\thelper.obliterateRange(\"A\", { pos: 2, side: Side.Before }, { pos: 4, side: Side.After });\n\t\t\t// [2, 4 ): before 2, before 5 => h e [l l o )_ w o r l d\n\t\t\thelper.obliterateRange(\n\t\t\t\t\"B\",\n\t\t\t\t{ pos: 2, side: Side.Before },\n\t\t\t\t{ pos: 5, side: Side.Before },\n\t\t\t);\n\n\t\t\thelper.insertText(\"C\", 2, \"123\");\n\t\t\thelper.insertText(\"C\", 8, \"456\");\n\n\t\t\thelper.processAllOps();\n\n\t\t\tassert.equal(helper.clients.A.getText(), \"he123 world\");\n\t\t\tassert.equal(helper.clients.B.getText(), \"he123 world\");\n\t\t\tassert.equal(helper.clients.C.getText(), \"he123 world\");\n\n\t\t\thelper.logger.validate();\n\t\t},\n\t\texpectedText: \"he123 world\",\n\t});\n});\n"]}
|
|
@@ -5,11 +5,20 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
const node_assert_1 = require("node:assert");
|
|
8
|
+
const test_pairwise_generator_1 = require("@fluid-private/test-pairwise-generator");
|
|
8
9
|
const mergeTree_js_1 = require("../mergeTree.js");
|
|
9
|
-
const
|
|
10
|
+
const sequencePlace_js_1 = require("../sequencePlace.js");
|
|
11
|
+
const clientTestHelper_js_1 = require("./clientTestHelper.js");
|
|
10
12
|
const testUtils_js_1 = require("./testUtils.js");
|
|
11
|
-
for (const incremental of
|
|
12
|
-
|
|
13
|
+
for (const { incremental, mergeTreeEnableSidedObliterate } of (0, test_pairwise_generator_1.generatePairwiseOptions)({
|
|
14
|
+
incremental: [true, false],
|
|
15
|
+
mergeTreeEnableSidedObliterate: [
|
|
16
|
+
false,
|
|
17
|
+
// TODO:AB#31001: Enable this once sided obliterate supports reconnect.
|
|
18
|
+
// true,
|
|
19
|
+
],
|
|
20
|
+
})) {
|
|
21
|
+
describe(`obliterate partial lengths incremental = ${incremental} enableSidedObliterate = ${mergeTreeEnableSidedObliterate}`, () => {
|
|
13
22
|
(0, testUtils_js_1.useStrictPartialLengthChecks)();
|
|
14
23
|
beforeEach(() => {
|
|
15
24
|
mergeTree_js_1.MergeTree.options.incrementalUpdate = incremental;
|
|
@@ -18,68 +27,60 @@ for (const incremental of [true, false]) {
|
|
|
18
27
|
mergeTree_js_1.MergeTree.options.incrementalUpdate = true;
|
|
19
28
|
});
|
|
20
29
|
it("obliterate does not expand during rebase", () => {
|
|
21
|
-
const helper = new
|
|
30
|
+
const helper = new clientTestHelper_js_1.ClientTestHelper({ mergeTreeEnableSidedObliterate });
|
|
22
31
|
helper.insertText("B", 0, "ABCD");
|
|
23
32
|
helper.processAllOps();
|
|
24
33
|
helper.removeRange("B", 0, 3);
|
|
25
|
-
helper.disconnect(
|
|
26
|
-
|
|
27
|
-
helper.reconnect(
|
|
28
|
-
helper.submitDisconnectedOp("C", cOp);
|
|
34
|
+
helper.disconnect("C");
|
|
35
|
+
helper.obliterateRange("C", 0, 1);
|
|
36
|
+
helper.reconnect("C");
|
|
29
37
|
helper.processAllOps();
|
|
30
38
|
node_assert_1.strict.equal(helper.clients.A.getText(), "D");
|
|
31
39
|
helper.logger.validate();
|
|
32
40
|
});
|
|
33
41
|
it("does delete reconnected insert into obliterate range if insert is rebased", () => {
|
|
34
|
-
const helper = new
|
|
42
|
+
const helper = new clientTestHelper_js_1.ClientTestHelper({ mergeTreeEnableSidedObliterate });
|
|
35
43
|
helper.insertText("B", 0, "ABCD");
|
|
36
44
|
helper.processAllOps();
|
|
37
45
|
helper.obliterateRange("B", 0, 3);
|
|
38
|
-
helper.disconnect(
|
|
39
|
-
|
|
40
|
-
helper.reconnect(
|
|
41
|
-
helper.submitDisconnectedOp("C", cOp);
|
|
46
|
+
helper.disconnect("C");
|
|
47
|
+
helper.insertText("C", 2, "aaa");
|
|
48
|
+
helper.reconnect("C");
|
|
42
49
|
helper.processAllOps();
|
|
43
50
|
node_assert_1.strict.equal(helper.clients.A.getText(), "D");
|
|
44
51
|
node_assert_1.strict.equal(helper.clients.C.getText(), "D");
|
|
45
52
|
helper.logger.validate();
|
|
46
53
|
});
|
|
47
54
|
it("deletes reconnected insert into obliterate range when entire string deleted if rebased", () => {
|
|
48
|
-
const helper = new
|
|
55
|
+
const helper = new clientTestHelper_js_1.ClientTestHelper({ mergeTreeEnableSidedObliterate });
|
|
49
56
|
helper.insertText("B", 0, "ABCD");
|
|
50
57
|
helper.processAllOps();
|
|
51
58
|
helper.obliterateRange("B", 0, 4);
|
|
52
|
-
helper.disconnect(
|
|
53
|
-
|
|
54
|
-
helper.reconnect(
|
|
55
|
-
helper.submitDisconnectedOp("C", cOp);
|
|
59
|
+
helper.disconnect("C");
|
|
60
|
+
helper.insertText("C", 2, "aaa");
|
|
61
|
+
helper.reconnect("C");
|
|
56
62
|
helper.processAllOps();
|
|
57
63
|
node_assert_1.strict.equal(helper.clients.A.getText(), "");
|
|
58
64
|
node_assert_1.strict.equal(helper.clients.C.getText(), "");
|
|
59
65
|
helper.logger.validate();
|
|
60
66
|
});
|
|
61
67
|
it("obliterates local segment while disconnected", () => {
|
|
62
|
-
const helper = new
|
|
68
|
+
const helper = new clientTestHelper_js_1.ClientTestHelper({ mergeTreeEnableSidedObliterate });
|
|
63
69
|
// [C]-D-(E)-F-H-G-B-A
|
|
64
70
|
helper.insertText("B", 0, "A");
|
|
65
|
-
helper.disconnect(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
helper.reconnect(
|
|
72
|
-
helper.submitDisconnectedOp("C", op0);
|
|
73
|
-
helper.submitDisconnectedOp("C", op1);
|
|
74
|
-
helper.submitDisconnectedOp("C", op2);
|
|
75
|
-
helper.submitDisconnectedOp("C", op3);
|
|
76
|
-
helper.submitDisconnectedOp("C", op4);
|
|
71
|
+
helper.disconnect("C");
|
|
72
|
+
helper.insertText("C", 0, "B");
|
|
73
|
+
helper.insertText("C", 0, "CDEFG");
|
|
74
|
+
helper.removeRange("C", 0, 1);
|
|
75
|
+
helper.obliterateRange("C", 1, 2);
|
|
76
|
+
helper.insertText("C", 2, "H");
|
|
77
|
+
helper.reconnect("C");
|
|
77
78
|
helper.processAllOps();
|
|
78
79
|
node_assert_1.strict.equal(helper.clients.A.getText(), "DFHGBA");
|
|
79
80
|
helper.logger.validate();
|
|
80
81
|
});
|
|
81
82
|
it("deletes concurrently inserted segment between separated group ops", () => {
|
|
82
|
-
const helper = new
|
|
83
|
+
const helper = new clientTestHelper_js_1.ClientTestHelper({ mergeTreeEnableSidedObliterate });
|
|
83
84
|
// B-A
|
|
84
85
|
// (B-C-A)
|
|
85
86
|
helper.insertText("A", 0, "A");
|
|
@@ -87,39 +88,37 @@ for (const incremental of [true, false]) {
|
|
|
87
88
|
helper.processAllOps();
|
|
88
89
|
helper.logger.validate();
|
|
89
90
|
helper.insertText("A", 1, "C");
|
|
90
|
-
helper.disconnect(
|
|
91
|
-
|
|
92
|
-
helper.reconnect(
|
|
93
|
-
helper.submitDisconnectedOp("B", op);
|
|
91
|
+
helper.disconnect("B");
|
|
92
|
+
helper.obliterateRange("B", 0, 2);
|
|
93
|
+
helper.reconnect("B");
|
|
94
94
|
helper.processAllOps();
|
|
95
95
|
node_assert_1.strict.equal(helper.clients.A.getText(), "");
|
|
96
96
|
helper.logger.validate();
|
|
97
97
|
});
|
|
98
98
|
it("removes correct number of pending segments", () => {
|
|
99
|
-
const helper = new
|
|
99
|
+
const helper = new clientTestHelper_js_1.ClientTestHelper({ mergeTreeEnableSidedObliterate });
|
|
100
100
|
// (BC)-[A]
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
helper.
|
|
105
|
-
helper.
|
|
106
|
-
helper.submitDisconnectedOp("A", op2);
|
|
101
|
+
helper.disconnect("A");
|
|
102
|
+
helper.insertText("A", 0, "A");
|
|
103
|
+
helper.insertText("A", 1, "BC");
|
|
104
|
+
helper.obliterateRange("A", 0, 2);
|
|
105
|
+
helper.reconnect("A");
|
|
107
106
|
helper.removeRange("A", 0, 1);
|
|
108
107
|
helper.processAllOps();
|
|
109
108
|
node_assert_1.strict.equal(helper.clients.A.getText(), "");
|
|
110
109
|
helper.logger.validate();
|
|
111
110
|
});
|
|
112
111
|
it("doesn't do obliterate ack traversal when starting segment has been acked", () => {
|
|
113
|
-
const helper = new
|
|
112
|
+
const helper = new clientTestHelper_js_1.ClientTestHelper({ mergeTreeEnableSidedObliterate });
|
|
114
113
|
// AB
|
|
115
114
|
// (E)-[F]-(G-D-(C-A)-B)
|
|
116
115
|
helper.insertText("B", 0, "AB");
|
|
117
116
|
helper.processAllOps();
|
|
118
117
|
helper.logger.validate();
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
helper.
|
|
122
|
-
helper.
|
|
118
|
+
helper.disconnect("A");
|
|
119
|
+
helper.insertText("A", 0, "C");
|
|
120
|
+
helper.obliterateRange("A", 0, 2);
|
|
121
|
+
helper.reconnect("A");
|
|
123
122
|
helper.insertText("B", 0, "D");
|
|
124
123
|
helper.insertText("A", 0, "EFG");
|
|
125
124
|
helper.obliterateRange("A", 0, 1);
|
|
@@ -130,32 +129,210 @@ for (const incremental of [true, false]) {
|
|
|
130
129
|
helper.logger.validate();
|
|
131
130
|
});
|
|
132
131
|
it("does not delete reconnected insert at start of obliterate range if rebased", () => {
|
|
133
|
-
const helper = new
|
|
132
|
+
const helper = new clientTestHelper_js_1.ClientTestHelper({ mergeTreeEnableSidedObliterate });
|
|
134
133
|
helper.insertText("B", 0, "ABCD");
|
|
135
134
|
helper.processAllOps();
|
|
136
135
|
helper.obliterateRange("B", 0, 3);
|
|
137
|
-
helper.disconnect(
|
|
138
|
-
|
|
139
|
-
helper.reconnect(
|
|
140
|
-
helper.submitDisconnectedOp("C", cOp);
|
|
136
|
+
helper.disconnect("C");
|
|
137
|
+
helper.insertText("C", 0, "aaa");
|
|
138
|
+
helper.reconnect("C");
|
|
141
139
|
helper.processAllOps();
|
|
142
140
|
node_assert_1.strict.equal(helper.clients.A.getText(), "aaaD");
|
|
143
141
|
node_assert_1.strict.equal(helper.clients.C.getText(), "aaaD");
|
|
144
142
|
helper.logger.validate();
|
|
145
143
|
});
|
|
146
144
|
it("does not delete reconnected insert at end of obliterate range", () => {
|
|
147
|
-
const helper = new
|
|
145
|
+
const helper = new clientTestHelper_js_1.ClientTestHelper({ mergeTreeEnableSidedObliterate });
|
|
148
146
|
helper.insertText("B", 0, "ABCD");
|
|
149
147
|
helper.processAllOps();
|
|
150
148
|
helper.obliterateRange("B", 0, 3);
|
|
151
|
-
helper.disconnect(
|
|
152
|
-
|
|
153
|
-
helper.reconnect(
|
|
154
|
-
helper.submitDisconnectedOp("C", cOp);
|
|
149
|
+
helper.disconnect("C");
|
|
150
|
+
helper.insertText("C", 3, "aaa");
|
|
151
|
+
helper.reconnect("C");
|
|
155
152
|
helper.processAllOps();
|
|
156
153
|
node_assert_1.strict.equal(helper.clients.A.getText(), "aaaD");
|
|
157
154
|
helper.logger.validate();
|
|
158
155
|
});
|
|
159
156
|
});
|
|
160
157
|
}
|
|
158
|
+
describe("sided obliterate reconnect", () => {
|
|
159
|
+
(0, testUtils_js_1.itCorrectlyObliterates)({
|
|
160
|
+
title: "add text, disconnect, obliterate, reconnect, insert adjacent to obliterated range",
|
|
161
|
+
action: (helper) => {
|
|
162
|
+
helper.insertText("A", 0, "hello world");
|
|
163
|
+
helper.processAllOps();
|
|
164
|
+
helper.disconnect("C");
|
|
165
|
+
helper.obliterateRange("C", { pos: 1, side: sequencePlace_js_1.Side.After }, { pos: 4, side: sequencePlace_js_1.Side.After });
|
|
166
|
+
// inserting adjacent to the obliterated range start
|
|
167
|
+
helper.reconnect("C");
|
|
168
|
+
helper.insertText("A", 2, "123");
|
|
169
|
+
},
|
|
170
|
+
expectedText: "he world",
|
|
171
|
+
});
|
|
172
|
+
(0, testUtils_js_1.itCorrectlyObliterates)({
|
|
173
|
+
title: "add text, disconnect, obliterate, insert adjacent to obliterated range, reconnect",
|
|
174
|
+
action: (helper) => {
|
|
175
|
+
helper.insertText("A", 0, "hello world");
|
|
176
|
+
helper.processAllOps();
|
|
177
|
+
helper.disconnect("C");
|
|
178
|
+
helper.obliterateRange("C", { pos: 1, side: sequencePlace_js_1.Side.After }, { pos: 4, side: sequencePlace_js_1.Side.After });
|
|
179
|
+
// inserting adjacent to the obliterated range start
|
|
180
|
+
helper.insertText("A", 2, "123");
|
|
181
|
+
helper.reconnect("C");
|
|
182
|
+
},
|
|
183
|
+
expectedText: "he world",
|
|
184
|
+
});
|
|
185
|
+
describe("obliterate rebasing over", () => {
|
|
186
|
+
for (const { removalType, getRemoveMethod } of [
|
|
187
|
+
{
|
|
188
|
+
removalType: "remove",
|
|
189
|
+
getRemoveMethod: (helper) => helper.removeRange.bind(helper),
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
removalType: "obliterate",
|
|
193
|
+
getRemoveMethod: (helper) => helper.obliterateRange.bind(helper),
|
|
194
|
+
},
|
|
195
|
+
]) {
|
|
196
|
+
(0, testUtils_js_1.itCorrectlyObliterates)({
|
|
197
|
+
title: `${removalType} overlapping obliterate start`,
|
|
198
|
+
action: (helper) => {
|
|
199
|
+
helper.insertText("A", 0, "0123456789");
|
|
200
|
+
helper.processAllOps();
|
|
201
|
+
helper.disconnect("B");
|
|
202
|
+
helper.obliterateRange("B", { pos: 1, side: sequencePlace_js_1.Side.Before }, { pos: 8, side: sequencePlace_js_1.Side.After });
|
|
203
|
+
helper.insertText("A", 5, "should be obliterated");
|
|
204
|
+
getRemoveMethod(helper)("A", 0, 2);
|
|
205
|
+
helper.reconnect("B");
|
|
206
|
+
},
|
|
207
|
+
expectedText: "9",
|
|
208
|
+
});
|
|
209
|
+
(0, testUtils_js_1.itCorrectlyObliterates)({
|
|
210
|
+
title: `${removalType} overlapping obliterate middle`,
|
|
211
|
+
action: (helper) => {
|
|
212
|
+
helper.insertText("A", 0, "0123456789");
|
|
213
|
+
helper.processAllOps();
|
|
214
|
+
helper.disconnect("B");
|
|
215
|
+
helper.obliterateRange("B", { pos: 1, side: sequencePlace_js_1.Side.Before }, { pos: 8, side: sequencePlace_js_1.Side.After });
|
|
216
|
+
getRemoveMethod(helper)("A", 3, 4);
|
|
217
|
+
helper.insertText("A", 5, "should be obliterated");
|
|
218
|
+
helper.reconnect("B");
|
|
219
|
+
},
|
|
220
|
+
expectedText: "09",
|
|
221
|
+
});
|
|
222
|
+
(0, testUtils_js_1.itCorrectlyObliterates)({
|
|
223
|
+
title: `${removalType} overlapping obliterate end`,
|
|
224
|
+
action: (helper) => {
|
|
225
|
+
helper.insertText("A", 0, "0123456789");
|
|
226
|
+
helper.processAllOps();
|
|
227
|
+
helper.disconnect("B");
|
|
228
|
+
helper.obliterateRange("B", { pos: 1, side: sequencePlace_js_1.Side.Before }, { pos: 8, side: sequencePlace_js_1.Side.After });
|
|
229
|
+
getRemoveMethod(helper)("A", 8, 10);
|
|
230
|
+
helper.insertText("A", 5, "should be obliterated");
|
|
231
|
+
helper.reconnect("B");
|
|
232
|
+
},
|
|
233
|
+
expectedText: "0",
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
// This test and the analogous endpoint test below provide some rationale for the policy of tending to shrink obliterates
|
|
238
|
+
// inward upon reconnect in the case that regions near their endpoints were removed between the original submission and resubmission.
|
|
239
|
+
(0, testUtils_js_1.itCorrectlyObliterates)({
|
|
240
|
+
title: "obliterate shrinks start point to best possible option",
|
|
241
|
+
action: (helper) => {
|
|
242
|
+
helper.insertText("A", 0, "0123456789");
|
|
243
|
+
helper.processAllOps();
|
|
244
|
+
helper.disconnect("B");
|
|
245
|
+
helper.obliterateRange("B", { pos: 3, side: sequencePlace_js_1.Side.After }, { pos: 8, side: sequencePlace_js_1.Side.Before }); // 4 through 7
|
|
246
|
+
helper.insertText("A", 7, "inside the original obliterate");
|
|
247
|
+
helper.removeRange("C", 1, 5); // 1234
|
|
248
|
+
helper.advanceClients("B");
|
|
249
|
+
// B recognizes an observer client at this seq will have '056inside the original obliterate789' and B's obliterate should additionally
|
|
250
|
+
// remove '5inside the original obliterate67'.
|
|
251
|
+
// It reconnects at this point and has a choice: it can either specify the startpoint of the obliterate as 'after the 0 character'
|
|
252
|
+
// (preserving the original side) or 'before the 5 character' (which will make its start endpoint no longer "sticky" like
|
|
253
|
+
// the original one). Seeing as the original startpoint has actually already been removed, we should choose the latter.
|
|
254
|
+
helper.reconnect("B");
|
|
255
|
+
// The possibility of another client doing something like this is additional justification for this policy:
|
|
256
|
+
// (point being that B will see this segment as clearly after the "0" character since it was inserted before the 3 in the original string)
|
|
257
|
+
helper.insertText("A", 3, "outside the original obliterate but in danger of being in the new one");
|
|
258
|
+
},
|
|
259
|
+
expectedText: "0outside the original obliterate but in danger of being in the new one89",
|
|
260
|
+
});
|
|
261
|
+
(0, testUtils_js_1.itCorrectlyObliterates)({
|
|
262
|
+
title: "obliterate shrinks end point to best possible option",
|
|
263
|
+
action: (helper) => {
|
|
264
|
+
helper.insertText("A", 0, "0123456789");
|
|
265
|
+
helper.processAllOps();
|
|
266
|
+
helper.disconnect("B");
|
|
267
|
+
helper.obliterateRange("B", { pos: 3, side: sequencePlace_js_1.Side.After }, { pos: 8, side: sequencePlace_js_1.Side.Before }); // 4 through 7
|
|
268
|
+
helper.insertText("A", 7, "inside the original obliterate");
|
|
269
|
+
helper.removeRange("C", 6, 9); // 678
|
|
270
|
+
helper.advanceClients("B");
|
|
271
|
+
// B recognizes an observer client at this seq will have '056inside the original obliterate789' and B's obliterate should additionally
|
|
272
|
+
// remove '5inside the original obliterate67'.
|
|
273
|
+
// It reconnects at this point and has a choice: it can either specify the startpoint of the obliterate as 'after the 0 character'
|
|
274
|
+
// (preserving the original side) or 'before the 5 character' (which will make its start endpoint no longer "sticky" like
|
|
275
|
+
// the original one). Seeing as the original startpoint has actually already been removed, we should choose the latter.
|
|
276
|
+
helper.reconnect("B");
|
|
277
|
+
// The possibility of another client doing something like this is additional justification for this policy:
|
|
278
|
+
// (point being that B will see this segment as clearly after the "0" character since it was inserted before the 3 in the original string)
|
|
279
|
+
helper.insertText("A", 9 + "inside the original obliterate".length, "outside the original obliterate but in danger of being in the new one");
|
|
280
|
+
},
|
|
281
|
+
expectedText: "0123outside the original obliterate but in danger of being in the new one9",
|
|
282
|
+
});
|
|
283
|
+
(0, testUtils_js_1.itCorrectlyObliterates)({
|
|
284
|
+
title: "recomputes obliterate tiebreak winner",
|
|
285
|
+
action: (helper) => {
|
|
286
|
+
helper.insertText("A", 0, "ABCDEFGHIJKLMNOPQ");
|
|
287
|
+
helper.processAllOps();
|
|
288
|
+
helper.disconnect("B");
|
|
289
|
+
helper.obliterateRange("D", { pos: 0, side: sequencePlace_js_1.Side.Before }, { pos: 6, side: sequencePlace_js_1.Side.After }); // ABCDEFG
|
|
290
|
+
helper.obliterateRange("C", { pos: 2, side: sequencePlace_js_1.Side.Before }, { pos: 8, side: sequencePlace_js_1.Side.After }); // CDEFGHI
|
|
291
|
+
helper.obliterateRange("B", { pos: 3, side: sequencePlace_js_1.Side.After }, { pos: 4, side: sequencePlace_js_1.Side.After }); // D
|
|
292
|
+
// This insertion position by B is critically inside the range that B originally obliterated, but that will no longer be the case
|
|
293
|
+
// later on when B reconnects, since the region B wanted to obliterate will be gone (so there is no way to specify the same obliterate).
|
|
294
|
+
helper.insertText("B", 4, "should go away");
|
|
295
|
+
helper.processAllOps();
|
|
296
|
+
helper.removeRange("C", 0, 1); // J
|
|
297
|
+
helper.insertText("C", 0, "01234567"); // C now sees '01234567KLMNOPQ'
|
|
298
|
+
helper.processAllOps();
|
|
299
|
+
// B now needs to recognize that it no longer necessarily has 'last-write-win' privilege over its insertion
|
|
300
|
+
// in the event that the new insertion position was obliterated concurrently to the op it's about to (re)submit.
|
|
301
|
+
helper.reconnect("B");
|
|
302
|
+
// ... and indeed, in this case A has obliterated a region containing the "should go away" B inserted.
|
|
303
|
+
helper.obliterateRange("A", { pos: 7, side: sequencePlace_js_1.Side.After }, { pos: 9, side: sequencePlace_js_1.Side.Before }); // K in '01234567KLMNOPQ', expanding on both ends
|
|
304
|
+
},
|
|
305
|
+
expectedText: "01234567LMNOPQ",
|
|
306
|
+
});
|
|
307
|
+
// This test case demonstrates the need to 'pre-compute' the result of rebasing obliterate endpoints upon reconnection
|
|
308
|
+
// before segment order is normalized.
|
|
309
|
+
// TODO: AB#34898: This seems to demonstrate an issue with segment normalization which should be investigated.
|
|
310
|
+
// Resolving that work item may involve including this as a test case targeted at segment ordering instead, and finding an analogous case
|
|
311
|
+
// where legitimate segment reording could affect obliterate rebasing.
|
|
312
|
+
(0, testUtils_js_1.itCorrectlyObliterates)({
|
|
313
|
+
title: "computes obliterate rebases before segment normalization",
|
|
314
|
+
action: (helper) => {
|
|
315
|
+
helper.insertText("A", 0, "0ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
|
316
|
+
helper.processAllOps();
|
|
317
|
+
helper.disconnect("B");
|
|
318
|
+
helper.obliterateRange("B", { pos: 9, side: sequencePlace_js_1.Side.Before }, { pos: 26, side: sequencePlace_js_1.Side.After }); // I through Z inclusive
|
|
319
|
+
helper.insertText("B", 3, "e"); // between "B" and "C"
|
|
320
|
+
helper.obliterateRange("B", { pos: 2, side: sequencePlace_js_1.Side.After }, { pos: 6, side: sequencePlace_js_1.Side.After }); // the inserted 'e' through F inclusive
|
|
321
|
+
helper.obliterateRange("A", { pos: 4, side: sequencePlace_js_1.Side.After }, { pos: 15, side: sequencePlace_js_1.Side.Before }); // E through N inclusive
|
|
322
|
+
helper.processAllOps();
|
|
323
|
+
// Before reconnecting, B's segment order is:
|
|
324
|
+
// 0ABeCDEFGHIJKLMNOPQRSTUVWXYZ
|
|
325
|
+
// B has issued obliterates for:
|
|
326
|
+
// 0ABeCDEFGHIJKLMNOPQRSTUVWXYZ
|
|
327
|
+
// ( ] [ ]
|
|
328
|
+
// and it sees that A has already obliterated:
|
|
329
|
+
// 0ABeCDEFGHIJKLMNOPQRSTUVWXYZ
|
|
330
|
+
// ( )
|
|
331
|
+
// Segment normalization on B will reorder "eCDEFGHIJKLMNOPQRSTUVWXYZ" to "eCDOPQRSTUVWXYZEFGHIJKLMN"
|
|
332
|
+
// (note that this seems unnecessary and is why AB#34898 is filed)
|
|
333
|
+
helper.reconnect("B");
|
|
334
|
+
},
|
|
335
|
+
expectedText: "0AB",
|
|
336
|
+
});
|
|
337
|
+
});
|
|
161
338
|
//# sourceMappingURL=obliterate.reconnect.spec.js.map
|