@fluidframework/debugger 2.83.0 → 2.90.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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # @fluidframework/debugger
2
2
 
3
+ ## 2.90.0
4
+
5
+ Dependency updates only.
6
+
3
7
  ## 2.83.0
4
8
 
5
9
  Dependency updates only.
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebuggerController.d.ts","sourceRoot":"","sources":["../src/fluidDebuggerController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fluidDebuggerController.d.ts","sourceRoot":"","sources":["../src/fluidDebuggerController.ts"],"names":[],"mappings":"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"}
@@ -227,7 +227,6 @@ class DebugReplayController extends internal_3.ReplayController {
227
227
  }
228
228
  async replay(emitter, fetchedOps) {
229
229
  let _fetchedOps = fetchedOps;
230
- // eslint-disable-next-line no-constant-condition
231
230
  while (true) {
232
231
  if (_fetchedOps.length === 0) {
233
232
  this.ui.updateNextOpText([]);
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebuggerController.js","sourceRoot":"","sources":["../src/fluidDebuggerController.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAuE;AAUvE,oEAAqE;AACrE,qEAMgD;AAGhD,iDAA2C;AAQ3C;;;GAGG;AACH,MAAa,qBAAsB,SAAQ,2BAAgB;IAA3D;;QAgCW,OAAE,GAAgB,IAA0B,CAAC,CAAC,gDAAgD;QAE9F,qBAAgB,GAAG,IAAI,mBAAQ,EAAU,CAAC;QAEpD,kEAAkE;QACxD,6BAAwB,GAAG,KAAK,CAAC;QAIjC,aAAQ,GAAe,EAAE,CAAC;QAC1B,gBAAW,GAAW,CAAC,CAAC;QACxB,kBAAa,GAAG,KAAK,CAAC;QACtB,iBAAY,GAAG,CAAC,CAAC;IAqS5B,CAAC;IAhVA,kDAAkD;IAC3C,MAAM,CAAC,MAAM,CAAC,QAA2B;QAC/C,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,EAAE,aAAa,EAAE,CAAC;YACrE,MAAM,UAAU,GAAG,IAAI,qBAAqB,EAAE,CAAC;YAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;YAChC,IAAI,EAAE,EAAE,CAAC;gBACR,OAAO,UAAU,CAAC;YACnB,CAAC;QACF,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAIS,MAAM,CAAC,KAAK,CAAC,WAAW,CACjC,sBAA+C,EAC/C,IAA0B;QAE1B,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,CAAC,CAAC;QACV,CAAC;QAED,0CAA0C;QAC1C,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAE,CAAC,KAAK,CAAC,UAAW,CAAC;QAClE,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAY,EAChC,sBAAsB,EACtB,cAAc,CACd,CAAC;QACF,OAAO,MAAM,CAAC,cAAc,CAAC;IAC9B,CAAC;IAsBM,WAAW,CAAC,EAAe;QACjC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,CAAC;IAEM,OAAO;QACb,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;IACtE,CAAC;IAED,kEAAkE;IAC3D,KAAK,CAAC,kBAAkB,CAAC,OAAiB;QAChD,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACxE,MAAM,GAAG,GAAG,MAAM,qBAAqB,CAAC,WAAW,CAAC,IAAI,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;QACvF,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,0BAAe,CAAC,IAAI,CAAC,sBAAsB,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;IAC3F,CAAC;IAEM,eAAe,CAAC,KAAa;QACnC,IAAI,IAAI,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YAC7D,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;IAEM,uBAAuB,CAAC,IAAU;QACxC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,wBAAwB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3C,OAAO;QACR,CAAC;QACD,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,KAAK,CAAC,wDAAwD,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3E,OAAO;QACR,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,MAAM,GAAG,KAAK,IAAI,EAAE;YAC1B,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBACjC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAgB,CAAC;gBACrC,IAAI,CAAC;oBACJ,MAAM,IAAI,GAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAkB,CAAC;oBAC9D;;;;;;;;;sBASiB;oBACjB,kEAAkE;oBAClE,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC;oBACtC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;oBAC1B,IAAI,CAAC,cAAc,CAClB,MAAM,CAAC,gBAAgB,EACvB,IAAI,6BAAkB,CAAC,IAAI,CAAC,EAC5B,IAAI,CAAC,IAAI,CACT,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,KAAK,CAAC,uBAAuB,KAAK,EAAE,CAAC,CAAC;oBACtC,OAAO;gBACR,CAAC;YACF,CAAC;QACF,CAAC,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,wBAAwB,CAAC,SAAkB;QACvD,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,2BAA2B,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,qBAAqB,EAAE,CAAC;QACvF,IAAI,QAAQ,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,2BAA2B,CAAC,CAAC;QAEhF,IAAI,SAAS,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;YACrF,QAAQ,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;QACjC,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IAEO,KAAK,CAAC,wBAAwB,CACrC,2BAA2B;QAE3B,MAAM,cAAc,GAAG,yCAAyC,CAC/D,2BAA2B,CAC3B,CAAC;QACF,IAAI,QAAQ,GAAgC,EAAE,CAAC;QAC/C,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;YAC5C,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAEM,OAAO,CAAC,SAAiB;QAC/B,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,2DAA2D;IACpD,eAAe;QACrB,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC;IACnC,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAC/B,sBAA+C,EAC/C,WAA0B,EAC1B,KAAa,EACb,OAAiB;QAEjB,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC5B,OAAO;QACR,CAAC;QAED,MAAM,WAAW,CAAC;QAElB,MAAM,KAAK,GAAG,MAAM,sBAAsB,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,WAAW,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAEpF,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC7C,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7C,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,eAAiC;QACzD,IAAI,IAAI,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC,mBAAmB,CAAC;QACjC,CAAC;QAED,IAAA,iBAAM,EAAC,CAAC,CAAC,eAAe,EAAE,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACnE,IAAA,iBAAM,EAAC,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC3E,IAAA,iBAAM,EAAC,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC1F,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,sBAAsB,GAAG,MAAM,eAAe,CAAC,gBAAgB,EAAE,CAAC;QAEvE,+CAA+C;QAC/C,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC7B,IAAI,CAAC,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACtE,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;gBAC7B,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACnC,IAAI,CAAC,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9C,CAAC;QACF,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAEzC,+EAA+E;QAC/E,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,MAAM,IAAI,GAAoB,EAAE,CAAC;QACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,IAAI,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;YACpC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;gBACpE,mEAAmE;gBACnE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAE,CAAC;gBACtC,WAAW,GAAG,IAAI,CAAC,mBAAmB,CACrC,IAAI,CAAC,sBAAsB,EAC3B,WAAW,EACX,KAAK,EACL,OAAO,CACP,CAAC;YACH,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxB,CAAC;QAED,oCAAoC;QACpC,mEAAmE;QACnE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YAC3B,IAAI,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,oEAAoE;QACpE,IAAI,CAAC,mBAAmB;YACvB,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,qBAAqB,CAAC,eAAe,CAAC;QAEjF,IAAA,iBAAM,EACL,IAAI,CAAC,eAAe,EAAE,KAAK,IAAI,CAAC,mBAAmB,EACnD,KAAK,CAAC,0EAA0E,CAChF,CAAC;QACF,OAAO,IAAI,CAAC,mBAAmB,CAAC;IACjC,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,MAAc;QACnC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAClE,CAAC;IAED,kDAAkD;IAC3C,KAAK,CAAC,WAAW,CAAC,SAAwB,EAAE,KAAa;QAC/D,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAClD,CAAC;IAED,kDAAkD;IAC3C,KAAK,CAAC,eAAe,CAAC,gBAA2B;QACvD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC3E,CAAC;IAEM,KAAK,CAAC,qBAAqB;QACjC,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;IACtC,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,SAAiB,EAAE,aAAsB;QAC3D,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC1B,IAAI,SAAS,KAAK,MAAM,CAAC,gBAAgB,EAAE,CAAC;gBAC3C,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAC5C,CAAC;QACF,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC;IAC7D,CAAC;IAEM,KAAK,CAAC,MAAM,CAClB,OAAkD,EAClD,UAAuC;QAEvC,IAAI,WAAW,GAAG,UAAU,CAAC;QAC7B,iDAAiD;QACjD,OAAO,IAAI,EAAE,CAAC;YACb,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;gBAC7B,OAAO;YACR,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;gBACnC,IAAI,CAAC,aAAa,GAAG,IAAI,mBAAQ,EAAU,CAAC;gBAE5C,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;gBAEtC,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;gBAEpD,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;gBAC/B,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;YAED,IAAI,OAAoC,CAAC;YACzC,IAAI,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;gBAC5C,OAAO,GAAG,WAAW,CAAC;gBACtB,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,CAAC;gBACvC,WAAW,GAAG,EAAE,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACP,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBAClD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;YACtB,CAAC;YACD,OAAO,CAAC,OAAO,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;IAES,cAAc,CACvB,GAAW,EACX,OAAuC,EACvC,OAA0B;QAE1B,IAAA,iBAAM,EACL,CAAC,IAAI,CAAC,eAAe,EAAE,EACvB,KAAK,CAAC,wDAAwD,CAC9D,CAAC;QACF,IAAA,iBAAM,EAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAA,iBAAM,EACL,IAAI,CAAC,eAAe,EAAE,EACtB,KAAK,CAAC,iEAAiE,CACvE,CAAC;QAEF,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;;AAhVF,sDAiVC;AApU0B,qCAAe,GAAG,CAAC,CAAC,AAAL,CAAM,CAAC,2CAA2C;AAsU5F,KAAK,SAAS,CAAC,CAAC,yCAAyC,CACxD,YAA0C;IAE1C,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACxD,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO;QACR,CAAC;QACD,MAAM,MAAM,CAAC,KAAK,CAAC;IACpB,CAAC;AACF,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, Deferred } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentAttributes,\n\tISnapshotTree,\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport {\n\tFileSnapshotReader,\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi.js\";\nimport { Sanitizer } from \"./sanitizer.js\";\n\n/**\n * @internal\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n * @internal\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (typeof localStorage === \"object\" && localStorage?.FluidDebugger) {\n\t\t\tconst controller = new DebugReplayController();\n\t\t\tconst ui = createUi(controller);\n\t\t\tif (ui) {\n\t\t\t\treturn controller;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected static readonly WindowClosedSeq = -1; // Seq# to indicate that user closed window\n\n\tprotected static async seqFromTree(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\ttree: ISnapshotTree | null,\n\t): Promise<number> {\n\t\tif (!tree) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// TODO Why are we non null asserting here\n\t\tconst attributesHash = tree.trees[\".protocol\"]!.blobs.attributes!;\n\t\tconst attrib = await readAndParse<IDocumentAttributes>(\n\t\t\tdocumentStorageService,\n\t\t\tattributesHash,\n\t\t);\n\t\treturn attrib.sequenceNumber;\n\t}\n\n\tprotected ui: IDebuggerUI = null as any as IDebuggerUI; // Not to check on every line that it's not null\n\tprotected stepsDeferred?: Deferred<number>;\n\tprotected startSeqDeferred = new Deferred<number>();\n\n\t// True will cause us ping server indefinitely waiting for new ops\n\tprotected retryFetchOpsOnEndOfFile = false;\n\n\tprotected documentService?: IDocumentService;\n\tprotected documentStorageService?: IDocumentStorageService;\n\tprotected versions: IVersion[] = [];\n\tprotected stepsToPlay: number = 0;\n\tprotected lastOpReached = false;\n\tprotected versionCount = 0;\n\n\tprotected storage?: ReadDocumentStorageServiceBase;\n\n\t// Member to prevent repeated initialization in initStorage(...), which also\n\t// returns if this controller should be used or function as a passthrough\n\tprivate shouldUseController: boolean | undefined;\n\n\tpublic connectToUi(ui: IDebuggerUI): void {\n\t\tthis.ui = ui;\n\t}\n\n\tpublic onClose(): void {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async onVersionSelection(version: IVersion): Promise<void> {\n\t\tif (!this.documentStorageService) {\n\t\t\tthrow new Error(\"onVersionSelection: no storage\");\n\t\t}\n\n\t\tconst tree = await this.documentStorageService.getSnapshotTree(version);\n\t\tconst seq = await DebugReplayController.seqFromTree(this.documentStorageService, tree);\n\t\tthis.resolveStorage(seq, new SnapshotStorage(this.documentStorageService, tree), version);\n\t}\n\n\tpublic onOpButtonClick(steps: number): void {\n\t\tif (this.stepsDeferred && !Number.isNaN(steps) && steps > 0) {\n\t\t\tthis.stepsDeferred.resolve(steps);\n\t\t}\n\t}\n\n\tpublic onSnapshotFileSelection(file: File): void {\n\t\tif (!/^snapshot.*\\.json/.exec(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.exec(file.name)) {\n\t\t\talert(`Incorrect file name - please use non-extended files: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reader = new FileReader();\n\t\treader.onload = async () => {\n\t\t\tif (this.documentStorageService) {\n\t\t\t\tconst text = reader.result as string;\n\t\t\t\ttry {\n\t\t\t\t\tconst json: IFileSnapshot = JSON.parse(text) as IFileSnapshot;\n\t\t\t\t\t/*\n Const docStorage = this.documentStorageService;\n const storage = {\n read: (blobId: string) => this.read(docStorage, blobId),\n };\n const seq = await DebugReplayController.seqFromTree(\n storage as IDocumentStorageService,\n tree);\n this.startSeqDeferred.resolve(seq);\n */\n\t\t\t\t\t// No ability to load ops, so just say - pick up from infinite op.\n\t\t\t\t\tthis.retryFetchOpsOnEndOfFile = false;\n\t\t\t\t\tthis.lastOpReached = true;\n\t\t\t\t\tthis.resolveStorage(\n\t\t\t\t\t\tNumber.MAX_SAFE_INTEGER,\n\t\t\t\t\t\tnew FileSnapshotReader(json),\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\talert(`Error parsing file: ${error}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treader.readAsText(file, \"utf-8\");\n\t}\n\n\tpublic async onDownloadOpsButtonClick(anonymize: boolean): Promise<string> {\n\t\tif (this.documentService === undefined) {\n\t\t\tthrow new Error(\"DocumentService required\");\n\t\t}\n\n\t\tconst documentDeltaStorageService = await this.documentService.connectToDeltaStorage();\n\t\tlet messages = await this.fetchOpsFromDeltaStorage(documentDeltaStorageService);\n\n\t\tif (anonymize) {\n\t\t\tconst sanitizer = new Sanitizer(messages, false /* fullScrub */, false /* noBail */);\n\t\t\tmessages = sanitizer.sanitize();\n\t\t}\n\n\t\treturn JSON.stringify(messages, undefined, 2);\n\t}\n\n\tprivate async fetchOpsFromDeltaStorage(\n\t\tdocumentDeltaStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst deltaGenerator = generateSequencedMessagesFromDeltaStorage(\n\t\t\tdocumentDeltaStorageService,\n\t\t);\n\t\tlet messages: ISequencedDocumentMessage[] = [];\n\t\tfor await (const message of deltaGenerator) {\n\t\t\tmessages = messages.concat(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\treturn undefined;\n\t}\n\n\t// Returns true if version / file / ops selections is made.\n\tpublic isSelectionMade(): boolean {\n\t\treturn this.storage !== undefined;\n\t}\n\n\tpublic async downloadVersionInfo(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\tprevRequest: Promise<void>,\n\t\tindex: number,\n\t\tversion: IVersion,\n\t): Promise<void> {\n\t\tif (this.isSelectionMade()) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait prevRequest;\n\n\t\tconst treeV = await documentStorageService.getSnapshotTree(version);\n\t\tconst seqV = await DebugReplayController.seqFromTree(documentStorageService, treeV);\n\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versionCount--;\n\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\tthis.ui.updateVersion(index, version, seqV);\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\tif (this.shouldUseController !== undefined) {\n\t\t\treturn this.shouldUseController;\n\t\t}\n\n\t\tassert(!!documentService, 0x080 /* \"Invalid document service!\" */);\n\t\tassert(!this.documentService, 0x081 /* \"Document service already set!\" */);\n\t\tassert(!this.documentStorageService, 0x082 /* \"Document storage service already set!\" */);\n\t\tthis.documentService = documentService;\n\t\tthis.documentStorageService = await documentService.connectToStorage();\n\n\t\t// User can chose \"file\" at any moment in time!\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versions = await this.documentStorageService.getVersions(\"\", 50);\n\t\t\tif (!this.isSelectionMade()) {\n\t\t\t\tthis.ui.addVersions(this.versions);\n\t\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\t}\n\t\t}\n\n\t\tthis.versionCount = this.versions.length;\n\n\t\t// Download all versions - do 10 downloads in parallel to avoid being throttled\n\t\tconst buckets = 10;\n\t\tconst work: Promise<void>[] = [];\n\t\tfor (let i = 0; i < buckets; i++) {\n\t\t\tlet prevRequest = Promise.resolve();\n\t\t\tfor (let index = i; index < this.versions.length; index += buckets) {\n\t\t\t\t// Non null asserting here because we are iterating though versions\n\t\t\t\tconst version = this.versions[index]!;\n\t\t\t\tprevRequest = this.downloadVersionInfo(\n\t\t\t\t\tthis.documentStorageService,\n\t\t\t\t\tprevRequest,\n\t\t\t\t\tindex,\n\t\t\t\t\tversion,\n\t\t\t\t);\n\t\t\t}\n\t\t\twork.push(prevRequest);\n\t\t}\n\n\t\t// Don't wait for stuff to populate.\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tPromise.all(work).then(() => {\n\t\t\tthis.ui.updateVersionText(0);\n\t\t});\n\n\t\t// This hangs until the user makes a selection or closes the window.\n\t\tthis.shouldUseController =\n\t\t\t(await this.startSeqDeferred.promise) !== DebugReplayController.WindowClosedSeq;\n\n\t\tassert(\n\t\t\tthis.isSelectionMade() === this.shouldUseController,\n\t\t\t0x083 /* \"User selection status does not match replay controller use status!\" */,\n\t\t);\n\t\treturn this.shouldUseController;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.readBlob(blobId);\n\t\t}\n\t\tthrow new Error(\"Reading blob before storage is setup properly\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getVersions(versionId, count);\n\t\t}\n\t\tthrow new Error(\"initStorage() was not called!\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getSnapshotTree(versionRequested?: IVersion): Promise<ISnapshotTree | null> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getSnapshotTree(versionRequested);\n\t\t}\n\t\tthrow new Error(\"Reading snapshot tree before storage is setup properly\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn this.startSeqDeferred.promise;\n\t}\n\n\t/**\n\t * Return true if we are done processing ops\n\t */\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (lastTimeStamp === undefined) {\n\t\t\tthis.lastOpReached = true;\n\t\t\tif (currentOp === Number.MAX_SAFE_INTEGER) {\n\t\t\t\tthis.ui.updateLastOpText(-1, false);\n\t\t\t} else {\n\t\t\t\tthis.ui.updateLastOpText(currentOp, false);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.ui.updateLastOpText(currentOp, true);\n\t\t}\n\t\treturn this.lastOpReached && !this.retryFetchOpsOnEndOfFile;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet _fetchedOps = fetchedOps;\n\t\t// eslint-disable-next-line no-constant-condition\n\t\twhile (true) {\n\t\t\tif (_fetchedOps.length === 0) {\n\t\t\t\tthis.ui.updateNextOpText([]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.stepsToPlay === 0) {\n\t\t\t\tthis.ui.disableNextOpButton(false);\n\t\t\t\tthis.stepsDeferred = new Deferred<number>();\n\n\t\t\t\tthis.ui.updateNextOpText(_fetchedOps);\n\n\t\t\t\tthis.stepsToPlay = await this.stepsDeferred.promise;\n\n\t\t\t\tthis.stepsDeferred = undefined;\n\t\t\t\tthis.ui.disableNextOpButton(true);\n\t\t\t}\n\n\t\t\tlet playOps: ISequencedDocumentMessage[];\n\t\t\tif (this.stepsToPlay >= _fetchedOps.length) {\n\t\t\t\tplayOps = _fetchedOps;\n\t\t\t\tthis.stepsToPlay -= _fetchedOps.length;\n\t\t\t\t_fetchedOps = [];\n\t\t\t} else {\n\t\t\t\tplayOps = _fetchedOps.splice(0, this.stepsToPlay);\n\t\t\t\tthis.stepsToPlay = 0;\n\t\t\t}\n\t\t\temitter(playOps);\n\t\t}\n\t}\n\n\tprotected resolveStorage(\n\t\tseq: number,\n\t\tstorage: ReadDocumentStorageServiceBase,\n\t\tversion: IVersion | string,\n\t): void {\n\t\tassert(\n\t\t\t!this.isSelectionMade(),\n\t\t\t0x084 /* \"On storage resolve, user selection already made!\" */,\n\t\t);\n\t\tassert(!!storage, 0x085 /* \"On storage resolve, missing storage!\" */);\n\t\tthis.storage = storage;\n\t\tassert(\n\t\t\tthis.isSelectionMade(),\n\t\t\t0x086 /* \"After storage resolve, user selection status still false!\" */,\n\t\t);\n\n\t\tthis.ui.versionSelected(seq, version);\n\t\tthis.startSeqDeferred.resolve(seq);\n\t}\n}\n\nasync function* generateSequencedMessagesFromDeltaStorage(\n\tdeltaStorage: IDocumentDeltaStorageService,\n): AsyncGenerator<ISequencedDocumentMessage[], void, undefined> {\n\tconst stream = deltaStorage.fetchMessages(1, undefined);\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\treturn;\n\t\t}\n\t\tyield result.value;\n\t}\n}\n"]}
1
+ {"version":3,"file":"fluidDebuggerController.js","sourceRoot":"","sources":["../src/fluidDebuggerController.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 { assert, Deferred } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentAttributes,\n\tISnapshotTree,\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport {\n\tFileSnapshotReader,\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi.js\";\nimport { Sanitizer } from \"./sanitizer.js\";\n\n/**\n * @internal\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n * @internal\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (typeof localStorage === \"object\" && localStorage?.FluidDebugger) {\n\t\t\tconst controller = new DebugReplayController();\n\t\t\tconst ui = createUi(controller);\n\t\t\tif (ui) {\n\t\t\t\treturn controller;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected static readonly WindowClosedSeq = -1; // Seq# to indicate that user closed window\n\n\tprotected static async seqFromTree(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\ttree: ISnapshotTree | null,\n\t): Promise<number> {\n\t\tif (!tree) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// TODO Why are we non null asserting here\n\t\tconst attributesHash = tree.trees[\".protocol\"]!.blobs.attributes!;\n\t\tconst attrib = await readAndParse<IDocumentAttributes>(\n\t\t\tdocumentStorageService,\n\t\t\tattributesHash,\n\t\t);\n\t\treturn attrib.sequenceNumber;\n\t}\n\n\tprotected ui: IDebuggerUI = null as any as IDebuggerUI; // Not to check on every line that it's not null\n\tprotected stepsDeferred?: Deferred<number>;\n\tprotected startSeqDeferred = new Deferred<number>();\n\n\t// True will cause us ping server indefinitely waiting for new ops\n\tprotected retryFetchOpsOnEndOfFile = false;\n\n\tprotected documentService?: IDocumentService;\n\tprotected documentStorageService?: IDocumentStorageService;\n\tprotected versions: IVersion[] = [];\n\tprotected stepsToPlay: number = 0;\n\tprotected lastOpReached = false;\n\tprotected versionCount = 0;\n\n\tprotected storage?: ReadDocumentStorageServiceBase;\n\n\t// Member to prevent repeated initialization in initStorage(...), which also\n\t// returns if this controller should be used or function as a passthrough\n\tprivate shouldUseController: boolean | undefined;\n\n\tpublic connectToUi(ui: IDebuggerUI): void {\n\t\tthis.ui = ui;\n\t}\n\n\tpublic onClose(): void {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async onVersionSelection(version: IVersion): Promise<void> {\n\t\tif (!this.documentStorageService) {\n\t\t\tthrow new Error(\"onVersionSelection: no storage\");\n\t\t}\n\n\t\tconst tree = await this.documentStorageService.getSnapshotTree(version);\n\t\tconst seq = await DebugReplayController.seqFromTree(this.documentStorageService, tree);\n\t\tthis.resolveStorage(seq, new SnapshotStorage(this.documentStorageService, tree), version);\n\t}\n\n\tpublic onOpButtonClick(steps: number): void {\n\t\tif (this.stepsDeferred && !Number.isNaN(steps) && steps > 0) {\n\t\t\tthis.stepsDeferred.resolve(steps);\n\t\t}\n\t}\n\n\tpublic onSnapshotFileSelection(file: File): void {\n\t\tif (!/^snapshot.*\\.json/.exec(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.exec(file.name)) {\n\t\t\talert(`Incorrect file name - please use non-extended files: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reader = new FileReader();\n\t\treader.onload = async () => {\n\t\t\tif (this.documentStorageService) {\n\t\t\t\tconst text = reader.result as string;\n\t\t\t\ttry {\n\t\t\t\t\tconst json: IFileSnapshot = JSON.parse(text) as IFileSnapshot;\n\t\t\t\t\t/*\n Const docStorage = this.documentStorageService;\n const storage = {\n read: (blobId: string) => this.read(docStorage, blobId),\n };\n const seq = await DebugReplayController.seqFromTree(\n storage as IDocumentStorageService,\n tree);\n this.startSeqDeferred.resolve(seq);\n */\n\t\t\t\t\t// No ability to load ops, so just say - pick up from infinite op.\n\t\t\t\t\tthis.retryFetchOpsOnEndOfFile = false;\n\t\t\t\t\tthis.lastOpReached = true;\n\t\t\t\t\tthis.resolveStorage(\n\t\t\t\t\t\tNumber.MAX_SAFE_INTEGER,\n\t\t\t\t\t\tnew FileSnapshotReader(json),\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\talert(`Error parsing file: ${error}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treader.readAsText(file, \"utf-8\");\n\t}\n\n\tpublic async onDownloadOpsButtonClick(anonymize: boolean): Promise<string> {\n\t\tif (this.documentService === undefined) {\n\t\t\tthrow new Error(\"DocumentService required\");\n\t\t}\n\n\t\tconst documentDeltaStorageService = await this.documentService.connectToDeltaStorage();\n\t\tlet messages = await this.fetchOpsFromDeltaStorage(documentDeltaStorageService);\n\n\t\tif (anonymize) {\n\t\t\tconst sanitizer = new Sanitizer(messages, false /* fullScrub */, false /* noBail */);\n\t\t\tmessages = sanitizer.sanitize();\n\t\t}\n\n\t\treturn JSON.stringify(messages, undefined, 2);\n\t}\n\n\tprivate async fetchOpsFromDeltaStorage(\n\t\tdocumentDeltaStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst deltaGenerator = generateSequencedMessagesFromDeltaStorage(\n\t\t\tdocumentDeltaStorageService,\n\t\t);\n\t\tlet messages: ISequencedDocumentMessage[] = [];\n\t\tfor await (const message of deltaGenerator) {\n\t\t\tmessages = messages.concat(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\treturn undefined;\n\t}\n\n\t// Returns true if version / file / ops selections is made.\n\tpublic isSelectionMade(): boolean {\n\t\treturn this.storage !== undefined;\n\t}\n\n\tpublic async downloadVersionInfo(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\tprevRequest: Promise<void>,\n\t\tindex: number,\n\t\tversion: IVersion,\n\t): Promise<void> {\n\t\tif (this.isSelectionMade()) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait prevRequest;\n\n\t\tconst treeV = await documentStorageService.getSnapshotTree(version);\n\t\tconst seqV = await DebugReplayController.seqFromTree(documentStorageService, treeV);\n\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versionCount--;\n\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\tthis.ui.updateVersion(index, version, seqV);\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\tif (this.shouldUseController !== undefined) {\n\t\t\treturn this.shouldUseController;\n\t\t}\n\n\t\tassert(!!documentService, 0x080 /* \"Invalid document service!\" */);\n\t\tassert(!this.documentService, 0x081 /* \"Document service already set!\" */);\n\t\tassert(!this.documentStorageService, 0x082 /* \"Document storage service already set!\" */);\n\t\tthis.documentService = documentService;\n\t\tthis.documentStorageService = await documentService.connectToStorage();\n\n\t\t// User can chose \"file\" at any moment in time!\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versions = await this.documentStorageService.getVersions(\"\", 50);\n\t\t\tif (!this.isSelectionMade()) {\n\t\t\t\tthis.ui.addVersions(this.versions);\n\t\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\t}\n\t\t}\n\n\t\tthis.versionCount = this.versions.length;\n\n\t\t// Download all versions - do 10 downloads in parallel to avoid being throttled\n\t\tconst buckets = 10;\n\t\tconst work: Promise<void>[] = [];\n\t\tfor (let i = 0; i < buckets; i++) {\n\t\t\tlet prevRequest = Promise.resolve();\n\t\t\tfor (let index = i; index < this.versions.length; index += buckets) {\n\t\t\t\t// Non null asserting here because we are iterating though versions\n\t\t\t\tconst version = this.versions[index]!;\n\t\t\t\tprevRequest = this.downloadVersionInfo(\n\t\t\t\t\tthis.documentStorageService,\n\t\t\t\t\tprevRequest,\n\t\t\t\t\tindex,\n\t\t\t\t\tversion,\n\t\t\t\t);\n\t\t\t}\n\t\t\twork.push(prevRequest);\n\t\t}\n\n\t\t// Don't wait for stuff to populate.\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tPromise.all(work).then(() => {\n\t\t\tthis.ui.updateVersionText(0);\n\t\t});\n\n\t\t// This hangs until the user makes a selection or closes the window.\n\t\tthis.shouldUseController =\n\t\t\t(await this.startSeqDeferred.promise) !== DebugReplayController.WindowClosedSeq;\n\n\t\tassert(\n\t\t\tthis.isSelectionMade() === this.shouldUseController,\n\t\t\t0x083 /* \"User selection status does not match replay controller use status!\" */,\n\t\t);\n\t\treturn this.shouldUseController;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.readBlob(blobId);\n\t\t}\n\t\tthrow new Error(\"Reading blob before storage is setup properly\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getVersions(versionId, count);\n\t\t}\n\t\tthrow new Error(\"initStorage() was not called!\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getSnapshotTree(versionRequested?: IVersion): Promise<ISnapshotTree | null> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getSnapshotTree(versionRequested);\n\t\t}\n\t\tthrow new Error(\"Reading snapshot tree before storage is setup properly\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn this.startSeqDeferred.promise;\n\t}\n\n\t/**\n\t * Return true if we are done processing ops\n\t */\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (lastTimeStamp === undefined) {\n\t\t\tthis.lastOpReached = true;\n\t\t\tif (currentOp === Number.MAX_SAFE_INTEGER) {\n\t\t\t\tthis.ui.updateLastOpText(-1, false);\n\t\t\t} else {\n\t\t\t\tthis.ui.updateLastOpText(currentOp, false);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.ui.updateLastOpText(currentOp, true);\n\t\t}\n\t\treturn this.lastOpReached && !this.retryFetchOpsOnEndOfFile;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet _fetchedOps = fetchedOps;\n\t\twhile (true) {\n\t\t\tif (_fetchedOps.length === 0) {\n\t\t\t\tthis.ui.updateNextOpText([]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.stepsToPlay === 0) {\n\t\t\t\tthis.ui.disableNextOpButton(false);\n\t\t\t\tthis.stepsDeferred = new Deferred<number>();\n\n\t\t\t\tthis.ui.updateNextOpText(_fetchedOps);\n\n\t\t\t\tthis.stepsToPlay = await this.stepsDeferred.promise;\n\n\t\t\t\tthis.stepsDeferred = undefined;\n\t\t\t\tthis.ui.disableNextOpButton(true);\n\t\t\t}\n\n\t\t\tlet playOps: ISequencedDocumentMessage[];\n\t\t\tif (this.stepsToPlay >= _fetchedOps.length) {\n\t\t\t\tplayOps = _fetchedOps;\n\t\t\t\tthis.stepsToPlay -= _fetchedOps.length;\n\t\t\t\t_fetchedOps = [];\n\t\t\t} else {\n\t\t\t\tplayOps = _fetchedOps.splice(0, this.stepsToPlay);\n\t\t\t\tthis.stepsToPlay = 0;\n\t\t\t}\n\t\t\temitter(playOps);\n\t\t}\n\t}\n\n\tprotected resolveStorage(\n\t\tseq: number,\n\t\tstorage: ReadDocumentStorageServiceBase,\n\t\tversion: IVersion | string,\n\t): void {\n\t\tassert(\n\t\t\t!this.isSelectionMade(),\n\t\t\t0x084 /* \"On storage resolve, user selection already made!\" */,\n\t\t);\n\t\tassert(!!storage, 0x085 /* \"On storage resolve, missing storage!\" */);\n\t\tthis.storage = storage;\n\t\tassert(\n\t\t\tthis.isSelectionMade(),\n\t\t\t0x086 /* \"After storage resolve, user selection status still false!\" */,\n\t\t);\n\n\t\tthis.ui.versionSelected(seq, version);\n\t\tthis.startSeqDeferred.resolve(seq);\n\t}\n}\n\nasync function* generateSequencedMessagesFromDeltaStorage(\n\tdeltaStorage: IDocumentDeltaStorageService,\n): AsyncGenerator<ISequencedDocumentMessage[], void, undefined> {\n\tconst stream = deltaStorage.fetchMessages(1, undefined);\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\treturn;\n\t\t}\n\t\tyield result.value;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../src/sanitizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkBH,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,KAAK,SAAS,MAAM,YAAY,CAAC;AAexC,aAAK,QAAQ;IACZ,OAAO,IAAA;IACP,KAAK,IAAA;IACL,IAAI,IAAA;IACJ,WAAW,IAAA;IACX,MAAM,IAAA;CACN;AAWD;;;;;GAKG;AACH,cAAM,kBAAkB;IAqBtB,QAAQ,CAAC,gBAAgB,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO;IAChE,QAAQ,CAAC,KAAK,EAAE,OAAO;IArBxB;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAoB;IACpC;;;OAGG;IACH,OAAO,CAAC,qBAAqB,CAAoB;IACjD,OAAO,CAAC,WAAW,CAAS;IAC5B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB,CAAK;gBAGrB,gBAAgB,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO,EACvD,KAAK,EAAE,OAAO;IAGxB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAMxB,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAmB9B,cAAc,IAAI,OAAO;IAQzB;;OAEG;IACH,uBAAuB,IAAI,GAAG;IAkB9B;;;;;OAKG;IACH,sBAAsB,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI;IA8C3C,KAAK,IAAI,IAAI;IAWb,mBAAmB,IAAI,OAAO;CAG9B;AAED,qBAAa,SAAS;IAwCpB,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,EAAE;IAC9C,QAAQ,CAAC,SAAS,EAAE,OAAO;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO;IA1CxB,QAAQ,CAAC,SAAS,sBAA6B;IAI/C,QAAQ,CAAC,mBAAmB,cAAqB;IAGjD,QAAQ,CAAC,qBAAqB,cAAqB;IAGnD,QAAQ,CAAC,cAAc,sBAA6B;IAEpD;;;;;OAKG;IACH,mBAAmB,WAAY,GAAG,UAAU,GAAG,KAAG,OAAO,CAgBvD;IAEF,QAAQ,CAAC,cAAc,EAAE,kBAAkB,CAAC;gBAGlC,QAAQ,EAAE,yBAAyB,EAAE,EACrC,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE,OAAO,EACf,KAAK,GAAE,OAAe;IAWhC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAMxB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAItC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAQlC,QAAQ,CAAC,cAAc,SAAU;IAEjC,QAAQ,CAAC,mBAAmB,UAAW,MAAM,KAAG,MAAM,CAQpD;IAEF;;;OAGG;IACH,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,QAA2B,GAAG,MAAM,GAAG,SAAS;IAmBlF,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE;IAcjC;;;;;OAKG;IACH,aAAa,CAEZ,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,YAAY,GAAE,GAAG,CAAC,MAAM,CAA4B,GAElD,MAAM,GAAG,IAAI;IAyBhB;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,GAAE,GAAG,CAAC,MAAM,CAA4B,GAAG,GAAG;IAkBjF,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAsB3B,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IA8B9B,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI;IAoBtC;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAiBrC;;;;;;;;;OASG;IACH,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAgB7B,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAO9B;;;;;;OAMG;IACH,mBAAmB,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI;IAmFxC,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IA2DzB;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAahC,QAAQ,IAAI,yBAAyB,EAAE;CAoDvC"}
1
+ {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../src/sanitizer.ts"],"names":[],"mappings":"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"}
package/dist/sanitizer.js CHANGED
@@ -336,7 +336,6 @@ class Sanitizer {
336
336
  return this.replaceText(input);
337
337
  }
338
338
  else if (Array.isArray(input)) {
339
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
340
339
  return this.replaceArray(input);
341
340
  }
342
341
  else if (typeof input === "object") {
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../src/sanitizer.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\n/**\n * This tool cleans up a message.json file downloaded through fluid-fetch to remove\n * user content and user identifying information. Enough information can be retained\n * to allow loading through Fluid Preview, or everything can be scrubbed so that only\n * replay-tool can read the result. Anonymous identifying information such as client\n * IDs are always retained. Object keys are NOT scrubbed, including those that are\n * nested within values (only leaf values are scrubbed).\n *\n * Note: While user content/information is scrubbed, it should not be assumed to be\n * fully anonymized because certain meta-information (such as word lengths and\n * consistent replacement) are preserved.\n *\n * Messages must match known structures when scrubbing for Fluid Preview.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport * as Validator from \"jsonschema\";\n\nimport {\n\tattachContentsSchema,\n\tchunkedOpContentsSchema,\n\tjoinContentsSchema,\n\tjoinDataSchema,\n\topContentsMapSchema,\n\topContentsMergeTreeDeltaOpSchema,\n\topContentsMergeTreeGroupOpSchema,\n\topContentsRegisterCollectionSchema,\n\topContentsSchema,\n\tproposeContentsSchema,\n} from \"./messageSchema.js\";\n\nenum TextType {\n\tGeneric,\n\tEmail,\n\tName,\n\tFluidObject,\n\tMapKey,\n}\n\n// Workaround to jsonschema package not supporting \"false\" as a schema\n// that matches nothing\nconst falseResult = {\n\tvalid: false,\n\ttoString: () => {\n\t\treturn \"Unmatched format\";\n\t},\n};\n\n/**\n * Class that takes chunkedOp messages and can provide their concatenated\n * contents along with re-write sanitized content in-place back into the\n * messages. Assumes sanitized messages are always less than or equal in\n * size to the original message.\n */\nclass ChunkedOpProcessor {\n\t/**\n\t * Message references so we can replace their contents in-place. These can\n\t * be top-level chunkedOp messages, or top-level op messages with a chunkedOp\n\t * within the contents\n\t */\n\tprivate messages = new Array<any>();\n\t/**\n\t * The messages' parsed contents for processing. Should parallel the\n\t * messages member\n\t */\n\tprivate parsedMessageContents = new Array<any>();\n\tprivate writtenBack = false;\n\t/**\n\t * keep track of the total starting length to make sure we don't somehow end\n\t * up with more content than we started with (meaning we may not be able to\n\t * write it back)\n\t */\n\tprivate concatenatedLength = 0;\n\n\tconstructor(\n\t\treadonly validateSchemaFn: (object: any, schema: any) => boolean,\n\t\treadonly debug: boolean,\n\t) {}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\taddMessage(message: any): void {\n\t\tthis.messages.push(message);\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(message.contents);\n\t\t\tif (message.type === \"op\") {\n\t\t\t\t// nested within a regular op\n\t\t\t\t// need to go deeper to get the desired contents\n\t\t\t\tparsed = parsed.contents;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthis.debugMsg(message.contents);\n\t\t}\n\t\tthis.validateSchemaFn(parsed, chunkedOpContentsSchema);\n\t\tthis.parsedMessageContents.push(parsed);\n\t}\n\n\thasAllMessages(): boolean {\n\t\tconst lastMsgContents = this.parsedMessageContents[this.parsedMessageContents.length - 1];\n\t\treturn (\n\t\t\tlastMsgContents.chunkId !== undefined &&\n\t\t\tlastMsgContents.chunkId === lastMsgContents.totalChunks\n\t\t);\n\t}\n\n\t/**\n\t * Gets the concatenated contents of all the messages parsed as JSON.\n\t */\n\tgetConcatenatedContents(): any {\n\t\tconst contentsString = this.parsedMessageContents.reduce(\n\t\t\t(previousValue: string, currentValue: any) => {\n\t\t\t\treturn previousValue + (currentValue.contents as string);\n\t\t\t},\n\t\t\t\"\",\n\t\t);\n\n\t\tthis.concatenatedLength = contentsString.length;\n\t\ttry {\n\t\t\treturn JSON.parse(contentsString);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(contentsString);\n\t\t\tthis.debugMsg(e);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Write back sanitized contents into the messages. The contents are\n\t * stringified, split up, and written in place to the messages that\n\t * were added earlier. The number of messages is preserved.\n\t * @param contents - Sanitized contents to write back\n\t */\n\twriteSanitizedContents(contents: any): void {\n\t\t// Write back a chunk size equal to the original\n\t\tconst chunkSize = this.parsedMessageContents[0].contents.length;\n\n\t\tlet stringified: string;\n\t\ttry {\n\t\t\tstringified = JSON.stringify(contents);\n\t\t\tassert(\n\t\t\t\tstringified.length <= this.concatenatedLength,\n\t\t\t\t0x089 /* \"Stringified length of chunk contents > total starting length\" */,\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthrow e;\n\t\t}\n\n\t\tfor (let i = 0; i < this.messages.length; i++) {\n\t\t\tconst substring = stringified.substring(i * chunkSize, (i + 1) * chunkSize);\n\n\t\t\tconst parsedContents = this.parsedMessageContents[i];\n\t\t\tparsedContents.contents = substring;\n\t\t\tconst message = this.messages[i];\n\n\t\t\tlet stringifiedParsedContents;\n\t\t\ttry {\n\t\t\t\t// for nested chunkedOps, we need to recreate the extra nesting layer\n\t\t\t\t// we removed earlier when adding the message\n\t\t\t\tif (message.type === \"op\") {\n\t\t\t\t\tconst nestingLayer = {\n\t\t\t\t\t\ttype: \"chunkedOp\",\n\t\t\t\t\t\tcontents: parsedContents,\n\t\t\t\t\t};\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(nestingLayer);\n\t\t\t\t} else {\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(parsedContents);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t}\n\n\t\t\tmessage.contents = stringifiedParsedContents;\n\t\t}\n\n\t\tthis.writtenBack = true;\n\t}\n\n\treset(): void {\n\t\tassert(\n\t\t\tthis.writtenBack,\n\t\t\t0x08a /* \"resetting ChunkedOpProcessor that never wrote back its contents\" */,\n\t\t);\n\t\tthis.messages = new Array<any>();\n\t\tthis.parsedMessageContents = new Array<any>();\n\t\tthis.writtenBack = false;\n\t\tthis.concatenatedLength = 0;\n\t}\n\n\tisPendingProcessing(): boolean {\n\t\treturn this.messages.length !== 0;\n\t}\n}\n\nexport class Sanitizer {\n\treadonly validator = new Validator.Validator();\n\t// Represents the keys used to store Fluid object identifiers, snapshot info,\n\t// and other string fields that should not be replaced in contents blobs to\n\t// ensure the messages are still usable\n\treadonly defaultExcludedKeys = new Set<string>();\n\t// Represents the keys used by merge-tree ops their \"seg\" property, where other\n\t// keys represent user information\n\treadonly mergeTreeExcludedKeys = new Set<string>();\n\t// Map of user information to what it was replaced with. Used to ensure the same\n\t// data have the same replacements\n\treadonly replacementMap = new Map<string, string>();\n\n\t/**\n\t * Validate that the provided message matches the provided schema.\n\t * For a full scrub, warn and continue (scrubber should fully sanitize unexpected\n\t * fields for ops), otherwise throw an error because we cannot be sure user\n\t * information is being sufficiently sanitized.\n\t */\n\tobjectMatchesSchema = (object: any, schema: any): boolean => {\n\t\tconst result = schema === false ? falseResult : this.validator.validate(object, schema);\n\t\tif (!result.valid) {\n\t\t\tconst errorMsg = `Bad msg fmt:\\n${result.toString()}\\n${JSON.stringify(\n\t\t\t\tobject,\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`;\n\n\t\t\tif (this.fullScrub || this.noBail) {\n\t\t\t\tthis.debugMsg(errorMsg);\n\t\t\t} else {\n\t\t\t\tthrow new Error(errorMsg);\n\t\t\t}\n\t\t}\n\t\treturn result.valid;\n\t};\n\n\treadonly chunkProcessor: ChunkedOpProcessor;\n\n\tconstructor(\n\t\treadonly messages: ISequencedDocumentMessage[],\n\t\treadonly fullScrub: boolean,\n\t\treadonly noBail: boolean,\n\t\treadonly debug: boolean = false,\n\t) {\n\t\tthis.defaultExcludedKeys.add(\"type\");\n\t\tthis.defaultExcludedKeys.add(\"id\");\n\t\tthis.defaultExcludedKeys.add(\"pkg\");\n\t\tthis.defaultExcludedKeys.add(\"snapshotFormatVersion\");\n\t\tthis.defaultExcludedKeys.add(\"packageVersion\");\n\t\tthis.mergeTreeExcludedKeys.add(\"nodeType\");\n\t\tthis.chunkProcessor = new ChunkedOpProcessor(this.objectMatchesSchema, debug);\n\t}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\tisFluidObjectKey(key: string): boolean {\n\t\treturn key === \"type\" || key === \"id\";\n\t}\n\n\tgetRandomText(len: number): string {\n\t\tlet str = \"\";\n\t\twhile (str.length < len) {\n\t\t\tstr = str + Math.random().toString(36).substring(2);\n\t\t}\n\t\treturn str.substr(0, len);\n\t}\n\n\treadonly wordTokenRegex = /\\S+/g;\n\n\treadonly replaceRandomTextFn = (match: string): string => {\n\t\tif (this.replacementMap.has(match)) {\n\t\t\treturn this.replacementMap.get(match)!;\n\t\t}\n\n\t\tconst replacement = this.getRandomText(match.length);\n\t\tthis.replacementMap.set(match, replacement);\n\t\treturn replacement;\n\t};\n\n\t/**\n\t * Replace text with garbage. FluidObject types are not replaced when not under\n\t * full scrub mode. All other text is replaced consistently.\n\t */\n\treplaceText(input?: string, type: TextType = TextType.Generic): string | undefined {\n\t\tif (input === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (type === TextType.FluidObject) {\n\t\t\tif (this.replacementMap.has(input)) {\n\t\t\t\treturn this.replacementMap.get(input)!;\n\t\t\t}\n\n\t\t\tconst replacement = this.fullScrub ? this.getRandomText(input.length) : input;\n\n\t\t\tthis.replacementMap.set(input, replacement);\n\t\t\treturn replacement;\n\t\t}\n\n\t\treturn input.replace(this.wordTokenRegex, this.replaceRandomTextFn);\n\t}\n\n\treplaceArray(input: any[]): any[] {\n\t\tfor (let i = 0; i < input.length; i++) {\n\t\t\tconst value = input[i];\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tinput[i] = this.replaceText(value);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tinput[i] = this.replaceArray(value);\n\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\tinput[i] = this.replaceObject(value);\n\t\t\t}\n\t\t}\n\t\treturn input;\n\t}\n\n\t/**\n\t * (sort of) recurses down the values of a JSON object to sanitize all its strings\n\t * (only checks strings, arrays, and objects)\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceObject(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tinput: object | null,\n\t\texcludedKeys: Set<string> = this.defaultExcludedKeys,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): object | null {\n\t\t// File might contain actual nulls\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tconst keys = Object.keys(input);\n\t\tkeys.forEach((key) => {\n\t\t\tif (this.fullScrub || !excludedKeys.has(key)) {\n\t\t\t\tconst value = input[key];\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\tinput[key] = this.replaceText(\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tthis.isFluidObjectKey(key) ? TextType.FluidObject : TextType.Generic,\n\t\t\t\t\t);\n\t\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\t\tinput[key] = this.replaceArray(value);\n\t\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\t\tinput[key] = this.replaceObject(value, excludedKeys);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn input;\n\t}\n\n\t/**\n\t * Replacement on an unknown type or a parsed root level object\n\t * without a key\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceAny(input: any, excludedKeys: Set<string> = this.defaultExcludedKeys): any {\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tif (typeof input === \"string\") {\n\t\t\treturn this.replaceText(input);\n\t\t} else if (Array.isArray(input)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn this.replaceArray(input);\n\t\t} else if (typeof input === \"object\") {\n\t\t\treturn this.replaceObject(input, excludedKeys);\n\t\t}\n\n\t\t// Don't run replacement on any other types\n\t\treturn input;\n\t}\n\n\tfixJoin(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, joinContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t}\n\n\t\ttry {\n\t\t\tlet data = JSON.parse(message.data);\n\t\t\tif (!this.objectMatchesSchema(data, joinDataSchema)) {\n\t\t\t\tdata = this.replaceAny(data);\n\t\t\t} else {\n\t\t\t\tconst user = data.detail.user;\n\t\t\t\tuser.id = this.replaceText(user.id, TextType.Email);\n\t\t\t\tuser.email = this.replaceText(user.email, TextType.Email);\n\t\t\t\tuser.name = this.replaceText(user.name, TextType.Name);\n\t\t\t}\n\n\t\t\tmessage.data = JSON.stringify(data);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t}\n\t}\n\n\tfixPropose(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, proposeContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t} else {\n\t\t\tif (typeof message.contents === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\t\tconst pkg = data.value?.package;\n\t\t\t\t\t\tif (pkg?.name) {\n\t\t\t\t\t\t\tpkg.name = this.replaceText(pkg.name, TextType.FluidObject);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Array.isArray(pkg?.fluid?.browser?.umd?.files)) {\n\t\t\t\t\t\t\tpkg.fluid.browser.umd.files = this.replaceArray(pkg.fluid.browser.umd.files);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tmessage.contents.value = this.replaceText(\n\t\t\t\t\t\tmessage.contents.value,\n\t\t\t\t\t\tTextType.FluidObject,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfixAttachEntries(entries: any[]): void {\n\t\tentries.forEach((element) => {\n\t\t\t// Tree type\n\t\t\tif (element.value.entries) {\n\t\t\t\tthis.fixAttachEntries(element.value.entries);\n\t\t\t} else {\n\t\t\t\t// Blob (leaf) type\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof element.value.contents === \"string\") {\n\t\t\t\t\t\tlet data = JSON.parse(element.value.contents);\n\t\t\t\t\t\tdata = this.replaceObject(data);\n\t\t\t\t\t\telement.value.contents = JSON.stringify(data);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Fix the content of an attach in place\n\t * @param contents - contents object to fix\n\t */\n\tfixAttachContents(contents: any): any {\n\t\tassert(\n\t\t\ttypeof contents === \"object\",\n\t\t\t0x08b /* \"Unexpected type on contents for fix of an attach!\" */,\n\t\t);\n\t\tif (!this.objectMatchesSchema(contents, attachContentsSchema)) {\n\t\t\tthis.replaceObject(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.id = this.replaceText(contents.id, TextType.FluidObject);\n\t\t\t\tcontents.type = this.replaceText(contents.type, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tthis.fixAttachEntries(contents.snapshot.entries);\n\t\t}\n\t}\n\n\t/**\n\t * Fix an attach message at the root level or a ContainerMessageType attach. Attach\n\t * messages found within an op message should instead have their contents parsed out\n\t * and sent to fixAttachContents.\n\t * @param message - The attach message to fix\n\t * @param withinOp - If the message is from within an op message (as opposed to being\n\t * an attach message at the root level). Root level attach messages have \"snapshot\"\n\t * under a \"contents\" key, whereas attach messages from within an op message have it\n\t * under a \"content\" key\n\t */\n\tfixAttach(message: any): void {\n\t\t// Handle case where contents is stringified json\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\tmessage.contents = JSON.stringify(data);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.fixAttachContents(message.contents);\n\t\t}\n\t}\n\n\tfixDeltaOp(deltaOp: any): void {\n\t\tdeltaOp.seg =\n\t\t\ttypeof deltaOp.seg === \"string\"\n\t\t\t\t? this.replaceText(deltaOp.seg)\n\t\t\t\t: this.replaceObject(deltaOp.seg, this.mergeTreeExcludedKeys);\n\t}\n\n\t/**\n\t * Fix the contents object for an op message. Does not do extra type handling. Does\n\t * not handle special container message types like \"attach\", \"component\", and\n\t * \"chunkedOp\" (these should be handled by the caller)\n\t * @param contents - The contents object for an op message. If it was a string in the\n\t * message, it must have been converted to an object first\n\t */\n\tfixOpContentsObject(contents: any): void {\n\t\t// do replacement\n\t\tif (!this.objectMatchesSchema(contents, opContentsSchema)) {\n\t\t\tthis.replaceAny(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.address = this.replaceText(contents.address, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tconst innerContent = contents.contents.content;\n\t\t\tassert(\n\t\t\t\tinnerContent !== undefined,\n\t\t\t\t0x08c /* \"innerContent for fixing op contents is undefined!\" */,\n\t\t\t);\n\t\t\tif (contents.contents.type === \"attach\") {\n\t\t\t\t// attach op\n\t\t\t\t// handle case where inner content is stringified json\n\t\t\t\tif (typeof contents.contents.content === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst data = JSON.parse(contents.contents.content);\n\t\t\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\t\t\tcontents.contents.content = JSON.stringify(data);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.fixAttachContents(contents.contents.content);\n\t\t\t\t}\n\t\t\t} else if (this.validator.validate(innerContent, opContentsMapSchema).valid) {\n\t\t\t\t// map op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeGroupOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree group op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tinnerContent.contents.ops.forEach((deltaOp) => {\n\t\t\t\t\tthis.fixDeltaOp(deltaOp);\n\t\t\t\t});\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeDeltaOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree delta op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tthis.fixDeltaOp(innerContent.contents);\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsRegisterCollectionSchema).valid\n\t\t\t) {\n\t\t\t\t// register collection op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// message contents don't match any known op format\n\t\t\t\tthis.objectMatchesSchema(contents, false);\n\t\t\t}\n\t\t}\n\t}\n\n\tfixOp(message: any): void {\n\t\t// handle case where contents is stringified json\n\t\tlet msgContents;\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmsgContents = JSON.parse(message.contents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tmsgContents = message.contents;\n\t\t}\n\n\t\t// handle container message types\n\t\tswitch (msgContents.type) {\n\t\t\tcase \"attach\": {\n\t\t\t\t// this one is like a regular attach op, except its contents aren't nested as deep\n\t\t\t\t// run fixAttach directly and return\n\t\t\t\tthis.fixAttach(msgContents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"component\": {\n\t\t\t\t// this one functionally nests its contents one layer deeper\n\t\t\t\t// bring up the contents object and continue as usual\n\t\t\t\tthis.fixOpContentsObject(msgContents.contents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"chunkedOp\": {\n\t\t\t\t// this is a (regular?) op split into multiple parts due to size, e.g. because it\n\t\t\t\t// has an attached image, and where the chunkedOp is within the top-level op's contents\n\t\t\t\t// (as opposed to being at the top-level). The contents of the chunks need to be\n\t\t\t\t// concatenated to form the complete stringified json object\n\t\t\t\t// Early return here to skip re-stringify because no changes are made until the last\n\t\t\t\t// chunk, and the ChunkedOpProcessor will handle everything at that point\n\t\t\t\treturn this.fixChunkedOp(message);\n\t\t\t}\n\t\t\tcase \"blobAttach\": {\n\t\t\t\t// TODO: handle this properly once blob api is used\n\t\t\t\tthis.debugMsg(\"TODO: blobAttach ops are skipped/unhandled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// A regular op\n\t\t\t\tthis.fixOpContentsObject(msgContents);\n\t\t\t}\n\t\t}\n\n\t\t// re-stringify the json if needed\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmessage.contents = JSON.stringify(msgContents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fixes a chunked operation by reassembling and sanitizing the message chunks.\n\t *\n\t * @param message - The top-level chunkedOp message or a top-level op message\n\t * with a chunkedOp inside its contents\n\t */\n\tfixChunkedOp(message: any): void {\n\t\tthis.chunkProcessor.addMessage(message);\n\t\tif (!this.chunkProcessor.hasAllMessages()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = this.chunkProcessor.getConcatenatedContents();\n\t\tthis.fixOpContentsObject(contents);\n\n\t\tthis.chunkProcessor.writeSanitizedContents(contents);\n\t\tthis.chunkProcessor.reset();\n\t}\n\n\tsanitize(): ISequencedDocumentMessage[] {\n\t\tlet seq = 0;\n\n\t\ttry {\n\t\t\tthis.messages.map((message) => {\n\t\t\t\tseq = message.sequenceNumber;\n\t\t\t\t// message types from protocol-definitions' protocol.ts\n\t\t\t\tswitch (message.type) {\n\t\t\t\t\tcase \"join\": {\n\t\t\t\t\t\tthis.fixJoin(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"propose\": {\n\t\t\t\t\t\tthis.fixPropose(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"attach\": {\n\t\t\t\t\t\tthis.fixAttach(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"op\": {\n\t\t\t\t\t\tthis.fixOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"chunkedOp\": {\n\t\t\t\t\t\tthis.fixChunkedOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"noop\":\n\t\t\t\t\tcase \"leave\":\n\t\t\t\t\tcase \"noClient\":\n\t\t\t\t\tcase \"summarize\":\n\t\t\t\t\tcase \"summaryAck\":\n\t\t\t\t\tcase \"summaryNack\":\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.debugMsg(`Unexpected op type ${message.type}`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// make sure we don't miss an incomplete chunked op at the end\n\t\t\tassert(\n\t\t\t\t!this.chunkProcessor.isPendingProcessing(),\n\t\t\t\t0x08d /* \"After sanitize, pending incomplete ops!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(`Error while processing sequenceNumber ${seq}`);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn this.messages;\n\t}\n}\n"]}
1
+ {"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../src/sanitizer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH;;;;;;;;;;;;;GAaG;AAEH,kEAA6D;AAE7D,sDAAwC;AAExC,yDAW4B;AAE5B,IAAK,QAMJ;AAND,WAAK,QAAQ;IACZ,6CAAO,CAAA;IACP,yCAAK,CAAA;IACL,uCAAI,CAAA;IACJ,qDAAW,CAAA;IACX,2CAAM,CAAA;AACP,CAAC,EANI,QAAQ,KAAR,QAAQ,QAMZ;AAED,sEAAsE;AACtE,uBAAuB;AACvB,MAAM,WAAW,GAAG;IACnB,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,GAAG,EAAE;QACd,OAAO,kBAAkB,CAAC;IAC3B,CAAC;CACD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,kBAAkB;IAoBvB,YACU,gBAAuD,EACvD,KAAc;QADd,qBAAgB,GAAhB,gBAAgB,CAAuC;QACvD,UAAK,GAAL,KAAK,CAAS;QArBxB;;;;WAIG;QACK,aAAQ,GAAG,IAAI,KAAK,EAAO,CAAC;QACpC;;;WAGG;QACK,0BAAqB,GAAG,IAAI,KAAK,EAAO,CAAC;QACzC,gBAAW,GAAG,KAAK,CAAC;QAC5B;;;;WAIG;QACK,uBAAkB,GAAG,CAAC,CAAC;IAK5B,CAAC;IAEJ,QAAQ,CAAC,GAAQ;QAChB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IAED,UAAU,CAAC,OAAY;QACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE5B,IAAI,MAAM,CAAC;QACX,IAAI,CAAC;YACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACtC,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC3B,6BAA6B;gBAC7B,gDAAgD;gBAChD,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;YAC1B,CAAC;QACF,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,0CAAuB,CAAC,CAAC;QACvD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,cAAc;QACb,MAAM,eAAe,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC1F,OAAO,CACN,eAAe,CAAC,OAAO,KAAK,SAAS;YACrC,eAAe,CAAC,OAAO,KAAK,eAAe,CAAC,WAAW,CACvD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,uBAAuB;QACtB,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CACvD,CAAC,aAAqB,EAAE,YAAiB,EAAE,EAAE;YAC5C,OAAO,aAAa,GAAI,YAAY,CAAC,QAAmB,CAAC;QAC1D,CAAC,EACD,EAAE,CACF,CAAC;QAEF,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC,MAAM,CAAC;QAChD,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjB,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACH,sBAAsB,CAAC,QAAa;QACnC,gDAAgD;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAEhE,IAAI,WAAmB,CAAC;QACxB,IAAI,CAAC;YACJ,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAA,iBAAM,EACL,WAAW,CAAC,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAC7C,KAAK,CAAC,oEAAoE,CAC1E,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjB,MAAM,CAAC,CAAC;QACT,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,MAAM,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;YAE5E,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACrD,cAAc,CAAC,QAAQ,GAAG,SAAS,CAAC;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAEjC,IAAI,yBAAyB,CAAC;YAC9B,IAAI,CAAC;gBACJ,qEAAqE;gBACrE,6CAA6C;gBAC7C,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC3B,MAAM,YAAY,GAAG;wBACpB,IAAI,EAAE,WAAW;wBACjB,QAAQ,EAAE,cAAc;qBACxB,CAAC;oBACF,yBAAyB,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;gBAC1D,CAAC;qBAAM,CAAC;oBACP,yBAAyB,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;gBAC5D,CAAC;YACF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,OAAO,CAAC,QAAQ,GAAG,yBAAyB,CAAC;QAC9C,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,KAAK;QACJ,IAAA,iBAAM,EACL,IAAI,CAAC,WAAW,EAChB,KAAK,CAAC,uEAAuE,CAC7E,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,KAAK,EAAO,CAAC;QACjC,IAAI,CAAC,qBAAqB,GAAG,IAAI,KAAK,EAAO,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,mBAAmB;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;IACnC,CAAC;CACD;AAED,MAAa,SAAS;IAuCrB,YACU,QAAqC,EACrC,SAAkB,EAClB,MAAe,EACf,QAAiB,KAAK;QAHtB,aAAQ,GAAR,QAAQ,CAA6B;QACrC,cAAS,GAAT,SAAS,CAAS;QAClB,WAAM,GAAN,MAAM,CAAS;QACf,UAAK,GAAL,KAAK,CAAiB;QA1CvB,cAAS,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QAC/C,6EAA6E;QAC7E,2EAA2E;QAC3E,uCAAuC;QAC9B,wBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;QACjD,+EAA+E;QAC/E,kCAAkC;QACzB,0BAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;QACnD,iFAAiF;QACjF,kCAAkC;QACzB,mBAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;QAEpD;;;;;WAKG;QACH,wBAAmB,GAAG,CAAC,MAAW,EAAE,MAAW,EAAW,EAAE;YAC3D,MAAM,MAAM,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACxF,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,QAAQ,GAAG,iBAAiB,MAAM,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,SAAS,CACrE,MAAM,EACN,SAAS,EACT,CAAC,CACD,EAAE,CAAC;gBAEJ,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBACnC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACP,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC3B,CAAC;YACF,CAAC;YACD,OAAO,MAAM,CAAC,KAAK,CAAC;QACrB,CAAC,CAAC;QAqCO,mBAAc,GAAG,MAAM,CAAC;QAExB,wBAAmB,GAAG,CAAC,KAAa,EAAU,EAAE;YACxD,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;YACxC,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACrD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAC5C,OAAO,WAAW,CAAC;QACpB,CAAC,CAAC;QArCD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACtD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC/C,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,cAAc,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;IAC/E,CAAC;IAED,QAAQ,CAAC,GAAQ;QAChB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IAED,gBAAgB,CAAC,GAAW;QAC3B,OAAO,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,IAAI,CAAC;IACvC,CAAC;IAED,aAAa,CAAC,GAAW;QACxB,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,OAAO,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACzB,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3B,CAAC;IAcD;;;OAGG;IACH,WAAW,CAAC,KAAc,EAAE,OAAiB,QAAQ,CAAC,OAAO;QAC5D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,IAAI,IAAI,KAAK,QAAQ,CAAC,WAAW,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;YACxC,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAE9E,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAC5C,OAAO,WAAW,CAAC;QACpB,CAAC;QAED,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACrE,CAAC;IAED,YAAY,CAAC,KAAY;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC/B,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACrC,CAAC;iBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACtC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,aAAa;IACZ,kDAAkD;IAClD,KAAoB,EACpB,eAA4B,IAAI,CAAC,mBAAmB;QAGpD,kCAAkC;QAClC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACpB,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;gBACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC/B,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAC5B,KAAK,EACL,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CACpE,CAAC;gBACH,CAAC;qBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBACvC,CAAC;qBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACtC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;gBACtD,CAAC;YACF,CAAC;QACF,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,KAAU,EAAE,eAA4B,IAAI,CAAC,mBAAmB;QAC1E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACd,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QAChD,CAAC;QAED,2CAA2C;QAC3C,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,CAAC,OAAY;QACnB,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE,qCAAkB,CAAC,EAAE,CAAC;YACrE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,CAAC;YACJ,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,iCAAc,CAAC,EAAE,CAAC;gBACrD,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACP,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC9B,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACpD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAC1D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YACxD,CAAC;YAED,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;IAED,UAAU,CAAC,OAAY;QACtB,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE,wCAAqB,CAAC,EAAE,CAAC;YACxE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACP,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1C,IAAI,CAAC;oBACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;oBAC1C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;wBACpB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;wBAChC,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC;4BACf,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;wBAC7D,CAAC;wBACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;4BACpD,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;wBAC9E,CAAC;oBACF,CAAC;gBACF,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,CACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,EACtB,QAAQ,CAAC,WAAW,CACpB,CAAC;gBACH,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED,gBAAgB,CAAC,OAAc;QAC9B,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,YAAY;YACZ,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC3B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACP,mBAAmB;gBACnB,IAAI,CAAC;oBACJ,IAAI,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;wBAChD,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;wBAC9C,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;wBAChC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAC/C,CAAC;gBACF,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;YACF,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,iBAAiB,CAAC,QAAa;QAC9B,IAAA,iBAAM,EACL,OAAO,QAAQ,KAAK,QAAQ,EAC5B,KAAK,CAAC,yDAAyD,CAC/D,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,uCAAoB,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACP,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAClE,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;YACvE,CAAC;YAED,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;IACF,CAAC;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,OAAY;QACrB,iDAAiD;QACjD,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC1C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAC7B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACjB,OAAO;YACR,CAAC;QACF,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC;IAED,UAAU,CAAC,OAAY;QACtB,OAAO,CAAC,GAAG;YACV,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ;gBAC9B,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC;gBAC/B,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACjE,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,QAAa;QAChC,iBAAiB;QACjB,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,mCAAgB,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACP,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC7E,CAAC;YAED,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC/C,IAAA,iBAAM,EACL,YAAY,KAAK,SAAS,EAC1B,KAAK,CAAC,yDAAyD,CAC/D,CAAC;YACF,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACzC,YAAY;gBACZ,sDAAsD;gBACtD,IAAI,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBACnD,IAAI,CAAC;wBACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;wBACnD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;wBAC7B,QAAQ,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAClD,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;gBACF,CAAC;qBAAM,CAAC;oBACP,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACnD,CAAC;YACF,CAAC;iBAAM,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,sCAAmB,CAAC,CAAC,KAAK,EAAE,CAAC;gBAC7E,SAAS;gBACT,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;oBACpF,YAAY,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAC3C,YAAY,CAAC,QAAQ,CAAC,GAAG,EACzB,QAAQ,CAAC,MAAM,CACf,CAAC;gBACH,CAAC;gBACD,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC/C,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAClD,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CACjC,CAAC;gBACH,CAAC;YACF,CAAC;iBAAM,IACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,mDAAgC,CAAC,CAAC,KAAK,EAC5E,CAAC;gBACF,sBAAsB;gBACtB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;gBACrF,CAAC;gBACD,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBAC7C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC1B,CAAC,CAAC,CAAC;YACJ,CAAC;iBAAM,IACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,mDAAgC,CAAC,CAAC,KAAK,EAC5E,CAAC;gBACF,sBAAsB;gBACtB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;gBACrF,CAAC;gBACD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YACxC,CAAC;iBAAM,IACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,qDAAkC,CAAC,CAAC,KAAK,EAC9E,CAAC;gBACF,yBAAyB;gBACzB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;oBACpF,YAAY,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAC3C,YAAY,CAAC,QAAQ,CAAC,GAAG,EACzB,QAAQ,CAAC,MAAM,CACf,CAAC;gBACH,CAAC;gBACD,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC/C,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAClD,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CACjC,CAAC;gBACH,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,mDAAmD;gBACnD,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC3C,CAAC;QACF,CAAC;IACF,CAAC;IAED,KAAK,CAAC,OAAY;QACjB,iDAAiD;QACjD,IAAI,WAAW,CAAC;QAChB,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACJ,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC5C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACjB,OAAO;YACR,CAAC;QACF,CAAC;aAAM,CAAC;YACP,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;QAChC,CAAC;QAED,iCAAiC;QACjC,QAAQ,WAAW,CAAC,IAAI,EAAE,CAAC;YAC1B,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACf,kFAAkF;gBAClF,oCAAoC;gBACpC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;gBAC5B,MAAM;YACP,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBAClB,4DAA4D;gBAC5D,qDAAqD;gBACrD,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC/C,MAAM;YACP,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBAClB,iFAAiF;gBACjF,uFAAuF;gBACvF,iFAAiF;gBACjF,4DAA4D;gBAC5D,oFAAoF;gBACpF,yEAAyE;gBACzE,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBACnB,mDAAmD;gBACnD,IAAI,CAAC,QAAQ,CAAC,4CAA4C,CAAC,CAAC;gBAC5D,OAAO;YACR,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACT,eAAe;gBACf,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;YACvC,CAAC;QACF,CAAC;QAED,kCAAkC;QAClC,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACJ,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAChD,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACjB,OAAO;YACR,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,OAAY;QACxB,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,EAAE,CAAC;YAC3C,OAAO;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,CAAC;QAC/D,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAEnC,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,QAAQ;QACP,IAAI,GAAG,GAAG,CAAC,CAAC;QAEZ,IAAI,CAAC;YACJ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC7B,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC;gBAC7B,uDAAuD;gBACvD,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;oBACtB,KAAK,MAAM,CAAC,CAAC,CAAC;wBACb,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;wBACtB,MAAM;oBACP,CAAC;oBACD,KAAK,SAAS,CAAC,CAAC,CAAC;wBAChB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;wBACzB,MAAM;oBACP,CAAC;oBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACf,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;wBACxB,MAAM;oBACP,CAAC;oBACD,KAAK,IAAI,CAAC,CAAC,CAAC;wBACX,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBACpB,MAAM;oBACP,CAAC;oBACD,KAAK,WAAW,CAAC,CAAC,CAAC;wBAClB,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;wBAC3B,MAAM;oBACP,CAAC;oBACD,KAAK,MAAM,CAAC;oBACZ,KAAK,OAAO,CAAC;oBACb,KAAK,UAAU,CAAC;oBAChB,KAAK,WAAW,CAAC;oBACjB,KAAK,YAAY,CAAC;oBAClB,KAAK,aAAa;wBACjB,MAAM;oBACP;wBACC,IAAI,CAAC,QAAQ,CAAC,sBAAsB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBACtD,CAAC;YACF,CAAC,CAAC,CAAC;YAEH,8DAA8D;YAC9D,IAAA,iBAAM,EACL,CAAC,IAAI,CAAC,cAAc,CAAC,mBAAmB,EAAE,EAC1C,KAAK,CAAC,+CAA+C,CACrD,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAC;YAC9D,MAAM,KAAK,CAAC;QACb,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;CACD;AA9gBD,8BA8gBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * This tool cleans up a message.json file downloaded through fluid-fetch to remove\n * user content and user identifying information. Enough information can be retained\n * to allow loading through Fluid Preview, or everything can be scrubbed so that only\n * replay-tool can read the result. Anonymous identifying information such as client\n * IDs are always retained. Object keys are NOT scrubbed, including those that are\n * nested within values (only leaf values are scrubbed).\n *\n * Note: While user content/information is scrubbed, it should not be assumed to be\n * fully anonymized because certain meta-information (such as word lengths and\n * consistent replacement) are preserved.\n *\n * Messages must match known structures when scrubbing for Fluid Preview.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport * as Validator from \"jsonschema\";\n\nimport {\n\tattachContentsSchema,\n\tchunkedOpContentsSchema,\n\tjoinContentsSchema,\n\tjoinDataSchema,\n\topContentsMapSchema,\n\topContentsMergeTreeDeltaOpSchema,\n\topContentsMergeTreeGroupOpSchema,\n\topContentsRegisterCollectionSchema,\n\topContentsSchema,\n\tproposeContentsSchema,\n} from \"./messageSchema.js\";\n\nenum TextType {\n\tGeneric,\n\tEmail,\n\tName,\n\tFluidObject,\n\tMapKey,\n}\n\n// Workaround to jsonschema package not supporting \"false\" as a schema\n// that matches nothing\nconst falseResult = {\n\tvalid: false,\n\ttoString: () => {\n\t\treturn \"Unmatched format\";\n\t},\n};\n\n/**\n * Class that takes chunkedOp messages and can provide their concatenated\n * contents along with re-write sanitized content in-place back into the\n * messages. Assumes sanitized messages are always less than or equal in\n * size to the original message.\n */\nclass ChunkedOpProcessor {\n\t/**\n\t * Message references so we can replace their contents in-place. These can\n\t * be top-level chunkedOp messages, or top-level op messages with a chunkedOp\n\t * within the contents\n\t */\n\tprivate messages = new Array<any>();\n\t/**\n\t * The messages' parsed contents for processing. Should parallel the\n\t * messages member\n\t */\n\tprivate parsedMessageContents = new Array<any>();\n\tprivate writtenBack = false;\n\t/**\n\t * keep track of the total starting length to make sure we don't somehow end\n\t * up with more content than we started with (meaning we may not be able to\n\t * write it back)\n\t */\n\tprivate concatenatedLength = 0;\n\n\tconstructor(\n\t\treadonly validateSchemaFn: (object: any, schema: any) => boolean,\n\t\treadonly debug: boolean,\n\t) {}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\taddMessage(message: any): void {\n\t\tthis.messages.push(message);\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(message.contents);\n\t\t\tif (message.type === \"op\") {\n\t\t\t\t// nested within a regular op\n\t\t\t\t// need to go deeper to get the desired contents\n\t\t\t\tparsed = parsed.contents;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthis.debugMsg(message.contents);\n\t\t}\n\t\tthis.validateSchemaFn(parsed, chunkedOpContentsSchema);\n\t\tthis.parsedMessageContents.push(parsed);\n\t}\n\n\thasAllMessages(): boolean {\n\t\tconst lastMsgContents = this.parsedMessageContents[this.parsedMessageContents.length - 1];\n\t\treturn (\n\t\t\tlastMsgContents.chunkId !== undefined &&\n\t\t\tlastMsgContents.chunkId === lastMsgContents.totalChunks\n\t\t);\n\t}\n\n\t/**\n\t * Gets the concatenated contents of all the messages parsed as JSON.\n\t */\n\tgetConcatenatedContents(): any {\n\t\tconst contentsString = this.parsedMessageContents.reduce(\n\t\t\t(previousValue: string, currentValue: any) => {\n\t\t\t\treturn previousValue + (currentValue.contents as string);\n\t\t\t},\n\t\t\t\"\",\n\t\t);\n\n\t\tthis.concatenatedLength = contentsString.length;\n\t\ttry {\n\t\t\treturn JSON.parse(contentsString);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(contentsString);\n\t\t\tthis.debugMsg(e);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Write back sanitized contents into the messages. The contents are\n\t * stringified, split up, and written in place to the messages that\n\t * were added earlier. The number of messages is preserved.\n\t * @param contents - Sanitized contents to write back\n\t */\n\twriteSanitizedContents(contents: any): void {\n\t\t// Write back a chunk size equal to the original\n\t\tconst chunkSize = this.parsedMessageContents[0].contents.length;\n\n\t\tlet stringified: string;\n\t\ttry {\n\t\t\tstringified = JSON.stringify(contents);\n\t\t\tassert(\n\t\t\t\tstringified.length <= this.concatenatedLength,\n\t\t\t\t0x089 /* \"Stringified length of chunk contents > total starting length\" */,\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthrow e;\n\t\t}\n\n\t\tfor (let i = 0; i < this.messages.length; i++) {\n\t\t\tconst substring = stringified.substring(i * chunkSize, (i + 1) * chunkSize);\n\n\t\t\tconst parsedContents = this.parsedMessageContents[i];\n\t\t\tparsedContents.contents = substring;\n\t\t\tconst message = this.messages[i];\n\n\t\t\tlet stringifiedParsedContents;\n\t\t\ttry {\n\t\t\t\t// for nested chunkedOps, we need to recreate the extra nesting layer\n\t\t\t\t// we removed earlier when adding the message\n\t\t\t\tif (message.type === \"op\") {\n\t\t\t\t\tconst nestingLayer = {\n\t\t\t\t\t\ttype: \"chunkedOp\",\n\t\t\t\t\t\tcontents: parsedContents,\n\t\t\t\t\t};\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(nestingLayer);\n\t\t\t\t} else {\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(parsedContents);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t}\n\n\t\t\tmessage.contents = stringifiedParsedContents;\n\t\t}\n\n\t\tthis.writtenBack = true;\n\t}\n\n\treset(): void {\n\t\tassert(\n\t\t\tthis.writtenBack,\n\t\t\t0x08a /* \"resetting ChunkedOpProcessor that never wrote back its contents\" */,\n\t\t);\n\t\tthis.messages = new Array<any>();\n\t\tthis.parsedMessageContents = new Array<any>();\n\t\tthis.writtenBack = false;\n\t\tthis.concatenatedLength = 0;\n\t}\n\n\tisPendingProcessing(): boolean {\n\t\treturn this.messages.length !== 0;\n\t}\n}\n\nexport class Sanitizer {\n\treadonly validator = new Validator.Validator();\n\t// Represents the keys used to store Fluid object identifiers, snapshot info,\n\t// and other string fields that should not be replaced in contents blobs to\n\t// ensure the messages are still usable\n\treadonly defaultExcludedKeys = new Set<string>();\n\t// Represents the keys used by merge-tree ops their \"seg\" property, where other\n\t// keys represent user information\n\treadonly mergeTreeExcludedKeys = new Set<string>();\n\t// Map of user information to what it was replaced with. Used to ensure the same\n\t// data have the same replacements\n\treadonly replacementMap = new Map<string, string>();\n\n\t/**\n\t * Validate that the provided message matches the provided schema.\n\t * For a full scrub, warn and continue (scrubber should fully sanitize unexpected\n\t * fields for ops), otherwise throw an error because we cannot be sure user\n\t * information is being sufficiently sanitized.\n\t */\n\tobjectMatchesSchema = (object: any, schema: any): boolean => {\n\t\tconst result = schema === false ? falseResult : this.validator.validate(object, schema);\n\t\tif (!result.valid) {\n\t\t\tconst errorMsg = `Bad msg fmt:\\n${result.toString()}\\n${JSON.stringify(\n\t\t\t\tobject,\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`;\n\n\t\t\tif (this.fullScrub || this.noBail) {\n\t\t\t\tthis.debugMsg(errorMsg);\n\t\t\t} else {\n\t\t\t\tthrow new Error(errorMsg);\n\t\t\t}\n\t\t}\n\t\treturn result.valid;\n\t};\n\n\treadonly chunkProcessor: ChunkedOpProcessor;\n\n\tconstructor(\n\t\treadonly messages: ISequencedDocumentMessage[],\n\t\treadonly fullScrub: boolean,\n\t\treadonly noBail: boolean,\n\t\treadonly debug: boolean = false,\n\t) {\n\t\tthis.defaultExcludedKeys.add(\"type\");\n\t\tthis.defaultExcludedKeys.add(\"id\");\n\t\tthis.defaultExcludedKeys.add(\"pkg\");\n\t\tthis.defaultExcludedKeys.add(\"snapshotFormatVersion\");\n\t\tthis.defaultExcludedKeys.add(\"packageVersion\");\n\t\tthis.mergeTreeExcludedKeys.add(\"nodeType\");\n\t\tthis.chunkProcessor = new ChunkedOpProcessor(this.objectMatchesSchema, debug);\n\t}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\tisFluidObjectKey(key: string): boolean {\n\t\treturn key === \"type\" || key === \"id\";\n\t}\n\n\tgetRandomText(len: number): string {\n\t\tlet str = \"\";\n\t\twhile (str.length < len) {\n\t\t\tstr = str + Math.random().toString(36).substring(2);\n\t\t}\n\t\treturn str.substr(0, len);\n\t}\n\n\treadonly wordTokenRegex = /\\S+/g;\n\n\treadonly replaceRandomTextFn = (match: string): string => {\n\t\tif (this.replacementMap.has(match)) {\n\t\t\treturn this.replacementMap.get(match)!;\n\t\t}\n\n\t\tconst replacement = this.getRandomText(match.length);\n\t\tthis.replacementMap.set(match, replacement);\n\t\treturn replacement;\n\t};\n\n\t/**\n\t * Replace text with garbage. FluidObject types are not replaced when not under\n\t * full scrub mode. All other text is replaced consistently.\n\t */\n\treplaceText(input?: string, type: TextType = TextType.Generic): string | undefined {\n\t\tif (input === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (type === TextType.FluidObject) {\n\t\t\tif (this.replacementMap.has(input)) {\n\t\t\t\treturn this.replacementMap.get(input)!;\n\t\t\t}\n\n\t\t\tconst replacement = this.fullScrub ? this.getRandomText(input.length) : input;\n\n\t\t\tthis.replacementMap.set(input, replacement);\n\t\t\treturn replacement;\n\t\t}\n\n\t\treturn input.replace(this.wordTokenRegex, this.replaceRandomTextFn);\n\t}\n\n\treplaceArray(input: any[]): any[] {\n\t\tfor (let i = 0; i < input.length; i++) {\n\t\t\tconst value = input[i];\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tinput[i] = this.replaceText(value);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tinput[i] = this.replaceArray(value);\n\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\tinput[i] = this.replaceObject(value);\n\t\t\t}\n\t\t}\n\t\treturn input;\n\t}\n\n\t/**\n\t * (sort of) recurses down the values of a JSON object to sanitize all its strings\n\t * (only checks strings, arrays, and objects)\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceObject(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tinput: object | null,\n\t\texcludedKeys: Set<string> = this.defaultExcludedKeys,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): object | null {\n\t\t// File might contain actual nulls\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tconst keys = Object.keys(input);\n\t\tkeys.forEach((key) => {\n\t\t\tif (this.fullScrub || !excludedKeys.has(key)) {\n\t\t\t\tconst value = input[key];\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\tinput[key] = this.replaceText(\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tthis.isFluidObjectKey(key) ? TextType.FluidObject : TextType.Generic,\n\t\t\t\t\t);\n\t\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\t\tinput[key] = this.replaceArray(value);\n\t\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\t\tinput[key] = this.replaceObject(value, excludedKeys);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn input;\n\t}\n\n\t/**\n\t * Replacement on an unknown type or a parsed root level object\n\t * without a key\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceAny(input: any, excludedKeys: Set<string> = this.defaultExcludedKeys): any {\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tif (typeof input === \"string\") {\n\t\t\treturn this.replaceText(input);\n\t\t} else if (Array.isArray(input)) {\n\t\t\treturn this.replaceArray(input);\n\t\t} else if (typeof input === \"object\") {\n\t\t\treturn this.replaceObject(input, excludedKeys);\n\t\t}\n\n\t\t// Don't run replacement on any other types\n\t\treturn input;\n\t}\n\n\tfixJoin(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, joinContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t}\n\n\t\ttry {\n\t\t\tlet data = JSON.parse(message.data);\n\t\t\tif (!this.objectMatchesSchema(data, joinDataSchema)) {\n\t\t\t\tdata = this.replaceAny(data);\n\t\t\t} else {\n\t\t\t\tconst user = data.detail.user;\n\t\t\t\tuser.id = this.replaceText(user.id, TextType.Email);\n\t\t\t\tuser.email = this.replaceText(user.email, TextType.Email);\n\t\t\t\tuser.name = this.replaceText(user.name, TextType.Name);\n\t\t\t}\n\n\t\t\tmessage.data = JSON.stringify(data);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t}\n\t}\n\n\tfixPropose(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, proposeContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t} else {\n\t\t\tif (typeof message.contents === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\t\tconst pkg = data.value?.package;\n\t\t\t\t\t\tif (pkg?.name) {\n\t\t\t\t\t\t\tpkg.name = this.replaceText(pkg.name, TextType.FluidObject);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Array.isArray(pkg?.fluid?.browser?.umd?.files)) {\n\t\t\t\t\t\t\tpkg.fluid.browser.umd.files = this.replaceArray(pkg.fluid.browser.umd.files);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tmessage.contents.value = this.replaceText(\n\t\t\t\t\t\tmessage.contents.value,\n\t\t\t\t\t\tTextType.FluidObject,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfixAttachEntries(entries: any[]): void {\n\t\tentries.forEach((element) => {\n\t\t\t// Tree type\n\t\t\tif (element.value.entries) {\n\t\t\t\tthis.fixAttachEntries(element.value.entries);\n\t\t\t} else {\n\t\t\t\t// Blob (leaf) type\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof element.value.contents === \"string\") {\n\t\t\t\t\t\tlet data = JSON.parse(element.value.contents);\n\t\t\t\t\t\tdata = this.replaceObject(data);\n\t\t\t\t\t\telement.value.contents = JSON.stringify(data);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Fix the content of an attach in place\n\t * @param contents - contents object to fix\n\t */\n\tfixAttachContents(contents: any): any {\n\t\tassert(\n\t\t\ttypeof contents === \"object\",\n\t\t\t0x08b /* \"Unexpected type on contents for fix of an attach!\" */,\n\t\t);\n\t\tif (!this.objectMatchesSchema(contents, attachContentsSchema)) {\n\t\t\tthis.replaceObject(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.id = this.replaceText(contents.id, TextType.FluidObject);\n\t\t\t\tcontents.type = this.replaceText(contents.type, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tthis.fixAttachEntries(contents.snapshot.entries);\n\t\t}\n\t}\n\n\t/**\n\t * Fix an attach message at the root level or a ContainerMessageType attach. Attach\n\t * messages found within an op message should instead have their contents parsed out\n\t * and sent to fixAttachContents.\n\t * @param message - The attach message to fix\n\t * @param withinOp - If the message is from within an op message (as opposed to being\n\t * an attach message at the root level). Root level attach messages have \"snapshot\"\n\t * under a \"contents\" key, whereas attach messages from within an op message have it\n\t * under a \"content\" key\n\t */\n\tfixAttach(message: any): void {\n\t\t// Handle case where contents is stringified json\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\tmessage.contents = JSON.stringify(data);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.fixAttachContents(message.contents);\n\t\t}\n\t}\n\n\tfixDeltaOp(deltaOp: any): void {\n\t\tdeltaOp.seg =\n\t\t\ttypeof deltaOp.seg === \"string\"\n\t\t\t\t? this.replaceText(deltaOp.seg)\n\t\t\t\t: this.replaceObject(deltaOp.seg, this.mergeTreeExcludedKeys);\n\t}\n\n\t/**\n\t * Fix the contents object for an op message. Does not do extra type handling. Does\n\t * not handle special container message types like \"attach\", \"component\", and\n\t * \"chunkedOp\" (these should be handled by the caller)\n\t * @param contents - The contents object for an op message. If it was a string in the\n\t * message, it must have been converted to an object first\n\t */\n\tfixOpContentsObject(contents: any): void {\n\t\t// do replacement\n\t\tif (!this.objectMatchesSchema(contents, opContentsSchema)) {\n\t\t\tthis.replaceAny(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.address = this.replaceText(contents.address, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tconst innerContent = contents.contents.content;\n\t\t\tassert(\n\t\t\t\tinnerContent !== undefined,\n\t\t\t\t0x08c /* \"innerContent for fixing op contents is undefined!\" */,\n\t\t\t);\n\t\t\tif (contents.contents.type === \"attach\") {\n\t\t\t\t// attach op\n\t\t\t\t// handle case where inner content is stringified json\n\t\t\t\tif (typeof contents.contents.content === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst data = JSON.parse(contents.contents.content);\n\t\t\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\t\t\tcontents.contents.content = JSON.stringify(data);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.fixAttachContents(contents.contents.content);\n\t\t\t\t}\n\t\t\t} else if (this.validator.validate(innerContent, opContentsMapSchema).valid) {\n\t\t\t\t// map op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeGroupOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree group op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tinnerContent.contents.ops.forEach((deltaOp) => {\n\t\t\t\t\tthis.fixDeltaOp(deltaOp);\n\t\t\t\t});\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeDeltaOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree delta op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tthis.fixDeltaOp(innerContent.contents);\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsRegisterCollectionSchema).valid\n\t\t\t) {\n\t\t\t\t// register collection op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// message contents don't match any known op format\n\t\t\t\tthis.objectMatchesSchema(contents, false);\n\t\t\t}\n\t\t}\n\t}\n\n\tfixOp(message: any): void {\n\t\t// handle case where contents is stringified json\n\t\tlet msgContents;\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmsgContents = JSON.parse(message.contents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tmsgContents = message.contents;\n\t\t}\n\n\t\t// handle container message types\n\t\tswitch (msgContents.type) {\n\t\t\tcase \"attach\": {\n\t\t\t\t// this one is like a regular attach op, except its contents aren't nested as deep\n\t\t\t\t// run fixAttach directly and return\n\t\t\t\tthis.fixAttach(msgContents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"component\": {\n\t\t\t\t// this one functionally nests its contents one layer deeper\n\t\t\t\t// bring up the contents object and continue as usual\n\t\t\t\tthis.fixOpContentsObject(msgContents.contents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"chunkedOp\": {\n\t\t\t\t// this is a (regular?) op split into multiple parts due to size, e.g. because it\n\t\t\t\t// has an attached image, and where the chunkedOp is within the top-level op's contents\n\t\t\t\t// (as opposed to being at the top-level). The contents of the chunks need to be\n\t\t\t\t// concatenated to form the complete stringified json object\n\t\t\t\t// Early return here to skip re-stringify because no changes are made until the last\n\t\t\t\t// chunk, and the ChunkedOpProcessor will handle everything at that point\n\t\t\t\treturn this.fixChunkedOp(message);\n\t\t\t}\n\t\t\tcase \"blobAttach\": {\n\t\t\t\t// TODO: handle this properly once blob api is used\n\t\t\t\tthis.debugMsg(\"TODO: blobAttach ops are skipped/unhandled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// A regular op\n\t\t\t\tthis.fixOpContentsObject(msgContents);\n\t\t\t}\n\t\t}\n\n\t\t// re-stringify the json if needed\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmessage.contents = JSON.stringify(msgContents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fixes a chunked operation by reassembling and sanitizing the message chunks.\n\t *\n\t * @param message - The top-level chunkedOp message or a top-level op message\n\t * with a chunkedOp inside its contents\n\t */\n\tfixChunkedOp(message: any): void {\n\t\tthis.chunkProcessor.addMessage(message);\n\t\tif (!this.chunkProcessor.hasAllMessages()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = this.chunkProcessor.getConcatenatedContents();\n\t\tthis.fixOpContentsObject(contents);\n\n\t\tthis.chunkProcessor.writeSanitizedContents(contents);\n\t\tthis.chunkProcessor.reset();\n\t}\n\n\tsanitize(): ISequencedDocumentMessage[] {\n\t\tlet seq = 0;\n\n\t\ttry {\n\t\t\tthis.messages.map((message) => {\n\t\t\t\tseq = message.sequenceNumber;\n\t\t\t\t// message types from protocol-definitions' protocol.ts\n\t\t\t\tswitch (message.type) {\n\t\t\t\t\tcase \"join\": {\n\t\t\t\t\t\tthis.fixJoin(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"propose\": {\n\t\t\t\t\t\tthis.fixPropose(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"attach\": {\n\t\t\t\t\t\tthis.fixAttach(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"op\": {\n\t\t\t\t\t\tthis.fixOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"chunkedOp\": {\n\t\t\t\t\t\tthis.fixChunkedOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"noop\":\n\t\t\t\t\tcase \"leave\":\n\t\t\t\t\tcase \"noClient\":\n\t\t\t\t\tcase \"summarize\":\n\t\t\t\t\tcase \"summaryAck\":\n\t\t\t\t\tcase \"summaryNack\":\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.debugMsg(`Unexpected op type ${message.type}`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// make sure we don't miss an incomplete chunked op at the end\n\t\t\tassert(\n\t\t\t\t!this.chunkProcessor.isPendingProcessing(),\n\t\t\t\t0x08d /* \"After sanitize, pending incomplete ops!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(`Error while processing sequenceNumber ${seq}`);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn this.messages;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebuggerController.d.ts","sourceRoot":"","sources":["../src/fluidDebuggerController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fluidDebuggerController.d.ts","sourceRoot":"","sources":["../src/fluidDebuggerController.ts"],"names":[],"mappings":"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"}
@@ -224,7 +224,6 @@ export class DebugReplayController extends ReplayController {
224
224
  }
225
225
  async replay(emitter, fetchedOps) {
226
226
  let _fetchedOps = fetchedOps;
227
- // eslint-disable-next-line no-constant-condition
228
227
  while (true) {
229
228
  if (_fetchedOps.length === 0) {
230
229
  this.ui.updateNextOpText([]);
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebuggerController.js","sourceRoot":"","sources":["../src/fluidDebuggerController.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 { assert, Deferred } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentAttributes,\n\tISnapshotTree,\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport {\n\tFileSnapshotReader,\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi.js\";\nimport { Sanitizer } from \"./sanitizer.js\";\n\n/**\n * @internal\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n * @internal\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (typeof localStorage === \"object\" && localStorage?.FluidDebugger) {\n\t\t\tconst controller = new DebugReplayController();\n\t\t\tconst ui = createUi(controller);\n\t\t\tif (ui) {\n\t\t\t\treturn controller;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected static readonly WindowClosedSeq = -1; // Seq# to indicate that user closed window\n\n\tprotected static async seqFromTree(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\ttree: ISnapshotTree | null,\n\t): Promise<number> {\n\t\tif (!tree) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// TODO Why are we non null asserting here\n\t\tconst attributesHash = tree.trees[\".protocol\"]!.blobs.attributes!;\n\t\tconst attrib = await readAndParse<IDocumentAttributes>(\n\t\t\tdocumentStorageService,\n\t\t\tattributesHash,\n\t\t);\n\t\treturn attrib.sequenceNumber;\n\t}\n\n\tprotected ui: IDebuggerUI = null as any as IDebuggerUI; // Not to check on every line that it's not null\n\tprotected stepsDeferred?: Deferred<number>;\n\tprotected startSeqDeferred = new Deferred<number>();\n\n\t// True will cause us ping server indefinitely waiting for new ops\n\tprotected retryFetchOpsOnEndOfFile = false;\n\n\tprotected documentService?: IDocumentService;\n\tprotected documentStorageService?: IDocumentStorageService;\n\tprotected versions: IVersion[] = [];\n\tprotected stepsToPlay: number = 0;\n\tprotected lastOpReached = false;\n\tprotected versionCount = 0;\n\n\tprotected storage?: ReadDocumentStorageServiceBase;\n\n\t// Member to prevent repeated initialization in initStorage(...), which also\n\t// returns if this controller should be used or function as a passthrough\n\tprivate shouldUseController: boolean | undefined;\n\n\tpublic connectToUi(ui: IDebuggerUI): void {\n\t\tthis.ui = ui;\n\t}\n\n\tpublic onClose(): void {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async onVersionSelection(version: IVersion): Promise<void> {\n\t\tif (!this.documentStorageService) {\n\t\t\tthrow new Error(\"onVersionSelection: no storage\");\n\t\t}\n\n\t\tconst tree = await this.documentStorageService.getSnapshotTree(version);\n\t\tconst seq = await DebugReplayController.seqFromTree(this.documentStorageService, tree);\n\t\tthis.resolveStorage(seq, new SnapshotStorage(this.documentStorageService, tree), version);\n\t}\n\n\tpublic onOpButtonClick(steps: number): void {\n\t\tif (this.stepsDeferred && !Number.isNaN(steps) && steps > 0) {\n\t\t\tthis.stepsDeferred.resolve(steps);\n\t\t}\n\t}\n\n\tpublic onSnapshotFileSelection(file: File): void {\n\t\tif (!/^snapshot.*\\.json/.exec(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.exec(file.name)) {\n\t\t\talert(`Incorrect file name - please use non-extended files: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reader = new FileReader();\n\t\treader.onload = async () => {\n\t\t\tif (this.documentStorageService) {\n\t\t\t\tconst text = reader.result as string;\n\t\t\t\ttry {\n\t\t\t\t\tconst json: IFileSnapshot = JSON.parse(text) as IFileSnapshot;\n\t\t\t\t\t/*\n Const docStorage = this.documentStorageService;\n const storage = {\n read: (blobId: string) => this.read(docStorage, blobId),\n };\n const seq = await DebugReplayController.seqFromTree(\n storage as IDocumentStorageService,\n tree);\n this.startSeqDeferred.resolve(seq);\n */\n\t\t\t\t\t// No ability to load ops, so just say - pick up from infinite op.\n\t\t\t\t\tthis.retryFetchOpsOnEndOfFile = false;\n\t\t\t\t\tthis.lastOpReached = true;\n\t\t\t\t\tthis.resolveStorage(\n\t\t\t\t\t\tNumber.MAX_SAFE_INTEGER,\n\t\t\t\t\t\tnew FileSnapshotReader(json),\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\talert(`Error parsing file: ${error}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treader.readAsText(file, \"utf-8\");\n\t}\n\n\tpublic async onDownloadOpsButtonClick(anonymize: boolean): Promise<string> {\n\t\tif (this.documentService === undefined) {\n\t\t\tthrow new Error(\"DocumentService required\");\n\t\t}\n\n\t\tconst documentDeltaStorageService = await this.documentService.connectToDeltaStorage();\n\t\tlet messages = await this.fetchOpsFromDeltaStorage(documentDeltaStorageService);\n\n\t\tif (anonymize) {\n\t\t\tconst sanitizer = new Sanitizer(messages, false /* fullScrub */, false /* noBail */);\n\t\t\tmessages = sanitizer.sanitize();\n\t\t}\n\n\t\treturn JSON.stringify(messages, undefined, 2);\n\t}\n\n\tprivate async fetchOpsFromDeltaStorage(\n\t\tdocumentDeltaStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst deltaGenerator = generateSequencedMessagesFromDeltaStorage(\n\t\t\tdocumentDeltaStorageService,\n\t\t);\n\t\tlet messages: ISequencedDocumentMessage[] = [];\n\t\tfor await (const message of deltaGenerator) {\n\t\t\tmessages = messages.concat(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\treturn undefined;\n\t}\n\n\t// Returns true if version / file / ops selections is made.\n\tpublic isSelectionMade(): boolean {\n\t\treturn this.storage !== undefined;\n\t}\n\n\tpublic async downloadVersionInfo(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\tprevRequest: Promise<void>,\n\t\tindex: number,\n\t\tversion: IVersion,\n\t): Promise<void> {\n\t\tif (this.isSelectionMade()) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait prevRequest;\n\n\t\tconst treeV = await documentStorageService.getSnapshotTree(version);\n\t\tconst seqV = await DebugReplayController.seqFromTree(documentStorageService, treeV);\n\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versionCount--;\n\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\tthis.ui.updateVersion(index, version, seqV);\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\tif (this.shouldUseController !== undefined) {\n\t\t\treturn this.shouldUseController;\n\t\t}\n\n\t\tassert(!!documentService, 0x080 /* \"Invalid document service!\" */);\n\t\tassert(!this.documentService, 0x081 /* \"Document service already set!\" */);\n\t\tassert(!this.documentStorageService, 0x082 /* \"Document storage service already set!\" */);\n\t\tthis.documentService = documentService;\n\t\tthis.documentStorageService = await documentService.connectToStorage();\n\n\t\t// User can chose \"file\" at any moment in time!\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versions = await this.documentStorageService.getVersions(\"\", 50);\n\t\t\tif (!this.isSelectionMade()) {\n\t\t\t\tthis.ui.addVersions(this.versions);\n\t\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\t}\n\t\t}\n\n\t\tthis.versionCount = this.versions.length;\n\n\t\t// Download all versions - do 10 downloads in parallel to avoid being throttled\n\t\tconst buckets = 10;\n\t\tconst work: Promise<void>[] = [];\n\t\tfor (let i = 0; i < buckets; i++) {\n\t\t\tlet prevRequest = Promise.resolve();\n\t\t\tfor (let index = i; index < this.versions.length; index += buckets) {\n\t\t\t\t// Non null asserting here because we are iterating though versions\n\t\t\t\tconst version = this.versions[index]!;\n\t\t\t\tprevRequest = this.downloadVersionInfo(\n\t\t\t\t\tthis.documentStorageService,\n\t\t\t\t\tprevRequest,\n\t\t\t\t\tindex,\n\t\t\t\t\tversion,\n\t\t\t\t);\n\t\t\t}\n\t\t\twork.push(prevRequest);\n\t\t}\n\n\t\t// Don't wait for stuff to populate.\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tPromise.all(work).then(() => {\n\t\t\tthis.ui.updateVersionText(0);\n\t\t});\n\n\t\t// This hangs until the user makes a selection or closes the window.\n\t\tthis.shouldUseController =\n\t\t\t(await this.startSeqDeferred.promise) !== DebugReplayController.WindowClosedSeq;\n\n\t\tassert(\n\t\t\tthis.isSelectionMade() === this.shouldUseController,\n\t\t\t0x083 /* \"User selection status does not match replay controller use status!\" */,\n\t\t);\n\t\treturn this.shouldUseController;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.readBlob(blobId);\n\t\t}\n\t\tthrow new Error(\"Reading blob before storage is setup properly\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getVersions(versionId, count);\n\t\t}\n\t\tthrow new Error(\"initStorage() was not called!\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getSnapshotTree(versionRequested?: IVersion): Promise<ISnapshotTree | null> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getSnapshotTree(versionRequested);\n\t\t}\n\t\tthrow new Error(\"Reading snapshot tree before storage is setup properly\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn this.startSeqDeferred.promise;\n\t}\n\n\t/**\n\t * Return true if we are done processing ops\n\t */\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (lastTimeStamp === undefined) {\n\t\t\tthis.lastOpReached = true;\n\t\t\tif (currentOp === Number.MAX_SAFE_INTEGER) {\n\t\t\t\tthis.ui.updateLastOpText(-1, false);\n\t\t\t} else {\n\t\t\t\tthis.ui.updateLastOpText(currentOp, false);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.ui.updateLastOpText(currentOp, true);\n\t\t}\n\t\treturn this.lastOpReached && !this.retryFetchOpsOnEndOfFile;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet _fetchedOps = fetchedOps;\n\t\t// eslint-disable-next-line no-constant-condition\n\t\twhile (true) {\n\t\t\tif (_fetchedOps.length === 0) {\n\t\t\t\tthis.ui.updateNextOpText([]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.stepsToPlay === 0) {\n\t\t\t\tthis.ui.disableNextOpButton(false);\n\t\t\t\tthis.stepsDeferred = new Deferred<number>();\n\n\t\t\t\tthis.ui.updateNextOpText(_fetchedOps);\n\n\t\t\t\tthis.stepsToPlay = await this.stepsDeferred.promise;\n\n\t\t\t\tthis.stepsDeferred = undefined;\n\t\t\t\tthis.ui.disableNextOpButton(true);\n\t\t\t}\n\n\t\t\tlet playOps: ISequencedDocumentMessage[];\n\t\t\tif (this.stepsToPlay >= _fetchedOps.length) {\n\t\t\t\tplayOps = _fetchedOps;\n\t\t\t\tthis.stepsToPlay -= _fetchedOps.length;\n\t\t\t\t_fetchedOps = [];\n\t\t\t} else {\n\t\t\t\tplayOps = _fetchedOps.splice(0, this.stepsToPlay);\n\t\t\t\tthis.stepsToPlay = 0;\n\t\t\t}\n\t\t\temitter(playOps);\n\t\t}\n\t}\n\n\tprotected resolveStorage(\n\t\tseq: number,\n\t\tstorage: ReadDocumentStorageServiceBase,\n\t\tversion: IVersion | string,\n\t): void {\n\t\tassert(\n\t\t\t!this.isSelectionMade(),\n\t\t\t0x084 /* \"On storage resolve, user selection already made!\" */,\n\t\t);\n\t\tassert(!!storage, 0x085 /* \"On storage resolve, missing storage!\" */);\n\t\tthis.storage = storage;\n\t\tassert(\n\t\t\tthis.isSelectionMade(),\n\t\t\t0x086 /* \"After storage resolve, user selection status still false!\" */,\n\t\t);\n\n\t\tthis.ui.versionSelected(seq, version);\n\t\tthis.startSeqDeferred.resolve(seq);\n\t}\n}\n\nasync function* generateSequencedMessagesFromDeltaStorage(\n\tdeltaStorage: IDocumentDeltaStorageService,\n): AsyncGenerator<ISequencedDocumentMessage[], void, undefined> {\n\tconst stream = deltaStorage.fetchMessages(1, undefined);\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\treturn;\n\t\t}\n\t\tyield result.value;\n\t}\n}\n"]}
1
+ {"version":3,"file":"fluidDebuggerController.js","sourceRoot":"","sources":["../src/fluidDebuggerController.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 { assert, Deferred } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentAttributes,\n\tISnapshotTree,\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport {\n\tFileSnapshotReader,\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi.js\";\nimport { Sanitizer } from \"./sanitizer.js\";\n\n/**\n * @internal\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n * @internal\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (typeof localStorage === \"object\" && localStorage?.FluidDebugger) {\n\t\t\tconst controller = new DebugReplayController();\n\t\t\tconst ui = createUi(controller);\n\t\t\tif (ui) {\n\t\t\t\treturn controller;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected static readonly WindowClosedSeq = -1; // Seq# to indicate that user closed window\n\n\tprotected static async seqFromTree(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\ttree: ISnapshotTree | null,\n\t): Promise<number> {\n\t\tif (!tree) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// TODO Why are we non null asserting here\n\t\tconst attributesHash = tree.trees[\".protocol\"]!.blobs.attributes!;\n\t\tconst attrib = await readAndParse<IDocumentAttributes>(\n\t\t\tdocumentStorageService,\n\t\t\tattributesHash,\n\t\t);\n\t\treturn attrib.sequenceNumber;\n\t}\n\n\tprotected ui: IDebuggerUI = null as any as IDebuggerUI; // Not to check on every line that it's not null\n\tprotected stepsDeferred?: Deferred<number>;\n\tprotected startSeqDeferred = new Deferred<number>();\n\n\t// True will cause us ping server indefinitely waiting for new ops\n\tprotected retryFetchOpsOnEndOfFile = false;\n\n\tprotected documentService?: IDocumentService;\n\tprotected documentStorageService?: IDocumentStorageService;\n\tprotected versions: IVersion[] = [];\n\tprotected stepsToPlay: number = 0;\n\tprotected lastOpReached = false;\n\tprotected versionCount = 0;\n\n\tprotected storage?: ReadDocumentStorageServiceBase;\n\n\t// Member to prevent repeated initialization in initStorage(...), which also\n\t// returns if this controller should be used or function as a passthrough\n\tprivate shouldUseController: boolean | undefined;\n\n\tpublic connectToUi(ui: IDebuggerUI): void {\n\t\tthis.ui = ui;\n\t}\n\n\tpublic onClose(): void {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async onVersionSelection(version: IVersion): Promise<void> {\n\t\tif (!this.documentStorageService) {\n\t\t\tthrow new Error(\"onVersionSelection: no storage\");\n\t\t}\n\n\t\tconst tree = await this.documentStorageService.getSnapshotTree(version);\n\t\tconst seq = await DebugReplayController.seqFromTree(this.documentStorageService, tree);\n\t\tthis.resolveStorage(seq, new SnapshotStorage(this.documentStorageService, tree), version);\n\t}\n\n\tpublic onOpButtonClick(steps: number): void {\n\t\tif (this.stepsDeferred && !Number.isNaN(steps) && steps > 0) {\n\t\t\tthis.stepsDeferred.resolve(steps);\n\t\t}\n\t}\n\n\tpublic onSnapshotFileSelection(file: File): void {\n\t\tif (!/^snapshot.*\\.json/.exec(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.exec(file.name)) {\n\t\t\talert(`Incorrect file name - please use non-extended files: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reader = new FileReader();\n\t\treader.onload = async () => {\n\t\t\tif (this.documentStorageService) {\n\t\t\t\tconst text = reader.result as string;\n\t\t\t\ttry {\n\t\t\t\t\tconst json: IFileSnapshot = JSON.parse(text) as IFileSnapshot;\n\t\t\t\t\t/*\n Const docStorage = this.documentStorageService;\n const storage = {\n read: (blobId: string) => this.read(docStorage, blobId),\n };\n const seq = await DebugReplayController.seqFromTree(\n storage as IDocumentStorageService,\n tree);\n this.startSeqDeferred.resolve(seq);\n */\n\t\t\t\t\t// No ability to load ops, so just say - pick up from infinite op.\n\t\t\t\t\tthis.retryFetchOpsOnEndOfFile = false;\n\t\t\t\t\tthis.lastOpReached = true;\n\t\t\t\t\tthis.resolveStorage(\n\t\t\t\t\t\tNumber.MAX_SAFE_INTEGER,\n\t\t\t\t\t\tnew FileSnapshotReader(json),\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\talert(`Error parsing file: ${error}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treader.readAsText(file, \"utf-8\");\n\t}\n\n\tpublic async onDownloadOpsButtonClick(anonymize: boolean): Promise<string> {\n\t\tif (this.documentService === undefined) {\n\t\t\tthrow new Error(\"DocumentService required\");\n\t\t}\n\n\t\tconst documentDeltaStorageService = await this.documentService.connectToDeltaStorage();\n\t\tlet messages = await this.fetchOpsFromDeltaStorage(documentDeltaStorageService);\n\n\t\tif (anonymize) {\n\t\t\tconst sanitizer = new Sanitizer(messages, false /* fullScrub */, false /* noBail */);\n\t\t\tmessages = sanitizer.sanitize();\n\t\t}\n\n\t\treturn JSON.stringify(messages, undefined, 2);\n\t}\n\n\tprivate async fetchOpsFromDeltaStorage(\n\t\tdocumentDeltaStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst deltaGenerator = generateSequencedMessagesFromDeltaStorage(\n\t\t\tdocumentDeltaStorageService,\n\t\t);\n\t\tlet messages: ISequencedDocumentMessage[] = [];\n\t\tfor await (const message of deltaGenerator) {\n\t\t\tmessages = messages.concat(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\treturn undefined;\n\t}\n\n\t// Returns true if version / file / ops selections is made.\n\tpublic isSelectionMade(): boolean {\n\t\treturn this.storage !== undefined;\n\t}\n\n\tpublic async downloadVersionInfo(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\tprevRequest: Promise<void>,\n\t\tindex: number,\n\t\tversion: IVersion,\n\t): Promise<void> {\n\t\tif (this.isSelectionMade()) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait prevRequest;\n\n\t\tconst treeV = await documentStorageService.getSnapshotTree(version);\n\t\tconst seqV = await DebugReplayController.seqFromTree(documentStorageService, treeV);\n\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versionCount--;\n\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\tthis.ui.updateVersion(index, version, seqV);\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\tif (this.shouldUseController !== undefined) {\n\t\t\treturn this.shouldUseController;\n\t\t}\n\n\t\tassert(!!documentService, 0x080 /* \"Invalid document service!\" */);\n\t\tassert(!this.documentService, 0x081 /* \"Document service already set!\" */);\n\t\tassert(!this.documentStorageService, 0x082 /* \"Document storage service already set!\" */);\n\t\tthis.documentService = documentService;\n\t\tthis.documentStorageService = await documentService.connectToStorage();\n\n\t\t// User can chose \"file\" at any moment in time!\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versions = await this.documentStorageService.getVersions(\"\", 50);\n\t\t\tif (!this.isSelectionMade()) {\n\t\t\t\tthis.ui.addVersions(this.versions);\n\t\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\t}\n\t\t}\n\n\t\tthis.versionCount = this.versions.length;\n\n\t\t// Download all versions - do 10 downloads in parallel to avoid being throttled\n\t\tconst buckets = 10;\n\t\tconst work: Promise<void>[] = [];\n\t\tfor (let i = 0; i < buckets; i++) {\n\t\t\tlet prevRequest = Promise.resolve();\n\t\t\tfor (let index = i; index < this.versions.length; index += buckets) {\n\t\t\t\t// Non null asserting here because we are iterating though versions\n\t\t\t\tconst version = this.versions[index]!;\n\t\t\t\tprevRequest = this.downloadVersionInfo(\n\t\t\t\t\tthis.documentStorageService,\n\t\t\t\t\tprevRequest,\n\t\t\t\t\tindex,\n\t\t\t\t\tversion,\n\t\t\t\t);\n\t\t\t}\n\t\t\twork.push(prevRequest);\n\t\t}\n\n\t\t// Don't wait for stuff to populate.\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tPromise.all(work).then(() => {\n\t\t\tthis.ui.updateVersionText(0);\n\t\t});\n\n\t\t// This hangs until the user makes a selection or closes the window.\n\t\tthis.shouldUseController =\n\t\t\t(await this.startSeqDeferred.promise) !== DebugReplayController.WindowClosedSeq;\n\n\t\tassert(\n\t\t\tthis.isSelectionMade() === this.shouldUseController,\n\t\t\t0x083 /* \"User selection status does not match replay controller use status!\" */,\n\t\t);\n\t\treturn this.shouldUseController;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.readBlob(blobId);\n\t\t}\n\t\tthrow new Error(\"Reading blob before storage is setup properly\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getVersions(versionId, count);\n\t\t}\n\t\tthrow new Error(\"initStorage() was not called!\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getSnapshotTree(versionRequested?: IVersion): Promise<ISnapshotTree | null> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getSnapshotTree(versionRequested);\n\t\t}\n\t\tthrow new Error(\"Reading snapshot tree before storage is setup properly\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn this.startSeqDeferred.promise;\n\t}\n\n\t/**\n\t * Return true if we are done processing ops\n\t */\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (lastTimeStamp === undefined) {\n\t\t\tthis.lastOpReached = true;\n\t\t\tif (currentOp === Number.MAX_SAFE_INTEGER) {\n\t\t\t\tthis.ui.updateLastOpText(-1, false);\n\t\t\t} else {\n\t\t\t\tthis.ui.updateLastOpText(currentOp, false);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.ui.updateLastOpText(currentOp, true);\n\t\t}\n\t\treturn this.lastOpReached && !this.retryFetchOpsOnEndOfFile;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet _fetchedOps = fetchedOps;\n\t\twhile (true) {\n\t\t\tif (_fetchedOps.length === 0) {\n\t\t\t\tthis.ui.updateNextOpText([]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.stepsToPlay === 0) {\n\t\t\t\tthis.ui.disableNextOpButton(false);\n\t\t\t\tthis.stepsDeferred = new Deferred<number>();\n\n\t\t\t\tthis.ui.updateNextOpText(_fetchedOps);\n\n\t\t\t\tthis.stepsToPlay = await this.stepsDeferred.promise;\n\n\t\t\t\tthis.stepsDeferred = undefined;\n\t\t\t\tthis.ui.disableNextOpButton(true);\n\t\t\t}\n\n\t\t\tlet playOps: ISequencedDocumentMessage[];\n\t\t\tif (this.stepsToPlay >= _fetchedOps.length) {\n\t\t\t\tplayOps = _fetchedOps;\n\t\t\t\tthis.stepsToPlay -= _fetchedOps.length;\n\t\t\t\t_fetchedOps = [];\n\t\t\t} else {\n\t\t\t\tplayOps = _fetchedOps.splice(0, this.stepsToPlay);\n\t\t\t\tthis.stepsToPlay = 0;\n\t\t\t}\n\t\t\temitter(playOps);\n\t\t}\n\t}\n\n\tprotected resolveStorage(\n\t\tseq: number,\n\t\tstorage: ReadDocumentStorageServiceBase,\n\t\tversion: IVersion | string,\n\t): void {\n\t\tassert(\n\t\t\t!this.isSelectionMade(),\n\t\t\t0x084 /* \"On storage resolve, user selection already made!\" */,\n\t\t);\n\t\tassert(!!storage, 0x085 /* \"On storage resolve, missing storage!\" */);\n\t\tthis.storage = storage;\n\t\tassert(\n\t\t\tthis.isSelectionMade(),\n\t\t\t0x086 /* \"After storage resolve, user selection status still false!\" */,\n\t\t);\n\n\t\tthis.ui.versionSelected(seq, version);\n\t\tthis.startSeqDeferred.resolve(seq);\n\t}\n}\n\nasync function* generateSequencedMessagesFromDeltaStorage(\n\tdeltaStorage: IDocumentDeltaStorageService,\n): AsyncGenerator<ISequencedDocumentMessage[], void, undefined> {\n\tconst stream = deltaStorage.fetchMessages(1, undefined);\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\treturn;\n\t\t}\n\t\tyield result.value;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../src/sanitizer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../src/sanitizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkBH,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,KAAK,SAAS,MAAM,YAAY,CAAC;AAexC,aAAK,QAAQ;IACZ,OAAO,IAAA;IACP,KAAK,IAAA;IACL,IAAI,IAAA;IACJ,WAAW,IAAA;IACX,MAAM,IAAA;CACN;AAWD;;;;;GAKG;AACH,cAAM,kBAAkB;IAqBtB,QAAQ,CAAC,gBAAgB,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO;IAChE,QAAQ,CAAC,KAAK,EAAE,OAAO;IArBxB;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAoB;IACpC;;;OAGG;IACH,OAAO,CAAC,qBAAqB,CAAoB;IACjD,OAAO,CAAC,WAAW,CAAS;IAC5B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB,CAAK;gBAGrB,gBAAgB,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO,EACvD,KAAK,EAAE,OAAO;IAGxB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAMxB,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAmB9B,cAAc,IAAI,OAAO;IAQzB;;OAEG;IACH,uBAAuB,IAAI,GAAG;IAkB9B;;;;;OAKG;IACH,sBAAsB,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI;IA8C3C,KAAK,IAAI,IAAI;IAWb,mBAAmB,IAAI,OAAO;CAG9B;AAED,qBAAa,SAAS;IAwCpB,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,EAAE;IAC9C,QAAQ,CAAC,SAAS,EAAE,OAAO;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO;IA1CxB,QAAQ,CAAC,SAAS,sBAA6B;IAI/C,QAAQ,CAAC,mBAAmB,cAAqB;IAGjD,QAAQ,CAAC,qBAAqB,cAAqB;IAGnD,QAAQ,CAAC,cAAc,sBAA6B;IAEpD;;;;;OAKG;IACH,mBAAmB,WAAY,GAAG,UAAU,GAAG,KAAG,OAAO,CAgBvD;IAEF,QAAQ,CAAC,cAAc,EAAE,kBAAkB,CAAC;gBAGlC,QAAQ,EAAE,yBAAyB,EAAE,EACrC,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE,OAAO,EACf,KAAK,GAAE,OAAe;IAWhC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAMxB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAItC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAQlC,QAAQ,CAAC,cAAc,SAAU;IAEjC,QAAQ,CAAC,mBAAmB,UAAW,MAAM,KAAG,MAAM,CAQpD;IAEF;;;OAGG;IACH,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,QAA2B,GAAG,MAAM,GAAG,SAAS;IAmBlF,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE;IAcjC;;;;;OAKG;IACH,aAAa,CAEZ,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,YAAY,GAAE,GAAG,CAAC,MAAM,CAA4B,GAElD,MAAM,GAAG,IAAI;IAyBhB;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,GAAE,GAAG,CAAC,MAAM,CAA4B,GAAG,GAAG;IAiBjF,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAsB3B,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IA8B9B,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI;IAoBtC;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG;IAiBrC;;;;;;;;;OASG;IACH,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAgB7B,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAO9B;;;;;;OAMG;IACH,mBAAmB,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI;IAmFxC,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IA2DzB;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAahC,QAAQ,IAAI,yBAAyB,EAAE;CAoDvC"}
package/lib/sanitizer.js CHANGED
@@ -310,7 +310,6 @@ export class Sanitizer {
310
310
  return this.replaceText(input);
311
311
  }
312
312
  else if (Array.isArray(input)) {
313
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
314
313
  return this.replaceArray(input);
315
314
  }
316
315
  else if (typeof input === "object") {
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../src/sanitizer.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\n/**\n * This tool cleans up a message.json file downloaded through fluid-fetch to remove\n * user content and user identifying information. Enough information can be retained\n * to allow loading through Fluid Preview, or everything can be scrubbed so that only\n * replay-tool can read the result. Anonymous identifying information such as client\n * IDs are always retained. Object keys are NOT scrubbed, including those that are\n * nested within values (only leaf values are scrubbed).\n *\n * Note: While user content/information is scrubbed, it should not be assumed to be\n * fully anonymized because certain meta-information (such as word lengths and\n * consistent replacement) are preserved.\n *\n * Messages must match known structures when scrubbing for Fluid Preview.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport * as Validator from \"jsonschema\";\n\nimport {\n\tattachContentsSchema,\n\tchunkedOpContentsSchema,\n\tjoinContentsSchema,\n\tjoinDataSchema,\n\topContentsMapSchema,\n\topContentsMergeTreeDeltaOpSchema,\n\topContentsMergeTreeGroupOpSchema,\n\topContentsRegisterCollectionSchema,\n\topContentsSchema,\n\tproposeContentsSchema,\n} from \"./messageSchema.js\";\n\nenum TextType {\n\tGeneric,\n\tEmail,\n\tName,\n\tFluidObject,\n\tMapKey,\n}\n\n// Workaround to jsonschema package not supporting \"false\" as a schema\n// that matches nothing\nconst falseResult = {\n\tvalid: false,\n\ttoString: () => {\n\t\treturn \"Unmatched format\";\n\t},\n};\n\n/**\n * Class that takes chunkedOp messages and can provide their concatenated\n * contents along with re-write sanitized content in-place back into the\n * messages. Assumes sanitized messages are always less than or equal in\n * size to the original message.\n */\nclass ChunkedOpProcessor {\n\t/**\n\t * Message references so we can replace their contents in-place. These can\n\t * be top-level chunkedOp messages, or top-level op messages with a chunkedOp\n\t * within the contents\n\t */\n\tprivate messages = new Array<any>();\n\t/**\n\t * The messages' parsed contents for processing. Should parallel the\n\t * messages member\n\t */\n\tprivate parsedMessageContents = new Array<any>();\n\tprivate writtenBack = false;\n\t/**\n\t * keep track of the total starting length to make sure we don't somehow end\n\t * up with more content than we started with (meaning we may not be able to\n\t * write it back)\n\t */\n\tprivate concatenatedLength = 0;\n\n\tconstructor(\n\t\treadonly validateSchemaFn: (object: any, schema: any) => boolean,\n\t\treadonly debug: boolean,\n\t) {}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\taddMessage(message: any): void {\n\t\tthis.messages.push(message);\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(message.contents);\n\t\t\tif (message.type === \"op\") {\n\t\t\t\t// nested within a regular op\n\t\t\t\t// need to go deeper to get the desired contents\n\t\t\t\tparsed = parsed.contents;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthis.debugMsg(message.contents);\n\t\t}\n\t\tthis.validateSchemaFn(parsed, chunkedOpContentsSchema);\n\t\tthis.parsedMessageContents.push(parsed);\n\t}\n\n\thasAllMessages(): boolean {\n\t\tconst lastMsgContents = this.parsedMessageContents[this.parsedMessageContents.length - 1];\n\t\treturn (\n\t\t\tlastMsgContents.chunkId !== undefined &&\n\t\t\tlastMsgContents.chunkId === lastMsgContents.totalChunks\n\t\t);\n\t}\n\n\t/**\n\t * Gets the concatenated contents of all the messages parsed as JSON.\n\t */\n\tgetConcatenatedContents(): any {\n\t\tconst contentsString = this.parsedMessageContents.reduce(\n\t\t\t(previousValue: string, currentValue: any) => {\n\t\t\t\treturn previousValue + (currentValue.contents as string);\n\t\t\t},\n\t\t\t\"\",\n\t\t);\n\n\t\tthis.concatenatedLength = contentsString.length;\n\t\ttry {\n\t\t\treturn JSON.parse(contentsString);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(contentsString);\n\t\t\tthis.debugMsg(e);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Write back sanitized contents into the messages. The contents are\n\t * stringified, split up, and written in place to the messages that\n\t * were added earlier. The number of messages is preserved.\n\t * @param contents - Sanitized contents to write back\n\t */\n\twriteSanitizedContents(contents: any): void {\n\t\t// Write back a chunk size equal to the original\n\t\tconst chunkSize = this.parsedMessageContents[0].contents.length;\n\n\t\tlet stringified: string;\n\t\ttry {\n\t\t\tstringified = JSON.stringify(contents);\n\t\t\tassert(\n\t\t\t\tstringified.length <= this.concatenatedLength,\n\t\t\t\t0x089 /* \"Stringified length of chunk contents > total starting length\" */,\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthrow e;\n\t\t}\n\n\t\tfor (let i = 0; i < this.messages.length; i++) {\n\t\t\tconst substring = stringified.substring(i * chunkSize, (i + 1) * chunkSize);\n\n\t\t\tconst parsedContents = this.parsedMessageContents[i];\n\t\t\tparsedContents.contents = substring;\n\t\t\tconst message = this.messages[i];\n\n\t\t\tlet stringifiedParsedContents;\n\t\t\ttry {\n\t\t\t\t// for nested chunkedOps, we need to recreate the extra nesting layer\n\t\t\t\t// we removed earlier when adding the message\n\t\t\t\tif (message.type === \"op\") {\n\t\t\t\t\tconst nestingLayer = {\n\t\t\t\t\t\ttype: \"chunkedOp\",\n\t\t\t\t\t\tcontents: parsedContents,\n\t\t\t\t\t};\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(nestingLayer);\n\t\t\t\t} else {\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(parsedContents);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t}\n\n\t\t\tmessage.contents = stringifiedParsedContents;\n\t\t}\n\n\t\tthis.writtenBack = true;\n\t}\n\n\treset(): void {\n\t\tassert(\n\t\t\tthis.writtenBack,\n\t\t\t0x08a /* \"resetting ChunkedOpProcessor that never wrote back its contents\" */,\n\t\t);\n\t\tthis.messages = new Array<any>();\n\t\tthis.parsedMessageContents = new Array<any>();\n\t\tthis.writtenBack = false;\n\t\tthis.concatenatedLength = 0;\n\t}\n\n\tisPendingProcessing(): boolean {\n\t\treturn this.messages.length !== 0;\n\t}\n}\n\nexport class Sanitizer {\n\treadonly validator = new Validator.Validator();\n\t// Represents the keys used to store Fluid object identifiers, snapshot info,\n\t// and other string fields that should not be replaced in contents blobs to\n\t// ensure the messages are still usable\n\treadonly defaultExcludedKeys = new Set<string>();\n\t// Represents the keys used by merge-tree ops their \"seg\" property, where other\n\t// keys represent user information\n\treadonly mergeTreeExcludedKeys = new Set<string>();\n\t// Map of user information to what it was replaced with. Used to ensure the same\n\t// data have the same replacements\n\treadonly replacementMap = new Map<string, string>();\n\n\t/**\n\t * Validate that the provided message matches the provided schema.\n\t * For a full scrub, warn and continue (scrubber should fully sanitize unexpected\n\t * fields for ops), otherwise throw an error because we cannot be sure user\n\t * information is being sufficiently sanitized.\n\t */\n\tobjectMatchesSchema = (object: any, schema: any): boolean => {\n\t\tconst result = schema === false ? falseResult : this.validator.validate(object, schema);\n\t\tif (!result.valid) {\n\t\t\tconst errorMsg = `Bad msg fmt:\\n${result.toString()}\\n${JSON.stringify(\n\t\t\t\tobject,\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`;\n\n\t\t\tif (this.fullScrub || this.noBail) {\n\t\t\t\tthis.debugMsg(errorMsg);\n\t\t\t} else {\n\t\t\t\tthrow new Error(errorMsg);\n\t\t\t}\n\t\t}\n\t\treturn result.valid;\n\t};\n\n\treadonly chunkProcessor: ChunkedOpProcessor;\n\n\tconstructor(\n\t\treadonly messages: ISequencedDocumentMessage[],\n\t\treadonly fullScrub: boolean,\n\t\treadonly noBail: boolean,\n\t\treadonly debug: boolean = false,\n\t) {\n\t\tthis.defaultExcludedKeys.add(\"type\");\n\t\tthis.defaultExcludedKeys.add(\"id\");\n\t\tthis.defaultExcludedKeys.add(\"pkg\");\n\t\tthis.defaultExcludedKeys.add(\"snapshotFormatVersion\");\n\t\tthis.defaultExcludedKeys.add(\"packageVersion\");\n\t\tthis.mergeTreeExcludedKeys.add(\"nodeType\");\n\t\tthis.chunkProcessor = new ChunkedOpProcessor(this.objectMatchesSchema, debug);\n\t}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\tisFluidObjectKey(key: string): boolean {\n\t\treturn key === \"type\" || key === \"id\";\n\t}\n\n\tgetRandomText(len: number): string {\n\t\tlet str = \"\";\n\t\twhile (str.length < len) {\n\t\t\tstr = str + Math.random().toString(36).substring(2);\n\t\t}\n\t\treturn str.substr(0, len);\n\t}\n\n\treadonly wordTokenRegex = /\\S+/g;\n\n\treadonly replaceRandomTextFn = (match: string): string => {\n\t\tif (this.replacementMap.has(match)) {\n\t\t\treturn this.replacementMap.get(match)!;\n\t\t}\n\n\t\tconst replacement = this.getRandomText(match.length);\n\t\tthis.replacementMap.set(match, replacement);\n\t\treturn replacement;\n\t};\n\n\t/**\n\t * Replace text with garbage. FluidObject types are not replaced when not under\n\t * full scrub mode. All other text is replaced consistently.\n\t */\n\treplaceText(input?: string, type: TextType = TextType.Generic): string | undefined {\n\t\tif (input === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (type === TextType.FluidObject) {\n\t\t\tif (this.replacementMap.has(input)) {\n\t\t\t\treturn this.replacementMap.get(input)!;\n\t\t\t}\n\n\t\t\tconst replacement = this.fullScrub ? this.getRandomText(input.length) : input;\n\n\t\t\tthis.replacementMap.set(input, replacement);\n\t\t\treturn replacement;\n\t\t}\n\n\t\treturn input.replace(this.wordTokenRegex, this.replaceRandomTextFn);\n\t}\n\n\treplaceArray(input: any[]): any[] {\n\t\tfor (let i = 0; i < input.length; i++) {\n\t\t\tconst value = input[i];\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tinput[i] = this.replaceText(value);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tinput[i] = this.replaceArray(value);\n\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\tinput[i] = this.replaceObject(value);\n\t\t\t}\n\t\t}\n\t\treturn input;\n\t}\n\n\t/**\n\t * (sort of) recurses down the values of a JSON object to sanitize all its strings\n\t * (only checks strings, arrays, and objects)\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceObject(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tinput: object | null,\n\t\texcludedKeys: Set<string> = this.defaultExcludedKeys,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): object | null {\n\t\t// File might contain actual nulls\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tconst keys = Object.keys(input);\n\t\tkeys.forEach((key) => {\n\t\t\tif (this.fullScrub || !excludedKeys.has(key)) {\n\t\t\t\tconst value = input[key];\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\tinput[key] = this.replaceText(\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tthis.isFluidObjectKey(key) ? TextType.FluidObject : TextType.Generic,\n\t\t\t\t\t);\n\t\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\t\tinput[key] = this.replaceArray(value);\n\t\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\t\tinput[key] = this.replaceObject(value, excludedKeys);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn input;\n\t}\n\n\t/**\n\t * Replacement on an unknown type or a parsed root level object\n\t * without a key\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceAny(input: any, excludedKeys: Set<string> = this.defaultExcludedKeys): any {\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tif (typeof input === \"string\") {\n\t\t\treturn this.replaceText(input);\n\t\t} else if (Array.isArray(input)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn this.replaceArray(input);\n\t\t} else if (typeof input === \"object\") {\n\t\t\treturn this.replaceObject(input, excludedKeys);\n\t\t}\n\n\t\t// Don't run replacement on any other types\n\t\treturn input;\n\t}\n\n\tfixJoin(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, joinContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t}\n\n\t\ttry {\n\t\t\tlet data = JSON.parse(message.data);\n\t\t\tif (!this.objectMatchesSchema(data, joinDataSchema)) {\n\t\t\t\tdata = this.replaceAny(data);\n\t\t\t} else {\n\t\t\t\tconst user = data.detail.user;\n\t\t\t\tuser.id = this.replaceText(user.id, TextType.Email);\n\t\t\t\tuser.email = this.replaceText(user.email, TextType.Email);\n\t\t\t\tuser.name = this.replaceText(user.name, TextType.Name);\n\t\t\t}\n\n\t\t\tmessage.data = JSON.stringify(data);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t}\n\t}\n\n\tfixPropose(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, proposeContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t} else {\n\t\t\tif (typeof message.contents === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\t\tconst pkg = data.value?.package;\n\t\t\t\t\t\tif (pkg?.name) {\n\t\t\t\t\t\t\tpkg.name = this.replaceText(pkg.name, TextType.FluidObject);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Array.isArray(pkg?.fluid?.browser?.umd?.files)) {\n\t\t\t\t\t\t\tpkg.fluid.browser.umd.files = this.replaceArray(pkg.fluid.browser.umd.files);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tmessage.contents.value = this.replaceText(\n\t\t\t\t\t\tmessage.contents.value,\n\t\t\t\t\t\tTextType.FluidObject,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfixAttachEntries(entries: any[]): void {\n\t\tentries.forEach((element) => {\n\t\t\t// Tree type\n\t\t\tif (element.value.entries) {\n\t\t\t\tthis.fixAttachEntries(element.value.entries);\n\t\t\t} else {\n\t\t\t\t// Blob (leaf) type\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof element.value.contents === \"string\") {\n\t\t\t\t\t\tlet data = JSON.parse(element.value.contents);\n\t\t\t\t\t\tdata = this.replaceObject(data);\n\t\t\t\t\t\telement.value.contents = JSON.stringify(data);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Fix the content of an attach in place\n\t * @param contents - contents object to fix\n\t */\n\tfixAttachContents(contents: any): any {\n\t\tassert(\n\t\t\ttypeof contents === \"object\",\n\t\t\t0x08b /* \"Unexpected type on contents for fix of an attach!\" */,\n\t\t);\n\t\tif (!this.objectMatchesSchema(contents, attachContentsSchema)) {\n\t\t\tthis.replaceObject(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.id = this.replaceText(contents.id, TextType.FluidObject);\n\t\t\t\tcontents.type = this.replaceText(contents.type, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tthis.fixAttachEntries(contents.snapshot.entries);\n\t\t}\n\t}\n\n\t/**\n\t * Fix an attach message at the root level or a ContainerMessageType attach. Attach\n\t * messages found within an op message should instead have their contents parsed out\n\t * and sent to fixAttachContents.\n\t * @param message - The attach message to fix\n\t * @param withinOp - If the message is from within an op message (as opposed to being\n\t * an attach message at the root level). Root level attach messages have \"snapshot\"\n\t * under a \"contents\" key, whereas attach messages from within an op message have it\n\t * under a \"content\" key\n\t */\n\tfixAttach(message: any): void {\n\t\t// Handle case where contents is stringified json\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\tmessage.contents = JSON.stringify(data);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.fixAttachContents(message.contents);\n\t\t}\n\t}\n\n\tfixDeltaOp(deltaOp: any): void {\n\t\tdeltaOp.seg =\n\t\t\ttypeof deltaOp.seg === \"string\"\n\t\t\t\t? this.replaceText(deltaOp.seg)\n\t\t\t\t: this.replaceObject(deltaOp.seg, this.mergeTreeExcludedKeys);\n\t}\n\n\t/**\n\t * Fix the contents object for an op message. Does not do extra type handling. Does\n\t * not handle special container message types like \"attach\", \"component\", and\n\t * \"chunkedOp\" (these should be handled by the caller)\n\t * @param contents - The contents object for an op message. If it was a string in the\n\t * message, it must have been converted to an object first\n\t */\n\tfixOpContentsObject(contents: any): void {\n\t\t// do replacement\n\t\tif (!this.objectMatchesSchema(contents, opContentsSchema)) {\n\t\t\tthis.replaceAny(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.address = this.replaceText(contents.address, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tconst innerContent = contents.contents.content;\n\t\t\tassert(\n\t\t\t\tinnerContent !== undefined,\n\t\t\t\t0x08c /* \"innerContent for fixing op contents is undefined!\" */,\n\t\t\t);\n\t\t\tif (contents.contents.type === \"attach\") {\n\t\t\t\t// attach op\n\t\t\t\t// handle case where inner content is stringified json\n\t\t\t\tif (typeof contents.contents.content === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst data = JSON.parse(contents.contents.content);\n\t\t\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\t\t\tcontents.contents.content = JSON.stringify(data);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.fixAttachContents(contents.contents.content);\n\t\t\t\t}\n\t\t\t} else if (this.validator.validate(innerContent, opContentsMapSchema).valid) {\n\t\t\t\t// map op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeGroupOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree group op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tinnerContent.contents.ops.forEach((deltaOp) => {\n\t\t\t\t\tthis.fixDeltaOp(deltaOp);\n\t\t\t\t});\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeDeltaOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree delta op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tthis.fixDeltaOp(innerContent.contents);\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsRegisterCollectionSchema).valid\n\t\t\t) {\n\t\t\t\t// register collection op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// message contents don't match any known op format\n\t\t\t\tthis.objectMatchesSchema(contents, false);\n\t\t\t}\n\t\t}\n\t}\n\n\tfixOp(message: any): void {\n\t\t// handle case where contents is stringified json\n\t\tlet msgContents;\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmsgContents = JSON.parse(message.contents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tmsgContents = message.contents;\n\t\t}\n\n\t\t// handle container message types\n\t\tswitch (msgContents.type) {\n\t\t\tcase \"attach\": {\n\t\t\t\t// this one is like a regular attach op, except its contents aren't nested as deep\n\t\t\t\t// run fixAttach directly and return\n\t\t\t\tthis.fixAttach(msgContents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"component\": {\n\t\t\t\t// this one functionally nests its contents one layer deeper\n\t\t\t\t// bring up the contents object and continue as usual\n\t\t\t\tthis.fixOpContentsObject(msgContents.contents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"chunkedOp\": {\n\t\t\t\t// this is a (regular?) op split into multiple parts due to size, e.g. because it\n\t\t\t\t// has an attached image, and where the chunkedOp is within the top-level op's contents\n\t\t\t\t// (as opposed to being at the top-level). The contents of the chunks need to be\n\t\t\t\t// concatenated to form the complete stringified json object\n\t\t\t\t// Early return here to skip re-stringify because no changes are made until the last\n\t\t\t\t// chunk, and the ChunkedOpProcessor will handle everything at that point\n\t\t\t\treturn this.fixChunkedOp(message);\n\t\t\t}\n\t\t\tcase \"blobAttach\": {\n\t\t\t\t// TODO: handle this properly once blob api is used\n\t\t\t\tthis.debugMsg(\"TODO: blobAttach ops are skipped/unhandled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// A regular op\n\t\t\t\tthis.fixOpContentsObject(msgContents);\n\t\t\t}\n\t\t}\n\n\t\t// re-stringify the json if needed\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmessage.contents = JSON.stringify(msgContents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fixes a chunked operation by reassembling and sanitizing the message chunks.\n\t *\n\t * @param message - The top-level chunkedOp message or a top-level op message\n\t * with a chunkedOp inside its contents\n\t */\n\tfixChunkedOp(message: any): void {\n\t\tthis.chunkProcessor.addMessage(message);\n\t\tif (!this.chunkProcessor.hasAllMessages()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = this.chunkProcessor.getConcatenatedContents();\n\t\tthis.fixOpContentsObject(contents);\n\n\t\tthis.chunkProcessor.writeSanitizedContents(contents);\n\t\tthis.chunkProcessor.reset();\n\t}\n\n\tsanitize(): ISequencedDocumentMessage[] {\n\t\tlet seq = 0;\n\n\t\ttry {\n\t\t\tthis.messages.map((message) => {\n\t\t\t\tseq = message.sequenceNumber;\n\t\t\t\t// message types from protocol-definitions' protocol.ts\n\t\t\t\tswitch (message.type) {\n\t\t\t\t\tcase \"join\": {\n\t\t\t\t\t\tthis.fixJoin(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"propose\": {\n\t\t\t\t\t\tthis.fixPropose(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"attach\": {\n\t\t\t\t\t\tthis.fixAttach(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"op\": {\n\t\t\t\t\t\tthis.fixOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"chunkedOp\": {\n\t\t\t\t\t\tthis.fixChunkedOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"noop\":\n\t\t\t\t\tcase \"leave\":\n\t\t\t\t\tcase \"noClient\":\n\t\t\t\t\tcase \"summarize\":\n\t\t\t\t\tcase \"summaryAck\":\n\t\t\t\t\tcase \"summaryNack\":\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.debugMsg(`Unexpected op type ${message.type}`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// make sure we don't miss an incomplete chunked op at the end\n\t\t\tassert(\n\t\t\t\t!this.chunkProcessor.isPendingProcessing(),\n\t\t\t\t0x08d /* \"After sanitize, pending incomplete ops!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(`Error while processing sequenceNumber ${seq}`);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn this.messages;\n\t}\n}\n"]}
1
+ {"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../src/sanitizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAE7D,OAAO,KAAK,SAAS,MAAM,YAAY,CAAC;AAExC,OAAO,EACN,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,gCAAgC,EAChC,gCAAgC,EAChC,kCAAkC,EAClC,gBAAgB,EAChB,qBAAqB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,IAAK,QAMJ;AAND,WAAK,QAAQ;IACZ,6CAAO,CAAA;IACP,yCAAK,CAAA;IACL,uCAAI,CAAA;IACJ,qDAAW,CAAA;IACX,2CAAM,CAAA;AACP,CAAC,EANI,QAAQ,KAAR,QAAQ,QAMZ;AAED,sEAAsE;AACtE,uBAAuB;AACvB,MAAM,WAAW,GAAG;IACnB,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,GAAG,EAAE;QACd,OAAO,kBAAkB,CAAC;IAC3B,CAAC;CACD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,kBAAkB;IAoBvB,YACU,gBAAuD,EACvD,KAAc;QADd,qBAAgB,GAAhB,gBAAgB,CAAuC;QACvD,UAAK,GAAL,KAAK,CAAS;QArBxB;;;;WAIG;QACK,aAAQ,GAAG,IAAI,KAAK,EAAO,CAAC;QACpC;;;WAGG;QACK,0BAAqB,GAAG,IAAI,KAAK,EAAO,CAAC;QACzC,gBAAW,GAAG,KAAK,CAAC;QAC5B;;;;WAIG;QACK,uBAAkB,GAAG,CAAC,CAAC;IAK5B,CAAC;IAEJ,QAAQ,CAAC,GAAQ;QAChB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IAED,UAAU,CAAC,OAAY;QACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE5B,IAAI,MAAM,CAAC;QACX,IAAI,CAAC;YACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACtC,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC3B,6BAA6B;gBAC7B,gDAAgD;gBAChD,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;YAC1B,CAAC;QACF,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;QACvD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,cAAc;QACb,MAAM,eAAe,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC1F,OAAO,CACN,eAAe,CAAC,OAAO,KAAK,SAAS;YACrC,eAAe,CAAC,OAAO,KAAK,eAAe,CAAC,WAAW,CACvD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,uBAAuB;QACtB,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CACvD,CAAC,aAAqB,EAAE,YAAiB,EAAE,EAAE;YAC5C,OAAO,aAAa,GAAI,YAAY,CAAC,QAAmB,CAAC;QAC1D,CAAC,EACD,EAAE,CACF,CAAC;QAEF,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC,MAAM,CAAC;QAChD,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjB,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACH,sBAAsB,CAAC,QAAa;QACnC,gDAAgD;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAEhE,IAAI,WAAmB,CAAC;QACxB,IAAI,CAAC;YACJ,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACvC,MAAM,CACL,WAAW,CAAC,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAC7C,KAAK,CAAC,oEAAoE,CAC1E,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjB,MAAM,CAAC,CAAC;QACT,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,MAAM,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;YAE5E,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACrD,cAAc,CAAC,QAAQ,GAAG,SAAS,CAAC;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAEjC,IAAI,yBAAyB,CAAC;YAC9B,IAAI,CAAC;gBACJ,qEAAqE;gBACrE,6CAA6C;gBAC7C,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC3B,MAAM,YAAY,GAAG;wBACpB,IAAI,EAAE,WAAW;wBACjB,QAAQ,EAAE,cAAc;qBACxB,CAAC;oBACF,yBAAyB,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;gBAC1D,CAAC;qBAAM,CAAC;oBACP,yBAAyB,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;gBAC5D,CAAC;YACF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,OAAO,CAAC,QAAQ,GAAG,yBAAyB,CAAC;QAC9C,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,KAAK;QACJ,MAAM,CACL,IAAI,CAAC,WAAW,EAChB,KAAK,CAAC,uEAAuE,CAC7E,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,KAAK,EAAO,CAAC;QACjC,IAAI,CAAC,qBAAqB,GAAG,IAAI,KAAK,EAAO,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,mBAAmB;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;IACnC,CAAC;CACD;AAED,MAAM,OAAO,SAAS;IAuCrB,YACU,QAAqC,EACrC,SAAkB,EAClB,MAAe,EACf,QAAiB,KAAK;QAHtB,aAAQ,GAAR,QAAQ,CAA6B;QACrC,cAAS,GAAT,SAAS,CAAS;QAClB,WAAM,GAAN,MAAM,CAAS;QACf,UAAK,GAAL,KAAK,CAAiB;QA1CvB,cAAS,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QAC/C,6EAA6E;QAC7E,2EAA2E;QAC3E,uCAAuC;QAC9B,wBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;QACjD,+EAA+E;QAC/E,kCAAkC;QACzB,0BAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;QACnD,iFAAiF;QACjF,kCAAkC;QACzB,mBAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;QAEpD;;;;;WAKG;QACH,wBAAmB,GAAG,CAAC,MAAW,EAAE,MAAW,EAAW,EAAE;YAC3D,MAAM,MAAM,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACxF,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,QAAQ,GAAG,iBAAiB,MAAM,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,SAAS,CACrE,MAAM,EACN,SAAS,EACT,CAAC,CACD,EAAE,CAAC;gBAEJ,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBACnC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACP,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC3B,CAAC;YACF,CAAC;YACD,OAAO,MAAM,CAAC,KAAK,CAAC;QACrB,CAAC,CAAC;QAqCO,mBAAc,GAAG,MAAM,CAAC;QAExB,wBAAmB,GAAG,CAAC,KAAa,EAAU,EAAE;YACxD,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;YACxC,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACrD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAC5C,OAAO,WAAW,CAAC;QACpB,CAAC,CAAC;QArCD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACtD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC/C,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,cAAc,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;IAC/E,CAAC;IAED,QAAQ,CAAC,GAAQ;QAChB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IAED,gBAAgB,CAAC,GAAW;QAC3B,OAAO,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,IAAI,CAAC;IACvC,CAAC;IAED,aAAa,CAAC,GAAW;QACxB,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,OAAO,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACzB,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3B,CAAC;IAcD;;;OAGG;IACH,WAAW,CAAC,KAAc,EAAE,OAAiB,QAAQ,CAAC,OAAO;QAC5D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,IAAI,IAAI,KAAK,QAAQ,CAAC,WAAW,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;YACxC,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAE9E,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAC5C,OAAO,WAAW,CAAC;QACpB,CAAC;QAED,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACrE,CAAC;IAED,YAAY,CAAC,KAAY;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC/B,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACrC,CAAC;iBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACtC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,aAAa;IACZ,kDAAkD;IAClD,KAAoB,EACpB,eAA4B,IAAI,CAAC,mBAAmB;QAGpD,kCAAkC;QAClC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACpB,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;gBACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC/B,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAC5B,KAAK,EACL,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CACpE,CAAC;gBACH,CAAC;qBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBACvC,CAAC;qBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACtC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;gBACtD,CAAC;YACF,CAAC;QACF,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,KAAU,EAAE,eAA4B,IAAI,CAAC,mBAAmB;QAC1E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACd,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QAChD,CAAC;QAED,2CAA2C;QAC3C,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,CAAC,OAAY;QACnB,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE,kBAAkB,CAAC,EAAE,CAAC;YACrE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,CAAC;YACJ,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;gBACrD,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACP,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC9B,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACpD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAC1D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YACxD,CAAC;YAED,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;IAED,UAAU,CAAC,OAAY;QACtB,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EAAE,CAAC;YACxE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACP,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1C,IAAI,CAAC;oBACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;oBAC1C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;wBACpB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;wBAChC,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC;4BACf,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;wBAC7D,CAAC;wBACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;4BACpD,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;wBAC9E,CAAC;oBACF,CAAC;gBACF,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,CACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,EACtB,QAAQ,CAAC,WAAW,CACpB,CAAC;gBACH,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED,gBAAgB,CAAC,OAAc;QAC9B,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,YAAY;YACZ,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC3B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACP,mBAAmB;gBACnB,IAAI,CAAC;oBACJ,IAAI,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;wBAChD,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;wBAC9C,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;wBAChC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAC/C,CAAC;gBACF,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;YACF,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,iBAAiB,CAAC,QAAa;QAC9B,MAAM,CACL,OAAO,QAAQ,KAAK,QAAQ,EAC5B,KAAK,CAAC,yDAAyD,CAC/D,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,oBAAoB,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACP,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAClE,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;YACvE,CAAC;YAED,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;IACF,CAAC;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,OAAY;QACrB,iDAAiD;QACjD,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC1C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAC7B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACjB,OAAO;YACR,CAAC;QACF,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC;IAED,UAAU,CAAC,OAAY;QACtB,OAAO,CAAC,GAAG;YACV,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ;gBAC9B,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC;gBAC/B,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACjE,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,QAAa;QAChC,iBAAiB;QACjB,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACP,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC7E,CAAC;YAED,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC/C,MAAM,CACL,YAAY,KAAK,SAAS,EAC1B,KAAK,CAAC,yDAAyD,CAC/D,CAAC;YACF,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACzC,YAAY;gBACZ,sDAAsD;gBACtD,IAAI,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBACnD,IAAI,CAAC;wBACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;wBACnD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;wBAC7B,QAAQ,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAClD,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;gBACF,CAAC;qBAAM,CAAC;oBACP,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACnD,CAAC;YACF,CAAC;iBAAM,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC,KAAK,EAAE,CAAC;gBAC7E,SAAS;gBACT,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;oBACpF,YAAY,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAC3C,YAAY,CAAC,QAAQ,CAAC,GAAG,EACzB,QAAQ,CAAC,MAAM,CACf,CAAC;gBACH,CAAC;gBACD,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC/C,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAClD,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CACjC,CAAC;gBACH,CAAC;YACF,CAAC;iBAAM,IACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,gCAAgC,CAAC,CAAC,KAAK,EAC5E,CAAC;gBACF,sBAAsB;gBACtB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;gBACrF,CAAC;gBACD,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBAC7C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC1B,CAAC,CAAC,CAAC;YACJ,CAAC;iBAAM,IACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,gCAAgC,CAAC,CAAC,KAAK,EAC5E,CAAC;gBACF,sBAAsB;gBACtB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;gBACrF,CAAC;gBACD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YACxC,CAAC;iBAAM,IACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,kCAAkC,CAAC,CAAC,KAAK,EAC9E,CAAC;gBACF,yBAAyB;gBACzB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;oBACpF,YAAY,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAC3C,YAAY,CAAC,QAAQ,CAAC,GAAG,EACzB,QAAQ,CAAC,MAAM,CACf,CAAC;gBACH,CAAC;gBACD,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC/C,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAClD,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CACjC,CAAC;gBACH,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,mDAAmD;gBACnD,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC3C,CAAC;QACF,CAAC;IACF,CAAC;IAED,KAAK,CAAC,OAAY;QACjB,iDAAiD;QACjD,IAAI,WAAW,CAAC;QAChB,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACJ,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC5C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACjB,OAAO;YACR,CAAC;QACF,CAAC;aAAM,CAAC;YACP,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;QAChC,CAAC;QAED,iCAAiC;QACjC,QAAQ,WAAW,CAAC,IAAI,EAAE,CAAC;YAC1B,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACf,kFAAkF;gBAClF,oCAAoC;gBACpC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;gBAC5B,MAAM;YACP,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBAClB,4DAA4D;gBAC5D,qDAAqD;gBACrD,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC/C,MAAM;YACP,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBAClB,iFAAiF;gBACjF,uFAAuF;gBACvF,iFAAiF;gBACjF,4DAA4D;gBAC5D,oFAAoF;gBACpF,yEAAyE;gBACzE,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBACnB,mDAAmD;gBACnD,IAAI,CAAC,QAAQ,CAAC,4CAA4C,CAAC,CAAC;gBAC5D,OAAO;YACR,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACT,eAAe;gBACf,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;YACvC,CAAC;QACF,CAAC;QAED,kCAAkC;QAClC,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACJ,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAChD,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACjB,OAAO;YACR,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,OAAY;QACxB,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,EAAE,CAAC;YAC3C,OAAO;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,CAAC;QAC/D,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAEnC,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,QAAQ;QACP,IAAI,GAAG,GAAG,CAAC,CAAC;QAEZ,IAAI,CAAC;YACJ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC7B,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC;gBAC7B,uDAAuD;gBACvD,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;oBACtB,KAAK,MAAM,CAAC,CAAC,CAAC;wBACb,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;wBACtB,MAAM;oBACP,CAAC;oBACD,KAAK,SAAS,CAAC,CAAC,CAAC;wBAChB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;wBACzB,MAAM;oBACP,CAAC;oBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACf,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;wBACxB,MAAM;oBACP,CAAC;oBACD,KAAK,IAAI,CAAC,CAAC,CAAC;wBACX,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBACpB,MAAM;oBACP,CAAC;oBACD,KAAK,WAAW,CAAC,CAAC,CAAC;wBAClB,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;wBAC3B,MAAM;oBACP,CAAC;oBACD,KAAK,MAAM,CAAC;oBACZ,KAAK,OAAO,CAAC;oBACb,KAAK,UAAU,CAAC;oBAChB,KAAK,WAAW,CAAC;oBACjB,KAAK,YAAY,CAAC;oBAClB,KAAK,aAAa;wBACjB,MAAM;oBACP;wBACC,IAAI,CAAC,QAAQ,CAAC,sBAAsB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBACtD,CAAC;YACF,CAAC,CAAC,CAAC;YAEH,8DAA8D;YAC9D,MAAM,CACL,CAAC,IAAI,CAAC,cAAc,CAAC,mBAAmB,EAAE,EAC1C,KAAK,CAAC,+CAA+C,CACrD,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAC;YAC9D,MAAM,KAAK,CAAC;QACb,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * This tool cleans up a message.json file downloaded through fluid-fetch to remove\n * user content and user identifying information. Enough information can be retained\n * to allow loading through Fluid Preview, or everything can be scrubbed so that only\n * replay-tool can read the result. Anonymous identifying information such as client\n * IDs are always retained. Object keys are NOT scrubbed, including those that are\n * nested within values (only leaf values are scrubbed).\n *\n * Note: While user content/information is scrubbed, it should not be assumed to be\n * fully anonymized because certain meta-information (such as word lengths and\n * consistent replacement) are preserved.\n *\n * Messages must match known structures when scrubbing for Fluid Preview.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport * as Validator from \"jsonschema\";\n\nimport {\n\tattachContentsSchema,\n\tchunkedOpContentsSchema,\n\tjoinContentsSchema,\n\tjoinDataSchema,\n\topContentsMapSchema,\n\topContentsMergeTreeDeltaOpSchema,\n\topContentsMergeTreeGroupOpSchema,\n\topContentsRegisterCollectionSchema,\n\topContentsSchema,\n\tproposeContentsSchema,\n} from \"./messageSchema.js\";\n\nenum TextType {\n\tGeneric,\n\tEmail,\n\tName,\n\tFluidObject,\n\tMapKey,\n}\n\n// Workaround to jsonschema package not supporting \"false\" as a schema\n// that matches nothing\nconst falseResult = {\n\tvalid: false,\n\ttoString: () => {\n\t\treturn \"Unmatched format\";\n\t},\n};\n\n/**\n * Class that takes chunkedOp messages and can provide their concatenated\n * contents along with re-write sanitized content in-place back into the\n * messages. Assumes sanitized messages are always less than or equal in\n * size to the original message.\n */\nclass ChunkedOpProcessor {\n\t/**\n\t * Message references so we can replace their contents in-place. These can\n\t * be top-level chunkedOp messages, or top-level op messages with a chunkedOp\n\t * within the contents\n\t */\n\tprivate messages = new Array<any>();\n\t/**\n\t * The messages' parsed contents for processing. Should parallel the\n\t * messages member\n\t */\n\tprivate parsedMessageContents = new Array<any>();\n\tprivate writtenBack = false;\n\t/**\n\t * keep track of the total starting length to make sure we don't somehow end\n\t * up with more content than we started with (meaning we may not be able to\n\t * write it back)\n\t */\n\tprivate concatenatedLength = 0;\n\n\tconstructor(\n\t\treadonly validateSchemaFn: (object: any, schema: any) => boolean,\n\t\treadonly debug: boolean,\n\t) {}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\taddMessage(message: any): void {\n\t\tthis.messages.push(message);\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(message.contents);\n\t\t\tif (message.type === \"op\") {\n\t\t\t\t// nested within a regular op\n\t\t\t\t// need to go deeper to get the desired contents\n\t\t\t\tparsed = parsed.contents;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthis.debugMsg(message.contents);\n\t\t}\n\t\tthis.validateSchemaFn(parsed, chunkedOpContentsSchema);\n\t\tthis.parsedMessageContents.push(parsed);\n\t}\n\n\thasAllMessages(): boolean {\n\t\tconst lastMsgContents = this.parsedMessageContents[this.parsedMessageContents.length - 1];\n\t\treturn (\n\t\t\tlastMsgContents.chunkId !== undefined &&\n\t\t\tlastMsgContents.chunkId === lastMsgContents.totalChunks\n\t\t);\n\t}\n\n\t/**\n\t * Gets the concatenated contents of all the messages parsed as JSON.\n\t */\n\tgetConcatenatedContents(): any {\n\t\tconst contentsString = this.parsedMessageContents.reduce(\n\t\t\t(previousValue: string, currentValue: any) => {\n\t\t\t\treturn previousValue + (currentValue.contents as string);\n\t\t\t},\n\t\t\t\"\",\n\t\t);\n\n\t\tthis.concatenatedLength = contentsString.length;\n\t\ttry {\n\t\t\treturn JSON.parse(contentsString);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(contentsString);\n\t\t\tthis.debugMsg(e);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Write back sanitized contents into the messages. The contents are\n\t * stringified, split up, and written in place to the messages that\n\t * were added earlier. The number of messages is preserved.\n\t * @param contents - Sanitized contents to write back\n\t */\n\twriteSanitizedContents(contents: any): void {\n\t\t// Write back a chunk size equal to the original\n\t\tconst chunkSize = this.parsedMessageContents[0].contents.length;\n\n\t\tlet stringified: string;\n\t\ttry {\n\t\t\tstringified = JSON.stringify(contents);\n\t\t\tassert(\n\t\t\t\tstringified.length <= this.concatenatedLength,\n\t\t\t\t0x089 /* \"Stringified length of chunk contents > total starting length\" */,\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthrow e;\n\t\t}\n\n\t\tfor (let i = 0; i < this.messages.length; i++) {\n\t\t\tconst substring = stringified.substring(i * chunkSize, (i + 1) * chunkSize);\n\n\t\t\tconst parsedContents = this.parsedMessageContents[i];\n\t\t\tparsedContents.contents = substring;\n\t\t\tconst message = this.messages[i];\n\n\t\t\tlet stringifiedParsedContents;\n\t\t\ttry {\n\t\t\t\t// for nested chunkedOps, we need to recreate the extra nesting layer\n\t\t\t\t// we removed earlier when adding the message\n\t\t\t\tif (message.type === \"op\") {\n\t\t\t\t\tconst nestingLayer = {\n\t\t\t\t\t\ttype: \"chunkedOp\",\n\t\t\t\t\t\tcontents: parsedContents,\n\t\t\t\t\t};\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(nestingLayer);\n\t\t\t\t} else {\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(parsedContents);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t}\n\n\t\t\tmessage.contents = stringifiedParsedContents;\n\t\t}\n\n\t\tthis.writtenBack = true;\n\t}\n\n\treset(): void {\n\t\tassert(\n\t\t\tthis.writtenBack,\n\t\t\t0x08a /* \"resetting ChunkedOpProcessor that never wrote back its contents\" */,\n\t\t);\n\t\tthis.messages = new Array<any>();\n\t\tthis.parsedMessageContents = new Array<any>();\n\t\tthis.writtenBack = false;\n\t\tthis.concatenatedLength = 0;\n\t}\n\n\tisPendingProcessing(): boolean {\n\t\treturn this.messages.length !== 0;\n\t}\n}\n\nexport class Sanitizer {\n\treadonly validator = new Validator.Validator();\n\t// Represents the keys used to store Fluid object identifiers, snapshot info,\n\t// and other string fields that should not be replaced in contents blobs to\n\t// ensure the messages are still usable\n\treadonly defaultExcludedKeys = new Set<string>();\n\t// Represents the keys used by merge-tree ops their \"seg\" property, where other\n\t// keys represent user information\n\treadonly mergeTreeExcludedKeys = new Set<string>();\n\t// Map of user information to what it was replaced with. Used to ensure the same\n\t// data have the same replacements\n\treadonly replacementMap = new Map<string, string>();\n\n\t/**\n\t * Validate that the provided message matches the provided schema.\n\t * For a full scrub, warn and continue (scrubber should fully sanitize unexpected\n\t * fields for ops), otherwise throw an error because we cannot be sure user\n\t * information is being sufficiently sanitized.\n\t */\n\tobjectMatchesSchema = (object: any, schema: any): boolean => {\n\t\tconst result = schema === false ? falseResult : this.validator.validate(object, schema);\n\t\tif (!result.valid) {\n\t\t\tconst errorMsg = `Bad msg fmt:\\n${result.toString()}\\n${JSON.stringify(\n\t\t\t\tobject,\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`;\n\n\t\t\tif (this.fullScrub || this.noBail) {\n\t\t\t\tthis.debugMsg(errorMsg);\n\t\t\t} else {\n\t\t\t\tthrow new Error(errorMsg);\n\t\t\t}\n\t\t}\n\t\treturn result.valid;\n\t};\n\n\treadonly chunkProcessor: ChunkedOpProcessor;\n\n\tconstructor(\n\t\treadonly messages: ISequencedDocumentMessage[],\n\t\treadonly fullScrub: boolean,\n\t\treadonly noBail: boolean,\n\t\treadonly debug: boolean = false,\n\t) {\n\t\tthis.defaultExcludedKeys.add(\"type\");\n\t\tthis.defaultExcludedKeys.add(\"id\");\n\t\tthis.defaultExcludedKeys.add(\"pkg\");\n\t\tthis.defaultExcludedKeys.add(\"snapshotFormatVersion\");\n\t\tthis.defaultExcludedKeys.add(\"packageVersion\");\n\t\tthis.mergeTreeExcludedKeys.add(\"nodeType\");\n\t\tthis.chunkProcessor = new ChunkedOpProcessor(this.objectMatchesSchema, debug);\n\t}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\tisFluidObjectKey(key: string): boolean {\n\t\treturn key === \"type\" || key === \"id\";\n\t}\n\n\tgetRandomText(len: number): string {\n\t\tlet str = \"\";\n\t\twhile (str.length < len) {\n\t\t\tstr = str + Math.random().toString(36).substring(2);\n\t\t}\n\t\treturn str.substr(0, len);\n\t}\n\n\treadonly wordTokenRegex = /\\S+/g;\n\n\treadonly replaceRandomTextFn = (match: string): string => {\n\t\tif (this.replacementMap.has(match)) {\n\t\t\treturn this.replacementMap.get(match)!;\n\t\t}\n\n\t\tconst replacement = this.getRandomText(match.length);\n\t\tthis.replacementMap.set(match, replacement);\n\t\treturn replacement;\n\t};\n\n\t/**\n\t * Replace text with garbage. FluidObject types are not replaced when not under\n\t * full scrub mode. All other text is replaced consistently.\n\t */\n\treplaceText(input?: string, type: TextType = TextType.Generic): string | undefined {\n\t\tif (input === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (type === TextType.FluidObject) {\n\t\t\tif (this.replacementMap.has(input)) {\n\t\t\t\treturn this.replacementMap.get(input)!;\n\t\t\t}\n\n\t\t\tconst replacement = this.fullScrub ? this.getRandomText(input.length) : input;\n\n\t\t\tthis.replacementMap.set(input, replacement);\n\t\t\treturn replacement;\n\t\t}\n\n\t\treturn input.replace(this.wordTokenRegex, this.replaceRandomTextFn);\n\t}\n\n\treplaceArray(input: any[]): any[] {\n\t\tfor (let i = 0; i < input.length; i++) {\n\t\t\tconst value = input[i];\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tinput[i] = this.replaceText(value);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tinput[i] = this.replaceArray(value);\n\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\tinput[i] = this.replaceObject(value);\n\t\t\t}\n\t\t}\n\t\treturn input;\n\t}\n\n\t/**\n\t * (sort of) recurses down the values of a JSON object to sanitize all its strings\n\t * (only checks strings, arrays, and objects)\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceObject(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tinput: object | null,\n\t\texcludedKeys: Set<string> = this.defaultExcludedKeys,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): object | null {\n\t\t// File might contain actual nulls\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tconst keys = Object.keys(input);\n\t\tkeys.forEach((key) => {\n\t\t\tif (this.fullScrub || !excludedKeys.has(key)) {\n\t\t\t\tconst value = input[key];\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\tinput[key] = this.replaceText(\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tthis.isFluidObjectKey(key) ? TextType.FluidObject : TextType.Generic,\n\t\t\t\t\t);\n\t\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\t\tinput[key] = this.replaceArray(value);\n\t\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\t\tinput[key] = this.replaceObject(value, excludedKeys);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn input;\n\t}\n\n\t/**\n\t * Replacement on an unknown type or a parsed root level object\n\t * without a key\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceAny(input: any, excludedKeys: Set<string> = this.defaultExcludedKeys): any {\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tif (typeof input === \"string\") {\n\t\t\treturn this.replaceText(input);\n\t\t} else if (Array.isArray(input)) {\n\t\t\treturn this.replaceArray(input);\n\t\t} else if (typeof input === \"object\") {\n\t\t\treturn this.replaceObject(input, excludedKeys);\n\t\t}\n\n\t\t// Don't run replacement on any other types\n\t\treturn input;\n\t}\n\n\tfixJoin(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, joinContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t}\n\n\t\ttry {\n\t\t\tlet data = JSON.parse(message.data);\n\t\t\tif (!this.objectMatchesSchema(data, joinDataSchema)) {\n\t\t\t\tdata = this.replaceAny(data);\n\t\t\t} else {\n\t\t\t\tconst user = data.detail.user;\n\t\t\t\tuser.id = this.replaceText(user.id, TextType.Email);\n\t\t\t\tuser.email = this.replaceText(user.email, TextType.Email);\n\t\t\t\tuser.name = this.replaceText(user.name, TextType.Name);\n\t\t\t}\n\n\t\t\tmessage.data = JSON.stringify(data);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t}\n\t}\n\n\tfixPropose(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, proposeContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t} else {\n\t\t\tif (typeof message.contents === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\t\tconst pkg = data.value?.package;\n\t\t\t\t\t\tif (pkg?.name) {\n\t\t\t\t\t\t\tpkg.name = this.replaceText(pkg.name, TextType.FluidObject);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Array.isArray(pkg?.fluid?.browser?.umd?.files)) {\n\t\t\t\t\t\t\tpkg.fluid.browser.umd.files = this.replaceArray(pkg.fluid.browser.umd.files);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tmessage.contents.value = this.replaceText(\n\t\t\t\t\t\tmessage.contents.value,\n\t\t\t\t\t\tTextType.FluidObject,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfixAttachEntries(entries: any[]): void {\n\t\tentries.forEach((element) => {\n\t\t\t// Tree type\n\t\t\tif (element.value.entries) {\n\t\t\t\tthis.fixAttachEntries(element.value.entries);\n\t\t\t} else {\n\t\t\t\t// Blob (leaf) type\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof element.value.contents === \"string\") {\n\t\t\t\t\t\tlet data = JSON.parse(element.value.contents);\n\t\t\t\t\t\tdata = this.replaceObject(data);\n\t\t\t\t\t\telement.value.contents = JSON.stringify(data);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Fix the content of an attach in place\n\t * @param contents - contents object to fix\n\t */\n\tfixAttachContents(contents: any): any {\n\t\tassert(\n\t\t\ttypeof contents === \"object\",\n\t\t\t0x08b /* \"Unexpected type on contents for fix of an attach!\" */,\n\t\t);\n\t\tif (!this.objectMatchesSchema(contents, attachContentsSchema)) {\n\t\t\tthis.replaceObject(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.id = this.replaceText(contents.id, TextType.FluidObject);\n\t\t\t\tcontents.type = this.replaceText(contents.type, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tthis.fixAttachEntries(contents.snapshot.entries);\n\t\t}\n\t}\n\n\t/**\n\t * Fix an attach message at the root level or a ContainerMessageType attach. Attach\n\t * messages found within an op message should instead have their contents parsed out\n\t * and sent to fixAttachContents.\n\t * @param message - The attach message to fix\n\t * @param withinOp - If the message is from within an op message (as opposed to being\n\t * an attach message at the root level). Root level attach messages have \"snapshot\"\n\t * under a \"contents\" key, whereas attach messages from within an op message have it\n\t * under a \"content\" key\n\t */\n\tfixAttach(message: any): void {\n\t\t// Handle case where contents is stringified json\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\tmessage.contents = JSON.stringify(data);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.fixAttachContents(message.contents);\n\t\t}\n\t}\n\n\tfixDeltaOp(deltaOp: any): void {\n\t\tdeltaOp.seg =\n\t\t\ttypeof deltaOp.seg === \"string\"\n\t\t\t\t? this.replaceText(deltaOp.seg)\n\t\t\t\t: this.replaceObject(deltaOp.seg, this.mergeTreeExcludedKeys);\n\t}\n\n\t/**\n\t * Fix the contents object for an op message. Does not do extra type handling. Does\n\t * not handle special container message types like \"attach\", \"component\", and\n\t * \"chunkedOp\" (these should be handled by the caller)\n\t * @param contents - The contents object for an op message. If it was a string in the\n\t * message, it must have been converted to an object first\n\t */\n\tfixOpContentsObject(contents: any): void {\n\t\t// do replacement\n\t\tif (!this.objectMatchesSchema(contents, opContentsSchema)) {\n\t\t\tthis.replaceAny(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.address = this.replaceText(contents.address, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tconst innerContent = contents.contents.content;\n\t\t\tassert(\n\t\t\t\tinnerContent !== undefined,\n\t\t\t\t0x08c /* \"innerContent for fixing op contents is undefined!\" */,\n\t\t\t);\n\t\t\tif (contents.contents.type === \"attach\") {\n\t\t\t\t// attach op\n\t\t\t\t// handle case where inner content is stringified json\n\t\t\t\tif (typeof contents.contents.content === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst data = JSON.parse(contents.contents.content);\n\t\t\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\t\t\tcontents.contents.content = JSON.stringify(data);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.fixAttachContents(contents.contents.content);\n\t\t\t\t}\n\t\t\t} else if (this.validator.validate(innerContent, opContentsMapSchema).valid) {\n\t\t\t\t// map op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeGroupOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree group op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tinnerContent.contents.ops.forEach((deltaOp) => {\n\t\t\t\t\tthis.fixDeltaOp(deltaOp);\n\t\t\t\t});\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeDeltaOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree delta op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tthis.fixDeltaOp(innerContent.contents);\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsRegisterCollectionSchema).valid\n\t\t\t) {\n\t\t\t\t// register collection op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// message contents don't match any known op format\n\t\t\t\tthis.objectMatchesSchema(contents, false);\n\t\t\t}\n\t\t}\n\t}\n\n\tfixOp(message: any): void {\n\t\t// handle case where contents is stringified json\n\t\tlet msgContents;\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmsgContents = JSON.parse(message.contents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tmsgContents = message.contents;\n\t\t}\n\n\t\t// handle container message types\n\t\tswitch (msgContents.type) {\n\t\t\tcase \"attach\": {\n\t\t\t\t// this one is like a regular attach op, except its contents aren't nested as deep\n\t\t\t\t// run fixAttach directly and return\n\t\t\t\tthis.fixAttach(msgContents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"component\": {\n\t\t\t\t// this one functionally nests its contents one layer deeper\n\t\t\t\t// bring up the contents object and continue as usual\n\t\t\t\tthis.fixOpContentsObject(msgContents.contents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"chunkedOp\": {\n\t\t\t\t// this is a (regular?) op split into multiple parts due to size, e.g. because it\n\t\t\t\t// has an attached image, and where the chunkedOp is within the top-level op's contents\n\t\t\t\t// (as opposed to being at the top-level). The contents of the chunks need to be\n\t\t\t\t// concatenated to form the complete stringified json object\n\t\t\t\t// Early return here to skip re-stringify because no changes are made until the last\n\t\t\t\t// chunk, and the ChunkedOpProcessor will handle everything at that point\n\t\t\t\treturn this.fixChunkedOp(message);\n\t\t\t}\n\t\t\tcase \"blobAttach\": {\n\t\t\t\t// TODO: handle this properly once blob api is used\n\t\t\t\tthis.debugMsg(\"TODO: blobAttach ops are skipped/unhandled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// A regular op\n\t\t\t\tthis.fixOpContentsObject(msgContents);\n\t\t\t}\n\t\t}\n\n\t\t// re-stringify the json if needed\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmessage.contents = JSON.stringify(msgContents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fixes a chunked operation by reassembling and sanitizing the message chunks.\n\t *\n\t * @param message - The top-level chunkedOp message or a top-level op message\n\t * with a chunkedOp inside its contents\n\t */\n\tfixChunkedOp(message: any): void {\n\t\tthis.chunkProcessor.addMessage(message);\n\t\tif (!this.chunkProcessor.hasAllMessages()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = this.chunkProcessor.getConcatenatedContents();\n\t\tthis.fixOpContentsObject(contents);\n\n\t\tthis.chunkProcessor.writeSanitizedContents(contents);\n\t\tthis.chunkProcessor.reset();\n\t}\n\n\tsanitize(): ISequencedDocumentMessage[] {\n\t\tlet seq = 0;\n\n\t\ttry {\n\t\t\tthis.messages.map((message) => {\n\t\t\t\tseq = message.sequenceNumber;\n\t\t\t\t// message types from protocol-definitions' protocol.ts\n\t\t\t\tswitch (message.type) {\n\t\t\t\t\tcase \"join\": {\n\t\t\t\t\t\tthis.fixJoin(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"propose\": {\n\t\t\t\t\t\tthis.fixPropose(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"attach\": {\n\t\t\t\t\t\tthis.fixAttach(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"op\": {\n\t\t\t\t\t\tthis.fixOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"chunkedOp\": {\n\t\t\t\t\t\tthis.fixChunkedOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"noop\":\n\t\t\t\t\tcase \"leave\":\n\t\t\t\t\tcase \"noClient\":\n\t\t\t\t\tcase \"summarize\":\n\t\t\t\t\tcase \"summaryAck\":\n\t\t\t\t\tcase \"summaryNack\":\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.debugMsg(`Unexpected op type ${message.type}`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// make sure we don't miss an incomplete chunked op at the end\n\t\t\tassert(\n\t\t\t\t!this.chunkProcessor.isPendingProcessing(),\n\t\t\t\t0x08d /* \"After sanitize, pending incomplete ops!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(`Error while processing sequenceNumber ${seq}`);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn this.messages;\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/debugger",
3
- "version": "2.83.0",
3
+ "version": "2.90.0",
4
4
  "description": "Fluid Debugger - a tool to play through history of a file",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -47,10 +47,10 @@
47
47
  "main": "lib/index.js",
48
48
  "types": "lib/public.d.ts",
49
49
  "dependencies": {
50
- "@fluidframework/core-utils": "~2.83.0",
51
- "@fluidframework/driver-definitions": "~2.83.0",
52
- "@fluidframework/driver-utils": "~2.83.0",
53
- "@fluidframework/replay-driver": "~2.83.0",
50
+ "@fluidframework/core-utils": "~2.90.0",
51
+ "@fluidframework/driver-definitions": "~2.90.0",
52
+ "@fluidframework/driver-utils": "~2.90.0",
53
+ "@fluidframework/replay-driver": "~2.90.0",
54
54
  "jsonschema": "^1.2.6"
55
55
  },
56
56
  "devDependencies": {
@@ -59,15 +59,15 @@
59
59
  "@fluid-tools/build-cli": "^0.63.0",
60
60
  "@fluidframework/build-common": "^2.0.3",
61
61
  "@fluidframework/build-tools": "^0.63.0",
62
- "@fluidframework/debugger-previous": "npm:@fluidframework/debugger@2.82.0",
63
- "@fluidframework/eslint-config-fluid": "~2.83.0",
62
+ "@fluidframework/debugger-previous": "npm:@fluidframework/debugger@2.83.0",
63
+ "@fluidframework/eslint-config-fluid": "~2.90.0",
64
64
  "@microsoft/api-extractor": "7.52.11",
65
65
  "@types/node": "~20.19.30",
66
66
  "concurrently": "^9.2.1",
67
67
  "copyfiles": "^2.4.1",
68
68
  "eslint": "~9.39.1",
69
69
  "jiti": "^2.6.1",
70
- "rimraf": "^6.1.2",
70
+ "rimraf": "^6.1.3",
71
71
  "typescript": "~5.4.5"
72
72
  },
73
73
  "fluidBuild": {
@@ -321,7 +321,6 @@ export class DebugReplayController extends ReplayController implements IDebugger
321
321
  fetchedOps: ISequencedDocumentMessage[],
322
322
  ): Promise<void> {
323
323
  let _fetchedOps = fetchedOps;
324
- // eslint-disable-next-line no-constant-condition
325
324
  while (true) {
326
325
  if (_fetchedOps.length === 0) {
327
326
  this.ui.updateNextOpText([]);
package/src/sanitizer.ts CHANGED
@@ -376,7 +376,6 @@ export class Sanitizer {
376
376
  if (typeof input === "string") {
377
377
  return this.replaceText(input);
378
378
  } else if (Array.isArray(input)) {
379
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
380
379
  return this.replaceArray(input);
381
380
  } else if (typeof input === "object") {
382
381
  return this.replaceObject(input, excludedKeys);