@smarterplan/ngx-smarterplan-core 1.4.9 → 1.4.11

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, Input, Component, Inject, EventEmitter, isDevMode, Output, Pipe, ViewChild, NgModule } from '@angular/core';
2
+ import { Injectable, Input, Component, InjectionToken, Inject, EventEmitter, isDevMode, Output, Pipe, ViewChild, NgModule } from '@angular/core';
3
3
  import * as i1 from '@ngx-translate/core';
4
4
  import { TranslateModule } from '@ngx-translate/core';
5
5
  import { Subject, BehaviorSubject, takeUntil, Observable } from 'rxjs';
@@ -96,6 +96,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
96
96
  type: Input
97
97
  }] } });
98
98
 
99
+ /**
100
+ * Injection token holding the Matterport SDK application key.
101
+ * Each consuming app must provide its own value via its environment file
102
+ * (see app.module.ts of each app for the provider registration).
103
+ */
104
+ const MATTERPORT_SDK_KEY = new InjectionToken('MATTERPORT_SDK_KEY');
105
+
99
106
  var CameraMode;
100
107
  (function (CameraMode) {
101
108
  CameraMode["DOLLHOUSE"] = "mode.dollhouse";
@@ -734,9 +741,15 @@ class SecurityCamera extends SceneComponent {
734
741
  this.highlight = new THREE.Mesh(roomMesh.geometry, shader);
735
742
  }
736
743
  toggleViewFrustum() {
737
- this.highlight.visible = !this.highlight.visible;
738
- this.edges.visible = !this.edges.visible;
739
- this.pivot.visible = !this.pivot.visible;
744
+ if (this.highlight) {
745
+ this.highlight.visible = !this.highlight.visible;
746
+ }
747
+ if (this.edges) {
748
+ this.edges.visible = !this.edges.visible;
749
+ }
750
+ if (this.pivot) {
751
+ this.pivot.visible = !this.pivot.visible;
752
+ }
740
753
  }
741
754
  makeAnimation() {
742
755
  const THREE = this.context.three;
@@ -2227,7 +2240,67 @@ class MatterportNavigationService {
2227
2240
  currentRooms = [];
2228
2241
  /** Sequence number of the floor currently visible in sdk.Floor.current (null = single-floor or unknown). */
2229
2242
  currentFloorSequence = null;
2243
+ // ── Bidirectional sid ↔ uuid lookup maps ──
2244
+ // sid = short runtime key used by Matterport SDK (collection keys, Sweep.moveTo, Camera.pose.sweep)
2245
+ // uuid = persistent identifier stored in the database (zone.sweepIDs, poi.matterportSweepID, startSweepID)
2246
+ sidToUuid = new Map();
2247
+ uuidToSid = new Map();
2230
2248
  constructor() { }
2249
+ // ── Sweep ID translation helpers ──
2250
+ /**
2251
+ * Builds the bidirectional sid ↔ uuid maps from the sweep collection.
2252
+ * Must be called every time the sweep collection is updated.
2253
+ */
2254
+ buildSweepIdMaps(collection) {
2255
+ this.sidToUuid.clear();
2256
+ this.uuidToSid.clear();
2257
+ if (!collection)
2258
+ return;
2259
+ for (const sid of Object.keys(collection)) {
2260
+ const sweepData = collection[sid];
2261
+ const uuid = sweepData?.uuid;
2262
+ if (uuid && uuid !== sid) {
2263
+ this.sidToUuid.set(sid, uuid);
2264
+ this.uuidToSid.set(uuid, sid);
2265
+ }
2266
+ // Also map sid→sid and uuid→uuid for pass-through cases
2267
+ this.sidToUuid.set(sid, uuid || sid);
2268
+ if (uuid) {
2269
+ this.uuidToSid.set(uuid, sid);
2270
+ }
2271
+ }
2272
+ if (isDevMode()) {
2273
+ console.debug(`[MatterportNavigation] Built sweep ID maps: ${this.sidToUuid.size} sids, ${this.uuidToSid.size} uuids`);
2274
+ }
2275
+ }
2276
+ /**
2277
+ * Resolves any sweep identifier (sid or uuid) to the SDK runtime **sid**.
2278
+ * This is what sdk.Sweep.moveTo() and sdk.Sweep.disable() expect.
2279
+ * Falls back to the input if no mapping exists.
2280
+ */
2281
+ resolveSweepSid(idOrUuid) {
2282
+ if (!idOrUuid)
2283
+ return idOrUuid;
2284
+ // If it's already a known sid (exists as a key in sweepCollection), return it
2285
+ if (this.sidToUuid.has(idOrUuid))
2286
+ return idOrUuid;
2287
+ // Otherwise try to map from uuid → sid
2288
+ return this.uuidToSid.get(idOrUuid) ?? idOrUuid;
2289
+ }
2290
+ /**
2291
+ * Resolves any sweep identifier (sid or uuid) to the persistent **uuid**.
2292
+ * This is what the database stores (zone.sweepIDs, poi.matterportSweepID).
2293
+ * Falls back to the input if no mapping exists.
2294
+ */
2295
+ resolveSweepUuid(sidOrUuid) {
2296
+ if (!sidOrUuid)
2297
+ return sidOrUuid;
2298
+ // If it's already a known uuid, return it
2299
+ if (this.uuidToSid.has(sidOrUuid))
2300
+ return sidOrUuid;
2301
+ // Otherwise try to map from sid → uuid
2302
+ return this.sidToUuid.get(sidOrUuid) ?? sidOrUuid;
2303
+ }
2231
2304
  async action_toolbox_floorplan(sdk) {
2232
2305
  if (this.inTransitionMode || this.inTransitionSweep) {
2233
2306
  console.log('viewer is in transition, cannot go floorplan');
@@ -2295,15 +2368,23 @@ class MatterportNavigationService {
2295
2368
  console.warn('No matterport floor found to move to');
2296
2369
  }
2297
2370
  }
2371
+ /**
2372
+ * Navigate to a sweep. The caller can pass either a sid or a uuid;
2373
+ * this method resolves it to the SDK sid before calling Sweep.moveTo().
2374
+ */
2298
2375
  async action_go_to_sweep(sdk, sweep, rotation) {
2299
- if (this.forbiddenSweeps.includes(sweep)) {
2376
+ const resolvedSid = this.resolveSweepSid(sweep);
2377
+ if (this.forbiddenSweeps.includes(sweep) || this.forbiddenSweeps.includes(resolvedSid)) {
2300
2378
  console.log('user is not allowed to go to this sweep');
2301
2379
  return;
2302
2380
  }
2381
+ if (isDevMode() && resolvedSid !== sweep) {
2382
+ console.debug(`[action_go_to_sweep] Resolved uuid "${sweep}" → sid "${resolvedSid}"`);
2383
+ }
2303
2384
  setTimeout(async () => {
2304
2385
  try {
2305
2386
  this.inTransitionSweep = true;
2306
- await sdk.Sweep.moveTo(sweep, {
2387
+ await sdk.Sweep.moveTo(resolvedSid, {
2307
2388
  transition: sdk.Camera.TransitionType.INSTANT,
2308
2389
  transitionTime: 1500
2309
2390
  });
@@ -2317,12 +2398,16 @@ class MatterportNavigationService {
2317
2398
  }
2318
2399
  }, 1000);
2319
2400
  }
2401
+ /**
2402
+ * Disable forbidden sweeps. Resolves each sweep ID to sid before calling SDK.
2403
+ */
2320
2404
  async removeForbiddenSweeps(sdk, forbiddenSweeps) {
2321
2405
  this.forbiddenSweeps = [...forbiddenSweeps];
2322
2406
  let removed = 0;
2323
2407
  await Promise.all(forbiddenSweeps.map(async (sweep) => {
2408
+ const resolvedSid = this.resolveSweepSid(sweep);
2324
2409
  try {
2325
- await sdk.Sweep.disable(sweep);
2410
+ await sdk.Sweep.disable(resolvedSid);
2326
2411
  removed += 1;
2327
2412
  }
2328
2413
  catch (error) {
@@ -2331,8 +2416,15 @@ class MatterportNavigationService {
2331
2416
  }));
2332
2417
  console.log('removed sweeps:', removed);
2333
2418
  }
2419
+ /**
2420
+ * Returns the current sweep as a **uuid** (for database matching).
2421
+ * The SDK's poseCamera.sweep is a sid; we translate it.
2422
+ */
2334
2423
  getCurrentSweep(poseCamera) {
2335
- return poseCamera?.sweep || null;
2424
+ const sid = poseCamera?.sweep || null;
2425
+ if (!sid)
2426
+ return null;
2427
+ return this.resolveSweepUuid(sid);
2336
2428
  }
2337
2429
  setCameraMode(mode) {
2338
2430
  this.inTransitionSweep = false;
@@ -3450,8 +3542,12 @@ class MatterportTagService {
3450
3542
  if (mattertagData.elementID === elementID) {
3451
3543
  tagID = mattertagID;
3452
3544
  const sweep = mattertagData.getSweepID();
3453
- if (sweep && sweeps && sweeps.includes(sweep)) {
3454
- sweepID = sweep;
3545
+ if (sweep && sweeps) {
3546
+ // sweep is a uuid; sweeps array contains sids – check both formats
3547
+ const resolvedSid = this.navigationService.resolveSweepSid(sweep);
3548
+ if (sweeps.includes(sweep) || sweeps.includes(resolvedSid)) {
3549
+ sweepID = sweep;
3550
+ }
3455
3551
  }
3456
3552
  }
3457
3553
  }
@@ -3516,23 +3612,34 @@ class MatterportTagService {
3516
3612
  else if (sdk) {
3517
3613
  const { comment, tagDescription } = this.tagService.getBillboardMediaToEmbed(object);
3518
3614
  if (comment) {
3519
- const attachmentID = await sdk.Tag.registerAttachment({
3520
- type: 'media',
3521
- data: {
3522
- url: comment.externalLink,
3523
- label: object.title || 'Media',
3524
- },
3525
- });
3615
+ // 1) Register the media attachment by passing the URL string(s).
3616
+ // registerAttachment returns an array of attachment IDs.
3617
+ const [attachmentID] = await sdk.Tag.registerAttachment(comment.externalLink);
3618
+ // 2) Attach the registered media to the tag.
3526
3619
  await sdk.Tag.attach(tagID, attachmentID);
3527
- const billboardAttachmentID = await sdk.Tag.registerAttachment({
3528
- type: 'billboard',
3529
- data: {
3530
- title: object.title,
3531
- description: tagDescription,
3620
+ // 3) Determine media type for the billboard (PHOTO or VIDEO).
3621
+ // Use a simple heuristic: YouTube/Vimeo -> VIDEO, otherwise PHOTO.
3622
+ // The SDK exposes MediaType on the Tag namespace.
3623
+ const isVideo = /youtube\.com|youtu\.be|vimeo\.com/i.test(comment.externalLink);
3624
+ const mediaType = isVideo ? sdk.Mattertag.MediaType.VIDEO : sdk.Mattertag.MediaType.PHOTO;
3625
+ // 4) Update the billboard text and media using editBillboard.
3626
+ // editBillboard accepts Partial<Tag.EditableProperties> such as label, description, media.
3627
+ await sdk.Tag.editBillboard(tagID, {
3628
+ label: object.title || 'Media',
3629
+ description: tagDescription || '',
3630
+ media: {
3631
+ type: mediaType,
3632
+ src: comment.externalLink,
3532
3633
  },
3533
3634
  });
3534
- await sdk.Tag.attach(tagID, billboardAttachmentID);
3535
- this.tagsAttachments[tagID] = billboardAttachmentID;
3635
+ // 5) Keep a local reference
3636
+ this.tagsAttachments[tagID] = {
3637
+ attachmentID,
3638
+ title: object.title || 'Media',
3639
+ description: tagDescription || '',
3640
+ mediaSrc: comment.externalLink,
3641
+ mediaType,
3642
+ };
3536
3643
  }
3537
3644
  }
3538
3645
  }
@@ -3563,6 +3670,7 @@ class Config {
3563
3670
  }
3564
3671
 
3565
3672
  class MatterportService {
3673
+ sdkKey;
3566
3674
  router;
3567
3675
  activeRoute;
3568
3676
  visibilityService;
@@ -3726,7 +3834,8 @@ class MatterportService {
3726
3834
  pointerMiddleClickHandler = (e) => {
3727
3835
  this.pointerService.updateCursorDisplay(this.poseMatterport);
3728
3836
  };
3729
- constructor(config, router, activeRoute, visibilityService, ngZone, measurementService, navigationService, pointerService, object3DService, matterportTagService) {
3837
+ constructor(config, sdkKey, router, activeRoute, visibilityService, ngZone, measurementService, navigationService, pointerService, object3DService, matterportTagService) {
3838
+ this.sdkKey = sdkKey;
3730
3839
  this.router = router;
3731
3840
  this.activeRoute = activeRoute;
3732
3841
  this.visibilityService = visibilityService;
@@ -3771,7 +3880,7 @@ class MatterportService {
3771
3880
  const showcaseWindow = iframe.contentWindow;
3772
3881
  iframe.addEventListener('load', async () => {
3773
3882
  try {
3774
- this.sdk = await showcaseWindow.MP_SDK.connect(showcaseWindow, 'qn9wsasuy5h2fzrbrn1nzr0id', '');
3883
+ this.sdk = await showcaseWindow.MP_SDK.connect(showcaseWindow, this.sdkKey, '');
3775
3884
  }
3776
3885
  catch (e) {
3777
3886
  console.error(e);
@@ -3862,13 +3971,16 @@ class MatterportService {
3862
3971
  onCollectionUpdated: function subscr(collection) {
3863
3972
  this.sweeps = Object.keys(collection);
3864
3973
  this.sweepCollection = collection;
3974
+ // Rebuild sid ↔ uuid maps whenever the collection updates
3975
+ this.navigationService.buildSweepIdMaps(collection);
3865
3976
  }.bind(this),
3866
3977
  });
3867
- // subscribe to current sweep
3978
+ // subscribe to current sweep – emit uuid (DB format) instead of raw sid
3868
3979
  this.sdk.Sweep.current.subscribe(function subscr(currentSweep) {
3869
3980
  if (currentSweep.sid === '')
3870
3981
  return;
3871
- this.currentSweep.next(currentSweep.sid);
3982
+ const uuid = this.navigationService.resolveSweepUuid(currentSweep.sid);
3983
+ this.currentSweep.next(uuid);
3872
3984
  }.bind(this));
3873
3985
  // Subscribe to Floor data
3874
3986
  this.sdk.Floor.data.subscribe({
@@ -3994,11 +4106,14 @@ class MatterportService {
3994
4106
  });
3995
4107
  });
3996
4108
  }
4109
+ /**
4110
+ * @deprecated Use navigationService.resolveSweepUuid() instead.
4111
+ * Kept temporarily for backwards compatibility.
4112
+ */
3997
4113
  getSweepUUIDForSid(sid) {
3998
- const collection = this.sweepCollection;
3999
- if (!collection || !collection[sid])
4000
- return null;
4001
- return collection[sid].uuid ?? null;
4114
+ return this.navigationService.resolveSweepUuid(sid) !== sid
4115
+ ? this.navigationService.resolveSweepUuid(sid)
4116
+ : null;
4002
4117
  }
4003
4118
  setLightingOff() {
4004
4119
  this.noLightForObjects = true;
@@ -4374,7 +4489,7 @@ class MatterportService {
4374
4489
  mattertagData.setPosition(JSON.parse(poi.coordinate));
4375
4490
  mattertagData.setPoi(poi); // to keep custom tagIcon and opacity
4376
4491
  }
4377
- mattertagData.setSweepID(this.poseCamera.sweep);
4492
+ mattertagData.setSweepID(this.navigationService.resolveSweepUuid(this.poseCamera.sweep));
4378
4493
  mattertagData.setRotation(this.poseCamera.rotation);
4379
4494
  mattertagData.setObject(element, poiType);
4380
4495
  this.mattertagToFollow = await this.addMattertagToViewer(mattertagData);
@@ -4387,7 +4502,7 @@ class MatterportService {
4387
4502
  */
4388
4503
  async addMattertagWhenAdding(poiType) {
4389
4504
  const mattertagData = new MattertagData(poiType);
4390
- mattertagData.setSweepID(this.poseCamera.sweep);
4505
+ mattertagData.setSweepID(this.navigationService.resolveSweepUuid(this.poseCamera.sweep));
4391
4506
  mattertagData.setRotation(this.poseCamera.rotation);
4392
4507
  this.setInteractionMode(ViewerInteractions.ADDING);
4393
4508
  await this.addCursorMattertag(mattertagData);
@@ -4674,7 +4789,7 @@ class MatterportService {
4674
4789
  toggleViewFrustum() {
4675
4790
  this.object3DService.toggleViewFrustum();
4676
4791
  }
4677
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MatterportService, deps: [{ token: 'config' }, { token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: BaseVisibilityService }, { token: i0.NgZone }, { token: MatterportMeasurementService }, { token: MatterportNavigationService }, { token: MatterportPointerService }, { token: MatterportObject3DService }, { token: MatterportTagService }], target: i0.ɵɵFactoryTarget.Injectable });
4792
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MatterportService, deps: [{ token: 'config' }, { token: MATTERPORT_SDK_KEY }, { token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: BaseVisibilityService }, { token: i0.NgZone }, { token: MatterportMeasurementService }, { token: MatterportNavigationService }, { token: MatterportPointerService }, { token: MatterportObject3DService }, { token: MatterportTagService }], target: i0.ɵɵFactoryTarget.Injectable });
4678
4793
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MatterportService, providedIn: 'root' });
4679
4794
  }
4680
4795
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MatterportService, decorators: [{
@@ -4685,6 +4800,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
4685
4800
  }], ctorParameters: () => [{ type: Config, decorators: [{
4686
4801
  type: Inject,
4687
4802
  args: ['config']
4803
+ }] }, { type: undefined, decorators: [{
4804
+ type: Inject,
4805
+ args: [MATTERPORT_SDK_KEY]
4688
4806
  }] }, { type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: BaseVisibilityService }, { type: i0.NgZone }, { type: MatterportMeasurementService }, { type: MatterportNavigationService }, { type: MatterportPointerService }, { type: MatterportObject3DService }, { type: MatterportTagService }] });
4689
4807
 
4690
4808
  /* eslint-disable no-await-in-loop */
@@ -4692,6 +4810,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
4692
4810
  /* eslint-disable no-underscore-dangle */
4693
4811
  /* eslint-disable class-methods-use-this */
4694
4812
  class ViewerService {
4813
+ sdkKey;
4695
4814
  poiService;
4696
4815
  matterportService;
4697
4816
  viewerMode = 'Matterport';
@@ -4729,7 +4848,8 @@ class ViewerService {
4729
4848
  },
4730
4849
  };
4731
4850
  isObjectLoaded = false;
4732
- constructor(poiService, matterportService) {
4851
+ constructor(sdkKey, poiService, matterportService) {
4852
+ this.sdkKey = sdkKey;
4733
4853
  this.poiService = poiService;
4734
4854
  this.matterportService = matterportService;
4735
4855
  this.setMode('Matterport');
@@ -4746,7 +4866,8 @@ class ViewerService {
4746
4866
  setMode(indexMode) {
4747
4867
  this.viewerMode = indexMode;
4748
4868
  }
4749
- setTourUrl(model3d, showIconPlan = true, showIconDollhouse = true, showIconFloors = true, showQuickStart = true, showFullscreen = true, showGuidedTour = true, showHighlightReel = true) {
4869
+ setTourUrl(options) {
4870
+ const { model3d, showIconPlan = true, showIconDollhouse = true, showIconFloors = true, showQuickStart = true, showFullscreen = true, showGuidedTour = true, showHighlightReel = true, showDefurnish = true, showRoomMeasurements = true } = options;
4750
4871
  const baseUrl = `/assets/bundle/showcase.html`;
4751
4872
  const params = [];
4752
4873
  // Modèle
@@ -4758,7 +4879,7 @@ class ViewerService {
4758
4879
  params.push(`log=0`);
4759
4880
  params.push(`brand=0`);
4760
4881
  params.push(`search=0`);
4761
- params.push(`applicationKey=qn9wsasuy5h2fzrbrn1nzr0id`);
4882
+ params.push(`applicationKey=${this.sdkKey}`);
4762
4883
  params.push(`mds=0`);
4763
4884
  // Quick start
4764
4885
  if (showQuickStart) {
@@ -4789,6 +4910,14 @@ class ViewerService {
4789
4910
  if (!showFullscreen) {
4790
4911
  params.push(`fs=0`);
4791
4912
  }
4913
+ // Defurnish
4914
+ if (showDefurnish) {
4915
+ params.push(`ad=1`);
4916
+ }
4917
+ // Room Measurements
4918
+ if (showRoomMeasurements) {
4919
+ params.push(`measurements=1`);
4920
+ }
4792
4921
  this.tourUrl = `${baseUrl}?${params.join("&")}`;
4793
4922
  }
4794
4923
  async clearAll() {
@@ -5100,7 +5229,7 @@ class ViewerService {
5100
5229
  isObject3DLoadedInPosition() {
5101
5230
  return this.isObjectLoaded;
5102
5231
  }
5103
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewerService, deps: [{ token: PoiService }, { token: MatterportService }], target: i0.ɵɵFactoryTarget.Injectable });
5232
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewerService, deps: [{ token: MATTERPORT_SDK_KEY }, { token: PoiService }, { token: MatterportService }], target: i0.ɵɵFactoryTarget.Injectable });
5104
5233
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewerService, providedIn: 'root' });
5105
5234
  }
5106
5235
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ViewerService, decorators: [{
@@ -5108,7 +5237,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
5108
5237
  args: [{
5109
5238
  providedIn: 'root',
5110
5239
  }]
5111
- }], ctorParameters: () => [{ type: PoiService }, { type: MatterportService }] });
5240
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
5241
+ type: Inject,
5242
+ args: [MATTERPORT_SDK_KEY]
5243
+ }] }, { type: PoiService }, { type: MatterportService }] });
5112
5244
 
5113
5245
  class ModalSwitchVisitComponent {
5114
5246
  activeModal;
@@ -6187,26 +6319,29 @@ class FilterService {
6187
6319
  zoneID = null, zone = null) {
6188
6320
  const filteredObjects = [];
6189
6321
  await Promise.all(objects.map(async (object) => {
6190
- const [poi] = object.pois.items;
6191
- if (poi && zone) {
6192
- if (zone.sweepIDs && zone.sweepIDs.includes(poi.matterportSweepID)) {
6193
- if (this.poiService.poiIsVirtual(poi) && zone.layer && zone.layer.name === "FLOOR") {
6194
- // we include in Floor zone only
6195
- filteredObjects.push(object);
6322
+ const pois = object.pois;
6323
+ if (pois) {
6324
+ const [poi] = pois.items;
6325
+ if (poi && zone) {
6326
+ if (zone.sweepIDs && zone.sweepIDs.includes(poi.matterportSweepID)) {
6327
+ if (this.poiService.poiIsVirtual(poi) && zone.layer && zone.layer.name === "FLOOR") {
6328
+ // we include in Floor zone only
6329
+ filteredObjects.push(object);
6330
+ }
6331
+ if (!this.poiService.poiIsVirtual(poi)) {
6332
+ filteredObjects.push(object);
6333
+ }
6196
6334
  }
6197
- if (!this.poiService.poiIsVirtual(poi)) {
6335
+ }
6336
+ if (poi && !zone && zoneID) {
6337
+ const zones = await this.zoneService.getZonesForObject(object);
6338
+ if (zones &&
6339
+ zones.some((zone_) => zone_.id === zoneID ||
6340
+ zone_.parentID === zoneID)) {
6198
6341
  filteredObjects.push(object);
6199
6342
  }
6200
6343
  }
6201
6344
  }
6202
- if (poi && !zone && zoneID) {
6203
- const zones = await this.zoneService.getZonesForObject(object);
6204
- if (zones &&
6205
- zones.some((zone_) => zone_.id === zoneID ||
6206
- zone_.parentID === zoneID)) {
6207
- filteredObjects.push(object);
6208
- }
6209
- }
6210
6345
  }));
6211
6346
  return filteredObjects;
6212
6347
  }
@@ -7166,10 +7301,9 @@ class NavigatorService {
7166
7301
  if (!this.currentSweep) {
7167
7302
  return;
7168
7303
  }
7169
- const uuid = this.matterportService.getSweepUUIDForSid(this.currentSweep);
7170
- console.log('uuid', uuid);
7171
- const sweepToMatch = uuid ?? this.currentSweep;
7172
- let zonesForSweep = this.zonesForUserForSpace?.filter((zone) => zone.sweepIDs && zone.sweepIDs.includes(sweepToMatch));
7304
+ // currentSweep is already a uuid (translated at the source in MatterportService),
7305
+ // so it matches directly against zone.sweepIDs which store uuids from the import.
7306
+ let zonesForSweep = this.zonesForUserForSpace?.filter((zone) => zone.sweepIDs && zone.sweepIDs.includes(this.currentSweep));
7173
7307
  const audioZones = this.audioZonesForUserForSpace?.filter((zone) => zone.sweepIDs && zone.sweepIDs.includes(this.currentSweep));
7174
7308
  this.audioZonesChange.next(audioZones);
7175
7309
  this.currentAudioZones = audioZones;
@@ -7478,7 +7612,7 @@ class TicketsService extends BaseObjectService {
7478
7612
  awsKinesisAnalytics; //AWS
7479
7613
  isMuseumUser = false;
7480
7614
  navSubscription;
7481
- filetrSubscription;
7615
+ filterSubscription;
7482
7616
  floorsPerSpace = null;
7483
7617
  selectedFloor = null;
7484
7618
  destroy$ = new Subject();
@@ -7506,7 +7640,7 @@ class TicketsService extends BaseObjectService {
7506
7640
  else {
7507
7641
  if (this.navSubscription) {
7508
7642
  this.navSubscription.unsubscribe();
7509
- this.filetrSubscription.unsubscribe();
7643
+ this.filterSubscription.unsubscribe();
7510
7644
  }
7511
7645
  }
7512
7646
  });
@@ -7517,6 +7651,9 @@ class TicketsService extends BaseObjectService {
7517
7651
  });
7518
7652
  }
7519
7653
  async initTickets() {
7654
+ if (this.userService.getSpModule() === SpModule.MUSEUM) {
7655
+ return;
7656
+ }
7520
7657
  let ticketsFiltered = [];
7521
7658
  if (this.currentSpaceID) {
7522
7659
  this.updating.next(true);
@@ -7689,11 +7826,8 @@ class TicketsService extends BaseObjectService {
7689
7826
  if (!ticket.ownerMissionID) {
7690
7827
  ticket.ownerMissionID = this.userService.currentMission(ticket.spaceID).id;
7691
7828
  }
7692
- // TODO!!! filter missions by space of ticket
7693
7829
  try {
7694
7830
  const receivedTicket = await this.createTicket(ticket);
7695
- // console.log('!!! Response from creating ticket :');
7696
- // console.log(receivedTicket);
7697
7831
  this.addEventToTicket(receivedTicket, {
7698
7832
  title: 'Création du ticket',
7699
7833
  description: `Ticket créé par -`,
@@ -7750,7 +7884,6 @@ class TicketsService extends BaseObjectService {
7750
7884
  }
7751
7885
  async updateStatusOfTicket(ticket, status) {
7752
7886
  const currentStatus = ticket.status;
7753
- const oldTicketStatus = ticket.status;
7754
7887
  ticket.status = status;
7755
7888
  if (currentStatus === status) {
7756
7889
  return ticket;
@@ -7916,32 +8049,33 @@ class TicketsService extends BaseObjectService {
7916
8049
  }
7917
8050
  }
7918
8051
  initSubscriptions() {
7919
- if (!this.isMuseumUser) {
7920
- this.navSubscription = this.zoneChangeService.zoneChange.subscribe((zone) => {
7921
- this.currentSpaceID = this.navigatorService.currentSpaceID;
7922
- if (!this.currentSpaceID) {
7923
- this.ticketTags.next(null);
7924
- this.ticketsUpdated.next({ space: [], zone: null });
7925
- this.ticketTypeFilter = null;
7926
- this.zoneIDFilter = null;
7927
- }
7928
- else if (zone.id !== this.zoneIDFilter) {
7929
- this.zoneIDFilter = zone.id;
7930
- // console.log("going to init tickets from zone");
7931
- this.initTickets().catch((e) => console.log(e.message));
7932
- }
7933
- });
7934
- this.filetrSubscription = this.filterService.subscribeToDataFilterUpdate((dateRange) => {
7935
- this.dateFilter = dateRange;
7936
- this.initTickets().catch((e) => console.log(e.message));
7937
- });
7938
- this.dateFilter = this.filterService.currentDateFilter;
7939
- this.updateDone.subscribe(() => {
7940
- if (this.currentSpaceID) {
7941
- this.initTickets().catch((e) => console.log(e.message));
7942
- }
7943
- });
8052
+ if (this.userService.getSpModule() === SpModule.MUSEUM) {
8053
+ return;
7944
8054
  }
8055
+ this.navSubscription = this.zoneChangeService.zoneChange.subscribe((zone) => {
8056
+ this.currentSpaceID = this.navigatorService.currentSpaceID;
8057
+ if (!this.currentSpaceID) {
8058
+ this.ticketTags.next(null);
8059
+ this.ticketsUpdated.next({ space: [], zone: null });
8060
+ this.ticketTypeFilter = null;
8061
+ this.zoneIDFilter = null;
8062
+ }
8063
+ else if (zone.id !== this.zoneIDFilter) {
8064
+ this.zoneIDFilter = zone.id;
8065
+ // console.log("going to init tickets from zone");
8066
+ this.initTickets().catch((e) => console.log(e.message));
8067
+ }
8068
+ });
8069
+ this.filterSubscription = this.filterService.subscribeToDataFilterUpdate((dateRange) => {
8070
+ this.dateFilter = dateRange;
8071
+ this.initTickets().catch((e) => console.log(e.message));
8072
+ });
8073
+ this.dateFilter = this.filterService.currentDateFilter;
8074
+ this.updateDone.subscribe(() => {
8075
+ if (this.currentSpaceID) {
8076
+ this.initTickets().catch((e) => console.log(e.message));
8077
+ }
8078
+ });
7945
8079
  }
7946
8080
  unsubscribe() {
7947
8081
  this.destroy$.next(true);
@@ -8335,7 +8469,7 @@ class EquipmentService extends BaseObjectService {
8335
8469
  });
8336
8470
  }
8337
8471
  async initEquips() {
8338
- if (!this.currentSpaceID) {
8472
+ if (!this.currentSpaceID || this.userService.getSpModule() === SpModule.MUSEUM) {
8339
8473
  return;
8340
8474
  }
8341
8475
  this.updating.next(true);
@@ -8563,64 +8697,56 @@ class EquipmentService extends BaseObjectService {
8563
8697
  }); // for lateral menu
8564
8698
  }
8565
8699
  initSubscriptions() {
8566
- if (!this.isMuseumUser) {
8567
- this.zoneChangeService.zoneChange
8568
- .pipe(takeUntil(this.destroy$))
8569
- .subscribe((zone) => {
8570
- if (!zone || !this.navigatorService.currentSpaceID) {
8571
- this.currentSpaceID = this.navigatorService.currentSpaceID;
8572
- this.equipmentsTags.next(null);
8573
- this.equipmentsUpdated.next({ space: [], zone: null });
8574
- this.zoneIDFilter = null;
8575
- this.currentEquipments = {
8576
- space: [],
8577
- zonesMap: new Map(),
8578
- };
8579
- return;
8580
- }
8581
- if (zone.id !== this.zoneIDFilter) {
8582
- this.zoneIDFilter = zone.id;
8583
- this.currentZone = zone;
8584
- if (this.currentSpaceID === this.navigatorService.currentSpaceID) {
8585
- // same space, only zone update
8586
- // console.log(
8587
- // "going to update equips for zone (same space)",
8588
- // zone,
8589
- // );
8590
- this.updateEquipsForZone();
8591
- }
8592
- else {
8593
- this.currentSpaceID = this.navigatorService.currentSpaceID;
8594
- // console.log(
8595
- // "going to init equips for zone for new space",
8596
- // this.currentSpaceID,
8597
- // );
8598
- this.initEquips();
8599
- }
8600
- }
8601
- });
8602
- this.deleteObservable
8603
- .pipe(takeUntil(this.destroy$))
8604
- .subscribe((equipment) => {
8605
- if (this.currentSpaceID) {
8606
- this.updateDueToDelete(equipment);
8607
- }
8608
- });
8609
- this.createObservable
8610
- .pipe(takeUntil(this.destroy$))
8611
- .subscribe((equipment) => {
8612
- if (this.currentSpaceID) {
8613
- this.updateDueToCreate(equipment);
8700
+ if (this.userService.getSpModule() === SpModule.MUSEUM) {
8701
+ return;
8702
+ }
8703
+ this.zoneChangeService.zoneChange
8704
+ .pipe(takeUntil(this.destroy$))
8705
+ .subscribe((zone) => {
8706
+ if (!zone || !this.navigatorService.currentSpaceID) {
8707
+ this.currentSpaceID = this.navigatorService.currentSpaceID;
8708
+ this.equipmentsTags.next(null);
8709
+ this.equipmentsUpdated.next({ space: [], zone: null });
8710
+ this.zoneIDFilter = null;
8711
+ this.currentEquipments = {
8712
+ space: [],
8713
+ zonesMap: new Map(),
8714
+ };
8715
+ return;
8716
+ }
8717
+ if (zone.id !== this.zoneIDFilter) {
8718
+ this.zoneIDFilter = zone.id;
8719
+ this.currentZone = zone;
8720
+ if (this.currentSpaceID === this.navigatorService.currentSpaceID) {
8721
+ this.updateEquipsForZone();
8614
8722
  }
8615
- });
8616
- this.updateObservable
8617
- .pipe(takeUntil(this.destroy$))
8618
- .subscribe((equipment) => {
8619
- if (this.currentSpaceID) {
8620
- this.updateDueToEquipUpdated(equipment);
8723
+ else {
8724
+ this.currentSpaceID = this.navigatorService.currentSpaceID;
8725
+ this.initEquips();
8621
8726
  }
8622
- });
8623
- }
8727
+ }
8728
+ });
8729
+ this.deleteObservable
8730
+ .pipe(takeUntil(this.destroy$))
8731
+ .subscribe((equipment) => {
8732
+ if (this.currentSpaceID) {
8733
+ this.updateDueToDelete(equipment);
8734
+ }
8735
+ });
8736
+ this.createObservable
8737
+ .pipe(takeUntil(this.destroy$))
8738
+ .subscribe((equipment) => {
8739
+ if (this.currentSpaceID) {
8740
+ this.updateDueToCreate(equipment);
8741
+ }
8742
+ });
8743
+ this.updateObservable
8744
+ .pipe(takeUntil(this.destroy$))
8745
+ .subscribe((equipment) => {
8746
+ if (this.currentSpaceID) {
8747
+ this.updateDueToEquipUpdated(equipment);
8748
+ }
8749
+ });
8624
8750
  }
8625
8751
  unsubscribe() {
8626
8752
  this.destroy$.next(true);
@@ -9632,8 +9758,11 @@ class CommentService {
9632
9758
  if (comment.ticketID && !comment.ticket) {
9633
9759
  comment.ticket = await this.API.__proto__.GetTicket(comment.ticketID);
9634
9760
  }
9635
- const values = comment.dimensions;
9636
- const numberPoints = values.length + 1;
9761
+ let values = comment.dimensions;
9762
+ let numberPoints = 0;
9763
+ if (values) {
9764
+ numberPoints = values.length + 1;
9765
+ }
9637
9766
  const poi = await this.poiService.getPoiByElementId(commentID);
9638
9767
  const measure = {
9639
9768
  id: comment.id,
@@ -12500,6 +12629,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
12500
12629
  }] }] });
12501
12630
 
12502
12631
  class MatterportImportService {
12632
+ sdkKey;
12503
12633
  navigationService;
12504
12634
  zoneService;
12505
12635
  viewerService;
@@ -12529,7 +12659,8 @@ class MatterportImportService {
12529
12659
  importingImages = new Subject();
12530
12660
  sweepProcessedCount = new Subject();
12531
12661
  totalSweepsCount = new Subject();
12532
- constructor(navigationService, zoneService, viewerService, layerService, userService, planService) {
12662
+ constructor(sdkKey, navigationService, zoneService, viewerService, layerService, userService, planService) {
12663
+ this.sdkKey = sdkKey;
12533
12664
  this.navigationService = navigationService;
12534
12665
  this.zoneService = zoneService;
12535
12666
  this.viewerService = viewerService;
@@ -12546,7 +12677,7 @@ class MatterportImportService {
12546
12677
  if (!iframe) {
12547
12678
  throw new Error('Cannot create iframe');
12548
12679
  }
12549
- this.viewerService.setTourUrl(modelID);
12680
+ this.viewerService.setTourUrl({ model3d: modelID });
12550
12681
  const url = this.viewerService.getTourUrl();
12551
12682
  iframe.setAttribute('src', url);
12552
12683
  iframe.allow = 'xr-spatial-tracking';
@@ -12560,7 +12691,7 @@ class MatterportImportService {
12560
12691
  return new Promise((res, rej) => {
12561
12692
  iframe.addEventListener('load', async () => {
12562
12693
  try {
12563
- this.sdk = await showcaseWindow.MP_SDK.connect(iframe, 'qn9wsasuy5h2fzrbrn1nzr0id', '');
12694
+ this.sdk = await showcaseWindow.MP_SDK.connect(iframe, this.sdkKey, '');
12564
12695
  // Subscribe to Floor data
12565
12696
  this.sdk.Floor.data.subscribe({
12566
12697
  onCollectionUpdated: function upd(collection) {
@@ -12680,20 +12811,47 @@ class MatterportImportService {
12680
12811
  const newLocal = await this.zoneService.create(zoneInput);
12681
12812
  return newLocal;
12682
12813
  }
12814
+ // --- Main import function (complete) ---
12683
12815
  async import360images(overrideExisting = true) {
12684
12816
  console.log('Importing 360 images');
12685
12817
  this.importingImages.next(true);
12686
12818
  return new Promise(async (resolve) => {
12687
12819
  const scans = Object.values(this.sweeps);
12688
- const nmbScans = Object.keys(scans).length;
12820
+ const nmbScans = scans.length;
12689
12821
  this.totalSweepsCount.next(nmbScans);
12690
12822
  const start = overrideExisting ? 0 : await this.getUploadedImageCount(this.modelID);
12691
12823
  for (let index = start; index < nmbScans; index += 1) {
12692
- if (!this.stop) {
12693
- await this.sdk.Sweep.moveTo(scans[index].uuid, { rotation: { x: 0, y: 0 }, transition: this.sdk.Camera.TransitionType.INSTANT, transitionTime: 0 });
12694
- const img = await this.sdk.Renderer.takeEquirectangular({ width: 2048, height: 1024 }, { mattertags: false, sweeps: true });
12695
- /**Upload on S3 are asynchronous, in order to no slow down the process*/
12696
- uploadBase64ImageWithRetry(img, scans[index].uuid, `visits/${this.modelID}/sweeps/`, 'sweep', 5).then((r) => {
12824
+ if (this.stop) {
12825
+ console.log('Abandoning import because it was cancelled');
12826
+ resolve(false);
12827
+ this.removeFrame();
12828
+ break;
12829
+ }
12830
+ const sweep = scans[index];
12831
+ console.log('Moving to sweep:', sweep);
12832
+ // Prefer legacy .id first, then uuid, then sid as last resort
12833
+ const moveId = sweep.id || sweep.uuid || sweep.sid;
12834
+ try {
12835
+ // Move to sweep (use the best available id)
12836
+ await this.sdk.Sweep.moveTo(moveId, {
12837
+ rotation: { x: 0, y: 0 },
12838
+ transition: this.sdk.Camera && this.sdk.Camera.TransitionType
12839
+ ? this.sdk.Camera.TransitionType.INSTANT
12840
+ : undefined,
12841
+ transitionTime: 0,
12842
+ });
12843
+ // Capture with automatic retry (ensures renderer readiness each attempt)
12844
+ const img = await this.captureEquirectangularWithRetry({ width: 2048, height: 1024 }, { mattertags: false, sweeps: true }, {
12845
+ maxAttempts: 3,
12846
+ initialBackoffMs: 500,
12847
+ perAttemptTimeoutMs: 8000,
12848
+ sweepIdForReadyCheck: moveId,
12849
+ waitForSweepTimeoutMs: 12000
12850
+ });
12851
+ // Upload asynchronously (do not await to keep throughput)
12852
+ uploadBase64ImageWithRetry(img,
12853
+ // prefer using uuid for storage name if available, else fallback to moveId
12854
+ sweep.uuid || moveId, `visits/${this.modelID}/sweeps/`, 'sweep', 5).then(() => {
12697
12855
  this.sweepProcessedCount.next(index);
12698
12856
  if (index === nmbScans - 1) {
12699
12857
  console.log('Import 360 done');
@@ -12705,17 +12863,156 @@ class MatterportImportService {
12705
12863
  console.log("Error uploading scan : ", e);
12706
12864
  });
12707
12865
  }
12708
- else {
12709
- console.log('Abandoning import because it was cancelled');
12710
- resolve(false);
12711
- this.removeFrame();
12712
- break;
12866
+ catch (err) {
12867
+ // capture failed after retries — log and continue to next sweep
12868
+ console.error(`Failed to capture sweep ${moveId} after retries:`, err);
12869
+ this.sweepProcessedCount.next(index);
12870
+ // continue to next sweep (change to `throw err` if you want to abort on first failure)
12871
+ continue;
12713
12872
  }
12714
12873
  }
12874
+ // If loop finishes without hitting the final resolve in upload promise:
12715
12875
  resolve(true);
12716
12876
  this.removeFrame();
12717
12877
  });
12718
12878
  }
12879
+ // --- capture with retry and backoff ---
12880
+ // options: renderer size; renderOptions: renderer flags; cfg: retry config
12881
+ async captureEquirectangularWithRetry(options, renderOptions, { maxAttempts = 3, initialBackoffMs = 500, perAttemptTimeoutMs = 8000, sweepIdForReadyCheck = null, waitForSweepTimeoutMs = 12000 } = {}) {
12882
+ let attempt = 0;
12883
+ let lastError = null;
12884
+ while (attempt < maxAttempts) {
12885
+ attempt += 1;
12886
+ try {
12887
+ // Ensure sweep is ready before each attempt if requested
12888
+ if (sweepIdForReadyCheck) {
12889
+ await this.waitForSweepReady(sweepIdForReadyCheck, waitForSweepTimeoutMs);
12890
+ // small safety delay to let renderer finalize
12891
+ await this.sleep(120);
12892
+ }
12893
+ // Race the takeEquirectangular call against a per-attempt timeout
12894
+ const img = await Promise.race([
12895
+ this.sdk.Renderer.takeEquirectangular(options, renderOptions),
12896
+ this.timeoutPromise(perAttemptTimeoutMs, `takeEquirectangular timed out after ${perAttemptTimeoutMs}ms`)
12897
+ ]);
12898
+ // success
12899
+ return img;
12900
+ }
12901
+ catch (err) {
12902
+ lastError = err;
12903
+ console.warn(`takeEquirectangular attempt ${attempt} failed:`, err);
12904
+ if (attempt >= maxAttempts) {
12905
+ throw lastError;
12906
+ }
12907
+ // exponential backoff before next attempt
12908
+ const backoff = initialBackoffMs * Math.pow(2, attempt - 1);
12909
+ // add small jitter to reduce thundering herd
12910
+ const jitter = Math.floor(Math.random() * 100);
12911
+ await this.sleep(backoff + jitter);
12912
+ // loop to next attempt
12913
+ }
12914
+ }
12915
+ throw lastError || new Error('captureEquirectangularWithRetry failed without error');
12916
+ }
12917
+ // --- Wait until the SDK reports the target sweep as current ---
12918
+ // Tries: sdk.Sweep.current.waitUntil -> sdk.Sweep.current.subscribe -> polling getCurrent/value
12919
+ // This function matches targetId against multiple fields and prioritizes .id matching.
12920
+ waitForSweepReady(targetId, timeoutMs = 10000) {
12921
+ const sdk = this.sdk;
12922
+ // helper to match multiple id fields, prioritizing id first
12923
+ const matchesTarget = (data) => {
12924
+ if (!data)
12925
+ return false;
12926
+ // check .id first (legacy), then uuid, sid, uid
12927
+ const fields = [data.id, data.uuid, data.sid, data.uid];
12928
+ return fields.some(f => !!f && String(f) === String(targetId));
12929
+ };
12930
+ // 1) prefer waitUntil if available on the observable
12931
+ if (sdk.Sweep && sdk.Sweep.current && typeof sdk.Sweep.current.waitUntil === 'function') {
12932
+ return Promise.race([
12933
+ sdk.Sweep.current.waitUntil((data) => matchesTarget(data)),
12934
+ this.timeoutPromise(timeoutMs, `Timeout waiting for sweep ${targetId}`)
12935
+ ]);
12936
+ }
12937
+ // 2) subscribe if available
12938
+ if (sdk.Sweep && sdk.Sweep.current && typeof sdk.Sweep.current.subscribe === 'function') {
12939
+ return new Promise((resolve, reject) => {
12940
+ const timer = setTimeout(() => {
12941
+ if (off)
12942
+ off();
12943
+ reject(new Error(`Timeout waiting for sweep ${targetId}`));
12944
+ }, timeoutMs);
12945
+ let off = null;
12946
+ try {
12947
+ // subscribe may return an unsubscribe function or an object with unsubscribe()
12948
+ const subResult = sdk.Sweep.current.subscribe((data) => {
12949
+ if (matchesTarget(data)) {
12950
+ clearTimeout(timer);
12951
+ try {
12952
+ if (typeof subResult === 'function')
12953
+ subResult();
12954
+ else if (subResult && typeof subResult.unsubscribe === 'function')
12955
+ subResult.unsubscribe();
12956
+ }
12957
+ catch (e) { /*ignore*/ }
12958
+ resolve();
12959
+ }
12960
+ });
12961
+ // if subscribe returned an unsubscribe function, keep it as off
12962
+ if (typeof subResult === 'function')
12963
+ off = subResult;
12964
+ else if (subResult && typeof subResult.unsubscribe === 'function')
12965
+ off = () => subResult.unsubscribe();
12966
+ }
12967
+ catch (e) {
12968
+ clearTimeout(timer);
12969
+ reject(new Error('sdk.Sweep.current.subscribe not usable'));
12970
+ }
12971
+ });
12972
+ }
12973
+ // 3) polling fallback: try getCurrent(), sdk.Sweep.current() function, or .value, else poll renderer readiness
12974
+ return new Promise(async (resolve, reject) => {
12975
+ const pollInterval = 200;
12976
+ const timer = setTimeout(() => {
12977
+ clearInterval(interval);
12978
+ reject(new Error(`Timeout waiting for sweep ${targetId}`));
12979
+ }, timeoutMs);
12980
+ const checkNow = async () => {
12981
+ try {
12982
+ let current = null;
12983
+ if (sdk.Sweep && typeof sdk.Sweep.getCurrent === 'function') {
12984
+ current = await sdk.Sweep.getCurrent();
12985
+ }
12986
+ else if (sdk.Sweep && typeof sdk.Sweep.current === 'function') {
12987
+ // some builds expose a function
12988
+ current = await sdk.Sweep.current();
12989
+ }
12990
+ else if (sdk.Sweep && sdk.Sweep.current && sdk.Sweep.current.value) {
12991
+ // some observables expose a .value
12992
+ current = sdk.Sweep.current.value;
12993
+ }
12994
+ if (matchesTarget(current)) {
12995
+ clearTimeout(timer);
12996
+ clearInterval(interval);
12997
+ resolve();
12998
+ }
12999
+ }
13000
+ catch (e) {
13001
+ // ignore and retry until timeout
13002
+ }
13003
+ };
13004
+ // initial immediate check
13005
+ await checkNow();
13006
+ const interval = setInterval(checkNow, pollInterval);
13007
+ });
13008
+ }
13009
+ // --- small helpers ---
13010
+ sleep(ms) {
13011
+ return new Promise(res => setTimeout(res, ms));
13012
+ }
13013
+ timeoutPromise(ms, message) {
13014
+ return new Promise((_, reject) => setTimeout(() => reject(new Error(message)), ms));
13015
+ }
12719
13016
  async getUploadedImageCount(modelID) {
12720
13017
  try {
12721
13018
  const images = await listFilesInFolder(`visits/${modelID}/sweeps/`);
@@ -12830,7 +13127,7 @@ class MatterportImportService {
12830
13127
  // create then
12831
13128
  return this.layerService.createLayerForOrganisation(name, currentOrgId);
12832
13129
  }
12833
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MatterportImportService, deps: [{ token: NavigationService }, { token: ZoneService }, { token: ViewerService }, { token: LayerService }, { token: BaseUserService }, { token: PlanService }], target: i0.ɵɵFactoryTarget.Injectable });
13130
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MatterportImportService, deps: [{ token: MATTERPORT_SDK_KEY }, { token: NavigationService }, { token: ZoneService }, { token: ViewerService }, { token: LayerService }, { token: BaseUserService }, { token: PlanService }], target: i0.ɵɵFactoryTarget.Injectable });
12834
13131
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MatterportImportService, providedIn: 'root' });
12835
13132
  }
12836
13133
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MatterportImportService, decorators: [{
@@ -12838,7 +13135,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
12838
13135
  args: [{
12839
13136
  providedIn: 'root',
12840
13137
  }]
12841
- }], ctorParameters: () => [{ type: NavigationService }, { type: ZoneService }, { type: ViewerService }, { type: LayerService }, { type: BaseUserService }, { type: PlanService }] });
13138
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
13139
+ type: Inject,
13140
+ args: [MATTERPORT_SDK_KEY]
13141
+ }] }, { type: NavigationService }, { type: ZoneService }, { type: ViewerService }, { type: LayerService }, { type: BaseUserService }, { type: PlanService }] });
12842
13142
 
12843
13143
  /* eslint-disable class-methods-use-this */
12844
13144
  class Object3DService {
@@ -13413,5 +13713,5 @@ function floatValidator() {
13413
13713
  * Generated bundle index. Do not edit.
13414
13714
  */
13415
13715
 
13416
- export { AffectationService, AvatarComponent, BaseLateralTabService, BaseTagService, BaseUserService, BaseVisibilityService, CameraMode, CaptureService, CaptureViewer, CommentService, CommentType, Config, ContentService, CsvExportComponent, DomainService, DomainType, DurationToStringPipe, EmailStatus, EquipmentService, EventService, EventStatus, EventType, FeatureService, FeatureType, FilterService, HashtagFromIdPipe, HashtagService, InterventionService, InventoryStatus, LayerService, LevelStatus, LoaderComponent, Locale, LocaleService, MatterportImportService, MatterportService, MattertagActionMode, MattertagData, MeasurementService, MenuBarComponent, MissionService, NavigationService, NavigatorService, NgxSmarterplanCoreModule, NgxSmarterplanCoreService, NodeService, Object3DService, OperationService, OrganisationService, PaymentStatus, PlanService, PoiService, PoiType, ProfileEntity, ProfileService, ProfileStatus, PropertyService, PropertyType, RoleStatus, SafeUrlPipe, SearchBarComponent, SearchObjectType, SearchService, SpModule, SpaceService, SpaceStatus, StatusEquipment, SupportModalComponent, SupportService, TagAction, TemplateService, TicketPriority, TicketStatus, TicketType, TicketsService, TimeDateToLocalStringPipe, TypeNote, UsernameFromIdPipe, ValidatorsService, ViewerInteractions, ViewerService, VisitService, ZoneChangeService, ZoneService, arraysContainSameElements, checkElementById, convertTimestampToLocalZone, dateHasExpired, dateTimeToLocalString, deleteFromS3, downloadBlob, downloadEquipmentDocument, downloadFile, downloadFileAsObject, durationToString, emailValidator, enumToArray, filterUniqueArrayByID, floatValidator, getBufferForFileFromS3, getCoefficientsForImage, getCurrentLang, getDistanceBetweenTwoPoints, getHighestLevelForMissions, getHighestRoleForMissions, getLevelsBelow, getLocaleLong, getLocaleShort, getMetaForImage, getRolesBelowForManager, getSignedFile, getSignedImageUrlForEquipment, getSignedImageUrlForProfile, getSignedImageUrlForSpace, getSpaceIDFromUrl, getVisitUrl, isEmptyObject, listFilesInFolder, mean, noEmptyValidator, numberToDateString, openDocument, openModalForVisitSwitch, poiTypeToString, pointToString, removeAllFilesFromFolderS3, removeNullKeysFromObject, showScanPointsOnPlanInDiv, shuffleArray, sortAlphabeticallyOnName, stringLocaleToEnum, stringToLowercaseNoSpaces, styleButton, textValidator, translateDatePeriod, uploadBase64Image, uploadBase64ImageWithRetry, uploadFileToS3, uploadJsonToS3, validEmail, wait, waitUntil };
13716
+ export { AffectationService, AvatarComponent, BaseLateralTabService, BaseTagService, BaseUserService, BaseVisibilityService, CameraMode, CaptureService, CaptureViewer, CommentService, CommentType, Config, ContentService, CsvExportComponent, DomainService, DomainType, DurationToStringPipe, EmailStatus, EquipmentService, EventService, EventStatus, EventType, FeatureService, FeatureType, FilterService, HashtagFromIdPipe, HashtagService, InterventionService, InventoryStatus, LayerService, LevelStatus, LoaderComponent, Locale, LocaleService, MATTERPORT_SDK_KEY, MatterportImportService, MatterportService, MattertagActionMode, MattertagData, MeasurementService, MenuBarComponent, MissionService, NavigationService, NavigatorService, NgxSmarterplanCoreModule, NgxSmarterplanCoreService, NodeService, Object3DService, OperationService, OrganisationService, PaymentStatus, PlanService, PoiService, PoiType, ProfileEntity, ProfileService, ProfileStatus, PropertyService, PropertyType, RoleStatus, SafeUrlPipe, SearchBarComponent, SearchObjectType, SearchService, SpModule, SpaceService, SpaceStatus, StatusEquipment, SupportModalComponent, SupportService, TagAction, TemplateService, TicketPriority, TicketStatus, TicketType, TicketsService, TimeDateToLocalStringPipe, TypeNote, UsernameFromIdPipe, ValidatorsService, ViewerInteractions, ViewerService, VisitService, ZoneChangeService, ZoneService, arraysContainSameElements, checkElementById, convertTimestampToLocalZone, dateHasExpired, dateTimeToLocalString, deleteFromS3, downloadBlob, downloadEquipmentDocument, downloadFile, downloadFileAsObject, durationToString, emailValidator, enumToArray, filterUniqueArrayByID, floatValidator, getBufferForFileFromS3, getCoefficientsForImage, getCurrentLang, getDistanceBetweenTwoPoints, getHighestLevelForMissions, getHighestRoleForMissions, getLevelsBelow, getLocaleLong, getLocaleShort, getMetaForImage, getRolesBelowForManager, getSignedFile, getSignedImageUrlForEquipment, getSignedImageUrlForProfile, getSignedImageUrlForSpace, getSpaceIDFromUrl, getVisitUrl, isEmptyObject, listFilesInFolder, mean, noEmptyValidator, numberToDateString, openDocument, openModalForVisitSwitch, poiTypeToString, pointToString, removeAllFilesFromFolderS3, removeNullKeysFromObject, showScanPointsOnPlanInDiv, shuffleArray, sortAlphabeticallyOnName, stringLocaleToEnum, stringToLowercaseNoSpaces, styleButton, textValidator, translateDatePeriod, uploadBase64Image, uploadBase64ImageWithRetry, uploadFileToS3, uploadJsonToS3, validEmail, wait, waitUntil };
13417
13717
  //# sourceMappingURL=smarterplan-ngx-smarterplan-core.mjs.map