@neurodyn/core-ar 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -472,6 +472,11 @@ function getFetch(options) {
472
472
  function getRuntimeConfig(options) {
473
473
  return options.runtimeConfig ?? getCoreArWidgetRuntimeConfig();
474
474
  }
475
+ function getBrandHeaders(runtimeConfig) {
476
+ return {
477
+ 'x-app-type': runtimeConfig.brand
478
+ };
479
+ }
475
480
  function getRuntimeUrl(apiOrigin, pathname, params = {}) {
476
481
  const url = new URL(pathname, apiOrigin);
477
482
  for (const [name, value] of Object.entries(params))if (value) url.searchParams.set(name, value);
@@ -527,12 +532,13 @@ function parseWidgetSession(value) {
527
532
  return data;
528
533
  }
529
534
  async function activateCoreWidget(publicKey, options = {}) {
530
- const { apiOrigin } = getRuntimeConfig(options);
531
- const response = await runtimeFetch(getRuntimeUrl(apiOrigin, '/public/widget/activate-core', {
535
+ const runtimeConfig = getRuntimeConfig(options);
536
+ const response = await runtimeFetch(getRuntimeUrl(runtimeConfig.apiOrigin, '/public/widget/activate-core', {
532
537
  mode: options.mode
533
538
  }), {
534
539
  cache: 'no-store',
535
540
  headers: {
541
+ ...getBrandHeaders(runtimeConfig),
536
542
  'x-api-key': publicKey
537
543
  },
538
544
  method: 'POST'
@@ -546,8 +552,8 @@ async function activateCoreWidget(publicKey, options = {}) {
546
552
  };
547
553
  }
548
554
  async function refreshWidgetSession(publicKey, previousToken, options = {}) {
549
- const { apiOrigin } = getRuntimeConfig(options);
550
- const response = await runtimeFetch(`${apiOrigin}/public/widget/token`, {
555
+ const runtimeConfig = getRuntimeConfig(options);
556
+ const response = await runtimeFetch(`${runtimeConfig.apiOrigin}/public/widget/token`, {
551
557
  body: JSON.stringify({
552
558
  token: previousToken,
553
559
  ...options.mode ? {
@@ -556,6 +562,7 @@ async function refreshWidgetSession(publicKey, previousToken, options = {}) {
556
562
  }),
557
563
  cache: 'no-store',
558
564
  headers: {
565
+ ...getBrandHeaders(runtimeConfig),
559
566
  'Content-Type': 'application/json',
560
567
  'x-api-key': publicKey
561
568
  },
@@ -565,12 +572,13 @@ async function refreshWidgetSession(publicKey, previousToken, options = {}) {
565
572
  return parseWidgetSession(await parseSuccessJson(response));
566
573
  }
567
574
  async function fetchWidgetObject(objectId, sessionToken, options = {}) {
568
- const { apiOrigin } = getRuntimeConfig(options);
569
- const response = await runtimeFetch(getRuntimeUrl(apiOrigin, `/public/objects/by-tinuuid/${encodeURIComponent(objectId)}`, {
575
+ const runtimeConfig = getRuntimeConfig(options);
576
+ const response = await runtimeFetch(getRuntimeUrl(runtimeConfig.apiOrigin, `/public/objects/by-tinuuid/${encodeURIComponent(objectId)}`, {
570
577
  variantId: options.variantId
571
578
  }), {
572
579
  cache: 'no-store',
573
580
  headers: {
581
+ ...getBrandHeaders(runtimeConfig),
574
582
  'x-widget-session-token': sessionToken
575
583
  },
576
584
  method: 'GET'
@@ -581,8 +589,8 @@ async function fetchWidgetObject(objectId, sessionToken, options = {}) {
581
589
  return data;
582
590
  }
583
591
  async function sendWidgetEvent(event, sessionToken, objectUuid, options = {}) {
584
- const { apiOrigin } = getRuntimeConfig(options);
585
- const response = await runtimeFetch(`${apiOrigin}/public/widget/events`, {
592
+ const runtimeConfig = getRuntimeConfig(options);
593
+ const response = await runtimeFetch(`${runtimeConfig.apiOrigin}/public/widget/events`, {
586
594
  body: JSON.stringify({
587
595
  event,
588
596
  ...objectUuid ? {
@@ -595,6 +603,7 @@ async function sendWidgetEvent(event, sessionToken, objectUuid, options = {}) {
595
603
  }),
596
604
  cache: 'no-store',
597
605
  headers: {
606
+ ...getBrandHeaders(runtimeConfig),
598
607
  'Content-Type': 'application/json',
599
608
  'x-widget-session-token': sessionToken
600
609
  },
@@ -613,6 +622,7 @@ async function fetchPublicObject(objectId, signal, runtimeConfig) {
613
622
  tinuuid: objectId
614
623
  }),
615
624
  headers: {
625
+ ...getBrandHeaders(resolvedConfig),
616
626
  'Content-Type': 'application/json'
617
627
  },
618
628
  method: 'POST'
@@ -627,12 +637,13 @@ async function fetchPublicObject(objectId, signal, runtimeConfig) {
627
637
  return data;
628
638
  }
629
639
  async function incrementObjectViews(objectId, runtimeConfig) {
630
- const { apiOrigin, fetchImpl } = runtimeConfig ?? getCoreArWidgetRuntimeConfig();
631
- await fetchImpl(`${apiOrigin}/catalog/object/incr-views`, {
640
+ const resolvedConfig = runtimeConfig ?? getCoreArWidgetRuntimeConfig();
641
+ await resolvedConfig.fetchImpl(`${resolvedConfig.apiOrigin}/catalog/object/incr-views`, {
632
642
  body: JSON.stringify({
633
643
  tinuuid: objectId
634
644
  }),
635
645
  headers: {
646
+ ...getBrandHeaders(resolvedConfig),
636
647
  'Content-Type': 'application/json'
637
648
  },
638
649
  method: 'POST'
@@ -666,6 +677,7 @@ async function initializeAdvancedArTrigger(trigger, options = {}) {
666
677
  let createdImage;
667
678
  let closeOwnedQr;
668
679
  let handlingUnsupportedClick = false;
680
+ let openingWebAr = false;
669
681
  let qrRevision = 0;
670
682
  if (!trigger.querySelector('img')) {
671
683
  createdImage = document.createElement('img');
@@ -690,6 +702,18 @@ async function initializeAdvancedArTrigger(trigger, options = {}) {
690
702
  }).catch(()=>void 0);
691
703
  };
692
704
  const handleMobileClick = async (event)=>{
705
+ if (options.webAr?.isAvailable()) {
706
+ event.preventDefault();
707
+ if (openingWebAr) return;
708
+ openingWebAr = true;
709
+ let opened = false;
710
+ try {
711
+ opened = await options.webAr.open().catch(()=>false);
712
+ } finally{
713
+ openingWebAr = false;
714
+ }
715
+ if (opened || !initialization.isCurrent()) return;
716
+ }
693
717
  if (isUnsupportedFetchInAr()) {
694
718
  event.preventDefault();
695
719
  if (handlingUnsupportedClick) return;
@@ -837,6 +861,7 @@ function initializeModalTrigger(trigger, options) {
837
861
  hid: trigger.dataset.objectHid,
838
862
  initialWidgetSessionToken: widgetSessionToken,
839
863
  lang: options.lang,
864
+ launchAr: options.launchAr,
840
865
  maxCameraOrbit: trigger.dataset.maxCameraOrbit,
841
866
  minCameraOrbit: trigger.dataset.minCameraOrbit,
842
867
  mode: options.mode,
@@ -890,6 +915,7 @@ async function initializeNativeArAnchor(link, options = {}) {
890
915
  const mobile = isMobile();
891
916
  let createdImage;
892
917
  let closeOwnedQr;
918
+ let openingWebAr = false;
893
919
  let qrRevision = 0;
894
920
  link.rel = 'ar';
895
921
  if (!link.querySelector('img')) {
@@ -913,10 +939,25 @@ async function initializeNativeArAnchor(link, options = {}) {
913
939
  closeOwnedQr = cleanup;
914
940
  }).catch(()=>void 0);
915
941
  };
916
- const handleMobileClick = ()=>{
942
+ const trackNativeLaunch = ()=>{
917
943
  runSafely(options.trackView ?? (()=>incrementObjectViews(objectId, options.runtimeConfig)));
918
944
  runSafely(()=>options.onAction?.('ar_launched'));
919
945
  };
946
+ const handleMobileClick = async (event)=>{
947
+ if (!options.webAr?.isAvailable()) return void trackNativeLaunch();
948
+ event.preventDefault();
949
+ if (openingWebAr) return;
950
+ openingWebAr = true;
951
+ let opened = false;
952
+ try {
953
+ opened = await options.webAr.open().catch(()=>false);
954
+ } finally{
955
+ openingWebAr = false;
956
+ }
957
+ if (opened || !initialization.isCurrent()) return;
958
+ trackNativeLaunch();
959
+ openNativeLink(nativeLink);
960
+ };
920
961
  if (mobile) {
921
962
  link.href = nativeLink;
922
963
  link.addEventListener('click', handleMobileClick);
@@ -936,6 +977,68 @@ async function initializeNativeArAnchor(link, options = {}) {
936
977
  else link.setAttribute('rel', originalRel);
937
978
  });
938
979
  }
980
+ const WEB_AR_TAP_WINDOW_MS = 3000;
981
+ const web_ar_dialog_DIALOG_EXIT_MS = 300;
982
+ let web_ar_dialog_pendingLoad;
983
+ async function importWebArDialog() {
984
+ const { ArDialog, prepareArSessionInPage } = await import("@neurodyn/react-ar");
985
+ const { createElement } = await import("react");
986
+ const { createRoot } = await import("react-dom/client");
987
+ return {
988
+ open: ({ onClose, ...props })=>{
989
+ const container = document.createElement('div');
990
+ container.setAttribute('data-core-ar-web-ar', '');
991
+ document.body.appendChild(container);
992
+ const root = createRoot(container);
993
+ let closed = false;
994
+ const render = (open)=>root.render(createElement(ArDialog, {
995
+ ...props,
996
+ onOpenChange: (next)=>{
997
+ if (!next) close();
998
+ },
999
+ open
1000
+ }));
1001
+ function close() {
1002
+ if (closed) return;
1003
+ closed = true;
1004
+ render(false);
1005
+ setTimeout(()=>{
1006
+ root.unmount();
1007
+ container.remove();
1008
+ }, web_ar_dialog_DIALOG_EXIT_MS);
1009
+ onClose?.();
1010
+ }
1011
+ render(true);
1012
+ return close;
1013
+ },
1014
+ prepare: prepareArSessionInPage
1015
+ };
1016
+ }
1017
+ function loadWebArDialog() {
1018
+ if (web_ar_dialog_pendingLoad) return web_ar_dialog_pendingLoad;
1019
+ const promise = importWebArDialog();
1020
+ web_ar_dialog_pendingLoad = promise;
1021
+ promise.catch(()=>{
1022
+ if (web_ar_dialog_pendingLoad === promise) web_ar_dialog_pendingLoad = void 0;
1023
+ });
1024
+ return promise;
1025
+ }
1026
+ async function prepareWebArDialog(tinuuid) {
1027
+ const dialog = await loadWebArDialog();
1028
+ return await dialog.prepare(tinuuid) ? dialog : null;
1029
+ }
1030
+ function withinTapWindow(promise, windowMs = WEB_AR_TAP_WINDOW_MS) {
1031
+ return new Promise((resolve, reject)=>{
1032
+ const timer = setTimeout(()=>resolve(null), windowMs);
1033
+ promise.then((value)=>{
1034
+ clearTimeout(timer);
1035
+ resolve(value);
1036
+ }, (error)=>{
1037
+ clearTimeout(timer);
1038
+ reject(error);
1039
+ });
1040
+ });
1041
+ }
939
1042
  const CORE_AR_WIDGET_TYPES = [
940
1043
  'advanced-ar',
941
1044
  'ar-one-click',
@@ -1136,6 +1239,7 @@ class CoreArWidgetElement extends HTMLElementBase {
1136
1239
  abortController;
1137
1240
  actionResetTimer;
1138
1241
  cleanup;
1242
+ closeWebAr;
1139
1243
  customLabelNodes = null;
1140
1244
  initializationRevision = 0;
1141
1245
  object;
@@ -1241,7 +1345,10 @@ class CoreArWidgetElement extends HTMLElementBase {
1241
1345
  cleanup();
1242
1346
  throw error;
1243
1347
  }
1244
- this.cleanup = cleanup;
1348
+ this.cleanup = ()=>{
1349
+ cleanup();
1350
+ this.closeWebAr?.();
1351
+ };
1245
1352
  this.setState('ready');
1246
1353
  this.dispatchWidgetEvent('core-ar-ready', {
1247
1354
  objectId,
@@ -1390,6 +1497,14 @@ class CoreArWidgetElement extends HTMLElementBase {
1390
1497
  return currentSession.token;
1391
1498
  },
1392
1499
  lang: 'arizo' === runtimeConfig.brand ? 'ru' : 'en',
1500
+ launchAr: canOpenWebAr() ? (target)=>this.openWebAr({
1501
+ apiBaseUrl: target.apiBaseUrl ?? runtimeConfig.apiOrigin,
1502
+ apiKey: target.apiKey ?? publicKey,
1503
+ hid: target.hid,
1504
+ language: target.lang,
1505
+ name: target.name,
1506
+ tinuuid: target.tinuuid
1507
+ }, ()=>target.widgetSessionToken, ()=>!signal.aborted) : void 0,
1393
1508
  mode: session.mode,
1394
1509
  modelViewerOrigin: runtimeConfig.modelViewerOrigin,
1395
1510
  onAction: (action)=>this.handleAction(action, runtimeConfig),
@@ -1427,7 +1542,8 @@ class CoreArWidgetElement extends HTMLElementBase {
1427
1542
  onAction: (action)=>this.handleAction(action, runtimeConfig),
1428
1543
  runtimeConfig,
1429
1544
  signal,
1430
- trackView: ()=>this.trackEvent('ar_launched', runtimeConfig)
1545
+ trackView: ()=>this.trackEvent('ar_launched', runtimeConfig),
1546
+ webAr: this.createWebArLauncher(object, publicKey, runtimeConfig, session.mode, signal)
1431
1547
  };
1432
1548
  if ('ar-one-click' === type) {
1433
1549
  if (!(this.trigger instanceof HTMLAnchorElement)) throw new CoreArWidgetComponentError('INITIALIZATION_FAILED');
@@ -1435,6 +1551,49 @@ class CoreArWidgetElement extends HTMLElementBase {
1435
1551
  }
1436
1552
  return initializeAdvancedArTrigger(this.trigger, options);
1437
1553
  }
1554
+ createWebArLauncher(object, publicKey, runtimeConfig, mode, signal) {
1555
+ const isCurrent = ()=>!signal.aborted;
1556
+ return {
1557
+ isAvailable: canOpenWebAr,
1558
+ open: async ()=>{
1559
+ this.setState('loading');
1560
+ const opened = await this.openWebAr({
1561
+ apiBaseUrl: runtimeConfig.apiOrigin,
1562
+ apiKey: publicKey,
1563
+ hid: this.variantId,
1564
+ language: 'arizo' === runtimeConfig.brand ? 'ru' : 'en',
1565
+ name: 'string' == typeof object.name ? object.name : void 0,
1566
+ onClose: ()=>{
1567
+ if (isCurrent()) this.setState('ready');
1568
+ },
1569
+ tinuuid: this.trigger?.dataset.objectTinuuid ?? object.tinuuid
1570
+ }, async ()=>(await this.ensureSession(publicKey, runtimeConfig, mode)).token, isCurrent);
1571
+ if (isCurrent()) this.setState(opened ? 'opening' : 'ready');
1572
+ return opened;
1573
+ }
1574
+ };
1575
+ }
1576
+ async openWebAr(options, getWidgetSessionToken, isCurrent) {
1577
+ const tinuuid = options.tinuuid?.trim();
1578
+ if (!tinuuid) return false;
1579
+ const ready = await withinTapWindow(Promise.all([
1580
+ prepareWebArDialog(tinuuid),
1581
+ Promise.resolve().then(getWidgetSessionToken)
1582
+ ])).catch(()=>null);
1583
+ const [dialog, token] = ready ?? [];
1584
+ if (!dialog || !this.isConnected || !isCurrent()) return false;
1585
+ this.closeWebAr?.();
1586
+ const close = dialog.open({
1587
+ ...options,
1588
+ initialWidgetSessionToken: token,
1589
+ onClose: ()=>{
1590
+ if (this.closeWebAr === close) this.closeWebAr = void 0;
1591
+ options.onClose?.();
1592
+ }
1593
+ });
1594
+ this.closeWebAr = close;
1595
+ return true;
1596
+ }
1438
1597
  handleAction(action, runtimeConfig) {
1439
1598
  this.setState('opening');
1440
1599
  if (('interacted' === action || 'widget_opened' === action) && 'ar-viewer' !== this.getAttribute('type')) this.trackEvent(action, runtimeConfig);
@@ -1481,6 +1640,9 @@ class CoreArWidgetElement extends HTMLElementBase {
1481
1640
  }));
1482
1641
  }
1483
1642
  }
1643
+ function canOpenWebAr() {
1644
+ return isMobile() && !isIOS();
1645
+ }
1484
1646
  function registerBrandedCoreWidget(brand) {
1485
1647
  if ("u" < typeof customElements) return;
1486
1648
  const tagName = CORE_AR_WIDGET_TAG_NAMES[brand];
@@ -0,0 +1,139 @@
1
+ <svg width="1000" height="1000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 264 264" aria-hidden="true" xmlns:c2pa="http://c2pa.org/manifest">
2
+ <style>
3
+ .camera-intro__k,.camera-intro__move,.camera-intro__drop,.camera-intro__finger{transform-box:view-box;transform-origin:0 0;animation-duration:10.6s;animation-iteration-count:infinite;animation-timing-function:linear;animation-fill-mode:both}
4
+ .camera-intro__move{transform-origin:132px 196px;animation-name:camera-intro-move}
5
+ .camera-intro__drop{transform-origin:132px 196px;animation-name:camera-intro-drop}
6
+ .camera-intro__stand{transform-box:fill-box;transform-origin:center}
7
+ .camera-intro__finger{animation-name:camera-intro-finger}
8
+ .camera-intro__ring{transform-box:fill-box;transform-origin:center;animation:camera-intro-ring 10.6s infinite both}
9
+ @keyframes camera-intro-drop{0%,28.30%{opacity:0;transform:translateY(-14px) scale(.92);animation-timing-function:cubic-bezier(.34,1.56,.64,1)}33.02%,100%{opacity:1;transform:none}}
10
+ .camera-intro__top{animation-name:camera-intro-top}@keyframes camera-intro-top{0%,39.15%{transform:translate(113.63px,177.63px) rotate(8.79deg) skewX(-16.1deg) scale(29.32,-17.72)}39.82%{transform:translate(113.61px,177.61px) rotate(8.86deg) skewX(-16.21deg) scale(29.31,-17.73)}40.50%{transform:translate(113.54px,177.54px) rotate(9.1deg) skewX(-16.56deg) scale(29.28,-17.75)}41.17%{transform:translate(113.4px,177.39px) rotate(9.57deg) skewX(-17.26deg) scale(29.2,-17.79)}41.85%{transform:translate(113.17px,177.14px) rotate(10.38deg) skewX(-18.42deg) scale(29.07,-17.87)}42.52%{transform:translate(112.8px,176.71px) rotate(11.77deg) skewX(-20.24deg) scale(28.82,-18.03)}43.19%{transform:translate(112.24px,175.96px) rotate(14.22deg) skewX(-23.02deg) scale(28.34,-18.34)}43.87%{transform:translate(111.51px,174.67px) rotate(18.43deg) skewX(-26.57deg) scale(27.39,-18.97)}44.54%{transform:translate(111.03px,173.36px) rotate(22.99deg) skewX(-28.85deg) scale(26.26,-19.79)}45.22%{transform:translate(110.86px,172.54px) rotate(25.97deg) skewX(-29.64deg) scale(25.51,-20.37)}45.89%{transform:translate(110.81px,172.06px) rotate(27.79deg) skewX(-29.9deg) scale(25.05,-20.75)}46.56%{transform:translate(110.79px,171.78px) rotate(28.91deg) skewX(-29.98deg) scale(24.77,-20.98)}47.24%{transform:translate(110.79px,171.61px) rotate(29.57deg) skewX(-30deg) scale(24.6,-21.12)}47.91%{transform:translate(110.79px,171.53px) rotate(29.9deg) skewX(-30deg) scale(24.52,-21.19)}48.58%,100%{transform:translate(110.79px,171.51px) rotate(30deg) skewX(-30deg) scale(24.49,-21.21)}}
11
+ .camera-intro__front{animation-name:camera-intro-front}@keyframes camera-intro-front{0%,39.15%{transform:translate(113.63px,202.12px) rotate(8.79deg) skewX(8.79deg) scale(29.32,-24.21)}39.82%{transform:translate(113.61px,202.1px) rotate(8.86deg) skewX(8.86deg) scale(29.31,-24.2)}40.50%{transform:translate(113.54px,202.03px) rotate(9.1deg) skewX(9.1deg) scale(29.28,-24.19)}41.17%{transform:translate(113.4px,201.89px) rotate(9.57deg) skewX(9.57deg) scale(29.2,-24.15)}41.85%{transform:translate(113.17px,201.63px) rotate(10.38deg) skewX(10.38deg) scale(29.07,-24.09)}42.52%{transform:translate(112.8px,201.21px) rotate(11.77deg) skewX(11.77deg) scale(28.82,-23.98)}43.19%{transform:translate(112.24px,200.45px) rotate(14.22deg) skewX(14.22deg) scale(28.34,-23.74)}43.87%{transform:translate(111.51px,199.17px) rotate(18.43deg) skewX(18.43deg) scale(27.39,-23.24)}44.54%{transform:translate(111.03px,197.85px) rotate(22.99deg) skewX(22.99deg) scale(26.26,-22.55)}45.22%{transform:translate(110.86px,197.03px) rotate(25.97deg) skewX(25.97deg) scale(25.51,-22.02)}45.89%{transform:translate(110.81px,196.56px) rotate(27.79deg) skewX(27.79deg) scale(25.05,-21.67)}46.56%{transform:translate(110.79px,196.27px) rotate(28.91deg) skewX(28.91deg) scale(24.77,-21.44)}47.24%{transform:translate(110.79px,196.11px) rotate(29.57deg) skewX(29.57deg) scale(24.6,-21.31)}47.91%{transform:translate(110.79px,196.02px) rotate(29.9deg) skewX(29.9deg) scale(24.52,-21.23)}48.58%,100%{transform:translate(110.79px,196px) rotate(30deg) skewX(30deg) scale(24.49,-21.21)}}
12
+ .camera-intro__right{animation-name:camera-intro-right}@keyframes camera-intro-right{0%,39.15%{transform:translate(142.61px,206.61px) rotate(-65.1deg) skewX(-65.1deg) scale(18.44,-10.31)}39.82%{transform:translate(142.57px,206.62px) rotate(-64.93deg) skewX(-64.93deg) scale(18.46,-10.38)}40.50%{transform:translate(142.44px,206.66px) rotate(-64.34deg) skewX(-64.34deg) scale(18.52,-10.61)}41.17%{transform:translate(142.2px,206.74px) rotate(-63.17deg) skewX(-63.17deg) scale(18.63,-11.05)}41.85%{transform:translate(141.76px,206.87px) rotate(-61.2deg) skewX(-61.2deg) scale(18.84,-11.8)}42.52%{transform:translate(141.02px,207.09px) rotate(-57.99deg) skewX(-57.99deg) scale(19.21,-12.99)}43.19%{transform:translate(139.71px,207.41px) rotate(-52.76deg) skewX(-52.76deg) scale(19.92,-14.82)}43.87%{transform:translate(137.49px,207.83px) rotate(-45deg) skewX(-45deg) scale(21.21,-17.32)}44.54%{transform:translate(135.21px,208.11px) rotate(-38.16deg) skewX(-38.16deg) scale(22.59,-19.26)}45.22%{transform:translate(133.79px,208.2px) rotate(-34.39deg) skewX(-34.39deg) scale(23.44,-20.21)}45.89%{transform:translate(132.97px,208.23px) rotate(-32.31deg) skewX(-32.31deg) scale(23.93,-20.7)}46.56%{transform:translate(132.47px,208.24px) rotate(-31.12deg) skewX(-31.12deg) scale(24.22,-20.97)}47.24%{transform:translate(132.19px,208.25px) rotate(-30.44deg) skewX(-30.44deg) scale(24.39,-21.12)}47.91%{transform:translate(132.04px,208.25px) rotate(-30.1deg) skewX(-30.1deg) scale(24.47,-21.19)}48.58%,100%{transform:translate(132px,208.25px) rotate(-30deg) skewX(-30deg) scale(24.49,-21.21)}}
13
+ .camera-intro__e0{animation-name:camera-intro-e0}@keyframes camera-intro-e0{0%,39.15%{transform:translate(121.39px,160.9px) rotate(8.79deg) scaleX(29.32)}39.82%{transform:translate(121.43px,160.89px) rotate(8.86deg) scaleX(29.31)}40.50%{transform:translate(121.56px,160.85px) rotate(9.1deg) scaleX(29.28)}41.17%{transform:translate(121.8px,160.76px) rotate(9.57deg) scaleX(29.2)}41.85%{transform:translate(122.24px,160.63px) rotate(10.38deg) scaleX(29.07)}42.52%{transform:translate(122.98px,160.42px) rotate(11.77deg) scaleX(28.82)}43.19%{transform:translate(124.29px,160.09px) rotate(14.22deg) scaleX(28.34)}43.87%{transform:translate(126.51px,159.67px) rotate(18.43deg) scaleX(27.39)}44.54%{transform:translate(128.79px,159.4px) rotate(22.99deg) scaleX(26.26)}45.22%{transform:translate(130.21px,159.3px) rotate(25.97deg) scaleX(25.51)}45.89%{transform:translate(131.03px,159.27px) rotate(27.79deg) scaleX(25.05)}46.56%{transform:translate(131.53px,159.26px) rotate(28.91deg) scaleX(24.77)}47.24%{transform:translate(131.81px,159.26px) rotate(29.57deg) scaleX(24.6)}47.91%{transform:translate(131.96px,159.26px) rotate(29.9deg) scaleX(24.52)}48.58%,100%{transform:translate(132px,159.26px) rotate(30deg) scaleX(24.49)}}
14
+ .camera-intro__e1{animation-name:camera-intro-e1}@keyframes camera-intro-e1{0%,39.15%{transform:translate(150.37px,165.38px) rotate(114.9deg) scaleX(18.44)}39.82%{transform:translate(150.39px,165.4px) rotate(115.07deg) scaleX(18.46)}40.50%{transform:translate(150.46px,165.47px) rotate(115.66deg) scaleX(18.52)}41.17%{transform:translate(150.6px,165.62px) rotate(116.83deg) scaleX(18.63)}41.85%{transform:translate(150.83px,165.87px) rotate(118.8deg) scaleX(18.84)}42.52%{transform:translate(151.2px,166.3px) rotate(122.01deg) scaleX(19.21)}43.19%{transform:translate(151.76px,167.06px) rotate(127.24deg) scaleX(19.92)}43.87%{transform:translate(152.49px,168.34px) rotate(135deg) scaleX(21.21)}44.54%{transform:translate(152.97px,169.65px) rotate(141.84deg) scaleX(22.59)}45.22%{transform:translate(153.14px,170.47px) rotate(145.61deg) scaleX(23.44)}45.89%{transform:translate(153.19px,170.95px) rotate(147.69deg) scaleX(23.93)}46.56%{transform:translate(153.21px,171.23px) rotate(148.88deg) scaleX(24.22)}47.24%{transform:translate(153.21px,171.4px) rotate(149.56deg) scaleX(24.39)}47.91%{transform:translate(153.21px,171.48px) rotate(149.9deg) scaleX(24.47)}48.58%,100%{transform:translate(153.21px,171.51px) rotate(150deg) scaleX(24.49)}}
15
+ .camera-intro__e2{animation-name:camera-intro-e2}@keyframes camera-intro-e2{0%,39.15%{transform:translate(142.61px,182.11px) rotate(-171.21deg) scaleX(29.32)}39.82%{transform:translate(142.57px,182.12px) rotate(-171.14deg) scaleX(29.31)}40.50%{transform:translate(142.44px,182.17px) rotate(-170.9deg) scaleX(29.28)}41.17%{transform:translate(142.2px,182.25px) rotate(-170.43deg) scaleX(29.2)}41.85%{transform:translate(141.76px,182.38px) rotate(-169.62deg) scaleX(29.07)}42.52%{transform:translate(141.02px,182.59px) rotate(-168.23deg) scaleX(28.82)}43.19%{transform:translate(139.71px,182.92px) rotate(-165.78deg) scaleX(28.34)}43.87%{transform:translate(137.49px,183.34px) rotate(-161.57deg) scaleX(27.39)}44.54%{transform:translate(135.21px,183.61px) rotate(-157.01deg) scaleX(26.26)}45.22%{transform:translate(133.79px,183.71px) rotate(-154.03deg) scaleX(25.51)}45.89%{transform:translate(132.97px,183.74px) rotate(-152.21deg) scaleX(25.05)}46.56%{transform:translate(132.47px,183.75px) rotate(-151.09deg) scaleX(24.77)}47.24%{transform:translate(132.19px,183.75px) rotate(-150.43deg) scaleX(24.6)}47.91%{transform:translate(132.04px,183.75px) rotate(-150.1deg) scaleX(24.52)}48.58%,100%{transform:translate(132px,183.75px) rotate(-150deg) scaleX(24.49)}}
16
+ .camera-intro__e3{animation-name:camera-intro-e3}@keyframes camera-intro-e3{0%,39.15%{transform:translate(113.63px,177.63px) rotate(-65.1deg) scaleX(18.44)}39.82%{transform:translate(113.61px,177.61px) rotate(-64.93deg) scaleX(18.46)}40.50%{transform:translate(113.54px,177.54px) rotate(-64.34deg) scaleX(18.52)}41.17%{transform:translate(113.4px,177.39px) rotate(-63.17deg) scaleX(18.63)}41.85%{transform:translate(113.17px,177.14px) rotate(-61.2deg) scaleX(18.84)}42.52%{transform:translate(112.8px,176.71px) rotate(-57.99deg) scaleX(19.21)}43.19%{transform:translate(112.24px,175.96px) rotate(-52.76deg) scaleX(19.92)}43.87%{transform:translate(111.51px,174.67px) rotate(-45deg) scaleX(21.21)}44.54%{transform:translate(111.03px,173.36px) rotate(-38.16deg) scaleX(22.59)}45.22%{transform:translate(110.86px,172.54px) rotate(-34.39deg) scaleX(23.44)}45.89%{transform:translate(110.81px,172.06px) rotate(-32.31deg) scaleX(23.93)}46.56%{transform:translate(110.79px,171.78px) rotate(-31.12deg) scaleX(24.22)}47.24%{transform:translate(110.79px,171.61px) rotate(-30.44deg) scaleX(24.39)}47.91%{transform:translate(110.79px,171.53px) rotate(-30.1deg) scaleX(24.47)}48.58%,100%{transform:translate(110.79px,171.51px) rotate(-30deg) scaleX(24.49)}}
17
+ .camera-intro__e4{animation-name:camera-intro-e4}@keyframes camera-intro-e4{0%,39.15%{transform:translate(113.63px,177.63px) rotate(90deg) scaleX(24.49)}39.82%{transform:translate(113.61px,177.61px) rotate(90deg) scaleX(24.49)}40.50%{transform:translate(113.54px,177.54px) rotate(90deg) scaleX(24.49)}41.17%{transform:translate(113.4px,177.39px) rotate(90deg) scaleX(24.49)}41.85%{transform:translate(113.17px,177.14px) rotate(90deg) scaleX(24.49)}42.52%{transform:translate(112.8px,176.71px) rotate(90deg) scaleX(24.49)}43.19%{transform:translate(112.24px,175.96px) rotate(90deg) scaleX(24.49)}43.87%{transform:translate(111.51px,174.67px) rotate(90deg) scaleX(24.49)}44.54%{transform:translate(111.03px,173.36px) rotate(90deg) scaleX(24.49)}45.22%{transform:translate(110.86px,172.54px) rotate(90deg) scaleX(24.49)}45.89%{transform:translate(110.81px,172.06px) rotate(90deg) scaleX(24.49)}46.56%{transform:translate(110.79px,171.78px) rotate(90deg) scaleX(24.49)}47.24%{transform:translate(110.79px,171.61px) rotate(90deg) scaleX(24.49)}47.91%{transform:translate(110.79px,171.53px) rotate(90deg) scaleX(24.49)}48.58%,100%{transform:translate(110.79px,171.51px) rotate(90deg) scaleX(24.49)}}
18
+ .camera-intro__e5{animation-name:camera-intro-e5}@keyframes camera-intro-e5{0%,39.15%{transform:translate(142.61px,182.11px) rotate(90deg) scaleX(24.49)}39.82%{transform:translate(142.57px,182.12px) rotate(90deg) scaleX(24.49)}40.50%{transform:translate(142.44px,182.17px) rotate(90deg) scaleX(24.49)}41.17%{transform:translate(142.2px,182.25px) rotate(90deg) scaleX(24.49)}41.85%{transform:translate(141.76px,182.38px) rotate(90deg) scaleX(24.49)}42.52%{transform:translate(141.02px,182.59px) rotate(90deg) scaleX(24.49)}43.19%{transform:translate(139.71px,182.92px) rotate(90deg) scaleX(24.49)}43.87%{transform:translate(137.49px,183.34px) rotate(90deg) scaleX(24.49)}44.54%{transform:translate(135.21px,183.61px) rotate(90deg) scaleX(24.49)}45.22%{transform:translate(133.79px,183.71px) rotate(90deg) scaleX(24.49)}45.89%{transform:translate(132.97px,183.74px) rotate(90deg) scaleX(24.49)}46.56%{transform:translate(132.47px,183.75px) rotate(90deg) scaleX(24.49)}47.24%{transform:translate(132.19px,183.75px) rotate(90deg) scaleX(24.49)}47.91%{transform:translate(132.04px,183.75px) rotate(90deg) scaleX(24.49)}48.58%,100%{transform:translate(132px,183.75px) rotate(90deg) scaleX(24.49)}}
19
+ .camera-intro__e6{animation-name:camera-intro-e6}@keyframes camera-intro-e6{0%,39.15%{transform:translate(150.37px,165.38px) rotate(90deg) scaleX(24.49)}39.82%{transform:translate(150.39px,165.4px) rotate(90deg) scaleX(24.49)}40.50%{transform:translate(150.46px,165.47px) rotate(90deg) scaleX(24.49)}41.17%{transform:translate(150.6px,165.62px) rotate(90deg) scaleX(24.49)}41.85%{transform:translate(150.83px,165.87px) rotate(90deg) scaleX(24.49)}42.52%{transform:translate(151.2px,166.3px) rotate(90deg) scaleX(24.49)}43.19%{transform:translate(151.76px,167.06px) rotate(90deg) scaleX(24.49)}43.87%{transform:translate(152.49px,168.34px) rotate(90deg) scaleX(24.49)}44.54%{transform:translate(152.97px,169.65px) rotate(90deg) scaleX(24.49)}45.22%{transform:translate(153.14px,170.47px) rotate(90deg) scaleX(24.49)}45.89%{transform:translate(153.19px,170.95px) rotate(90deg) scaleX(24.49)}46.56%{transform:translate(153.21px,171.23px) rotate(90deg) scaleX(24.49)}47.24%{transform:translate(153.21px,171.4px) rotate(90deg) scaleX(24.49)}47.91%{transform:translate(153.21px,171.48px) rotate(90deg) scaleX(24.49)}48.58%,100%{transform:translate(153.21px,171.51px) rotate(90deg) scaleX(24.49)}}
20
+ .camera-intro__e7{animation-name:camera-intro-e7}@keyframes camera-intro-e7{0%,39.15%{transform:translate(113.63px,202.12px) rotate(8.79deg) scaleX(29.32)}39.82%{transform:translate(113.61px,202.1px) rotate(8.86deg) scaleX(29.31)}40.50%{transform:translate(113.54px,202.03px) rotate(9.1deg) scaleX(29.28)}41.17%{transform:translate(113.4px,201.89px) rotate(9.57deg) scaleX(29.2)}41.85%{transform:translate(113.17px,201.63px) rotate(10.38deg) scaleX(29.07)}42.52%{transform:translate(112.8px,201.21px) rotate(11.77deg) scaleX(28.82)}43.19%{transform:translate(112.24px,200.45px) rotate(14.22deg) scaleX(28.34)}43.87%{transform:translate(111.51px,199.17px) rotate(18.43deg) scaleX(27.39)}44.54%{transform:translate(111.03px,197.85px) rotate(22.99deg) scaleX(26.26)}45.22%{transform:translate(110.86px,197.03px) rotate(25.97deg) scaleX(25.51)}45.89%{transform:translate(110.81px,196.56px) rotate(27.79deg) scaleX(25.05)}46.56%{transform:translate(110.79px,196.27px) rotate(28.91deg) scaleX(24.77)}47.24%{transform:translate(110.79px,196.11px) rotate(29.57deg) scaleX(24.6)}47.91%{transform:translate(110.79px,196.02px) rotate(29.9deg) scaleX(24.52)}48.58%,100%{transform:translate(110.79px,196px) rotate(30deg) scaleX(24.49)}}
21
+ .camera-intro__e8{animation-name:camera-intro-e8}@keyframes camera-intro-e8{0%,39.15%{transform:translate(142.61px,206.61px) rotate(-65.1deg) scaleX(18.44)}39.82%{transform:translate(142.57px,206.62px) rotate(-64.93deg) scaleX(18.46)}40.50%{transform:translate(142.44px,206.66px) rotate(-64.34deg) scaleX(18.52)}41.17%{transform:translate(142.2px,206.74px) rotate(-63.17deg) scaleX(18.63)}41.85%{transform:translate(141.76px,206.87px) rotate(-61.2deg) scaleX(18.84)}42.52%{transform:translate(141.02px,207.09px) rotate(-57.99deg) scaleX(19.21)}43.19%{transform:translate(139.71px,207.41px) rotate(-52.76deg) scaleX(19.92)}43.87%{transform:translate(137.49px,207.83px) rotate(-45deg) scaleX(21.21)}44.54%{transform:translate(135.21px,208.11px) rotate(-38.16deg) scaleX(22.59)}45.22%{transform:translate(133.79px,208.2px) rotate(-34.39deg) scaleX(23.44)}45.89%{transform:translate(132.97px,208.23px) rotate(-32.31deg) scaleX(23.93)}46.56%{transform:translate(132.47px,208.24px) rotate(-31.12deg) scaleX(24.22)}47.24%{transform:translate(132.19px,208.25px) rotate(-30.44deg) scaleX(24.39)}47.91%{transform:translate(132.04px,208.25px) rotate(-30.1deg) scaleX(24.47)}48.58%,100%{transform:translate(132px,208.25px) rotate(-30deg) scaleX(24.49)}}
22
+ .camera-intro__vTbl{animation-name:camera-intro-vTbl}@keyframes camera-intro-vTbl{0%,39.15%{transform:translate(121.39px,160.9px)}39.82%{transform:translate(121.43px,160.89px)}40.50%{transform:translate(121.56px,160.85px)}41.17%{transform:translate(121.8px,160.76px)}41.85%{transform:translate(122.24px,160.63px)}42.52%{transform:translate(122.98px,160.42px)}43.19%{transform:translate(124.29px,160.09px)}43.87%{transform:translate(126.51px,159.67px)}44.54%{transform:translate(128.79px,159.4px)}45.22%{transform:translate(130.21px,159.3px)}45.89%{transform:translate(131.03px,159.27px)}46.56%{transform:translate(131.53px,159.26px)}47.24%{transform:translate(131.81px,159.26px)}47.91%{transform:translate(131.96px,159.26px)}48.58%,100%{transform:translate(132px,159.26px)}}
23
+ .camera-intro__vTbr{animation-name:camera-intro-vTbr}@keyframes camera-intro-vTbr{0%,39.15%{transform:translate(150.37px,165.38px)}39.82%{transform:translate(150.39px,165.4px)}40.50%{transform:translate(150.46px,165.47px)}41.17%{transform:translate(150.6px,165.62px)}41.85%{transform:translate(150.83px,165.87px)}42.52%{transform:translate(151.2px,166.3px)}43.19%{transform:translate(151.76px,167.06px)}43.87%{transform:translate(152.49px,168.34px)}44.54%{transform:translate(152.97px,169.65px)}45.22%{transform:translate(153.14px,170.47px)}45.89%{transform:translate(153.19px,170.95px)}46.56%{transform:translate(153.21px,171.23px)}47.24%{transform:translate(153.21px,171.4px)}47.91%{transform:translate(153.21px,171.48px)}48.58%,100%{transform:translate(153.21px,171.51px)}}
24
+ .camera-intro__vTfl{animation-name:camera-intro-vTfl}@keyframes camera-intro-vTfl{0%,39.15%{transform:translate(113.63px,177.63px)}39.82%{transform:translate(113.61px,177.61px)}40.50%{transform:translate(113.54px,177.54px)}41.17%{transform:translate(113.4px,177.39px)}41.85%{transform:translate(113.17px,177.14px)}42.52%{transform:translate(112.8px,176.71px)}43.19%{transform:translate(112.24px,175.96px)}43.87%{transform:translate(111.51px,174.67px)}44.54%{transform:translate(111.03px,173.36px)}45.22%{transform:translate(110.86px,172.54px)}45.89%{transform:translate(110.81px,172.06px)}46.56%{transform:translate(110.79px,171.78px)}47.24%{transform:translate(110.79px,171.61px)}47.91%{transform:translate(110.79px,171.53px)}48.58%,100%{transform:translate(110.79px,171.51px)}}
25
+ .camera-intro__vTfr{animation-name:camera-intro-vTfr}@keyframes camera-intro-vTfr{0%,39.15%{transform:translate(142.61px,182.11px)}39.82%{transform:translate(142.57px,182.12px)}40.50%{transform:translate(142.44px,182.17px)}41.17%{transform:translate(142.2px,182.25px)}41.85%{transform:translate(141.76px,182.38px)}42.52%{transform:translate(141.02px,182.59px)}43.19%{transform:translate(139.71px,182.92px)}43.87%{transform:translate(137.49px,183.34px)}44.54%{transform:translate(135.21px,183.61px)}45.22%{transform:translate(133.79px,183.71px)}45.89%{transform:translate(132.97px,183.74px)}46.56%{transform:translate(132.47px,183.75px)}47.24%{transform:translate(132.19px,183.75px)}47.91%{transform:translate(132.04px,183.75px)}48.58%,100%{transform:translate(132px,183.75px)}}
26
+ .camera-intro__vBfl{animation-name:camera-intro-vBfl}@keyframes camera-intro-vBfl{0%,39.15%{transform:translate(113.63px,202.12px)}39.82%{transform:translate(113.61px,202.1px)}40.50%{transform:translate(113.54px,202.03px)}41.17%{transform:translate(113.4px,201.89px)}41.85%{transform:translate(113.17px,201.63px)}42.52%{transform:translate(112.8px,201.21px)}43.19%{transform:translate(112.24px,200.45px)}43.87%{transform:translate(111.51px,199.17px)}44.54%{transform:translate(111.03px,197.85px)}45.22%{transform:translate(110.86px,197.03px)}45.89%{transform:translate(110.81px,196.56px)}46.56%{transform:translate(110.79px,196.27px)}47.24%{transform:translate(110.79px,196.11px)}47.91%{transform:translate(110.79px,196.02px)}48.58%,100%{transform:translate(110.79px,196px)}}
27
+ .camera-intro__vBfr{animation-name:camera-intro-vBfr}@keyframes camera-intro-vBfr{0%,39.15%{transform:translate(142.61px,206.61px)}39.82%{transform:translate(142.57px,206.62px)}40.50%{transform:translate(142.44px,206.66px)}41.17%{transform:translate(142.2px,206.74px)}41.85%{transform:translate(141.76px,206.87px)}42.52%{transform:translate(141.02px,207.09px)}43.19%{transform:translate(139.71px,207.41px)}43.87%{transform:translate(137.49px,207.83px)}44.54%{transform:translate(135.21px,208.11px)}45.22%{transform:translate(133.79px,208.2px)}45.89%{transform:translate(132.97px,208.23px)}46.56%{transform:translate(132.47px,208.24px)}47.24%{transform:translate(132.19px,208.25px)}47.91%{transform:translate(132.04px,208.25px)}48.58%,100%{transform:translate(132px,208.25px)}}
28
+ .camera-intro__vBbr{animation-name:camera-intro-vBbr}@keyframes camera-intro-vBbr{0%,39.15%{transform:translate(150.37px,189.88px)}39.82%{transform:translate(150.39px,189.9px)}40.50%{transform:translate(150.46px,189.97px)}41.17%{transform:translate(150.6px,190.11px)}41.85%{transform:translate(150.83px,190.37px)}42.52%{transform:translate(151.2px,190.79px)}43.19%{transform:translate(151.76px,191.55px)}43.87%{transform:translate(152.49px,192.83px)}44.54%{transform:translate(152.97px,194.15px)}45.22%{transform:translate(153.14px,194.97px)}45.89%{transform:translate(153.19px,195.44px)}46.56%{transform:translate(153.21px,195.73px)}47.24%{transform:translate(153.21px,195.89px)}47.91%{transform:translate(153.21px,195.98px)}48.58%,100%{transform:translate(153.21px,196px)}}
29
+ @keyframes camera-intro-move{0%,55.66%{transform:none;animation-timing-function:cubic-bezier(.7,0,.3,1)}65.09%,100%{transform:translate(0px,-53.59px) scale(0.85)}}
30
+ @keyframes camera-intro-finger{0%,36.79%{opacity:0;transform:translate(150px,230px);animation-timing-function:cubic-bezier(.34,1.56,.64,1)}39.15%{opacity:1;transform:translate(150px,224px);animation-timing-function:cubic-bezier(.7,0,.3,1)}48.58%{opacity:1;transform:translate(114px,224px);animation-timing-function:cubic-bezier(.5,0,.75,0)}51.42%{opacity:0;transform:translate(114px,230px)}53.30%{opacity:0;transform:translate(132px,189.75px);animation-timing-function:cubic-bezier(.34,1.56,.64,1)}55.66%{opacity:1;transform:translate(132px,183.75px);animation-timing-function:cubic-bezier(.7,0,.3,1)}65.09%{opacity:1;transform:translate(132px,132px);animation-timing-function:cubic-bezier(.5,0,.75,0)}67.92%,100%{opacity:0;transform:translate(132px,138px)}}
31
+ @keyframes camera-intro-ring{0%,36.79%{transform:scale(.4);animation-timing-function:cubic-bezier(.34,1.56,.64,1)}39.15%,48.58%{transform:scale(1);animation-timing-function:ease-out}51.42%{transform:scale(1.6)}53.30%{transform:scale(.4);animation-timing-function:cubic-bezier(.34,1.56,.64,1)}55.66%,65.09%{transform:scale(1);animation-timing-function:ease-out}67.92%,100%{transform:scale(1.6)}}
32
+ .camera-intro__pan{transform-box:view-box;animation:camera-intro-pan 10.6s infinite both}
33
+ @keyframes camera-intro-pan{0%,7.55%{transform:translate(0,0);animation-timing-function:cubic-bezier(.45,0,.55,1)}12.26%{transform:translate(0,-16px);animation-timing-function:cubic-bezier(.45,0,.55,1)}17.45%{transform:translate(-10px,-16px);animation-timing-function:cubic-bezier(.45,0,.55,1)}23.11%{transform:translate(10px,-16px);animation-timing-function:cubic-bezier(.45,0,.55,1)}27.36%,100%{transform:translate(0,0)}}
34
+ .camera-intro__d104{animation:camera-intro-d104 10.6s infinite both}@keyframes camera-intro-d104{0%,20.75%{opacity:0}22.17%,32.08%{opacity:1}36.79%,100%{opacity:0}}
35
+ .camera-intro__d112{animation:camera-intro-d112 10.6s infinite both}@keyframes camera-intro-d112{0%,19.81%{opacity:0}21.23%,32.08%{opacity:1}36.79%,100%{opacity:0}}
36
+ .camera-intro__d120{animation:camera-intro-d120 10.6s infinite both}@keyframes camera-intro-d120{0%,18.87%{opacity:0}20.28%,32.08%{opacity:1}36.79%,100%{opacity:0}}
37
+ .camera-intro__d128{animation:camera-intro-d128 10.6s infinite both}@keyframes camera-intro-d128{0%,17.92%{opacity:0}19.34%,32.08%{opacity:1}36.79%,100%{opacity:0}}
38
+ .camera-intro__d136{animation:camera-intro-d136 10.6s infinite both}@keyframes camera-intro-d136{0%,12.74%{opacity:0}14.15%,32.08%{opacity:1}36.79%,100%{opacity:0}}
39
+ .camera-intro__d144{animation:camera-intro-d144 10.6s infinite both}@keyframes camera-intro-d144{0%,13.68%{opacity:0}15.09%,32.08%{opacity:1}36.79%,100%{opacity:0}}
40
+ .camera-intro__d152{animation:camera-intro-d152 10.6s infinite both}@keyframes camera-intro-d152{0%,14.62%{opacity:0}16.04%,32.08%{opacity:1}36.79%,100%{opacity:0}}
41
+ .camera-intro__d160{animation:camera-intro-d160 10.6s infinite both}@keyframes camera-intro-d160{0%,15.57%{opacity:0}16.98%,32.08%{opacity:1}36.79%,100%{opacity:0}}
42
+
43
+ .camera-intro__bg{animation:camera-intro-bg 10.6s infinite both}
44
+ @keyframes camera-intro-bg{0%,59.43%{opacity:1}66.04%,100%{opacity:0}}
45
+ .camera-intro__stand{animation:camera-intro-standfade 10.6s infinite both}
46
+ @keyframes camera-intro-standfade{0%,30.19%{opacity:0;transform:scale(.6);animation-timing-function:cubic-bezier(.34,1.56,.64,1)}33.96%,60.38%{opacity:1;transform:none}65.09%,100%{opacity:0;transform:none}}
47
+ .camera-intro__faces{animation:camera-intro-faces 10.6s infinite both}
48
+ @keyframes camera-intro-faces{0%,69.81%{opacity:1}73.11%,100%{opacity:0}}
49
+ .camera-intro__wire{animation:camera-intro-wire 10.6s infinite both}
50
+ @keyframes camera-intro-wire{0%,69.81%{opacity:1}69.91%,100%{opacity:0}}
51
+ .camera-intro__logo{animation:camera-intro-logo 10.6s infinite both}
52
+ @keyframes camera-intro-logo{0%,69.81%{opacity:0}69.91%,100%{opacity:1}}
53
+ .camera-intro__lw{animation:camera-intro-lw 10.6s infinite both}
54
+ @keyframes camera-intro-lw{0%,78.30%{stroke-width:1.7px;animation-timing-function:cubic-bezier(.34,1.56,.64,1)}81.60%,100%{stroke-width:4.37px}}
55
+ .camera-intro__spin{transform-box:view-box;transform-origin:132px 132px;animation:camera-intro-spin 10.6s infinite both}
56
+ @keyframes camera-intro-spin{0%,71.70%{transform:rotate(0deg);animation-timing-function:cubic-bezier(.5,0,.9,.6)}74.06%{transform:rotate(30deg) scale(.86);animation-timing-function:cubic-bezier(.2,.5,.4,1.25)}76.60%,100%{transform:rotate(60deg) scale(1)}}
57
+ .camera-intro__orbit{stroke-dasharray:1;transform-box:view-box;transform-origin:132px 132px;transform:rotate(-90deg);animation:camera-intro-orbit 10.6s infinite both}
58
+ @keyframes camera-intro-orbit{0%,72.55%{stroke-dashoffset:1;opacity:0}72.64%{stroke-dashoffset:1;opacity:1;animation-timing-function:cubic-bezier(.45,0,.3,1)}77.36%,78.77%{stroke-dashoffset:0;opacity:1}80.66%,100%{stroke-dashoffset:0;opacity:0}}
59
+ .camera-intro__disc{transform-box:view-box;transform-origin:132px 132px;animation:camera-intro-disc 10.6s infinite both}
60
+ @keyframes camera-intro-disc{0%,76.89%{transform:scale(0);animation-timing-function:cubic-bezier(.34,1.56,.64,1)}80.66%,100%{transform:none}}
61
+ .camera-intro__hub{transform-box:view-box;transform-origin:132px 132px;animation:camera-intro-hub 10.6s infinite both}
62
+ @keyframes camera-intro-hub{0%,79.72%{transform:scale(0);animation-timing-function:cubic-bezier(.34,1.56,.64,1)}83.02%,100%{transform:none}}
63
+ .camera-intro__all{animation:camera-intro-all 10.6s infinite both}
64
+ @keyframes camera-intro-all{0%,2.83%{opacity:0}7.55%,92.45%{opacity:1}97.17%,100%{opacity:0}}
65
+
66
+ @media (prefers-reduced-motion:reduce){
67
+ .camera-intro__k,.camera-intro__move,.camera-intro__drop,.camera-intro__finger,.camera-intro__stand,.camera-intro__ring,.camera-intro__bg,.camera-intro__all,.camera-intro__pan,.camera-intro__dot,.camera-intro__faces,.camera-intro__wire,.camera-intro__logo,.camera-intro__lw,.camera-intro__spin,.camera-intro__orbit,.camera-intro__disc,.camera-intro__hub{animation:none}
68
+ .camera-intro__bg,.camera-intro__all,.camera-intro__drop,.camera-intro__stand,.camera-intro__faces,.camera-intro__wire{opacity:1;transform:none}
69
+ .camera-intro__move,.camera-intro__pan{transform:none}
70
+ .camera-intro__finger,.camera-intro__dot,.camera-intro__logo,.camera-intro__disc,.camera-intro__orbit{opacity:0}
71
+ .camera-intro__top{transform:translate(110.79px,171.51px) rotate(30deg) skewX(-30deg) scale(24.49,-21.21)}
72
+ .camera-intro__front{transform:translate(110.79px,196px) rotate(30deg) skewX(30deg) scale(24.49,-21.21)}
73
+ .camera-intro__right{transform:translate(132px,208.25px) rotate(-30deg) skewX(-30deg) scale(24.49,-21.21)}
74
+ .camera-intro__e0{transform:translate(132px,159.26px) rotate(30deg) scaleX(24.49)}
75
+ .camera-intro__e1{transform:translate(153.21px,171.51px) rotate(150deg) scaleX(24.49)}
76
+ .camera-intro__e2{transform:translate(132px,183.75px) rotate(-150deg) scaleX(24.49)}
77
+ .camera-intro__e3{transform:translate(110.79px,171.51px) rotate(-30deg) scaleX(24.49)}
78
+ .camera-intro__e4{transform:translate(110.79px,171.51px) rotate(90deg) scaleX(24.49)}
79
+ .camera-intro__e5{transform:translate(132px,183.75px) rotate(90deg) scaleX(24.49)}
80
+ .camera-intro__e6{transform:translate(153.21px,171.51px) rotate(90deg) scaleX(24.49)}
81
+ .camera-intro__e7{transform:translate(110.79px,196px) rotate(30deg) scaleX(24.49)}
82
+ .camera-intro__e8{transform:translate(132px,208.25px) rotate(-30deg) scaleX(24.49)}
83
+ .camera-intro__vTbl{transform:translate(132px,159.26px)}
84
+ .camera-intro__vTbr{transform:translate(153.21px,171.51px)}
85
+ .camera-intro__vTfl{transform:translate(110.79px,171.51px)}
86
+ .camera-intro__vTfr{transform:translate(132px,183.75px)}
87
+ .camera-intro__vBfl{transform:translate(110.79px,196px)}
88
+ .camera-intro__vBfr{transform:translate(132px,208.25px)}
89
+ .camera-intro__vBbr{transform:translate(153.21px,196px)}
90
+ }
91
+ </style>
92
+ <defs>
93
+ <clipPath id="camera-intro-scr"><rect x="87" y="31" width="90" height="202" rx="13"/></clipPath>
94
+ <linearGradient id="camera-intro-gw" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#4B4D58"/><stop offset="1" stop-color="#3B3C45"/></linearGradient>
95
+ <linearGradient id="camera-intro-gfl" x1="0" y1="150" x2="0" y2="233" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#34353D"/><stop offset="1" stop-color="#1F2025"/></linearGradient>
96
+ <linearGradient id="camera-intro-gc" x1="0" y1="31" x2="0" y2="92" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#202127"/><stop offset="1" stop-color="#33343C"/></linearGradient>
97
+ <linearGradient id="camera-intro-gl" x1="87" y1="0" x2="177" y2="0" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#26272D"/><stop offset=".2" stop-color="#35363E" stop-opacity="0"/><stop offset=".8" stop-color="#35363E" stop-opacity="0"/><stop offset="1" stop-color="#26272D"/></linearGradient>
98
+ <linearGradient id="camera-intro-gwin" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#8A8EA0"/><stop offset="1" stop-color="#666979"/></linearGradient>
99
+ <linearGradient id="camera-intro-glt" x1="0" y1="150" x2="0" y2="200" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff" stop-opacity=".1"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient>
100
+ <linearGradient id="camera-intro-gt" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#7A7B86"/><stop offset="1" stop-color="#666772"/></linearGradient>
101
+ <linearGradient id="camera-intro-gf" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#55565F"/><stop offset="1" stop-color="#43444C"/></linearGradient>
102
+ <linearGradient id="camera-intro-gr" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#3D3E46"/><stop offset="1" stop-color="#2E2F35"/></linearGradient>
103
+ <radialGradient id="camera-intro-sh"><stop offset="0" stop-color="#000" stop-opacity=".5"/><stop offset="1" stop-color="#000" stop-opacity="0"/></radialGradient>
104
+ <linearGradient id="camera-intro-o" x1="107.37" y1="156.63" x2="156.63" y2="107.37" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#E2335C"/><stop offset=".5" stop-color="#F0622E"/><stop offset="1" stop-color="#F8A43C"/></linearGradient>
105
+ </defs>
106
+ <rect x="83" y="27" width="98" height="210" rx="17" fill="#121317" stroke="#E9EAEE" stroke-width="2.5"/>
107
+ <path d="M81.5 70V84M81.5 92V106M182.5 80V102" stroke="#E9EAEE" stroke-width="2" stroke-linecap="round"/>
108
+ <rect x="87" y="31" width="90" height="202" rx="13" fill="#1B1C21"/>
109
+ <g clip-path="url(#camera-intro-scr)"><g class="camera-intro__all">
110
+ <g class="camera-intro__bg">
111
+ <g class="camera-intro__pan">
112
+ <path d="M100 92L-45.66 -40H309.66L164 92Z" fill="url(#camera-intro-gc)"/><path d="M100 92L-45.66 -40V300L100 150ZM164 92L309.66 -40V300L164 150Z" fill="#2C2D34"/><path d="M100 150L-65.52 300H329.52L164 150Z" fill="url(#camera-intro-gfl)"/>
113
+ <path d="M100 92H164V150H100Z" fill="url(#camera-intro-gw)"/>
114
+ <rect x="116" y="102" width="32" height="30" rx="2" fill="url(#camera-intro-gwin)"/>
115
+ <path d="M116 150H148L175.59 200H88.41Z" fill="url(#camera-intro-glt)"/>
116
+ <g fill="#5B6BFF"><g class="camera-intro__dot camera-intro__d104"><circle cx="92.41" cy="162" r="0.96"/><circle cx="78.9" cy="176" r="1.27"/><circle cx="61.52" cy="194" r="1.67"/><circle cx="40.28" cy="216" r="2.15"/><circle cx="15.17" cy="242" r="2.72"/></g><g class="camera-intro__dot camera-intro__d112"><circle cx="103.72" cy="162" r="0.96"/><circle cx="94.07" cy="176" r="1.27"/><circle cx="81.66" cy="194" r="1.67"/><circle cx="66.48" cy="216" r="2.15"/><circle cx="48.55" cy="242" r="2.72"/></g><g class="camera-intro__dot camera-intro__d120"><circle cx="115.03" cy="162" r="0.96"/><circle cx="109.24" cy="176" r="1.27"/><circle cx="101.79" cy="194" r="1.67"/><circle cx="92.69" cy="216" r="2.15"/><circle cx="81.93" cy="242" r="2.72"/></g><g class="camera-intro__dot camera-intro__d128"><circle cx="126.34" cy="162" r="0.96"/><circle cx="124.41" cy="176" r="1.27"/><circle cx="121.93" cy="194" r="1.67"/><circle cx="118.9" cy="216" r="2.15"/><circle cx="115.31" cy="242" r="2.72"/></g><g class="camera-intro__dot camera-intro__d136"><circle cx="137.66" cy="162" r="0.96"/><circle cx="139.59" cy="176" r="1.27"/><circle cx="142.07" cy="194" r="1.67"/><circle cx="145.1" cy="216" r="2.15"/><circle cx="148.69" cy="242" r="2.72"/></g><g class="camera-intro__dot camera-intro__d144"><circle cx="148.97" cy="162" r="0.96"/><circle cx="154.76" cy="176" r="1.27"/><circle cx="162.21" cy="194" r="1.67"/><circle cx="171.31" cy="216" r="2.15"/><circle cx="182.07" cy="242" r="2.72"/></g><g class="camera-intro__dot camera-intro__d152"><circle cx="160.28" cy="162" r="0.96"/><circle cx="169.93" cy="176" r="1.27"/><circle cx="182.34" cy="194" r="1.67"/><circle cx="197.52" cy="216" r="2.15"/><circle cx="215.45" cy="242" r="2.72"/></g><g class="camera-intro__dot camera-intro__d160"><circle cx="171.59" cy="162" r="0.96"/><circle cx="185.1" cy="176" r="1.27"/><circle cx="202.48" cy="194" r="1.67"/><circle cx="223.72" cy="216" r="2.15"/><circle cx="248.83" cy="242" r="2.72"/></g></g>
117
+ </g>
118
+ <rect x="87" y="31" width="90" height="202" fill="url(#camera-intro-gl)"/>
119
+ </g>
120
+ <circle class="camera-intro__disc" cx="132" cy="132" r="35.19" fill="url(#camera-intro-o)"/>
121
+ <circle class="camera-intro__orbit" pathLength="1" cx="132" cy="132" r="35.19" fill="none" stroke="#fff" stroke-opacity=".6" stroke-width="1.5" stroke-linecap="round"/>
122
+ <g class="camera-intro__drop"><g class="camera-intro__move">
123
+ <g class="camera-intro__stand"><ellipse cx="132" cy="199" rx="29.93" ry="18.85" fill="url(#camera-intro-sh)"/>
124
+ <ellipse cx="132" cy="196" rx="27.21" ry="15.71" fill="none" stroke="#fff" stroke-opacity=".5" stroke-width="1.5"/></g>
125
+ <g class="camera-intro__faces"><path class="camera-intro__k camera-intro__top" d="M0 0H1V1H0Z" fill="url(#camera-intro-gt)"/><path class="camera-intro__k camera-intro__front" d="M0 0H1V1H0Z" fill="url(#camera-intro-gf)"/><path class="camera-intro__k camera-intro__right" d="M0 0H1V1H0Z" fill="url(#camera-intro-gr)"/></g>
126
+ <g class="camera-intro__wire"><g stroke="#F4F5F8" stroke-width="2" fill="none"><path class="camera-intro__k camera-intro__e0" d="M0 0H1"/><path class="camera-intro__k camera-intro__e1" d="M0 0H1"/><path class="camera-intro__k camera-intro__e2" d="M0 0H1"/><path class="camera-intro__k camera-intro__e3" d="M0 0H1"/><path class="camera-intro__k camera-intro__e4" d="M0 0H1"/><path class="camera-intro__k camera-intro__e5" d="M0 0H1"/><path class="camera-intro__k camera-intro__e6" d="M0 0H1"/><path class="camera-intro__k camera-intro__e7" d="M0 0H1"/><path class="camera-intro__k camera-intro__e8" d="M0 0H1"/></g><g fill="#F4F5F8"><circle class="camera-intro__k camera-intro__vTbl" r="1"/><circle class="camera-intro__k camera-intro__vTbr" r="1"/><circle class="camera-intro__k camera-intro__vTfl" r="1"/><circle class="camera-intro__k camera-intro__vTfr" r="1"/><circle class="camera-intro__k camera-intro__vBfl" r="1"/><circle class="camera-intro__k camera-intro__vBfr" r="1"/><circle class="camera-intro__k camera-intro__vBbr" r="1"/></g></g>
127
+ </g></g>
128
+ <g class="camera-intro__logo" fill="none" stroke="#F4F5F8" stroke-linejoin="round" stroke-linecap="round">
129
+ <path class="camera-intro__lw" d="M132 152.82L113.97 142.41L113.97 121.59L132 111.18L150.03 121.59L150.03 142.41Z"/>
130
+ <g class="camera-intro__spin"><path class="camera-intro__lw" d="M132 132L113.97 121.59M132 132L150.03 121.59M132 132L132 152.82"/></g>
131
+ <circle class="camera-intro__hub" cx="132" cy="132" r="6.04" fill="url(#camera-intro-o)" stroke-width="4.37"/>
132
+ </g>
133
+ <g class="camera-intro__finger">
134
+ <circle class="camera-intro__ring" r="8" fill="#fff" stroke="#5B6BFF" stroke-opacity=".7" stroke-width="1.75"/>
135
+ <circle r="5" fill="#5B6BFF"/>
136
+ </g>
137
+ </g></g>
138
+ <rect x="119" y="36" width="26" height="8" rx="4" fill="#000"/>
139
+ </svg>