@itwin/ecschema-rpcinterface-tests 5.14.0-dev.7 → 5.14.0-dev.9

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.
@@ -35922,6 +35922,7 @@ function isBinaryImageSource(source) {
35922
35922
  __webpack_require__.r(__webpack_exports__);
35923
35923
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
35924
35924
  /* harmony export */ getPullChangesIpcChannel: () => (/* binding */ getPullChangesIpcChannel),
35925
+ /* harmony export */ getPushChangesIpcChannel: () => (/* binding */ getPushChangesIpcChannel),
35925
35926
  /* harmony export */ ipcAppChannels: () => (/* binding */ ipcAppChannels)
35926
35927
  /* harmony export */ });
35927
35928
  /*---------------------------------------------------------------------------------------------
@@ -35932,9 +35933,16 @@ __webpack_require__.r(__webpack_exports__);
35932
35933
  * @module NativeApp
35933
35934
  */
35934
35935
  /** Get IPC channel name used for reporting progress of pulling changes into iModel.
35936
+ * @param key the key of the briefcase being pulled into.
35935
35937
  * @internal
35936
35938
  */
35937
- const getPullChangesIpcChannel = (iModelId) => `${ipcAppChannels.functions}/pullChanges/${iModelId}`;
35939
+ const getPullChangesIpcChannel = (key) => `${ipcAppChannels.functions}/pullChanges/${key}`;
35940
+ /** Get IPC channel name used for reporting the progress of the changeset download that [[IpcAppFunctions.pushChanges]] performs before
35941
+ * uploading. Kept distinct from [[getPullChangesIpcChannel]] so that a listener attached for a pull never observes a push's download.
35942
+ * @param key the key of the briefcase being pushed from.
35943
+ * @internal
35944
+ */
35945
+ const getPushChangesIpcChannel = (key) => `${ipcAppChannels.functions}/pushChanges/pullProgress/${key}`;
35938
35946
  /** @internal */
35939
35947
  const ipcAppChannels = {
35940
35948
  functions: "itwinjs-core/ipc-app",
@@ -45770,6 +45778,7 @@ __webpack_require__.r(__webpack_exports__);
45770
45778
  /* harmony export */ getMarkerText: () => (/* reexport safe */ _annotation_TextBlock__WEBPACK_IMPORTED_MODULE_3__.getMarkerText),
45771
45779
  /* harmony export */ getMaximumMajorTileFormatVersion: () => (/* reexport safe */ _tile_TileMetadata__WEBPACK_IMPORTED_MODULE_163__.getMaximumMajorTileFormatVersion),
45772
45780
  /* harmony export */ getPullChangesIpcChannel: () => (/* reexport safe */ _IpcAppProps__WEBPACK_IMPORTED_MODULE_80__.getPullChangesIpcChannel),
45781
+ /* harmony export */ getPushChangesIpcChannel: () => (/* reexport safe */ _IpcAppProps__WEBPACK_IMPORTED_MODULE_80__.getPushChangesIpcChannel),
45773
45782
  /* harmony export */ getTileObjectReference: () => (/* reexport safe */ _TileProps__WEBPACK_IMPORTED_MODULE_122__.getTileObjectReference),
45774
45783
  /* harmony export */ iModelTileTreeIdToString: () => (/* reexport safe */ _tile_TileMetadata__WEBPACK_IMPORTED_MODULE_163__.iModelTileTreeIdToString),
45775
45784
  /* harmony export */ iTwinChannel: () => (/* reexport safe */ _ipc_IpcSocket__WEBPACK_IMPORTED_MODULE_74__.iTwinChannel),
@@ -62394,6 +62403,17 @@ class SchemaCache {
62394
62403
  return entry.schemaInfo;
62395
62404
  return undefined;
62396
62405
  }
62406
+ /**
62407
+ * Gets the schema info which matches the provided SchemaKey. The schema info may be returned before the schema is fully loaded.
62408
+ * Does not await partially loaded schemas.
62409
+ * @param schemaKey The SchemaKey describing the schema to get from the cache.
62410
+ * @param matchType The match type to use when locating the schema
62411
+ */
62412
+ getSchemaInfoSync(schemaKey, matchType = _ECObjects__WEBPACK_IMPORTED_MODULE_0__.SchemaMatchType.Latest) {
62413
+ if (this.count === 0)
62414
+ return undefined;
62415
+ return this.findEntry(schemaKey, matchType)?.schemaInfo;
62416
+ }
62397
62417
  /**
62398
62418
  * Gets the schema which matches the provided SchemaKey. If the schema is partially loaded an exception will be thrown.
62399
62419
  * @param schemaKey The SchemaKey describing the schema to get from the cache.
@@ -62591,6 +62611,16 @@ class SchemaContext {
62591
62611
  getCachedSchemaSync(schemaKey, matchType = _ECObjects__WEBPACK_IMPORTED_MODULE_0__.SchemaMatchType.Latest) {
62592
62612
  return this._knownSchemas.getSchemaSync(schemaKey, matchType);
62593
62613
  }
62614
+ /**
62615
+ * Attempts to get a SchemaInfo from the context's cache.
62616
+ * Returns the info even if the schema is only partially loaded.
62617
+ * @param schemaKey The SchemaKey to identify the Schema.
62618
+ * @param matchType The SchemaMatch type to use. Default is SchemaMatchType.Latest.
62619
+ * @internal
62620
+ */
62621
+ getCachedSchemaInfoSync(schemaKey, matchType = _ECObjects__WEBPACK_IMPORTED_MODULE_0__.SchemaMatchType.Latest) {
62622
+ return this._knownSchemas.getSchemaInfoSync(schemaKey, matchType);
62623
+ }
62594
62624
  async getSchemaItem(schemaNameOrKey, itemNameOrCtor, itemConstructor) {
62595
62625
  let schemaKey;
62596
62626
  if (typeof schemaNameOrKey === "string") {
@@ -62866,11 +62896,25 @@ class SchemaReadHelper {
62866
62896
  }
62867
62897
  this._schemaInfo = schemaInfo;
62868
62898
  // Need to add this schema to the context to be able to locate schemaItems within the context.
62869
- if (addSchemaToCache && !this._context.schemaExists(schema.schemaKey)) {
62870
- await this._context.addSchemaPromise(schemaInfo, schema, this.loadSchema(schemaInfo, schema));
62899
+ if (addSchemaToCache) {
62900
+ this.checkForReadVersionConflict(schema.schemaKey);
62901
+ if (!this._context.schemaExists(schema.schemaKey))
62902
+ await this._context.addSchemaPromise(schemaInfo, schema, this.loadSchema(schemaInfo, schema));
62871
62903
  }
62872
62904
  return schemaInfo;
62873
62905
  }
62906
+ /**
62907
+ * Two read-incompatible versions of the same schema can never substitute for one another.
62908
+ * Detect it here and fail with a clear error.
62909
+ * @param schemaKey The exact key of the schema about to be loaded into the context.
62910
+ */
62911
+ checkForReadVersionConflict(schemaKey) {
62912
+ const existingInfo = this._context.getCachedSchemaInfoSync(new _SchemaKey__WEBPACK_IMPORTED_MODULE_5__.SchemaKey(schemaKey.name), _ECObjects__WEBPACK_IMPORTED_MODULE_1__.SchemaMatchType.Latest);
62913
+ if (existingInfo && existingInfo.schemaKey.readVersion !== schemaKey.readVersion) {
62914
+ throw new _Exception__WEBPACK_IMPORTED_MODULE_2__.ECSchemaError(_Exception__WEBPACK_IMPORTED_MODULE_2__.ECSchemaStatus.DuplicateSchema, `The schema '${schemaKey.toString(true)}' cannot be loaded: the read-incompatible version '${existingInfo.schemaKey.toString(true)}' is already loaded in this context. ` +
62915
+ `A schema graph cannot require two read-incompatible versions of the same schema.`);
62916
+ }
62917
+ }
62874
62918
  /**
62875
62919
  * Populates the given Schema from a serialized representation.
62876
62920
  * @param schema The Schema to populate
@@ -62892,7 +62936,7 @@ class SchemaReadHelper {
62892
62936
  throw new _Exception__WEBPACK_IMPORTED_MODULE_2__.ECSchemaError(_Exception__WEBPACK_IMPORTED_MODULE_2__.ECSchemaStatus.UnableToLoadSchema, `Could not load schema ${schema.schemaKey.toString()}`);
62893
62937
  return loadedSchema;
62894
62938
  }
62895
- const cachedSchema = await this._context.getCachedSchema(schemaInfo.schemaKey, _ECObjects__WEBPACK_IMPORTED_MODULE_1__.SchemaMatchType.Latest);
62939
+ const cachedSchema = await this._context.getCachedSchema(schemaInfo.schemaKey, _ECObjects__WEBPACK_IMPORTED_MODULE_1__.SchemaMatchType.LatestReadCompatible);
62896
62940
  if (undefined === cachedSchema)
62897
62941
  throw new _Exception__WEBPACK_IMPORTED_MODULE_2__.ECSchemaError(_Exception__WEBPACK_IMPORTED_MODULE_2__.ECSchemaStatus.UnableToLoadSchema, `Could not load schema ${schema.schemaKey.toString()}`);
62898
62942
  return cachedSchema;
@@ -62944,6 +62988,7 @@ class SchemaReadHelper {
62944
62988
  schema.fromJSONSync(this._parser.parseSchema());
62945
62989
  this._schema = schema;
62946
62990
  // Need to add this schema to the context to be able to locate schemaItems within the context.
62991
+ this.checkForReadVersionConflict(schema.schemaKey);
62947
62992
  if (!this._context.schemaExists(schema.schemaKey))
62948
62993
  this._context.addSchemaSync(schema);
62949
62994
  // Load schema references first
@@ -85504,29 +85549,38 @@ class BriefcaseConnection extends _IModelConnection__WEBPACK_IMPORTED_MODULE_5__
85504
85549
  async abandonChanges() {
85505
85550
  await _IpcApp__WEBPACK_IMPORTED_MODULE_6__.IpcApp.appFunctionIpc.abandonChanges(this.key); // eslint-disable-line @typescript-eslint/no-deprecated
85506
85551
  }
85552
+ /** Subscribes to changeset download progress events on `channel` and wires `abortSignal` to `cancel`.
85553
+ * @returns a function that removes every listener that was added.
85554
+ */
85555
+ listenForChangesetDownloadProgress(args) {
85556
+ const { channel, cancel, downloadProgressCallback, abortSignal } = args;
85557
+ const removeListeners = [];
85558
+ if (downloadProgressCallback) {
85559
+ const handleProgress = (_evt, data) => downloadProgressCallback(data);
85560
+ removeListeners.push(_IpcApp__WEBPACK_IMPORTED_MODULE_6__.IpcApp.addListener(channel, handleProgress));
85561
+ }
85562
+ if (abortSignal) {
85563
+ const abort = () => void cancel();
85564
+ abortSignal.addEventListener("abort", abort);
85565
+ removeListeners.push(() => abortSignal.removeEventListener("abort", abort));
85566
+ }
85567
+ return () => removeListeners.forEach((remove) => remove());
85568
+ }
85507
85569
  /** Pull (and potentially merge if there are local changes) up to a specified changeset from iModelHub into this briefcase
85508
85570
  * @param toIndex The changeset index to pull changes to. If `undefined`, pull all changes.
85509
85571
  * @param options Options for pulling changes.
85510
85572
  * @see [[BriefcaseTxns.onChangesPulled]] for the event dispatched after changes are pulled.
85511
85573
  */
85512
85574
  async pullChanges(toIndex, options) {
85513
- const removeListeners = [];
85514
- const shouldReportProgress = !!options?.downloadProgressCallback;
85515
- if (shouldReportProgress) {
85516
- const handleProgress = (_evt, data) => {
85517
- options?.downloadProgressCallback?.(data);
85518
- };
85519
- const removeProgressListener = _IpcApp__WEBPACK_IMPORTED_MODULE_6__.IpcApp.addListener((0,_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.getPullChangesIpcChannel)(this.iModelId), handleProgress);
85520
- removeListeners.push(removeProgressListener);
85521
- }
85522
- if (options?.abortSignal) {
85523
- const abort = () => void _IpcApp__WEBPACK_IMPORTED_MODULE_6__.IpcApp.appFunctionIpc.cancelPullChangesRequest(this.key);
85524
- options?.abortSignal.addEventListener("abort", abort);
85525
- removeListeners.push(() => options?.abortSignal?.removeEventListener("abort", abort));
85526
- }
85527
85575
  this.requireTimeline();
85576
+ const removeListeners = this.listenForChangesetDownloadProgress({
85577
+ channel: (0,_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.getPullChangesIpcChannel)(this.key),
85578
+ cancel: async () => _IpcApp__WEBPACK_IMPORTED_MODULE_6__.IpcApp.appFunctionIpc.cancelPullChangesRequest(this.key),
85579
+ downloadProgressCallback: options?.downloadProgressCallback,
85580
+ abortSignal: options?.abortSignal,
85581
+ });
85528
85582
  const ipcAppOptions = {
85529
- reportProgress: shouldReportProgress,
85583
+ reportProgress: !!options?.downloadProgressCallback,
85530
85584
  progressInterval: options?.progressInterval,
85531
85585
  enableCancellation: !!options?.abortSignal,
85532
85586
  };
@@ -85534,18 +85588,29 @@ class BriefcaseConnection extends _IModelConnection__WEBPACK_IMPORTED_MODULE_5__
85534
85588
  this.changeset = await _IpcApp__WEBPACK_IMPORTED_MODULE_6__.IpcApp.appFunctionIpc.pullChanges(this.key, toIndex, ipcAppOptions);
85535
85589
  }
85536
85590
  finally {
85537
- removeListeners.forEach((remove) => remove());
85591
+ removeListeners();
85538
85592
  }
85539
85593
  await this.invalidateSchemaViewIfChanged();
85540
85594
  }
85541
- /** Create a changeset from local Txns and push to iModelHub. On success, clear Txn table.
85542
- * @param description The description for the changeset
85543
- * @returns the changesetId of the pushed changes
85544
- * @see [[BriefcaseTxns.onChangesPushed]] for the event dispatched after changes are pushed.
85545
- */
85546
- async pushChanges(description) {
85595
+ async pushChanges(description, options) {
85547
85596
  this.requireTimeline();
85548
- return this.changeset = await _IpcApp__WEBPACK_IMPORTED_MODULE_6__.IpcApp.appFunctionIpc.pushChanges(this.key, description);
85597
+ const removeListeners = this.listenForChangesetDownloadProgress({
85598
+ channel: (0,_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.getPushChangesIpcChannel)(this.key),
85599
+ cancel: async () => _IpcApp__WEBPACK_IMPORTED_MODULE_6__.IpcApp.appFunctionIpc.cancelPushChangesRequest(this.key),
85600
+ downloadProgressCallback: options?.downloadProgressCallback,
85601
+ abortSignal: options?.abortSignal,
85602
+ });
85603
+ const ipcAppOptions = {
85604
+ reportDownloadProgress: !!options?.downloadProgressCallback,
85605
+ downloadProgressInterval: options?.downloadProgressInterval,
85606
+ enableCancellation: !!options?.abortSignal,
85607
+ };
85608
+ try {
85609
+ return this.changeset = await _IpcApp__WEBPACK_IMPORTED_MODULE_6__.IpcApp.appFunctionIpc.pushChanges(this.key, description, ipcAppOptions);
85610
+ }
85611
+ finally {
85612
+ removeListeners();
85613
+ }
85549
85614
  }
85550
85615
  /** The current graphical editing scope, if one is in progress.
85551
85616
  * @see [[enterEditingScope]] to begin graphical editing.
@@ -195147,15 +195212,18 @@ __webpack_require__.r(__webpack_exports__);
195147
195212
 
195148
195213
 
195149
195214
  /**
195150
- * fitPoints and end condition data for [[AkimaCurve3d]]
195215
+ * Data for an [[AkimaCurve3d]]
195151
195216
  * * This is a "typed object" version of the serializer-friendly [[AkimaCurve3dProps]]
195152
- * * Typical use cases rarely require all parameters, so the constructor does not itemize them as parameters.
195153
195217
  * @public
195154
195218
  */
195155
195219
  class AkimaCurve3dOptions {
195220
+ /**
195221
+ * Points that the curve must pass through.
195222
+ * * Traditional DGN-style Akima curves interpret the first two and last two fit points as end tangent conditions,
195223
+ * however as the current implementation uses another interpolation algorithm, there is no such interpretation here.
195224
+ */
195156
195225
  fitPoints;
195157
195226
  /**
195158
- *
195159
195227
  * @param fitPoints points to CAPTURE
195160
195228
  * @param knots array to CAPTURE
195161
195229
  */
@@ -195166,7 +195234,7 @@ class AkimaCurve3dOptions {
195166
195234
  * First and last 2 points are "beyond the end" for control of end slope.
195167
195235
  fitPoints: Point3d[];
195168
195236
 
195169
- /** Clone with strongly typed members reduced to simple json. */
195237
+ /** Clone with strongly typed members reduced to simple json. */
195170
195238
  cloneAsAkimaCurve3dProps() {
195171
195239
  const props = {
195172
195240
  fitPoints: _geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_2__.Point3dArray.cloneDeepJSONNumberArrays(this.fitPoints),
@@ -195183,24 +195251,25 @@ class AkimaCurve3dOptions {
195183
195251
  const result = new AkimaCurve3dOptions(_geometry3d_PointHelpers__WEBPACK_IMPORTED_MODULE_2__.Point3dArray.clonePoint3dArray(source.fitPoints));
195184
195252
  return result;
195185
195253
  }
195254
+ /** Whether the two options are equivalent or both undefined. */
195186
195255
  static areAlmostEqual(dataA, dataB) {
195187
195256
  if (dataA === undefined && dataB === undefined)
195188
195257
  return true;
195189
- if (dataA !== undefined && dataB !== undefined) {
195258
+ if (dataA !== undefined && dataB !== undefined)
195190
195259
  return _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.almostEqualArrays(dataA.fitPoints, dataB.fitPoints, (a, b) => a.isAlmostEqual(b));
195191
- }
195192
195260
  return false;
195193
195261
  }
195194
195262
  }
195195
195263
  /**
195196
- * Interpolating curve.
195264
+ * Interpolating curve using the Akima formulation.
195197
195265
  * * Derive from [[ProxyCurve]]
195198
195266
  * * Use a [[BSplineCurve3d]] as the proxy
195199
- * *
195267
+ * * Currently the Akima formulation is replaced with a Greville interpolation.
195200
195268
  * @public
195201
195269
  */
195202
195270
  class AkimaCurve3d extends _curve_ProxyCurve__WEBPACK_IMPORTED_MODULE_0__.ProxyCurve {
195203
- curvePrimitiveType = "interpolationCurve";
195271
+ /** String name for schema properties. */
195272
+ curvePrimitiveType = "akimaCurve";
195204
195273
  _options;
195205
195274
  /** CAPTURE properties and proxy curve. */
195206
195275
  constructor(properties, proxyCurve) {
@@ -195215,9 +195284,9 @@ class AkimaCurve3d extends _curve_ProxyCurve__WEBPACK_IMPORTED_MODULE_0__.ProxyC
195215
195284
  return result;
195216
195285
  }
195217
195286
  /**
195218
- * Create an [[AkimaCurve3d]] based on points, knots, and other properties in the [[AkimaCurve3dProps]] or [[AkimaCurve3dOptions]].
195287
+ * Create an [[AkimaCurve3d]] based on an [[AkimaCurve3dProps]] or [[AkimaCurve3dOptions]].
195219
195288
  * * This saves a COPY OF the options or props.
195220
- * * Use createCapture () if the options or props can be used without copy
195289
+ * * Use createCapture() if the options or props can be used without copy
195221
195290
  */
195222
195291
  static create(options) {
195223
195292
  let optionsCopy;
@@ -195270,11 +195339,9 @@ class AkimaCurve3d extends _curve_ProxyCurve__WEBPACK_IMPORTED_MODULE_0__.ProxyC
195270
195339
  * Transform this [[AkimaCurve3d]] and its defining data in place
195271
195340
  */
195272
195341
  tryTransformInPlace(transform) {
195273
- const proxyOk = this._proxyCurve.tryTransformInPlace(transform);
195274
- if (proxyOk) {
195275
- transform.multiplyPoint3dArray(this._options.fitPoints);
195276
- }
195277
- return proxyOk;
195342
+ this._proxyCurve.tryTransformInPlace(transform);
195343
+ transform.multiplyPoint3dArray(this._options.fitPoints);
195344
+ return true; // we know this succeeds
195278
195345
  }
195279
195346
  /**
195280
195347
  * Find intervals of this CurvePrimitive that are interior to a clipper.
@@ -195296,6 +195363,7 @@ class AkimaCurve3d extends _curve_ProxyCurve__WEBPACK_IMPORTED_MODULE_0__.ProxyC
195296
195363
  }
195297
195364
  /** Test if `other` is also an [[AkimaCurve3d]] */
195298
195365
  isSameGeometryClass(other) { return other instanceof AkimaCurve3d; }
195366
+ /** Test if this [[AkimaCurve3d]] is almost equal to another GeometryQuery object. */
195299
195367
  isAlmostEqual(other) {
195300
195368
  if (other instanceof AkimaCurve3d) {
195301
195369
  return AkimaCurve3dOptions.areAlmostEqual(this._options, other._options);
@@ -196200,10 +196268,11 @@ class BSplineCurve3d extends BSplineCurve3dBase {
196200
196268
  }
196201
196269
  /**
196202
196270
  * Create a B-spline curve from an Akima curve.
196203
- * @param options collection of points and end conditions.
196271
+ * * The Akima formulation of the curve is currently replaced by a Greville interpolation.
196272
+ * @param options data for construction
196204
196273
  */
196205
196274
  static createFromAkimaCurve3dOptions(options) {
196206
- return _BSplineCurveOps__WEBPACK_IMPORTED_MODULE_19__.BSplineCurveOps.createThroughPoints(options.fitPoints, 4); // temporary
196275
+ return _BSplineCurveOps__WEBPACK_IMPORTED_MODULE_19__.BSplineCurveOps.createThroughPoints(options.fitPoints, 4);
196207
196276
  }
196208
196277
  /**
196209
196278
  * Create a B-spline curve with given knots.
@@ -200240,8 +200309,7 @@ class InterpolationCurve3dOptions {
200240
200309
  result._endTangent = source.endTangent ? _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_3__.Vector3d.fromJSON(source.endTangent) : undefined;
200241
200310
  return result;
200242
200311
  }
200243
- // ugh.
200244
- // vector equality test with awkward rule that 000 matches undefined.
200312
+ /** Vector equality test, with the additional rule that the zero vector matches undefined. */
200245
200313
  static areAlmostEqualAllow000AsUndefined(a, b) {
200246
200314
  if (a !== undefined && a.maxAbs() === 0)
200247
200315
  a = undefined;
@@ -200251,6 +200319,7 @@ class InterpolationCurve3dOptions {
200251
200319
  return a.isAlmostEqual(b);
200252
200320
  return a === undefined && b === undefined;
200253
200321
  }
200322
+ /** Whether the two options are equivalent or both undefined. */
200254
200323
  static areAlmostEqual(dataA, dataB) {
200255
200324
  if (dataA === undefined && dataB === undefined)
200256
200325
  return true;
@@ -200299,6 +200368,7 @@ class InterpolationCurve3dOptions {
200299
200368
  * @public
200300
200369
  */
200301
200370
  class InterpolationCurve3d extends _curve_ProxyCurve__WEBPACK_IMPORTED_MODULE_1__.ProxyCurve {
200371
+ /** String name for schema properties. */
200302
200372
  curvePrimitiveType = "interpolationCurve";
200303
200373
  _options;
200304
200374
  /** CAPTURE properties and proxy curve. */
@@ -200371,15 +200441,13 @@ class InterpolationCurve3d extends _curve_ProxyCurve__WEBPACK_IMPORTED_MODULE_1_
200371
200441
  * Transform this [[InterpolationCurve3d]] and its defining data in place
200372
200442
  */
200373
200443
  tryTransformInPlace(transform) {
200374
- const proxyOk = this._proxyCurve.tryTransformInPlace(transform);
200375
- if (proxyOk) {
200376
- transform.multiplyPoint3dArrayInPlace(this._options.fitPoints);
200377
- if (this._options.startTangent)
200378
- transform.multiplyVectorInPlace(this._options.startTangent);
200379
- if (this._options.endTangent)
200380
- transform.multiplyVectorInPlace(this._options.endTangent);
200381
- }
200382
- return proxyOk;
200444
+ this._proxyCurve.tryTransformInPlace(transform);
200445
+ transform.multiplyPoint3dArrayInPlace(this._options.fitPoints);
200446
+ if (this._options.startTangent)
200447
+ transform.multiplyVectorInPlace(this._options.startTangent);
200448
+ if (this._options.endTangent)
200449
+ transform.multiplyVectorInPlace(this._options.endTangent);
200450
+ return true; // we know this succeeds
200383
200451
  }
200384
200452
  /**
200385
200453
  * Find intervals of this CurvePrimitive that are interior to a clipper.
@@ -200399,6 +200467,7 @@ class InterpolationCurve3d extends _curve_ProxyCurve__WEBPACK_IMPORTED_MODULE_1_
200399
200467
  cloneTransformed(transform) {
200400
200468
  return super.cloneTransformed(transform);
200401
200469
  }
200470
+ /** Test if this [[InterpolationCurve3d]] is almost equal to another GeometryQuery object. */
200402
200471
  isAlmostEqual(other) {
200403
200472
  if (other instanceof InterpolationCurve3d) {
200404
200473
  return InterpolationCurve3dOptions.areAlmostEqual(this._options, other._options);
@@ -203847,8 +203916,6 @@ class ClipUtilities {
203847
203916
  if (!worldToLocal)
203848
203917
  return result;
203849
203918
  const localRegion = region.cloneTransformed(worldToLocal); // parallel to xy-plane so we can ignore z
203850
- if (!localRegion)
203851
- return result;
203852
203919
  // We can only clip convex polygons with our clipper machinery, but the input region doesn't have to be
203853
203920
  // convex or even a polygon. We get around this limitation by using a Boolean operation, which admits
203854
203921
  // *any* planar regions, albeit in local coordinates. First, we clip a rectangle that covers the input region
@@ -209484,10 +209551,7 @@ class CurveChainWithDistanceIndex extends _curve_CurvePrimitive__WEBPACK_IMPORTE
209484
209551
  * @param options how finely to stroke the path to create the distance index
209485
209552
  */
209486
209553
  cloneTransformed(transform, options) {
209487
- const c = this._path.clone();
209488
- if (c.tryTransformInPlace(transform))
209489
- return CurveChainWithDistanceIndex.createCapture(c, options);
209490
- return undefined;
209554
+ return CurveChainWithDistanceIndex.createCapture(this._path.cloneTransformed(transform), options);
209491
209555
  }
209492
209556
  /**
209493
209557
  * Reference to the contained path.
@@ -209508,8 +209572,7 @@ class CurveChainWithDistanceIndex extends _curve_CurvePrimitive__WEBPACK_IMPORTE
209508
209572
  * @param options how finely to stroke the path to create the distance index
209509
209573
  */
209510
209574
  clone(options) {
209511
- const c = this._path.clone();
209512
- return CurveChainWithDistanceIndex.createCapture(c, options);
209575
+ return CurveChainWithDistanceIndex.createCapture(this._path.clone(), options);
209513
209576
  }
209514
209577
  /**
209515
209578
  * Return a portion of this curve with its own distance index.
@@ -209687,15 +209750,10 @@ class CurveChainWithDistanceIndex extends _curve_CurvePrimitive__WEBPACK_IMPORTE
209687
209750
  * @return cloned flattened CurveChain, or reference to the input chain if no nesting
209688
209751
  */
209689
209752
  static flattenNestedChains(chain) {
209690
- if (-1 === chain.children.findIndex((child) => { return child instanceof CurveChainWithDistanceIndex; }))
209753
+ if (-1 === chain.children.findIndex((c) => c instanceof CurveChainWithDistanceIndex))
209691
209754
  return chain;
209692
209755
  const flatChain = chain.clone();
209693
- const flatChildren = flatChain.children.flatMap((child) => {
209694
- if (child instanceof CurveChainWithDistanceIndex)
209695
- return child.path.children;
209696
- else
209697
- return [child];
209698
- });
209756
+ const flatChildren = flatChain.children.flatMap((c) => c instanceof CurveChainWithDistanceIndex ? c.path.children : c);
209699
209757
  flatChain.children.splice(0, Infinity, ...flatChildren);
209700
209758
  return flatChain;
209701
209759
  }
@@ -209876,18 +209934,13 @@ class CurveChainWithDistanceIndex extends _curve_CurvePrimitive__WEBPACK_IMPORTE
209876
209934
  return result;
209877
209935
  }
209878
209936
  /**
209879
- * Attempt to transform in place.
209880
- * * Warning: If any child transform fails, `this` object becomes invalid but that should never happen.
209881
- * @param transform the transform to be applied.
209882
- * @returns true if all of child transforms succeed and false otherwise.
209937
+ * Transform the chain in place.
209938
+ * * Does NOT recompute the distance index.
209939
+ * * For best results, use a rigid transform. Otherwise, it is better to call [[cloneTransformed]] so that the
209940
+ * distance index is recomputed.
209883
209941
  */
209884
209942
  tryTransformInPlace(transform) {
209885
- let numFail = 0;
209886
- for (const c of this._path.children) {
209887
- if (!c.tryTransformInPlace(transform))
209888
- numFail++;
209889
- }
209890
- return numFail === 0;
209943
+ return this._path.tryTransformInPlace(transform);
209891
209944
  }
209892
209945
  /** Reverse the curve's data so that its fractional stroking moves in the opposite direction. */
209893
209946
  reverseInPlace() {
@@ -210190,8 +210243,6 @@ __webpack_require__.r(__webpack_exports__);
210190
210243
  class CurveCollection extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_6__.GeometryQuery {
210191
210244
  /** String name for schema properties */
210192
210245
  geometryCategory = "curveCollection";
210193
- /** Flag for inner loop status. Only used by `Loop`. */
210194
- isInner = false;
210195
210246
  /** Return the sum of the lengths of all contained curves. */
210196
210247
  sumLengths() {
210197
210248
  return _internalContexts_SumLengthsContext__WEBPACK_IMPORTED_MODULE_13__.SumLengthsContext.sumLengths(this);
@@ -210599,6 +210650,18 @@ class CurveChain extends CurveCollection {
210599
210650
  }
210600
210651
  return undefined;
210601
210652
  }
210653
+ /** Return a deep copy. */
210654
+ clone() {
210655
+ return super.clone();
210656
+ }
210657
+ /** Create a deep copy of transformed curves. */
210658
+ cloneTransformed(transform) {
210659
+ return super.cloneTransformed(transform);
210660
+ }
210661
+ /** Create a deep copy with all linestrings broken down into multiple LineSegment3d. */
210662
+ cloneWithExpandedLineStrings() {
210663
+ return super.cloneWithExpandedLineStrings();
210664
+ }
210602
210665
  /**
210603
210666
  * Add a child curve.
210604
210667
  * @param child curve to add to the chain. The curve is captured by this instance.
@@ -210729,6 +210792,18 @@ class BagOfCurves extends CurveCollection {
210729
210792
  cloneEmptyPeer() {
210730
210793
  return new BagOfCurves();
210731
210794
  }
210795
+ /** Return a deep copy. */
210796
+ clone() {
210797
+ return super.clone();
210798
+ }
210799
+ /** Create a deep copy of transformed curves. */
210800
+ cloneTransformed(transform) {
210801
+ return super.cloneTransformed(transform);
210802
+ }
210803
+ /** Create a deep copy with all linestrings broken down into multiple LineSegment3d. */
210804
+ cloneWithExpandedLineStrings() {
210805
+ return super.cloneWithExpandedLineStrings();
210806
+ }
210732
210807
  /** Add a child */
210733
210808
  tryAddChild(child) {
210734
210809
  if (child)
@@ -211720,11 +211795,10 @@ class CurveFactory {
211720
211795
  // The alignment condition is equivalent to positive projected curve area computed wrt to the plane normal.
211721
211796
  const toLocal = _geometry3d_Matrix3d__WEBPACK_IMPORTED_MODULE_4__.Matrix3d.createRigidHeadsUp(planeNormal).transpose();
211722
211797
  const projection = closedCurve.cloneTransformed(_geometry3d_Transform__WEBPACK_IMPORTED_MODULE_11__.Transform.createOriginAndMatrix(undefined, toLocal));
211723
- if (projection) { // now we can ignore z-coords
211724
- const areaXY = _RegionOps__WEBPACK_IMPORTED_MODULE_25__.RegionOps.computeXYArea(projection);
211725
- if (areaXY && areaXY < 0)
211726
- curve.reverseInPlace();
211727
- }
211798
+ // now we can ignore z-coords
211799
+ const areaXY = _RegionOps__WEBPACK_IMPORTED_MODULE_25__.RegionOps.computeXYArea(projection);
211800
+ if (areaXY && areaXY < 0)
211801
+ curve.reverseInPlace();
211728
211802
  }
211729
211803
  }
211730
211804
  /**
@@ -212883,9 +212957,9 @@ __webpack_require__.r(__webpack_exports__);
212883
212957
  /* harmony import */ var _geometry3d_Transform__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../geometry3d/Transform */ "../../core/geometry/lib/esm/geometry3d/Transform.js");
212884
212958
  /* harmony import */ var _CurveLocationDetail__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./CurveLocationDetail */ "../../core/geometry/lib/esm/curve/CurveLocationDetail.js");
212885
212959
  /* harmony import */ var _GeometryQuery__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./GeometryQuery */ "../../core/geometry/lib/esm/curve/GeometryQuery.js");
212886
- /* harmony import */ var _internalContexts_AppendPlaneIntersectionStrokeHandler__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./internalContexts/AppendPlaneIntersectionStrokeHandler */ "../../core/geometry/lib/esm/curve/internalContexts/AppendPlaneIntersectionStrokeHandler.js");
212887
- /* harmony import */ var _internalContexts_ClosestPointStrokeHandler__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./internalContexts/ClosestPointStrokeHandler */ "../../core/geometry/lib/esm/curve/internalContexts/ClosestPointStrokeHandler.js");
212888
- /* harmony import */ var _internalContexts_AnnounceTangentStrokeHandler__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./internalContexts/AnnounceTangentStrokeHandler */ "../../core/geometry/lib/esm/curve/internalContexts/AnnounceTangentStrokeHandler.js");
212960
+ /* harmony import */ var _internalContexts_AnnounceTangentStrokeHandler__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./internalContexts/AnnounceTangentStrokeHandler */ "../../core/geometry/lib/esm/curve/internalContexts/AnnounceTangentStrokeHandler.js");
212961
+ /* harmony import */ var _internalContexts_AppendPlaneIntersectionStrokeHandler__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./internalContexts/AppendPlaneIntersectionStrokeHandler */ "../../core/geometry/lib/esm/curve/internalContexts/AppendPlaneIntersectionStrokeHandler.js");
212962
+ /* harmony import */ var _internalContexts_ClosestPointStrokeHandler__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./internalContexts/ClosestPointStrokeHandler */ "../../core/geometry/lib/esm/curve/internalContexts/ClosestPointStrokeHandler.js");
212889
212963
  /* harmony import */ var _internalContexts_CurveLengthContext__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./internalContexts/CurveLengthContext */ "../../core/geometry/lib/esm/curve/internalContexts/CurveLengthContext.js");
212890
212964
  /*---------------------------------------------------------------------------------------------
212891
212965
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
@@ -213304,7 +213378,7 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_9__.Geometr
213304
213378
  * @returns details `d` of the closest point. The distance from spacePoint to the closest point is stored in `d.a`.
213305
213379
  */
213306
213380
  closestPoint(spacePoint, extend = false, result) {
213307
- const strokeHandler = new _internalContexts_ClosestPointStrokeHandler__WEBPACK_IMPORTED_MODULE_11__.ClosestPointStrokeHandler(spacePoint, extend, result);
213381
+ const strokeHandler = new _internalContexts_ClosestPointStrokeHandler__WEBPACK_IMPORTED_MODULE_12__.ClosestPointStrokeHandler(spacePoint, extend, result);
213308
213382
  this.emitStrokableParts(strokeHandler);
213309
213383
  return strokeHandler.claimResult();
213310
213384
  }
@@ -213320,7 +213394,7 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_9__.Geometr
213320
213394
  * @returns details `d` of the closest point. The distance from spacePoint to the closest point is stored in `d.a`.
213321
213395
  */
213322
213396
  closestPointXY(spacePoint, extend = false, result) {
213323
- const strokeHandler = new _internalContexts_ClosestPointStrokeHandler__WEBPACK_IMPORTED_MODULE_11__.ClosestPointStrokeHandler(spacePoint, extend, result, true);
213397
+ const strokeHandler = new _internalContexts_ClosestPointStrokeHandler__WEBPACK_IMPORTED_MODULE_12__.ClosestPointStrokeHandler(spacePoint, extend, result, true);
213324
213398
  this.emitStrokableParts(strokeHandler);
213325
213399
  return strokeHandler.claimResult();
213326
213400
  }
@@ -213336,7 +213410,7 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_9__.Geometr
213336
213410
  * @param options (optional) options for computing tangents. See [[TangentOptions]] for defaults.
213337
213411
  */
213338
213412
  emitTangents(spacePoint, announceTangent, options) {
213339
- const strokeHandler = new _internalContexts_AnnounceTangentStrokeHandler__WEBPACK_IMPORTED_MODULE_12__.AnnounceTangentStrokeHandler(spacePoint, announceTangent, options);
213413
+ const strokeHandler = new _internalContexts_AnnounceTangentStrokeHandler__WEBPACK_IMPORTED_MODULE_10__.AnnounceTangentStrokeHandler(spacePoint, announceTangent, options);
213340
213414
  this.emitStrokableParts(strokeHandler, options?.strokeOptions);
213341
213415
  }
213342
213416
  /**
@@ -213431,7 +213505,7 @@ class CurvePrimitive extends _GeometryQuery__WEBPACK_IMPORTED_MODULE_9__.Geometr
213431
213505
  * @returns Return the number of CurveLocationDetail's added to the result array.
213432
213506
  */
213433
213507
  appendPlaneIntersectionPoints(plane, result) {
213434
- const strokeHandler = new _internalContexts_AppendPlaneIntersectionStrokeHandler__WEBPACK_IMPORTED_MODULE_10__.AppendPlaneIntersectionStrokeHandler(plane, result);
213508
+ const strokeHandler = new _internalContexts_AppendPlaneIntersectionStrokeHandler__WEBPACK_IMPORTED_MODULE_11__.AppendPlaneIntersectionStrokeHandler(plane, result);
213435
213509
  const n0 = result.length;
213436
213510
  this.emitStrokableParts(strokeHandler);
213437
213511
  return result.length - n0;
@@ -213629,6 +213703,13 @@ __webpack_require__.r(__webpack_exports__);
213629
213703
  /* harmony export */ RecursiveCurveProcessorWithStack: () => (/* binding */ RecursiveCurveProcessorWithStack)
213630
213704
  /* harmony export */ });
213631
213705
  /* harmony import */ var _CurvePrimitive__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./CurvePrimitive */ "../../core/geometry/lib/esm/curve/CurvePrimitive.js");
213706
+ /*---------------------------------------------------------------------------------------------
213707
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
213708
+ * See LICENSE.md in the project root for license terms and full copyright notice.
213709
+ *--------------------------------------------------------------------------------------------*/
213710
+ /** @packageDocumentation
213711
+ * @module Curve
213712
+ */
213632
213713
 
213633
213714
  /** base class for detailed traversal of curve artifacts.
213634
213715
  * * This recurses to children in the quickest way (no records of path)
@@ -213664,7 +213745,10 @@ class RecursiveCurveProcessor {
213664
213745
  announceUnionRegion(data, _indexInParent = -1) {
213665
213746
  let i = 0;
213666
213747
  for (const child of data.children) {
213667
- child.announceToCurveProcessor(this, i++);
213748
+ if (child.curveCollectionType === "loop")
213749
+ this.announceLoop(child, i++);
213750
+ else
213751
+ this.announceParityRegion(child, i++);
213668
213752
  }
213669
213753
  }
213670
213754
  /** announce a bag of curves.
@@ -213726,9 +213810,15 @@ class RecursiveCurveProcessorWithStack extends RecursiveCurveProcessor {
213726
213810
  this.leave();
213727
213811
  }
213728
213812
  /** announce beginning or end of a parity region */
213729
- announceUnionRegion(data, indexInParent = -1) {
213813
+ announceUnionRegion(data, _indexInParent = -1) {
213730
213814
  this.enter(data);
213731
- super.announceUnionRegion(data, indexInParent);
213815
+ let i = 0;
213816
+ for (const child of data.children) {
213817
+ if (child.curveCollectionType === "loop")
213818
+ this.announceLoop(child, i++);
213819
+ else
213820
+ this.announceParityRegion(child, i++);
213821
+ }
213732
213822
  this.leave();
213733
213823
  }
213734
213824
  /**
@@ -214334,7 +214424,7 @@ class LineSegment3d extends _CurvePrimitive__WEBPACK_IMPORTED_MODULE_11__.CurveP
214334
214424
  this._point0 = this._point1;
214335
214425
  this._point1 = a;
214336
214426
  }
214337
- /** Transform the two endpoints of this LinSegment. */
214427
+ /** Transform the two endpoints of this line segment. */
214338
214428
  tryTransformInPlace(transform) {
214339
214429
  this._point0 = transform.multiplyPoint3d(this._point0, this._point0);
214340
214430
  this._point1 = transform.multiplyPoint3d(this._point1, this._point1);
@@ -216149,12 +216239,19 @@ __webpack_require__.r(__webpack_exports__);
216149
216239
  class Loop extends _CurveCollection__WEBPACK_IMPORTED_MODULE_1__.CurveChain {
216150
216240
  /** String name for schema properties */
216151
216241
  curveCollectionType = "loop";
216152
- /** Tag value that can be set to true for user code to mark inner and outer loops. */
216242
+ /**
216243
+ * Flag for inner loop status (default value is `false`).
216244
+ * * Typical usage is to set to `true` on hole `Loop`s in a `ParityRegion` to distinguish them from the outer `Loop`.
216245
+ * * This property is only set by the user, and does not affect region processing.
216246
+ * * This property is propagated through [[clone]] and JSON/FlatBuffer de/serialization.
216247
+ * * For best de/serialization results, avoid setting to `false` on multiple `Loop`s of a `ParityRegion`.
216248
+ */
216153
216249
  isInner = false;
216154
216250
  /** Test if `other` is a `Loop` */
216155
216251
  isSameGeometryClass(other) {
216156
216252
  return other instanceof Loop;
216157
216253
  }
216254
+ /** Construct an empty loop. */
216158
216255
  constructor() {
216159
216256
  super();
216160
216257
  }
@@ -216224,10 +216321,28 @@ class Loop extends _CurveCollection__WEBPACK_IMPORTED_MODULE_1__.CurveChain {
216224
216321
  emptyClone.isInner = this.isInner;
216225
216322
  return emptyClone;
216226
216323
  }
216324
+ /** Return a deep copy. */
216325
+ clone() {
216326
+ return super.clone();
216327
+ }
216328
+ /** Create a deep copy of transformed curves. */
216329
+ cloneTransformed(transform) {
216330
+ return super.cloneTransformed(transform);
216331
+ }
216332
+ /** Create a deep copy with all linestrings broken down into multiple LineSegment3d. */
216333
+ cloneWithExpandedLineStrings() {
216334
+ return super.cloneWithExpandedLineStrings();
216335
+ }
216227
216336
  /** Second step of double dispatch: call `handler.handleLoop(this)` */
216228
216337
  dispatchToGeometryHandler(handler) {
216229
216338
  return handler.handleLoop(this);
216230
216339
  }
216340
+ /** Test for near equality */
216341
+ isAlmostEqual(other) {
216342
+ if (!super.isAlmostEqual(other))
216343
+ return false;
216344
+ return this.isInner === other.isInner;
216345
+ }
216231
216346
  }
216232
216347
  /**
216233
216348
  * Structure carrying a pair of loops with curve geometry.
@@ -216535,14 +216650,15 @@ class ParityRegion extends _CurveCollection__WEBPACK_IMPORTED_MODULE_0__.CurveCo
216535
216650
  }
216536
216651
  /** Return a deep copy. */
216537
216652
  clone() {
216538
- const clone = new ParityRegion();
216539
- let child;
216540
- for (child of this.children) {
216541
- const childClone = child.clone();
216542
- if (childClone instanceof _Loop__WEBPACK_IMPORTED_MODULE_1__.Loop)
216543
- clone.children.push(childClone);
216544
- }
216545
- return clone;
216653
+ return super.clone();
216654
+ }
216655
+ /** Create a deep copy of transformed curves. */
216656
+ cloneTransformed(transform) {
216657
+ return super.cloneTransformed(transform);
216658
+ }
216659
+ /** Create a deep copy with all linestrings broken down into multiple LineSegment3d. */
216660
+ cloneWithExpandedLineStrings() {
216661
+ return super.cloneWithExpandedLineStrings();
216546
216662
  }
216547
216663
  /** Stroke these curves into a new ParityRegion. */
216548
216664
  cloneStroked(options) {
@@ -216671,6 +216787,18 @@ class Path extends _CurveCollection__WEBPACK_IMPORTED_MODULE_2__.CurveChain {
216671
216787
  cloneEmptyPeer() {
216672
216788
  return new Path();
216673
216789
  }
216790
+ /** Return a deep copy. */
216791
+ clone() {
216792
+ return super.clone();
216793
+ }
216794
+ /** Create a deep copy of transformed curves. */
216795
+ cloneTransformed(transform) {
216796
+ return super.cloneTransformed(transform);
216797
+ }
216798
+ /** Create a deep copy with all linestrings broken down into multiple LineSegment3d. */
216799
+ cloneWithExpandedLineStrings() {
216800
+ return super.cloneWithExpandedLineStrings();
216801
+ }
216674
216802
  /** Second step of double dispatch: call `handler.handlePath(this)` */
216675
216803
  dispatchToGeometryHandler(handler) {
216676
216804
  return handler.handlePath(this);
@@ -216946,9 +217074,8 @@ class ProxyCurve extends _curve_CurvePrimitive__WEBPACK_IMPORTED_MODULE_0__.Curv
216946
217074
  /** Return a transformed clone. */
216947
217075
  cloneTransformed(transform) {
216948
217076
  const myClone = this.clone();
216949
- if (myClone.tryTransformInPlace(transform))
216950
- return myClone;
216951
- return undefined;
217077
+ myClone.tryTransformInPlace(transform);
217078
+ return myClone;
216952
217079
  }
216953
217080
  /** Implement by proxyCurve. Subclasses may eventually override this default implementation. */
216954
217081
  clonePartialCurve(fractionA, fractionB) {
@@ -219017,8 +219144,6 @@ class RegionOps {
219017
219144
  const worldToLocal = localToWorld.inverse();
219018
219145
  (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(worldToLocal !== undefined, "FrameBuilder's transform is invertible");
219019
219146
  regionXY = region.cloneTransformed(worldToLocal);
219020
- if (!regionXY)
219021
- return undefined;
219022
219147
  }
219023
219148
  const momentData = RegionOps.computeXYAreaMoments(regionXY);
219024
219149
  if (!momentData)
@@ -221247,6 +221372,18 @@ class UnionRegion extends _CurveCollection__WEBPACK_IMPORTED_MODULE_0__.CurveCol
221247
221372
  cloneEmptyPeer() {
221248
221373
  return new UnionRegion();
221249
221374
  }
221375
+ /** Return a deep copy. */
221376
+ clone() {
221377
+ return super.clone();
221378
+ }
221379
+ /** Create a deep copy of transformed curves. */
221380
+ cloneTransformed(transform) {
221381
+ return super.cloneTransformed(transform);
221382
+ }
221383
+ /** Create a deep copy with all linestrings broken down into multiple LineSegment3d. */
221384
+ cloneWithExpandedLineStrings() {
221385
+ return super.cloneWithExpandedLineStrings();
221386
+ }
221250
221387
  /**
221251
221388
  * Try to add a child (by capturing it).
221252
221389
  * * Returns false if the `AnyCurve` child is not a region type.
@@ -221859,6 +221996,7 @@ __webpack_require__.r(__webpack_exports__);
221859
221996
  * Algorithmic class for cloning curve collections.
221860
221997
  * * recurse through collection nodes, building image nodes as needed and inserting clones of children.
221861
221998
  * * for individual primitive, invoke doClone (protected) for direct clone; insert into parent
221999
+ * @internal
221862
222000
  */
221863
222001
  class CloneCurvesContext extends _CurveProcessor__WEBPACK_IMPORTED_MODULE_1__.RecursiveCurveProcessorWithStack {
221864
222002
  _result;
@@ -221897,7 +222035,7 @@ class CloneCurvesContext extends _CurveProcessor__WEBPACK_IMPORTED_MODULE_1__.Re
221897
222035
  const c = this.doClone(primitive);
221898
222036
  if (c !== undefined && this._stack.length > 0) {
221899
222037
  const parent = this._stack[this._stack.length - 1];
221900
- if (parent instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_0__.CurveChain || parent instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_0__.BagOfCurves)
222038
+ if (parent instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_0__.CurveChain || parent instanceof _CurveCollection__WEBPACK_IMPORTED_MODULE_0__.BagOfCurves) {
221901
222039
  if (Array.isArray(c)) {
221902
222040
  for (const c1 of c) {
221903
222041
  parent.tryAddChild(c1);
@@ -221906,6 +222044,7 @@ class CloneCurvesContext extends _CurveProcessor__WEBPACK_IMPORTED_MODULE_1__.Re
221906
222044
  else {
221907
222045
  parent.tryAddChild(c);
221908
222046
  }
222047
+ }
221909
222048
  }
221910
222049
  }
221911
222050
  }
@@ -227733,26 +227872,34 @@ __webpack_require__.r(__webpack_exports__);
227733
227872
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
227734
227873
  /* harmony export */ TransformInPlaceContext: () => (/* binding */ TransformInPlaceContext)
227735
227874
  /* harmony export */ });
227736
- /* harmony import */ var _CurveProcessor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../CurveProcessor */ "../../core/geometry/lib/esm/curve/CurveProcessor.js");
227875
+ /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
227876
+ /* harmony import */ var _CurveProcessor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../CurveProcessor */ "../../core/geometry/lib/esm/curve/CurveProcessor.js");
227877
+ /*---------------------------------------------------------------------------------------------
227878
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
227879
+ * See LICENSE.md in the project root for license terms and full copyright notice.
227880
+ *--------------------------------------------------------------------------------------------*/
227881
+ /** @packageDocumentation
227882
+ * @module Curve
227883
+ */
227737
227884
 
227738
- /** Algorithmic class: Transform curves in place.
227885
+
227886
+ /** Algorithmic class: Transform curves in place. Always expected to succeed.
227739
227887
  * @internal
227740
227888
  */
227741
- class TransformInPlaceContext extends _CurveProcessor__WEBPACK_IMPORTED_MODULE_0__.RecursiveCurveProcessor {
227742
- numFail;
227743
- numOK;
227889
+ class TransformInPlaceContext extends _CurveProcessor__WEBPACK_IMPORTED_MODULE_1__.RecursiveCurveProcessor {
227744
227890
  transform;
227745
- constructor(transform) { super(); this.numFail = 0; this.numOK = 0; this.transform = transform; }
227891
+ constructor(transform) {
227892
+ super();
227893
+ this.transform = transform;
227894
+ }
227746
227895
  static tryTransformInPlace(target, transform) {
227747
227896
  const context = new TransformInPlaceContext(transform);
227748
227897
  target.announceToCurveProcessor(context);
227749
- return context.numFail === 0;
227898
+ return true;
227750
227899
  }
227751
227900
  announceCurvePrimitive(curvePrimitive, _indexInParent) {
227752
227901
  if (!curvePrimitive.tryTransformInPlace(this.transform))
227753
- this.numFail++;
227754
- else
227755
- this.numOK++;
227902
+ (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(false, "TransformInPlaceContext: unexpected failure of tryTransformInPlace");
227756
227903
  }
227757
227904
  }
227758
227905
 
@@ -231188,9 +231335,12 @@ class DirectSpiral3d extends _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_13__.T
231188
231335
  clone() {
231189
231336
  return new DirectSpiral3d(this.localToWorld.clone(), this._spiralType, this.designProperties?.clone(), this._nominalL1, this._nominalR1, this._activeFractionInterval?.clone(), this._evaluator.clone());
231190
231337
  }
231191
- /** Apply `transform` to this spiral's local to world transform. */
231192
- tryTransformInPlace(transformA) {
231193
- const rigidData = this.applyRigidPartOfTransform(transformA);
231338
+ /**
231339
+ * Apply `transform` to this spiral's local to world transform.
231340
+ * * Only the rigid part of the transform is applied.
231341
+ */
231342
+ tryTransformInPlace(transform) {
231343
+ const rigidData = this.applyRigidPartOfTransform(transform);
231194
231344
  if (rigidData !== undefined) {
231195
231345
  this._nominalL1 *= rigidData.scale;
231196
231346
  this._nominalR1 *= rigidData.scale;
@@ -231595,9 +231745,12 @@ class IntegratedSpiral3d extends _TransitionSpiral3d__WEBPACK_IMPORTED_MODULE_15
231595
231745
  clone() {
231596
231746
  return new IntegratedSpiral3d(this._spiralType, this._evaluator, this.radius01.clone(), this.bearing01.clone(), this.activeFractionInterval.clone(), this.localToWorld.clone(), this._arcLength01, this._designProperties?.clone());
231597
231747
  }
231598
- /** Apply `transform` to this spiral's local to world transform. */
231599
- tryTransformInPlace(transformA) {
231600
- const rigidData = this.applyRigidPartOfTransform(transformA);
231748
+ /**
231749
+ * Apply `transform` to this spiral's local to world transform.
231750
+ * * Only the rigid part of the transform is applied.
231751
+ */
231752
+ tryTransformInPlace(transform) {
231753
+ const rigidData = this.applyRigidPartOfTransform(transform);
231601
231754
  if (rigidData !== undefined) {
231602
231755
  this._curvature01.x0 /= rigidData.scale;
231603
231756
  this._curvature01.x1 /= rigidData.scale;
@@ -282545,8 +282698,11 @@ function nullToUndefined(data) {
282545
282698
  function createTypedCurveCollection(collectionType) {
282546
282699
  if (collectionType === 1)
282547
282700
  return new _curve_Path__WEBPACK_IMPORTED_MODULE_14__.Path();
282548
- if (collectionType === 2 || collectionType === 3)
282549
- return new _curve_Loop__WEBPACK_IMPORTED_MODULE_12__.Loop();
282701
+ if (collectionType === 2 || collectionType === 3) {
282702
+ const loop = new _curve_Loop__WEBPACK_IMPORTED_MODULE_12__.Loop();
282703
+ loop.isInner = collectionType === 3;
282704
+ return loop;
282705
+ }
282550
282706
  if (collectionType === 4)
282551
282707
  return new _curve_ParityRegion__WEBPACK_IMPORTED_MODULE_13__.ParityRegion();
282552
282708
  if (collectionType === 5)
@@ -282780,9 +282936,8 @@ class BGFBWriter {
282780
282936
  let cvType = 0;
282781
282937
  if (cv instanceof _curve_Path__WEBPACK_IMPORTED_MODULE_16__.Path)
282782
282938
  cvType = 1;
282783
- else if (cv instanceof _curve_Loop__WEBPACK_IMPORTED_MODULE_14__.Loop) {
282939
+ else if (cv instanceof _curve_Loop__WEBPACK_IMPORTED_MODULE_14__.Loop)
282784
282940
  cvType = cv.isInner ? 3 : 2;
282785
- }
282786
282941
  else if (cv instanceof _curve_ParityRegion__WEBPACK_IMPORTED_MODULE_15__.ParityRegion)
282787
282942
  cvType = 4;
282788
282943
  else if (cv instanceof _curve_UnionRegion__WEBPACK_IMPORTED_MODULE_21__.UnionRegion)
@@ -283988,16 +284143,17 @@ var IModelJson;
283988
284143
  return undefined;
283989
284144
  }
283990
284145
  /** parse contents of a curve collection to a CurveCollection instance */
283991
- static parseCurveCollectionMembers(result, data) {
283992
- if (data && Array.isArray(data)) {
283993
- for (const c of data) {
283994
- const g = Reader.parse(c);
283995
- if (g instanceof _curve_GeometryQuery__WEBPACK_IMPORTED_MODULE_11__.GeometryQuery && ("curveCollection" === g.geometryCategory || "curvePrimitive" === g.geometryCategory))
283996
- result.tryAddChild(g);
283997
- }
283998
- return result;
284146
+ static parseCurveCollectionMembers(result, data, isInner = false) {
284147
+ if (!data || !Array.isArray(data))
284148
+ return undefined;
284149
+ for (const c of data) {
284150
+ const g = Reader.parse(c);
284151
+ if (g instanceof _curve_GeometryQuery__WEBPACK_IMPORTED_MODULE_11__.GeometryQuery && ("curveCollection" === g.geometryCategory || "curvePrimitive" === g.geometryCategory))
284152
+ result.tryAddChild(g);
283999
284153
  }
284000
- return undefined;
284154
+ if (isInner && result instanceof _curve_Loop__WEBPACK_IMPORTED_MODULE_14__.Loop)
284155
+ result.isInner = true;
284156
+ return result;
284001
284157
  }
284002
284158
  /** Parse content of `bsurf` to BSplineSurface3d or BSplineSurface3dH */
284003
284159
  static parseBsurf(data) {
@@ -284215,7 +284371,7 @@ var IModelJson;
284215
284371
  return Reader.parseCurveCollectionMembers(new _curve_Path__WEBPACK_IMPORTED_MODULE_16__.Path(), json.path);
284216
284372
  }
284217
284373
  else if (json.hasOwnProperty("loop")) {
284218
- return Reader.parseCurveCollectionMembers(new _curve_Loop__WEBPACK_IMPORTED_MODULE_14__.Loop(), json.loop);
284374
+ return Reader.parseCurveCollectionMembers(new _curve_Loop__WEBPACK_IMPORTED_MODULE_14__.Loop(), json.loop, json.hasOwnProperty("isInner") && true === json.isInner);
284219
284375
  }
284220
284376
  else if (json.hasOwnProperty("parityRegion")) {
284221
284377
  return Reader.parseCurveCollectionMembers(new _curve_ParityRegion__WEBPACK_IMPORTED_MODULE_15__.ParityRegion(), json.parityRegion);
@@ -284541,7 +284697,7 @@ var IModelJson;
284541
284697
  }
284542
284698
  /** Convert strongly typed instance to tagged json */
284543
284699
  handleLoop(data) {
284544
- return { loop: this.collectChildren(data) };
284700
+ return { loop: this.collectChildren(data), isInner: data.isInner ? true : undefined };
284545
284701
  }
284546
284702
  /** Convert strongly typed instance to tagged json */
284547
284703
  handleParityRegion(data) {
@@ -284557,12 +284713,10 @@ var IModelJson;
284557
284713
  }
284558
284714
  collectChildren(data) {
284559
284715
  const children = [];
284560
- if (data.children && Array.isArray(data.children)) {
284561
- for (const child of data.children) {
284562
- const cdata = child.dispatchToGeometryHandler(this);
284563
- if (cdata)
284564
- children.push(cdata);
284565
- }
284716
+ for (const child of data.children) {
284717
+ const cdata = child.dispatchToGeometryHandler(this);
284718
+ if (cdata)
284719
+ children.push(cdata);
284566
284720
  }
284567
284721
  return children;
284568
284722
  }
@@ -295800,23 +295954,9 @@ class ITwinLocalization {
295800
295954
  this.i18next.loadNamespaces(name, (err) => {
295801
295955
  if (!err)
295802
295956
  return resolve();
295803
- // Here we got a non-null err object.
295804
- // This method is called when the system has attempted to load the resources for the namespaces for each possible locale.
295805
- // For example 'fr-ca' might be the most specific locale, in which case 'fr' and 'en' are fallback locales.
295806
- // Using Backend from i18next-http-backend, err will be an array of strings of each namespace it tried to read and its locale.
295807
- // There might be errs for some other namespaces as well as this one. We resolve the promise unless there's an error for each possible locale.
295808
- let locales = this.getLanguageList().map((thisLocale) => `/${thisLocale}/`);
295809
- try {
295810
- for (const thisError of err) {
295811
- if (typeof thisError === "string")
295812
- locales = locales.filter((thisLocale) => !thisError.includes(thisLocale));
295813
- }
295814
- }
295815
- catch {
295816
- locales = [];
295817
- }
295818
- // if we removed every locale from the array, it wasn't loaded.
295819
- if (locales.length === 0)
295957
+ // i18next can return errors from other concurrent namespace loads in this callback.
295958
+ const wasLoaded = this.getLanguageList().some((language) => this.i18next.hasResourceBundle(language, name));
295959
+ if (!wasLoaded)
295820
295960
  _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_3__.Logger.logError("i18n", `No resources for namespace ${name} could be loaded`);
295821
295961
  resolve();
295822
295962
  });
@@ -336830,7 +336970,7 @@ class WMS {
336830
336970
  (module) {
336831
336971
 
336832
336972
  "use strict";
336833
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.14.0-dev.7","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s build:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts && npm run -s extract","extract":"betools extract --fileExt=ts --extractFrom=./src/test/example-code --recursive --out=../../generated-docs/extract","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run build:test-worker && vitest --run","cover":"npm run build:test-worker && vitest --run","build:test-worker":"vite build --config ./src/test/worker/vite.config.mts 1>&2","build:workers":"rimraf lib/workers/webpack && vite build --config ./src/workers/ImdlParser/vite.config.mts 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@bentley/aec-units-schema":"^1.0.3","@bentley/formats-schema":"^1.0.0","@bentley/units-schema":"^1.0.11","@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/node":"~20.17.0","@types/sinon":"^17.0.2","@vitest/browser-playwright":"^4.1.10","@vitest/coverage-v8":"^4.1.10","cpx2":"^8.0.0","eslint":"^9.31.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","typescript":"~5.6.2","vite":"^6.4.3","vitest":"^4.1.10","vite-plugin-static-copy":"2.2.0"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^4.4.5","@loaders.gl/draco":"^4.4.5","fuse.js":"^3.3.0","wms-capabilities":"0.6.0"}}');
336973
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.14.0-dev.9","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s build:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts && npm run -s extract","extract":"betools extract --fileExt=ts --extractFrom=./src/test/example-code --recursive --out=../../generated-docs/extract","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run build:test-worker && vitest --run","cover":"npm run build:test-worker && vitest --run","build:test-worker":"vite build --config ./src/test/worker/vite.config.mts 1>&2","build:workers":"rimraf lib/workers/webpack && vite build --config ./src/workers/ImdlParser/vite.config.mts 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@bentley/aec-units-schema":"^1.0.3","@bentley/formats-schema":"^1.0.0","@bentley/units-schema":"^1.0.11","@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/node":"~20.17.0","@types/sinon":"^17.0.2","@vitest/browser-playwright":"^4.1.10","@vitest/coverage-v8":"^4.1.10","cpx2":"^8.0.0","eslint":"^9.31.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","typescript":"~5.6.2","vite":"^6.4.3","vitest":"^4.1.10","vite-plugin-static-copy":"2.2.0"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^4.4.5","@loaders.gl/draco":"^4.4.5","fuse.js":"^3.3.0","wms-capabilities":"0.6.0"}}');
336834
336974
 
336835
336975
  /***/ }
336836
336976