@itwin/rpcinterface-full-stack-tests 5.13.0-dev.16 → 5.13.0-dev.18

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.
@@ -111451,6 +111451,8 @@ const COPYRIGHT_NOTICE = `Copyright © 2017-${new Date().getFullYear()} <a href=
111451
111451
 
111452
111452
 
111453
111453
 
111454
+ /** CSS class name applied to the notice element of a logo card created by [[IModelApp.makeLogoCard]]. */
111455
+ const logoCardNoticeClassName = "logo-cards";
111454
111456
  /**
111455
111457
  * Global singleton that connects the user interface with the iTwin.js services. There can be only one IModelApp active in a session. All
111456
111458
  * members of IModelApp are static, and it serves as a singleton object for gaining access to session information.
@@ -111963,10 +111965,21 @@ class IModelApp {
111963
111965
  }
111964
111966
  if (undefined !== opts.notice) {
111965
111967
  if (typeof opts.notice === "string")
111966
- IModelApp.makeHTMLElement("p", { parent: noticeCell, innerHTML: opts.notice, className: "logo-cards" });
111968
+ IModelApp.makeHTMLElement("p", { parent: noticeCell, innerHTML: opts.notice, className: logoCardNoticeClassName });
111967
111969
  else
111968
111970
  noticeCell.appendChild(opts.notice);
111969
111971
  }
111972
+ else if (undefined !== opts.noticeLines) {
111973
+ // A <p> cannot legally contain flow content, so use a <div> when a line is an element.
111974
+ const containerTag = opts.noticeLines.some((line) => typeof line !== "string") ? "div" : "p";
111975
+ const notice = IModelApp.makeHTMLElement(containerTag, { parent: noticeCell, className: logoCardNoticeClassName });
111976
+ opts.noticeLines.forEach((line, index) => {
111977
+ if (index > 0)
111978
+ notice.appendChild(IModelApp.makeHTMLElement("br"));
111979
+ // Strings are appended as text nodes so they are never parsed as HTML.
111980
+ notice.append(line);
111981
+ });
111982
+ }
111970
111983
  return card;
111971
111984
  }
111972
111985
  /** Make the logo card for the library itself. This card gets placed at the top of the stack.
@@ -113533,7 +113546,9 @@ let iModelJsCss = `
113533
113546
 
113534
113547
  .logo-cards {
113535
113548
  position:relative;
113536
- width:100%
113549
+ width:100%;
113550
+ margin-block-start:1em;
113551
+ margin-block-end:1em
113537
113552
  }
113538
113553
 
113539
113554
  .imodeljs-modal-overlay {
@@ -113577,7 +113592,7 @@ let iModelJsCss = `
113577
113592
  max-width: calc(100% - (2 * var(--width-border))) !important;
113578
113593
  width: unset !important;
113579
113594
  }
113580
- .imodeljs-about .logo-card-message p {
113595
+ .imodeljs-about .logo-card-message p, .imodeljs-about .logo-card-message .logo-cards {
113581
113596
  margin-block-end: 1em;
113582
113597
  }
113583
113598
  .imodeljs-about .logo-cards {
@@ -116223,9 +116238,12 @@ class Google3dTilesProvider {
116223
116238
  // Order by most occurances to least
116224
116239
  // See https://developers.google.com/maps/documentation/tile/create-renderer#display-attributions
116225
116240
  const sortedCopyrights = [...copyrightMap.entries()].sort((a, b) => b[1] - a[1]);
116226
- let copyrightMsg = "Data provided by:<br><ul>";
116227
- copyrightMsg += sortedCopyrights.map(([key]) => `<li>${key}</li>`).join("");
116228
- copyrightMsg += "</ul>";
116241
+ const list = document.createElement("ul");
116242
+ for (const [key] of sortedCopyrights) {
116243
+ const item = document.createElement("li");
116244
+ item.textContent = key;
116245
+ list.appendChild(item);
116246
+ }
116229
116247
  const iconSrc = document.createElement("img");
116230
116248
  iconSrc.src = `${_IModelApp__WEBPACK_IMPORTED_MODULE_8__.IModelApp.publicPath}images/GoogleMaps_Logo_Gray.svg`;
116231
116249
  iconSrc.style.padding = "10px 10px 5px 10px";
@@ -116233,7 +116251,7 @@ class Google3dTilesProvider {
116233
116251
  iconSrc,
116234
116252
  iconWidth: 98,
116235
116253
  heading: "Google Photorealistic 3D Tiles",
116236
- notice: copyrightMsg
116254
+ noticeLines: ["Data provided by:", list],
116237
116255
  }));
116238
116256
  }
116239
116257
  }
@@ -136623,7 +136641,7 @@ class GoogleMapsDecorator {
136623
136641
  const copyrightText = sortedCopyrights.map(([key]) => ` • ${key}`).join("");
136624
136642
  // Create and add element, offset to leave space for i.js and Google logos
136625
136643
  const elem = document.createElement("div");
136626
- elem.innerHTML = copyrightText;
136644
+ elem.textContent = copyrightText;
136627
136645
  elem.style.color = "white";
136628
136646
  elem.style.fontSize = "11px";
136629
136647
  elem.style.textWrap = "wrap";
@@ -173470,6 +173488,7 @@ __webpack_require__.r(__webpack_exports__);
173470
173488
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
173471
173489
  /* harmony export */ OrbitGtTileTree: () => (/* binding */ OrbitGtTileTree),
173472
173490
  /* harmony export */ OrbitGtTreeReference: () => (/* binding */ OrbitGtTreeReference),
173491
+ /* harmony export */ computeOrthometricVerticalShift: () => (/* binding */ computeOrthometricVerticalShift),
173473
173492
  /* harmony export */ createOrbitGtTileTreeReference: () => (/* binding */ createOrbitGtTileTreeReference)
173474
173493
  /* harmony export */ });
173475
173494
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
@@ -173477,11 +173496,12 @@ __webpack_require__.r(__webpack_exports__);
173477
173496
  /* harmony import */ var _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @itwin/core-geometry */ "../../core/geometry/lib/esm/core-geometry.js");
173478
173497
  /* harmony import */ var _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @itwin/core-orbitgt */ "../../core/orbitgt/lib/esm/core-orbitgt.js");
173479
173498
  /* harmony import */ var _BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../BackgroundMapGeometry */ "../../core/frontend/lib/esm/BackgroundMapGeometry.js");
173480
- /* harmony import */ var _DisplayStyleState__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../DisplayStyleState */ "../../core/frontend/lib/esm/DisplayStyleState.js");
173481
- /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
173482
- /* harmony import */ var _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../RealityDataSource */ "../../core/frontend/lib/esm/RealityDataSource.js");
173483
- /* harmony import */ var _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../common/internal/render/MeshPrimitives */ "../../core/frontend/lib/esm/common/internal/render/MeshPrimitives.js");
173484
- /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
173499
+ /* harmony import */ var _common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../common/FrontendLoggerCategory */ "../../core/frontend/lib/esm/common/FrontendLoggerCategory.js");
173500
+ /* harmony import */ var _DisplayStyleState__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../DisplayStyleState */ "../../core/frontend/lib/esm/DisplayStyleState.js");
173501
+ /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
173502
+ /* harmony import */ var _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../RealityDataSource */ "../../core/frontend/lib/esm/RealityDataSource.js");
173503
+ /* harmony import */ var _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../common/internal/render/MeshPrimitives */ "../../core/frontend/lib/esm/common/internal/render/MeshPrimitives.js");
173504
+ /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
173485
173505
  /*---------------------------------------------------------------------------------------------
173486
173506
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
173487
173507
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -173499,6 +173519,7 @@ __webpack_require__.r(__webpack_exports__);
173499
173519
 
173500
173520
 
173501
173521
 
173522
+
173502
173523
  const scratchRange = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.create();
173503
173524
  const scratchWorldFrustum = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Frustum();
173504
173525
  function compareSourceKeys(lhs, rhs) {
@@ -173562,7 +173583,7 @@ class OrbitGtTileTreeParams {
173562
173583
  id;
173563
173584
  modelId;
173564
173585
  iModel;
173565
- get priority() { return _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileLoadPriority.Context; }
173586
+ get priority() { return _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileLoadPriority.Context; }
173566
173587
  constructor(rdSourceKey, iModel, modelId, location) {
173567
173588
  this.location = location;
173568
173589
  const key = rdSourceKey;
@@ -173571,10 +173592,10 @@ class OrbitGtTileTreeParams {
173571
173592
  this.iModel = iModel;
173572
173593
  }
173573
173594
  }
173574
- class OrbitGtRootTile extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.Tile {
173595
+ class OrbitGtRootTile extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.Tile {
173575
173596
  _loadChildren(_resolve, _reject) { }
173576
173597
  async requestContent(_isCanceled) { return undefined; }
173577
- get channel() { return _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.tileAdmin.channels.getForHttp("itwinjs-orbitgit"); }
173598
+ get channel() { return _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.channels.getForHttp("itwinjs-orbitgit"); }
173578
173599
  async readContent(_data, _system, _isCanceled) { return {}; }
173579
173600
  freeMemory() { }
173580
173601
  constructor(params, tree) { super(params, tree); }
@@ -173644,7 +173665,7 @@ class TileSortProjector {
173644
173665
  coordinate.z = point.z;
173645
173666
  }
173646
173667
  }
173647
- class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileUsageMarker {
173668
+ class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileUsageMarker {
173648
173669
  graphic;
173649
173670
  constructor(graphic, viewport, time) {
173650
173671
  super();
@@ -173655,7 +173676,7 @@ class OrbitGtTileGraphic extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.Til
173655
173676
  this.graphic[Symbol.dispose]();
173656
173677
  }
173657
173678
  }
173658
- class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTree {
173679
+ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.TileTree {
173659
173680
  _dataManager;
173660
173681
  _centerOffset;
173661
173682
  _ecefTransform;
@@ -173671,7 +173692,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173671
173692
  this._dataManager = _dataManager;
173672
173693
  this._centerOffset = _centerOffset;
173673
173694
  this._ecefTransform = _ecefTransform;
173674
- this._layerHandler = new _tile_internal__WEBPACK_IMPORTED_MODULE_9__.LayerTileTreeHandler(this);
173695
+ this._layerHandler = new _tile_internal__WEBPACK_IMPORTED_MODULE_10__.LayerTileTreeHandler(this);
173675
173696
  this._tileParams = { contentId: "0", range: cloudRange, maximumSize: 256 };
173676
173697
  this.rootTile = new OrbitGtRootTile(this._tileParams, this);
173677
173698
  }
@@ -173720,7 +173741,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173720
173741
  let totalPointCount = 0;
173721
173742
  const tileCount = frameData.tilesToRender.size();
173722
173743
  // Inform TileAdmin about tiles we are handling ourselves...
173723
- _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.tileAdmin.addExternalTilesForUser(args.context.viewport, { requested: frameData.tilesToLoad.size() + (frameData.hasMissingData() ? 1 : 0), selected: tileCount, ready: tileCount });
173744
+ _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.addExternalTilesForUser(args.context.viewport, { requested: frameData.tilesToLoad.size() + (frameData.hasMissingData() ? 1 : 0), selected: tileCount, ready: tileCount });
173724
173745
  if (debugBuilder)
173725
173746
  debugBuilder.setSymbology(_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ColorDef.red, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ColorDef.red, 1);
173726
173747
  let minLevel = 100, maxLevel = -100;
@@ -173741,8 +173762,8 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173741
173762
  range.high.addInPlace(this._centerOffset);
173742
173763
  const qParams = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QParams3d.fromRange(range, undefined, (tile.points8 != null) ? _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Quantization.rangeScale8 : _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Quantization.rangeScale16);
173743
173764
  const featureTable = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.FeatureTable(1, this.modelId, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.BatchType.Primary);
173744
- const features = new _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_8__.Mesh.Features(featureTable);
173745
- const system = _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.renderSystem;
173765
+ const features = new _common_internal_render_MeshPrimitives__WEBPACK_IMPORTED_MODULE_9__.Mesh.Features(featureTable);
173766
+ const system = _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.renderSystem;
173746
173767
  const voxelSize = (range.high.x - range.low.x) / 64;
173747
173768
  features.add(new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Feature(this.modelId), 1);
173748
173769
  const tilePoints = (tile.points8 != null) ? tile.points8.toNativeBuffer() : tile.points16.toNativeBuffer();
@@ -173769,8 +173790,34 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173769
173790
  }
173770
173791
  args.drawGraphics();
173771
173792
  if (frameData.hasMissingData()) {
173772
- this._dataManager.loadData(frameData).then(() => _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.tileAdmin.onTileLoad.raiseEvent(this.rootTile)).catch((_err) => undefined);
173793
+ this._dataManager.loadData(frameData).then(() => _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.tileAdmin.onTileLoad.raiseEvent(this.rootTile)).catch((_err) => undefined);
173794
+ }
173795
+ }
173796
+ }
173797
+ /** Computes the vertical shift, in meters along geodetic up, to correctly place a point cloud whose CRS does not
173798
+ * define a vertical datum, assuming its heights are orthometric (relative to the geoid).
173799
+ *
173800
+ * The shift is the difference between converting the point cloud's origin with its height treated as orthometric
173801
+ * versus ellipsoidal (`heightAsEllipsoidalDbZ`, already computed by the caller). Returns zero if the shift cannot
173802
+ * be computed or the iModel's converter makes no distinction between the two.
173803
+ * Exported strictly for tests.
173804
+ * @internal
173805
+ */
173806
+ async function computeOrthometricVerticalShift(geoOrigin, heightAsEllipsoidalDbZ, iModel) {
173807
+ const geoidConverter = iModel.noGcsDefined ? undefined : iModel.geoServices.getConverter({ horizontalCRS: { epsg: 4326 }, verticalCRS: { id: "GEOID" } });
173808
+ if (undefined === geoidConverter)
173809
+ return 0;
173810
+ try {
173811
+ const response = await geoidConverter.getIModelCoordinatesFromGeoCoordinates([geoOrigin]);
173812
+ if (response.iModelCoords[0].s !== _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success) {
173813
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__.FrontendLoggerCategory.RealityData, `Failed to compute orthometric height correction for point cloud (status ${response.iModelCoords[0].s}); heights will be treated as ellipsoidal`);
173814
+ return 0;
173773
173815
  }
173816
+ return _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p).z - heightAsEllipsoidalDbZ;
173817
+ }
173818
+ catch (err) {
173819
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logError(_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_5__.FrontendLoggerCategory.RealityData, err);
173820
+ return 0;
173774
173821
  }
173775
173822
  }
173776
173823
  (function (OrbitGtTileTree) {
@@ -173796,7 +173843,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173796
173843
  return isValidSASToken(props.sasToken);
173797
173844
  }
173798
173845
  async function createOrbitGtTileTree(rdSourceKey, iModel, modelId) {
173799
- const rdSource = await _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.fromKey(rdSourceKey, iModel.iTwinId);
173846
+ const rdSource = await _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.fromKey(rdSourceKey, iModel.iTwinId);
173800
173847
  const isContextShare = rdSourceKey.provider === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.ContextShare;
173801
173848
  const isTilestUrl = rdSourceKey.provider === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.TilesetUrl;
173802
173849
  let blobStringUrl;
@@ -173807,7 +173854,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173807
173854
  const docRootName = realityData.rootDocument;
173808
173855
  if (!docRootName)
173809
173856
  return undefined;
173810
- const token = await _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.getAccessToken();
173857
+ const token = await _IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.getAccessToken();
173811
173858
  const blobUrl = await realityData.getBlobUrl(token, docRootName);
173812
173859
  blobStringUrl = blobUrl.toString();
173813
173860
  }
@@ -173815,7 +173862,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173815
173862
  blobStringUrl = rdSourceKey.id;
173816
173863
  }
173817
173864
  else {
173818
- const orbitGtBlobProps = _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.createOrbitGtBlobPropsFromKey(rdSourceKey);
173865
+ const orbitGtBlobProps = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createOrbitGtBlobPropsFromKey(rdSourceKey);
173819
173866
  if (orbitGtBlobProps === undefined)
173820
173867
  return undefined;
173821
173868
  if (!isValidOrbitGtBlobProps(orbitGtBlobProps))
@@ -173850,7 +173897,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173850
173897
  const wgs84CRS = "4978";
173851
173898
  await _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.ENGINE.prepareForArea(wgs84CRS, new _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.OrbitGtBounds());
173852
173899
  const pointCloudToEcef = transformFromOrbitGt(_itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.createTransform(pointCloudCRS, new _itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.OrbitGtCoordinate(pointCloudCenter.x, pointCloudCenter.y, pointCloudCenter.z), wgs84CRS));
173853
- const pointCloudCenterToEcef = pointCloudToEcef.multiplyTransformTransform(addCloudCenter);
173900
+ let pointCloudCenterToEcef = pointCloudToEcef.multiplyTransformTransform(addCloudCenter);
173854
173901
  ecefTransform.setFrom(pointCloudCenterToEcef);
173855
173902
  let ecefToDb = iModel.getMapEcefToDb(0);
173856
173903
  // In initial publishing version the iModel ecef Transform was used to locate the reality model.
@@ -173870,7 +173917,21 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173870
173917
  const geoOrigin = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(cartographicOrigin.longitudeDegrees, cartographicOrigin.latitudeDegrees, cartographicOrigin.height);
173871
173918
  const response = await geoConverter.getIModelCoordinatesFromGeoCoordinates([geoOrigin]);
173872
173919
  if (response.iModelCoords[0].s === _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success) {
173873
- const ecefToDbOrigin = await (0,_BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__.calculateEcefToDbTransformAtLocation)(_itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p), iModel);
173920
+ const dbOriginFromGcs = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(response.iModelCoords[0].p);
173921
+ // A projected CRS defines no vertical datum, so the point cloud's heights are conventionally orthometric -
173922
+ // but pointCloudToEcef above treated them as ellipsoidal. Correct the placement by the difference.
173923
+ // (A compound CRS also takes this path; that stays correct unless orbitgt gains a geoid model.)
173924
+ if (_itwin_core_orbitgt__WEBPACK_IMPORTED_MODULE_3__.CRSManager.ENGINE.isProjectedCRS(pointCloudCRS)) {
173925
+ const verticalShift = await computeOrthometricVerticalShift(geoOrigin, dbOriginFromGcs.z, iModel);
173926
+ if (0 !== verticalShift) {
173927
+ const upVector = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Vector3d.createStartEnd(cartographicOrigin.toEcef(), _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Cartographic.fromRadians({ longitude: cartographicOrigin.longitude, latitude: cartographicOrigin.latitude, height: cartographicOrigin.height + 1 }).toEcef()).normalize();
173928
+ if (undefined !== upVector) {
173929
+ pointCloudCenterToEcef = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Transform.createTranslation(upVector.scale(verticalShift)).multiplyTransformTransform(pointCloudCenterToEcef);
173930
+ ecefTransform.setFrom(pointCloudCenterToEcef);
173931
+ }
173932
+ }
173933
+ }
173934
+ const ecefToDbOrigin = await (0,_BackgroundMapGeometry__WEBPACK_IMPORTED_MODULE_4__.calculateEcefToDbTransformAtLocation)(dbOriginFromGcs, iModel);
173874
173935
  if (ecefToDbOrigin)
173875
173936
  ecefToDb = ecefToDbOrigin;
173876
173937
  }
@@ -173890,7 +173951,7 @@ class OrbitGtTileTree extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.TileTr
173890
173951
  /** Supplies a reality data [[TileTree]] from a URL. May be associated with a persistent [[GeometricModelState]], or attached at run-time via a [[ContextOrbitGtState]].
173891
173952
  * Exported strictly for tests.
173892
173953
  */
173893
- class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.RealityModelTileTree.Reference {
173954
+ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_10__.RealityModelTileTree.Reference {
173894
173955
  treeOwner;
173895
173956
  _rdSourceKey;
173896
173957
  _modelId;
@@ -173903,15 +173964,15 @@ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.R
173903
173964
  this._rdSourceKey = props.rdSourceKey;
173904
173965
  }
173905
173966
  else if (props.orbitGtBlob) {
173906
- this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.createKeyFromOrbitGtBlobProps(props.orbitGtBlob);
173967
+ this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createKeyFromOrbitGtBlobProps(props.orbitGtBlob);
173907
173968
  }
173908
173969
  else {
173909
173970
  // TODO: Maybe we should throw an exception
173910
- this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_7__.RealityDataSource.createKeyFromBlobUrl("", _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.OrbitGtBlob, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataFormat.OPC);
173971
+ this._rdSourceKey = _RealityDataSource__WEBPACK_IMPORTED_MODULE_8__.RealityDataSource.createKeyFromBlobUrl("", _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataProvider.OrbitGtBlob, _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RealityDataFormat.OPC);
173911
173972
  }
173912
173973
  // ###TODO find compatible model Id
173913
173974
  let modelId = props.modelId;
173914
- if (undefined === modelId && this._source instanceof _DisplayStyleState__WEBPACK_IMPORTED_MODULE_5__.DisplayStyleState)
173975
+ if (undefined === modelId && this._source instanceof _DisplayStyleState__WEBPACK_IMPORTED_MODULE_6__.DisplayStyleState)
173915
173976
  modelId = orbitGtTreeSupplier.findCompatibleContextRealityModelId(this._rdSourceKey, this._source);
173916
173977
  this._modelId = modelId ?? props.iModel.transientIds.getNext();
173917
173978
  const ogtTreeId = { rdSourceKey: this._rdSourceKey, modelId: this.modelId };
@@ -173926,11 +173987,15 @@ class OrbitGtTreeReference extends _tile_internal__WEBPACK_IMPORTED_MODULE_9__.R
173926
173987
  if (undefined === tree || hit.iModel !== tree.iModel)
173927
173988
  return undefined;
173928
173989
  const strings = [];
173929
- strings.push(_IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.localization.getLocalizedString("iModelJs:RealityModelTypes.OrbitGTPointCloud"));
173990
+ strings.push(_IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.localization.getLocalizedString("iModelJs:RealityModelTypes.OrbitGTPointCloud"));
173930
173991
  if (this._name)
173931
- strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.localization.getLocalizedString("iModelJs:TooltipInfo.Name")} ${this._name}`);
173992
+ strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_7__.IModelApp.localization.getLocalizedString("iModelJs:TooltipInfo.Name")} ${this._name}`);
173932
173993
  const div = document.createElement("div");
173933
- div.innerHTML = strings.join("<br>");
173994
+ strings.forEach((str, index) => {
173995
+ if (index > 0)
173996
+ div.appendChild(document.createElement("br"));
173997
+ div.appendChild(document.createTextNode(str));
173998
+ });
173934
173999
  return div;
173935
174000
  }
173936
174001
  }
@@ -175694,7 +175759,11 @@ class RealityTreeReference extends RealityModelTileTree.Reference {
175694
175759
  if (-1 === key.indexOf("#")) // Avoid internal cesium
175695
175760
  strings.push(`${key}: ${JSON.stringify(batch[key])}`);
175696
175761
  const div = document.createElement("div");
175697
- div.innerHTML = strings.join("<br>");
175762
+ strings.forEach((str, index) => {
175763
+ if (index > 0)
175764
+ div.appendChild(document.createElement("br"));
175765
+ div.appendChild(document.createTextNode(str));
175766
+ });
175698
175767
  return div;
175699
175768
  }
175700
175769
  /** @deprecated in 5.0 - might be removed in next major version. Use [addAttributions] instead. */
@@ -176882,7 +176951,21 @@ class ArcGisUtilities {
176882
176951
  */
176883
176952
  static async validateSource(args) {
176884
176953
  const { source, ignoreCache, capabilitiesFilter } = args;
176885
- const metadata = await this.getServiceJson({ url: source.url, formatId: source.formatId, userName: source.userName, password: source.password, queryParams: source.collectQueryParams(), ignoreCache });
176954
+ let metadata;
176955
+ try {
176956
+ metadata = await this.getServiceJson({ url: source.url, formatId: source.formatId, userName: source.userName, password: source.password, queryParams: source.collectQueryParams(), ignoreCache });
176957
+ }
176958
+ catch (err) {
176959
+ if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError) {
176960
+ let blockedOrigin;
176961
+ try {
176962
+ blockedOrigin = new URL(err.url).origin;
176963
+ }
176964
+ catch { /* non-hierarchical URL */ }
176965
+ return { status: _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
176966
+ }
176967
+ throw err;
176968
+ }
176886
176969
  const json = metadata?.content;
176887
176970
  if (json === undefined) {
176888
176971
  return { status: _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerSourceStatus.InvalidUrl };
@@ -176945,6 +177028,9 @@ class ArcGisUtilities {
176945
177028
  * @param password Password to use for legacy token based security
176946
177029
  * @param ignoreCache Flag to skip cache lookup (i.e. force a new server request)
176947
177030
  * @param requireToken Flag to indicate if a token is required
177031
+ * @throws [[MapLayerUntrustedOriginError]] if an NTLM/Negotiate challenge could not be answered because
177032
+ * the URL's origin is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]);
177033
+ * all other errors are caught and reported by returning `undefined`.
176948
177034
  */
176949
177035
  static async getServiceJson(args) {
176950
177036
  const { url, formatId, userName, password, queryParams, ignoreCache, requireToken } = args;
@@ -176980,8 +177066,17 @@ class ArcGisUtilities {
176980
177066
  }
176981
177067
  let response = await fetch(tmpUrl, { method: "GET" });
176982
177068
  if (response.status === 401 && !requireToken && (0,_request_utils__WEBPACK_IMPORTED_MODULE_3__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
176983
- // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
176984
- response = await fetch(tmpUrl, { method: "GET", credentials: "include" });
177069
+ // fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
177070
+ const challengedUrl = response.url || tmpUrl.toString();
177071
+ if (!_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(challengedUrl))
177072
+ throw new _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError(challengedUrl);
177073
+ _IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(challengedUrl);
177074
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication).
177075
+ response = await fetch(challengedUrl, {
177076
+ method: "GET",
177077
+ credentials: "include",
177078
+ redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
177079
+ });
176985
177080
  }
176986
177081
  // Append security token when corresponding error code is returned by ArcGIS service
176987
177082
  let errorCode = await ArcGisUtilities.checkForResponseErrorCode(response);
@@ -177003,8 +177098,10 @@ class ArcGisUtilities {
177003
177098
  ArcGisUtilities._serviceCache.set(url, (errorCode === undefined ? info : undefined));
177004
177099
  return info; // Always return json, even though it contains an error code.
177005
177100
  }
177006
- catch {
177101
+ catch (err) {
177007
177102
  ArcGisUtilities._serviceCache.set(url, undefined);
177103
+ if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_1__.MapLayerUntrustedOriginError)
177104
+ throw err; // propagate so callers can report the blocked origin
177008
177105
  return undefined;
177009
177106
  }
177010
177107
  }
@@ -177166,7 +177263,9 @@ class ArcGISImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE_0__.
177166
177263
  try {
177167
177264
  metadata = await _tile_internal__WEBPACK_IMPORTED_MODULE_0__.ArcGisUtilities.getServiceJson({ url: this._settings.url, formatId: this._settings.formatId, userName: this._settings.userName, password: this._settings.password, queryParams: this._settings.collectQueryParams() });
177168
177265
  }
177169
- catch {
177266
+ catch (err) {
177267
+ if (err instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError)
177268
+ this.reportBlockedOrigin(err.url);
177170
177269
  }
177171
177270
  if (metadata && metadata.accessTokenRequired) {
177172
177271
  const accessClient = _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.mapLayerFormatRegistry.getAccessClient(this._settings.formatId);
@@ -177214,12 +177313,32 @@ class ArcGISImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE_0__.
177214
177313
  await this._firstRequestPromise;
177215
177314
  let response;
177216
177315
  try {
177217
- response = await fetch(urlObj, { ...options, credentials: this._includeUserCredentials ? "include" : undefined });
177316
+ const requestUrl = urlObj.toString();
177317
+ const includeCredentials = this.includeUserCredentials(requestUrl);
177318
+ response = await fetch(urlObj, {
177319
+ ...options,
177320
+ credentials: includeCredentials ? "include" : undefined,
177321
+ redirect: includeCredentials ? this.credentialedRedirect : options?.redirect,
177322
+ });
177323
+ if (includeCredentials)
177324
+ this.checkCredentialedRedirect(requestUrl, response);
177218
177325
  if (response.status === 401 && !this._lastAccessToken && (0,_request_utils__WEBPACK_IMPORTED_MODULE_3__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
177219
- // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
177220
- response = await fetch(urlObj, { ...options, credentials: "include" });
177221
- if (response.status === 200) {
177222
- this._includeUserCredentials = true; // avoid going through 401 challenges over and over
177326
+ // fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
177327
+ const challengedUrl = response.url || requestUrl;
177328
+ if (this.isSsoAllowed(challengedUrl)) {
177329
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication).
177330
+ this.logUntrustedOriginUse(challengedUrl);
177331
+ response = await fetch(challengedUrl, {
177332
+ ...options,
177333
+ credentials: "include",
177334
+ redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
177335
+ });
177336
+ if (response.status === 200) {
177337
+ this.recordSsoSucceeded(challengedUrl); // avoid going through 401 challenges over and over for this origin
177338
+ }
177339
+ }
177340
+ else {
177341
+ this.reportBlockedOrigin(challengedUrl);
177223
177342
  }
177224
177343
  }
177225
177344
  if ((this._lastAccessToken && response.status === 400)
@@ -177432,8 +177551,12 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
177432
177551
  }
177433
177552
  async initialize() {
177434
177553
  const metadata = await this.getServiceJson();
177435
- if (metadata?.content === undefined)
177554
+ if (metadata?.content === undefined) {
177555
+ // By returning (i.e., not throwing), we ensure the tile tree gets created and the current provider is preserved to report status.
177556
+ if (this.status === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerImageryProviderStatus.UntrustedOrigin)
177557
+ return;
177436
177558
  throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_0__.ServerError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_5__.IModelStatus.ValidationFailed, "");
177559
+ }
177437
177560
  const json = metadata.content;
177438
177561
  if (json?.error?.code === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.ArcGisErrorCode.TokenRequired
177439
177562
  || json?.error?.code === _tile_internal__WEBPACK_IMPORTED_MODULE_2__.ArcGisErrorCode.InvalidToken
@@ -177518,7 +177641,7 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
177518
177641
  addLogoCards(cards) {
177519
177642
  if (!cards.dataset.arcGisLogoCard) {
177520
177643
  cards.dataset.arcGisLogoCard = "true";
177521
- cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.makeLogoCard({ heading: "ArcGIS", notice: this._copyrightText }));
177644
+ cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_1__.IModelApp.makeLogoCard({ heading: "ArcGIS", noticeLines: [this._copyrightText] }));
177522
177645
  }
177523
177646
  }
177524
177647
  async addAttributions(cards, _vp) {
@@ -177559,7 +177682,7 @@ class ArcGISMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MOD
177559
177682
  if (json && Array.isArray(json.results)) {
177560
177683
  for (const result of json.results) {
177561
177684
  if (result.attributes !== undefined && result.attributes[result.displayFieldName] !== undefined) {
177562
- const thisString = `${result.displayFieldName}: ${result.attributes[result.displayFieldName]}`;
177685
+ const thisString = `${(0,_tile_internal__WEBPACK_IMPORTED_MODULE_2__.escapeHtml)(String(result.displayFieldName))}: ${(0,_tile_internal__WEBPACK_IMPORTED_MODULE_2__.escapeHtml)(String(result.attributes[result.displayFieldName]))}`;
177563
177686
  if (!stringSet.has(thisString)) {
177564
177687
  strings.push(thisString);
177565
177688
  stringSet.add(thisString);
@@ -177875,13 +177998,7 @@ class BingMapsImageryLayerProvider extends _tile_internal__WEBPACK_IMPORTED_MODU
177875
177998
  const copyrights = [];
177876
177999
  for (const match of matchingAttributions)
177877
178000
  copyrights.push(match.copyrightMessage);
177878
- let copyrightMsg = "";
177879
- for (let i = 0; i < copyrights.length; ++i) {
177880
- if (i > 0)
177881
- copyrightMsg += "<br>";
177882
- copyrightMsg += copyrights[i];
177883
- }
177884
- cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.makeLogoCard({ iconSrc: `${_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.publicPath}images/bing.svg`, heading: "Microsoft Bing", notice: copyrightMsg }));
178001
+ cards.appendChild(_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.makeLogoCard({ iconSrc: `${_IModelApp__WEBPACK_IMPORTED_MODULE_2__.IModelApp.publicPath}images/bing.svg`, heading: "Microsoft Bing", noticeLines: copyrights }));
177885
178002
  }
177886
178003
  async addAttributions(cards, vp) {
177887
178004
  // eslint-disable-next-line @typescript-eslint/no-deprecated
@@ -178490,7 +178607,10 @@ class WmsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODULE
178490
178607
  // Don't throw error if unauthorized status:
178491
178608
  // We want the tile tree to be created, so that end-user can get feedback on which layer is missing credentials.
178492
178609
  // When credentials will be provided, a new provider will be created, and initialization should be fine.
178493
- if (error?.status === 401) {
178610
+ if (error instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError) {
178611
+ this.reportBlockedOrigin(error.url);
178612
+ }
178613
+ else if (error?.status === 401) {
178494
178614
  this.setStatus(_tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerImageryProviderStatus.RequireAuth);
178495
178615
  }
178496
178616
  else {
@@ -178652,7 +178772,8 @@ class WmtsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODUL
178652
178772
  }
178653
178773
  async initialize() {
178654
178774
  try {
178655
- this._capabilities = await _tile_internal__WEBPACK_IMPORTED_MODULE_2__.WmtsCapabilities.create(this._baseUrl);
178775
+ const credentials = (this._settings.userName && this._settings.password ? { user: this._settings.userName, password: this._settings.password } : undefined);
178776
+ this._capabilities = await _tile_internal__WEBPACK_IMPORTED_MODULE_2__.WmtsCapabilities.create(this._baseUrl, credentials);
178656
178777
  this.initPreferredTileMatrixSet();
178657
178778
  this.initPreferredStyle();
178658
178779
  this.initDisplayedLayer();
@@ -178665,7 +178786,10 @@ class WmtsMapLayerImageryProvider extends _tile_internal__WEBPACK_IMPORTED_MODUL
178665
178786
  // Don't throw error if unauthorized status:
178666
178787
  // We want the tile tree to be created, so that end-user can get feedback on which layer is missing credentials.
178667
178788
  // When credentials will be provided, a new provider will be created, and initialization should be fine.
178668
- if (error?.status === 401) {
178789
+ if (error instanceof _tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerUntrustedOriginError) {
178790
+ this.reportBlockedOrigin(error.url);
178791
+ }
178792
+ else if (error?.status === 401) {
178669
178793
  this.setStatus(_tile_internal__WEBPACK_IMPORTED_MODULE_2__.MapLayerImageryProviderStatus.RequireAuth);
178670
178794
  }
178671
178795
  else {
@@ -179476,14 +179600,18 @@ __webpack_require__.r(__webpack_exports__);
179476
179600
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
179477
179601
  /* harmony export */ WmsUtilities: () => (/* binding */ WmsUtilities)
179478
179602
  /* harmony export */ });
179479
- /* harmony import */ var _request_Request__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../request/Request */ "../../core/frontend/lib/esm/request/Request.js");
179480
- /* harmony import */ var _request_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../request/utils */ "../../core/frontend/lib/esm/request/utils.js");
179603
+ /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
179604
+ /* harmony import */ var _request_Request__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../request/Request */ "../../core/frontend/lib/esm/request/Request.js");
179605
+ /* harmony import */ var _request_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../request/utils */ "../../core/frontend/lib/esm/request/utils.js");
179606
+ /* harmony import */ var _tile_internal__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../tile/internal */ "../../core/frontend/lib/esm/tile/internal.js");
179481
179607
  /*---------------------------------------------------------------------------------------------
179482
179608
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
179483
179609
  * See LICENSE.md in the project root for license terms and full copyright notice.
179484
179610
  *--------------------------------------------------------------------------------------------*/
179485
179611
 
179486
179612
 
179613
+
179614
+
179487
179615
  /** @packageDocumentation
179488
179616
  * @module Tiles
179489
179617
  */
@@ -179500,16 +179628,35 @@ class WmsUtilities {
179500
179628
  static async fetchXml(url, credentials) {
179501
179629
  let headers;
179502
179630
  if (credentials && credentials.user && credentials.password) {
179503
- headers = new Headers();
179504
- (0,_request_utils__WEBPACK_IMPORTED_MODULE_1__.setBasicAuthorization)(headers, credentials);
179631
+ // Basic credentials are considered settings-derived credentials for this source. When the registry is
179632
+ // enforcing trusted origins, the source URL itself is the only implicitly trusted origin for basic auth;
179633
+ // opaque/custom-protocol URLs have no network origin and must therefore be treated as untrusted.
179634
+ const allowBasicAuth = !_IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins
179635
+ || _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, url);
179636
+ if (allowBasicAuth) {
179637
+ headers = new Headers();
179638
+ (0,_request_utils__WEBPACK_IMPORTED_MODULE_2__.setBasicAuthorization)(headers, credentials);
179639
+ }
179505
179640
  }
179506
179641
  let response = await fetch(url, { method: "GET", headers });
179507
- if (!credentials && response.status === 401 && (0,_request_utils__WEBPACK_IMPORTED_MODULE_1__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
179508
- // We got a http 401 challenge, lets try SSO (i.e. Windows Authentication)
179509
- response = await fetch(url, { method: "GET", credentials: "include" });
179642
+ if (!headers && credentials && credentials.user && credentials.password && (response.status === 401 || response.status === 403)) {
179643
+ throw new _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError(url);
179644
+ }
179645
+ if (!credentials && response.status === 401 && (0,_request_utils__WEBPACK_IMPORTED_MODULE_2__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
179646
+ // fetch follows redirects transparently, so trust decisions target the final (post-redirect) URL.
179647
+ const challengedUrl = response.url || url;
179648
+ if (!_IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(challengedUrl))
179649
+ throw new _tile_internal__WEBPACK_IMPORTED_MODULE_3__.MapLayerUntrustedOriginError(challengedUrl);
179650
+ _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(challengedUrl);
179651
+ // We got a http 401 challenge, lets try SSO (i.e. Windows Authentication).
179652
+ response = await fetch(challengedUrl, {
179653
+ method: "GET",
179654
+ credentials: "include",
179655
+ redirect: _IModelApp__WEBPACK_IMPORTED_MODULE_0__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined,
179656
+ });
179510
179657
  }
179511
179658
  if (response.status !== 200)
179512
- throw new _request_Request__WEBPACK_IMPORTED_MODULE_0__.HttpResponseError(response.status, await response.text());
179659
+ throw new _request_Request__WEBPACK_IMPORTED_MODULE_1__.HttpResponseError(response.status, await response.text());
179513
179660
  return response.text();
179514
179661
  }
179515
179662
  }
@@ -191923,6 +192070,7 @@ __webpack_require__.r(__webpack_exports__);
191923
192070
  /* harmony export */ MapLayerSourceStatus: () => (/* reexport safe */ _map_MapLayerSources__WEBPACK_IMPORTED_MODULE_86__.MapLayerSourceStatus),
191924
192071
  /* harmony export */ MapLayerSources: () => (/* reexport safe */ _map_MapLayerSources__WEBPACK_IMPORTED_MODULE_86__.MapLayerSources),
191925
192072
  /* harmony export */ MapLayerTileTreeReference: () => (/* reexport safe */ _map_MapLayerTileTreeReference__WEBPACK_IMPORTED_MODULE_64__.MapLayerTileTreeReference),
192073
+ /* harmony export */ MapLayerUntrustedOriginError: () => (/* reexport safe */ _map_MapLayerFormatRegistry__WEBPACK_IMPORTED_MODULE_42__.MapLayerUntrustedOriginError),
191926
192074
  /* harmony export */ MapTile: () => (/* reexport safe */ _map_MapTile__WEBPACK_IMPORTED_MODULE_70__.MapTile),
191927
192075
  /* harmony export */ MapTileLoader: () => (/* reexport safe */ _internal_tile_map_MapTileLoader__WEBPACK_IMPORTED_MODULE_72__.MapTileLoader),
191928
192076
  /* harmony export */ MapTileProjection: () => (/* reexport safe */ _map_MapTile__WEBPACK_IMPORTED_MODULE_70__.MapTileProjection),
@@ -192002,6 +192150,7 @@ __webpack_require__.r(__webpack_exports__);
192002
192150
  /* harmony export */ collectMaskRefs: () => (/* reexport safe */ _internal_tile_PrimaryTileTree__WEBPACK_IMPORTED_MODULE_82__.collectMaskRefs),
192003
192151
  /* harmony export */ compareMapLayer: () => (/* reexport safe */ _internal_render_webgl_MapLayerParams__WEBPACK_IMPORTED_MODULE_94__.compareMapLayer),
192004
192152
  /* harmony export */ computeCesiumTokenTimeoutInterval: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.computeCesiumTokenTimeoutInterval),
192153
+ /* harmony export */ computeOrthometricVerticalShift: () => (/* reexport safe */ _internal_tile_OrbitGtTileTree__WEBPACK_IMPORTED_MODULE_84__.computeOrthometricVerticalShift),
192005
192154
  /* harmony export */ createClassifierTileTreeReference: () => (/* reexport safe */ _internal_tile_ClassifierTileTree__WEBPACK_IMPORTED_MODULE_83__.createClassifierTileTreeReference),
192006
192155
  /* harmony export */ createDefaultViewFlagOverrides: () => (/* reexport safe */ _internal_tile_ViewFlagOverrides__WEBPACK_IMPORTED_MODULE_0__.createDefaultViewFlagOverrides),
192007
192156
  /* harmony export */ createGraphicFromDescription: () => (/* reexport safe */ _internal_tile_ImdlGraphicsCreator__WEBPACK_IMPORTED_MODULE_37__.createGraphicFromDescription),
@@ -192018,6 +192167,7 @@ __webpack_require__.r(__webpack_exports__);
192018
192167
  /* harmony export */ decodeMeshoptBuffer: () => (/* reexport safe */ _internal_tile_MeshoptCompression__WEBPACK_IMPORTED_MODULE_93__.decodeMeshoptBuffer),
192019
192168
  /* harmony export */ deflateCoordinates: () => (/* reexport safe */ _internal_tile_map_ImageryProviders_CoordinatesUtils__WEBPACK_IMPORTED_MODULE_47__.deflateCoordinates),
192020
192169
  /* harmony export */ disposeTileTreesForGeometricModels: () => (/* reexport safe */ _internal_tile_PrimaryTileTree__WEBPACK_IMPORTED_MODULE_82__.disposeTileTreesForGeometricModels),
192170
+ /* harmony export */ escapeHtml: () => (/* reexport safe */ _map_MapLayerImageryProvider__WEBPACK_IMPORTED_MODULE_49__.escapeHtml),
192021
192171
  /* harmony export */ getCesiumAccessClient: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAccessClient),
192022
192172
  /* harmony export */ getCesiumAccessTokenAndEndpointUrl: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAccessTokenAndEndpointUrl),
192023
192173
  /* harmony export */ getCesiumAssetUrl: () => (/* reexport safe */ _map_CesiumTerrainProvider__WEBPACK_IMPORTED_MODULE_68__.getCesiumAssetUrl),
@@ -192037,7 +192187,8 @@ __webpack_require__.r(__webpack_exports__);
192037
192187
  /* harmony export */ readImdlContent: () => (/* reexport safe */ _ImdlReader__WEBPACK_IMPORTED_MODULE_35__.readImdlContent),
192038
192188
  /* harmony export */ readPntsColors: () => (/* reexport safe */ _internal_tile_PntsReader__WEBPACK_IMPORTED_MODULE_76__.readPntsColors),
192039
192189
  /* harmony export */ readPointCloudTileContent: () => (/* reexport safe */ _internal_tile_PntsReader__WEBPACK_IMPORTED_MODULE_76__.readPointCloudTileContent),
192040
- /* harmony export */ tileTreeReferenceFromRenderGraphic: () => (/* reexport safe */ _RenderGraphicTileTree__WEBPACK_IMPORTED_MODULE_78__.tileTreeReferenceFromRenderGraphic)
192190
+ /* harmony export */ tileTreeReferenceFromRenderGraphic: () => (/* reexport safe */ _RenderGraphicTileTree__WEBPACK_IMPORTED_MODULE_78__.tileTreeReferenceFromRenderGraphic),
192191
+ /* harmony export */ tryGetOrigin: () => (/* reexport safe */ _map_MapLayerImageryProvider__WEBPACK_IMPORTED_MODULE_49__.tryGetOrigin)
192041
192192
  /* harmony export */ });
192042
192193
  /* harmony import */ var _internal_tile_ViewFlagOverrides__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../internal/tile/ViewFlagOverrides */ "../../core/frontend/lib/esm/internal/tile/ViewFlagOverrides.js");
192043
192194
  /* harmony import */ var _map_MapCartoRectangle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./map/MapCartoRectangle */ "../../core/frontend/lib/esm/tile/map/MapCartoRectangle.js");
@@ -193736,7 +193887,8 @@ __webpack_require__.r(__webpack_exports__);
193736
193887
  __webpack_require__.r(__webpack_exports__);
193737
193888
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
193738
193889
  /* harmony export */ MapLayerFormat: () => (/* binding */ MapLayerFormat),
193739
- /* harmony export */ MapLayerFormatRegistry: () => (/* binding */ MapLayerFormatRegistry)
193890
+ /* harmony export */ MapLayerFormatRegistry: () => (/* binding */ MapLayerFormatRegistry),
193891
+ /* harmony export */ MapLayerUntrustedOriginError: () => (/* binding */ MapLayerUntrustedOriginError)
193740
193892
  /* harmony export */ });
193741
193893
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
193742
193894
  /* harmony import */ var _IModelApp__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../IModelApp */ "../../core/frontend/lib/esm/IModelApp.js");
@@ -193751,7 +193903,7 @@ __webpack_require__.r(__webpack_exports__);
193751
193903
 
193752
193904
 
193753
193905
 
193754
- const loggerCategory = "ArcGISFeatureProvider";
193906
+ const loggerCategory = "MapLayerFormatRegistry";
193755
193907
  /**
193756
193908
  * Class representing a map-layer format.
193757
193909
  * Each format has it's unique 'formatId' string, used to uniquely identify a format in the [[MapLayerFormatRegistry]].
@@ -193800,16 +193952,127 @@ class MapLayerFormat {
193800
193952
  return undefined;
193801
193953
  }
193802
193954
  }
193955
+ /** Error thrown when an NTLM or Negotiate http 401 challenge could not be answered because the request
193956
+ * URL's origin is not listed in [[MapLayerFormatRegistry.trustedCredentialsOrigins]]
193957
+ * (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
193958
+ * Thrown by the static map-layer utilities (e.g. capabilities / service-metadata fetches) that have no
193959
+ * provider instance on which to report the blocked origin; callers convert it to
193960
+ * [[MapLayerImageryProviderStatus.UntrustedOrigin]] (provider initialization) or
193961
+ * [[MapLayerSourceStatus.UntrustedOrigin]] (source validation).
193962
+ * @internal
193963
+ */
193964
+ class MapLayerUntrustedOriginError extends Error {
193965
+ /** The URL of the request whose authentication challenge was left unanswered. */
193966
+ url;
193967
+ constructor(url) {
193968
+ super(`Authentication blocked: origin of '${url}' is not listed in MapLayerFormatRegistry.trustedCredentialsOrigins`);
193969
+ this.url = url;
193970
+ }
193971
+ }
193803
193972
  /**
193804
193973
  * A registry of MapLayerFormats identified by their unique format IDs. The registry can be accessed via [[IModelApp.mapLayerFormatRegistry]].
193805
193974
  * @public
193806
193975
  */
193807
193976
  class MapLayerFormatRegistry {
193808
193977
  _configOptions;
193978
+ _trustedCredentialsOrigins = [];
193979
+ /** Opt-in enforcement of origin restrictions on map-layer credentials.
193980
+ * When enabled, map layer providers:
193981
+ * - attach the basic-auth credentials stored in the layer settings only to requests targeting the origin
193982
+ * of the layer's settings URL or an origin listed in [[trustedCredentialsOrigins]];
193983
+ * - retry a request with browser credentials included (i.e. SSO / Windows Authentication) after an NTLM
193984
+ * or Negotiate http 401 challenge only for origins explicitly listed in [[trustedCredentialsOrigins]]
193985
+ * (the settings-URL origin is NOT implicitly trusted for SSO, since map-layer URLs may originate from
193986
+ * untrusted user input while SSO shares the user's ambient identity).
193987
+ * Default is false, preserving the legacy behavior of sending credentials to any request URL.
193988
+ * @beta
193989
+ */
193990
+ restrictCredentialsToTrustedOrigins = false;
193809
193991
  constructor(opts) {
193810
193992
  this._configOptions = opts ?? {};
193811
193993
  _internal__WEBPACK_IMPORTED_MODULE_2__.internalMapLayerImageryFormats.forEach((format) => this.register(format));
193812
193994
  }
193995
+ /** Origins (e.g. "https://tiles.example.com") to which map layer providers may send credentials —
193996
+ * both the basic-auth credentials stored in the layer settings and browser credentials for
193997
+ * SSO (i.e. Windows Authentication) retries after an NTLM or Negotiate http 401 challenge.
193998
+ * Only enforced when [[restrictCredentialsToTrustedOrigins]] is enabled.
193999
+ * For basic-auth, the origin of each map layer's settings URL is always implicitly trusted; for SSO,
194000
+ * origins must be explicitly listed here.
194001
+ * Entries are normalized to their origin (scheme + host + port); only `http:` and `https:` URLs are accepted,
194002
+ * and any other entry is ignored and logged. Opaque schemes such as `file:`, `data:`, `about:` and custom
194003
+ * Electron protocols are rejected because they all share the same serialized origin, so trusting one would
194004
+ * trust every other.
194005
+ * @beta
194006
+ */
194007
+ get trustedCredentialsOrigins() {
194008
+ return this._trustedCredentialsOrigins;
194009
+ }
194010
+ set trustedCredentialsOrigins(origins) {
194011
+ const normalized = [];
194012
+ for (const entry of origins) {
194013
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(entry);
194014
+ if (origin !== undefined)
194015
+ normalized.push(origin);
194016
+ else
194017
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(loggerCategory, `trustedCredentialsOrigins: ignoring '${entry}'; entries must be http or https URLs.`);
194018
+ }
194019
+ this._trustedCredentialsOrigins = normalized;
194020
+ }
194021
+ /** Returns true if a request to the given URL may be retried with browser credentials included
194022
+ * (i.e. SSO / Windows Authentication) after an NTLM or Negotiate http 401 challenge.
194023
+ * Always true unless [[restrictCredentialsToTrustedOrigins]] is enabled (opt-in).
194024
+ * When enabled, the URL's origin must be explicitly listed in [[trustedCredentialsOrigins]];
194025
+ * unlike basic-auth, the settings-URL origin is NOT implicitly trusted because SSO shares the user's
194026
+ * ambient identity, and map-layer URLs may originate from untrusted user input.
194027
+ * @internal
194028
+ */
194029
+ isSsoAllowed(url) {
194030
+ if (!this.restrictCredentialsToTrustedOrigins)
194031
+ return true;
194032
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url);
194033
+ // Entries are normalized to their origin by the [[trustedCredentialsOrigins]] setter.
194034
+ return origin !== undefined && this._trustedCredentialsOrigins.includes(origin);
194035
+ }
194036
+ /** Returns true if the basic-auth credentials belonging to a map-layer source or settings URL may be
194037
+ * attached to a request to the given URL. Always true unless [[restrictCredentialsToTrustedOrigins]]
194038
+ * is enabled (opt-in). When enabled, the origin of `settingsUrl` is implicitly trusted (the credentials
194039
+ * belong to that server); any other origin must be listed in [[trustedCredentialsOrigins]].
194040
+ * @internal
194041
+ */
194042
+ isCredentialsSharingAllowed(url, settingsUrl) {
194043
+ if (!this.restrictCredentialsToTrustedOrigins)
194044
+ return true;
194045
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url);
194046
+ if (origin === undefined)
194047
+ return false;
194048
+ if (origin === (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(settingsUrl))
194049
+ return true;
194050
+ // Entries are normalized to their origin by the [[trustedCredentialsOrigins]] setter.
194051
+ return this._trustedCredentialsOrigins.includes(origin);
194052
+ }
194053
+ /** Origins for which a "credentials sent to untrusted origin" warning was already logged;
194054
+ * used to log the discovery warning only once per origin.
194055
+ */
194056
+ _untrustedUseLogged = new Set();
194057
+ /** Logs a warning (once per origin) when credentials are sent to an origin that would be blocked
194058
+ * if [[restrictCredentialsToTrustedOrigins]] were enabled.
194059
+ * Helps applications discover the origins they need to whitelist before opting in to the restriction.
194060
+ * If `settingsUrl` is supplied, requests sharing its origin are not logged, since that origin is
194061
+ * implicitly trusted for basic-auth.
194062
+ * @internal
194063
+ */
194064
+ logUntrustedOriginUse(url, settingsUrl) {
194065
+ if (this.restrictCredentialsToTrustedOrigins)
194066
+ return; // restriction active; nothing to preview
194067
+ const origin = (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(url) ?? url;
194068
+ if (settingsUrl !== undefined && origin === (0,_internal__WEBPACK_IMPORTED_MODULE_2__.tryGetOrigin)(settingsUrl))
194069
+ return; // implicitly trusted for basic-auth
194070
+ if (this._untrustedUseLogged.has(origin) || this._trustedCredentialsOrigins.includes(origin))
194071
+ return;
194072
+ this._untrustedUseLogged.add(origin);
194073
+ _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logWarning(loggerCategory, `Credentials sent to origin '${origin}' which is not in MapLayerFormatRegistry.trustedCredentialsOrigins; `
194074
+ + "this request would be blocked if restrictCredentialsToTrustedOrigins were enabled.");
194075
+ }
193813
194076
  _formats = new Map();
193814
194077
  isRegistered(formatId) { return this._formats.get(formatId) !== undefined; }
193815
194078
  register(formatClass) {
@@ -193975,6 +194238,14 @@ class WmsMapLayerFormat extends ImageryMapLayerFormat {
193975
194238
  return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.Valid, subLayers };
193976
194239
  }
193977
194240
  catch (err) {
194241
+ if (err instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError) {
194242
+ let blockedOrigin;
194243
+ try {
194244
+ blockedOrigin = new URL(err.url).origin;
194245
+ }
194246
+ catch { /* non-hierarchical URL */ }
194247
+ return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
194248
+ }
193978
194249
  let status = _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidUrl;
193979
194250
  if (err?.status === 401) {
193980
194251
  status = ((userName && password) ? _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidCredentials : _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.RequireAuth);
@@ -194040,6 +194311,14 @@ class WmtsMapLayerFormat extends ImageryMapLayerFormat {
194040
194311
  return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.Valid, subLayers };
194041
194312
  }
194042
194313
  catch (err) {
194314
+ if (err instanceof _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerUntrustedOriginError) {
194315
+ let blockedOrigin;
194316
+ try {
194317
+ blockedOrigin = new URL(err.url).origin;
194318
+ }
194319
+ catch { /* non-hierarchical URL */ }
194320
+ return { status: _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.UntrustedOrigin, blockedOrigin };
194321
+ }
194043
194322
  let status = _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidUrl;
194044
194323
  if (err?.status === 401) {
194045
194324
  status = ((userName && password) ? _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.InvalidCredentials : _internal__WEBPACK_IMPORTED_MODULE_0__.MapLayerSourceStatus.RequireAuth);
@@ -194104,7 +194383,9 @@ const internalMapLayerImageryFormats = [WmsMapLayerFormat, WmtsMapLayerFormat, A
194104
194383
  __webpack_require__.r(__webpack_exports__);
194105
194384
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
194106
194385
  /* harmony export */ MapLayerImageryProvider: () => (/* binding */ MapLayerImageryProvider),
194107
- /* harmony export */ MapLayerImageryProviderStatus: () => (/* binding */ MapLayerImageryProviderStatus)
194386
+ /* harmony export */ MapLayerImageryProviderStatus: () => (/* binding */ MapLayerImageryProviderStatus),
194387
+ /* harmony export */ escapeHtml: () => (/* binding */ escapeHtml),
194388
+ /* harmony export */ tryGetOrigin: () => (/* binding */ tryGetOrigin)
194108
194389
  /* harmony export */ });
194109
194390
  /* harmony import */ var _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @itwin/core-bentley */ "../../core/bentley/lib/esm/core-bentley.js");
194110
194391
  /* harmony import */ var _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @itwin/core-common */ "../../core/common/lib/esm/core-common.js");
@@ -194131,6 +194412,34 @@ __webpack_require__.r(__webpack_exports__);
194131
194412
  const tileImageSize = 256, untiledImageSize = 256;
194132
194413
  const earthRadius = 6378137;
194133
194414
  const doDebugToolTips = false;
194415
+ /** Escapes HTML metacharacters so the text renders literally when assigned to `innerHTML`.
194416
+ * Use for any server- or user-supplied string that ends up in the map tooltip, which is rendered
194417
+ * as HTML by [[MapLayerTileTreeReference.getToolTip]].
194418
+ * @internal
194419
+ */
194420
+ function escapeHtml(text) {
194421
+ return text.replace(/[&<>"']/g, (c) => `&#${c.charCodeAt(0)};`);
194422
+ }
194423
+ /** Returns the origin (scheme + host + port) of the given URL, or undefined if it cannot be parsed or does
194424
+ * not denote a distinct network origin.
194425
+ *
194426
+ * Only `http:` and `https:` URLs yield an origin. Every other scheme is rejected because opaque URLs
194427
+ * — `file:`, `data:`, `about:`, `blob:null`, and the custom protocols Electron hosts commonly register —
194428
+ * all serialize to the literal string `"null"`. Comparing those would make unrelated URLs look same-origin,
194429
+ * so a single trusted entry could unlock all of them. Callers use this for credential-trust decisions, and
194430
+ * returning `undefined` keeps those decisions fail-closed.
194431
+ * @internal
194432
+ */
194433
+ function tryGetOrigin(url) {
194434
+ let parsed;
194435
+ try {
194436
+ parsed = new URL(url);
194437
+ }
194438
+ catch {
194439
+ return undefined;
194440
+ }
194441
+ return (parsed.protocol === "http:" || parsed.protocol === "https:") ? parsed.origin : undefined;
194442
+ }
194134
194443
  /** The status of the map layer imagery provider that lets you know if authentication is needed to request tiles.
194135
194444
  * @public
194136
194445
  */
@@ -194138,6 +194447,12 @@ var MapLayerImageryProviderStatus;
194138
194447
  (function (MapLayerImageryProviderStatus) {
194139
194448
  MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["Valid"] = 0] = "Valid";
194140
194449
  MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["RequireAuth"] = 1] = "RequireAuth";
194450
+ /** A request received an authentication challenge, but credentials were withheld because the request origin
194451
+ * is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
194452
+ * The blocked origins are available via [[MapLayerImageryProvider.blockedOrigins]].
194453
+ * @beta
194454
+ */
194455
+ MapLayerImageryProviderStatus[MapLayerImageryProviderStatus["UntrustedOrigin"] = 2] = "UntrustedOrigin";
194141
194456
  })(MapLayerImageryProviderStatus || (MapLayerImageryProviderStatus = {}));
194142
194457
  /** Abstract class for map layer imagery providers.
194143
194458
  * Map layer imagery providers request and provide tile images and other data. Each map layer from a separate source needs its own imagery provider object.
@@ -194155,7 +194470,41 @@ class MapLayerImageryProvider {
194155
194470
  /** @internal */
194156
194471
  _status = MapLayerImageryProviderStatus.Valid;
194157
194472
  /** @internal */
194158
- _includeUserCredentials = false;
194473
+ _blockedOrigins = new Set();
194474
+ /** Origins of requests for which credentials were withheld because they are not trusted
194475
+ * (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
194476
+ * Populated when [[status]] transitions to [[MapLayerImageryProviderStatus.UntrustedOrigin]];
194477
+ * [[onStatusChanged]] is raised again each time a new origin is added. Cleared by [[resetStatus]].
194478
+ * @beta
194479
+ */
194480
+ get blockedOrigins() { return [...this._blockedOrigins]; }
194481
+ /** Origins for which a previous SSO handshake (i.e. Windows Authentication) succeeded.
194482
+ * Browser credentials are only included for subsequent requests targeting these origins,
194483
+ * so that a successful handshake with one host does not leak credentials to other hosts
194484
+ * this provider may contact.
194485
+ * @internal
194486
+ */
194487
+ _ssoSucceededOrigins = new Set();
194488
+ /** Returns true if browser credentials should be included for the given URL because a previous
194489
+ * SSO handshake succeeded for its origin AND the origin is still allowed by the current policy
194490
+ * (see [[MapLayerFormatRegistry.isSsoAllowed]]). Re-checking the policy ensures a handshake recorded
194491
+ * while enforcement was disabled — or before an origin was removed from
194492
+ * [[MapLayerFormatRegistry.trustedCredentialsOrigins]] — does not keep latching credentials on.
194493
+ * @internal
194494
+ */
194495
+ includeUserCredentials(url) {
194496
+ const origin = tryGetOrigin(url);
194497
+ return origin !== undefined && this._ssoSucceededOrigins.has(origin) && this.isSsoAllowed(url);
194498
+ }
194499
+ /** Records that an SSO handshake succeeded for the given URL's origin, so subsequent requests
194500
+ * to that origin include browser credentials without going through another 401 challenge.
194501
+ * @internal
194502
+ */
194503
+ recordSsoSucceeded(url) {
194504
+ const origin = tryGetOrigin(url);
194505
+ if (origin !== undefined)
194506
+ this._ssoSucceededOrigins.add(origin);
194507
+ }
194159
194508
  /** @internal */
194160
194509
  onFirstRequestCompleted = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
194161
194510
  /** @internal */
@@ -194171,7 +194520,17 @@ class MapLayerImageryProvider {
194171
194520
  * @public
194172
194521
  */
194173
194522
  get supportsMapFeatureInfo() { return false; }
194174
- resetStatus() { this.setStatus(MapLayerImageryProviderStatus.Valid); }
194523
+ /** Reset the provider's status to [[MapLayerImageryProviderStatus.Valid]] and clear the list of
194524
+ * [[blockedOrigins]] accumulated while in the [[MapLayerImageryProviderStatus.UntrustedOrigin]] state.
194525
+ * Raises [[onStatusChanged]] if the status actually changes.
194526
+ * Typically called after the user has provided credentials or the application has updated
194527
+ * [[MapLayerFormatRegistry.trustedCredentialsOrigins]], so that subsequent requests are re-attempted.
194528
+ * @beta
194529
+ */
194530
+ resetStatus() {
194531
+ this._blockedOrigins.clear();
194532
+ this.setStatus(MapLayerImageryProviderStatus.Valid);
194533
+ }
194175
194534
  /** @internal */
194176
194535
  get tileSize() { return this._usesCachedTiles ? tileImageSize : untiledImageSize; }
194177
194536
  /** @internal */
@@ -194345,6 +194704,32 @@ class MapLayerImageryProvider {
194345
194704
  (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.setBasicAuthorization)(headers, this._settings.userName, this._settings.password);
194346
194705
  }
194347
194706
  }
194707
+ /** Returns true if the given URL has the same origin as this layer's settings URL.
194708
+ * Used to avoid leaking credentials to third-party hosts.
194709
+ * @internal
194710
+ */
194711
+ matchesSettingsUrlOrigin(url) {
194712
+ const origin = tryGetOrigin(url);
194713
+ return origin !== undefined && origin === tryGetOrigin(this._settings.url);
194714
+ }
194715
+ /** Returns true if the basic-auth credentials from the layer settings may be attached to a request to the given URL.
194716
+ * Always true unless [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is enabled (opt-in).
194717
+ * When enabled, the origin of this layer's settings URL is implicitly trusted (the credentials belong to that
194718
+ * server); other origins must be listed in [[MapLayerFormatRegistry.trustedCredentialsOrigins]].
194719
+ * See [[MapLayerFormatRegistry.isCredentialsSharingAllowed]].
194720
+ * @internal
194721
+ */
194722
+ isCredentialsSharingAllowed(url) {
194723
+ return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.isCredentialsSharingAllowed(url, this._settings.url);
194724
+ }
194725
+ /** Returns true if a request to the given URL may be retried with browser credentials included
194726
+ * (i.e. SSO / Windows Authentication) after an NTLM or Negotiate http 401 challenge.
194727
+ * See [[MapLayerFormatRegistry.isSsoAllowed]].
194728
+ * @internal
194729
+ */
194730
+ isSsoAllowed(url) {
194731
+ return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.isSsoAllowed(url);
194732
+ }
194348
194733
  /** @internal */
194349
194734
  async makeTileRequest(url, timeoutMs, authorization) {
194350
194735
  // We want to complete the first request before letting other requests go;
@@ -194364,40 +194749,132 @@ class MapLayerImageryProvider {
194364
194749
  throw new Error("fetch call failed");
194365
194750
  return response;
194366
194751
  }
194752
+ /** Records the given URL's origin and transitions the status to [[MapLayerImageryProviderStatus.UntrustedOrigin]].
194753
+ * Called when a request received an authentication challenge that could not be answered because the origin
194754
+ * is not trusted (see [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]]).
194755
+ * Raises [[onStatusChanged]] on the status transition, and again whenever a new origin is added.
194756
+ * @internal
194757
+ */
194758
+ reportBlockedOrigin(url) {
194759
+ const origin = tryGetOrigin(url) ?? url;
194760
+ const isNewOrigin = !this._blockedOrigins.has(origin);
194761
+ this._blockedOrigins.add(origin);
194762
+ if (this._status !== MapLayerImageryProviderStatus.UntrustedOrigin)
194763
+ this.setStatus(MapLayerImageryProviderStatus.UntrustedOrigin);
194764
+ else if (isNewOrigin)
194765
+ this.onStatusChanged.raiseEvent(this); // status unchanged, but a new origin was blocked
194766
+ }
194767
+ /** Logs a warning (once per origin, app-wide) when credentials are sent to an origin that would be blocked
194768
+ * if [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] were enabled.
194769
+ * Helps applications discover the origins they need to whitelist before opting in to the restriction.
194770
+ * See [[MapLayerFormatRegistry.logUntrustedOriginUse]].
194771
+ * @internal
194772
+ */
194773
+ logUntrustedOriginUse(url) {
194774
+ _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.logUntrustedOriginUse(url);
194775
+ }
194776
+ /** The redirect policy to apply to a request that carries browser credentials (see [[includeUserCredentials]]).
194777
+ *
194778
+ * When [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is enabled, redirects are refused
194779
+ * outright (`"error"`). `fetch` cannot be asked to follow only same-origin redirects, and by the time a
194780
+ * followed redirect can be inspected the credentials have already been delivered to the destination — so
194781
+ * refusing is the only way to honour the guarantee that credentials reach none but the origins listed in
194782
+ * [[MapLayerFormatRegistry.trustedCredentialsOrigins]]. Legitimate same-origin redirects fail as a result;
194783
+ * that is the cost of the opt-in restriction.
194784
+ *
194785
+ * When the restriction is disabled (the default), redirects are followed as before and
194786
+ * [[checkCredentialedRedirect]] reports the destination after the fact.
194787
+ * @internal
194788
+ */
194789
+ get credentialedRedirect() {
194790
+ return _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined;
194791
+ }
194792
+ /** Detects that a request carrying browser credentials (see [[includeUserCredentials]]) was transparently
194793
+ * redirected to a different origin, and reports or logs that origin.
194794
+ *
194795
+ * This is a **best-effort, after-the-fact** signal used only while
194796
+ * [[MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]] is disabled, where credentialed requests
194797
+ * still follow redirects (see [[credentialedRedirect]]). It cannot prevent the exposure — the credentials
194798
+ * have already been sent — and it does not fire at all when the destination denies CORS, because `fetch`
194799
+ * then rejects instead of returning a `Response`. The destination origin is never latched as SSO-succeeded,
194800
+ * so credentials do not keep flowing to it.
194801
+ * @internal
194802
+ */
194803
+ checkCredentialedRedirect(requestedUrl, response) {
194804
+ const finalOrigin = tryGetOrigin(response.url);
194805
+ if (!response.url || finalOrigin === undefined || finalOrigin === tryGetOrigin(requestedUrl))
194806
+ return;
194807
+ if (!this.isSsoAllowed(response.url))
194808
+ this.reportBlockedOrigin(response.url);
194809
+ else
194810
+ this.logUntrustedOriginUse(response.url); // no-op when the restriction is enabled
194811
+ }
194367
194812
  /** @internal */
194368
194813
  async makeRequest(url, timeoutMs, authorization) {
194369
194814
  let response;
194370
194815
  let headers;
194371
194816
  let hasCreds = false;
194817
+ // Whether this request had basic-auth credentials of its own to offer. Requests carrying a caller-supplied
194818
+ // `authorization` are excluded: those bypass the origin policy entirely.
194819
+ const hasSettingsCreds = !authorization && !!this._settings.userName && !!this._settings.password;
194372
194820
  if (authorization) {
194373
194821
  headers = new Headers();
194374
194822
  headers.set("Authorization", authorization);
194375
194823
  }
194376
- else if (this._settings.userName && this._settings.password) {
194377
- hasCreds = true;
194378
- headers = new Headers();
194379
- this.setRequestAuthorization(headers);
194824
+ else if (hasSettingsCreds) {
194825
+ if (this.isCredentialsSharingAllowed(url)) {
194826
+ hasCreds = true;
194827
+ headers = new Headers();
194828
+ this.setRequestAuthorization(headers);
194829
+ if (!this.matchesSettingsUrlOrigin(url))
194830
+ this.logUntrustedOriginUse(url);
194831
+ }
194380
194832
  }
194833
+ const includeCredentials = this.includeUserCredentials(url);
194381
194834
  const opts = {
194382
194835
  method: "GET",
194383
194836
  headers,
194384
- credentials: this._includeUserCredentials ? "include" : undefined,
194837
+ credentials: includeCredentials ? "include" : undefined,
194838
+ redirect: includeCredentials ? this.credentialedRedirect : undefined,
194385
194839
  };
194386
194840
  if (timeoutMs !== undefined)
194387
194841
  (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.setRequestTimeout)(opts, timeoutMs);
194388
194842
  response = await fetch(url, opts);
194843
+ if (includeCredentials)
194844
+ this.checkCredentialedRedirect(url, response);
194845
+ // fetch follows redirects transparently, so all trust decisions below target the final
194846
+ // (post-redirect) URL reported by the response, not the URL we asked for.
194847
+ const challengedUrl = response.url || url;
194389
194848
  if (response.status === 401
194390
194849
  && (0,_request_utils__WEBPACK_IMPORTED_MODULE_6__.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])
194391
- && !this._includeUserCredentials
194850
+ && !includeCredentials
194392
194851
  && !hasCreds) {
194393
- // Removed the previous headers and make sure "include" credentials is set
194394
- opts.headers = undefined;
194395
- opts.credentials = "include";
194396
- // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
194397
- response = await fetch(url, opts);
194398
- if (response.status === 200) {
194399
- this._includeUserCredentials = true; // avoid going through 401 challenges over and over
194852
+ if (this.isSsoAllowed(challengedUrl)) {
194853
+ // Removed the previous headers and make sure "include" credentials is set
194854
+ opts.headers = undefined;
194855
+ opts.credentials = "include";
194856
+ // A Negotiate/NTLM handshake is normally a same-URL 401 round-trip, but in legacy mode we preserve
194857
+ // the previous behavior and allow the browser to follow redirects after the authenticated retry.
194858
+ opts.redirect = _IModelApp__WEBPACK_IMPORTED_MODULE_3__.IModelApp.mapLayerFormatRegistry.restrictCredentialsToTrustedOrigins ? "error" : undefined;
194859
+ this.logUntrustedOriginUse(challengedUrl);
194860
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
194861
+ response = await fetch(challengedUrl, opts);
194862
+ if (response.status === 200) {
194863
+ this.recordSsoSucceeded(challengedUrl); // avoid going through 401 challenges over and over for this origin
194864
+ }
194400
194865
  }
194866
+ else {
194867
+ this.reportBlockedOrigin(challengedUrl);
194868
+ }
194869
+ }
194870
+ else if ((response.status === 401 || response.status === 403) && hasSettingsCreds && !this.isCredentialsSharingAllowed(challengedUrl)) {
194871
+ // Some servers answer an unauthenticated request with 403 (Forbidden) rather than a 401 challenge;
194872
+ // since this request could not present its credentials to the challenging origin, either status most
194873
+ // likely results from that. The permission is recomputed for the challenged URL rather than reusing the
194874
+ // decision made for the requested one: `fetch` strips the Authorization header when it follows a
194875
+ // cross-origin redirect, so a trusted request can still arrive unauthenticated at an untrusted origin,
194876
+ // and conversely a request that started out untrusted may end up at an origin that is trusted.
194877
+ this.reportBlockedOrigin(challengedUrl);
194401
194878
  }
194402
194879
  return response;
194403
194880
  }
@@ -194429,16 +194906,28 @@ class MapLayerImageryProvider {
194429
194906
  }
194430
194907
  /** @internal */
194431
194908
  async toolTipFromUrl(strings, url) {
194432
- const headers = new Headers();
194433
- this.setRequestAuthorization(headers);
194909
+ let headers;
194910
+ if (this.isCredentialsSharingAllowed(url)) {
194911
+ headers = new Headers();
194912
+ this.setRequestAuthorization(headers);
194913
+ }
194434
194914
  try {
194915
+ const includeCredentials = this.includeUserCredentials(url);
194435
194916
  const response = await fetch(url, {
194436
194917
  method: "GET",
194437
194918
  headers,
194438
- credentials: this._includeUserCredentials ? "include" : undefined,
194919
+ credentials: includeCredentials ? "include" : undefined,
194920
+ redirect: includeCredentials ? this.credentialedRedirect : undefined,
194439
194921
  });
194440
- const text = await response.text();
194441
- if (undefined !== text) {
194922
+ if (includeCredentials)
194923
+ this.checkCredentialedRedirect(url, response);
194924
+ let text = await response.text();
194925
+ if (text) {
194926
+ // Tooltip content (e.g. WMS GetFeatureInfo responses) is rendered as HTML downstream and may
194927
+ // deliberately contain markup; text from origins not trusted for credentials is escaped.
194928
+ // fetch follows redirects transparently, so the text may come from a different origin than requested.
194929
+ if (!this.isCredentialsSharingAllowed(response.url || url))
194930
+ text = escapeHtml(text);
194442
194931
  strings.push(text);
194443
194932
  }
194444
194933
  }
@@ -194618,6 +195107,12 @@ var MapLayerSourceStatus;
194618
195107
  /** Format is not compatible with the URL provided.
194619
195108
  */
194620
195109
  MapLayerSourceStatus[MapLayerSourceStatus["IncompatibleFormat"] = 7] = "IncompatibleFormat";
195110
+ /** Authentication could not be attempted because the source's origin is not trusted
195111
+ * (see [MapLayerFormatRegistry.restrictCredentialsToTrustedOrigins]($frontend)). Add the origin to
195112
+ * [MapLayerFormatRegistry.trustedCredentialsOrigins]($frontend) rather than prompting for credentials.
195113
+ * @beta
195114
+ */
195115
+ MapLayerSourceStatus[MapLayerSourceStatus["UntrustedOrigin"] = 8] = "UntrustedOrigin";
194621
195116
  })(MapLayerSourceStatus || (MapLayerSourceStatus = {}));
194622
195117
  /** A source for map layers. These may be catalogued for convenient use by users or applications.
194623
195118
  * @public
@@ -194905,10 +195400,8 @@ class MapLayerTileTreeReference extends _internal__WEBPACK_IMPORTED_MODULE_3__.T
194905
195400
  const tree = this.treeOwner.tileTree;
194906
195401
  if (undefined === tree || hit.iModel !== tree.iModel || tree.modelId !== hit.sourceId)
194907
195402
  return undefined;
194908
- const strings = [];
194909
- strings.push(`Map Layer: ${this._layerSettings.name}`);
194910
195403
  const div = document.createElement("div");
194911
- div.innerHTML = strings.join("<br>");
195404
+ div.textContent = `Map Layer: ${this._layerSettings.name}`;
194912
195405
  return div;
194913
195406
  }
194914
195407
  decorate(_context) {
@@ -196617,7 +197110,9 @@ class MapTileTreeReference extends _internal__WEBPACK_IMPORTED_MODULE_7__.TileTr
196617
197110
  let carto;
196618
197111
  const strings = [];
196619
197112
  const getTooltipFunc = async (imageryTreeRef, quadId, cartoGraphic, imageryTree) => {
196620
- strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_4__.IModelApp.localization.getLocalizedString("iModelJs:MapLayers.ImageryLayer")}: ${imageryTreeRef.layerSettings.name}`);
197113
+ // innerHTML is used below because imageryLoader.getToolTip may deliberately supply markup.
197114
+ const layerName = (0,_internal__WEBPACK_IMPORTED_MODULE_7__.escapeHtml)(imageryTreeRef.layerSettings.name);
197115
+ strings.push(`${_IModelApp__WEBPACK_IMPORTED_MODULE_4__.IModelApp.localization.getLocalizedString("iModelJs:MapLayers.ImageryLayer")}: ${layerName}`);
196621
197116
  carto = cartoGraphic;
196622
197117
  await imageryTree.imageryLoader.getToolTip(strings, quadId, cartoGraphic, imageryTree);
196623
197118
  };
@@ -342457,7 +342952,7 @@ class TestContext {
342457
342952
  this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
342458
342953
  const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${process.env.IMJS_URL_PREFIX ?? ""}api.bentley.com/imodels` } });
342459
342954
  await core_frontend_1.NoRenderApp.startup({
342460
- applicationVersion: "5.13.0-dev.16",
342955
+ applicationVersion: "5.13.0-dev.18",
342461
342956
  applicationId: this.settings.gprid,
342462
342957
  authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.serviceAuthToken),
342463
342958
  hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
@@ -367652,7 +368147,7 @@ var loadLanguages = instance.loadLanguages;
367652
368147
  (module) {
367653
368148
 
367654
368149
  "use strict";
367655
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.13.0-dev.16","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.3.4","@loaders.gl/draco":"~4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
368150
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.13.0-dev.18","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.3.4","@loaders.gl/draco":"~4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
367656
368151
 
367657
368152
  /***/ },
367658
368153