@neurodyn/react-room-viewer 0.0.35 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +152 -2
  2. package/dist/index.js +559 -257
  3. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Component, Suspense, createContext, memo, use as external_react_use, useCallback, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo as external_react_useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
3
+ import { Direction, Popover, Select, Slider } from "radix-ui";
3
4
  import { createPortal } from "react-dom";
4
5
  import { I18nextProvider, initReactI18next, useTranslation } from "react-i18next";
5
6
  import react_shadow from "react-shadow";
@@ -27,7 +28,6 @@ import { formatHex, oklch } from "culori";
27
28
  import qrcode from "qrcode";
28
29
  import { GLTFExporter } from "three/examples/jsm/exporters/GLTFExporter.js";
29
30
  import { USDZExporter } from "three/examples/jsm/exporters/USDZExporter.js";
30
- import { Popover, Select, Slider } from "radix-ui";
31
31
  var __webpack_modules__ = {
32
32
  "./src/style.css?inline" (module, __webpack_exports__, __webpack_require__) {
33
33
  __webpack_require__.d(__webpack_exports__, {
@@ -528,6 +528,38 @@ var __webpack_modules__ = {
528
528
  inset-block: calc(var(--spacing) * 0);
529
529
  }
530
530
 
531
+ .start-0 {
532
+ inset-inline-start: calc(var(--spacing) * 0);
533
+ }
534
+
535
+ .start-2 {
536
+ inset-inline-start: calc(var(--spacing) * 2);
537
+ }
538
+
539
+ .start-6 {
540
+ inset-inline-start: calc(var(--spacing) * 6);
541
+ }
542
+
543
+ .end-0 {
544
+ inset-inline-end: calc(var(--spacing) * 0);
545
+ }
546
+
547
+ .end-1 {
548
+ inset-inline-end: calc(var(--spacing) * 1);
549
+ }
550
+
551
+ .end-2 {
552
+ inset-inline-end: calc(var(--spacing) * 2);
553
+ }
554
+
555
+ .end-4 {
556
+ inset-inline-end: calc(var(--spacing) * 4);
557
+ }
558
+
559
+ .end-6 {
560
+ inset-inline-end: calc(var(--spacing) * 6);
561
+ }
562
+
531
563
  .top-0 {
532
564
  top: calc(var(--spacing) * 0);
533
565
  }
@@ -576,14 +608,6 @@ var __webpack_modules__ = {
576
608
  top: 100%;
577
609
  }
578
610
 
579
- .right-0 {
580
- right: calc(var(--spacing) * 0);
581
- }
582
-
583
- .right-1 {
584
- right: calc(var(--spacing) * 1);
585
- }
586
-
587
611
  .right-2 {
588
612
  right: calc(var(--spacing) * 2);
589
613
  }
@@ -592,14 +616,6 @@ var __webpack_modules__ = {
592
616
  right: calc(var(--spacing) * 3);
593
617
  }
594
618
 
595
- .right-4 {
596
- right: calc(var(--spacing) * 4);
597
- }
598
-
599
- .right-6 {
600
- right: calc(var(--spacing) * 6);
601
- }
602
-
603
619
  .right-\\[-1\\.36\\%\\] {
604
620
  right: -1.36%;
605
621
  }
@@ -636,14 +652,6 @@ var __webpack_modules__ = {
636
652
  left: 50%;
637
653
  }
638
654
 
639
- .left-2 {
640
- left: calc(var(--spacing) * 2);
641
- }
642
-
643
- .left-6 {
644
- left: calc(var(--spacing) * 6);
645
- }
646
-
647
655
  .left-\\[-1\\.36\\%\\] {
648
656
  left: -1.36%;
649
657
  }
@@ -762,6 +770,14 @@ var __webpack_modules__ = {
762
770
  margin-inline-start: -1px;
763
771
  }
764
772
 
773
+ .ms-4 {
774
+ margin-inline-start: calc(var(--spacing) * 4);
775
+ }
776
+
777
+ .ms-auto {
778
+ margin-inline-start: auto;
779
+ }
780
+
765
781
  .-mt-2 {
766
782
  margin-top: calc(var(--spacing) * -2);
767
783
  }
@@ -794,14 +810,6 @@ var __webpack_modules__ = {
794
810
  margin-left: calc(var(--spacing) * 1);
795
811
  }
796
812
 
797
- .ml-4 {
798
- margin-left: calc(var(--spacing) * 4);
799
- }
800
-
801
- .ml-auto {
802
- margin-left: auto;
803
- }
804
-
805
813
  .box-border {
806
814
  box-sizing: border-box;
807
815
  }
@@ -2329,6 +2337,30 @@ var __webpack_modules__ = {
2329
2337
  padding-block: calc(var(--spacing) * 14);
2330
2338
  }
2331
2339
 
2340
+ .ps-2 {
2341
+ padding-inline-start: calc(var(--spacing) * 2);
2342
+ }
2343
+
2344
+ .ps-3 {
2345
+ padding-inline-start: calc(var(--spacing) * 3);
2346
+ }
2347
+
2348
+ .ps-8 {
2349
+ padding-inline-start: calc(var(--spacing) * 8);
2350
+ }
2351
+
2352
+ .pe-1 {
2353
+ padding-inline-end: calc(var(--spacing) * 1);
2354
+ }
2355
+
2356
+ .pe-2 {
2357
+ padding-inline-end: calc(var(--spacing) * 2);
2358
+ }
2359
+
2360
+ .pe-8 {
2361
+ padding-inline-end: calc(var(--spacing) * 8);
2362
+ }
2363
+
2332
2364
  .pt-1 {
2333
2365
  padding-top: calc(var(--spacing) * 1);
2334
2366
  }
@@ -2349,10 +2381,6 @@ var __webpack_modules__ = {
2349
2381
  padding-right: calc(var(--spacing) * 1);
2350
2382
  }
2351
2383
 
2352
- .pr-2 {
2353
- padding-right: calc(var(--spacing) * 2);
2354
- }
2355
-
2356
2384
  .pr-2\\.5 {
2357
2385
  padding-right: calc(var(--spacing) * 2.5);
2358
2386
  }
@@ -2365,10 +2393,6 @@ var __webpack_modules__ = {
2365
2393
  padding-right: calc(var(--spacing) * 5);
2366
2394
  }
2367
2395
 
2368
- .pr-8 {
2369
- padding-right: calc(var(--spacing) * 8);
2370
- }
2371
-
2372
2396
  .pb-4 {
2373
2397
  padding-bottom: calc(var(--spacing) * 4);
2374
2398
  }
@@ -2385,18 +2409,10 @@ var __webpack_modules__ = {
2385
2409
  padding-bottom: 5px;
2386
2410
  }
2387
2411
 
2388
- .pl-2 {
2389
- padding-left: calc(var(--spacing) * 2);
2390
- }
2391
-
2392
2412
  .pl-3 {
2393
2413
  padding-left: calc(var(--spacing) * 3);
2394
2414
  }
2395
2415
 
2396
- .pl-8 {
2397
- padding-left: calc(var(--spacing) * 8);
2398
- }
2399
-
2400
2416
  .text-center {
2401
2417
  text-align: center;
2402
2418
  }
@@ -2405,6 +2421,10 @@ var __webpack_modules__ = {
2405
2421
  text-align: left;
2406
2422
  }
2407
2423
 
2424
+ .text-start {
2425
+ text-align: start;
2426
+ }
2427
+
2408
2428
  .align-middle {
2409
2429
  vertical-align: middle;
2410
2430
  }
@@ -4620,6 +4640,10 @@ var __webpack_modules__ = {
4620
4640
  }
4621
4641
 
4622
4642
  @media (width >= 640px) {
4643
+ .sm\\:end-6 {
4644
+ inset-inline-end: calc(var(--spacing) * 6);
4645
+ }
4646
+
4623
4647
  .sm\\:top-6 {
4624
4648
  top: calc(var(--spacing) * 6);
4625
4649
  }
@@ -4628,10 +4652,6 @@ var __webpack_modules__ = {
4628
4652
  top: 50%;
4629
4653
  }
4630
4654
 
4631
- .sm\\:right-6 {
4632
- right: calc(var(--spacing) * 6);
4633
- }
4634
-
4635
4655
  .sm\\:bottom-auto {
4636
4656
  bottom: auto;
4637
4657
  }
@@ -4862,6 +4882,10 @@ var __webpack_modules__ = {
4862
4882
  }
4863
4883
  }
4864
4884
 
4885
+ .rtl\\:rotate-180:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
4886
+ rotate: 180deg;
4887
+ }
4888
+
4865
4889
  .dark\\:bg-input\\/30:is(.dark *) {
4866
4890
  background-color: var(--input);
4867
4891
  }
@@ -5091,6 +5115,10 @@ var __webpack_modules__ = {
5091
5115
  }
5092
5116
  }
5093
5117
 
5118
+ .\\[data-chrome-slot\\=\\"ar-card\\"\\]\\:visible:is(), .\\[data-chrome-slot\\=\\"product-card\\"\\]\\:visible:is() {
5119
+ visibility: visible;
5120
+ }
5121
+
5094
5122
  :is(.\\*\\:\\[span\\]\\:last\\:flex > *):is(span):last-child {
5095
5123
  display: flex;
5096
5124
  }
@@ -5458,8 +5486,17 @@ var __webpack_modules__ = {
5458
5486
  font-display: swap;
5459
5487
  }
5460
5488
 
5489
+ @font-face {
5490
+ font-family: __tw4_shd_noto_arabic_7x4q2;
5491
+ src: url("https://fonts.gstatic.com/s/notosansarabic/v33/nwpCtLGrOAZMl5nJ_wfgRg3DrWFZWsnVBJ_sS6tlqHHFlj4wv4r4xA.woff2") format("woff2");
5492
+ font-weight: 100 900;
5493
+ font-style: normal;
5494
+ font-display: swap;
5495
+ unicode-range: U+6??, U+750-77F, U+870-891, U+897-8E1, U+8E3-8FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
5496
+ }
5497
+
5461
5498
  :root {
5462
- --v-font-family: "__tw4_shd_inter_7x4q2", sans-serif;
5499
+ --v-font-family: "__tw4_shd_inter_7x4q2", "__tw4_shd_noto_arabic_7x4q2", sans-serif;
5463
5500
  font-family: var(--v-font-family);
5464
5501
  font-feature-settings: "liga" 1, "calt" 1;
5465
5502
  -webkit-font-smoothing: antialiased;
@@ -6125,6 +6162,15 @@ var __webpack_modules__ = {
6125
6162
  font-style: normal;
6126
6163
  font-display: swap;
6127
6164
  }
6165
+
6166
+ @font-face {
6167
+ font-family: __tw4_shd_noto_arabic_7x4q2;
6168
+ src: url("https://fonts.gstatic.com/s/notosansarabic/v33/nwpCtLGrOAZMl5nJ_wfgRg3DrWFZWsnVBJ_sS6tlqHHFlj4wv4r4xA.woff2") format("woff2");
6169
+ font-weight: 100 900;
6170
+ font-style: normal;
6171
+ font-display: swap;
6172
+ unicode-range: U+6??, U+750-77F, U+870-891, U+897-8E1, U+8E3-8FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
6173
+ }
6128
6174
  `,
6129
6175
  ""
6130
6176
  ]);
@@ -6257,6 +6303,155 @@ function ThemeProvider({ children, defaultTheme = 'system', storageKey = 'v-them
6257
6303
  }
6258
6304
  var fontsinline = __webpack_require__("../ui/src/styles/fonts.css?inline");
6259
6305
  const ns1 = {
6306
+ matting: 'الحافة الداخلية',
6307
+ close: 'إغلاق',
6308
+ mattingOptions: {
6309
+ none: 'بدون'
6310
+ },
6311
+ units: {
6312
+ cm: 'سم',
6313
+ in: 'بوصة'
6314
+ },
6315
+ ar: {
6316
+ viewInPlace: 'اعرضه في مكانك',
6317
+ scanQrCode: 'امسح رمز QR هذا بكاميرا هاتفك لعرض المنتج بتقنية الواقع المعزز',
6318
+ deviceRequirementsDisclaimer: '*يتطلب جهازًا ومتصفحًا يدعمان الواقع المعزز. نوصي بنظام iOS 18 أو أحدث مع Safari، أو Android 7.0 أو أحدث مع Chrome.',
6319
+ appClipScanTitle: 'امسح الرمز بكاميرا هاتفك',
6320
+ appClipRequirement: 'يعمل عرض الواقع المعزز على iOS 18 أو أحدث'
6321
+ },
6322
+ legal: {
6323
+ termsOfUse: 'شروط الاستخدام',
6324
+ conjunction: ' و',
6325
+ privacyPolicy: 'سياسة الخصوصية'
6326
+ },
6327
+ shareMessage: {
6328
+ 'wall-panel': 'معاينة ألواح الجدران',
6329
+ wallart: 'معاينة اللوحة الفنية',
6330
+ rugs: 'معاينة السجادة',
6331
+ flooring: 'معاينة الأرضية'
6332
+ },
6333
+ rooms: {
6334
+ 'room-example-11': 'غرفة نموذجية 11',
6335
+ 'room-example-12': 'غرفة نموذجية 12',
6336
+ 'room-example-13': 'غرفة نموذجية 13',
6337
+ 'room-example-14': 'غرفة نموذجية 14',
6338
+ 'room-example-15': 'غرفة نموذجية 15',
6339
+ 'carpet-bathroom': 'الحمّام',
6340
+ 'carpet-bedroom': 'غرفة النوم',
6341
+ 'carpet-entryway': 'المدخل',
6342
+ 'carpet-living-room': 'غرفة المعيشة'
6343
+ },
6344
+ scene: {
6345
+ tunePosition: 'ضبط الموضع',
6346
+ angle: 'الزاوية',
6347
+ rotation: 'الدوران',
6348
+ resetPosition: 'إعادة التعيين'
6349
+ },
6350
+ accessError: {
6351
+ unauthorized: 'مفتاح API غير صالح',
6352
+ 'payment-required': 'العارض غير متاح مؤقتًا'
6353
+ },
6354
+ loadError: {
6355
+ 'viewer-load-failed': 'تعذّر تحميل العارض. يُرجى المحاولة مرة أخرى.',
6356
+ 'artwork-load-failed': 'تعذّر تحميل الصورة — رابطها مفقود أو غير صحيح في إعدادات الأداة.',
6357
+ 'room-load-failed': 'تعذّر تحميل صورة الغرفة. يُرجى المحاولة مرة أخرى.'
6358
+ },
6359
+ missingSurface: {
6360
+ floor: {
6361
+ title: 'لم نتمكن من العثور على الأرضية',
6362
+ body: 'جرّب صورة تظهر فيها الأرضية.'
6363
+ },
6364
+ wall: {
6365
+ title: 'لم نتمكن من العثور على جدار',
6366
+ body: 'جرّب صورة يظهر فيها جدار.'
6367
+ },
6368
+ uploadAnother: 'رفع صورة أخرى'
6369
+ },
6370
+ wallPanel: {
6371
+ loading: 'جارٍ تحميل الخامة',
6372
+ panelActions: 'إجراءات اللوح {{number}}',
6373
+ retry: 'تعذّر التحميل. اختر مرة أخرى لإعادة المحاولة.',
6374
+ actions: 'إجراءات اللوح',
6375
+ materials: 'الخامات',
6376
+ materialFallback: 'الخامة {{number}}',
6377
+ rotate: 'تدوير اللوح',
6378
+ delete: 'حذف اللوح'
6379
+ },
6380
+ wallArt: {
6381
+ pictureFrame: 'الإطار'
6382
+ },
6383
+ resourceType: {
6384
+ 'wall-panel': {
6385
+ productCategory: 'لوح جداري',
6386
+ productCardTitle: 'اللوح المحدد',
6387
+ replaceProduct: 'استبدال اللوح',
6388
+ replaceProductShort: 'استبدال'
6389
+ },
6390
+ wallart: {
6391
+ productCardTitle: 'اللوحة الفنية المحددة',
6392
+ appearance: 'استبدال'
6393
+ },
6394
+ rugs: {
6395
+ productCategory: 'سجادة',
6396
+ productCardTitle: 'السجادة المحددة',
6397
+ replaceProduct: 'استبدال السجادة',
6398
+ replaceProductShort: 'استبدال'
6399
+ },
6400
+ flooring: {
6401
+ productCategory: 'أرضية',
6402
+ productCardTitle: 'الأرضية المحددة',
6403
+ replaceProduct: 'استبدال الأرضية',
6404
+ replaceProductShort: 'استبدال'
6405
+ }
6406
+ },
6407
+ floor: {
6408
+ scene: {
6409
+ share: 'مشاركة',
6410
+ download: 'تنزيل',
6411
+ hideCatalog: 'إخفاء الكتالوج',
6412
+ description: 'الوصف',
6413
+ interiorCardTitle: 'التصميم الداخلي',
6414
+ tryAtHome: 'جرّبه في منزلك',
6415
+ tryAtHomeBody: 'عبر كاميرا هاتفك'
6416
+ },
6417
+ materialSelection: {
6418
+ flooring: 'اختر الأرضية',
6419
+ rugs: 'اختر سجادة',
6420
+ 'wall-panel': 'اختر لوحًا',
6421
+ title: 'اختيار الخامة'
6422
+ },
6423
+ interiorSelection: {
6424
+ title: 'اختر التصميم الداخلي',
6425
+ uploadPhoto: 'ارفع صورتك',
6426
+ invalidFile: 'تعذّر رفع الصورة، يُرجى المحاولة مرة أخرى',
6427
+ customTitle: 'صورك',
6428
+ presetsTitle: 'تصاميم داخلية جاهزة',
6429
+ currentInterior: 'التصميم الداخلي الحالي',
6430
+ chooseInterior: 'اختر التصميم الداخلي',
6431
+ chooseInteriorShort: 'اختر'
6432
+ },
6433
+ processing: {
6434
+ title: 'جارٍ تجهيز غرفتك',
6435
+ progressLabel: 'تقدّم تجهيز الغرفة',
6436
+ stages: {
6437
+ reading: 'جارٍ قراءة صورتك...',
6438
+ mapping: 'جارٍ تحديد الأرضيات والجدران...',
6439
+ lighting: 'جارٍ موازنة الإضاءة والمنظور...',
6440
+ finalizing: 'جارٍ إنشاء المعاينة...',
6441
+ ready: 'الغرفة جاهزة...'
6442
+ }
6443
+ },
6444
+ error: {
6445
+ title: 'حدث خطأ ما',
6446
+ processingBody: 'لم نتمكن هذه المرة من رفع الصورة ومعالجتها',
6447
+ loadBody: 'تعذّر تحميل العارض. يُرجى المحاولة مرة أخرى.',
6448
+ tryAgain: 'حاول مرة أخرى',
6449
+ cancel: 'إلغاء'
6450
+ }
6451
+ }
6452
+ };
6453
+ const ar_ns1 = ns1;
6454
+ const ns1_ns1 = {
6260
6455
  matting: 'Matting',
6261
6456
  close: 'Close',
6262
6457
  mattingOptions: {
@@ -6275,7 +6470,7 @@ const ns1 = {
6275
6470
  },
6276
6471
  legal: {
6277
6472
  termsOfUse: 'Terms of Use',
6278
- conjunction: 'and',
6473
+ conjunction: ' and ',
6279
6474
  privacyPolicy: 'Privacy Policy'
6280
6475
  },
6281
6476
  shareMessage: {
@@ -6404,8 +6599,8 @@ const ns1 = {
6404
6599
  }
6405
6600
  }
6406
6601
  };
6407
- const en_ns1 = ns1;
6408
- const ns1_ns1 = {
6602
+ const en_ns1 = ns1_ns1;
6603
+ const ru_ns1_ns1 = {
6409
6604
  matting: 'Паспарту',
6410
6605
  close: 'Закрыть',
6411
6606
  mattingOptions: {
@@ -6424,7 +6619,7 @@ const ns1_ns1 = {
6424
6619
  },
6425
6620
  legal: {
6426
6621
  termsOfUse: 'Условия использования',
6427
- conjunction: 'и',
6622
+ conjunction: ' и ',
6428
6623
  privacyPolicy: 'Политика конфиденциальности'
6429
6624
  },
6430
6625
  shareMessage: {
@@ -6553,17 +6748,20 @@ const ns1_ns1 = {
6553
6748
  }
6554
6749
  }
6555
6750
  };
6556
- const ru_ns1 = ns1_ns1;
6751
+ const ru_ns1 = ru_ns1_ns1;
6557
6752
  const resources = {
6558
6753
  en: {
6559
6754
  translation: en_ns1
6560
6755
  },
6561
6756
  ru: {
6562
6757
  translation: ru_ns1
6758
+ },
6759
+ ar: {
6760
+ translation: ar_ns1
6563
6761
  }
6564
6762
  };
6565
- const roomViewerI18n = i18next.createInstance();
6566
- roomViewerI18n.use(i18next_browser_languagedetector).use(initReactI18next).init({
6763
+ const ROOM_VIEWER_LANGUAGES = Object.keys(resources);
6764
+ const initOptions = {
6567
6765
  debug: false,
6568
6766
  detection: {
6569
6767
  caches: []
@@ -6573,7 +6771,38 @@ roomViewerI18n.use(i18next_browser_languagedetector).use(initReactI18next).init(
6573
6771
  interpolation: {
6574
6772
  escapeValue: false
6575
6773
  }
6576
- });
6774
+ };
6775
+ function createRoomViewerI18n(language) {
6776
+ const instance = i18next.createInstance();
6777
+ instance.use(i18next_browser_languagedetector).init({
6778
+ ...initOptions,
6779
+ lng: language
6780
+ });
6781
+ return instance;
6782
+ }
6783
+ const roomViewerI18n = i18next.createInstance();
6784
+ roomViewerI18n.use(i18next_browser_languagedetector).use(initReactI18next).init(initOptions);
6785
+ function resolveRoomViewerLanguage(i18n) {
6786
+ const language = i18n.resolvedLanguage ?? i18n.language;
6787
+ return ROOM_VIEWER_LANGUAGES.find((candidate)=>candidate === language) ?? 'en';
6788
+ }
6789
+ function getRoomViewerDirection(language) {
6790
+ return 'ar' === language ? 'rtl' : 'ltr';
6791
+ }
6792
+ function useRoomViewerLanguage() {
6793
+ const { i18n } = useTranslation();
6794
+ return resolveRoomViewerLanguage(i18n);
6795
+ }
6796
+ function useRoomViewerDirection(viewerI18n) {
6797
+ const { i18n } = useTranslation(void 0, {
6798
+ i18n: viewerI18n
6799
+ });
6800
+ const language = resolveRoomViewerLanguage(i18n);
6801
+ return {
6802
+ language,
6803
+ direction: getRoomViewerDirection(language)
6804
+ };
6805
+ }
6577
6806
  const PROPERTY_BLOCK_RE = /@property\s+(--[^{\s]+)\s*\{([^}]*)\}/g;
6578
6807
  const INITIAL_VALUE_RE = /initial-value:([^;}]+)/i;
6579
6808
  const NON_INHERITING_RE = /inherits:\s*false(?:\s*;|\s*$)/i;
@@ -6601,69 +6830,6 @@ ${propertyDefaults}
6601
6830
  }
6602
6831
  var styleinline = __webpack_require__("./src/style.css?inline");
6603
6832
  const shadowRootCssText = createShadowRootCssText(styleinline.A);
6604
- function getRoomViewerBackendApiBaseUrl(baseUrl) {
6605
- const normalized = baseUrl?.trim().replace(/\/+$/, '') ?? '';
6606
- if (!normalized || normalized.includes('/v1/http') || normalized.endsWith('/v1')) return normalized || void 0;
6607
- const httpSegmentIndex = normalized.indexOf('/http');
6608
- if (httpSegmentIndex >= 0) return `${normalized.slice(0, httpSegmentIndex)}/v1${normalized.slice(httpSegmentIndex)}`;
6609
- return `${normalized}/v1`;
6610
- }
6611
- const shopifyProxyApiBaseUrl = getRoomViewerBackendApiBaseUrl("/apps/vizbl-wall-art/http") ?? '';
6612
- function getRoomViewerApiBaseUrl(baseUrl) {
6613
- return baseUrl?.trim().replace(/\/+$/, '').replace(/\/(?:v1(?:\/http)?|http)$/, '') || void 0;
6614
- }
6615
- function normalizeRoomViewerApiKey(apiKey) {
6616
- const trimmed = apiKey?.trim();
6617
- return trimmed || void 0;
6618
- }
6619
- function normalizeRoomViewerTinuuid(tinuuid) {
6620
- const trimmed = tinuuid?.trim();
6621
- return trimmed || void 0;
6622
- }
6623
- function shouldUseRoomViewerPublicApi(options) {
6624
- return 'shopify' === options.source || void 0 !== options.apiKey;
6625
- }
6626
- function getRoomViewerPublicApiProductType(options) {
6627
- if ('wall-panel' === options.resourceType) return 'panels';
6628
- if ('rugs' === options.resourceType) return 'rugs';
6629
- if ('flooring' === options.resourceType) return 'flooring';
6630
- return 'shopify' === options.source ? 'wallart-shopify' : 'wallart';
6631
- }
6632
- function getRoomViewerBackendProductType(options) {
6633
- if ('wall-panel' === options.resourceType) return 'panels';
6634
- if ('rugs' === options.resourceType) return 'rugs';
6635
- if ('flooring' === options.resourceType) return 'flooring';
6636
- return 'wallart';
6637
- }
6638
- function getRoomViewerPublicApiQuery(options) {
6639
- const productType = getRoomViewerPublicApiProductType(options);
6640
- return 'panels' === productType ? {
6641
- query: void 0,
6642
- config: {
6643
- params: {
6644
- productType
6645
- }
6646
- }
6647
- } : {
6648
- query: {
6649
- productType
6650
- },
6651
- config: {}
6652
- };
6653
- }
6654
- function getRoomViewerActivationQuery(options) {
6655
- return getRoomViewerPublicApiQuery('wall-panel' === options.resourceType ? options : {
6656
- ...options,
6657
- resourceType: void 0
6658
- });
6659
- }
6660
- function getRoomViewerAccessError(error) {
6661
- if (!isAxiosError(error)) return null;
6662
- const status = error.response?.status;
6663
- if (401 === status) return 'unauthorized';
6664
- if (402 === status) return 'payment-required';
6665
- return null;
6666
- }
6667
6833
  const DEFAULT_API_TIMEOUT = 30000;
6668
6834
  function createDefaultClient(defaultBaseURL) {
6669
6835
  return axios.create({
@@ -7088,6 +7254,17 @@ async function layoutControllerReadLayoutConfig(headers, config = {}) {
7088
7254
  });
7089
7255
  return res.data;
7090
7256
  }
7257
+ async function arLaunchControllerCreateArLaunch(data, config = {}) {
7258
+ const { client: request = client_client, ...requestConfig } = config;
7259
+ const requestData = data;
7260
+ const res = await request({
7261
+ method: "POST",
7262
+ url: "/public/ar-launches",
7263
+ data: requestData,
7264
+ ...requestConfig
7265
+ });
7266
+ return res.data;
7267
+ }
7091
7268
  async function publicApiControllerActivateWallart(params, config = {}) {
7092
7269
  const { client: request = client_client, ...requestConfig } = config;
7093
7270
  const res = await request({
@@ -7098,65 +7275,65 @@ async function publicApiControllerActivateWallart(params, config = {}) {
7098
7275
  });
7099
7276
  return res.data;
7100
7277
  }
7101
- async function publicApiControllerGetKitItems(data, config = {}) {
7278
+ async function publicApiControllerIssueWidgetToken(data, config = {}) {
7102
7279
  const { client: request = client_client, ...requestConfig } = config;
7103
7280
  const requestData = data;
7104
7281
  const res = await request({
7105
7282
  method: "POST",
7106
- url: "/public/kits/items",
7283
+ url: "/public/widget/token",
7107
7284
  data: requestData,
7108
7285
  ...requestConfig
7109
7286
  });
7110
7287
  return res.data;
7111
7288
  }
7112
- async function publicApiControllerGetPublicObjects(data, params, config = {}) {
7289
+ async function publicApiControllerReadKitItems(data, config = {}) {
7113
7290
  const { client: request = client_client, ...requestConfig } = config;
7114
7291
  const requestData = data;
7115
7292
  const res = await request({
7116
7293
  method: "POST",
7117
- url: "/public/objects/public",
7118
- params,
7294
+ url: "/public/kits/items",
7119
7295
  data: requestData,
7120
7296
  ...requestConfig
7121
7297
  });
7122
7298
  return res.data;
7123
7299
  }
7124
- async function publicApiControllerGetShopifyWidgetRooms(params, config = {}) {
7300
+ async function publicApiControllerReadObjectByTinuuid({ tinuuid }, params, config = {}) {
7125
7301
  const { client: request = client_client, ...requestConfig } = config;
7126
7302
  const res = await request({
7127
- method: "POST",
7128
- url: "/public/widget/shopify/get-rooms",
7303
+ method: "GET",
7304
+ url: `/public/objects/by-tinuuid/${tinuuid}`,
7129
7305
  params,
7130
7306
  ...requestConfig
7131
7307
  });
7132
7308
  return res.data;
7133
7309
  }
7134
- async function publicApiControllerGetWidgetRooms(config = {}) {
7310
+ async function publicApiControllerReadPublicObjects(data, params, config = {}) {
7135
7311
  const { client: request = client_client, ...requestConfig } = config;
7312
+ const requestData = data;
7136
7313
  const res = await request({
7137
7314
  method: "POST",
7138
- url: "/public/widget/get-rooms",
7315
+ url: "/public/objects/public",
7316
+ params,
7317
+ data: requestData,
7139
7318
  ...requestConfig
7140
7319
  });
7141
7320
  return res.data;
7142
7321
  }
7143
- async function publicApiControllerIssueWidgetToken(data, config = {}) {
7322
+ async function publicApiControllerReadShopifyWidgetRooms(params, config = {}) {
7144
7323
  const { client: request = client_client, ...requestConfig } = config;
7145
- const requestData = data;
7146
7324
  const res = await request({
7147
7325
  method: "POST",
7148
- url: "/public/widget/token",
7149
- data: requestData,
7326
+ url: "/public/widget/shopify/get-rooms",
7327
+ params,
7150
7328
  ...requestConfig
7151
7329
  });
7152
7330
  return res.data;
7153
7331
  }
7154
- async function publicApiControllerReadObjectByTinuuid({ tinuuid }, params, config = {}) {
7332
+ async function publicApiControllerReadWidgetRooms(config = {}) {
7155
7333
  const { client: request = client_client, ...requestConfig } = config;
7156
7334
  const res = await request({
7157
- method: "GET",
7158
- url: `/public/objects/by-tinuuid/${tinuuid}`,
7159
- params,
7335
+ method: "POST",
7336
+ url: "/public/widget/get-rooms",
7160
7337
  ...requestConfig
7161
7338
  });
7162
7339
  return res.data;
@@ -7184,6 +7361,90 @@ async function widgetEventsControllerCreateWidgetEvent(data, config = {}) {
7184
7361
  });
7185
7362
  return res.data;
7186
7363
  }
7364
+ function getRoomViewerAccessError(error) {
7365
+ if (!isAxiosError(error)) return null;
7366
+ const status = error.response?.status;
7367
+ if (401 === status) return 'unauthorized';
7368
+ if (402 === status) return 'payment-required';
7369
+ return null;
7370
+ }
7371
+ function createArLaunchId() {
7372
+ if ("u" > typeof crypto && 'function' == typeof crypto.randomUUID) return crypto.randomUUID();
7373
+ const bytes = crypto.getRandomValues(new Uint8Array(16));
7374
+ bytes[6] = 0x0F & bytes[6] | 0x40;
7375
+ bytes[8] = 0x3F & bytes[8] | 0x80;
7376
+ const hex = Array.from(bytes, (byte)=>byte.toString(16).padStart(2, '0')).join('');
7377
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
7378
+ }
7379
+ async function requestArLaunch(session, { format, launchId, tinuuid }) {
7380
+ try {
7381
+ await arLaunchControllerCreateArLaunch({
7382
+ entryPoint: 'ar_launched',
7383
+ format,
7384
+ launchId,
7385
+ tinuuid
7386
+ }, await session.getApiConfigForRequest());
7387
+ return 'granted';
7388
+ } catch (error) {
7389
+ return 'payment-required' === getRoomViewerAccessError(error) ? 'payment-required' : 'unavailable';
7390
+ }
7391
+ }
7392
+ function getRoomViewerBackendApiBaseUrl(baseUrl) {
7393
+ const normalized = baseUrl?.trim().replace(/\/+$/, '') ?? '';
7394
+ if (!normalized || normalized.includes('/v1/http') || normalized.endsWith('/v1')) return normalized || void 0;
7395
+ const httpSegmentIndex = normalized.indexOf('/http');
7396
+ if (httpSegmentIndex >= 0) return `${normalized.slice(0, httpSegmentIndex)}/v1${normalized.slice(httpSegmentIndex)}`;
7397
+ return `${normalized}/v1`;
7398
+ }
7399
+ const shopifyProxyApiBaseUrl = getRoomViewerBackendApiBaseUrl("/apps/vizbl-wall-art/http") ?? '';
7400
+ function getRoomViewerApiBaseUrl(baseUrl) {
7401
+ return baseUrl?.trim().replace(/\/+$/, '').replace(/\/(?:v1(?:\/http)?|http)$/, '') || void 0;
7402
+ }
7403
+ function normalizeRoomViewerApiKey(apiKey) {
7404
+ const trimmed = apiKey?.trim();
7405
+ return trimmed || void 0;
7406
+ }
7407
+ function normalizeRoomViewerTinuuid(tinuuid) {
7408
+ const trimmed = tinuuid?.trim();
7409
+ return trimmed || void 0;
7410
+ }
7411
+ function shouldUseRoomViewerPublicApi(options) {
7412
+ return 'shopify' === options.source || void 0 !== options.apiKey;
7413
+ }
7414
+ function getRoomViewerPublicApiProductType(options) {
7415
+ if ('wall-panel' === options.resourceType) return 'panels';
7416
+ if ('rugs' === options.resourceType) return 'rugs';
7417
+ if ('flooring' === options.resourceType) return 'flooring';
7418
+ return 'shopify' === options.source ? 'wallart-shopify' : 'wallart';
7419
+ }
7420
+ function getRoomViewerBackendProductType(options) {
7421
+ if ('wall-panel' === options.resourceType) return 'panels';
7422
+ if ('rugs' === options.resourceType) return 'rugs';
7423
+ if ('flooring' === options.resourceType) return 'flooring';
7424
+ return 'wallart';
7425
+ }
7426
+ function getRoomViewerPublicApiQuery(options) {
7427
+ const productType = getRoomViewerPublicApiProductType(options);
7428
+ return 'panels' === productType ? {
7429
+ query: void 0,
7430
+ config: {
7431
+ params: {
7432
+ productType
7433
+ }
7434
+ }
7435
+ } : {
7436
+ query: {
7437
+ productType
7438
+ },
7439
+ config: {}
7440
+ };
7441
+ }
7442
+ function getRoomViewerActivationQuery(options) {
7443
+ return getRoomViewerPublicApiQuery('wall-panel' === options.resourceType ? options : {
7444
+ ...options,
7445
+ resourceType: void 0
7446
+ });
7447
+ }
7187
7448
  const WIDGET_SESSION_TOKEN_HEADER = 'x-widget-session-token';
7188
7449
  const DEFAULT_REFRESH_THRESHOLD_MS = 30000;
7189
7450
  const createWidgetEventViaGeneratedApi = (data, config)=>widgetEventsControllerCreateWidgetEvent(data, config);
@@ -7267,10 +7528,20 @@ function createWidgetSessionClient(activationData, options) {
7267
7528
  function sendWidgetEvent(session, event, options = {}) {
7268
7529
  if (!session) return;
7269
7530
  const createWidgetEvent = options.createWidgetEvent ?? createWidgetEventViaGeneratedApi;
7270
- session.getApiConfigForRequest(options.apiConfig).then((apiConfig)=>createWidgetEvent({
7531
+ session.getApiConfigForRequest(options.apiConfig).then((apiConfig)=>{
7532
+ const pagePath = currentPagePath();
7533
+ return createWidgetEvent({
7271
7534
  event,
7272
- timestamp: new Date().toISOString()
7273
- }, apiConfig)).catch(()=>{});
7535
+ timestamp: new Date().toISOString(),
7536
+ ...pagePath ? {
7537
+ page_path: pagePath
7538
+ } : {}
7539
+ }, apiConfig);
7540
+ }).catch(()=>{});
7541
+ }
7542
+ function currentPagePath(locationRef = globalThis.location) {
7543
+ const path = locationRef?.pathname;
7544
+ return 'string' == typeof path && path.startsWith('/') ? path : void 0;
7274
7545
  }
7275
7546
  async function getRoomViewerPublicApiHeaders(options) {
7276
7547
  const headers = {
@@ -7282,9 +7553,10 @@ async function getRoomViewerPublicApiHeaders(options) {
7282
7553
  return headers;
7283
7554
  }
7284
7555
  function getRoomViewerLanguageHeaders(options) {
7285
- return options.language ? {
7286
- Lang: options.language
7287
- } : void 0;
7556
+ if (!options.language) return;
7557
+ return {
7558
+ Lang: 'ru' === options.language ? 'ru' : 'en'
7559
+ };
7288
7560
  }
7289
7561
  function roomViewerObjectQueryKey(tinuuid, options) {
7290
7562
  return [
@@ -7361,7 +7633,7 @@ async function fetchRoomViewerOwnerObjects(ownerUuid, page, options) {
7361
7633
  signal: options.signal
7362
7634
  });
7363
7635
  const { query, config } = getRoomViewerPublicApiQuery(options);
7364
- return await publicApiControllerGetPublicObjects({
7636
+ return await publicApiControllerReadPublicObjects({
7365
7637
  ...data,
7366
7638
  productType: getRoomViewerPublicApiProductType(options)
7367
7639
  }, query, {
@@ -7384,7 +7656,7 @@ async function fetchRoomViewerKitObjects(kitUuid, _ownerUuid, page, options) {
7384
7656
  signal: options.signal
7385
7657
  });
7386
7658
  const { query, config } = getRoomViewerPublicApiQuery(options);
7387
- const response = await publicApiControllerGetKitItems({
7659
+ const response = await publicApiControllerReadKitItems({
7388
7660
  kitUuid,
7389
7661
  page,
7390
7662
  limit: KIT_PAGE_LIMIT
@@ -7423,10 +7695,10 @@ async function fetchRoomViewerRooms(options) {
7423
7695
  signal: options.signal
7424
7696
  };
7425
7697
  const publicQuery = getRoomViewerPublicApiQuery(options);
7426
- const response = 'shopify' === options.source ? await publicApiControllerGetShopifyWidgetRooms(publicQuery.query, {
7698
+ const response = 'shopify' === options.source ? await publicApiControllerReadShopifyWidgetRooms(publicQuery.query, {
7427
7699
  ...config,
7428
7700
  ...publicQuery.config
7429
- }) : await publicApiControllerGetWidgetRooms(config);
7701
+ }) : await publicApiControllerReadWidgetRooms(config);
7430
7702
  return response.rooms.filter((room)=>false !== room.active).sort((left, right)=>(left.position ?? 0) - (right.position ?? 0)).map((room)=>({
7431
7703
  id: room.id,
7432
7704
  name: room.name,
@@ -7509,7 +7781,7 @@ function DialogContent({ className, children, contentInsideOverlay = false, show
7509
7781
  children,
7510
7782
  showCloseButton && /*#__PURE__*/ jsxs(Close, {
7511
7783
  "data-slot": "dialog-close",
7512
- className: "focus-visible:ring-ring/30 absolute top-4 right-4 inline-flex size-6 cursor-pointer items-center justify-center rounded-full text-icons-light transition-colors hover:text-icons-normal focus-visible:text-icons-dark focus-visible:ring-2 focus-visible:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0",
7784
+ className: "focus-visible:ring-ring/30 absolute top-4 end-4 inline-flex size-6 cursor-pointer items-center justify-center rounded-full text-icons-light transition-colors hover:text-icons-normal focus-visible:text-icons-dark focus-visible:ring-2 focus-visible:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0",
7513
7785
  children: [
7514
7786
  /*#__PURE__*/ jsx(XIcon, {
7515
7787
  className: "size-6"
@@ -8088,19 +8360,19 @@ function DropdownMenuItem({ className, inset, variant = 'default', ...props }) {
8088
8360
  "data-slot": "dropdown-menu-item",
8089
8361
  "data-inset": inset,
8090
8362
  "data-variant": variant,
8091
- className: utils_cn('relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden hover:bg-background-base focus:bg-background-base data-[highlighted]:bg-background-base data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:hover:bg-destructive/10 data-[highlighted][data-variant=destructive]:bg-destructive/10 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*=text-])]:text-muted-foreground data-[variant=destructive]:[&_svg:not([class*=text-])]:text-inherit [&_svg]:pointer-events-none [&_svg]:shrink-0', inset && 'pl-8', className),
8363
+ className: utils_cn('relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden hover:bg-background-base focus:bg-background-base data-[highlighted]:bg-background-base data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:hover:bg-destructive/10 data-[highlighted][data-variant=destructive]:bg-destructive/10 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*=text-])]:text-muted-foreground data-[variant=destructive]:[&_svg:not([class*=text-])]:text-inherit [&_svg]:pointer-events-none [&_svg]:shrink-0', inset && 'ps-8', className),
8092
8364
  ...props
8093
8365
  });
8094
8366
  }
8095
8367
  function DropdownMenuCheckboxItem({ className, children, checked, indicatorPosition = 'left', ...props }) {
8096
8368
  return /*#__PURE__*/ jsxs(CheckboxItem, {
8097
8369
  "data-slot": "dropdown-menu-checkbox-item",
8098
- className: utils_cn('relative flex cursor-default select-none items-center rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden hover:bg-background-base focus:bg-background-base data-[highlighted]:bg-background-base data-[disabled]:pointer-events-none data-[disabled]:opacity-50', 'right' === indicatorPosition && 'pr-8 pl-2', className),
8370
+ className: utils_cn('relative flex cursor-default select-none items-center rounded-sm py-1.5 pe-2 ps-8 text-sm outline-hidden hover:bg-background-base focus:bg-background-base data-[highlighted]:bg-background-base data-[disabled]:pointer-events-none data-[disabled]:opacity-50', 'right' === indicatorPosition && 'pe-8 ps-2', className),
8099
8371
  checked: checked,
8100
8372
  ...props,
8101
8373
  children: [
8102
8374
  /*#__PURE__*/ jsx("span", {
8103
- className: utils_cn('pointer-events-none absolute flex size-3.5 items-center justify-center', 'right' === indicatorPosition ? 'right-2' : 'left-2'),
8375
+ className: utils_cn('pointer-events-none absolute flex size-3.5 items-center justify-center', 'right' === indicatorPosition ? 'end-2' : 'start-2'),
8104
8376
  children: /*#__PURE__*/ jsx(ItemIndicator, {
8105
8377
  children: /*#__PURE__*/ jsx(CheckIcon, {
8106
8378
  className: "size-4"
@@ -8115,7 +8387,7 @@ function DropdownMenuLabel({ className, inset, ...props }) {
8115
8387
  return /*#__PURE__*/ jsx(react_dropdown_menu_Label, {
8116
8388
  "data-slot": "dropdown-menu-label",
8117
8389
  "data-inset": inset,
8118
- className: utils_cn('px-2 py-1.5 text-sm font-medium', inset && 'pl-8', className),
8390
+ className: utils_cn('px-2 py-1.5 text-sm font-medium', inset && 'ps-8', className),
8119
8391
  ...props
8120
8392
  });
8121
8393
  }
@@ -12234,7 +12506,7 @@ function InteriorSelectionEntry({ rooms, customRooms, selectedRoomId, isInvalidF
12234
12506
  function renderInteriorCards(interiorRooms) {
12235
12507
  return interiorRooms.map((room)=>/*#__PURE__*/ jsxs("button", {
12236
12508
  type: "button",
12237
- className: "group relative aspect-[4/3] overflow-hidden rounded-2xl bg-background-base text-left transition focus-visible:ring-2 focus-visible:ring-icons-normal focus-visible:outline-hidden",
12509
+ className: "group relative aspect-[4/3] overflow-hidden rounded-2xl bg-background-base text-start transition focus-visible:ring-2 focus-visible:ring-icons-normal focus-visible:outline-hidden",
12238
12510
  "aria-pressed": room.id === selectedRoomId,
12239
12511
  onClick: ()=>onSelectRoom(room.id),
12240
12512
  children: [
@@ -12259,7 +12531,7 @@ function InteriorSelectionEntry({ rooms, customRooms, selectedRoomId, isInvalidF
12259
12531
  type: "button",
12260
12532
  variant: "outline",
12261
12533
  size: "icon",
12262
- className: "absolute top-4 right-4 sm:top-6 sm:right-6",
12534
+ className: "absolute top-4 end-4 sm:top-6 sm:end-6",
12263
12535
  "aria-label": t('close'),
12264
12536
  "data-testid": "floor-interior-selection-icon-close",
12265
12537
  children: /*#__PURE__*/ jsx(close_Close, {})
@@ -12312,7 +12584,7 @@ function InteriorSelectionEntry({ rooms, customRooms, selectedRoomId, isInvalidF
12312
12584
  ]
12313
12585
  }),
12314
12586
  /*#__PURE__*/ jsx("div", {
12315
- className: "grid min-h-0 overflow-y-auto overflow-x-hidden overscroll-contain pr-1 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden",
12587
+ className: "grid min-h-0 overflow-y-auto overflow-x-hidden overscroll-contain pe-1 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden",
12316
12588
  "data-testid": "floor-interior-selection-scroll-content",
12317
12589
  children: /*#__PURE__*/ jsxs("div", {
12318
12590
  className: "grid min-h-max gap-4",
@@ -12775,7 +13047,7 @@ function MaterialSelectionContent({ className, gridClassName, titleClassName, on
12775
13047
  /*#__PURE__*/ jsx("div", {
12776
13048
  "data-testid": "material-selection-grid",
12777
13049
  ref: gridRef,
12778
- className: utils_cn('min-h-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-contain pr-1 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden', gridClassName),
13050
+ className: utils_cn('min-h-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-contain pe-1 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden', gridClassName),
12779
13051
  onScroll: handleScroll,
12780
13052
  children: /*#__PURE__*/ jsxs("div", {
12781
13053
  className: "grid min-h-max grid-cols-3 gap-x-2 gap-y-2",
@@ -12788,7 +13060,7 @@ function MaterialSelectionContent({ className, gridClassName, titleClassName, on
12788
13060
  type: "button",
12789
13061
  "data-selected": isSelected,
12790
13062
  "aria-pressed": isSelected,
12791
- className: "group flex min-w-0 flex-col gap-1 rounded-lg bg-background-containers text-left focus-visible:ring-2 focus-visible:ring-icons-normal focus-visible:outline-hidden",
13063
+ className: "group flex min-w-0 flex-col gap-1 rounded-lg bg-background-containers text-start focus-visible:ring-2 focus-visible:ring-icons-normal focus-visible:outline-hidden",
12792
13064
  onClick: ()=>handleSelectMaterial(materialId),
12793
13065
  onKeyDown: (event)=>{
12794
13066
  if ('Enter' === event.key || ' ' === event.key) {
@@ -12808,7 +13080,7 @@ function MaterialSelectionContent({ className, gridClassName, titleClassName, on
12808
13080
  className: "size-6 text-icons-normal"
12809
13081
  }),
12810
13082
  isSelected && /*#__PURE__*/ jsx("span", {
12811
- className: "absolute top-1 right-1 grid size-6 place-items-center rounded-full bg-icons-blue text-icons-white",
13083
+ className: "absolute top-1 end-1 grid size-6 place-items-center rounded-full bg-icons-blue text-icons-white",
12812
13084
  "data-testid": "material-selection-selected-check",
12813
13085
  children: /*#__PURE__*/ jsx(CheckDone, {
12814
13086
  className: "size-4"
@@ -12969,7 +13241,7 @@ function ProcessingRoomDialog({ isComplete, open, onCloseAnimationEnd, onOpenCha
12969
13241
  className: "flex min-w-0 items-center justify-between gap-3",
12970
13242
  children: [
12971
13243
  /*#__PURE__*/ jsx("span", {
12972
- className: "typo-base-14 min-w-0 flex-1 truncate text-left font-medium text-text-light",
13244
+ className: "typo-base-14 min-w-0 flex-1 truncate text-start font-medium text-text-light",
12973
13245
  children: t(activeStage.translationKey)
12974
13246
  }),
12975
13247
  /*#__PURE__*/ jsxs("span", {
@@ -13338,9 +13610,7 @@ function QRCode({ data, foreground, background, robustness = 'M', className, ...
13338
13610
  });
13339
13611
  }
13340
13612
  function useRoomViewerTenant() {
13341
- const { i18n } = useTranslation();
13342
- const language = i18n.resolvedLanguage ?? i18n.language;
13343
- return 'ru' === language ? 'arizo' : 'vizbl';
13613
+ return 'ru' === useRoomViewerLanguage() ? 'arizo' : 'vizbl';
13344
13614
  }
13345
13615
  function isAbsoluteUrl(value) {
13346
13616
  return /^[a-z][a-z0-9+.-]*:/i.test(value) || value.startsWith('//');
@@ -13371,6 +13641,7 @@ function buildRoomViewerArUrl({ height, language, name, src, tenantConfig, tinuu
13371
13641
  if (widgetSessionToken) url.searchParams.set('widgetSessionToken', widgetSessionToken);
13372
13642
  return url.toString();
13373
13643
  }
13644
+ const AR_LAUNCH_TIMEOUT_MS = 3000;
13374
13645
  async function whenArModeSelected(modelViewer) {
13375
13646
  await modelViewer.updateComplete;
13376
13647
  if (!modelViewer.canActivateAR && navigator.xr?.isSessionSupported) {
@@ -13399,7 +13670,7 @@ async function presentAr(modelViewer) {
13399
13670
  function AR({ className, buttonClassName, buttonLeadingIcon, buttonLabel, buttonSize, buttonVariant = 'contrast', ...props }) {
13400
13671
  const { type, width, height, name } = useRoomViewerMetadata();
13401
13672
  const { handoff } = resolveResourceProfile(type);
13402
- const { src, tinuuid, widgetSession } = useRoomViewerResource();
13673
+ const { setAccessError, src, tinuuid, widgetSession } = useRoomViewerResource();
13403
13674
  const { containerRef, resourceRef } = useRoomViewerSceneState();
13404
13675
  const { t, i18n } = useTranslation();
13405
13676
  const tenant = useRoomViewerTenant();
@@ -13475,16 +13746,34 @@ function AR({ className, buttonClassName, buttonLeadingIcon, buttonLabel, button
13475
13746
  modelViewerMountRef.current = null;
13476
13747
  setIsModelViewerRequested(false);
13477
13748
  }
13749
+ async function readWidgetSessionToken() {
13750
+ return widgetSession?.getTokenForRequest().catch(()=>widgetSession.token);
13751
+ }
13478
13752
  async function refreshHandoffWidgetSessionToken() {
13479
- const nextToken = await widgetSession?.getTokenForRequest().catch(()=>widgetSession.token);
13480
- setHandoffWidgetSessionToken(nextToken);
13753
+ setHandoffWidgetSessionToken(await readWidgetSessionToken());
13754
+ }
13755
+ async function payForArLaunch() {
13756
+ if (!widgetSession || !tinuuid) return 'unavailable';
13757
+ const timeout = new Promise((resolve)=>{
13758
+ window.setTimeout(()=>resolve('unavailable'), AR_LAUNCH_TIMEOUT_MS);
13759
+ });
13760
+ return Promise.race([
13761
+ requestArLaunch(widgetSession, {
13762
+ format: isIOS() ? 'usdz' : 'glb',
13763
+ launchId: createArLaunchId(),
13764
+ tinuuid
13765
+ }),
13766
+ timeout
13767
+ ]);
13481
13768
  }
13482
13769
  const handleClick = async ()=>{
13483
13770
  if (handoff?.ar === 'appclip') {
13484
13771
  if (!tinuuid) return;
13485
13772
  if (isIOS() && appClipUrl) {
13486
- sendWidgetEvent(widgetSession, 'appclip');
13487
- window.location.assign(appClipUrl);
13773
+ const token = await readWidgetSessionToken();
13774
+ const link = new URL(appClipUrl);
13775
+ if (token) link.searchParams.set('widgetSessionToken', token);
13776
+ window.location.assign(link.toString());
13488
13777
  return;
13489
13778
  }
13490
13779
  await refreshHandoffWidgetSessionToken();
@@ -13501,53 +13790,59 @@ function AR({ className, buttonClassName, buttonLeadingIcon, buttonLabel, button
13501
13790
  }
13502
13791
  const sceneResource = resourceRef.current;
13503
13792
  if (!sceneResource) return void releaseModelViewer();
13504
- if (modelViewer.canActivateAR) try {
13505
- setIsSceneExporting(true);
13506
- const clone = sceneResource.clone(true);
13507
- clone.position.set(0, 0, 0);
13508
- clone.quaternion.identity();
13509
- clone.updateMatrix();
13510
- clone.updateMatrixWorld(true);
13511
- if (isIOS()) {
13512
- clone.rotation.set(-Math.PI / 2, 0, 0);
13793
+ if (modelViewer.canActivateAR) {
13794
+ if (await payForArLaunch() === 'payment-required') {
13795
+ releaseModelViewer();
13796
+ setAccessError('payment-required');
13797
+ return;
13798
+ }
13799
+ try {
13800
+ setIsSceneExporting(true);
13801
+ const clone = sceneResource.clone(true);
13802
+ clone.position.set(0, 0, 0);
13803
+ clone.quaternion.identity();
13513
13804
  clone.updateMatrix();
13514
13805
  clone.updateMatrixWorld(true);
13515
- const usdzExporter = new USDZExporter();
13516
- const usdzBuffer = await usdzExporter.parseAsync(clone, {
13517
- ar: {
13518
- anchoring: {
13519
- type: 'plane'
13520
- },
13521
- planeAnchoring: {
13522
- alignment: 'vertical'
13806
+ if (isIOS()) {
13807
+ clone.rotation.set(-Math.PI / 2, 0, 0);
13808
+ clone.updateMatrix();
13809
+ clone.updateMatrixWorld(true);
13810
+ const usdzExporter = new USDZExporter();
13811
+ const usdzBuffer = await usdzExporter.parseAsync(clone, {
13812
+ ar: {
13813
+ anchoring: {
13814
+ type: 'plane'
13815
+ },
13816
+ planeAnchoring: {
13817
+ alignment: 'vertical'
13818
+ }
13523
13819
  }
13524
- }
13525
- });
13526
- const usdzFile = new File([
13527
- usdzBuffer
13528
- ], 'scene.usdz', {
13529
- type: 'model/vnd.usdz+zip'
13530
- });
13531
- setUsdzUrl(URL.createObjectURL(usdzFile));
13532
- } else {
13533
- const glbExporter = new GLTFExporter();
13534
- const glbBuffer = await glbExporter.parseAsync(clone, {
13535
- binary: true
13536
- });
13537
- const glbFile = new File([
13538
- glbBuffer
13539
- ], 'scene.glb', {
13540
- type: 'model/gltf-binary'
13541
- });
13542
- setGlbUrl(URL.createObjectURL(glbFile));
13820
+ });
13821
+ const usdzFile = new File([
13822
+ usdzBuffer
13823
+ ], 'scene.usdz', {
13824
+ type: 'model/vnd.usdz+zip'
13825
+ });
13826
+ setUsdzUrl(URL.createObjectURL(usdzFile));
13827
+ } else {
13828
+ const glbExporter = new GLTFExporter();
13829
+ const glbBuffer = await glbExporter.parseAsync(clone, {
13830
+ binary: true
13831
+ });
13832
+ const glbFile = new File([
13833
+ glbBuffer
13834
+ ], 'scene.glb', {
13835
+ type: 'model/gltf-binary'
13836
+ });
13837
+ setGlbUrl(URL.createObjectURL(glbFile));
13838
+ }
13839
+ } catch (error) {
13840
+ releaseModelViewer();
13841
+ throw error;
13842
+ } finally{
13843
+ setIsSceneExporting(false);
13543
13844
  }
13544
- } catch (error) {
13545
- releaseModelViewer();
13546
- throw error;
13547
- } finally{
13548
- setIsSceneExporting(false);
13549
- }
13550
- else {
13845
+ } else {
13551
13846
  releaseModelViewer();
13552
13847
  await refreshHandoffWidgetSessionToken();
13553
13848
  setOpen(true);
@@ -13633,9 +13928,7 @@ function AR({ className, buttonClassName, buttonLeadingIcon, buttonLabel, button
13633
13928
  },
13634
13929
  children: t('legal.termsOfUse')
13635
13930
  }),
13636
- ' ',
13637
13931
  t('legal.conjunction'),
13638
- ' ',
13639
13932
  /*#__PURE__*/ jsx("a", {
13640
13933
  href: tenantConfig.PRIVACY_URL,
13641
13934
  target: "_blank",
@@ -13790,12 +14083,12 @@ function SelectContent({ className, children, position = 'item-aligned', align =
13790
14083
  function SelectItem({ className, children, ...props }) {
13791
14084
  return /*#__PURE__*/ jsxs(Select.Item, {
13792
14085
  "data-slot": "select-item",
13793
- className: utils_cn('relative flex w-full cursor-pointer select-none items-center gap-2 rounded-md py-2.5 pr-8 pl-3 outline-hidden', 'typo-base-16 text-text-sub', 'focus:bg-background-base focus:text-text-dark', 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50', '[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-6 [&_svg:not([class*=text-])]:text-text-dark', '*:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2', className),
14086
+ className: utils_cn('relative flex w-full cursor-pointer select-none items-center gap-2 rounded-md py-2.5 pe-8 ps-3 outline-hidden', 'typo-base-16 text-text-sub', 'focus:bg-background-base focus:text-text-dark', 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50', '[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-6 [&_svg:not([class*=text-])]:text-text-dark', '*:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2', className),
13794
14087
  ...props,
13795
14088
  children: [
13796
14089
  /*#__PURE__*/ jsx("span", {
13797
14090
  "data-slot": "select-item-indicator",
13798
- className: "absolute right-2 flex size-6 items-center justify-center",
14091
+ className: "absolute end-2 flex size-6 items-center justify-center",
13799
14092
  children: /*#__PURE__*/ jsx(Select.ItemIndicator, {
13800
14093
  children: /*#__PURE__*/ jsx(CheckDone, {
13801
14094
  className: "size-5"
@@ -14278,9 +14571,9 @@ function ResetPositionButton() {
14278
14571
  });
14279
14572
  }
14280
14573
  const CONTAINER_CLASS_NAMES = {
14281
- card: 'flex min-h-24 w-fit max-w-100 items-center gap-4 rounded-2xl bg-background-containers p-4 text-left text-text-dark shadow-[var(--shadow-login)]',
14282
- 'compact-card': 'flex min-h-[116px] w-fit max-w-[421px] items-center gap-4 rounded-2xl bg-background-containers p-4 text-left text-text-dark shadow-[var(--shadow-login)]',
14283
- 'flow-card': 'flex items-center justify-start gap-4 border-b border-border-light bg-background-containers p-4 text-left'
14574
+ card: 'flex min-h-24 w-fit max-w-100 items-center gap-4 rounded-2xl bg-background-containers p-4 text-start text-text-dark shadow-[var(--shadow-login)]',
14575
+ 'compact-card': 'flex min-h-[116px] w-fit max-w-[421px] items-center gap-4 rounded-2xl bg-background-containers p-4 text-start text-text-dark shadow-[var(--shadow-login)]',
14576
+ 'flow-card': 'flex items-center justify-start gap-4 border-b border-border-light bg-background-containers p-4 text-start'
14284
14577
  };
14285
14578
  const ICON_CLASS_NAMES = {
14286
14579
  card: 'size-6 text-icons-normal',
@@ -14414,7 +14707,7 @@ function ProductCardSlot({ actions, band, slot, presentation }) {
14414
14707
  children: [
14415
14708
  /*#__PURE__*/ jsx(SelectTrigger, {
14416
14709
  size: "sm",
14417
- className: "ml-auto w-fit min-w-0 shrink data-[size=sm]:h-8 *:data-[slot=select-value]:block *:data-[slot=select-value]:truncate",
14710
+ className: "ms-auto w-fit min-w-0 shrink data-[size=sm]:h-8 *:data-[slot=select-value]:block *:data-[slot=select-value]:truncate",
14418
14711
  "data-testid": `${testId}-variant-select`,
14419
14712
  children: /*#__PURE__*/ jsx(SelectValue, {})
14420
14713
  }),
@@ -14435,9 +14728,9 @@ function ProductCardSlot({ actions, band, slot, presentation }) {
14435
14728
  });
14436
14729
  }
14437
14730
  const RoomCardSlot_CONTAINER_CLASS_NAMES = {
14438
- card: 'flex h-24 w-[254px] items-center gap-4 overflow-hidden rounded-2xl bg-background-containers p-4 text-left text-text-dark shadow-[var(--shadow-login)]',
14439
- 'framed-row': 'flex h-[72px] items-center justify-between gap-3 overflow-hidden rounded-2xl bg-background-containers p-4 text-left text-text-dark shadow-[var(--shadow-login)]',
14440
- 'plain-row': 'flex w-full items-center justify-between gap-3 rounded-full bg-background-containers text-left'
14731
+ card: 'flex h-24 w-[254px] items-center gap-4 overflow-hidden rounded-2xl bg-background-containers p-4 text-start text-text-dark shadow-[var(--shadow-login)]',
14732
+ 'framed-row': 'flex h-[72px] items-center justify-between gap-3 overflow-hidden rounded-2xl bg-background-containers p-4 text-start text-text-dark shadow-[var(--shadow-login)]',
14733
+ 'plain-row': 'flex w-full items-center justify-between gap-3 rounded-full bg-background-containers text-start'
14441
14734
  };
14442
14735
  const RoomCardSlot_CARD_TEST_IDS = {
14443
14736
  desktop: 'floor-room-card',
@@ -15806,7 +16099,7 @@ function ImmersiveRoomChrome({ showDialogCloseButton = false }) {
15806
16099
  })
15807
16100
  }),
15808
16101
  /*#__PURE__*/ jsxs("div", {
15809
- className: "pointer-events-none absolute top-0 right-0 left-0 z-20 flex min-h-22 items-start justify-between gap-4 bg-linear-to-b from-black/75 via-black/35 to-transparent px-4 pt-4 pb-8 text-constant-white sm:px-6 lg:min-h-25 lg:pt-6",
16102
+ className: "pointer-events-none absolute top-0 end-0 start-0 z-20 flex min-h-22 items-start justify-between gap-4 bg-linear-to-b from-black/75 via-black/35 to-transparent px-4 pt-4 pb-8 text-constant-white sm:px-6 lg:min-h-25 lg:pt-6",
15810
16103
  children: [
15811
16104
  /*#__PURE__*/ jsx("div", {
15812
16105
  className: "min-w-0 pt-1",
@@ -15902,7 +16195,7 @@ function ImmersiveRoomChrome({ showDialogCloseButton = false }) {
15902
16195
  ]
15903
16196
  }),
15904
16197
  /*#__PURE__*/ jsxs("div", {
15905
- className: "pointer-events-none absolute right-6 bottom-6 left-6 z-20 hidden items-end justify-between gap-4 lg:flex",
16198
+ className: "pointer-events-none absolute end-6 bottom-6 start-6 z-20 hidden items-end justify-between gap-4 lg:flex",
15906
16199
  "data-testid": "floor-desktop-cards",
15907
16200
  children: [
15908
16201
  /*#__PURE__*/ jsx("div", {
@@ -15924,7 +16217,7 @@ function ImmersiveRoomChrome({ showDialogCloseButton = false }) {
15924
16217
  ]
15925
16218
  }),
15926
16219
  /*#__PURE__*/ jsxs("div", {
15927
- className: "pointer-events-none absolute right-6 bottom-6 left-6 z-20 hidden items-end justify-between gap-2 sm:flex lg:hidden",
16220
+ className: "pointer-events-none absolute end-6 bottom-6 start-6 z-20 hidden items-end justify-between gap-2 sm:flex lg:hidden",
15928
16221
  "data-testid": "floor-tablet-cards",
15929
16222
  children: [
15930
16223
  /*#__PURE__*/ jsx("div", {
@@ -15970,7 +16263,7 @@ function ImmersiveRoomChrome({ showDialogCloseButton = false }) {
15970
16263
  }),
15971
16264
  isMaterialSelectionPanelOpen && !hasActiveError && /*#__PURE__*/ jsx(MaterialSelectionContent, {
15972
16265
  [MATERIAL_SELECTION_PANEL_ATTRIBUTE]: true,
15973
- className: "absolute bottom-[152px] left-6 z-30 hidden max-h-[calc(100%-252px)] w-[348px] rounded-2xl bg-background-containers sm:flex lg:bottom-[132px] lg:max-h-[calc(100%-232px)]",
16266
+ className: "absolute bottom-[152px] start-6 z-30 hidden max-h-[calc(100%-252px)] w-[348px] rounded-2xl bg-background-containers sm:flex lg:bottom-[132px] lg:max-h-[calc(100%-232px)]",
15974
16267
  gridClassName: "px-4 pb-4",
15975
16268
  titleClassName: "px-4 pt-4",
15976
16269
  onOpenChange: handleCloseMaterialSelection
@@ -16097,11 +16390,6 @@ function RoomViewerContainer(props) {
16097
16390
  ...props
16098
16391
  });
16099
16392
  }
16100
- function useRoomViewerLanguage() {
16101
- const { i18n } = useTranslation();
16102
- const language = i18n.resolvedLanguage ?? i18n.language;
16103
- return 'ru' === language ? 'ru' : 'en';
16104
- }
16105
16393
  function isBlankArtworkSource(src) {
16106
16394
  return 'string' != typeof src || 0 === src.trim().length;
16107
16395
  }
@@ -16666,7 +16954,7 @@ function RoomViewerRoot({ type, src, tinuuid, roomId, name, height, width, langu
16666
16954
  type
16667
16955
  ]);
16668
16956
  useEffect(()=>{
16669
- if ('string' == typeof language) i18n.changeLanguage(language);
16957
+ if ('string' == typeof language && language !== i18n.language) i18n.changeLanguage(language);
16670
16958
  }, [
16671
16959
  i18n,
16672
16960
  language
@@ -16701,6 +16989,8 @@ configureApiClient({
16701
16989
  });
16702
16990
  function RoomViewerDialog({ type, src, tinuuid, roomId, width, height, dimensionUnit, displayUnit, name, language, apiKey, source, widgetSession, disableClose = false, open, defaultOpen, onOpenChange }) {
16703
16991
  const [themeRoot, setThemeRoot] = useState(null);
16992
+ const [viewerI18n] = useState(()=>createRoomViewerI18n(language));
16993
+ const { language: uiLanguage, direction } = useRoomViewerDirection(viewerI18n);
16704
16994
  const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen ?? false);
16705
16995
  const dialogOpen = open ?? uncontrolledOpen;
16706
16996
  const [hasRenderedDialogContent, setHasRenderedDialogContent] = useState(dialogOpen);
@@ -16764,15 +17054,20 @@ function RoomViewerDialog({ type, src, tinuuid, roomId, width, height, dimension
16764
17054
  children: shadowRootCssText
16765
17055
  }),
16766
17056
  /*#__PURE__*/ jsx("div", {
16767
- ref: setThemeRoot
17057
+ ref: setThemeRoot,
17058
+ dir: direction,
17059
+ lang: uiLanguage
16768
17060
  }),
16769
17061
  themeRoot && /*#__PURE__*/ jsx(ThemeProvider, {
16770
17062
  root: themeRoot,
16771
17063
  storageKey: "neurodyn-theme",
16772
17064
  defaultTheme: "light",
16773
- children: /*#__PURE__*/ jsx(I18nextProvider, {
16774
- i18n: roomViewerI18n,
16775
- children: shouldRenderRoomViewerRoot && roomViewerRoot
17065
+ children: /*#__PURE__*/ jsx(Direction.Provider, {
17066
+ dir: direction,
17067
+ children: /*#__PURE__*/ jsx(I18nextProvider, {
17068
+ i18n: viewerI18n,
17069
+ children: shouldRenderRoomViewerRoot && roomViewerRoot
17070
+ })
16776
17071
  })
16777
17072
  })
16778
17073
  ]
@@ -16782,6 +17077,8 @@ function RoomViewerDialog({ type, src, tinuuid, roomId, width, height, dimension
16782
17077
  }
16783
17078
  function RoomViewer({ type, src, tinuuid, roomId, name, language, width, height, dimensionUnit, displayUnit, apiKey, source, widgetSession, className, ...props }) {
16784
17079
  const [themeRoot, setThemeRoot] = useState(null);
17080
+ const [viewerI18n] = useState(()=>createRoomViewerI18n(language));
17081
+ const { language: uiLanguage, direction } = useRoomViewerDirection(viewerI18n);
16785
17082
  return /*#__PURE__*/ jsxs(Fragment, {
16786
17083
  children: [
16787
17084
  /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx("style", {
@@ -16802,6 +17099,8 @@ function RoomViewer({ type, src, tinuuid, roomId, name, language, width, height,
16802
17099
  }),
16803
17100
  /*#__PURE__*/ jsx("div", {
16804
17101
  ref: setThemeRoot,
17102
+ dir: direction,
17103
+ lang: uiLanguage,
16805
17104
  style: {
16806
17105
  height: '100%',
16807
17106
  width: '100%'
@@ -16810,22 +17109,25 @@ function RoomViewer({ type, src, tinuuid, roomId, name, language, width, height,
16810
17109
  root: themeRoot,
16811
17110
  storageKey: "neurodyn-theme",
16812
17111
  defaultTheme: "light",
16813
- children: /*#__PURE__*/ jsx(I18nextProvider, {
16814
- i18n: roomViewerI18n,
16815
- children: /*#__PURE__*/ jsx(RoomViewerRoot, {
16816
- type: type,
16817
- src: src,
16818
- tinuuid: tinuuid,
16819
- roomId: roomId,
16820
- name: name,
16821
- language: language,
16822
- width: width,
16823
- height: height,
16824
- dimensionUnit: dimensionUnit,
16825
- displayUnit: displayUnit,
16826
- apiKey: apiKey,
16827
- source: source,
16828
- widgetSession: widgetSession
17112
+ children: /*#__PURE__*/ jsx(Direction.Provider, {
17113
+ dir: direction,
17114
+ children: /*#__PURE__*/ jsx(I18nextProvider, {
17115
+ i18n: viewerI18n,
17116
+ children: /*#__PURE__*/ jsx(RoomViewerRoot, {
17117
+ type: type,
17118
+ src: src,
17119
+ tinuuid: tinuuid,
17120
+ roomId: roomId,
17121
+ name: name,
17122
+ language: language,
17123
+ width: width,
17124
+ height: height,
17125
+ dimensionUnit: dimensionUnit,
17126
+ displayUnit: displayUnit,
17127
+ apiKey: apiKey,
17128
+ source: source,
17129
+ widgetSession: widgetSession
17130
+ })
16829
17131
  })
16830
17132
  })
16831
17133
  })